VPP-1032: fix coverity warnings
[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, (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 not_last = 0;
7568   u8 is_multipath = 0;
7569   u8 address_set = 0;
7570   u8 address_length_set = 0;
7571   u32 next_hop_table_id = 0;
7572   u32 resolve_attempts = 0;
7573   u32 dst_address_length = 0;
7574   u8 next_hop_set = 0;
7575   ip4_address_t v4_dst_address, v4_next_hop_address;
7576   ip6_address_t v6_dst_address, v6_next_hop_address;
7577   int count = 1;
7578   int j;
7579   f64 before = 0;
7580   u32 random_add_del = 0;
7581   u32 *random_vector = 0;
7582   uword *random_hash;
7583   u32 random_seed = 0xdeaddabe;
7584   u32 classify_table_index = ~0;
7585   u8 is_classify = 0;
7586   u8 resolve_host = 0, resolve_attached = 0;
7587   mpls_label_t *next_hop_out_label_stack = NULL;
7588   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7589   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7590
7591   /* Parse args required to build the message */
7592   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7593     {
7594       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7595         ;
7596       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7597         ;
7598       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
7599         {
7600           address_set = 1;
7601           is_ipv6 = 0;
7602         }
7603       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
7604         {
7605           address_set = 1;
7606           is_ipv6 = 1;
7607         }
7608       else if (unformat (i, "/%d", &dst_address_length))
7609         {
7610           address_length_set = 1;
7611         }
7612
7613       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
7614                                          &v4_next_hop_address))
7615         {
7616           next_hop_set = 1;
7617         }
7618       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
7619                                          &v6_next_hop_address))
7620         {
7621           next_hop_set = 1;
7622         }
7623       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
7624         ;
7625       else if (unformat (i, "weight %d", &next_hop_weight))
7626         ;
7627       else if (unformat (i, "drop"))
7628         {
7629           is_drop = 1;
7630         }
7631       else if (unformat (i, "null-send-unreach"))
7632         {
7633           is_unreach = 1;
7634         }
7635       else if (unformat (i, "null-send-prohibit"))
7636         {
7637           is_prohibit = 1;
7638         }
7639       else if (unformat (i, "local"))
7640         {
7641           is_local = 1;
7642         }
7643       else if (unformat (i, "classify %d", &classify_table_index))
7644         {
7645           is_classify = 1;
7646         }
7647       else if (unformat (i, "del"))
7648         is_add = 0;
7649       else if (unformat (i, "add"))
7650         is_add = 1;
7651       else if (unformat (i, "not-last"))
7652         not_last = 1;
7653       else if (unformat (i, "resolve-via-host"))
7654         resolve_host = 1;
7655       else if (unformat (i, "resolve-via-attached"))
7656         resolve_attached = 1;
7657       else if (unformat (i, "multipath"))
7658         is_multipath = 1;
7659       else if (unformat (i, "vrf %d", &vrf_id))
7660         ;
7661       else if (unformat (i, "create-vrf"))
7662         create_vrf_if_needed = 1;
7663       else if (unformat (i, "count %d", &count))
7664         ;
7665       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
7666         ;
7667       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7668         ;
7669       else if (unformat (i, "out-label %d", &next_hop_out_label))
7670         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7671       else if (unformat (i, "via-label %d", &next_hop_via_label))
7672         ;
7673       else if (unformat (i, "random"))
7674         random_add_del = 1;
7675       else if (unformat (i, "seed %d", &random_seed))
7676         ;
7677       else
7678         {
7679           clib_warning ("parse error '%U'", format_unformat_error, i);
7680           return -99;
7681         }
7682     }
7683
7684   if (!next_hop_set && !is_drop && !is_local &&
7685       !is_classify && !is_unreach && !is_prohibit &&
7686       MPLS_LABEL_INVALID == next_hop_via_label)
7687     {
7688       errmsg
7689         ("next hop / local / drop / unreach / prohibit / classify not set");
7690       return -99;
7691     }
7692
7693   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
7694     {
7695       errmsg ("next hop and next-hop via label set");
7696       return -99;
7697     }
7698   if (address_set == 0)
7699     {
7700       errmsg ("missing addresses");
7701       return -99;
7702     }
7703
7704   if (address_length_set == 0)
7705     {
7706       errmsg ("missing address length");
7707       return -99;
7708     }
7709
7710   /* Generate a pile of unique, random routes */
7711   if (random_add_del)
7712     {
7713       u32 this_random_address;
7714       random_hash = hash_create (count, sizeof (uword));
7715
7716       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
7717       for (j = 0; j <= count; j++)
7718         {
7719           do
7720             {
7721               this_random_address = random_u32 (&random_seed);
7722               this_random_address =
7723                 clib_host_to_net_u32 (this_random_address);
7724             }
7725           while (hash_get (random_hash, this_random_address));
7726           vec_add1 (random_vector, this_random_address);
7727           hash_set (random_hash, this_random_address, 1);
7728         }
7729       hash_free (random_hash);
7730       v4_dst_address.as_u32 = random_vector[0];
7731     }
7732
7733   if (count > 1)
7734     {
7735       /* Turn on async mode */
7736       vam->async_mode = 1;
7737       vam->async_errors = 0;
7738       before = vat_time_now (vam);
7739     }
7740
7741   for (j = 0; j < count; j++)
7742     {
7743       /* Construct the API message */
7744       M2 (IP_ADD_DEL_ROUTE, mp,
7745           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7746
7747       mp->next_hop_sw_if_index = ntohl (sw_if_index);
7748       mp->table_id = ntohl (vrf_id);
7749       mp->create_vrf_if_needed = create_vrf_if_needed;
7750
7751       mp->is_add = is_add;
7752       mp->is_drop = is_drop;
7753       mp->is_unreach = is_unreach;
7754       mp->is_prohibit = is_prohibit;
7755       mp->is_ipv6 = is_ipv6;
7756       mp->is_local = is_local;
7757       mp->is_classify = is_classify;
7758       mp->is_multipath = is_multipath;
7759       mp->is_resolve_host = resolve_host;
7760       mp->is_resolve_attached = resolve_attached;
7761       mp->not_last = not_last;
7762       mp->next_hop_weight = next_hop_weight;
7763       mp->dst_address_length = dst_address_length;
7764       mp->next_hop_table_id = ntohl (next_hop_table_id);
7765       mp->classify_table_index = ntohl (classify_table_index);
7766       mp->next_hop_via_label = ntohl (next_hop_via_label);
7767       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7768       if (0 != mp->next_hop_n_out_labels)
7769         {
7770           memcpy (mp->next_hop_out_label_stack,
7771                   next_hop_out_label_stack,
7772                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7773           vec_free (next_hop_out_label_stack);
7774         }
7775
7776       if (is_ipv6)
7777         {
7778           clib_memcpy (mp->dst_address, &v6_dst_address,
7779                        sizeof (v6_dst_address));
7780           if (next_hop_set)
7781             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
7782                          sizeof (v6_next_hop_address));
7783           increment_v6_address (&v6_dst_address);
7784         }
7785       else
7786         {
7787           clib_memcpy (mp->dst_address, &v4_dst_address,
7788                        sizeof (v4_dst_address));
7789           if (next_hop_set)
7790             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
7791                          sizeof (v4_next_hop_address));
7792           if (random_add_del)
7793             v4_dst_address.as_u32 = random_vector[j + 1];
7794           else
7795             increment_v4_address (&v4_dst_address);
7796         }
7797       /* send it... */
7798       S (mp);
7799       /* If we receive SIGTERM, stop now... */
7800       if (vam->do_exit)
7801         break;
7802     }
7803
7804   /* When testing multiple add/del ops, use a control-ping to sync */
7805   if (count > 1)
7806     {
7807       vl_api_control_ping_t *mp_ping;
7808       f64 after;
7809       f64 timeout;
7810
7811       /* Shut off async mode */
7812       vam->async_mode = 0;
7813
7814       MPING (CONTROL_PING, mp_ping);
7815       S (mp_ping);
7816
7817       timeout = vat_time_now (vam) + 1.0;
7818       while (vat_time_now (vam) < timeout)
7819         if (vam->result_ready == 1)
7820           goto out;
7821       vam->retval = -99;
7822
7823     out:
7824       if (vam->retval == -99)
7825         errmsg ("timeout");
7826
7827       if (vam->async_errors > 0)
7828         {
7829           errmsg ("%d asynchronous errors", vam->async_errors);
7830           vam->retval = -98;
7831         }
7832       vam->async_errors = 0;
7833       after = vat_time_now (vam);
7834
7835       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7836       if (j > 0)
7837         count = j;
7838
7839       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7840              count, after - before, count / (after - before));
7841     }
7842   else
7843     {
7844       int ret;
7845
7846       /* Wait for a reply... */
7847       W (ret);
7848       return ret;
7849     }
7850
7851   /* Return the good/bad news */
7852   return (vam->retval);
7853 }
7854
7855 static int
7856 api_ip_mroute_add_del (vat_main_t * vam)
7857 {
7858   unformat_input_t *i = vam->input;
7859   vl_api_ip_mroute_add_del_t *mp;
7860   u32 sw_if_index = ~0, vrf_id = 0;
7861   u8 is_ipv6 = 0;
7862   u8 is_local = 0;
7863   u8 create_vrf_if_needed = 0;
7864   u8 is_add = 1;
7865   u8 address_set = 0;
7866   u32 grp_address_length = 0;
7867   ip4_address_t v4_grp_address, v4_src_address;
7868   ip6_address_t v6_grp_address, v6_src_address;
7869   mfib_itf_flags_t iflags = 0;
7870   mfib_entry_flags_t eflags = 0;
7871   int ret;
7872
7873   /* Parse args required to build the message */
7874   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7875     {
7876       if (unformat (i, "sw_if_index %d", &sw_if_index))
7877         ;
7878       else if (unformat (i, "%U %U",
7879                          unformat_ip4_address, &v4_src_address,
7880                          unformat_ip4_address, &v4_grp_address))
7881         {
7882           grp_address_length = 64;
7883           address_set = 1;
7884           is_ipv6 = 0;
7885         }
7886       else if (unformat (i, "%U %U",
7887                          unformat_ip6_address, &v6_src_address,
7888                          unformat_ip6_address, &v6_grp_address))
7889         {
7890           grp_address_length = 256;
7891           address_set = 1;
7892           is_ipv6 = 1;
7893         }
7894       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
7895         {
7896           memset (&v4_src_address, 0, sizeof (v4_src_address));
7897           grp_address_length = 32;
7898           address_set = 1;
7899           is_ipv6 = 0;
7900         }
7901       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
7902         {
7903           memset (&v6_src_address, 0, sizeof (v6_src_address));
7904           grp_address_length = 128;
7905           address_set = 1;
7906           is_ipv6 = 1;
7907         }
7908       else if (unformat (i, "/%d", &grp_address_length))
7909         ;
7910       else if (unformat (i, "local"))
7911         {
7912           is_local = 1;
7913         }
7914       else if (unformat (i, "del"))
7915         is_add = 0;
7916       else if (unformat (i, "add"))
7917         is_add = 1;
7918       else if (unformat (i, "vrf %d", &vrf_id))
7919         ;
7920       else if (unformat (i, "create-vrf"))
7921         create_vrf_if_needed = 1;
7922       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
7923         ;
7924       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
7925         ;
7926       else
7927         {
7928           clib_warning ("parse error '%U'", format_unformat_error, i);
7929           return -99;
7930         }
7931     }
7932
7933   if (address_set == 0)
7934     {
7935       errmsg ("missing addresses\n");
7936       return -99;
7937     }
7938
7939   /* Construct the API message */
7940   M (IP_MROUTE_ADD_DEL, mp);
7941
7942   mp->next_hop_sw_if_index = ntohl (sw_if_index);
7943   mp->table_id = ntohl (vrf_id);
7944   mp->create_vrf_if_needed = create_vrf_if_needed;
7945
7946   mp->is_add = is_add;
7947   mp->is_ipv6 = is_ipv6;
7948   mp->is_local = is_local;
7949   mp->itf_flags = ntohl (iflags);
7950   mp->entry_flags = ntohl (eflags);
7951   mp->grp_address_length = grp_address_length;
7952   mp->grp_address_length = ntohs (mp->grp_address_length);
7953
7954   if (is_ipv6)
7955     {
7956       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
7957       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
7958     }
7959   else
7960     {
7961       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
7962       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
7963
7964     }
7965
7966   /* send it... */
7967   S (mp);
7968   /* Wait for a reply... */
7969   W (ret);
7970   return ret;
7971 }
7972
7973 static int
7974 api_mpls_table_add_del (vat_main_t * vam)
7975 {
7976   unformat_input_t *i = vam->input;
7977   vl_api_mpls_table_add_del_t *mp;
7978   u32 table_id = ~0;
7979   u8 is_add = 1;
7980   int ret = 0;
7981
7982   /* Parse args required to build the message */
7983   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7984     {
7985       if (unformat (i, "table %d", &table_id))
7986         ;
7987       else if (unformat (i, "del"))
7988         is_add = 0;
7989       else if (unformat (i, "add"))
7990         is_add = 1;
7991       else
7992         {
7993           clib_warning ("parse error '%U'", format_unformat_error, i);
7994           return -99;
7995         }
7996     }
7997
7998   if (~0 == table_id)
7999     {
8000       errmsg ("missing table-ID");
8001       return -99;
8002     }
8003
8004   /* Construct the API message */
8005   M (MPLS_TABLE_ADD_DEL, mp);
8006
8007   mp->mt_table_id = ntohl (table_id);
8008   mp->mt_is_add = is_add;
8009
8010   /* send it... */
8011   S (mp);
8012
8013   /* Wait for a reply... */
8014   W (ret);
8015
8016   return ret;
8017 }
8018
8019 static int
8020 api_mpls_route_add_del (vat_main_t * vam)
8021 {
8022   unformat_input_t *i = vam->input;
8023   vl_api_mpls_route_add_del_t *mp;
8024   u32 sw_if_index = ~0, table_id = 0;
8025   u8 create_table_if_needed = 0;
8026   u8 is_add = 1;
8027   u32 next_hop_weight = 1;
8028   u8 is_multipath = 0;
8029   u32 next_hop_table_id = 0;
8030   u8 next_hop_set = 0;
8031   ip4_address_t v4_next_hop_address = {
8032     .as_u32 = 0,
8033   };
8034   ip6_address_t v6_next_hop_address = { {0} };
8035   int count = 1;
8036   int j;
8037   f64 before = 0;
8038   u32 classify_table_index = ~0;
8039   u8 is_classify = 0;
8040   u8 resolve_host = 0, resolve_attached = 0;
8041   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8042   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8043   mpls_label_t *next_hop_out_label_stack = NULL;
8044   mpls_label_t local_label = MPLS_LABEL_INVALID;
8045   u8 is_eos = 0;
8046   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8047
8048   /* Parse args required to build the message */
8049   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8050     {
8051       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8052         ;
8053       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8054         ;
8055       else if (unformat (i, "%d", &local_label))
8056         ;
8057       else if (unformat (i, "eos"))
8058         is_eos = 1;
8059       else if (unformat (i, "non-eos"))
8060         is_eos = 0;
8061       else if (unformat (i, "via %U", unformat_ip4_address,
8062                          &v4_next_hop_address))
8063         {
8064           next_hop_set = 1;
8065           next_hop_proto = DPO_PROTO_IP4;
8066         }
8067       else if (unformat (i, "via %U", unformat_ip6_address,
8068                          &v6_next_hop_address))
8069         {
8070           next_hop_set = 1;
8071           next_hop_proto = DPO_PROTO_IP6;
8072         }
8073       else if (unformat (i, "weight %d", &next_hop_weight))
8074         ;
8075       else if (unformat (i, "create-table"))
8076         create_table_if_needed = 1;
8077       else if (unformat (i, "classify %d", &classify_table_index))
8078         {
8079           is_classify = 1;
8080         }
8081       else if (unformat (i, "del"))
8082         is_add = 0;
8083       else if (unformat (i, "add"))
8084         is_add = 1;
8085       else if (unformat (i, "resolve-via-host"))
8086         resolve_host = 1;
8087       else if (unformat (i, "resolve-via-attached"))
8088         resolve_attached = 1;
8089       else if (unformat (i, "multipath"))
8090         is_multipath = 1;
8091       else if (unformat (i, "count %d", &count))
8092         ;
8093       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8094         {
8095           next_hop_set = 1;
8096           next_hop_proto = DPO_PROTO_IP4;
8097         }
8098       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8099         {
8100           next_hop_set = 1;
8101           next_hop_proto = DPO_PROTO_IP6;
8102         }
8103       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8104         ;
8105       else if (unformat (i, "via-label %d", &next_hop_via_label))
8106         ;
8107       else if (unformat (i, "out-label %d", &next_hop_out_label))
8108         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8109       else
8110         {
8111           clib_warning ("parse error '%U'", format_unformat_error, i);
8112           return -99;
8113         }
8114     }
8115
8116   if (!next_hop_set && !is_classify)
8117     {
8118       errmsg ("next hop / classify not set");
8119       return -99;
8120     }
8121
8122   if (MPLS_LABEL_INVALID == local_label)
8123     {
8124       errmsg ("missing label");
8125       return -99;
8126     }
8127
8128   if (count > 1)
8129     {
8130       /* Turn on async mode */
8131       vam->async_mode = 1;
8132       vam->async_errors = 0;
8133       before = vat_time_now (vam);
8134     }
8135
8136   for (j = 0; j < count; j++)
8137     {
8138       /* Construct the API message */
8139       M2 (MPLS_ROUTE_ADD_DEL, mp,
8140           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8141
8142       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8143       mp->mr_table_id = ntohl (table_id);
8144       mp->mr_create_table_if_needed = create_table_if_needed;
8145
8146       mp->mr_is_add = is_add;
8147       mp->mr_next_hop_proto = next_hop_proto;
8148       mp->mr_is_classify = is_classify;
8149       mp->mr_is_multipath = is_multipath;
8150       mp->mr_is_resolve_host = resolve_host;
8151       mp->mr_is_resolve_attached = resolve_attached;
8152       mp->mr_next_hop_weight = next_hop_weight;
8153       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8154       mp->mr_classify_table_index = ntohl (classify_table_index);
8155       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8156       mp->mr_label = ntohl (local_label);
8157       mp->mr_eos = is_eos;
8158
8159       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8160       if (0 != mp->mr_next_hop_n_out_labels)
8161         {
8162           memcpy (mp->mr_next_hop_out_label_stack,
8163                   next_hop_out_label_stack,
8164                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8165           vec_free (next_hop_out_label_stack);
8166         }
8167
8168       if (next_hop_set)
8169         {
8170           if (DPO_PROTO_IP4 == next_hop_proto)
8171             {
8172               clib_memcpy (mp->mr_next_hop,
8173                            &v4_next_hop_address,
8174                            sizeof (v4_next_hop_address));
8175             }
8176           else if (DPO_PROTO_IP6 == next_hop_proto)
8177
8178             {
8179               clib_memcpy (mp->mr_next_hop,
8180                            &v6_next_hop_address,
8181                            sizeof (v6_next_hop_address));
8182             }
8183         }
8184       local_label++;
8185
8186       /* send it... */
8187       S (mp);
8188       /* If we receive SIGTERM, stop now... */
8189       if (vam->do_exit)
8190         break;
8191     }
8192
8193   /* When testing multiple add/del ops, use a control-ping to sync */
8194   if (count > 1)
8195     {
8196       vl_api_control_ping_t *mp_ping;
8197       f64 after;
8198       f64 timeout;
8199
8200       /* Shut off async mode */
8201       vam->async_mode = 0;
8202
8203       MPING (CONTROL_PING, mp_ping);
8204       S (mp_ping);
8205
8206       timeout = vat_time_now (vam) + 1.0;
8207       while (vat_time_now (vam) < timeout)
8208         if (vam->result_ready == 1)
8209           goto out;
8210       vam->retval = -99;
8211
8212     out:
8213       if (vam->retval == -99)
8214         errmsg ("timeout");
8215
8216       if (vam->async_errors > 0)
8217         {
8218           errmsg ("%d asynchronous errors", vam->async_errors);
8219           vam->retval = -98;
8220         }
8221       vam->async_errors = 0;
8222       after = vat_time_now (vam);
8223
8224       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8225       if (j > 0)
8226         count = j;
8227
8228       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8229              count, after - before, count / (after - before));
8230     }
8231   else
8232     {
8233       int ret;
8234
8235       /* Wait for a reply... */
8236       W (ret);
8237       return ret;
8238     }
8239
8240   /* Return the good/bad news */
8241   return (vam->retval);
8242 }
8243
8244 static int
8245 api_mpls_ip_bind_unbind (vat_main_t * vam)
8246 {
8247   unformat_input_t *i = vam->input;
8248   vl_api_mpls_ip_bind_unbind_t *mp;
8249   u32 ip_table_id = 0;
8250   u8 create_table_if_needed = 0;
8251   u8 is_bind = 1;
8252   u8 is_ip4 = 1;
8253   ip4_address_t v4_address;
8254   ip6_address_t v6_address;
8255   u32 address_length;
8256   u8 address_set = 0;
8257   mpls_label_t local_label = MPLS_LABEL_INVALID;
8258   int ret;
8259
8260   /* Parse args required to build the message */
8261   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8262     {
8263       if (unformat (i, "%U/%d", unformat_ip4_address,
8264                     &v4_address, &address_length))
8265         {
8266           is_ip4 = 1;
8267           address_set = 1;
8268         }
8269       else if (unformat (i, "%U/%d", unformat_ip6_address,
8270                          &v6_address, &address_length))
8271         {
8272           is_ip4 = 0;
8273           address_set = 1;
8274         }
8275       else if (unformat (i, "%d", &local_label))
8276         ;
8277       else if (unformat (i, "create-table"))
8278         create_table_if_needed = 1;
8279       else if (unformat (i, "table-id %d", &ip_table_id))
8280         ;
8281       else if (unformat (i, "unbind"))
8282         is_bind = 0;
8283       else if (unformat (i, "bind"))
8284         is_bind = 1;
8285       else
8286         {
8287           clib_warning ("parse error '%U'", format_unformat_error, i);
8288           return -99;
8289         }
8290     }
8291
8292   if (!address_set)
8293     {
8294       errmsg ("IP addres not set");
8295       return -99;
8296     }
8297
8298   if (MPLS_LABEL_INVALID == local_label)
8299     {
8300       errmsg ("missing label");
8301       return -99;
8302     }
8303
8304   /* Construct the API message */
8305   M (MPLS_IP_BIND_UNBIND, mp);
8306
8307   mp->mb_create_table_if_needed = create_table_if_needed;
8308   mp->mb_is_bind = is_bind;
8309   mp->mb_is_ip4 = is_ip4;
8310   mp->mb_ip_table_id = ntohl (ip_table_id);
8311   mp->mb_mpls_table_id = 0;
8312   mp->mb_label = ntohl (local_label);
8313   mp->mb_address_length = address_length;
8314
8315   if (is_ip4)
8316     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8317   else
8318     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8319
8320   /* send it... */
8321   S (mp);
8322
8323   /* Wait for a reply... */
8324   W (ret);
8325   return ret;
8326 }
8327
8328 static int
8329 api_proxy_arp_add_del (vat_main_t * vam)
8330 {
8331   unformat_input_t *i = vam->input;
8332   vl_api_proxy_arp_add_del_t *mp;
8333   u32 vrf_id = 0;
8334   u8 is_add = 1;
8335   ip4_address_t lo, hi;
8336   u8 range_set = 0;
8337   int ret;
8338
8339   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8340     {
8341       if (unformat (i, "vrf %d", &vrf_id))
8342         ;
8343       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
8344                          unformat_ip4_address, &hi))
8345         range_set = 1;
8346       else if (unformat (i, "del"))
8347         is_add = 0;
8348       else
8349         {
8350           clib_warning ("parse error '%U'", format_unformat_error, i);
8351           return -99;
8352         }
8353     }
8354
8355   if (range_set == 0)
8356     {
8357       errmsg ("address range not set");
8358       return -99;
8359     }
8360
8361   M (PROXY_ARP_ADD_DEL, mp);
8362
8363   mp->vrf_id = ntohl (vrf_id);
8364   mp->is_add = is_add;
8365   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
8366   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
8367
8368   S (mp);
8369   W (ret);
8370   return ret;
8371 }
8372
8373 static int
8374 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8375 {
8376   unformat_input_t *i = vam->input;
8377   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8378   u32 sw_if_index;
8379   u8 enable = 1;
8380   u8 sw_if_index_set = 0;
8381   int ret;
8382
8383   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8384     {
8385       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8386         sw_if_index_set = 1;
8387       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8388         sw_if_index_set = 1;
8389       else if (unformat (i, "enable"))
8390         enable = 1;
8391       else if (unformat (i, "disable"))
8392         enable = 0;
8393       else
8394         {
8395           clib_warning ("parse error '%U'", format_unformat_error, i);
8396           return -99;
8397         }
8398     }
8399
8400   if (sw_if_index_set == 0)
8401     {
8402       errmsg ("missing interface name or sw_if_index");
8403       return -99;
8404     }
8405
8406   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8407
8408   mp->sw_if_index = ntohl (sw_if_index);
8409   mp->enable_disable = enable;
8410
8411   S (mp);
8412   W (ret);
8413   return ret;
8414 }
8415
8416 static int
8417 api_mpls_tunnel_add_del (vat_main_t * vam)
8418 {
8419   unformat_input_t *i = vam->input;
8420   vl_api_mpls_tunnel_add_del_t *mp;
8421
8422   u8 is_add = 1;
8423   u8 l2_only = 0;
8424   u32 sw_if_index = ~0;
8425   u32 next_hop_sw_if_index = ~0;
8426   u32 next_hop_proto_is_ip4 = 1;
8427
8428   u32 next_hop_table_id = 0;
8429   ip4_address_t v4_next_hop_address = {
8430     .as_u32 = 0,
8431   };
8432   ip6_address_t v6_next_hop_address = { {0} };
8433   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
8434   int ret;
8435
8436   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8437     {
8438       if (unformat (i, "add"))
8439         is_add = 1;
8440       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8441         is_add = 0;
8442       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
8443         ;
8444       else if (unformat (i, "via %U",
8445                          unformat_ip4_address, &v4_next_hop_address))
8446         {
8447           next_hop_proto_is_ip4 = 1;
8448         }
8449       else if (unformat (i, "via %U",
8450                          unformat_ip6_address, &v6_next_hop_address))
8451         {
8452           next_hop_proto_is_ip4 = 0;
8453         }
8454       else if (unformat (i, "l2-only"))
8455         l2_only = 1;
8456       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8457         ;
8458       else if (unformat (i, "out-label %d", &next_hop_out_label))
8459         vec_add1 (labels, ntohl (next_hop_out_label));
8460       else
8461         {
8462           clib_warning ("parse error '%U'", format_unformat_error, i);
8463           return -99;
8464         }
8465     }
8466
8467   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
8468
8469   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
8470   mp->mt_sw_if_index = ntohl (sw_if_index);
8471   mp->mt_is_add = is_add;
8472   mp->mt_l2_only = l2_only;
8473   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
8474   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
8475
8476   mp->mt_next_hop_n_out_labels = vec_len (labels);
8477
8478   if (0 != mp->mt_next_hop_n_out_labels)
8479     {
8480       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
8481                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
8482       vec_free (labels);
8483     }
8484
8485   if (next_hop_proto_is_ip4)
8486     {
8487       clib_memcpy (mp->mt_next_hop,
8488                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8489     }
8490   else
8491     {
8492       clib_memcpy (mp->mt_next_hop,
8493                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8494     }
8495
8496   S (mp);
8497   W (ret);
8498   return ret;
8499 }
8500
8501 static int
8502 api_sw_interface_set_unnumbered (vat_main_t * vam)
8503 {
8504   unformat_input_t *i = vam->input;
8505   vl_api_sw_interface_set_unnumbered_t *mp;
8506   u32 sw_if_index;
8507   u32 unnum_sw_index = ~0;
8508   u8 is_add = 1;
8509   u8 sw_if_index_set = 0;
8510   int ret;
8511
8512   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8513     {
8514       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8515         sw_if_index_set = 1;
8516       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8517         sw_if_index_set = 1;
8518       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8519         ;
8520       else if (unformat (i, "del"))
8521         is_add = 0;
8522       else
8523         {
8524           clib_warning ("parse error '%U'", format_unformat_error, i);
8525           return -99;
8526         }
8527     }
8528
8529   if (sw_if_index_set == 0)
8530     {
8531       errmsg ("missing interface name or sw_if_index");
8532       return -99;
8533     }
8534
8535   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8536
8537   mp->sw_if_index = ntohl (sw_if_index);
8538   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8539   mp->is_add = is_add;
8540
8541   S (mp);
8542   W (ret);
8543   return ret;
8544 }
8545
8546 static int
8547 api_ip_neighbor_add_del (vat_main_t * vam)
8548 {
8549   unformat_input_t *i = vam->input;
8550   vl_api_ip_neighbor_add_del_t *mp;
8551   u32 sw_if_index;
8552   u8 sw_if_index_set = 0;
8553   u8 is_add = 1;
8554   u8 is_static = 0;
8555   u8 is_no_fib_entry = 0;
8556   u8 mac_address[6];
8557   u8 mac_set = 0;
8558   u8 v4_address_set = 0;
8559   u8 v6_address_set = 0;
8560   ip4_address_t v4address;
8561   ip6_address_t v6address;
8562   int ret;
8563
8564   memset (mac_address, 0, sizeof (mac_address));
8565
8566   /* Parse args required to build the message */
8567   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8568     {
8569       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8570         {
8571           mac_set = 1;
8572         }
8573       else if (unformat (i, "del"))
8574         is_add = 0;
8575       else
8576         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8577         sw_if_index_set = 1;
8578       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8579         sw_if_index_set = 1;
8580       else if (unformat (i, "is_static"))
8581         is_static = 1;
8582       else if (unformat (i, "no-fib-entry"))
8583         is_no_fib_entry = 1;
8584       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
8585         v4_address_set = 1;
8586       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
8587         v6_address_set = 1;
8588       else
8589         {
8590           clib_warning ("parse error '%U'", format_unformat_error, i);
8591           return -99;
8592         }
8593     }
8594
8595   if (sw_if_index_set == 0)
8596     {
8597       errmsg ("missing interface name or sw_if_index");
8598       return -99;
8599     }
8600   if (v4_address_set && v6_address_set)
8601     {
8602       errmsg ("both v4 and v6 addresses set");
8603       return -99;
8604     }
8605   if (!v4_address_set && !v6_address_set)
8606     {
8607       errmsg ("no address set");
8608       return -99;
8609     }
8610
8611   /* Construct the API message */
8612   M (IP_NEIGHBOR_ADD_DEL, mp);
8613
8614   mp->sw_if_index = ntohl (sw_if_index);
8615   mp->is_add = is_add;
8616   mp->is_static = is_static;
8617   mp->is_no_adj_fib = is_no_fib_entry;
8618   if (mac_set)
8619     clib_memcpy (mp->mac_address, mac_address, 6);
8620   if (v6_address_set)
8621     {
8622       mp->is_ipv6 = 1;
8623       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
8624     }
8625   else
8626     {
8627       /* mp->is_ipv6 = 0; via memset in M macro above */
8628       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
8629     }
8630
8631   /* send it... */
8632   S (mp);
8633
8634   /* Wait for a reply, return good/bad news  */
8635   W (ret);
8636   return ret;
8637 }
8638
8639 static int
8640 api_reset_vrf (vat_main_t * vam)
8641 {
8642   unformat_input_t *i = vam->input;
8643   vl_api_reset_vrf_t *mp;
8644   u32 vrf_id = 0;
8645   u8 is_ipv6 = 0;
8646   u8 vrf_id_set = 0;
8647   int ret;
8648
8649   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8650     {
8651       if (unformat (i, "vrf %d", &vrf_id))
8652         vrf_id_set = 1;
8653       else if (unformat (i, "ipv6"))
8654         is_ipv6 = 1;
8655       else
8656         {
8657           clib_warning ("parse error '%U'", format_unformat_error, i);
8658           return -99;
8659         }
8660     }
8661
8662   if (vrf_id_set == 0)
8663     {
8664       errmsg ("missing vrf id");
8665       return -99;
8666     }
8667
8668   M (RESET_VRF, mp);
8669
8670   mp->vrf_id = ntohl (vrf_id);
8671   mp->is_ipv6 = is_ipv6;
8672
8673   S (mp);
8674   W (ret);
8675   return ret;
8676 }
8677
8678 static int
8679 api_create_vlan_subif (vat_main_t * vam)
8680 {
8681   unformat_input_t *i = vam->input;
8682   vl_api_create_vlan_subif_t *mp;
8683   u32 sw_if_index;
8684   u8 sw_if_index_set = 0;
8685   u32 vlan_id;
8686   u8 vlan_id_set = 0;
8687   int ret;
8688
8689   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8690     {
8691       if (unformat (i, "sw_if_index %d", &sw_if_index))
8692         sw_if_index_set = 1;
8693       else
8694         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8695         sw_if_index_set = 1;
8696       else if (unformat (i, "vlan %d", &vlan_id))
8697         vlan_id_set = 1;
8698       else
8699         {
8700           clib_warning ("parse error '%U'", format_unformat_error, i);
8701           return -99;
8702         }
8703     }
8704
8705   if (sw_if_index_set == 0)
8706     {
8707       errmsg ("missing interface name or sw_if_index");
8708       return -99;
8709     }
8710
8711   if (vlan_id_set == 0)
8712     {
8713       errmsg ("missing vlan_id");
8714       return -99;
8715     }
8716   M (CREATE_VLAN_SUBIF, mp);
8717
8718   mp->sw_if_index = ntohl (sw_if_index);
8719   mp->vlan_id = ntohl (vlan_id);
8720
8721   S (mp);
8722   W (ret);
8723   return ret;
8724 }
8725
8726 #define foreach_create_subif_bit                \
8727 _(no_tags)                                      \
8728 _(one_tag)                                      \
8729 _(two_tags)                                     \
8730 _(dot1ad)                                       \
8731 _(exact_match)                                  \
8732 _(default_sub)                                  \
8733 _(outer_vlan_id_any)                            \
8734 _(inner_vlan_id_any)
8735
8736 static int
8737 api_create_subif (vat_main_t * vam)
8738 {
8739   unformat_input_t *i = vam->input;
8740   vl_api_create_subif_t *mp;
8741   u32 sw_if_index;
8742   u8 sw_if_index_set = 0;
8743   u32 sub_id;
8744   u8 sub_id_set = 0;
8745   u32 no_tags = 0;
8746   u32 one_tag = 0;
8747   u32 two_tags = 0;
8748   u32 dot1ad = 0;
8749   u32 exact_match = 0;
8750   u32 default_sub = 0;
8751   u32 outer_vlan_id_any = 0;
8752   u32 inner_vlan_id_any = 0;
8753   u32 tmp;
8754   u16 outer_vlan_id = 0;
8755   u16 inner_vlan_id = 0;
8756   int ret;
8757
8758   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8759     {
8760       if (unformat (i, "sw_if_index %d", &sw_if_index))
8761         sw_if_index_set = 1;
8762       else
8763         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8764         sw_if_index_set = 1;
8765       else if (unformat (i, "sub_id %d", &sub_id))
8766         sub_id_set = 1;
8767       else if (unformat (i, "outer_vlan_id %d", &tmp))
8768         outer_vlan_id = tmp;
8769       else if (unformat (i, "inner_vlan_id %d", &tmp))
8770         inner_vlan_id = tmp;
8771
8772 #define _(a) else if (unformat (i, #a)) a = 1 ;
8773       foreach_create_subif_bit
8774 #undef _
8775         else
8776         {
8777           clib_warning ("parse error '%U'", format_unformat_error, i);
8778           return -99;
8779         }
8780     }
8781
8782   if (sw_if_index_set == 0)
8783     {
8784       errmsg ("missing interface name or sw_if_index");
8785       return -99;
8786     }
8787
8788   if (sub_id_set == 0)
8789     {
8790       errmsg ("missing sub_id");
8791       return -99;
8792     }
8793   M (CREATE_SUBIF, mp);
8794
8795   mp->sw_if_index = ntohl (sw_if_index);
8796   mp->sub_id = ntohl (sub_id);
8797
8798 #define _(a) mp->a = a;
8799   foreach_create_subif_bit;
8800 #undef _
8801
8802   mp->outer_vlan_id = ntohs (outer_vlan_id);
8803   mp->inner_vlan_id = ntohs (inner_vlan_id);
8804
8805   S (mp);
8806   W (ret);
8807   return ret;
8808 }
8809
8810 static int
8811 api_oam_add_del (vat_main_t * vam)
8812 {
8813   unformat_input_t *i = vam->input;
8814   vl_api_oam_add_del_t *mp;
8815   u32 vrf_id = 0;
8816   u8 is_add = 1;
8817   ip4_address_t src, dst;
8818   u8 src_set = 0;
8819   u8 dst_set = 0;
8820   int ret;
8821
8822   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8823     {
8824       if (unformat (i, "vrf %d", &vrf_id))
8825         ;
8826       else if (unformat (i, "src %U", unformat_ip4_address, &src))
8827         src_set = 1;
8828       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
8829         dst_set = 1;
8830       else if (unformat (i, "del"))
8831         is_add = 0;
8832       else
8833         {
8834           clib_warning ("parse error '%U'", format_unformat_error, i);
8835           return -99;
8836         }
8837     }
8838
8839   if (src_set == 0)
8840     {
8841       errmsg ("missing src addr");
8842       return -99;
8843     }
8844
8845   if (dst_set == 0)
8846     {
8847       errmsg ("missing dst addr");
8848       return -99;
8849     }
8850
8851   M (OAM_ADD_DEL, mp);
8852
8853   mp->vrf_id = ntohl (vrf_id);
8854   mp->is_add = is_add;
8855   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
8856   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
8857
8858   S (mp);
8859   W (ret);
8860   return ret;
8861 }
8862
8863 static int
8864 api_reset_fib (vat_main_t * vam)
8865 {
8866   unformat_input_t *i = vam->input;
8867   vl_api_reset_fib_t *mp;
8868   u32 vrf_id = 0;
8869   u8 is_ipv6 = 0;
8870   u8 vrf_id_set = 0;
8871
8872   int ret;
8873   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8874     {
8875       if (unformat (i, "vrf %d", &vrf_id))
8876         vrf_id_set = 1;
8877       else if (unformat (i, "ipv6"))
8878         is_ipv6 = 1;
8879       else
8880         {
8881           clib_warning ("parse error '%U'", format_unformat_error, i);
8882           return -99;
8883         }
8884     }
8885
8886   if (vrf_id_set == 0)
8887     {
8888       errmsg ("missing vrf id");
8889       return -99;
8890     }
8891
8892   M (RESET_FIB, mp);
8893
8894   mp->vrf_id = ntohl (vrf_id);
8895   mp->is_ipv6 = is_ipv6;
8896
8897   S (mp);
8898   W (ret);
8899   return ret;
8900 }
8901
8902 static int
8903 api_dhcp_proxy_config (vat_main_t * vam)
8904 {
8905   unformat_input_t *i = vam->input;
8906   vl_api_dhcp_proxy_config_t *mp;
8907   u32 rx_vrf_id = 0;
8908   u32 server_vrf_id = 0;
8909   u8 is_add = 1;
8910   u8 v4_address_set = 0;
8911   u8 v6_address_set = 0;
8912   ip4_address_t v4address;
8913   ip6_address_t v6address;
8914   u8 v4_src_address_set = 0;
8915   u8 v6_src_address_set = 0;
8916   ip4_address_t v4srcaddress;
8917   ip6_address_t v6srcaddress;
8918   int ret;
8919
8920   /* Parse args required to build the message */
8921   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8922     {
8923       if (unformat (i, "del"))
8924         is_add = 0;
8925       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
8926         ;
8927       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
8928         ;
8929       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
8930         v4_address_set = 1;
8931       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
8932         v6_address_set = 1;
8933       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
8934         v4_src_address_set = 1;
8935       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
8936         v6_src_address_set = 1;
8937       else
8938         break;
8939     }
8940
8941   if (v4_address_set && v6_address_set)
8942     {
8943       errmsg ("both v4 and v6 server addresses set");
8944       return -99;
8945     }
8946   if (!v4_address_set && !v6_address_set)
8947     {
8948       errmsg ("no server addresses set");
8949       return -99;
8950     }
8951
8952   if (v4_src_address_set && v6_src_address_set)
8953     {
8954       errmsg ("both v4 and v6  src addresses set");
8955       return -99;
8956     }
8957   if (!v4_src_address_set && !v6_src_address_set)
8958     {
8959       errmsg ("no src addresses set");
8960       return -99;
8961     }
8962
8963   if (!(v4_src_address_set && v4_address_set) &&
8964       !(v6_src_address_set && v6_address_set))
8965     {
8966       errmsg ("no matching server and src addresses set");
8967       return -99;
8968     }
8969
8970   /* Construct the API message */
8971   M (DHCP_PROXY_CONFIG, mp);
8972
8973   mp->is_add = is_add;
8974   mp->rx_vrf_id = ntohl (rx_vrf_id);
8975   mp->server_vrf_id = ntohl (server_vrf_id);
8976   if (v6_address_set)
8977     {
8978       mp->is_ipv6 = 1;
8979       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
8980       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
8981     }
8982   else
8983     {
8984       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
8985       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
8986     }
8987
8988   /* send it... */
8989   S (mp);
8990
8991   /* Wait for a reply, return good/bad news  */
8992   W (ret);
8993   return ret;
8994 }
8995
8996 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
8997 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
8998
8999 static void
9000 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9001 {
9002   vat_main_t *vam = &vat_main;
9003   u32 i, count = mp->count;
9004   vl_api_dhcp_server_t *s;
9005
9006   if (mp->is_ipv6)
9007     print (vam->ofp,
9008            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
9009            ntohl (mp->rx_vrf_id),
9010            format_ip6_address, mp->dhcp_src_address,
9011            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9012   else
9013     print (vam->ofp,
9014            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
9015            ntohl (mp->rx_vrf_id),
9016            format_ip4_address, mp->dhcp_src_address,
9017            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9018
9019   for (i = 0; i < count; i++)
9020     {
9021       s = &mp->servers[i];
9022
9023       if (mp->is_ipv6)
9024         print (vam->ofp,
9025                " Server Table-ID %d, Server Address %U",
9026                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9027       else
9028         print (vam->ofp,
9029                " Server Table-ID %d, Server Address %U",
9030                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9031     }
9032 }
9033
9034 static void vl_api_dhcp_proxy_details_t_handler_json
9035   (vl_api_dhcp_proxy_details_t * mp)
9036 {
9037   vat_main_t *vam = &vat_main;
9038   vat_json_node_t *node = NULL;
9039   u32 i, count = mp->count;
9040   struct in_addr ip4;
9041   struct in6_addr ip6;
9042   vl_api_dhcp_server_t *s;
9043
9044   if (VAT_JSON_ARRAY != vam->json_tree.type)
9045     {
9046       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9047       vat_json_init_array (&vam->json_tree);
9048     }
9049   node = vat_json_array_add (&vam->json_tree);
9050
9051   vat_json_init_object (node);
9052   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9053   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9054   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9055
9056   if (mp->is_ipv6)
9057     {
9058       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9059       vat_json_object_add_ip6 (node, "src_address", ip6);
9060     }
9061   else
9062     {
9063       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9064       vat_json_object_add_ip4 (node, "src_address", ip4);
9065     }
9066
9067   for (i = 0; i < count; i++)
9068     {
9069       s = &mp->servers[i];
9070
9071       vat_json_object_add_uint (node, "server-table-id",
9072                                 ntohl (s->server_vrf_id));
9073
9074       if (mp->is_ipv6)
9075         {
9076           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9077           vat_json_object_add_ip4 (node, "src_address", ip4);
9078         }
9079       else
9080         {
9081           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9082           vat_json_object_add_ip6 (node, "server_address", ip6);
9083         }
9084     }
9085 }
9086
9087 static int
9088 api_dhcp_proxy_dump (vat_main_t * vam)
9089 {
9090   unformat_input_t *i = vam->input;
9091   vl_api_control_ping_t *mp_ping;
9092   vl_api_dhcp_proxy_dump_t *mp;
9093   u8 is_ipv6 = 0;
9094   int ret;
9095
9096   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9097     {
9098       if (unformat (i, "ipv6"))
9099         is_ipv6 = 1;
9100       else
9101         {
9102           clib_warning ("parse error '%U'", format_unformat_error, i);
9103           return -99;
9104         }
9105     }
9106
9107   M (DHCP_PROXY_DUMP, mp);
9108
9109   mp->is_ip6 = is_ipv6;
9110   S (mp);
9111
9112   /* Use a control ping for synchronization */
9113   MPING (CONTROL_PING, mp_ping);
9114   S (mp_ping);
9115
9116   W (ret);
9117   return ret;
9118 }
9119
9120 static int
9121 api_dhcp_proxy_set_vss (vat_main_t * vam)
9122 {
9123   unformat_input_t *i = vam->input;
9124   vl_api_dhcp_proxy_set_vss_t *mp;
9125   u8 is_ipv6 = 0;
9126   u8 is_add = 1;
9127   u32 tbl_id;
9128   u8 tbl_id_set = 0;
9129   u32 oui;
9130   u8 oui_set = 0;
9131   u32 fib_id;
9132   u8 fib_id_set = 0;
9133   int ret;
9134
9135   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9136     {
9137       if (unformat (i, "tbl_id %d", &tbl_id))
9138         tbl_id_set = 1;
9139       if (unformat (i, "fib_id %d", &fib_id))
9140         fib_id_set = 1;
9141       if (unformat (i, "oui %d", &oui))
9142         oui_set = 1;
9143       else if (unformat (i, "ipv6"))
9144         is_ipv6 = 1;
9145       else if (unformat (i, "del"))
9146         is_add = 0;
9147       else
9148         {
9149           clib_warning ("parse error '%U'", format_unformat_error, i);
9150           return -99;
9151         }
9152     }
9153
9154   if (tbl_id_set == 0)
9155     {
9156       errmsg ("missing tbl id");
9157       return -99;
9158     }
9159
9160   if (fib_id_set == 0)
9161     {
9162       errmsg ("missing fib id");
9163       return -99;
9164     }
9165   if (oui_set == 0)
9166     {
9167       errmsg ("missing oui");
9168       return -99;
9169     }
9170
9171   M (DHCP_PROXY_SET_VSS, mp);
9172   mp->tbl_id = ntohl (tbl_id);
9173   mp->fib_id = ntohl (fib_id);
9174   mp->oui = ntohl (oui);
9175   mp->is_ipv6 = is_ipv6;
9176   mp->is_add = is_add;
9177
9178   S (mp);
9179   W (ret);
9180   return ret;
9181 }
9182
9183 static int
9184 api_dhcp_client_config (vat_main_t * vam)
9185 {
9186   unformat_input_t *i = vam->input;
9187   vl_api_dhcp_client_config_t *mp;
9188   u32 sw_if_index;
9189   u8 sw_if_index_set = 0;
9190   u8 is_add = 1;
9191   u8 *hostname = 0;
9192   u8 disable_event = 0;
9193   int ret;
9194
9195   /* Parse args required to build the message */
9196   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9197     {
9198       if (unformat (i, "del"))
9199         is_add = 0;
9200       else
9201         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9202         sw_if_index_set = 1;
9203       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9204         sw_if_index_set = 1;
9205       else if (unformat (i, "hostname %s", &hostname))
9206         ;
9207       else if (unformat (i, "disable_event"))
9208         disable_event = 1;
9209       else
9210         break;
9211     }
9212
9213   if (sw_if_index_set == 0)
9214     {
9215       errmsg ("missing interface name or sw_if_index");
9216       return -99;
9217     }
9218
9219   if (vec_len (hostname) > 63)
9220     {
9221       errmsg ("hostname too long");
9222     }
9223   vec_add1 (hostname, 0);
9224
9225   /* Construct the API message */
9226   M (DHCP_CLIENT_CONFIG, mp);
9227
9228   mp->sw_if_index = htonl (sw_if_index);
9229   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
9230   vec_free (hostname);
9231   mp->is_add = is_add;
9232   mp->want_dhcp_event = disable_event ? 0 : 1;
9233   mp->pid = htonl (getpid ());
9234
9235   /* send it... */
9236   S (mp);
9237
9238   /* Wait for a reply, return good/bad news  */
9239   W (ret);
9240   return ret;
9241 }
9242
9243 static int
9244 api_set_ip_flow_hash (vat_main_t * vam)
9245 {
9246   unformat_input_t *i = vam->input;
9247   vl_api_set_ip_flow_hash_t *mp;
9248   u32 vrf_id = 0;
9249   u8 is_ipv6 = 0;
9250   u8 vrf_id_set = 0;
9251   u8 src = 0;
9252   u8 dst = 0;
9253   u8 sport = 0;
9254   u8 dport = 0;
9255   u8 proto = 0;
9256   u8 reverse = 0;
9257   int ret;
9258
9259   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9260     {
9261       if (unformat (i, "vrf %d", &vrf_id))
9262         vrf_id_set = 1;
9263       else if (unformat (i, "ipv6"))
9264         is_ipv6 = 1;
9265       else if (unformat (i, "src"))
9266         src = 1;
9267       else if (unformat (i, "dst"))
9268         dst = 1;
9269       else if (unformat (i, "sport"))
9270         sport = 1;
9271       else if (unformat (i, "dport"))
9272         dport = 1;
9273       else if (unformat (i, "proto"))
9274         proto = 1;
9275       else if (unformat (i, "reverse"))
9276         reverse = 1;
9277
9278       else
9279         {
9280           clib_warning ("parse error '%U'", format_unformat_error, i);
9281           return -99;
9282         }
9283     }
9284
9285   if (vrf_id_set == 0)
9286     {
9287       errmsg ("missing vrf id");
9288       return -99;
9289     }
9290
9291   M (SET_IP_FLOW_HASH, mp);
9292   mp->src = src;
9293   mp->dst = dst;
9294   mp->sport = sport;
9295   mp->dport = dport;
9296   mp->proto = proto;
9297   mp->reverse = reverse;
9298   mp->vrf_id = ntohl (vrf_id);
9299   mp->is_ipv6 = is_ipv6;
9300
9301   S (mp);
9302   W (ret);
9303   return ret;
9304 }
9305
9306 static int
9307 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9308 {
9309   unformat_input_t *i = vam->input;
9310   vl_api_sw_interface_ip6_enable_disable_t *mp;
9311   u32 sw_if_index;
9312   u8 sw_if_index_set = 0;
9313   u8 enable = 0;
9314   int ret;
9315
9316   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9317     {
9318       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9319         sw_if_index_set = 1;
9320       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9321         sw_if_index_set = 1;
9322       else if (unformat (i, "enable"))
9323         enable = 1;
9324       else if (unformat (i, "disable"))
9325         enable = 0;
9326       else
9327         {
9328           clib_warning ("parse error '%U'", format_unformat_error, i);
9329           return -99;
9330         }
9331     }
9332
9333   if (sw_if_index_set == 0)
9334     {
9335       errmsg ("missing interface name or sw_if_index");
9336       return -99;
9337     }
9338
9339   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9340
9341   mp->sw_if_index = ntohl (sw_if_index);
9342   mp->enable = enable;
9343
9344   S (mp);
9345   W (ret);
9346   return ret;
9347 }
9348
9349 static int
9350 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
9351 {
9352   unformat_input_t *i = vam->input;
9353   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
9354   u32 sw_if_index;
9355   u8 sw_if_index_set = 0;
9356   u8 v6_address_set = 0;
9357   ip6_address_t v6address;
9358   int ret;
9359
9360   /* Parse args required to build the message */
9361   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9362     {
9363       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9364         sw_if_index_set = 1;
9365       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9366         sw_if_index_set = 1;
9367       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9368         v6_address_set = 1;
9369       else
9370         break;
9371     }
9372
9373   if (sw_if_index_set == 0)
9374     {
9375       errmsg ("missing interface name or sw_if_index");
9376       return -99;
9377     }
9378   if (!v6_address_set)
9379     {
9380       errmsg ("no address set");
9381       return -99;
9382     }
9383
9384   /* Construct the API message */
9385   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
9386
9387   mp->sw_if_index = ntohl (sw_if_index);
9388   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9389
9390   /* send it... */
9391   S (mp);
9392
9393   /* Wait for a reply, return good/bad news  */
9394   W (ret);
9395   return ret;
9396 }
9397
9398 static int
9399 api_ip6nd_proxy_add_del (vat_main_t * vam)
9400 {
9401   unformat_input_t *i = vam->input;
9402   vl_api_ip6nd_proxy_add_del_t *mp;
9403   u32 sw_if_index = ~0;
9404   u8 v6_address_set = 0;
9405   ip6_address_t v6address;
9406   u8 is_del = 0;
9407   int ret;
9408
9409   /* Parse args required to build the message */
9410   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9411     {
9412       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9413         ;
9414       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9415         ;
9416       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9417         v6_address_set = 1;
9418       if (unformat (i, "del"))
9419         is_del = 1;
9420       else
9421         {
9422           clib_warning ("parse error '%U'", format_unformat_error, i);
9423           return -99;
9424         }
9425     }
9426
9427   if (sw_if_index == ~0)
9428     {
9429       errmsg ("missing interface name or sw_if_index");
9430       return -99;
9431     }
9432   if (!v6_address_set)
9433     {
9434       errmsg ("no address set");
9435       return -99;
9436     }
9437
9438   /* Construct the API message */
9439   M (IP6ND_PROXY_ADD_DEL, mp);
9440
9441   mp->is_del = is_del;
9442   mp->sw_if_index = ntohl (sw_if_index);
9443   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9444
9445   /* send it... */
9446   S (mp);
9447
9448   /* Wait for a reply, return good/bad news  */
9449   W (ret);
9450   return ret;
9451 }
9452
9453 static int
9454 api_ip6nd_proxy_dump (vat_main_t * vam)
9455 {
9456   vl_api_ip6nd_proxy_dump_t *mp;
9457   vl_api_control_ping_t *mp_ping;
9458   int ret;
9459
9460   M (IP6ND_PROXY_DUMP, mp);
9461
9462   S (mp);
9463
9464   /* Use a control ping for synchronization */
9465   MPING (CONTROL_PING, mp_ping);
9466   S (mp_ping);
9467
9468   W (ret);
9469   return ret;
9470 }
9471
9472 static void vl_api_ip6nd_proxy_details_t_handler
9473   (vl_api_ip6nd_proxy_details_t * mp)
9474 {
9475   vat_main_t *vam = &vat_main;
9476
9477   print (vam->ofp, "host %U sw_if_index %d",
9478          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
9479 }
9480
9481 static void vl_api_ip6nd_proxy_details_t_handler_json
9482   (vl_api_ip6nd_proxy_details_t * mp)
9483 {
9484   vat_main_t *vam = &vat_main;
9485   struct in6_addr ip6;
9486   vat_json_node_t *node = NULL;
9487
9488   if (VAT_JSON_ARRAY != vam->json_tree.type)
9489     {
9490       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9491       vat_json_init_array (&vam->json_tree);
9492     }
9493   node = vat_json_array_add (&vam->json_tree);
9494
9495   vat_json_init_object (node);
9496   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9497
9498   clib_memcpy (&ip6, mp->address, sizeof (ip6));
9499   vat_json_object_add_ip6 (node, "host", ip6);
9500 }
9501
9502 static int
9503 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9504 {
9505   unformat_input_t *i = vam->input;
9506   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9507   u32 sw_if_index;
9508   u8 sw_if_index_set = 0;
9509   u32 address_length = 0;
9510   u8 v6_address_set = 0;
9511   ip6_address_t v6address;
9512   u8 use_default = 0;
9513   u8 no_advertise = 0;
9514   u8 off_link = 0;
9515   u8 no_autoconfig = 0;
9516   u8 no_onlink = 0;
9517   u8 is_no = 0;
9518   u32 val_lifetime = 0;
9519   u32 pref_lifetime = 0;
9520   int ret;
9521
9522   /* Parse args required to build the message */
9523   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9524     {
9525       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9526         sw_if_index_set = 1;
9527       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9528         sw_if_index_set = 1;
9529       else if (unformat (i, "%U/%d",
9530                          unformat_ip6_address, &v6address, &address_length))
9531         v6_address_set = 1;
9532       else if (unformat (i, "val_life %d", &val_lifetime))
9533         ;
9534       else if (unformat (i, "pref_life %d", &pref_lifetime))
9535         ;
9536       else if (unformat (i, "def"))
9537         use_default = 1;
9538       else if (unformat (i, "noadv"))
9539         no_advertise = 1;
9540       else if (unformat (i, "offl"))
9541         off_link = 1;
9542       else if (unformat (i, "noauto"))
9543         no_autoconfig = 1;
9544       else if (unformat (i, "nolink"))
9545         no_onlink = 1;
9546       else if (unformat (i, "isno"))
9547         is_no = 1;
9548       else
9549         {
9550           clib_warning ("parse error '%U'", format_unformat_error, i);
9551           return -99;
9552         }
9553     }
9554
9555   if (sw_if_index_set == 0)
9556     {
9557       errmsg ("missing interface name or sw_if_index");
9558       return -99;
9559     }
9560   if (!v6_address_set)
9561     {
9562       errmsg ("no address set");
9563       return -99;
9564     }
9565
9566   /* Construct the API message */
9567   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9568
9569   mp->sw_if_index = ntohl (sw_if_index);
9570   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9571   mp->address_length = address_length;
9572   mp->use_default = use_default;
9573   mp->no_advertise = no_advertise;
9574   mp->off_link = off_link;
9575   mp->no_autoconfig = no_autoconfig;
9576   mp->no_onlink = no_onlink;
9577   mp->is_no = is_no;
9578   mp->val_lifetime = ntohl (val_lifetime);
9579   mp->pref_lifetime = ntohl (pref_lifetime);
9580
9581   /* send it... */
9582   S (mp);
9583
9584   /* Wait for a reply, return good/bad news  */
9585   W (ret);
9586   return ret;
9587 }
9588
9589 static int
9590 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9591 {
9592   unformat_input_t *i = vam->input;
9593   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9594   u32 sw_if_index;
9595   u8 sw_if_index_set = 0;
9596   u8 suppress = 0;
9597   u8 managed = 0;
9598   u8 other = 0;
9599   u8 ll_option = 0;
9600   u8 send_unicast = 0;
9601   u8 cease = 0;
9602   u8 is_no = 0;
9603   u8 default_router = 0;
9604   u32 max_interval = 0;
9605   u32 min_interval = 0;
9606   u32 lifetime = 0;
9607   u32 initial_count = 0;
9608   u32 initial_interval = 0;
9609   int ret;
9610
9611
9612   /* Parse args required to build the message */
9613   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9614     {
9615       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9616         sw_if_index_set = 1;
9617       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9618         sw_if_index_set = 1;
9619       else if (unformat (i, "maxint %d", &max_interval))
9620         ;
9621       else if (unformat (i, "minint %d", &min_interval))
9622         ;
9623       else if (unformat (i, "life %d", &lifetime))
9624         ;
9625       else if (unformat (i, "count %d", &initial_count))
9626         ;
9627       else if (unformat (i, "interval %d", &initial_interval))
9628         ;
9629       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9630         suppress = 1;
9631       else if (unformat (i, "managed"))
9632         managed = 1;
9633       else if (unformat (i, "other"))
9634         other = 1;
9635       else if (unformat (i, "ll"))
9636         ll_option = 1;
9637       else if (unformat (i, "send"))
9638         send_unicast = 1;
9639       else if (unformat (i, "cease"))
9640         cease = 1;
9641       else if (unformat (i, "isno"))
9642         is_no = 1;
9643       else if (unformat (i, "def"))
9644         default_router = 1;
9645       else
9646         {
9647           clib_warning ("parse error '%U'", format_unformat_error, i);
9648           return -99;
9649         }
9650     }
9651
9652   if (sw_if_index_set == 0)
9653     {
9654       errmsg ("missing interface name or sw_if_index");
9655       return -99;
9656     }
9657
9658   /* Construct the API message */
9659   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9660
9661   mp->sw_if_index = ntohl (sw_if_index);
9662   mp->max_interval = ntohl (max_interval);
9663   mp->min_interval = ntohl (min_interval);
9664   mp->lifetime = ntohl (lifetime);
9665   mp->initial_count = ntohl (initial_count);
9666   mp->initial_interval = ntohl (initial_interval);
9667   mp->suppress = suppress;
9668   mp->managed = managed;
9669   mp->other = other;
9670   mp->ll_option = ll_option;
9671   mp->send_unicast = send_unicast;
9672   mp->cease = cease;
9673   mp->is_no = is_no;
9674   mp->default_router = default_router;
9675
9676   /* send it... */
9677   S (mp);
9678
9679   /* Wait for a reply, return good/bad news  */
9680   W (ret);
9681   return ret;
9682 }
9683
9684 static int
9685 api_set_arp_neighbor_limit (vat_main_t * vam)
9686 {
9687   unformat_input_t *i = vam->input;
9688   vl_api_set_arp_neighbor_limit_t *mp;
9689   u32 arp_nbr_limit;
9690   u8 limit_set = 0;
9691   u8 is_ipv6 = 0;
9692   int ret;
9693
9694   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9695     {
9696       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
9697         limit_set = 1;
9698       else if (unformat (i, "ipv6"))
9699         is_ipv6 = 1;
9700       else
9701         {
9702           clib_warning ("parse error '%U'", format_unformat_error, i);
9703           return -99;
9704         }
9705     }
9706
9707   if (limit_set == 0)
9708     {
9709       errmsg ("missing limit value");
9710       return -99;
9711     }
9712
9713   M (SET_ARP_NEIGHBOR_LIMIT, mp);
9714
9715   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
9716   mp->is_ipv6 = is_ipv6;
9717
9718   S (mp);
9719   W (ret);
9720   return ret;
9721 }
9722
9723 static int
9724 api_l2_patch_add_del (vat_main_t * vam)
9725 {
9726   unformat_input_t *i = vam->input;
9727   vl_api_l2_patch_add_del_t *mp;
9728   u32 rx_sw_if_index;
9729   u8 rx_sw_if_index_set = 0;
9730   u32 tx_sw_if_index;
9731   u8 tx_sw_if_index_set = 0;
9732   u8 is_add = 1;
9733   int ret;
9734
9735   /* Parse args required to build the message */
9736   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9737     {
9738       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9739         rx_sw_if_index_set = 1;
9740       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9741         tx_sw_if_index_set = 1;
9742       else if (unformat (i, "rx"))
9743         {
9744           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9745             {
9746               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9747                             &rx_sw_if_index))
9748                 rx_sw_if_index_set = 1;
9749             }
9750           else
9751             break;
9752         }
9753       else if (unformat (i, "tx"))
9754         {
9755           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9756             {
9757               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9758                             &tx_sw_if_index))
9759                 tx_sw_if_index_set = 1;
9760             }
9761           else
9762             break;
9763         }
9764       else if (unformat (i, "del"))
9765         is_add = 0;
9766       else
9767         break;
9768     }
9769
9770   if (rx_sw_if_index_set == 0)
9771     {
9772       errmsg ("missing rx interface name or rx_sw_if_index");
9773       return -99;
9774     }
9775
9776   if (tx_sw_if_index_set == 0)
9777     {
9778       errmsg ("missing tx interface name or tx_sw_if_index");
9779       return -99;
9780     }
9781
9782   M (L2_PATCH_ADD_DEL, mp);
9783
9784   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9785   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9786   mp->is_add = is_add;
9787
9788   S (mp);
9789   W (ret);
9790   return ret;
9791 }
9792
9793 u8 is_del;
9794 u8 localsid_addr[16];
9795 u8 end_psp;
9796 u8 behavior;
9797 u32 sw_if_index;
9798 u32 vlan_index;
9799 u32 fib_table;
9800 u8 nh_addr[16];
9801
9802 static int
9803 api_sr_localsid_add_del (vat_main_t * vam)
9804 {
9805   unformat_input_t *i = vam->input;
9806   vl_api_sr_localsid_add_del_t *mp;
9807
9808   u8 is_del;
9809   ip6_address_t localsid;
9810   u8 end_psp = 0;
9811   u8 behavior = ~0;
9812   u32 sw_if_index;
9813   u32 fib_table = ~(u32) 0;
9814   ip6_address_t next_hop;
9815
9816   bool nexthop_set = 0;
9817
9818   int ret;
9819
9820   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9821     {
9822       if (unformat (i, "del"))
9823         is_del = 1;
9824       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9825       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
9826         nexthop_set = 1;
9827       else if (unformat (i, "behavior %u", &behavior));
9828       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9829       else if (unformat (i, "fib-table %u", &fib_table));
9830       else if (unformat (i, "end.psp %u", &behavior));
9831       else
9832         break;
9833     }
9834
9835   M (SR_LOCALSID_ADD_DEL, mp);
9836
9837   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
9838   if (nexthop_set)
9839     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
9840   mp->behavior = behavior;
9841   mp->sw_if_index = ntohl (sw_if_index);
9842   mp->fib_table = ntohl (fib_table);
9843   mp->end_psp = end_psp;
9844   mp->is_del = is_del;
9845
9846   S (mp);
9847   W (ret);
9848   return ret;
9849 }
9850
9851 static int
9852 api_ioam_enable (vat_main_t * vam)
9853 {
9854   unformat_input_t *input = vam->input;
9855   vl_api_ioam_enable_t *mp;
9856   u32 id = 0;
9857   int has_trace_option = 0;
9858   int has_pot_option = 0;
9859   int has_seqno_option = 0;
9860   int has_analyse_option = 0;
9861   int ret;
9862
9863   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9864     {
9865       if (unformat (input, "trace"))
9866         has_trace_option = 1;
9867       else if (unformat (input, "pot"))
9868         has_pot_option = 1;
9869       else if (unformat (input, "seqno"))
9870         has_seqno_option = 1;
9871       else if (unformat (input, "analyse"))
9872         has_analyse_option = 1;
9873       else
9874         break;
9875     }
9876   M (IOAM_ENABLE, mp);
9877   mp->id = htons (id);
9878   mp->seqno = has_seqno_option;
9879   mp->analyse = has_analyse_option;
9880   mp->pot_enable = has_pot_option;
9881   mp->trace_enable = has_trace_option;
9882
9883   S (mp);
9884   W (ret);
9885   return ret;
9886 }
9887
9888
9889 static int
9890 api_ioam_disable (vat_main_t * vam)
9891 {
9892   vl_api_ioam_disable_t *mp;
9893   int ret;
9894
9895   M (IOAM_DISABLE, mp);
9896   S (mp);
9897   W (ret);
9898   return ret;
9899 }
9900
9901 #define foreach_tcp_proto_field                 \
9902 _(src_port)                                     \
9903 _(dst_port)
9904
9905 #define foreach_udp_proto_field                 \
9906 _(src_port)                                     \
9907 _(dst_port)
9908
9909 #define foreach_ip4_proto_field                 \
9910 _(src_address)                                  \
9911 _(dst_address)                                  \
9912 _(tos)                                          \
9913 _(length)                                       \
9914 _(fragment_id)                                  \
9915 _(ttl)                                          \
9916 _(protocol)                                     \
9917 _(checksum)
9918
9919 typedef struct
9920 {
9921   u16 src_port, dst_port;
9922 } tcpudp_header_t;
9923
9924 #if VPP_API_TEST_BUILTIN == 0
9925 uword
9926 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9927 {
9928   u8 **maskp = va_arg (*args, u8 **);
9929   u8 *mask = 0;
9930   u8 found_something = 0;
9931   tcp_header_t *tcp;
9932
9933 #define _(a) u8 a=0;
9934   foreach_tcp_proto_field;
9935 #undef _
9936
9937   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9938     {
9939       if (0);
9940 #define _(a) else if (unformat (input, #a)) a=1;
9941       foreach_tcp_proto_field
9942 #undef _
9943         else
9944         break;
9945     }
9946
9947 #define _(a) found_something += a;
9948   foreach_tcp_proto_field;
9949 #undef _
9950
9951   if (found_something == 0)
9952     return 0;
9953
9954   vec_validate (mask, sizeof (*tcp) - 1);
9955
9956   tcp = (tcp_header_t *) mask;
9957
9958 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
9959   foreach_tcp_proto_field;
9960 #undef _
9961
9962   *maskp = mask;
9963   return 1;
9964 }
9965
9966 uword
9967 unformat_udp_mask (unformat_input_t * input, va_list * args)
9968 {
9969   u8 **maskp = va_arg (*args, u8 **);
9970   u8 *mask = 0;
9971   u8 found_something = 0;
9972   udp_header_t *udp;
9973
9974 #define _(a) u8 a=0;
9975   foreach_udp_proto_field;
9976 #undef _
9977
9978   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9979     {
9980       if (0);
9981 #define _(a) else if (unformat (input, #a)) a=1;
9982       foreach_udp_proto_field
9983 #undef _
9984         else
9985         break;
9986     }
9987
9988 #define _(a) found_something += a;
9989   foreach_udp_proto_field;
9990 #undef _
9991
9992   if (found_something == 0)
9993     return 0;
9994
9995   vec_validate (mask, sizeof (*udp) - 1);
9996
9997   udp = (udp_header_t *) mask;
9998
9999 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
10000   foreach_udp_proto_field;
10001 #undef _
10002
10003   *maskp = mask;
10004   return 1;
10005 }
10006
10007 uword
10008 unformat_l4_mask (unformat_input_t * input, va_list * args)
10009 {
10010   u8 **maskp = va_arg (*args, u8 **);
10011   u16 src_port = 0, dst_port = 0;
10012   tcpudp_header_t *tcpudp;
10013
10014   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10015     {
10016       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10017         return 1;
10018       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10019         return 1;
10020       else if (unformat (input, "src_port"))
10021         src_port = 0xFFFF;
10022       else if (unformat (input, "dst_port"))
10023         dst_port = 0xFFFF;
10024       else
10025         return 0;
10026     }
10027
10028   if (!src_port && !dst_port)
10029     return 0;
10030
10031   u8 *mask = 0;
10032   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10033
10034   tcpudp = (tcpudp_header_t *) mask;
10035   tcpudp->src_port = src_port;
10036   tcpudp->dst_port = dst_port;
10037
10038   *maskp = mask;
10039
10040   return 1;
10041 }
10042
10043 uword
10044 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10045 {
10046   u8 **maskp = va_arg (*args, u8 **);
10047   u8 *mask = 0;
10048   u8 found_something = 0;
10049   ip4_header_t *ip;
10050
10051 #define _(a) u8 a=0;
10052   foreach_ip4_proto_field;
10053 #undef _
10054   u8 version = 0;
10055   u8 hdr_length = 0;
10056
10057
10058   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10059     {
10060       if (unformat (input, "version"))
10061         version = 1;
10062       else if (unformat (input, "hdr_length"))
10063         hdr_length = 1;
10064       else if (unformat (input, "src"))
10065         src_address = 1;
10066       else if (unformat (input, "dst"))
10067         dst_address = 1;
10068       else if (unformat (input, "proto"))
10069         protocol = 1;
10070
10071 #define _(a) else if (unformat (input, #a)) a=1;
10072       foreach_ip4_proto_field
10073 #undef _
10074         else
10075         break;
10076     }
10077
10078 #define _(a) found_something += a;
10079   foreach_ip4_proto_field;
10080 #undef _
10081
10082   if (found_something == 0)
10083     return 0;
10084
10085   vec_validate (mask, sizeof (*ip) - 1);
10086
10087   ip = (ip4_header_t *) mask;
10088
10089 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10090   foreach_ip4_proto_field;
10091 #undef _
10092
10093   ip->ip_version_and_header_length = 0;
10094
10095   if (version)
10096     ip->ip_version_and_header_length |= 0xF0;
10097
10098   if (hdr_length)
10099     ip->ip_version_and_header_length |= 0x0F;
10100
10101   *maskp = mask;
10102   return 1;
10103 }
10104
10105 #define foreach_ip6_proto_field                 \
10106 _(src_address)                                  \
10107 _(dst_address)                                  \
10108 _(payload_length)                               \
10109 _(hop_limit)                                    \
10110 _(protocol)
10111
10112 uword
10113 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10114 {
10115   u8 **maskp = va_arg (*args, u8 **);
10116   u8 *mask = 0;
10117   u8 found_something = 0;
10118   ip6_header_t *ip;
10119   u32 ip_version_traffic_class_and_flow_label;
10120
10121 #define _(a) u8 a=0;
10122   foreach_ip6_proto_field;
10123 #undef _
10124   u8 version = 0;
10125   u8 traffic_class = 0;
10126   u8 flow_label = 0;
10127
10128   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10129     {
10130       if (unformat (input, "version"))
10131         version = 1;
10132       else if (unformat (input, "traffic-class"))
10133         traffic_class = 1;
10134       else if (unformat (input, "flow-label"))
10135         flow_label = 1;
10136       else if (unformat (input, "src"))
10137         src_address = 1;
10138       else if (unformat (input, "dst"))
10139         dst_address = 1;
10140       else if (unformat (input, "proto"))
10141         protocol = 1;
10142
10143 #define _(a) else if (unformat (input, #a)) a=1;
10144       foreach_ip6_proto_field
10145 #undef _
10146         else
10147         break;
10148     }
10149
10150 #define _(a) found_something += a;
10151   foreach_ip6_proto_field;
10152 #undef _
10153
10154   if (found_something == 0)
10155     return 0;
10156
10157   vec_validate (mask, sizeof (*ip) - 1);
10158
10159   ip = (ip6_header_t *) mask;
10160
10161 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10162   foreach_ip6_proto_field;
10163 #undef _
10164
10165   ip_version_traffic_class_and_flow_label = 0;
10166
10167   if (version)
10168     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10169
10170   if (traffic_class)
10171     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10172
10173   if (flow_label)
10174     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10175
10176   ip->ip_version_traffic_class_and_flow_label =
10177     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10178
10179   *maskp = mask;
10180   return 1;
10181 }
10182
10183 uword
10184 unformat_l3_mask (unformat_input_t * input, va_list * args)
10185 {
10186   u8 **maskp = va_arg (*args, u8 **);
10187
10188   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10189     {
10190       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10191         return 1;
10192       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10193         return 1;
10194       else
10195         break;
10196     }
10197   return 0;
10198 }
10199
10200 uword
10201 unformat_l2_mask (unformat_input_t * input, va_list * args)
10202 {
10203   u8 **maskp = va_arg (*args, u8 **);
10204   u8 *mask = 0;
10205   u8 src = 0;
10206   u8 dst = 0;
10207   u8 proto = 0;
10208   u8 tag1 = 0;
10209   u8 tag2 = 0;
10210   u8 ignore_tag1 = 0;
10211   u8 ignore_tag2 = 0;
10212   u8 cos1 = 0;
10213   u8 cos2 = 0;
10214   u8 dot1q = 0;
10215   u8 dot1ad = 0;
10216   int len = 14;
10217
10218   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10219     {
10220       if (unformat (input, "src"))
10221         src = 1;
10222       else if (unformat (input, "dst"))
10223         dst = 1;
10224       else if (unformat (input, "proto"))
10225         proto = 1;
10226       else if (unformat (input, "tag1"))
10227         tag1 = 1;
10228       else if (unformat (input, "tag2"))
10229         tag2 = 1;
10230       else if (unformat (input, "ignore-tag1"))
10231         ignore_tag1 = 1;
10232       else if (unformat (input, "ignore-tag2"))
10233         ignore_tag2 = 1;
10234       else if (unformat (input, "cos1"))
10235         cos1 = 1;
10236       else if (unformat (input, "cos2"))
10237         cos2 = 1;
10238       else if (unformat (input, "dot1q"))
10239         dot1q = 1;
10240       else if (unformat (input, "dot1ad"))
10241         dot1ad = 1;
10242       else
10243         break;
10244     }
10245   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10246        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10247     return 0;
10248
10249   if (tag1 || ignore_tag1 || cos1 || dot1q)
10250     len = 18;
10251   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10252     len = 22;
10253
10254   vec_validate (mask, len - 1);
10255
10256   if (dst)
10257     memset (mask, 0xff, 6);
10258
10259   if (src)
10260     memset (mask + 6, 0xff, 6);
10261
10262   if (tag2 || dot1ad)
10263     {
10264       /* inner vlan tag */
10265       if (tag2)
10266         {
10267           mask[19] = 0xff;
10268           mask[18] = 0x0f;
10269         }
10270       if (cos2)
10271         mask[18] |= 0xe0;
10272       if (proto)
10273         mask[21] = mask[20] = 0xff;
10274       if (tag1)
10275         {
10276           mask[15] = 0xff;
10277           mask[14] = 0x0f;
10278         }
10279       if (cos1)
10280         mask[14] |= 0xe0;
10281       *maskp = mask;
10282       return 1;
10283     }
10284   if (tag1 | dot1q)
10285     {
10286       if (tag1)
10287         {
10288           mask[15] = 0xff;
10289           mask[14] = 0x0f;
10290         }
10291       if (cos1)
10292         mask[14] |= 0xe0;
10293       if (proto)
10294         mask[16] = mask[17] = 0xff;
10295
10296       *maskp = mask;
10297       return 1;
10298     }
10299   if (cos2)
10300     mask[18] |= 0xe0;
10301   if (cos1)
10302     mask[14] |= 0xe0;
10303   if (proto)
10304     mask[12] = mask[13] = 0xff;
10305
10306   *maskp = mask;
10307   return 1;
10308 }
10309
10310 uword
10311 unformat_classify_mask (unformat_input_t * input, va_list * args)
10312 {
10313   u8 **maskp = va_arg (*args, u8 **);
10314   u32 *skipp = va_arg (*args, u32 *);
10315   u32 *matchp = va_arg (*args, u32 *);
10316   u32 match;
10317   u8 *mask = 0;
10318   u8 *l2 = 0;
10319   u8 *l3 = 0;
10320   u8 *l4 = 0;
10321   int i;
10322
10323   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10324     {
10325       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10326         ;
10327       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10328         ;
10329       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10330         ;
10331       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10332         ;
10333       else
10334         break;
10335     }
10336
10337   if (l4 && !l3)
10338     {
10339       vec_free (mask);
10340       vec_free (l2);
10341       vec_free (l4);
10342       return 0;
10343     }
10344
10345   if (mask || l2 || l3 || l4)
10346     {
10347       if (l2 || l3 || l4)
10348         {
10349           /* "With a free Ethernet header in every package" */
10350           if (l2 == 0)
10351             vec_validate (l2, 13);
10352           mask = l2;
10353           if (vec_len (l3))
10354             {
10355               vec_append (mask, l3);
10356               vec_free (l3);
10357             }
10358           if (vec_len (l4))
10359             {
10360               vec_append (mask, l4);
10361               vec_free (l4);
10362             }
10363         }
10364
10365       /* Scan forward looking for the first significant mask octet */
10366       for (i = 0; i < vec_len (mask); i++)
10367         if (mask[i])
10368           break;
10369
10370       /* compute (skip, match) params */
10371       *skipp = i / sizeof (u32x4);
10372       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10373
10374       /* Pad mask to an even multiple of the vector size */
10375       while (vec_len (mask) % sizeof (u32x4))
10376         vec_add1 (mask, 0);
10377
10378       match = vec_len (mask) / sizeof (u32x4);
10379
10380       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10381         {
10382           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10383           if (*tmp || *(tmp + 1))
10384             break;
10385           match--;
10386         }
10387       if (match == 0)
10388         clib_warning ("BUG: match 0");
10389
10390       _vec_len (mask) = match * sizeof (u32x4);
10391
10392       *matchp = match;
10393       *maskp = mask;
10394
10395       return 1;
10396     }
10397
10398   return 0;
10399 }
10400 #endif /* VPP_API_TEST_BUILTIN */
10401
10402 #define foreach_l2_next                         \
10403 _(drop, DROP)                                   \
10404 _(ethernet, ETHERNET_INPUT)                     \
10405 _(ip4, IP4_INPUT)                               \
10406 _(ip6, IP6_INPUT)
10407
10408 uword
10409 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10410 {
10411   u32 *miss_next_indexp = va_arg (*args, u32 *);
10412   u32 next_index = 0;
10413   u32 tmp;
10414
10415 #define _(n,N) \
10416   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10417   foreach_l2_next;
10418 #undef _
10419
10420   if (unformat (input, "%d", &tmp))
10421     {
10422       next_index = tmp;
10423       goto out;
10424     }
10425
10426   return 0;
10427
10428 out:
10429   *miss_next_indexp = next_index;
10430   return 1;
10431 }
10432
10433 #define foreach_ip_next                         \
10434 _(drop, DROP)                                   \
10435 _(local, LOCAL)                                 \
10436 _(rewrite, REWRITE)
10437
10438 uword
10439 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10440 {
10441   u32 *miss_next_indexp = va_arg (*args, u32 *);
10442   u32 next_index = 0;
10443   u32 tmp;
10444
10445 #define _(n,N) \
10446   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10447   foreach_ip_next;
10448 #undef _
10449
10450   if (unformat (input, "%d", &tmp))
10451     {
10452       next_index = tmp;
10453       goto out;
10454     }
10455
10456   return 0;
10457
10458 out:
10459   *miss_next_indexp = next_index;
10460   return 1;
10461 }
10462
10463 #define foreach_acl_next                        \
10464 _(deny, DENY)
10465
10466 uword
10467 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10468 {
10469   u32 *miss_next_indexp = va_arg (*args, u32 *);
10470   u32 next_index = 0;
10471   u32 tmp;
10472
10473 #define _(n,N) \
10474   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10475   foreach_acl_next;
10476 #undef _
10477
10478   if (unformat (input, "permit"))
10479     {
10480       next_index = ~0;
10481       goto out;
10482     }
10483   else if (unformat (input, "%d", &tmp))
10484     {
10485       next_index = tmp;
10486       goto out;
10487     }
10488
10489   return 0;
10490
10491 out:
10492   *miss_next_indexp = next_index;
10493   return 1;
10494 }
10495
10496 uword
10497 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10498 {
10499   u32 *r = va_arg (*args, u32 *);
10500
10501   if (unformat (input, "conform-color"))
10502     *r = POLICE_CONFORM;
10503   else if (unformat (input, "exceed-color"))
10504     *r = POLICE_EXCEED;
10505   else
10506     return 0;
10507
10508   return 1;
10509 }
10510
10511 static int
10512 api_classify_add_del_table (vat_main_t * vam)
10513 {
10514   unformat_input_t *i = vam->input;
10515   vl_api_classify_add_del_table_t *mp;
10516
10517   u32 nbuckets = 2;
10518   u32 skip = ~0;
10519   u32 match = ~0;
10520   int is_add = 1;
10521   int del_chain = 0;
10522   u32 table_index = ~0;
10523   u32 next_table_index = ~0;
10524   u32 miss_next_index = ~0;
10525   u32 memory_size = 32 << 20;
10526   u8 *mask = 0;
10527   u32 current_data_flag = 0;
10528   int current_data_offset = 0;
10529   int ret;
10530
10531   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10532     {
10533       if (unformat (i, "del"))
10534         is_add = 0;
10535       else if (unformat (i, "del-chain"))
10536         {
10537           is_add = 0;
10538           del_chain = 1;
10539         }
10540       else if (unformat (i, "buckets %d", &nbuckets))
10541         ;
10542       else if (unformat (i, "memory_size %d", &memory_size))
10543         ;
10544       else if (unformat (i, "skip %d", &skip))
10545         ;
10546       else if (unformat (i, "match %d", &match))
10547         ;
10548       else if (unformat (i, "table %d", &table_index))
10549         ;
10550       else if (unformat (i, "mask %U", unformat_classify_mask,
10551                          &mask, &skip, &match))
10552         ;
10553       else if (unformat (i, "next-table %d", &next_table_index))
10554         ;
10555       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10556                          &miss_next_index))
10557         ;
10558       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10559                          &miss_next_index))
10560         ;
10561       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10562                          &miss_next_index))
10563         ;
10564       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10565         ;
10566       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10567         ;
10568       else
10569         break;
10570     }
10571
10572   if (is_add && mask == 0)
10573     {
10574       errmsg ("Mask required");
10575       return -99;
10576     }
10577
10578   if (is_add && skip == ~0)
10579     {
10580       errmsg ("skip count required");
10581       return -99;
10582     }
10583
10584   if (is_add && match == ~0)
10585     {
10586       errmsg ("match count required");
10587       return -99;
10588     }
10589
10590   if (!is_add && table_index == ~0)
10591     {
10592       errmsg ("table index required for delete");
10593       return -99;
10594     }
10595
10596   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10597
10598   mp->is_add = is_add;
10599   mp->del_chain = del_chain;
10600   mp->table_index = ntohl (table_index);
10601   mp->nbuckets = ntohl (nbuckets);
10602   mp->memory_size = ntohl (memory_size);
10603   mp->skip_n_vectors = ntohl (skip);
10604   mp->match_n_vectors = ntohl (match);
10605   mp->next_table_index = ntohl (next_table_index);
10606   mp->miss_next_index = ntohl (miss_next_index);
10607   mp->current_data_flag = ntohl (current_data_flag);
10608   mp->current_data_offset = ntohl (current_data_offset);
10609   clib_memcpy (mp->mask, mask, vec_len (mask));
10610
10611   vec_free (mask);
10612
10613   S (mp);
10614   W (ret);
10615   return ret;
10616 }
10617
10618 #if VPP_API_TEST_BUILTIN == 0
10619 uword
10620 unformat_l4_match (unformat_input_t * input, va_list * args)
10621 {
10622   u8 **matchp = va_arg (*args, u8 **);
10623
10624   u8 *proto_header = 0;
10625   int src_port = 0;
10626   int dst_port = 0;
10627
10628   tcpudp_header_t h;
10629
10630   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10631     {
10632       if (unformat (input, "src_port %d", &src_port))
10633         ;
10634       else if (unformat (input, "dst_port %d", &dst_port))
10635         ;
10636       else
10637         return 0;
10638     }
10639
10640   h.src_port = clib_host_to_net_u16 (src_port);
10641   h.dst_port = clib_host_to_net_u16 (dst_port);
10642   vec_validate (proto_header, sizeof (h) - 1);
10643   memcpy (proto_header, &h, sizeof (h));
10644
10645   *matchp = proto_header;
10646
10647   return 1;
10648 }
10649
10650 uword
10651 unformat_ip4_match (unformat_input_t * input, va_list * args)
10652 {
10653   u8 **matchp = va_arg (*args, u8 **);
10654   u8 *match = 0;
10655   ip4_header_t *ip;
10656   int version = 0;
10657   u32 version_val;
10658   int hdr_length = 0;
10659   u32 hdr_length_val;
10660   int src = 0, dst = 0;
10661   ip4_address_t src_val, dst_val;
10662   int proto = 0;
10663   u32 proto_val;
10664   int tos = 0;
10665   u32 tos_val;
10666   int length = 0;
10667   u32 length_val;
10668   int fragment_id = 0;
10669   u32 fragment_id_val;
10670   int ttl = 0;
10671   int ttl_val;
10672   int checksum = 0;
10673   u32 checksum_val;
10674
10675   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10676     {
10677       if (unformat (input, "version %d", &version_val))
10678         version = 1;
10679       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10680         hdr_length = 1;
10681       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10682         src = 1;
10683       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10684         dst = 1;
10685       else if (unformat (input, "proto %d", &proto_val))
10686         proto = 1;
10687       else if (unformat (input, "tos %d", &tos_val))
10688         tos = 1;
10689       else if (unformat (input, "length %d", &length_val))
10690         length = 1;
10691       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10692         fragment_id = 1;
10693       else if (unformat (input, "ttl %d", &ttl_val))
10694         ttl = 1;
10695       else if (unformat (input, "checksum %d", &checksum_val))
10696         checksum = 1;
10697       else
10698         break;
10699     }
10700
10701   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10702       + ttl + checksum == 0)
10703     return 0;
10704
10705   /*
10706    * Aligned because we use the real comparison functions
10707    */
10708   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10709
10710   ip = (ip4_header_t *) match;
10711
10712   /* These are realistically matched in practice */
10713   if (src)
10714     ip->src_address.as_u32 = src_val.as_u32;
10715
10716   if (dst)
10717     ip->dst_address.as_u32 = dst_val.as_u32;
10718
10719   if (proto)
10720     ip->protocol = proto_val;
10721
10722
10723   /* These are not, but they're included for completeness */
10724   if (version)
10725     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10726
10727   if (hdr_length)
10728     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10729
10730   if (tos)
10731     ip->tos = tos_val;
10732
10733   if (length)
10734     ip->length = clib_host_to_net_u16 (length_val);
10735
10736   if (ttl)
10737     ip->ttl = ttl_val;
10738
10739   if (checksum)
10740     ip->checksum = clib_host_to_net_u16 (checksum_val);
10741
10742   *matchp = match;
10743   return 1;
10744 }
10745
10746 uword
10747 unformat_ip6_match (unformat_input_t * input, va_list * args)
10748 {
10749   u8 **matchp = va_arg (*args, u8 **);
10750   u8 *match = 0;
10751   ip6_header_t *ip;
10752   int version = 0;
10753   u32 version_val;
10754   u8 traffic_class = 0;
10755   u32 traffic_class_val = 0;
10756   u8 flow_label = 0;
10757   u8 flow_label_val;
10758   int src = 0, dst = 0;
10759   ip6_address_t src_val, dst_val;
10760   int proto = 0;
10761   u32 proto_val;
10762   int payload_length = 0;
10763   u32 payload_length_val;
10764   int hop_limit = 0;
10765   int hop_limit_val;
10766   u32 ip_version_traffic_class_and_flow_label;
10767
10768   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10769     {
10770       if (unformat (input, "version %d", &version_val))
10771         version = 1;
10772       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10773         traffic_class = 1;
10774       else if (unformat (input, "flow_label %d", &flow_label_val))
10775         flow_label = 1;
10776       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10777         src = 1;
10778       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10779         dst = 1;
10780       else if (unformat (input, "proto %d", &proto_val))
10781         proto = 1;
10782       else if (unformat (input, "payload_length %d", &payload_length_val))
10783         payload_length = 1;
10784       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10785         hop_limit = 1;
10786       else
10787         break;
10788     }
10789
10790   if (version + traffic_class + flow_label + src + dst + proto +
10791       payload_length + hop_limit == 0)
10792     return 0;
10793
10794   /*
10795    * Aligned because we use the real comparison functions
10796    */
10797   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10798
10799   ip = (ip6_header_t *) match;
10800
10801   if (src)
10802     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10803
10804   if (dst)
10805     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10806
10807   if (proto)
10808     ip->protocol = proto_val;
10809
10810   ip_version_traffic_class_and_flow_label = 0;
10811
10812   if (version)
10813     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10814
10815   if (traffic_class)
10816     ip_version_traffic_class_and_flow_label |=
10817       (traffic_class_val & 0xFF) << 20;
10818
10819   if (flow_label)
10820     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10821
10822   ip->ip_version_traffic_class_and_flow_label =
10823     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10824
10825   if (payload_length)
10826     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10827
10828   if (hop_limit)
10829     ip->hop_limit = hop_limit_val;
10830
10831   *matchp = match;
10832   return 1;
10833 }
10834
10835 uword
10836 unformat_l3_match (unformat_input_t * input, va_list * args)
10837 {
10838   u8 **matchp = va_arg (*args, u8 **);
10839
10840   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10841     {
10842       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10843         return 1;
10844       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10845         return 1;
10846       else
10847         break;
10848     }
10849   return 0;
10850 }
10851
10852 uword
10853 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10854 {
10855   u8 *tagp = va_arg (*args, u8 *);
10856   u32 tag;
10857
10858   if (unformat (input, "%d", &tag))
10859     {
10860       tagp[0] = (tag >> 8) & 0x0F;
10861       tagp[1] = tag & 0xFF;
10862       return 1;
10863     }
10864
10865   return 0;
10866 }
10867
10868 uword
10869 unformat_l2_match (unformat_input_t * input, va_list * args)
10870 {
10871   u8 **matchp = va_arg (*args, u8 **);
10872   u8 *match = 0;
10873   u8 src = 0;
10874   u8 src_val[6];
10875   u8 dst = 0;
10876   u8 dst_val[6];
10877   u8 proto = 0;
10878   u16 proto_val;
10879   u8 tag1 = 0;
10880   u8 tag1_val[2];
10881   u8 tag2 = 0;
10882   u8 tag2_val[2];
10883   int len = 14;
10884   u8 ignore_tag1 = 0;
10885   u8 ignore_tag2 = 0;
10886   u8 cos1 = 0;
10887   u8 cos2 = 0;
10888   u32 cos1_val = 0;
10889   u32 cos2_val = 0;
10890
10891   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10892     {
10893       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10894         src = 1;
10895       else
10896         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10897         dst = 1;
10898       else if (unformat (input, "proto %U",
10899                          unformat_ethernet_type_host_byte_order, &proto_val))
10900         proto = 1;
10901       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10902         tag1 = 1;
10903       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10904         tag2 = 1;
10905       else if (unformat (input, "ignore-tag1"))
10906         ignore_tag1 = 1;
10907       else if (unformat (input, "ignore-tag2"))
10908         ignore_tag2 = 1;
10909       else if (unformat (input, "cos1 %d", &cos1_val))
10910         cos1 = 1;
10911       else if (unformat (input, "cos2 %d", &cos2_val))
10912         cos2 = 1;
10913       else
10914         break;
10915     }
10916   if ((src + dst + proto + tag1 + tag2 +
10917        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10918     return 0;
10919
10920   if (tag1 || ignore_tag1 || cos1)
10921     len = 18;
10922   if (tag2 || ignore_tag2 || cos2)
10923     len = 22;
10924
10925   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10926
10927   if (dst)
10928     clib_memcpy (match, dst_val, 6);
10929
10930   if (src)
10931     clib_memcpy (match + 6, src_val, 6);
10932
10933   if (tag2)
10934     {
10935       /* inner vlan tag */
10936       match[19] = tag2_val[1];
10937       match[18] = tag2_val[0];
10938       if (cos2)
10939         match[18] |= (cos2_val & 0x7) << 5;
10940       if (proto)
10941         {
10942           match[21] = proto_val & 0xff;
10943           match[20] = proto_val >> 8;
10944         }
10945       if (tag1)
10946         {
10947           match[15] = tag1_val[1];
10948           match[14] = tag1_val[0];
10949         }
10950       if (cos1)
10951         match[14] |= (cos1_val & 0x7) << 5;
10952       *matchp = match;
10953       return 1;
10954     }
10955   if (tag1)
10956     {
10957       match[15] = tag1_val[1];
10958       match[14] = tag1_val[0];
10959       if (proto)
10960         {
10961           match[17] = proto_val & 0xff;
10962           match[16] = proto_val >> 8;
10963         }
10964       if (cos1)
10965         match[14] |= (cos1_val & 0x7) << 5;
10966
10967       *matchp = match;
10968       return 1;
10969     }
10970   if (cos2)
10971     match[18] |= (cos2_val & 0x7) << 5;
10972   if (cos1)
10973     match[14] |= (cos1_val & 0x7) << 5;
10974   if (proto)
10975     {
10976       match[13] = proto_val & 0xff;
10977       match[12] = proto_val >> 8;
10978     }
10979
10980   *matchp = match;
10981   return 1;
10982 }
10983 #endif
10984
10985 uword
10986 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10987 {
10988   u8 **matchp = va_arg (*args, u8 **);
10989   u32 skip_n_vectors = va_arg (*args, u32);
10990   u32 match_n_vectors = va_arg (*args, u32);
10991
10992   u8 *match = 0;
10993   u8 *l2 = 0;
10994   u8 *l3 = 0;
10995   u8 *l4 = 0;
10996
10997   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10998     {
10999       if (unformat (input, "hex %U", unformat_hex_string, &match))
11000         ;
11001       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11002         ;
11003       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11004         ;
11005       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11006         ;
11007       else
11008         break;
11009     }
11010
11011   if (l4 && !l3)
11012     {
11013       vec_free (match);
11014       vec_free (l2);
11015       vec_free (l4);
11016       return 0;
11017     }
11018
11019   if (match || l2 || l3 || l4)
11020     {
11021       if (l2 || l3 || l4)
11022         {
11023           /* "Win a free Ethernet header in every packet" */
11024           if (l2 == 0)
11025             vec_validate_aligned (l2, 13, sizeof (u32x4));
11026           match = l2;
11027           if (vec_len (l3))
11028             {
11029               vec_append_aligned (match, l3, sizeof (u32x4));
11030               vec_free (l3);
11031             }
11032           if (vec_len (l4))
11033             {
11034               vec_append_aligned (match, l4, sizeof (u32x4));
11035               vec_free (l4);
11036             }
11037         }
11038
11039       /* Make sure the vector is big enough even if key is all 0's */
11040       vec_validate_aligned
11041         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11042          sizeof (u32x4));
11043
11044       /* Set size, include skipped vectors */
11045       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11046
11047       *matchp = match;
11048
11049       return 1;
11050     }
11051
11052   return 0;
11053 }
11054
11055 static int
11056 api_classify_add_del_session (vat_main_t * vam)
11057 {
11058   unformat_input_t *i = vam->input;
11059   vl_api_classify_add_del_session_t *mp;
11060   int is_add = 1;
11061   u32 table_index = ~0;
11062   u32 hit_next_index = ~0;
11063   u32 opaque_index = ~0;
11064   u8 *match = 0;
11065   i32 advance = 0;
11066   u32 skip_n_vectors = 0;
11067   u32 match_n_vectors = 0;
11068   u32 action = 0;
11069   u32 metadata = 0;
11070   int ret;
11071
11072   /*
11073    * Warning: you have to supply skip_n and match_n
11074    * because the API client cant simply look at the classify
11075    * table object.
11076    */
11077
11078   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11079     {
11080       if (unformat (i, "del"))
11081         is_add = 0;
11082       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11083                          &hit_next_index))
11084         ;
11085       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11086                          &hit_next_index))
11087         ;
11088       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11089                          &hit_next_index))
11090         ;
11091       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11092         ;
11093       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11094         ;
11095       else if (unformat (i, "opaque-index %d", &opaque_index))
11096         ;
11097       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11098         ;
11099       else if (unformat (i, "match_n %d", &match_n_vectors))
11100         ;
11101       else if (unformat (i, "match %U", api_unformat_classify_match,
11102                          &match, skip_n_vectors, match_n_vectors))
11103         ;
11104       else if (unformat (i, "advance %d", &advance))
11105         ;
11106       else if (unformat (i, "table-index %d", &table_index))
11107         ;
11108       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11109         action = 1;
11110       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11111         action = 2;
11112       else if (unformat (i, "action %d", &action))
11113         ;
11114       else if (unformat (i, "metadata %d", &metadata))
11115         ;
11116       else
11117         break;
11118     }
11119
11120   if (table_index == ~0)
11121     {
11122       errmsg ("Table index required");
11123       return -99;
11124     }
11125
11126   if (is_add && match == 0)
11127     {
11128       errmsg ("Match value required");
11129       return -99;
11130     }
11131
11132   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11133
11134   mp->is_add = is_add;
11135   mp->table_index = ntohl (table_index);
11136   mp->hit_next_index = ntohl (hit_next_index);
11137   mp->opaque_index = ntohl (opaque_index);
11138   mp->advance = ntohl (advance);
11139   mp->action = action;
11140   mp->metadata = ntohl (metadata);
11141   clib_memcpy (mp->match, match, vec_len (match));
11142   vec_free (match);
11143
11144   S (mp);
11145   W (ret);
11146   return ret;
11147 }
11148
11149 static int
11150 api_classify_set_interface_ip_table (vat_main_t * vam)
11151 {
11152   unformat_input_t *i = vam->input;
11153   vl_api_classify_set_interface_ip_table_t *mp;
11154   u32 sw_if_index;
11155   int sw_if_index_set;
11156   u32 table_index = ~0;
11157   u8 is_ipv6 = 0;
11158   int ret;
11159
11160   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11161     {
11162       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11163         sw_if_index_set = 1;
11164       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11165         sw_if_index_set = 1;
11166       else if (unformat (i, "table %d", &table_index))
11167         ;
11168       else
11169         {
11170           clib_warning ("parse error '%U'", format_unformat_error, i);
11171           return -99;
11172         }
11173     }
11174
11175   if (sw_if_index_set == 0)
11176     {
11177       errmsg ("missing interface name or sw_if_index");
11178       return -99;
11179     }
11180
11181
11182   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11183
11184   mp->sw_if_index = ntohl (sw_if_index);
11185   mp->table_index = ntohl (table_index);
11186   mp->is_ipv6 = is_ipv6;
11187
11188   S (mp);
11189   W (ret);
11190   return ret;
11191 }
11192
11193 static int
11194 api_classify_set_interface_l2_tables (vat_main_t * vam)
11195 {
11196   unformat_input_t *i = vam->input;
11197   vl_api_classify_set_interface_l2_tables_t *mp;
11198   u32 sw_if_index;
11199   int sw_if_index_set;
11200   u32 ip4_table_index = ~0;
11201   u32 ip6_table_index = ~0;
11202   u32 other_table_index = ~0;
11203   u32 is_input = 1;
11204   int ret;
11205
11206   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11207     {
11208       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11209         sw_if_index_set = 1;
11210       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11211         sw_if_index_set = 1;
11212       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11213         ;
11214       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11215         ;
11216       else if (unformat (i, "other-table %d", &other_table_index))
11217         ;
11218       else if (unformat (i, "is-input %d", &is_input))
11219         ;
11220       else
11221         {
11222           clib_warning ("parse error '%U'", format_unformat_error, i);
11223           return -99;
11224         }
11225     }
11226
11227   if (sw_if_index_set == 0)
11228     {
11229       errmsg ("missing interface name or sw_if_index");
11230       return -99;
11231     }
11232
11233
11234   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11235
11236   mp->sw_if_index = ntohl (sw_if_index);
11237   mp->ip4_table_index = ntohl (ip4_table_index);
11238   mp->ip6_table_index = ntohl (ip6_table_index);
11239   mp->other_table_index = ntohl (other_table_index);
11240   mp->is_input = (u8) is_input;
11241
11242   S (mp);
11243   W (ret);
11244   return ret;
11245 }
11246
11247 static int
11248 api_set_ipfix_exporter (vat_main_t * vam)
11249 {
11250   unformat_input_t *i = vam->input;
11251   vl_api_set_ipfix_exporter_t *mp;
11252   ip4_address_t collector_address;
11253   u8 collector_address_set = 0;
11254   u32 collector_port = ~0;
11255   ip4_address_t src_address;
11256   u8 src_address_set = 0;
11257   u32 vrf_id = ~0;
11258   u32 path_mtu = ~0;
11259   u32 template_interval = ~0;
11260   u8 udp_checksum = 0;
11261   int ret;
11262
11263   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11264     {
11265       if (unformat (i, "collector_address %U", unformat_ip4_address,
11266                     &collector_address))
11267         collector_address_set = 1;
11268       else if (unformat (i, "collector_port %d", &collector_port))
11269         ;
11270       else if (unformat (i, "src_address %U", unformat_ip4_address,
11271                          &src_address))
11272         src_address_set = 1;
11273       else if (unformat (i, "vrf_id %d", &vrf_id))
11274         ;
11275       else if (unformat (i, "path_mtu %d", &path_mtu))
11276         ;
11277       else if (unformat (i, "template_interval %d", &template_interval))
11278         ;
11279       else if (unformat (i, "udp_checksum"))
11280         udp_checksum = 1;
11281       else
11282         break;
11283     }
11284
11285   if (collector_address_set == 0)
11286     {
11287       errmsg ("collector_address required");
11288       return -99;
11289     }
11290
11291   if (src_address_set == 0)
11292     {
11293       errmsg ("src_address required");
11294       return -99;
11295     }
11296
11297   M (SET_IPFIX_EXPORTER, mp);
11298
11299   memcpy (mp->collector_address, collector_address.data,
11300           sizeof (collector_address.data));
11301   mp->collector_port = htons ((u16) collector_port);
11302   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11303   mp->vrf_id = htonl (vrf_id);
11304   mp->path_mtu = htonl (path_mtu);
11305   mp->template_interval = htonl (template_interval);
11306   mp->udp_checksum = udp_checksum;
11307
11308   S (mp);
11309   W (ret);
11310   return ret;
11311 }
11312
11313 static int
11314 api_set_ipfix_classify_stream (vat_main_t * vam)
11315 {
11316   unformat_input_t *i = vam->input;
11317   vl_api_set_ipfix_classify_stream_t *mp;
11318   u32 domain_id = 0;
11319   u32 src_port = UDP_DST_PORT_ipfix;
11320   int ret;
11321
11322   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11323     {
11324       if (unformat (i, "domain %d", &domain_id))
11325         ;
11326       else if (unformat (i, "src_port %d", &src_port))
11327         ;
11328       else
11329         {
11330           errmsg ("unknown input `%U'", format_unformat_error, i);
11331           return -99;
11332         }
11333     }
11334
11335   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11336
11337   mp->domain_id = htonl (domain_id);
11338   mp->src_port = htons ((u16) src_port);
11339
11340   S (mp);
11341   W (ret);
11342   return ret;
11343 }
11344
11345 static int
11346 api_ipfix_classify_table_add_del (vat_main_t * vam)
11347 {
11348   unformat_input_t *i = vam->input;
11349   vl_api_ipfix_classify_table_add_del_t *mp;
11350   int is_add = -1;
11351   u32 classify_table_index = ~0;
11352   u8 ip_version = 0;
11353   u8 transport_protocol = 255;
11354   int ret;
11355
11356   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11357     {
11358       if (unformat (i, "add"))
11359         is_add = 1;
11360       else if (unformat (i, "del"))
11361         is_add = 0;
11362       else if (unformat (i, "table %d", &classify_table_index))
11363         ;
11364       else if (unformat (i, "ip4"))
11365         ip_version = 4;
11366       else if (unformat (i, "ip6"))
11367         ip_version = 6;
11368       else if (unformat (i, "tcp"))
11369         transport_protocol = 6;
11370       else if (unformat (i, "udp"))
11371         transport_protocol = 17;
11372       else
11373         {
11374           errmsg ("unknown input `%U'", format_unformat_error, i);
11375           return -99;
11376         }
11377     }
11378
11379   if (is_add == -1)
11380     {
11381       errmsg ("expecting: add|del");
11382       return -99;
11383     }
11384   if (classify_table_index == ~0)
11385     {
11386       errmsg ("classifier table not specified");
11387       return -99;
11388     }
11389   if (ip_version == 0)
11390     {
11391       errmsg ("IP version not specified");
11392       return -99;
11393     }
11394
11395   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11396
11397   mp->is_add = is_add;
11398   mp->table_id = htonl (classify_table_index);
11399   mp->ip_version = ip_version;
11400   mp->transport_protocol = transport_protocol;
11401
11402   S (mp);
11403   W (ret);
11404   return ret;
11405 }
11406
11407 static int
11408 api_get_node_index (vat_main_t * vam)
11409 {
11410   unformat_input_t *i = vam->input;
11411   vl_api_get_node_index_t *mp;
11412   u8 *name = 0;
11413   int ret;
11414
11415   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11416     {
11417       if (unformat (i, "node %s", &name))
11418         ;
11419       else
11420         break;
11421     }
11422   if (name == 0)
11423     {
11424       errmsg ("node name required");
11425       return -99;
11426     }
11427   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11428     {
11429       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11430       return -99;
11431     }
11432
11433   M (GET_NODE_INDEX, mp);
11434   clib_memcpy (mp->node_name, name, vec_len (name));
11435   vec_free (name);
11436
11437   S (mp);
11438   W (ret);
11439   return ret;
11440 }
11441
11442 static int
11443 api_get_next_index (vat_main_t * vam)
11444 {
11445   unformat_input_t *i = vam->input;
11446   vl_api_get_next_index_t *mp;
11447   u8 *node_name = 0, *next_node_name = 0;
11448   int ret;
11449
11450   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11451     {
11452       if (unformat (i, "node-name %s", &node_name))
11453         ;
11454       else if (unformat (i, "next-node-name %s", &next_node_name))
11455         break;
11456     }
11457
11458   if (node_name == 0)
11459     {
11460       errmsg ("node name required");
11461       return -99;
11462     }
11463   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11464     {
11465       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11466       return -99;
11467     }
11468
11469   if (next_node_name == 0)
11470     {
11471       errmsg ("next node name required");
11472       return -99;
11473     }
11474   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11475     {
11476       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11477       return -99;
11478     }
11479
11480   M (GET_NEXT_INDEX, mp);
11481   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11482   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11483   vec_free (node_name);
11484   vec_free (next_node_name);
11485
11486   S (mp);
11487   W (ret);
11488   return ret;
11489 }
11490
11491 static int
11492 api_add_node_next (vat_main_t * vam)
11493 {
11494   unformat_input_t *i = vam->input;
11495   vl_api_add_node_next_t *mp;
11496   u8 *name = 0;
11497   u8 *next = 0;
11498   int ret;
11499
11500   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11501     {
11502       if (unformat (i, "node %s", &name))
11503         ;
11504       else if (unformat (i, "next %s", &next))
11505         ;
11506       else
11507         break;
11508     }
11509   if (name == 0)
11510     {
11511       errmsg ("node name required");
11512       return -99;
11513     }
11514   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11515     {
11516       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11517       return -99;
11518     }
11519   if (next == 0)
11520     {
11521       errmsg ("next node required");
11522       return -99;
11523     }
11524   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11525     {
11526       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11527       return -99;
11528     }
11529
11530   M (ADD_NODE_NEXT, mp);
11531   clib_memcpy (mp->node_name, name, vec_len (name));
11532   clib_memcpy (mp->next_name, next, vec_len (next));
11533   vec_free (name);
11534   vec_free (next);
11535
11536   S (mp);
11537   W (ret);
11538   return ret;
11539 }
11540
11541 static int
11542 api_l2tpv3_create_tunnel (vat_main_t * vam)
11543 {
11544   unformat_input_t *i = vam->input;
11545   ip6_address_t client_address, our_address;
11546   int client_address_set = 0;
11547   int our_address_set = 0;
11548   u32 local_session_id = 0;
11549   u32 remote_session_id = 0;
11550   u64 local_cookie = 0;
11551   u64 remote_cookie = 0;
11552   u8 l2_sublayer_present = 0;
11553   vl_api_l2tpv3_create_tunnel_t *mp;
11554   int ret;
11555
11556   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11557     {
11558       if (unformat (i, "client_address %U", unformat_ip6_address,
11559                     &client_address))
11560         client_address_set = 1;
11561       else if (unformat (i, "our_address %U", unformat_ip6_address,
11562                          &our_address))
11563         our_address_set = 1;
11564       else if (unformat (i, "local_session_id %d", &local_session_id))
11565         ;
11566       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11567         ;
11568       else if (unformat (i, "local_cookie %lld", &local_cookie))
11569         ;
11570       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11571         ;
11572       else if (unformat (i, "l2-sublayer-present"))
11573         l2_sublayer_present = 1;
11574       else
11575         break;
11576     }
11577
11578   if (client_address_set == 0)
11579     {
11580       errmsg ("client_address required");
11581       return -99;
11582     }
11583
11584   if (our_address_set == 0)
11585     {
11586       errmsg ("our_address required");
11587       return -99;
11588     }
11589
11590   M (L2TPV3_CREATE_TUNNEL, mp);
11591
11592   clib_memcpy (mp->client_address, client_address.as_u8,
11593                sizeof (mp->client_address));
11594
11595   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11596
11597   mp->local_session_id = ntohl (local_session_id);
11598   mp->remote_session_id = ntohl (remote_session_id);
11599   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11600   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11601   mp->l2_sublayer_present = l2_sublayer_present;
11602   mp->is_ipv6 = 1;
11603
11604   S (mp);
11605   W (ret);
11606   return ret;
11607 }
11608
11609 static int
11610 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11611 {
11612   unformat_input_t *i = vam->input;
11613   u32 sw_if_index;
11614   u8 sw_if_index_set = 0;
11615   u64 new_local_cookie = 0;
11616   u64 new_remote_cookie = 0;
11617   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11618   int ret;
11619
11620   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11621     {
11622       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11623         sw_if_index_set = 1;
11624       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11625         sw_if_index_set = 1;
11626       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11627         ;
11628       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11629         ;
11630       else
11631         break;
11632     }
11633
11634   if (sw_if_index_set == 0)
11635     {
11636       errmsg ("missing interface name or sw_if_index");
11637       return -99;
11638     }
11639
11640   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11641
11642   mp->sw_if_index = ntohl (sw_if_index);
11643   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11644   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11645
11646   S (mp);
11647   W (ret);
11648   return ret;
11649 }
11650
11651 static int
11652 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11653 {
11654   unformat_input_t *i = vam->input;
11655   vl_api_l2tpv3_interface_enable_disable_t *mp;
11656   u32 sw_if_index;
11657   u8 sw_if_index_set = 0;
11658   u8 enable_disable = 1;
11659   int ret;
11660
11661   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11662     {
11663       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11664         sw_if_index_set = 1;
11665       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11666         sw_if_index_set = 1;
11667       else if (unformat (i, "enable"))
11668         enable_disable = 1;
11669       else if (unformat (i, "disable"))
11670         enable_disable = 0;
11671       else
11672         break;
11673     }
11674
11675   if (sw_if_index_set == 0)
11676     {
11677       errmsg ("missing interface name or sw_if_index");
11678       return -99;
11679     }
11680
11681   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11682
11683   mp->sw_if_index = ntohl (sw_if_index);
11684   mp->enable_disable = enable_disable;
11685
11686   S (mp);
11687   W (ret);
11688   return ret;
11689 }
11690
11691 static int
11692 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11693 {
11694   unformat_input_t *i = vam->input;
11695   vl_api_l2tpv3_set_lookup_key_t *mp;
11696   u8 key = ~0;
11697   int ret;
11698
11699   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11700     {
11701       if (unformat (i, "lookup_v6_src"))
11702         key = L2T_LOOKUP_SRC_ADDRESS;
11703       else if (unformat (i, "lookup_v6_dst"))
11704         key = L2T_LOOKUP_DST_ADDRESS;
11705       else if (unformat (i, "lookup_session_id"))
11706         key = L2T_LOOKUP_SESSION_ID;
11707       else
11708         break;
11709     }
11710
11711   if (key == (u8) ~ 0)
11712     {
11713       errmsg ("l2tp session lookup key unset");
11714       return -99;
11715     }
11716
11717   M (L2TPV3_SET_LOOKUP_KEY, mp);
11718
11719   mp->key = key;
11720
11721   S (mp);
11722   W (ret);
11723   return ret;
11724 }
11725
11726 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11727   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11728 {
11729   vat_main_t *vam = &vat_main;
11730
11731   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11732          format_ip6_address, mp->our_address,
11733          format_ip6_address, mp->client_address,
11734          clib_net_to_host_u32 (mp->sw_if_index));
11735
11736   print (vam->ofp,
11737          "   local cookies %016llx %016llx remote cookie %016llx",
11738          clib_net_to_host_u64 (mp->local_cookie[0]),
11739          clib_net_to_host_u64 (mp->local_cookie[1]),
11740          clib_net_to_host_u64 (mp->remote_cookie));
11741
11742   print (vam->ofp, "   local session-id %d remote session-id %d",
11743          clib_net_to_host_u32 (mp->local_session_id),
11744          clib_net_to_host_u32 (mp->remote_session_id));
11745
11746   print (vam->ofp, "   l2 specific sublayer %s\n",
11747          mp->l2_sublayer_present ? "preset" : "absent");
11748
11749 }
11750
11751 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11752   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11753 {
11754   vat_main_t *vam = &vat_main;
11755   vat_json_node_t *node = NULL;
11756   struct in6_addr addr;
11757
11758   if (VAT_JSON_ARRAY != vam->json_tree.type)
11759     {
11760       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11761       vat_json_init_array (&vam->json_tree);
11762     }
11763   node = vat_json_array_add (&vam->json_tree);
11764
11765   vat_json_init_object (node);
11766
11767   clib_memcpy (&addr, mp->our_address, sizeof (addr));
11768   vat_json_object_add_ip6 (node, "our_address", addr);
11769   clib_memcpy (&addr, mp->client_address, sizeof (addr));
11770   vat_json_object_add_ip6 (node, "client_address", addr);
11771
11772   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11773   vat_json_init_array (lc);
11774   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11775   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11776   vat_json_object_add_uint (node, "remote_cookie",
11777                             clib_net_to_host_u64 (mp->remote_cookie));
11778
11779   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11780   vat_json_object_add_uint (node, "local_session_id",
11781                             clib_net_to_host_u32 (mp->local_session_id));
11782   vat_json_object_add_uint (node, "remote_session_id",
11783                             clib_net_to_host_u32 (mp->remote_session_id));
11784   vat_json_object_add_string_copy (node, "l2_sublayer",
11785                                    mp->l2_sublayer_present ? (u8 *) "present"
11786                                    : (u8 *) "absent");
11787 }
11788
11789 static int
11790 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11791 {
11792   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11793   vl_api_control_ping_t *mp_ping;
11794   int ret;
11795
11796   /* Get list of l2tpv3-tunnel interfaces */
11797   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11798   S (mp);
11799
11800   /* Use a control ping for synchronization */
11801   MPING (CONTROL_PING, mp_ping);
11802   S (mp_ping);
11803
11804   W (ret);
11805   return ret;
11806 }
11807
11808
11809 static void vl_api_sw_interface_tap_details_t_handler
11810   (vl_api_sw_interface_tap_details_t * mp)
11811 {
11812   vat_main_t *vam = &vat_main;
11813
11814   print (vam->ofp, "%-16s %d",
11815          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
11816 }
11817
11818 static void vl_api_sw_interface_tap_details_t_handler_json
11819   (vl_api_sw_interface_tap_details_t * mp)
11820 {
11821   vat_main_t *vam = &vat_main;
11822   vat_json_node_t *node = NULL;
11823
11824   if (VAT_JSON_ARRAY != vam->json_tree.type)
11825     {
11826       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11827       vat_json_init_array (&vam->json_tree);
11828     }
11829   node = vat_json_array_add (&vam->json_tree);
11830
11831   vat_json_init_object (node);
11832   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11833   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11834 }
11835
11836 static int
11837 api_sw_interface_tap_dump (vat_main_t * vam)
11838 {
11839   vl_api_sw_interface_tap_dump_t *mp;
11840   vl_api_control_ping_t *mp_ping;
11841   int ret;
11842
11843   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
11844   /* Get list of tap interfaces */
11845   M (SW_INTERFACE_TAP_DUMP, mp);
11846   S (mp);
11847
11848   /* Use a control ping for synchronization */
11849   MPING (CONTROL_PING, mp_ping);
11850   S (mp_ping);
11851
11852   W (ret);
11853   return ret;
11854 }
11855
11856 static uword unformat_vxlan_decap_next
11857   (unformat_input_t * input, va_list * args)
11858 {
11859   u32 *result = va_arg (*args, u32 *);
11860   u32 tmp;
11861
11862   if (unformat (input, "l2"))
11863     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11864   else if (unformat (input, "%d", &tmp))
11865     *result = tmp;
11866   else
11867     return 0;
11868   return 1;
11869 }
11870
11871 static int
11872 api_vxlan_add_del_tunnel (vat_main_t * vam)
11873 {
11874   unformat_input_t *line_input = vam->input;
11875   vl_api_vxlan_add_del_tunnel_t *mp;
11876   ip46_address_t src, dst;
11877   u8 is_add = 1;
11878   u8 ipv4_set = 0, ipv6_set = 0;
11879   u8 src_set = 0;
11880   u8 dst_set = 0;
11881   u8 grp_set = 0;
11882   u32 mcast_sw_if_index = ~0;
11883   u32 encap_vrf_id = 0;
11884   u32 decap_next_index = ~0;
11885   u32 vni = 0;
11886   int ret;
11887
11888   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11889   memset (&src, 0, sizeof src);
11890   memset (&dst, 0, sizeof dst);
11891
11892   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11893     {
11894       if (unformat (line_input, "del"))
11895         is_add = 0;
11896       else
11897         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11898         {
11899           ipv4_set = 1;
11900           src_set = 1;
11901         }
11902       else
11903         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11904         {
11905           ipv4_set = 1;
11906           dst_set = 1;
11907         }
11908       else
11909         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11910         {
11911           ipv6_set = 1;
11912           src_set = 1;
11913         }
11914       else
11915         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11916         {
11917           ipv6_set = 1;
11918           dst_set = 1;
11919         }
11920       else if (unformat (line_input, "group %U %U",
11921                          unformat_ip4_address, &dst.ip4,
11922                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11923         {
11924           grp_set = dst_set = 1;
11925           ipv4_set = 1;
11926         }
11927       else if (unformat (line_input, "group %U",
11928                          unformat_ip4_address, &dst.ip4))
11929         {
11930           grp_set = dst_set = 1;
11931           ipv4_set = 1;
11932         }
11933       else if (unformat (line_input, "group %U %U",
11934                          unformat_ip6_address, &dst.ip6,
11935                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11936         {
11937           grp_set = dst_set = 1;
11938           ipv6_set = 1;
11939         }
11940       else if (unformat (line_input, "group %U",
11941                          unformat_ip6_address, &dst.ip6))
11942         {
11943           grp_set = dst_set = 1;
11944           ipv6_set = 1;
11945         }
11946       else
11947         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11948         ;
11949       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11950         ;
11951       else if (unformat (line_input, "decap-next %U",
11952                          unformat_vxlan_decap_next, &decap_next_index))
11953         ;
11954       else if (unformat (line_input, "vni %d", &vni))
11955         ;
11956       else
11957         {
11958           errmsg ("parse error '%U'", format_unformat_error, line_input);
11959           return -99;
11960         }
11961     }
11962
11963   if (src_set == 0)
11964     {
11965       errmsg ("tunnel src address not specified");
11966       return -99;
11967     }
11968   if (dst_set == 0)
11969     {
11970       errmsg ("tunnel dst address not specified");
11971       return -99;
11972     }
11973
11974   if (grp_set && !ip46_address_is_multicast (&dst))
11975     {
11976       errmsg ("tunnel group address not multicast");
11977       return -99;
11978     }
11979   if (grp_set && mcast_sw_if_index == ~0)
11980     {
11981       errmsg ("tunnel nonexistent multicast device");
11982       return -99;
11983     }
11984   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11985     {
11986       errmsg ("tunnel dst address must be unicast");
11987       return -99;
11988     }
11989
11990
11991   if (ipv4_set && ipv6_set)
11992     {
11993       errmsg ("both IPv4 and IPv6 addresses specified");
11994       return -99;
11995     }
11996
11997   if ((vni == 0) || (vni >> 24))
11998     {
11999       errmsg ("vni not specified or out of range");
12000       return -99;
12001     }
12002
12003   M (VXLAN_ADD_DEL_TUNNEL, mp);
12004
12005   if (ipv6_set)
12006     {
12007       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12008       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12009     }
12010   else
12011     {
12012       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12013       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12014     }
12015   mp->encap_vrf_id = ntohl (encap_vrf_id);
12016   mp->decap_next_index = ntohl (decap_next_index);
12017   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12018   mp->vni = ntohl (vni);
12019   mp->is_add = is_add;
12020   mp->is_ipv6 = ipv6_set;
12021
12022   S (mp);
12023   W (ret);
12024   return ret;
12025 }
12026
12027 static void vl_api_vxlan_tunnel_details_t_handler
12028   (vl_api_vxlan_tunnel_details_t * mp)
12029 {
12030   vat_main_t *vam = &vat_main;
12031   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12032   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12033
12034   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12035          ntohl (mp->sw_if_index),
12036          format_ip46_address, &src, IP46_TYPE_ANY,
12037          format_ip46_address, &dst, IP46_TYPE_ANY,
12038          ntohl (mp->encap_vrf_id),
12039          ntohl (mp->decap_next_index), ntohl (mp->vni),
12040          ntohl (mp->mcast_sw_if_index));
12041 }
12042
12043 static void vl_api_vxlan_tunnel_details_t_handler_json
12044   (vl_api_vxlan_tunnel_details_t * mp)
12045 {
12046   vat_main_t *vam = &vat_main;
12047   vat_json_node_t *node = NULL;
12048
12049   if (VAT_JSON_ARRAY != vam->json_tree.type)
12050     {
12051       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12052       vat_json_init_array (&vam->json_tree);
12053     }
12054   node = vat_json_array_add (&vam->json_tree);
12055
12056   vat_json_init_object (node);
12057   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12058   if (mp->is_ipv6)
12059     {
12060       struct in6_addr ip6;
12061
12062       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12063       vat_json_object_add_ip6 (node, "src_address", ip6);
12064       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12065       vat_json_object_add_ip6 (node, "dst_address", ip6);
12066     }
12067   else
12068     {
12069       struct in_addr ip4;
12070
12071       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12072       vat_json_object_add_ip4 (node, "src_address", ip4);
12073       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12074       vat_json_object_add_ip4 (node, "dst_address", ip4);
12075     }
12076   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12077   vat_json_object_add_uint (node, "decap_next_index",
12078                             ntohl (mp->decap_next_index));
12079   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12080   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12081   vat_json_object_add_uint (node, "mcast_sw_if_index",
12082                             ntohl (mp->mcast_sw_if_index));
12083 }
12084
12085 static int
12086 api_vxlan_tunnel_dump (vat_main_t * vam)
12087 {
12088   unformat_input_t *i = vam->input;
12089   vl_api_vxlan_tunnel_dump_t *mp;
12090   vl_api_control_ping_t *mp_ping;
12091   u32 sw_if_index;
12092   u8 sw_if_index_set = 0;
12093   int ret;
12094
12095   /* Parse args required to build the message */
12096   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12097     {
12098       if (unformat (i, "sw_if_index %d", &sw_if_index))
12099         sw_if_index_set = 1;
12100       else
12101         break;
12102     }
12103
12104   if (sw_if_index_set == 0)
12105     {
12106       sw_if_index = ~0;
12107     }
12108
12109   if (!vam->json_output)
12110     {
12111       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12112              "sw_if_index", "src_address", "dst_address",
12113              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12114     }
12115
12116   /* Get list of vxlan-tunnel interfaces */
12117   M (VXLAN_TUNNEL_DUMP, mp);
12118
12119   mp->sw_if_index = htonl (sw_if_index);
12120
12121   S (mp);
12122
12123   /* Use a control ping for synchronization */
12124   MPING (CONTROL_PING, mp_ping);
12125   S (mp_ping);
12126
12127   W (ret);
12128   return ret;
12129 }
12130
12131 static uword unformat_geneve_decap_next
12132   (unformat_input_t * input, va_list * args)
12133 {
12134   u32 *result = va_arg (*args, u32 *);
12135   u32 tmp;
12136
12137   if (unformat (input, "l2"))
12138     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12139   else if (unformat (input, "%d", &tmp))
12140     *result = tmp;
12141   else
12142     return 0;
12143   return 1;
12144 }
12145
12146 static int
12147 api_geneve_add_del_tunnel (vat_main_t * vam)
12148 {
12149   unformat_input_t *line_input = vam->input;
12150   vl_api_geneve_add_del_tunnel_t *mp;
12151   ip46_address_t src, dst;
12152   u8 is_add = 1;
12153   u8 ipv4_set = 0, ipv6_set = 0;
12154   u8 src_set = 0;
12155   u8 dst_set = 0;
12156   u8 grp_set = 0;
12157   u32 mcast_sw_if_index = ~0;
12158   u32 encap_vrf_id = 0;
12159   u32 decap_next_index = ~0;
12160   u32 vni = 0;
12161   int ret;
12162
12163   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12164   memset (&src, 0, sizeof src);
12165   memset (&dst, 0, sizeof dst);
12166
12167   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12168     {
12169       if (unformat (line_input, "del"))
12170         is_add = 0;
12171       else
12172         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12173         {
12174           ipv4_set = 1;
12175           src_set = 1;
12176         }
12177       else
12178         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12179         {
12180           ipv4_set = 1;
12181           dst_set = 1;
12182         }
12183       else
12184         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12185         {
12186           ipv6_set = 1;
12187           src_set = 1;
12188         }
12189       else
12190         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12191         {
12192           ipv6_set = 1;
12193           dst_set = 1;
12194         }
12195       else if (unformat (line_input, "group %U %U",
12196                          unformat_ip4_address, &dst.ip4,
12197                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12198         {
12199           grp_set = dst_set = 1;
12200           ipv4_set = 1;
12201         }
12202       else if (unformat (line_input, "group %U",
12203                          unformat_ip4_address, &dst.ip4))
12204         {
12205           grp_set = dst_set = 1;
12206           ipv4_set = 1;
12207         }
12208       else if (unformat (line_input, "group %U %U",
12209                          unformat_ip6_address, &dst.ip6,
12210                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12211         {
12212           grp_set = dst_set = 1;
12213           ipv6_set = 1;
12214         }
12215       else if (unformat (line_input, "group %U",
12216                          unformat_ip6_address, &dst.ip6))
12217         {
12218           grp_set = dst_set = 1;
12219           ipv6_set = 1;
12220         }
12221       else
12222         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12223         ;
12224       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12225         ;
12226       else if (unformat (line_input, "decap-next %U",
12227                          unformat_geneve_decap_next, &decap_next_index))
12228         ;
12229       else if (unformat (line_input, "vni %d", &vni))
12230         ;
12231       else
12232         {
12233           errmsg ("parse error '%U'", format_unformat_error, line_input);
12234           return -99;
12235         }
12236     }
12237
12238   if (src_set == 0)
12239     {
12240       errmsg ("tunnel src address not specified");
12241       return -99;
12242     }
12243   if (dst_set == 0)
12244     {
12245       errmsg ("tunnel dst address not specified");
12246       return -99;
12247     }
12248
12249   if (grp_set && !ip46_address_is_multicast (&dst))
12250     {
12251       errmsg ("tunnel group address not multicast");
12252       return -99;
12253     }
12254   if (grp_set && mcast_sw_if_index == ~0)
12255     {
12256       errmsg ("tunnel nonexistent multicast device");
12257       return -99;
12258     }
12259   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12260     {
12261       errmsg ("tunnel dst address must be unicast");
12262       return -99;
12263     }
12264
12265
12266   if (ipv4_set && ipv6_set)
12267     {
12268       errmsg ("both IPv4 and IPv6 addresses specified");
12269       return -99;
12270     }
12271
12272   if ((vni == 0) || (vni >> 24))
12273     {
12274       errmsg ("vni not specified or out of range");
12275       return -99;
12276     }
12277
12278   M (GENEVE_ADD_DEL_TUNNEL, mp);
12279
12280   if (ipv6_set)
12281     {
12282       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12283       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12284     }
12285   else
12286     {
12287       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12288       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12289     }
12290   mp->encap_vrf_id = ntohl (encap_vrf_id);
12291   mp->decap_next_index = ntohl (decap_next_index);
12292   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12293   mp->vni = ntohl (vni);
12294   mp->is_add = is_add;
12295   mp->is_ipv6 = ipv6_set;
12296
12297   S (mp);
12298   W (ret);
12299   return ret;
12300 }
12301
12302 static void vl_api_geneve_tunnel_details_t_handler
12303   (vl_api_geneve_tunnel_details_t * mp)
12304 {
12305   vat_main_t *vam = &vat_main;
12306   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12307   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12308
12309   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12310          ntohl (mp->sw_if_index),
12311          format_ip46_address, &src, IP46_TYPE_ANY,
12312          format_ip46_address, &dst, IP46_TYPE_ANY,
12313          ntohl (mp->encap_vrf_id),
12314          ntohl (mp->decap_next_index), ntohl (mp->vni),
12315          ntohl (mp->mcast_sw_if_index));
12316 }
12317
12318 static void vl_api_geneve_tunnel_details_t_handler_json
12319   (vl_api_geneve_tunnel_details_t * mp)
12320 {
12321   vat_main_t *vam = &vat_main;
12322   vat_json_node_t *node = NULL;
12323
12324   if (VAT_JSON_ARRAY != vam->json_tree.type)
12325     {
12326       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12327       vat_json_init_array (&vam->json_tree);
12328     }
12329   node = vat_json_array_add (&vam->json_tree);
12330
12331   vat_json_init_object (node);
12332   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12333   if (mp->is_ipv6)
12334     {
12335       struct in6_addr ip6;
12336
12337       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12338       vat_json_object_add_ip6 (node, "src_address", ip6);
12339       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12340       vat_json_object_add_ip6 (node, "dst_address", ip6);
12341     }
12342   else
12343     {
12344       struct in_addr ip4;
12345
12346       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12347       vat_json_object_add_ip4 (node, "src_address", ip4);
12348       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12349       vat_json_object_add_ip4 (node, "dst_address", ip4);
12350     }
12351   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12352   vat_json_object_add_uint (node, "decap_next_index",
12353                             ntohl (mp->decap_next_index));
12354   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12355   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12356   vat_json_object_add_uint (node, "mcast_sw_if_index",
12357                             ntohl (mp->mcast_sw_if_index));
12358 }
12359
12360 static int
12361 api_geneve_tunnel_dump (vat_main_t * vam)
12362 {
12363   unformat_input_t *i = vam->input;
12364   vl_api_geneve_tunnel_dump_t *mp;
12365   vl_api_control_ping_t *mp_ping;
12366   u32 sw_if_index;
12367   u8 sw_if_index_set = 0;
12368   int ret;
12369
12370   /* Parse args required to build the message */
12371   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12372     {
12373       if (unformat (i, "sw_if_index %d", &sw_if_index))
12374         sw_if_index_set = 1;
12375       else
12376         break;
12377     }
12378
12379   if (sw_if_index_set == 0)
12380     {
12381       sw_if_index = ~0;
12382     }
12383
12384   if (!vam->json_output)
12385     {
12386       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12387              "sw_if_index", "local_address", "remote_address",
12388              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12389     }
12390
12391   /* Get list of geneve-tunnel interfaces */
12392   M (GENEVE_TUNNEL_DUMP, mp);
12393
12394   mp->sw_if_index = htonl (sw_if_index);
12395
12396   S (mp);
12397
12398   /* Use a control ping for synchronization */
12399   M (CONTROL_PING, mp_ping);
12400   S (mp_ping);
12401
12402   W (ret);
12403   return ret;
12404 }
12405
12406 static int
12407 api_gre_add_del_tunnel (vat_main_t * vam)
12408 {
12409   unformat_input_t *line_input = vam->input;
12410   vl_api_gre_add_del_tunnel_t *mp;
12411   ip4_address_t src4, dst4;
12412   ip6_address_t src6, dst6;
12413   u8 is_add = 1;
12414   u8 ipv4_set = 0;
12415   u8 ipv6_set = 0;
12416   u8 teb = 0;
12417   u8 src_set = 0;
12418   u8 dst_set = 0;
12419   u32 outer_fib_id = 0;
12420   int ret;
12421
12422   memset (&src4, 0, sizeof src4);
12423   memset (&dst4, 0, sizeof dst4);
12424   memset (&src6, 0, sizeof src6);
12425   memset (&dst6, 0, sizeof dst6);
12426
12427   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12428     {
12429       if (unformat (line_input, "del"))
12430         is_add = 0;
12431       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
12432         {
12433           src_set = 1;
12434           ipv4_set = 1;
12435         }
12436       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
12437         {
12438           dst_set = 1;
12439           ipv4_set = 1;
12440         }
12441       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
12442         {
12443           src_set = 1;
12444           ipv6_set = 1;
12445         }
12446       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
12447         {
12448           dst_set = 1;
12449           ipv6_set = 1;
12450         }
12451       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
12452         ;
12453       else if (unformat (line_input, "teb"))
12454         teb = 1;
12455       else
12456         {
12457           errmsg ("parse error '%U'", format_unformat_error, line_input);
12458           return -99;
12459         }
12460     }
12461
12462   if (src_set == 0)
12463     {
12464       errmsg ("tunnel src address not specified");
12465       return -99;
12466     }
12467   if (dst_set == 0)
12468     {
12469       errmsg ("tunnel dst address not specified");
12470       return -99;
12471     }
12472   if (ipv4_set && ipv6_set)
12473     {
12474       errmsg ("both IPv4 and IPv6 addresses specified");
12475       return -99;
12476     }
12477
12478
12479   M (GRE_ADD_DEL_TUNNEL, mp);
12480
12481   if (ipv4_set)
12482     {
12483       clib_memcpy (&mp->src_address, &src4, 4);
12484       clib_memcpy (&mp->dst_address, &dst4, 4);
12485     }
12486   else
12487     {
12488       clib_memcpy (&mp->src_address, &src6, 16);
12489       clib_memcpy (&mp->dst_address, &dst6, 16);
12490     }
12491   mp->outer_fib_id = ntohl (outer_fib_id);
12492   mp->is_add = is_add;
12493   mp->teb = teb;
12494   mp->is_ipv6 = ipv6_set;
12495
12496   S (mp);
12497   W (ret);
12498   return ret;
12499 }
12500
12501 static void vl_api_gre_tunnel_details_t_handler
12502   (vl_api_gre_tunnel_details_t * mp)
12503 {
12504   vat_main_t *vam = &vat_main;
12505   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
12506   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
12507
12508   print (vam->ofp, "%11d%24U%24U%6d%14d",
12509          ntohl (mp->sw_if_index),
12510          format_ip46_address, &src, IP46_TYPE_ANY,
12511          format_ip46_address, &dst, IP46_TYPE_ANY,
12512          mp->teb, ntohl (mp->outer_fib_id));
12513 }
12514
12515 static void vl_api_gre_tunnel_details_t_handler_json
12516   (vl_api_gre_tunnel_details_t * mp)
12517 {
12518   vat_main_t *vam = &vat_main;
12519   vat_json_node_t *node = NULL;
12520   struct in_addr ip4;
12521   struct in6_addr ip6;
12522
12523   if (VAT_JSON_ARRAY != vam->json_tree.type)
12524     {
12525       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12526       vat_json_init_array (&vam->json_tree);
12527     }
12528   node = vat_json_array_add (&vam->json_tree);
12529
12530   vat_json_init_object (node);
12531   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12532   if (!mp->is_ipv6)
12533     {
12534       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
12535       vat_json_object_add_ip4 (node, "src_address", ip4);
12536       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
12537       vat_json_object_add_ip4 (node, "dst_address", ip4);
12538     }
12539   else
12540     {
12541       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
12542       vat_json_object_add_ip6 (node, "src_address", ip6);
12543       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
12544       vat_json_object_add_ip6 (node, "dst_address", ip6);
12545     }
12546   vat_json_object_add_uint (node, "teb", mp->teb);
12547   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
12548   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
12549 }
12550
12551 static int
12552 api_gre_tunnel_dump (vat_main_t * vam)
12553 {
12554   unformat_input_t *i = vam->input;
12555   vl_api_gre_tunnel_dump_t *mp;
12556   vl_api_control_ping_t *mp_ping;
12557   u32 sw_if_index;
12558   u8 sw_if_index_set = 0;
12559   int ret;
12560
12561   /* Parse args required to build the message */
12562   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12563     {
12564       if (unformat (i, "sw_if_index %d", &sw_if_index))
12565         sw_if_index_set = 1;
12566       else
12567         break;
12568     }
12569
12570   if (sw_if_index_set == 0)
12571     {
12572       sw_if_index = ~0;
12573     }
12574
12575   if (!vam->json_output)
12576     {
12577       print (vam->ofp, "%11s%24s%24s%6s%14s",
12578              "sw_if_index", "src_address", "dst_address", "teb",
12579              "outer_fib_id");
12580     }
12581
12582   /* Get list of gre-tunnel interfaces */
12583   M (GRE_TUNNEL_DUMP, mp);
12584
12585   mp->sw_if_index = htonl (sw_if_index);
12586
12587   S (mp);
12588
12589   /* Use a control ping for synchronization */
12590   MPING (CONTROL_PING, mp_ping);
12591   S (mp_ping);
12592
12593   W (ret);
12594   return ret;
12595 }
12596
12597 static int
12598 api_l2_fib_clear_table (vat_main_t * vam)
12599 {
12600 //  unformat_input_t * i = vam->input;
12601   vl_api_l2_fib_clear_table_t *mp;
12602   int ret;
12603
12604   M (L2_FIB_CLEAR_TABLE, mp);
12605
12606   S (mp);
12607   W (ret);
12608   return ret;
12609 }
12610
12611 static int
12612 api_l2_interface_efp_filter (vat_main_t * vam)
12613 {
12614   unformat_input_t *i = vam->input;
12615   vl_api_l2_interface_efp_filter_t *mp;
12616   u32 sw_if_index;
12617   u8 enable = 1;
12618   u8 sw_if_index_set = 0;
12619   int ret;
12620
12621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12622     {
12623       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12624         sw_if_index_set = 1;
12625       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12626         sw_if_index_set = 1;
12627       else if (unformat (i, "enable"))
12628         enable = 1;
12629       else if (unformat (i, "disable"))
12630         enable = 0;
12631       else
12632         {
12633           clib_warning ("parse error '%U'", format_unformat_error, i);
12634           return -99;
12635         }
12636     }
12637
12638   if (sw_if_index_set == 0)
12639     {
12640       errmsg ("missing sw_if_index");
12641       return -99;
12642     }
12643
12644   M (L2_INTERFACE_EFP_FILTER, mp);
12645
12646   mp->sw_if_index = ntohl (sw_if_index);
12647   mp->enable_disable = enable;
12648
12649   S (mp);
12650   W (ret);
12651   return ret;
12652 }
12653
12654 #define foreach_vtr_op                          \
12655 _("disable",  L2_VTR_DISABLED)                  \
12656 _("push-1",  L2_VTR_PUSH_1)                     \
12657 _("push-2",  L2_VTR_PUSH_2)                     \
12658 _("pop-1",  L2_VTR_POP_1)                       \
12659 _("pop-2",  L2_VTR_POP_2)                       \
12660 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12661 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12662 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12663 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12664
12665 static int
12666 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12667 {
12668   unformat_input_t *i = vam->input;
12669   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12670   u32 sw_if_index;
12671   u8 sw_if_index_set = 0;
12672   u8 vtr_op_set = 0;
12673   u32 vtr_op = 0;
12674   u32 push_dot1q = 1;
12675   u32 tag1 = ~0;
12676   u32 tag2 = ~0;
12677   int ret;
12678
12679   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12680     {
12681       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12682         sw_if_index_set = 1;
12683       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12684         sw_if_index_set = 1;
12685       else if (unformat (i, "vtr_op %d", &vtr_op))
12686         vtr_op_set = 1;
12687 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12688       foreach_vtr_op
12689 #undef _
12690         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12691         ;
12692       else if (unformat (i, "tag1 %d", &tag1))
12693         ;
12694       else if (unformat (i, "tag2 %d", &tag2))
12695         ;
12696       else
12697         {
12698           clib_warning ("parse error '%U'", format_unformat_error, i);
12699           return -99;
12700         }
12701     }
12702
12703   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12704     {
12705       errmsg ("missing vtr operation or sw_if_index");
12706       return -99;
12707     }
12708
12709   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12710   mp->sw_if_index = ntohl (sw_if_index);
12711   mp->vtr_op = ntohl (vtr_op);
12712   mp->push_dot1q = ntohl (push_dot1q);
12713   mp->tag1 = ntohl (tag1);
12714   mp->tag2 = ntohl (tag2);
12715
12716   S (mp);
12717   W (ret);
12718   return ret;
12719 }
12720
12721 static int
12722 api_create_vhost_user_if (vat_main_t * vam)
12723 {
12724   unformat_input_t *i = vam->input;
12725   vl_api_create_vhost_user_if_t *mp;
12726   u8 *file_name;
12727   u8 is_server = 0;
12728   u8 file_name_set = 0;
12729   u32 custom_dev_instance = ~0;
12730   u8 hwaddr[6];
12731   u8 use_custom_mac = 0;
12732   u8 *tag = 0;
12733   int ret;
12734
12735   /* Shut up coverity */
12736   memset (hwaddr, 0, sizeof (hwaddr));
12737
12738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12739     {
12740       if (unformat (i, "socket %s", &file_name))
12741         {
12742           file_name_set = 1;
12743         }
12744       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12745         ;
12746       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12747         use_custom_mac = 1;
12748       else if (unformat (i, "server"))
12749         is_server = 1;
12750       else if (unformat (i, "tag %s", &tag))
12751         ;
12752       else
12753         break;
12754     }
12755
12756   if (file_name_set == 0)
12757     {
12758       errmsg ("missing socket file name");
12759       return -99;
12760     }
12761
12762   if (vec_len (file_name) > 255)
12763     {
12764       errmsg ("socket file name too long");
12765       return -99;
12766     }
12767   vec_add1 (file_name, 0);
12768
12769   M (CREATE_VHOST_USER_IF, mp);
12770
12771   mp->is_server = is_server;
12772   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12773   vec_free (file_name);
12774   if (custom_dev_instance != ~0)
12775     {
12776       mp->renumber = 1;
12777       mp->custom_dev_instance = ntohl (custom_dev_instance);
12778     }
12779   mp->use_custom_mac = use_custom_mac;
12780   clib_memcpy (mp->mac_address, hwaddr, 6);
12781   if (tag)
12782     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12783   vec_free (tag);
12784
12785   S (mp);
12786   W (ret);
12787   return ret;
12788 }
12789
12790 static int
12791 api_modify_vhost_user_if (vat_main_t * vam)
12792 {
12793   unformat_input_t *i = vam->input;
12794   vl_api_modify_vhost_user_if_t *mp;
12795   u8 *file_name;
12796   u8 is_server = 0;
12797   u8 file_name_set = 0;
12798   u32 custom_dev_instance = ~0;
12799   u8 sw_if_index_set = 0;
12800   u32 sw_if_index = (u32) ~ 0;
12801   int ret;
12802
12803   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12804     {
12805       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12806         sw_if_index_set = 1;
12807       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12808         sw_if_index_set = 1;
12809       else if (unformat (i, "socket %s", &file_name))
12810         {
12811           file_name_set = 1;
12812         }
12813       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12814         ;
12815       else if (unformat (i, "server"))
12816         is_server = 1;
12817       else
12818         break;
12819     }
12820
12821   if (sw_if_index_set == 0)
12822     {
12823       errmsg ("missing sw_if_index or interface name");
12824       return -99;
12825     }
12826
12827   if (file_name_set == 0)
12828     {
12829       errmsg ("missing socket file name");
12830       return -99;
12831     }
12832
12833   if (vec_len (file_name) > 255)
12834     {
12835       errmsg ("socket file name too long");
12836       return -99;
12837     }
12838   vec_add1 (file_name, 0);
12839
12840   M (MODIFY_VHOST_USER_IF, mp);
12841
12842   mp->sw_if_index = ntohl (sw_if_index);
12843   mp->is_server = is_server;
12844   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12845   vec_free (file_name);
12846   if (custom_dev_instance != ~0)
12847     {
12848       mp->renumber = 1;
12849       mp->custom_dev_instance = ntohl (custom_dev_instance);
12850     }
12851
12852   S (mp);
12853   W (ret);
12854   return ret;
12855 }
12856
12857 static int
12858 api_delete_vhost_user_if (vat_main_t * vam)
12859 {
12860   unformat_input_t *i = vam->input;
12861   vl_api_delete_vhost_user_if_t *mp;
12862   u32 sw_if_index = ~0;
12863   u8 sw_if_index_set = 0;
12864   int ret;
12865
12866   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12867     {
12868       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12869         sw_if_index_set = 1;
12870       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12871         sw_if_index_set = 1;
12872       else
12873         break;
12874     }
12875
12876   if (sw_if_index_set == 0)
12877     {
12878       errmsg ("missing sw_if_index or interface name");
12879       return -99;
12880     }
12881
12882
12883   M (DELETE_VHOST_USER_IF, mp);
12884
12885   mp->sw_if_index = ntohl (sw_if_index);
12886
12887   S (mp);
12888   W (ret);
12889   return ret;
12890 }
12891
12892 static void vl_api_sw_interface_vhost_user_details_t_handler
12893   (vl_api_sw_interface_vhost_user_details_t * mp)
12894 {
12895   vat_main_t *vam = &vat_main;
12896
12897   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12898          (char *) mp->interface_name,
12899          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12900          clib_net_to_host_u64 (mp->features), mp->is_server,
12901          ntohl (mp->num_regions), (char *) mp->sock_filename);
12902   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12903 }
12904
12905 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12906   (vl_api_sw_interface_vhost_user_details_t * mp)
12907 {
12908   vat_main_t *vam = &vat_main;
12909   vat_json_node_t *node = NULL;
12910
12911   if (VAT_JSON_ARRAY != vam->json_tree.type)
12912     {
12913       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12914       vat_json_init_array (&vam->json_tree);
12915     }
12916   node = vat_json_array_add (&vam->json_tree);
12917
12918   vat_json_init_object (node);
12919   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12920   vat_json_object_add_string_copy (node, "interface_name",
12921                                    mp->interface_name);
12922   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12923                             ntohl (mp->virtio_net_hdr_sz));
12924   vat_json_object_add_uint (node, "features",
12925                             clib_net_to_host_u64 (mp->features));
12926   vat_json_object_add_uint (node, "is_server", mp->is_server);
12927   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12928   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12929   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12930 }
12931
12932 static int
12933 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12934 {
12935   vl_api_sw_interface_vhost_user_dump_t *mp;
12936   vl_api_control_ping_t *mp_ping;
12937   int ret;
12938   print (vam->ofp,
12939          "Interface name            idx hdr_sz features server regions filename");
12940
12941   /* Get list of vhost-user interfaces */
12942   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12943   S (mp);
12944
12945   /* Use a control ping for synchronization */
12946   MPING (CONTROL_PING, mp_ping);
12947   S (mp_ping);
12948
12949   W (ret);
12950   return ret;
12951 }
12952
12953 static int
12954 api_show_version (vat_main_t * vam)
12955 {
12956   vl_api_show_version_t *mp;
12957   int ret;
12958
12959   M (SHOW_VERSION, mp);
12960
12961   S (mp);
12962   W (ret);
12963   return ret;
12964 }
12965
12966
12967 static int
12968 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12969 {
12970   unformat_input_t *line_input = vam->input;
12971   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12972   ip4_address_t local4, remote4;
12973   ip6_address_t local6, remote6;
12974   u8 is_add = 1;
12975   u8 ipv4_set = 0, ipv6_set = 0;
12976   u8 local_set = 0;
12977   u8 remote_set = 0;
12978   u8 grp_set = 0;
12979   u32 mcast_sw_if_index = ~0;
12980   u32 encap_vrf_id = 0;
12981   u32 decap_vrf_id = 0;
12982   u8 protocol = ~0;
12983   u32 vni;
12984   u8 vni_set = 0;
12985   int ret;
12986
12987   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12988   memset (&local4, 0, sizeof local4);
12989   memset (&remote4, 0, sizeof remote4);
12990   memset (&local6, 0, sizeof local6);
12991   memset (&remote6, 0, sizeof remote6);
12992
12993   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12994     {
12995       if (unformat (line_input, "del"))
12996         is_add = 0;
12997       else if (unformat (line_input, "local %U",
12998                          unformat_ip4_address, &local4))
12999         {
13000           local_set = 1;
13001           ipv4_set = 1;
13002         }
13003       else if (unformat (line_input, "remote %U",
13004                          unformat_ip4_address, &remote4))
13005         {
13006           remote_set = 1;
13007           ipv4_set = 1;
13008         }
13009       else if (unformat (line_input, "local %U",
13010                          unformat_ip6_address, &local6))
13011         {
13012           local_set = 1;
13013           ipv6_set = 1;
13014         }
13015       else if (unformat (line_input, "remote %U",
13016                          unformat_ip6_address, &remote6))
13017         {
13018           remote_set = 1;
13019           ipv6_set = 1;
13020         }
13021       else if (unformat (line_input, "group %U %U",
13022                          unformat_ip4_address, &remote4,
13023                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13024         {
13025           grp_set = remote_set = 1;
13026           ipv4_set = 1;
13027         }
13028       else if (unformat (line_input, "group %U",
13029                          unformat_ip4_address, &remote4))
13030         {
13031           grp_set = remote_set = 1;
13032           ipv4_set = 1;
13033         }
13034       else if (unformat (line_input, "group %U %U",
13035                          unformat_ip6_address, &remote6,
13036                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13037         {
13038           grp_set = remote_set = 1;
13039           ipv6_set = 1;
13040         }
13041       else if (unformat (line_input, "group %U",
13042                          unformat_ip6_address, &remote6))
13043         {
13044           grp_set = remote_set = 1;
13045           ipv6_set = 1;
13046         }
13047       else
13048         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13049         ;
13050       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13051         ;
13052       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13053         ;
13054       else if (unformat (line_input, "vni %d", &vni))
13055         vni_set = 1;
13056       else if (unformat (line_input, "next-ip4"))
13057         protocol = 1;
13058       else if (unformat (line_input, "next-ip6"))
13059         protocol = 2;
13060       else if (unformat (line_input, "next-ethernet"))
13061         protocol = 3;
13062       else if (unformat (line_input, "next-nsh"))
13063         protocol = 4;
13064       else
13065         {
13066           errmsg ("parse error '%U'", format_unformat_error, line_input);
13067           return -99;
13068         }
13069     }
13070
13071   if (local_set == 0)
13072     {
13073       errmsg ("tunnel local address not specified");
13074       return -99;
13075     }
13076   if (remote_set == 0)
13077     {
13078       errmsg ("tunnel remote address not specified");
13079       return -99;
13080     }
13081   if (grp_set && mcast_sw_if_index == ~0)
13082     {
13083       errmsg ("tunnel nonexistent multicast device");
13084       return -99;
13085     }
13086   if (ipv4_set && ipv6_set)
13087     {
13088       errmsg ("both IPv4 and IPv6 addresses specified");
13089       return -99;
13090     }
13091
13092   if (vni_set == 0)
13093     {
13094       errmsg ("vni not specified");
13095       return -99;
13096     }
13097
13098   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13099
13100
13101   if (ipv6_set)
13102     {
13103       clib_memcpy (&mp->local, &local6, sizeof (local6));
13104       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13105     }
13106   else
13107     {
13108       clib_memcpy (&mp->local, &local4, sizeof (local4));
13109       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13110     }
13111
13112   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13113   mp->encap_vrf_id = ntohl (encap_vrf_id);
13114   mp->decap_vrf_id = ntohl (decap_vrf_id);
13115   mp->protocol = protocol;
13116   mp->vni = ntohl (vni);
13117   mp->is_add = is_add;
13118   mp->is_ipv6 = ipv6_set;
13119
13120   S (mp);
13121   W (ret);
13122   return ret;
13123 }
13124
13125 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13126   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13127 {
13128   vat_main_t *vam = &vat_main;
13129   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13130   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13131
13132   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13133          ntohl (mp->sw_if_index),
13134          format_ip46_address, &local, IP46_TYPE_ANY,
13135          format_ip46_address, &remote, IP46_TYPE_ANY,
13136          ntohl (mp->vni), mp->protocol,
13137          ntohl (mp->mcast_sw_if_index),
13138          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13139 }
13140
13141
13142 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13143   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13144 {
13145   vat_main_t *vam = &vat_main;
13146   vat_json_node_t *node = NULL;
13147   struct in_addr ip4;
13148   struct in6_addr ip6;
13149
13150   if (VAT_JSON_ARRAY != vam->json_tree.type)
13151     {
13152       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13153       vat_json_init_array (&vam->json_tree);
13154     }
13155   node = vat_json_array_add (&vam->json_tree);
13156
13157   vat_json_init_object (node);
13158   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13159   if (mp->is_ipv6)
13160     {
13161       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13162       vat_json_object_add_ip6 (node, "local", ip6);
13163       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13164       vat_json_object_add_ip6 (node, "remote", ip6);
13165     }
13166   else
13167     {
13168       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13169       vat_json_object_add_ip4 (node, "local", ip4);
13170       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13171       vat_json_object_add_ip4 (node, "remote", ip4);
13172     }
13173   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13174   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13175   vat_json_object_add_uint (node, "mcast_sw_if_index",
13176                             ntohl (mp->mcast_sw_if_index));
13177   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13178   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13179   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13180 }
13181
13182 static int
13183 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13184 {
13185   unformat_input_t *i = vam->input;
13186   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13187   vl_api_control_ping_t *mp_ping;
13188   u32 sw_if_index;
13189   u8 sw_if_index_set = 0;
13190   int ret;
13191
13192   /* Parse args required to build the message */
13193   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13194     {
13195       if (unformat (i, "sw_if_index %d", &sw_if_index))
13196         sw_if_index_set = 1;
13197       else
13198         break;
13199     }
13200
13201   if (sw_if_index_set == 0)
13202     {
13203       sw_if_index = ~0;
13204     }
13205
13206   if (!vam->json_output)
13207     {
13208       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13209              "sw_if_index", "local", "remote", "vni",
13210              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13211     }
13212
13213   /* Get list of vxlan-tunnel interfaces */
13214   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13215
13216   mp->sw_if_index = htonl (sw_if_index);
13217
13218   S (mp);
13219
13220   /* Use a control ping for synchronization */
13221   MPING (CONTROL_PING, mp_ping);
13222   S (mp_ping);
13223
13224   W (ret);
13225   return ret;
13226 }
13227
13228
13229 u8 *
13230 format_l2_fib_mac_address (u8 * s, va_list * args)
13231 {
13232   u8 *a = va_arg (*args, u8 *);
13233
13234   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
13235                  a[2], a[3], a[4], a[5], a[6], a[7]);
13236 }
13237
13238 static void vl_api_l2_fib_table_details_t_handler
13239   (vl_api_l2_fib_table_details_t * mp)
13240 {
13241   vat_main_t *vam = &vat_main;
13242
13243   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13244          "       %d       %d     %d",
13245          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
13246          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13247          mp->bvi_mac);
13248 }
13249
13250 static void vl_api_l2_fib_table_details_t_handler_json
13251   (vl_api_l2_fib_table_details_t * mp)
13252 {
13253   vat_main_t *vam = &vat_main;
13254   vat_json_node_t *node = NULL;
13255
13256   if (VAT_JSON_ARRAY != vam->json_tree.type)
13257     {
13258       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13259       vat_json_init_array (&vam->json_tree);
13260     }
13261   node = vat_json_array_add (&vam->json_tree);
13262
13263   vat_json_init_object (node);
13264   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13265   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
13266   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13267   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13268   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13269   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13270 }
13271
13272 static int
13273 api_l2_fib_table_dump (vat_main_t * vam)
13274 {
13275   unformat_input_t *i = vam->input;
13276   vl_api_l2_fib_table_dump_t *mp;
13277   vl_api_control_ping_t *mp_ping;
13278   u32 bd_id;
13279   u8 bd_id_set = 0;
13280   int ret;
13281
13282   /* Parse args required to build the message */
13283   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13284     {
13285       if (unformat (i, "bd_id %d", &bd_id))
13286         bd_id_set = 1;
13287       else
13288         break;
13289     }
13290
13291   if (bd_id_set == 0)
13292     {
13293       errmsg ("missing bridge domain");
13294       return -99;
13295     }
13296
13297   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13298
13299   /* Get list of l2 fib entries */
13300   M (L2_FIB_TABLE_DUMP, mp);
13301
13302   mp->bd_id = ntohl (bd_id);
13303   S (mp);
13304
13305   /* Use a control ping for synchronization */
13306   MPING (CONTROL_PING, mp_ping);
13307   S (mp_ping);
13308
13309   W (ret);
13310   return ret;
13311 }
13312
13313
13314 static int
13315 api_interface_name_renumber (vat_main_t * vam)
13316 {
13317   unformat_input_t *line_input = vam->input;
13318   vl_api_interface_name_renumber_t *mp;
13319   u32 sw_if_index = ~0;
13320   u32 new_show_dev_instance = ~0;
13321   int ret;
13322
13323   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13324     {
13325       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13326                     &sw_if_index))
13327         ;
13328       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13329         ;
13330       else if (unformat (line_input, "new_show_dev_instance %d",
13331                          &new_show_dev_instance))
13332         ;
13333       else
13334         break;
13335     }
13336
13337   if (sw_if_index == ~0)
13338     {
13339       errmsg ("missing interface name or sw_if_index");
13340       return -99;
13341     }
13342
13343   if (new_show_dev_instance == ~0)
13344     {
13345       errmsg ("missing new_show_dev_instance");
13346       return -99;
13347     }
13348
13349   M (INTERFACE_NAME_RENUMBER, mp);
13350
13351   mp->sw_if_index = ntohl (sw_if_index);
13352   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13353
13354   S (mp);
13355   W (ret);
13356   return ret;
13357 }
13358
13359 static int
13360 api_want_ip4_arp_events (vat_main_t * vam)
13361 {
13362   unformat_input_t *line_input = vam->input;
13363   vl_api_want_ip4_arp_events_t *mp;
13364   ip4_address_t address;
13365   int address_set = 0;
13366   u32 enable_disable = 1;
13367   int ret;
13368
13369   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13370     {
13371       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
13372         address_set = 1;
13373       else if (unformat (line_input, "del"))
13374         enable_disable = 0;
13375       else
13376         break;
13377     }
13378
13379   if (address_set == 0)
13380     {
13381       errmsg ("missing addresses");
13382       return -99;
13383     }
13384
13385   M (WANT_IP4_ARP_EVENTS, mp);
13386   mp->enable_disable = enable_disable;
13387   mp->pid = htonl (getpid ());
13388   mp->address = address.as_u32;
13389
13390   S (mp);
13391   W (ret);
13392   return ret;
13393 }
13394
13395 static int
13396 api_want_ip6_nd_events (vat_main_t * vam)
13397 {
13398   unformat_input_t *line_input = vam->input;
13399   vl_api_want_ip6_nd_events_t *mp;
13400   ip6_address_t address;
13401   int address_set = 0;
13402   u32 enable_disable = 1;
13403   int ret;
13404
13405   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13406     {
13407       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
13408         address_set = 1;
13409       else if (unformat (line_input, "del"))
13410         enable_disable = 0;
13411       else
13412         break;
13413     }
13414
13415   if (address_set == 0)
13416     {
13417       errmsg ("missing addresses");
13418       return -99;
13419     }
13420
13421   M (WANT_IP6_ND_EVENTS, mp);
13422   mp->enable_disable = enable_disable;
13423   mp->pid = htonl (getpid ());
13424   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
13425
13426   S (mp);
13427   W (ret);
13428   return ret;
13429 }
13430
13431 static int
13432 api_want_l2_macs_events (vat_main_t * vam)
13433 {
13434   unformat_input_t *line_input = vam->input;
13435   vl_api_want_l2_macs_events_t *mp;
13436   u8 enable_disable = 1;
13437   u32 scan_delay = 0;
13438   u32 max_macs_in_event = 0;
13439   u32 learn_limit = 0;
13440   int ret;
13441
13442   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13443     {
13444       if (unformat (line_input, "learn-limit %d", &learn_limit))
13445         ;
13446       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13447         ;
13448       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13449         ;
13450       else if (unformat (line_input, "disable"))
13451         enable_disable = 0;
13452       else
13453         break;
13454     }
13455
13456   M (WANT_L2_MACS_EVENTS, mp);
13457   mp->enable_disable = enable_disable;
13458   mp->pid = htonl (getpid ());
13459   mp->learn_limit = htonl (learn_limit);
13460   mp->scan_delay = (u8) scan_delay;
13461   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13462   S (mp);
13463   W (ret);
13464   return ret;
13465 }
13466
13467 static int
13468 api_input_acl_set_interface (vat_main_t * vam)
13469 {
13470   unformat_input_t *i = vam->input;
13471   vl_api_input_acl_set_interface_t *mp;
13472   u32 sw_if_index;
13473   int sw_if_index_set;
13474   u32 ip4_table_index = ~0;
13475   u32 ip6_table_index = ~0;
13476   u32 l2_table_index = ~0;
13477   u8 is_add = 1;
13478   int ret;
13479
13480   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13481     {
13482       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13483         sw_if_index_set = 1;
13484       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13485         sw_if_index_set = 1;
13486       else if (unformat (i, "del"))
13487         is_add = 0;
13488       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13489         ;
13490       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13491         ;
13492       else if (unformat (i, "l2-table %d", &l2_table_index))
13493         ;
13494       else
13495         {
13496           clib_warning ("parse error '%U'", format_unformat_error, i);
13497           return -99;
13498         }
13499     }
13500
13501   if (sw_if_index_set == 0)
13502     {
13503       errmsg ("missing interface name or sw_if_index");
13504       return -99;
13505     }
13506
13507   M (INPUT_ACL_SET_INTERFACE, mp);
13508
13509   mp->sw_if_index = ntohl (sw_if_index);
13510   mp->ip4_table_index = ntohl (ip4_table_index);
13511   mp->ip6_table_index = ntohl (ip6_table_index);
13512   mp->l2_table_index = ntohl (l2_table_index);
13513   mp->is_add = is_add;
13514
13515   S (mp);
13516   W (ret);
13517   return ret;
13518 }
13519
13520 static int
13521 api_ip_address_dump (vat_main_t * vam)
13522 {
13523   unformat_input_t *i = vam->input;
13524   vl_api_ip_address_dump_t *mp;
13525   vl_api_control_ping_t *mp_ping;
13526   u32 sw_if_index = ~0;
13527   u8 sw_if_index_set = 0;
13528   u8 ipv4_set = 0;
13529   u8 ipv6_set = 0;
13530   int ret;
13531
13532   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13533     {
13534       if (unformat (i, "sw_if_index %d", &sw_if_index))
13535         sw_if_index_set = 1;
13536       else
13537         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13538         sw_if_index_set = 1;
13539       else if (unformat (i, "ipv4"))
13540         ipv4_set = 1;
13541       else if (unformat (i, "ipv6"))
13542         ipv6_set = 1;
13543       else
13544         break;
13545     }
13546
13547   if (ipv4_set && ipv6_set)
13548     {
13549       errmsg ("ipv4 and ipv6 flags cannot be both set");
13550       return -99;
13551     }
13552
13553   if ((!ipv4_set) && (!ipv6_set))
13554     {
13555       errmsg ("no ipv4 nor ipv6 flag set");
13556       return -99;
13557     }
13558
13559   if (sw_if_index_set == 0)
13560     {
13561       errmsg ("missing interface name or sw_if_index");
13562       return -99;
13563     }
13564
13565   vam->current_sw_if_index = sw_if_index;
13566   vam->is_ipv6 = ipv6_set;
13567
13568   M (IP_ADDRESS_DUMP, mp);
13569   mp->sw_if_index = ntohl (sw_if_index);
13570   mp->is_ipv6 = ipv6_set;
13571   S (mp);
13572
13573   /* Use a control ping for synchronization */
13574   MPING (CONTROL_PING, mp_ping);
13575   S (mp_ping);
13576
13577   W (ret);
13578   return ret;
13579 }
13580
13581 static int
13582 api_ip_dump (vat_main_t * vam)
13583 {
13584   vl_api_ip_dump_t *mp;
13585   vl_api_control_ping_t *mp_ping;
13586   unformat_input_t *in = vam->input;
13587   int ipv4_set = 0;
13588   int ipv6_set = 0;
13589   int is_ipv6;
13590   int i;
13591   int ret;
13592
13593   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13594     {
13595       if (unformat (in, "ipv4"))
13596         ipv4_set = 1;
13597       else if (unformat (in, "ipv6"))
13598         ipv6_set = 1;
13599       else
13600         break;
13601     }
13602
13603   if (ipv4_set && ipv6_set)
13604     {
13605       errmsg ("ipv4 and ipv6 flags cannot be both set");
13606       return -99;
13607     }
13608
13609   if ((!ipv4_set) && (!ipv6_set))
13610     {
13611       errmsg ("no ipv4 nor ipv6 flag set");
13612       return -99;
13613     }
13614
13615   is_ipv6 = ipv6_set;
13616   vam->is_ipv6 = is_ipv6;
13617
13618   /* free old data */
13619   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13620     {
13621       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13622     }
13623   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13624
13625   M (IP_DUMP, mp);
13626   mp->is_ipv6 = ipv6_set;
13627   S (mp);
13628
13629   /* Use a control ping for synchronization */
13630   MPING (CONTROL_PING, mp_ping);
13631   S (mp_ping);
13632
13633   W (ret);
13634   return ret;
13635 }
13636
13637 static int
13638 api_ipsec_spd_add_del (vat_main_t * vam)
13639 {
13640   unformat_input_t *i = vam->input;
13641   vl_api_ipsec_spd_add_del_t *mp;
13642   u32 spd_id = ~0;
13643   u8 is_add = 1;
13644   int ret;
13645
13646   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13647     {
13648       if (unformat (i, "spd_id %d", &spd_id))
13649         ;
13650       else if (unformat (i, "del"))
13651         is_add = 0;
13652       else
13653         {
13654           clib_warning ("parse error '%U'", format_unformat_error, i);
13655           return -99;
13656         }
13657     }
13658   if (spd_id == ~0)
13659     {
13660       errmsg ("spd_id must be set");
13661       return -99;
13662     }
13663
13664   M (IPSEC_SPD_ADD_DEL, mp);
13665
13666   mp->spd_id = ntohl (spd_id);
13667   mp->is_add = is_add;
13668
13669   S (mp);
13670   W (ret);
13671   return ret;
13672 }
13673
13674 static int
13675 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13676 {
13677   unformat_input_t *i = vam->input;
13678   vl_api_ipsec_interface_add_del_spd_t *mp;
13679   u32 sw_if_index;
13680   u8 sw_if_index_set = 0;
13681   u32 spd_id = (u32) ~ 0;
13682   u8 is_add = 1;
13683   int ret;
13684
13685   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13686     {
13687       if (unformat (i, "del"))
13688         is_add = 0;
13689       else if (unformat (i, "spd_id %d", &spd_id))
13690         ;
13691       else
13692         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13693         sw_if_index_set = 1;
13694       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13695         sw_if_index_set = 1;
13696       else
13697         {
13698           clib_warning ("parse error '%U'", format_unformat_error, i);
13699           return -99;
13700         }
13701
13702     }
13703
13704   if (spd_id == (u32) ~ 0)
13705     {
13706       errmsg ("spd_id must be set");
13707       return -99;
13708     }
13709
13710   if (sw_if_index_set == 0)
13711     {
13712       errmsg ("missing interface name or sw_if_index");
13713       return -99;
13714     }
13715
13716   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13717
13718   mp->spd_id = ntohl (spd_id);
13719   mp->sw_if_index = ntohl (sw_if_index);
13720   mp->is_add = is_add;
13721
13722   S (mp);
13723   W (ret);
13724   return ret;
13725 }
13726
13727 static int
13728 api_ipsec_spd_add_del_entry (vat_main_t * vam)
13729 {
13730   unformat_input_t *i = vam->input;
13731   vl_api_ipsec_spd_add_del_entry_t *mp;
13732   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
13733   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13734   i32 priority = 0;
13735   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13736   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13737   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
13738   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
13739   int ret;
13740
13741   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
13742   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
13743   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
13744   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
13745   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
13746   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
13747
13748   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13749     {
13750       if (unformat (i, "del"))
13751         is_add = 0;
13752       if (unformat (i, "outbound"))
13753         is_outbound = 1;
13754       if (unformat (i, "inbound"))
13755         is_outbound = 0;
13756       else if (unformat (i, "spd_id %d", &spd_id))
13757         ;
13758       else if (unformat (i, "sa_id %d", &sa_id))
13759         ;
13760       else if (unformat (i, "priority %d", &priority))
13761         ;
13762       else if (unformat (i, "protocol %d", &protocol))
13763         ;
13764       else if (unformat (i, "lport_start %d", &lport_start))
13765         ;
13766       else if (unformat (i, "lport_stop %d", &lport_stop))
13767         ;
13768       else if (unformat (i, "rport_start %d", &rport_start))
13769         ;
13770       else if (unformat (i, "rport_stop %d", &rport_stop))
13771         ;
13772       else
13773         if (unformat
13774             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
13775         {
13776           is_ipv6 = 0;
13777           is_ip_any = 0;
13778         }
13779       else
13780         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
13781         {
13782           is_ipv6 = 0;
13783           is_ip_any = 0;
13784         }
13785       else
13786         if (unformat
13787             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
13788         {
13789           is_ipv6 = 0;
13790           is_ip_any = 0;
13791         }
13792       else
13793         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
13794         {
13795           is_ipv6 = 0;
13796           is_ip_any = 0;
13797         }
13798       else
13799         if (unformat
13800             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
13801         {
13802           is_ipv6 = 1;
13803           is_ip_any = 0;
13804         }
13805       else
13806         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
13807         {
13808           is_ipv6 = 1;
13809           is_ip_any = 0;
13810         }
13811       else
13812         if (unformat
13813             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
13814         {
13815           is_ipv6 = 1;
13816           is_ip_any = 0;
13817         }
13818       else
13819         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
13820         {
13821           is_ipv6 = 1;
13822           is_ip_any = 0;
13823         }
13824       else
13825         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13826         {
13827           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13828             {
13829               clib_warning ("unsupported action: 'resolve'");
13830               return -99;
13831             }
13832         }
13833       else
13834         {
13835           clib_warning ("parse error '%U'", format_unformat_error, i);
13836           return -99;
13837         }
13838
13839     }
13840
13841   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
13842
13843   mp->spd_id = ntohl (spd_id);
13844   mp->priority = ntohl (priority);
13845   mp->is_outbound = is_outbound;
13846
13847   mp->is_ipv6 = is_ipv6;
13848   if (is_ipv6 || is_ip_any)
13849     {
13850       clib_memcpy (mp->remote_address_start, &raddr6_start,
13851                    sizeof (ip6_address_t));
13852       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
13853                    sizeof (ip6_address_t));
13854       clib_memcpy (mp->local_address_start, &laddr6_start,
13855                    sizeof (ip6_address_t));
13856       clib_memcpy (mp->local_address_stop, &laddr6_stop,
13857                    sizeof (ip6_address_t));
13858     }
13859   else
13860     {
13861       clib_memcpy (mp->remote_address_start, &raddr4_start,
13862                    sizeof (ip4_address_t));
13863       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
13864                    sizeof (ip4_address_t));
13865       clib_memcpy (mp->local_address_start, &laddr4_start,
13866                    sizeof (ip4_address_t));
13867       clib_memcpy (mp->local_address_stop, &laddr4_stop,
13868                    sizeof (ip4_address_t));
13869     }
13870   mp->protocol = (u8) protocol;
13871   mp->local_port_start = ntohs ((u16) lport_start);
13872   mp->local_port_stop = ntohs ((u16) lport_stop);
13873   mp->remote_port_start = ntohs ((u16) rport_start);
13874   mp->remote_port_stop = ntohs ((u16) rport_stop);
13875   mp->policy = (u8) policy;
13876   mp->sa_id = ntohl (sa_id);
13877   mp->is_add = is_add;
13878   mp->is_ip_any = is_ip_any;
13879   S (mp);
13880   W (ret);
13881   return ret;
13882 }
13883
13884 static int
13885 api_ipsec_sad_add_del_entry (vat_main_t * vam)
13886 {
13887   unformat_input_t *i = vam->input;
13888   vl_api_ipsec_sad_add_del_entry_t *mp;
13889   u32 sad_id = 0, spi = 0;
13890   u8 *ck = 0, *ik = 0;
13891   u8 is_add = 1;
13892
13893   u8 protocol = IPSEC_PROTOCOL_AH;
13894   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
13895   u32 crypto_alg = 0, integ_alg = 0;
13896   ip4_address_t tun_src4;
13897   ip4_address_t tun_dst4;
13898   ip6_address_t tun_src6;
13899   ip6_address_t tun_dst6;
13900   int ret;
13901
13902   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13903     {
13904       if (unformat (i, "del"))
13905         is_add = 0;
13906       else if (unformat (i, "sad_id %d", &sad_id))
13907         ;
13908       else if (unformat (i, "spi %d", &spi))
13909         ;
13910       else if (unformat (i, "esp"))
13911         protocol = IPSEC_PROTOCOL_ESP;
13912       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
13913         {
13914           is_tunnel = 1;
13915           is_tunnel_ipv6 = 0;
13916         }
13917       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
13918         {
13919           is_tunnel = 1;
13920           is_tunnel_ipv6 = 0;
13921         }
13922       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
13923         {
13924           is_tunnel = 1;
13925           is_tunnel_ipv6 = 1;
13926         }
13927       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
13928         {
13929           is_tunnel = 1;
13930           is_tunnel_ipv6 = 1;
13931         }
13932       else
13933         if (unformat
13934             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
13935         {
13936           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
13937               crypto_alg >= IPSEC_CRYPTO_N_ALG)
13938             {
13939               clib_warning ("unsupported crypto-alg: '%U'",
13940                             format_ipsec_crypto_alg, crypto_alg);
13941               return -99;
13942             }
13943         }
13944       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13945         ;
13946       else
13947         if (unformat
13948             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
13949         {
13950           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
13951               integ_alg >= IPSEC_INTEG_N_ALG)
13952             {
13953               clib_warning ("unsupported integ-alg: '%U'",
13954                             format_ipsec_integ_alg, integ_alg);
13955               return -99;
13956             }
13957         }
13958       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13959         ;
13960       else
13961         {
13962           clib_warning ("parse error '%U'", format_unformat_error, i);
13963           return -99;
13964         }
13965
13966     }
13967
13968   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
13969
13970   mp->sad_id = ntohl (sad_id);
13971   mp->is_add = is_add;
13972   mp->protocol = protocol;
13973   mp->spi = ntohl (spi);
13974   mp->is_tunnel = is_tunnel;
13975   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
13976   mp->crypto_algorithm = crypto_alg;
13977   mp->integrity_algorithm = integ_alg;
13978   mp->crypto_key_length = vec_len (ck);
13979   mp->integrity_key_length = vec_len (ik);
13980
13981   if (mp->crypto_key_length > sizeof (mp->crypto_key))
13982     mp->crypto_key_length = sizeof (mp->crypto_key);
13983
13984   if (mp->integrity_key_length > sizeof (mp->integrity_key))
13985     mp->integrity_key_length = sizeof (mp->integrity_key);
13986
13987   if (ck)
13988     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
13989   if (ik)
13990     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
13991
13992   if (is_tunnel)
13993     {
13994       if (is_tunnel_ipv6)
13995         {
13996           clib_memcpy (mp->tunnel_src_address, &tun_src6,
13997                        sizeof (ip6_address_t));
13998           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
13999                        sizeof (ip6_address_t));
14000         }
14001       else
14002         {
14003           clib_memcpy (mp->tunnel_src_address, &tun_src4,
14004                        sizeof (ip4_address_t));
14005           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
14006                        sizeof (ip4_address_t));
14007         }
14008     }
14009
14010   S (mp);
14011   W (ret);
14012   return ret;
14013 }
14014
14015 static int
14016 api_ipsec_sa_set_key (vat_main_t * vam)
14017 {
14018   unformat_input_t *i = vam->input;
14019   vl_api_ipsec_sa_set_key_t *mp;
14020   u32 sa_id;
14021   u8 *ck = 0, *ik = 0;
14022   int ret;
14023
14024   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14025     {
14026       if (unformat (i, "sa_id %d", &sa_id))
14027         ;
14028       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14029         ;
14030       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14031         ;
14032       else
14033         {
14034           clib_warning ("parse error '%U'", format_unformat_error, i);
14035           return -99;
14036         }
14037     }
14038
14039   M (IPSEC_SA_SET_KEY, mp);
14040
14041   mp->sa_id = ntohl (sa_id);
14042   mp->crypto_key_length = vec_len (ck);
14043   mp->integrity_key_length = vec_len (ik);
14044
14045   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14046     mp->crypto_key_length = sizeof (mp->crypto_key);
14047
14048   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14049     mp->integrity_key_length = sizeof (mp->integrity_key);
14050
14051   if (ck)
14052     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14053   if (ik)
14054     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14055
14056   S (mp);
14057   W (ret);
14058   return ret;
14059 }
14060
14061 static int
14062 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14063 {
14064   unformat_input_t *i = vam->input;
14065   vl_api_ipsec_tunnel_if_add_del_t *mp;
14066   u32 local_spi = 0, remote_spi = 0;
14067   u32 crypto_alg = 0, integ_alg = 0;
14068   u8 *lck = NULL, *rck = NULL;
14069   u8 *lik = NULL, *rik = NULL;
14070   ip4_address_t local_ip = { {0} };
14071   ip4_address_t remote_ip = { {0} };
14072   u8 is_add = 1;
14073   u8 esn = 0;
14074   u8 anti_replay = 0;
14075   int ret;
14076
14077   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14078     {
14079       if (unformat (i, "del"))
14080         is_add = 0;
14081       else if (unformat (i, "esn"))
14082         esn = 1;
14083       else if (unformat (i, "anti_replay"))
14084         anti_replay = 1;
14085       else if (unformat (i, "local_spi %d", &local_spi))
14086         ;
14087       else if (unformat (i, "remote_spi %d", &remote_spi))
14088         ;
14089       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
14090         ;
14091       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
14092         ;
14093       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14094         ;
14095       else
14096         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14097         ;
14098       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14099         ;
14100       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14101         ;
14102       else
14103         if (unformat
14104             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14105         {
14106           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14107               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14108             {
14109               errmsg ("unsupported crypto-alg: '%U'\n",
14110                       format_ipsec_crypto_alg, crypto_alg);
14111               return -99;
14112             }
14113         }
14114       else
14115         if (unformat
14116             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14117         {
14118           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14119               integ_alg >= IPSEC_INTEG_N_ALG)
14120             {
14121               errmsg ("unsupported integ-alg: '%U'\n",
14122                       format_ipsec_integ_alg, integ_alg);
14123               return -99;
14124             }
14125         }
14126       else
14127         {
14128           errmsg ("parse error '%U'\n", format_unformat_error, i);
14129           return -99;
14130         }
14131     }
14132
14133   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14134
14135   mp->is_add = is_add;
14136   mp->esn = esn;
14137   mp->anti_replay = anti_replay;
14138
14139   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
14140   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
14141
14142   mp->local_spi = htonl (local_spi);
14143   mp->remote_spi = htonl (remote_spi);
14144   mp->crypto_alg = (u8) crypto_alg;
14145
14146   mp->local_crypto_key_len = 0;
14147   if (lck)
14148     {
14149       mp->local_crypto_key_len = vec_len (lck);
14150       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14151         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14152       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14153     }
14154
14155   mp->remote_crypto_key_len = 0;
14156   if (rck)
14157     {
14158       mp->remote_crypto_key_len = vec_len (rck);
14159       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14160         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14161       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14162     }
14163
14164   mp->integ_alg = (u8) integ_alg;
14165
14166   mp->local_integ_key_len = 0;
14167   if (lik)
14168     {
14169       mp->local_integ_key_len = vec_len (lik);
14170       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14171         mp->local_integ_key_len = sizeof (mp->local_integ_key);
14172       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14173     }
14174
14175   mp->remote_integ_key_len = 0;
14176   if (rik)
14177     {
14178       mp->remote_integ_key_len = vec_len (rik);
14179       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14180         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14181       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14182     }
14183
14184   S (mp);
14185   W (ret);
14186   return ret;
14187 }
14188
14189 static void
14190 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14191 {
14192   vat_main_t *vam = &vat_main;
14193
14194   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14195          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
14196          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
14197          "tunnel_src_addr %U tunnel_dst_addr %U "
14198          "salt %u seq_outbound %lu last_seq_inbound %lu "
14199          "replay_window %lu total_data_size %lu\n",
14200          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
14201          mp->protocol,
14202          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
14203          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
14204          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
14205          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14206          mp->tunnel_src_addr,
14207          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14208          mp->tunnel_dst_addr,
14209          ntohl (mp->salt),
14210          clib_net_to_host_u64 (mp->seq_outbound),
14211          clib_net_to_host_u64 (mp->last_seq_inbound),
14212          clib_net_to_host_u64 (mp->replay_window),
14213          clib_net_to_host_u64 (mp->total_data_size));
14214 }
14215
14216 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14217 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14218
14219 static void vl_api_ipsec_sa_details_t_handler_json
14220   (vl_api_ipsec_sa_details_t * mp)
14221 {
14222   vat_main_t *vam = &vat_main;
14223   vat_json_node_t *node = NULL;
14224   struct in_addr src_ip4, dst_ip4;
14225   struct in6_addr src_ip6, dst_ip6;
14226
14227   if (VAT_JSON_ARRAY != vam->json_tree.type)
14228     {
14229       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14230       vat_json_init_array (&vam->json_tree);
14231     }
14232   node = vat_json_array_add (&vam->json_tree);
14233
14234   vat_json_init_object (node);
14235   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
14236   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14237   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
14238   vat_json_object_add_uint (node, "proto", mp->protocol);
14239   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
14240   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
14241   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
14242   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
14243   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
14244   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
14245   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
14246                              mp->crypto_key_len);
14247   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
14248                              mp->integ_key_len);
14249   if (mp->is_tunnel_ip6)
14250     {
14251       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
14252       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
14253       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
14254       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
14255     }
14256   else
14257     {
14258       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
14259       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
14260       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
14261       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
14262     }
14263   vat_json_object_add_uint (node, "replay_window",
14264                             clib_net_to_host_u64 (mp->replay_window));
14265   vat_json_object_add_uint (node, "total_data_size",
14266                             clib_net_to_host_u64 (mp->total_data_size));
14267
14268 }
14269
14270 static int
14271 api_ipsec_sa_dump (vat_main_t * vam)
14272 {
14273   unformat_input_t *i = vam->input;
14274   vl_api_ipsec_sa_dump_t *mp;
14275   vl_api_control_ping_t *mp_ping;
14276   u32 sa_id = ~0;
14277   int ret;
14278
14279   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14280     {
14281       if (unformat (i, "sa_id %d", &sa_id))
14282         ;
14283       else
14284         {
14285           clib_warning ("parse error '%U'", format_unformat_error, i);
14286           return -99;
14287         }
14288     }
14289
14290   M (IPSEC_SA_DUMP, mp);
14291
14292   mp->sa_id = ntohl (sa_id);
14293
14294   S (mp);
14295
14296   /* Use a control ping for synchronization */
14297   M (CONTROL_PING, mp_ping);
14298   S (mp_ping);
14299
14300   W (ret);
14301   return ret;
14302 }
14303
14304 static int
14305 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
14306 {
14307   unformat_input_t *i = vam->input;
14308   vl_api_ipsec_tunnel_if_set_key_t *mp;
14309   u32 sw_if_index = ~0;
14310   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
14311   u8 *key = 0;
14312   u32 alg = ~0;
14313   int ret;
14314
14315   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14316     {
14317       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14318         ;
14319       else
14320         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
14321         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
14322       else
14323         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
14324         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
14325       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
14326         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
14327       else
14328         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
14329         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
14330       else if (unformat (i, "%U", unformat_hex_string, &key))
14331         ;
14332       else
14333         {
14334           clib_warning ("parse error '%U'", format_unformat_error, i);
14335           return -99;
14336         }
14337     }
14338
14339   if (sw_if_index == ~0)
14340     {
14341       errmsg ("interface must be specified");
14342       return -99;
14343     }
14344
14345   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
14346     {
14347       errmsg ("key type must be specified");
14348       return -99;
14349     }
14350
14351   if (alg == ~0)
14352     {
14353       errmsg ("algorithm must be specified");
14354       return -99;
14355     }
14356
14357   if (vec_len (key) == 0)
14358     {
14359       errmsg ("key must be specified");
14360       return -99;
14361     }
14362
14363   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
14364
14365   mp->sw_if_index = htonl (sw_if_index);
14366   mp->alg = alg;
14367   mp->key_type = key_type;
14368   mp->key_len = vec_len (key);
14369   clib_memcpy (mp->key, key, vec_len (key));
14370
14371   S (mp);
14372   W (ret);
14373
14374   return ret;
14375 }
14376
14377 static int
14378 api_ikev2_profile_add_del (vat_main_t * vam)
14379 {
14380   unformat_input_t *i = vam->input;
14381   vl_api_ikev2_profile_add_del_t *mp;
14382   u8 is_add = 1;
14383   u8 *name = 0;
14384   int ret;
14385
14386   const char *valid_chars = "a-zA-Z0-9_";
14387
14388   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14389     {
14390       if (unformat (i, "del"))
14391         is_add = 0;
14392       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14393         vec_add1 (name, 0);
14394       else
14395         {
14396           errmsg ("parse error '%U'", format_unformat_error, i);
14397           return -99;
14398         }
14399     }
14400
14401   if (!vec_len (name))
14402     {
14403       errmsg ("profile name must be specified");
14404       return -99;
14405     }
14406
14407   if (vec_len (name) > 64)
14408     {
14409       errmsg ("profile name too long");
14410       return -99;
14411     }
14412
14413   M (IKEV2_PROFILE_ADD_DEL, mp);
14414
14415   clib_memcpy (mp->name, name, vec_len (name));
14416   mp->is_add = is_add;
14417   vec_free (name);
14418
14419   S (mp);
14420   W (ret);
14421   return ret;
14422 }
14423
14424 static int
14425 api_ikev2_profile_set_auth (vat_main_t * vam)
14426 {
14427   unformat_input_t *i = vam->input;
14428   vl_api_ikev2_profile_set_auth_t *mp;
14429   u8 *name = 0;
14430   u8 *data = 0;
14431   u32 auth_method = 0;
14432   u8 is_hex = 0;
14433   int ret;
14434
14435   const char *valid_chars = "a-zA-Z0-9_";
14436
14437   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14438     {
14439       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14440         vec_add1 (name, 0);
14441       else if (unformat (i, "auth_method %U",
14442                          unformat_ikev2_auth_method, &auth_method))
14443         ;
14444       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
14445         is_hex = 1;
14446       else if (unformat (i, "auth_data %v", &data))
14447         ;
14448       else
14449         {
14450           errmsg ("parse error '%U'", format_unformat_error, i);
14451           return -99;
14452         }
14453     }
14454
14455   if (!vec_len (name))
14456     {
14457       errmsg ("profile name must be specified");
14458       return -99;
14459     }
14460
14461   if (vec_len (name) > 64)
14462     {
14463       errmsg ("profile name too long");
14464       return -99;
14465     }
14466
14467   if (!vec_len (data))
14468     {
14469       errmsg ("auth_data must be specified");
14470       return -99;
14471     }
14472
14473   if (!auth_method)
14474     {
14475       errmsg ("auth_method must be specified");
14476       return -99;
14477     }
14478
14479   M (IKEV2_PROFILE_SET_AUTH, mp);
14480
14481   mp->is_hex = is_hex;
14482   mp->auth_method = (u8) auth_method;
14483   mp->data_len = vec_len (data);
14484   clib_memcpy (mp->name, name, vec_len (name));
14485   clib_memcpy (mp->data, data, vec_len (data));
14486   vec_free (name);
14487   vec_free (data);
14488
14489   S (mp);
14490   W (ret);
14491   return ret;
14492 }
14493
14494 static int
14495 api_ikev2_profile_set_id (vat_main_t * vam)
14496 {
14497   unformat_input_t *i = vam->input;
14498   vl_api_ikev2_profile_set_id_t *mp;
14499   u8 *name = 0;
14500   u8 *data = 0;
14501   u8 is_local = 0;
14502   u32 id_type = 0;
14503   ip4_address_t ip4;
14504   int ret;
14505
14506   const char *valid_chars = "a-zA-Z0-9_";
14507
14508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14509     {
14510       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14511         vec_add1 (name, 0);
14512       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
14513         ;
14514       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
14515         {
14516           data = vec_new (u8, 4);
14517           clib_memcpy (data, ip4.as_u8, 4);
14518         }
14519       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
14520         ;
14521       else if (unformat (i, "id_data %v", &data))
14522         ;
14523       else if (unformat (i, "local"))
14524         is_local = 1;
14525       else if (unformat (i, "remote"))
14526         is_local = 0;
14527       else
14528         {
14529           errmsg ("parse error '%U'", format_unformat_error, i);
14530           return -99;
14531         }
14532     }
14533
14534   if (!vec_len (name))
14535     {
14536       errmsg ("profile name must be specified");
14537       return -99;
14538     }
14539
14540   if (vec_len (name) > 64)
14541     {
14542       errmsg ("profile name too long");
14543       return -99;
14544     }
14545
14546   if (!vec_len (data))
14547     {
14548       errmsg ("id_data must be specified");
14549       return -99;
14550     }
14551
14552   if (!id_type)
14553     {
14554       errmsg ("id_type must be specified");
14555       return -99;
14556     }
14557
14558   M (IKEV2_PROFILE_SET_ID, mp);
14559
14560   mp->is_local = is_local;
14561   mp->id_type = (u8) id_type;
14562   mp->data_len = vec_len (data);
14563   clib_memcpy (mp->name, name, vec_len (name));
14564   clib_memcpy (mp->data, data, vec_len (data));
14565   vec_free (name);
14566   vec_free (data);
14567
14568   S (mp);
14569   W (ret);
14570   return ret;
14571 }
14572
14573 static int
14574 api_ikev2_profile_set_ts (vat_main_t * vam)
14575 {
14576   unformat_input_t *i = vam->input;
14577   vl_api_ikev2_profile_set_ts_t *mp;
14578   u8 *name = 0;
14579   u8 is_local = 0;
14580   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
14581   ip4_address_t start_addr, end_addr;
14582
14583   const char *valid_chars = "a-zA-Z0-9_";
14584   int ret;
14585
14586   start_addr.as_u32 = 0;
14587   end_addr.as_u32 = (u32) ~ 0;
14588
14589   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14590     {
14591       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14592         vec_add1 (name, 0);
14593       else if (unformat (i, "protocol %d", &proto))
14594         ;
14595       else if (unformat (i, "start_port %d", &start_port))
14596         ;
14597       else if (unformat (i, "end_port %d", &end_port))
14598         ;
14599       else
14600         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
14601         ;
14602       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
14603         ;
14604       else if (unformat (i, "local"))
14605         is_local = 1;
14606       else if (unformat (i, "remote"))
14607         is_local = 0;
14608       else
14609         {
14610           errmsg ("parse error '%U'", format_unformat_error, i);
14611           return -99;
14612         }
14613     }
14614
14615   if (!vec_len (name))
14616     {
14617       errmsg ("profile name must be specified");
14618       return -99;
14619     }
14620
14621   if (vec_len (name) > 64)
14622     {
14623       errmsg ("profile name too long");
14624       return -99;
14625     }
14626
14627   M (IKEV2_PROFILE_SET_TS, mp);
14628
14629   mp->is_local = is_local;
14630   mp->proto = (u8) proto;
14631   mp->start_port = (u16) start_port;
14632   mp->end_port = (u16) end_port;
14633   mp->start_addr = start_addr.as_u32;
14634   mp->end_addr = end_addr.as_u32;
14635   clib_memcpy (mp->name, name, vec_len (name));
14636   vec_free (name);
14637
14638   S (mp);
14639   W (ret);
14640   return ret;
14641 }
14642
14643 static int
14644 api_ikev2_set_local_key (vat_main_t * vam)
14645 {
14646   unformat_input_t *i = vam->input;
14647   vl_api_ikev2_set_local_key_t *mp;
14648   u8 *file = 0;
14649   int ret;
14650
14651   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14652     {
14653       if (unformat (i, "file %v", &file))
14654         vec_add1 (file, 0);
14655       else
14656         {
14657           errmsg ("parse error '%U'", format_unformat_error, i);
14658           return -99;
14659         }
14660     }
14661
14662   if (!vec_len (file))
14663     {
14664       errmsg ("RSA key file must be specified");
14665       return -99;
14666     }
14667
14668   if (vec_len (file) > 256)
14669     {
14670       errmsg ("file name too long");
14671       return -99;
14672     }
14673
14674   M (IKEV2_SET_LOCAL_KEY, mp);
14675
14676   clib_memcpy (mp->key_file, file, vec_len (file));
14677   vec_free (file);
14678
14679   S (mp);
14680   W (ret);
14681   return ret;
14682 }
14683
14684 static int
14685 api_ikev2_set_responder (vat_main_t * vam)
14686 {
14687   unformat_input_t *i = vam->input;
14688   vl_api_ikev2_set_responder_t *mp;
14689   int ret;
14690   u8 *name = 0;
14691   u32 sw_if_index = ~0;
14692   ip4_address_t address;
14693
14694   const char *valid_chars = "a-zA-Z0-9_";
14695
14696   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14697     {
14698       if (unformat
14699           (i, "%U interface %d address %U", unformat_token, valid_chars,
14700            &name, &sw_if_index, unformat_ip4_address, &address))
14701         vec_add1 (name, 0);
14702       else
14703         {
14704           errmsg ("parse error '%U'", format_unformat_error, i);
14705           return -99;
14706         }
14707     }
14708
14709   if (!vec_len (name))
14710     {
14711       errmsg ("profile name must be specified");
14712       return -99;
14713     }
14714
14715   if (vec_len (name) > 64)
14716     {
14717       errmsg ("profile name too long");
14718       return -99;
14719     }
14720
14721   M (IKEV2_SET_RESPONDER, mp);
14722
14723   clib_memcpy (mp->name, name, vec_len (name));
14724   vec_free (name);
14725
14726   mp->sw_if_index = sw_if_index;
14727   clib_memcpy (mp->address, &address, sizeof (address));
14728
14729   S (mp);
14730   W (ret);
14731   return ret;
14732 }
14733
14734 static int
14735 api_ikev2_set_ike_transforms (vat_main_t * vam)
14736 {
14737   unformat_input_t *i = vam->input;
14738   vl_api_ikev2_set_ike_transforms_t *mp;
14739   int ret;
14740   u8 *name = 0;
14741   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
14742
14743   const char *valid_chars = "a-zA-Z0-9_";
14744
14745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14746     {
14747       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
14748                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
14749         vec_add1 (name, 0);
14750       else
14751         {
14752           errmsg ("parse error '%U'", format_unformat_error, i);
14753           return -99;
14754         }
14755     }
14756
14757   if (!vec_len (name))
14758     {
14759       errmsg ("profile name must be specified");
14760       return -99;
14761     }
14762
14763   if (vec_len (name) > 64)
14764     {
14765       errmsg ("profile name too long");
14766       return -99;
14767     }
14768
14769   M (IKEV2_SET_IKE_TRANSFORMS, mp);
14770
14771   clib_memcpy (mp->name, name, vec_len (name));
14772   vec_free (name);
14773   mp->crypto_alg = crypto_alg;
14774   mp->crypto_key_size = crypto_key_size;
14775   mp->integ_alg = integ_alg;
14776   mp->dh_group = dh_group;
14777
14778   S (mp);
14779   W (ret);
14780   return ret;
14781 }
14782
14783
14784 static int
14785 api_ikev2_set_esp_transforms (vat_main_t * vam)
14786 {
14787   unformat_input_t *i = vam->input;
14788   vl_api_ikev2_set_esp_transforms_t *mp;
14789   int ret;
14790   u8 *name = 0;
14791   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
14792
14793   const char *valid_chars = "a-zA-Z0-9_";
14794
14795   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14796     {
14797       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
14798                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
14799         vec_add1 (name, 0);
14800       else
14801         {
14802           errmsg ("parse error '%U'", format_unformat_error, i);
14803           return -99;
14804         }
14805     }
14806
14807   if (!vec_len (name))
14808     {
14809       errmsg ("profile name must be specified");
14810       return -99;
14811     }
14812
14813   if (vec_len (name) > 64)
14814     {
14815       errmsg ("profile name too long");
14816       return -99;
14817     }
14818
14819   M (IKEV2_SET_ESP_TRANSFORMS, mp);
14820
14821   clib_memcpy (mp->name, name, vec_len (name));
14822   vec_free (name);
14823   mp->crypto_alg = crypto_alg;
14824   mp->crypto_key_size = crypto_key_size;
14825   mp->integ_alg = integ_alg;
14826   mp->dh_group = dh_group;
14827
14828   S (mp);
14829   W (ret);
14830   return ret;
14831 }
14832
14833 static int
14834 api_ikev2_set_sa_lifetime (vat_main_t * vam)
14835 {
14836   unformat_input_t *i = vam->input;
14837   vl_api_ikev2_set_sa_lifetime_t *mp;
14838   int ret;
14839   u8 *name = 0;
14840   u64 lifetime, lifetime_maxdata;
14841   u32 lifetime_jitter, handover;
14842
14843   const char *valid_chars = "a-zA-Z0-9_";
14844
14845   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14846     {
14847       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
14848                     &lifetime, &lifetime_jitter, &handover,
14849                     &lifetime_maxdata))
14850         vec_add1 (name, 0);
14851       else
14852         {
14853           errmsg ("parse error '%U'", format_unformat_error, i);
14854           return -99;
14855         }
14856     }
14857
14858   if (!vec_len (name))
14859     {
14860       errmsg ("profile name must be specified");
14861       return -99;
14862     }
14863
14864   if (vec_len (name) > 64)
14865     {
14866       errmsg ("profile name too long");
14867       return -99;
14868     }
14869
14870   M (IKEV2_SET_SA_LIFETIME, mp);
14871
14872   clib_memcpy (mp->name, name, vec_len (name));
14873   vec_free (name);
14874   mp->lifetime = lifetime;
14875   mp->lifetime_jitter = lifetime_jitter;
14876   mp->handover = handover;
14877   mp->lifetime_maxdata = lifetime_maxdata;
14878
14879   S (mp);
14880   W (ret);
14881   return ret;
14882 }
14883
14884 static int
14885 api_ikev2_initiate_sa_init (vat_main_t * vam)
14886 {
14887   unformat_input_t *i = vam->input;
14888   vl_api_ikev2_initiate_sa_init_t *mp;
14889   int ret;
14890   u8 *name = 0;
14891
14892   const char *valid_chars = "a-zA-Z0-9_";
14893
14894   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14895     {
14896       if (unformat (i, "%U", unformat_token, valid_chars, &name))
14897         vec_add1 (name, 0);
14898       else
14899         {
14900           errmsg ("parse error '%U'", format_unformat_error, i);
14901           return -99;
14902         }
14903     }
14904
14905   if (!vec_len (name))
14906     {
14907       errmsg ("profile name must be specified");
14908       return -99;
14909     }
14910
14911   if (vec_len (name) > 64)
14912     {
14913       errmsg ("profile name too long");
14914       return -99;
14915     }
14916
14917   M (IKEV2_INITIATE_SA_INIT, mp);
14918
14919   clib_memcpy (mp->name, name, vec_len (name));
14920   vec_free (name);
14921
14922   S (mp);
14923   W (ret);
14924   return ret;
14925 }
14926
14927 static int
14928 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
14929 {
14930   unformat_input_t *i = vam->input;
14931   vl_api_ikev2_initiate_del_ike_sa_t *mp;
14932   int ret;
14933   u64 ispi;
14934
14935
14936   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14937     {
14938       if (unformat (i, "%lx", &ispi))
14939         ;
14940       else
14941         {
14942           errmsg ("parse error '%U'", format_unformat_error, i);
14943           return -99;
14944         }
14945     }
14946
14947   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
14948
14949   mp->ispi = ispi;
14950
14951   S (mp);
14952   W (ret);
14953   return ret;
14954 }
14955
14956 static int
14957 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
14958 {
14959   unformat_input_t *i = vam->input;
14960   vl_api_ikev2_initiate_del_child_sa_t *mp;
14961   int ret;
14962   u32 ispi;
14963
14964
14965   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14966     {
14967       if (unformat (i, "%x", &ispi))
14968         ;
14969       else
14970         {
14971           errmsg ("parse error '%U'", format_unformat_error, i);
14972           return -99;
14973         }
14974     }
14975
14976   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
14977
14978   mp->ispi = ispi;
14979
14980   S (mp);
14981   W (ret);
14982   return ret;
14983 }
14984
14985 static int
14986 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
14987 {
14988   unformat_input_t *i = vam->input;
14989   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
14990   int ret;
14991   u32 ispi;
14992
14993
14994   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14995     {
14996       if (unformat (i, "%x", &ispi))
14997         ;
14998       else
14999         {
15000           errmsg ("parse error '%U'", format_unformat_error, i);
15001           return -99;
15002         }
15003     }
15004
15005   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
15006
15007   mp->ispi = ispi;
15008
15009   S (mp);
15010   W (ret);
15011   return ret;
15012 }
15013
15014 /*
15015  * MAP
15016  */
15017 static int
15018 api_map_add_domain (vat_main_t * vam)
15019 {
15020   unformat_input_t *i = vam->input;
15021   vl_api_map_add_domain_t *mp;
15022
15023   ip4_address_t ip4_prefix;
15024   ip6_address_t ip6_prefix;
15025   ip6_address_t ip6_src;
15026   u32 num_m_args = 0;
15027   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
15028     0, psid_length = 0;
15029   u8 is_translation = 0;
15030   u32 mtu = 0;
15031   u32 ip6_src_len = 128;
15032   int ret;
15033
15034   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15035     {
15036       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
15037                     &ip4_prefix, &ip4_prefix_len))
15038         num_m_args++;
15039       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
15040                          &ip6_prefix, &ip6_prefix_len))
15041         num_m_args++;
15042       else
15043         if (unformat
15044             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
15045              &ip6_src_len))
15046         num_m_args++;
15047       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
15048         num_m_args++;
15049       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
15050         num_m_args++;
15051       else if (unformat (i, "psid-offset %d", &psid_offset))
15052         num_m_args++;
15053       else if (unformat (i, "psid-len %d", &psid_length))
15054         num_m_args++;
15055       else if (unformat (i, "mtu %d", &mtu))
15056         num_m_args++;
15057       else if (unformat (i, "map-t"))
15058         is_translation = 1;
15059       else
15060         {
15061           clib_warning ("parse error '%U'", format_unformat_error, i);
15062           return -99;
15063         }
15064     }
15065
15066   if (num_m_args < 3)
15067     {
15068       errmsg ("mandatory argument(s) missing");
15069       return -99;
15070     }
15071
15072   /* Construct the API message */
15073   M (MAP_ADD_DOMAIN, mp);
15074
15075   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
15076   mp->ip4_prefix_len = ip4_prefix_len;
15077
15078   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
15079   mp->ip6_prefix_len = ip6_prefix_len;
15080
15081   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
15082   mp->ip6_src_prefix_len = ip6_src_len;
15083
15084   mp->ea_bits_len = ea_bits_len;
15085   mp->psid_offset = psid_offset;
15086   mp->psid_length = psid_length;
15087   mp->is_translation = is_translation;
15088   mp->mtu = htons (mtu);
15089
15090   /* send it... */
15091   S (mp);
15092
15093   /* Wait for a reply, return good/bad news  */
15094   W (ret);
15095   return ret;
15096 }
15097
15098 static int
15099 api_map_del_domain (vat_main_t * vam)
15100 {
15101   unformat_input_t *i = vam->input;
15102   vl_api_map_del_domain_t *mp;
15103
15104   u32 num_m_args = 0;
15105   u32 index;
15106   int ret;
15107
15108   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15109     {
15110       if (unformat (i, "index %d", &index))
15111         num_m_args++;
15112       else
15113         {
15114           clib_warning ("parse error '%U'", format_unformat_error, i);
15115           return -99;
15116         }
15117     }
15118
15119   if (num_m_args != 1)
15120     {
15121       errmsg ("mandatory argument(s) missing");
15122       return -99;
15123     }
15124
15125   /* Construct the API message */
15126   M (MAP_DEL_DOMAIN, mp);
15127
15128   mp->index = ntohl (index);
15129
15130   /* send it... */
15131   S (mp);
15132
15133   /* Wait for a reply, return good/bad news  */
15134   W (ret);
15135   return ret;
15136 }
15137
15138 static int
15139 api_map_add_del_rule (vat_main_t * vam)
15140 {
15141   unformat_input_t *i = vam->input;
15142   vl_api_map_add_del_rule_t *mp;
15143   u8 is_add = 1;
15144   ip6_address_t ip6_dst;
15145   u32 num_m_args = 0, index, psid = 0;
15146   int ret;
15147
15148   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15149     {
15150       if (unformat (i, "index %d", &index))
15151         num_m_args++;
15152       else if (unformat (i, "psid %d", &psid))
15153         num_m_args++;
15154       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
15155         num_m_args++;
15156       else if (unformat (i, "del"))
15157         {
15158           is_add = 0;
15159         }
15160       else
15161         {
15162           clib_warning ("parse error '%U'", format_unformat_error, i);
15163           return -99;
15164         }
15165     }
15166
15167   /* Construct the API message */
15168   M (MAP_ADD_DEL_RULE, mp);
15169
15170   mp->index = ntohl (index);
15171   mp->is_add = is_add;
15172   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
15173   mp->psid = ntohs (psid);
15174
15175   /* send it... */
15176   S (mp);
15177
15178   /* Wait for a reply, return good/bad news  */
15179   W (ret);
15180   return ret;
15181 }
15182
15183 static int
15184 api_map_domain_dump (vat_main_t * vam)
15185 {
15186   vl_api_map_domain_dump_t *mp;
15187   vl_api_control_ping_t *mp_ping;
15188   int ret;
15189
15190   /* Construct the API message */
15191   M (MAP_DOMAIN_DUMP, mp);
15192
15193   /* send it... */
15194   S (mp);
15195
15196   /* Use a control ping for synchronization */
15197   MPING (CONTROL_PING, mp_ping);
15198   S (mp_ping);
15199
15200   W (ret);
15201   return ret;
15202 }
15203
15204 static int
15205 api_map_rule_dump (vat_main_t * vam)
15206 {
15207   unformat_input_t *i = vam->input;
15208   vl_api_map_rule_dump_t *mp;
15209   vl_api_control_ping_t *mp_ping;
15210   u32 domain_index = ~0;
15211   int ret;
15212
15213   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15214     {
15215       if (unformat (i, "index %u", &domain_index))
15216         ;
15217       else
15218         break;
15219     }
15220
15221   if (domain_index == ~0)
15222     {
15223       clib_warning ("parse error: domain index expected");
15224       return -99;
15225     }
15226
15227   /* Construct the API message */
15228   M (MAP_RULE_DUMP, mp);
15229
15230   mp->domain_index = htonl (domain_index);
15231
15232   /* send it... */
15233   S (mp);
15234
15235   /* Use a control ping for synchronization */
15236   MPING (CONTROL_PING, mp_ping);
15237   S (mp_ping);
15238
15239   W (ret);
15240   return ret;
15241 }
15242
15243 static void vl_api_map_add_domain_reply_t_handler
15244   (vl_api_map_add_domain_reply_t * mp)
15245 {
15246   vat_main_t *vam = &vat_main;
15247   i32 retval = ntohl (mp->retval);
15248
15249   if (vam->async_mode)
15250     {
15251       vam->async_errors += (retval < 0);
15252     }
15253   else
15254     {
15255       vam->retval = retval;
15256       vam->result_ready = 1;
15257     }
15258 }
15259
15260 static void vl_api_map_add_domain_reply_t_handler_json
15261   (vl_api_map_add_domain_reply_t * mp)
15262 {
15263   vat_main_t *vam = &vat_main;
15264   vat_json_node_t node;
15265
15266   vat_json_init_object (&node);
15267   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
15268   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
15269
15270   vat_json_print (vam->ofp, &node);
15271   vat_json_free (&node);
15272
15273   vam->retval = ntohl (mp->retval);
15274   vam->result_ready = 1;
15275 }
15276
15277 static int
15278 api_get_first_msg_id (vat_main_t * vam)
15279 {
15280   vl_api_get_first_msg_id_t *mp;
15281   unformat_input_t *i = vam->input;
15282   u8 *name;
15283   u8 name_set = 0;
15284   int ret;
15285
15286   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15287     {
15288       if (unformat (i, "client %s", &name))
15289         name_set = 1;
15290       else
15291         break;
15292     }
15293
15294   if (name_set == 0)
15295     {
15296       errmsg ("missing client name");
15297       return -99;
15298     }
15299   vec_add1 (name, 0);
15300
15301   if (vec_len (name) > 63)
15302     {
15303       errmsg ("client name too long");
15304       return -99;
15305     }
15306
15307   M (GET_FIRST_MSG_ID, mp);
15308   clib_memcpy (mp->name, name, vec_len (name));
15309   S (mp);
15310   W (ret);
15311   return ret;
15312 }
15313
15314 static int
15315 api_cop_interface_enable_disable (vat_main_t * vam)
15316 {
15317   unformat_input_t *line_input = vam->input;
15318   vl_api_cop_interface_enable_disable_t *mp;
15319   u32 sw_if_index = ~0;
15320   u8 enable_disable = 1;
15321   int ret;
15322
15323   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15324     {
15325       if (unformat (line_input, "disable"))
15326         enable_disable = 0;
15327       if (unformat (line_input, "enable"))
15328         enable_disable = 1;
15329       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15330                          vam, &sw_if_index))
15331         ;
15332       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15333         ;
15334       else
15335         break;
15336     }
15337
15338   if (sw_if_index == ~0)
15339     {
15340       errmsg ("missing interface name or sw_if_index");
15341       return -99;
15342     }
15343
15344   /* Construct the API message */
15345   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15346   mp->sw_if_index = ntohl (sw_if_index);
15347   mp->enable_disable = enable_disable;
15348
15349   /* send it... */
15350   S (mp);
15351   /* Wait for the reply */
15352   W (ret);
15353   return ret;
15354 }
15355
15356 static int
15357 api_cop_whitelist_enable_disable (vat_main_t * vam)
15358 {
15359   unformat_input_t *line_input = vam->input;
15360   vl_api_cop_whitelist_enable_disable_t *mp;
15361   u32 sw_if_index = ~0;
15362   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15363   u32 fib_id = 0;
15364   int ret;
15365
15366   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15367     {
15368       if (unformat (line_input, "ip4"))
15369         ip4 = 1;
15370       else if (unformat (line_input, "ip6"))
15371         ip6 = 1;
15372       else if (unformat (line_input, "default"))
15373         default_cop = 1;
15374       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15375                          vam, &sw_if_index))
15376         ;
15377       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15378         ;
15379       else if (unformat (line_input, "fib-id %d", &fib_id))
15380         ;
15381       else
15382         break;
15383     }
15384
15385   if (sw_if_index == ~0)
15386     {
15387       errmsg ("missing interface name or sw_if_index");
15388       return -99;
15389     }
15390
15391   /* Construct the API message */
15392   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15393   mp->sw_if_index = ntohl (sw_if_index);
15394   mp->fib_id = ntohl (fib_id);
15395   mp->ip4 = ip4;
15396   mp->ip6 = ip6;
15397   mp->default_cop = default_cop;
15398
15399   /* send it... */
15400   S (mp);
15401   /* Wait for the reply */
15402   W (ret);
15403   return ret;
15404 }
15405
15406 static int
15407 api_get_node_graph (vat_main_t * vam)
15408 {
15409   vl_api_get_node_graph_t *mp;
15410   int ret;
15411
15412   M (GET_NODE_GRAPH, mp);
15413
15414   /* send it... */
15415   S (mp);
15416   /* Wait for the reply */
15417   W (ret);
15418   return ret;
15419 }
15420
15421 /* *INDENT-OFF* */
15422 /** Used for parsing LISP eids */
15423 typedef CLIB_PACKED(struct{
15424   u8 addr[16];   /**< eid address */
15425   u32 len;       /**< prefix length if IP */
15426   u8 type;      /**< type of eid */
15427 }) lisp_eid_vat_t;
15428 /* *INDENT-ON* */
15429
15430 static uword
15431 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15432 {
15433   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15434
15435   memset (a, 0, sizeof (a[0]));
15436
15437   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15438     {
15439       a->type = 0;              /* ipv4 type */
15440     }
15441   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15442     {
15443       a->type = 1;              /* ipv6 type */
15444     }
15445   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15446     {
15447       a->type = 2;              /* mac type */
15448     }
15449   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15450     {
15451       a->type = 3;              /* NSH type */
15452       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15453       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15454     }
15455   else
15456     {
15457       return 0;
15458     }
15459
15460   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15461     {
15462       return 0;
15463     }
15464
15465   return 1;
15466 }
15467
15468 static int
15469 lisp_eid_size_vat (u8 type)
15470 {
15471   switch (type)
15472     {
15473     case 0:
15474       return 4;
15475     case 1:
15476       return 16;
15477     case 2:
15478       return 6;
15479     case 3:
15480       return 5;
15481     }
15482   return 0;
15483 }
15484
15485 static void
15486 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15487 {
15488   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15489 }
15490
15491 static int
15492 api_one_add_del_locator_set (vat_main_t * vam)
15493 {
15494   unformat_input_t *input = vam->input;
15495   vl_api_one_add_del_locator_set_t *mp;
15496   u8 is_add = 1;
15497   u8 *locator_set_name = NULL;
15498   u8 locator_set_name_set = 0;
15499   vl_api_local_locator_t locator, *locators = 0;
15500   u32 sw_if_index, priority, weight;
15501   u32 data_len = 0;
15502
15503   int ret;
15504   /* Parse args required to build the message */
15505   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15506     {
15507       if (unformat (input, "del"))
15508         {
15509           is_add = 0;
15510         }
15511       else if (unformat (input, "locator-set %s", &locator_set_name))
15512         {
15513           locator_set_name_set = 1;
15514         }
15515       else if (unformat (input, "sw_if_index %u p %u w %u",
15516                          &sw_if_index, &priority, &weight))
15517         {
15518           locator.sw_if_index = htonl (sw_if_index);
15519           locator.priority = priority;
15520           locator.weight = weight;
15521           vec_add1 (locators, locator);
15522         }
15523       else
15524         if (unformat
15525             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15526              &sw_if_index, &priority, &weight))
15527         {
15528           locator.sw_if_index = htonl (sw_if_index);
15529           locator.priority = priority;
15530           locator.weight = weight;
15531           vec_add1 (locators, locator);
15532         }
15533       else
15534         break;
15535     }
15536
15537   if (locator_set_name_set == 0)
15538     {
15539       errmsg ("missing locator-set name");
15540       vec_free (locators);
15541       return -99;
15542     }
15543
15544   if (vec_len (locator_set_name) > 64)
15545     {
15546       errmsg ("locator-set name too long");
15547       vec_free (locator_set_name);
15548       vec_free (locators);
15549       return -99;
15550     }
15551   vec_add1 (locator_set_name, 0);
15552
15553   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15554
15555   /* Construct the API message */
15556   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15557
15558   mp->is_add = is_add;
15559   clib_memcpy (mp->locator_set_name, locator_set_name,
15560                vec_len (locator_set_name));
15561   vec_free (locator_set_name);
15562
15563   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15564   if (locators)
15565     clib_memcpy (mp->locators, locators, data_len);
15566   vec_free (locators);
15567
15568   /* send it... */
15569   S (mp);
15570
15571   /* Wait for a reply... */
15572   W (ret);
15573   return ret;
15574 }
15575
15576 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15577
15578 static int
15579 api_one_add_del_locator (vat_main_t * vam)
15580 {
15581   unformat_input_t *input = vam->input;
15582   vl_api_one_add_del_locator_t *mp;
15583   u32 tmp_if_index = ~0;
15584   u32 sw_if_index = ~0;
15585   u8 sw_if_index_set = 0;
15586   u8 sw_if_index_if_name_set = 0;
15587   u32 priority = ~0;
15588   u8 priority_set = 0;
15589   u32 weight = ~0;
15590   u8 weight_set = 0;
15591   u8 is_add = 1;
15592   u8 *locator_set_name = NULL;
15593   u8 locator_set_name_set = 0;
15594   int ret;
15595
15596   /* Parse args required to build the message */
15597   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15598     {
15599       if (unformat (input, "del"))
15600         {
15601           is_add = 0;
15602         }
15603       else if (unformat (input, "locator-set %s", &locator_set_name))
15604         {
15605           locator_set_name_set = 1;
15606         }
15607       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15608                          &tmp_if_index))
15609         {
15610           sw_if_index_if_name_set = 1;
15611           sw_if_index = tmp_if_index;
15612         }
15613       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15614         {
15615           sw_if_index_set = 1;
15616           sw_if_index = tmp_if_index;
15617         }
15618       else if (unformat (input, "p %d", &priority))
15619         {
15620           priority_set = 1;
15621         }
15622       else if (unformat (input, "w %d", &weight))
15623         {
15624           weight_set = 1;
15625         }
15626       else
15627         break;
15628     }
15629
15630   if (locator_set_name_set == 0)
15631     {
15632       errmsg ("missing locator-set name");
15633       return -99;
15634     }
15635
15636   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15637     {
15638       errmsg ("missing sw_if_index");
15639       vec_free (locator_set_name);
15640       return -99;
15641     }
15642
15643   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15644     {
15645       errmsg ("cannot use both params interface name and sw_if_index");
15646       vec_free (locator_set_name);
15647       return -99;
15648     }
15649
15650   if (priority_set == 0)
15651     {
15652       errmsg ("missing locator-set priority");
15653       vec_free (locator_set_name);
15654       return -99;
15655     }
15656
15657   if (weight_set == 0)
15658     {
15659       errmsg ("missing locator-set weight");
15660       vec_free (locator_set_name);
15661       return -99;
15662     }
15663
15664   if (vec_len (locator_set_name) > 64)
15665     {
15666       errmsg ("locator-set name too long");
15667       vec_free (locator_set_name);
15668       return -99;
15669     }
15670   vec_add1 (locator_set_name, 0);
15671
15672   /* Construct the API message */
15673   M (ONE_ADD_DEL_LOCATOR, mp);
15674
15675   mp->is_add = is_add;
15676   mp->sw_if_index = ntohl (sw_if_index);
15677   mp->priority = priority;
15678   mp->weight = weight;
15679   clib_memcpy (mp->locator_set_name, locator_set_name,
15680                vec_len (locator_set_name));
15681   vec_free (locator_set_name);
15682
15683   /* send it... */
15684   S (mp);
15685
15686   /* Wait for a reply... */
15687   W (ret);
15688   return ret;
15689 }
15690
15691 #define api_lisp_add_del_locator api_one_add_del_locator
15692
15693 uword
15694 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15695 {
15696   u32 *key_id = va_arg (*args, u32 *);
15697   u8 *s = 0;
15698
15699   if (unformat (input, "%s", &s))
15700     {
15701       if (!strcmp ((char *) s, "sha1"))
15702         key_id[0] = HMAC_SHA_1_96;
15703       else if (!strcmp ((char *) s, "sha256"))
15704         key_id[0] = HMAC_SHA_256_128;
15705       else
15706         {
15707           clib_warning ("invalid key_id: '%s'", s);
15708           key_id[0] = HMAC_NO_KEY;
15709         }
15710     }
15711   else
15712     return 0;
15713
15714   vec_free (s);
15715   return 1;
15716 }
15717
15718 static int
15719 api_one_add_del_local_eid (vat_main_t * vam)
15720 {
15721   unformat_input_t *input = vam->input;
15722   vl_api_one_add_del_local_eid_t *mp;
15723   u8 is_add = 1;
15724   u8 eid_set = 0;
15725   lisp_eid_vat_t _eid, *eid = &_eid;
15726   u8 *locator_set_name = 0;
15727   u8 locator_set_name_set = 0;
15728   u32 vni = 0;
15729   u16 key_id = 0;
15730   u8 *key = 0;
15731   int ret;
15732
15733   /* Parse args required to build the message */
15734   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15735     {
15736       if (unformat (input, "del"))
15737         {
15738           is_add = 0;
15739         }
15740       else if (unformat (input, "vni %d", &vni))
15741         {
15742           ;
15743         }
15744       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15745         {
15746           eid_set = 1;
15747         }
15748       else if (unformat (input, "locator-set %s", &locator_set_name))
15749         {
15750           locator_set_name_set = 1;
15751         }
15752       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15753         ;
15754       else if (unformat (input, "secret-key %_%v%_", &key))
15755         ;
15756       else
15757         break;
15758     }
15759
15760   if (locator_set_name_set == 0)
15761     {
15762       errmsg ("missing locator-set name");
15763       return -99;
15764     }
15765
15766   if (0 == eid_set)
15767     {
15768       errmsg ("EID address not set!");
15769       vec_free (locator_set_name);
15770       return -99;
15771     }
15772
15773   if (key && (0 == key_id))
15774     {
15775       errmsg ("invalid key_id!");
15776       return -99;
15777     }
15778
15779   if (vec_len (key) > 64)
15780     {
15781       errmsg ("key too long");
15782       vec_free (key);
15783       return -99;
15784     }
15785
15786   if (vec_len (locator_set_name) > 64)
15787     {
15788       errmsg ("locator-set name too long");
15789       vec_free (locator_set_name);
15790       return -99;
15791     }
15792   vec_add1 (locator_set_name, 0);
15793
15794   /* Construct the API message */
15795   M (ONE_ADD_DEL_LOCAL_EID, mp);
15796
15797   mp->is_add = is_add;
15798   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15799   mp->eid_type = eid->type;
15800   mp->prefix_len = eid->len;
15801   mp->vni = clib_host_to_net_u32 (vni);
15802   mp->key_id = clib_host_to_net_u16 (key_id);
15803   clib_memcpy (mp->locator_set_name, locator_set_name,
15804                vec_len (locator_set_name));
15805   clib_memcpy (mp->key, key, vec_len (key));
15806
15807   vec_free (locator_set_name);
15808   vec_free (key);
15809
15810   /* send it... */
15811   S (mp);
15812
15813   /* Wait for a reply... */
15814   W (ret);
15815   return ret;
15816 }
15817
15818 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15819
15820 static int
15821 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15822 {
15823   u32 dp_table = 0, vni = 0;;
15824   unformat_input_t *input = vam->input;
15825   vl_api_gpe_add_del_fwd_entry_t *mp;
15826   u8 is_add = 1;
15827   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15828   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15829   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15830   u32 action = ~0, w;
15831   ip4_address_t rmt_rloc4, lcl_rloc4;
15832   ip6_address_t rmt_rloc6, lcl_rloc6;
15833   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15834   int ret;
15835
15836   memset (&rloc, 0, sizeof (rloc));
15837
15838   /* Parse args required to build the message */
15839   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15840     {
15841       if (unformat (input, "del"))
15842         is_add = 0;
15843       else if (unformat (input, "add"))
15844         is_add = 1;
15845       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15846         {
15847           rmt_eid_set = 1;
15848         }
15849       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15850         {
15851           lcl_eid_set = 1;
15852         }
15853       else if (unformat (input, "vrf %d", &dp_table))
15854         ;
15855       else if (unformat (input, "bd %d", &dp_table))
15856         ;
15857       else if (unformat (input, "vni %d", &vni))
15858         ;
15859       else if (unformat (input, "w %d", &w))
15860         {
15861           if (!curr_rloc)
15862             {
15863               errmsg ("No RLOC configured for setting priority/weight!");
15864               return -99;
15865             }
15866           curr_rloc->weight = w;
15867         }
15868       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15869                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15870         {
15871           rloc.is_ip4 = 1;
15872
15873           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15874           rloc.weight = 0;
15875           vec_add1 (lcl_locs, rloc);
15876
15877           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15878           vec_add1 (rmt_locs, rloc);
15879           /* weight saved in rmt loc */
15880           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15881         }
15882       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15883                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15884         {
15885           rloc.is_ip4 = 0;
15886           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15887           rloc.weight = 0;
15888           vec_add1 (lcl_locs, rloc);
15889
15890           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15891           vec_add1 (rmt_locs, rloc);
15892           /* weight saved in rmt loc */
15893           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15894         }
15895       else if (unformat (input, "action %d", &action))
15896         {
15897           ;
15898         }
15899       else
15900         {
15901           clib_warning ("parse error '%U'", format_unformat_error, input);
15902           return -99;
15903         }
15904     }
15905
15906   if (!rmt_eid_set)
15907     {
15908       errmsg ("remote eid addresses not set");
15909       return -99;
15910     }
15911
15912   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15913     {
15914       errmsg ("eid types don't match");
15915       return -99;
15916     }
15917
15918   if (0 == rmt_locs && (u32) ~ 0 == action)
15919     {
15920       errmsg ("action not set for negative mapping");
15921       return -99;
15922     }
15923
15924   /* Construct the API message */
15925   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15926       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15927
15928   mp->is_add = is_add;
15929   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15930   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15931   mp->eid_type = rmt_eid->type;
15932   mp->dp_table = clib_host_to_net_u32 (dp_table);
15933   mp->vni = clib_host_to_net_u32 (vni);
15934   mp->rmt_len = rmt_eid->len;
15935   mp->lcl_len = lcl_eid->len;
15936   mp->action = action;
15937
15938   if (0 != rmt_locs && 0 != lcl_locs)
15939     {
15940       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15941       clib_memcpy (mp->locs, lcl_locs,
15942                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15943
15944       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15945       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15946                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15947     }
15948   vec_free (lcl_locs);
15949   vec_free (rmt_locs);
15950
15951   /* send it... */
15952   S (mp);
15953
15954   /* Wait for a reply... */
15955   W (ret);
15956   return ret;
15957 }
15958
15959 static int
15960 api_one_add_del_map_server (vat_main_t * vam)
15961 {
15962   unformat_input_t *input = vam->input;
15963   vl_api_one_add_del_map_server_t *mp;
15964   u8 is_add = 1;
15965   u8 ipv4_set = 0;
15966   u8 ipv6_set = 0;
15967   ip4_address_t ipv4;
15968   ip6_address_t ipv6;
15969   int ret;
15970
15971   /* Parse args required to build the message */
15972   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15973     {
15974       if (unformat (input, "del"))
15975         {
15976           is_add = 0;
15977         }
15978       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15979         {
15980           ipv4_set = 1;
15981         }
15982       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15983         {
15984           ipv6_set = 1;
15985         }
15986       else
15987         break;
15988     }
15989
15990   if (ipv4_set && ipv6_set)
15991     {
15992       errmsg ("both eid v4 and v6 addresses set");
15993       return -99;
15994     }
15995
15996   if (!ipv4_set && !ipv6_set)
15997     {
15998       errmsg ("eid addresses not set");
15999       return -99;
16000     }
16001
16002   /* Construct the API message */
16003   M (ONE_ADD_DEL_MAP_SERVER, mp);
16004
16005   mp->is_add = is_add;
16006   if (ipv6_set)
16007     {
16008       mp->is_ipv6 = 1;
16009       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16010     }
16011   else
16012     {
16013       mp->is_ipv6 = 0;
16014       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16015     }
16016
16017   /* send it... */
16018   S (mp);
16019
16020   /* Wait for a reply... */
16021   W (ret);
16022   return ret;
16023 }
16024
16025 #define api_lisp_add_del_map_server api_one_add_del_map_server
16026
16027 static int
16028 api_one_add_del_map_resolver (vat_main_t * vam)
16029 {
16030   unformat_input_t *input = vam->input;
16031   vl_api_one_add_del_map_resolver_t *mp;
16032   u8 is_add = 1;
16033   u8 ipv4_set = 0;
16034   u8 ipv6_set = 0;
16035   ip4_address_t ipv4;
16036   ip6_address_t ipv6;
16037   int ret;
16038
16039   /* Parse args required to build the message */
16040   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16041     {
16042       if (unformat (input, "del"))
16043         {
16044           is_add = 0;
16045         }
16046       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16047         {
16048           ipv4_set = 1;
16049         }
16050       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16051         {
16052           ipv6_set = 1;
16053         }
16054       else
16055         break;
16056     }
16057
16058   if (ipv4_set && ipv6_set)
16059     {
16060       errmsg ("both eid v4 and v6 addresses set");
16061       return -99;
16062     }
16063
16064   if (!ipv4_set && !ipv6_set)
16065     {
16066       errmsg ("eid addresses not set");
16067       return -99;
16068     }
16069
16070   /* Construct the API message */
16071   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16072
16073   mp->is_add = is_add;
16074   if (ipv6_set)
16075     {
16076       mp->is_ipv6 = 1;
16077       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16078     }
16079   else
16080     {
16081       mp->is_ipv6 = 0;
16082       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16083     }
16084
16085   /* send it... */
16086   S (mp);
16087
16088   /* Wait for a reply... */
16089   W (ret);
16090   return ret;
16091 }
16092
16093 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16094
16095 static int
16096 api_lisp_gpe_enable_disable (vat_main_t * vam)
16097 {
16098   unformat_input_t *input = vam->input;
16099   vl_api_gpe_enable_disable_t *mp;
16100   u8 is_set = 0;
16101   u8 is_en = 1;
16102   int ret;
16103
16104   /* Parse args required to build the message */
16105   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16106     {
16107       if (unformat (input, "enable"))
16108         {
16109           is_set = 1;
16110           is_en = 1;
16111         }
16112       else if (unformat (input, "disable"))
16113         {
16114           is_set = 1;
16115           is_en = 0;
16116         }
16117       else
16118         break;
16119     }
16120
16121   if (is_set == 0)
16122     {
16123       errmsg ("Value not set");
16124       return -99;
16125     }
16126
16127   /* Construct the API message */
16128   M (GPE_ENABLE_DISABLE, mp);
16129
16130   mp->is_en = is_en;
16131
16132   /* send it... */
16133   S (mp);
16134
16135   /* Wait for a reply... */
16136   W (ret);
16137   return ret;
16138 }
16139
16140 static int
16141 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16142 {
16143   unformat_input_t *input = vam->input;
16144   vl_api_one_rloc_probe_enable_disable_t *mp;
16145   u8 is_set = 0;
16146   u8 is_en = 0;
16147   int ret;
16148
16149   /* Parse args required to build the message */
16150   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16151     {
16152       if (unformat (input, "enable"))
16153         {
16154           is_set = 1;
16155           is_en = 1;
16156         }
16157       else if (unformat (input, "disable"))
16158         is_set = 1;
16159       else
16160         break;
16161     }
16162
16163   if (!is_set)
16164     {
16165       errmsg ("Value not set");
16166       return -99;
16167     }
16168
16169   /* Construct the API message */
16170   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16171
16172   mp->is_enabled = is_en;
16173
16174   /* send it... */
16175   S (mp);
16176
16177   /* Wait for a reply... */
16178   W (ret);
16179   return ret;
16180 }
16181
16182 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16183
16184 static int
16185 api_one_map_register_enable_disable (vat_main_t * vam)
16186 {
16187   unformat_input_t *input = vam->input;
16188   vl_api_one_map_register_enable_disable_t *mp;
16189   u8 is_set = 0;
16190   u8 is_en = 0;
16191   int ret;
16192
16193   /* Parse args required to build the message */
16194   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16195     {
16196       if (unformat (input, "enable"))
16197         {
16198           is_set = 1;
16199           is_en = 1;
16200         }
16201       else if (unformat (input, "disable"))
16202         is_set = 1;
16203       else
16204         break;
16205     }
16206
16207   if (!is_set)
16208     {
16209       errmsg ("Value not set");
16210       return -99;
16211     }
16212
16213   /* Construct the API message */
16214   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16215
16216   mp->is_enabled = is_en;
16217
16218   /* send it... */
16219   S (mp);
16220
16221   /* Wait for a reply... */
16222   W (ret);
16223   return ret;
16224 }
16225
16226 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16227
16228 static int
16229 api_one_enable_disable (vat_main_t * vam)
16230 {
16231   unformat_input_t *input = vam->input;
16232   vl_api_one_enable_disable_t *mp;
16233   u8 is_set = 0;
16234   u8 is_en = 0;
16235   int ret;
16236
16237   /* Parse args required to build the message */
16238   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16239     {
16240       if (unformat (input, "enable"))
16241         {
16242           is_set = 1;
16243           is_en = 1;
16244         }
16245       else if (unformat (input, "disable"))
16246         {
16247           is_set = 1;
16248         }
16249       else
16250         break;
16251     }
16252
16253   if (!is_set)
16254     {
16255       errmsg ("Value not set");
16256       return -99;
16257     }
16258
16259   /* Construct the API message */
16260   M (ONE_ENABLE_DISABLE, mp);
16261
16262   mp->is_en = is_en;
16263
16264   /* send it... */
16265   S (mp);
16266
16267   /* Wait for a reply... */
16268   W (ret);
16269   return ret;
16270 }
16271
16272 #define api_lisp_enable_disable api_one_enable_disable
16273
16274 static int
16275 api_show_one_map_register_state (vat_main_t * vam)
16276 {
16277   vl_api_show_one_map_register_state_t *mp;
16278   int ret;
16279
16280   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16281
16282   /* send */
16283   S (mp);
16284
16285   /* wait for reply */
16286   W (ret);
16287   return ret;
16288 }
16289
16290 #define api_show_lisp_map_register_state api_show_one_map_register_state
16291
16292 static int
16293 api_show_one_rloc_probe_state (vat_main_t * vam)
16294 {
16295   vl_api_show_one_rloc_probe_state_t *mp;
16296   int ret;
16297
16298   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16299
16300   /* send */
16301   S (mp);
16302
16303   /* wait for reply */
16304   W (ret);
16305   return ret;
16306 }
16307
16308 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16309
16310 static int
16311 api_one_add_del_ndp_entry (vat_main_t * vam)
16312 {
16313   vl_api_one_add_del_ndp_entry_t *mp;
16314   unformat_input_t *input = vam->input;
16315   u8 is_add = 1;
16316   u8 mac_set = 0;
16317   u8 bd_set = 0;
16318   u8 ip_set = 0;
16319   u8 mac[6] = { 0, };
16320   u8 ip6[16] = { 0, };
16321   u32 bd = ~0;
16322   int ret;
16323
16324   /* Parse args required to build the message */
16325   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16326     {
16327       if (unformat (input, "del"))
16328         is_add = 0;
16329       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16330         mac_set = 1;
16331       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16332         ip_set = 1;
16333       else if (unformat (input, "bd %d", &bd))
16334         bd_set = 1;
16335       else
16336         {
16337           errmsg ("parse error '%U'", format_unformat_error, input);
16338           return -99;
16339         }
16340     }
16341
16342   if (!bd_set || !ip_set || (!mac_set && is_add))
16343     {
16344       errmsg ("Missing BD, IP or MAC!");
16345       return -99;
16346     }
16347
16348   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16349   mp->is_add = is_add;
16350   clib_memcpy (mp->mac, mac, 6);
16351   mp->bd = clib_host_to_net_u32 (bd);
16352   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16353
16354   /* send */
16355   S (mp);
16356
16357   /* wait for reply */
16358   W (ret);
16359   return ret;
16360 }
16361
16362 static int
16363 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16364 {
16365   vl_api_one_add_del_l2_arp_entry_t *mp;
16366   unformat_input_t *input = vam->input;
16367   u8 is_add = 1;
16368   u8 mac_set = 0;
16369   u8 bd_set = 0;
16370   u8 ip_set = 0;
16371   u8 mac[6] = { 0, };
16372   u32 ip4 = 0, bd = ~0;
16373   int ret;
16374
16375   /* Parse args required to build the message */
16376   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16377     {
16378       if (unformat (input, "del"))
16379         is_add = 0;
16380       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16381         mac_set = 1;
16382       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16383         ip_set = 1;
16384       else if (unformat (input, "bd %d", &bd))
16385         bd_set = 1;
16386       else
16387         {
16388           errmsg ("parse error '%U'", format_unformat_error, input);
16389           return -99;
16390         }
16391     }
16392
16393   if (!bd_set || !ip_set || (!mac_set && is_add))
16394     {
16395       errmsg ("Missing BD, IP or MAC!");
16396       return -99;
16397     }
16398
16399   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16400   mp->is_add = is_add;
16401   clib_memcpy (mp->mac, mac, 6);
16402   mp->bd = clib_host_to_net_u32 (bd);
16403   mp->ip4 = ip4;
16404
16405   /* send */
16406   S (mp);
16407
16408   /* wait for reply */
16409   W (ret);
16410   return ret;
16411 }
16412
16413 static int
16414 api_one_ndp_bd_get (vat_main_t * vam)
16415 {
16416   vl_api_one_ndp_bd_get_t *mp;
16417   int ret;
16418
16419   M (ONE_NDP_BD_GET, mp);
16420
16421   /* send */
16422   S (mp);
16423
16424   /* wait for reply */
16425   W (ret);
16426   return ret;
16427 }
16428
16429 static int
16430 api_one_ndp_entries_get (vat_main_t * vam)
16431 {
16432   vl_api_one_ndp_entries_get_t *mp;
16433   unformat_input_t *input = vam->input;
16434   u8 bd_set = 0;
16435   u32 bd = ~0;
16436   int ret;
16437
16438   /* Parse args required to build the message */
16439   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16440     {
16441       if (unformat (input, "bd %d", &bd))
16442         bd_set = 1;
16443       else
16444         {
16445           errmsg ("parse error '%U'", format_unformat_error, input);
16446           return -99;
16447         }
16448     }
16449
16450   if (!bd_set)
16451     {
16452       errmsg ("Expected bridge domain!");
16453       return -99;
16454     }
16455
16456   M (ONE_NDP_ENTRIES_GET, mp);
16457   mp->bd = clib_host_to_net_u32 (bd);
16458
16459   /* send */
16460   S (mp);
16461
16462   /* wait for reply */
16463   W (ret);
16464   return ret;
16465 }
16466
16467 static int
16468 api_one_l2_arp_bd_get (vat_main_t * vam)
16469 {
16470   vl_api_one_l2_arp_bd_get_t *mp;
16471   int ret;
16472
16473   M (ONE_L2_ARP_BD_GET, mp);
16474
16475   /* send */
16476   S (mp);
16477
16478   /* wait for reply */
16479   W (ret);
16480   return ret;
16481 }
16482
16483 static int
16484 api_one_l2_arp_entries_get (vat_main_t * vam)
16485 {
16486   vl_api_one_l2_arp_entries_get_t *mp;
16487   unformat_input_t *input = vam->input;
16488   u8 bd_set = 0;
16489   u32 bd = ~0;
16490   int ret;
16491
16492   /* Parse args required to build the message */
16493   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16494     {
16495       if (unformat (input, "bd %d", &bd))
16496         bd_set = 1;
16497       else
16498         {
16499           errmsg ("parse error '%U'", format_unformat_error, input);
16500           return -99;
16501         }
16502     }
16503
16504   if (!bd_set)
16505     {
16506       errmsg ("Expected bridge domain!");
16507       return -99;
16508     }
16509
16510   M (ONE_L2_ARP_ENTRIES_GET, mp);
16511   mp->bd = clib_host_to_net_u32 (bd);
16512
16513   /* send */
16514   S (mp);
16515
16516   /* wait for reply */
16517   W (ret);
16518   return ret;
16519 }
16520
16521 static int
16522 api_one_stats_enable_disable (vat_main_t * vam)
16523 {
16524   vl_api_one_stats_enable_disable_t *mp;
16525   unformat_input_t *input = vam->input;
16526   u8 is_set = 0;
16527   u8 is_en = 0;
16528   int ret;
16529
16530   /* Parse args required to build the message */
16531   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16532     {
16533       if (unformat (input, "enable"))
16534         {
16535           is_set = 1;
16536           is_en = 1;
16537         }
16538       else if (unformat (input, "disable"))
16539         {
16540           is_set = 1;
16541         }
16542       else
16543         break;
16544     }
16545
16546   if (!is_set)
16547     {
16548       errmsg ("Value not set");
16549       return -99;
16550     }
16551
16552   M (ONE_STATS_ENABLE_DISABLE, mp);
16553   mp->is_en = is_en;
16554
16555   /* send */
16556   S (mp);
16557
16558   /* wait for reply */
16559   W (ret);
16560   return ret;
16561 }
16562
16563 static int
16564 api_show_one_stats_enable_disable (vat_main_t * vam)
16565 {
16566   vl_api_show_one_stats_enable_disable_t *mp;
16567   int ret;
16568
16569   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16570
16571   /* send */
16572   S (mp);
16573
16574   /* wait for reply */
16575   W (ret);
16576   return ret;
16577 }
16578
16579 static int
16580 api_show_one_map_request_mode (vat_main_t * vam)
16581 {
16582   vl_api_show_one_map_request_mode_t *mp;
16583   int ret;
16584
16585   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16586
16587   /* send */
16588   S (mp);
16589
16590   /* wait for reply */
16591   W (ret);
16592   return ret;
16593 }
16594
16595 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16596
16597 static int
16598 api_one_map_request_mode (vat_main_t * vam)
16599 {
16600   unformat_input_t *input = vam->input;
16601   vl_api_one_map_request_mode_t *mp;
16602   u8 mode = 0;
16603   int ret;
16604
16605   /* Parse args required to build the message */
16606   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16607     {
16608       if (unformat (input, "dst-only"))
16609         mode = 0;
16610       else if (unformat (input, "src-dst"))
16611         mode = 1;
16612       else
16613         {
16614           errmsg ("parse error '%U'", format_unformat_error, input);
16615           return -99;
16616         }
16617     }
16618
16619   M (ONE_MAP_REQUEST_MODE, mp);
16620
16621   mp->mode = mode;
16622
16623   /* send */
16624   S (mp);
16625
16626   /* wait for reply */
16627   W (ret);
16628   return ret;
16629 }
16630
16631 #define api_lisp_map_request_mode api_one_map_request_mode
16632
16633 /**
16634  * Enable/disable ONE proxy ITR.
16635  *
16636  * @param vam vpp API test context
16637  * @return return code
16638  */
16639 static int
16640 api_one_pitr_set_locator_set (vat_main_t * vam)
16641 {
16642   u8 ls_name_set = 0;
16643   unformat_input_t *input = vam->input;
16644   vl_api_one_pitr_set_locator_set_t *mp;
16645   u8 is_add = 1;
16646   u8 *ls_name = 0;
16647   int ret;
16648
16649   /* Parse args required to build the message */
16650   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16651     {
16652       if (unformat (input, "del"))
16653         is_add = 0;
16654       else if (unformat (input, "locator-set %s", &ls_name))
16655         ls_name_set = 1;
16656       else
16657         {
16658           errmsg ("parse error '%U'", format_unformat_error, input);
16659           return -99;
16660         }
16661     }
16662
16663   if (!ls_name_set)
16664     {
16665       errmsg ("locator-set name not set!");
16666       return -99;
16667     }
16668
16669   M (ONE_PITR_SET_LOCATOR_SET, mp);
16670
16671   mp->is_add = is_add;
16672   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16673   vec_free (ls_name);
16674
16675   /* send */
16676   S (mp);
16677
16678   /* wait for reply */
16679   W (ret);
16680   return ret;
16681 }
16682
16683 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16684
16685 static int
16686 api_one_nsh_set_locator_set (vat_main_t * vam)
16687 {
16688   u8 ls_name_set = 0;
16689   unformat_input_t *input = vam->input;
16690   vl_api_one_nsh_set_locator_set_t *mp;
16691   u8 is_add = 1;
16692   u8 *ls_name = 0;
16693   int ret;
16694
16695   /* Parse args required to build the message */
16696   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16697     {
16698       if (unformat (input, "del"))
16699         is_add = 0;
16700       else if (unformat (input, "ls %s", &ls_name))
16701         ls_name_set = 1;
16702       else
16703         {
16704           errmsg ("parse error '%U'", format_unformat_error, input);
16705           return -99;
16706         }
16707     }
16708
16709   if (!ls_name_set && is_add)
16710     {
16711       errmsg ("locator-set name not set!");
16712       return -99;
16713     }
16714
16715   M (ONE_NSH_SET_LOCATOR_SET, mp);
16716
16717   mp->is_add = is_add;
16718   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16719   vec_free (ls_name);
16720
16721   /* send */
16722   S (mp);
16723
16724   /* wait for reply */
16725   W (ret);
16726   return ret;
16727 }
16728
16729 static int
16730 api_show_one_pitr (vat_main_t * vam)
16731 {
16732   vl_api_show_one_pitr_t *mp;
16733   int ret;
16734
16735   if (!vam->json_output)
16736     {
16737       print (vam->ofp, "%=20s", "lisp status:");
16738     }
16739
16740   M (SHOW_ONE_PITR, mp);
16741   /* send it... */
16742   S (mp);
16743
16744   /* Wait for a reply... */
16745   W (ret);
16746   return ret;
16747 }
16748
16749 #define api_show_lisp_pitr api_show_one_pitr
16750
16751 static int
16752 api_one_use_petr (vat_main_t * vam)
16753 {
16754   unformat_input_t *input = vam->input;
16755   vl_api_one_use_petr_t *mp;
16756   u8 is_add = 0;
16757   ip_address_t ip;
16758   int ret;
16759
16760   memset (&ip, 0, sizeof (ip));
16761
16762   /* Parse args required to build the message */
16763   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16764     {
16765       if (unformat (input, "disable"))
16766         is_add = 0;
16767       else
16768         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16769         {
16770           is_add = 1;
16771           ip_addr_version (&ip) = IP4;
16772         }
16773       else
16774         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16775         {
16776           is_add = 1;
16777           ip_addr_version (&ip) = IP6;
16778         }
16779       else
16780         {
16781           errmsg ("parse error '%U'", format_unformat_error, input);
16782           return -99;
16783         }
16784     }
16785
16786   M (ONE_USE_PETR, mp);
16787
16788   mp->is_add = is_add;
16789   if (is_add)
16790     {
16791       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16792       if (mp->is_ip4)
16793         clib_memcpy (mp->address, &ip, 4);
16794       else
16795         clib_memcpy (mp->address, &ip, 16);
16796     }
16797
16798   /* send */
16799   S (mp);
16800
16801   /* wait for reply */
16802   W (ret);
16803   return ret;
16804 }
16805
16806 #define api_lisp_use_petr api_one_use_petr
16807
16808 static int
16809 api_show_one_nsh_mapping (vat_main_t * vam)
16810 {
16811   vl_api_show_one_use_petr_t *mp;
16812   int ret;
16813
16814   if (!vam->json_output)
16815     {
16816       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16817     }
16818
16819   M (SHOW_ONE_NSH_MAPPING, mp);
16820   /* send it... */
16821   S (mp);
16822
16823   /* Wait for a reply... */
16824   W (ret);
16825   return ret;
16826 }
16827
16828 static int
16829 api_show_one_use_petr (vat_main_t * vam)
16830 {
16831   vl_api_show_one_use_petr_t *mp;
16832   int ret;
16833
16834   if (!vam->json_output)
16835     {
16836       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16837     }
16838
16839   M (SHOW_ONE_USE_PETR, mp);
16840   /* send it... */
16841   S (mp);
16842
16843   /* Wait for a reply... */
16844   W (ret);
16845   return ret;
16846 }
16847
16848 #define api_show_lisp_use_petr api_show_one_use_petr
16849
16850 /**
16851  * Add/delete mapping between vni and vrf
16852  */
16853 static int
16854 api_one_eid_table_add_del_map (vat_main_t * vam)
16855 {
16856   unformat_input_t *input = vam->input;
16857   vl_api_one_eid_table_add_del_map_t *mp;
16858   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16859   u32 vni, vrf, bd_index;
16860   int ret;
16861
16862   /* Parse args required to build the message */
16863   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16864     {
16865       if (unformat (input, "del"))
16866         is_add = 0;
16867       else if (unformat (input, "vrf %d", &vrf))
16868         vrf_set = 1;
16869       else if (unformat (input, "bd_index %d", &bd_index))
16870         bd_index_set = 1;
16871       else if (unformat (input, "vni %d", &vni))
16872         vni_set = 1;
16873       else
16874         break;
16875     }
16876
16877   if (!vni_set || (!vrf_set && !bd_index_set))
16878     {
16879       errmsg ("missing arguments!");
16880       return -99;
16881     }
16882
16883   if (vrf_set && bd_index_set)
16884     {
16885       errmsg ("error: both vrf and bd entered!");
16886       return -99;
16887     }
16888
16889   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16890
16891   mp->is_add = is_add;
16892   mp->vni = htonl (vni);
16893   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16894   mp->is_l2 = bd_index_set;
16895
16896   /* send */
16897   S (mp);
16898
16899   /* wait for reply */
16900   W (ret);
16901   return ret;
16902 }
16903
16904 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16905
16906 uword
16907 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16908 {
16909   u32 *action = va_arg (*args, u32 *);
16910   u8 *s = 0;
16911
16912   if (unformat (input, "%s", &s))
16913     {
16914       if (!strcmp ((char *) s, "no-action"))
16915         action[0] = 0;
16916       else if (!strcmp ((char *) s, "natively-forward"))
16917         action[0] = 1;
16918       else if (!strcmp ((char *) s, "send-map-request"))
16919         action[0] = 2;
16920       else if (!strcmp ((char *) s, "drop"))
16921         action[0] = 3;
16922       else
16923         {
16924           clib_warning ("invalid action: '%s'", s);
16925           action[0] = 3;
16926         }
16927     }
16928   else
16929     return 0;
16930
16931   vec_free (s);
16932   return 1;
16933 }
16934
16935 /**
16936  * Add/del remote mapping to/from ONE control plane
16937  *
16938  * @param vam vpp API test context
16939  * @return return code
16940  */
16941 static int
16942 api_one_add_del_remote_mapping (vat_main_t * vam)
16943 {
16944   unformat_input_t *input = vam->input;
16945   vl_api_one_add_del_remote_mapping_t *mp;
16946   u32 vni = 0;
16947   lisp_eid_vat_t _eid, *eid = &_eid;
16948   lisp_eid_vat_t _seid, *seid = &_seid;
16949   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
16950   u32 action = ~0, p, w, data_len;
16951   ip4_address_t rloc4;
16952   ip6_address_t rloc6;
16953   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
16954   int ret;
16955
16956   memset (&rloc, 0, sizeof (rloc));
16957
16958   /* Parse args required to build the message */
16959   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16960     {
16961       if (unformat (input, "del-all"))
16962         {
16963           del_all = 1;
16964         }
16965       else if (unformat (input, "del"))
16966         {
16967           is_add = 0;
16968         }
16969       else if (unformat (input, "add"))
16970         {
16971           is_add = 1;
16972         }
16973       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16974         {
16975           eid_set = 1;
16976         }
16977       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
16978         {
16979           seid_set = 1;
16980         }
16981       else if (unformat (input, "vni %d", &vni))
16982         {
16983           ;
16984         }
16985       else if (unformat (input, "p %d w %d", &p, &w))
16986         {
16987           if (!curr_rloc)
16988             {
16989               errmsg ("No RLOC configured for setting priority/weight!");
16990               return -99;
16991             }
16992           curr_rloc->priority = p;
16993           curr_rloc->weight = w;
16994         }
16995       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
16996         {
16997           rloc.is_ip4 = 1;
16998           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
16999           vec_add1 (rlocs, rloc);
17000           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17001         }
17002       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
17003         {
17004           rloc.is_ip4 = 0;
17005           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17006           vec_add1 (rlocs, rloc);
17007           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17008         }
17009       else if (unformat (input, "action %U",
17010                          unformat_negative_mapping_action, &action))
17011         {
17012           ;
17013         }
17014       else
17015         {
17016           clib_warning ("parse error '%U'", format_unformat_error, input);
17017           return -99;
17018         }
17019     }
17020
17021   if (0 == eid_set)
17022     {
17023       errmsg ("missing params!");
17024       return -99;
17025     }
17026
17027   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17028     {
17029       errmsg ("no action set for negative map-reply!");
17030       return -99;
17031     }
17032
17033   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17034
17035   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17036   mp->is_add = is_add;
17037   mp->vni = htonl (vni);
17038   mp->action = (u8) action;
17039   mp->is_src_dst = seid_set;
17040   mp->eid_len = eid->len;
17041   mp->seid_len = seid->len;
17042   mp->del_all = del_all;
17043   mp->eid_type = eid->type;
17044   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17045   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17046
17047   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17048   clib_memcpy (mp->rlocs, rlocs, data_len);
17049   vec_free (rlocs);
17050
17051   /* send it... */
17052   S (mp);
17053
17054   /* Wait for a reply... */
17055   W (ret);
17056   return ret;
17057 }
17058
17059 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17060
17061 /**
17062  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17063  * forwarding entries in data-plane accordingly.
17064  *
17065  * @param vam vpp API test context
17066  * @return return code
17067  */
17068 static int
17069 api_one_add_del_adjacency (vat_main_t * vam)
17070 {
17071   unformat_input_t *input = vam->input;
17072   vl_api_one_add_del_adjacency_t *mp;
17073   u32 vni = 0;
17074   ip4_address_t leid4, reid4;
17075   ip6_address_t leid6, reid6;
17076   u8 reid_mac[6] = { 0 };
17077   u8 leid_mac[6] = { 0 };
17078   u8 reid_type, leid_type;
17079   u32 leid_len = 0, reid_len = 0, len;
17080   u8 is_add = 1;
17081   int ret;
17082
17083   leid_type = reid_type = (u8) ~ 0;
17084
17085   /* Parse args required to build the message */
17086   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17087     {
17088       if (unformat (input, "del"))
17089         {
17090           is_add = 0;
17091         }
17092       else if (unformat (input, "add"))
17093         {
17094           is_add = 1;
17095         }
17096       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17097                          &reid4, &len))
17098         {
17099           reid_type = 0;        /* ipv4 */
17100           reid_len = len;
17101         }
17102       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17103                          &reid6, &len))
17104         {
17105           reid_type = 1;        /* ipv6 */
17106           reid_len = len;
17107         }
17108       else if (unformat (input, "reid %U", unformat_ethernet_address,
17109                          reid_mac))
17110         {
17111           reid_type = 2;        /* mac */
17112         }
17113       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17114                          &leid4, &len))
17115         {
17116           leid_type = 0;        /* ipv4 */
17117           leid_len = len;
17118         }
17119       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17120                          &leid6, &len))
17121         {
17122           leid_type = 1;        /* ipv6 */
17123           leid_len = len;
17124         }
17125       else if (unformat (input, "leid %U", unformat_ethernet_address,
17126                          leid_mac))
17127         {
17128           leid_type = 2;        /* mac */
17129         }
17130       else if (unformat (input, "vni %d", &vni))
17131         {
17132           ;
17133         }
17134       else
17135         {
17136           errmsg ("parse error '%U'", format_unformat_error, input);
17137           return -99;
17138         }
17139     }
17140
17141   if ((u8) ~ 0 == reid_type)
17142     {
17143       errmsg ("missing params!");
17144       return -99;
17145     }
17146
17147   if (leid_type != reid_type)
17148     {
17149       errmsg ("remote and local EIDs are of different types!");
17150       return -99;
17151     }
17152
17153   M (ONE_ADD_DEL_ADJACENCY, mp);
17154   mp->is_add = is_add;
17155   mp->vni = htonl (vni);
17156   mp->leid_len = leid_len;
17157   mp->reid_len = reid_len;
17158   mp->eid_type = reid_type;
17159
17160   switch (mp->eid_type)
17161     {
17162     case 0:
17163       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17164       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17165       break;
17166     case 1:
17167       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17168       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17169       break;
17170     case 2:
17171       clib_memcpy (mp->leid, leid_mac, 6);
17172       clib_memcpy (mp->reid, reid_mac, 6);
17173       break;
17174     default:
17175       errmsg ("unknown EID type %d!", mp->eid_type);
17176       return 0;
17177     }
17178
17179   /* send it... */
17180   S (mp);
17181
17182   /* Wait for a reply... */
17183   W (ret);
17184   return ret;
17185 }
17186
17187 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17188
17189 uword
17190 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17191 {
17192   u32 *mode = va_arg (*args, u32 *);
17193
17194   if (unformat (input, "lisp"))
17195     *mode = 0;
17196   else if (unformat (input, "vxlan"))
17197     *mode = 1;
17198   else
17199     return 0;
17200
17201   return 1;
17202 }
17203
17204 static int
17205 api_gpe_get_encap_mode (vat_main_t * vam)
17206 {
17207   vl_api_gpe_get_encap_mode_t *mp;
17208   int ret;
17209
17210   /* Construct the API message */
17211   M (GPE_GET_ENCAP_MODE, mp);
17212
17213   /* send it... */
17214   S (mp);
17215
17216   /* Wait for a reply... */
17217   W (ret);
17218   return ret;
17219 }
17220
17221 static int
17222 api_gpe_set_encap_mode (vat_main_t * vam)
17223 {
17224   unformat_input_t *input = vam->input;
17225   vl_api_gpe_set_encap_mode_t *mp;
17226   int ret;
17227   u32 mode = 0;
17228
17229   /* Parse args required to build the message */
17230   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17231     {
17232       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17233         ;
17234       else
17235         break;
17236     }
17237
17238   /* Construct the API message */
17239   M (GPE_SET_ENCAP_MODE, mp);
17240
17241   mp->mode = mode;
17242
17243   /* send it... */
17244   S (mp);
17245
17246   /* Wait for a reply... */
17247   W (ret);
17248   return ret;
17249 }
17250
17251 static int
17252 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17253 {
17254   unformat_input_t *input = vam->input;
17255   vl_api_gpe_add_del_iface_t *mp;
17256   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17257   u32 dp_table = 0, vni = 0;
17258   int ret;
17259
17260   /* Parse args required to build the message */
17261   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17262     {
17263       if (unformat (input, "up"))
17264         {
17265           action_set = 1;
17266           is_add = 1;
17267         }
17268       else if (unformat (input, "down"))
17269         {
17270           action_set = 1;
17271           is_add = 0;
17272         }
17273       else if (unformat (input, "table_id %d", &dp_table))
17274         {
17275           dp_table_set = 1;
17276         }
17277       else if (unformat (input, "bd_id %d", &dp_table))
17278         {
17279           dp_table_set = 1;
17280           is_l2 = 1;
17281         }
17282       else if (unformat (input, "vni %d", &vni))
17283         {
17284           vni_set = 1;
17285         }
17286       else
17287         break;
17288     }
17289
17290   if (action_set == 0)
17291     {
17292       errmsg ("Action not set");
17293       return -99;
17294     }
17295   if (dp_table_set == 0 || vni_set == 0)
17296     {
17297       errmsg ("vni and dp_table must be set");
17298       return -99;
17299     }
17300
17301   /* Construct the API message */
17302   M (GPE_ADD_DEL_IFACE, mp);
17303
17304   mp->is_add = is_add;
17305   mp->dp_table = clib_host_to_net_u32 (dp_table);
17306   mp->is_l2 = is_l2;
17307   mp->vni = clib_host_to_net_u32 (vni);
17308
17309   /* send it... */
17310   S (mp);
17311
17312   /* Wait for a reply... */
17313   W (ret);
17314   return ret;
17315 }
17316
17317 static int
17318 api_one_map_register_fallback_threshold (vat_main_t * vam)
17319 {
17320   unformat_input_t *input = vam->input;
17321   vl_api_one_map_register_fallback_threshold_t *mp;
17322   u32 value = 0;
17323   u8 is_set = 0;
17324   int ret;
17325
17326   /* Parse args required to build the message */
17327   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17328     {
17329       if (unformat (input, "%u", &value))
17330         is_set = 1;
17331       else
17332         {
17333           clib_warning ("parse error '%U'", format_unformat_error, input);
17334           return -99;
17335         }
17336     }
17337
17338   if (!is_set)
17339     {
17340       errmsg ("fallback threshold value is missing!");
17341       return -99;
17342     }
17343
17344   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17345   mp->value = clib_host_to_net_u32 (value);
17346
17347   /* send it... */
17348   S (mp);
17349
17350   /* Wait for a reply... */
17351   W (ret);
17352   return ret;
17353 }
17354
17355 static int
17356 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17357 {
17358   vl_api_show_one_map_register_fallback_threshold_t *mp;
17359   int ret;
17360
17361   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17362
17363   /* send it... */
17364   S (mp);
17365
17366   /* Wait for a reply... */
17367   W (ret);
17368   return ret;
17369 }
17370
17371 uword
17372 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17373 {
17374   u32 *proto = va_arg (*args, u32 *);
17375
17376   if (unformat (input, "udp"))
17377     *proto = 1;
17378   else if (unformat (input, "api"))
17379     *proto = 2;
17380   else
17381     return 0;
17382
17383   return 1;
17384 }
17385
17386 static int
17387 api_one_set_transport_protocol (vat_main_t * vam)
17388 {
17389   unformat_input_t *input = vam->input;
17390   vl_api_one_set_transport_protocol_t *mp;
17391   u8 is_set = 0;
17392   u32 protocol = 0;
17393   int ret;
17394
17395   /* Parse args required to build the message */
17396   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17397     {
17398       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17399         is_set = 1;
17400       else
17401         {
17402           clib_warning ("parse error '%U'", format_unformat_error, input);
17403           return -99;
17404         }
17405     }
17406
17407   if (!is_set)
17408     {
17409       errmsg ("Transport protocol missing!");
17410       return -99;
17411     }
17412
17413   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17414   mp->protocol = (u8) protocol;
17415
17416   /* send it... */
17417   S (mp);
17418
17419   /* Wait for a reply... */
17420   W (ret);
17421   return ret;
17422 }
17423
17424 static int
17425 api_one_get_transport_protocol (vat_main_t * vam)
17426 {
17427   vl_api_one_get_transport_protocol_t *mp;
17428   int ret;
17429
17430   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17431
17432   /* send it... */
17433   S (mp);
17434
17435   /* Wait for a reply... */
17436   W (ret);
17437   return ret;
17438 }
17439
17440 static int
17441 api_one_map_register_set_ttl (vat_main_t * vam)
17442 {
17443   unformat_input_t *input = vam->input;
17444   vl_api_one_map_register_set_ttl_t *mp;
17445   u32 ttl = 0;
17446   u8 is_set = 0;
17447   int ret;
17448
17449   /* Parse args required to build the message */
17450   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17451     {
17452       if (unformat (input, "%u", &ttl))
17453         is_set = 1;
17454       else
17455         {
17456           clib_warning ("parse error '%U'", format_unformat_error, input);
17457           return -99;
17458         }
17459     }
17460
17461   if (!is_set)
17462     {
17463       errmsg ("TTL value missing!");
17464       return -99;
17465     }
17466
17467   M (ONE_MAP_REGISTER_SET_TTL, mp);
17468   mp->ttl = clib_host_to_net_u32 (ttl);
17469
17470   /* send it... */
17471   S (mp);
17472
17473   /* Wait for a reply... */
17474   W (ret);
17475   return ret;
17476 }
17477
17478 static int
17479 api_show_one_map_register_ttl (vat_main_t * vam)
17480 {
17481   vl_api_show_one_map_register_ttl_t *mp;
17482   int ret;
17483
17484   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17485
17486   /* send it... */
17487   S (mp);
17488
17489   /* Wait for a reply... */
17490   W (ret);
17491   return ret;
17492 }
17493
17494 /**
17495  * Add/del map request itr rlocs from ONE control plane and updates
17496  *
17497  * @param vam vpp API test context
17498  * @return return code
17499  */
17500 static int
17501 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17502 {
17503   unformat_input_t *input = vam->input;
17504   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17505   u8 *locator_set_name = 0;
17506   u8 locator_set_name_set = 0;
17507   u8 is_add = 1;
17508   int ret;
17509
17510   /* Parse args required to build the message */
17511   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17512     {
17513       if (unformat (input, "del"))
17514         {
17515           is_add = 0;
17516         }
17517       else if (unformat (input, "%_%v%_", &locator_set_name))
17518         {
17519           locator_set_name_set = 1;
17520         }
17521       else
17522         {
17523           clib_warning ("parse error '%U'", format_unformat_error, input);
17524           return -99;
17525         }
17526     }
17527
17528   if (is_add && !locator_set_name_set)
17529     {
17530       errmsg ("itr-rloc is not set!");
17531       return -99;
17532     }
17533
17534   if (is_add && vec_len (locator_set_name) > 64)
17535     {
17536       errmsg ("itr-rloc locator-set name too long");
17537       vec_free (locator_set_name);
17538       return -99;
17539     }
17540
17541   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17542   mp->is_add = is_add;
17543   if (is_add)
17544     {
17545       clib_memcpy (mp->locator_set_name, locator_set_name,
17546                    vec_len (locator_set_name));
17547     }
17548   else
17549     {
17550       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17551     }
17552   vec_free (locator_set_name);
17553
17554   /* send it... */
17555   S (mp);
17556
17557   /* Wait for a reply... */
17558   W (ret);
17559   return ret;
17560 }
17561
17562 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17563
17564 static int
17565 api_one_locator_dump (vat_main_t * vam)
17566 {
17567   unformat_input_t *input = vam->input;
17568   vl_api_one_locator_dump_t *mp;
17569   vl_api_control_ping_t *mp_ping;
17570   u8 is_index_set = 0, is_name_set = 0;
17571   u8 *ls_name = 0;
17572   u32 ls_index = ~0;
17573   int ret;
17574
17575   /* Parse args required to build the message */
17576   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17577     {
17578       if (unformat (input, "ls_name %_%v%_", &ls_name))
17579         {
17580           is_name_set = 1;
17581         }
17582       else if (unformat (input, "ls_index %d", &ls_index))
17583         {
17584           is_index_set = 1;
17585         }
17586       else
17587         {
17588           errmsg ("parse error '%U'", format_unformat_error, input);
17589           return -99;
17590         }
17591     }
17592
17593   if (!is_index_set && !is_name_set)
17594     {
17595       errmsg ("error: expected one of index or name!");
17596       return -99;
17597     }
17598
17599   if (is_index_set && is_name_set)
17600     {
17601       errmsg ("error: only one param expected!");
17602       return -99;
17603     }
17604
17605   if (vec_len (ls_name) > 62)
17606     {
17607       errmsg ("error: locator set name too long!");
17608       return -99;
17609     }
17610
17611   if (!vam->json_output)
17612     {
17613       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17614     }
17615
17616   M (ONE_LOCATOR_DUMP, mp);
17617   mp->is_index_set = is_index_set;
17618
17619   if (is_index_set)
17620     mp->ls_index = clib_host_to_net_u32 (ls_index);
17621   else
17622     {
17623       vec_add1 (ls_name, 0);
17624       strncpy ((char *) mp->ls_name, (char *) ls_name,
17625                sizeof (mp->ls_name) - 1);
17626     }
17627
17628   /* send it... */
17629   S (mp);
17630
17631   /* Use a control ping for synchronization */
17632   MPING (CONTROL_PING, mp_ping);
17633   S (mp_ping);
17634
17635   /* Wait for a reply... */
17636   W (ret);
17637   return ret;
17638 }
17639
17640 #define api_lisp_locator_dump api_one_locator_dump
17641
17642 static int
17643 api_one_locator_set_dump (vat_main_t * vam)
17644 {
17645   vl_api_one_locator_set_dump_t *mp;
17646   vl_api_control_ping_t *mp_ping;
17647   unformat_input_t *input = vam->input;
17648   u8 filter = 0;
17649   int ret;
17650
17651   /* Parse args required to build the message */
17652   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17653     {
17654       if (unformat (input, "local"))
17655         {
17656           filter = 1;
17657         }
17658       else if (unformat (input, "remote"))
17659         {
17660           filter = 2;
17661         }
17662       else
17663         {
17664           errmsg ("parse error '%U'", format_unformat_error, input);
17665           return -99;
17666         }
17667     }
17668
17669   if (!vam->json_output)
17670     {
17671       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17672     }
17673
17674   M (ONE_LOCATOR_SET_DUMP, mp);
17675
17676   mp->filter = filter;
17677
17678   /* send it... */
17679   S (mp);
17680
17681   /* Use a control ping for synchronization */
17682   MPING (CONTROL_PING, mp_ping);
17683   S (mp_ping);
17684
17685   /* Wait for a reply... */
17686   W (ret);
17687   return ret;
17688 }
17689
17690 #define api_lisp_locator_set_dump api_one_locator_set_dump
17691
17692 static int
17693 api_one_eid_table_map_dump (vat_main_t * vam)
17694 {
17695   u8 is_l2 = 0;
17696   u8 mode_set = 0;
17697   unformat_input_t *input = vam->input;
17698   vl_api_one_eid_table_map_dump_t *mp;
17699   vl_api_control_ping_t *mp_ping;
17700   int ret;
17701
17702   /* Parse args required to build the message */
17703   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17704     {
17705       if (unformat (input, "l2"))
17706         {
17707           is_l2 = 1;
17708           mode_set = 1;
17709         }
17710       else if (unformat (input, "l3"))
17711         {
17712           is_l2 = 0;
17713           mode_set = 1;
17714         }
17715       else
17716         {
17717           errmsg ("parse error '%U'", format_unformat_error, input);
17718           return -99;
17719         }
17720     }
17721
17722   if (!mode_set)
17723     {
17724       errmsg ("expected one of 'l2' or 'l3' parameter!");
17725       return -99;
17726     }
17727
17728   if (!vam->json_output)
17729     {
17730       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17731     }
17732
17733   M (ONE_EID_TABLE_MAP_DUMP, mp);
17734   mp->is_l2 = is_l2;
17735
17736   /* send it... */
17737   S (mp);
17738
17739   /* Use a control ping for synchronization */
17740   MPING (CONTROL_PING, mp_ping);
17741   S (mp_ping);
17742
17743   /* Wait for a reply... */
17744   W (ret);
17745   return ret;
17746 }
17747
17748 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17749
17750 static int
17751 api_one_eid_table_vni_dump (vat_main_t * vam)
17752 {
17753   vl_api_one_eid_table_vni_dump_t *mp;
17754   vl_api_control_ping_t *mp_ping;
17755   int ret;
17756
17757   if (!vam->json_output)
17758     {
17759       print (vam->ofp, "VNI");
17760     }
17761
17762   M (ONE_EID_TABLE_VNI_DUMP, mp);
17763
17764   /* send it... */
17765   S (mp);
17766
17767   /* Use a control ping for synchronization */
17768   MPING (CONTROL_PING, mp_ping);
17769   S (mp_ping);
17770
17771   /* Wait for a reply... */
17772   W (ret);
17773   return ret;
17774 }
17775
17776 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17777
17778 static int
17779 api_one_eid_table_dump (vat_main_t * vam)
17780 {
17781   unformat_input_t *i = vam->input;
17782   vl_api_one_eid_table_dump_t *mp;
17783   vl_api_control_ping_t *mp_ping;
17784   struct in_addr ip4;
17785   struct in6_addr ip6;
17786   u8 mac[6];
17787   u8 eid_type = ~0, eid_set = 0;
17788   u32 prefix_length = ~0, t, vni = 0;
17789   u8 filter = 0;
17790   int ret;
17791   lisp_nsh_api_t nsh;
17792
17793   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17794     {
17795       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17796         {
17797           eid_set = 1;
17798           eid_type = 0;
17799           prefix_length = t;
17800         }
17801       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17802         {
17803           eid_set = 1;
17804           eid_type = 1;
17805           prefix_length = t;
17806         }
17807       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17808         {
17809           eid_set = 1;
17810           eid_type = 2;
17811         }
17812       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17813         {
17814           eid_set = 1;
17815           eid_type = 3;
17816         }
17817       else if (unformat (i, "vni %d", &t))
17818         {
17819           vni = t;
17820         }
17821       else if (unformat (i, "local"))
17822         {
17823           filter = 1;
17824         }
17825       else if (unformat (i, "remote"))
17826         {
17827           filter = 2;
17828         }
17829       else
17830         {
17831           errmsg ("parse error '%U'", format_unformat_error, i);
17832           return -99;
17833         }
17834     }
17835
17836   if (!vam->json_output)
17837     {
17838       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17839              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17840     }
17841
17842   M (ONE_EID_TABLE_DUMP, mp);
17843
17844   mp->filter = filter;
17845   if (eid_set)
17846     {
17847       mp->eid_set = 1;
17848       mp->vni = htonl (vni);
17849       mp->eid_type = eid_type;
17850       switch (eid_type)
17851         {
17852         case 0:
17853           mp->prefix_length = prefix_length;
17854           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17855           break;
17856         case 1:
17857           mp->prefix_length = prefix_length;
17858           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17859           break;
17860         case 2:
17861           clib_memcpy (mp->eid, mac, sizeof (mac));
17862           break;
17863         case 3:
17864           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17865           break;
17866         default:
17867           errmsg ("unknown EID type %d!", eid_type);
17868           return -99;
17869         }
17870     }
17871
17872   /* send it... */
17873   S (mp);
17874
17875   /* Use a control ping for synchronization */
17876   MPING (CONTROL_PING, mp_ping);
17877   S (mp_ping);
17878
17879   /* Wait for a reply... */
17880   W (ret);
17881   return ret;
17882 }
17883
17884 #define api_lisp_eid_table_dump api_one_eid_table_dump
17885
17886 static int
17887 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17888 {
17889   unformat_input_t *i = vam->input;
17890   vl_api_gpe_fwd_entries_get_t *mp;
17891   u8 vni_set = 0;
17892   u32 vni = ~0;
17893   int ret;
17894
17895   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17896     {
17897       if (unformat (i, "vni %d", &vni))
17898         {
17899           vni_set = 1;
17900         }
17901       else
17902         {
17903           errmsg ("parse error '%U'", format_unformat_error, i);
17904           return -99;
17905         }
17906     }
17907
17908   if (!vni_set)
17909     {
17910       errmsg ("vni not set!");
17911       return -99;
17912     }
17913
17914   if (!vam->json_output)
17915     {
17916       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17917              "leid", "reid");
17918     }
17919
17920   M (GPE_FWD_ENTRIES_GET, mp);
17921   mp->vni = clib_host_to_net_u32 (vni);
17922
17923   /* send it... */
17924   S (mp);
17925
17926   /* Wait for a reply... */
17927   W (ret);
17928   return ret;
17929 }
17930
17931 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
17932 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
17933 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
17934 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
17935 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
17936 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
17937 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
17938 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
17939
17940 static int
17941 api_one_adjacencies_get (vat_main_t * vam)
17942 {
17943   unformat_input_t *i = vam->input;
17944   vl_api_one_adjacencies_get_t *mp;
17945   u8 vni_set = 0;
17946   u32 vni = ~0;
17947   int ret;
17948
17949   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17950     {
17951       if (unformat (i, "vni %d", &vni))
17952         {
17953           vni_set = 1;
17954         }
17955       else
17956         {
17957           errmsg ("parse error '%U'", format_unformat_error, i);
17958           return -99;
17959         }
17960     }
17961
17962   if (!vni_set)
17963     {
17964       errmsg ("vni not set!");
17965       return -99;
17966     }
17967
17968   if (!vam->json_output)
17969     {
17970       print (vam->ofp, "%s %40s", "leid", "reid");
17971     }
17972
17973   M (ONE_ADJACENCIES_GET, mp);
17974   mp->vni = clib_host_to_net_u32 (vni);
17975
17976   /* send it... */
17977   S (mp);
17978
17979   /* Wait for a reply... */
17980   W (ret);
17981   return ret;
17982 }
17983
17984 #define api_lisp_adjacencies_get api_one_adjacencies_get
17985
17986 static int
17987 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
17988 {
17989   unformat_input_t *i = vam->input;
17990   vl_api_gpe_native_fwd_rpaths_get_t *mp;
17991   int ret;
17992   u8 ip_family_set = 0, is_ip4 = 1;
17993
17994   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17995     {
17996       if (unformat (i, "ip4"))
17997         {
17998           ip_family_set = 1;
17999           is_ip4 = 1;
18000         }
18001       else if (unformat (i, "ip6"))
18002         {
18003           ip_family_set = 1;
18004           is_ip4 = 0;
18005         }
18006       else
18007         {
18008           errmsg ("parse error '%U'", format_unformat_error, i);
18009           return -99;
18010         }
18011     }
18012
18013   if (!ip_family_set)
18014     {
18015       errmsg ("ip family not set!");
18016       return -99;
18017     }
18018
18019   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18020   mp->is_ip4 = is_ip4;
18021
18022   /* send it... */
18023   S (mp);
18024
18025   /* Wait for a reply... */
18026   W (ret);
18027   return ret;
18028 }
18029
18030 static int
18031 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18032 {
18033   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18034   int ret;
18035
18036   if (!vam->json_output)
18037     {
18038       print (vam->ofp, "VNIs");
18039     }
18040
18041   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18042
18043   /* send it... */
18044   S (mp);
18045
18046   /* Wait for a reply... */
18047   W (ret);
18048   return ret;
18049 }
18050
18051 static int
18052 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18053 {
18054   unformat_input_t *i = vam->input;
18055   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18056   int ret = 0;
18057   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18058   struct in_addr ip4;
18059   struct in6_addr ip6;
18060   u32 table_id = 0, nh_sw_if_index = ~0;
18061
18062   memset (&ip4, 0, sizeof (ip4));
18063   memset (&ip6, 0, sizeof (ip6));
18064
18065   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18066     {
18067       if (unformat (i, "del"))
18068         is_add = 0;
18069       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18070                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18071         {
18072           ip_set = 1;
18073           is_ip4 = 1;
18074         }
18075       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18076                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18077         {
18078           ip_set = 1;
18079           is_ip4 = 0;
18080         }
18081       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18082         {
18083           ip_set = 1;
18084           is_ip4 = 1;
18085           nh_sw_if_index = ~0;
18086         }
18087       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18088         {
18089           ip_set = 1;
18090           is_ip4 = 0;
18091           nh_sw_if_index = ~0;
18092         }
18093       else if (unformat (i, "table %d", &table_id))
18094         ;
18095       else
18096         {
18097           errmsg ("parse error '%U'", format_unformat_error, i);
18098           return -99;
18099         }
18100     }
18101
18102   if (!ip_set)
18103     {
18104       errmsg ("nh addr not set!");
18105       return -99;
18106     }
18107
18108   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18109   mp->is_add = is_add;
18110   mp->table_id = clib_host_to_net_u32 (table_id);
18111   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18112   mp->is_ip4 = is_ip4;
18113   if (is_ip4)
18114     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18115   else
18116     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18117
18118   /* send it... */
18119   S (mp);
18120
18121   /* Wait for a reply... */
18122   W (ret);
18123   return ret;
18124 }
18125
18126 static int
18127 api_one_map_server_dump (vat_main_t * vam)
18128 {
18129   vl_api_one_map_server_dump_t *mp;
18130   vl_api_control_ping_t *mp_ping;
18131   int ret;
18132
18133   if (!vam->json_output)
18134     {
18135       print (vam->ofp, "%=20s", "Map server");
18136     }
18137
18138   M (ONE_MAP_SERVER_DUMP, mp);
18139   /* send it... */
18140   S (mp);
18141
18142   /* Use a control ping for synchronization */
18143   MPING (CONTROL_PING, mp_ping);
18144   S (mp_ping);
18145
18146   /* Wait for a reply... */
18147   W (ret);
18148   return ret;
18149 }
18150
18151 #define api_lisp_map_server_dump api_one_map_server_dump
18152
18153 static int
18154 api_one_map_resolver_dump (vat_main_t * vam)
18155 {
18156   vl_api_one_map_resolver_dump_t *mp;
18157   vl_api_control_ping_t *mp_ping;
18158   int ret;
18159
18160   if (!vam->json_output)
18161     {
18162       print (vam->ofp, "%=20s", "Map resolver");
18163     }
18164
18165   M (ONE_MAP_RESOLVER_DUMP, mp);
18166   /* send it... */
18167   S (mp);
18168
18169   /* Use a control ping for synchronization */
18170   MPING (CONTROL_PING, mp_ping);
18171   S (mp_ping);
18172
18173   /* Wait for a reply... */
18174   W (ret);
18175   return ret;
18176 }
18177
18178 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18179
18180 static int
18181 api_one_stats_flush (vat_main_t * vam)
18182 {
18183   vl_api_one_stats_flush_t *mp;
18184   int ret = 0;
18185
18186   M (ONE_STATS_FLUSH, mp);
18187   S (mp);
18188   W (ret);
18189   return ret;
18190 }
18191
18192 static int
18193 api_one_stats_dump (vat_main_t * vam)
18194 {
18195   vl_api_one_stats_dump_t *mp;
18196   vl_api_control_ping_t *mp_ping;
18197   int ret;
18198
18199   M (ONE_STATS_DUMP, mp);
18200   /* send it... */
18201   S (mp);
18202
18203   /* Use a control ping for synchronization */
18204   MPING (CONTROL_PING, mp_ping);
18205   S (mp_ping);
18206
18207   /* Wait for a reply... */
18208   W (ret);
18209   return ret;
18210 }
18211
18212 static int
18213 api_show_one_status (vat_main_t * vam)
18214 {
18215   vl_api_show_one_status_t *mp;
18216   int ret;
18217
18218   if (!vam->json_output)
18219     {
18220       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18221     }
18222
18223   M (SHOW_ONE_STATUS, mp);
18224   /* send it... */
18225   S (mp);
18226   /* Wait for a reply... */
18227   W (ret);
18228   return ret;
18229 }
18230
18231 #define api_show_lisp_status api_show_one_status
18232
18233 static int
18234 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18235 {
18236   vl_api_gpe_fwd_entry_path_dump_t *mp;
18237   vl_api_control_ping_t *mp_ping;
18238   unformat_input_t *i = vam->input;
18239   u32 fwd_entry_index = ~0;
18240   int ret;
18241
18242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18243     {
18244       if (unformat (i, "index %d", &fwd_entry_index))
18245         ;
18246       else
18247         break;
18248     }
18249
18250   if (~0 == fwd_entry_index)
18251     {
18252       errmsg ("no index specified!");
18253       return -99;
18254     }
18255
18256   if (!vam->json_output)
18257     {
18258       print (vam->ofp, "first line");
18259     }
18260
18261   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18262
18263   /* send it... */
18264   S (mp);
18265   /* Use a control ping for synchronization */
18266   MPING (CONTROL_PING, mp_ping);
18267   S (mp_ping);
18268
18269   /* Wait for a reply... */
18270   W (ret);
18271   return ret;
18272 }
18273
18274 static int
18275 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18276 {
18277   vl_api_one_get_map_request_itr_rlocs_t *mp;
18278   int ret;
18279
18280   if (!vam->json_output)
18281     {
18282       print (vam->ofp, "%=20s", "itr-rlocs:");
18283     }
18284
18285   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18286   /* send it... */
18287   S (mp);
18288   /* Wait for a reply... */
18289   W (ret);
18290   return ret;
18291 }
18292
18293 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18294
18295 static int
18296 api_af_packet_create (vat_main_t * vam)
18297 {
18298   unformat_input_t *i = vam->input;
18299   vl_api_af_packet_create_t *mp;
18300   u8 *host_if_name = 0;
18301   u8 hw_addr[6];
18302   u8 random_hw_addr = 1;
18303   int ret;
18304
18305   memset (hw_addr, 0, sizeof (hw_addr));
18306
18307   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18308     {
18309       if (unformat (i, "name %s", &host_if_name))
18310         vec_add1 (host_if_name, 0);
18311       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18312         random_hw_addr = 0;
18313       else
18314         break;
18315     }
18316
18317   if (!vec_len (host_if_name))
18318     {
18319       errmsg ("host-interface name must be specified");
18320       return -99;
18321     }
18322
18323   if (vec_len (host_if_name) > 64)
18324     {
18325       errmsg ("host-interface name too long");
18326       return -99;
18327     }
18328
18329   M (AF_PACKET_CREATE, mp);
18330
18331   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18332   clib_memcpy (mp->hw_addr, hw_addr, 6);
18333   mp->use_random_hw_addr = random_hw_addr;
18334   vec_free (host_if_name);
18335
18336   S (mp);
18337
18338   /* *INDENT-OFF* */
18339   W2 (ret,
18340       ({
18341         if (ret == 0)
18342           fprintf (vam->ofp ? vam->ofp : stderr,
18343                    " new sw_if_index = %d\n", vam->sw_if_index);
18344       }));
18345   /* *INDENT-ON* */
18346   return ret;
18347 }
18348
18349 static int
18350 api_af_packet_delete (vat_main_t * vam)
18351 {
18352   unformat_input_t *i = vam->input;
18353   vl_api_af_packet_delete_t *mp;
18354   u8 *host_if_name = 0;
18355   int ret;
18356
18357   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18358     {
18359       if (unformat (i, "name %s", &host_if_name))
18360         vec_add1 (host_if_name, 0);
18361       else
18362         break;
18363     }
18364
18365   if (!vec_len (host_if_name))
18366     {
18367       errmsg ("host-interface name must be specified");
18368       return -99;
18369     }
18370
18371   if (vec_len (host_if_name) > 64)
18372     {
18373       errmsg ("host-interface name too long");
18374       return -99;
18375     }
18376
18377   M (AF_PACKET_DELETE, mp);
18378
18379   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18380   vec_free (host_if_name);
18381
18382   S (mp);
18383   W (ret);
18384   return ret;
18385 }
18386
18387 static int
18388 api_policer_add_del (vat_main_t * vam)
18389 {
18390   unformat_input_t *i = vam->input;
18391   vl_api_policer_add_del_t *mp;
18392   u8 is_add = 1;
18393   u8 *name = 0;
18394   u32 cir = 0;
18395   u32 eir = 0;
18396   u64 cb = 0;
18397   u64 eb = 0;
18398   u8 rate_type = 0;
18399   u8 round_type = 0;
18400   u8 type = 0;
18401   u8 color_aware = 0;
18402   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18403   int ret;
18404
18405   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18406   conform_action.dscp = 0;
18407   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18408   exceed_action.dscp = 0;
18409   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18410   violate_action.dscp = 0;
18411
18412   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18413     {
18414       if (unformat (i, "del"))
18415         is_add = 0;
18416       else if (unformat (i, "name %s", &name))
18417         vec_add1 (name, 0);
18418       else if (unformat (i, "cir %u", &cir))
18419         ;
18420       else if (unformat (i, "eir %u", &eir))
18421         ;
18422       else if (unformat (i, "cb %u", &cb))
18423         ;
18424       else if (unformat (i, "eb %u", &eb))
18425         ;
18426       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18427                          &rate_type))
18428         ;
18429       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18430                          &round_type))
18431         ;
18432       else if (unformat (i, "type %U", unformat_policer_type, &type))
18433         ;
18434       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18435                          &conform_action))
18436         ;
18437       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18438                          &exceed_action))
18439         ;
18440       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18441                          &violate_action))
18442         ;
18443       else if (unformat (i, "color-aware"))
18444         color_aware = 1;
18445       else
18446         break;
18447     }
18448
18449   if (!vec_len (name))
18450     {
18451       errmsg ("policer name must be specified");
18452       return -99;
18453     }
18454
18455   if (vec_len (name) > 64)
18456     {
18457       errmsg ("policer name too long");
18458       return -99;
18459     }
18460
18461   M (POLICER_ADD_DEL, mp);
18462
18463   clib_memcpy (mp->name, name, vec_len (name));
18464   vec_free (name);
18465   mp->is_add = is_add;
18466   mp->cir = ntohl (cir);
18467   mp->eir = ntohl (eir);
18468   mp->cb = clib_net_to_host_u64 (cb);
18469   mp->eb = clib_net_to_host_u64 (eb);
18470   mp->rate_type = rate_type;
18471   mp->round_type = round_type;
18472   mp->type = type;
18473   mp->conform_action_type = conform_action.action_type;
18474   mp->conform_dscp = conform_action.dscp;
18475   mp->exceed_action_type = exceed_action.action_type;
18476   mp->exceed_dscp = exceed_action.dscp;
18477   mp->violate_action_type = violate_action.action_type;
18478   mp->violate_dscp = violate_action.dscp;
18479   mp->color_aware = color_aware;
18480
18481   S (mp);
18482   W (ret);
18483   return ret;
18484 }
18485
18486 static int
18487 api_policer_dump (vat_main_t * vam)
18488 {
18489   unformat_input_t *i = vam->input;
18490   vl_api_policer_dump_t *mp;
18491   vl_api_control_ping_t *mp_ping;
18492   u8 *match_name = 0;
18493   u8 match_name_valid = 0;
18494   int ret;
18495
18496   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18497     {
18498       if (unformat (i, "name %s", &match_name))
18499         {
18500           vec_add1 (match_name, 0);
18501           match_name_valid = 1;
18502         }
18503       else
18504         break;
18505     }
18506
18507   M (POLICER_DUMP, mp);
18508   mp->match_name_valid = match_name_valid;
18509   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18510   vec_free (match_name);
18511   /* send it... */
18512   S (mp);
18513
18514   /* Use a control ping for synchronization */
18515   MPING (CONTROL_PING, mp_ping);
18516   S (mp_ping);
18517
18518   /* Wait for a reply... */
18519   W (ret);
18520   return ret;
18521 }
18522
18523 static int
18524 api_policer_classify_set_interface (vat_main_t * vam)
18525 {
18526   unformat_input_t *i = vam->input;
18527   vl_api_policer_classify_set_interface_t *mp;
18528   u32 sw_if_index;
18529   int sw_if_index_set;
18530   u32 ip4_table_index = ~0;
18531   u32 ip6_table_index = ~0;
18532   u32 l2_table_index = ~0;
18533   u8 is_add = 1;
18534   int ret;
18535
18536   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18537     {
18538       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18539         sw_if_index_set = 1;
18540       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18541         sw_if_index_set = 1;
18542       else if (unformat (i, "del"))
18543         is_add = 0;
18544       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18545         ;
18546       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18547         ;
18548       else if (unformat (i, "l2-table %d", &l2_table_index))
18549         ;
18550       else
18551         {
18552           clib_warning ("parse error '%U'", format_unformat_error, i);
18553           return -99;
18554         }
18555     }
18556
18557   if (sw_if_index_set == 0)
18558     {
18559       errmsg ("missing interface name or sw_if_index");
18560       return -99;
18561     }
18562
18563   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18564
18565   mp->sw_if_index = ntohl (sw_if_index);
18566   mp->ip4_table_index = ntohl (ip4_table_index);
18567   mp->ip6_table_index = ntohl (ip6_table_index);
18568   mp->l2_table_index = ntohl (l2_table_index);
18569   mp->is_add = is_add;
18570
18571   S (mp);
18572   W (ret);
18573   return ret;
18574 }
18575
18576 static int
18577 api_policer_classify_dump (vat_main_t * vam)
18578 {
18579   unformat_input_t *i = vam->input;
18580   vl_api_policer_classify_dump_t *mp;
18581   vl_api_control_ping_t *mp_ping;
18582   u8 type = POLICER_CLASSIFY_N_TABLES;
18583   int ret;
18584
18585   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18586     ;
18587   else
18588     {
18589       errmsg ("classify table type must be specified");
18590       return -99;
18591     }
18592
18593   if (!vam->json_output)
18594     {
18595       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18596     }
18597
18598   M (POLICER_CLASSIFY_DUMP, mp);
18599   mp->type = type;
18600   /* send it... */
18601   S (mp);
18602
18603   /* Use a control ping for synchronization */
18604   MPING (CONTROL_PING, mp_ping);
18605   S (mp_ping);
18606
18607   /* Wait for a reply... */
18608   W (ret);
18609   return ret;
18610 }
18611
18612 static int
18613 api_netmap_create (vat_main_t * vam)
18614 {
18615   unformat_input_t *i = vam->input;
18616   vl_api_netmap_create_t *mp;
18617   u8 *if_name = 0;
18618   u8 hw_addr[6];
18619   u8 random_hw_addr = 1;
18620   u8 is_pipe = 0;
18621   u8 is_master = 0;
18622   int ret;
18623
18624   memset (hw_addr, 0, sizeof (hw_addr));
18625
18626   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18627     {
18628       if (unformat (i, "name %s", &if_name))
18629         vec_add1 (if_name, 0);
18630       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18631         random_hw_addr = 0;
18632       else if (unformat (i, "pipe"))
18633         is_pipe = 1;
18634       else if (unformat (i, "master"))
18635         is_master = 1;
18636       else if (unformat (i, "slave"))
18637         is_master = 0;
18638       else
18639         break;
18640     }
18641
18642   if (!vec_len (if_name))
18643     {
18644       errmsg ("interface name must be specified");
18645       return -99;
18646     }
18647
18648   if (vec_len (if_name) > 64)
18649     {
18650       errmsg ("interface name too long");
18651       return -99;
18652     }
18653
18654   M (NETMAP_CREATE, mp);
18655
18656   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18657   clib_memcpy (mp->hw_addr, hw_addr, 6);
18658   mp->use_random_hw_addr = random_hw_addr;
18659   mp->is_pipe = is_pipe;
18660   mp->is_master = is_master;
18661   vec_free (if_name);
18662
18663   S (mp);
18664   W (ret);
18665   return ret;
18666 }
18667
18668 static int
18669 api_netmap_delete (vat_main_t * vam)
18670 {
18671   unformat_input_t *i = vam->input;
18672   vl_api_netmap_delete_t *mp;
18673   u8 *if_name = 0;
18674   int ret;
18675
18676   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18677     {
18678       if (unformat (i, "name %s", &if_name))
18679         vec_add1 (if_name, 0);
18680       else
18681         break;
18682     }
18683
18684   if (!vec_len (if_name))
18685     {
18686       errmsg ("interface name must be specified");
18687       return -99;
18688     }
18689
18690   if (vec_len (if_name) > 64)
18691     {
18692       errmsg ("interface name too long");
18693       return -99;
18694     }
18695
18696   M (NETMAP_DELETE, mp);
18697
18698   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18699   vec_free (if_name);
18700
18701   S (mp);
18702   W (ret);
18703   return ret;
18704 }
18705
18706 static void
18707 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
18708 {
18709   if (fp->afi == IP46_TYPE_IP6)
18710     print (vam->ofp,
18711            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18712            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18713            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18714            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18715            format_ip6_address, fp->next_hop);
18716   else if (fp->afi == IP46_TYPE_IP4)
18717     print (vam->ofp,
18718            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18719            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18720            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18721            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18722            format_ip4_address, fp->next_hop);
18723 }
18724
18725 static void
18726 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18727                                  vl_api_fib_path2_t * fp)
18728 {
18729   struct in_addr ip4;
18730   struct in6_addr ip6;
18731
18732   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18733   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18734   vat_json_object_add_uint (node, "is_local", fp->is_local);
18735   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
18736   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
18737   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
18738   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
18739   if (fp->afi == IP46_TYPE_IP4)
18740     {
18741       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
18742       vat_json_object_add_ip4 (node, "next_hop", ip4);
18743     }
18744   else if (fp->afi == IP46_TYPE_IP6)
18745     {
18746       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
18747       vat_json_object_add_ip6 (node, "next_hop", ip6);
18748     }
18749 }
18750
18751 static void
18752 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18753 {
18754   vat_main_t *vam = &vat_main;
18755   int count = ntohl (mp->mt_count);
18756   vl_api_fib_path2_t *fp;
18757   i32 i;
18758
18759   print (vam->ofp, "[%d]: sw_if_index %d via:",
18760          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
18761   fp = mp->mt_paths;
18762   for (i = 0; i < count; i++)
18763     {
18764       vl_api_mpls_fib_path_print (vam, fp);
18765       fp++;
18766     }
18767
18768   print (vam->ofp, "");
18769 }
18770
18771 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18772 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18773
18774 static void
18775 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18776 {
18777   vat_main_t *vam = &vat_main;
18778   vat_json_node_t *node = NULL;
18779   int count = ntohl (mp->mt_count);
18780   vl_api_fib_path2_t *fp;
18781   i32 i;
18782
18783   if (VAT_JSON_ARRAY != vam->json_tree.type)
18784     {
18785       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18786       vat_json_init_array (&vam->json_tree);
18787     }
18788   node = vat_json_array_add (&vam->json_tree);
18789
18790   vat_json_init_object (node);
18791   vat_json_object_add_uint (node, "tunnel_index",
18792                             ntohl (mp->mt_tunnel_index));
18793   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
18794
18795   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
18796
18797   fp = mp->mt_paths;
18798   for (i = 0; i < count; i++)
18799     {
18800       vl_api_mpls_fib_path_json_print (node, fp);
18801       fp++;
18802     }
18803 }
18804
18805 static int
18806 api_mpls_tunnel_dump (vat_main_t * vam)
18807 {
18808   vl_api_mpls_tunnel_dump_t *mp;
18809   vl_api_control_ping_t *mp_ping;
18810   i32 index = -1;
18811   int ret;
18812
18813   /* Parse args required to build the message */
18814   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
18815     {
18816       if (!unformat (vam->input, "tunnel_index %d", &index))
18817         {
18818           index = -1;
18819           break;
18820         }
18821     }
18822
18823   print (vam->ofp, "  tunnel_index %d", index);
18824
18825   M (MPLS_TUNNEL_DUMP, mp);
18826   mp->tunnel_index = htonl (index);
18827   S (mp);
18828
18829   /* Use a control ping for synchronization */
18830   MPING (CONTROL_PING, mp_ping);
18831   S (mp_ping);
18832
18833   W (ret);
18834   return ret;
18835 }
18836
18837 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
18838 #define vl_api_mpls_fib_details_t_print vl_noop_handler
18839
18840
18841 static void
18842 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
18843 {
18844   vat_main_t *vam = &vat_main;
18845   int count = ntohl (mp->count);
18846   vl_api_fib_path2_t *fp;
18847   int i;
18848
18849   print (vam->ofp,
18850          "table-id %d, label %u, ess_bit %u",
18851          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
18852   fp = mp->path;
18853   for (i = 0; i < count; i++)
18854     {
18855       vl_api_mpls_fib_path_print (vam, fp);
18856       fp++;
18857     }
18858 }
18859
18860 static void vl_api_mpls_fib_details_t_handler_json
18861   (vl_api_mpls_fib_details_t * mp)
18862 {
18863   vat_main_t *vam = &vat_main;
18864   int count = ntohl (mp->count);
18865   vat_json_node_t *node = NULL;
18866   vl_api_fib_path2_t *fp;
18867   int i;
18868
18869   if (VAT_JSON_ARRAY != vam->json_tree.type)
18870     {
18871       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18872       vat_json_init_array (&vam->json_tree);
18873     }
18874   node = vat_json_array_add (&vam->json_tree);
18875
18876   vat_json_init_object (node);
18877   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
18878   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
18879   vat_json_object_add_uint (node, "label", ntohl (mp->label));
18880   vat_json_object_add_uint (node, "path_count", count);
18881   fp = mp->path;
18882   for (i = 0; i < count; i++)
18883     {
18884       vl_api_mpls_fib_path_json_print (node, fp);
18885       fp++;
18886     }
18887 }
18888
18889 static int
18890 api_mpls_fib_dump (vat_main_t * vam)
18891 {
18892   vl_api_mpls_fib_dump_t *mp;
18893   vl_api_control_ping_t *mp_ping;
18894   int ret;
18895
18896   M (MPLS_FIB_DUMP, mp);
18897   S (mp);
18898
18899   /* Use a control ping for synchronization */
18900   MPING (CONTROL_PING, mp_ping);
18901   S (mp_ping);
18902
18903   W (ret);
18904   return ret;
18905 }
18906
18907 #define vl_api_ip_fib_details_t_endian vl_noop_handler
18908 #define vl_api_ip_fib_details_t_print vl_noop_handler
18909
18910 static void
18911 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
18912 {
18913   vat_main_t *vam = &vat_main;
18914   int count = ntohl (mp->count);
18915   vl_api_fib_path_t *fp;
18916   int i;
18917
18918   print (vam->ofp,
18919          "table-id %d, prefix %U/%d",
18920          ntohl (mp->table_id), format_ip4_address, mp->address,
18921          mp->address_length);
18922   fp = mp->path;
18923   for (i = 0; i < count; i++)
18924     {
18925       if (fp->afi == IP46_TYPE_IP6)
18926         print (vam->ofp,
18927                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18928                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18929                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18930                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18931                format_ip6_address, fp->next_hop);
18932       else if (fp->afi == IP46_TYPE_IP4)
18933         print (vam->ofp,
18934                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18935                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18936                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18937                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18938                format_ip4_address, fp->next_hop);
18939       fp++;
18940     }
18941 }
18942
18943 static void vl_api_ip_fib_details_t_handler_json
18944   (vl_api_ip_fib_details_t * mp)
18945 {
18946   vat_main_t *vam = &vat_main;
18947   int count = ntohl (mp->count);
18948   vat_json_node_t *node = NULL;
18949   struct in_addr ip4;
18950   struct in6_addr ip6;
18951   vl_api_fib_path_t *fp;
18952   int i;
18953
18954   if (VAT_JSON_ARRAY != vam->json_tree.type)
18955     {
18956       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18957       vat_json_init_array (&vam->json_tree);
18958     }
18959   node = vat_json_array_add (&vam->json_tree);
18960
18961   vat_json_init_object (node);
18962   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
18963   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
18964   vat_json_object_add_ip4 (node, "prefix", ip4);
18965   vat_json_object_add_uint (node, "mask_length", mp->address_length);
18966   vat_json_object_add_uint (node, "path_count", count);
18967   fp = mp->path;
18968   for (i = 0; i < count; i++)
18969     {
18970       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18971       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18972       vat_json_object_add_uint (node, "is_local", fp->is_local);
18973       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
18974       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
18975       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
18976       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
18977       if (fp->afi == IP46_TYPE_IP4)
18978         {
18979           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
18980           vat_json_object_add_ip4 (node, "next_hop", ip4);
18981         }
18982       else if (fp->afi == IP46_TYPE_IP6)
18983         {
18984           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
18985           vat_json_object_add_ip6 (node, "next_hop", ip6);
18986         }
18987     }
18988 }
18989
18990 static int
18991 api_ip_fib_dump (vat_main_t * vam)
18992 {
18993   vl_api_ip_fib_dump_t *mp;
18994   vl_api_control_ping_t *mp_ping;
18995   int ret;
18996
18997   M (IP_FIB_DUMP, mp);
18998   S (mp);
18999
19000   /* Use a control ping for synchronization */
19001   MPING (CONTROL_PING, mp_ping);
19002   S (mp_ping);
19003
19004   W (ret);
19005   return ret;
19006 }
19007
19008 static int
19009 api_ip_mfib_dump (vat_main_t * vam)
19010 {
19011   vl_api_ip_mfib_dump_t *mp;
19012   vl_api_control_ping_t *mp_ping;
19013   int ret;
19014
19015   M (IP_MFIB_DUMP, mp);
19016   S (mp);
19017
19018   /* Use a control ping for synchronization */
19019   MPING (CONTROL_PING, mp_ping);
19020   S (mp_ping);
19021
19022   W (ret);
19023   return ret;
19024 }
19025
19026 static void vl_api_ip_neighbor_details_t_handler
19027   (vl_api_ip_neighbor_details_t * mp)
19028 {
19029   vat_main_t *vam = &vat_main;
19030
19031   print (vam->ofp, "%c %U %U",
19032          (mp->is_static) ? 'S' : 'D',
19033          format_ethernet_address, &mp->mac_address,
19034          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
19035          &mp->ip_address);
19036 }
19037
19038 static void vl_api_ip_neighbor_details_t_handler_json
19039   (vl_api_ip_neighbor_details_t * mp)
19040 {
19041
19042   vat_main_t *vam = &vat_main;
19043   vat_json_node_t *node;
19044   struct in_addr ip4;
19045   struct in6_addr ip6;
19046
19047   if (VAT_JSON_ARRAY != vam->json_tree.type)
19048     {
19049       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19050       vat_json_init_array (&vam->json_tree);
19051     }
19052   node = vat_json_array_add (&vam->json_tree);
19053
19054   vat_json_init_object (node);
19055   vat_json_object_add_string_copy (node, "flag",
19056                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
19057                                    "dynamic");
19058
19059   vat_json_object_add_string_copy (node, "link_layer",
19060                                    format (0, "%U", format_ethernet_address,
19061                                            &mp->mac_address));
19062
19063   if (mp->is_ipv6)
19064     {
19065       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
19066       vat_json_object_add_ip6 (node, "ip_address", ip6);
19067     }
19068   else
19069     {
19070       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
19071       vat_json_object_add_ip4 (node, "ip_address", ip4);
19072     }
19073 }
19074
19075 static int
19076 api_ip_neighbor_dump (vat_main_t * vam)
19077 {
19078   unformat_input_t *i = vam->input;
19079   vl_api_ip_neighbor_dump_t *mp;
19080   vl_api_control_ping_t *mp_ping;
19081   u8 is_ipv6 = 0;
19082   u32 sw_if_index = ~0;
19083   int ret;
19084
19085   /* Parse args required to build the message */
19086   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19087     {
19088       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19089         ;
19090       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19091         ;
19092       else if (unformat (i, "ip6"))
19093         is_ipv6 = 1;
19094       else
19095         break;
19096     }
19097
19098   if (sw_if_index == ~0)
19099     {
19100       errmsg ("missing interface name or sw_if_index");
19101       return -99;
19102     }
19103
19104   M (IP_NEIGHBOR_DUMP, mp);
19105   mp->is_ipv6 = (u8) is_ipv6;
19106   mp->sw_if_index = ntohl (sw_if_index);
19107   S (mp);
19108
19109   /* Use a control ping for synchronization */
19110   MPING (CONTROL_PING, mp_ping);
19111   S (mp_ping);
19112
19113   W (ret);
19114   return ret;
19115 }
19116
19117 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
19118 #define vl_api_ip6_fib_details_t_print vl_noop_handler
19119
19120 static void
19121 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
19122 {
19123   vat_main_t *vam = &vat_main;
19124   int count = ntohl (mp->count);
19125   vl_api_fib_path_t *fp;
19126   int i;
19127
19128   print (vam->ofp,
19129          "table-id %d, prefix %U/%d",
19130          ntohl (mp->table_id), format_ip6_address, mp->address,
19131          mp->address_length);
19132   fp = mp->path;
19133   for (i = 0; i < count; i++)
19134     {
19135       if (fp->afi == IP46_TYPE_IP6)
19136         print (vam->ofp,
19137                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19138                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19139                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19140                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19141                format_ip6_address, fp->next_hop);
19142       else if (fp->afi == IP46_TYPE_IP4)
19143         print (vam->ofp,
19144                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19145                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19146                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19147                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19148                format_ip4_address, fp->next_hop);
19149       fp++;
19150     }
19151 }
19152
19153 static void vl_api_ip6_fib_details_t_handler_json
19154   (vl_api_ip6_fib_details_t * mp)
19155 {
19156   vat_main_t *vam = &vat_main;
19157   int count = ntohl (mp->count);
19158   vat_json_node_t *node = NULL;
19159   struct in_addr ip4;
19160   struct in6_addr ip6;
19161   vl_api_fib_path_t *fp;
19162   int i;
19163
19164   if (VAT_JSON_ARRAY != vam->json_tree.type)
19165     {
19166       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19167       vat_json_init_array (&vam->json_tree);
19168     }
19169   node = vat_json_array_add (&vam->json_tree);
19170
19171   vat_json_init_object (node);
19172   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19173   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
19174   vat_json_object_add_ip6 (node, "prefix", ip6);
19175   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19176   vat_json_object_add_uint (node, "path_count", count);
19177   fp = mp->path;
19178   for (i = 0; i < count; i++)
19179     {
19180       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19181       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19182       vat_json_object_add_uint (node, "is_local", fp->is_local);
19183       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19184       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19185       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19186       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19187       if (fp->afi == IP46_TYPE_IP4)
19188         {
19189           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19190           vat_json_object_add_ip4 (node, "next_hop", ip4);
19191         }
19192       else if (fp->afi == IP46_TYPE_IP6)
19193         {
19194           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19195           vat_json_object_add_ip6 (node, "next_hop", ip6);
19196         }
19197     }
19198 }
19199
19200 static int
19201 api_ip6_fib_dump (vat_main_t * vam)
19202 {
19203   vl_api_ip6_fib_dump_t *mp;
19204   vl_api_control_ping_t *mp_ping;
19205   int ret;
19206
19207   M (IP6_FIB_DUMP, mp);
19208   S (mp);
19209
19210   /* Use a control ping for synchronization */
19211   MPING (CONTROL_PING, mp_ping);
19212   S (mp_ping);
19213
19214   W (ret);
19215   return ret;
19216 }
19217
19218 static int
19219 api_ip6_mfib_dump (vat_main_t * vam)
19220 {
19221   vl_api_ip6_mfib_dump_t *mp;
19222   vl_api_control_ping_t *mp_ping;
19223   int ret;
19224
19225   M (IP6_MFIB_DUMP, mp);
19226   S (mp);
19227
19228   /* Use a control ping for synchronization */
19229   MPING (CONTROL_PING, mp_ping);
19230   S (mp_ping);
19231
19232   W (ret);
19233   return ret;
19234 }
19235
19236 int
19237 api_classify_table_ids (vat_main_t * vam)
19238 {
19239   vl_api_classify_table_ids_t *mp;
19240   int ret;
19241
19242   /* Construct the API message */
19243   M (CLASSIFY_TABLE_IDS, mp);
19244   mp->context = 0;
19245
19246   S (mp);
19247   W (ret);
19248   return ret;
19249 }
19250
19251 int
19252 api_classify_table_by_interface (vat_main_t * vam)
19253 {
19254   unformat_input_t *input = vam->input;
19255   vl_api_classify_table_by_interface_t *mp;
19256
19257   u32 sw_if_index = ~0;
19258   int ret;
19259   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19260     {
19261       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19262         ;
19263       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19264         ;
19265       else
19266         break;
19267     }
19268   if (sw_if_index == ~0)
19269     {
19270       errmsg ("missing interface name or sw_if_index");
19271       return -99;
19272     }
19273
19274   /* Construct the API message */
19275   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19276   mp->context = 0;
19277   mp->sw_if_index = ntohl (sw_if_index);
19278
19279   S (mp);
19280   W (ret);
19281   return ret;
19282 }
19283
19284 int
19285 api_classify_table_info (vat_main_t * vam)
19286 {
19287   unformat_input_t *input = vam->input;
19288   vl_api_classify_table_info_t *mp;
19289
19290   u32 table_id = ~0;
19291   int ret;
19292   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19293     {
19294       if (unformat (input, "table_id %d", &table_id))
19295         ;
19296       else
19297         break;
19298     }
19299   if (table_id == ~0)
19300     {
19301       errmsg ("missing table id");
19302       return -99;
19303     }
19304
19305   /* Construct the API message */
19306   M (CLASSIFY_TABLE_INFO, mp);
19307   mp->context = 0;
19308   mp->table_id = ntohl (table_id);
19309
19310   S (mp);
19311   W (ret);
19312   return ret;
19313 }
19314
19315 int
19316 api_classify_session_dump (vat_main_t * vam)
19317 {
19318   unformat_input_t *input = vam->input;
19319   vl_api_classify_session_dump_t *mp;
19320   vl_api_control_ping_t *mp_ping;
19321
19322   u32 table_id = ~0;
19323   int ret;
19324   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19325     {
19326       if (unformat (input, "table_id %d", &table_id))
19327         ;
19328       else
19329         break;
19330     }
19331   if (table_id == ~0)
19332     {
19333       errmsg ("missing table id");
19334       return -99;
19335     }
19336
19337   /* Construct the API message */
19338   M (CLASSIFY_SESSION_DUMP, mp);
19339   mp->context = 0;
19340   mp->table_id = ntohl (table_id);
19341   S (mp);
19342
19343   /* Use a control ping for synchronization */
19344   MPING (CONTROL_PING, mp_ping);
19345   S (mp_ping);
19346
19347   W (ret);
19348   return ret;
19349 }
19350
19351 static void
19352 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19353 {
19354   vat_main_t *vam = &vat_main;
19355
19356   print (vam->ofp, "collector_address %U, collector_port %d, "
19357          "src_address %U, vrf_id %d, path_mtu %u, "
19358          "template_interval %u, udp_checksum %d",
19359          format_ip4_address, mp->collector_address,
19360          ntohs (mp->collector_port),
19361          format_ip4_address, mp->src_address,
19362          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19363          ntohl (mp->template_interval), mp->udp_checksum);
19364
19365   vam->retval = 0;
19366   vam->result_ready = 1;
19367 }
19368
19369 static void
19370   vl_api_ipfix_exporter_details_t_handler_json
19371   (vl_api_ipfix_exporter_details_t * mp)
19372 {
19373   vat_main_t *vam = &vat_main;
19374   vat_json_node_t node;
19375   struct in_addr collector_address;
19376   struct in_addr src_address;
19377
19378   vat_json_init_object (&node);
19379   clib_memcpy (&collector_address, &mp->collector_address,
19380                sizeof (collector_address));
19381   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19382   vat_json_object_add_uint (&node, "collector_port",
19383                             ntohs (mp->collector_port));
19384   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19385   vat_json_object_add_ip4 (&node, "src_address", src_address);
19386   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19387   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19388   vat_json_object_add_uint (&node, "template_interval",
19389                             ntohl (mp->template_interval));
19390   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19391
19392   vat_json_print (vam->ofp, &node);
19393   vat_json_free (&node);
19394   vam->retval = 0;
19395   vam->result_ready = 1;
19396 }
19397
19398 int
19399 api_ipfix_exporter_dump (vat_main_t * vam)
19400 {
19401   vl_api_ipfix_exporter_dump_t *mp;
19402   int ret;
19403
19404   /* Construct the API message */
19405   M (IPFIX_EXPORTER_DUMP, mp);
19406   mp->context = 0;
19407
19408   S (mp);
19409   W (ret);
19410   return ret;
19411 }
19412
19413 static int
19414 api_ipfix_classify_stream_dump (vat_main_t * vam)
19415 {
19416   vl_api_ipfix_classify_stream_dump_t *mp;
19417   int ret;
19418
19419   /* Construct the API message */
19420   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19421   mp->context = 0;
19422
19423   S (mp);
19424   W (ret);
19425   return ret;
19426   /* NOTREACHED */
19427   return 0;
19428 }
19429
19430 static void
19431   vl_api_ipfix_classify_stream_details_t_handler
19432   (vl_api_ipfix_classify_stream_details_t * mp)
19433 {
19434   vat_main_t *vam = &vat_main;
19435   print (vam->ofp, "domain_id %d, src_port %d",
19436          ntohl (mp->domain_id), ntohs (mp->src_port));
19437   vam->retval = 0;
19438   vam->result_ready = 1;
19439 }
19440
19441 static void
19442   vl_api_ipfix_classify_stream_details_t_handler_json
19443   (vl_api_ipfix_classify_stream_details_t * mp)
19444 {
19445   vat_main_t *vam = &vat_main;
19446   vat_json_node_t node;
19447
19448   vat_json_init_object (&node);
19449   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19450   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19451
19452   vat_json_print (vam->ofp, &node);
19453   vat_json_free (&node);
19454   vam->retval = 0;
19455   vam->result_ready = 1;
19456 }
19457
19458 static int
19459 api_ipfix_classify_table_dump (vat_main_t * vam)
19460 {
19461   vl_api_ipfix_classify_table_dump_t *mp;
19462   vl_api_control_ping_t *mp_ping;
19463   int ret;
19464
19465   if (!vam->json_output)
19466     {
19467       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19468              "transport_protocol");
19469     }
19470
19471   /* Construct the API message */
19472   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19473
19474   /* send it... */
19475   S (mp);
19476
19477   /* Use a control ping for synchronization */
19478   MPING (CONTROL_PING, mp_ping);
19479   S (mp_ping);
19480
19481   W (ret);
19482   return ret;
19483 }
19484
19485 static void
19486   vl_api_ipfix_classify_table_details_t_handler
19487   (vl_api_ipfix_classify_table_details_t * mp)
19488 {
19489   vat_main_t *vam = &vat_main;
19490   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19491          mp->transport_protocol);
19492 }
19493
19494 static void
19495   vl_api_ipfix_classify_table_details_t_handler_json
19496   (vl_api_ipfix_classify_table_details_t * mp)
19497 {
19498   vat_json_node_t *node = NULL;
19499   vat_main_t *vam = &vat_main;
19500
19501   if (VAT_JSON_ARRAY != vam->json_tree.type)
19502     {
19503       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19504       vat_json_init_array (&vam->json_tree);
19505     }
19506
19507   node = vat_json_array_add (&vam->json_tree);
19508   vat_json_init_object (node);
19509
19510   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19511   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19512   vat_json_object_add_uint (node, "transport_protocol",
19513                             mp->transport_protocol);
19514 }
19515
19516 static int
19517 api_sw_interface_span_enable_disable (vat_main_t * vam)
19518 {
19519   unformat_input_t *i = vam->input;
19520   vl_api_sw_interface_span_enable_disable_t *mp;
19521   u32 src_sw_if_index = ~0;
19522   u32 dst_sw_if_index = ~0;
19523   u8 state = 3;
19524   int ret;
19525   u8 is_l2 = 0;
19526
19527   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19528     {
19529       if (unformat
19530           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19531         ;
19532       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19533         ;
19534       else
19535         if (unformat
19536             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19537         ;
19538       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19539         ;
19540       else if (unformat (i, "disable"))
19541         state = 0;
19542       else if (unformat (i, "rx"))
19543         state = 1;
19544       else if (unformat (i, "tx"))
19545         state = 2;
19546       else if (unformat (i, "both"))
19547         state = 3;
19548       else if (unformat (i, "l2"))
19549         is_l2 = 1;
19550       else
19551         break;
19552     }
19553
19554   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19555
19556   mp->sw_if_index_from = htonl (src_sw_if_index);
19557   mp->sw_if_index_to = htonl (dst_sw_if_index);
19558   mp->state = state;
19559   mp->is_l2 = is_l2;
19560
19561   S (mp);
19562   W (ret);
19563   return ret;
19564 }
19565
19566 static void
19567 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19568                                             * mp)
19569 {
19570   vat_main_t *vam = &vat_main;
19571   u8 *sw_if_from_name = 0;
19572   u8 *sw_if_to_name = 0;
19573   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19574   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19575   char *states[] = { "none", "rx", "tx", "both" };
19576   hash_pair_t *p;
19577
19578   /* *INDENT-OFF* */
19579   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19580   ({
19581     if ((u32) p->value[0] == sw_if_index_from)
19582       {
19583         sw_if_from_name = (u8 *)(p->key);
19584         if (sw_if_to_name)
19585           break;
19586       }
19587     if ((u32) p->value[0] == sw_if_index_to)
19588       {
19589         sw_if_to_name = (u8 *)(p->key);
19590         if (sw_if_from_name)
19591           break;
19592       }
19593   }));
19594   /* *INDENT-ON* */
19595   print (vam->ofp, "%20s => %20s (%s)",
19596          sw_if_from_name, sw_if_to_name, states[mp->state]);
19597 }
19598
19599 static void
19600   vl_api_sw_interface_span_details_t_handler_json
19601   (vl_api_sw_interface_span_details_t * mp)
19602 {
19603   vat_main_t *vam = &vat_main;
19604   vat_json_node_t *node = NULL;
19605   u8 *sw_if_from_name = 0;
19606   u8 *sw_if_to_name = 0;
19607   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19608   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19609   hash_pair_t *p;
19610
19611   /* *INDENT-OFF* */
19612   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19613   ({
19614     if ((u32) p->value[0] == sw_if_index_from)
19615       {
19616         sw_if_from_name = (u8 *)(p->key);
19617         if (sw_if_to_name)
19618           break;
19619       }
19620     if ((u32) p->value[0] == sw_if_index_to)
19621       {
19622         sw_if_to_name = (u8 *)(p->key);
19623         if (sw_if_from_name)
19624           break;
19625       }
19626   }));
19627   /* *INDENT-ON* */
19628
19629   if (VAT_JSON_ARRAY != vam->json_tree.type)
19630     {
19631       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19632       vat_json_init_array (&vam->json_tree);
19633     }
19634   node = vat_json_array_add (&vam->json_tree);
19635
19636   vat_json_init_object (node);
19637   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19638   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19639   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19640   if (0 != sw_if_to_name)
19641     {
19642       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19643     }
19644   vat_json_object_add_uint (node, "state", mp->state);
19645 }
19646
19647 static int
19648 api_sw_interface_span_dump (vat_main_t * vam)
19649 {
19650   unformat_input_t *input = vam->input;
19651   vl_api_sw_interface_span_dump_t *mp;
19652   vl_api_control_ping_t *mp_ping;
19653   u8 is_l2 = 0;
19654   int ret;
19655
19656   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19657     {
19658       if (unformat (input, "l2"))
19659         is_l2 = 1;
19660       else
19661         break;
19662     }
19663
19664   M (SW_INTERFACE_SPAN_DUMP, mp);
19665   mp->is_l2 = is_l2;
19666   S (mp);
19667
19668   /* Use a control ping for synchronization */
19669   MPING (CONTROL_PING, mp_ping);
19670   S (mp_ping);
19671
19672   W (ret);
19673   return ret;
19674 }
19675
19676 int
19677 api_pg_create_interface (vat_main_t * vam)
19678 {
19679   unformat_input_t *input = vam->input;
19680   vl_api_pg_create_interface_t *mp;
19681
19682   u32 if_id = ~0;
19683   int ret;
19684   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19685     {
19686       if (unformat (input, "if_id %d", &if_id))
19687         ;
19688       else
19689         break;
19690     }
19691   if (if_id == ~0)
19692     {
19693       errmsg ("missing pg interface index");
19694       return -99;
19695     }
19696
19697   /* Construct the API message */
19698   M (PG_CREATE_INTERFACE, mp);
19699   mp->context = 0;
19700   mp->interface_id = ntohl (if_id);
19701
19702   S (mp);
19703   W (ret);
19704   return ret;
19705 }
19706
19707 int
19708 api_pg_capture (vat_main_t * vam)
19709 {
19710   unformat_input_t *input = vam->input;
19711   vl_api_pg_capture_t *mp;
19712
19713   u32 if_id = ~0;
19714   u8 enable = 1;
19715   u32 count = 1;
19716   u8 pcap_file_set = 0;
19717   u8 *pcap_file = 0;
19718   int ret;
19719   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19720     {
19721       if (unformat (input, "if_id %d", &if_id))
19722         ;
19723       else if (unformat (input, "pcap %s", &pcap_file))
19724         pcap_file_set = 1;
19725       else if (unformat (input, "count %d", &count))
19726         ;
19727       else if (unformat (input, "disable"))
19728         enable = 0;
19729       else
19730         break;
19731     }
19732   if (if_id == ~0)
19733     {
19734       errmsg ("missing pg interface index");
19735       return -99;
19736     }
19737   if (pcap_file_set > 0)
19738     {
19739       if (vec_len (pcap_file) > 255)
19740         {
19741           errmsg ("pcap file name is too long");
19742           return -99;
19743         }
19744     }
19745
19746   u32 name_len = vec_len (pcap_file);
19747   /* Construct the API message */
19748   M (PG_CAPTURE, mp);
19749   mp->context = 0;
19750   mp->interface_id = ntohl (if_id);
19751   mp->is_enabled = enable;
19752   mp->count = ntohl (count);
19753   mp->pcap_name_length = ntohl (name_len);
19754   if (pcap_file_set != 0)
19755     {
19756       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19757     }
19758   vec_free (pcap_file);
19759
19760   S (mp);
19761   W (ret);
19762   return ret;
19763 }
19764
19765 int
19766 api_pg_enable_disable (vat_main_t * vam)
19767 {
19768   unformat_input_t *input = vam->input;
19769   vl_api_pg_enable_disable_t *mp;
19770
19771   u8 enable = 1;
19772   u8 stream_name_set = 0;
19773   u8 *stream_name = 0;
19774   int ret;
19775   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19776     {
19777       if (unformat (input, "stream %s", &stream_name))
19778         stream_name_set = 1;
19779       else if (unformat (input, "disable"))
19780         enable = 0;
19781       else
19782         break;
19783     }
19784
19785   if (stream_name_set > 0)
19786     {
19787       if (vec_len (stream_name) > 255)
19788         {
19789           errmsg ("stream name too long");
19790           return -99;
19791         }
19792     }
19793
19794   u32 name_len = vec_len (stream_name);
19795   /* Construct the API message */
19796   M (PG_ENABLE_DISABLE, mp);
19797   mp->context = 0;
19798   mp->is_enabled = enable;
19799   if (stream_name_set != 0)
19800     {
19801       mp->stream_name_length = ntohl (name_len);
19802       clib_memcpy (mp->stream_name, stream_name, name_len);
19803     }
19804   vec_free (stream_name);
19805
19806   S (mp);
19807   W (ret);
19808   return ret;
19809 }
19810
19811 int
19812 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19813 {
19814   unformat_input_t *input = vam->input;
19815   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19816
19817   u16 *low_ports = 0;
19818   u16 *high_ports = 0;
19819   u16 this_low;
19820   u16 this_hi;
19821   ip4_address_t ip4_addr;
19822   ip6_address_t ip6_addr;
19823   u32 length;
19824   u32 tmp, tmp2;
19825   u8 prefix_set = 0;
19826   u32 vrf_id = ~0;
19827   u8 is_add = 1;
19828   u8 is_ipv6 = 0;
19829   int ret;
19830
19831   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19832     {
19833       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
19834         {
19835           prefix_set = 1;
19836         }
19837       else
19838         if (unformat
19839             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
19840         {
19841           prefix_set = 1;
19842           is_ipv6 = 1;
19843         }
19844       else if (unformat (input, "vrf %d", &vrf_id))
19845         ;
19846       else if (unformat (input, "del"))
19847         is_add = 0;
19848       else if (unformat (input, "port %d", &tmp))
19849         {
19850           if (tmp == 0 || tmp > 65535)
19851             {
19852               errmsg ("port %d out of range", tmp);
19853               return -99;
19854             }
19855           this_low = tmp;
19856           this_hi = this_low + 1;
19857           vec_add1 (low_ports, this_low);
19858           vec_add1 (high_ports, this_hi);
19859         }
19860       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19861         {
19862           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19863             {
19864               errmsg ("incorrect range parameters");
19865               return -99;
19866             }
19867           this_low = tmp;
19868           /* Note: in debug CLI +1 is added to high before
19869              passing to real fn that does "the work"
19870              (ip_source_and_port_range_check_add_del).
19871              This fn is a wrapper around the binary API fn a
19872              control plane will call, which expects this increment
19873              to have occurred. Hence letting the binary API control
19874              plane fn do the increment for consistency between VAT
19875              and other control planes.
19876            */
19877           this_hi = tmp2;
19878           vec_add1 (low_ports, this_low);
19879           vec_add1 (high_ports, this_hi);
19880         }
19881       else
19882         break;
19883     }
19884
19885   if (prefix_set == 0)
19886     {
19887       errmsg ("<address>/<mask> not specified");
19888       return -99;
19889     }
19890
19891   if (vrf_id == ~0)
19892     {
19893       errmsg ("VRF ID required, not specified");
19894       return -99;
19895     }
19896
19897   if (vrf_id == 0)
19898     {
19899       errmsg
19900         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19901       return -99;
19902     }
19903
19904   if (vec_len (low_ports) == 0)
19905     {
19906       errmsg ("At least one port or port range required");
19907       return -99;
19908     }
19909
19910   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19911
19912   mp->is_add = is_add;
19913
19914   if (is_ipv6)
19915     {
19916       mp->is_ipv6 = 1;
19917       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
19918     }
19919   else
19920     {
19921       mp->is_ipv6 = 0;
19922       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
19923     }
19924
19925   mp->mask_length = length;
19926   mp->number_of_ranges = vec_len (low_ports);
19927
19928   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
19929   vec_free (low_ports);
19930
19931   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
19932   vec_free (high_ports);
19933
19934   mp->vrf_id = ntohl (vrf_id);
19935
19936   S (mp);
19937   W (ret);
19938   return ret;
19939 }
19940
19941 int
19942 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
19943 {
19944   unformat_input_t *input = vam->input;
19945   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
19946   u32 sw_if_index = ~0;
19947   int vrf_set = 0;
19948   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
19949   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
19950   u8 is_add = 1;
19951   int ret;
19952
19953   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19954     {
19955       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19956         ;
19957       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19958         ;
19959       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
19960         vrf_set = 1;
19961       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
19962         vrf_set = 1;
19963       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
19964         vrf_set = 1;
19965       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
19966         vrf_set = 1;
19967       else if (unformat (input, "del"))
19968         is_add = 0;
19969       else
19970         break;
19971     }
19972
19973   if (sw_if_index == ~0)
19974     {
19975       errmsg ("Interface required but not specified");
19976       return -99;
19977     }
19978
19979   if (vrf_set == 0)
19980     {
19981       errmsg ("VRF ID required but not specified");
19982       return -99;
19983     }
19984
19985   if (tcp_out_vrf_id == 0
19986       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
19987     {
19988       errmsg
19989         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19990       return -99;
19991     }
19992
19993   /* Construct the API message */
19994   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
19995
19996   mp->sw_if_index = ntohl (sw_if_index);
19997   mp->is_add = is_add;
19998   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
19999   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20000   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20001   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20002
20003   /* send it... */
20004   S (mp);
20005
20006   /* Wait for a reply... */
20007   W (ret);
20008   return ret;
20009 }
20010
20011 static int
20012 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
20013 {
20014   unformat_input_t *i = vam->input;
20015   vl_api_ipsec_gre_add_del_tunnel_t *mp;
20016   u32 local_sa_id = 0;
20017   u32 remote_sa_id = 0;
20018   ip4_address_t src_address;
20019   ip4_address_t dst_address;
20020   u8 is_add = 1;
20021   int ret;
20022
20023   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20024     {
20025       if (unformat (i, "local_sa %d", &local_sa_id))
20026         ;
20027       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20028         ;
20029       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
20030         ;
20031       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
20032         ;
20033       else if (unformat (i, "del"))
20034         is_add = 0;
20035       else
20036         {
20037           clib_warning ("parse error '%U'", format_unformat_error, i);
20038           return -99;
20039         }
20040     }
20041
20042   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
20043
20044   mp->local_sa_id = ntohl (local_sa_id);
20045   mp->remote_sa_id = ntohl (remote_sa_id);
20046   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
20047   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
20048   mp->is_add = is_add;
20049
20050   S (mp);
20051   W (ret);
20052   return ret;
20053 }
20054
20055 static int
20056 api_punt (vat_main_t * vam)
20057 {
20058   unformat_input_t *i = vam->input;
20059   vl_api_punt_t *mp;
20060   u32 ipv = ~0;
20061   u32 protocol = ~0;
20062   u32 port = ~0;
20063   int is_add = 1;
20064   int ret;
20065
20066   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20067     {
20068       if (unformat (i, "ip %d", &ipv))
20069         ;
20070       else if (unformat (i, "protocol %d", &protocol))
20071         ;
20072       else if (unformat (i, "port %d", &port))
20073         ;
20074       else if (unformat (i, "del"))
20075         is_add = 0;
20076       else
20077         {
20078           clib_warning ("parse error '%U'", format_unformat_error, i);
20079           return -99;
20080         }
20081     }
20082
20083   M (PUNT, mp);
20084
20085   mp->is_add = (u8) is_add;
20086   mp->ipv = (u8) ipv;
20087   mp->l4_protocol = (u8) protocol;
20088   mp->l4_port = htons ((u16) port);
20089
20090   S (mp);
20091   W (ret);
20092   return ret;
20093 }
20094
20095 static void vl_api_ipsec_gre_tunnel_details_t_handler
20096   (vl_api_ipsec_gre_tunnel_details_t * mp)
20097 {
20098   vat_main_t *vam = &vat_main;
20099
20100   print (vam->ofp, "%11d%15U%15U%14d%14d",
20101          ntohl (mp->sw_if_index),
20102          format_ip4_address, &mp->src_address,
20103          format_ip4_address, &mp->dst_address,
20104          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
20105 }
20106
20107 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
20108   (vl_api_ipsec_gre_tunnel_details_t * mp)
20109 {
20110   vat_main_t *vam = &vat_main;
20111   vat_json_node_t *node = NULL;
20112   struct in_addr ip4;
20113
20114   if (VAT_JSON_ARRAY != vam->json_tree.type)
20115     {
20116       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20117       vat_json_init_array (&vam->json_tree);
20118     }
20119   node = vat_json_array_add (&vam->json_tree);
20120
20121   vat_json_init_object (node);
20122   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
20123   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
20124   vat_json_object_add_ip4 (node, "src_address", ip4);
20125   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
20126   vat_json_object_add_ip4 (node, "dst_address", ip4);
20127   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
20128   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
20129 }
20130
20131 static int
20132 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
20133 {
20134   unformat_input_t *i = vam->input;
20135   vl_api_ipsec_gre_tunnel_dump_t *mp;
20136   vl_api_control_ping_t *mp_ping;
20137   u32 sw_if_index;
20138   u8 sw_if_index_set = 0;
20139   int ret;
20140
20141   /* Parse args required to build the message */
20142   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20143     {
20144       if (unformat (i, "sw_if_index %d", &sw_if_index))
20145         sw_if_index_set = 1;
20146       else
20147         break;
20148     }
20149
20150   if (sw_if_index_set == 0)
20151     {
20152       sw_if_index = ~0;
20153     }
20154
20155   if (!vam->json_output)
20156     {
20157       print (vam->ofp, "%11s%15s%15s%14s%14s",
20158              "sw_if_index", "src_address", "dst_address",
20159              "local_sa_id", "remote_sa_id");
20160     }
20161
20162   /* Get list of gre-tunnel interfaces */
20163   M (IPSEC_GRE_TUNNEL_DUMP, mp);
20164
20165   mp->sw_if_index = htonl (sw_if_index);
20166
20167   S (mp);
20168
20169   /* Use a control ping for synchronization */
20170   MPING (CONTROL_PING, mp_ping);
20171   S (mp_ping);
20172
20173   W (ret);
20174   return ret;
20175 }
20176
20177 static int
20178 api_delete_subif (vat_main_t * vam)
20179 {
20180   unformat_input_t *i = vam->input;
20181   vl_api_delete_subif_t *mp;
20182   u32 sw_if_index = ~0;
20183   int ret;
20184
20185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20186     {
20187       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20188         ;
20189       if (unformat (i, "sw_if_index %d", &sw_if_index))
20190         ;
20191       else
20192         break;
20193     }
20194
20195   if (sw_if_index == ~0)
20196     {
20197       errmsg ("missing sw_if_index");
20198       return -99;
20199     }
20200
20201   /* Construct the API message */
20202   M (DELETE_SUBIF, mp);
20203   mp->sw_if_index = ntohl (sw_if_index);
20204
20205   S (mp);
20206   W (ret);
20207   return ret;
20208 }
20209
20210 #define foreach_pbb_vtr_op      \
20211 _("disable",  L2_VTR_DISABLED)  \
20212 _("pop",  L2_VTR_POP_2)         \
20213 _("push",  L2_VTR_PUSH_2)
20214
20215 static int
20216 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20217 {
20218   unformat_input_t *i = vam->input;
20219   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20220   u32 sw_if_index = ~0, vtr_op = ~0;
20221   u16 outer_tag = ~0;
20222   u8 dmac[6], smac[6];
20223   u8 dmac_set = 0, smac_set = 0;
20224   u16 vlanid = 0;
20225   u32 sid = ~0;
20226   u32 tmp;
20227   int ret;
20228
20229   /* Shut up coverity */
20230   memset (dmac, 0, sizeof (dmac));
20231   memset (smac, 0, sizeof (smac));
20232
20233   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20234     {
20235       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20236         ;
20237       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20238         ;
20239       else if (unformat (i, "vtr_op %d", &vtr_op))
20240         ;
20241 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20242       foreach_pbb_vtr_op
20243 #undef _
20244         else if (unformat (i, "translate_pbb_stag"))
20245         {
20246           if (unformat (i, "%d", &tmp))
20247             {
20248               vtr_op = L2_VTR_TRANSLATE_2_1;
20249               outer_tag = tmp;
20250             }
20251           else
20252             {
20253               errmsg
20254                 ("translate_pbb_stag operation requires outer tag definition");
20255               return -99;
20256             }
20257         }
20258       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20259         dmac_set++;
20260       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20261         smac_set++;
20262       else if (unformat (i, "sid %d", &sid))
20263         ;
20264       else if (unformat (i, "vlanid %d", &tmp))
20265         vlanid = tmp;
20266       else
20267         {
20268           clib_warning ("parse error '%U'", format_unformat_error, i);
20269           return -99;
20270         }
20271     }
20272
20273   if ((sw_if_index == ~0) || (vtr_op == ~0))
20274     {
20275       errmsg ("missing sw_if_index or vtr operation");
20276       return -99;
20277     }
20278   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20279       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20280     {
20281       errmsg
20282         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20283       return -99;
20284     }
20285
20286   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20287   mp->sw_if_index = ntohl (sw_if_index);
20288   mp->vtr_op = ntohl (vtr_op);
20289   mp->outer_tag = ntohs (outer_tag);
20290   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20291   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20292   mp->b_vlanid = ntohs (vlanid);
20293   mp->i_sid = ntohl (sid);
20294
20295   S (mp);
20296   W (ret);
20297   return ret;
20298 }
20299
20300 static int
20301 api_flow_classify_set_interface (vat_main_t * vam)
20302 {
20303   unformat_input_t *i = vam->input;
20304   vl_api_flow_classify_set_interface_t *mp;
20305   u32 sw_if_index;
20306   int sw_if_index_set;
20307   u32 ip4_table_index = ~0;
20308   u32 ip6_table_index = ~0;
20309   u8 is_add = 1;
20310   int ret;
20311
20312   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20313     {
20314       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20315         sw_if_index_set = 1;
20316       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20317         sw_if_index_set = 1;
20318       else if (unformat (i, "del"))
20319         is_add = 0;
20320       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20321         ;
20322       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20323         ;
20324       else
20325         {
20326           clib_warning ("parse error '%U'", format_unformat_error, i);
20327           return -99;
20328         }
20329     }
20330
20331   if (sw_if_index_set == 0)
20332     {
20333       errmsg ("missing interface name or sw_if_index");
20334       return -99;
20335     }
20336
20337   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20338
20339   mp->sw_if_index = ntohl (sw_if_index);
20340   mp->ip4_table_index = ntohl (ip4_table_index);
20341   mp->ip6_table_index = ntohl (ip6_table_index);
20342   mp->is_add = is_add;
20343
20344   S (mp);
20345   W (ret);
20346   return ret;
20347 }
20348
20349 static int
20350 api_flow_classify_dump (vat_main_t * vam)
20351 {
20352   unformat_input_t *i = vam->input;
20353   vl_api_flow_classify_dump_t *mp;
20354   vl_api_control_ping_t *mp_ping;
20355   u8 type = FLOW_CLASSIFY_N_TABLES;
20356   int ret;
20357
20358   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20359     ;
20360   else
20361     {
20362       errmsg ("classify table type must be specified");
20363       return -99;
20364     }
20365
20366   if (!vam->json_output)
20367     {
20368       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20369     }
20370
20371   M (FLOW_CLASSIFY_DUMP, mp);
20372   mp->type = type;
20373   /* send it... */
20374   S (mp);
20375
20376   /* Use a control ping for synchronization */
20377   MPING (CONTROL_PING, mp_ping);
20378   S (mp_ping);
20379
20380   /* Wait for a reply... */
20381   W (ret);
20382   return ret;
20383 }
20384
20385 static int
20386 api_feature_enable_disable (vat_main_t * vam)
20387 {
20388   unformat_input_t *i = vam->input;
20389   vl_api_feature_enable_disable_t *mp;
20390   u8 *arc_name = 0;
20391   u8 *feature_name = 0;
20392   u32 sw_if_index = ~0;
20393   u8 enable = 1;
20394   int ret;
20395
20396   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20397     {
20398       if (unformat (i, "arc_name %s", &arc_name))
20399         ;
20400       else if (unformat (i, "feature_name %s", &feature_name))
20401         ;
20402       else
20403         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20404         ;
20405       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20406         ;
20407       else if (unformat (i, "disable"))
20408         enable = 0;
20409       else
20410         break;
20411     }
20412
20413   if (arc_name == 0)
20414     {
20415       errmsg ("missing arc name");
20416       return -99;
20417     }
20418   if (vec_len (arc_name) > 63)
20419     {
20420       errmsg ("arc name too long");
20421     }
20422
20423   if (feature_name == 0)
20424     {
20425       errmsg ("missing feature name");
20426       return -99;
20427     }
20428   if (vec_len (feature_name) > 63)
20429     {
20430       errmsg ("feature name too long");
20431     }
20432
20433   if (sw_if_index == ~0)
20434     {
20435       errmsg ("missing interface name or sw_if_index");
20436       return -99;
20437     }
20438
20439   /* Construct the API message */
20440   M (FEATURE_ENABLE_DISABLE, mp);
20441   mp->sw_if_index = ntohl (sw_if_index);
20442   mp->enable = enable;
20443   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20444   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20445   vec_free (arc_name);
20446   vec_free (feature_name);
20447
20448   S (mp);
20449   W (ret);
20450   return ret;
20451 }
20452
20453 static int
20454 api_sw_interface_tag_add_del (vat_main_t * vam)
20455 {
20456   unformat_input_t *i = vam->input;
20457   vl_api_sw_interface_tag_add_del_t *mp;
20458   u32 sw_if_index = ~0;
20459   u8 *tag = 0;
20460   u8 enable = 1;
20461   int ret;
20462
20463   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20464     {
20465       if (unformat (i, "tag %s", &tag))
20466         ;
20467       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20468         ;
20469       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20470         ;
20471       else if (unformat (i, "del"))
20472         enable = 0;
20473       else
20474         break;
20475     }
20476
20477   if (sw_if_index == ~0)
20478     {
20479       errmsg ("missing interface name or sw_if_index");
20480       return -99;
20481     }
20482
20483   if (enable && (tag == 0))
20484     {
20485       errmsg ("no tag specified");
20486       return -99;
20487     }
20488
20489   /* Construct the API message */
20490   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20491   mp->sw_if_index = ntohl (sw_if_index);
20492   mp->is_add = enable;
20493   if (enable)
20494     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20495   vec_free (tag);
20496
20497   S (mp);
20498   W (ret);
20499   return ret;
20500 }
20501
20502 static void vl_api_l2_xconnect_details_t_handler
20503   (vl_api_l2_xconnect_details_t * mp)
20504 {
20505   vat_main_t *vam = &vat_main;
20506
20507   print (vam->ofp, "%15d%15d",
20508          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20509 }
20510
20511 static void vl_api_l2_xconnect_details_t_handler_json
20512   (vl_api_l2_xconnect_details_t * mp)
20513 {
20514   vat_main_t *vam = &vat_main;
20515   vat_json_node_t *node = NULL;
20516
20517   if (VAT_JSON_ARRAY != vam->json_tree.type)
20518     {
20519       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20520       vat_json_init_array (&vam->json_tree);
20521     }
20522   node = vat_json_array_add (&vam->json_tree);
20523
20524   vat_json_init_object (node);
20525   vat_json_object_add_uint (node, "rx_sw_if_index",
20526                             ntohl (mp->rx_sw_if_index));
20527   vat_json_object_add_uint (node, "tx_sw_if_index",
20528                             ntohl (mp->tx_sw_if_index));
20529 }
20530
20531 static int
20532 api_l2_xconnect_dump (vat_main_t * vam)
20533 {
20534   vl_api_l2_xconnect_dump_t *mp;
20535   vl_api_control_ping_t *mp_ping;
20536   int ret;
20537
20538   if (!vam->json_output)
20539     {
20540       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20541     }
20542
20543   M (L2_XCONNECT_DUMP, mp);
20544
20545   S (mp);
20546
20547   /* Use a control ping for synchronization */
20548   MPING (CONTROL_PING, mp_ping);
20549   S (mp_ping);
20550
20551   W (ret);
20552   return ret;
20553 }
20554
20555 static int
20556 api_sw_interface_set_mtu (vat_main_t * vam)
20557 {
20558   unformat_input_t *i = vam->input;
20559   vl_api_sw_interface_set_mtu_t *mp;
20560   u32 sw_if_index = ~0;
20561   u32 mtu = 0;
20562   int ret;
20563
20564   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20565     {
20566       if (unformat (i, "mtu %d", &mtu))
20567         ;
20568       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20569         ;
20570       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20571         ;
20572       else
20573         break;
20574     }
20575
20576   if (sw_if_index == ~0)
20577     {
20578       errmsg ("missing interface name or sw_if_index");
20579       return -99;
20580     }
20581
20582   if (mtu == 0)
20583     {
20584       errmsg ("no mtu specified");
20585       return -99;
20586     }
20587
20588   /* Construct the API message */
20589   M (SW_INTERFACE_SET_MTU, mp);
20590   mp->sw_if_index = ntohl (sw_if_index);
20591   mp->mtu = ntohs ((u16) mtu);
20592
20593   S (mp);
20594   W (ret);
20595   return ret;
20596 }
20597
20598 static int
20599 api_p2p_ethernet_add (vat_main_t * vam)
20600 {
20601   unformat_input_t *i = vam->input;
20602   vl_api_p2p_ethernet_add_t *mp;
20603   u32 parent_if_index = ~0;
20604   u32 sub_id = ~0;
20605   u8 remote_mac[6];
20606   u8 mac_set = 0;
20607   int ret;
20608
20609   memset (remote_mac, 0, sizeof (remote_mac));
20610   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20611     {
20612       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20613         ;
20614       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20615         ;
20616       else
20617         if (unformat
20618             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20619         mac_set++;
20620       else if (unformat (i, "sub_id %d", &sub_id))
20621         ;
20622       else
20623         {
20624           clib_warning ("parse error '%U'", format_unformat_error, i);
20625           return -99;
20626         }
20627     }
20628
20629   if (parent_if_index == ~0)
20630     {
20631       errmsg ("missing interface name or sw_if_index");
20632       return -99;
20633     }
20634   if (mac_set == 0)
20635     {
20636       errmsg ("missing remote mac address");
20637       return -99;
20638     }
20639   if (sub_id == ~0)
20640     {
20641       errmsg ("missing sub-interface id");
20642       return -99;
20643     }
20644
20645   M (P2P_ETHERNET_ADD, mp);
20646   mp->parent_if_index = ntohl (parent_if_index);
20647   mp->subif_id = ntohl (sub_id);
20648   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20649
20650   S (mp);
20651   W (ret);
20652   return ret;
20653 }
20654
20655 static int
20656 api_p2p_ethernet_del (vat_main_t * vam)
20657 {
20658   unformat_input_t *i = vam->input;
20659   vl_api_p2p_ethernet_del_t *mp;
20660   u32 parent_if_index = ~0;
20661   u8 remote_mac[6];
20662   u8 mac_set = 0;
20663   int ret;
20664
20665   memset (remote_mac, 0, sizeof (remote_mac));
20666   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20667     {
20668       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20669         ;
20670       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20671         ;
20672       else
20673         if (unformat
20674             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20675         mac_set++;
20676       else
20677         {
20678           clib_warning ("parse error '%U'", format_unformat_error, i);
20679           return -99;
20680         }
20681     }
20682
20683   if (parent_if_index == ~0)
20684     {
20685       errmsg ("missing interface name or sw_if_index");
20686       return -99;
20687     }
20688   if (mac_set == 0)
20689     {
20690       errmsg ("missing remote mac address");
20691       return -99;
20692     }
20693
20694   M (P2P_ETHERNET_DEL, mp);
20695   mp->parent_if_index = ntohl (parent_if_index);
20696   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20697
20698   S (mp);
20699   W (ret);
20700   return ret;
20701 }
20702
20703 static int
20704 api_lldp_config (vat_main_t * vam)
20705 {
20706   unformat_input_t *i = vam->input;
20707   vl_api_lldp_config_t *mp;
20708   int tx_hold = 0;
20709   int tx_interval = 0;
20710   u8 *sys_name = NULL;
20711   int ret;
20712
20713   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20714     {
20715       if (unformat (i, "system-name %s", &sys_name))
20716         ;
20717       else if (unformat (i, "tx-hold %d", &tx_hold))
20718         ;
20719       else if (unformat (i, "tx-interval %d", &tx_interval))
20720         ;
20721       else
20722         {
20723           clib_warning ("parse error '%U'", format_unformat_error, i);
20724           return -99;
20725         }
20726     }
20727
20728   vec_add1 (sys_name, 0);
20729
20730   M (LLDP_CONFIG, mp);
20731   mp->tx_hold = htonl (tx_hold);
20732   mp->tx_interval = htonl (tx_interval);
20733   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20734   vec_free (sys_name);
20735
20736   S (mp);
20737   W (ret);
20738   return ret;
20739 }
20740
20741 static int
20742 api_sw_interface_set_lldp (vat_main_t * vam)
20743 {
20744   unformat_input_t *i = vam->input;
20745   vl_api_sw_interface_set_lldp_t *mp;
20746   u32 sw_if_index = ~0;
20747   u32 enable = 1;
20748   u8 *port_desc = NULL, *mgmt_oid = NULL;
20749   ip4_address_t ip4_addr;
20750   ip6_address_t ip6_addr;
20751   int ret;
20752
20753   memset (&ip4_addr, 0, sizeof (ip4_addr));
20754   memset (&ip6_addr, 0, sizeof (ip6_addr));
20755
20756   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20757     {
20758       if (unformat (i, "disable"))
20759         enable = 0;
20760       else
20761         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20762         ;
20763       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20764         ;
20765       else if (unformat (i, "port-desc %s", &port_desc))
20766         ;
20767       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20768         ;
20769       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20770         ;
20771       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20772         ;
20773       else
20774         break;
20775     }
20776
20777   if (sw_if_index == ~0)
20778     {
20779       errmsg ("missing interface name or sw_if_index");
20780       return -99;
20781     }
20782
20783   /* Construct the API message */
20784   vec_add1 (port_desc, 0);
20785   vec_add1 (mgmt_oid, 0);
20786   M (SW_INTERFACE_SET_LLDP, mp);
20787   mp->sw_if_index = ntohl (sw_if_index);
20788   mp->enable = enable;
20789   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20790   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20791   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20792   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20793   vec_free (port_desc);
20794   vec_free (mgmt_oid);
20795
20796   S (mp);
20797   W (ret);
20798   return ret;
20799 }
20800
20801 static int
20802 api_tcp_configure_src_addresses (vat_main_t * vam)
20803 {
20804   vl_api_tcp_configure_src_addresses_t *mp;
20805   unformat_input_t *i = vam->input;
20806   ip4_address_t v4first, v4last;
20807   ip6_address_t v6first, v6last;
20808   u8 range_set = 0;
20809   u32 vrf_id = 0;
20810   int ret;
20811
20812   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20813     {
20814       if (unformat (i, "%U - %U",
20815                     unformat_ip4_address, &v4first,
20816                     unformat_ip4_address, &v4last))
20817         {
20818           if (range_set)
20819             {
20820               errmsg ("one range per message (range already set)");
20821               return -99;
20822             }
20823           range_set = 1;
20824         }
20825       else if (unformat (i, "%U - %U",
20826                          unformat_ip6_address, &v6first,
20827                          unformat_ip6_address, &v6last))
20828         {
20829           if (range_set)
20830             {
20831               errmsg ("one range per message (range already set)");
20832               return -99;
20833             }
20834           range_set = 2;
20835         }
20836       else if (unformat (i, "vrf %d", &vrf_id))
20837         ;
20838       else
20839         break;
20840     }
20841
20842   if (range_set == 0)
20843     {
20844       errmsg ("address range not set");
20845       return -99;
20846     }
20847
20848   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20849   mp->vrf_id = ntohl (vrf_id);
20850   /* ipv6? */
20851   if (range_set == 2)
20852     {
20853       mp->is_ipv6 = 1;
20854       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20855       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20856     }
20857   else
20858     {
20859       mp->is_ipv6 = 0;
20860       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20861       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20862     }
20863   S (mp);
20864   W (ret);
20865   return ret;
20866 }
20867
20868 static int
20869 api_app_namespace_add_del (vat_main_t * vam)
20870 {
20871   vl_api_app_namespace_add_del_t *mp;
20872   unformat_input_t *i = vam->input;
20873   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
20874   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
20875   u64 secret;
20876   int ret;
20877
20878   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20879     {
20880       if (unformat (i, "id %_%v%_", &ns_id))
20881         ;
20882       else if (unformat (i, "secret %lu", &secret))
20883         secret_set = 1;
20884       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20885         sw_if_index_set = 1;
20886       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
20887         ;
20888       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
20889         ;
20890       else
20891         break;
20892     }
20893   if (!ns_id || !secret_set || !sw_if_index_set)
20894     {
20895       errmsg ("namespace id, secret and sw_if_index must be set");
20896       return -99;
20897     }
20898   if (vec_len (ns_id) > 64)
20899     {
20900       errmsg ("namespace id too long");
20901       return -99;
20902     }
20903   M (APP_NAMESPACE_ADD_DEL, mp);
20904
20905   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
20906   mp->namespace_id_len = vec_len (ns_id);
20907   mp->secret = secret;
20908   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20909   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
20910   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
20911   vec_free (ns_id);
20912   S (mp);
20913   W (ret);
20914   return ret;
20915 }
20916
20917 static int
20918 api_memfd_segment_create (vat_main_t * vam)
20919 {
20920 #if VPP_API_TEST_BUILTIN == 0
20921   unformat_input_t *i = vam->input;
20922   vl_api_memfd_segment_create_t *mp;
20923   u64 size = 64 << 20;
20924   int ret;
20925
20926   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20927     {
20928       if (unformat (i, "size %U", unformat_memory_size, &size))
20929         ;
20930       else
20931         break;
20932     }
20933
20934   M (MEMFD_SEGMENT_CREATE, mp);
20935   mp->requested_size = size;
20936   S (mp);
20937   W (ret);
20938   return ret;
20939
20940 #else
20941   errmsg ("memfd_segment_create (builtin) not supported");
20942   return -99;
20943 #endif
20944 }
20945
20946 static int
20947 api_dns_enable_disable (vat_main_t * vam)
20948 {
20949   unformat_input_t *line_input = vam->input;
20950   vl_api_dns_enable_disable_t *mp;
20951   u8 enable_disable = 1;
20952   int ret;
20953
20954   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20955     {
20956       if (unformat (line_input, "disable"))
20957         enable_disable = 0;
20958       if (unformat (line_input, "enable"))
20959         enable_disable = 1;
20960       else
20961         break;
20962     }
20963
20964   /* Construct the API message */
20965   M (DNS_ENABLE_DISABLE, mp);
20966   mp->enable = enable_disable;
20967
20968   /* send it... */
20969   S (mp);
20970   /* Wait for the reply */
20971   W (ret);
20972   return ret;
20973 }
20974
20975 static int
20976 api_dns_resolve_name (vat_main_t * vam)
20977 {
20978   unformat_input_t *line_input = vam->input;
20979   vl_api_dns_resolve_name_t *mp;
20980   u8 *name = 0;
20981   int ret;
20982
20983   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20984     {
20985       if (unformat (line_input, "%s", &name))
20986         ;
20987       else
20988         break;
20989     }
20990
20991   if (vec_len (name) > 127)
20992     {
20993       errmsg ("name too long");
20994       return -99;
20995     }
20996
20997   /* Construct the API message */
20998   M (DNS_RESOLVE_NAME, mp);
20999   memcpy (mp->name, name, vec_len (name));
21000   vec_free (name);
21001
21002   /* send it... */
21003   S (mp);
21004   /* Wait for the reply */
21005   W (ret);
21006   return ret;
21007 }
21008
21009 static int
21010 api_dns_name_server_add_del (vat_main_t * vam)
21011 {
21012   unformat_input_t *i = vam->input;
21013   vl_api_dns_name_server_add_del_t *mp;
21014   u8 is_add = 1;
21015   ip6_address_t ip6_server;
21016   ip4_address_t ip4_server;
21017   int ip6_set = 0;
21018   int ip4_set = 0;
21019   int ret = 0;
21020
21021   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21022     {
21023       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21024         ip6_set = 1;
21025       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21026         ip4_set = 1;
21027       else if (unformat (i, "del"))
21028         is_add = 0;
21029       else
21030         {
21031           clib_warning ("parse error '%U'", format_unformat_error, i);
21032           return -99;
21033         }
21034     }
21035
21036   if (ip4_set && ip6_set)
21037     {
21038       errmsg ("Only one server address allowed per message");
21039       return -99;
21040     }
21041   if ((ip4_set + ip6_set) == 0)
21042     {
21043       errmsg ("Server address required");
21044       return -99;
21045     }
21046
21047   /* Construct the API message */
21048   M (DNS_NAME_SERVER_ADD_DEL, mp);
21049
21050   if (ip6_set)
21051     {
21052       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21053       mp->is_ip6 = 1;
21054     }
21055   else
21056     {
21057       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21058       mp->is_ip6 = 0;
21059     }
21060
21061   mp->is_add = is_add;
21062
21063   /* send it... */
21064   S (mp);
21065
21066   /* Wait for a reply, return good/bad news  */
21067   W (ret);
21068   return ret;
21069 }
21070
21071
21072 static int
21073 q_or_quit (vat_main_t * vam)
21074 {
21075 #if VPP_API_TEST_BUILTIN == 0
21076   longjmp (vam->jump_buf, 1);
21077 #endif
21078   return 0;                     /* not so much */
21079 }
21080
21081 static int
21082 q (vat_main_t * vam)
21083 {
21084   return q_or_quit (vam);
21085 }
21086
21087 static int
21088 quit (vat_main_t * vam)
21089 {
21090   return q_or_quit (vam);
21091 }
21092
21093 static int
21094 comment (vat_main_t * vam)
21095 {
21096   return 0;
21097 }
21098
21099 static int
21100 cmd_cmp (void *a1, void *a2)
21101 {
21102   u8 **c1 = a1;
21103   u8 **c2 = a2;
21104
21105   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21106 }
21107
21108 static int
21109 help (vat_main_t * vam)
21110 {
21111   u8 **cmds = 0;
21112   u8 *name = 0;
21113   hash_pair_t *p;
21114   unformat_input_t *i = vam->input;
21115   int j;
21116
21117   if (unformat (i, "%s", &name))
21118     {
21119       uword *hs;
21120
21121       vec_add1 (name, 0);
21122
21123       hs = hash_get_mem (vam->help_by_name, name);
21124       if (hs)
21125         print (vam->ofp, "usage: %s %s", name, hs[0]);
21126       else
21127         print (vam->ofp, "No such msg / command '%s'", name);
21128       vec_free (name);
21129       return 0;
21130     }
21131
21132   print (vam->ofp, "Help is available for the following:");
21133
21134     /* *INDENT-OFF* */
21135     hash_foreach_pair (p, vam->function_by_name,
21136     ({
21137       vec_add1 (cmds, (u8 *)(p->key));
21138     }));
21139     /* *INDENT-ON* */
21140
21141   vec_sort_with_function (cmds, cmd_cmp);
21142
21143   for (j = 0; j < vec_len (cmds); j++)
21144     print (vam->ofp, "%s", cmds[j]);
21145
21146   vec_free (cmds);
21147   return 0;
21148 }
21149
21150 static int
21151 set (vat_main_t * vam)
21152 {
21153   u8 *name = 0, *value = 0;
21154   unformat_input_t *i = vam->input;
21155
21156   if (unformat (i, "%s", &name))
21157     {
21158       /* The input buffer is a vector, not a string. */
21159       value = vec_dup (i->buffer);
21160       vec_delete (value, i->index, 0);
21161       /* Almost certainly has a trailing newline */
21162       if (value[vec_len (value) - 1] == '\n')
21163         value[vec_len (value) - 1] = 0;
21164       /* Make sure it's a proper string, one way or the other */
21165       vec_add1 (value, 0);
21166       (void) clib_macro_set_value (&vam->macro_main,
21167                                    (char *) name, (char *) value);
21168     }
21169   else
21170     errmsg ("usage: set <name> <value>");
21171
21172   vec_free (name);
21173   vec_free (value);
21174   return 0;
21175 }
21176
21177 static int
21178 unset (vat_main_t * vam)
21179 {
21180   u8 *name = 0;
21181
21182   if (unformat (vam->input, "%s", &name))
21183     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21184       errmsg ("unset: %s wasn't set", name);
21185   vec_free (name);
21186   return 0;
21187 }
21188
21189 typedef struct
21190 {
21191   u8 *name;
21192   u8 *value;
21193 } macro_sort_t;
21194
21195
21196 static int
21197 macro_sort_cmp (void *a1, void *a2)
21198 {
21199   macro_sort_t *s1 = a1;
21200   macro_sort_t *s2 = a2;
21201
21202   return strcmp ((char *) (s1->name), (char *) (s2->name));
21203 }
21204
21205 static int
21206 dump_macro_table (vat_main_t * vam)
21207 {
21208   macro_sort_t *sort_me = 0, *sm;
21209   int i;
21210   hash_pair_t *p;
21211
21212     /* *INDENT-OFF* */
21213     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21214     ({
21215       vec_add2 (sort_me, sm, 1);
21216       sm->name = (u8 *)(p->key);
21217       sm->value = (u8 *) (p->value[0]);
21218     }));
21219     /* *INDENT-ON* */
21220
21221   vec_sort_with_function (sort_me, macro_sort_cmp);
21222
21223   if (vec_len (sort_me))
21224     print (vam->ofp, "%-15s%s", "Name", "Value");
21225   else
21226     print (vam->ofp, "The macro table is empty...");
21227
21228   for (i = 0; i < vec_len (sort_me); i++)
21229     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21230   return 0;
21231 }
21232
21233 static int
21234 dump_node_table (vat_main_t * vam)
21235 {
21236   int i, j;
21237   vlib_node_t *node, *next_node;
21238
21239   if (vec_len (vam->graph_nodes) == 0)
21240     {
21241       print (vam->ofp, "Node table empty, issue get_node_graph...");
21242       return 0;
21243     }
21244
21245   for (i = 0; i < vec_len (vam->graph_nodes); i++)
21246     {
21247       node = vam->graph_nodes[i];
21248       print (vam->ofp, "[%d] %s", i, node->name);
21249       for (j = 0; j < vec_len (node->next_nodes); j++)
21250         {
21251           if (node->next_nodes[j] != ~0)
21252             {
21253               next_node = vam->graph_nodes[node->next_nodes[j]];
21254               print (vam->ofp, "  [%d] %s", j, next_node->name);
21255             }
21256         }
21257     }
21258   return 0;
21259 }
21260
21261 static int
21262 value_sort_cmp (void *a1, void *a2)
21263 {
21264   name_sort_t *n1 = a1;
21265   name_sort_t *n2 = a2;
21266
21267   if (n1->value < n2->value)
21268     return -1;
21269   if (n1->value > n2->value)
21270     return 1;
21271   return 0;
21272 }
21273
21274
21275 static int
21276 dump_msg_api_table (vat_main_t * vam)
21277 {
21278   api_main_t *am = &api_main;
21279   name_sort_t *nses = 0, *ns;
21280   hash_pair_t *hp;
21281   int i;
21282
21283   /* *INDENT-OFF* */
21284   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21285   ({
21286     vec_add2 (nses, ns, 1);
21287     ns->name = (u8 *)(hp->key);
21288     ns->value = (u32) hp->value[0];
21289   }));
21290   /* *INDENT-ON* */
21291
21292   vec_sort_with_function (nses, value_sort_cmp);
21293
21294   for (i = 0; i < vec_len (nses); i++)
21295     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21296   vec_free (nses);
21297   return 0;
21298 }
21299
21300 static int
21301 get_msg_id (vat_main_t * vam)
21302 {
21303   u8 *name_and_crc;
21304   u32 message_index;
21305
21306   if (unformat (vam->input, "%s", &name_and_crc))
21307     {
21308       message_index = vl_api_get_msg_index (name_and_crc);
21309       if (message_index == ~0)
21310         {
21311           print (vam->ofp, " '%s' not found", name_and_crc);
21312           return 0;
21313         }
21314       print (vam->ofp, " '%s' has message index %d",
21315              name_and_crc, message_index);
21316       return 0;
21317     }
21318   errmsg ("name_and_crc required...");
21319   return 0;
21320 }
21321
21322 static int
21323 search_node_table (vat_main_t * vam)
21324 {
21325   unformat_input_t *line_input = vam->input;
21326   u8 *node_to_find;
21327   int j;
21328   vlib_node_t *node, *next_node;
21329   uword *p;
21330
21331   if (vam->graph_node_index_by_name == 0)
21332     {
21333       print (vam->ofp, "Node table empty, issue get_node_graph...");
21334       return 0;
21335     }
21336
21337   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21338     {
21339       if (unformat (line_input, "%s", &node_to_find))
21340         {
21341           vec_add1 (node_to_find, 0);
21342           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21343           if (p == 0)
21344             {
21345               print (vam->ofp, "%s not found...", node_to_find);
21346               goto out;
21347             }
21348           node = vam->graph_nodes[p[0]];
21349           print (vam->ofp, "[%d] %s", p[0], node->name);
21350           for (j = 0; j < vec_len (node->next_nodes); j++)
21351             {
21352               if (node->next_nodes[j] != ~0)
21353                 {
21354                   next_node = vam->graph_nodes[node->next_nodes[j]];
21355                   print (vam->ofp, "  [%d] %s", j, next_node->name);
21356                 }
21357             }
21358         }
21359
21360       else
21361         {
21362           clib_warning ("parse error '%U'", format_unformat_error,
21363                         line_input);
21364           return -99;
21365         }
21366
21367     out:
21368       vec_free (node_to_find);
21369
21370     }
21371
21372   return 0;
21373 }
21374
21375
21376 static int
21377 script (vat_main_t * vam)
21378 {
21379 #if (VPP_API_TEST_BUILTIN==0)
21380   u8 *s = 0;
21381   char *save_current_file;
21382   unformat_input_t save_input;
21383   jmp_buf save_jump_buf;
21384   u32 save_line_number;
21385
21386   FILE *new_fp, *save_ifp;
21387
21388   if (unformat (vam->input, "%s", &s))
21389     {
21390       new_fp = fopen ((char *) s, "r");
21391       if (new_fp == 0)
21392         {
21393           errmsg ("Couldn't open script file %s", s);
21394           vec_free (s);
21395           return -99;
21396         }
21397     }
21398   else
21399     {
21400       errmsg ("Missing script name");
21401       return -99;
21402     }
21403
21404   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
21405   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
21406   save_ifp = vam->ifp;
21407   save_line_number = vam->input_line_number;
21408   save_current_file = (char *) vam->current_file;
21409
21410   vam->input_line_number = 0;
21411   vam->ifp = new_fp;
21412   vam->current_file = s;
21413   do_one_file (vam);
21414
21415   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
21416   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
21417   vam->ifp = save_ifp;
21418   vam->input_line_number = save_line_number;
21419   vam->current_file = (u8 *) save_current_file;
21420   vec_free (s);
21421
21422   return 0;
21423 #else
21424   clib_warning ("use the exec command...");
21425   return -99;
21426 #endif
21427 }
21428
21429 static int
21430 echo (vat_main_t * vam)
21431 {
21432   print (vam->ofp, "%v", vam->input->buffer);
21433   return 0;
21434 }
21435
21436 /* List of API message constructors, CLI names map to api_xxx */
21437 #define foreach_vpe_api_msg                                             \
21438 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
21439 _(sw_interface_dump,"")                                                 \
21440 _(sw_interface_set_flags,                                               \
21441   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
21442 _(sw_interface_add_del_address,                                         \
21443   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
21444 _(sw_interface_set_table,                                               \
21445   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
21446 _(sw_interface_set_mpls_enable,                                         \
21447   "<intfc> | sw_if_index [disable | dis]")                              \
21448 _(sw_interface_set_vpath,                                               \
21449   "<intfc> | sw_if_index <id> enable | disable")                        \
21450 _(sw_interface_set_vxlan_bypass,                                        \
21451   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21452 _(sw_interface_set_geneve_bypass,                                       \
21453   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21454 _(sw_interface_set_l2_xconnect,                                         \
21455   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21456   "enable | disable")                                                   \
21457 _(sw_interface_set_l2_bridge,                                           \
21458   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
21459   "[shg <split-horizon-group>] [bvi]\n"                                 \
21460   "enable | disable")                                                   \
21461 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
21462 _(bridge_domain_add_del,                                                \
21463   "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") \
21464 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
21465 _(l2fib_add_del,                                                        \
21466   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
21467 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
21468 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
21469 _(l2_flags,                                                             \
21470   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21471 _(bridge_flags,                                                         \
21472   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21473 _(tap_connect,                                                          \
21474   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
21475 _(tap_modify,                                                           \
21476   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
21477 _(tap_delete,                                                           \
21478   "<vpp-if-name> | sw_if_index <id>")                                   \
21479 _(sw_interface_tap_dump, "")                                            \
21480 _(ip_table_add_del,                                                     \
21481   "table-id <n> [ipv6]\n")                                              \
21482 _(ip_add_del_route,                                                     \
21483   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
21484   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
21485   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
21486   "[multipath] [count <n>]")                                            \
21487 _(ip_mroute_add_del,                                                    \
21488   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
21489   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
21490 _(mpls_table_add_del,                                                   \
21491   "table-id <n>\n")                                                     \
21492 _(mpls_route_add_del,                                                   \
21493   "<label> <eos> via <addr> [table-id <n>]\n"                           \
21494   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
21495   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
21496   "[multipath] [count <n>]")                                            \
21497 _(mpls_ip_bind_unbind,                                                  \
21498   "<label> <addr/len>")                                                 \
21499 _(mpls_tunnel_add_del,                                                  \
21500   " via <addr> [table-id <n>]\n"                                        \
21501   "sw_if_index <id>] [l2]  [del]")                                      \
21502 _(proxy_arp_add_del,                                                    \
21503   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
21504 _(proxy_arp_intfc_enable_disable,                                       \
21505   "<intfc> | sw_if_index <id> enable | disable")                        \
21506 _(sw_interface_set_unnumbered,                                          \
21507   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
21508 _(ip_neighbor_add_del,                                                  \
21509   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
21510   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
21511 _(reset_vrf, "vrf <id> [ipv6]")                                         \
21512 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
21513 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
21514   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
21515   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
21516   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
21517 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
21518 _(reset_fib, "vrf <n> [ipv6]")                                          \
21519 _(dhcp_proxy_config,                                                    \
21520   "svr <v46-address> src <v46-address>\n"                               \
21521    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
21522 _(dhcp_proxy_set_vss,                                                   \
21523   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
21524 _(dhcp_proxy_dump, "ip6")                                               \
21525 _(dhcp_client_config,                                                   \
21526   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
21527 _(set_ip_flow_hash,                                                     \
21528   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
21529 _(sw_interface_ip6_enable_disable,                                      \
21530   "<intfc> | sw_if_index <id> enable | disable")                        \
21531 _(sw_interface_ip6_set_link_local_address,                              \
21532   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
21533 _(ip6nd_proxy_add_del,                                                  \
21534   "<intfc> | sw_if_index <id> <ip6-address>")                           \
21535 _(ip6nd_proxy_dump, "")                                                 \
21536 _(sw_interface_ip6nd_ra_prefix,                                         \
21537   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
21538   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
21539   "[nolink] [isno]")                                                    \
21540 _(sw_interface_ip6nd_ra_config,                                         \
21541   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
21542   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
21543   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
21544 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
21545 _(l2_patch_add_del,                                                     \
21546   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21547   "enable | disable")                                                   \
21548 _(sr_localsid_add_del,                                                  \
21549   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
21550   "fib-table <num> (end.psp) sw_if_index <num>")                        \
21551 _(classify_add_del_table,                                               \
21552   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
21553   " [del] [del-chain] mask <mask-value>\n"                              \
21554   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
21555   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
21556 _(classify_add_del_session,                                             \
21557   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
21558   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
21559   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
21560   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
21561 _(classify_set_interface_ip_table,                                      \
21562   "<intfc> | sw_if_index <nn> table <nn>")                              \
21563 _(classify_set_interface_l2_tables,                                     \
21564   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21565   "  [other-table <nn>]")                                               \
21566 _(get_node_index, "node <node-name")                                    \
21567 _(add_node_next, "node <node-name> next <next-node-name>")              \
21568 _(l2tpv3_create_tunnel,                                                 \
21569   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
21570   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
21571   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
21572 _(l2tpv3_set_tunnel_cookies,                                            \
21573   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
21574   "[new_remote_cookie <nn>]\n")                                         \
21575 _(l2tpv3_interface_enable_disable,                                      \
21576   "<intfc> | sw_if_index <nn> enable | disable")                        \
21577 _(l2tpv3_set_lookup_key,                                                \
21578   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
21579 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
21580 _(vxlan_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 _(geneve_add_del_tunnel,                                                \
21585   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21586   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21587   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21588 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
21589 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
21590 _(gre_add_del_tunnel,                                                   \
21591   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
21592 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
21593 _(l2_fib_clear_table, "")                                               \
21594 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
21595 _(l2_interface_vlan_tag_rewrite,                                        \
21596   "<intfc> | sw_if_index <nn> \n"                                       \
21597   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
21598   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
21599 _(create_vhost_user_if,                                                 \
21600         "socket <filename> [server] [renumber <dev_instance>] "         \
21601         "[mac <mac_address>]")                                          \
21602 _(modify_vhost_user_if,                                                 \
21603         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
21604         "[server] [renumber <dev_instance>]")                           \
21605 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
21606 _(sw_interface_vhost_user_dump, "")                                     \
21607 _(show_version, "")                                                     \
21608 _(vxlan_gpe_add_del_tunnel,                                             \
21609   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
21610   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21611   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
21612   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
21613 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
21614 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
21615 _(interface_name_renumber,                                              \
21616   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
21617 _(input_acl_set_interface,                                              \
21618   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21619   "  [l2-table <nn>] [del]")                                            \
21620 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
21621 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
21622 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
21623 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
21624 _(ip_dump, "ipv4 | ipv6")                                               \
21625 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
21626 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
21627   "  spid_id <n> ")                                                     \
21628 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
21629   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
21630   "  integ_alg <alg> integ_key <hex>")                                  \
21631 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
21632   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
21633   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
21634   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
21635 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
21636 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
21637   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
21638   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
21639   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
21640 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
21641 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
21642   "  <alg> <hex>\n")                                                    \
21643 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
21644 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
21645   "(auth_data 0x<data> | auth_data <data>)")                            \
21646 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
21647   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
21648 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
21649   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
21650   "(local|remote)")                                                     \
21651 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
21652 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
21653 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
21654 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
21655 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
21656 _(ikev2_initiate_sa_init, "<profile_name>")                             \
21657 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
21658 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
21659 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
21660 _(delete_loopback,"sw_if_index <nn>")                                   \
21661 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
21662 _(map_add_domain,                                                       \
21663   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
21664   "ip6-src <ip6addr> "                                                  \
21665   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
21666 _(map_del_domain, "index <n>")                                          \
21667 _(map_add_del_rule,                                                     \
21668   "index <n> psid <n> dst <ip6addr> [del]")                             \
21669 _(map_domain_dump, "")                                                  \
21670 _(map_rule_dump, "index <map-domain>")                                  \
21671 _(want_interface_events,  "enable|disable")                             \
21672 _(want_stats,"enable|disable")                                          \
21673 _(get_first_msg_id, "client <name>")                                    \
21674 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
21675 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
21676   "fib-id <nn> [ip4][ip6][default]")                                    \
21677 _(get_node_graph, " ")                                                  \
21678 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
21679 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
21680 _(ioam_disable, "")                                                     \
21681 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
21682                             " sw_if_index <sw_if_index> p <priority> "  \
21683                             "w <weight>] [del]")                        \
21684 _(one_add_del_locator, "locator-set <locator_name> "                    \
21685                         "iface <intf> | sw_if_index <sw_if_index> "     \
21686                         "p <priority> w <weight> [del]")                \
21687 _(one_add_del_local_eid,"vni <vni> eid "                                \
21688                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21689                          "locator-set <locator_name> [del]"             \
21690                          "[key-id sha1|sha256 secret-key <secret-key>]")\
21691 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
21692 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
21693 _(one_enable_disable, "enable|disable")                                 \
21694 _(one_map_register_enable_disable, "enable|disable")                    \
21695 _(one_map_register_fallback_threshold, "<value>")                       \
21696 _(one_rloc_probe_enable_disable, "enable|disable")                      \
21697 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
21698                                "[seid <seid>] "                         \
21699                                "rloc <locator> p <prio> "               \
21700                                "w <weight> [rloc <loc> ... ] "          \
21701                                "action <action> [del-all]")             \
21702 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
21703                           "<local-eid>")                                \
21704 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
21705 _(one_use_petr, "ip-address> | disable")                                \
21706 _(one_map_request_mode, "src-dst|dst-only")                             \
21707 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
21708 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
21709 _(one_locator_set_dump, "[local | remote]")                             \
21710 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
21711 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
21712                        "[local] | [remote]")                            \
21713 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
21714 _(one_ndp_bd_get, "")                                                   \
21715 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
21716 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
21717 _(one_l2_arp_bd_get, "")                                                \
21718 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
21719 _(one_stats_enable_disable, "enable|disalbe")                           \
21720 _(show_one_stats_enable_disable, "")                                    \
21721 _(one_eid_table_vni_dump, "")                                           \
21722 _(one_eid_table_map_dump, "l2|l3")                                      \
21723 _(one_map_resolver_dump, "")                                            \
21724 _(one_map_server_dump, "")                                              \
21725 _(one_adjacencies_get, "vni <vni>")                                     \
21726 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
21727 _(show_one_rloc_probe_state, "")                                        \
21728 _(show_one_map_register_state, "")                                      \
21729 _(show_one_status, "")                                                  \
21730 _(one_stats_dump, "")                                                   \
21731 _(one_stats_flush, "")                                                  \
21732 _(one_get_map_request_itr_rlocs, "")                                    \
21733 _(one_map_register_set_ttl, "<ttl>")                                    \
21734 _(one_set_transport_protocol, "udp|api")                                \
21735 _(one_get_transport_protocol, "")                                       \
21736 _(show_one_nsh_mapping, "")                                             \
21737 _(show_one_pitr, "")                                                    \
21738 _(show_one_use_petr, "")                                                \
21739 _(show_one_map_request_mode, "")                                        \
21740 _(show_one_map_register_ttl, "")                                        \
21741 _(show_one_map_register_fallback_threshold, "")                         \
21742 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
21743                             " sw_if_index <sw_if_index> p <priority> "  \
21744                             "w <weight>] [del]")                        \
21745 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
21746                         "iface <intf> | sw_if_index <sw_if_index> "     \
21747                         "p <priority> w <weight> [del]")                \
21748 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
21749                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21750                          "locator-set <locator_name> [del]"             \
21751                          "[key-id sha1|sha256 secret-key <secret-key>]") \
21752 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
21753 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
21754 _(lisp_enable_disable, "enable|disable")                                \
21755 _(lisp_map_register_enable_disable, "enable|disable")                   \
21756 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
21757 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
21758                                "[seid <seid>] "                         \
21759                                "rloc <locator> p <prio> "               \
21760                                "w <weight> [rloc <loc> ... ] "          \
21761                                "action <action> [del-all]")             \
21762 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
21763                           "<local-eid>")                                \
21764 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
21765 _(lisp_use_petr, "<ip-address> | disable")                              \
21766 _(lisp_map_request_mode, "src-dst|dst-only")                            \
21767 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
21768 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
21769 _(lisp_locator_set_dump, "[local | remote]")                            \
21770 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
21771 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
21772                        "[local] | [remote]")                            \
21773 _(lisp_eid_table_vni_dump, "")                                          \
21774 _(lisp_eid_table_map_dump, "l2|l3")                                     \
21775 _(lisp_map_resolver_dump, "")                                           \
21776 _(lisp_map_server_dump, "")                                             \
21777 _(lisp_adjacencies_get, "vni <vni>")                                    \
21778 _(gpe_fwd_entry_vnis_get, "")                                           \
21779 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
21780 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
21781                                 "[table <table-id>]")                   \
21782 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
21783 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
21784 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
21785 _(gpe_get_encap_mode, "")                                               \
21786 _(lisp_gpe_add_del_iface, "up|down")                                    \
21787 _(lisp_gpe_enable_disable, "enable|disable")                            \
21788 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
21789   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
21790 _(show_lisp_rloc_probe_state, "")                                       \
21791 _(show_lisp_map_register_state, "")                                     \
21792 _(show_lisp_status, "")                                                 \
21793 _(lisp_get_map_request_itr_rlocs, "")                                   \
21794 _(show_lisp_pitr, "")                                                   \
21795 _(show_lisp_use_petr, "")                                               \
21796 _(show_lisp_map_request_mode, "")                                       \
21797 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
21798 _(af_packet_delete, "name <host interface name>")                       \
21799 _(policer_add_del, "name <policer name> <params> [del]")                \
21800 _(policer_dump, "[name <policer name>]")                                \
21801 _(policer_classify_set_interface,                                       \
21802   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21803   "  [l2-table <nn>] [del]")                                            \
21804 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
21805 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
21806     "[master|slave]")                                                   \
21807 _(netmap_delete, "name <interface name>")                               \
21808 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
21809 _(mpls_fib_dump, "")                                                    \
21810 _(classify_table_ids, "")                                               \
21811 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
21812 _(classify_table_info, "table_id <nn>")                                 \
21813 _(classify_session_dump, "table_id <nn>")                               \
21814 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
21815     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
21816     "[template_interval <nn>] [udp_checksum]")                          \
21817 _(ipfix_exporter_dump, "")                                              \
21818 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
21819 _(ipfix_classify_stream_dump, "")                                       \
21820 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
21821 _(ipfix_classify_table_dump, "")                                        \
21822 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
21823 _(sw_interface_span_dump, "[l2]")                                           \
21824 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
21825 _(pg_create_interface, "if_id <nn>")                                    \
21826 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
21827 _(pg_enable_disable, "[stream <id>] disable")                           \
21828 _(ip_source_and_port_range_check_add_del,                               \
21829   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
21830 _(ip_source_and_port_range_check_interface_add_del,                     \
21831   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
21832   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
21833 _(ipsec_gre_add_del_tunnel,                                             \
21834   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
21835 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
21836 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
21837 _(l2_interface_pbb_tag_rewrite,                                         \
21838   "<intfc> | sw_if_index <nn> \n"                                       \
21839   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
21840   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
21841 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
21842 _(flow_classify_set_interface,                                          \
21843   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
21844 _(flow_classify_dump, "type [ip4|ip6]")                                 \
21845 _(ip_fib_dump, "")                                                      \
21846 _(ip_mfib_dump, "")                                                     \
21847 _(ip6_fib_dump, "")                                                     \
21848 _(ip6_mfib_dump, "")                                                    \
21849 _(feature_enable_disable, "arc_name <arc_name> "                        \
21850   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
21851 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
21852 "[disable]")                                                            \
21853 _(l2_xconnect_dump, "")                                                 \
21854 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
21855 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
21856 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
21857 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
21858 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
21859 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
21860 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
21861   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
21862 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
21863 _(memfd_segment_create,"size <nnn>")                                    \
21864 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
21865 _(dns_enable_disable, "[enable][disable]")                              \
21866 _(dns_name_server_add_del, "<ip-address> [del]")                        \
21867 _(dns_resolve_name, "<hostname>")
21868
21869 /* List of command functions, CLI names map directly to functions */
21870 #define foreach_cli_function                                    \
21871 _(comment, "usage: comment <ignore-rest-of-line>")              \
21872 _(dump_interface_table, "usage: dump_interface_table")          \
21873 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21874 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21875 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21876 _(dump_stats_table, "usage: dump_stats_table")                  \
21877 _(dump_macro_table, "usage: dump_macro_table ")                 \
21878 _(dump_node_table, "usage: dump_node_table")                    \
21879 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21880 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21881 _(echo, "usage: echo <message>")                                \
21882 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21883 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21884 _(help, "usage: help")                                          \
21885 _(q, "usage: quit")                                             \
21886 _(quit, "usage: quit")                                          \
21887 _(search_node_table, "usage: search_node_table <name>...")      \
21888 _(set, "usage: set <variable-name> <value>")                    \
21889 _(script, "usage: script <file-name>")                          \
21890 _(unset, "usage: unset <variable-name>")
21891 #define _(N,n)                                  \
21892     static void vl_api_##n##_t_handler_uni      \
21893     (vl_api_##n##_t * mp)                       \
21894     {                                           \
21895         vat_main_t * vam = &vat_main;           \
21896         if (vam->json_output) {                 \
21897             vl_api_##n##_t_handler_json(mp);    \
21898         } else {                                \
21899             vl_api_##n##_t_handler(mp);         \
21900         }                                       \
21901     }
21902 foreach_vpe_api_reply_msg;
21903 #if VPP_API_TEST_BUILTIN == 0
21904 foreach_standalone_reply_msg;
21905 #endif
21906 #undef _
21907
21908 void
21909 vat_api_hookup (vat_main_t * vam)
21910 {
21911 #define _(N,n)                                                  \
21912     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21913                            vl_api_##n##_t_handler_uni,          \
21914                            vl_noop_handler,                     \
21915                            vl_api_##n##_t_endian,               \
21916                            vl_api_##n##_t_print,                \
21917                            sizeof(vl_api_##n##_t), 1);
21918   foreach_vpe_api_reply_msg;
21919 #if VPP_API_TEST_BUILTIN == 0
21920   foreach_standalone_reply_msg;
21921 #endif
21922 #undef _
21923
21924 #if (VPP_API_TEST_BUILTIN==0)
21925   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
21926
21927   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
21928
21929   vam->function_by_name = hash_create_string (0, sizeof (uword));
21930
21931   vam->help_by_name = hash_create_string (0, sizeof (uword));
21932 #endif
21933
21934   /* API messages we can send */
21935 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
21936   foreach_vpe_api_msg;
21937 #undef _
21938
21939   /* Help strings */
21940 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21941   foreach_vpe_api_msg;
21942 #undef _
21943
21944   /* CLI functions */
21945 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
21946   foreach_cli_function;
21947 #undef _
21948
21949   /* Help strings */
21950 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21951   foreach_cli_function;
21952 #undef _
21953 }
21954
21955 #if VPP_API_TEST_BUILTIN
21956 static clib_error_t *
21957 vat_api_hookup_shim (vlib_main_t * vm)
21958 {
21959   vat_api_hookup (&vat_main);
21960   return 0;
21961 }
21962
21963 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
21964 #endif
21965
21966 /*
21967  * fd.io coding-style-patch-verification: ON
21968  *
21969  * Local Variables:
21970  * eval: (c-set-style "gnu")
21971  * End:
21972  */