Enforce FIB table creation before use
[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       retval = memfd_slave_init (&memfd);
2141       if (retval)
2142         clib_warning ("WARNING: segment map returned %d", retval);
2143
2144       /* Pivot to the memory client segment that vpp just created */
2145
2146       am->vlib_rp = (void *) (memfd.requested_va + MMAP_PAGESIZE);
2147
2148       am->shmem_hdr = (void *) am->vlib_rp->user_ctx;
2149
2150       vl_client_install_client_message_handlers ();
2151
2152       vl_client_connect_to_vlib_no_map ("pvt",
2153                                         "vpp_api_test(p)",
2154                                         32 /* input_queue_length */ );
2155       if (close (my_fd) < 0)
2156         clib_unix_warning ("close memfd fd pivot");
2157       vam->vl_input_queue = am->shmem_hdr->vl_input_queue;
2158
2159       vl_socket_client_enable_disable (&vam->socket_client_main,
2160                                        0 /* disable socket */ );
2161     }
2162
2163 out:
2164   if (vam->async_mode)
2165     {
2166       vam->async_errors += (retval < 0);
2167     }
2168   else
2169     {
2170       vam->retval = retval;
2171       vam->result_ready = 1;
2172     }
2173 #endif
2174 }
2175
2176 static void vl_api_memfd_segment_create_reply_t_handler_json
2177   (vl_api_memfd_segment_create_reply_t * mp)
2178 {
2179   clib_warning ("no");
2180 }
2181
2182 static void vl_api_dns_resolve_name_reply_t_handler
2183   (vl_api_dns_resolve_name_reply_t * mp)
2184 {
2185   vat_main_t *vam = &vat_main;
2186   i32 retval = ntohl (mp->retval);
2187   if (vam->async_mode)
2188     {
2189       vam->async_errors += (retval < 0);
2190     }
2191   else
2192     {
2193       vam->retval = retval;
2194       vam->result_ready = 1;
2195
2196       if (retval == 0)
2197         {
2198           if (mp->ip4_set)
2199             clib_warning ("ip4 address %U", format_ip4_address,
2200                           (ip4_address_t *) mp->ip4_address);
2201           if (mp->ip6_set)
2202             clib_warning ("ip6 address %U", format_ip6_address,
2203                           (ip6_address_t *) mp->ip6_address);
2204         }
2205       else
2206         clib_warning ("retval %d", retval);
2207     }
2208 }
2209
2210 static void vl_api_dns_resolve_name_reply_t_handler_json
2211   (vl_api_dns_resolve_name_reply_t * mp)
2212 {
2213   clib_warning ("no");
2214 }
2215
2216 static void vl_api_ip_address_details_t_handler
2217   (vl_api_ip_address_details_t * mp)
2218 {
2219   vat_main_t *vam = &vat_main;
2220   static ip_address_details_t empty_ip_address_details = { {0} };
2221   ip_address_details_t *address = NULL;
2222   ip_details_t *current_ip_details = NULL;
2223   ip_details_t *details = NULL;
2224
2225   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2226
2227   if (!details || vam->current_sw_if_index >= vec_len (details)
2228       || !details[vam->current_sw_if_index].present)
2229     {
2230       errmsg ("ip address details arrived but not stored");
2231       errmsg ("ip_dump should be called first");
2232       return;
2233     }
2234
2235   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2236
2237 #define addresses (current_ip_details->addr)
2238
2239   vec_validate_init_empty (addresses, vec_len (addresses),
2240                            empty_ip_address_details);
2241
2242   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2243
2244   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2245   address->prefix_length = mp->prefix_length;
2246 #undef addresses
2247 }
2248
2249 static void vl_api_ip_address_details_t_handler_json
2250   (vl_api_ip_address_details_t * mp)
2251 {
2252   vat_main_t *vam = &vat_main;
2253   vat_json_node_t *node = NULL;
2254   struct in6_addr ip6;
2255   struct in_addr ip4;
2256
2257   if (VAT_JSON_ARRAY != vam->json_tree.type)
2258     {
2259       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2260       vat_json_init_array (&vam->json_tree);
2261     }
2262   node = vat_json_array_add (&vam->json_tree);
2263
2264   vat_json_init_object (node);
2265   if (vam->is_ipv6)
2266     {
2267       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2268       vat_json_object_add_ip6 (node, "ip", ip6);
2269     }
2270   else
2271     {
2272       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2273       vat_json_object_add_ip4 (node, "ip", ip4);
2274     }
2275   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2276 }
2277
2278 static void
2279 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2280 {
2281   vat_main_t *vam = &vat_main;
2282   static ip_details_t empty_ip_details = { 0 };
2283   ip_details_t *ip = NULL;
2284   u32 sw_if_index = ~0;
2285
2286   sw_if_index = ntohl (mp->sw_if_index);
2287
2288   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2289                            sw_if_index, empty_ip_details);
2290
2291   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2292                          sw_if_index);
2293
2294   ip->present = 1;
2295 }
2296
2297 static void
2298 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2299 {
2300   vat_main_t *vam = &vat_main;
2301
2302   if (VAT_JSON_ARRAY != vam->json_tree.type)
2303     {
2304       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2305       vat_json_init_array (&vam->json_tree);
2306     }
2307   vat_json_array_add_uint (&vam->json_tree,
2308                            clib_net_to_host_u32 (mp->sw_if_index));
2309 }
2310
2311 static void vl_api_map_domain_details_t_handler_json
2312   (vl_api_map_domain_details_t * mp)
2313 {
2314   vat_json_node_t *node = NULL;
2315   vat_main_t *vam = &vat_main;
2316   struct in6_addr ip6;
2317   struct in_addr ip4;
2318
2319   if (VAT_JSON_ARRAY != vam->json_tree.type)
2320     {
2321       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2322       vat_json_init_array (&vam->json_tree);
2323     }
2324
2325   node = vat_json_array_add (&vam->json_tree);
2326   vat_json_init_object (node);
2327
2328   vat_json_object_add_uint (node, "domain_index",
2329                             clib_net_to_host_u32 (mp->domain_index));
2330   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
2331   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
2332   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
2333   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
2334   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
2335   vat_json_object_add_ip6 (node, "ip6_src", ip6);
2336   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
2337   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
2338   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
2339   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
2340   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
2341   vat_json_object_add_int (node, "psid_length", mp->psid_length);
2342   vat_json_object_add_uint (node, "flags", mp->flags);
2343   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
2344   vat_json_object_add_int (node, "is_translation", mp->is_translation);
2345 }
2346
2347 static void vl_api_map_domain_details_t_handler
2348   (vl_api_map_domain_details_t * mp)
2349 {
2350   vat_main_t *vam = &vat_main;
2351
2352   if (mp->is_translation)
2353     {
2354       print (vam->ofp,
2355              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2356              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2357              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2358              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2359              clib_net_to_host_u32 (mp->domain_index));
2360     }
2361   else
2362     {
2363       print (vam->ofp,
2364              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2365              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2366              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2367              format_ip6_address, mp->ip6_src,
2368              clib_net_to_host_u32 (mp->domain_index));
2369     }
2370   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2371          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2372          mp->is_translation ? "map-t" : "");
2373 }
2374
2375 static void vl_api_map_rule_details_t_handler_json
2376   (vl_api_map_rule_details_t * mp)
2377 {
2378   struct in6_addr ip6;
2379   vat_json_node_t *node = NULL;
2380   vat_main_t *vam = &vat_main;
2381
2382   if (VAT_JSON_ARRAY != vam->json_tree.type)
2383     {
2384       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2385       vat_json_init_array (&vam->json_tree);
2386     }
2387
2388   node = vat_json_array_add (&vam->json_tree);
2389   vat_json_init_object (node);
2390
2391   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2392   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2393   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2394 }
2395
2396 static void
2397 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2398 {
2399   vat_main_t *vam = &vat_main;
2400   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2401          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2402 }
2403
2404 static void
2405 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2406 {
2407   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2408           "router_addr %U host_mac %U",
2409           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2410           format_ip4_address, &mp->host_address,
2411           format_ip4_address, &mp->router_address,
2412           format_ethernet_address, mp->host_mac);
2413 }
2414
2415 static void vl_api_dhcp_compl_event_t_handler_json
2416   (vl_api_dhcp_compl_event_t * mp)
2417 {
2418   /* JSON output not supported */
2419 }
2420
2421 static void
2422 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2423                               u32 counter)
2424 {
2425   vat_main_t *vam = &vat_main;
2426   static u64 default_counter = 0;
2427
2428   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2429                            NULL);
2430   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2431                            sw_if_index, default_counter);
2432   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2433 }
2434
2435 static void
2436 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2437                                 interface_counter_t counter)
2438 {
2439   vat_main_t *vam = &vat_main;
2440   static interface_counter_t default_counter = { 0, };
2441
2442   vec_validate_init_empty (vam->combined_interface_counters,
2443                            vnet_counter_type, NULL);
2444   vec_validate_init_empty (vam->combined_interface_counters
2445                            [vnet_counter_type], sw_if_index, default_counter);
2446   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2447 }
2448
2449 static void vl_api_vnet_interface_simple_counters_t_handler
2450   (vl_api_vnet_interface_simple_counters_t * mp)
2451 {
2452   /* not supported */
2453 }
2454
2455 static void vl_api_vnet_interface_combined_counters_t_handler
2456   (vl_api_vnet_interface_combined_counters_t * mp)
2457 {
2458   /* not supported */
2459 }
2460
2461 static void vl_api_vnet_interface_simple_counters_t_handler_json
2462   (vl_api_vnet_interface_simple_counters_t * mp)
2463 {
2464   u64 *v_packets;
2465   u64 packets;
2466   u32 count;
2467   u32 first_sw_if_index;
2468   int i;
2469
2470   count = ntohl (mp->count);
2471   first_sw_if_index = ntohl (mp->first_sw_if_index);
2472
2473   v_packets = (u64 *) & mp->data;
2474   for (i = 0; i < count; i++)
2475     {
2476       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2477       set_simple_interface_counter (mp->vnet_counter_type,
2478                                     first_sw_if_index + i, packets);
2479       v_packets++;
2480     }
2481 }
2482
2483 static void vl_api_vnet_interface_combined_counters_t_handler_json
2484   (vl_api_vnet_interface_combined_counters_t * mp)
2485 {
2486   interface_counter_t counter;
2487   vlib_counter_t *v;
2488   u32 first_sw_if_index;
2489   int i;
2490   u32 count;
2491
2492   count = ntohl (mp->count);
2493   first_sw_if_index = ntohl (mp->first_sw_if_index);
2494
2495   v = (vlib_counter_t *) & mp->data;
2496   for (i = 0; i < count; i++)
2497     {
2498       counter.packets =
2499         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2500       counter.bytes =
2501         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2502       set_combined_interface_counter (mp->vnet_counter_type,
2503                                       first_sw_if_index + i, counter);
2504       v++;
2505     }
2506 }
2507
2508 static u32
2509 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2510 {
2511   vat_main_t *vam = &vat_main;
2512   u32 i;
2513
2514   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2515     {
2516       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2517         {
2518           return i;
2519         }
2520     }
2521   return ~0;
2522 }
2523
2524 static u32
2525 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2526 {
2527   vat_main_t *vam = &vat_main;
2528   u32 i;
2529
2530   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2531     {
2532       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2533         {
2534           return i;
2535         }
2536     }
2537   return ~0;
2538 }
2539
2540 static void vl_api_vnet_ip4_fib_counters_t_handler
2541   (vl_api_vnet_ip4_fib_counters_t * mp)
2542 {
2543   /* not supported */
2544 }
2545
2546 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2547   (vl_api_vnet_ip4_fib_counters_t * mp)
2548 {
2549   vat_main_t *vam = &vat_main;
2550   vl_api_ip4_fib_counter_t *v;
2551   ip4_fib_counter_t *counter;
2552   struct in_addr ip4;
2553   u32 vrf_id;
2554   u32 vrf_index;
2555   u32 count;
2556   int i;
2557
2558   vrf_id = ntohl (mp->vrf_id);
2559   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2560   if (~0 == vrf_index)
2561     {
2562       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2563       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2564       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2565       vec_validate (vam->ip4_fib_counters, vrf_index);
2566       vam->ip4_fib_counters[vrf_index] = NULL;
2567     }
2568
2569   vec_free (vam->ip4_fib_counters[vrf_index]);
2570   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2571   count = ntohl (mp->count);
2572   for (i = 0; i < count; i++)
2573     {
2574       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2575       counter = &vam->ip4_fib_counters[vrf_index][i];
2576       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2577       counter->address = ip4;
2578       counter->address_length = v->address_length;
2579       counter->packets = clib_net_to_host_u64 (v->packets);
2580       counter->bytes = clib_net_to_host_u64 (v->bytes);
2581       v++;
2582     }
2583 }
2584
2585 static void vl_api_vnet_ip4_nbr_counters_t_handler
2586   (vl_api_vnet_ip4_nbr_counters_t * mp)
2587 {
2588   /* not supported */
2589 }
2590
2591 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2592   (vl_api_vnet_ip4_nbr_counters_t * mp)
2593 {
2594   vat_main_t *vam = &vat_main;
2595   vl_api_ip4_nbr_counter_t *v;
2596   ip4_nbr_counter_t *counter;
2597   u32 sw_if_index;
2598   u32 count;
2599   int i;
2600
2601   sw_if_index = ntohl (mp->sw_if_index);
2602   count = ntohl (mp->count);
2603   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2604
2605   if (mp->begin)
2606     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2607
2608   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2609   for (i = 0; i < count; i++)
2610     {
2611       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2612       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2613       counter->address.s_addr = v->address;
2614       counter->packets = clib_net_to_host_u64 (v->packets);
2615       counter->bytes = clib_net_to_host_u64 (v->bytes);
2616       counter->linkt = v->link_type;
2617       v++;
2618     }
2619 }
2620
2621 static void vl_api_vnet_ip6_fib_counters_t_handler
2622   (vl_api_vnet_ip6_fib_counters_t * mp)
2623 {
2624   /* not supported */
2625 }
2626
2627 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2628   (vl_api_vnet_ip6_fib_counters_t * mp)
2629 {
2630   vat_main_t *vam = &vat_main;
2631   vl_api_ip6_fib_counter_t *v;
2632   ip6_fib_counter_t *counter;
2633   struct in6_addr ip6;
2634   u32 vrf_id;
2635   u32 vrf_index;
2636   u32 count;
2637   int i;
2638
2639   vrf_id = ntohl (mp->vrf_id);
2640   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2641   if (~0 == vrf_index)
2642     {
2643       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2644       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2645       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2646       vec_validate (vam->ip6_fib_counters, vrf_index);
2647       vam->ip6_fib_counters[vrf_index] = NULL;
2648     }
2649
2650   vec_free (vam->ip6_fib_counters[vrf_index]);
2651   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2652   count = ntohl (mp->count);
2653   for (i = 0; i < count; i++)
2654     {
2655       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2656       counter = &vam->ip6_fib_counters[vrf_index][i];
2657       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2658       counter->address = ip6;
2659       counter->address_length = v->address_length;
2660       counter->packets = clib_net_to_host_u64 (v->packets);
2661       counter->bytes = clib_net_to_host_u64 (v->bytes);
2662       v++;
2663     }
2664 }
2665
2666 static void vl_api_vnet_ip6_nbr_counters_t_handler
2667   (vl_api_vnet_ip6_nbr_counters_t * mp)
2668 {
2669   /* not supported */
2670 }
2671
2672 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2673   (vl_api_vnet_ip6_nbr_counters_t * mp)
2674 {
2675   vat_main_t *vam = &vat_main;
2676   vl_api_ip6_nbr_counter_t *v;
2677   ip6_nbr_counter_t *counter;
2678   struct in6_addr ip6;
2679   u32 sw_if_index;
2680   u32 count;
2681   int i;
2682
2683   sw_if_index = ntohl (mp->sw_if_index);
2684   count = ntohl (mp->count);
2685   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2686
2687   if (mp->begin)
2688     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2689
2690   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2691   for (i = 0; i < count; i++)
2692     {
2693       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2694       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2695       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2696       counter->address = ip6;
2697       counter->packets = clib_net_to_host_u64 (v->packets);
2698       counter->bytes = clib_net_to_host_u64 (v->bytes);
2699       v++;
2700     }
2701 }
2702
2703 static void vl_api_get_first_msg_id_reply_t_handler
2704   (vl_api_get_first_msg_id_reply_t * mp)
2705 {
2706   vat_main_t *vam = &vat_main;
2707   i32 retval = ntohl (mp->retval);
2708
2709   if (vam->async_mode)
2710     {
2711       vam->async_errors += (retval < 0);
2712     }
2713   else
2714     {
2715       vam->retval = retval;
2716       vam->result_ready = 1;
2717     }
2718   if (retval >= 0)
2719     {
2720       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2721     }
2722 }
2723
2724 static void vl_api_get_first_msg_id_reply_t_handler_json
2725   (vl_api_get_first_msg_id_reply_t * mp)
2726 {
2727   vat_main_t *vam = &vat_main;
2728   vat_json_node_t node;
2729
2730   vat_json_init_object (&node);
2731   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2732   vat_json_object_add_uint (&node, "first_msg_id",
2733                             (uint) ntohs (mp->first_msg_id));
2734
2735   vat_json_print (vam->ofp, &node);
2736   vat_json_free (&node);
2737
2738   vam->retval = ntohl (mp->retval);
2739   vam->result_ready = 1;
2740 }
2741
2742 static void vl_api_get_node_graph_reply_t_handler
2743   (vl_api_get_node_graph_reply_t * mp)
2744 {
2745   vat_main_t *vam = &vat_main;
2746   api_main_t *am = &api_main;
2747   i32 retval = ntohl (mp->retval);
2748   u8 *pvt_copy, *reply;
2749   void *oldheap;
2750   vlib_node_t *node;
2751   int i;
2752
2753   if (vam->async_mode)
2754     {
2755       vam->async_errors += (retval < 0);
2756     }
2757   else
2758     {
2759       vam->retval = retval;
2760       vam->result_ready = 1;
2761     }
2762
2763   /* "Should never happen..." */
2764   if (retval != 0)
2765     return;
2766
2767   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2768   pvt_copy = vec_dup (reply);
2769
2770   /* Toss the shared-memory original... */
2771   pthread_mutex_lock (&am->vlib_rp->mutex);
2772   oldheap = svm_push_data_heap (am->vlib_rp);
2773
2774   vec_free (reply);
2775
2776   svm_pop_heap (oldheap);
2777   pthread_mutex_unlock (&am->vlib_rp->mutex);
2778
2779   if (vam->graph_nodes)
2780     {
2781       hash_free (vam->graph_node_index_by_name);
2782
2783       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2784         {
2785           node = vam->graph_nodes[i];
2786           vec_free (node->name);
2787           vec_free (node->next_nodes);
2788           vec_free (node);
2789         }
2790       vec_free (vam->graph_nodes);
2791     }
2792
2793   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2794   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2795   vec_free (pvt_copy);
2796
2797   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2798     {
2799       node = vam->graph_nodes[i];
2800       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2801     }
2802 }
2803
2804 static void vl_api_get_node_graph_reply_t_handler_json
2805   (vl_api_get_node_graph_reply_t * mp)
2806 {
2807   vat_main_t *vam = &vat_main;
2808   api_main_t *am = &api_main;
2809   void *oldheap;
2810   vat_json_node_t node;
2811   u8 *reply;
2812
2813   /* $$$$ make this real? */
2814   vat_json_init_object (&node);
2815   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2816   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2817
2818   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2819
2820   /* Toss the shared-memory original... */
2821   pthread_mutex_lock (&am->vlib_rp->mutex);
2822   oldheap = svm_push_data_heap (am->vlib_rp);
2823
2824   vec_free (reply);
2825
2826   svm_pop_heap (oldheap);
2827   pthread_mutex_unlock (&am->vlib_rp->mutex);
2828
2829   vat_json_print (vam->ofp, &node);
2830   vat_json_free (&node);
2831
2832   vam->retval = ntohl (mp->retval);
2833   vam->result_ready = 1;
2834 }
2835
2836 static void
2837 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2838 {
2839   vat_main_t *vam = &vat_main;
2840   u8 *s = 0;
2841
2842   if (mp->local)
2843     {
2844       s = format (s, "%=16d%=16d%=16d",
2845                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2846     }
2847   else
2848     {
2849       s = format (s, "%=16U%=16d%=16d",
2850                   mp->is_ipv6 ? format_ip6_address :
2851                   format_ip4_address,
2852                   mp->ip_address, mp->priority, mp->weight);
2853     }
2854
2855   print (vam->ofp, "%v", s);
2856   vec_free (s);
2857 }
2858
2859 static void
2860 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2861 {
2862   vat_main_t *vam = &vat_main;
2863   vat_json_node_t *node = NULL;
2864   struct in6_addr ip6;
2865   struct in_addr ip4;
2866
2867   if (VAT_JSON_ARRAY != vam->json_tree.type)
2868     {
2869       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2870       vat_json_init_array (&vam->json_tree);
2871     }
2872   node = vat_json_array_add (&vam->json_tree);
2873   vat_json_init_object (node);
2874
2875   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2876   vat_json_object_add_uint (node, "priority", mp->priority);
2877   vat_json_object_add_uint (node, "weight", mp->weight);
2878
2879   if (mp->local)
2880     vat_json_object_add_uint (node, "sw_if_index",
2881                               clib_net_to_host_u32 (mp->sw_if_index));
2882   else
2883     {
2884       if (mp->is_ipv6)
2885         {
2886           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2887           vat_json_object_add_ip6 (node, "address", ip6);
2888         }
2889       else
2890         {
2891           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2892           vat_json_object_add_ip4 (node, "address", ip4);
2893         }
2894     }
2895 }
2896
2897 static void
2898 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2899                                           mp)
2900 {
2901   vat_main_t *vam = &vat_main;
2902   u8 *ls_name = 0;
2903
2904   ls_name = format (0, "%s", mp->ls_name);
2905
2906   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2907          ls_name);
2908   vec_free (ls_name);
2909 }
2910
2911 static void
2912   vl_api_one_locator_set_details_t_handler_json
2913   (vl_api_one_locator_set_details_t * mp)
2914 {
2915   vat_main_t *vam = &vat_main;
2916   vat_json_node_t *node = 0;
2917   u8 *ls_name = 0;
2918
2919   ls_name = format (0, "%s", mp->ls_name);
2920   vec_add1 (ls_name, 0);
2921
2922   if (VAT_JSON_ARRAY != vam->json_tree.type)
2923     {
2924       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2925       vat_json_init_array (&vam->json_tree);
2926     }
2927   node = vat_json_array_add (&vam->json_tree);
2928
2929   vat_json_init_object (node);
2930   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2931   vat_json_object_add_uint (node, "ls_index",
2932                             clib_net_to_host_u32 (mp->ls_index));
2933   vec_free (ls_name);
2934 }
2935
2936 typedef struct
2937 {
2938   u32 spi;
2939   u8 si;
2940 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2941
2942 uword
2943 unformat_nsh_address (unformat_input_t * input, va_list * args)
2944 {
2945   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2946   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2947 }
2948
2949 u8 *
2950 format_nsh_address_vat (u8 * s, va_list * args)
2951 {
2952   nsh_t *a = va_arg (*args, nsh_t *);
2953   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2954 }
2955
2956 static u8 *
2957 format_lisp_flat_eid (u8 * s, va_list * args)
2958 {
2959   u32 type = va_arg (*args, u32);
2960   u8 *eid = va_arg (*args, u8 *);
2961   u32 eid_len = va_arg (*args, u32);
2962
2963   switch (type)
2964     {
2965     case 0:
2966       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2967     case 1:
2968       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2969     case 2:
2970       return format (s, "%U", format_ethernet_address, eid);
2971     case 3:
2972       return format (s, "%U", format_nsh_address_vat, eid);
2973     }
2974   return 0;
2975 }
2976
2977 static u8 *
2978 format_lisp_eid_vat (u8 * s, va_list * args)
2979 {
2980   u32 type = va_arg (*args, u32);
2981   u8 *eid = va_arg (*args, u8 *);
2982   u32 eid_len = va_arg (*args, u32);
2983   u8 *seid = va_arg (*args, u8 *);
2984   u32 seid_len = va_arg (*args, u32);
2985   u32 is_src_dst = va_arg (*args, u32);
2986
2987   if (is_src_dst)
2988     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2989
2990   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2991
2992   return s;
2993 }
2994
2995 static void
2996 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2997 {
2998   vat_main_t *vam = &vat_main;
2999   u8 *s = 0, *eid = 0;
3000
3001   if (~0 == mp->locator_set_index)
3002     s = format (0, "action: %d", mp->action);
3003   else
3004     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3005
3006   eid = format (0, "%U", format_lisp_eid_vat,
3007                 mp->eid_type,
3008                 mp->eid,
3009                 mp->eid_prefix_len,
3010                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3011   vec_add1 (eid, 0);
3012
3013   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3014          clib_net_to_host_u32 (mp->vni),
3015          eid,
3016          mp->is_local ? "local" : "remote",
3017          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3018          clib_net_to_host_u16 (mp->key_id), mp->key);
3019
3020   vec_free (s);
3021   vec_free (eid);
3022 }
3023
3024 static void
3025 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3026                                              * mp)
3027 {
3028   vat_main_t *vam = &vat_main;
3029   vat_json_node_t *node = 0;
3030   u8 *eid = 0;
3031
3032   if (VAT_JSON_ARRAY != vam->json_tree.type)
3033     {
3034       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3035       vat_json_init_array (&vam->json_tree);
3036     }
3037   node = vat_json_array_add (&vam->json_tree);
3038
3039   vat_json_init_object (node);
3040   if (~0 == mp->locator_set_index)
3041     vat_json_object_add_uint (node, "action", mp->action);
3042   else
3043     vat_json_object_add_uint (node, "locator_set_index",
3044                               clib_net_to_host_u32 (mp->locator_set_index));
3045
3046   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3047   if (mp->eid_type == 3)
3048     {
3049       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3050       vat_json_init_object (nsh_json);
3051       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3052       vat_json_object_add_uint (nsh_json, "spi",
3053                                 clib_net_to_host_u32 (nsh->spi));
3054       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3055     }
3056   else
3057     {
3058       eid = format (0, "%U", format_lisp_eid_vat,
3059                     mp->eid_type,
3060                     mp->eid,
3061                     mp->eid_prefix_len,
3062                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3063       vec_add1 (eid, 0);
3064       vat_json_object_add_string_copy (node, "eid", eid);
3065       vec_free (eid);
3066     }
3067   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3068   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3069   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3070
3071   if (mp->key_id)
3072     {
3073       vat_json_object_add_uint (node, "key_id",
3074                                 clib_net_to_host_u16 (mp->key_id));
3075       vat_json_object_add_string_copy (node, "key", mp->key);
3076     }
3077 }
3078
3079 static void
3080 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3081 {
3082   vat_main_t *vam = &vat_main;
3083   u8 *seid = 0, *deid = 0;
3084   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3085
3086   deid = format (0, "%U", format_lisp_eid_vat,
3087                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3088
3089   seid = format (0, "%U", format_lisp_eid_vat,
3090                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3091
3092   vec_add1 (deid, 0);
3093   vec_add1 (seid, 0);
3094
3095   if (mp->is_ip4)
3096     format_ip_address_fcn = format_ip4_address;
3097   else
3098     format_ip_address_fcn = format_ip6_address;
3099
3100
3101   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3102          clib_net_to_host_u32 (mp->vni),
3103          seid, deid,
3104          format_ip_address_fcn, mp->lloc,
3105          format_ip_address_fcn, mp->rloc,
3106          clib_net_to_host_u32 (mp->pkt_count),
3107          clib_net_to_host_u32 (mp->bytes));
3108
3109   vec_free (deid);
3110   vec_free (seid);
3111 }
3112
3113 static void
3114 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3115 {
3116   struct in6_addr ip6;
3117   struct in_addr ip4;
3118   vat_main_t *vam = &vat_main;
3119   vat_json_node_t *node = 0;
3120   u8 *deid = 0, *seid = 0;
3121
3122   if (VAT_JSON_ARRAY != vam->json_tree.type)
3123     {
3124       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3125       vat_json_init_array (&vam->json_tree);
3126     }
3127   node = vat_json_array_add (&vam->json_tree);
3128
3129   vat_json_init_object (node);
3130   deid = format (0, "%U", format_lisp_eid_vat,
3131                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3132
3133   seid = format (0, "%U", format_lisp_eid_vat,
3134                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3135
3136   vec_add1 (deid, 0);
3137   vec_add1 (seid, 0);
3138
3139   vat_json_object_add_string_copy (node, "seid", seid);
3140   vat_json_object_add_string_copy (node, "deid", deid);
3141   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3142
3143   if (mp->is_ip4)
3144     {
3145       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3146       vat_json_object_add_ip4 (node, "lloc", ip4);
3147       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3148       vat_json_object_add_ip4 (node, "rloc", ip4);
3149     }
3150   else
3151     {
3152       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3153       vat_json_object_add_ip6 (node, "lloc", ip6);
3154       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3155       vat_json_object_add_ip6 (node, "rloc", ip6);
3156     }
3157   vat_json_object_add_uint (node, "pkt_count",
3158                             clib_net_to_host_u32 (mp->pkt_count));
3159   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3160
3161   vec_free (deid);
3162   vec_free (seid);
3163 }
3164
3165 static void
3166   vl_api_one_eid_table_map_details_t_handler
3167   (vl_api_one_eid_table_map_details_t * mp)
3168 {
3169   vat_main_t *vam = &vat_main;
3170
3171   u8 *line = format (0, "%=10d%=10d",
3172                      clib_net_to_host_u32 (mp->vni),
3173                      clib_net_to_host_u32 (mp->dp_table));
3174   print (vam->ofp, "%v", line);
3175   vec_free (line);
3176 }
3177
3178 static void
3179   vl_api_one_eid_table_map_details_t_handler_json
3180   (vl_api_one_eid_table_map_details_t * mp)
3181 {
3182   vat_main_t *vam = &vat_main;
3183   vat_json_node_t *node = NULL;
3184
3185   if (VAT_JSON_ARRAY != vam->json_tree.type)
3186     {
3187       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3188       vat_json_init_array (&vam->json_tree);
3189     }
3190   node = vat_json_array_add (&vam->json_tree);
3191   vat_json_init_object (node);
3192   vat_json_object_add_uint (node, "dp_table",
3193                             clib_net_to_host_u32 (mp->dp_table));
3194   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3195 }
3196
3197 static void
3198   vl_api_one_eid_table_vni_details_t_handler
3199   (vl_api_one_eid_table_vni_details_t * mp)
3200 {
3201   vat_main_t *vam = &vat_main;
3202
3203   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3204   print (vam->ofp, "%v", line);
3205   vec_free (line);
3206 }
3207
3208 static void
3209   vl_api_one_eid_table_vni_details_t_handler_json
3210   (vl_api_one_eid_table_vni_details_t * mp)
3211 {
3212   vat_main_t *vam = &vat_main;
3213   vat_json_node_t *node = NULL;
3214
3215   if (VAT_JSON_ARRAY != vam->json_tree.type)
3216     {
3217       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3218       vat_json_init_array (&vam->json_tree);
3219     }
3220   node = vat_json_array_add (&vam->json_tree);
3221   vat_json_init_object (node);
3222   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3223 }
3224
3225 static void
3226   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3227   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3228 {
3229   vat_main_t *vam = &vat_main;
3230   int retval = clib_net_to_host_u32 (mp->retval);
3231
3232   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3233   print (vam->ofp, "fallback threshold value: %d", mp->value);
3234
3235   vam->retval = retval;
3236   vam->result_ready = 1;
3237 }
3238
3239 static void
3240   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3241   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3242 {
3243   vat_main_t *vam = &vat_main;
3244   vat_json_node_t _node, *node = &_node;
3245   int retval = clib_net_to_host_u32 (mp->retval);
3246
3247   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3248   vat_json_init_object (node);
3249   vat_json_object_add_uint (node, "value", mp->value);
3250
3251   vat_json_print (vam->ofp, node);
3252   vat_json_free (node);
3253
3254   vam->retval = retval;
3255   vam->result_ready = 1;
3256 }
3257
3258 static void
3259   vl_api_show_one_map_register_state_reply_t_handler
3260   (vl_api_show_one_map_register_state_reply_t * mp)
3261 {
3262   vat_main_t *vam = &vat_main;
3263   int retval = clib_net_to_host_u32 (mp->retval);
3264
3265   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3266
3267   vam->retval = retval;
3268   vam->result_ready = 1;
3269 }
3270
3271 static void
3272   vl_api_show_one_map_register_state_reply_t_handler_json
3273   (vl_api_show_one_map_register_state_reply_t * mp)
3274 {
3275   vat_main_t *vam = &vat_main;
3276   vat_json_node_t _node, *node = &_node;
3277   int retval = clib_net_to_host_u32 (mp->retval);
3278
3279   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3280
3281   vat_json_init_object (node);
3282   vat_json_object_add_string_copy (node, "state", s);
3283
3284   vat_json_print (vam->ofp, node);
3285   vat_json_free (node);
3286
3287   vam->retval = retval;
3288   vam->result_ready = 1;
3289   vec_free (s);
3290 }
3291
3292 static void
3293   vl_api_show_one_rloc_probe_state_reply_t_handler
3294   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3295 {
3296   vat_main_t *vam = &vat_main;
3297   int retval = clib_net_to_host_u32 (mp->retval);
3298
3299   if (retval)
3300     goto end;
3301
3302   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3303 end:
3304   vam->retval = retval;
3305   vam->result_ready = 1;
3306 }
3307
3308 static void
3309   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3310   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3311 {
3312   vat_main_t *vam = &vat_main;
3313   vat_json_node_t _node, *node = &_node;
3314   int retval = clib_net_to_host_u32 (mp->retval);
3315
3316   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3317   vat_json_init_object (node);
3318   vat_json_object_add_string_copy (node, "state", s);
3319
3320   vat_json_print (vam->ofp, node);
3321   vat_json_free (node);
3322
3323   vam->retval = retval;
3324   vam->result_ready = 1;
3325   vec_free (s);
3326 }
3327
3328 static void
3329   vl_api_show_one_stats_enable_disable_reply_t_handler
3330   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3331 {
3332   vat_main_t *vam = &vat_main;
3333   int retval = clib_net_to_host_u32 (mp->retval);
3334
3335   if (retval)
3336     goto end;
3337
3338   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3339 end:
3340   vam->retval = retval;
3341   vam->result_ready = 1;
3342 }
3343
3344 static void
3345   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3346   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3347 {
3348   vat_main_t *vam = &vat_main;
3349   vat_json_node_t _node, *node = &_node;
3350   int retval = clib_net_to_host_u32 (mp->retval);
3351
3352   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3353   vat_json_init_object (node);
3354   vat_json_object_add_string_copy (node, "state", s);
3355
3356   vat_json_print (vam->ofp, node);
3357   vat_json_free (node);
3358
3359   vam->retval = retval;
3360   vam->result_ready = 1;
3361   vec_free (s);
3362 }
3363
3364 static void
3365 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3366 {
3367   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3368   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3369   e->vni = clib_net_to_host_u32 (e->vni);
3370 }
3371
3372 static void
3373   gpe_fwd_entries_get_reply_t_net_to_host
3374   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3375 {
3376   u32 i;
3377
3378   mp->count = clib_net_to_host_u32 (mp->count);
3379   for (i = 0; i < mp->count; i++)
3380     {
3381       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3382     }
3383 }
3384
3385 static u8 *
3386 format_gpe_encap_mode (u8 * s, va_list * args)
3387 {
3388   u32 mode = va_arg (*args, u32);
3389
3390   switch (mode)
3391     {
3392     case 0:
3393       return format (s, "lisp");
3394     case 1:
3395       return format (s, "vxlan");
3396     }
3397   return 0;
3398 }
3399
3400 static void
3401   vl_api_gpe_get_encap_mode_reply_t_handler
3402   (vl_api_gpe_get_encap_mode_reply_t * mp)
3403 {
3404   vat_main_t *vam = &vat_main;
3405
3406   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3407   vam->retval = ntohl (mp->retval);
3408   vam->result_ready = 1;
3409 }
3410
3411 static void
3412   vl_api_gpe_get_encap_mode_reply_t_handler_json
3413   (vl_api_gpe_get_encap_mode_reply_t * mp)
3414 {
3415   vat_main_t *vam = &vat_main;
3416   vat_json_node_t node;
3417
3418   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3419   vec_add1 (encap_mode, 0);
3420
3421   vat_json_init_object (&node);
3422   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3423
3424   vec_free (encap_mode);
3425   vat_json_print (vam->ofp, &node);
3426   vat_json_free (&node);
3427
3428   vam->retval = ntohl (mp->retval);
3429   vam->result_ready = 1;
3430 }
3431
3432 static void
3433   vl_api_gpe_fwd_entry_path_details_t_handler
3434   (vl_api_gpe_fwd_entry_path_details_t * mp)
3435 {
3436   vat_main_t *vam = &vat_main;
3437   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3438
3439   if (mp->lcl_loc.is_ip4)
3440     format_ip_address_fcn = format_ip4_address;
3441   else
3442     format_ip_address_fcn = format_ip6_address;
3443
3444   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3445          format_ip_address_fcn, &mp->lcl_loc,
3446          format_ip_address_fcn, &mp->rmt_loc);
3447 }
3448
3449 static void
3450 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3451 {
3452   struct in6_addr ip6;
3453   struct in_addr ip4;
3454
3455   if (loc->is_ip4)
3456     {
3457       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3458       vat_json_object_add_ip4 (n, "address", ip4);
3459     }
3460   else
3461     {
3462       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3463       vat_json_object_add_ip6 (n, "address", ip6);
3464     }
3465   vat_json_object_add_uint (n, "weight", loc->weight);
3466 }
3467
3468 static void
3469   vl_api_gpe_fwd_entry_path_details_t_handler_json
3470   (vl_api_gpe_fwd_entry_path_details_t * mp)
3471 {
3472   vat_main_t *vam = &vat_main;
3473   vat_json_node_t *node = NULL;
3474   vat_json_node_t *loc_node;
3475
3476   if (VAT_JSON_ARRAY != vam->json_tree.type)
3477     {
3478       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3479       vat_json_init_array (&vam->json_tree);
3480     }
3481   node = vat_json_array_add (&vam->json_tree);
3482   vat_json_init_object (node);
3483
3484   loc_node = vat_json_object_add (node, "local_locator");
3485   vat_json_init_object (loc_node);
3486   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3487
3488   loc_node = vat_json_object_add (node, "remote_locator");
3489   vat_json_init_object (loc_node);
3490   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3491 }
3492
3493 static void
3494   vl_api_gpe_fwd_entries_get_reply_t_handler
3495   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3496 {
3497   vat_main_t *vam = &vat_main;
3498   u32 i;
3499   int retval = clib_net_to_host_u32 (mp->retval);
3500   vl_api_gpe_fwd_entry_t *e;
3501
3502   if (retval)
3503     goto end;
3504
3505   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3506
3507   for (i = 0; i < mp->count; i++)
3508     {
3509       e = &mp->entries[i];
3510       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3511              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3512              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3513     }
3514
3515 end:
3516   vam->retval = retval;
3517   vam->result_ready = 1;
3518 }
3519
3520 static void
3521   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3522   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3523 {
3524   u8 *s = 0;
3525   vat_main_t *vam = &vat_main;
3526   vat_json_node_t *e = 0, root;
3527   u32 i;
3528   int retval = clib_net_to_host_u32 (mp->retval);
3529   vl_api_gpe_fwd_entry_t *fwd;
3530
3531   if (retval)
3532     goto end;
3533
3534   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3535   vat_json_init_array (&root);
3536
3537   for (i = 0; i < mp->count; i++)
3538     {
3539       e = vat_json_array_add (&root);
3540       fwd = &mp->entries[i];
3541
3542       vat_json_init_object (e);
3543       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3544       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3545       vat_json_object_add_int (e, "vni", fwd->vni);
3546       vat_json_object_add_int (e, "action", fwd->action);
3547
3548       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3549                   fwd->leid_prefix_len);
3550       vec_add1 (s, 0);
3551       vat_json_object_add_string_copy (e, "leid", s);
3552       vec_free (s);
3553
3554       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3555                   fwd->reid_prefix_len);
3556       vec_add1 (s, 0);
3557       vat_json_object_add_string_copy (e, "reid", s);
3558       vec_free (s);
3559     }
3560
3561   vat_json_print (vam->ofp, &root);
3562   vat_json_free (&root);
3563
3564 end:
3565   vam->retval = retval;
3566   vam->result_ready = 1;
3567 }
3568
3569 static void
3570   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3571   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3572 {
3573   vat_main_t *vam = &vat_main;
3574   u32 i, n;
3575   int retval = clib_net_to_host_u32 (mp->retval);
3576   vl_api_gpe_native_fwd_rpath_t *r;
3577
3578   if (retval)
3579     goto end;
3580
3581   n = clib_net_to_host_u32 (mp->count);
3582
3583   for (i = 0; i < n; i++)
3584     {
3585       r = &mp->entries[i];
3586       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3587              clib_net_to_host_u32 (r->fib_index),
3588              clib_net_to_host_u32 (r->nh_sw_if_index),
3589              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3590     }
3591
3592 end:
3593   vam->retval = retval;
3594   vam->result_ready = 1;
3595 }
3596
3597 static void
3598   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3599   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3600 {
3601   vat_main_t *vam = &vat_main;
3602   vat_json_node_t root, *e;
3603   u32 i, n;
3604   int retval = clib_net_to_host_u32 (mp->retval);
3605   vl_api_gpe_native_fwd_rpath_t *r;
3606   u8 *s;
3607
3608   if (retval)
3609     goto end;
3610
3611   n = clib_net_to_host_u32 (mp->count);
3612   vat_json_init_array (&root);
3613
3614   for (i = 0; i < n; i++)
3615     {
3616       e = vat_json_array_add (&root);
3617       vat_json_init_object (e);
3618       r = &mp->entries[i];
3619       s =
3620         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3621                 r->nh_addr);
3622       vec_add1 (s, 0);
3623       vat_json_object_add_string_copy (e, "ip4", s);
3624       vec_free (s);
3625
3626       vat_json_object_add_uint (e, "fib_index",
3627                                 clib_net_to_host_u32 (r->fib_index));
3628       vat_json_object_add_uint (e, "nh_sw_if_index",
3629                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3630     }
3631
3632   vat_json_print (vam->ofp, &root);
3633   vat_json_free (&root);
3634
3635 end:
3636   vam->retval = retval;
3637   vam->result_ready = 1;
3638 }
3639
3640 static void
3641   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3642   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3643 {
3644   vat_main_t *vam = &vat_main;
3645   u32 i, n;
3646   int retval = clib_net_to_host_u32 (mp->retval);
3647
3648   if (retval)
3649     goto end;
3650
3651   n = clib_net_to_host_u32 (mp->count);
3652
3653   for (i = 0; i < n; i++)
3654     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3655
3656 end:
3657   vam->retval = retval;
3658   vam->result_ready = 1;
3659 }
3660
3661 static void
3662   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3663   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3664 {
3665   vat_main_t *vam = &vat_main;
3666   vat_json_node_t root;
3667   u32 i, n;
3668   int retval = clib_net_to_host_u32 (mp->retval);
3669
3670   if (retval)
3671     goto end;
3672
3673   n = clib_net_to_host_u32 (mp->count);
3674   vat_json_init_array (&root);
3675
3676   for (i = 0; i < n; i++)
3677     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3678
3679   vat_json_print (vam->ofp, &root);
3680   vat_json_free (&root);
3681
3682 end:
3683   vam->retval = retval;
3684   vam->result_ready = 1;
3685 }
3686
3687 static void
3688   vl_api_one_ndp_entries_get_reply_t_handler
3689   (vl_api_one_ndp_entries_get_reply_t * mp)
3690 {
3691   vat_main_t *vam = &vat_main;
3692   u32 i, n;
3693   int retval = clib_net_to_host_u32 (mp->retval);
3694
3695   if (retval)
3696     goto end;
3697
3698   n = clib_net_to_host_u32 (mp->count);
3699
3700   for (i = 0; i < n; i++)
3701     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3702            format_ethernet_address, mp->entries[i].mac);
3703
3704 end:
3705   vam->retval = retval;
3706   vam->result_ready = 1;
3707 }
3708
3709 static void
3710   vl_api_one_ndp_entries_get_reply_t_handler_json
3711   (vl_api_one_ndp_entries_get_reply_t * mp)
3712 {
3713   u8 *s = 0;
3714   vat_main_t *vam = &vat_main;
3715   vat_json_node_t *e = 0, root;
3716   u32 i, n;
3717   int retval = clib_net_to_host_u32 (mp->retval);
3718   vl_api_one_ndp_entry_t *arp_entry;
3719
3720   if (retval)
3721     goto end;
3722
3723   n = clib_net_to_host_u32 (mp->count);
3724   vat_json_init_array (&root);
3725
3726   for (i = 0; i < n; i++)
3727     {
3728       e = vat_json_array_add (&root);
3729       arp_entry = &mp->entries[i];
3730
3731       vat_json_init_object (e);
3732       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3733       vec_add1 (s, 0);
3734
3735       vat_json_object_add_string_copy (e, "mac", s);
3736       vec_free (s);
3737
3738       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3739       vec_add1 (s, 0);
3740       vat_json_object_add_string_copy (e, "ip6", s);
3741       vec_free (s);
3742     }
3743
3744   vat_json_print (vam->ofp, &root);
3745   vat_json_free (&root);
3746
3747 end:
3748   vam->retval = retval;
3749   vam->result_ready = 1;
3750 }
3751
3752 static void
3753   vl_api_one_l2_arp_entries_get_reply_t_handler
3754   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3755 {
3756   vat_main_t *vam = &vat_main;
3757   u32 i, n;
3758   int retval = clib_net_to_host_u32 (mp->retval);
3759
3760   if (retval)
3761     goto end;
3762
3763   n = clib_net_to_host_u32 (mp->count);
3764
3765   for (i = 0; i < n; i++)
3766     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3767            format_ethernet_address, mp->entries[i].mac);
3768
3769 end:
3770   vam->retval = retval;
3771   vam->result_ready = 1;
3772 }
3773
3774 static void
3775   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3776   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3777 {
3778   u8 *s = 0;
3779   vat_main_t *vam = &vat_main;
3780   vat_json_node_t *e = 0, root;
3781   u32 i, n;
3782   int retval = clib_net_to_host_u32 (mp->retval);
3783   vl_api_one_l2_arp_entry_t *arp_entry;
3784
3785   if (retval)
3786     goto end;
3787
3788   n = clib_net_to_host_u32 (mp->count);
3789   vat_json_init_array (&root);
3790
3791   for (i = 0; i < n; i++)
3792     {
3793       e = vat_json_array_add (&root);
3794       arp_entry = &mp->entries[i];
3795
3796       vat_json_init_object (e);
3797       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3798       vec_add1 (s, 0);
3799
3800       vat_json_object_add_string_copy (e, "mac", s);
3801       vec_free (s);
3802
3803       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3804       vec_add1 (s, 0);
3805       vat_json_object_add_string_copy (e, "ip4", s);
3806       vec_free (s);
3807     }
3808
3809   vat_json_print (vam->ofp, &root);
3810   vat_json_free (&root);
3811
3812 end:
3813   vam->retval = retval;
3814   vam->result_ready = 1;
3815 }
3816
3817 static void
3818 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3819 {
3820   vat_main_t *vam = &vat_main;
3821   u32 i, n;
3822   int retval = clib_net_to_host_u32 (mp->retval);
3823
3824   if (retval)
3825     goto end;
3826
3827   n = clib_net_to_host_u32 (mp->count);
3828
3829   for (i = 0; i < n; i++)
3830     {
3831       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3832     }
3833
3834 end:
3835   vam->retval = retval;
3836   vam->result_ready = 1;
3837 }
3838
3839 static void
3840   vl_api_one_ndp_bd_get_reply_t_handler_json
3841   (vl_api_one_ndp_bd_get_reply_t * mp)
3842 {
3843   vat_main_t *vam = &vat_main;
3844   vat_json_node_t root;
3845   u32 i, n;
3846   int retval = clib_net_to_host_u32 (mp->retval);
3847
3848   if (retval)
3849     goto end;
3850
3851   n = clib_net_to_host_u32 (mp->count);
3852   vat_json_init_array (&root);
3853
3854   for (i = 0; i < n; i++)
3855     {
3856       vat_json_array_add_uint (&root,
3857                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3858     }
3859
3860   vat_json_print (vam->ofp, &root);
3861   vat_json_free (&root);
3862
3863 end:
3864   vam->retval = retval;
3865   vam->result_ready = 1;
3866 }
3867
3868 static void
3869   vl_api_one_l2_arp_bd_get_reply_t_handler
3870   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3871 {
3872   vat_main_t *vam = &vat_main;
3873   u32 i, n;
3874   int retval = clib_net_to_host_u32 (mp->retval);
3875
3876   if (retval)
3877     goto end;
3878
3879   n = clib_net_to_host_u32 (mp->count);
3880
3881   for (i = 0; i < n; i++)
3882     {
3883       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3884     }
3885
3886 end:
3887   vam->retval = retval;
3888   vam->result_ready = 1;
3889 }
3890
3891 static void
3892   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3893   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3894 {
3895   vat_main_t *vam = &vat_main;
3896   vat_json_node_t root;
3897   u32 i, n;
3898   int retval = clib_net_to_host_u32 (mp->retval);
3899
3900   if (retval)
3901     goto end;
3902
3903   n = clib_net_to_host_u32 (mp->count);
3904   vat_json_init_array (&root);
3905
3906   for (i = 0; i < n; i++)
3907     {
3908       vat_json_array_add_uint (&root,
3909                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3910     }
3911
3912   vat_json_print (vam->ofp, &root);
3913   vat_json_free (&root);
3914
3915 end:
3916   vam->retval = retval;
3917   vam->result_ready = 1;
3918 }
3919
3920 static void
3921   vl_api_one_adjacencies_get_reply_t_handler
3922   (vl_api_one_adjacencies_get_reply_t * mp)
3923 {
3924   vat_main_t *vam = &vat_main;
3925   u32 i, n;
3926   int retval = clib_net_to_host_u32 (mp->retval);
3927   vl_api_one_adjacency_t *a;
3928
3929   if (retval)
3930     goto end;
3931
3932   n = clib_net_to_host_u32 (mp->count);
3933
3934   for (i = 0; i < n; i++)
3935     {
3936       a = &mp->adjacencies[i];
3937       print (vam->ofp, "%U %40U",
3938              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3939              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3940     }
3941
3942 end:
3943   vam->retval = retval;
3944   vam->result_ready = 1;
3945 }
3946
3947 static void
3948   vl_api_one_adjacencies_get_reply_t_handler_json
3949   (vl_api_one_adjacencies_get_reply_t * mp)
3950 {
3951   u8 *s = 0;
3952   vat_main_t *vam = &vat_main;
3953   vat_json_node_t *e = 0, root;
3954   u32 i, n;
3955   int retval = clib_net_to_host_u32 (mp->retval);
3956   vl_api_one_adjacency_t *a;
3957
3958   if (retval)
3959     goto end;
3960
3961   n = clib_net_to_host_u32 (mp->count);
3962   vat_json_init_array (&root);
3963
3964   for (i = 0; i < n; i++)
3965     {
3966       e = vat_json_array_add (&root);
3967       a = &mp->adjacencies[i];
3968
3969       vat_json_init_object (e);
3970       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3971                   a->leid_prefix_len);
3972       vec_add1 (s, 0);
3973       vat_json_object_add_string_copy (e, "leid", s);
3974       vec_free (s);
3975
3976       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3977                   a->reid_prefix_len);
3978       vec_add1 (s, 0);
3979       vat_json_object_add_string_copy (e, "reid", s);
3980       vec_free (s);
3981     }
3982
3983   vat_json_print (vam->ofp, &root);
3984   vat_json_free (&root);
3985
3986 end:
3987   vam->retval = retval;
3988   vam->result_ready = 1;
3989 }
3990
3991 static void
3992 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3993 {
3994   vat_main_t *vam = &vat_main;
3995
3996   print (vam->ofp, "%=20U",
3997          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3998          mp->ip_address);
3999 }
4000
4001 static void
4002   vl_api_one_map_server_details_t_handler_json
4003   (vl_api_one_map_server_details_t * mp)
4004 {
4005   vat_main_t *vam = &vat_main;
4006   vat_json_node_t *node = NULL;
4007   struct in6_addr ip6;
4008   struct in_addr ip4;
4009
4010   if (VAT_JSON_ARRAY != vam->json_tree.type)
4011     {
4012       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4013       vat_json_init_array (&vam->json_tree);
4014     }
4015   node = vat_json_array_add (&vam->json_tree);
4016
4017   vat_json_init_object (node);
4018   if (mp->is_ipv6)
4019     {
4020       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4021       vat_json_object_add_ip6 (node, "map-server", ip6);
4022     }
4023   else
4024     {
4025       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4026       vat_json_object_add_ip4 (node, "map-server", ip4);
4027     }
4028 }
4029
4030 static void
4031 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4032                                            * mp)
4033 {
4034   vat_main_t *vam = &vat_main;
4035
4036   print (vam->ofp, "%=20U",
4037          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4038          mp->ip_address);
4039 }
4040
4041 static void
4042   vl_api_one_map_resolver_details_t_handler_json
4043   (vl_api_one_map_resolver_details_t * mp)
4044 {
4045   vat_main_t *vam = &vat_main;
4046   vat_json_node_t *node = NULL;
4047   struct in6_addr ip6;
4048   struct in_addr ip4;
4049
4050   if (VAT_JSON_ARRAY != vam->json_tree.type)
4051     {
4052       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4053       vat_json_init_array (&vam->json_tree);
4054     }
4055   node = vat_json_array_add (&vam->json_tree);
4056
4057   vat_json_init_object (node);
4058   if (mp->is_ipv6)
4059     {
4060       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4061       vat_json_object_add_ip6 (node, "map resolver", ip6);
4062     }
4063   else
4064     {
4065       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4066       vat_json_object_add_ip4 (node, "map resolver", ip4);
4067     }
4068 }
4069
4070 static void
4071 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4072 {
4073   vat_main_t *vam = &vat_main;
4074   i32 retval = ntohl (mp->retval);
4075
4076   if (0 <= retval)
4077     {
4078       print (vam->ofp, "feature: %s\ngpe: %s",
4079              mp->feature_status ? "enabled" : "disabled",
4080              mp->gpe_status ? "enabled" : "disabled");
4081     }
4082
4083   vam->retval = retval;
4084   vam->result_ready = 1;
4085 }
4086
4087 static void
4088   vl_api_show_one_status_reply_t_handler_json
4089   (vl_api_show_one_status_reply_t * mp)
4090 {
4091   vat_main_t *vam = &vat_main;
4092   vat_json_node_t node;
4093   u8 *gpe_status = NULL;
4094   u8 *feature_status = NULL;
4095
4096   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4097   feature_status = format (0, "%s",
4098                            mp->feature_status ? "enabled" : "disabled");
4099   vec_add1 (gpe_status, 0);
4100   vec_add1 (feature_status, 0);
4101
4102   vat_json_init_object (&node);
4103   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4104   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4105
4106   vec_free (gpe_status);
4107   vec_free (feature_status);
4108
4109   vat_json_print (vam->ofp, &node);
4110   vat_json_free (&node);
4111
4112   vam->retval = ntohl (mp->retval);
4113   vam->result_ready = 1;
4114 }
4115
4116 static void
4117   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4118   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4119 {
4120   vat_main_t *vam = &vat_main;
4121   i32 retval = ntohl (mp->retval);
4122
4123   if (retval >= 0)
4124     {
4125       print (vam->ofp, "%=20s", mp->locator_set_name);
4126     }
4127
4128   vam->retval = retval;
4129   vam->result_ready = 1;
4130 }
4131
4132 static void
4133   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4134   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4135 {
4136   vat_main_t *vam = &vat_main;
4137   vat_json_node_t *node = NULL;
4138
4139   if (VAT_JSON_ARRAY != vam->json_tree.type)
4140     {
4141       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4142       vat_json_init_array (&vam->json_tree);
4143     }
4144   node = vat_json_array_add (&vam->json_tree);
4145
4146   vat_json_init_object (node);
4147   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4148
4149   vat_json_print (vam->ofp, node);
4150   vat_json_free (node);
4151
4152   vam->retval = ntohl (mp->retval);
4153   vam->result_ready = 1;
4154 }
4155
4156 static u8 *
4157 format_lisp_map_request_mode (u8 * s, va_list * args)
4158 {
4159   u32 mode = va_arg (*args, u32);
4160
4161   switch (mode)
4162     {
4163     case 0:
4164       return format (0, "dst-only");
4165     case 1:
4166       return format (0, "src-dst");
4167     }
4168   return 0;
4169 }
4170
4171 static void
4172   vl_api_show_one_map_request_mode_reply_t_handler
4173   (vl_api_show_one_map_request_mode_reply_t * mp)
4174 {
4175   vat_main_t *vam = &vat_main;
4176   i32 retval = ntohl (mp->retval);
4177
4178   if (0 <= retval)
4179     {
4180       u32 mode = mp->mode;
4181       print (vam->ofp, "map_request_mode: %U",
4182              format_lisp_map_request_mode, mode);
4183     }
4184
4185   vam->retval = retval;
4186   vam->result_ready = 1;
4187 }
4188
4189 static void
4190   vl_api_show_one_map_request_mode_reply_t_handler_json
4191   (vl_api_show_one_map_request_mode_reply_t * mp)
4192 {
4193   vat_main_t *vam = &vat_main;
4194   vat_json_node_t node;
4195   u8 *s = 0;
4196   u32 mode;
4197
4198   mode = mp->mode;
4199   s = format (0, "%U", format_lisp_map_request_mode, mode);
4200   vec_add1 (s, 0);
4201
4202   vat_json_init_object (&node);
4203   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4204   vat_json_print (vam->ofp, &node);
4205   vat_json_free (&node);
4206
4207   vec_free (s);
4208   vam->retval = ntohl (mp->retval);
4209   vam->result_ready = 1;
4210 }
4211
4212 static void
4213   vl_api_show_one_use_petr_reply_t_handler
4214   (vl_api_show_one_use_petr_reply_t * mp)
4215 {
4216   vat_main_t *vam = &vat_main;
4217   i32 retval = ntohl (mp->retval);
4218
4219   if (0 <= retval)
4220     {
4221       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4222       if (mp->status)
4223         {
4224           print (vam->ofp, "Proxy-ETR address; %U",
4225                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4226                  mp->address);
4227         }
4228     }
4229
4230   vam->retval = retval;
4231   vam->result_ready = 1;
4232 }
4233
4234 static void
4235   vl_api_show_one_use_petr_reply_t_handler_json
4236   (vl_api_show_one_use_petr_reply_t * mp)
4237 {
4238   vat_main_t *vam = &vat_main;
4239   vat_json_node_t node;
4240   u8 *status = 0;
4241   struct in_addr ip4;
4242   struct in6_addr ip6;
4243
4244   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4245   vec_add1 (status, 0);
4246
4247   vat_json_init_object (&node);
4248   vat_json_object_add_string_copy (&node, "status", status);
4249   if (mp->status)
4250     {
4251       if (mp->is_ip4)
4252         {
4253           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4254           vat_json_object_add_ip6 (&node, "address", ip6);
4255         }
4256       else
4257         {
4258           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4259           vat_json_object_add_ip4 (&node, "address", ip4);
4260         }
4261     }
4262
4263   vec_free (status);
4264
4265   vat_json_print (vam->ofp, &node);
4266   vat_json_free (&node);
4267
4268   vam->retval = ntohl (mp->retval);
4269   vam->result_ready = 1;
4270 }
4271
4272 static void
4273   vl_api_show_one_nsh_mapping_reply_t_handler
4274   (vl_api_show_one_nsh_mapping_reply_t * mp)
4275 {
4276   vat_main_t *vam = &vat_main;
4277   i32 retval = ntohl (mp->retval);
4278
4279   if (0 <= retval)
4280     {
4281       print (vam->ofp, "%-20s%-16s",
4282              mp->is_set ? "set" : "not-set",
4283              mp->is_set ? (char *) mp->locator_set_name : "");
4284     }
4285
4286   vam->retval = retval;
4287   vam->result_ready = 1;
4288 }
4289
4290 static void
4291   vl_api_show_one_nsh_mapping_reply_t_handler_json
4292   (vl_api_show_one_nsh_mapping_reply_t * mp)
4293 {
4294   vat_main_t *vam = &vat_main;
4295   vat_json_node_t node;
4296   u8 *status = 0;
4297
4298   status = format (0, "%s", mp->is_set ? "yes" : "no");
4299   vec_add1 (status, 0);
4300
4301   vat_json_init_object (&node);
4302   vat_json_object_add_string_copy (&node, "is_set", status);
4303   if (mp->is_set)
4304     {
4305       vat_json_object_add_string_copy (&node, "locator_set",
4306                                        mp->locator_set_name);
4307     }
4308
4309   vec_free (status);
4310
4311   vat_json_print (vam->ofp, &node);
4312   vat_json_free (&node);
4313
4314   vam->retval = ntohl (mp->retval);
4315   vam->result_ready = 1;
4316 }
4317
4318 static void
4319   vl_api_show_one_map_register_ttl_reply_t_handler
4320   (vl_api_show_one_map_register_ttl_reply_t * mp)
4321 {
4322   vat_main_t *vam = &vat_main;
4323   i32 retval = ntohl (mp->retval);
4324
4325   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4326
4327   if (0 <= retval)
4328     {
4329       print (vam->ofp, "ttl: %u", mp->ttl);
4330     }
4331
4332   vam->retval = retval;
4333   vam->result_ready = 1;
4334 }
4335
4336 static void
4337   vl_api_show_one_map_register_ttl_reply_t_handler_json
4338   (vl_api_show_one_map_register_ttl_reply_t * mp)
4339 {
4340   vat_main_t *vam = &vat_main;
4341   vat_json_node_t node;
4342
4343   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4344   vat_json_init_object (&node);
4345   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4346
4347   vat_json_print (vam->ofp, &node);
4348   vat_json_free (&node);
4349
4350   vam->retval = ntohl (mp->retval);
4351   vam->result_ready = 1;
4352 }
4353
4354 static void
4355 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4356 {
4357   vat_main_t *vam = &vat_main;
4358   i32 retval = ntohl (mp->retval);
4359
4360   if (0 <= retval)
4361     {
4362       print (vam->ofp, "%-20s%-16s",
4363              mp->status ? "enabled" : "disabled",
4364              mp->status ? (char *) mp->locator_set_name : "");
4365     }
4366
4367   vam->retval = retval;
4368   vam->result_ready = 1;
4369 }
4370
4371 static void
4372 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4373 {
4374   vat_main_t *vam = &vat_main;
4375   vat_json_node_t node;
4376   u8 *status = 0;
4377
4378   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4379   vec_add1 (status, 0);
4380
4381   vat_json_init_object (&node);
4382   vat_json_object_add_string_copy (&node, "status", status);
4383   if (mp->status)
4384     {
4385       vat_json_object_add_string_copy (&node, "locator_set",
4386                                        mp->locator_set_name);
4387     }
4388
4389   vec_free (status);
4390
4391   vat_json_print (vam->ofp, &node);
4392   vat_json_free (&node);
4393
4394   vam->retval = ntohl (mp->retval);
4395   vam->result_ready = 1;
4396 }
4397
4398 static u8 *
4399 format_policer_type (u8 * s, va_list * va)
4400 {
4401   u32 i = va_arg (*va, u32);
4402
4403   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4404     s = format (s, "1r2c");
4405   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4406     s = format (s, "1r3c");
4407   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4408     s = format (s, "2r3c-2698");
4409   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4410     s = format (s, "2r3c-4115");
4411   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4412     s = format (s, "2r3c-mef5cf1");
4413   else
4414     s = format (s, "ILLEGAL");
4415   return s;
4416 }
4417
4418 static u8 *
4419 format_policer_rate_type (u8 * s, va_list * va)
4420 {
4421   u32 i = va_arg (*va, u32);
4422
4423   if (i == SSE2_QOS_RATE_KBPS)
4424     s = format (s, "kbps");
4425   else if (i == SSE2_QOS_RATE_PPS)
4426     s = format (s, "pps");
4427   else
4428     s = format (s, "ILLEGAL");
4429   return s;
4430 }
4431
4432 static u8 *
4433 format_policer_round_type (u8 * s, va_list * va)
4434 {
4435   u32 i = va_arg (*va, u32);
4436
4437   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4438     s = format (s, "closest");
4439   else if (i == SSE2_QOS_ROUND_TO_UP)
4440     s = format (s, "up");
4441   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4442     s = format (s, "down");
4443   else
4444     s = format (s, "ILLEGAL");
4445   return s;
4446 }
4447
4448 static u8 *
4449 format_policer_action_type (u8 * s, va_list * va)
4450 {
4451   u32 i = va_arg (*va, u32);
4452
4453   if (i == SSE2_QOS_ACTION_DROP)
4454     s = format (s, "drop");
4455   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4456     s = format (s, "transmit");
4457   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4458     s = format (s, "mark-and-transmit");
4459   else
4460     s = format (s, "ILLEGAL");
4461   return s;
4462 }
4463
4464 static u8 *
4465 format_dscp (u8 * s, va_list * va)
4466 {
4467   u32 i = va_arg (*va, u32);
4468   char *t = 0;
4469
4470   switch (i)
4471     {
4472 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4473       foreach_vnet_dscp
4474 #undef _
4475     default:
4476       return format (s, "ILLEGAL");
4477     }
4478   s = format (s, "%s", t);
4479   return s;
4480 }
4481
4482 static void
4483 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4484 {
4485   vat_main_t *vam = &vat_main;
4486   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4487
4488   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4489     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4490   else
4491     conform_dscp_str = format (0, "");
4492
4493   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4494     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4495   else
4496     exceed_dscp_str = format (0, "");
4497
4498   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4499     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4500   else
4501     violate_dscp_str = format (0, "");
4502
4503   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4504          "rate type %U, round type %U, %s rate, %s color-aware, "
4505          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4506          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4507          "conform action %U%s, exceed action %U%s, violate action %U%s",
4508          mp->name,
4509          format_policer_type, mp->type,
4510          ntohl (mp->cir),
4511          ntohl (mp->eir),
4512          clib_net_to_host_u64 (mp->cb),
4513          clib_net_to_host_u64 (mp->eb),
4514          format_policer_rate_type, mp->rate_type,
4515          format_policer_round_type, mp->round_type,
4516          mp->single_rate ? "single" : "dual",
4517          mp->color_aware ? "is" : "not",
4518          ntohl (mp->cir_tokens_per_period),
4519          ntohl (mp->pir_tokens_per_period),
4520          ntohl (mp->scale),
4521          ntohl (mp->current_limit),
4522          ntohl (mp->current_bucket),
4523          ntohl (mp->extended_limit),
4524          ntohl (mp->extended_bucket),
4525          clib_net_to_host_u64 (mp->last_update_time),
4526          format_policer_action_type, mp->conform_action_type,
4527          conform_dscp_str,
4528          format_policer_action_type, mp->exceed_action_type,
4529          exceed_dscp_str,
4530          format_policer_action_type, mp->violate_action_type,
4531          violate_dscp_str);
4532
4533   vec_free (conform_dscp_str);
4534   vec_free (exceed_dscp_str);
4535   vec_free (violate_dscp_str);
4536 }
4537
4538 static void vl_api_policer_details_t_handler_json
4539   (vl_api_policer_details_t * mp)
4540 {
4541   vat_main_t *vam = &vat_main;
4542   vat_json_node_t *node;
4543   u8 *rate_type_str, *round_type_str, *type_str;
4544   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4545
4546   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4547   round_type_str =
4548     format (0, "%U", format_policer_round_type, mp->round_type);
4549   type_str = format (0, "%U", format_policer_type, mp->type);
4550   conform_action_str = format (0, "%U", format_policer_action_type,
4551                                mp->conform_action_type);
4552   exceed_action_str = format (0, "%U", format_policer_action_type,
4553                               mp->exceed_action_type);
4554   violate_action_str = format (0, "%U", format_policer_action_type,
4555                                mp->violate_action_type);
4556
4557   if (VAT_JSON_ARRAY != vam->json_tree.type)
4558     {
4559       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4560       vat_json_init_array (&vam->json_tree);
4561     }
4562   node = vat_json_array_add (&vam->json_tree);
4563
4564   vat_json_init_object (node);
4565   vat_json_object_add_string_copy (node, "name", mp->name);
4566   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4567   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4568   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4569   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4570   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4571   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4572   vat_json_object_add_string_copy (node, "type", type_str);
4573   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4574   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4575   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4576   vat_json_object_add_uint (node, "cir_tokens_per_period",
4577                             ntohl (mp->cir_tokens_per_period));
4578   vat_json_object_add_uint (node, "eir_tokens_per_period",
4579                             ntohl (mp->pir_tokens_per_period));
4580   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4581   vat_json_object_add_uint (node, "current_bucket",
4582                             ntohl (mp->current_bucket));
4583   vat_json_object_add_uint (node, "extended_limit",
4584                             ntohl (mp->extended_limit));
4585   vat_json_object_add_uint (node, "extended_bucket",
4586                             ntohl (mp->extended_bucket));
4587   vat_json_object_add_uint (node, "last_update_time",
4588                             ntohl (mp->last_update_time));
4589   vat_json_object_add_string_copy (node, "conform_action",
4590                                    conform_action_str);
4591   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4592     {
4593       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4594       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4595       vec_free (dscp_str);
4596     }
4597   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4598   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4599     {
4600       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4601       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4602       vec_free (dscp_str);
4603     }
4604   vat_json_object_add_string_copy (node, "violate_action",
4605                                    violate_action_str);
4606   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4607     {
4608       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4609       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4610       vec_free (dscp_str);
4611     }
4612
4613   vec_free (rate_type_str);
4614   vec_free (round_type_str);
4615   vec_free (type_str);
4616   vec_free (conform_action_str);
4617   vec_free (exceed_action_str);
4618   vec_free (violate_action_str);
4619 }
4620
4621 static void
4622 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4623                                            mp)
4624 {
4625   vat_main_t *vam = &vat_main;
4626   int i, count = ntohl (mp->count);
4627
4628   if (count > 0)
4629     print (vam->ofp, "classify table ids (%d) : ", count);
4630   for (i = 0; i < count; i++)
4631     {
4632       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4633       print (vam->ofp, (i < count - 1) ? "," : "");
4634     }
4635   vam->retval = ntohl (mp->retval);
4636   vam->result_ready = 1;
4637 }
4638
4639 static void
4640   vl_api_classify_table_ids_reply_t_handler_json
4641   (vl_api_classify_table_ids_reply_t * mp)
4642 {
4643   vat_main_t *vam = &vat_main;
4644   int i, count = ntohl (mp->count);
4645
4646   if (count > 0)
4647     {
4648       vat_json_node_t node;
4649
4650       vat_json_init_object (&node);
4651       for (i = 0; i < count; i++)
4652         {
4653           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4654         }
4655       vat_json_print (vam->ofp, &node);
4656       vat_json_free (&node);
4657     }
4658   vam->retval = ntohl (mp->retval);
4659   vam->result_ready = 1;
4660 }
4661
4662 static void
4663   vl_api_classify_table_by_interface_reply_t_handler
4664   (vl_api_classify_table_by_interface_reply_t * mp)
4665 {
4666   vat_main_t *vam = &vat_main;
4667   u32 table_id;
4668
4669   table_id = ntohl (mp->l2_table_id);
4670   if (table_id != ~0)
4671     print (vam->ofp, "l2 table id : %d", table_id);
4672   else
4673     print (vam->ofp, "l2 table id : No input ACL tables configured");
4674   table_id = ntohl (mp->ip4_table_id);
4675   if (table_id != ~0)
4676     print (vam->ofp, "ip4 table id : %d", table_id);
4677   else
4678     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4679   table_id = ntohl (mp->ip6_table_id);
4680   if (table_id != ~0)
4681     print (vam->ofp, "ip6 table id : %d", table_id);
4682   else
4683     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4684   vam->retval = ntohl (mp->retval);
4685   vam->result_ready = 1;
4686 }
4687
4688 static void
4689   vl_api_classify_table_by_interface_reply_t_handler_json
4690   (vl_api_classify_table_by_interface_reply_t * mp)
4691 {
4692   vat_main_t *vam = &vat_main;
4693   vat_json_node_t node;
4694
4695   vat_json_init_object (&node);
4696
4697   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4698   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4699   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4700
4701   vat_json_print (vam->ofp, &node);
4702   vat_json_free (&node);
4703
4704   vam->retval = ntohl (mp->retval);
4705   vam->result_ready = 1;
4706 }
4707
4708 static void vl_api_policer_add_del_reply_t_handler
4709   (vl_api_policer_add_del_reply_t * mp)
4710 {
4711   vat_main_t *vam = &vat_main;
4712   i32 retval = ntohl (mp->retval);
4713   if (vam->async_mode)
4714     {
4715       vam->async_errors += (retval < 0);
4716     }
4717   else
4718     {
4719       vam->retval = retval;
4720       vam->result_ready = 1;
4721       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4722         /*
4723          * Note: this is just barely thread-safe, depends on
4724          * the main thread spinning waiting for an answer...
4725          */
4726         errmsg ("policer index %d", ntohl (mp->policer_index));
4727     }
4728 }
4729
4730 static void vl_api_policer_add_del_reply_t_handler_json
4731   (vl_api_policer_add_del_reply_t * mp)
4732 {
4733   vat_main_t *vam = &vat_main;
4734   vat_json_node_t node;
4735
4736   vat_json_init_object (&node);
4737   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4738   vat_json_object_add_uint (&node, "policer_index",
4739                             ntohl (mp->policer_index));
4740
4741   vat_json_print (vam->ofp, &node);
4742   vat_json_free (&node);
4743
4744   vam->retval = ntohl (mp->retval);
4745   vam->result_ready = 1;
4746 }
4747
4748 /* Format hex dump. */
4749 u8 *
4750 format_hex_bytes (u8 * s, va_list * va)
4751 {
4752   u8 *bytes = va_arg (*va, u8 *);
4753   int n_bytes = va_arg (*va, int);
4754   uword i;
4755
4756   /* Print short or long form depending on byte count. */
4757   uword short_form = n_bytes <= 32;
4758   u32 indent = format_get_indent (s);
4759
4760   if (n_bytes == 0)
4761     return s;
4762
4763   for (i = 0; i < n_bytes; i++)
4764     {
4765       if (!short_form && (i % 32) == 0)
4766         s = format (s, "%08x: ", i);
4767       s = format (s, "%02x", bytes[i]);
4768       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4769         s = format (s, "\n%U", format_white_space, indent);
4770     }
4771
4772   return s;
4773 }
4774
4775 static void
4776 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4777                                             * mp)
4778 {
4779   vat_main_t *vam = &vat_main;
4780   i32 retval = ntohl (mp->retval);
4781   if (retval == 0)
4782     {
4783       print (vam->ofp, "classify table info :");
4784       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4785              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4786              ntohl (mp->miss_next_index));
4787       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4788              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4789              ntohl (mp->match_n_vectors));
4790       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4791              ntohl (mp->mask_length));
4792     }
4793   vam->retval = retval;
4794   vam->result_ready = 1;
4795 }
4796
4797 static void
4798   vl_api_classify_table_info_reply_t_handler_json
4799   (vl_api_classify_table_info_reply_t * mp)
4800 {
4801   vat_main_t *vam = &vat_main;
4802   vat_json_node_t node;
4803
4804   i32 retval = ntohl (mp->retval);
4805   if (retval == 0)
4806     {
4807       vat_json_init_object (&node);
4808
4809       vat_json_object_add_int (&node, "sessions",
4810                                ntohl (mp->active_sessions));
4811       vat_json_object_add_int (&node, "nexttbl",
4812                                ntohl (mp->next_table_index));
4813       vat_json_object_add_int (&node, "nextnode",
4814                                ntohl (mp->miss_next_index));
4815       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4816       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4817       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4818       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4819                       ntohl (mp->mask_length), 0);
4820       vat_json_object_add_string_copy (&node, "mask", s);
4821
4822       vat_json_print (vam->ofp, &node);
4823       vat_json_free (&node);
4824     }
4825   vam->retval = ntohl (mp->retval);
4826   vam->result_ready = 1;
4827 }
4828
4829 static void
4830 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4831                                            mp)
4832 {
4833   vat_main_t *vam = &vat_main;
4834
4835   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4836          ntohl (mp->hit_next_index), ntohl (mp->advance),
4837          ntohl (mp->opaque_index));
4838   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4839          ntohl (mp->match_length));
4840 }
4841
4842 static void
4843   vl_api_classify_session_details_t_handler_json
4844   (vl_api_classify_session_details_t * mp)
4845 {
4846   vat_main_t *vam = &vat_main;
4847   vat_json_node_t *node = NULL;
4848
4849   if (VAT_JSON_ARRAY != vam->json_tree.type)
4850     {
4851       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4852       vat_json_init_array (&vam->json_tree);
4853     }
4854   node = vat_json_array_add (&vam->json_tree);
4855
4856   vat_json_init_object (node);
4857   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4858   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4859   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4860   u8 *s =
4861     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4862             0);
4863   vat_json_object_add_string_copy (node, "match", s);
4864 }
4865
4866 static void vl_api_pg_create_interface_reply_t_handler
4867   (vl_api_pg_create_interface_reply_t * mp)
4868 {
4869   vat_main_t *vam = &vat_main;
4870
4871   vam->retval = ntohl (mp->retval);
4872   vam->result_ready = 1;
4873 }
4874
4875 static void vl_api_pg_create_interface_reply_t_handler_json
4876   (vl_api_pg_create_interface_reply_t * mp)
4877 {
4878   vat_main_t *vam = &vat_main;
4879   vat_json_node_t node;
4880
4881   i32 retval = ntohl (mp->retval);
4882   if (retval == 0)
4883     {
4884       vat_json_init_object (&node);
4885
4886       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4887
4888       vat_json_print (vam->ofp, &node);
4889       vat_json_free (&node);
4890     }
4891   vam->retval = ntohl (mp->retval);
4892   vam->result_ready = 1;
4893 }
4894
4895 static void vl_api_policer_classify_details_t_handler
4896   (vl_api_policer_classify_details_t * mp)
4897 {
4898   vat_main_t *vam = &vat_main;
4899
4900   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4901          ntohl (mp->table_index));
4902 }
4903
4904 static void vl_api_policer_classify_details_t_handler_json
4905   (vl_api_policer_classify_details_t * mp)
4906 {
4907   vat_main_t *vam = &vat_main;
4908   vat_json_node_t *node;
4909
4910   if (VAT_JSON_ARRAY != vam->json_tree.type)
4911     {
4912       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4913       vat_json_init_array (&vam->json_tree);
4914     }
4915   node = vat_json_array_add (&vam->json_tree);
4916
4917   vat_json_init_object (node);
4918   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4919   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4920 }
4921
4922 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
4923   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4924 {
4925   vat_main_t *vam = &vat_main;
4926   i32 retval = ntohl (mp->retval);
4927   if (vam->async_mode)
4928     {
4929       vam->async_errors += (retval < 0);
4930     }
4931   else
4932     {
4933       vam->retval = retval;
4934       vam->sw_if_index = ntohl (mp->sw_if_index);
4935       vam->result_ready = 1;
4936     }
4937 }
4938
4939 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
4940   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4941 {
4942   vat_main_t *vam = &vat_main;
4943   vat_json_node_t node;
4944
4945   vat_json_init_object (&node);
4946   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4947   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
4948
4949   vat_json_print (vam->ofp, &node);
4950   vat_json_free (&node);
4951
4952   vam->retval = ntohl (mp->retval);
4953   vam->result_ready = 1;
4954 }
4955
4956 static void vl_api_flow_classify_details_t_handler
4957   (vl_api_flow_classify_details_t * mp)
4958 {
4959   vat_main_t *vam = &vat_main;
4960
4961   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4962          ntohl (mp->table_index));
4963 }
4964
4965 static void vl_api_flow_classify_details_t_handler_json
4966   (vl_api_flow_classify_details_t * mp)
4967 {
4968   vat_main_t *vam = &vat_main;
4969   vat_json_node_t *node;
4970
4971   if (VAT_JSON_ARRAY != vam->json_tree.type)
4972     {
4973       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4974       vat_json_init_array (&vam->json_tree);
4975     }
4976   node = vat_json_array_add (&vam->json_tree);
4977
4978   vat_json_init_object (node);
4979   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4980   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4981 }
4982
4983 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
4984 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
4985 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
4986 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
4987 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
4988 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
4989 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
4990 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
4991 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
4992 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
4993 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
4994 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
4995 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
4996 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
4997 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
4998 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
4999 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5000 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5001 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5002 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5003 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5004 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5005
5006 /*
5007  * Generate boilerplate reply handlers, which
5008  * dig the return value out of the xxx_reply_t API message,
5009  * stick it into vam->retval, and set vam->result_ready
5010  *
5011  * Could also do this by pointing N message decode slots at
5012  * a single function, but that could break in subtle ways.
5013  */
5014
5015 #define foreach_standard_reply_retval_handler           \
5016 _(sw_interface_set_flags_reply)                         \
5017 _(sw_interface_add_del_address_reply)                   \
5018 _(sw_interface_set_table_reply)                         \
5019 _(sw_interface_set_mpls_enable_reply)                   \
5020 _(sw_interface_set_vpath_reply)                         \
5021 _(sw_interface_set_vxlan_bypass_reply)                  \
5022 _(sw_interface_set_geneve_bypass_reply)                 \
5023 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5024 _(sw_interface_set_l2_bridge_reply)                     \
5025 _(bridge_domain_add_del_reply)                          \
5026 _(sw_interface_set_l2_xconnect_reply)                   \
5027 _(l2fib_add_del_reply)                                  \
5028 _(l2fib_flush_int_reply)                                \
5029 _(l2fib_flush_bd_reply)                                 \
5030 _(ip_add_del_route_reply)                               \
5031 _(ip_table_add_del_reply)                               \
5032 _(ip_mroute_add_del_reply)                              \
5033 _(mpls_route_add_del_reply)                             \
5034 _(mpls_table_add_del_reply)                             \
5035 _(mpls_ip_bind_unbind_reply)                            \
5036 _(proxy_arp_add_del_reply)                              \
5037 _(proxy_arp_intfc_enable_disable_reply)                 \
5038 _(sw_interface_set_unnumbered_reply)                    \
5039 _(ip_neighbor_add_del_reply)                            \
5040 _(reset_vrf_reply)                                      \
5041 _(oam_add_del_reply)                                    \
5042 _(reset_fib_reply)                                      \
5043 _(dhcp_proxy_config_reply)                              \
5044 _(dhcp_proxy_set_vss_reply)                             \
5045 _(dhcp_client_config_reply)                             \
5046 _(set_ip_flow_hash_reply)                               \
5047 _(sw_interface_ip6_enable_disable_reply)                \
5048 _(sw_interface_ip6_set_link_local_address_reply)        \
5049 _(ip6nd_proxy_add_del_reply)                            \
5050 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5051 _(sw_interface_ip6nd_ra_config_reply)                   \
5052 _(set_arp_neighbor_limit_reply)                         \
5053 _(l2_patch_add_del_reply)                               \
5054 _(sr_policy_add_reply)                                  \
5055 _(sr_policy_mod_reply)                                  \
5056 _(sr_policy_del_reply)                                  \
5057 _(sr_localsid_add_del_reply)                            \
5058 _(sr_steering_add_del_reply)                            \
5059 _(classify_add_del_session_reply)                       \
5060 _(classify_set_interface_ip_table_reply)                \
5061 _(classify_set_interface_l2_tables_reply)               \
5062 _(l2tpv3_set_tunnel_cookies_reply)                      \
5063 _(l2tpv3_interface_enable_disable_reply)                \
5064 _(l2tpv3_set_lookup_key_reply)                          \
5065 _(l2_fib_clear_table_reply)                             \
5066 _(l2_interface_efp_filter_reply)                        \
5067 _(l2_interface_vlan_tag_rewrite_reply)                  \
5068 _(modify_vhost_user_if_reply)                           \
5069 _(delete_vhost_user_if_reply)                           \
5070 _(want_ip4_arp_events_reply)                            \
5071 _(want_ip6_nd_events_reply)                             \
5072 _(want_l2_macs_events_reply)                            \
5073 _(input_acl_set_interface_reply)                        \
5074 _(ipsec_spd_add_del_reply)                              \
5075 _(ipsec_interface_add_del_spd_reply)                    \
5076 _(ipsec_spd_add_del_entry_reply)                        \
5077 _(ipsec_sad_add_del_entry_reply)                        \
5078 _(ipsec_sa_set_key_reply)                               \
5079 _(ipsec_tunnel_if_add_del_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 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5314 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5315 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5316 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5317 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5318 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5319 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5320 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5321 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5322 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5323 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5324 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5325 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5326 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5327 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5328 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5329 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5330 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5331 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5332 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5333 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5334 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5335 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5336 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5337 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5338 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5339 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5340 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5341 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5342 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5343 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5344 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5345 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5346 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5347 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5348 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5349 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5350 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5351 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5352   one_map_register_enable_disable_reply)                                \
5353 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5354 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5355 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5356 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5357   one_map_register_fallback_threshold_reply)                            \
5358 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5359   one_rloc_probe_enable_disable_reply)                                  \
5360 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5361 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5362 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5363 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5364 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5365 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5366 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5367 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5368 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5369 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5370 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5371 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5372 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5373 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5374 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5375 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5376   show_one_stats_enable_disable_reply)                                  \
5377 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5378 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5379 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5380 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5381 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5382 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5383 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5384 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5385 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5386 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5387 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5388 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5389 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5390 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5391 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5392   gpe_add_del_native_fwd_rpath_reply)                                   \
5393 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5394   gpe_fwd_entry_path_details)                                           \
5395 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5396 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5397   one_add_del_map_request_itr_rlocs_reply)                              \
5398 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5399   one_get_map_request_itr_rlocs_reply)                                  \
5400 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5401 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5402 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5403 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5404 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5405 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5406   show_one_map_register_state_reply)                                    \
5407 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5408 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5409   show_one_map_register_fallback_threshold_reply)                       \
5410 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5411 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5412 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5413 _(POLICER_DETAILS, policer_details)                                     \
5414 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5415 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5416 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5417 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5418 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5419 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5420 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5421 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5422 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5423 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5424 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5425 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5426 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5427 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5428 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5429 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5430 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5431 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5432 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5433 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5434 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5435 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5436 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5437 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5438 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5439  ip_source_and_port_range_check_add_del_reply)                          \
5440 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5441  ip_source_and_port_range_check_interface_add_del_reply)                \
5442 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5443 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5444 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5445 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5446 _(PUNT_REPLY, punt_reply)                                               \
5447 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5448 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5449 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5450 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5451 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5452 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5453 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5454 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5455 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5456 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5457 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5458 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5459 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5460 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5461 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5462 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5463 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)
5464
5465 #define foreach_standalone_reply_msg                                    \
5466 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5467 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5468 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5469 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5470 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5471 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5472 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
5473 _(MEMFD_SEGMENT_CREATE_REPLY, memfd_segment_create_reply)               \
5474
5475 typedef struct
5476 {
5477   u8 *name;
5478   u32 value;
5479 } name_sort_t;
5480
5481
5482 #define STR_VTR_OP_CASE(op)     \
5483     case L2_VTR_ ## op:         \
5484         return "" # op;
5485
5486 static const char *
5487 str_vtr_op (u32 vtr_op)
5488 {
5489   switch (vtr_op)
5490     {
5491       STR_VTR_OP_CASE (DISABLED);
5492       STR_VTR_OP_CASE (PUSH_1);
5493       STR_VTR_OP_CASE (PUSH_2);
5494       STR_VTR_OP_CASE (POP_1);
5495       STR_VTR_OP_CASE (POP_2);
5496       STR_VTR_OP_CASE (TRANSLATE_1_1);
5497       STR_VTR_OP_CASE (TRANSLATE_1_2);
5498       STR_VTR_OP_CASE (TRANSLATE_2_1);
5499       STR_VTR_OP_CASE (TRANSLATE_2_2);
5500     }
5501
5502   return "UNKNOWN";
5503 }
5504
5505 static int
5506 dump_sub_interface_table (vat_main_t * vam)
5507 {
5508   const sw_interface_subif_t *sub = NULL;
5509
5510   if (vam->json_output)
5511     {
5512       clib_warning
5513         ("JSON output supported only for VPE API calls and dump_stats_table");
5514       return -99;
5515     }
5516
5517   print (vam->ofp,
5518          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5519          "Interface", "sw_if_index",
5520          "sub id", "dot1ad", "tags", "outer id",
5521          "inner id", "exact", "default", "outer any", "inner any");
5522
5523   vec_foreach (sub, vam->sw_if_subif_table)
5524   {
5525     print (vam->ofp,
5526            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5527            sub->interface_name,
5528            sub->sw_if_index,
5529            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5530            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5531            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5532            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5533     if (sub->vtr_op != L2_VTR_DISABLED)
5534       {
5535         print (vam->ofp,
5536                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5537                "tag1: %d tag2: %d ]",
5538                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5539                sub->vtr_tag1, sub->vtr_tag2);
5540       }
5541   }
5542
5543   return 0;
5544 }
5545
5546 static int
5547 name_sort_cmp (void *a1, void *a2)
5548 {
5549   name_sort_t *n1 = a1;
5550   name_sort_t *n2 = a2;
5551
5552   return strcmp ((char *) n1->name, (char *) n2->name);
5553 }
5554
5555 static int
5556 dump_interface_table (vat_main_t * vam)
5557 {
5558   hash_pair_t *p;
5559   name_sort_t *nses = 0, *ns;
5560
5561   if (vam->json_output)
5562     {
5563       clib_warning
5564         ("JSON output supported only for VPE API calls and dump_stats_table");
5565       return -99;
5566     }
5567
5568   /* *INDENT-OFF* */
5569   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5570   ({
5571     vec_add2 (nses, ns, 1);
5572     ns->name = (u8 *)(p->key);
5573     ns->value = (u32) p->value[0];
5574   }));
5575   /* *INDENT-ON* */
5576
5577   vec_sort_with_function (nses, name_sort_cmp);
5578
5579   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5580   vec_foreach (ns, nses)
5581   {
5582     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5583   }
5584   vec_free (nses);
5585   return 0;
5586 }
5587
5588 static int
5589 dump_ip_table (vat_main_t * vam, int is_ipv6)
5590 {
5591   const ip_details_t *det = NULL;
5592   const ip_address_details_t *address = NULL;
5593   u32 i = ~0;
5594
5595   print (vam->ofp, "%-12s", "sw_if_index");
5596
5597   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5598   {
5599     i++;
5600     if (!det->present)
5601       {
5602         continue;
5603       }
5604     print (vam->ofp, "%-12d", i);
5605     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5606     if (!det->addr)
5607       {
5608         continue;
5609       }
5610     vec_foreach (address, det->addr)
5611     {
5612       print (vam->ofp,
5613              "            %-30U%-13d",
5614              is_ipv6 ? format_ip6_address : format_ip4_address,
5615              address->ip, address->prefix_length);
5616     }
5617   }
5618
5619   return 0;
5620 }
5621
5622 static int
5623 dump_ipv4_table (vat_main_t * vam)
5624 {
5625   if (vam->json_output)
5626     {
5627       clib_warning
5628         ("JSON output supported only for VPE API calls and dump_stats_table");
5629       return -99;
5630     }
5631
5632   return dump_ip_table (vam, 0);
5633 }
5634
5635 static int
5636 dump_ipv6_table (vat_main_t * vam)
5637 {
5638   if (vam->json_output)
5639     {
5640       clib_warning
5641         ("JSON output supported only for VPE API calls and dump_stats_table");
5642       return -99;
5643     }
5644
5645   return dump_ip_table (vam, 1);
5646 }
5647
5648 static char *
5649 counter_type_to_str (u8 counter_type, u8 is_combined)
5650 {
5651   if (!is_combined)
5652     {
5653       switch (counter_type)
5654         {
5655         case VNET_INTERFACE_COUNTER_DROP:
5656           return "drop";
5657         case VNET_INTERFACE_COUNTER_PUNT:
5658           return "punt";
5659         case VNET_INTERFACE_COUNTER_IP4:
5660           return "ip4";
5661         case VNET_INTERFACE_COUNTER_IP6:
5662           return "ip6";
5663         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5664           return "rx-no-buf";
5665         case VNET_INTERFACE_COUNTER_RX_MISS:
5666           return "rx-miss";
5667         case VNET_INTERFACE_COUNTER_RX_ERROR:
5668           return "rx-error";
5669         case VNET_INTERFACE_COUNTER_TX_ERROR:
5670           return "tx-error";
5671         default:
5672           return "INVALID-COUNTER-TYPE";
5673         }
5674     }
5675   else
5676     {
5677       switch (counter_type)
5678         {
5679         case VNET_INTERFACE_COUNTER_RX:
5680           return "rx";
5681         case VNET_INTERFACE_COUNTER_TX:
5682           return "tx";
5683         default:
5684           return "INVALID-COUNTER-TYPE";
5685         }
5686     }
5687 }
5688
5689 static int
5690 dump_stats_table (vat_main_t * vam)
5691 {
5692   vat_json_node_t node;
5693   vat_json_node_t *msg_array;
5694   vat_json_node_t *msg;
5695   vat_json_node_t *counter_array;
5696   vat_json_node_t *counter;
5697   interface_counter_t c;
5698   u64 packets;
5699   ip4_fib_counter_t *c4;
5700   ip6_fib_counter_t *c6;
5701   ip4_nbr_counter_t *n4;
5702   ip6_nbr_counter_t *n6;
5703   int i, j;
5704
5705   if (!vam->json_output)
5706     {
5707       clib_warning ("dump_stats_table supported only in JSON format");
5708       return -99;
5709     }
5710
5711   vat_json_init_object (&node);
5712
5713   /* interface counters */
5714   msg_array = vat_json_object_add (&node, "interface_counters");
5715   vat_json_init_array (msg_array);
5716   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5717     {
5718       msg = vat_json_array_add (msg_array);
5719       vat_json_init_object (msg);
5720       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5721                                        (u8 *) counter_type_to_str (i, 0));
5722       vat_json_object_add_int (msg, "is_combined", 0);
5723       counter_array = vat_json_object_add (msg, "data");
5724       vat_json_init_array (counter_array);
5725       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5726         {
5727           packets = vam->simple_interface_counters[i][j];
5728           vat_json_array_add_uint (counter_array, packets);
5729         }
5730     }
5731   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5732     {
5733       msg = vat_json_array_add (msg_array);
5734       vat_json_init_object (msg);
5735       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5736                                        (u8 *) counter_type_to_str (i, 1));
5737       vat_json_object_add_int (msg, "is_combined", 1);
5738       counter_array = vat_json_object_add (msg, "data");
5739       vat_json_init_array (counter_array);
5740       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5741         {
5742           c = vam->combined_interface_counters[i][j];
5743           counter = vat_json_array_add (counter_array);
5744           vat_json_init_object (counter);
5745           vat_json_object_add_uint (counter, "packets", c.packets);
5746           vat_json_object_add_uint (counter, "bytes", c.bytes);
5747         }
5748     }
5749
5750   /* ip4 fib counters */
5751   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
5752   vat_json_init_array (msg_array);
5753   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
5754     {
5755       msg = vat_json_array_add (msg_array);
5756       vat_json_init_object (msg);
5757       vat_json_object_add_uint (msg, "vrf_id",
5758                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
5759       counter_array = vat_json_object_add (msg, "c");
5760       vat_json_init_array (counter_array);
5761       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
5762         {
5763           counter = vat_json_array_add (counter_array);
5764           vat_json_init_object (counter);
5765           c4 = &vam->ip4_fib_counters[i][j];
5766           vat_json_object_add_ip4 (counter, "address", c4->address);
5767           vat_json_object_add_uint (counter, "address_length",
5768                                     c4->address_length);
5769           vat_json_object_add_uint (counter, "packets", c4->packets);
5770           vat_json_object_add_uint (counter, "bytes", c4->bytes);
5771         }
5772     }
5773
5774   /* ip6 fib counters */
5775   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
5776   vat_json_init_array (msg_array);
5777   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
5778     {
5779       msg = vat_json_array_add (msg_array);
5780       vat_json_init_object (msg);
5781       vat_json_object_add_uint (msg, "vrf_id",
5782                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
5783       counter_array = vat_json_object_add (msg, "c");
5784       vat_json_init_array (counter_array);
5785       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
5786         {
5787           counter = vat_json_array_add (counter_array);
5788           vat_json_init_object (counter);
5789           c6 = &vam->ip6_fib_counters[i][j];
5790           vat_json_object_add_ip6 (counter, "address", c6->address);
5791           vat_json_object_add_uint (counter, "address_length",
5792                                     c6->address_length);
5793           vat_json_object_add_uint (counter, "packets", c6->packets);
5794           vat_json_object_add_uint (counter, "bytes", c6->bytes);
5795         }
5796     }
5797
5798   /* ip4 nbr counters */
5799   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
5800   vat_json_init_array (msg_array);
5801   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
5802     {
5803       msg = vat_json_array_add (msg_array);
5804       vat_json_init_object (msg);
5805       vat_json_object_add_uint (msg, "sw_if_index", i);
5806       counter_array = vat_json_object_add (msg, "c");
5807       vat_json_init_array (counter_array);
5808       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
5809         {
5810           counter = vat_json_array_add (counter_array);
5811           vat_json_init_object (counter);
5812           n4 = &vam->ip4_nbr_counters[i][j];
5813           vat_json_object_add_ip4 (counter, "address", n4->address);
5814           vat_json_object_add_uint (counter, "link-type", n4->linkt);
5815           vat_json_object_add_uint (counter, "packets", n4->packets);
5816           vat_json_object_add_uint (counter, "bytes", n4->bytes);
5817         }
5818     }
5819
5820   /* ip6 nbr counters */
5821   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
5822   vat_json_init_array (msg_array);
5823   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
5824     {
5825       msg = vat_json_array_add (msg_array);
5826       vat_json_init_object (msg);
5827       vat_json_object_add_uint (msg, "sw_if_index", i);
5828       counter_array = vat_json_object_add (msg, "c");
5829       vat_json_init_array (counter_array);
5830       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
5831         {
5832           counter = vat_json_array_add (counter_array);
5833           vat_json_init_object (counter);
5834           n6 = &vam->ip6_nbr_counters[i][j];
5835           vat_json_object_add_ip6 (counter, "address", n6->address);
5836           vat_json_object_add_uint (counter, "packets", n6->packets);
5837           vat_json_object_add_uint (counter, "bytes", n6->bytes);
5838         }
5839     }
5840
5841   vat_json_print (vam->ofp, &node);
5842   vat_json_free (&node);
5843
5844   return 0;
5845 }
5846
5847 /*
5848  * Pass CLI buffers directly in the CLI_INBAND API message,
5849  * instead of an additional shared memory area.
5850  */
5851 static int
5852 exec_inband (vat_main_t * vam)
5853 {
5854   vl_api_cli_inband_t *mp;
5855   unformat_input_t *i = vam->input;
5856   int ret;
5857
5858   if (vec_len (i->buffer) == 0)
5859     return -1;
5860
5861   if (vam->exec_mode == 0 && unformat (i, "mode"))
5862     {
5863       vam->exec_mode = 1;
5864       return 0;
5865     }
5866   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5867     {
5868       vam->exec_mode = 0;
5869       return 0;
5870     }
5871
5872   /*
5873    * In order for the CLI command to work, it
5874    * must be a vector ending in \n, not a C-string ending
5875    * in \n\0.
5876    */
5877   u32 len = vec_len (vam->input->buffer);
5878   M2 (CLI_INBAND, mp, len);
5879   clib_memcpy (mp->cmd, vam->input->buffer, len);
5880   mp->length = htonl (len);
5881
5882   S (mp);
5883   W (ret);
5884   /* json responses may or may not include a useful reply... */
5885   if (vec_len (vam->cmd_reply))
5886     print (vam->ofp, (char *) (vam->cmd_reply));
5887   return ret;
5888 }
5889
5890 int
5891 exec (vat_main_t * vam)
5892 {
5893   return exec_inband (vam);
5894 }
5895
5896 static int
5897 api_create_loopback (vat_main_t * vam)
5898 {
5899   unformat_input_t *i = vam->input;
5900   vl_api_create_loopback_t *mp;
5901   vl_api_create_loopback_instance_t *mp_lbi;
5902   u8 mac_address[6];
5903   u8 mac_set = 0;
5904   u8 is_specified = 0;
5905   u32 user_instance = 0;
5906   int ret;
5907
5908   memset (mac_address, 0, sizeof (mac_address));
5909
5910   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5911     {
5912       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5913         mac_set = 1;
5914       if (unformat (i, "instance %d", &user_instance))
5915         is_specified = 1;
5916       else
5917         break;
5918     }
5919
5920   if (is_specified)
5921     {
5922       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5923       mp_lbi->is_specified = is_specified;
5924       if (is_specified)
5925         mp_lbi->user_instance = htonl (user_instance);
5926       if (mac_set)
5927         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5928       S (mp_lbi);
5929     }
5930   else
5931     {
5932       /* Construct the API message */
5933       M (CREATE_LOOPBACK, mp);
5934       if (mac_set)
5935         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5936       S (mp);
5937     }
5938
5939   W (ret);
5940   return ret;
5941 }
5942
5943 static int
5944 api_delete_loopback (vat_main_t * vam)
5945 {
5946   unformat_input_t *i = vam->input;
5947   vl_api_delete_loopback_t *mp;
5948   u32 sw_if_index = ~0;
5949   int ret;
5950
5951   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5952     {
5953       if (unformat (i, "sw_if_index %d", &sw_if_index))
5954         ;
5955       else
5956         break;
5957     }
5958
5959   if (sw_if_index == ~0)
5960     {
5961       errmsg ("missing sw_if_index");
5962       return -99;
5963     }
5964
5965   /* Construct the API message */
5966   M (DELETE_LOOPBACK, mp);
5967   mp->sw_if_index = ntohl (sw_if_index);
5968
5969   S (mp);
5970   W (ret);
5971   return ret;
5972 }
5973
5974 static int
5975 api_want_stats (vat_main_t * vam)
5976 {
5977   unformat_input_t *i = vam->input;
5978   vl_api_want_stats_t *mp;
5979   int enable = -1;
5980   int ret;
5981
5982   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5983     {
5984       if (unformat (i, "enable"))
5985         enable = 1;
5986       else if (unformat (i, "disable"))
5987         enable = 0;
5988       else
5989         break;
5990     }
5991
5992   if (enable == -1)
5993     {
5994       errmsg ("missing enable|disable");
5995       return -99;
5996     }
5997
5998   M (WANT_STATS, mp);
5999   mp->enable_disable = enable;
6000
6001   S (mp);
6002   W (ret);
6003   return ret;
6004 }
6005
6006 static int
6007 api_want_interface_events (vat_main_t * vam)
6008 {
6009   unformat_input_t *i = vam->input;
6010   vl_api_want_interface_events_t *mp;
6011   int enable = -1;
6012   int ret;
6013
6014   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6015     {
6016       if (unformat (i, "enable"))
6017         enable = 1;
6018       else if (unformat (i, "disable"))
6019         enable = 0;
6020       else
6021         break;
6022     }
6023
6024   if (enable == -1)
6025     {
6026       errmsg ("missing enable|disable");
6027       return -99;
6028     }
6029
6030   M (WANT_INTERFACE_EVENTS, mp);
6031   mp->enable_disable = enable;
6032
6033   vam->interface_event_display = enable;
6034
6035   S (mp);
6036   W (ret);
6037   return ret;
6038 }
6039
6040
6041 /* Note: non-static, called once to set up the initial intfc table */
6042 int
6043 api_sw_interface_dump (vat_main_t * vam)
6044 {
6045   vl_api_sw_interface_dump_t *mp;
6046   vl_api_control_ping_t *mp_ping;
6047   hash_pair_t *p;
6048   name_sort_t *nses = 0, *ns;
6049   sw_interface_subif_t *sub = NULL;
6050   int ret;
6051
6052   /* Toss the old name table */
6053   /* *INDENT-OFF* */
6054   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6055   ({
6056     vec_add2 (nses, ns, 1);
6057     ns->name = (u8 *)(p->key);
6058     ns->value = (u32) p->value[0];
6059   }));
6060   /* *INDENT-ON* */
6061
6062   hash_free (vam->sw_if_index_by_interface_name);
6063
6064   vec_foreach (ns, nses) vec_free (ns->name);
6065
6066   vec_free (nses);
6067
6068   vec_foreach (sub, vam->sw_if_subif_table)
6069   {
6070     vec_free (sub->interface_name);
6071   }
6072   vec_free (vam->sw_if_subif_table);
6073
6074   /* recreate the interface name hash table */
6075   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6076
6077   /* Get list of ethernets */
6078   M (SW_INTERFACE_DUMP, mp);
6079   mp->name_filter_valid = 1;
6080   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
6081   S (mp);
6082
6083   /* and local / loopback interfaces */
6084   M (SW_INTERFACE_DUMP, mp);
6085   mp->name_filter_valid = 1;
6086   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
6087   S (mp);
6088
6089   /* and packet-generator interfaces */
6090   M (SW_INTERFACE_DUMP, mp);
6091   mp->name_filter_valid = 1;
6092   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
6093   S (mp);
6094
6095   /* and vxlan-gpe tunnel interfaces */
6096   M (SW_INTERFACE_DUMP, mp);
6097   mp->name_filter_valid = 1;
6098   strncpy ((char *) mp->name_filter, "vxlan_gpe",
6099            sizeof (mp->name_filter) - 1);
6100   S (mp);
6101
6102   /* and vxlan tunnel interfaces */
6103   M (SW_INTERFACE_DUMP, mp);
6104   mp->name_filter_valid = 1;
6105   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
6106   S (mp);
6107
6108   /* and geneve tunnel interfaces */
6109   M (SW_INTERFACE_DUMP, mp);
6110   mp->name_filter_valid = 1;
6111   strncpy ((char *) mp->name_filter, "geneve", sizeof (mp->name_filter) - 1);
6112   S (mp);
6113
6114   /* and host (af_packet) interfaces */
6115   M (SW_INTERFACE_DUMP, mp);
6116   mp->name_filter_valid = 1;
6117   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
6118   S (mp);
6119
6120   /* and l2tpv3 tunnel interfaces */
6121   M (SW_INTERFACE_DUMP, mp);
6122   mp->name_filter_valid = 1;
6123   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
6124            sizeof (mp->name_filter) - 1);
6125   S (mp);
6126
6127   /* and GRE tunnel interfaces */
6128   M (SW_INTERFACE_DUMP, mp);
6129   mp->name_filter_valid = 1;
6130   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
6131   S (mp);
6132
6133   /* and LISP-GPE interfaces */
6134   M (SW_INTERFACE_DUMP, mp);
6135   mp->name_filter_valid = 1;
6136   strncpy ((char *) mp->name_filter, "lisp_gpe",
6137            sizeof (mp->name_filter) - 1);
6138   S (mp);
6139
6140   /* and IPSEC tunnel interfaces */
6141   M (SW_INTERFACE_DUMP, mp);
6142   mp->name_filter_valid = 1;
6143   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
6144   S (mp);
6145
6146   /* Use a control ping for synchronization */
6147   MPING (CONTROL_PING, mp_ping);
6148   S (mp_ping);
6149
6150   W (ret);
6151   return ret;
6152 }
6153
6154 static int
6155 api_sw_interface_set_flags (vat_main_t * vam)
6156 {
6157   unformat_input_t *i = vam->input;
6158   vl_api_sw_interface_set_flags_t *mp;
6159   u32 sw_if_index;
6160   u8 sw_if_index_set = 0;
6161   u8 admin_up = 0;
6162   int ret;
6163
6164   /* Parse args required to build the message */
6165   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6166     {
6167       if (unformat (i, "admin-up"))
6168         admin_up = 1;
6169       else if (unformat (i, "admin-down"))
6170         admin_up = 0;
6171       else
6172         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6173         sw_if_index_set = 1;
6174       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6175         sw_if_index_set = 1;
6176       else
6177         break;
6178     }
6179
6180   if (sw_if_index_set == 0)
6181     {
6182       errmsg ("missing interface name or sw_if_index");
6183       return -99;
6184     }
6185
6186   /* Construct the API message */
6187   M (SW_INTERFACE_SET_FLAGS, mp);
6188   mp->sw_if_index = ntohl (sw_if_index);
6189   mp->admin_up_down = admin_up;
6190
6191   /* send it... */
6192   S (mp);
6193
6194   /* Wait for a reply, return the good/bad news... */
6195   W (ret);
6196   return ret;
6197 }
6198
6199 static int
6200 api_sw_interface_clear_stats (vat_main_t * vam)
6201 {
6202   unformat_input_t *i = vam->input;
6203   vl_api_sw_interface_clear_stats_t *mp;
6204   u32 sw_if_index;
6205   u8 sw_if_index_set = 0;
6206   int ret;
6207
6208   /* Parse args required to build the message */
6209   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6210     {
6211       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6212         sw_if_index_set = 1;
6213       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6214         sw_if_index_set = 1;
6215       else
6216         break;
6217     }
6218
6219   /* Construct the API message */
6220   M (SW_INTERFACE_CLEAR_STATS, mp);
6221
6222   if (sw_if_index_set == 1)
6223     mp->sw_if_index = ntohl (sw_if_index);
6224   else
6225     mp->sw_if_index = ~0;
6226
6227   /* send it... */
6228   S (mp);
6229
6230   /* Wait for a reply, return the good/bad news... */
6231   W (ret);
6232   return ret;
6233 }
6234
6235 static int
6236 api_sw_interface_add_del_address (vat_main_t * vam)
6237 {
6238   unformat_input_t *i = vam->input;
6239   vl_api_sw_interface_add_del_address_t *mp;
6240   u32 sw_if_index;
6241   u8 sw_if_index_set = 0;
6242   u8 is_add = 1, del_all = 0;
6243   u32 address_length = 0;
6244   u8 v4_address_set = 0;
6245   u8 v6_address_set = 0;
6246   ip4_address_t v4address;
6247   ip6_address_t v6address;
6248   int ret;
6249
6250   /* Parse args required to build the message */
6251   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6252     {
6253       if (unformat (i, "del-all"))
6254         del_all = 1;
6255       else if (unformat (i, "del"))
6256         is_add = 0;
6257       else
6258         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6259         sw_if_index_set = 1;
6260       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6261         sw_if_index_set = 1;
6262       else if (unformat (i, "%U/%d",
6263                          unformat_ip4_address, &v4address, &address_length))
6264         v4_address_set = 1;
6265       else if (unformat (i, "%U/%d",
6266                          unformat_ip6_address, &v6address, &address_length))
6267         v6_address_set = 1;
6268       else
6269         break;
6270     }
6271
6272   if (sw_if_index_set == 0)
6273     {
6274       errmsg ("missing interface name or sw_if_index");
6275       return -99;
6276     }
6277   if (v4_address_set && v6_address_set)
6278     {
6279       errmsg ("both v4 and v6 addresses set");
6280       return -99;
6281     }
6282   if (!v4_address_set && !v6_address_set && !del_all)
6283     {
6284       errmsg ("no addresses set");
6285       return -99;
6286     }
6287
6288   /* Construct the API message */
6289   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6290
6291   mp->sw_if_index = ntohl (sw_if_index);
6292   mp->is_add = is_add;
6293   mp->del_all = del_all;
6294   if (v6_address_set)
6295     {
6296       mp->is_ipv6 = 1;
6297       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6298     }
6299   else
6300     {
6301       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6302     }
6303   mp->address_length = address_length;
6304
6305   /* send it... */
6306   S (mp);
6307
6308   /* Wait for a reply, return good/bad news  */
6309   W (ret);
6310   return ret;
6311 }
6312
6313 static int
6314 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6315 {
6316   unformat_input_t *i = vam->input;
6317   vl_api_sw_interface_set_mpls_enable_t *mp;
6318   u32 sw_if_index;
6319   u8 sw_if_index_set = 0;
6320   u8 enable = 1;
6321   int ret;
6322
6323   /* Parse args required to build the message */
6324   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6325     {
6326       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6327         sw_if_index_set = 1;
6328       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6329         sw_if_index_set = 1;
6330       else if (unformat (i, "disable"))
6331         enable = 0;
6332       else if (unformat (i, "dis"))
6333         enable = 0;
6334       else
6335         break;
6336     }
6337
6338   if (sw_if_index_set == 0)
6339     {
6340       errmsg ("missing interface name or sw_if_index");
6341       return -99;
6342     }
6343
6344   /* Construct the API message */
6345   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6346
6347   mp->sw_if_index = ntohl (sw_if_index);
6348   mp->enable = enable;
6349
6350   /* send it... */
6351   S (mp);
6352
6353   /* Wait for a reply... */
6354   W (ret);
6355   return ret;
6356 }
6357
6358 static int
6359 api_sw_interface_set_table (vat_main_t * vam)
6360 {
6361   unformat_input_t *i = vam->input;
6362   vl_api_sw_interface_set_table_t *mp;
6363   u32 sw_if_index, vrf_id = 0;
6364   u8 sw_if_index_set = 0;
6365   u8 is_ipv6 = 0;
6366   int ret;
6367
6368   /* Parse args required to build the message */
6369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6370     {
6371       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6372         sw_if_index_set = 1;
6373       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6374         sw_if_index_set = 1;
6375       else if (unformat (i, "vrf %d", &vrf_id))
6376         ;
6377       else if (unformat (i, "ipv6"))
6378         is_ipv6 = 1;
6379       else
6380         break;
6381     }
6382
6383   if (sw_if_index_set == 0)
6384     {
6385       errmsg ("missing interface name or sw_if_index");
6386       return -99;
6387     }
6388
6389   /* Construct the API message */
6390   M (SW_INTERFACE_SET_TABLE, mp);
6391
6392   mp->sw_if_index = ntohl (sw_if_index);
6393   mp->is_ipv6 = is_ipv6;
6394   mp->vrf_id = ntohl (vrf_id);
6395
6396   /* send it... */
6397   S (mp);
6398
6399   /* Wait for a reply... */
6400   W (ret);
6401   return ret;
6402 }
6403
6404 static void vl_api_sw_interface_get_table_reply_t_handler
6405   (vl_api_sw_interface_get_table_reply_t * mp)
6406 {
6407   vat_main_t *vam = &vat_main;
6408
6409   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6410
6411   vam->retval = ntohl (mp->retval);
6412   vam->result_ready = 1;
6413
6414 }
6415
6416 static void vl_api_sw_interface_get_table_reply_t_handler_json
6417   (vl_api_sw_interface_get_table_reply_t * mp)
6418 {
6419   vat_main_t *vam = &vat_main;
6420   vat_json_node_t node;
6421
6422   vat_json_init_object (&node);
6423   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6424   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6425
6426   vat_json_print (vam->ofp, &node);
6427   vat_json_free (&node);
6428
6429   vam->retval = ntohl (mp->retval);
6430   vam->result_ready = 1;
6431 }
6432
6433 static int
6434 api_sw_interface_get_table (vat_main_t * vam)
6435 {
6436   unformat_input_t *i = vam->input;
6437   vl_api_sw_interface_get_table_t *mp;
6438   u32 sw_if_index;
6439   u8 sw_if_index_set = 0;
6440   u8 is_ipv6 = 0;
6441   int ret;
6442
6443   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6444     {
6445       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6446         sw_if_index_set = 1;
6447       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6448         sw_if_index_set = 1;
6449       else if (unformat (i, "ipv6"))
6450         is_ipv6 = 1;
6451       else
6452         break;
6453     }
6454
6455   if (sw_if_index_set == 0)
6456     {
6457       errmsg ("missing interface name or sw_if_index");
6458       return -99;
6459     }
6460
6461   M (SW_INTERFACE_GET_TABLE, mp);
6462   mp->sw_if_index = htonl (sw_if_index);
6463   mp->is_ipv6 = is_ipv6;
6464
6465   S (mp);
6466   W (ret);
6467   return ret;
6468 }
6469
6470 static int
6471 api_sw_interface_set_vpath (vat_main_t * vam)
6472 {
6473   unformat_input_t *i = vam->input;
6474   vl_api_sw_interface_set_vpath_t *mp;
6475   u32 sw_if_index = 0;
6476   u8 sw_if_index_set = 0;
6477   u8 is_enable = 0;
6478   int ret;
6479
6480   /* Parse args required to build the message */
6481   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6482     {
6483       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6484         sw_if_index_set = 1;
6485       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6486         sw_if_index_set = 1;
6487       else if (unformat (i, "enable"))
6488         is_enable = 1;
6489       else if (unformat (i, "disable"))
6490         is_enable = 0;
6491       else
6492         break;
6493     }
6494
6495   if (sw_if_index_set == 0)
6496     {
6497       errmsg ("missing interface name or sw_if_index");
6498       return -99;
6499     }
6500
6501   /* Construct the API message */
6502   M (SW_INTERFACE_SET_VPATH, mp);
6503
6504   mp->sw_if_index = ntohl (sw_if_index);
6505   mp->enable = is_enable;
6506
6507   /* send it... */
6508   S (mp);
6509
6510   /* Wait for a reply... */
6511   W (ret);
6512   return ret;
6513 }
6514
6515 static int
6516 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6517 {
6518   unformat_input_t *i = vam->input;
6519   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6520   u32 sw_if_index = 0;
6521   u8 sw_if_index_set = 0;
6522   u8 is_enable = 1;
6523   u8 is_ipv6 = 0;
6524   int ret;
6525
6526   /* Parse args required to build the message */
6527   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6528     {
6529       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6530         sw_if_index_set = 1;
6531       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6532         sw_if_index_set = 1;
6533       else if (unformat (i, "enable"))
6534         is_enable = 1;
6535       else if (unformat (i, "disable"))
6536         is_enable = 0;
6537       else if (unformat (i, "ip4"))
6538         is_ipv6 = 0;
6539       else if (unformat (i, "ip6"))
6540         is_ipv6 = 1;
6541       else
6542         break;
6543     }
6544
6545   if (sw_if_index_set == 0)
6546     {
6547       errmsg ("missing interface name or sw_if_index");
6548       return -99;
6549     }
6550
6551   /* Construct the API message */
6552   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6553
6554   mp->sw_if_index = ntohl (sw_if_index);
6555   mp->enable = is_enable;
6556   mp->is_ipv6 = is_ipv6;
6557
6558   /* send it... */
6559   S (mp);
6560
6561   /* Wait for a reply... */
6562   W (ret);
6563   return ret;
6564 }
6565
6566 static int
6567 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6568 {
6569   unformat_input_t *i = vam->input;
6570   vl_api_sw_interface_set_geneve_bypass_t *mp;
6571   u32 sw_if_index = 0;
6572   u8 sw_if_index_set = 0;
6573   u8 is_enable = 1;
6574   u8 is_ipv6 = 0;
6575   int ret;
6576
6577   /* Parse args required to build the message */
6578   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6579     {
6580       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6581         sw_if_index_set = 1;
6582       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6583         sw_if_index_set = 1;
6584       else if (unformat (i, "enable"))
6585         is_enable = 1;
6586       else if (unformat (i, "disable"))
6587         is_enable = 0;
6588       else if (unformat (i, "ip4"))
6589         is_ipv6 = 0;
6590       else if (unformat (i, "ip6"))
6591         is_ipv6 = 1;
6592       else
6593         break;
6594     }
6595
6596   if (sw_if_index_set == 0)
6597     {
6598       errmsg ("missing interface name or sw_if_index");
6599       return -99;
6600     }
6601
6602   /* Construct the API message */
6603   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6604
6605   mp->sw_if_index = ntohl (sw_if_index);
6606   mp->enable = is_enable;
6607   mp->is_ipv6 = is_ipv6;
6608
6609   /* send it... */
6610   S (mp);
6611
6612   /* Wait for a reply... */
6613   W (ret);
6614   return ret;
6615 }
6616
6617 static int
6618 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6619 {
6620   unformat_input_t *i = vam->input;
6621   vl_api_sw_interface_set_l2_xconnect_t *mp;
6622   u32 rx_sw_if_index;
6623   u8 rx_sw_if_index_set = 0;
6624   u32 tx_sw_if_index;
6625   u8 tx_sw_if_index_set = 0;
6626   u8 enable = 1;
6627   int ret;
6628
6629   /* Parse args required to build the message */
6630   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6631     {
6632       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6633         rx_sw_if_index_set = 1;
6634       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6635         tx_sw_if_index_set = 1;
6636       else if (unformat (i, "rx"))
6637         {
6638           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6639             {
6640               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6641                             &rx_sw_if_index))
6642                 rx_sw_if_index_set = 1;
6643             }
6644           else
6645             break;
6646         }
6647       else if (unformat (i, "tx"))
6648         {
6649           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6650             {
6651               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6652                             &tx_sw_if_index))
6653                 tx_sw_if_index_set = 1;
6654             }
6655           else
6656             break;
6657         }
6658       else if (unformat (i, "enable"))
6659         enable = 1;
6660       else if (unformat (i, "disable"))
6661         enable = 0;
6662       else
6663         break;
6664     }
6665
6666   if (rx_sw_if_index_set == 0)
6667     {
6668       errmsg ("missing rx interface name or rx_sw_if_index");
6669       return -99;
6670     }
6671
6672   if (enable && (tx_sw_if_index_set == 0))
6673     {
6674       errmsg ("missing tx interface name or tx_sw_if_index");
6675       return -99;
6676     }
6677
6678   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6679
6680   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6681   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6682   mp->enable = enable;
6683
6684   S (mp);
6685   W (ret);
6686   return ret;
6687 }
6688
6689 static int
6690 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6691 {
6692   unformat_input_t *i = vam->input;
6693   vl_api_sw_interface_set_l2_bridge_t *mp;
6694   u32 rx_sw_if_index;
6695   u8 rx_sw_if_index_set = 0;
6696   u32 bd_id;
6697   u8 bd_id_set = 0;
6698   u8 bvi = 0;
6699   u32 shg = 0;
6700   u8 enable = 1;
6701   int ret;
6702
6703   /* Parse args required to build the message */
6704   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6705     {
6706       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6707         rx_sw_if_index_set = 1;
6708       else if (unformat (i, "bd_id %d", &bd_id))
6709         bd_id_set = 1;
6710       else
6711         if (unformat
6712             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6713         rx_sw_if_index_set = 1;
6714       else if (unformat (i, "shg %d", &shg))
6715         ;
6716       else if (unformat (i, "bvi"))
6717         bvi = 1;
6718       else if (unformat (i, "enable"))
6719         enable = 1;
6720       else if (unformat (i, "disable"))
6721         enable = 0;
6722       else
6723         break;
6724     }
6725
6726   if (rx_sw_if_index_set == 0)
6727     {
6728       errmsg ("missing rx interface name or sw_if_index");
6729       return -99;
6730     }
6731
6732   if (enable && (bd_id_set == 0))
6733     {
6734       errmsg ("missing bridge domain");
6735       return -99;
6736     }
6737
6738   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6739
6740   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6741   mp->bd_id = ntohl (bd_id);
6742   mp->shg = (u8) shg;
6743   mp->bvi = bvi;
6744   mp->enable = enable;
6745
6746   S (mp);
6747   W (ret);
6748   return ret;
6749 }
6750
6751 static int
6752 api_bridge_domain_dump (vat_main_t * vam)
6753 {
6754   unformat_input_t *i = vam->input;
6755   vl_api_bridge_domain_dump_t *mp;
6756   vl_api_control_ping_t *mp_ping;
6757   u32 bd_id = ~0;
6758   int ret;
6759
6760   /* Parse args required to build the message */
6761   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6762     {
6763       if (unformat (i, "bd_id %d", &bd_id))
6764         ;
6765       else
6766         break;
6767     }
6768
6769   M (BRIDGE_DOMAIN_DUMP, mp);
6770   mp->bd_id = ntohl (bd_id);
6771   S (mp);
6772
6773   /* Use a control ping for synchronization */
6774   MPING (CONTROL_PING, mp_ping);
6775   S (mp_ping);
6776
6777   W (ret);
6778   return ret;
6779 }
6780
6781 static int
6782 api_bridge_domain_add_del (vat_main_t * vam)
6783 {
6784   unformat_input_t *i = vam->input;
6785   vl_api_bridge_domain_add_del_t *mp;
6786   u32 bd_id = ~0;
6787   u8 is_add = 1;
6788   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6789   u8 *bd_tag = NULL;
6790   u32 mac_age = 0;
6791   int ret;
6792
6793   /* Parse args required to build the message */
6794   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6795     {
6796       if (unformat (i, "bd_id %d", &bd_id))
6797         ;
6798       else if (unformat (i, "flood %d", &flood))
6799         ;
6800       else if (unformat (i, "uu-flood %d", &uu_flood))
6801         ;
6802       else if (unformat (i, "forward %d", &forward))
6803         ;
6804       else if (unformat (i, "learn %d", &learn))
6805         ;
6806       else if (unformat (i, "arp-term %d", &arp_term))
6807         ;
6808       else if (unformat (i, "mac-age %d", &mac_age))
6809         ;
6810       else if (unformat (i, "bd-tag %s", &bd_tag))
6811         ;
6812       else if (unformat (i, "del"))
6813         {
6814           is_add = 0;
6815           flood = uu_flood = forward = learn = 0;
6816         }
6817       else
6818         break;
6819     }
6820
6821   if (bd_id == ~0)
6822     {
6823       errmsg ("missing bridge domain");
6824       ret = -99;
6825       goto done;
6826     }
6827
6828   if (mac_age > 255)
6829     {
6830       errmsg ("mac age must be less than 256 ");
6831       ret = -99;
6832       goto done;
6833     }
6834
6835   if ((bd_tag) && (strlen ((char *) bd_tag) > 63))
6836     {
6837       errmsg ("bd-tag cannot be longer than 63");
6838       ret = -99;
6839       goto done;
6840     }
6841
6842   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6843
6844   mp->bd_id = ntohl (bd_id);
6845   mp->flood = flood;
6846   mp->uu_flood = uu_flood;
6847   mp->forward = forward;
6848   mp->learn = learn;
6849   mp->arp_term = arp_term;
6850   mp->is_add = is_add;
6851   mp->mac_age = (u8) mac_age;
6852   if (bd_tag)
6853     strcpy ((char *) mp->bd_tag, (char *) bd_tag);
6854
6855   S (mp);
6856   W (ret);
6857
6858 done:
6859   vec_free (bd_tag);
6860   return ret;
6861 }
6862
6863 static int
6864 api_l2fib_flush_bd (vat_main_t * vam)
6865 {
6866   unformat_input_t *i = vam->input;
6867   vl_api_l2fib_flush_bd_t *mp;
6868   u32 bd_id = ~0;
6869   int ret;
6870
6871   /* Parse args required to build the message */
6872   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6873     {
6874       if (unformat (i, "bd_id %d", &bd_id));
6875       else
6876         break;
6877     }
6878
6879   if (bd_id == ~0)
6880     {
6881       errmsg ("missing bridge domain");
6882       return -99;
6883     }
6884
6885   M (L2FIB_FLUSH_BD, mp);
6886
6887   mp->bd_id = htonl (bd_id);
6888
6889   S (mp);
6890   W (ret);
6891   return ret;
6892 }
6893
6894 static int
6895 api_l2fib_flush_int (vat_main_t * vam)
6896 {
6897   unformat_input_t *i = vam->input;
6898   vl_api_l2fib_flush_int_t *mp;
6899   u32 sw_if_index = ~0;
6900   int ret;
6901
6902   /* Parse args required to build the message */
6903   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6904     {
6905       if (unformat (i, "sw_if_index %d", &sw_if_index));
6906       else
6907         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6908       else
6909         break;
6910     }
6911
6912   if (sw_if_index == ~0)
6913     {
6914       errmsg ("missing interface name or sw_if_index");
6915       return -99;
6916     }
6917
6918   M (L2FIB_FLUSH_INT, mp);
6919
6920   mp->sw_if_index = ntohl (sw_if_index);
6921
6922   S (mp);
6923   W (ret);
6924   return ret;
6925 }
6926
6927 static int
6928 api_l2fib_add_del (vat_main_t * vam)
6929 {
6930   unformat_input_t *i = vam->input;
6931   vl_api_l2fib_add_del_t *mp;
6932   f64 timeout;
6933   u64 mac = 0;
6934   u8 mac_set = 0;
6935   u32 bd_id;
6936   u8 bd_id_set = 0;
6937   u32 sw_if_index = ~0;
6938   u8 sw_if_index_set = 0;
6939   u8 is_add = 1;
6940   u8 static_mac = 0;
6941   u8 filter_mac = 0;
6942   u8 bvi_mac = 0;
6943   int count = 1;
6944   f64 before = 0;
6945   int j;
6946
6947   /* Parse args required to build the message */
6948   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6949     {
6950       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
6951         mac_set = 1;
6952       else if (unformat (i, "bd_id %d", &bd_id))
6953         bd_id_set = 1;
6954       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6955         sw_if_index_set = 1;
6956       else if (unformat (i, "sw_if"))
6957         {
6958           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6959             {
6960               if (unformat
6961                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6962                 sw_if_index_set = 1;
6963             }
6964           else
6965             break;
6966         }
6967       else if (unformat (i, "static"))
6968         static_mac = 1;
6969       else if (unformat (i, "filter"))
6970         {
6971           filter_mac = 1;
6972           static_mac = 1;
6973         }
6974       else if (unformat (i, "bvi"))
6975         {
6976           bvi_mac = 1;
6977           static_mac = 1;
6978         }
6979       else if (unformat (i, "del"))
6980         is_add = 0;
6981       else if (unformat (i, "count %d", &count))
6982         ;
6983       else
6984         break;
6985     }
6986
6987   if (mac_set == 0)
6988     {
6989       errmsg ("missing mac address");
6990       return -99;
6991     }
6992
6993   if (bd_id_set == 0)
6994     {
6995       errmsg ("missing bridge domain");
6996       return -99;
6997     }
6998
6999   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7000     {
7001       errmsg ("missing interface name or sw_if_index");
7002       return -99;
7003     }
7004
7005   if (count > 1)
7006     {
7007       /* Turn on async mode */
7008       vam->async_mode = 1;
7009       vam->async_errors = 0;
7010       before = vat_time_now (vam);
7011     }
7012
7013   for (j = 0; j < count; j++)
7014     {
7015       M (L2FIB_ADD_DEL, mp);
7016
7017       mp->mac = mac;
7018       mp->bd_id = ntohl (bd_id);
7019       mp->is_add = is_add;
7020
7021       if (is_add)
7022         {
7023           mp->sw_if_index = ntohl (sw_if_index);
7024           mp->static_mac = static_mac;
7025           mp->filter_mac = filter_mac;
7026           mp->bvi_mac = bvi_mac;
7027         }
7028       increment_mac_address (&mac);
7029       /* send it... */
7030       S (mp);
7031     }
7032
7033   if (count > 1)
7034     {
7035       vl_api_control_ping_t *mp_ping;
7036       f64 after;
7037
7038       /* Shut off async mode */
7039       vam->async_mode = 0;
7040
7041       MPING (CONTROL_PING, mp_ping);
7042       S (mp_ping);
7043
7044       timeout = vat_time_now (vam) + 1.0;
7045       while (vat_time_now (vam) < timeout)
7046         if (vam->result_ready == 1)
7047           goto out;
7048       vam->retval = -99;
7049
7050     out:
7051       if (vam->retval == -99)
7052         errmsg ("timeout");
7053
7054       if (vam->async_errors > 0)
7055         {
7056           errmsg ("%d asynchronous errors", vam->async_errors);
7057           vam->retval = -98;
7058         }
7059       vam->async_errors = 0;
7060       after = vat_time_now (vam);
7061
7062       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7063              count, after - before, count / (after - before));
7064     }
7065   else
7066     {
7067       int ret;
7068
7069       /* Wait for a reply... */
7070       W (ret);
7071       return ret;
7072     }
7073   /* Return the good/bad news */
7074   return (vam->retval);
7075 }
7076
7077 static int
7078 api_bridge_domain_set_mac_age (vat_main_t * vam)
7079 {
7080   unformat_input_t *i = vam->input;
7081   vl_api_bridge_domain_set_mac_age_t *mp;
7082   u32 bd_id = ~0;
7083   u32 mac_age = 0;
7084   int ret;
7085
7086   /* Parse args required to build the message */
7087   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7088     {
7089       if (unformat (i, "bd_id %d", &bd_id));
7090       else if (unformat (i, "mac-age %d", &mac_age));
7091       else
7092         break;
7093     }
7094
7095   if (bd_id == ~0)
7096     {
7097       errmsg ("missing bridge domain");
7098       return -99;
7099     }
7100
7101   if (mac_age > 255)
7102     {
7103       errmsg ("mac age must be less than 256 ");
7104       return -99;
7105     }
7106
7107   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7108
7109   mp->bd_id = htonl (bd_id);
7110   mp->mac_age = (u8) mac_age;
7111
7112   S (mp);
7113   W (ret);
7114   return ret;
7115 }
7116
7117 static int
7118 api_l2_flags (vat_main_t * vam)
7119 {
7120   unformat_input_t *i = vam->input;
7121   vl_api_l2_flags_t *mp;
7122   u32 sw_if_index;
7123   u32 flags = 0;
7124   u8 sw_if_index_set = 0;
7125   u8 is_set = 0;
7126   int ret;
7127
7128   /* Parse args required to build the message */
7129   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7130     {
7131       if (unformat (i, "sw_if_index %d", &sw_if_index))
7132         sw_if_index_set = 1;
7133       else if (unformat (i, "sw_if"))
7134         {
7135           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7136             {
7137               if (unformat
7138                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7139                 sw_if_index_set = 1;
7140             }
7141           else
7142             break;
7143         }
7144       else if (unformat (i, "learn"))
7145         flags |= L2_LEARN;
7146       else if (unformat (i, "forward"))
7147         flags |= L2_FWD;
7148       else if (unformat (i, "flood"))
7149         flags |= L2_FLOOD;
7150       else if (unformat (i, "uu-flood"))
7151         flags |= L2_UU_FLOOD;
7152       else if (unformat (i, "arp-term"))
7153         flags |= L2_ARP_TERM;
7154       else if (unformat (i, "off"))
7155         is_set = 0;
7156       else if (unformat (i, "disable"))
7157         is_set = 0;
7158       else
7159         break;
7160     }
7161
7162   if (sw_if_index_set == 0)
7163     {
7164       errmsg ("missing interface name or sw_if_index");
7165       return -99;
7166     }
7167
7168   M (L2_FLAGS, mp);
7169
7170   mp->sw_if_index = ntohl (sw_if_index);
7171   mp->feature_bitmap = ntohl (flags);
7172   mp->is_set = is_set;
7173
7174   S (mp);
7175   W (ret);
7176   return ret;
7177 }
7178
7179 static int
7180 api_bridge_flags (vat_main_t * vam)
7181 {
7182   unformat_input_t *i = vam->input;
7183   vl_api_bridge_flags_t *mp;
7184   u32 bd_id;
7185   u8 bd_id_set = 0;
7186   u8 is_set = 1;
7187   u32 flags = 0;
7188   int ret;
7189
7190   /* Parse args required to build the message */
7191   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7192     {
7193       if (unformat (i, "bd_id %d", &bd_id))
7194         bd_id_set = 1;
7195       else if (unformat (i, "learn"))
7196         flags |= L2_LEARN;
7197       else if (unformat (i, "forward"))
7198         flags |= L2_FWD;
7199       else if (unformat (i, "flood"))
7200         flags |= L2_FLOOD;
7201       else if (unformat (i, "uu-flood"))
7202         flags |= L2_UU_FLOOD;
7203       else if (unformat (i, "arp-term"))
7204         flags |= L2_ARP_TERM;
7205       else if (unformat (i, "off"))
7206         is_set = 0;
7207       else if (unformat (i, "disable"))
7208         is_set = 0;
7209       else
7210         break;
7211     }
7212
7213   if (bd_id_set == 0)
7214     {
7215       errmsg ("missing bridge domain");
7216       return -99;
7217     }
7218
7219   M (BRIDGE_FLAGS, mp);
7220
7221   mp->bd_id = ntohl (bd_id);
7222   mp->feature_bitmap = ntohl (flags);
7223   mp->is_set = is_set;
7224
7225   S (mp);
7226   W (ret);
7227   return ret;
7228 }
7229
7230 static int
7231 api_bd_ip_mac_add_del (vat_main_t * vam)
7232 {
7233   unformat_input_t *i = vam->input;
7234   vl_api_bd_ip_mac_add_del_t *mp;
7235   u32 bd_id;
7236   u8 is_ipv6 = 0;
7237   u8 is_add = 1;
7238   u8 bd_id_set = 0;
7239   u8 ip_set = 0;
7240   u8 mac_set = 0;
7241   ip4_address_t v4addr;
7242   ip6_address_t v6addr;
7243   u8 macaddr[6];
7244   int ret;
7245
7246
7247   /* Parse args required to build the message */
7248   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7249     {
7250       if (unformat (i, "bd_id %d", &bd_id))
7251         {
7252           bd_id_set++;
7253         }
7254       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7255         {
7256           ip_set++;
7257         }
7258       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7259         {
7260           ip_set++;
7261           is_ipv6++;
7262         }
7263       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7264         {
7265           mac_set++;
7266         }
7267       else if (unformat (i, "del"))
7268         is_add = 0;
7269       else
7270         break;
7271     }
7272
7273   if (bd_id_set == 0)
7274     {
7275       errmsg ("missing bridge domain");
7276       return -99;
7277     }
7278   else if (ip_set == 0)
7279     {
7280       errmsg ("missing IP address");
7281       return -99;
7282     }
7283   else if (mac_set == 0)
7284     {
7285       errmsg ("missing MAC address");
7286       return -99;
7287     }
7288
7289   M (BD_IP_MAC_ADD_DEL, mp);
7290
7291   mp->bd_id = ntohl (bd_id);
7292   mp->is_ipv6 = is_ipv6;
7293   mp->is_add = is_add;
7294   if (is_ipv6)
7295     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7296   else
7297     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7298   clib_memcpy (mp->mac_address, macaddr, 6);
7299   S (mp);
7300   W (ret);
7301   return ret;
7302 }
7303
7304 static int
7305 api_tap_connect (vat_main_t * vam)
7306 {
7307   unformat_input_t *i = vam->input;
7308   vl_api_tap_connect_t *mp;
7309   u8 mac_address[6];
7310   u8 random_mac = 1;
7311   u8 name_set = 0;
7312   u8 *tap_name;
7313   u8 *tag = 0;
7314   ip4_address_t ip4_address;
7315   u32 ip4_mask_width;
7316   int ip4_address_set = 0;
7317   ip6_address_t ip6_address;
7318   u32 ip6_mask_width;
7319   int ip6_address_set = 0;
7320   int ret;
7321
7322   memset (mac_address, 0, sizeof (mac_address));
7323
7324   /* Parse args required to build the message */
7325   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7326     {
7327       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7328         {
7329           random_mac = 0;
7330         }
7331       else if (unformat (i, "random-mac"))
7332         random_mac = 1;
7333       else if (unformat (i, "tapname %s", &tap_name))
7334         name_set = 1;
7335       else if (unformat (i, "tag %s", &tag))
7336         ;
7337       else if (unformat (i, "address %U/%d",
7338                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7339         ip4_address_set = 1;
7340       else if (unformat (i, "address %U/%d",
7341                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7342         ip6_address_set = 1;
7343       else
7344         break;
7345     }
7346
7347   if (name_set == 0)
7348     {
7349       errmsg ("missing tap name");
7350       return -99;
7351     }
7352   if (vec_len (tap_name) > 63)
7353     {
7354       errmsg ("tap name too long");
7355       return -99;
7356     }
7357   vec_add1 (tap_name, 0);
7358
7359   if (vec_len (tag) > 63)
7360     {
7361       errmsg ("tag too long");
7362       return -99;
7363     }
7364
7365   /* Construct the API message */
7366   M (TAP_CONNECT, mp);
7367
7368   mp->use_random_mac = random_mac;
7369   clib_memcpy (mp->mac_address, mac_address, 6);
7370   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7371   if (tag)
7372     clib_memcpy (mp->tag, tag, vec_len (tag));
7373
7374   if (ip4_address_set)
7375     {
7376       mp->ip4_address_set = 1;
7377       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7378       mp->ip4_mask_width = ip4_mask_width;
7379     }
7380   if (ip6_address_set)
7381     {
7382       mp->ip6_address_set = 1;
7383       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7384       mp->ip6_mask_width = ip6_mask_width;
7385     }
7386
7387   vec_free (tap_name);
7388   vec_free (tag);
7389
7390   /* send it... */
7391   S (mp);
7392
7393   /* Wait for a reply... */
7394   W (ret);
7395   return ret;
7396 }
7397
7398 static int
7399 api_tap_modify (vat_main_t * vam)
7400 {
7401   unformat_input_t *i = vam->input;
7402   vl_api_tap_modify_t *mp;
7403   u8 mac_address[6];
7404   u8 random_mac = 1;
7405   u8 name_set = 0;
7406   u8 *tap_name;
7407   u32 sw_if_index = ~0;
7408   u8 sw_if_index_set = 0;
7409   int ret;
7410
7411   memset (mac_address, 0, sizeof (mac_address));
7412
7413   /* Parse args required to build the message */
7414   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7415     {
7416       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7417         sw_if_index_set = 1;
7418       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7419         sw_if_index_set = 1;
7420       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7421         {
7422           random_mac = 0;
7423         }
7424       else if (unformat (i, "random-mac"))
7425         random_mac = 1;
7426       else if (unformat (i, "tapname %s", &tap_name))
7427         name_set = 1;
7428       else
7429         break;
7430     }
7431
7432   if (sw_if_index_set == 0)
7433     {
7434       errmsg ("missing vpp interface name");
7435       return -99;
7436     }
7437   if (name_set == 0)
7438     {
7439       errmsg ("missing tap name");
7440       return -99;
7441     }
7442   if (vec_len (tap_name) > 63)
7443     {
7444       errmsg ("tap name too long");
7445     }
7446   vec_add1 (tap_name, 0);
7447
7448   /* Construct the API message */
7449   M (TAP_MODIFY, mp);
7450
7451   mp->use_random_mac = random_mac;
7452   mp->sw_if_index = ntohl (sw_if_index);
7453   clib_memcpy (mp->mac_address, mac_address, 6);
7454   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7455   vec_free (tap_name);
7456
7457   /* send it... */
7458   S (mp);
7459
7460   /* Wait for a reply... */
7461   W (ret);
7462   return ret;
7463 }
7464
7465 static int
7466 api_tap_delete (vat_main_t * vam)
7467 {
7468   unformat_input_t *i = vam->input;
7469   vl_api_tap_delete_t *mp;
7470   u32 sw_if_index = ~0;
7471   u8 sw_if_index_set = 0;
7472   int ret;
7473
7474   /* Parse args required to build the message */
7475   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7476     {
7477       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7478         sw_if_index_set = 1;
7479       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7480         sw_if_index_set = 1;
7481       else
7482         break;
7483     }
7484
7485   if (sw_if_index_set == 0)
7486     {
7487       errmsg ("missing vpp interface name");
7488       return -99;
7489     }
7490
7491   /* Construct the API message */
7492   M (TAP_DELETE, mp);
7493
7494   mp->sw_if_index = ntohl (sw_if_index);
7495
7496   /* send it... */
7497   S (mp);
7498
7499   /* Wait for a reply... */
7500   W (ret);
7501   return ret;
7502 }
7503
7504 static int
7505 api_ip_table_add_del (vat_main_t * vam)
7506 {
7507   unformat_input_t *i = vam->input;
7508   vl_api_ip_table_add_del_t *mp;
7509   u32 table_id = ~0;
7510   u8 is_ipv6 = 0;
7511   u8 is_add = 1;
7512   int ret = 0;
7513
7514   /* Parse args required to build the message */
7515   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7516     {
7517       if (unformat (i, "ipv6"))
7518         is_ipv6 = 1;
7519       else if (unformat (i, "del"))
7520         is_add = 0;
7521       else if (unformat (i, "add"))
7522         is_add = 1;
7523       else if (unformat (i, "table %d", &table_id))
7524         ;
7525       else
7526         {
7527           clib_warning ("parse error '%U'", format_unformat_error, i);
7528           return -99;
7529         }
7530     }
7531
7532   if (~0 == table_id)
7533     {
7534       errmsg ("missing table-ID");
7535       return -99;
7536     }
7537
7538   /* Construct the API message */
7539   M (IP_TABLE_ADD_DEL, mp);
7540
7541   mp->table_id = ntohl (table_id);
7542   mp->is_ipv6 = is_ipv6;
7543   mp->is_add = is_add;
7544
7545   /* send it... */
7546   S (mp);
7547
7548   /* Wait for a reply... */
7549   W (ret);
7550
7551   return ret;
7552 }
7553
7554 static int
7555 api_ip_add_del_route (vat_main_t * vam)
7556 {
7557   unformat_input_t *i = vam->input;
7558   vl_api_ip_add_del_route_t *mp;
7559   u32 sw_if_index = ~0, vrf_id = 0;
7560   u8 is_ipv6 = 0;
7561   u8 is_local = 0, is_drop = 0;
7562   u8 is_unreach = 0, is_prohibit = 0;
7563   u8 is_add = 1;
7564   u32 next_hop_weight = 1;
7565   u8 not_last = 0;
7566   u8 is_multipath = 0;
7567   u8 address_set = 0;
7568   u8 address_length_set = 0;
7569   u32 next_hop_table_id = 0;
7570   u32 resolve_attempts = 0;
7571   u32 dst_address_length = 0;
7572   u8 next_hop_set = 0;
7573   ip4_address_t v4_dst_address, v4_next_hop_address;
7574   ip6_address_t v6_dst_address, v6_next_hop_address;
7575   int count = 1;
7576   int j;
7577   f64 before = 0;
7578   u32 random_add_del = 0;
7579   u32 *random_vector = 0;
7580   uword *random_hash;
7581   u32 random_seed = 0xdeaddabe;
7582   u32 classify_table_index = ~0;
7583   u8 is_classify = 0;
7584   u8 resolve_host = 0, resolve_attached = 0;
7585   mpls_label_t *next_hop_out_label_stack = NULL;
7586   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7587   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7588
7589   /* Parse args required to build the message */
7590   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7591     {
7592       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7593         ;
7594       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7595         ;
7596       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
7597         {
7598           address_set = 1;
7599           is_ipv6 = 0;
7600         }
7601       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
7602         {
7603           address_set = 1;
7604           is_ipv6 = 1;
7605         }
7606       else if (unformat (i, "/%d", &dst_address_length))
7607         {
7608           address_length_set = 1;
7609         }
7610
7611       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
7612                                          &v4_next_hop_address))
7613         {
7614           next_hop_set = 1;
7615         }
7616       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
7617                                          &v6_next_hop_address))
7618         {
7619           next_hop_set = 1;
7620         }
7621       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
7622         ;
7623       else if (unformat (i, "weight %d", &next_hop_weight))
7624         ;
7625       else if (unformat (i, "drop"))
7626         {
7627           is_drop = 1;
7628         }
7629       else if (unformat (i, "null-send-unreach"))
7630         {
7631           is_unreach = 1;
7632         }
7633       else if (unformat (i, "null-send-prohibit"))
7634         {
7635           is_prohibit = 1;
7636         }
7637       else if (unformat (i, "local"))
7638         {
7639           is_local = 1;
7640         }
7641       else if (unformat (i, "classify %d", &classify_table_index))
7642         {
7643           is_classify = 1;
7644         }
7645       else if (unformat (i, "del"))
7646         is_add = 0;
7647       else if (unformat (i, "add"))
7648         is_add = 1;
7649       else if (unformat (i, "not-last"))
7650         not_last = 1;
7651       else if (unformat (i, "resolve-via-host"))
7652         resolve_host = 1;
7653       else if (unformat (i, "resolve-via-attached"))
7654         resolve_attached = 1;
7655       else if (unformat (i, "multipath"))
7656         is_multipath = 1;
7657       else if (unformat (i, "vrf %d", &vrf_id))
7658         ;
7659       else if (unformat (i, "count %d", &count))
7660         ;
7661       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
7662         ;
7663       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7664         ;
7665       else if (unformat (i, "out-label %d", &next_hop_out_label))
7666         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7667       else if (unformat (i, "via-label %d", &next_hop_via_label))
7668         ;
7669       else if (unformat (i, "random"))
7670         random_add_del = 1;
7671       else if (unformat (i, "seed %d", &random_seed))
7672         ;
7673       else
7674         {
7675           clib_warning ("parse error '%U'", format_unformat_error, i);
7676           return -99;
7677         }
7678     }
7679
7680   if (!next_hop_set && !is_drop && !is_local &&
7681       !is_classify && !is_unreach && !is_prohibit &&
7682       MPLS_LABEL_INVALID == next_hop_via_label)
7683     {
7684       errmsg
7685         ("next hop / local / drop / unreach / prohibit / classify not set");
7686       return -99;
7687     }
7688
7689   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
7690     {
7691       errmsg ("next hop and next-hop via label set");
7692       return -99;
7693     }
7694   if (address_set == 0)
7695     {
7696       errmsg ("missing addresses");
7697       return -99;
7698     }
7699
7700   if (address_length_set == 0)
7701     {
7702       errmsg ("missing address length");
7703       return -99;
7704     }
7705
7706   /* Generate a pile of unique, random routes */
7707   if (random_add_del)
7708     {
7709       u32 this_random_address;
7710       random_hash = hash_create (count, sizeof (uword));
7711
7712       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
7713       for (j = 0; j <= count; j++)
7714         {
7715           do
7716             {
7717               this_random_address = random_u32 (&random_seed);
7718               this_random_address =
7719                 clib_host_to_net_u32 (this_random_address);
7720             }
7721           while (hash_get (random_hash, this_random_address));
7722           vec_add1 (random_vector, this_random_address);
7723           hash_set (random_hash, this_random_address, 1);
7724         }
7725       hash_free (random_hash);
7726       v4_dst_address.as_u32 = random_vector[0];
7727     }
7728
7729   if (count > 1)
7730     {
7731       /* Turn on async mode */
7732       vam->async_mode = 1;
7733       vam->async_errors = 0;
7734       before = vat_time_now (vam);
7735     }
7736
7737   for (j = 0; j < count; j++)
7738     {
7739       /* Construct the API message */
7740       M2 (IP_ADD_DEL_ROUTE, mp,
7741           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7742
7743       mp->next_hop_sw_if_index = ntohl (sw_if_index);
7744       mp->table_id = ntohl (vrf_id);
7745
7746       mp->is_add = is_add;
7747       mp->is_drop = is_drop;
7748       mp->is_unreach = is_unreach;
7749       mp->is_prohibit = is_prohibit;
7750       mp->is_ipv6 = is_ipv6;
7751       mp->is_local = is_local;
7752       mp->is_classify = is_classify;
7753       mp->is_multipath = is_multipath;
7754       mp->is_resolve_host = resolve_host;
7755       mp->is_resolve_attached = resolve_attached;
7756       mp->not_last = not_last;
7757       mp->next_hop_weight = next_hop_weight;
7758       mp->dst_address_length = dst_address_length;
7759       mp->next_hop_table_id = ntohl (next_hop_table_id);
7760       mp->classify_table_index = ntohl (classify_table_index);
7761       mp->next_hop_via_label = ntohl (next_hop_via_label);
7762       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7763       if (0 != mp->next_hop_n_out_labels)
7764         {
7765           memcpy (mp->next_hop_out_label_stack,
7766                   next_hop_out_label_stack,
7767                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7768           vec_free (next_hop_out_label_stack);
7769         }
7770
7771       if (is_ipv6)
7772         {
7773           clib_memcpy (mp->dst_address, &v6_dst_address,
7774                        sizeof (v6_dst_address));
7775           if (next_hop_set)
7776             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
7777                          sizeof (v6_next_hop_address));
7778           increment_v6_address (&v6_dst_address);
7779         }
7780       else
7781         {
7782           clib_memcpy (mp->dst_address, &v4_dst_address,
7783                        sizeof (v4_dst_address));
7784           if (next_hop_set)
7785             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
7786                          sizeof (v4_next_hop_address));
7787           if (random_add_del)
7788             v4_dst_address.as_u32 = random_vector[j + 1];
7789           else
7790             increment_v4_address (&v4_dst_address);
7791         }
7792       /* send it... */
7793       S (mp);
7794       /* If we receive SIGTERM, stop now... */
7795       if (vam->do_exit)
7796         break;
7797     }
7798
7799   /* When testing multiple add/del ops, use a control-ping to sync */
7800   if (count > 1)
7801     {
7802       vl_api_control_ping_t *mp_ping;
7803       f64 after;
7804       f64 timeout;
7805
7806       /* Shut off async mode */
7807       vam->async_mode = 0;
7808
7809       MPING (CONTROL_PING, mp_ping);
7810       S (mp_ping);
7811
7812       timeout = vat_time_now (vam) + 1.0;
7813       while (vat_time_now (vam) < timeout)
7814         if (vam->result_ready == 1)
7815           goto out;
7816       vam->retval = -99;
7817
7818     out:
7819       if (vam->retval == -99)
7820         errmsg ("timeout");
7821
7822       if (vam->async_errors > 0)
7823         {
7824           errmsg ("%d asynchronous errors", vam->async_errors);
7825           vam->retval = -98;
7826         }
7827       vam->async_errors = 0;
7828       after = vat_time_now (vam);
7829
7830       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7831       if (j > 0)
7832         count = j;
7833
7834       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7835              count, after - before, count / (after - before));
7836     }
7837   else
7838     {
7839       int ret;
7840
7841       /* Wait for a reply... */
7842       W (ret);
7843       return ret;
7844     }
7845
7846   /* Return the good/bad news */
7847   return (vam->retval);
7848 }
7849
7850 static int
7851 api_ip_mroute_add_del (vat_main_t * vam)
7852 {
7853   unformat_input_t *i = vam->input;
7854   vl_api_ip_mroute_add_del_t *mp;
7855   u32 sw_if_index = ~0, vrf_id = 0;
7856   u8 is_ipv6 = 0;
7857   u8 is_local = 0;
7858   u8 is_add = 1;
7859   u8 address_set = 0;
7860   u32 grp_address_length = 0;
7861   ip4_address_t v4_grp_address, v4_src_address;
7862   ip6_address_t v6_grp_address, v6_src_address;
7863   mfib_itf_flags_t iflags = 0;
7864   mfib_entry_flags_t eflags = 0;
7865   int ret;
7866
7867   /* Parse args required to build the message */
7868   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7869     {
7870       if (unformat (i, "sw_if_index %d", &sw_if_index))
7871         ;
7872       else if (unformat (i, "%U %U",
7873                          unformat_ip4_address, &v4_src_address,
7874                          unformat_ip4_address, &v4_grp_address))
7875         {
7876           grp_address_length = 64;
7877           address_set = 1;
7878           is_ipv6 = 0;
7879         }
7880       else if (unformat (i, "%U %U",
7881                          unformat_ip6_address, &v6_src_address,
7882                          unformat_ip6_address, &v6_grp_address))
7883         {
7884           grp_address_length = 256;
7885           address_set = 1;
7886           is_ipv6 = 1;
7887         }
7888       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
7889         {
7890           memset (&v4_src_address, 0, sizeof (v4_src_address));
7891           grp_address_length = 32;
7892           address_set = 1;
7893           is_ipv6 = 0;
7894         }
7895       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
7896         {
7897           memset (&v6_src_address, 0, sizeof (v6_src_address));
7898           grp_address_length = 128;
7899           address_set = 1;
7900           is_ipv6 = 1;
7901         }
7902       else if (unformat (i, "/%d", &grp_address_length))
7903         ;
7904       else if (unformat (i, "local"))
7905         {
7906           is_local = 1;
7907         }
7908       else if (unformat (i, "del"))
7909         is_add = 0;
7910       else if (unformat (i, "add"))
7911         is_add = 1;
7912       else if (unformat (i, "vrf %d", &vrf_id))
7913         ;
7914       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
7915         ;
7916       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
7917         ;
7918       else
7919         {
7920           clib_warning ("parse error '%U'", format_unformat_error, i);
7921           return -99;
7922         }
7923     }
7924
7925   if (address_set == 0)
7926     {
7927       errmsg ("missing addresses\n");
7928       return -99;
7929     }
7930
7931   /* Construct the API message */
7932   M (IP_MROUTE_ADD_DEL, mp);
7933
7934   mp->next_hop_sw_if_index = ntohl (sw_if_index);
7935   mp->table_id = ntohl (vrf_id);
7936
7937   mp->is_add = is_add;
7938   mp->is_ipv6 = is_ipv6;
7939   mp->is_local = is_local;
7940   mp->itf_flags = ntohl (iflags);
7941   mp->entry_flags = ntohl (eflags);
7942   mp->grp_address_length = grp_address_length;
7943   mp->grp_address_length = ntohs (mp->grp_address_length);
7944
7945   if (is_ipv6)
7946     {
7947       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
7948       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
7949     }
7950   else
7951     {
7952       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
7953       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
7954
7955     }
7956
7957   /* send it... */
7958   S (mp);
7959   /* Wait for a reply... */
7960   W (ret);
7961   return ret;
7962 }
7963
7964 static int
7965 api_mpls_table_add_del (vat_main_t * vam)
7966 {
7967   unformat_input_t *i = vam->input;
7968   vl_api_mpls_table_add_del_t *mp;
7969   u32 table_id = ~0;
7970   u8 is_add = 1;
7971   int ret = 0;
7972
7973   /* Parse args required to build the message */
7974   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7975     {
7976       if (unformat (i, "del"))
7977         is_add = 0;
7978       else if (unformat (i, "add"))
7979         is_add = 1;
7980       else if (unformat (i, "table-id %d", &table_id))
7981         ;
7982       else
7983         {
7984           clib_warning ("parse error '%U'", format_unformat_error, i);
7985           return -99;
7986         }
7987     }
7988
7989   if (~0 == table_id)
7990     {
7991       errmsg ("missing table-ID");
7992       return -99;
7993     }
7994
7995   /* Construct the API message */
7996   M (MPLS_TABLE_ADD_DEL, mp);
7997
7998   mp->mt_table_id = ntohl (table_id);
7999   mp->mt_is_add = is_add;
8000
8001   /* send it... */
8002   S (mp);
8003
8004   /* Wait for a reply... */
8005   W (ret);
8006
8007   return ret;
8008 }
8009
8010 static int
8011 api_mpls_route_add_del (vat_main_t * vam)
8012 {
8013   unformat_input_t *i = vam->input;
8014   vl_api_mpls_route_add_del_t *mp;
8015   u32 sw_if_index = ~0, table_id = 0;
8016   u8 is_add = 1;
8017   u32 next_hop_weight = 1;
8018   u8 is_multipath = 0;
8019   u32 next_hop_table_id = 0;
8020   u8 next_hop_set = 0;
8021   ip4_address_t v4_next_hop_address = {
8022     .as_u32 = 0,
8023   };
8024   ip6_address_t v6_next_hop_address = { {0} };
8025   int count = 1;
8026   int j;
8027   f64 before = 0;
8028   u32 classify_table_index = ~0;
8029   u8 is_classify = 0;
8030   u8 resolve_host = 0, resolve_attached = 0;
8031   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8032   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8033   mpls_label_t *next_hop_out_label_stack = NULL;
8034   mpls_label_t local_label = MPLS_LABEL_INVALID;
8035   u8 is_eos = 0;
8036   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8037
8038   /* Parse args required to build the message */
8039   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8040     {
8041       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8042         ;
8043       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8044         ;
8045       else if (unformat (i, "%d", &local_label))
8046         ;
8047       else if (unformat (i, "eos"))
8048         is_eos = 1;
8049       else if (unformat (i, "non-eos"))
8050         is_eos = 0;
8051       else if (unformat (i, "via %U", unformat_ip4_address,
8052                          &v4_next_hop_address))
8053         {
8054           next_hop_set = 1;
8055           next_hop_proto = DPO_PROTO_IP4;
8056         }
8057       else if (unformat (i, "via %U", unformat_ip6_address,
8058                          &v6_next_hop_address))
8059         {
8060           next_hop_set = 1;
8061           next_hop_proto = DPO_PROTO_IP6;
8062         }
8063       else if (unformat (i, "weight %d", &next_hop_weight))
8064         ;
8065       else if (unformat (i, "classify %d", &classify_table_index))
8066         {
8067           is_classify = 1;
8068         }
8069       else if (unformat (i, "del"))
8070         is_add = 0;
8071       else if (unformat (i, "add"))
8072         is_add = 1;
8073       else if (unformat (i, "resolve-via-host"))
8074         resolve_host = 1;
8075       else if (unformat (i, "resolve-via-attached"))
8076         resolve_attached = 1;
8077       else if (unformat (i, "multipath"))
8078         is_multipath = 1;
8079       else if (unformat (i, "count %d", &count))
8080         ;
8081       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8082         {
8083           next_hop_set = 1;
8084           next_hop_proto = DPO_PROTO_IP4;
8085         }
8086       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8087         {
8088           next_hop_set = 1;
8089           next_hop_proto = DPO_PROTO_IP6;
8090         }
8091       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8092         ;
8093       else if (unformat (i, "via-label %d", &next_hop_via_label))
8094         ;
8095       else if (unformat (i, "out-label %d", &next_hop_out_label))
8096         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8097       else
8098         {
8099           clib_warning ("parse error '%U'", format_unformat_error, i);
8100           return -99;
8101         }
8102     }
8103
8104   if (!next_hop_set && !is_classify)
8105     {
8106       errmsg ("next hop / classify not set");
8107       return -99;
8108     }
8109
8110   if (MPLS_LABEL_INVALID == local_label)
8111     {
8112       errmsg ("missing label");
8113       return -99;
8114     }
8115
8116   if (count > 1)
8117     {
8118       /* Turn on async mode */
8119       vam->async_mode = 1;
8120       vam->async_errors = 0;
8121       before = vat_time_now (vam);
8122     }
8123
8124   for (j = 0; j < count; j++)
8125     {
8126       /* Construct the API message */
8127       M2 (MPLS_ROUTE_ADD_DEL, mp,
8128           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8129
8130       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8131       mp->mr_table_id = ntohl (table_id);
8132
8133       mp->mr_is_add = is_add;
8134       mp->mr_next_hop_proto = next_hop_proto;
8135       mp->mr_is_classify = is_classify;
8136       mp->mr_is_multipath = is_multipath;
8137       mp->mr_is_resolve_host = resolve_host;
8138       mp->mr_is_resolve_attached = resolve_attached;
8139       mp->mr_next_hop_weight = next_hop_weight;
8140       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8141       mp->mr_classify_table_index = ntohl (classify_table_index);
8142       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8143       mp->mr_label = ntohl (local_label);
8144       mp->mr_eos = is_eos;
8145
8146       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8147       if (0 != mp->mr_next_hop_n_out_labels)
8148         {
8149           memcpy (mp->mr_next_hop_out_label_stack,
8150                   next_hop_out_label_stack,
8151                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8152           vec_free (next_hop_out_label_stack);
8153         }
8154
8155       if (next_hop_set)
8156         {
8157           if (DPO_PROTO_IP4 == next_hop_proto)
8158             {
8159               clib_memcpy (mp->mr_next_hop,
8160                            &v4_next_hop_address,
8161                            sizeof (v4_next_hop_address));
8162             }
8163           else if (DPO_PROTO_IP6 == next_hop_proto)
8164
8165             {
8166               clib_memcpy (mp->mr_next_hop,
8167                            &v6_next_hop_address,
8168                            sizeof (v6_next_hop_address));
8169             }
8170         }
8171       local_label++;
8172
8173       /* send it... */
8174       S (mp);
8175       /* If we receive SIGTERM, stop now... */
8176       if (vam->do_exit)
8177         break;
8178     }
8179
8180   /* When testing multiple add/del ops, use a control-ping to sync */
8181   if (count > 1)
8182     {
8183       vl_api_control_ping_t *mp_ping;
8184       f64 after;
8185       f64 timeout;
8186
8187       /* Shut off async mode */
8188       vam->async_mode = 0;
8189
8190       MPING (CONTROL_PING, mp_ping);
8191       S (mp_ping);
8192
8193       timeout = vat_time_now (vam) + 1.0;
8194       while (vat_time_now (vam) < timeout)
8195         if (vam->result_ready == 1)
8196           goto out;
8197       vam->retval = -99;
8198
8199     out:
8200       if (vam->retval == -99)
8201         errmsg ("timeout");
8202
8203       if (vam->async_errors > 0)
8204         {
8205           errmsg ("%d asynchronous errors", vam->async_errors);
8206           vam->retval = -98;
8207         }
8208       vam->async_errors = 0;
8209       after = vat_time_now (vam);
8210
8211       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8212       if (j > 0)
8213         count = j;
8214
8215       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8216              count, after - before, count / (after - before));
8217     }
8218   else
8219     {
8220       int ret;
8221
8222       /* Wait for a reply... */
8223       W (ret);
8224       return ret;
8225     }
8226
8227   /* Return the good/bad news */
8228   return (vam->retval);
8229 }
8230
8231 static int
8232 api_mpls_ip_bind_unbind (vat_main_t * vam)
8233 {
8234   unformat_input_t *i = vam->input;
8235   vl_api_mpls_ip_bind_unbind_t *mp;
8236   u32 ip_table_id = 0;
8237   u8 is_bind = 1;
8238   u8 is_ip4 = 1;
8239   ip4_address_t v4_address;
8240   ip6_address_t v6_address;
8241   u32 address_length;
8242   u8 address_set = 0;
8243   mpls_label_t local_label = MPLS_LABEL_INVALID;
8244   int ret;
8245
8246   /* Parse args required to build the message */
8247   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8248     {
8249       if (unformat (i, "%U/%d", unformat_ip4_address,
8250                     &v4_address, &address_length))
8251         {
8252           is_ip4 = 1;
8253           address_set = 1;
8254         }
8255       else if (unformat (i, "%U/%d", unformat_ip6_address,
8256                          &v6_address, &address_length))
8257         {
8258           is_ip4 = 0;
8259           address_set = 1;
8260         }
8261       else if (unformat (i, "%d", &local_label))
8262         ;
8263       else if (unformat (i, "table-id %d", &ip_table_id))
8264         ;
8265       else if (unformat (i, "unbind"))
8266         is_bind = 0;
8267       else if (unformat (i, "bind"))
8268         is_bind = 1;
8269       else
8270         {
8271           clib_warning ("parse error '%U'", format_unformat_error, i);
8272           return -99;
8273         }
8274     }
8275
8276   if (!address_set)
8277     {
8278       errmsg ("IP addres not set");
8279       return -99;
8280     }
8281
8282   if (MPLS_LABEL_INVALID == local_label)
8283     {
8284       errmsg ("missing label");
8285       return -99;
8286     }
8287
8288   /* Construct the API message */
8289   M (MPLS_IP_BIND_UNBIND, mp);
8290
8291   mp->mb_is_bind = is_bind;
8292   mp->mb_is_ip4 = is_ip4;
8293   mp->mb_ip_table_id = ntohl (ip_table_id);
8294   mp->mb_mpls_table_id = 0;
8295   mp->mb_label = ntohl (local_label);
8296   mp->mb_address_length = address_length;
8297
8298   if (is_ip4)
8299     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8300   else
8301     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8302
8303   /* send it... */
8304   S (mp);
8305
8306   /* Wait for a reply... */
8307   W (ret);
8308   return ret;
8309 }
8310
8311 static int
8312 api_proxy_arp_add_del (vat_main_t * vam)
8313 {
8314   unformat_input_t *i = vam->input;
8315   vl_api_proxy_arp_add_del_t *mp;
8316   u32 vrf_id = 0;
8317   u8 is_add = 1;
8318   ip4_address_t lo, hi;
8319   u8 range_set = 0;
8320   int ret;
8321
8322   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8323     {
8324       if (unformat (i, "vrf %d", &vrf_id))
8325         ;
8326       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
8327                          unformat_ip4_address, &hi))
8328         range_set = 1;
8329       else if (unformat (i, "del"))
8330         is_add = 0;
8331       else
8332         {
8333           clib_warning ("parse error '%U'", format_unformat_error, i);
8334           return -99;
8335         }
8336     }
8337
8338   if (range_set == 0)
8339     {
8340       errmsg ("address range not set");
8341       return -99;
8342     }
8343
8344   M (PROXY_ARP_ADD_DEL, mp);
8345
8346   mp->vrf_id = ntohl (vrf_id);
8347   mp->is_add = is_add;
8348   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
8349   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
8350
8351   S (mp);
8352   W (ret);
8353   return ret;
8354 }
8355
8356 static int
8357 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8358 {
8359   unformat_input_t *i = vam->input;
8360   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8361   u32 sw_if_index;
8362   u8 enable = 1;
8363   u8 sw_if_index_set = 0;
8364   int ret;
8365
8366   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8367     {
8368       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8369         sw_if_index_set = 1;
8370       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8371         sw_if_index_set = 1;
8372       else if (unformat (i, "enable"))
8373         enable = 1;
8374       else if (unformat (i, "disable"))
8375         enable = 0;
8376       else
8377         {
8378           clib_warning ("parse error '%U'", format_unformat_error, i);
8379           return -99;
8380         }
8381     }
8382
8383   if (sw_if_index_set == 0)
8384     {
8385       errmsg ("missing interface name or sw_if_index");
8386       return -99;
8387     }
8388
8389   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8390
8391   mp->sw_if_index = ntohl (sw_if_index);
8392   mp->enable_disable = enable;
8393
8394   S (mp);
8395   W (ret);
8396   return ret;
8397 }
8398
8399 static int
8400 api_mpls_tunnel_add_del (vat_main_t * vam)
8401 {
8402   unformat_input_t *i = vam->input;
8403   vl_api_mpls_tunnel_add_del_t *mp;
8404
8405   u8 is_add = 1;
8406   u8 l2_only = 0;
8407   u32 sw_if_index = ~0;
8408   u32 next_hop_sw_if_index = ~0;
8409   u32 next_hop_proto_is_ip4 = 1;
8410
8411   u32 next_hop_table_id = 0;
8412   ip4_address_t v4_next_hop_address = {
8413     .as_u32 = 0,
8414   };
8415   ip6_address_t v6_next_hop_address = { {0} };
8416   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
8417   int ret;
8418
8419   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8420     {
8421       if (unformat (i, "add"))
8422         is_add = 1;
8423       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8424         is_add = 0;
8425       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
8426         ;
8427       else if (unformat (i, "via %U",
8428                          unformat_ip4_address, &v4_next_hop_address))
8429         {
8430           next_hop_proto_is_ip4 = 1;
8431         }
8432       else if (unformat (i, "via %U",
8433                          unformat_ip6_address, &v6_next_hop_address))
8434         {
8435           next_hop_proto_is_ip4 = 0;
8436         }
8437       else if (unformat (i, "l2-only"))
8438         l2_only = 1;
8439       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8440         ;
8441       else if (unformat (i, "out-label %d", &next_hop_out_label))
8442         vec_add1 (labels, ntohl (next_hop_out_label));
8443       else
8444         {
8445           clib_warning ("parse error '%U'", format_unformat_error, i);
8446           return -99;
8447         }
8448     }
8449
8450   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
8451
8452   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
8453   mp->mt_sw_if_index = ntohl (sw_if_index);
8454   mp->mt_is_add = is_add;
8455   mp->mt_l2_only = l2_only;
8456   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
8457   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
8458
8459   mp->mt_next_hop_n_out_labels = vec_len (labels);
8460
8461   if (0 != mp->mt_next_hop_n_out_labels)
8462     {
8463       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
8464                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
8465       vec_free (labels);
8466     }
8467
8468   if (next_hop_proto_is_ip4)
8469     {
8470       clib_memcpy (mp->mt_next_hop,
8471                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8472     }
8473   else
8474     {
8475       clib_memcpy (mp->mt_next_hop,
8476                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8477     }
8478
8479   S (mp);
8480   W (ret);
8481   return ret;
8482 }
8483
8484 static int
8485 api_sw_interface_set_unnumbered (vat_main_t * vam)
8486 {
8487   unformat_input_t *i = vam->input;
8488   vl_api_sw_interface_set_unnumbered_t *mp;
8489   u32 sw_if_index;
8490   u32 unnum_sw_index = ~0;
8491   u8 is_add = 1;
8492   u8 sw_if_index_set = 0;
8493   int ret;
8494
8495   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8496     {
8497       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8498         sw_if_index_set = 1;
8499       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8500         sw_if_index_set = 1;
8501       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8502         ;
8503       else if (unformat (i, "del"))
8504         is_add = 0;
8505       else
8506         {
8507           clib_warning ("parse error '%U'", format_unformat_error, i);
8508           return -99;
8509         }
8510     }
8511
8512   if (sw_if_index_set == 0)
8513     {
8514       errmsg ("missing interface name or sw_if_index");
8515       return -99;
8516     }
8517
8518   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8519
8520   mp->sw_if_index = ntohl (sw_if_index);
8521   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8522   mp->is_add = is_add;
8523
8524   S (mp);
8525   W (ret);
8526   return ret;
8527 }
8528
8529 static int
8530 api_ip_neighbor_add_del (vat_main_t * vam)
8531 {
8532   unformat_input_t *i = vam->input;
8533   vl_api_ip_neighbor_add_del_t *mp;
8534   u32 sw_if_index;
8535   u8 sw_if_index_set = 0;
8536   u8 is_add = 1;
8537   u8 is_static = 0;
8538   u8 is_no_fib_entry = 0;
8539   u8 mac_address[6];
8540   u8 mac_set = 0;
8541   u8 v4_address_set = 0;
8542   u8 v6_address_set = 0;
8543   ip4_address_t v4address;
8544   ip6_address_t v6address;
8545   int ret;
8546
8547   memset (mac_address, 0, sizeof (mac_address));
8548
8549   /* Parse args required to build the message */
8550   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8551     {
8552       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8553         {
8554           mac_set = 1;
8555         }
8556       else if (unformat (i, "del"))
8557         is_add = 0;
8558       else
8559         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8560         sw_if_index_set = 1;
8561       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8562         sw_if_index_set = 1;
8563       else if (unformat (i, "is_static"))
8564         is_static = 1;
8565       else if (unformat (i, "no-fib-entry"))
8566         is_no_fib_entry = 1;
8567       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
8568         v4_address_set = 1;
8569       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
8570         v6_address_set = 1;
8571       else
8572         {
8573           clib_warning ("parse error '%U'", format_unformat_error, i);
8574           return -99;
8575         }
8576     }
8577
8578   if (sw_if_index_set == 0)
8579     {
8580       errmsg ("missing interface name or sw_if_index");
8581       return -99;
8582     }
8583   if (v4_address_set && v6_address_set)
8584     {
8585       errmsg ("both v4 and v6 addresses set");
8586       return -99;
8587     }
8588   if (!v4_address_set && !v6_address_set)
8589     {
8590       errmsg ("no address set");
8591       return -99;
8592     }
8593
8594   /* Construct the API message */
8595   M (IP_NEIGHBOR_ADD_DEL, mp);
8596
8597   mp->sw_if_index = ntohl (sw_if_index);
8598   mp->is_add = is_add;
8599   mp->is_static = is_static;
8600   mp->is_no_adj_fib = is_no_fib_entry;
8601   if (mac_set)
8602     clib_memcpy (mp->mac_address, mac_address, 6);
8603   if (v6_address_set)
8604     {
8605       mp->is_ipv6 = 1;
8606       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
8607     }
8608   else
8609     {
8610       /* mp->is_ipv6 = 0; via memset in M macro above */
8611       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
8612     }
8613
8614   /* send it... */
8615   S (mp);
8616
8617   /* Wait for a reply, return good/bad news  */
8618   W (ret);
8619   return ret;
8620 }
8621
8622 static int
8623 api_reset_vrf (vat_main_t * vam)
8624 {
8625   unformat_input_t *i = vam->input;
8626   vl_api_reset_vrf_t *mp;
8627   u32 vrf_id = 0;
8628   u8 is_ipv6 = 0;
8629   u8 vrf_id_set = 0;
8630   int ret;
8631
8632   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8633     {
8634       if (unformat (i, "vrf %d", &vrf_id))
8635         vrf_id_set = 1;
8636       else if (unformat (i, "ipv6"))
8637         is_ipv6 = 1;
8638       else
8639         {
8640           clib_warning ("parse error '%U'", format_unformat_error, i);
8641           return -99;
8642         }
8643     }
8644
8645   if (vrf_id_set == 0)
8646     {
8647       errmsg ("missing vrf id");
8648       return -99;
8649     }
8650
8651   M (RESET_VRF, mp);
8652
8653   mp->vrf_id = ntohl (vrf_id);
8654   mp->is_ipv6 = is_ipv6;
8655
8656   S (mp);
8657   W (ret);
8658   return ret;
8659 }
8660
8661 static int
8662 api_create_vlan_subif (vat_main_t * vam)
8663 {
8664   unformat_input_t *i = vam->input;
8665   vl_api_create_vlan_subif_t *mp;
8666   u32 sw_if_index;
8667   u8 sw_if_index_set = 0;
8668   u32 vlan_id;
8669   u8 vlan_id_set = 0;
8670   int ret;
8671
8672   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8673     {
8674       if (unformat (i, "sw_if_index %d", &sw_if_index))
8675         sw_if_index_set = 1;
8676       else
8677         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8678         sw_if_index_set = 1;
8679       else if (unformat (i, "vlan %d", &vlan_id))
8680         vlan_id_set = 1;
8681       else
8682         {
8683           clib_warning ("parse error '%U'", format_unformat_error, i);
8684           return -99;
8685         }
8686     }
8687
8688   if (sw_if_index_set == 0)
8689     {
8690       errmsg ("missing interface name or sw_if_index");
8691       return -99;
8692     }
8693
8694   if (vlan_id_set == 0)
8695     {
8696       errmsg ("missing vlan_id");
8697       return -99;
8698     }
8699   M (CREATE_VLAN_SUBIF, mp);
8700
8701   mp->sw_if_index = ntohl (sw_if_index);
8702   mp->vlan_id = ntohl (vlan_id);
8703
8704   S (mp);
8705   W (ret);
8706   return ret;
8707 }
8708
8709 #define foreach_create_subif_bit                \
8710 _(no_tags)                                      \
8711 _(one_tag)                                      \
8712 _(two_tags)                                     \
8713 _(dot1ad)                                       \
8714 _(exact_match)                                  \
8715 _(default_sub)                                  \
8716 _(outer_vlan_id_any)                            \
8717 _(inner_vlan_id_any)
8718
8719 static int
8720 api_create_subif (vat_main_t * vam)
8721 {
8722   unformat_input_t *i = vam->input;
8723   vl_api_create_subif_t *mp;
8724   u32 sw_if_index;
8725   u8 sw_if_index_set = 0;
8726   u32 sub_id;
8727   u8 sub_id_set = 0;
8728   u32 no_tags = 0;
8729   u32 one_tag = 0;
8730   u32 two_tags = 0;
8731   u32 dot1ad = 0;
8732   u32 exact_match = 0;
8733   u32 default_sub = 0;
8734   u32 outer_vlan_id_any = 0;
8735   u32 inner_vlan_id_any = 0;
8736   u32 tmp;
8737   u16 outer_vlan_id = 0;
8738   u16 inner_vlan_id = 0;
8739   int ret;
8740
8741   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8742     {
8743       if (unformat (i, "sw_if_index %d", &sw_if_index))
8744         sw_if_index_set = 1;
8745       else
8746         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8747         sw_if_index_set = 1;
8748       else if (unformat (i, "sub_id %d", &sub_id))
8749         sub_id_set = 1;
8750       else if (unformat (i, "outer_vlan_id %d", &tmp))
8751         outer_vlan_id = tmp;
8752       else if (unformat (i, "inner_vlan_id %d", &tmp))
8753         inner_vlan_id = tmp;
8754
8755 #define _(a) else if (unformat (i, #a)) a = 1 ;
8756       foreach_create_subif_bit
8757 #undef _
8758         else
8759         {
8760           clib_warning ("parse error '%U'", format_unformat_error, i);
8761           return -99;
8762         }
8763     }
8764
8765   if (sw_if_index_set == 0)
8766     {
8767       errmsg ("missing interface name or sw_if_index");
8768       return -99;
8769     }
8770
8771   if (sub_id_set == 0)
8772     {
8773       errmsg ("missing sub_id");
8774       return -99;
8775     }
8776   M (CREATE_SUBIF, mp);
8777
8778   mp->sw_if_index = ntohl (sw_if_index);
8779   mp->sub_id = ntohl (sub_id);
8780
8781 #define _(a) mp->a = a;
8782   foreach_create_subif_bit;
8783 #undef _
8784
8785   mp->outer_vlan_id = ntohs (outer_vlan_id);
8786   mp->inner_vlan_id = ntohs (inner_vlan_id);
8787
8788   S (mp);
8789   W (ret);
8790   return ret;
8791 }
8792
8793 static int
8794 api_oam_add_del (vat_main_t * vam)
8795 {
8796   unformat_input_t *i = vam->input;
8797   vl_api_oam_add_del_t *mp;
8798   u32 vrf_id = 0;
8799   u8 is_add = 1;
8800   ip4_address_t src, dst;
8801   u8 src_set = 0;
8802   u8 dst_set = 0;
8803   int ret;
8804
8805   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8806     {
8807       if (unformat (i, "vrf %d", &vrf_id))
8808         ;
8809       else if (unformat (i, "src %U", unformat_ip4_address, &src))
8810         src_set = 1;
8811       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
8812         dst_set = 1;
8813       else if (unformat (i, "del"))
8814         is_add = 0;
8815       else
8816         {
8817           clib_warning ("parse error '%U'", format_unformat_error, i);
8818           return -99;
8819         }
8820     }
8821
8822   if (src_set == 0)
8823     {
8824       errmsg ("missing src addr");
8825       return -99;
8826     }
8827
8828   if (dst_set == 0)
8829     {
8830       errmsg ("missing dst addr");
8831       return -99;
8832     }
8833
8834   M (OAM_ADD_DEL, mp);
8835
8836   mp->vrf_id = ntohl (vrf_id);
8837   mp->is_add = is_add;
8838   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
8839   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
8840
8841   S (mp);
8842   W (ret);
8843   return ret;
8844 }
8845
8846 static int
8847 api_reset_fib (vat_main_t * vam)
8848 {
8849   unformat_input_t *i = vam->input;
8850   vl_api_reset_fib_t *mp;
8851   u32 vrf_id = 0;
8852   u8 is_ipv6 = 0;
8853   u8 vrf_id_set = 0;
8854
8855   int ret;
8856   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8857     {
8858       if (unformat (i, "vrf %d", &vrf_id))
8859         vrf_id_set = 1;
8860       else if (unformat (i, "ipv6"))
8861         is_ipv6 = 1;
8862       else
8863         {
8864           clib_warning ("parse error '%U'", format_unformat_error, i);
8865           return -99;
8866         }
8867     }
8868
8869   if (vrf_id_set == 0)
8870     {
8871       errmsg ("missing vrf id");
8872       return -99;
8873     }
8874
8875   M (RESET_FIB, mp);
8876
8877   mp->vrf_id = ntohl (vrf_id);
8878   mp->is_ipv6 = is_ipv6;
8879
8880   S (mp);
8881   W (ret);
8882   return ret;
8883 }
8884
8885 static int
8886 api_dhcp_proxy_config (vat_main_t * vam)
8887 {
8888   unformat_input_t *i = vam->input;
8889   vl_api_dhcp_proxy_config_t *mp;
8890   u32 rx_vrf_id = 0;
8891   u32 server_vrf_id = 0;
8892   u8 is_add = 1;
8893   u8 v4_address_set = 0;
8894   u8 v6_address_set = 0;
8895   ip4_address_t v4address;
8896   ip6_address_t v6address;
8897   u8 v4_src_address_set = 0;
8898   u8 v6_src_address_set = 0;
8899   ip4_address_t v4srcaddress;
8900   ip6_address_t v6srcaddress;
8901   int ret;
8902
8903   /* Parse args required to build the message */
8904   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8905     {
8906       if (unformat (i, "del"))
8907         is_add = 0;
8908       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
8909         ;
8910       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
8911         ;
8912       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
8913         v4_address_set = 1;
8914       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
8915         v6_address_set = 1;
8916       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
8917         v4_src_address_set = 1;
8918       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
8919         v6_src_address_set = 1;
8920       else
8921         break;
8922     }
8923
8924   if (v4_address_set && v6_address_set)
8925     {
8926       errmsg ("both v4 and v6 server addresses set");
8927       return -99;
8928     }
8929   if (!v4_address_set && !v6_address_set)
8930     {
8931       errmsg ("no server addresses set");
8932       return -99;
8933     }
8934
8935   if (v4_src_address_set && v6_src_address_set)
8936     {
8937       errmsg ("both v4 and v6  src addresses set");
8938       return -99;
8939     }
8940   if (!v4_src_address_set && !v6_src_address_set)
8941     {
8942       errmsg ("no src addresses set");
8943       return -99;
8944     }
8945
8946   if (!(v4_src_address_set && v4_address_set) &&
8947       !(v6_src_address_set && v6_address_set))
8948     {
8949       errmsg ("no matching server and src addresses set");
8950       return -99;
8951     }
8952
8953   /* Construct the API message */
8954   M (DHCP_PROXY_CONFIG, mp);
8955
8956   mp->is_add = is_add;
8957   mp->rx_vrf_id = ntohl (rx_vrf_id);
8958   mp->server_vrf_id = ntohl (server_vrf_id);
8959   if (v6_address_set)
8960     {
8961       mp->is_ipv6 = 1;
8962       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
8963       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
8964     }
8965   else
8966     {
8967       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
8968       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
8969     }
8970
8971   /* send it... */
8972   S (mp);
8973
8974   /* Wait for a reply, return good/bad news  */
8975   W (ret);
8976   return ret;
8977 }
8978
8979 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
8980 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
8981
8982 static void
8983 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
8984 {
8985   vat_main_t *vam = &vat_main;
8986   u32 i, count = mp->count;
8987   vl_api_dhcp_server_t *s;
8988
8989   if (mp->is_ipv6)
8990     print (vam->ofp,
8991            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8992            ntohl (mp->rx_vrf_id),
8993            format_ip6_address, mp->dhcp_src_address,
8994            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8995   else
8996     print (vam->ofp,
8997            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8998            ntohl (mp->rx_vrf_id),
8999            format_ip4_address, mp->dhcp_src_address,
9000            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9001
9002   for (i = 0; i < count; i++)
9003     {
9004       s = &mp->servers[i];
9005
9006       if (mp->is_ipv6)
9007         print (vam->ofp,
9008                " Server Table-ID %d, Server Address %U",
9009                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9010       else
9011         print (vam->ofp,
9012                " Server Table-ID %d, Server Address %U",
9013                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9014     }
9015 }
9016
9017 static void vl_api_dhcp_proxy_details_t_handler_json
9018   (vl_api_dhcp_proxy_details_t * mp)
9019 {
9020   vat_main_t *vam = &vat_main;
9021   vat_json_node_t *node = NULL;
9022   u32 i, count = mp->count;
9023   struct in_addr ip4;
9024   struct in6_addr ip6;
9025   vl_api_dhcp_server_t *s;
9026
9027   if (VAT_JSON_ARRAY != vam->json_tree.type)
9028     {
9029       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9030       vat_json_init_array (&vam->json_tree);
9031     }
9032   node = vat_json_array_add (&vam->json_tree);
9033
9034   vat_json_init_object (node);
9035   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9036   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9037   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9038
9039   if (mp->is_ipv6)
9040     {
9041       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9042       vat_json_object_add_ip6 (node, "src_address", ip6);
9043     }
9044   else
9045     {
9046       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9047       vat_json_object_add_ip4 (node, "src_address", ip4);
9048     }
9049
9050   for (i = 0; i < count; i++)
9051     {
9052       s = &mp->servers[i];
9053
9054       vat_json_object_add_uint (node, "server-table-id",
9055                                 ntohl (s->server_vrf_id));
9056
9057       if (mp->is_ipv6)
9058         {
9059           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9060           vat_json_object_add_ip4 (node, "src_address", ip4);
9061         }
9062       else
9063         {
9064           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9065           vat_json_object_add_ip6 (node, "server_address", ip6);
9066         }
9067     }
9068 }
9069
9070 static int
9071 api_dhcp_proxy_dump (vat_main_t * vam)
9072 {
9073   unformat_input_t *i = vam->input;
9074   vl_api_control_ping_t *mp_ping;
9075   vl_api_dhcp_proxy_dump_t *mp;
9076   u8 is_ipv6 = 0;
9077   int ret;
9078
9079   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9080     {
9081       if (unformat (i, "ipv6"))
9082         is_ipv6 = 1;
9083       else
9084         {
9085           clib_warning ("parse error '%U'", format_unformat_error, i);
9086           return -99;
9087         }
9088     }
9089
9090   M (DHCP_PROXY_DUMP, mp);
9091
9092   mp->is_ip6 = is_ipv6;
9093   S (mp);
9094
9095   /* Use a control ping for synchronization */
9096   MPING (CONTROL_PING, mp_ping);
9097   S (mp_ping);
9098
9099   W (ret);
9100   return ret;
9101 }
9102
9103 static int
9104 api_dhcp_proxy_set_vss (vat_main_t * vam)
9105 {
9106   unformat_input_t *i = vam->input;
9107   vl_api_dhcp_proxy_set_vss_t *mp;
9108   u8 is_ipv6 = 0;
9109   u8 is_add = 1;
9110   u32 tbl_id;
9111   u8 tbl_id_set = 0;
9112   u32 oui;
9113   u8 oui_set = 0;
9114   u32 fib_id;
9115   u8 fib_id_set = 0;
9116   int ret;
9117
9118   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9119     {
9120       if (unformat (i, "tbl_id %d", &tbl_id))
9121         tbl_id_set = 1;
9122       if (unformat (i, "fib_id %d", &fib_id))
9123         fib_id_set = 1;
9124       if (unformat (i, "oui %d", &oui))
9125         oui_set = 1;
9126       else if (unformat (i, "ipv6"))
9127         is_ipv6 = 1;
9128       else if (unformat (i, "del"))
9129         is_add = 0;
9130       else
9131         {
9132           clib_warning ("parse error '%U'", format_unformat_error, i);
9133           return -99;
9134         }
9135     }
9136
9137   if (tbl_id_set == 0)
9138     {
9139       errmsg ("missing tbl id");
9140       return -99;
9141     }
9142
9143   if (fib_id_set == 0)
9144     {
9145       errmsg ("missing fib id");
9146       return -99;
9147     }
9148   if (oui_set == 0)
9149     {
9150       errmsg ("missing oui");
9151       return -99;
9152     }
9153
9154   M (DHCP_PROXY_SET_VSS, mp);
9155   mp->tbl_id = ntohl (tbl_id);
9156   mp->fib_id = ntohl (fib_id);
9157   mp->oui = ntohl (oui);
9158   mp->is_ipv6 = is_ipv6;
9159   mp->is_add = is_add;
9160
9161   S (mp);
9162   W (ret);
9163   return ret;
9164 }
9165
9166 static int
9167 api_dhcp_client_config (vat_main_t * vam)
9168 {
9169   unformat_input_t *i = vam->input;
9170   vl_api_dhcp_client_config_t *mp;
9171   u32 sw_if_index;
9172   u8 sw_if_index_set = 0;
9173   u8 is_add = 1;
9174   u8 *hostname = 0;
9175   u8 disable_event = 0;
9176   int ret;
9177
9178   /* Parse args required to build the message */
9179   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9180     {
9181       if (unformat (i, "del"))
9182         is_add = 0;
9183       else
9184         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9185         sw_if_index_set = 1;
9186       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9187         sw_if_index_set = 1;
9188       else if (unformat (i, "hostname %s", &hostname))
9189         ;
9190       else if (unformat (i, "disable_event"))
9191         disable_event = 1;
9192       else
9193         break;
9194     }
9195
9196   if (sw_if_index_set == 0)
9197     {
9198       errmsg ("missing interface name or sw_if_index");
9199       return -99;
9200     }
9201
9202   if (vec_len (hostname) > 63)
9203     {
9204       errmsg ("hostname too long");
9205     }
9206   vec_add1 (hostname, 0);
9207
9208   /* Construct the API message */
9209   M (DHCP_CLIENT_CONFIG, mp);
9210
9211   mp->sw_if_index = htonl (sw_if_index);
9212   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
9213   vec_free (hostname);
9214   mp->is_add = is_add;
9215   mp->want_dhcp_event = disable_event ? 0 : 1;
9216   mp->pid = htonl (getpid ());
9217
9218   /* send it... */
9219   S (mp);
9220
9221   /* Wait for a reply, return good/bad news  */
9222   W (ret);
9223   return ret;
9224 }
9225
9226 static int
9227 api_set_ip_flow_hash (vat_main_t * vam)
9228 {
9229   unformat_input_t *i = vam->input;
9230   vl_api_set_ip_flow_hash_t *mp;
9231   u32 vrf_id = 0;
9232   u8 is_ipv6 = 0;
9233   u8 vrf_id_set = 0;
9234   u8 src = 0;
9235   u8 dst = 0;
9236   u8 sport = 0;
9237   u8 dport = 0;
9238   u8 proto = 0;
9239   u8 reverse = 0;
9240   int ret;
9241
9242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9243     {
9244       if (unformat (i, "vrf %d", &vrf_id))
9245         vrf_id_set = 1;
9246       else if (unformat (i, "ipv6"))
9247         is_ipv6 = 1;
9248       else if (unformat (i, "src"))
9249         src = 1;
9250       else if (unformat (i, "dst"))
9251         dst = 1;
9252       else if (unformat (i, "sport"))
9253         sport = 1;
9254       else if (unformat (i, "dport"))
9255         dport = 1;
9256       else if (unformat (i, "proto"))
9257         proto = 1;
9258       else if (unformat (i, "reverse"))
9259         reverse = 1;
9260
9261       else
9262         {
9263           clib_warning ("parse error '%U'", format_unformat_error, i);
9264           return -99;
9265         }
9266     }
9267
9268   if (vrf_id_set == 0)
9269     {
9270       errmsg ("missing vrf id");
9271       return -99;
9272     }
9273
9274   M (SET_IP_FLOW_HASH, mp);
9275   mp->src = src;
9276   mp->dst = dst;
9277   mp->sport = sport;
9278   mp->dport = dport;
9279   mp->proto = proto;
9280   mp->reverse = reverse;
9281   mp->vrf_id = ntohl (vrf_id);
9282   mp->is_ipv6 = is_ipv6;
9283
9284   S (mp);
9285   W (ret);
9286   return ret;
9287 }
9288
9289 static int
9290 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9291 {
9292   unformat_input_t *i = vam->input;
9293   vl_api_sw_interface_ip6_enable_disable_t *mp;
9294   u32 sw_if_index;
9295   u8 sw_if_index_set = 0;
9296   u8 enable = 0;
9297   int ret;
9298
9299   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9300     {
9301       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9302         sw_if_index_set = 1;
9303       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9304         sw_if_index_set = 1;
9305       else if (unformat (i, "enable"))
9306         enable = 1;
9307       else if (unformat (i, "disable"))
9308         enable = 0;
9309       else
9310         {
9311           clib_warning ("parse error '%U'", format_unformat_error, i);
9312           return -99;
9313         }
9314     }
9315
9316   if (sw_if_index_set == 0)
9317     {
9318       errmsg ("missing interface name or sw_if_index");
9319       return -99;
9320     }
9321
9322   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9323
9324   mp->sw_if_index = ntohl (sw_if_index);
9325   mp->enable = enable;
9326
9327   S (mp);
9328   W (ret);
9329   return ret;
9330 }
9331
9332 static int
9333 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
9334 {
9335   unformat_input_t *i = vam->input;
9336   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
9337   u32 sw_if_index;
9338   u8 sw_if_index_set = 0;
9339   u8 v6_address_set = 0;
9340   ip6_address_t v6address;
9341   int ret;
9342
9343   /* Parse args required to build the message */
9344   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9345     {
9346       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9347         sw_if_index_set = 1;
9348       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9349         sw_if_index_set = 1;
9350       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9351         v6_address_set = 1;
9352       else
9353         break;
9354     }
9355
9356   if (sw_if_index_set == 0)
9357     {
9358       errmsg ("missing interface name or sw_if_index");
9359       return -99;
9360     }
9361   if (!v6_address_set)
9362     {
9363       errmsg ("no address set");
9364       return -99;
9365     }
9366
9367   /* Construct the API message */
9368   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
9369
9370   mp->sw_if_index = ntohl (sw_if_index);
9371   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9372
9373   /* send it... */
9374   S (mp);
9375
9376   /* Wait for a reply, return good/bad news  */
9377   W (ret);
9378   return ret;
9379 }
9380
9381 static int
9382 api_ip6nd_proxy_add_del (vat_main_t * vam)
9383 {
9384   unformat_input_t *i = vam->input;
9385   vl_api_ip6nd_proxy_add_del_t *mp;
9386   u32 sw_if_index = ~0;
9387   u8 v6_address_set = 0;
9388   ip6_address_t v6address;
9389   u8 is_del = 0;
9390   int ret;
9391
9392   /* Parse args required to build the message */
9393   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9394     {
9395       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9396         ;
9397       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9398         ;
9399       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9400         v6_address_set = 1;
9401       if (unformat (i, "del"))
9402         is_del = 1;
9403       else
9404         {
9405           clib_warning ("parse error '%U'", format_unformat_error, i);
9406           return -99;
9407         }
9408     }
9409
9410   if (sw_if_index == ~0)
9411     {
9412       errmsg ("missing interface name or sw_if_index");
9413       return -99;
9414     }
9415   if (!v6_address_set)
9416     {
9417       errmsg ("no address set");
9418       return -99;
9419     }
9420
9421   /* Construct the API message */
9422   M (IP6ND_PROXY_ADD_DEL, mp);
9423
9424   mp->is_del = is_del;
9425   mp->sw_if_index = ntohl (sw_if_index);
9426   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9427
9428   /* send it... */
9429   S (mp);
9430
9431   /* Wait for a reply, return good/bad news  */
9432   W (ret);
9433   return ret;
9434 }
9435
9436 static int
9437 api_ip6nd_proxy_dump (vat_main_t * vam)
9438 {
9439   vl_api_ip6nd_proxy_dump_t *mp;
9440   vl_api_control_ping_t *mp_ping;
9441   int ret;
9442
9443   M (IP6ND_PROXY_DUMP, mp);
9444
9445   S (mp);
9446
9447   /* Use a control ping for synchronization */
9448   MPING (CONTROL_PING, mp_ping);
9449   S (mp_ping);
9450
9451   W (ret);
9452   return ret;
9453 }
9454
9455 static void vl_api_ip6nd_proxy_details_t_handler
9456   (vl_api_ip6nd_proxy_details_t * mp)
9457 {
9458   vat_main_t *vam = &vat_main;
9459
9460   print (vam->ofp, "host %U sw_if_index %d",
9461          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
9462 }
9463
9464 static void vl_api_ip6nd_proxy_details_t_handler_json
9465   (vl_api_ip6nd_proxy_details_t * mp)
9466 {
9467   vat_main_t *vam = &vat_main;
9468   struct in6_addr ip6;
9469   vat_json_node_t *node = NULL;
9470
9471   if (VAT_JSON_ARRAY != vam->json_tree.type)
9472     {
9473       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9474       vat_json_init_array (&vam->json_tree);
9475     }
9476   node = vat_json_array_add (&vam->json_tree);
9477
9478   vat_json_init_object (node);
9479   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9480
9481   clib_memcpy (&ip6, mp->address, sizeof (ip6));
9482   vat_json_object_add_ip6 (node, "host", ip6);
9483 }
9484
9485 static int
9486 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9487 {
9488   unformat_input_t *i = vam->input;
9489   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9490   u32 sw_if_index;
9491   u8 sw_if_index_set = 0;
9492   u32 address_length = 0;
9493   u8 v6_address_set = 0;
9494   ip6_address_t v6address;
9495   u8 use_default = 0;
9496   u8 no_advertise = 0;
9497   u8 off_link = 0;
9498   u8 no_autoconfig = 0;
9499   u8 no_onlink = 0;
9500   u8 is_no = 0;
9501   u32 val_lifetime = 0;
9502   u32 pref_lifetime = 0;
9503   int ret;
9504
9505   /* Parse args required to build the message */
9506   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9507     {
9508       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9509         sw_if_index_set = 1;
9510       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9511         sw_if_index_set = 1;
9512       else if (unformat (i, "%U/%d",
9513                          unformat_ip6_address, &v6address, &address_length))
9514         v6_address_set = 1;
9515       else if (unformat (i, "val_life %d", &val_lifetime))
9516         ;
9517       else if (unformat (i, "pref_life %d", &pref_lifetime))
9518         ;
9519       else if (unformat (i, "def"))
9520         use_default = 1;
9521       else if (unformat (i, "noadv"))
9522         no_advertise = 1;
9523       else if (unformat (i, "offl"))
9524         off_link = 1;
9525       else if (unformat (i, "noauto"))
9526         no_autoconfig = 1;
9527       else if (unformat (i, "nolink"))
9528         no_onlink = 1;
9529       else if (unformat (i, "isno"))
9530         is_no = 1;
9531       else
9532         {
9533           clib_warning ("parse error '%U'", format_unformat_error, i);
9534           return -99;
9535         }
9536     }
9537
9538   if (sw_if_index_set == 0)
9539     {
9540       errmsg ("missing interface name or sw_if_index");
9541       return -99;
9542     }
9543   if (!v6_address_set)
9544     {
9545       errmsg ("no address set");
9546       return -99;
9547     }
9548
9549   /* Construct the API message */
9550   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9551
9552   mp->sw_if_index = ntohl (sw_if_index);
9553   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9554   mp->address_length = address_length;
9555   mp->use_default = use_default;
9556   mp->no_advertise = no_advertise;
9557   mp->off_link = off_link;
9558   mp->no_autoconfig = no_autoconfig;
9559   mp->no_onlink = no_onlink;
9560   mp->is_no = is_no;
9561   mp->val_lifetime = ntohl (val_lifetime);
9562   mp->pref_lifetime = ntohl (pref_lifetime);
9563
9564   /* send it... */
9565   S (mp);
9566
9567   /* Wait for a reply, return good/bad news  */
9568   W (ret);
9569   return ret;
9570 }
9571
9572 static int
9573 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9574 {
9575   unformat_input_t *i = vam->input;
9576   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9577   u32 sw_if_index;
9578   u8 sw_if_index_set = 0;
9579   u8 suppress = 0;
9580   u8 managed = 0;
9581   u8 other = 0;
9582   u8 ll_option = 0;
9583   u8 send_unicast = 0;
9584   u8 cease = 0;
9585   u8 is_no = 0;
9586   u8 default_router = 0;
9587   u32 max_interval = 0;
9588   u32 min_interval = 0;
9589   u32 lifetime = 0;
9590   u32 initial_count = 0;
9591   u32 initial_interval = 0;
9592   int ret;
9593
9594
9595   /* Parse args required to build the message */
9596   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9597     {
9598       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9599         sw_if_index_set = 1;
9600       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9601         sw_if_index_set = 1;
9602       else if (unformat (i, "maxint %d", &max_interval))
9603         ;
9604       else if (unformat (i, "minint %d", &min_interval))
9605         ;
9606       else if (unformat (i, "life %d", &lifetime))
9607         ;
9608       else if (unformat (i, "count %d", &initial_count))
9609         ;
9610       else if (unformat (i, "interval %d", &initial_interval))
9611         ;
9612       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9613         suppress = 1;
9614       else if (unformat (i, "managed"))
9615         managed = 1;
9616       else if (unformat (i, "other"))
9617         other = 1;
9618       else if (unformat (i, "ll"))
9619         ll_option = 1;
9620       else if (unformat (i, "send"))
9621         send_unicast = 1;
9622       else if (unformat (i, "cease"))
9623         cease = 1;
9624       else if (unformat (i, "isno"))
9625         is_no = 1;
9626       else if (unformat (i, "def"))
9627         default_router = 1;
9628       else
9629         {
9630           clib_warning ("parse error '%U'", format_unformat_error, i);
9631           return -99;
9632         }
9633     }
9634
9635   if (sw_if_index_set == 0)
9636     {
9637       errmsg ("missing interface name or sw_if_index");
9638       return -99;
9639     }
9640
9641   /* Construct the API message */
9642   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9643
9644   mp->sw_if_index = ntohl (sw_if_index);
9645   mp->max_interval = ntohl (max_interval);
9646   mp->min_interval = ntohl (min_interval);
9647   mp->lifetime = ntohl (lifetime);
9648   mp->initial_count = ntohl (initial_count);
9649   mp->initial_interval = ntohl (initial_interval);
9650   mp->suppress = suppress;
9651   mp->managed = managed;
9652   mp->other = other;
9653   mp->ll_option = ll_option;
9654   mp->send_unicast = send_unicast;
9655   mp->cease = cease;
9656   mp->is_no = is_no;
9657   mp->default_router = default_router;
9658
9659   /* send it... */
9660   S (mp);
9661
9662   /* Wait for a reply, return good/bad news  */
9663   W (ret);
9664   return ret;
9665 }
9666
9667 static int
9668 api_set_arp_neighbor_limit (vat_main_t * vam)
9669 {
9670   unformat_input_t *i = vam->input;
9671   vl_api_set_arp_neighbor_limit_t *mp;
9672   u32 arp_nbr_limit;
9673   u8 limit_set = 0;
9674   u8 is_ipv6 = 0;
9675   int ret;
9676
9677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9678     {
9679       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
9680         limit_set = 1;
9681       else if (unformat (i, "ipv6"))
9682         is_ipv6 = 1;
9683       else
9684         {
9685           clib_warning ("parse error '%U'", format_unformat_error, i);
9686           return -99;
9687         }
9688     }
9689
9690   if (limit_set == 0)
9691     {
9692       errmsg ("missing limit value");
9693       return -99;
9694     }
9695
9696   M (SET_ARP_NEIGHBOR_LIMIT, mp);
9697
9698   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
9699   mp->is_ipv6 = is_ipv6;
9700
9701   S (mp);
9702   W (ret);
9703   return ret;
9704 }
9705
9706 static int
9707 api_l2_patch_add_del (vat_main_t * vam)
9708 {
9709   unformat_input_t *i = vam->input;
9710   vl_api_l2_patch_add_del_t *mp;
9711   u32 rx_sw_if_index;
9712   u8 rx_sw_if_index_set = 0;
9713   u32 tx_sw_if_index;
9714   u8 tx_sw_if_index_set = 0;
9715   u8 is_add = 1;
9716   int ret;
9717
9718   /* Parse args required to build the message */
9719   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9720     {
9721       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9722         rx_sw_if_index_set = 1;
9723       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9724         tx_sw_if_index_set = 1;
9725       else if (unformat (i, "rx"))
9726         {
9727           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9728             {
9729               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9730                             &rx_sw_if_index))
9731                 rx_sw_if_index_set = 1;
9732             }
9733           else
9734             break;
9735         }
9736       else if (unformat (i, "tx"))
9737         {
9738           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9739             {
9740               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9741                             &tx_sw_if_index))
9742                 tx_sw_if_index_set = 1;
9743             }
9744           else
9745             break;
9746         }
9747       else if (unformat (i, "del"))
9748         is_add = 0;
9749       else
9750         break;
9751     }
9752
9753   if (rx_sw_if_index_set == 0)
9754     {
9755       errmsg ("missing rx interface name or rx_sw_if_index");
9756       return -99;
9757     }
9758
9759   if (tx_sw_if_index_set == 0)
9760     {
9761       errmsg ("missing tx interface name or tx_sw_if_index");
9762       return -99;
9763     }
9764
9765   M (L2_PATCH_ADD_DEL, mp);
9766
9767   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9768   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9769   mp->is_add = is_add;
9770
9771   S (mp);
9772   W (ret);
9773   return ret;
9774 }
9775
9776 u8 is_del;
9777 u8 localsid_addr[16];
9778 u8 end_psp;
9779 u8 behavior;
9780 u32 sw_if_index;
9781 u32 vlan_index;
9782 u32 fib_table;
9783 u8 nh_addr[16];
9784
9785 static int
9786 api_sr_localsid_add_del (vat_main_t * vam)
9787 {
9788   unformat_input_t *i = vam->input;
9789   vl_api_sr_localsid_add_del_t *mp;
9790
9791   u8 is_del;
9792   ip6_address_t localsid;
9793   u8 end_psp = 0;
9794   u8 behavior = ~0;
9795   u32 sw_if_index;
9796   u32 fib_table = ~(u32) 0;
9797   ip6_address_t next_hop;
9798
9799   bool nexthop_set = 0;
9800
9801   int ret;
9802
9803   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9804     {
9805       if (unformat (i, "del"))
9806         is_del = 1;
9807       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9808       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
9809         nexthop_set = 1;
9810       else if (unformat (i, "behavior %u", &behavior));
9811       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9812       else if (unformat (i, "fib-table %u", &fib_table));
9813       else if (unformat (i, "end.psp %u", &behavior));
9814       else
9815         break;
9816     }
9817
9818   M (SR_LOCALSID_ADD_DEL, mp);
9819
9820   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
9821   if (nexthop_set)
9822     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
9823   mp->behavior = behavior;
9824   mp->sw_if_index = ntohl (sw_if_index);
9825   mp->fib_table = ntohl (fib_table);
9826   mp->end_psp = end_psp;
9827   mp->is_del = is_del;
9828
9829   S (mp);
9830   W (ret);
9831   return ret;
9832 }
9833
9834 static int
9835 api_ioam_enable (vat_main_t * vam)
9836 {
9837   unformat_input_t *input = vam->input;
9838   vl_api_ioam_enable_t *mp;
9839   u32 id = 0;
9840   int has_trace_option = 0;
9841   int has_pot_option = 0;
9842   int has_seqno_option = 0;
9843   int has_analyse_option = 0;
9844   int ret;
9845
9846   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9847     {
9848       if (unformat (input, "trace"))
9849         has_trace_option = 1;
9850       else if (unformat (input, "pot"))
9851         has_pot_option = 1;
9852       else if (unformat (input, "seqno"))
9853         has_seqno_option = 1;
9854       else if (unformat (input, "analyse"))
9855         has_analyse_option = 1;
9856       else
9857         break;
9858     }
9859   M (IOAM_ENABLE, mp);
9860   mp->id = htons (id);
9861   mp->seqno = has_seqno_option;
9862   mp->analyse = has_analyse_option;
9863   mp->pot_enable = has_pot_option;
9864   mp->trace_enable = has_trace_option;
9865
9866   S (mp);
9867   W (ret);
9868   return ret;
9869 }
9870
9871
9872 static int
9873 api_ioam_disable (vat_main_t * vam)
9874 {
9875   vl_api_ioam_disable_t *mp;
9876   int ret;
9877
9878   M (IOAM_DISABLE, mp);
9879   S (mp);
9880   W (ret);
9881   return ret;
9882 }
9883
9884 #define foreach_tcp_proto_field                 \
9885 _(src_port)                                     \
9886 _(dst_port)
9887
9888 #define foreach_udp_proto_field                 \
9889 _(src_port)                                     \
9890 _(dst_port)
9891
9892 #define foreach_ip4_proto_field                 \
9893 _(src_address)                                  \
9894 _(dst_address)                                  \
9895 _(tos)                                          \
9896 _(length)                                       \
9897 _(fragment_id)                                  \
9898 _(ttl)                                          \
9899 _(protocol)                                     \
9900 _(checksum)
9901
9902 typedef struct
9903 {
9904   u16 src_port, dst_port;
9905 } tcpudp_header_t;
9906
9907 #if VPP_API_TEST_BUILTIN == 0
9908 uword
9909 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9910 {
9911   u8 **maskp = va_arg (*args, u8 **);
9912   u8 *mask = 0;
9913   u8 found_something = 0;
9914   tcp_header_t *tcp;
9915
9916 #define _(a) u8 a=0;
9917   foreach_tcp_proto_field;
9918 #undef _
9919
9920   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9921     {
9922       if (0);
9923 #define _(a) else if (unformat (input, #a)) a=1;
9924       foreach_tcp_proto_field
9925 #undef _
9926         else
9927         break;
9928     }
9929
9930 #define _(a) found_something += a;
9931   foreach_tcp_proto_field;
9932 #undef _
9933
9934   if (found_something == 0)
9935     return 0;
9936
9937   vec_validate (mask, sizeof (*tcp) - 1);
9938
9939   tcp = (tcp_header_t *) mask;
9940
9941 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
9942   foreach_tcp_proto_field;
9943 #undef _
9944
9945   *maskp = mask;
9946   return 1;
9947 }
9948
9949 uword
9950 unformat_udp_mask (unformat_input_t * input, va_list * args)
9951 {
9952   u8 **maskp = va_arg (*args, u8 **);
9953   u8 *mask = 0;
9954   u8 found_something = 0;
9955   udp_header_t *udp;
9956
9957 #define _(a) u8 a=0;
9958   foreach_udp_proto_field;
9959 #undef _
9960
9961   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9962     {
9963       if (0);
9964 #define _(a) else if (unformat (input, #a)) a=1;
9965       foreach_udp_proto_field
9966 #undef _
9967         else
9968         break;
9969     }
9970
9971 #define _(a) found_something += a;
9972   foreach_udp_proto_field;
9973 #undef _
9974
9975   if (found_something == 0)
9976     return 0;
9977
9978   vec_validate (mask, sizeof (*udp) - 1);
9979
9980   udp = (udp_header_t *) mask;
9981
9982 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
9983   foreach_udp_proto_field;
9984 #undef _
9985
9986   *maskp = mask;
9987   return 1;
9988 }
9989
9990 uword
9991 unformat_l4_mask (unformat_input_t * input, va_list * args)
9992 {
9993   u8 **maskp = va_arg (*args, u8 **);
9994   u16 src_port = 0, dst_port = 0;
9995   tcpudp_header_t *tcpudp;
9996
9997   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9998     {
9999       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10000         return 1;
10001       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10002         return 1;
10003       else if (unformat (input, "src_port"))
10004         src_port = 0xFFFF;
10005       else if (unformat (input, "dst_port"))
10006         dst_port = 0xFFFF;
10007       else
10008         return 0;
10009     }
10010
10011   if (!src_port && !dst_port)
10012     return 0;
10013
10014   u8 *mask = 0;
10015   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10016
10017   tcpudp = (tcpudp_header_t *) mask;
10018   tcpudp->src_port = src_port;
10019   tcpudp->dst_port = dst_port;
10020
10021   *maskp = mask;
10022
10023   return 1;
10024 }
10025
10026 uword
10027 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10028 {
10029   u8 **maskp = va_arg (*args, u8 **);
10030   u8 *mask = 0;
10031   u8 found_something = 0;
10032   ip4_header_t *ip;
10033
10034 #define _(a) u8 a=0;
10035   foreach_ip4_proto_field;
10036 #undef _
10037   u8 version = 0;
10038   u8 hdr_length = 0;
10039
10040
10041   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10042     {
10043       if (unformat (input, "version"))
10044         version = 1;
10045       else if (unformat (input, "hdr_length"))
10046         hdr_length = 1;
10047       else if (unformat (input, "src"))
10048         src_address = 1;
10049       else if (unformat (input, "dst"))
10050         dst_address = 1;
10051       else if (unformat (input, "proto"))
10052         protocol = 1;
10053
10054 #define _(a) else if (unformat (input, #a)) a=1;
10055       foreach_ip4_proto_field
10056 #undef _
10057         else
10058         break;
10059     }
10060
10061 #define _(a) found_something += a;
10062   foreach_ip4_proto_field;
10063 #undef _
10064
10065   if (found_something == 0)
10066     return 0;
10067
10068   vec_validate (mask, sizeof (*ip) - 1);
10069
10070   ip = (ip4_header_t *) mask;
10071
10072 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10073   foreach_ip4_proto_field;
10074 #undef _
10075
10076   ip->ip_version_and_header_length = 0;
10077
10078   if (version)
10079     ip->ip_version_and_header_length |= 0xF0;
10080
10081   if (hdr_length)
10082     ip->ip_version_and_header_length |= 0x0F;
10083
10084   *maskp = mask;
10085   return 1;
10086 }
10087
10088 #define foreach_ip6_proto_field                 \
10089 _(src_address)                                  \
10090 _(dst_address)                                  \
10091 _(payload_length)                               \
10092 _(hop_limit)                                    \
10093 _(protocol)
10094
10095 uword
10096 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10097 {
10098   u8 **maskp = va_arg (*args, u8 **);
10099   u8 *mask = 0;
10100   u8 found_something = 0;
10101   ip6_header_t *ip;
10102   u32 ip_version_traffic_class_and_flow_label;
10103
10104 #define _(a) u8 a=0;
10105   foreach_ip6_proto_field;
10106 #undef _
10107   u8 version = 0;
10108   u8 traffic_class = 0;
10109   u8 flow_label = 0;
10110
10111   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10112     {
10113       if (unformat (input, "version"))
10114         version = 1;
10115       else if (unformat (input, "traffic-class"))
10116         traffic_class = 1;
10117       else if (unformat (input, "flow-label"))
10118         flow_label = 1;
10119       else if (unformat (input, "src"))
10120         src_address = 1;
10121       else if (unformat (input, "dst"))
10122         dst_address = 1;
10123       else if (unformat (input, "proto"))
10124         protocol = 1;
10125
10126 #define _(a) else if (unformat (input, #a)) a=1;
10127       foreach_ip6_proto_field
10128 #undef _
10129         else
10130         break;
10131     }
10132
10133 #define _(a) found_something += a;
10134   foreach_ip6_proto_field;
10135 #undef _
10136
10137   if (found_something == 0)
10138     return 0;
10139
10140   vec_validate (mask, sizeof (*ip) - 1);
10141
10142   ip = (ip6_header_t *) mask;
10143
10144 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10145   foreach_ip6_proto_field;
10146 #undef _
10147
10148   ip_version_traffic_class_and_flow_label = 0;
10149
10150   if (version)
10151     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10152
10153   if (traffic_class)
10154     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10155
10156   if (flow_label)
10157     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10158
10159   ip->ip_version_traffic_class_and_flow_label =
10160     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10161
10162   *maskp = mask;
10163   return 1;
10164 }
10165
10166 uword
10167 unformat_l3_mask (unformat_input_t * input, va_list * args)
10168 {
10169   u8 **maskp = va_arg (*args, u8 **);
10170
10171   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10172     {
10173       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10174         return 1;
10175       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10176         return 1;
10177       else
10178         break;
10179     }
10180   return 0;
10181 }
10182
10183 uword
10184 unformat_l2_mask (unformat_input_t * input, va_list * args)
10185 {
10186   u8 **maskp = va_arg (*args, u8 **);
10187   u8 *mask = 0;
10188   u8 src = 0;
10189   u8 dst = 0;
10190   u8 proto = 0;
10191   u8 tag1 = 0;
10192   u8 tag2 = 0;
10193   u8 ignore_tag1 = 0;
10194   u8 ignore_tag2 = 0;
10195   u8 cos1 = 0;
10196   u8 cos2 = 0;
10197   u8 dot1q = 0;
10198   u8 dot1ad = 0;
10199   int len = 14;
10200
10201   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10202     {
10203       if (unformat (input, "src"))
10204         src = 1;
10205       else if (unformat (input, "dst"))
10206         dst = 1;
10207       else if (unformat (input, "proto"))
10208         proto = 1;
10209       else if (unformat (input, "tag1"))
10210         tag1 = 1;
10211       else if (unformat (input, "tag2"))
10212         tag2 = 1;
10213       else if (unformat (input, "ignore-tag1"))
10214         ignore_tag1 = 1;
10215       else if (unformat (input, "ignore-tag2"))
10216         ignore_tag2 = 1;
10217       else if (unformat (input, "cos1"))
10218         cos1 = 1;
10219       else if (unformat (input, "cos2"))
10220         cos2 = 1;
10221       else if (unformat (input, "dot1q"))
10222         dot1q = 1;
10223       else if (unformat (input, "dot1ad"))
10224         dot1ad = 1;
10225       else
10226         break;
10227     }
10228   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10229        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10230     return 0;
10231
10232   if (tag1 || ignore_tag1 || cos1 || dot1q)
10233     len = 18;
10234   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10235     len = 22;
10236
10237   vec_validate (mask, len - 1);
10238
10239   if (dst)
10240     memset (mask, 0xff, 6);
10241
10242   if (src)
10243     memset (mask + 6, 0xff, 6);
10244
10245   if (tag2 || dot1ad)
10246     {
10247       /* inner vlan tag */
10248       if (tag2)
10249         {
10250           mask[19] = 0xff;
10251           mask[18] = 0x0f;
10252         }
10253       if (cos2)
10254         mask[18] |= 0xe0;
10255       if (proto)
10256         mask[21] = mask[20] = 0xff;
10257       if (tag1)
10258         {
10259           mask[15] = 0xff;
10260           mask[14] = 0x0f;
10261         }
10262       if (cos1)
10263         mask[14] |= 0xe0;
10264       *maskp = mask;
10265       return 1;
10266     }
10267   if (tag1 | dot1q)
10268     {
10269       if (tag1)
10270         {
10271           mask[15] = 0xff;
10272           mask[14] = 0x0f;
10273         }
10274       if (cos1)
10275         mask[14] |= 0xe0;
10276       if (proto)
10277         mask[16] = mask[17] = 0xff;
10278
10279       *maskp = mask;
10280       return 1;
10281     }
10282   if (cos2)
10283     mask[18] |= 0xe0;
10284   if (cos1)
10285     mask[14] |= 0xe0;
10286   if (proto)
10287     mask[12] = mask[13] = 0xff;
10288
10289   *maskp = mask;
10290   return 1;
10291 }
10292
10293 uword
10294 unformat_classify_mask (unformat_input_t * input, va_list * args)
10295 {
10296   u8 **maskp = va_arg (*args, u8 **);
10297   u32 *skipp = va_arg (*args, u32 *);
10298   u32 *matchp = va_arg (*args, u32 *);
10299   u32 match;
10300   u8 *mask = 0;
10301   u8 *l2 = 0;
10302   u8 *l3 = 0;
10303   u8 *l4 = 0;
10304   int i;
10305
10306   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10307     {
10308       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10309         ;
10310       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10311         ;
10312       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10313         ;
10314       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10315         ;
10316       else
10317         break;
10318     }
10319
10320   if (l4 && !l3)
10321     {
10322       vec_free (mask);
10323       vec_free (l2);
10324       vec_free (l4);
10325       return 0;
10326     }
10327
10328   if (mask || l2 || l3 || l4)
10329     {
10330       if (l2 || l3 || l4)
10331         {
10332           /* "With a free Ethernet header in every package" */
10333           if (l2 == 0)
10334             vec_validate (l2, 13);
10335           mask = l2;
10336           if (vec_len (l3))
10337             {
10338               vec_append (mask, l3);
10339               vec_free (l3);
10340             }
10341           if (vec_len (l4))
10342             {
10343               vec_append (mask, l4);
10344               vec_free (l4);
10345             }
10346         }
10347
10348       /* Scan forward looking for the first significant mask octet */
10349       for (i = 0; i < vec_len (mask); i++)
10350         if (mask[i])
10351           break;
10352
10353       /* compute (skip, match) params */
10354       *skipp = i / sizeof (u32x4);
10355       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10356
10357       /* Pad mask to an even multiple of the vector size */
10358       while (vec_len (mask) % sizeof (u32x4))
10359         vec_add1 (mask, 0);
10360
10361       match = vec_len (mask) / sizeof (u32x4);
10362
10363       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10364         {
10365           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10366           if (*tmp || *(tmp + 1))
10367             break;
10368           match--;
10369         }
10370       if (match == 0)
10371         clib_warning ("BUG: match 0");
10372
10373       _vec_len (mask) = match * sizeof (u32x4);
10374
10375       *matchp = match;
10376       *maskp = mask;
10377
10378       return 1;
10379     }
10380
10381   return 0;
10382 }
10383 #endif /* VPP_API_TEST_BUILTIN */
10384
10385 #define foreach_l2_next                         \
10386 _(drop, DROP)                                   \
10387 _(ethernet, ETHERNET_INPUT)                     \
10388 _(ip4, IP4_INPUT)                               \
10389 _(ip6, IP6_INPUT)
10390
10391 uword
10392 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10393 {
10394   u32 *miss_next_indexp = va_arg (*args, u32 *);
10395   u32 next_index = 0;
10396   u32 tmp;
10397
10398 #define _(n,N) \
10399   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10400   foreach_l2_next;
10401 #undef _
10402
10403   if (unformat (input, "%d", &tmp))
10404     {
10405       next_index = tmp;
10406       goto out;
10407     }
10408
10409   return 0;
10410
10411 out:
10412   *miss_next_indexp = next_index;
10413   return 1;
10414 }
10415
10416 #define foreach_ip_next                         \
10417 _(drop, DROP)                                   \
10418 _(local, LOCAL)                                 \
10419 _(rewrite, REWRITE)
10420
10421 uword
10422 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10423 {
10424   u32 *miss_next_indexp = va_arg (*args, u32 *);
10425   u32 next_index = 0;
10426   u32 tmp;
10427
10428 #define _(n,N) \
10429   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10430   foreach_ip_next;
10431 #undef _
10432
10433   if (unformat (input, "%d", &tmp))
10434     {
10435       next_index = tmp;
10436       goto out;
10437     }
10438
10439   return 0;
10440
10441 out:
10442   *miss_next_indexp = next_index;
10443   return 1;
10444 }
10445
10446 #define foreach_acl_next                        \
10447 _(deny, DENY)
10448
10449 uword
10450 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10451 {
10452   u32 *miss_next_indexp = va_arg (*args, u32 *);
10453   u32 next_index = 0;
10454   u32 tmp;
10455
10456 #define _(n,N) \
10457   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10458   foreach_acl_next;
10459 #undef _
10460
10461   if (unformat (input, "permit"))
10462     {
10463       next_index = ~0;
10464       goto out;
10465     }
10466   else if (unformat (input, "%d", &tmp))
10467     {
10468       next_index = tmp;
10469       goto out;
10470     }
10471
10472   return 0;
10473
10474 out:
10475   *miss_next_indexp = next_index;
10476   return 1;
10477 }
10478
10479 uword
10480 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10481 {
10482   u32 *r = va_arg (*args, u32 *);
10483
10484   if (unformat (input, "conform-color"))
10485     *r = POLICE_CONFORM;
10486   else if (unformat (input, "exceed-color"))
10487     *r = POLICE_EXCEED;
10488   else
10489     return 0;
10490
10491   return 1;
10492 }
10493
10494 static int
10495 api_classify_add_del_table (vat_main_t * vam)
10496 {
10497   unformat_input_t *i = vam->input;
10498   vl_api_classify_add_del_table_t *mp;
10499
10500   u32 nbuckets = 2;
10501   u32 skip = ~0;
10502   u32 match = ~0;
10503   int is_add = 1;
10504   int del_chain = 0;
10505   u32 table_index = ~0;
10506   u32 next_table_index = ~0;
10507   u32 miss_next_index = ~0;
10508   u32 memory_size = 32 << 20;
10509   u8 *mask = 0;
10510   u32 current_data_flag = 0;
10511   int current_data_offset = 0;
10512   int ret;
10513
10514   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10515     {
10516       if (unformat (i, "del"))
10517         is_add = 0;
10518       else if (unformat (i, "del-chain"))
10519         {
10520           is_add = 0;
10521           del_chain = 1;
10522         }
10523       else if (unformat (i, "buckets %d", &nbuckets))
10524         ;
10525       else if (unformat (i, "memory_size %d", &memory_size))
10526         ;
10527       else if (unformat (i, "skip %d", &skip))
10528         ;
10529       else if (unformat (i, "match %d", &match))
10530         ;
10531       else if (unformat (i, "table %d", &table_index))
10532         ;
10533       else if (unformat (i, "mask %U", unformat_classify_mask,
10534                          &mask, &skip, &match))
10535         ;
10536       else if (unformat (i, "next-table %d", &next_table_index))
10537         ;
10538       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10539                          &miss_next_index))
10540         ;
10541       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10542                          &miss_next_index))
10543         ;
10544       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10545                          &miss_next_index))
10546         ;
10547       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10548         ;
10549       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10550         ;
10551       else
10552         break;
10553     }
10554
10555   if (is_add && mask == 0)
10556     {
10557       errmsg ("Mask required");
10558       return -99;
10559     }
10560
10561   if (is_add && skip == ~0)
10562     {
10563       errmsg ("skip count required");
10564       return -99;
10565     }
10566
10567   if (is_add && match == ~0)
10568     {
10569       errmsg ("match count required");
10570       return -99;
10571     }
10572
10573   if (!is_add && table_index == ~0)
10574     {
10575       errmsg ("table index required for delete");
10576       return -99;
10577     }
10578
10579   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10580
10581   mp->is_add = is_add;
10582   mp->del_chain = del_chain;
10583   mp->table_index = ntohl (table_index);
10584   mp->nbuckets = ntohl (nbuckets);
10585   mp->memory_size = ntohl (memory_size);
10586   mp->skip_n_vectors = ntohl (skip);
10587   mp->match_n_vectors = ntohl (match);
10588   mp->next_table_index = ntohl (next_table_index);
10589   mp->miss_next_index = ntohl (miss_next_index);
10590   mp->current_data_flag = ntohl (current_data_flag);
10591   mp->current_data_offset = ntohl (current_data_offset);
10592   clib_memcpy (mp->mask, mask, vec_len (mask));
10593
10594   vec_free (mask);
10595
10596   S (mp);
10597   W (ret);
10598   return ret;
10599 }
10600
10601 #if VPP_API_TEST_BUILTIN == 0
10602 uword
10603 unformat_l4_match (unformat_input_t * input, va_list * args)
10604 {
10605   u8 **matchp = va_arg (*args, u8 **);
10606
10607   u8 *proto_header = 0;
10608   int src_port = 0;
10609   int dst_port = 0;
10610
10611   tcpudp_header_t h;
10612
10613   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10614     {
10615       if (unformat (input, "src_port %d", &src_port))
10616         ;
10617       else if (unformat (input, "dst_port %d", &dst_port))
10618         ;
10619       else
10620         return 0;
10621     }
10622
10623   h.src_port = clib_host_to_net_u16 (src_port);
10624   h.dst_port = clib_host_to_net_u16 (dst_port);
10625   vec_validate (proto_header, sizeof (h) - 1);
10626   memcpy (proto_header, &h, sizeof (h));
10627
10628   *matchp = proto_header;
10629
10630   return 1;
10631 }
10632
10633 uword
10634 unformat_ip4_match (unformat_input_t * input, va_list * args)
10635 {
10636   u8 **matchp = va_arg (*args, u8 **);
10637   u8 *match = 0;
10638   ip4_header_t *ip;
10639   int version = 0;
10640   u32 version_val;
10641   int hdr_length = 0;
10642   u32 hdr_length_val;
10643   int src = 0, dst = 0;
10644   ip4_address_t src_val, dst_val;
10645   int proto = 0;
10646   u32 proto_val;
10647   int tos = 0;
10648   u32 tos_val;
10649   int length = 0;
10650   u32 length_val;
10651   int fragment_id = 0;
10652   u32 fragment_id_val;
10653   int ttl = 0;
10654   int ttl_val;
10655   int checksum = 0;
10656   u32 checksum_val;
10657
10658   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10659     {
10660       if (unformat (input, "version %d", &version_val))
10661         version = 1;
10662       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10663         hdr_length = 1;
10664       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10665         src = 1;
10666       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10667         dst = 1;
10668       else if (unformat (input, "proto %d", &proto_val))
10669         proto = 1;
10670       else if (unformat (input, "tos %d", &tos_val))
10671         tos = 1;
10672       else if (unformat (input, "length %d", &length_val))
10673         length = 1;
10674       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10675         fragment_id = 1;
10676       else if (unformat (input, "ttl %d", &ttl_val))
10677         ttl = 1;
10678       else if (unformat (input, "checksum %d", &checksum_val))
10679         checksum = 1;
10680       else
10681         break;
10682     }
10683
10684   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10685       + ttl + checksum == 0)
10686     return 0;
10687
10688   /*
10689    * Aligned because we use the real comparison functions
10690    */
10691   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10692
10693   ip = (ip4_header_t *) match;
10694
10695   /* These are realistically matched in practice */
10696   if (src)
10697     ip->src_address.as_u32 = src_val.as_u32;
10698
10699   if (dst)
10700     ip->dst_address.as_u32 = dst_val.as_u32;
10701
10702   if (proto)
10703     ip->protocol = proto_val;
10704
10705
10706   /* These are not, but they're included for completeness */
10707   if (version)
10708     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10709
10710   if (hdr_length)
10711     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10712
10713   if (tos)
10714     ip->tos = tos_val;
10715
10716   if (length)
10717     ip->length = clib_host_to_net_u16 (length_val);
10718
10719   if (ttl)
10720     ip->ttl = ttl_val;
10721
10722   if (checksum)
10723     ip->checksum = clib_host_to_net_u16 (checksum_val);
10724
10725   *matchp = match;
10726   return 1;
10727 }
10728
10729 uword
10730 unformat_ip6_match (unformat_input_t * input, va_list * args)
10731 {
10732   u8 **matchp = va_arg (*args, u8 **);
10733   u8 *match = 0;
10734   ip6_header_t *ip;
10735   int version = 0;
10736   u32 version_val;
10737   u8 traffic_class = 0;
10738   u32 traffic_class_val = 0;
10739   u8 flow_label = 0;
10740   u8 flow_label_val;
10741   int src = 0, dst = 0;
10742   ip6_address_t src_val, dst_val;
10743   int proto = 0;
10744   u32 proto_val;
10745   int payload_length = 0;
10746   u32 payload_length_val;
10747   int hop_limit = 0;
10748   int hop_limit_val;
10749   u32 ip_version_traffic_class_and_flow_label;
10750
10751   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10752     {
10753       if (unformat (input, "version %d", &version_val))
10754         version = 1;
10755       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10756         traffic_class = 1;
10757       else if (unformat (input, "flow_label %d", &flow_label_val))
10758         flow_label = 1;
10759       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10760         src = 1;
10761       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10762         dst = 1;
10763       else if (unformat (input, "proto %d", &proto_val))
10764         proto = 1;
10765       else if (unformat (input, "payload_length %d", &payload_length_val))
10766         payload_length = 1;
10767       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10768         hop_limit = 1;
10769       else
10770         break;
10771     }
10772
10773   if (version + traffic_class + flow_label + src + dst + proto +
10774       payload_length + hop_limit == 0)
10775     return 0;
10776
10777   /*
10778    * Aligned because we use the real comparison functions
10779    */
10780   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10781
10782   ip = (ip6_header_t *) match;
10783
10784   if (src)
10785     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10786
10787   if (dst)
10788     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10789
10790   if (proto)
10791     ip->protocol = proto_val;
10792
10793   ip_version_traffic_class_and_flow_label = 0;
10794
10795   if (version)
10796     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10797
10798   if (traffic_class)
10799     ip_version_traffic_class_and_flow_label |=
10800       (traffic_class_val & 0xFF) << 20;
10801
10802   if (flow_label)
10803     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10804
10805   ip->ip_version_traffic_class_and_flow_label =
10806     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10807
10808   if (payload_length)
10809     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10810
10811   if (hop_limit)
10812     ip->hop_limit = hop_limit_val;
10813
10814   *matchp = match;
10815   return 1;
10816 }
10817
10818 uword
10819 unformat_l3_match (unformat_input_t * input, va_list * args)
10820 {
10821   u8 **matchp = va_arg (*args, u8 **);
10822
10823   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10824     {
10825       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10826         return 1;
10827       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10828         return 1;
10829       else
10830         break;
10831     }
10832   return 0;
10833 }
10834
10835 uword
10836 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10837 {
10838   u8 *tagp = va_arg (*args, u8 *);
10839   u32 tag;
10840
10841   if (unformat (input, "%d", &tag))
10842     {
10843       tagp[0] = (tag >> 8) & 0x0F;
10844       tagp[1] = tag & 0xFF;
10845       return 1;
10846     }
10847
10848   return 0;
10849 }
10850
10851 uword
10852 unformat_l2_match (unformat_input_t * input, va_list * args)
10853 {
10854   u8 **matchp = va_arg (*args, u8 **);
10855   u8 *match = 0;
10856   u8 src = 0;
10857   u8 src_val[6];
10858   u8 dst = 0;
10859   u8 dst_val[6];
10860   u8 proto = 0;
10861   u16 proto_val;
10862   u8 tag1 = 0;
10863   u8 tag1_val[2];
10864   u8 tag2 = 0;
10865   u8 tag2_val[2];
10866   int len = 14;
10867   u8 ignore_tag1 = 0;
10868   u8 ignore_tag2 = 0;
10869   u8 cos1 = 0;
10870   u8 cos2 = 0;
10871   u32 cos1_val = 0;
10872   u32 cos2_val = 0;
10873
10874   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10875     {
10876       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10877         src = 1;
10878       else
10879         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10880         dst = 1;
10881       else if (unformat (input, "proto %U",
10882                          unformat_ethernet_type_host_byte_order, &proto_val))
10883         proto = 1;
10884       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10885         tag1 = 1;
10886       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10887         tag2 = 1;
10888       else if (unformat (input, "ignore-tag1"))
10889         ignore_tag1 = 1;
10890       else if (unformat (input, "ignore-tag2"))
10891         ignore_tag2 = 1;
10892       else if (unformat (input, "cos1 %d", &cos1_val))
10893         cos1 = 1;
10894       else if (unformat (input, "cos2 %d", &cos2_val))
10895         cos2 = 1;
10896       else
10897         break;
10898     }
10899   if ((src + dst + proto + tag1 + tag2 +
10900        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10901     return 0;
10902
10903   if (tag1 || ignore_tag1 || cos1)
10904     len = 18;
10905   if (tag2 || ignore_tag2 || cos2)
10906     len = 22;
10907
10908   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10909
10910   if (dst)
10911     clib_memcpy (match, dst_val, 6);
10912
10913   if (src)
10914     clib_memcpy (match + 6, src_val, 6);
10915
10916   if (tag2)
10917     {
10918       /* inner vlan tag */
10919       match[19] = tag2_val[1];
10920       match[18] = tag2_val[0];
10921       if (cos2)
10922         match[18] |= (cos2_val & 0x7) << 5;
10923       if (proto)
10924         {
10925           match[21] = proto_val & 0xff;
10926           match[20] = proto_val >> 8;
10927         }
10928       if (tag1)
10929         {
10930           match[15] = tag1_val[1];
10931           match[14] = tag1_val[0];
10932         }
10933       if (cos1)
10934         match[14] |= (cos1_val & 0x7) << 5;
10935       *matchp = match;
10936       return 1;
10937     }
10938   if (tag1)
10939     {
10940       match[15] = tag1_val[1];
10941       match[14] = tag1_val[0];
10942       if (proto)
10943         {
10944           match[17] = proto_val & 0xff;
10945           match[16] = proto_val >> 8;
10946         }
10947       if (cos1)
10948         match[14] |= (cos1_val & 0x7) << 5;
10949
10950       *matchp = match;
10951       return 1;
10952     }
10953   if (cos2)
10954     match[18] |= (cos2_val & 0x7) << 5;
10955   if (cos1)
10956     match[14] |= (cos1_val & 0x7) << 5;
10957   if (proto)
10958     {
10959       match[13] = proto_val & 0xff;
10960       match[12] = proto_val >> 8;
10961     }
10962
10963   *matchp = match;
10964   return 1;
10965 }
10966 #endif
10967
10968 uword
10969 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10970 {
10971   u8 **matchp = va_arg (*args, u8 **);
10972   u32 skip_n_vectors = va_arg (*args, u32);
10973   u32 match_n_vectors = va_arg (*args, u32);
10974
10975   u8 *match = 0;
10976   u8 *l2 = 0;
10977   u8 *l3 = 0;
10978   u8 *l4 = 0;
10979
10980   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10981     {
10982       if (unformat (input, "hex %U", unformat_hex_string, &match))
10983         ;
10984       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10985         ;
10986       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10987         ;
10988       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10989         ;
10990       else
10991         break;
10992     }
10993
10994   if (l4 && !l3)
10995     {
10996       vec_free (match);
10997       vec_free (l2);
10998       vec_free (l4);
10999       return 0;
11000     }
11001
11002   if (match || l2 || l3 || l4)
11003     {
11004       if (l2 || l3 || l4)
11005         {
11006           /* "Win a free Ethernet header in every packet" */
11007           if (l2 == 0)
11008             vec_validate_aligned (l2, 13, sizeof (u32x4));
11009           match = l2;
11010           if (vec_len (l3))
11011             {
11012               vec_append_aligned (match, l3, sizeof (u32x4));
11013               vec_free (l3);
11014             }
11015           if (vec_len (l4))
11016             {
11017               vec_append_aligned (match, l4, sizeof (u32x4));
11018               vec_free (l4);
11019             }
11020         }
11021
11022       /* Make sure the vector is big enough even if key is all 0's */
11023       vec_validate_aligned
11024         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11025          sizeof (u32x4));
11026
11027       /* Set size, include skipped vectors */
11028       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11029
11030       *matchp = match;
11031
11032       return 1;
11033     }
11034
11035   return 0;
11036 }
11037
11038 static int
11039 api_classify_add_del_session (vat_main_t * vam)
11040 {
11041   unformat_input_t *i = vam->input;
11042   vl_api_classify_add_del_session_t *mp;
11043   int is_add = 1;
11044   u32 table_index = ~0;
11045   u32 hit_next_index = ~0;
11046   u32 opaque_index = ~0;
11047   u8 *match = 0;
11048   i32 advance = 0;
11049   u32 skip_n_vectors = 0;
11050   u32 match_n_vectors = 0;
11051   u32 action = 0;
11052   u32 metadata = 0;
11053   int ret;
11054
11055   /*
11056    * Warning: you have to supply skip_n and match_n
11057    * because the API client cant simply look at the classify
11058    * table object.
11059    */
11060
11061   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11062     {
11063       if (unformat (i, "del"))
11064         is_add = 0;
11065       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11066                          &hit_next_index))
11067         ;
11068       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11069                          &hit_next_index))
11070         ;
11071       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11072                          &hit_next_index))
11073         ;
11074       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11075         ;
11076       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11077         ;
11078       else if (unformat (i, "opaque-index %d", &opaque_index))
11079         ;
11080       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11081         ;
11082       else if (unformat (i, "match_n %d", &match_n_vectors))
11083         ;
11084       else if (unformat (i, "match %U", api_unformat_classify_match,
11085                          &match, skip_n_vectors, match_n_vectors))
11086         ;
11087       else if (unformat (i, "advance %d", &advance))
11088         ;
11089       else if (unformat (i, "table-index %d", &table_index))
11090         ;
11091       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11092         action = 1;
11093       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11094         action = 2;
11095       else if (unformat (i, "action %d", &action))
11096         ;
11097       else if (unformat (i, "metadata %d", &metadata))
11098         ;
11099       else
11100         break;
11101     }
11102
11103   if (table_index == ~0)
11104     {
11105       errmsg ("Table index required");
11106       return -99;
11107     }
11108
11109   if (is_add && match == 0)
11110     {
11111       errmsg ("Match value required");
11112       return -99;
11113     }
11114
11115   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11116
11117   mp->is_add = is_add;
11118   mp->table_index = ntohl (table_index);
11119   mp->hit_next_index = ntohl (hit_next_index);
11120   mp->opaque_index = ntohl (opaque_index);
11121   mp->advance = ntohl (advance);
11122   mp->action = action;
11123   mp->metadata = ntohl (metadata);
11124   clib_memcpy (mp->match, match, vec_len (match));
11125   vec_free (match);
11126
11127   S (mp);
11128   W (ret);
11129   return ret;
11130 }
11131
11132 static int
11133 api_classify_set_interface_ip_table (vat_main_t * vam)
11134 {
11135   unformat_input_t *i = vam->input;
11136   vl_api_classify_set_interface_ip_table_t *mp;
11137   u32 sw_if_index;
11138   int sw_if_index_set;
11139   u32 table_index = ~0;
11140   u8 is_ipv6 = 0;
11141   int ret;
11142
11143   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11144     {
11145       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11146         sw_if_index_set = 1;
11147       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11148         sw_if_index_set = 1;
11149       else if (unformat (i, "table %d", &table_index))
11150         ;
11151       else
11152         {
11153           clib_warning ("parse error '%U'", format_unformat_error, i);
11154           return -99;
11155         }
11156     }
11157
11158   if (sw_if_index_set == 0)
11159     {
11160       errmsg ("missing interface name or sw_if_index");
11161       return -99;
11162     }
11163
11164
11165   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11166
11167   mp->sw_if_index = ntohl (sw_if_index);
11168   mp->table_index = ntohl (table_index);
11169   mp->is_ipv6 = is_ipv6;
11170
11171   S (mp);
11172   W (ret);
11173   return ret;
11174 }
11175
11176 static int
11177 api_classify_set_interface_l2_tables (vat_main_t * vam)
11178 {
11179   unformat_input_t *i = vam->input;
11180   vl_api_classify_set_interface_l2_tables_t *mp;
11181   u32 sw_if_index;
11182   int sw_if_index_set;
11183   u32 ip4_table_index = ~0;
11184   u32 ip6_table_index = ~0;
11185   u32 other_table_index = ~0;
11186   u32 is_input = 1;
11187   int ret;
11188
11189   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11190     {
11191       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11192         sw_if_index_set = 1;
11193       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11194         sw_if_index_set = 1;
11195       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11196         ;
11197       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11198         ;
11199       else if (unformat (i, "other-table %d", &other_table_index))
11200         ;
11201       else if (unformat (i, "is-input %d", &is_input))
11202         ;
11203       else
11204         {
11205           clib_warning ("parse error '%U'", format_unformat_error, i);
11206           return -99;
11207         }
11208     }
11209
11210   if (sw_if_index_set == 0)
11211     {
11212       errmsg ("missing interface name or sw_if_index");
11213       return -99;
11214     }
11215
11216
11217   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11218
11219   mp->sw_if_index = ntohl (sw_if_index);
11220   mp->ip4_table_index = ntohl (ip4_table_index);
11221   mp->ip6_table_index = ntohl (ip6_table_index);
11222   mp->other_table_index = ntohl (other_table_index);
11223   mp->is_input = (u8) is_input;
11224
11225   S (mp);
11226   W (ret);
11227   return ret;
11228 }
11229
11230 static int
11231 api_set_ipfix_exporter (vat_main_t * vam)
11232 {
11233   unformat_input_t *i = vam->input;
11234   vl_api_set_ipfix_exporter_t *mp;
11235   ip4_address_t collector_address;
11236   u8 collector_address_set = 0;
11237   u32 collector_port = ~0;
11238   ip4_address_t src_address;
11239   u8 src_address_set = 0;
11240   u32 vrf_id = ~0;
11241   u32 path_mtu = ~0;
11242   u32 template_interval = ~0;
11243   u8 udp_checksum = 0;
11244   int ret;
11245
11246   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11247     {
11248       if (unformat (i, "collector_address %U", unformat_ip4_address,
11249                     &collector_address))
11250         collector_address_set = 1;
11251       else if (unformat (i, "collector_port %d", &collector_port))
11252         ;
11253       else if (unformat (i, "src_address %U", unformat_ip4_address,
11254                          &src_address))
11255         src_address_set = 1;
11256       else if (unformat (i, "vrf_id %d", &vrf_id))
11257         ;
11258       else if (unformat (i, "path_mtu %d", &path_mtu))
11259         ;
11260       else if (unformat (i, "template_interval %d", &template_interval))
11261         ;
11262       else if (unformat (i, "udp_checksum"))
11263         udp_checksum = 1;
11264       else
11265         break;
11266     }
11267
11268   if (collector_address_set == 0)
11269     {
11270       errmsg ("collector_address required");
11271       return -99;
11272     }
11273
11274   if (src_address_set == 0)
11275     {
11276       errmsg ("src_address required");
11277       return -99;
11278     }
11279
11280   M (SET_IPFIX_EXPORTER, mp);
11281
11282   memcpy (mp->collector_address, collector_address.data,
11283           sizeof (collector_address.data));
11284   mp->collector_port = htons ((u16) collector_port);
11285   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11286   mp->vrf_id = htonl (vrf_id);
11287   mp->path_mtu = htonl (path_mtu);
11288   mp->template_interval = htonl (template_interval);
11289   mp->udp_checksum = udp_checksum;
11290
11291   S (mp);
11292   W (ret);
11293   return ret;
11294 }
11295
11296 static int
11297 api_set_ipfix_classify_stream (vat_main_t * vam)
11298 {
11299   unformat_input_t *i = vam->input;
11300   vl_api_set_ipfix_classify_stream_t *mp;
11301   u32 domain_id = 0;
11302   u32 src_port = UDP_DST_PORT_ipfix;
11303   int ret;
11304
11305   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11306     {
11307       if (unformat (i, "domain %d", &domain_id))
11308         ;
11309       else if (unformat (i, "src_port %d", &src_port))
11310         ;
11311       else
11312         {
11313           errmsg ("unknown input `%U'", format_unformat_error, i);
11314           return -99;
11315         }
11316     }
11317
11318   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11319
11320   mp->domain_id = htonl (domain_id);
11321   mp->src_port = htons ((u16) src_port);
11322
11323   S (mp);
11324   W (ret);
11325   return ret;
11326 }
11327
11328 static int
11329 api_ipfix_classify_table_add_del (vat_main_t * vam)
11330 {
11331   unformat_input_t *i = vam->input;
11332   vl_api_ipfix_classify_table_add_del_t *mp;
11333   int is_add = -1;
11334   u32 classify_table_index = ~0;
11335   u8 ip_version = 0;
11336   u8 transport_protocol = 255;
11337   int ret;
11338
11339   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11340     {
11341       if (unformat (i, "add"))
11342         is_add = 1;
11343       else if (unformat (i, "del"))
11344         is_add = 0;
11345       else if (unformat (i, "table %d", &classify_table_index))
11346         ;
11347       else if (unformat (i, "ip4"))
11348         ip_version = 4;
11349       else if (unformat (i, "ip6"))
11350         ip_version = 6;
11351       else if (unformat (i, "tcp"))
11352         transport_protocol = 6;
11353       else if (unformat (i, "udp"))
11354         transport_protocol = 17;
11355       else
11356         {
11357           errmsg ("unknown input `%U'", format_unformat_error, i);
11358           return -99;
11359         }
11360     }
11361
11362   if (is_add == -1)
11363     {
11364       errmsg ("expecting: add|del");
11365       return -99;
11366     }
11367   if (classify_table_index == ~0)
11368     {
11369       errmsg ("classifier table not specified");
11370       return -99;
11371     }
11372   if (ip_version == 0)
11373     {
11374       errmsg ("IP version not specified");
11375       return -99;
11376     }
11377
11378   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11379
11380   mp->is_add = is_add;
11381   mp->table_id = htonl (classify_table_index);
11382   mp->ip_version = ip_version;
11383   mp->transport_protocol = transport_protocol;
11384
11385   S (mp);
11386   W (ret);
11387   return ret;
11388 }
11389
11390 static int
11391 api_get_node_index (vat_main_t * vam)
11392 {
11393   unformat_input_t *i = vam->input;
11394   vl_api_get_node_index_t *mp;
11395   u8 *name = 0;
11396   int ret;
11397
11398   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11399     {
11400       if (unformat (i, "node %s", &name))
11401         ;
11402       else
11403         break;
11404     }
11405   if (name == 0)
11406     {
11407       errmsg ("node name required");
11408       return -99;
11409     }
11410   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11411     {
11412       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11413       return -99;
11414     }
11415
11416   M (GET_NODE_INDEX, mp);
11417   clib_memcpy (mp->node_name, name, vec_len (name));
11418   vec_free (name);
11419
11420   S (mp);
11421   W (ret);
11422   return ret;
11423 }
11424
11425 static int
11426 api_get_next_index (vat_main_t * vam)
11427 {
11428   unformat_input_t *i = vam->input;
11429   vl_api_get_next_index_t *mp;
11430   u8 *node_name = 0, *next_node_name = 0;
11431   int ret;
11432
11433   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11434     {
11435       if (unformat (i, "node-name %s", &node_name))
11436         ;
11437       else if (unformat (i, "next-node-name %s", &next_node_name))
11438         break;
11439     }
11440
11441   if (node_name == 0)
11442     {
11443       errmsg ("node name required");
11444       return -99;
11445     }
11446   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11447     {
11448       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11449       return -99;
11450     }
11451
11452   if (next_node_name == 0)
11453     {
11454       errmsg ("next node name required");
11455       return -99;
11456     }
11457   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11458     {
11459       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11460       return -99;
11461     }
11462
11463   M (GET_NEXT_INDEX, mp);
11464   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11465   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11466   vec_free (node_name);
11467   vec_free (next_node_name);
11468
11469   S (mp);
11470   W (ret);
11471   return ret;
11472 }
11473
11474 static int
11475 api_add_node_next (vat_main_t * vam)
11476 {
11477   unformat_input_t *i = vam->input;
11478   vl_api_add_node_next_t *mp;
11479   u8 *name = 0;
11480   u8 *next = 0;
11481   int ret;
11482
11483   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11484     {
11485       if (unformat (i, "node %s", &name))
11486         ;
11487       else if (unformat (i, "next %s", &next))
11488         ;
11489       else
11490         break;
11491     }
11492   if (name == 0)
11493     {
11494       errmsg ("node name required");
11495       return -99;
11496     }
11497   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11498     {
11499       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11500       return -99;
11501     }
11502   if (next == 0)
11503     {
11504       errmsg ("next node required");
11505       return -99;
11506     }
11507   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11508     {
11509       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11510       return -99;
11511     }
11512
11513   M (ADD_NODE_NEXT, mp);
11514   clib_memcpy (mp->node_name, name, vec_len (name));
11515   clib_memcpy (mp->next_name, next, vec_len (next));
11516   vec_free (name);
11517   vec_free (next);
11518
11519   S (mp);
11520   W (ret);
11521   return ret;
11522 }
11523
11524 static int
11525 api_l2tpv3_create_tunnel (vat_main_t * vam)
11526 {
11527   unformat_input_t *i = vam->input;
11528   ip6_address_t client_address, our_address;
11529   int client_address_set = 0;
11530   int our_address_set = 0;
11531   u32 local_session_id = 0;
11532   u32 remote_session_id = 0;
11533   u64 local_cookie = 0;
11534   u64 remote_cookie = 0;
11535   u8 l2_sublayer_present = 0;
11536   vl_api_l2tpv3_create_tunnel_t *mp;
11537   int ret;
11538
11539   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11540     {
11541       if (unformat (i, "client_address %U", unformat_ip6_address,
11542                     &client_address))
11543         client_address_set = 1;
11544       else if (unformat (i, "our_address %U", unformat_ip6_address,
11545                          &our_address))
11546         our_address_set = 1;
11547       else if (unformat (i, "local_session_id %d", &local_session_id))
11548         ;
11549       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11550         ;
11551       else if (unformat (i, "local_cookie %lld", &local_cookie))
11552         ;
11553       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11554         ;
11555       else if (unformat (i, "l2-sublayer-present"))
11556         l2_sublayer_present = 1;
11557       else
11558         break;
11559     }
11560
11561   if (client_address_set == 0)
11562     {
11563       errmsg ("client_address required");
11564       return -99;
11565     }
11566
11567   if (our_address_set == 0)
11568     {
11569       errmsg ("our_address required");
11570       return -99;
11571     }
11572
11573   M (L2TPV3_CREATE_TUNNEL, mp);
11574
11575   clib_memcpy (mp->client_address, client_address.as_u8,
11576                sizeof (mp->client_address));
11577
11578   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11579
11580   mp->local_session_id = ntohl (local_session_id);
11581   mp->remote_session_id = ntohl (remote_session_id);
11582   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11583   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11584   mp->l2_sublayer_present = l2_sublayer_present;
11585   mp->is_ipv6 = 1;
11586
11587   S (mp);
11588   W (ret);
11589   return ret;
11590 }
11591
11592 static int
11593 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11594 {
11595   unformat_input_t *i = vam->input;
11596   u32 sw_if_index;
11597   u8 sw_if_index_set = 0;
11598   u64 new_local_cookie = 0;
11599   u64 new_remote_cookie = 0;
11600   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11601   int ret;
11602
11603   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11604     {
11605       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11606         sw_if_index_set = 1;
11607       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11608         sw_if_index_set = 1;
11609       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11610         ;
11611       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11612         ;
11613       else
11614         break;
11615     }
11616
11617   if (sw_if_index_set == 0)
11618     {
11619       errmsg ("missing interface name or sw_if_index");
11620       return -99;
11621     }
11622
11623   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11624
11625   mp->sw_if_index = ntohl (sw_if_index);
11626   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11627   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11628
11629   S (mp);
11630   W (ret);
11631   return ret;
11632 }
11633
11634 static int
11635 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11636 {
11637   unformat_input_t *i = vam->input;
11638   vl_api_l2tpv3_interface_enable_disable_t *mp;
11639   u32 sw_if_index;
11640   u8 sw_if_index_set = 0;
11641   u8 enable_disable = 1;
11642   int ret;
11643
11644   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11645     {
11646       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11647         sw_if_index_set = 1;
11648       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11649         sw_if_index_set = 1;
11650       else if (unformat (i, "enable"))
11651         enable_disable = 1;
11652       else if (unformat (i, "disable"))
11653         enable_disable = 0;
11654       else
11655         break;
11656     }
11657
11658   if (sw_if_index_set == 0)
11659     {
11660       errmsg ("missing interface name or sw_if_index");
11661       return -99;
11662     }
11663
11664   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11665
11666   mp->sw_if_index = ntohl (sw_if_index);
11667   mp->enable_disable = enable_disable;
11668
11669   S (mp);
11670   W (ret);
11671   return ret;
11672 }
11673
11674 static int
11675 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11676 {
11677   unformat_input_t *i = vam->input;
11678   vl_api_l2tpv3_set_lookup_key_t *mp;
11679   u8 key = ~0;
11680   int ret;
11681
11682   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11683     {
11684       if (unformat (i, "lookup_v6_src"))
11685         key = L2T_LOOKUP_SRC_ADDRESS;
11686       else if (unformat (i, "lookup_v6_dst"))
11687         key = L2T_LOOKUP_DST_ADDRESS;
11688       else if (unformat (i, "lookup_session_id"))
11689         key = L2T_LOOKUP_SESSION_ID;
11690       else
11691         break;
11692     }
11693
11694   if (key == (u8) ~ 0)
11695     {
11696       errmsg ("l2tp session lookup key unset");
11697       return -99;
11698     }
11699
11700   M (L2TPV3_SET_LOOKUP_KEY, mp);
11701
11702   mp->key = key;
11703
11704   S (mp);
11705   W (ret);
11706   return ret;
11707 }
11708
11709 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11710   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11711 {
11712   vat_main_t *vam = &vat_main;
11713
11714   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11715          format_ip6_address, mp->our_address,
11716          format_ip6_address, mp->client_address,
11717          clib_net_to_host_u32 (mp->sw_if_index));
11718
11719   print (vam->ofp,
11720          "   local cookies %016llx %016llx remote cookie %016llx",
11721          clib_net_to_host_u64 (mp->local_cookie[0]),
11722          clib_net_to_host_u64 (mp->local_cookie[1]),
11723          clib_net_to_host_u64 (mp->remote_cookie));
11724
11725   print (vam->ofp, "   local session-id %d remote session-id %d",
11726          clib_net_to_host_u32 (mp->local_session_id),
11727          clib_net_to_host_u32 (mp->remote_session_id));
11728
11729   print (vam->ofp, "   l2 specific sublayer %s\n",
11730          mp->l2_sublayer_present ? "preset" : "absent");
11731
11732 }
11733
11734 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11735   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11736 {
11737   vat_main_t *vam = &vat_main;
11738   vat_json_node_t *node = NULL;
11739   struct in6_addr addr;
11740
11741   if (VAT_JSON_ARRAY != vam->json_tree.type)
11742     {
11743       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11744       vat_json_init_array (&vam->json_tree);
11745     }
11746   node = vat_json_array_add (&vam->json_tree);
11747
11748   vat_json_init_object (node);
11749
11750   clib_memcpy (&addr, mp->our_address, sizeof (addr));
11751   vat_json_object_add_ip6 (node, "our_address", addr);
11752   clib_memcpy (&addr, mp->client_address, sizeof (addr));
11753   vat_json_object_add_ip6 (node, "client_address", addr);
11754
11755   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11756   vat_json_init_array (lc);
11757   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11758   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11759   vat_json_object_add_uint (node, "remote_cookie",
11760                             clib_net_to_host_u64 (mp->remote_cookie));
11761
11762   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11763   vat_json_object_add_uint (node, "local_session_id",
11764                             clib_net_to_host_u32 (mp->local_session_id));
11765   vat_json_object_add_uint (node, "remote_session_id",
11766                             clib_net_to_host_u32 (mp->remote_session_id));
11767   vat_json_object_add_string_copy (node, "l2_sublayer",
11768                                    mp->l2_sublayer_present ? (u8 *) "present"
11769                                    : (u8 *) "absent");
11770 }
11771
11772 static int
11773 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11774 {
11775   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11776   vl_api_control_ping_t *mp_ping;
11777   int ret;
11778
11779   /* Get list of l2tpv3-tunnel interfaces */
11780   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11781   S (mp);
11782
11783   /* Use a control ping for synchronization */
11784   MPING (CONTROL_PING, mp_ping);
11785   S (mp_ping);
11786
11787   W (ret);
11788   return ret;
11789 }
11790
11791
11792 static void vl_api_sw_interface_tap_details_t_handler
11793   (vl_api_sw_interface_tap_details_t * mp)
11794 {
11795   vat_main_t *vam = &vat_main;
11796
11797   print (vam->ofp, "%-16s %d",
11798          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
11799 }
11800
11801 static void vl_api_sw_interface_tap_details_t_handler_json
11802   (vl_api_sw_interface_tap_details_t * mp)
11803 {
11804   vat_main_t *vam = &vat_main;
11805   vat_json_node_t *node = NULL;
11806
11807   if (VAT_JSON_ARRAY != vam->json_tree.type)
11808     {
11809       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11810       vat_json_init_array (&vam->json_tree);
11811     }
11812   node = vat_json_array_add (&vam->json_tree);
11813
11814   vat_json_init_object (node);
11815   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11816   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11817 }
11818
11819 static int
11820 api_sw_interface_tap_dump (vat_main_t * vam)
11821 {
11822   vl_api_sw_interface_tap_dump_t *mp;
11823   vl_api_control_ping_t *mp_ping;
11824   int ret;
11825
11826   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
11827   /* Get list of tap interfaces */
11828   M (SW_INTERFACE_TAP_DUMP, mp);
11829   S (mp);
11830
11831   /* Use a control ping for synchronization */
11832   MPING (CONTROL_PING, mp_ping);
11833   S (mp_ping);
11834
11835   W (ret);
11836   return ret;
11837 }
11838
11839 static uword unformat_vxlan_decap_next
11840   (unformat_input_t * input, va_list * args)
11841 {
11842   u32 *result = va_arg (*args, u32 *);
11843   u32 tmp;
11844
11845   if (unformat (input, "l2"))
11846     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11847   else if (unformat (input, "%d", &tmp))
11848     *result = tmp;
11849   else
11850     return 0;
11851   return 1;
11852 }
11853
11854 static int
11855 api_vxlan_add_del_tunnel (vat_main_t * vam)
11856 {
11857   unformat_input_t *line_input = vam->input;
11858   vl_api_vxlan_add_del_tunnel_t *mp;
11859   ip46_address_t src, dst;
11860   u8 is_add = 1;
11861   u8 ipv4_set = 0, ipv6_set = 0;
11862   u8 src_set = 0;
11863   u8 dst_set = 0;
11864   u8 grp_set = 0;
11865   u32 mcast_sw_if_index = ~0;
11866   u32 encap_vrf_id = 0;
11867   u32 decap_next_index = ~0;
11868   u32 vni = 0;
11869   int ret;
11870
11871   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11872   memset (&src, 0, sizeof src);
11873   memset (&dst, 0, sizeof dst);
11874
11875   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11876     {
11877       if (unformat (line_input, "del"))
11878         is_add = 0;
11879       else
11880         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11881         {
11882           ipv4_set = 1;
11883           src_set = 1;
11884         }
11885       else
11886         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11887         {
11888           ipv4_set = 1;
11889           dst_set = 1;
11890         }
11891       else
11892         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11893         {
11894           ipv6_set = 1;
11895           src_set = 1;
11896         }
11897       else
11898         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11899         {
11900           ipv6_set = 1;
11901           dst_set = 1;
11902         }
11903       else if (unformat (line_input, "group %U %U",
11904                          unformat_ip4_address, &dst.ip4,
11905                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11906         {
11907           grp_set = dst_set = 1;
11908           ipv4_set = 1;
11909         }
11910       else if (unformat (line_input, "group %U",
11911                          unformat_ip4_address, &dst.ip4))
11912         {
11913           grp_set = dst_set = 1;
11914           ipv4_set = 1;
11915         }
11916       else if (unformat (line_input, "group %U %U",
11917                          unformat_ip6_address, &dst.ip6,
11918                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11919         {
11920           grp_set = dst_set = 1;
11921           ipv6_set = 1;
11922         }
11923       else if (unformat (line_input, "group %U",
11924                          unformat_ip6_address, &dst.ip6))
11925         {
11926           grp_set = dst_set = 1;
11927           ipv6_set = 1;
11928         }
11929       else
11930         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11931         ;
11932       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11933         ;
11934       else if (unformat (line_input, "decap-next %U",
11935                          unformat_vxlan_decap_next, &decap_next_index))
11936         ;
11937       else if (unformat (line_input, "vni %d", &vni))
11938         ;
11939       else
11940         {
11941           errmsg ("parse error '%U'", format_unformat_error, line_input);
11942           return -99;
11943         }
11944     }
11945
11946   if (src_set == 0)
11947     {
11948       errmsg ("tunnel src address not specified");
11949       return -99;
11950     }
11951   if (dst_set == 0)
11952     {
11953       errmsg ("tunnel dst address not specified");
11954       return -99;
11955     }
11956
11957   if (grp_set && !ip46_address_is_multicast (&dst))
11958     {
11959       errmsg ("tunnel group address not multicast");
11960       return -99;
11961     }
11962   if (grp_set && mcast_sw_if_index == ~0)
11963     {
11964       errmsg ("tunnel nonexistent multicast device");
11965       return -99;
11966     }
11967   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11968     {
11969       errmsg ("tunnel dst address must be unicast");
11970       return -99;
11971     }
11972
11973
11974   if (ipv4_set && ipv6_set)
11975     {
11976       errmsg ("both IPv4 and IPv6 addresses specified");
11977       return -99;
11978     }
11979
11980   if ((vni == 0) || (vni >> 24))
11981     {
11982       errmsg ("vni not specified or out of range");
11983       return -99;
11984     }
11985
11986   M (VXLAN_ADD_DEL_TUNNEL, mp);
11987
11988   if (ipv6_set)
11989     {
11990       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
11991       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
11992     }
11993   else
11994     {
11995       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
11996       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
11997     }
11998   mp->encap_vrf_id = ntohl (encap_vrf_id);
11999   mp->decap_next_index = ntohl (decap_next_index);
12000   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12001   mp->vni = ntohl (vni);
12002   mp->is_add = is_add;
12003   mp->is_ipv6 = ipv6_set;
12004
12005   S (mp);
12006   W (ret);
12007   return ret;
12008 }
12009
12010 static void vl_api_vxlan_tunnel_details_t_handler
12011   (vl_api_vxlan_tunnel_details_t * mp)
12012 {
12013   vat_main_t *vam = &vat_main;
12014   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12015   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12016
12017   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12018          ntohl (mp->sw_if_index),
12019          format_ip46_address, &src, IP46_TYPE_ANY,
12020          format_ip46_address, &dst, IP46_TYPE_ANY,
12021          ntohl (mp->encap_vrf_id),
12022          ntohl (mp->decap_next_index), ntohl (mp->vni),
12023          ntohl (mp->mcast_sw_if_index));
12024 }
12025
12026 static void vl_api_vxlan_tunnel_details_t_handler_json
12027   (vl_api_vxlan_tunnel_details_t * mp)
12028 {
12029   vat_main_t *vam = &vat_main;
12030   vat_json_node_t *node = NULL;
12031
12032   if (VAT_JSON_ARRAY != vam->json_tree.type)
12033     {
12034       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12035       vat_json_init_array (&vam->json_tree);
12036     }
12037   node = vat_json_array_add (&vam->json_tree);
12038
12039   vat_json_init_object (node);
12040   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12041   if (mp->is_ipv6)
12042     {
12043       struct in6_addr ip6;
12044
12045       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12046       vat_json_object_add_ip6 (node, "src_address", ip6);
12047       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12048       vat_json_object_add_ip6 (node, "dst_address", ip6);
12049     }
12050   else
12051     {
12052       struct in_addr ip4;
12053
12054       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12055       vat_json_object_add_ip4 (node, "src_address", ip4);
12056       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12057       vat_json_object_add_ip4 (node, "dst_address", ip4);
12058     }
12059   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12060   vat_json_object_add_uint (node, "decap_next_index",
12061                             ntohl (mp->decap_next_index));
12062   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12063   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12064   vat_json_object_add_uint (node, "mcast_sw_if_index",
12065                             ntohl (mp->mcast_sw_if_index));
12066 }
12067
12068 static int
12069 api_vxlan_tunnel_dump (vat_main_t * vam)
12070 {
12071   unformat_input_t *i = vam->input;
12072   vl_api_vxlan_tunnel_dump_t *mp;
12073   vl_api_control_ping_t *mp_ping;
12074   u32 sw_if_index;
12075   u8 sw_if_index_set = 0;
12076   int ret;
12077
12078   /* Parse args required to build the message */
12079   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12080     {
12081       if (unformat (i, "sw_if_index %d", &sw_if_index))
12082         sw_if_index_set = 1;
12083       else
12084         break;
12085     }
12086
12087   if (sw_if_index_set == 0)
12088     {
12089       sw_if_index = ~0;
12090     }
12091
12092   if (!vam->json_output)
12093     {
12094       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12095              "sw_if_index", "src_address", "dst_address",
12096              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12097     }
12098
12099   /* Get list of vxlan-tunnel interfaces */
12100   M (VXLAN_TUNNEL_DUMP, mp);
12101
12102   mp->sw_if_index = htonl (sw_if_index);
12103
12104   S (mp);
12105
12106   /* Use a control ping for synchronization */
12107   MPING (CONTROL_PING, mp_ping);
12108   S (mp_ping);
12109
12110   W (ret);
12111   return ret;
12112 }
12113
12114 static uword unformat_geneve_decap_next
12115   (unformat_input_t * input, va_list * args)
12116 {
12117   u32 *result = va_arg (*args, u32 *);
12118   u32 tmp;
12119
12120   if (unformat (input, "l2"))
12121     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12122   else if (unformat (input, "%d", &tmp))
12123     *result = tmp;
12124   else
12125     return 0;
12126   return 1;
12127 }
12128
12129 static int
12130 api_geneve_add_del_tunnel (vat_main_t * vam)
12131 {
12132   unformat_input_t *line_input = vam->input;
12133   vl_api_geneve_add_del_tunnel_t *mp;
12134   ip46_address_t src, dst;
12135   u8 is_add = 1;
12136   u8 ipv4_set = 0, ipv6_set = 0;
12137   u8 src_set = 0;
12138   u8 dst_set = 0;
12139   u8 grp_set = 0;
12140   u32 mcast_sw_if_index = ~0;
12141   u32 encap_vrf_id = 0;
12142   u32 decap_next_index = ~0;
12143   u32 vni = 0;
12144   int ret;
12145
12146   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12147   memset (&src, 0, sizeof src);
12148   memset (&dst, 0, sizeof dst);
12149
12150   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12151     {
12152       if (unformat (line_input, "del"))
12153         is_add = 0;
12154       else
12155         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12156         {
12157           ipv4_set = 1;
12158           src_set = 1;
12159         }
12160       else
12161         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12162         {
12163           ipv4_set = 1;
12164           dst_set = 1;
12165         }
12166       else
12167         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12168         {
12169           ipv6_set = 1;
12170           src_set = 1;
12171         }
12172       else
12173         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12174         {
12175           ipv6_set = 1;
12176           dst_set = 1;
12177         }
12178       else if (unformat (line_input, "group %U %U",
12179                          unformat_ip4_address, &dst.ip4,
12180                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12181         {
12182           grp_set = dst_set = 1;
12183           ipv4_set = 1;
12184         }
12185       else if (unformat (line_input, "group %U",
12186                          unformat_ip4_address, &dst.ip4))
12187         {
12188           grp_set = dst_set = 1;
12189           ipv4_set = 1;
12190         }
12191       else if (unformat (line_input, "group %U %U",
12192                          unformat_ip6_address, &dst.ip6,
12193                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12194         {
12195           grp_set = dst_set = 1;
12196           ipv6_set = 1;
12197         }
12198       else if (unformat (line_input, "group %U",
12199                          unformat_ip6_address, &dst.ip6))
12200         {
12201           grp_set = dst_set = 1;
12202           ipv6_set = 1;
12203         }
12204       else
12205         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12206         ;
12207       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12208         ;
12209       else if (unformat (line_input, "decap-next %U",
12210                          unformat_geneve_decap_next, &decap_next_index))
12211         ;
12212       else if (unformat (line_input, "vni %d", &vni))
12213         ;
12214       else
12215         {
12216           errmsg ("parse error '%U'", format_unformat_error, line_input);
12217           return -99;
12218         }
12219     }
12220
12221   if (src_set == 0)
12222     {
12223       errmsg ("tunnel src address not specified");
12224       return -99;
12225     }
12226   if (dst_set == 0)
12227     {
12228       errmsg ("tunnel dst address not specified");
12229       return -99;
12230     }
12231
12232   if (grp_set && !ip46_address_is_multicast (&dst))
12233     {
12234       errmsg ("tunnel group address not multicast");
12235       return -99;
12236     }
12237   if (grp_set && mcast_sw_if_index == ~0)
12238     {
12239       errmsg ("tunnel nonexistent multicast device");
12240       return -99;
12241     }
12242   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12243     {
12244       errmsg ("tunnel dst address must be unicast");
12245       return -99;
12246     }
12247
12248
12249   if (ipv4_set && ipv6_set)
12250     {
12251       errmsg ("both IPv4 and IPv6 addresses specified");
12252       return -99;
12253     }
12254
12255   if ((vni == 0) || (vni >> 24))
12256     {
12257       errmsg ("vni not specified or out of range");
12258       return -99;
12259     }
12260
12261   M (GENEVE_ADD_DEL_TUNNEL, mp);
12262
12263   if (ipv6_set)
12264     {
12265       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12266       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12267     }
12268   else
12269     {
12270       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12271       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12272     }
12273   mp->encap_vrf_id = ntohl (encap_vrf_id);
12274   mp->decap_next_index = ntohl (decap_next_index);
12275   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12276   mp->vni = ntohl (vni);
12277   mp->is_add = is_add;
12278   mp->is_ipv6 = ipv6_set;
12279
12280   S (mp);
12281   W (ret);
12282   return ret;
12283 }
12284
12285 static void vl_api_geneve_tunnel_details_t_handler
12286   (vl_api_geneve_tunnel_details_t * mp)
12287 {
12288   vat_main_t *vam = &vat_main;
12289   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12290   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12291
12292   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12293          ntohl (mp->sw_if_index),
12294          format_ip46_address, &src, IP46_TYPE_ANY,
12295          format_ip46_address, &dst, IP46_TYPE_ANY,
12296          ntohl (mp->encap_vrf_id),
12297          ntohl (mp->decap_next_index), ntohl (mp->vni),
12298          ntohl (mp->mcast_sw_if_index));
12299 }
12300
12301 static void vl_api_geneve_tunnel_details_t_handler_json
12302   (vl_api_geneve_tunnel_details_t * mp)
12303 {
12304   vat_main_t *vam = &vat_main;
12305   vat_json_node_t *node = NULL;
12306
12307   if (VAT_JSON_ARRAY != vam->json_tree.type)
12308     {
12309       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12310       vat_json_init_array (&vam->json_tree);
12311     }
12312   node = vat_json_array_add (&vam->json_tree);
12313
12314   vat_json_init_object (node);
12315   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12316   if (mp->is_ipv6)
12317     {
12318       struct in6_addr ip6;
12319
12320       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12321       vat_json_object_add_ip6 (node, "src_address", ip6);
12322       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12323       vat_json_object_add_ip6 (node, "dst_address", ip6);
12324     }
12325   else
12326     {
12327       struct in_addr ip4;
12328
12329       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12330       vat_json_object_add_ip4 (node, "src_address", ip4);
12331       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12332       vat_json_object_add_ip4 (node, "dst_address", ip4);
12333     }
12334   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12335   vat_json_object_add_uint (node, "decap_next_index",
12336                             ntohl (mp->decap_next_index));
12337   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12338   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12339   vat_json_object_add_uint (node, "mcast_sw_if_index",
12340                             ntohl (mp->mcast_sw_if_index));
12341 }
12342
12343 static int
12344 api_geneve_tunnel_dump (vat_main_t * vam)
12345 {
12346   unformat_input_t *i = vam->input;
12347   vl_api_geneve_tunnel_dump_t *mp;
12348   vl_api_control_ping_t *mp_ping;
12349   u32 sw_if_index;
12350   u8 sw_if_index_set = 0;
12351   int ret;
12352
12353   /* Parse args required to build the message */
12354   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12355     {
12356       if (unformat (i, "sw_if_index %d", &sw_if_index))
12357         sw_if_index_set = 1;
12358       else
12359         break;
12360     }
12361
12362   if (sw_if_index_set == 0)
12363     {
12364       sw_if_index = ~0;
12365     }
12366
12367   if (!vam->json_output)
12368     {
12369       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12370              "sw_if_index", "local_address", "remote_address",
12371              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12372     }
12373
12374   /* Get list of geneve-tunnel interfaces */
12375   M (GENEVE_TUNNEL_DUMP, mp);
12376
12377   mp->sw_if_index = htonl (sw_if_index);
12378
12379   S (mp);
12380
12381   /* Use a control ping for synchronization */
12382   M (CONTROL_PING, mp_ping);
12383   S (mp_ping);
12384
12385   W (ret);
12386   return ret;
12387 }
12388
12389 static int
12390 api_gre_add_del_tunnel (vat_main_t * vam)
12391 {
12392   unformat_input_t *line_input = vam->input;
12393   vl_api_gre_add_del_tunnel_t *mp;
12394   ip4_address_t src4, dst4;
12395   ip6_address_t src6, dst6;
12396   u8 is_add = 1;
12397   u8 ipv4_set = 0;
12398   u8 ipv6_set = 0;
12399   u8 teb = 0;
12400   u8 src_set = 0;
12401   u8 dst_set = 0;
12402   u32 outer_fib_id = 0;
12403   int ret;
12404
12405   memset (&src4, 0, sizeof src4);
12406   memset (&dst4, 0, sizeof dst4);
12407   memset (&src6, 0, sizeof src6);
12408   memset (&dst6, 0, sizeof dst6);
12409
12410   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12411     {
12412       if (unformat (line_input, "del"))
12413         is_add = 0;
12414       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
12415         {
12416           src_set = 1;
12417           ipv4_set = 1;
12418         }
12419       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
12420         {
12421           dst_set = 1;
12422           ipv4_set = 1;
12423         }
12424       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
12425         {
12426           src_set = 1;
12427           ipv6_set = 1;
12428         }
12429       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
12430         {
12431           dst_set = 1;
12432           ipv6_set = 1;
12433         }
12434       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
12435         ;
12436       else if (unformat (line_input, "teb"))
12437         teb = 1;
12438       else
12439         {
12440           errmsg ("parse error '%U'", format_unformat_error, line_input);
12441           return -99;
12442         }
12443     }
12444
12445   if (src_set == 0)
12446     {
12447       errmsg ("tunnel src address not specified");
12448       return -99;
12449     }
12450   if (dst_set == 0)
12451     {
12452       errmsg ("tunnel dst address not specified");
12453       return -99;
12454     }
12455   if (ipv4_set && ipv6_set)
12456     {
12457       errmsg ("both IPv4 and IPv6 addresses specified");
12458       return -99;
12459     }
12460
12461
12462   M (GRE_ADD_DEL_TUNNEL, mp);
12463
12464   if (ipv4_set)
12465     {
12466       clib_memcpy (&mp->src_address, &src4, 4);
12467       clib_memcpy (&mp->dst_address, &dst4, 4);
12468     }
12469   else
12470     {
12471       clib_memcpy (&mp->src_address, &src6, 16);
12472       clib_memcpy (&mp->dst_address, &dst6, 16);
12473     }
12474   mp->outer_fib_id = ntohl (outer_fib_id);
12475   mp->is_add = is_add;
12476   mp->teb = teb;
12477   mp->is_ipv6 = ipv6_set;
12478
12479   S (mp);
12480   W (ret);
12481   return ret;
12482 }
12483
12484 static void vl_api_gre_tunnel_details_t_handler
12485   (vl_api_gre_tunnel_details_t * mp)
12486 {
12487   vat_main_t *vam = &vat_main;
12488   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
12489   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
12490
12491   print (vam->ofp, "%11d%24U%24U%6d%14d",
12492          ntohl (mp->sw_if_index),
12493          format_ip46_address, &src, IP46_TYPE_ANY,
12494          format_ip46_address, &dst, IP46_TYPE_ANY,
12495          mp->teb, ntohl (mp->outer_fib_id));
12496 }
12497
12498 static void vl_api_gre_tunnel_details_t_handler_json
12499   (vl_api_gre_tunnel_details_t * mp)
12500 {
12501   vat_main_t *vam = &vat_main;
12502   vat_json_node_t *node = NULL;
12503   struct in_addr ip4;
12504   struct in6_addr ip6;
12505
12506   if (VAT_JSON_ARRAY != vam->json_tree.type)
12507     {
12508       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12509       vat_json_init_array (&vam->json_tree);
12510     }
12511   node = vat_json_array_add (&vam->json_tree);
12512
12513   vat_json_init_object (node);
12514   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12515   if (!mp->is_ipv6)
12516     {
12517       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
12518       vat_json_object_add_ip4 (node, "src_address", ip4);
12519       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
12520       vat_json_object_add_ip4 (node, "dst_address", ip4);
12521     }
12522   else
12523     {
12524       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
12525       vat_json_object_add_ip6 (node, "src_address", ip6);
12526       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
12527       vat_json_object_add_ip6 (node, "dst_address", ip6);
12528     }
12529   vat_json_object_add_uint (node, "teb", mp->teb);
12530   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
12531   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
12532 }
12533
12534 static int
12535 api_gre_tunnel_dump (vat_main_t * vam)
12536 {
12537   unformat_input_t *i = vam->input;
12538   vl_api_gre_tunnel_dump_t *mp;
12539   vl_api_control_ping_t *mp_ping;
12540   u32 sw_if_index;
12541   u8 sw_if_index_set = 0;
12542   int ret;
12543
12544   /* Parse args required to build the message */
12545   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12546     {
12547       if (unformat (i, "sw_if_index %d", &sw_if_index))
12548         sw_if_index_set = 1;
12549       else
12550         break;
12551     }
12552
12553   if (sw_if_index_set == 0)
12554     {
12555       sw_if_index = ~0;
12556     }
12557
12558   if (!vam->json_output)
12559     {
12560       print (vam->ofp, "%11s%24s%24s%6s%14s",
12561              "sw_if_index", "src_address", "dst_address", "teb",
12562              "outer_fib_id");
12563     }
12564
12565   /* Get list of gre-tunnel interfaces */
12566   M (GRE_TUNNEL_DUMP, mp);
12567
12568   mp->sw_if_index = htonl (sw_if_index);
12569
12570   S (mp);
12571
12572   /* Use a control ping for synchronization */
12573   MPING (CONTROL_PING, mp_ping);
12574   S (mp_ping);
12575
12576   W (ret);
12577   return ret;
12578 }
12579
12580 static int
12581 api_l2_fib_clear_table (vat_main_t * vam)
12582 {
12583 //  unformat_input_t * i = vam->input;
12584   vl_api_l2_fib_clear_table_t *mp;
12585   int ret;
12586
12587   M (L2_FIB_CLEAR_TABLE, mp);
12588
12589   S (mp);
12590   W (ret);
12591   return ret;
12592 }
12593
12594 static int
12595 api_l2_interface_efp_filter (vat_main_t * vam)
12596 {
12597   unformat_input_t *i = vam->input;
12598   vl_api_l2_interface_efp_filter_t *mp;
12599   u32 sw_if_index;
12600   u8 enable = 1;
12601   u8 sw_if_index_set = 0;
12602   int ret;
12603
12604   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12605     {
12606       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12607         sw_if_index_set = 1;
12608       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12609         sw_if_index_set = 1;
12610       else if (unformat (i, "enable"))
12611         enable = 1;
12612       else if (unformat (i, "disable"))
12613         enable = 0;
12614       else
12615         {
12616           clib_warning ("parse error '%U'", format_unformat_error, i);
12617           return -99;
12618         }
12619     }
12620
12621   if (sw_if_index_set == 0)
12622     {
12623       errmsg ("missing sw_if_index");
12624       return -99;
12625     }
12626
12627   M (L2_INTERFACE_EFP_FILTER, mp);
12628
12629   mp->sw_if_index = ntohl (sw_if_index);
12630   mp->enable_disable = enable;
12631
12632   S (mp);
12633   W (ret);
12634   return ret;
12635 }
12636
12637 #define foreach_vtr_op                          \
12638 _("disable",  L2_VTR_DISABLED)                  \
12639 _("push-1",  L2_VTR_PUSH_1)                     \
12640 _("push-2",  L2_VTR_PUSH_2)                     \
12641 _("pop-1",  L2_VTR_POP_1)                       \
12642 _("pop-2",  L2_VTR_POP_2)                       \
12643 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12644 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12645 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12646 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12647
12648 static int
12649 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12650 {
12651   unformat_input_t *i = vam->input;
12652   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12653   u32 sw_if_index;
12654   u8 sw_if_index_set = 0;
12655   u8 vtr_op_set = 0;
12656   u32 vtr_op = 0;
12657   u32 push_dot1q = 1;
12658   u32 tag1 = ~0;
12659   u32 tag2 = ~0;
12660   int ret;
12661
12662   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12663     {
12664       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12665         sw_if_index_set = 1;
12666       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12667         sw_if_index_set = 1;
12668       else if (unformat (i, "vtr_op %d", &vtr_op))
12669         vtr_op_set = 1;
12670 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12671       foreach_vtr_op
12672 #undef _
12673         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12674         ;
12675       else if (unformat (i, "tag1 %d", &tag1))
12676         ;
12677       else if (unformat (i, "tag2 %d", &tag2))
12678         ;
12679       else
12680         {
12681           clib_warning ("parse error '%U'", format_unformat_error, i);
12682           return -99;
12683         }
12684     }
12685
12686   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12687     {
12688       errmsg ("missing vtr operation or sw_if_index");
12689       return -99;
12690     }
12691
12692   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12693   mp->sw_if_index = ntohl (sw_if_index);
12694   mp->vtr_op = ntohl (vtr_op);
12695   mp->push_dot1q = ntohl (push_dot1q);
12696   mp->tag1 = ntohl (tag1);
12697   mp->tag2 = ntohl (tag2);
12698
12699   S (mp);
12700   W (ret);
12701   return ret;
12702 }
12703
12704 static int
12705 api_create_vhost_user_if (vat_main_t * vam)
12706 {
12707   unformat_input_t *i = vam->input;
12708   vl_api_create_vhost_user_if_t *mp;
12709   u8 *file_name;
12710   u8 is_server = 0;
12711   u8 file_name_set = 0;
12712   u32 custom_dev_instance = ~0;
12713   u8 hwaddr[6];
12714   u8 use_custom_mac = 0;
12715   u8 *tag = 0;
12716   int ret;
12717
12718   /* Shut up coverity */
12719   memset (hwaddr, 0, sizeof (hwaddr));
12720
12721   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12722     {
12723       if (unformat (i, "socket %s", &file_name))
12724         {
12725           file_name_set = 1;
12726         }
12727       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12728         ;
12729       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12730         use_custom_mac = 1;
12731       else if (unformat (i, "server"))
12732         is_server = 1;
12733       else if (unformat (i, "tag %s", &tag))
12734         ;
12735       else
12736         break;
12737     }
12738
12739   if (file_name_set == 0)
12740     {
12741       errmsg ("missing socket file name");
12742       return -99;
12743     }
12744
12745   if (vec_len (file_name) > 255)
12746     {
12747       errmsg ("socket file name too long");
12748       return -99;
12749     }
12750   vec_add1 (file_name, 0);
12751
12752   M (CREATE_VHOST_USER_IF, mp);
12753
12754   mp->is_server = is_server;
12755   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12756   vec_free (file_name);
12757   if (custom_dev_instance != ~0)
12758     {
12759       mp->renumber = 1;
12760       mp->custom_dev_instance = ntohl (custom_dev_instance);
12761     }
12762   mp->use_custom_mac = use_custom_mac;
12763   clib_memcpy (mp->mac_address, hwaddr, 6);
12764   if (tag)
12765     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12766   vec_free (tag);
12767
12768   S (mp);
12769   W (ret);
12770   return ret;
12771 }
12772
12773 static int
12774 api_modify_vhost_user_if (vat_main_t * vam)
12775 {
12776   unformat_input_t *i = vam->input;
12777   vl_api_modify_vhost_user_if_t *mp;
12778   u8 *file_name;
12779   u8 is_server = 0;
12780   u8 file_name_set = 0;
12781   u32 custom_dev_instance = ~0;
12782   u8 sw_if_index_set = 0;
12783   u32 sw_if_index = (u32) ~ 0;
12784   int ret;
12785
12786   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12787     {
12788       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12789         sw_if_index_set = 1;
12790       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12791         sw_if_index_set = 1;
12792       else if (unformat (i, "socket %s", &file_name))
12793         {
12794           file_name_set = 1;
12795         }
12796       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12797         ;
12798       else if (unformat (i, "server"))
12799         is_server = 1;
12800       else
12801         break;
12802     }
12803
12804   if (sw_if_index_set == 0)
12805     {
12806       errmsg ("missing sw_if_index or interface name");
12807       return -99;
12808     }
12809
12810   if (file_name_set == 0)
12811     {
12812       errmsg ("missing socket file name");
12813       return -99;
12814     }
12815
12816   if (vec_len (file_name) > 255)
12817     {
12818       errmsg ("socket file name too long");
12819       return -99;
12820     }
12821   vec_add1 (file_name, 0);
12822
12823   M (MODIFY_VHOST_USER_IF, mp);
12824
12825   mp->sw_if_index = ntohl (sw_if_index);
12826   mp->is_server = is_server;
12827   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12828   vec_free (file_name);
12829   if (custom_dev_instance != ~0)
12830     {
12831       mp->renumber = 1;
12832       mp->custom_dev_instance = ntohl (custom_dev_instance);
12833     }
12834
12835   S (mp);
12836   W (ret);
12837   return ret;
12838 }
12839
12840 static int
12841 api_delete_vhost_user_if (vat_main_t * vam)
12842 {
12843   unformat_input_t *i = vam->input;
12844   vl_api_delete_vhost_user_if_t *mp;
12845   u32 sw_if_index = ~0;
12846   u8 sw_if_index_set = 0;
12847   int ret;
12848
12849   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12850     {
12851       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12852         sw_if_index_set = 1;
12853       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12854         sw_if_index_set = 1;
12855       else
12856         break;
12857     }
12858
12859   if (sw_if_index_set == 0)
12860     {
12861       errmsg ("missing sw_if_index or interface name");
12862       return -99;
12863     }
12864
12865
12866   M (DELETE_VHOST_USER_IF, mp);
12867
12868   mp->sw_if_index = ntohl (sw_if_index);
12869
12870   S (mp);
12871   W (ret);
12872   return ret;
12873 }
12874
12875 static void vl_api_sw_interface_vhost_user_details_t_handler
12876   (vl_api_sw_interface_vhost_user_details_t * mp)
12877 {
12878   vat_main_t *vam = &vat_main;
12879
12880   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12881          (char *) mp->interface_name,
12882          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12883          clib_net_to_host_u64 (mp->features), mp->is_server,
12884          ntohl (mp->num_regions), (char *) mp->sock_filename);
12885   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12886 }
12887
12888 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12889   (vl_api_sw_interface_vhost_user_details_t * mp)
12890 {
12891   vat_main_t *vam = &vat_main;
12892   vat_json_node_t *node = NULL;
12893
12894   if (VAT_JSON_ARRAY != vam->json_tree.type)
12895     {
12896       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12897       vat_json_init_array (&vam->json_tree);
12898     }
12899   node = vat_json_array_add (&vam->json_tree);
12900
12901   vat_json_init_object (node);
12902   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12903   vat_json_object_add_string_copy (node, "interface_name",
12904                                    mp->interface_name);
12905   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12906                             ntohl (mp->virtio_net_hdr_sz));
12907   vat_json_object_add_uint (node, "features",
12908                             clib_net_to_host_u64 (mp->features));
12909   vat_json_object_add_uint (node, "is_server", mp->is_server);
12910   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12911   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12912   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12913 }
12914
12915 static int
12916 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12917 {
12918   vl_api_sw_interface_vhost_user_dump_t *mp;
12919   vl_api_control_ping_t *mp_ping;
12920   int ret;
12921   print (vam->ofp,
12922          "Interface name            idx hdr_sz features server regions filename");
12923
12924   /* Get list of vhost-user interfaces */
12925   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12926   S (mp);
12927
12928   /* Use a control ping for synchronization */
12929   MPING (CONTROL_PING, mp_ping);
12930   S (mp_ping);
12931
12932   W (ret);
12933   return ret;
12934 }
12935
12936 static int
12937 api_show_version (vat_main_t * vam)
12938 {
12939   vl_api_show_version_t *mp;
12940   int ret;
12941
12942   M (SHOW_VERSION, mp);
12943
12944   S (mp);
12945   W (ret);
12946   return ret;
12947 }
12948
12949
12950 static int
12951 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12952 {
12953   unformat_input_t *line_input = vam->input;
12954   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12955   ip4_address_t local4, remote4;
12956   ip6_address_t local6, remote6;
12957   u8 is_add = 1;
12958   u8 ipv4_set = 0, ipv6_set = 0;
12959   u8 local_set = 0;
12960   u8 remote_set = 0;
12961   u8 grp_set = 0;
12962   u32 mcast_sw_if_index = ~0;
12963   u32 encap_vrf_id = 0;
12964   u32 decap_vrf_id = 0;
12965   u8 protocol = ~0;
12966   u32 vni;
12967   u8 vni_set = 0;
12968   int ret;
12969
12970   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12971   memset (&local4, 0, sizeof local4);
12972   memset (&remote4, 0, sizeof remote4);
12973   memset (&local6, 0, sizeof local6);
12974   memset (&remote6, 0, sizeof remote6);
12975
12976   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12977     {
12978       if (unformat (line_input, "del"))
12979         is_add = 0;
12980       else if (unformat (line_input, "local %U",
12981                          unformat_ip4_address, &local4))
12982         {
12983           local_set = 1;
12984           ipv4_set = 1;
12985         }
12986       else if (unformat (line_input, "remote %U",
12987                          unformat_ip4_address, &remote4))
12988         {
12989           remote_set = 1;
12990           ipv4_set = 1;
12991         }
12992       else if (unformat (line_input, "local %U",
12993                          unformat_ip6_address, &local6))
12994         {
12995           local_set = 1;
12996           ipv6_set = 1;
12997         }
12998       else if (unformat (line_input, "remote %U",
12999                          unformat_ip6_address, &remote6))
13000         {
13001           remote_set = 1;
13002           ipv6_set = 1;
13003         }
13004       else if (unformat (line_input, "group %U %U",
13005                          unformat_ip4_address, &remote4,
13006                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13007         {
13008           grp_set = remote_set = 1;
13009           ipv4_set = 1;
13010         }
13011       else if (unformat (line_input, "group %U",
13012                          unformat_ip4_address, &remote4))
13013         {
13014           grp_set = remote_set = 1;
13015           ipv4_set = 1;
13016         }
13017       else if (unformat (line_input, "group %U %U",
13018                          unformat_ip6_address, &remote6,
13019                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13020         {
13021           grp_set = remote_set = 1;
13022           ipv6_set = 1;
13023         }
13024       else if (unformat (line_input, "group %U",
13025                          unformat_ip6_address, &remote6))
13026         {
13027           grp_set = remote_set = 1;
13028           ipv6_set = 1;
13029         }
13030       else
13031         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13032         ;
13033       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13034         ;
13035       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13036         ;
13037       else if (unformat (line_input, "vni %d", &vni))
13038         vni_set = 1;
13039       else if (unformat (line_input, "next-ip4"))
13040         protocol = 1;
13041       else if (unformat (line_input, "next-ip6"))
13042         protocol = 2;
13043       else if (unformat (line_input, "next-ethernet"))
13044         protocol = 3;
13045       else if (unformat (line_input, "next-nsh"))
13046         protocol = 4;
13047       else
13048         {
13049           errmsg ("parse error '%U'", format_unformat_error, line_input);
13050           return -99;
13051         }
13052     }
13053
13054   if (local_set == 0)
13055     {
13056       errmsg ("tunnel local address not specified");
13057       return -99;
13058     }
13059   if (remote_set == 0)
13060     {
13061       errmsg ("tunnel remote address not specified");
13062       return -99;
13063     }
13064   if (grp_set && mcast_sw_if_index == ~0)
13065     {
13066       errmsg ("tunnel nonexistent multicast device");
13067       return -99;
13068     }
13069   if (ipv4_set && ipv6_set)
13070     {
13071       errmsg ("both IPv4 and IPv6 addresses specified");
13072       return -99;
13073     }
13074
13075   if (vni_set == 0)
13076     {
13077       errmsg ("vni not specified");
13078       return -99;
13079     }
13080
13081   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13082
13083
13084   if (ipv6_set)
13085     {
13086       clib_memcpy (&mp->local, &local6, sizeof (local6));
13087       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13088     }
13089   else
13090     {
13091       clib_memcpy (&mp->local, &local4, sizeof (local4));
13092       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13093     }
13094
13095   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13096   mp->encap_vrf_id = ntohl (encap_vrf_id);
13097   mp->decap_vrf_id = ntohl (decap_vrf_id);
13098   mp->protocol = protocol;
13099   mp->vni = ntohl (vni);
13100   mp->is_add = is_add;
13101   mp->is_ipv6 = ipv6_set;
13102
13103   S (mp);
13104   W (ret);
13105   return ret;
13106 }
13107
13108 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13109   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13110 {
13111   vat_main_t *vam = &vat_main;
13112   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13113   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13114
13115   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13116          ntohl (mp->sw_if_index),
13117          format_ip46_address, &local, IP46_TYPE_ANY,
13118          format_ip46_address, &remote, IP46_TYPE_ANY,
13119          ntohl (mp->vni), mp->protocol,
13120          ntohl (mp->mcast_sw_if_index),
13121          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13122 }
13123
13124
13125 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13126   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13127 {
13128   vat_main_t *vam = &vat_main;
13129   vat_json_node_t *node = NULL;
13130   struct in_addr ip4;
13131   struct in6_addr ip6;
13132
13133   if (VAT_JSON_ARRAY != vam->json_tree.type)
13134     {
13135       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13136       vat_json_init_array (&vam->json_tree);
13137     }
13138   node = vat_json_array_add (&vam->json_tree);
13139
13140   vat_json_init_object (node);
13141   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13142   if (mp->is_ipv6)
13143     {
13144       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13145       vat_json_object_add_ip6 (node, "local", ip6);
13146       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13147       vat_json_object_add_ip6 (node, "remote", ip6);
13148     }
13149   else
13150     {
13151       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13152       vat_json_object_add_ip4 (node, "local", ip4);
13153       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13154       vat_json_object_add_ip4 (node, "remote", ip4);
13155     }
13156   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13157   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13158   vat_json_object_add_uint (node, "mcast_sw_if_index",
13159                             ntohl (mp->mcast_sw_if_index));
13160   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13161   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13162   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13163 }
13164
13165 static int
13166 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13167 {
13168   unformat_input_t *i = vam->input;
13169   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13170   vl_api_control_ping_t *mp_ping;
13171   u32 sw_if_index;
13172   u8 sw_if_index_set = 0;
13173   int ret;
13174
13175   /* Parse args required to build the message */
13176   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13177     {
13178       if (unformat (i, "sw_if_index %d", &sw_if_index))
13179         sw_if_index_set = 1;
13180       else
13181         break;
13182     }
13183
13184   if (sw_if_index_set == 0)
13185     {
13186       sw_if_index = ~0;
13187     }
13188
13189   if (!vam->json_output)
13190     {
13191       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13192              "sw_if_index", "local", "remote", "vni",
13193              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13194     }
13195
13196   /* Get list of vxlan-tunnel interfaces */
13197   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13198
13199   mp->sw_if_index = htonl (sw_if_index);
13200
13201   S (mp);
13202
13203   /* Use a control ping for synchronization */
13204   MPING (CONTROL_PING, mp_ping);
13205   S (mp_ping);
13206
13207   W (ret);
13208   return ret;
13209 }
13210
13211
13212 u8 *
13213 format_l2_fib_mac_address (u8 * s, va_list * args)
13214 {
13215   u8 *a = va_arg (*args, u8 *);
13216
13217   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
13218                  a[2], a[3], a[4], a[5], a[6], a[7]);
13219 }
13220
13221 static void vl_api_l2_fib_table_details_t_handler
13222   (vl_api_l2_fib_table_details_t * mp)
13223 {
13224   vat_main_t *vam = &vat_main;
13225
13226   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13227          "       %d       %d     %d",
13228          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
13229          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13230          mp->bvi_mac);
13231 }
13232
13233 static void vl_api_l2_fib_table_details_t_handler_json
13234   (vl_api_l2_fib_table_details_t * mp)
13235 {
13236   vat_main_t *vam = &vat_main;
13237   vat_json_node_t *node = NULL;
13238
13239   if (VAT_JSON_ARRAY != vam->json_tree.type)
13240     {
13241       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13242       vat_json_init_array (&vam->json_tree);
13243     }
13244   node = vat_json_array_add (&vam->json_tree);
13245
13246   vat_json_init_object (node);
13247   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13248   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
13249   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13250   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13251   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13252   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13253 }
13254
13255 static int
13256 api_l2_fib_table_dump (vat_main_t * vam)
13257 {
13258   unformat_input_t *i = vam->input;
13259   vl_api_l2_fib_table_dump_t *mp;
13260   vl_api_control_ping_t *mp_ping;
13261   u32 bd_id;
13262   u8 bd_id_set = 0;
13263   int ret;
13264
13265   /* Parse args required to build the message */
13266   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13267     {
13268       if (unformat (i, "bd_id %d", &bd_id))
13269         bd_id_set = 1;
13270       else
13271         break;
13272     }
13273
13274   if (bd_id_set == 0)
13275     {
13276       errmsg ("missing bridge domain");
13277       return -99;
13278     }
13279
13280   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13281
13282   /* Get list of l2 fib entries */
13283   M (L2_FIB_TABLE_DUMP, mp);
13284
13285   mp->bd_id = ntohl (bd_id);
13286   S (mp);
13287
13288   /* Use a control ping for synchronization */
13289   MPING (CONTROL_PING, mp_ping);
13290   S (mp_ping);
13291
13292   W (ret);
13293   return ret;
13294 }
13295
13296
13297 static int
13298 api_interface_name_renumber (vat_main_t * vam)
13299 {
13300   unformat_input_t *line_input = vam->input;
13301   vl_api_interface_name_renumber_t *mp;
13302   u32 sw_if_index = ~0;
13303   u32 new_show_dev_instance = ~0;
13304   int ret;
13305
13306   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13307     {
13308       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13309                     &sw_if_index))
13310         ;
13311       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13312         ;
13313       else if (unformat (line_input, "new_show_dev_instance %d",
13314                          &new_show_dev_instance))
13315         ;
13316       else
13317         break;
13318     }
13319
13320   if (sw_if_index == ~0)
13321     {
13322       errmsg ("missing interface name or sw_if_index");
13323       return -99;
13324     }
13325
13326   if (new_show_dev_instance == ~0)
13327     {
13328       errmsg ("missing new_show_dev_instance");
13329       return -99;
13330     }
13331
13332   M (INTERFACE_NAME_RENUMBER, mp);
13333
13334   mp->sw_if_index = ntohl (sw_if_index);
13335   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13336
13337   S (mp);
13338   W (ret);
13339   return ret;
13340 }
13341
13342 static int
13343 api_want_ip4_arp_events (vat_main_t * vam)
13344 {
13345   unformat_input_t *line_input = vam->input;
13346   vl_api_want_ip4_arp_events_t *mp;
13347   ip4_address_t address;
13348   int address_set = 0;
13349   u32 enable_disable = 1;
13350   int ret;
13351
13352   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13353     {
13354       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
13355         address_set = 1;
13356       else if (unformat (line_input, "del"))
13357         enable_disable = 0;
13358       else
13359         break;
13360     }
13361
13362   if (address_set == 0)
13363     {
13364       errmsg ("missing addresses");
13365       return -99;
13366     }
13367
13368   M (WANT_IP4_ARP_EVENTS, mp);
13369   mp->enable_disable = enable_disable;
13370   mp->pid = htonl (getpid ());
13371   mp->address = address.as_u32;
13372
13373   S (mp);
13374   W (ret);
13375   return ret;
13376 }
13377
13378 static int
13379 api_want_ip6_nd_events (vat_main_t * vam)
13380 {
13381   unformat_input_t *line_input = vam->input;
13382   vl_api_want_ip6_nd_events_t *mp;
13383   ip6_address_t address;
13384   int address_set = 0;
13385   u32 enable_disable = 1;
13386   int ret;
13387
13388   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13389     {
13390       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
13391         address_set = 1;
13392       else if (unformat (line_input, "del"))
13393         enable_disable = 0;
13394       else
13395         break;
13396     }
13397
13398   if (address_set == 0)
13399     {
13400       errmsg ("missing addresses");
13401       return -99;
13402     }
13403
13404   M (WANT_IP6_ND_EVENTS, mp);
13405   mp->enable_disable = enable_disable;
13406   mp->pid = htonl (getpid ());
13407   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
13408
13409   S (mp);
13410   W (ret);
13411   return ret;
13412 }
13413
13414 static int
13415 api_want_l2_macs_events (vat_main_t * vam)
13416 {
13417   unformat_input_t *line_input = vam->input;
13418   vl_api_want_l2_macs_events_t *mp;
13419   u8 enable_disable = 1;
13420   u32 scan_delay = 0;
13421   u32 max_macs_in_event = 0;
13422   u32 learn_limit = 0;
13423   int ret;
13424
13425   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13426     {
13427       if (unformat (line_input, "learn-limit %d", &learn_limit))
13428         ;
13429       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13430         ;
13431       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13432         ;
13433       else if (unformat (line_input, "disable"))
13434         enable_disable = 0;
13435       else
13436         break;
13437     }
13438
13439   M (WANT_L2_MACS_EVENTS, mp);
13440   mp->enable_disable = enable_disable;
13441   mp->pid = htonl (getpid ());
13442   mp->learn_limit = htonl (learn_limit);
13443   mp->scan_delay = (u8) scan_delay;
13444   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13445   S (mp);
13446   W (ret);
13447   return ret;
13448 }
13449
13450 static int
13451 api_input_acl_set_interface (vat_main_t * vam)
13452 {
13453   unformat_input_t *i = vam->input;
13454   vl_api_input_acl_set_interface_t *mp;
13455   u32 sw_if_index;
13456   int sw_if_index_set;
13457   u32 ip4_table_index = ~0;
13458   u32 ip6_table_index = ~0;
13459   u32 l2_table_index = ~0;
13460   u8 is_add = 1;
13461   int ret;
13462
13463   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13464     {
13465       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13466         sw_if_index_set = 1;
13467       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13468         sw_if_index_set = 1;
13469       else if (unformat (i, "del"))
13470         is_add = 0;
13471       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13472         ;
13473       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13474         ;
13475       else if (unformat (i, "l2-table %d", &l2_table_index))
13476         ;
13477       else
13478         {
13479           clib_warning ("parse error '%U'", format_unformat_error, i);
13480           return -99;
13481         }
13482     }
13483
13484   if (sw_if_index_set == 0)
13485     {
13486       errmsg ("missing interface name or sw_if_index");
13487       return -99;
13488     }
13489
13490   M (INPUT_ACL_SET_INTERFACE, mp);
13491
13492   mp->sw_if_index = ntohl (sw_if_index);
13493   mp->ip4_table_index = ntohl (ip4_table_index);
13494   mp->ip6_table_index = ntohl (ip6_table_index);
13495   mp->l2_table_index = ntohl (l2_table_index);
13496   mp->is_add = is_add;
13497
13498   S (mp);
13499   W (ret);
13500   return ret;
13501 }
13502
13503 static int
13504 api_ip_address_dump (vat_main_t * vam)
13505 {
13506   unformat_input_t *i = vam->input;
13507   vl_api_ip_address_dump_t *mp;
13508   vl_api_control_ping_t *mp_ping;
13509   u32 sw_if_index = ~0;
13510   u8 sw_if_index_set = 0;
13511   u8 ipv4_set = 0;
13512   u8 ipv6_set = 0;
13513   int ret;
13514
13515   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13516     {
13517       if (unformat (i, "sw_if_index %d", &sw_if_index))
13518         sw_if_index_set = 1;
13519       else
13520         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13521         sw_if_index_set = 1;
13522       else if (unformat (i, "ipv4"))
13523         ipv4_set = 1;
13524       else if (unformat (i, "ipv6"))
13525         ipv6_set = 1;
13526       else
13527         break;
13528     }
13529
13530   if (ipv4_set && ipv6_set)
13531     {
13532       errmsg ("ipv4 and ipv6 flags cannot be both set");
13533       return -99;
13534     }
13535
13536   if ((!ipv4_set) && (!ipv6_set))
13537     {
13538       errmsg ("no ipv4 nor ipv6 flag set");
13539       return -99;
13540     }
13541
13542   if (sw_if_index_set == 0)
13543     {
13544       errmsg ("missing interface name or sw_if_index");
13545       return -99;
13546     }
13547
13548   vam->current_sw_if_index = sw_if_index;
13549   vam->is_ipv6 = ipv6_set;
13550
13551   M (IP_ADDRESS_DUMP, mp);
13552   mp->sw_if_index = ntohl (sw_if_index);
13553   mp->is_ipv6 = ipv6_set;
13554   S (mp);
13555
13556   /* Use a control ping for synchronization */
13557   MPING (CONTROL_PING, mp_ping);
13558   S (mp_ping);
13559
13560   W (ret);
13561   return ret;
13562 }
13563
13564 static int
13565 api_ip_dump (vat_main_t * vam)
13566 {
13567   vl_api_ip_dump_t *mp;
13568   vl_api_control_ping_t *mp_ping;
13569   unformat_input_t *in = vam->input;
13570   int ipv4_set = 0;
13571   int ipv6_set = 0;
13572   int is_ipv6;
13573   int i;
13574   int ret;
13575
13576   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13577     {
13578       if (unformat (in, "ipv4"))
13579         ipv4_set = 1;
13580       else if (unformat (in, "ipv6"))
13581         ipv6_set = 1;
13582       else
13583         break;
13584     }
13585
13586   if (ipv4_set && ipv6_set)
13587     {
13588       errmsg ("ipv4 and ipv6 flags cannot be both set");
13589       return -99;
13590     }
13591
13592   if ((!ipv4_set) && (!ipv6_set))
13593     {
13594       errmsg ("no ipv4 nor ipv6 flag set");
13595       return -99;
13596     }
13597
13598   is_ipv6 = ipv6_set;
13599   vam->is_ipv6 = is_ipv6;
13600
13601   /* free old data */
13602   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13603     {
13604       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13605     }
13606   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13607
13608   M (IP_DUMP, mp);
13609   mp->is_ipv6 = ipv6_set;
13610   S (mp);
13611
13612   /* Use a control ping for synchronization */
13613   MPING (CONTROL_PING, mp_ping);
13614   S (mp_ping);
13615
13616   W (ret);
13617   return ret;
13618 }
13619
13620 static int
13621 api_ipsec_spd_add_del (vat_main_t * vam)
13622 {
13623   unformat_input_t *i = vam->input;
13624   vl_api_ipsec_spd_add_del_t *mp;
13625   u32 spd_id = ~0;
13626   u8 is_add = 1;
13627   int ret;
13628
13629   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13630     {
13631       if (unformat (i, "spd_id %d", &spd_id))
13632         ;
13633       else if (unformat (i, "del"))
13634         is_add = 0;
13635       else
13636         {
13637           clib_warning ("parse error '%U'", format_unformat_error, i);
13638           return -99;
13639         }
13640     }
13641   if (spd_id == ~0)
13642     {
13643       errmsg ("spd_id must be set");
13644       return -99;
13645     }
13646
13647   M (IPSEC_SPD_ADD_DEL, mp);
13648
13649   mp->spd_id = ntohl (spd_id);
13650   mp->is_add = is_add;
13651
13652   S (mp);
13653   W (ret);
13654   return ret;
13655 }
13656
13657 static int
13658 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13659 {
13660   unformat_input_t *i = vam->input;
13661   vl_api_ipsec_interface_add_del_spd_t *mp;
13662   u32 sw_if_index;
13663   u8 sw_if_index_set = 0;
13664   u32 spd_id = (u32) ~ 0;
13665   u8 is_add = 1;
13666   int ret;
13667
13668   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13669     {
13670       if (unformat (i, "del"))
13671         is_add = 0;
13672       else if (unformat (i, "spd_id %d", &spd_id))
13673         ;
13674       else
13675         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13676         sw_if_index_set = 1;
13677       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13678         sw_if_index_set = 1;
13679       else
13680         {
13681           clib_warning ("parse error '%U'", format_unformat_error, i);
13682           return -99;
13683         }
13684
13685     }
13686
13687   if (spd_id == (u32) ~ 0)
13688     {
13689       errmsg ("spd_id must be set");
13690       return -99;
13691     }
13692
13693   if (sw_if_index_set == 0)
13694     {
13695       errmsg ("missing interface name or sw_if_index");
13696       return -99;
13697     }
13698
13699   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13700
13701   mp->spd_id = ntohl (spd_id);
13702   mp->sw_if_index = ntohl (sw_if_index);
13703   mp->is_add = is_add;
13704
13705   S (mp);
13706   W (ret);
13707   return ret;
13708 }
13709
13710 static int
13711 api_ipsec_spd_add_del_entry (vat_main_t * vam)
13712 {
13713   unformat_input_t *i = vam->input;
13714   vl_api_ipsec_spd_add_del_entry_t *mp;
13715   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
13716   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13717   i32 priority = 0;
13718   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13719   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13720   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
13721   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
13722   int ret;
13723
13724   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
13725   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
13726   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
13727   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
13728   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
13729   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
13730
13731   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13732     {
13733       if (unformat (i, "del"))
13734         is_add = 0;
13735       if (unformat (i, "outbound"))
13736         is_outbound = 1;
13737       if (unformat (i, "inbound"))
13738         is_outbound = 0;
13739       else if (unformat (i, "spd_id %d", &spd_id))
13740         ;
13741       else if (unformat (i, "sa_id %d", &sa_id))
13742         ;
13743       else if (unformat (i, "priority %d", &priority))
13744         ;
13745       else if (unformat (i, "protocol %d", &protocol))
13746         ;
13747       else if (unformat (i, "lport_start %d", &lport_start))
13748         ;
13749       else if (unformat (i, "lport_stop %d", &lport_stop))
13750         ;
13751       else if (unformat (i, "rport_start %d", &rport_start))
13752         ;
13753       else if (unformat (i, "rport_stop %d", &rport_stop))
13754         ;
13755       else
13756         if (unformat
13757             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
13758         {
13759           is_ipv6 = 0;
13760           is_ip_any = 0;
13761         }
13762       else
13763         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
13764         {
13765           is_ipv6 = 0;
13766           is_ip_any = 0;
13767         }
13768       else
13769         if (unformat
13770             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
13771         {
13772           is_ipv6 = 0;
13773           is_ip_any = 0;
13774         }
13775       else
13776         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
13777         {
13778           is_ipv6 = 0;
13779           is_ip_any = 0;
13780         }
13781       else
13782         if (unformat
13783             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
13784         {
13785           is_ipv6 = 1;
13786           is_ip_any = 0;
13787         }
13788       else
13789         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
13790         {
13791           is_ipv6 = 1;
13792           is_ip_any = 0;
13793         }
13794       else
13795         if (unformat
13796             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
13797         {
13798           is_ipv6 = 1;
13799           is_ip_any = 0;
13800         }
13801       else
13802         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
13803         {
13804           is_ipv6 = 1;
13805           is_ip_any = 0;
13806         }
13807       else
13808         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13809         {
13810           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13811             {
13812               clib_warning ("unsupported action: 'resolve'");
13813               return -99;
13814             }
13815         }
13816       else
13817         {
13818           clib_warning ("parse error '%U'", format_unformat_error, i);
13819           return -99;
13820         }
13821
13822     }
13823
13824   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
13825
13826   mp->spd_id = ntohl (spd_id);
13827   mp->priority = ntohl (priority);
13828   mp->is_outbound = is_outbound;
13829
13830   mp->is_ipv6 = is_ipv6;
13831   if (is_ipv6 || is_ip_any)
13832     {
13833       clib_memcpy (mp->remote_address_start, &raddr6_start,
13834                    sizeof (ip6_address_t));
13835       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
13836                    sizeof (ip6_address_t));
13837       clib_memcpy (mp->local_address_start, &laddr6_start,
13838                    sizeof (ip6_address_t));
13839       clib_memcpy (mp->local_address_stop, &laddr6_stop,
13840                    sizeof (ip6_address_t));
13841     }
13842   else
13843     {
13844       clib_memcpy (mp->remote_address_start, &raddr4_start,
13845                    sizeof (ip4_address_t));
13846       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
13847                    sizeof (ip4_address_t));
13848       clib_memcpy (mp->local_address_start, &laddr4_start,
13849                    sizeof (ip4_address_t));
13850       clib_memcpy (mp->local_address_stop, &laddr4_stop,
13851                    sizeof (ip4_address_t));
13852     }
13853   mp->protocol = (u8) protocol;
13854   mp->local_port_start = ntohs ((u16) lport_start);
13855   mp->local_port_stop = ntohs ((u16) lport_stop);
13856   mp->remote_port_start = ntohs ((u16) rport_start);
13857   mp->remote_port_stop = ntohs ((u16) rport_stop);
13858   mp->policy = (u8) policy;
13859   mp->sa_id = ntohl (sa_id);
13860   mp->is_add = is_add;
13861   mp->is_ip_any = is_ip_any;
13862   S (mp);
13863   W (ret);
13864   return ret;
13865 }
13866
13867 static int
13868 api_ipsec_sad_add_del_entry (vat_main_t * vam)
13869 {
13870   unformat_input_t *i = vam->input;
13871   vl_api_ipsec_sad_add_del_entry_t *mp;
13872   u32 sad_id = 0, spi = 0;
13873   u8 *ck = 0, *ik = 0;
13874   u8 is_add = 1;
13875
13876   u8 protocol = IPSEC_PROTOCOL_AH;
13877   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
13878   u32 crypto_alg = 0, integ_alg = 0;
13879   ip4_address_t tun_src4;
13880   ip4_address_t tun_dst4;
13881   ip6_address_t tun_src6;
13882   ip6_address_t tun_dst6;
13883   int ret;
13884
13885   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13886     {
13887       if (unformat (i, "del"))
13888         is_add = 0;
13889       else if (unformat (i, "sad_id %d", &sad_id))
13890         ;
13891       else if (unformat (i, "spi %d", &spi))
13892         ;
13893       else if (unformat (i, "esp"))
13894         protocol = IPSEC_PROTOCOL_ESP;
13895       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
13896         {
13897           is_tunnel = 1;
13898           is_tunnel_ipv6 = 0;
13899         }
13900       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
13901         {
13902           is_tunnel = 1;
13903           is_tunnel_ipv6 = 0;
13904         }
13905       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
13906         {
13907           is_tunnel = 1;
13908           is_tunnel_ipv6 = 1;
13909         }
13910       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
13911         {
13912           is_tunnel = 1;
13913           is_tunnel_ipv6 = 1;
13914         }
13915       else
13916         if (unformat
13917             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
13918         {
13919           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
13920               crypto_alg >= IPSEC_CRYPTO_N_ALG)
13921             {
13922               clib_warning ("unsupported crypto-alg: '%U'",
13923                             format_ipsec_crypto_alg, crypto_alg);
13924               return -99;
13925             }
13926         }
13927       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13928         ;
13929       else
13930         if (unformat
13931             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
13932         {
13933           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
13934               integ_alg >= IPSEC_INTEG_N_ALG)
13935             {
13936               clib_warning ("unsupported integ-alg: '%U'",
13937                             format_ipsec_integ_alg, integ_alg);
13938               return -99;
13939             }
13940         }
13941       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13942         ;
13943       else
13944         {
13945           clib_warning ("parse error '%U'", format_unformat_error, i);
13946           return -99;
13947         }
13948
13949     }
13950
13951   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
13952
13953   mp->sad_id = ntohl (sad_id);
13954   mp->is_add = is_add;
13955   mp->protocol = protocol;
13956   mp->spi = ntohl (spi);
13957   mp->is_tunnel = is_tunnel;
13958   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
13959   mp->crypto_algorithm = crypto_alg;
13960   mp->integrity_algorithm = integ_alg;
13961   mp->crypto_key_length = vec_len (ck);
13962   mp->integrity_key_length = vec_len (ik);
13963
13964   if (mp->crypto_key_length > sizeof (mp->crypto_key))
13965     mp->crypto_key_length = sizeof (mp->crypto_key);
13966
13967   if (mp->integrity_key_length > sizeof (mp->integrity_key))
13968     mp->integrity_key_length = sizeof (mp->integrity_key);
13969
13970   if (ck)
13971     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
13972   if (ik)
13973     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
13974
13975   if (is_tunnel)
13976     {
13977       if (is_tunnel_ipv6)
13978         {
13979           clib_memcpy (mp->tunnel_src_address, &tun_src6,
13980                        sizeof (ip6_address_t));
13981           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
13982                        sizeof (ip6_address_t));
13983         }
13984       else
13985         {
13986           clib_memcpy (mp->tunnel_src_address, &tun_src4,
13987                        sizeof (ip4_address_t));
13988           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
13989                        sizeof (ip4_address_t));
13990         }
13991     }
13992
13993   S (mp);
13994   W (ret);
13995   return ret;
13996 }
13997
13998 static int
13999 api_ipsec_sa_set_key (vat_main_t * vam)
14000 {
14001   unformat_input_t *i = vam->input;
14002   vl_api_ipsec_sa_set_key_t *mp;
14003   u32 sa_id;
14004   u8 *ck = 0, *ik = 0;
14005   int ret;
14006
14007   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14008     {
14009       if (unformat (i, "sa_id %d", &sa_id))
14010         ;
14011       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14012         ;
14013       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14014         ;
14015       else
14016         {
14017           clib_warning ("parse error '%U'", format_unformat_error, i);
14018           return -99;
14019         }
14020     }
14021
14022   M (IPSEC_SA_SET_KEY, mp);
14023
14024   mp->sa_id = ntohl (sa_id);
14025   mp->crypto_key_length = vec_len (ck);
14026   mp->integrity_key_length = vec_len (ik);
14027
14028   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14029     mp->crypto_key_length = sizeof (mp->crypto_key);
14030
14031   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14032     mp->integrity_key_length = sizeof (mp->integrity_key);
14033
14034   if (ck)
14035     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14036   if (ik)
14037     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14038
14039   S (mp);
14040   W (ret);
14041   return ret;
14042 }
14043
14044 static int
14045 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14046 {
14047   unformat_input_t *i = vam->input;
14048   vl_api_ipsec_tunnel_if_add_del_t *mp;
14049   u32 local_spi = 0, remote_spi = 0;
14050   u32 crypto_alg = 0, integ_alg = 0;
14051   u8 *lck = NULL, *rck = NULL;
14052   u8 *lik = NULL, *rik = NULL;
14053   ip4_address_t local_ip = { {0} };
14054   ip4_address_t remote_ip = { {0} };
14055   u8 is_add = 1;
14056   u8 esn = 0;
14057   u8 anti_replay = 0;
14058   int ret;
14059
14060   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14061     {
14062       if (unformat (i, "del"))
14063         is_add = 0;
14064       else if (unformat (i, "esn"))
14065         esn = 1;
14066       else if (unformat (i, "anti_replay"))
14067         anti_replay = 1;
14068       else if (unformat (i, "local_spi %d", &local_spi))
14069         ;
14070       else if (unformat (i, "remote_spi %d", &remote_spi))
14071         ;
14072       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
14073         ;
14074       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
14075         ;
14076       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14077         ;
14078       else
14079         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14080         ;
14081       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14082         ;
14083       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14084         ;
14085       else
14086         if (unformat
14087             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14088         {
14089           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14090               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14091             {
14092               errmsg ("unsupported crypto-alg: '%U'\n",
14093                       format_ipsec_crypto_alg, crypto_alg);
14094               return -99;
14095             }
14096         }
14097       else
14098         if (unformat
14099             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14100         {
14101           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14102               integ_alg >= IPSEC_INTEG_N_ALG)
14103             {
14104               errmsg ("unsupported integ-alg: '%U'\n",
14105                       format_ipsec_integ_alg, integ_alg);
14106               return -99;
14107             }
14108         }
14109       else
14110         {
14111           errmsg ("parse error '%U'\n", format_unformat_error, i);
14112           return -99;
14113         }
14114     }
14115
14116   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14117
14118   mp->is_add = is_add;
14119   mp->esn = esn;
14120   mp->anti_replay = anti_replay;
14121
14122   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
14123   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
14124
14125   mp->local_spi = htonl (local_spi);
14126   mp->remote_spi = htonl (remote_spi);
14127   mp->crypto_alg = (u8) crypto_alg;
14128
14129   mp->local_crypto_key_len = 0;
14130   if (lck)
14131     {
14132       mp->local_crypto_key_len = vec_len (lck);
14133       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14134         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14135       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14136     }
14137
14138   mp->remote_crypto_key_len = 0;
14139   if (rck)
14140     {
14141       mp->remote_crypto_key_len = vec_len (rck);
14142       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14143         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14144       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14145     }
14146
14147   mp->integ_alg = (u8) integ_alg;
14148
14149   mp->local_integ_key_len = 0;
14150   if (lik)
14151     {
14152       mp->local_integ_key_len = vec_len (lik);
14153       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14154         mp->local_integ_key_len = sizeof (mp->local_integ_key);
14155       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14156     }
14157
14158   mp->remote_integ_key_len = 0;
14159   if (rik)
14160     {
14161       mp->remote_integ_key_len = vec_len (rik);
14162       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14163         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14164       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14165     }
14166
14167   S (mp);
14168   W (ret);
14169   return ret;
14170 }
14171
14172 static void
14173 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14174 {
14175   vat_main_t *vam = &vat_main;
14176
14177   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14178          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
14179          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
14180          "tunnel_src_addr %U tunnel_dst_addr %U "
14181          "salt %u seq_outbound %lu last_seq_inbound %lu "
14182          "replay_window %lu total_data_size %lu\n",
14183          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
14184          mp->protocol,
14185          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
14186          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
14187          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
14188          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14189          mp->tunnel_src_addr,
14190          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14191          mp->tunnel_dst_addr,
14192          ntohl (mp->salt),
14193          clib_net_to_host_u64 (mp->seq_outbound),
14194          clib_net_to_host_u64 (mp->last_seq_inbound),
14195          clib_net_to_host_u64 (mp->replay_window),
14196          clib_net_to_host_u64 (mp->total_data_size));
14197 }
14198
14199 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14200 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14201
14202 static void vl_api_ipsec_sa_details_t_handler_json
14203   (vl_api_ipsec_sa_details_t * mp)
14204 {
14205   vat_main_t *vam = &vat_main;
14206   vat_json_node_t *node = NULL;
14207   struct in_addr src_ip4, dst_ip4;
14208   struct in6_addr src_ip6, dst_ip6;
14209
14210   if (VAT_JSON_ARRAY != vam->json_tree.type)
14211     {
14212       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14213       vat_json_init_array (&vam->json_tree);
14214     }
14215   node = vat_json_array_add (&vam->json_tree);
14216
14217   vat_json_init_object (node);
14218   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
14219   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14220   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
14221   vat_json_object_add_uint (node, "proto", mp->protocol);
14222   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
14223   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
14224   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
14225   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
14226   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
14227   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
14228   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
14229                              mp->crypto_key_len);
14230   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
14231                              mp->integ_key_len);
14232   if (mp->is_tunnel_ip6)
14233     {
14234       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
14235       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
14236       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
14237       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
14238     }
14239   else
14240     {
14241       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
14242       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
14243       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
14244       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
14245     }
14246   vat_json_object_add_uint (node, "replay_window",
14247                             clib_net_to_host_u64 (mp->replay_window));
14248   vat_json_object_add_uint (node, "total_data_size",
14249                             clib_net_to_host_u64 (mp->total_data_size));
14250
14251 }
14252
14253 static int
14254 api_ipsec_sa_dump (vat_main_t * vam)
14255 {
14256   unformat_input_t *i = vam->input;
14257   vl_api_ipsec_sa_dump_t *mp;
14258   vl_api_control_ping_t *mp_ping;
14259   u32 sa_id = ~0;
14260   int ret;
14261
14262   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14263     {
14264       if (unformat (i, "sa_id %d", &sa_id))
14265         ;
14266       else
14267         {
14268           clib_warning ("parse error '%U'", format_unformat_error, i);
14269           return -99;
14270         }
14271     }
14272
14273   M (IPSEC_SA_DUMP, mp);
14274
14275   mp->sa_id = ntohl (sa_id);
14276
14277   S (mp);
14278
14279   /* Use a control ping for synchronization */
14280   M (CONTROL_PING, mp_ping);
14281   S (mp_ping);
14282
14283   W (ret);
14284   return ret;
14285 }
14286
14287 static int
14288 api_ikev2_profile_add_del (vat_main_t * vam)
14289 {
14290   unformat_input_t *i = vam->input;
14291   vl_api_ikev2_profile_add_del_t *mp;
14292   u8 is_add = 1;
14293   u8 *name = 0;
14294   int ret;
14295
14296   const char *valid_chars = "a-zA-Z0-9_";
14297
14298   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14299     {
14300       if (unformat (i, "del"))
14301         is_add = 0;
14302       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14303         vec_add1 (name, 0);
14304       else
14305         {
14306           errmsg ("parse error '%U'", format_unformat_error, i);
14307           return -99;
14308         }
14309     }
14310
14311   if (!vec_len (name))
14312     {
14313       errmsg ("profile name must be specified");
14314       return -99;
14315     }
14316
14317   if (vec_len (name) > 64)
14318     {
14319       errmsg ("profile name too long");
14320       return -99;
14321     }
14322
14323   M (IKEV2_PROFILE_ADD_DEL, mp);
14324
14325   clib_memcpy (mp->name, name, vec_len (name));
14326   mp->is_add = is_add;
14327   vec_free (name);
14328
14329   S (mp);
14330   W (ret);
14331   return ret;
14332 }
14333
14334 static int
14335 api_ikev2_profile_set_auth (vat_main_t * vam)
14336 {
14337   unformat_input_t *i = vam->input;
14338   vl_api_ikev2_profile_set_auth_t *mp;
14339   u8 *name = 0;
14340   u8 *data = 0;
14341   u32 auth_method = 0;
14342   u8 is_hex = 0;
14343   int ret;
14344
14345   const char *valid_chars = "a-zA-Z0-9_";
14346
14347   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14348     {
14349       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14350         vec_add1 (name, 0);
14351       else if (unformat (i, "auth_method %U",
14352                          unformat_ikev2_auth_method, &auth_method))
14353         ;
14354       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
14355         is_hex = 1;
14356       else if (unformat (i, "auth_data %v", &data))
14357         ;
14358       else
14359         {
14360           errmsg ("parse error '%U'", format_unformat_error, i);
14361           return -99;
14362         }
14363     }
14364
14365   if (!vec_len (name))
14366     {
14367       errmsg ("profile name must be specified");
14368       return -99;
14369     }
14370
14371   if (vec_len (name) > 64)
14372     {
14373       errmsg ("profile name too long");
14374       return -99;
14375     }
14376
14377   if (!vec_len (data))
14378     {
14379       errmsg ("auth_data must be specified");
14380       return -99;
14381     }
14382
14383   if (!auth_method)
14384     {
14385       errmsg ("auth_method must be specified");
14386       return -99;
14387     }
14388
14389   M (IKEV2_PROFILE_SET_AUTH, mp);
14390
14391   mp->is_hex = is_hex;
14392   mp->auth_method = (u8) auth_method;
14393   mp->data_len = vec_len (data);
14394   clib_memcpy (mp->name, name, vec_len (name));
14395   clib_memcpy (mp->data, data, vec_len (data));
14396   vec_free (name);
14397   vec_free (data);
14398
14399   S (mp);
14400   W (ret);
14401   return ret;
14402 }
14403
14404 static int
14405 api_ikev2_profile_set_id (vat_main_t * vam)
14406 {
14407   unformat_input_t *i = vam->input;
14408   vl_api_ikev2_profile_set_id_t *mp;
14409   u8 *name = 0;
14410   u8 *data = 0;
14411   u8 is_local = 0;
14412   u32 id_type = 0;
14413   ip4_address_t ip4;
14414   int ret;
14415
14416   const char *valid_chars = "a-zA-Z0-9_";
14417
14418   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14419     {
14420       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14421         vec_add1 (name, 0);
14422       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
14423         ;
14424       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
14425         {
14426           data = vec_new (u8, 4);
14427           clib_memcpy (data, ip4.as_u8, 4);
14428         }
14429       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
14430         ;
14431       else if (unformat (i, "id_data %v", &data))
14432         ;
14433       else if (unformat (i, "local"))
14434         is_local = 1;
14435       else if (unformat (i, "remote"))
14436         is_local = 0;
14437       else
14438         {
14439           errmsg ("parse error '%U'", format_unformat_error, i);
14440           return -99;
14441         }
14442     }
14443
14444   if (!vec_len (name))
14445     {
14446       errmsg ("profile name must be specified");
14447       return -99;
14448     }
14449
14450   if (vec_len (name) > 64)
14451     {
14452       errmsg ("profile name too long");
14453       return -99;
14454     }
14455
14456   if (!vec_len (data))
14457     {
14458       errmsg ("id_data must be specified");
14459       return -99;
14460     }
14461
14462   if (!id_type)
14463     {
14464       errmsg ("id_type must be specified");
14465       return -99;
14466     }
14467
14468   M (IKEV2_PROFILE_SET_ID, mp);
14469
14470   mp->is_local = is_local;
14471   mp->id_type = (u8) id_type;
14472   mp->data_len = vec_len (data);
14473   clib_memcpy (mp->name, name, vec_len (name));
14474   clib_memcpy (mp->data, data, vec_len (data));
14475   vec_free (name);
14476   vec_free (data);
14477
14478   S (mp);
14479   W (ret);
14480   return ret;
14481 }
14482
14483 static int
14484 api_ikev2_profile_set_ts (vat_main_t * vam)
14485 {
14486   unformat_input_t *i = vam->input;
14487   vl_api_ikev2_profile_set_ts_t *mp;
14488   u8 *name = 0;
14489   u8 is_local = 0;
14490   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
14491   ip4_address_t start_addr, end_addr;
14492
14493   const char *valid_chars = "a-zA-Z0-9_";
14494   int ret;
14495
14496   start_addr.as_u32 = 0;
14497   end_addr.as_u32 = (u32) ~ 0;
14498
14499   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14500     {
14501       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14502         vec_add1 (name, 0);
14503       else if (unformat (i, "protocol %d", &proto))
14504         ;
14505       else if (unformat (i, "start_port %d", &start_port))
14506         ;
14507       else if (unformat (i, "end_port %d", &end_port))
14508         ;
14509       else
14510         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
14511         ;
14512       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
14513         ;
14514       else if (unformat (i, "local"))
14515         is_local = 1;
14516       else if (unformat (i, "remote"))
14517         is_local = 0;
14518       else
14519         {
14520           errmsg ("parse error '%U'", format_unformat_error, i);
14521           return -99;
14522         }
14523     }
14524
14525   if (!vec_len (name))
14526     {
14527       errmsg ("profile name must be specified");
14528       return -99;
14529     }
14530
14531   if (vec_len (name) > 64)
14532     {
14533       errmsg ("profile name too long");
14534       return -99;
14535     }
14536
14537   M (IKEV2_PROFILE_SET_TS, mp);
14538
14539   mp->is_local = is_local;
14540   mp->proto = (u8) proto;
14541   mp->start_port = (u16) start_port;
14542   mp->end_port = (u16) end_port;
14543   mp->start_addr = start_addr.as_u32;
14544   mp->end_addr = end_addr.as_u32;
14545   clib_memcpy (mp->name, name, vec_len (name));
14546   vec_free (name);
14547
14548   S (mp);
14549   W (ret);
14550   return ret;
14551 }
14552
14553 static int
14554 api_ikev2_set_local_key (vat_main_t * vam)
14555 {
14556   unformat_input_t *i = vam->input;
14557   vl_api_ikev2_set_local_key_t *mp;
14558   u8 *file = 0;
14559   int ret;
14560
14561   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14562     {
14563       if (unformat (i, "file %v", &file))
14564         vec_add1 (file, 0);
14565       else
14566         {
14567           errmsg ("parse error '%U'", format_unformat_error, i);
14568           return -99;
14569         }
14570     }
14571
14572   if (!vec_len (file))
14573     {
14574       errmsg ("RSA key file must be specified");
14575       return -99;
14576     }
14577
14578   if (vec_len (file) > 256)
14579     {
14580       errmsg ("file name too long");
14581       return -99;
14582     }
14583
14584   M (IKEV2_SET_LOCAL_KEY, mp);
14585
14586   clib_memcpy (mp->key_file, file, vec_len (file));
14587   vec_free (file);
14588
14589   S (mp);
14590   W (ret);
14591   return ret;
14592 }
14593
14594 static int
14595 api_ikev2_set_responder (vat_main_t * vam)
14596 {
14597   unformat_input_t *i = vam->input;
14598   vl_api_ikev2_set_responder_t *mp;
14599   int ret;
14600   u8 *name = 0;
14601   u32 sw_if_index = ~0;
14602   ip4_address_t address;
14603
14604   const char *valid_chars = "a-zA-Z0-9_";
14605
14606   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14607     {
14608       if (unformat
14609           (i, "%U interface %d address %U", unformat_token, valid_chars,
14610            &name, &sw_if_index, unformat_ip4_address, &address))
14611         vec_add1 (name, 0);
14612       else
14613         {
14614           errmsg ("parse error '%U'", format_unformat_error, i);
14615           return -99;
14616         }
14617     }
14618
14619   if (!vec_len (name))
14620     {
14621       errmsg ("profile name must be specified");
14622       return -99;
14623     }
14624
14625   if (vec_len (name) > 64)
14626     {
14627       errmsg ("profile name too long");
14628       return -99;
14629     }
14630
14631   M (IKEV2_SET_RESPONDER, mp);
14632
14633   clib_memcpy (mp->name, name, vec_len (name));
14634   vec_free (name);
14635
14636   mp->sw_if_index = sw_if_index;
14637   clib_memcpy (mp->address, &address, sizeof (address));
14638
14639   S (mp);
14640   W (ret);
14641   return ret;
14642 }
14643
14644 static int
14645 api_ikev2_set_ike_transforms (vat_main_t * vam)
14646 {
14647   unformat_input_t *i = vam->input;
14648   vl_api_ikev2_set_ike_transforms_t *mp;
14649   int ret;
14650   u8 *name = 0;
14651   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
14652
14653   const char *valid_chars = "a-zA-Z0-9_";
14654
14655   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14656     {
14657       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
14658                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
14659         vec_add1 (name, 0);
14660       else
14661         {
14662           errmsg ("parse error '%U'", format_unformat_error, i);
14663           return -99;
14664         }
14665     }
14666
14667   if (!vec_len (name))
14668     {
14669       errmsg ("profile name must be specified");
14670       return -99;
14671     }
14672
14673   if (vec_len (name) > 64)
14674     {
14675       errmsg ("profile name too long");
14676       return -99;
14677     }
14678
14679   M (IKEV2_SET_IKE_TRANSFORMS, mp);
14680
14681   clib_memcpy (mp->name, name, vec_len (name));
14682   vec_free (name);
14683   mp->crypto_alg = crypto_alg;
14684   mp->crypto_key_size = crypto_key_size;
14685   mp->integ_alg = integ_alg;
14686   mp->dh_group = dh_group;
14687
14688   S (mp);
14689   W (ret);
14690   return ret;
14691 }
14692
14693
14694 static int
14695 api_ikev2_set_esp_transforms (vat_main_t * vam)
14696 {
14697   unformat_input_t *i = vam->input;
14698   vl_api_ikev2_set_esp_transforms_t *mp;
14699   int ret;
14700   u8 *name = 0;
14701   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
14702
14703   const char *valid_chars = "a-zA-Z0-9_";
14704
14705   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14706     {
14707       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
14708                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
14709         vec_add1 (name, 0);
14710       else
14711         {
14712           errmsg ("parse error '%U'", format_unformat_error, i);
14713           return -99;
14714         }
14715     }
14716
14717   if (!vec_len (name))
14718     {
14719       errmsg ("profile name must be specified");
14720       return -99;
14721     }
14722
14723   if (vec_len (name) > 64)
14724     {
14725       errmsg ("profile name too long");
14726       return -99;
14727     }
14728
14729   M (IKEV2_SET_ESP_TRANSFORMS, mp);
14730
14731   clib_memcpy (mp->name, name, vec_len (name));
14732   vec_free (name);
14733   mp->crypto_alg = crypto_alg;
14734   mp->crypto_key_size = crypto_key_size;
14735   mp->integ_alg = integ_alg;
14736   mp->dh_group = dh_group;
14737
14738   S (mp);
14739   W (ret);
14740   return ret;
14741 }
14742
14743 static int
14744 api_ikev2_set_sa_lifetime (vat_main_t * vam)
14745 {
14746   unformat_input_t *i = vam->input;
14747   vl_api_ikev2_set_sa_lifetime_t *mp;
14748   int ret;
14749   u8 *name = 0;
14750   u64 lifetime, lifetime_maxdata;
14751   u32 lifetime_jitter, handover;
14752
14753   const char *valid_chars = "a-zA-Z0-9_";
14754
14755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14756     {
14757       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
14758                     &lifetime, &lifetime_jitter, &handover,
14759                     &lifetime_maxdata))
14760         vec_add1 (name, 0);
14761       else
14762         {
14763           errmsg ("parse error '%U'", format_unformat_error, i);
14764           return -99;
14765         }
14766     }
14767
14768   if (!vec_len (name))
14769     {
14770       errmsg ("profile name must be specified");
14771       return -99;
14772     }
14773
14774   if (vec_len (name) > 64)
14775     {
14776       errmsg ("profile name too long");
14777       return -99;
14778     }
14779
14780   M (IKEV2_SET_SA_LIFETIME, mp);
14781
14782   clib_memcpy (mp->name, name, vec_len (name));
14783   vec_free (name);
14784   mp->lifetime = lifetime;
14785   mp->lifetime_jitter = lifetime_jitter;
14786   mp->handover = handover;
14787   mp->lifetime_maxdata = lifetime_maxdata;
14788
14789   S (mp);
14790   W (ret);
14791   return ret;
14792 }
14793
14794 static int
14795 api_ikev2_initiate_sa_init (vat_main_t * vam)
14796 {
14797   unformat_input_t *i = vam->input;
14798   vl_api_ikev2_initiate_sa_init_t *mp;
14799   int ret;
14800   u8 *name = 0;
14801
14802   const char *valid_chars = "a-zA-Z0-9_";
14803
14804   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14805     {
14806       if (unformat (i, "%U", unformat_token, valid_chars, &name))
14807         vec_add1 (name, 0);
14808       else
14809         {
14810           errmsg ("parse error '%U'", format_unformat_error, i);
14811           return -99;
14812         }
14813     }
14814
14815   if (!vec_len (name))
14816     {
14817       errmsg ("profile name must be specified");
14818       return -99;
14819     }
14820
14821   if (vec_len (name) > 64)
14822     {
14823       errmsg ("profile name too long");
14824       return -99;
14825     }
14826
14827   M (IKEV2_INITIATE_SA_INIT, mp);
14828
14829   clib_memcpy (mp->name, name, vec_len (name));
14830   vec_free (name);
14831
14832   S (mp);
14833   W (ret);
14834   return ret;
14835 }
14836
14837 static int
14838 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
14839 {
14840   unformat_input_t *i = vam->input;
14841   vl_api_ikev2_initiate_del_ike_sa_t *mp;
14842   int ret;
14843   u64 ispi;
14844
14845
14846   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14847     {
14848       if (unformat (i, "%lx", &ispi))
14849         ;
14850       else
14851         {
14852           errmsg ("parse error '%U'", format_unformat_error, i);
14853           return -99;
14854         }
14855     }
14856
14857   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
14858
14859   mp->ispi = ispi;
14860
14861   S (mp);
14862   W (ret);
14863   return ret;
14864 }
14865
14866 static int
14867 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
14868 {
14869   unformat_input_t *i = vam->input;
14870   vl_api_ikev2_initiate_del_child_sa_t *mp;
14871   int ret;
14872   u32 ispi;
14873
14874
14875   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14876     {
14877       if (unformat (i, "%x", &ispi))
14878         ;
14879       else
14880         {
14881           errmsg ("parse error '%U'", format_unformat_error, i);
14882           return -99;
14883         }
14884     }
14885
14886   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
14887
14888   mp->ispi = ispi;
14889
14890   S (mp);
14891   W (ret);
14892   return ret;
14893 }
14894
14895 static int
14896 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
14897 {
14898   unformat_input_t *i = vam->input;
14899   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
14900   int ret;
14901   u32 ispi;
14902
14903
14904   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14905     {
14906       if (unformat (i, "%x", &ispi))
14907         ;
14908       else
14909         {
14910           errmsg ("parse error '%U'", format_unformat_error, i);
14911           return -99;
14912         }
14913     }
14914
14915   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
14916
14917   mp->ispi = ispi;
14918
14919   S (mp);
14920   W (ret);
14921   return ret;
14922 }
14923
14924 /*
14925  * MAP
14926  */
14927 static int
14928 api_map_add_domain (vat_main_t * vam)
14929 {
14930   unformat_input_t *i = vam->input;
14931   vl_api_map_add_domain_t *mp;
14932
14933   ip4_address_t ip4_prefix;
14934   ip6_address_t ip6_prefix;
14935   ip6_address_t ip6_src;
14936   u32 num_m_args = 0;
14937   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
14938     0, psid_length = 0;
14939   u8 is_translation = 0;
14940   u32 mtu = 0;
14941   u32 ip6_src_len = 128;
14942   int ret;
14943
14944   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14945     {
14946       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
14947                     &ip4_prefix, &ip4_prefix_len))
14948         num_m_args++;
14949       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
14950                          &ip6_prefix, &ip6_prefix_len))
14951         num_m_args++;
14952       else
14953         if (unformat
14954             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
14955              &ip6_src_len))
14956         num_m_args++;
14957       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
14958         num_m_args++;
14959       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
14960         num_m_args++;
14961       else if (unformat (i, "psid-offset %d", &psid_offset))
14962         num_m_args++;
14963       else if (unformat (i, "psid-len %d", &psid_length))
14964         num_m_args++;
14965       else if (unformat (i, "mtu %d", &mtu))
14966         num_m_args++;
14967       else if (unformat (i, "map-t"))
14968         is_translation = 1;
14969       else
14970         {
14971           clib_warning ("parse error '%U'", format_unformat_error, i);
14972           return -99;
14973         }
14974     }
14975
14976   if (num_m_args < 3)
14977     {
14978       errmsg ("mandatory argument(s) missing");
14979       return -99;
14980     }
14981
14982   /* Construct the API message */
14983   M (MAP_ADD_DOMAIN, mp);
14984
14985   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
14986   mp->ip4_prefix_len = ip4_prefix_len;
14987
14988   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
14989   mp->ip6_prefix_len = ip6_prefix_len;
14990
14991   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
14992   mp->ip6_src_prefix_len = ip6_src_len;
14993
14994   mp->ea_bits_len = ea_bits_len;
14995   mp->psid_offset = psid_offset;
14996   mp->psid_length = psid_length;
14997   mp->is_translation = is_translation;
14998   mp->mtu = htons (mtu);
14999
15000   /* send it... */
15001   S (mp);
15002
15003   /* Wait for a reply, return good/bad news  */
15004   W (ret);
15005   return ret;
15006 }
15007
15008 static int
15009 api_map_del_domain (vat_main_t * vam)
15010 {
15011   unformat_input_t *i = vam->input;
15012   vl_api_map_del_domain_t *mp;
15013
15014   u32 num_m_args = 0;
15015   u32 index;
15016   int ret;
15017
15018   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15019     {
15020       if (unformat (i, "index %d", &index))
15021         num_m_args++;
15022       else
15023         {
15024           clib_warning ("parse error '%U'", format_unformat_error, i);
15025           return -99;
15026         }
15027     }
15028
15029   if (num_m_args != 1)
15030     {
15031       errmsg ("mandatory argument(s) missing");
15032       return -99;
15033     }
15034
15035   /* Construct the API message */
15036   M (MAP_DEL_DOMAIN, mp);
15037
15038   mp->index = ntohl (index);
15039
15040   /* send it... */
15041   S (mp);
15042
15043   /* Wait for a reply, return good/bad news  */
15044   W (ret);
15045   return ret;
15046 }
15047
15048 static int
15049 api_map_add_del_rule (vat_main_t * vam)
15050 {
15051   unformat_input_t *i = vam->input;
15052   vl_api_map_add_del_rule_t *mp;
15053   u8 is_add = 1;
15054   ip6_address_t ip6_dst;
15055   u32 num_m_args = 0, index, psid = 0;
15056   int ret;
15057
15058   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15059     {
15060       if (unformat (i, "index %d", &index))
15061         num_m_args++;
15062       else if (unformat (i, "psid %d", &psid))
15063         num_m_args++;
15064       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
15065         num_m_args++;
15066       else if (unformat (i, "del"))
15067         {
15068           is_add = 0;
15069         }
15070       else
15071         {
15072           clib_warning ("parse error '%U'", format_unformat_error, i);
15073           return -99;
15074         }
15075     }
15076
15077   /* Construct the API message */
15078   M (MAP_ADD_DEL_RULE, mp);
15079
15080   mp->index = ntohl (index);
15081   mp->is_add = is_add;
15082   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
15083   mp->psid = ntohs (psid);
15084
15085   /* send it... */
15086   S (mp);
15087
15088   /* Wait for a reply, return good/bad news  */
15089   W (ret);
15090   return ret;
15091 }
15092
15093 static int
15094 api_map_domain_dump (vat_main_t * vam)
15095 {
15096   vl_api_map_domain_dump_t *mp;
15097   vl_api_control_ping_t *mp_ping;
15098   int ret;
15099
15100   /* Construct the API message */
15101   M (MAP_DOMAIN_DUMP, mp);
15102
15103   /* send it... */
15104   S (mp);
15105
15106   /* Use a control ping for synchronization */
15107   MPING (CONTROL_PING, mp_ping);
15108   S (mp_ping);
15109
15110   W (ret);
15111   return ret;
15112 }
15113
15114 static int
15115 api_map_rule_dump (vat_main_t * vam)
15116 {
15117   unformat_input_t *i = vam->input;
15118   vl_api_map_rule_dump_t *mp;
15119   vl_api_control_ping_t *mp_ping;
15120   u32 domain_index = ~0;
15121   int ret;
15122
15123   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15124     {
15125       if (unformat (i, "index %u", &domain_index))
15126         ;
15127       else
15128         break;
15129     }
15130
15131   if (domain_index == ~0)
15132     {
15133       clib_warning ("parse error: domain index expected");
15134       return -99;
15135     }
15136
15137   /* Construct the API message */
15138   M (MAP_RULE_DUMP, mp);
15139
15140   mp->domain_index = htonl (domain_index);
15141
15142   /* send it... */
15143   S (mp);
15144
15145   /* Use a control ping for synchronization */
15146   MPING (CONTROL_PING, mp_ping);
15147   S (mp_ping);
15148
15149   W (ret);
15150   return ret;
15151 }
15152
15153 static void vl_api_map_add_domain_reply_t_handler
15154   (vl_api_map_add_domain_reply_t * mp)
15155 {
15156   vat_main_t *vam = &vat_main;
15157   i32 retval = ntohl (mp->retval);
15158
15159   if (vam->async_mode)
15160     {
15161       vam->async_errors += (retval < 0);
15162     }
15163   else
15164     {
15165       vam->retval = retval;
15166       vam->result_ready = 1;
15167     }
15168 }
15169
15170 static void vl_api_map_add_domain_reply_t_handler_json
15171   (vl_api_map_add_domain_reply_t * mp)
15172 {
15173   vat_main_t *vam = &vat_main;
15174   vat_json_node_t node;
15175
15176   vat_json_init_object (&node);
15177   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
15178   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
15179
15180   vat_json_print (vam->ofp, &node);
15181   vat_json_free (&node);
15182
15183   vam->retval = ntohl (mp->retval);
15184   vam->result_ready = 1;
15185 }
15186
15187 static int
15188 api_get_first_msg_id (vat_main_t * vam)
15189 {
15190   vl_api_get_first_msg_id_t *mp;
15191   unformat_input_t *i = vam->input;
15192   u8 *name;
15193   u8 name_set = 0;
15194   int ret;
15195
15196   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15197     {
15198       if (unformat (i, "client %s", &name))
15199         name_set = 1;
15200       else
15201         break;
15202     }
15203
15204   if (name_set == 0)
15205     {
15206       errmsg ("missing client name");
15207       return -99;
15208     }
15209   vec_add1 (name, 0);
15210
15211   if (vec_len (name) > 63)
15212     {
15213       errmsg ("client name too long");
15214       return -99;
15215     }
15216
15217   M (GET_FIRST_MSG_ID, mp);
15218   clib_memcpy (mp->name, name, vec_len (name));
15219   S (mp);
15220   W (ret);
15221   return ret;
15222 }
15223
15224 static int
15225 api_cop_interface_enable_disable (vat_main_t * vam)
15226 {
15227   unformat_input_t *line_input = vam->input;
15228   vl_api_cop_interface_enable_disable_t *mp;
15229   u32 sw_if_index = ~0;
15230   u8 enable_disable = 1;
15231   int ret;
15232
15233   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15234     {
15235       if (unformat (line_input, "disable"))
15236         enable_disable = 0;
15237       if (unformat (line_input, "enable"))
15238         enable_disable = 1;
15239       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15240                          vam, &sw_if_index))
15241         ;
15242       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15243         ;
15244       else
15245         break;
15246     }
15247
15248   if (sw_if_index == ~0)
15249     {
15250       errmsg ("missing interface name or sw_if_index");
15251       return -99;
15252     }
15253
15254   /* Construct the API message */
15255   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15256   mp->sw_if_index = ntohl (sw_if_index);
15257   mp->enable_disable = enable_disable;
15258
15259   /* send it... */
15260   S (mp);
15261   /* Wait for the reply */
15262   W (ret);
15263   return ret;
15264 }
15265
15266 static int
15267 api_cop_whitelist_enable_disable (vat_main_t * vam)
15268 {
15269   unformat_input_t *line_input = vam->input;
15270   vl_api_cop_whitelist_enable_disable_t *mp;
15271   u32 sw_if_index = ~0;
15272   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15273   u32 fib_id = 0;
15274   int ret;
15275
15276   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15277     {
15278       if (unformat (line_input, "ip4"))
15279         ip4 = 1;
15280       else if (unformat (line_input, "ip6"))
15281         ip6 = 1;
15282       else if (unformat (line_input, "default"))
15283         default_cop = 1;
15284       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15285                          vam, &sw_if_index))
15286         ;
15287       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15288         ;
15289       else if (unformat (line_input, "fib-id %d", &fib_id))
15290         ;
15291       else
15292         break;
15293     }
15294
15295   if (sw_if_index == ~0)
15296     {
15297       errmsg ("missing interface name or sw_if_index");
15298       return -99;
15299     }
15300
15301   /* Construct the API message */
15302   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15303   mp->sw_if_index = ntohl (sw_if_index);
15304   mp->fib_id = ntohl (fib_id);
15305   mp->ip4 = ip4;
15306   mp->ip6 = ip6;
15307   mp->default_cop = default_cop;
15308
15309   /* send it... */
15310   S (mp);
15311   /* Wait for the reply */
15312   W (ret);
15313   return ret;
15314 }
15315
15316 static int
15317 api_get_node_graph (vat_main_t * vam)
15318 {
15319   vl_api_get_node_graph_t *mp;
15320   int ret;
15321
15322   M (GET_NODE_GRAPH, mp);
15323
15324   /* send it... */
15325   S (mp);
15326   /* Wait for the reply */
15327   W (ret);
15328   return ret;
15329 }
15330
15331 /* *INDENT-OFF* */
15332 /** Used for parsing LISP eids */
15333 typedef CLIB_PACKED(struct{
15334   u8 addr[16];   /**< eid address */
15335   u32 len;       /**< prefix length if IP */
15336   u8 type;      /**< type of eid */
15337 }) lisp_eid_vat_t;
15338 /* *INDENT-ON* */
15339
15340 static uword
15341 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15342 {
15343   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15344
15345   memset (a, 0, sizeof (a[0]));
15346
15347   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15348     {
15349       a->type = 0;              /* ipv4 type */
15350     }
15351   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15352     {
15353       a->type = 1;              /* ipv6 type */
15354     }
15355   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15356     {
15357       a->type = 2;              /* mac type */
15358     }
15359   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15360     {
15361       a->type = 3;              /* NSH type */
15362       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15363       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15364     }
15365   else
15366     {
15367       return 0;
15368     }
15369
15370   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15371     {
15372       return 0;
15373     }
15374
15375   return 1;
15376 }
15377
15378 static int
15379 lisp_eid_size_vat (u8 type)
15380 {
15381   switch (type)
15382     {
15383     case 0:
15384       return 4;
15385     case 1:
15386       return 16;
15387     case 2:
15388       return 6;
15389     case 3:
15390       return 5;
15391     }
15392   return 0;
15393 }
15394
15395 static void
15396 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15397 {
15398   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15399 }
15400
15401 static int
15402 api_one_add_del_locator_set (vat_main_t * vam)
15403 {
15404   unformat_input_t *input = vam->input;
15405   vl_api_one_add_del_locator_set_t *mp;
15406   u8 is_add = 1;
15407   u8 *locator_set_name = NULL;
15408   u8 locator_set_name_set = 0;
15409   vl_api_local_locator_t locator, *locators = 0;
15410   u32 sw_if_index, priority, weight;
15411   u32 data_len = 0;
15412
15413   int ret;
15414   /* Parse args required to build the message */
15415   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15416     {
15417       if (unformat (input, "del"))
15418         {
15419           is_add = 0;
15420         }
15421       else if (unformat (input, "locator-set %s", &locator_set_name))
15422         {
15423           locator_set_name_set = 1;
15424         }
15425       else if (unformat (input, "sw_if_index %u p %u w %u",
15426                          &sw_if_index, &priority, &weight))
15427         {
15428           locator.sw_if_index = htonl (sw_if_index);
15429           locator.priority = priority;
15430           locator.weight = weight;
15431           vec_add1 (locators, locator);
15432         }
15433       else
15434         if (unformat
15435             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15436              &sw_if_index, &priority, &weight))
15437         {
15438           locator.sw_if_index = htonl (sw_if_index);
15439           locator.priority = priority;
15440           locator.weight = weight;
15441           vec_add1 (locators, locator);
15442         }
15443       else
15444         break;
15445     }
15446
15447   if (locator_set_name_set == 0)
15448     {
15449       errmsg ("missing locator-set name");
15450       vec_free (locators);
15451       return -99;
15452     }
15453
15454   if (vec_len (locator_set_name) > 64)
15455     {
15456       errmsg ("locator-set name too long");
15457       vec_free (locator_set_name);
15458       vec_free (locators);
15459       return -99;
15460     }
15461   vec_add1 (locator_set_name, 0);
15462
15463   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15464
15465   /* Construct the API message */
15466   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15467
15468   mp->is_add = is_add;
15469   clib_memcpy (mp->locator_set_name, locator_set_name,
15470                vec_len (locator_set_name));
15471   vec_free (locator_set_name);
15472
15473   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15474   if (locators)
15475     clib_memcpy (mp->locators, locators, data_len);
15476   vec_free (locators);
15477
15478   /* send it... */
15479   S (mp);
15480
15481   /* Wait for a reply... */
15482   W (ret);
15483   return ret;
15484 }
15485
15486 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15487
15488 static int
15489 api_one_add_del_locator (vat_main_t * vam)
15490 {
15491   unformat_input_t *input = vam->input;
15492   vl_api_one_add_del_locator_t *mp;
15493   u32 tmp_if_index = ~0;
15494   u32 sw_if_index = ~0;
15495   u8 sw_if_index_set = 0;
15496   u8 sw_if_index_if_name_set = 0;
15497   u32 priority = ~0;
15498   u8 priority_set = 0;
15499   u32 weight = ~0;
15500   u8 weight_set = 0;
15501   u8 is_add = 1;
15502   u8 *locator_set_name = NULL;
15503   u8 locator_set_name_set = 0;
15504   int ret;
15505
15506   /* Parse args required to build the message */
15507   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15508     {
15509       if (unformat (input, "del"))
15510         {
15511           is_add = 0;
15512         }
15513       else if (unformat (input, "locator-set %s", &locator_set_name))
15514         {
15515           locator_set_name_set = 1;
15516         }
15517       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15518                          &tmp_if_index))
15519         {
15520           sw_if_index_if_name_set = 1;
15521           sw_if_index = tmp_if_index;
15522         }
15523       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15524         {
15525           sw_if_index_set = 1;
15526           sw_if_index = tmp_if_index;
15527         }
15528       else if (unformat (input, "p %d", &priority))
15529         {
15530           priority_set = 1;
15531         }
15532       else if (unformat (input, "w %d", &weight))
15533         {
15534           weight_set = 1;
15535         }
15536       else
15537         break;
15538     }
15539
15540   if (locator_set_name_set == 0)
15541     {
15542       errmsg ("missing locator-set name");
15543       return -99;
15544     }
15545
15546   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15547     {
15548       errmsg ("missing sw_if_index");
15549       vec_free (locator_set_name);
15550       return -99;
15551     }
15552
15553   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15554     {
15555       errmsg ("cannot use both params interface name and sw_if_index");
15556       vec_free (locator_set_name);
15557       return -99;
15558     }
15559
15560   if (priority_set == 0)
15561     {
15562       errmsg ("missing locator-set priority");
15563       vec_free (locator_set_name);
15564       return -99;
15565     }
15566
15567   if (weight_set == 0)
15568     {
15569       errmsg ("missing locator-set weight");
15570       vec_free (locator_set_name);
15571       return -99;
15572     }
15573
15574   if (vec_len (locator_set_name) > 64)
15575     {
15576       errmsg ("locator-set name too long");
15577       vec_free (locator_set_name);
15578       return -99;
15579     }
15580   vec_add1 (locator_set_name, 0);
15581
15582   /* Construct the API message */
15583   M (ONE_ADD_DEL_LOCATOR, mp);
15584
15585   mp->is_add = is_add;
15586   mp->sw_if_index = ntohl (sw_if_index);
15587   mp->priority = priority;
15588   mp->weight = weight;
15589   clib_memcpy (mp->locator_set_name, locator_set_name,
15590                vec_len (locator_set_name));
15591   vec_free (locator_set_name);
15592
15593   /* send it... */
15594   S (mp);
15595
15596   /* Wait for a reply... */
15597   W (ret);
15598   return ret;
15599 }
15600
15601 #define api_lisp_add_del_locator api_one_add_del_locator
15602
15603 uword
15604 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15605 {
15606   u32 *key_id = va_arg (*args, u32 *);
15607   u8 *s = 0;
15608
15609   if (unformat (input, "%s", &s))
15610     {
15611       if (!strcmp ((char *) s, "sha1"))
15612         key_id[0] = HMAC_SHA_1_96;
15613       else if (!strcmp ((char *) s, "sha256"))
15614         key_id[0] = HMAC_SHA_256_128;
15615       else
15616         {
15617           clib_warning ("invalid key_id: '%s'", s);
15618           key_id[0] = HMAC_NO_KEY;
15619         }
15620     }
15621   else
15622     return 0;
15623
15624   vec_free (s);
15625   return 1;
15626 }
15627
15628 static int
15629 api_one_add_del_local_eid (vat_main_t * vam)
15630 {
15631   unformat_input_t *input = vam->input;
15632   vl_api_one_add_del_local_eid_t *mp;
15633   u8 is_add = 1;
15634   u8 eid_set = 0;
15635   lisp_eid_vat_t _eid, *eid = &_eid;
15636   u8 *locator_set_name = 0;
15637   u8 locator_set_name_set = 0;
15638   u32 vni = 0;
15639   u16 key_id = 0;
15640   u8 *key = 0;
15641   int ret;
15642
15643   /* Parse args required to build the message */
15644   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15645     {
15646       if (unformat (input, "del"))
15647         {
15648           is_add = 0;
15649         }
15650       else if (unformat (input, "vni %d", &vni))
15651         {
15652           ;
15653         }
15654       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15655         {
15656           eid_set = 1;
15657         }
15658       else if (unformat (input, "locator-set %s", &locator_set_name))
15659         {
15660           locator_set_name_set = 1;
15661         }
15662       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15663         ;
15664       else if (unformat (input, "secret-key %_%v%_", &key))
15665         ;
15666       else
15667         break;
15668     }
15669
15670   if (locator_set_name_set == 0)
15671     {
15672       errmsg ("missing locator-set name");
15673       return -99;
15674     }
15675
15676   if (0 == eid_set)
15677     {
15678       errmsg ("EID address not set!");
15679       vec_free (locator_set_name);
15680       return -99;
15681     }
15682
15683   if (key && (0 == key_id))
15684     {
15685       errmsg ("invalid key_id!");
15686       return -99;
15687     }
15688
15689   if (vec_len (key) > 64)
15690     {
15691       errmsg ("key too long");
15692       vec_free (key);
15693       return -99;
15694     }
15695
15696   if (vec_len (locator_set_name) > 64)
15697     {
15698       errmsg ("locator-set name too long");
15699       vec_free (locator_set_name);
15700       return -99;
15701     }
15702   vec_add1 (locator_set_name, 0);
15703
15704   /* Construct the API message */
15705   M (ONE_ADD_DEL_LOCAL_EID, mp);
15706
15707   mp->is_add = is_add;
15708   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15709   mp->eid_type = eid->type;
15710   mp->prefix_len = eid->len;
15711   mp->vni = clib_host_to_net_u32 (vni);
15712   mp->key_id = clib_host_to_net_u16 (key_id);
15713   clib_memcpy (mp->locator_set_name, locator_set_name,
15714                vec_len (locator_set_name));
15715   clib_memcpy (mp->key, key, vec_len (key));
15716
15717   vec_free (locator_set_name);
15718   vec_free (key);
15719
15720   /* send it... */
15721   S (mp);
15722
15723   /* Wait for a reply... */
15724   W (ret);
15725   return ret;
15726 }
15727
15728 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15729
15730 static int
15731 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15732 {
15733   u32 dp_table = 0, vni = 0;;
15734   unformat_input_t *input = vam->input;
15735   vl_api_gpe_add_del_fwd_entry_t *mp;
15736   u8 is_add = 1;
15737   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15738   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15739   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15740   u32 action = ~0, w;
15741   ip4_address_t rmt_rloc4, lcl_rloc4;
15742   ip6_address_t rmt_rloc6, lcl_rloc6;
15743   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15744   int ret;
15745
15746   memset (&rloc, 0, sizeof (rloc));
15747
15748   /* Parse args required to build the message */
15749   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15750     {
15751       if (unformat (input, "del"))
15752         is_add = 0;
15753       else if (unformat (input, "add"))
15754         is_add = 1;
15755       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15756         {
15757           rmt_eid_set = 1;
15758         }
15759       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15760         {
15761           lcl_eid_set = 1;
15762         }
15763       else if (unformat (input, "vrf %d", &dp_table))
15764         ;
15765       else if (unformat (input, "bd %d", &dp_table))
15766         ;
15767       else if (unformat (input, "vni %d", &vni))
15768         ;
15769       else if (unformat (input, "w %d", &w))
15770         {
15771           if (!curr_rloc)
15772             {
15773               errmsg ("No RLOC configured for setting priority/weight!");
15774               return -99;
15775             }
15776           curr_rloc->weight = w;
15777         }
15778       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15779                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15780         {
15781           rloc.is_ip4 = 1;
15782
15783           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15784           rloc.weight = 0;
15785           vec_add1 (lcl_locs, rloc);
15786
15787           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15788           vec_add1 (rmt_locs, rloc);
15789           /* weight saved in rmt loc */
15790           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15791         }
15792       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15793                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15794         {
15795           rloc.is_ip4 = 0;
15796           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15797           rloc.weight = 0;
15798           vec_add1 (lcl_locs, rloc);
15799
15800           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15801           vec_add1 (rmt_locs, rloc);
15802           /* weight saved in rmt loc */
15803           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15804         }
15805       else if (unformat (input, "action %d", &action))
15806         {
15807           ;
15808         }
15809       else
15810         {
15811           clib_warning ("parse error '%U'", format_unformat_error, input);
15812           return -99;
15813         }
15814     }
15815
15816   if (!rmt_eid_set)
15817     {
15818       errmsg ("remote eid addresses not set");
15819       return -99;
15820     }
15821
15822   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15823     {
15824       errmsg ("eid types don't match");
15825       return -99;
15826     }
15827
15828   if (0 == rmt_locs && (u32) ~ 0 == action)
15829     {
15830       errmsg ("action not set for negative mapping");
15831       return -99;
15832     }
15833
15834   /* Construct the API message */
15835   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15836       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15837
15838   mp->is_add = is_add;
15839   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15840   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15841   mp->eid_type = rmt_eid->type;
15842   mp->dp_table = clib_host_to_net_u32 (dp_table);
15843   mp->vni = clib_host_to_net_u32 (vni);
15844   mp->rmt_len = rmt_eid->len;
15845   mp->lcl_len = lcl_eid->len;
15846   mp->action = action;
15847
15848   if (0 != rmt_locs && 0 != lcl_locs)
15849     {
15850       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15851       clib_memcpy (mp->locs, lcl_locs,
15852                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15853
15854       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15855       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15856                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15857     }
15858   vec_free (lcl_locs);
15859   vec_free (rmt_locs);
15860
15861   /* send it... */
15862   S (mp);
15863
15864   /* Wait for a reply... */
15865   W (ret);
15866   return ret;
15867 }
15868
15869 static int
15870 api_one_add_del_map_server (vat_main_t * vam)
15871 {
15872   unformat_input_t *input = vam->input;
15873   vl_api_one_add_del_map_server_t *mp;
15874   u8 is_add = 1;
15875   u8 ipv4_set = 0;
15876   u8 ipv6_set = 0;
15877   ip4_address_t ipv4;
15878   ip6_address_t ipv6;
15879   int ret;
15880
15881   /* Parse args required to build the message */
15882   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15883     {
15884       if (unformat (input, "del"))
15885         {
15886           is_add = 0;
15887         }
15888       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15889         {
15890           ipv4_set = 1;
15891         }
15892       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15893         {
15894           ipv6_set = 1;
15895         }
15896       else
15897         break;
15898     }
15899
15900   if (ipv4_set && ipv6_set)
15901     {
15902       errmsg ("both eid v4 and v6 addresses set");
15903       return -99;
15904     }
15905
15906   if (!ipv4_set && !ipv6_set)
15907     {
15908       errmsg ("eid addresses not set");
15909       return -99;
15910     }
15911
15912   /* Construct the API message */
15913   M (ONE_ADD_DEL_MAP_SERVER, mp);
15914
15915   mp->is_add = is_add;
15916   if (ipv6_set)
15917     {
15918       mp->is_ipv6 = 1;
15919       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15920     }
15921   else
15922     {
15923       mp->is_ipv6 = 0;
15924       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15925     }
15926
15927   /* send it... */
15928   S (mp);
15929
15930   /* Wait for a reply... */
15931   W (ret);
15932   return ret;
15933 }
15934
15935 #define api_lisp_add_del_map_server api_one_add_del_map_server
15936
15937 static int
15938 api_one_add_del_map_resolver (vat_main_t * vam)
15939 {
15940   unformat_input_t *input = vam->input;
15941   vl_api_one_add_del_map_resolver_t *mp;
15942   u8 is_add = 1;
15943   u8 ipv4_set = 0;
15944   u8 ipv6_set = 0;
15945   ip4_address_t ipv4;
15946   ip6_address_t ipv6;
15947   int ret;
15948
15949   /* Parse args required to build the message */
15950   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15951     {
15952       if (unformat (input, "del"))
15953         {
15954           is_add = 0;
15955         }
15956       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15957         {
15958           ipv4_set = 1;
15959         }
15960       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15961         {
15962           ipv6_set = 1;
15963         }
15964       else
15965         break;
15966     }
15967
15968   if (ipv4_set && ipv6_set)
15969     {
15970       errmsg ("both eid v4 and v6 addresses set");
15971       return -99;
15972     }
15973
15974   if (!ipv4_set && !ipv6_set)
15975     {
15976       errmsg ("eid addresses not set");
15977       return -99;
15978     }
15979
15980   /* Construct the API message */
15981   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
15982
15983   mp->is_add = is_add;
15984   if (ipv6_set)
15985     {
15986       mp->is_ipv6 = 1;
15987       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15988     }
15989   else
15990     {
15991       mp->is_ipv6 = 0;
15992       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15993     }
15994
15995   /* send it... */
15996   S (mp);
15997
15998   /* Wait for a reply... */
15999   W (ret);
16000   return ret;
16001 }
16002
16003 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16004
16005 static int
16006 api_lisp_gpe_enable_disable (vat_main_t * vam)
16007 {
16008   unformat_input_t *input = vam->input;
16009   vl_api_gpe_enable_disable_t *mp;
16010   u8 is_set = 0;
16011   u8 is_en = 1;
16012   int ret;
16013
16014   /* Parse args required to build the message */
16015   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16016     {
16017       if (unformat (input, "enable"))
16018         {
16019           is_set = 1;
16020           is_en = 1;
16021         }
16022       else if (unformat (input, "disable"))
16023         {
16024           is_set = 1;
16025           is_en = 0;
16026         }
16027       else
16028         break;
16029     }
16030
16031   if (is_set == 0)
16032     {
16033       errmsg ("Value not set");
16034       return -99;
16035     }
16036
16037   /* Construct the API message */
16038   M (GPE_ENABLE_DISABLE, mp);
16039
16040   mp->is_en = is_en;
16041
16042   /* send it... */
16043   S (mp);
16044
16045   /* Wait for a reply... */
16046   W (ret);
16047   return ret;
16048 }
16049
16050 static int
16051 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16052 {
16053   unformat_input_t *input = vam->input;
16054   vl_api_one_rloc_probe_enable_disable_t *mp;
16055   u8 is_set = 0;
16056   u8 is_en = 0;
16057   int ret;
16058
16059   /* Parse args required to build the message */
16060   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16061     {
16062       if (unformat (input, "enable"))
16063         {
16064           is_set = 1;
16065           is_en = 1;
16066         }
16067       else if (unformat (input, "disable"))
16068         is_set = 1;
16069       else
16070         break;
16071     }
16072
16073   if (!is_set)
16074     {
16075       errmsg ("Value not set");
16076       return -99;
16077     }
16078
16079   /* Construct the API message */
16080   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16081
16082   mp->is_enabled = is_en;
16083
16084   /* send it... */
16085   S (mp);
16086
16087   /* Wait for a reply... */
16088   W (ret);
16089   return ret;
16090 }
16091
16092 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16093
16094 static int
16095 api_one_map_register_enable_disable (vat_main_t * vam)
16096 {
16097   unformat_input_t *input = vam->input;
16098   vl_api_one_map_register_enable_disable_t *mp;
16099   u8 is_set = 0;
16100   u8 is_en = 0;
16101   int ret;
16102
16103   /* Parse args required to build the message */
16104   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16105     {
16106       if (unformat (input, "enable"))
16107         {
16108           is_set = 1;
16109           is_en = 1;
16110         }
16111       else if (unformat (input, "disable"))
16112         is_set = 1;
16113       else
16114         break;
16115     }
16116
16117   if (!is_set)
16118     {
16119       errmsg ("Value not set");
16120       return -99;
16121     }
16122
16123   /* Construct the API message */
16124   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16125
16126   mp->is_enabled = is_en;
16127
16128   /* send it... */
16129   S (mp);
16130
16131   /* Wait for a reply... */
16132   W (ret);
16133   return ret;
16134 }
16135
16136 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16137
16138 static int
16139 api_one_enable_disable (vat_main_t * vam)
16140 {
16141   unformat_input_t *input = vam->input;
16142   vl_api_one_enable_disable_t *mp;
16143   u8 is_set = 0;
16144   u8 is_en = 0;
16145   int ret;
16146
16147   /* Parse args required to build the message */
16148   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16149     {
16150       if (unformat (input, "enable"))
16151         {
16152           is_set = 1;
16153           is_en = 1;
16154         }
16155       else if (unformat (input, "disable"))
16156         {
16157           is_set = 1;
16158         }
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_ENABLE_DISABLE, mp);
16171
16172   mp->is_en = 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_enable_disable api_one_enable_disable
16183
16184 static int
16185 api_show_one_map_register_state (vat_main_t * vam)
16186 {
16187   vl_api_show_one_map_register_state_t *mp;
16188   int ret;
16189
16190   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16191
16192   /* send */
16193   S (mp);
16194
16195   /* wait for reply */
16196   W (ret);
16197   return ret;
16198 }
16199
16200 #define api_show_lisp_map_register_state api_show_one_map_register_state
16201
16202 static int
16203 api_show_one_rloc_probe_state (vat_main_t * vam)
16204 {
16205   vl_api_show_one_rloc_probe_state_t *mp;
16206   int ret;
16207
16208   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16209
16210   /* send */
16211   S (mp);
16212
16213   /* wait for reply */
16214   W (ret);
16215   return ret;
16216 }
16217
16218 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16219
16220 static int
16221 api_one_add_del_ndp_entry (vat_main_t * vam)
16222 {
16223   vl_api_one_add_del_ndp_entry_t *mp;
16224   unformat_input_t *input = vam->input;
16225   u8 is_add = 1;
16226   u8 mac_set = 0;
16227   u8 bd_set = 0;
16228   u8 ip_set = 0;
16229   u8 mac[6] = { 0, };
16230   u8 ip6[16] = { 0, };
16231   u32 bd = ~0;
16232   int ret;
16233
16234   /* Parse args required to build the message */
16235   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16236     {
16237       if (unformat (input, "del"))
16238         is_add = 0;
16239       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16240         mac_set = 1;
16241       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16242         ip_set = 1;
16243       else if (unformat (input, "bd %d", &bd))
16244         bd_set = 1;
16245       else
16246         {
16247           errmsg ("parse error '%U'", format_unformat_error, input);
16248           return -99;
16249         }
16250     }
16251
16252   if (!bd_set || !ip_set || (!mac_set && is_add))
16253     {
16254       errmsg ("Missing BD, IP or MAC!");
16255       return -99;
16256     }
16257
16258   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16259   mp->is_add = is_add;
16260   clib_memcpy (mp->mac, mac, 6);
16261   mp->bd = clib_host_to_net_u32 (bd);
16262   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16263
16264   /* send */
16265   S (mp);
16266
16267   /* wait for reply */
16268   W (ret);
16269   return ret;
16270 }
16271
16272 static int
16273 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16274 {
16275   vl_api_one_add_del_l2_arp_entry_t *mp;
16276   unformat_input_t *input = vam->input;
16277   u8 is_add = 1;
16278   u8 mac_set = 0;
16279   u8 bd_set = 0;
16280   u8 ip_set = 0;
16281   u8 mac[6] = { 0, };
16282   u32 ip4 = 0, bd = ~0;
16283   int ret;
16284
16285   /* Parse args required to build the message */
16286   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16287     {
16288       if (unformat (input, "del"))
16289         is_add = 0;
16290       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16291         mac_set = 1;
16292       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16293         ip_set = 1;
16294       else if (unformat (input, "bd %d", &bd))
16295         bd_set = 1;
16296       else
16297         {
16298           errmsg ("parse error '%U'", format_unformat_error, input);
16299           return -99;
16300         }
16301     }
16302
16303   if (!bd_set || !ip_set || (!mac_set && is_add))
16304     {
16305       errmsg ("Missing BD, IP or MAC!");
16306       return -99;
16307     }
16308
16309   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16310   mp->is_add = is_add;
16311   clib_memcpy (mp->mac, mac, 6);
16312   mp->bd = clib_host_to_net_u32 (bd);
16313   mp->ip4 = ip4;
16314
16315   /* send */
16316   S (mp);
16317
16318   /* wait for reply */
16319   W (ret);
16320   return ret;
16321 }
16322
16323 static int
16324 api_one_ndp_bd_get (vat_main_t * vam)
16325 {
16326   vl_api_one_ndp_bd_get_t *mp;
16327   int ret;
16328
16329   M (ONE_NDP_BD_GET, mp);
16330
16331   /* send */
16332   S (mp);
16333
16334   /* wait for reply */
16335   W (ret);
16336   return ret;
16337 }
16338
16339 static int
16340 api_one_ndp_entries_get (vat_main_t * vam)
16341 {
16342   vl_api_one_ndp_entries_get_t *mp;
16343   unformat_input_t *input = vam->input;
16344   u8 bd_set = 0;
16345   u32 bd = ~0;
16346   int ret;
16347
16348   /* Parse args required to build the message */
16349   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16350     {
16351       if (unformat (input, "bd %d", &bd))
16352         bd_set = 1;
16353       else
16354         {
16355           errmsg ("parse error '%U'", format_unformat_error, input);
16356           return -99;
16357         }
16358     }
16359
16360   if (!bd_set)
16361     {
16362       errmsg ("Expected bridge domain!");
16363       return -99;
16364     }
16365
16366   M (ONE_NDP_ENTRIES_GET, mp);
16367   mp->bd = clib_host_to_net_u32 (bd);
16368
16369   /* send */
16370   S (mp);
16371
16372   /* wait for reply */
16373   W (ret);
16374   return ret;
16375 }
16376
16377 static int
16378 api_one_l2_arp_bd_get (vat_main_t * vam)
16379 {
16380   vl_api_one_l2_arp_bd_get_t *mp;
16381   int ret;
16382
16383   M (ONE_L2_ARP_BD_GET, mp);
16384
16385   /* send */
16386   S (mp);
16387
16388   /* wait for reply */
16389   W (ret);
16390   return ret;
16391 }
16392
16393 static int
16394 api_one_l2_arp_entries_get (vat_main_t * vam)
16395 {
16396   vl_api_one_l2_arp_entries_get_t *mp;
16397   unformat_input_t *input = vam->input;
16398   u8 bd_set = 0;
16399   u32 bd = ~0;
16400   int ret;
16401
16402   /* Parse args required to build the message */
16403   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16404     {
16405       if (unformat (input, "bd %d", &bd))
16406         bd_set = 1;
16407       else
16408         {
16409           errmsg ("parse error '%U'", format_unformat_error, input);
16410           return -99;
16411         }
16412     }
16413
16414   if (!bd_set)
16415     {
16416       errmsg ("Expected bridge domain!");
16417       return -99;
16418     }
16419
16420   M (ONE_L2_ARP_ENTRIES_GET, mp);
16421   mp->bd = clib_host_to_net_u32 (bd);
16422
16423   /* send */
16424   S (mp);
16425
16426   /* wait for reply */
16427   W (ret);
16428   return ret;
16429 }
16430
16431 static int
16432 api_one_stats_enable_disable (vat_main_t * vam)
16433 {
16434   vl_api_one_stats_enable_disable_t *mp;
16435   unformat_input_t *input = vam->input;
16436   u8 is_set = 0;
16437   u8 is_en = 0;
16438   int ret;
16439
16440   /* Parse args required to build the message */
16441   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16442     {
16443       if (unformat (input, "enable"))
16444         {
16445           is_set = 1;
16446           is_en = 1;
16447         }
16448       else if (unformat (input, "disable"))
16449         {
16450           is_set = 1;
16451         }
16452       else
16453         break;
16454     }
16455
16456   if (!is_set)
16457     {
16458       errmsg ("Value not set");
16459       return -99;
16460     }
16461
16462   M (ONE_STATS_ENABLE_DISABLE, mp);
16463   mp->is_en = is_en;
16464
16465   /* send */
16466   S (mp);
16467
16468   /* wait for reply */
16469   W (ret);
16470   return ret;
16471 }
16472
16473 static int
16474 api_show_one_stats_enable_disable (vat_main_t * vam)
16475 {
16476   vl_api_show_one_stats_enable_disable_t *mp;
16477   int ret;
16478
16479   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16480
16481   /* send */
16482   S (mp);
16483
16484   /* wait for reply */
16485   W (ret);
16486   return ret;
16487 }
16488
16489 static int
16490 api_show_one_map_request_mode (vat_main_t * vam)
16491 {
16492   vl_api_show_one_map_request_mode_t *mp;
16493   int ret;
16494
16495   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16496
16497   /* send */
16498   S (mp);
16499
16500   /* wait for reply */
16501   W (ret);
16502   return ret;
16503 }
16504
16505 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16506
16507 static int
16508 api_one_map_request_mode (vat_main_t * vam)
16509 {
16510   unformat_input_t *input = vam->input;
16511   vl_api_one_map_request_mode_t *mp;
16512   u8 mode = 0;
16513   int ret;
16514
16515   /* Parse args required to build the message */
16516   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16517     {
16518       if (unformat (input, "dst-only"))
16519         mode = 0;
16520       else if (unformat (input, "src-dst"))
16521         mode = 1;
16522       else
16523         {
16524           errmsg ("parse error '%U'", format_unformat_error, input);
16525           return -99;
16526         }
16527     }
16528
16529   M (ONE_MAP_REQUEST_MODE, mp);
16530
16531   mp->mode = mode;
16532
16533   /* send */
16534   S (mp);
16535
16536   /* wait for reply */
16537   W (ret);
16538   return ret;
16539 }
16540
16541 #define api_lisp_map_request_mode api_one_map_request_mode
16542
16543 /**
16544  * Enable/disable ONE proxy ITR.
16545  *
16546  * @param vam vpp API test context
16547  * @return return code
16548  */
16549 static int
16550 api_one_pitr_set_locator_set (vat_main_t * vam)
16551 {
16552   u8 ls_name_set = 0;
16553   unformat_input_t *input = vam->input;
16554   vl_api_one_pitr_set_locator_set_t *mp;
16555   u8 is_add = 1;
16556   u8 *ls_name = 0;
16557   int ret;
16558
16559   /* Parse args required to build the message */
16560   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16561     {
16562       if (unformat (input, "del"))
16563         is_add = 0;
16564       else if (unformat (input, "locator-set %s", &ls_name))
16565         ls_name_set = 1;
16566       else
16567         {
16568           errmsg ("parse error '%U'", format_unformat_error, input);
16569           return -99;
16570         }
16571     }
16572
16573   if (!ls_name_set)
16574     {
16575       errmsg ("locator-set name not set!");
16576       return -99;
16577     }
16578
16579   M (ONE_PITR_SET_LOCATOR_SET, mp);
16580
16581   mp->is_add = is_add;
16582   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16583   vec_free (ls_name);
16584
16585   /* send */
16586   S (mp);
16587
16588   /* wait for reply */
16589   W (ret);
16590   return ret;
16591 }
16592
16593 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16594
16595 static int
16596 api_one_nsh_set_locator_set (vat_main_t * vam)
16597 {
16598   u8 ls_name_set = 0;
16599   unformat_input_t *input = vam->input;
16600   vl_api_one_nsh_set_locator_set_t *mp;
16601   u8 is_add = 1;
16602   u8 *ls_name = 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, "del"))
16609         is_add = 0;
16610       else if (unformat (input, "ls %s", &ls_name))
16611         ls_name_set = 1;
16612       else
16613         {
16614           errmsg ("parse error '%U'", format_unformat_error, input);
16615           return -99;
16616         }
16617     }
16618
16619   if (!ls_name_set && is_add)
16620     {
16621       errmsg ("locator-set name not set!");
16622       return -99;
16623     }
16624
16625   M (ONE_NSH_SET_LOCATOR_SET, mp);
16626
16627   mp->is_add = is_add;
16628   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16629   vec_free (ls_name);
16630
16631   /* send */
16632   S (mp);
16633
16634   /* wait for reply */
16635   W (ret);
16636   return ret;
16637 }
16638
16639 static int
16640 api_show_one_pitr (vat_main_t * vam)
16641 {
16642   vl_api_show_one_pitr_t *mp;
16643   int ret;
16644
16645   if (!vam->json_output)
16646     {
16647       print (vam->ofp, "%=20s", "lisp status:");
16648     }
16649
16650   M (SHOW_ONE_PITR, mp);
16651   /* send it... */
16652   S (mp);
16653
16654   /* Wait for a reply... */
16655   W (ret);
16656   return ret;
16657 }
16658
16659 #define api_show_lisp_pitr api_show_one_pitr
16660
16661 static int
16662 api_one_use_petr (vat_main_t * vam)
16663 {
16664   unformat_input_t *input = vam->input;
16665   vl_api_one_use_petr_t *mp;
16666   u8 is_add = 0;
16667   ip_address_t ip;
16668   int ret;
16669
16670   memset (&ip, 0, sizeof (ip));
16671
16672   /* Parse args required to build the message */
16673   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16674     {
16675       if (unformat (input, "disable"))
16676         is_add = 0;
16677       else
16678         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16679         {
16680           is_add = 1;
16681           ip_addr_version (&ip) = IP4;
16682         }
16683       else
16684         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16685         {
16686           is_add = 1;
16687           ip_addr_version (&ip) = IP6;
16688         }
16689       else
16690         {
16691           errmsg ("parse error '%U'", format_unformat_error, input);
16692           return -99;
16693         }
16694     }
16695
16696   M (ONE_USE_PETR, mp);
16697
16698   mp->is_add = is_add;
16699   if (is_add)
16700     {
16701       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16702       if (mp->is_ip4)
16703         clib_memcpy (mp->address, &ip, 4);
16704       else
16705         clib_memcpy (mp->address, &ip, 16);
16706     }
16707
16708   /* send */
16709   S (mp);
16710
16711   /* wait for reply */
16712   W (ret);
16713   return ret;
16714 }
16715
16716 #define api_lisp_use_petr api_one_use_petr
16717
16718 static int
16719 api_show_one_nsh_mapping (vat_main_t * vam)
16720 {
16721   vl_api_show_one_use_petr_t *mp;
16722   int ret;
16723
16724   if (!vam->json_output)
16725     {
16726       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16727     }
16728
16729   M (SHOW_ONE_NSH_MAPPING, mp);
16730   /* send it... */
16731   S (mp);
16732
16733   /* Wait for a reply... */
16734   W (ret);
16735   return ret;
16736 }
16737
16738 static int
16739 api_show_one_use_petr (vat_main_t * vam)
16740 {
16741   vl_api_show_one_use_petr_t *mp;
16742   int ret;
16743
16744   if (!vam->json_output)
16745     {
16746       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16747     }
16748
16749   M (SHOW_ONE_USE_PETR, mp);
16750   /* send it... */
16751   S (mp);
16752
16753   /* Wait for a reply... */
16754   W (ret);
16755   return ret;
16756 }
16757
16758 #define api_show_lisp_use_petr api_show_one_use_petr
16759
16760 /**
16761  * Add/delete mapping between vni and vrf
16762  */
16763 static int
16764 api_one_eid_table_add_del_map (vat_main_t * vam)
16765 {
16766   unformat_input_t *input = vam->input;
16767   vl_api_one_eid_table_add_del_map_t *mp;
16768   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16769   u32 vni, vrf, bd_index;
16770   int ret;
16771
16772   /* Parse args required to build the message */
16773   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16774     {
16775       if (unformat (input, "del"))
16776         is_add = 0;
16777       else if (unformat (input, "vrf %d", &vrf))
16778         vrf_set = 1;
16779       else if (unformat (input, "bd_index %d", &bd_index))
16780         bd_index_set = 1;
16781       else if (unformat (input, "vni %d", &vni))
16782         vni_set = 1;
16783       else
16784         break;
16785     }
16786
16787   if (!vni_set || (!vrf_set && !bd_index_set))
16788     {
16789       errmsg ("missing arguments!");
16790       return -99;
16791     }
16792
16793   if (vrf_set && bd_index_set)
16794     {
16795       errmsg ("error: both vrf and bd entered!");
16796       return -99;
16797     }
16798
16799   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16800
16801   mp->is_add = is_add;
16802   mp->vni = htonl (vni);
16803   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16804   mp->is_l2 = bd_index_set;
16805
16806   /* send */
16807   S (mp);
16808
16809   /* wait for reply */
16810   W (ret);
16811   return ret;
16812 }
16813
16814 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16815
16816 uword
16817 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16818 {
16819   u32 *action = va_arg (*args, u32 *);
16820   u8 *s = 0;
16821
16822   if (unformat (input, "%s", &s))
16823     {
16824       if (!strcmp ((char *) s, "no-action"))
16825         action[0] = 0;
16826       else if (!strcmp ((char *) s, "natively-forward"))
16827         action[0] = 1;
16828       else if (!strcmp ((char *) s, "send-map-request"))
16829         action[0] = 2;
16830       else if (!strcmp ((char *) s, "drop"))
16831         action[0] = 3;
16832       else
16833         {
16834           clib_warning ("invalid action: '%s'", s);
16835           action[0] = 3;
16836         }
16837     }
16838   else
16839     return 0;
16840
16841   vec_free (s);
16842   return 1;
16843 }
16844
16845 /**
16846  * Add/del remote mapping to/from ONE control plane
16847  *
16848  * @param vam vpp API test context
16849  * @return return code
16850  */
16851 static int
16852 api_one_add_del_remote_mapping (vat_main_t * vam)
16853 {
16854   unformat_input_t *input = vam->input;
16855   vl_api_one_add_del_remote_mapping_t *mp;
16856   u32 vni = 0;
16857   lisp_eid_vat_t _eid, *eid = &_eid;
16858   lisp_eid_vat_t _seid, *seid = &_seid;
16859   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
16860   u32 action = ~0, p, w, data_len;
16861   ip4_address_t rloc4;
16862   ip6_address_t rloc6;
16863   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
16864   int ret;
16865
16866   memset (&rloc, 0, sizeof (rloc));
16867
16868   /* Parse args required to build the message */
16869   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16870     {
16871       if (unformat (input, "del-all"))
16872         {
16873           del_all = 1;
16874         }
16875       else if (unformat (input, "del"))
16876         {
16877           is_add = 0;
16878         }
16879       else if (unformat (input, "add"))
16880         {
16881           is_add = 1;
16882         }
16883       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16884         {
16885           eid_set = 1;
16886         }
16887       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
16888         {
16889           seid_set = 1;
16890         }
16891       else if (unformat (input, "vni %d", &vni))
16892         {
16893           ;
16894         }
16895       else if (unformat (input, "p %d w %d", &p, &w))
16896         {
16897           if (!curr_rloc)
16898             {
16899               errmsg ("No RLOC configured for setting priority/weight!");
16900               return -99;
16901             }
16902           curr_rloc->priority = p;
16903           curr_rloc->weight = w;
16904         }
16905       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
16906         {
16907           rloc.is_ip4 = 1;
16908           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
16909           vec_add1 (rlocs, rloc);
16910           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16911         }
16912       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
16913         {
16914           rloc.is_ip4 = 0;
16915           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
16916           vec_add1 (rlocs, rloc);
16917           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16918         }
16919       else if (unformat (input, "action %U",
16920                          unformat_negative_mapping_action, &action))
16921         {
16922           ;
16923         }
16924       else
16925         {
16926           clib_warning ("parse error '%U'", format_unformat_error, input);
16927           return -99;
16928         }
16929     }
16930
16931   if (0 == eid_set)
16932     {
16933       errmsg ("missing params!");
16934       return -99;
16935     }
16936
16937   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
16938     {
16939       errmsg ("no action set for negative map-reply!");
16940       return -99;
16941     }
16942
16943   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
16944
16945   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
16946   mp->is_add = is_add;
16947   mp->vni = htonl (vni);
16948   mp->action = (u8) action;
16949   mp->is_src_dst = seid_set;
16950   mp->eid_len = eid->len;
16951   mp->seid_len = seid->len;
16952   mp->del_all = del_all;
16953   mp->eid_type = eid->type;
16954   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16955   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
16956
16957   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
16958   clib_memcpy (mp->rlocs, rlocs, data_len);
16959   vec_free (rlocs);
16960
16961   /* send it... */
16962   S (mp);
16963
16964   /* Wait for a reply... */
16965   W (ret);
16966   return ret;
16967 }
16968
16969 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
16970
16971 /**
16972  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
16973  * forwarding entries in data-plane accordingly.
16974  *
16975  * @param vam vpp API test context
16976  * @return return code
16977  */
16978 static int
16979 api_one_add_del_adjacency (vat_main_t * vam)
16980 {
16981   unformat_input_t *input = vam->input;
16982   vl_api_one_add_del_adjacency_t *mp;
16983   u32 vni = 0;
16984   ip4_address_t leid4, reid4;
16985   ip6_address_t leid6, reid6;
16986   u8 reid_mac[6] = { 0 };
16987   u8 leid_mac[6] = { 0 };
16988   u8 reid_type, leid_type;
16989   u32 leid_len = 0, reid_len = 0, len;
16990   u8 is_add = 1;
16991   int ret;
16992
16993   leid_type = reid_type = (u8) ~ 0;
16994
16995   /* Parse args required to build the message */
16996   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16997     {
16998       if (unformat (input, "del"))
16999         {
17000           is_add = 0;
17001         }
17002       else if (unformat (input, "add"))
17003         {
17004           is_add = 1;
17005         }
17006       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17007                          &reid4, &len))
17008         {
17009           reid_type = 0;        /* ipv4 */
17010           reid_len = len;
17011         }
17012       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17013                          &reid6, &len))
17014         {
17015           reid_type = 1;        /* ipv6 */
17016           reid_len = len;
17017         }
17018       else if (unformat (input, "reid %U", unformat_ethernet_address,
17019                          reid_mac))
17020         {
17021           reid_type = 2;        /* mac */
17022         }
17023       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17024                          &leid4, &len))
17025         {
17026           leid_type = 0;        /* ipv4 */
17027           leid_len = len;
17028         }
17029       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17030                          &leid6, &len))
17031         {
17032           leid_type = 1;        /* ipv6 */
17033           leid_len = len;
17034         }
17035       else if (unformat (input, "leid %U", unformat_ethernet_address,
17036                          leid_mac))
17037         {
17038           leid_type = 2;        /* mac */
17039         }
17040       else if (unformat (input, "vni %d", &vni))
17041         {
17042           ;
17043         }
17044       else
17045         {
17046           errmsg ("parse error '%U'", format_unformat_error, input);
17047           return -99;
17048         }
17049     }
17050
17051   if ((u8) ~ 0 == reid_type)
17052     {
17053       errmsg ("missing params!");
17054       return -99;
17055     }
17056
17057   if (leid_type != reid_type)
17058     {
17059       errmsg ("remote and local EIDs are of different types!");
17060       return -99;
17061     }
17062
17063   M (ONE_ADD_DEL_ADJACENCY, mp);
17064   mp->is_add = is_add;
17065   mp->vni = htonl (vni);
17066   mp->leid_len = leid_len;
17067   mp->reid_len = reid_len;
17068   mp->eid_type = reid_type;
17069
17070   switch (mp->eid_type)
17071     {
17072     case 0:
17073       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17074       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17075       break;
17076     case 1:
17077       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17078       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17079       break;
17080     case 2:
17081       clib_memcpy (mp->leid, leid_mac, 6);
17082       clib_memcpy (mp->reid, reid_mac, 6);
17083       break;
17084     default:
17085       errmsg ("unknown EID type %d!", mp->eid_type);
17086       return 0;
17087     }
17088
17089   /* send it... */
17090   S (mp);
17091
17092   /* Wait for a reply... */
17093   W (ret);
17094   return ret;
17095 }
17096
17097 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17098
17099 uword
17100 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17101 {
17102   u32 *mode = va_arg (*args, u32 *);
17103
17104   if (unformat (input, "lisp"))
17105     *mode = 0;
17106   else if (unformat (input, "vxlan"))
17107     *mode = 1;
17108   else
17109     return 0;
17110
17111   return 1;
17112 }
17113
17114 static int
17115 api_gpe_get_encap_mode (vat_main_t * vam)
17116 {
17117   vl_api_gpe_get_encap_mode_t *mp;
17118   int ret;
17119
17120   /* Construct the API message */
17121   M (GPE_GET_ENCAP_MODE, mp);
17122
17123   /* send it... */
17124   S (mp);
17125
17126   /* Wait for a reply... */
17127   W (ret);
17128   return ret;
17129 }
17130
17131 static int
17132 api_gpe_set_encap_mode (vat_main_t * vam)
17133 {
17134   unformat_input_t *input = vam->input;
17135   vl_api_gpe_set_encap_mode_t *mp;
17136   int ret;
17137   u32 mode = 0;
17138
17139   /* Parse args required to build the message */
17140   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17141     {
17142       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17143         ;
17144       else
17145         break;
17146     }
17147
17148   /* Construct the API message */
17149   M (GPE_SET_ENCAP_MODE, mp);
17150
17151   mp->mode = mode;
17152
17153   /* send it... */
17154   S (mp);
17155
17156   /* Wait for a reply... */
17157   W (ret);
17158   return ret;
17159 }
17160
17161 static int
17162 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17163 {
17164   unformat_input_t *input = vam->input;
17165   vl_api_gpe_add_del_iface_t *mp;
17166   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17167   u32 dp_table = 0, vni = 0;
17168   int ret;
17169
17170   /* Parse args required to build the message */
17171   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17172     {
17173       if (unformat (input, "up"))
17174         {
17175           action_set = 1;
17176           is_add = 1;
17177         }
17178       else if (unformat (input, "down"))
17179         {
17180           action_set = 1;
17181           is_add = 0;
17182         }
17183       else if (unformat (input, "table_id %d", &dp_table))
17184         {
17185           dp_table_set = 1;
17186         }
17187       else if (unformat (input, "bd_id %d", &dp_table))
17188         {
17189           dp_table_set = 1;
17190           is_l2 = 1;
17191         }
17192       else if (unformat (input, "vni %d", &vni))
17193         {
17194           vni_set = 1;
17195         }
17196       else
17197         break;
17198     }
17199
17200   if (action_set == 0)
17201     {
17202       errmsg ("Action not set");
17203       return -99;
17204     }
17205   if (dp_table_set == 0 || vni_set == 0)
17206     {
17207       errmsg ("vni and dp_table must be set");
17208       return -99;
17209     }
17210
17211   /* Construct the API message */
17212   M (GPE_ADD_DEL_IFACE, mp);
17213
17214   mp->is_add = is_add;
17215   mp->dp_table = clib_host_to_net_u32 (dp_table);
17216   mp->is_l2 = is_l2;
17217   mp->vni = clib_host_to_net_u32 (vni);
17218
17219   /* send it... */
17220   S (mp);
17221
17222   /* Wait for a reply... */
17223   W (ret);
17224   return ret;
17225 }
17226
17227 static int
17228 api_one_map_register_fallback_threshold (vat_main_t * vam)
17229 {
17230   unformat_input_t *input = vam->input;
17231   vl_api_one_map_register_fallback_threshold_t *mp;
17232   u32 value = 0;
17233   u8 is_set = 0;
17234   int ret;
17235
17236   /* Parse args required to build the message */
17237   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17238     {
17239       if (unformat (input, "%u", &value))
17240         is_set = 1;
17241       else
17242         {
17243           clib_warning ("parse error '%U'", format_unformat_error, input);
17244           return -99;
17245         }
17246     }
17247
17248   if (!is_set)
17249     {
17250       errmsg ("fallback threshold value is missing!");
17251       return -99;
17252     }
17253
17254   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17255   mp->value = clib_host_to_net_u32 (value);
17256
17257   /* send it... */
17258   S (mp);
17259
17260   /* Wait for a reply... */
17261   W (ret);
17262   return ret;
17263 }
17264
17265 static int
17266 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17267 {
17268   vl_api_show_one_map_register_fallback_threshold_t *mp;
17269   int ret;
17270
17271   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17272
17273   /* send it... */
17274   S (mp);
17275
17276   /* Wait for a reply... */
17277   W (ret);
17278   return ret;
17279 }
17280
17281 uword
17282 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17283 {
17284   u32 *proto = va_arg (*args, u32 *);
17285
17286   if (unformat (input, "udp"))
17287     *proto = 1;
17288   else if (unformat (input, "api"))
17289     *proto = 2;
17290   else
17291     return 0;
17292
17293   return 1;
17294 }
17295
17296 static int
17297 api_one_set_transport_protocol (vat_main_t * vam)
17298 {
17299   unformat_input_t *input = vam->input;
17300   vl_api_one_set_transport_protocol_t *mp;
17301   u8 is_set = 0;
17302   u32 protocol = 0;
17303   int ret;
17304
17305   /* Parse args required to build the message */
17306   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17307     {
17308       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17309         is_set = 1;
17310       else
17311         {
17312           clib_warning ("parse error '%U'", format_unformat_error, input);
17313           return -99;
17314         }
17315     }
17316
17317   if (!is_set)
17318     {
17319       errmsg ("Transport protocol missing!");
17320       return -99;
17321     }
17322
17323   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17324   mp->protocol = (u8) protocol;
17325
17326   /* send it... */
17327   S (mp);
17328
17329   /* Wait for a reply... */
17330   W (ret);
17331   return ret;
17332 }
17333
17334 static int
17335 api_one_get_transport_protocol (vat_main_t * vam)
17336 {
17337   vl_api_one_get_transport_protocol_t *mp;
17338   int ret;
17339
17340   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17341
17342   /* send it... */
17343   S (mp);
17344
17345   /* Wait for a reply... */
17346   W (ret);
17347   return ret;
17348 }
17349
17350 static int
17351 api_one_map_register_set_ttl (vat_main_t * vam)
17352 {
17353   unformat_input_t *input = vam->input;
17354   vl_api_one_map_register_set_ttl_t *mp;
17355   u32 ttl = 0;
17356   u8 is_set = 0;
17357   int ret;
17358
17359   /* Parse args required to build the message */
17360   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17361     {
17362       if (unformat (input, "%u", &ttl))
17363         is_set = 1;
17364       else
17365         {
17366           clib_warning ("parse error '%U'", format_unformat_error, input);
17367           return -99;
17368         }
17369     }
17370
17371   if (!is_set)
17372     {
17373       errmsg ("TTL value missing!");
17374       return -99;
17375     }
17376
17377   M (ONE_MAP_REGISTER_SET_TTL, mp);
17378   mp->ttl = clib_host_to_net_u32 (ttl);
17379
17380   /* send it... */
17381   S (mp);
17382
17383   /* Wait for a reply... */
17384   W (ret);
17385   return ret;
17386 }
17387
17388 static int
17389 api_show_one_map_register_ttl (vat_main_t * vam)
17390 {
17391   vl_api_show_one_map_register_ttl_t *mp;
17392   int ret;
17393
17394   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17395
17396   /* send it... */
17397   S (mp);
17398
17399   /* Wait for a reply... */
17400   W (ret);
17401   return ret;
17402 }
17403
17404 /**
17405  * Add/del map request itr rlocs from ONE control plane and updates
17406  *
17407  * @param vam vpp API test context
17408  * @return return code
17409  */
17410 static int
17411 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17412 {
17413   unformat_input_t *input = vam->input;
17414   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17415   u8 *locator_set_name = 0;
17416   u8 locator_set_name_set = 0;
17417   u8 is_add = 1;
17418   int ret;
17419
17420   /* Parse args required to build the message */
17421   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17422     {
17423       if (unformat (input, "del"))
17424         {
17425           is_add = 0;
17426         }
17427       else if (unformat (input, "%_%v%_", &locator_set_name))
17428         {
17429           locator_set_name_set = 1;
17430         }
17431       else
17432         {
17433           clib_warning ("parse error '%U'", format_unformat_error, input);
17434           return -99;
17435         }
17436     }
17437
17438   if (is_add && !locator_set_name_set)
17439     {
17440       errmsg ("itr-rloc is not set!");
17441       return -99;
17442     }
17443
17444   if (is_add && vec_len (locator_set_name) > 64)
17445     {
17446       errmsg ("itr-rloc locator-set name too long");
17447       vec_free (locator_set_name);
17448       return -99;
17449     }
17450
17451   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17452   mp->is_add = is_add;
17453   if (is_add)
17454     {
17455       clib_memcpy (mp->locator_set_name, locator_set_name,
17456                    vec_len (locator_set_name));
17457     }
17458   else
17459     {
17460       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17461     }
17462   vec_free (locator_set_name);
17463
17464   /* send it... */
17465   S (mp);
17466
17467   /* Wait for a reply... */
17468   W (ret);
17469   return ret;
17470 }
17471
17472 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17473
17474 static int
17475 api_one_locator_dump (vat_main_t * vam)
17476 {
17477   unformat_input_t *input = vam->input;
17478   vl_api_one_locator_dump_t *mp;
17479   vl_api_control_ping_t *mp_ping;
17480   u8 is_index_set = 0, is_name_set = 0;
17481   u8 *ls_name = 0;
17482   u32 ls_index = ~0;
17483   int ret;
17484
17485   /* Parse args required to build the message */
17486   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17487     {
17488       if (unformat (input, "ls_name %_%v%_", &ls_name))
17489         {
17490           is_name_set = 1;
17491         }
17492       else if (unformat (input, "ls_index %d", &ls_index))
17493         {
17494           is_index_set = 1;
17495         }
17496       else
17497         {
17498           errmsg ("parse error '%U'", format_unformat_error, input);
17499           return -99;
17500         }
17501     }
17502
17503   if (!is_index_set && !is_name_set)
17504     {
17505       errmsg ("error: expected one of index or name!");
17506       return -99;
17507     }
17508
17509   if (is_index_set && is_name_set)
17510     {
17511       errmsg ("error: only one param expected!");
17512       return -99;
17513     }
17514
17515   if (vec_len (ls_name) > 62)
17516     {
17517       errmsg ("error: locator set name too long!");
17518       return -99;
17519     }
17520
17521   if (!vam->json_output)
17522     {
17523       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17524     }
17525
17526   M (ONE_LOCATOR_DUMP, mp);
17527   mp->is_index_set = is_index_set;
17528
17529   if (is_index_set)
17530     mp->ls_index = clib_host_to_net_u32 (ls_index);
17531   else
17532     {
17533       vec_add1 (ls_name, 0);
17534       strncpy ((char *) mp->ls_name, (char *) ls_name,
17535                sizeof (mp->ls_name) - 1);
17536     }
17537
17538   /* send it... */
17539   S (mp);
17540
17541   /* Use a control ping for synchronization */
17542   MPING (CONTROL_PING, mp_ping);
17543   S (mp_ping);
17544
17545   /* Wait for a reply... */
17546   W (ret);
17547   return ret;
17548 }
17549
17550 #define api_lisp_locator_dump api_one_locator_dump
17551
17552 static int
17553 api_one_locator_set_dump (vat_main_t * vam)
17554 {
17555   vl_api_one_locator_set_dump_t *mp;
17556   vl_api_control_ping_t *mp_ping;
17557   unformat_input_t *input = vam->input;
17558   u8 filter = 0;
17559   int ret;
17560
17561   /* Parse args required to build the message */
17562   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17563     {
17564       if (unformat (input, "local"))
17565         {
17566           filter = 1;
17567         }
17568       else if (unformat (input, "remote"))
17569         {
17570           filter = 2;
17571         }
17572       else
17573         {
17574           errmsg ("parse error '%U'", format_unformat_error, input);
17575           return -99;
17576         }
17577     }
17578
17579   if (!vam->json_output)
17580     {
17581       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17582     }
17583
17584   M (ONE_LOCATOR_SET_DUMP, mp);
17585
17586   mp->filter = filter;
17587
17588   /* send it... */
17589   S (mp);
17590
17591   /* Use a control ping for synchronization */
17592   MPING (CONTROL_PING, mp_ping);
17593   S (mp_ping);
17594
17595   /* Wait for a reply... */
17596   W (ret);
17597   return ret;
17598 }
17599
17600 #define api_lisp_locator_set_dump api_one_locator_set_dump
17601
17602 static int
17603 api_one_eid_table_map_dump (vat_main_t * vam)
17604 {
17605   u8 is_l2 = 0;
17606   u8 mode_set = 0;
17607   unformat_input_t *input = vam->input;
17608   vl_api_one_eid_table_map_dump_t *mp;
17609   vl_api_control_ping_t *mp_ping;
17610   int ret;
17611
17612   /* Parse args required to build the message */
17613   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17614     {
17615       if (unformat (input, "l2"))
17616         {
17617           is_l2 = 1;
17618           mode_set = 1;
17619         }
17620       else if (unformat (input, "l3"))
17621         {
17622           is_l2 = 0;
17623           mode_set = 1;
17624         }
17625       else
17626         {
17627           errmsg ("parse error '%U'", format_unformat_error, input);
17628           return -99;
17629         }
17630     }
17631
17632   if (!mode_set)
17633     {
17634       errmsg ("expected one of 'l2' or 'l3' parameter!");
17635       return -99;
17636     }
17637
17638   if (!vam->json_output)
17639     {
17640       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17641     }
17642
17643   M (ONE_EID_TABLE_MAP_DUMP, mp);
17644   mp->is_l2 = is_l2;
17645
17646   /* send it... */
17647   S (mp);
17648
17649   /* Use a control ping for synchronization */
17650   MPING (CONTROL_PING, mp_ping);
17651   S (mp_ping);
17652
17653   /* Wait for a reply... */
17654   W (ret);
17655   return ret;
17656 }
17657
17658 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17659
17660 static int
17661 api_one_eid_table_vni_dump (vat_main_t * vam)
17662 {
17663   vl_api_one_eid_table_vni_dump_t *mp;
17664   vl_api_control_ping_t *mp_ping;
17665   int ret;
17666
17667   if (!vam->json_output)
17668     {
17669       print (vam->ofp, "VNI");
17670     }
17671
17672   M (ONE_EID_TABLE_VNI_DUMP, mp);
17673
17674   /* send it... */
17675   S (mp);
17676
17677   /* Use a control ping for synchronization */
17678   MPING (CONTROL_PING, mp_ping);
17679   S (mp_ping);
17680
17681   /* Wait for a reply... */
17682   W (ret);
17683   return ret;
17684 }
17685
17686 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17687
17688 static int
17689 api_one_eid_table_dump (vat_main_t * vam)
17690 {
17691   unformat_input_t *i = vam->input;
17692   vl_api_one_eid_table_dump_t *mp;
17693   vl_api_control_ping_t *mp_ping;
17694   struct in_addr ip4;
17695   struct in6_addr ip6;
17696   u8 mac[6];
17697   u8 eid_type = ~0, eid_set = 0;
17698   u32 prefix_length = ~0, t, vni = 0;
17699   u8 filter = 0;
17700   int ret;
17701   lisp_nsh_api_t nsh;
17702
17703   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17704     {
17705       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17706         {
17707           eid_set = 1;
17708           eid_type = 0;
17709           prefix_length = t;
17710         }
17711       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17712         {
17713           eid_set = 1;
17714           eid_type = 1;
17715           prefix_length = t;
17716         }
17717       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17718         {
17719           eid_set = 1;
17720           eid_type = 2;
17721         }
17722       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17723         {
17724           eid_set = 1;
17725           eid_type = 3;
17726         }
17727       else if (unformat (i, "vni %d", &t))
17728         {
17729           vni = t;
17730         }
17731       else if (unformat (i, "local"))
17732         {
17733           filter = 1;
17734         }
17735       else if (unformat (i, "remote"))
17736         {
17737           filter = 2;
17738         }
17739       else
17740         {
17741           errmsg ("parse error '%U'", format_unformat_error, i);
17742           return -99;
17743         }
17744     }
17745
17746   if (!vam->json_output)
17747     {
17748       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17749              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17750     }
17751
17752   M (ONE_EID_TABLE_DUMP, mp);
17753
17754   mp->filter = filter;
17755   if (eid_set)
17756     {
17757       mp->eid_set = 1;
17758       mp->vni = htonl (vni);
17759       mp->eid_type = eid_type;
17760       switch (eid_type)
17761         {
17762         case 0:
17763           mp->prefix_length = prefix_length;
17764           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17765           break;
17766         case 1:
17767           mp->prefix_length = prefix_length;
17768           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17769           break;
17770         case 2:
17771           clib_memcpy (mp->eid, mac, sizeof (mac));
17772           break;
17773         case 3:
17774           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17775           break;
17776         default:
17777           errmsg ("unknown EID type %d!", eid_type);
17778           return -99;
17779         }
17780     }
17781
17782   /* send it... */
17783   S (mp);
17784
17785   /* Use a control ping for synchronization */
17786   MPING (CONTROL_PING, mp_ping);
17787   S (mp_ping);
17788
17789   /* Wait for a reply... */
17790   W (ret);
17791   return ret;
17792 }
17793
17794 #define api_lisp_eid_table_dump api_one_eid_table_dump
17795
17796 static int
17797 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17798 {
17799   unformat_input_t *i = vam->input;
17800   vl_api_gpe_fwd_entries_get_t *mp;
17801   u8 vni_set = 0;
17802   u32 vni = ~0;
17803   int ret;
17804
17805   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17806     {
17807       if (unformat (i, "vni %d", &vni))
17808         {
17809           vni_set = 1;
17810         }
17811       else
17812         {
17813           errmsg ("parse error '%U'", format_unformat_error, i);
17814           return -99;
17815         }
17816     }
17817
17818   if (!vni_set)
17819     {
17820       errmsg ("vni not set!");
17821       return -99;
17822     }
17823
17824   if (!vam->json_output)
17825     {
17826       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17827              "leid", "reid");
17828     }
17829
17830   M (GPE_FWD_ENTRIES_GET, mp);
17831   mp->vni = clib_host_to_net_u32 (vni);
17832
17833   /* send it... */
17834   S (mp);
17835
17836   /* Wait for a reply... */
17837   W (ret);
17838   return ret;
17839 }
17840
17841 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
17842 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
17843 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
17844 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
17845 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
17846 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
17847 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
17848 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
17849
17850 static int
17851 api_one_adjacencies_get (vat_main_t * vam)
17852 {
17853   unformat_input_t *i = vam->input;
17854   vl_api_one_adjacencies_get_t *mp;
17855   u8 vni_set = 0;
17856   u32 vni = ~0;
17857   int ret;
17858
17859   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17860     {
17861       if (unformat (i, "vni %d", &vni))
17862         {
17863           vni_set = 1;
17864         }
17865       else
17866         {
17867           errmsg ("parse error '%U'", format_unformat_error, i);
17868           return -99;
17869         }
17870     }
17871
17872   if (!vni_set)
17873     {
17874       errmsg ("vni not set!");
17875       return -99;
17876     }
17877
17878   if (!vam->json_output)
17879     {
17880       print (vam->ofp, "%s %40s", "leid", "reid");
17881     }
17882
17883   M (ONE_ADJACENCIES_GET, mp);
17884   mp->vni = clib_host_to_net_u32 (vni);
17885
17886   /* send it... */
17887   S (mp);
17888
17889   /* Wait for a reply... */
17890   W (ret);
17891   return ret;
17892 }
17893
17894 #define api_lisp_adjacencies_get api_one_adjacencies_get
17895
17896 static int
17897 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
17898 {
17899   unformat_input_t *i = vam->input;
17900   vl_api_gpe_native_fwd_rpaths_get_t *mp;
17901   int ret;
17902   u8 ip_family_set = 0, is_ip4 = 1;
17903
17904   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17905     {
17906       if (unformat (i, "ip4"))
17907         {
17908           ip_family_set = 1;
17909           is_ip4 = 1;
17910         }
17911       else if (unformat (i, "ip6"))
17912         {
17913           ip_family_set = 1;
17914           is_ip4 = 0;
17915         }
17916       else
17917         {
17918           errmsg ("parse error '%U'", format_unformat_error, i);
17919           return -99;
17920         }
17921     }
17922
17923   if (!ip_family_set)
17924     {
17925       errmsg ("ip family not set!");
17926       return -99;
17927     }
17928
17929   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
17930   mp->is_ip4 = is_ip4;
17931
17932   /* send it... */
17933   S (mp);
17934
17935   /* Wait for a reply... */
17936   W (ret);
17937   return ret;
17938 }
17939
17940 static int
17941 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
17942 {
17943   vl_api_gpe_fwd_entry_vnis_get_t *mp;
17944   int ret;
17945
17946   if (!vam->json_output)
17947     {
17948       print (vam->ofp, "VNIs");
17949     }
17950
17951   M (GPE_FWD_ENTRY_VNIS_GET, mp);
17952
17953   /* send it... */
17954   S (mp);
17955
17956   /* Wait for a reply... */
17957   W (ret);
17958   return ret;
17959 }
17960
17961 static int
17962 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
17963 {
17964   unformat_input_t *i = vam->input;
17965   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
17966   int ret = 0;
17967   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
17968   struct in_addr ip4;
17969   struct in6_addr ip6;
17970   u32 table_id = 0, nh_sw_if_index = ~0;
17971
17972   memset (&ip4, 0, sizeof (ip4));
17973   memset (&ip6, 0, sizeof (ip6));
17974
17975   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17976     {
17977       if (unformat (i, "del"))
17978         is_add = 0;
17979       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
17980                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17981         {
17982           ip_set = 1;
17983           is_ip4 = 1;
17984         }
17985       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
17986                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17987         {
17988           ip_set = 1;
17989           is_ip4 = 0;
17990         }
17991       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
17992         {
17993           ip_set = 1;
17994           is_ip4 = 1;
17995           nh_sw_if_index = ~0;
17996         }
17997       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
17998         {
17999           ip_set = 1;
18000           is_ip4 = 0;
18001           nh_sw_if_index = ~0;
18002         }
18003       else if (unformat (i, "table %d", &table_id))
18004         ;
18005       else
18006         {
18007           errmsg ("parse error '%U'", format_unformat_error, i);
18008           return -99;
18009         }
18010     }
18011
18012   if (!ip_set)
18013     {
18014       errmsg ("nh addr not set!");
18015       return -99;
18016     }
18017
18018   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18019   mp->is_add = is_add;
18020   mp->table_id = clib_host_to_net_u32 (table_id);
18021   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18022   mp->is_ip4 = is_ip4;
18023   if (is_ip4)
18024     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18025   else
18026     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18027
18028   /* send it... */
18029   S (mp);
18030
18031   /* Wait for a reply... */
18032   W (ret);
18033   return ret;
18034 }
18035
18036 static int
18037 api_one_map_server_dump (vat_main_t * vam)
18038 {
18039   vl_api_one_map_server_dump_t *mp;
18040   vl_api_control_ping_t *mp_ping;
18041   int ret;
18042
18043   if (!vam->json_output)
18044     {
18045       print (vam->ofp, "%=20s", "Map server");
18046     }
18047
18048   M (ONE_MAP_SERVER_DUMP, mp);
18049   /* send it... */
18050   S (mp);
18051
18052   /* Use a control ping for synchronization */
18053   MPING (CONTROL_PING, mp_ping);
18054   S (mp_ping);
18055
18056   /* Wait for a reply... */
18057   W (ret);
18058   return ret;
18059 }
18060
18061 #define api_lisp_map_server_dump api_one_map_server_dump
18062
18063 static int
18064 api_one_map_resolver_dump (vat_main_t * vam)
18065 {
18066   vl_api_one_map_resolver_dump_t *mp;
18067   vl_api_control_ping_t *mp_ping;
18068   int ret;
18069
18070   if (!vam->json_output)
18071     {
18072       print (vam->ofp, "%=20s", "Map resolver");
18073     }
18074
18075   M (ONE_MAP_RESOLVER_DUMP, mp);
18076   /* send it... */
18077   S (mp);
18078
18079   /* Use a control ping for synchronization */
18080   MPING (CONTROL_PING, mp_ping);
18081   S (mp_ping);
18082
18083   /* Wait for a reply... */
18084   W (ret);
18085   return ret;
18086 }
18087
18088 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18089
18090 static int
18091 api_one_stats_flush (vat_main_t * vam)
18092 {
18093   vl_api_one_stats_flush_t *mp;
18094   int ret = 0;
18095
18096   M (ONE_STATS_FLUSH, mp);
18097   S (mp);
18098   W (ret);
18099   return ret;
18100 }
18101
18102 static int
18103 api_one_stats_dump (vat_main_t * vam)
18104 {
18105   vl_api_one_stats_dump_t *mp;
18106   vl_api_control_ping_t *mp_ping;
18107   int ret;
18108
18109   M (ONE_STATS_DUMP, mp);
18110   /* send it... */
18111   S (mp);
18112
18113   /* Use a control ping for synchronization */
18114   MPING (CONTROL_PING, mp_ping);
18115   S (mp_ping);
18116
18117   /* Wait for a reply... */
18118   W (ret);
18119   return ret;
18120 }
18121
18122 static int
18123 api_show_one_status (vat_main_t * vam)
18124 {
18125   vl_api_show_one_status_t *mp;
18126   int ret;
18127
18128   if (!vam->json_output)
18129     {
18130       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18131     }
18132
18133   M (SHOW_ONE_STATUS, mp);
18134   /* send it... */
18135   S (mp);
18136   /* Wait for a reply... */
18137   W (ret);
18138   return ret;
18139 }
18140
18141 #define api_show_lisp_status api_show_one_status
18142
18143 static int
18144 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18145 {
18146   vl_api_gpe_fwd_entry_path_dump_t *mp;
18147   vl_api_control_ping_t *mp_ping;
18148   unformat_input_t *i = vam->input;
18149   u32 fwd_entry_index = ~0;
18150   int ret;
18151
18152   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18153     {
18154       if (unformat (i, "index %d", &fwd_entry_index))
18155         ;
18156       else
18157         break;
18158     }
18159
18160   if (~0 == fwd_entry_index)
18161     {
18162       errmsg ("no index specified!");
18163       return -99;
18164     }
18165
18166   if (!vam->json_output)
18167     {
18168       print (vam->ofp, "first line");
18169     }
18170
18171   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18172
18173   /* send it... */
18174   S (mp);
18175   /* Use a control ping for synchronization */
18176   MPING (CONTROL_PING, mp_ping);
18177   S (mp_ping);
18178
18179   /* Wait for a reply... */
18180   W (ret);
18181   return ret;
18182 }
18183
18184 static int
18185 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18186 {
18187   vl_api_one_get_map_request_itr_rlocs_t *mp;
18188   int ret;
18189
18190   if (!vam->json_output)
18191     {
18192       print (vam->ofp, "%=20s", "itr-rlocs:");
18193     }
18194
18195   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18196   /* send it... */
18197   S (mp);
18198   /* Wait for a reply... */
18199   W (ret);
18200   return ret;
18201 }
18202
18203 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18204
18205 static int
18206 api_af_packet_create (vat_main_t * vam)
18207 {
18208   unformat_input_t *i = vam->input;
18209   vl_api_af_packet_create_t *mp;
18210   u8 *host_if_name = 0;
18211   u8 hw_addr[6];
18212   u8 random_hw_addr = 1;
18213   int ret;
18214
18215   memset (hw_addr, 0, sizeof (hw_addr));
18216
18217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18218     {
18219       if (unformat (i, "name %s", &host_if_name))
18220         vec_add1 (host_if_name, 0);
18221       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18222         random_hw_addr = 0;
18223       else
18224         break;
18225     }
18226
18227   if (!vec_len (host_if_name))
18228     {
18229       errmsg ("host-interface name must be specified");
18230       return -99;
18231     }
18232
18233   if (vec_len (host_if_name) > 64)
18234     {
18235       errmsg ("host-interface name too long");
18236       return -99;
18237     }
18238
18239   M (AF_PACKET_CREATE, mp);
18240
18241   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18242   clib_memcpy (mp->hw_addr, hw_addr, 6);
18243   mp->use_random_hw_addr = random_hw_addr;
18244   vec_free (host_if_name);
18245
18246   S (mp);
18247
18248   /* *INDENT-OFF* */
18249   W2 (ret,
18250       ({
18251         if (ret == 0)
18252           fprintf (vam->ofp ? vam->ofp : stderr,
18253                    " new sw_if_index = %d\n", vam->sw_if_index);
18254       }));
18255   /* *INDENT-ON* */
18256   return ret;
18257 }
18258
18259 static int
18260 api_af_packet_delete (vat_main_t * vam)
18261 {
18262   unformat_input_t *i = vam->input;
18263   vl_api_af_packet_delete_t *mp;
18264   u8 *host_if_name = 0;
18265   int ret;
18266
18267   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18268     {
18269       if (unformat (i, "name %s", &host_if_name))
18270         vec_add1 (host_if_name, 0);
18271       else
18272         break;
18273     }
18274
18275   if (!vec_len (host_if_name))
18276     {
18277       errmsg ("host-interface name must be specified");
18278       return -99;
18279     }
18280
18281   if (vec_len (host_if_name) > 64)
18282     {
18283       errmsg ("host-interface name too long");
18284       return -99;
18285     }
18286
18287   M (AF_PACKET_DELETE, mp);
18288
18289   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18290   vec_free (host_if_name);
18291
18292   S (mp);
18293   W (ret);
18294   return ret;
18295 }
18296
18297 static int
18298 api_policer_add_del (vat_main_t * vam)
18299 {
18300   unformat_input_t *i = vam->input;
18301   vl_api_policer_add_del_t *mp;
18302   u8 is_add = 1;
18303   u8 *name = 0;
18304   u32 cir = 0;
18305   u32 eir = 0;
18306   u64 cb = 0;
18307   u64 eb = 0;
18308   u8 rate_type = 0;
18309   u8 round_type = 0;
18310   u8 type = 0;
18311   u8 color_aware = 0;
18312   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18313   int ret;
18314
18315   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18316   conform_action.dscp = 0;
18317   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18318   exceed_action.dscp = 0;
18319   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18320   violate_action.dscp = 0;
18321
18322   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18323     {
18324       if (unformat (i, "del"))
18325         is_add = 0;
18326       else if (unformat (i, "name %s", &name))
18327         vec_add1 (name, 0);
18328       else if (unformat (i, "cir %u", &cir))
18329         ;
18330       else if (unformat (i, "eir %u", &eir))
18331         ;
18332       else if (unformat (i, "cb %u", &cb))
18333         ;
18334       else if (unformat (i, "eb %u", &eb))
18335         ;
18336       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18337                          &rate_type))
18338         ;
18339       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18340                          &round_type))
18341         ;
18342       else if (unformat (i, "type %U", unformat_policer_type, &type))
18343         ;
18344       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18345                          &conform_action))
18346         ;
18347       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18348                          &exceed_action))
18349         ;
18350       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18351                          &violate_action))
18352         ;
18353       else if (unformat (i, "color-aware"))
18354         color_aware = 1;
18355       else
18356         break;
18357     }
18358
18359   if (!vec_len (name))
18360     {
18361       errmsg ("policer name must be specified");
18362       return -99;
18363     }
18364
18365   if (vec_len (name) > 64)
18366     {
18367       errmsg ("policer name too long");
18368       return -99;
18369     }
18370
18371   M (POLICER_ADD_DEL, mp);
18372
18373   clib_memcpy (mp->name, name, vec_len (name));
18374   vec_free (name);
18375   mp->is_add = is_add;
18376   mp->cir = ntohl (cir);
18377   mp->eir = ntohl (eir);
18378   mp->cb = clib_net_to_host_u64 (cb);
18379   mp->eb = clib_net_to_host_u64 (eb);
18380   mp->rate_type = rate_type;
18381   mp->round_type = round_type;
18382   mp->type = type;
18383   mp->conform_action_type = conform_action.action_type;
18384   mp->conform_dscp = conform_action.dscp;
18385   mp->exceed_action_type = exceed_action.action_type;
18386   mp->exceed_dscp = exceed_action.dscp;
18387   mp->violate_action_type = violate_action.action_type;
18388   mp->violate_dscp = violate_action.dscp;
18389   mp->color_aware = color_aware;
18390
18391   S (mp);
18392   W (ret);
18393   return ret;
18394 }
18395
18396 static int
18397 api_policer_dump (vat_main_t * vam)
18398 {
18399   unformat_input_t *i = vam->input;
18400   vl_api_policer_dump_t *mp;
18401   vl_api_control_ping_t *mp_ping;
18402   u8 *match_name = 0;
18403   u8 match_name_valid = 0;
18404   int ret;
18405
18406   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18407     {
18408       if (unformat (i, "name %s", &match_name))
18409         {
18410           vec_add1 (match_name, 0);
18411           match_name_valid = 1;
18412         }
18413       else
18414         break;
18415     }
18416
18417   M (POLICER_DUMP, mp);
18418   mp->match_name_valid = match_name_valid;
18419   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18420   vec_free (match_name);
18421   /* send it... */
18422   S (mp);
18423
18424   /* Use a control ping for synchronization */
18425   MPING (CONTROL_PING, mp_ping);
18426   S (mp_ping);
18427
18428   /* Wait for a reply... */
18429   W (ret);
18430   return ret;
18431 }
18432
18433 static int
18434 api_policer_classify_set_interface (vat_main_t * vam)
18435 {
18436   unformat_input_t *i = vam->input;
18437   vl_api_policer_classify_set_interface_t *mp;
18438   u32 sw_if_index;
18439   int sw_if_index_set;
18440   u32 ip4_table_index = ~0;
18441   u32 ip6_table_index = ~0;
18442   u32 l2_table_index = ~0;
18443   u8 is_add = 1;
18444   int ret;
18445
18446   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18447     {
18448       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18449         sw_if_index_set = 1;
18450       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18451         sw_if_index_set = 1;
18452       else if (unformat (i, "del"))
18453         is_add = 0;
18454       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18455         ;
18456       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18457         ;
18458       else if (unformat (i, "l2-table %d", &l2_table_index))
18459         ;
18460       else
18461         {
18462           clib_warning ("parse error '%U'", format_unformat_error, i);
18463           return -99;
18464         }
18465     }
18466
18467   if (sw_if_index_set == 0)
18468     {
18469       errmsg ("missing interface name or sw_if_index");
18470       return -99;
18471     }
18472
18473   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18474
18475   mp->sw_if_index = ntohl (sw_if_index);
18476   mp->ip4_table_index = ntohl (ip4_table_index);
18477   mp->ip6_table_index = ntohl (ip6_table_index);
18478   mp->l2_table_index = ntohl (l2_table_index);
18479   mp->is_add = is_add;
18480
18481   S (mp);
18482   W (ret);
18483   return ret;
18484 }
18485
18486 static int
18487 api_policer_classify_dump (vat_main_t * vam)
18488 {
18489   unformat_input_t *i = vam->input;
18490   vl_api_policer_classify_dump_t *mp;
18491   vl_api_control_ping_t *mp_ping;
18492   u8 type = POLICER_CLASSIFY_N_TABLES;
18493   int ret;
18494
18495   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18496     ;
18497   else
18498     {
18499       errmsg ("classify table type must be specified");
18500       return -99;
18501     }
18502
18503   if (!vam->json_output)
18504     {
18505       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18506     }
18507
18508   M (POLICER_CLASSIFY_DUMP, mp);
18509   mp->type = type;
18510   /* send it... */
18511   S (mp);
18512
18513   /* Use a control ping for synchronization */
18514   MPING (CONTROL_PING, mp_ping);
18515   S (mp_ping);
18516
18517   /* Wait for a reply... */
18518   W (ret);
18519   return ret;
18520 }
18521
18522 static int
18523 api_netmap_create (vat_main_t * vam)
18524 {
18525   unformat_input_t *i = vam->input;
18526   vl_api_netmap_create_t *mp;
18527   u8 *if_name = 0;
18528   u8 hw_addr[6];
18529   u8 random_hw_addr = 1;
18530   u8 is_pipe = 0;
18531   u8 is_master = 0;
18532   int ret;
18533
18534   memset (hw_addr, 0, sizeof (hw_addr));
18535
18536   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18537     {
18538       if (unformat (i, "name %s", &if_name))
18539         vec_add1 (if_name, 0);
18540       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18541         random_hw_addr = 0;
18542       else if (unformat (i, "pipe"))
18543         is_pipe = 1;
18544       else if (unformat (i, "master"))
18545         is_master = 1;
18546       else if (unformat (i, "slave"))
18547         is_master = 0;
18548       else
18549         break;
18550     }
18551
18552   if (!vec_len (if_name))
18553     {
18554       errmsg ("interface name must be specified");
18555       return -99;
18556     }
18557
18558   if (vec_len (if_name) > 64)
18559     {
18560       errmsg ("interface name too long");
18561       return -99;
18562     }
18563
18564   M (NETMAP_CREATE, mp);
18565
18566   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18567   clib_memcpy (mp->hw_addr, hw_addr, 6);
18568   mp->use_random_hw_addr = random_hw_addr;
18569   mp->is_pipe = is_pipe;
18570   mp->is_master = is_master;
18571   vec_free (if_name);
18572
18573   S (mp);
18574   W (ret);
18575   return ret;
18576 }
18577
18578 static int
18579 api_netmap_delete (vat_main_t * vam)
18580 {
18581   unformat_input_t *i = vam->input;
18582   vl_api_netmap_delete_t *mp;
18583   u8 *if_name = 0;
18584   int ret;
18585
18586   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18587     {
18588       if (unformat (i, "name %s", &if_name))
18589         vec_add1 (if_name, 0);
18590       else
18591         break;
18592     }
18593
18594   if (!vec_len (if_name))
18595     {
18596       errmsg ("interface name must be specified");
18597       return -99;
18598     }
18599
18600   if (vec_len (if_name) > 64)
18601     {
18602       errmsg ("interface name too long");
18603       return -99;
18604     }
18605
18606   M (NETMAP_DELETE, mp);
18607
18608   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18609   vec_free (if_name);
18610
18611   S (mp);
18612   W (ret);
18613   return ret;
18614 }
18615
18616 static void
18617 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
18618 {
18619   if (fp->afi == IP46_TYPE_IP6)
18620     print (vam->ofp,
18621            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18622            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18623            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18624            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18625            format_ip6_address, fp->next_hop);
18626   else if (fp->afi == IP46_TYPE_IP4)
18627     print (vam->ofp,
18628            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18629            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18630            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18631            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18632            format_ip4_address, fp->next_hop);
18633 }
18634
18635 static void
18636 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18637                                  vl_api_fib_path2_t * fp)
18638 {
18639   struct in_addr ip4;
18640   struct in6_addr ip6;
18641
18642   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18643   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18644   vat_json_object_add_uint (node, "is_local", fp->is_local);
18645   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
18646   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
18647   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
18648   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
18649   if (fp->afi == IP46_TYPE_IP4)
18650     {
18651       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
18652       vat_json_object_add_ip4 (node, "next_hop", ip4);
18653     }
18654   else if (fp->afi == IP46_TYPE_IP6)
18655     {
18656       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
18657       vat_json_object_add_ip6 (node, "next_hop", ip6);
18658     }
18659 }
18660
18661 static void
18662 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18663 {
18664   vat_main_t *vam = &vat_main;
18665   int count = ntohl (mp->mt_count);
18666   vl_api_fib_path2_t *fp;
18667   i32 i;
18668
18669   print (vam->ofp, "[%d]: sw_if_index %d via:",
18670          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
18671   fp = mp->mt_paths;
18672   for (i = 0; i < count; i++)
18673     {
18674       vl_api_mpls_fib_path_print (vam, fp);
18675       fp++;
18676     }
18677
18678   print (vam->ofp, "");
18679 }
18680
18681 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18682 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18683
18684 static void
18685 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18686 {
18687   vat_main_t *vam = &vat_main;
18688   vat_json_node_t *node = NULL;
18689   int count = ntohl (mp->mt_count);
18690   vl_api_fib_path2_t *fp;
18691   i32 i;
18692
18693   if (VAT_JSON_ARRAY != vam->json_tree.type)
18694     {
18695       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18696       vat_json_init_array (&vam->json_tree);
18697     }
18698   node = vat_json_array_add (&vam->json_tree);
18699
18700   vat_json_init_object (node);
18701   vat_json_object_add_uint (node, "tunnel_index",
18702                             ntohl (mp->mt_tunnel_index));
18703   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
18704
18705   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
18706
18707   fp = mp->mt_paths;
18708   for (i = 0; i < count; i++)
18709     {
18710       vl_api_mpls_fib_path_json_print (node, fp);
18711       fp++;
18712     }
18713 }
18714
18715 static int
18716 api_mpls_tunnel_dump (vat_main_t * vam)
18717 {
18718   vl_api_mpls_tunnel_dump_t *mp;
18719   vl_api_control_ping_t *mp_ping;
18720   i32 index = -1;
18721   int ret;
18722
18723   /* Parse args required to build the message */
18724   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
18725     {
18726       if (!unformat (vam->input, "tunnel_index %d", &index))
18727         {
18728           index = -1;
18729           break;
18730         }
18731     }
18732
18733   print (vam->ofp, "  tunnel_index %d", index);
18734
18735   M (MPLS_TUNNEL_DUMP, mp);
18736   mp->tunnel_index = htonl (index);
18737   S (mp);
18738
18739   /* Use a control ping for synchronization */
18740   MPING (CONTROL_PING, mp_ping);
18741   S (mp_ping);
18742
18743   W (ret);
18744   return ret;
18745 }
18746
18747 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
18748 #define vl_api_mpls_fib_details_t_print vl_noop_handler
18749
18750
18751 static void
18752 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
18753 {
18754   vat_main_t *vam = &vat_main;
18755   int count = ntohl (mp->count);
18756   vl_api_fib_path2_t *fp;
18757   int i;
18758
18759   print (vam->ofp,
18760          "table-id %d, label %u, ess_bit %u",
18761          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
18762   fp = mp->path;
18763   for (i = 0; i < count; i++)
18764     {
18765       vl_api_mpls_fib_path_print (vam, fp);
18766       fp++;
18767     }
18768 }
18769
18770 static void vl_api_mpls_fib_details_t_handler_json
18771   (vl_api_mpls_fib_details_t * mp)
18772 {
18773   vat_main_t *vam = &vat_main;
18774   int count = ntohl (mp->count);
18775   vat_json_node_t *node = NULL;
18776   vl_api_fib_path2_t *fp;
18777   int i;
18778
18779   if (VAT_JSON_ARRAY != vam->json_tree.type)
18780     {
18781       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18782       vat_json_init_array (&vam->json_tree);
18783     }
18784   node = vat_json_array_add (&vam->json_tree);
18785
18786   vat_json_init_object (node);
18787   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
18788   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
18789   vat_json_object_add_uint (node, "label", ntohl (mp->label));
18790   vat_json_object_add_uint (node, "path_count", count);
18791   fp = mp->path;
18792   for (i = 0; i < count; i++)
18793     {
18794       vl_api_mpls_fib_path_json_print (node, fp);
18795       fp++;
18796     }
18797 }
18798
18799 static int
18800 api_mpls_fib_dump (vat_main_t * vam)
18801 {
18802   vl_api_mpls_fib_dump_t *mp;
18803   vl_api_control_ping_t *mp_ping;
18804   int ret;
18805
18806   M (MPLS_FIB_DUMP, mp);
18807   S (mp);
18808
18809   /* Use a control ping for synchronization */
18810   MPING (CONTROL_PING, mp_ping);
18811   S (mp_ping);
18812
18813   W (ret);
18814   return ret;
18815 }
18816
18817 #define vl_api_ip_fib_details_t_endian vl_noop_handler
18818 #define vl_api_ip_fib_details_t_print vl_noop_handler
18819
18820 static void
18821 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
18822 {
18823   vat_main_t *vam = &vat_main;
18824   int count = ntohl (mp->count);
18825   vl_api_fib_path_t *fp;
18826   int i;
18827
18828   print (vam->ofp,
18829          "table-id %d, prefix %U/%d",
18830          ntohl (mp->table_id), format_ip4_address, mp->address,
18831          mp->address_length);
18832   fp = mp->path;
18833   for (i = 0; i < count; i++)
18834     {
18835       if (fp->afi == IP46_TYPE_IP6)
18836         print (vam->ofp,
18837                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18838                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18839                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18840                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18841                format_ip6_address, fp->next_hop);
18842       else if (fp->afi == IP46_TYPE_IP4)
18843         print (vam->ofp,
18844                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18845                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18846                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18847                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18848                format_ip4_address, fp->next_hop);
18849       fp++;
18850     }
18851 }
18852
18853 static void vl_api_ip_fib_details_t_handler_json
18854   (vl_api_ip_fib_details_t * mp)
18855 {
18856   vat_main_t *vam = &vat_main;
18857   int count = ntohl (mp->count);
18858   vat_json_node_t *node = NULL;
18859   struct in_addr ip4;
18860   struct in6_addr ip6;
18861   vl_api_fib_path_t *fp;
18862   int i;
18863
18864   if (VAT_JSON_ARRAY != vam->json_tree.type)
18865     {
18866       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18867       vat_json_init_array (&vam->json_tree);
18868     }
18869   node = vat_json_array_add (&vam->json_tree);
18870
18871   vat_json_init_object (node);
18872   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
18873   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
18874   vat_json_object_add_ip4 (node, "prefix", ip4);
18875   vat_json_object_add_uint (node, "mask_length", mp->address_length);
18876   vat_json_object_add_uint (node, "path_count", count);
18877   fp = mp->path;
18878   for (i = 0; i < count; i++)
18879     {
18880       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18881       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18882       vat_json_object_add_uint (node, "is_local", fp->is_local);
18883       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
18884       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
18885       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
18886       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
18887       if (fp->afi == IP46_TYPE_IP4)
18888         {
18889           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
18890           vat_json_object_add_ip4 (node, "next_hop", ip4);
18891         }
18892       else if (fp->afi == IP46_TYPE_IP6)
18893         {
18894           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
18895           vat_json_object_add_ip6 (node, "next_hop", ip6);
18896         }
18897     }
18898 }
18899
18900 static int
18901 api_ip_fib_dump (vat_main_t * vam)
18902 {
18903   vl_api_ip_fib_dump_t *mp;
18904   vl_api_control_ping_t *mp_ping;
18905   int ret;
18906
18907   M (IP_FIB_DUMP, mp);
18908   S (mp);
18909
18910   /* Use a control ping for synchronization */
18911   MPING (CONTROL_PING, mp_ping);
18912   S (mp_ping);
18913
18914   W (ret);
18915   return ret;
18916 }
18917
18918 static int
18919 api_ip_mfib_dump (vat_main_t * vam)
18920 {
18921   vl_api_ip_mfib_dump_t *mp;
18922   vl_api_control_ping_t *mp_ping;
18923   int ret;
18924
18925   M (IP_MFIB_DUMP, mp);
18926   S (mp);
18927
18928   /* Use a control ping for synchronization */
18929   MPING (CONTROL_PING, mp_ping);
18930   S (mp_ping);
18931
18932   W (ret);
18933   return ret;
18934 }
18935
18936 static void vl_api_ip_neighbor_details_t_handler
18937   (vl_api_ip_neighbor_details_t * mp)
18938 {
18939   vat_main_t *vam = &vat_main;
18940
18941   print (vam->ofp, "%c %U %U",
18942          (mp->is_static) ? 'S' : 'D',
18943          format_ethernet_address, &mp->mac_address,
18944          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
18945          &mp->ip_address);
18946 }
18947
18948 static void vl_api_ip_neighbor_details_t_handler_json
18949   (vl_api_ip_neighbor_details_t * mp)
18950 {
18951
18952   vat_main_t *vam = &vat_main;
18953   vat_json_node_t *node;
18954   struct in_addr ip4;
18955   struct in6_addr ip6;
18956
18957   if (VAT_JSON_ARRAY != vam->json_tree.type)
18958     {
18959       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18960       vat_json_init_array (&vam->json_tree);
18961     }
18962   node = vat_json_array_add (&vam->json_tree);
18963
18964   vat_json_init_object (node);
18965   vat_json_object_add_string_copy (node, "flag",
18966                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
18967                                    "dynamic");
18968
18969   vat_json_object_add_string_copy (node, "link_layer",
18970                                    format (0, "%U", format_ethernet_address,
18971                                            &mp->mac_address));
18972
18973   if (mp->is_ipv6)
18974     {
18975       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
18976       vat_json_object_add_ip6 (node, "ip_address", ip6);
18977     }
18978   else
18979     {
18980       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
18981       vat_json_object_add_ip4 (node, "ip_address", ip4);
18982     }
18983 }
18984
18985 static int
18986 api_ip_neighbor_dump (vat_main_t * vam)
18987 {
18988   unformat_input_t *i = vam->input;
18989   vl_api_ip_neighbor_dump_t *mp;
18990   vl_api_control_ping_t *mp_ping;
18991   u8 is_ipv6 = 0;
18992   u32 sw_if_index = ~0;
18993   int ret;
18994
18995   /* Parse args required to build the message */
18996   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18997     {
18998       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18999         ;
19000       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19001         ;
19002       else if (unformat (i, "ip6"))
19003         is_ipv6 = 1;
19004       else
19005         break;
19006     }
19007
19008   if (sw_if_index == ~0)
19009     {
19010       errmsg ("missing interface name or sw_if_index");
19011       return -99;
19012     }
19013
19014   M (IP_NEIGHBOR_DUMP, mp);
19015   mp->is_ipv6 = (u8) is_ipv6;
19016   mp->sw_if_index = ntohl (sw_if_index);
19017   S (mp);
19018
19019   /* Use a control ping for synchronization */
19020   MPING (CONTROL_PING, mp_ping);
19021   S (mp_ping);
19022
19023   W (ret);
19024   return ret;
19025 }
19026
19027 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
19028 #define vl_api_ip6_fib_details_t_print vl_noop_handler
19029
19030 static void
19031 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
19032 {
19033   vat_main_t *vam = &vat_main;
19034   int count = ntohl (mp->count);
19035   vl_api_fib_path_t *fp;
19036   int i;
19037
19038   print (vam->ofp,
19039          "table-id %d, prefix %U/%d",
19040          ntohl (mp->table_id), format_ip6_address, mp->address,
19041          mp->address_length);
19042   fp = mp->path;
19043   for (i = 0; i < count; i++)
19044     {
19045       if (fp->afi == IP46_TYPE_IP6)
19046         print (vam->ofp,
19047                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19048                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19049                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19050                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19051                format_ip6_address, fp->next_hop);
19052       else if (fp->afi == IP46_TYPE_IP4)
19053         print (vam->ofp,
19054                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19055                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19056                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19057                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19058                format_ip4_address, fp->next_hop);
19059       fp++;
19060     }
19061 }
19062
19063 static void vl_api_ip6_fib_details_t_handler_json
19064   (vl_api_ip6_fib_details_t * mp)
19065 {
19066   vat_main_t *vam = &vat_main;
19067   int count = ntohl (mp->count);
19068   vat_json_node_t *node = NULL;
19069   struct in_addr ip4;
19070   struct in6_addr ip6;
19071   vl_api_fib_path_t *fp;
19072   int i;
19073
19074   if (VAT_JSON_ARRAY != vam->json_tree.type)
19075     {
19076       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19077       vat_json_init_array (&vam->json_tree);
19078     }
19079   node = vat_json_array_add (&vam->json_tree);
19080
19081   vat_json_init_object (node);
19082   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19083   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
19084   vat_json_object_add_ip6 (node, "prefix", ip6);
19085   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19086   vat_json_object_add_uint (node, "path_count", count);
19087   fp = mp->path;
19088   for (i = 0; i < count; i++)
19089     {
19090       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19091       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19092       vat_json_object_add_uint (node, "is_local", fp->is_local);
19093       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19094       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19095       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19096       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19097       if (fp->afi == IP46_TYPE_IP4)
19098         {
19099           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19100           vat_json_object_add_ip4 (node, "next_hop", ip4);
19101         }
19102       else if (fp->afi == IP46_TYPE_IP6)
19103         {
19104           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19105           vat_json_object_add_ip6 (node, "next_hop", ip6);
19106         }
19107     }
19108 }
19109
19110 static int
19111 api_ip6_fib_dump (vat_main_t * vam)
19112 {
19113   vl_api_ip6_fib_dump_t *mp;
19114   vl_api_control_ping_t *mp_ping;
19115   int ret;
19116
19117   M (IP6_FIB_DUMP, mp);
19118   S (mp);
19119
19120   /* Use a control ping for synchronization */
19121   MPING (CONTROL_PING, mp_ping);
19122   S (mp_ping);
19123
19124   W (ret);
19125   return ret;
19126 }
19127
19128 static int
19129 api_ip6_mfib_dump (vat_main_t * vam)
19130 {
19131   vl_api_ip6_mfib_dump_t *mp;
19132   vl_api_control_ping_t *mp_ping;
19133   int ret;
19134
19135   M (IP6_MFIB_DUMP, mp);
19136   S (mp);
19137
19138   /* Use a control ping for synchronization */
19139   MPING (CONTROL_PING, mp_ping);
19140   S (mp_ping);
19141
19142   W (ret);
19143   return ret;
19144 }
19145
19146 int
19147 api_classify_table_ids (vat_main_t * vam)
19148 {
19149   vl_api_classify_table_ids_t *mp;
19150   int ret;
19151
19152   /* Construct the API message */
19153   M (CLASSIFY_TABLE_IDS, mp);
19154   mp->context = 0;
19155
19156   S (mp);
19157   W (ret);
19158   return ret;
19159 }
19160
19161 int
19162 api_classify_table_by_interface (vat_main_t * vam)
19163 {
19164   unformat_input_t *input = vam->input;
19165   vl_api_classify_table_by_interface_t *mp;
19166
19167   u32 sw_if_index = ~0;
19168   int ret;
19169   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19170     {
19171       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19172         ;
19173       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19174         ;
19175       else
19176         break;
19177     }
19178   if (sw_if_index == ~0)
19179     {
19180       errmsg ("missing interface name or sw_if_index");
19181       return -99;
19182     }
19183
19184   /* Construct the API message */
19185   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19186   mp->context = 0;
19187   mp->sw_if_index = ntohl (sw_if_index);
19188
19189   S (mp);
19190   W (ret);
19191   return ret;
19192 }
19193
19194 int
19195 api_classify_table_info (vat_main_t * vam)
19196 {
19197   unformat_input_t *input = vam->input;
19198   vl_api_classify_table_info_t *mp;
19199
19200   u32 table_id = ~0;
19201   int ret;
19202   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19203     {
19204       if (unformat (input, "table_id %d", &table_id))
19205         ;
19206       else
19207         break;
19208     }
19209   if (table_id == ~0)
19210     {
19211       errmsg ("missing table id");
19212       return -99;
19213     }
19214
19215   /* Construct the API message */
19216   M (CLASSIFY_TABLE_INFO, mp);
19217   mp->context = 0;
19218   mp->table_id = ntohl (table_id);
19219
19220   S (mp);
19221   W (ret);
19222   return ret;
19223 }
19224
19225 int
19226 api_classify_session_dump (vat_main_t * vam)
19227 {
19228   unformat_input_t *input = vam->input;
19229   vl_api_classify_session_dump_t *mp;
19230   vl_api_control_ping_t *mp_ping;
19231
19232   u32 table_id = ~0;
19233   int ret;
19234   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19235     {
19236       if (unformat (input, "table_id %d", &table_id))
19237         ;
19238       else
19239         break;
19240     }
19241   if (table_id == ~0)
19242     {
19243       errmsg ("missing table id");
19244       return -99;
19245     }
19246
19247   /* Construct the API message */
19248   M (CLASSIFY_SESSION_DUMP, mp);
19249   mp->context = 0;
19250   mp->table_id = ntohl (table_id);
19251   S (mp);
19252
19253   /* Use a control ping for synchronization */
19254   MPING (CONTROL_PING, mp_ping);
19255   S (mp_ping);
19256
19257   W (ret);
19258   return ret;
19259 }
19260
19261 static void
19262 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19263 {
19264   vat_main_t *vam = &vat_main;
19265
19266   print (vam->ofp, "collector_address %U, collector_port %d, "
19267          "src_address %U, vrf_id %d, path_mtu %u, "
19268          "template_interval %u, udp_checksum %d",
19269          format_ip4_address, mp->collector_address,
19270          ntohs (mp->collector_port),
19271          format_ip4_address, mp->src_address,
19272          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19273          ntohl (mp->template_interval), mp->udp_checksum);
19274
19275   vam->retval = 0;
19276   vam->result_ready = 1;
19277 }
19278
19279 static void
19280   vl_api_ipfix_exporter_details_t_handler_json
19281   (vl_api_ipfix_exporter_details_t * mp)
19282 {
19283   vat_main_t *vam = &vat_main;
19284   vat_json_node_t node;
19285   struct in_addr collector_address;
19286   struct in_addr src_address;
19287
19288   vat_json_init_object (&node);
19289   clib_memcpy (&collector_address, &mp->collector_address,
19290                sizeof (collector_address));
19291   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19292   vat_json_object_add_uint (&node, "collector_port",
19293                             ntohs (mp->collector_port));
19294   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19295   vat_json_object_add_ip4 (&node, "src_address", src_address);
19296   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19297   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19298   vat_json_object_add_uint (&node, "template_interval",
19299                             ntohl (mp->template_interval));
19300   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19301
19302   vat_json_print (vam->ofp, &node);
19303   vat_json_free (&node);
19304   vam->retval = 0;
19305   vam->result_ready = 1;
19306 }
19307
19308 int
19309 api_ipfix_exporter_dump (vat_main_t * vam)
19310 {
19311   vl_api_ipfix_exporter_dump_t *mp;
19312   int ret;
19313
19314   /* Construct the API message */
19315   M (IPFIX_EXPORTER_DUMP, mp);
19316   mp->context = 0;
19317
19318   S (mp);
19319   W (ret);
19320   return ret;
19321 }
19322
19323 static int
19324 api_ipfix_classify_stream_dump (vat_main_t * vam)
19325 {
19326   vl_api_ipfix_classify_stream_dump_t *mp;
19327   int ret;
19328
19329   /* Construct the API message */
19330   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19331   mp->context = 0;
19332
19333   S (mp);
19334   W (ret);
19335   return ret;
19336   /* NOTREACHED */
19337   return 0;
19338 }
19339
19340 static void
19341   vl_api_ipfix_classify_stream_details_t_handler
19342   (vl_api_ipfix_classify_stream_details_t * mp)
19343 {
19344   vat_main_t *vam = &vat_main;
19345   print (vam->ofp, "domain_id %d, src_port %d",
19346          ntohl (mp->domain_id), ntohs (mp->src_port));
19347   vam->retval = 0;
19348   vam->result_ready = 1;
19349 }
19350
19351 static void
19352   vl_api_ipfix_classify_stream_details_t_handler_json
19353   (vl_api_ipfix_classify_stream_details_t * mp)
19354 {
19355   vat_main_t *vam = &vat_main;
19356   vat_json_node_t node;
19357
19358   vat_json_init_object (&node);
19359   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19360   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19361
19362   vat_json_print (vam->ofp, &node);
19363   vat_json_free (&node);
19364   vam->retval = 0;
19365   vam->result_ready = 1;
19366 }
19367
19368 static int
19369 api_ipfix_classify_table_dump (vat_main_t * vam)
19370 {
19371   vl_api_ipfix_classify_table_dump_t *mp;
19372   vl_api_control_ping_t *mp_ping;
19373   int ret;
19374
19375   if (!vam->json_output)
19376     {
19377       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19378              "transport_protocol");
19379     }
19380
19381   /* Construct the API message */
19382   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19383
19384   /* send it... */
19385   S (mp);
19386
19387   /* Use a control ping for synchronization */
19388   MPING (CONTROL_PING, mp_ping);
19389   S (mp_ping);
19390
19391   W (ret);
19392   return ret;
19393 }
19394
19395 static void
19396   vl_api_ipfix_classify_table_details_t_handler
19397   (vl_api_ipfix_classify_table_details_t * mp)
19398 {
19399   vat_main_t *vam = &vat_main;
19400   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19401          mp->transport_protocol);
19402 }
19403
19404 static void
19405   vl_api_ipfix_classify_table_details_t_handler_json
19406   (vl_api_ipfix_classify_table_details_t * mp)
19407 {
19408   vat_json_node_t *node = NULL;
19409   vat_main_t *vam = &vat_main;
19410
19411   if (VAT_JSON_ARRAY != vam->json_tree.type)
19412     {
19413       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19414       vat_json_init_array (&vam->json_tree);
19415     }
19416
19417   node = vat_json_array_add (&vam->json_tree);
19418   vat_json_init_object (node);
19419
19420   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19421   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19422   vat_json_object_add_uint (node, "transport_protocol",
19423                             mp->transport_protocol);
19424 }
19425
19426 static int
19427 api_sw_interface_span_enable_disable (vat_main_t * vam)
19428 {
19429   unformat_input_t *i = vam->input;
19430   vl_api_sw_interface_span_enable_disable_t *mp;
19431   u32 src_sw_if_index = ~0;
19432   u32 dst_sw_if_index = ~0;
19433   u8 state = 3;
19434   int ret;
19435   u8 is_l2 = 0;
19436
19437   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19438     {
19439       if (unformat
19440           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19441         ;
19442       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19443         ;
19444       else
19445         if (unformat
19446             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19447         ;
19448       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19449         ;
19450       else if (unformat (i, "disable"))
19451         state = 0;
19452       else if (unformat (i, "rx"))
19453         state = 1;
19454       else if (unformat (i, "tx"))
19455         state = 2;
19456       else if (unformat (i, "both"))
19457         state = 3;
19458       else if (unformat (i, "l2"))
19459         is_l2 = 1;
19460       else
19461         break;
19462     }
19463
19464   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19465
19466   mp->sw_if_index_from = htonl (src_sw_if_index);
19467   mp->sw_if_index_to = htonl (dst_sw_if_index);
19468   mp->state = state;
19469   mp->is_l2 = is_l2;
19470
19471   S (mp);
19472   W (ret);
19473   return ret;
19474 }
19475
19476 static void
19477 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19478                                             * mp)
19479 {
19480   vat_main_t *vam = &vat_main;
19481   u8 *sw_if_from_name = 0;
19482   u8 *sw_if_to_name = 0;
19483   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19484   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19485   char *states[] = { "none", "rx", "tx", "both" };
19486   hash_pair_t *p;
19487
19488   /* *INDENT-OFF* */
19489   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19490   ({
19491     if ((u32) p->value[0] == sw_if_index_from)
19492       {
19493         sw_if_from_name = (u8 *)(p->key);
19494         if (sw_if_to_name)
19495           break;
19496       }
19497     if ((u32) p->value[0] == sw_if_index_to)
19498       {
19499         sw_if_to_name = (u8 *)(p->key);
19500         if (sw_if_from_name)
19501           break;
19502       }
19503   }));
19504   /* *INDENT-ON* */
19505   print (vam->ofp, "%20s => %20s (%s)",
19506          sw_if_from_name, sw_if_to_name, states[mp->state]);
19507 }
19508
19509 static void
19510   vl_api_sw_interface_span_details_t_handler_json
19511   (vl_api_sw_interface_span_details_t * mp)
19512 {
19513   vat_main_t *vam = &vat_main;
19514   vat_json_node_t *node = NULL;
19515   u8 *sw_if_from_name = 0;
19516   u8 *sw_if_to_name = 0;
19517   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19518   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19519   hash_pair_t *p;
19520
19521   /* *INDENT-OFF* */
19522   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19523   ({
19524     if ((u32) p->value[0] == sw_if_index_from)
19525       {
19526         sw_if_from_name = (u8 *)(p->key);
19527         if (sw_if_to_name)
19528           break;
19529       }
19530     if ((u32) p->value[0] == sw_if_index_to)
19531       {
19532         sw_if_to_name = (u8 *)(p->key);
19533         if (sw_if_from_name)
19534           break;
19535       }
19536   }));
19537   /* *INDENT-ON* */
19538
19539   if (VAT_JSON_ARRAY != vam->json_tree.type)
19540     {
19541       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19542       vat_json_init_array (&vam->json_tree);
19543     }
19544   node = vat_json_array_add (&vam->json_tree);
19545
19546   vat_json_init_object (node);
19547   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19548   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19549   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19550   if (0 != sw_if_to_name)
19551     {
19552       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19553     }
19554   vat_json_object_add_uint (node, "state", mp->state);
19555 }
19556
19557 static int
19558 api_sw_interface_span_dump (vat_main_t * vam)
19559 {
19560   unformat_input_t *input = vam->input;
19561   vl_api_sw_interface_span_dump_t *mp;
19562   vl_api_control_ping_t *mp_ping;
19563   u8 is_l2 = 0;
19564   int ret;
19565
19566   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19567     {
19568       if (unformat (input, "l2"))
19569         is_l2 = 1;
19570       else
19571         break;
19572     }
19573
19574   M (SW_INTERFACE_SPAN_DUMP, mp);
19575   mp->is_l2 = is_l2;
19576   S (mp);
19577
19578   /* Use a control ping for synchronization */
19579   MPING (CONTROL_PING, mp_ping);
19580   S (mp_ping);
19581
19582   W (ret);
19583   return ret;
19584 }
19585
19586 int
19587 api_pg_create_interface (vat_main_t * vam)
19588 {
19589   unformat_input_t *input = vam->input;
19590   vl_api_pg_create_interface_t *mp;
19591
19592   u32 if_id = ~0;
19593   int ret;
19594   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19595     {
19596       if (unformat (input, "if_id %d", &if_id))
19597         ;
19598       else
19599         break;
19600     }
19601   if (if_id == ~0)
19602     {
19603       errmsg ("missing pg interface index");
19604       return -99;
19605     }
19606
19607   /* Construct the API message */
19608   M (PG_CREATE_INTERFACE, mp);
19609   mp->context = 0;
19610   mp->interface_id = ntohl (if_id);
19611
19612   S (mp);
19613   W (ret);
19614   return ret;
19615 }
19616
19617 int
19618 api_pg_capture (vat_main_t * vam)
19619 {
19620   unformat_input_t *input = vam->input;
19621   vl_api_pg_capture_t *mp;
19622
19623   u32 if_id = ~0;
19624   u8 enable = 1;
19625   u32 count = 1;
19626   u8 pcap_file_set = 0;
19627   u8 *pcap_file = 0;
19628   int ret;
19629   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19630     {
19631       if (unformat (input, "if_id %d", &if_id))
19632         ;
19633       else if (unformat (input, "pcap %s", &pcap_file))
19634         pcap_file_set = 1;
19635       else if (unformat (input, "count %d", &count))
19636         ;
19637       else if (unformat (input, "disable"))
19638         enable = 0;
19639       else
19640         break;
19641     }
19642   if (if_id == ~0)
19643     {
19644       errmsg ("missing pg interface index");
19645       return -99;
19646     }
19647   if (pcap_file_set > 0)
19648     {
19649       if (vec_len (pcap_file) > 255)
19650         {
19651           errmsg ("pcap file name is too long");
19652           return -99;
19653         }
19654     }
19655
19656   u32 name_len = vec_len (pcap_file);
19657   /* Construct the API message */
19658   M (PG_CAPTURE, mp);
19659   mp->context = 0;
19660   mp->interface_id = ntohl (if_id);
19661   mp->is_enabled = enable;
19662   mp->count = ntohl (count);
19663   mp->pcap_name_length = ntohl (name_len);
19664   if (pcap_file_set != 0)
19665     {
19666       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19667     }
19668   vec_free (pcap_file);
19669
19670   S (mp);
19671   W (ret);
19672   return ret;
19673 }
19674
19675 int
19676 api_pg_enable_disable (vat_main_t * vam)
19677 {
19678   unformat_input_t *input = vam->input;
19679   vl_api_pg_enable_disable_t *mp;
19680
19681   u8 enable = 1;
19682   u8 stream_name_set = 0;
19683   u8 *stream_name = 0;
19684   int ret;
19685   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19686     {
19687       if (unformat (input, "stream %s", &stream_name))
19688         stream_name_set = 1;
19689       else if (unformat (input, "disable"))
19690         enable = 0;
19691       else
19692         break;
19693     }
19694
19695   if (stream_name_set > 0)
19696     {
19697       if (vec_len (stream_name) > 255)
19698         {
19699           errmsg ("stream name too long");
19700           return -99;
19701         }
19702     }
19703
19704   u32 name_len = vec_len (stream_name);
19705   /* Construct the API message */
19706   M (PG_ENABLE_DISABLE, mp);
19707   mp->context = 0;
19708   mp->is_enabled = enable;
19709   if (stream_name_set != 0)
19710     {
19711       mp->stream_name_length = ntohl (name_len);
19712       clib_memcpy (mp->stream_name, stream_name, name_len);
19713     }
19714   vec_free (stream_name);
19715
19716   S (mp);
19717   W (ret);
19718   return ret;
19719 }
19720
19721 int
19722 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19723 {
19724   unformat_input_t *input = vam->input;
19725   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19726
19727   u16 *low_ports = 0;
19728   u16 *high_ports = 0;
19729   u16 this_low;
19730   u16 this_hi;
19731   ip4_address_t ip4_addr;
19732   ip6_address_t ip6_addr;
19733   u32 length;
19734   u32 tmp, tmp2;
19735   u8 prefix_set = 0;
19736   u32 vrf_id = ~0;
19737   u8 is_add = 1;
19738   u8 is_ipv6 = 0;
19739   int ret;
19740
19741   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19742     {
19743       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
19744         {
19745           prefix_set = 1;
19746         }
19747       else
19748         if (unformat
19749             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
19750         {
19751           prefix_set = 1;
19752           is_ipv6 = 1;
19753         }
19754       else if (unformat (input, "vrf %d", &vrf_id))
19755         ;
19756       else if (unformat (input, "del"))
19757         is_add = 0;
19758       else if (unformat (input, "port %d", &tmp))
19759         {
19760           if (tmp == 0 || tmp > 65535)
19761             {
19762               errmsg ("port %d out of range", tmp);
19763               return -99;
19764             }
19765           this_low = tmp;
19766           this_hi = this_low + 1;
19767           vec_add1 (low_ports, this_low);
19768           vec_add1 (high_ports, this_hi);
19769         }
19770       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19771         {
19772           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19773             {
19774               errmsg ("incorrect range parameters");
19775               return -99;
19776             }
19777           this_low = tmp;
19778           /* Note: in debug CLI +1 is added to high before
19779              passing to real fn that does "the work"
19780              (ip_source_and_port_range_check_add_del).
19781              This fn is a wrapper around the binary API fn a
19782              control plane will call, which expects this increment
19783              to have occurred. Hence letting the binary API control
19784              plane fn do the increment for consistency between VAT
19785              and other control planes.
19786            */
19787           this_hi = tmp2;
19788           vec_add1 (low_ports, this_low);
19789           vec_add1 (high_ports, this_hi);
19790         }
19791       else
19792         break;
19793     }
19794
19795   if (prefix_set == 0)
19796     {
19797       errmsg ("<address>/<mask> not specified");
19798       return -99;
19799     }
19800
19801   if (vrf_id == ~0)
19802     {
19803       errmsg ("VRF ID required, not specified");
19804       return -99;
19805     }
19806
19807   if (vrf_id == 0)
19808     {
19809       errmsg
19810         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19811       return -99;
19812     }
19813
19814   if (vec_len (low_ports) == 0)
19815     {
19816       errmsg ("At least one port or port range required");
19817       return -99;
19818     }
19819
19820   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19821
19822   mp->is_add = is_add;
19823
19824   if (is_ipv6)
19825     {
19826       mp->is_ipv6 = 1;
19827       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
19828     }
19829   else
19830     {
19831       mp->is_ipv6 = 0;
19832       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
19833     }
19834
19835   mp->mask_length = length;
19836   mp->number_of_ranges = vec_len (low_ports);
19837
19838   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
19839   vec_free (low_ports);
19840
19841   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
19842   vec_free (high_ports);
19843
19844   mp->vrf_id = ntohl (vrf_id);
19845
19846   S (mp);
19847   W (ret);
19848   return ret;
19849 }
19850
19851 int
19852 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
19853 {
19854   unformat_input_t *input = vam->input;
19855   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
19856   u32 sw_if_index = ~0;
19857   int vrf_set = 0;
19858   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
19859   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
19860   u8 is_add = 1;
19861   int ret;
19862
19863   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19864     {
19865       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19866         ;
19867       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19868         ;
19869       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
19870         vrf_set = 1;
19871       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
19872         vrf_set = 1;
19873       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
19874         vrf_set = 1;
19875       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
19876         vrf_set = 1;
19877       else if (unformat (input, "del"))
19878         is_add = 0;
19879       else
19880         break;
19881     }
19882
19883   if (sw_if_index == ~0)
19884     {
19885       errmsg ("Interface required but not specified");
19886       return -99;
19887     }
19888
19889   if (vrf_set == 0)
19890     {
19891       errmsg ("VRF ID required but not specified");
19892       return -99;
19893     }
19894
19895   if (tcp_out_vrf_id == 0
19896       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
19897     {
19898       errmsg
19899         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19900       return -99;
19901     }
19902
19903   /* Construct the API message */
19904   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
19905
19906   mp->sw_if_index = ntohl (sw_if_index);
19907   mp->is_add = is_add;
19908   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
19909   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
19910   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
19911   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
19912
19913   /* send it... */
19914   S (mp);
19915
19916   /* Wait for a reply... */
19917   W (ret);
19918   return ret;
19919 }
19920
19921 static int
19922 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
19923 {
19924   unformat_input_t *i = vam->input;
19925   vl_api_ipsec_gre_add_del_tunnel_t *mp;
19926   u32 local_sa_id = 0;
19927   u32 remote_sa_id = 0;
19928   ip4_address_t src_address;
19929   ip4_address_t dst_address;
19930   u8 is_add = 1;
19931   int ret;
19932
19933   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19934     {
19935       if (unformat (i, "local_sa %d", &local_sa_id))
19936         ;
19937       else if (unformat (i, "remote_sa %d", &remote_sa_id))
19938         ;
19939       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
19940         ;
19941       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
19942         ;
19943       else if (unformat (i, "del"))
19944         is_add = 0;
19945       else
19946         {
19947           clib_warning ("parse error '%U'", format_unformat_error, i);
19948           return -99;
19949         }
19950     }
19951
19952   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
19953
19954   mp->local_sa_id = ntohl (local_sa_id);
19955   mp->remote_sa_id = ntohl (remote_sa_id);
19956   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
19957   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
19958   mp->is_add = is_add;
19959
19960   S (mp);
19961   W (ret);
19962   return ret;
19963 }
19964
19965 static int
19966 api_punt (vat_main_t * vam)
19967 {
19968   unformat_input_t *i = vam->input;
19969   vl_api_punt_t *mp;
19970   u32 ipv = ~0;
19971   u32 protocol = ~0;
19972   u32 port = ~0;
19973   int is_add = 1;
19974   int ret;
19975
19976   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19977     {
19978       if (unformat (i, "ip %d", &ipv))
19979         ;
19980       else if (unformat (i, "protocol %d", &protocol))
19981         ;
19982       else if (unformat (i, "port %d", &port))
19983         ;
19984       else if (unformat (i, "del"))
19985         is_add = 0;
19986       else
19987         {
19988           clib_warning ("parse error '%U'", format_unformat_error, i);
19989           return -99;
19990         }
19991     }
19992
19993   M (PUNT, mp);
19994
19995   mp->is_add = (u8) is_add;
19996   mp->ipv = (u8) ipv;
19997   mp->l4_protocol = (u8) protocol;
19998   mp->l4_port = htons ((u16) port);
19999
20000   S (mp);
20001   W (ret);
20002   return ret;
20003 }
20004
20005 static void vl_api_ipsec_gre_tunnel_details_t_handler
20006   (vl_api_ipsec_gre_tunnel_details_t * mp)
20007 {
20008   vat_main_t *vam = &vat_main;
20009
20010   print (vam->ofp, "%11d%15U%15U%14d%14d",
20011          ntohl (mp->sw_if_index),
20012          format_ip4_address, &mp->src_address,
20013          format_ip4_address, &mp->dst_address,
20014          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
20015 }
20016
20017 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
20018   (vl_api_ipsec_gre_tunnel_details_t * mp)
20019 {
20020   vat_main_t *vam = &vat_main;
20021   vat_json_node_t *node = NULL;
20022   struct in_addr ip4;
20023
20024   if (VAT_JSON_ARRAY != vam->json_tree.type)
20025     {
20026       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20027       vat_json_init_array (&vam->json_tree);
20028     }
20029   node = vat_json_array_add (&vam->json_tree);
20030
20031   vat_json_init_object (node);
20032   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
20033   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
20034   vat_json_object_add_ip4 (node, "src_address", ip4);
20035   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
20036   vat_json_object_add_ip4 (node, "dst_address", ip4);
20037   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
20038   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
20039 }
20040
20041 static int
20042 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
20043 {
20044   unformat_input_t *i = vam->input;
20045   vl_api_ipsec_gre_tunnel_dump_t *mp;
20046   vl_api_control_ping_t *mp_ping;
20047   u32 sw_if_index;
20048   u8 sw_if_index_set = 0;
20049   int ret;
20050
20051   /* Parse args required to build the message */
20052   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20053     {
20054       if (unformat (i, "sw_if_index %d", &sw_if_index))
20055         sw_if_index_set = 1;
20056       else
20057         break;
20058     }
20059
20060   if (sw_if_index_set == 0)
20061     {
20062       sw_if_index = ~0;
20063     }
20064
20065   if (!vam->json_output)
20066     {
20067       print (vam->ofp, "%11s%15s%15s%14s%14s",
20068              "sw_if_index", "src_address", "dst_address",
20069              "local_sa_id", "remote_sa_id");
20070     }
20071
20072   /* Get list of gre-tunnel interfaces */
20073   M (IPSEC_GRE_TUNNEL_DUMP, mp);
20074
20075   mp->sw_if_index = htonl (sw_if_index);
20076
20077   S (mp);
20078
20079   /* Use a control ping for synchronization */
20080   MPING (CONTROL_PING, mp_ping);
20081   S (mp_ping);
20082
20083   W (ret);
20084   return ret;
20085 }
20086
20087 static int
20088 api_delete_subif (vat_main_t * vam)
20089 {
20090   unformat_input_t *i = vam->input;
20091   vl_api_delete_subif_t *mp;
20092   u32 sw_if_index = ~0;
20093   int ret;
20094
20095   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20096     {
20097       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20098         ;
20099       if (unformat (i, "sw_if_index %d", &sw_if_index))
20100         ;
20101       else
20102         break;
20103     }
20104
20105   if (sw_if_index == ~0)
20106     {
20107       errmsg ("missing sw_if_index");
20108       return -99;
20109     }
20110
20111   /* Construct the API message */
20112   M (DELETE_SUBIF, mp);
20113   mp->sw_if_index = ntohl (sw_if_index);
20114
20115   S (mp);
20116   W (ret);
20117   return ret;
20118 }
20119
20120 #define foreach_pbb_vtr_op      \
20121 _("disable",  L2_VTR_DISABLED)  \
20122 _("pop",  L2_VTR_POP_2)         \
20123 _("push",  L2_VTR_PUSH_2)
20124
20125 static int
20126 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20127 {
20128   unformat_input_t *i = vam->input;
20129   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20130   u32 sw_if_index = ~0, vtr_op = ~0;
20131   u16 outer_tag = ~0;
20132   u8 dmac[6], smac[6];
20133   u8 dmac_set = 0, smac_set = 0;
20134   u16 vlanid = 0;
20135   u32 sid = ~0;
20136   u32 tmp;
20137   int ret;
20138
20139   /* Shut up coverity */
20140   memset (dmac, 0, sizeof (dmac));
20141   memset (smac, 0, sizeof (smac));
20142
20143   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20144     {
20145       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20146         ;
20147       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20148         ;
20149       else if (unformat (i, "vtr_op %d", &vtr_op))
20150         ;
20151 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20152       foreach_pbb_vtr_op
20153 #undef _
20154         else if (unformat (i, "translate_pbb_stag"))
20155         {
20156           if (unformat (i, "%d", &tmp))
20157             {
20158               vtr_op = L2_VTR_TRANSLATE_2_1;
20159               outer_tag = tmp;
20160             }
20161           else
20162             {
20163               errmsg
20164                 ("translate_pbb_stag operation requires outer tag definition");
20165               return -99;
20166             }
20167         }
20168       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20169         dmac_set++;
20170       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20171         smac_set++;
20172       else if (unformat (i, "sid %d", &sid))
20173         ;
20174       else if (unformat (i, "vlanid %d", &tmp))
20175         vlanid = tmp;
20176       else
20177         {
20178           clib_warning ("parse error '%U'", format_unformat_error, i);
20179           return -99;
20180         }
20181     }
20182
20183   if ((sw_if_index == ~0) || (vtr_op == ~0))
20184     {
20185       errmsg ("missing sw_if_index or vtr operation");
20186       return -99;
20187     }
20188   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20189       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20190     {
20191       errmsg
20192         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20193       return -99;
20194     }
20195
20196   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20197   mp->sw_if_index = ntohl (sw_if_index);
20198   mp->vtr_op = ntohl (vtr_op);
20199   mp->outer_tag = ntohs (outer_tag);
20200   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20201   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20202   mp->b_vlanid = ntohs (vlanid);
20203   mp->i_sid = ntohl (sid);
20204
20205   S (mp);
20206   W (ret);
20207   return ret;
20208 }
20209
20210 static int
20211 api_flow_classify_set_interface (vat_main_t * vam)
20212 {
20213   unformat_input_t *i = vam->input;
20214   vl_api_flow_classify_set_interface_t *mp;
20215   u32 sw_if_index;
20216   int sw_if_index_set;
20217   u32 ip4_table_index = ~0;
20218   u32 ip6_table_index = ~0;
20219   u8 is_add = 1;
20220   int ret;
20221
20222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20223     {
20224       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20225         sw_if_index_set = 1;
20226       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20227         sw_if_index_set = 1;
20228       else if (unformat (i, "del"))
20229         is_add = 0;
20230       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20231         ;
20232       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20233         ;
20234       else
20235         {
20236           clib_warning ("parse error '%U'", format_unformat_error, i);
20237           return -99;
20238         }
20239     }
20240
20241   if (sw_if_index_set == 0)
20242     {
20243       errmsg ("missing interface name or sw_if_index");
20244       return -99;
20245     }
20246
20247   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20248
20249   mp->sw_if_index = ntohl (sw_if_index);
20250   mp->ip4_table_index = ntohl (ip4_table_index);
20251   mp->ip6_table_index = ntohl (ip6_table_index);
20252   mp->is_add = is_add;
20253
20254   S (mp);
20255   W (ret);
20256   return ret;
20257 }
20258
20259 static int
20260 api_flow_classify_dump (vat_main_t * vam)
20261 {
20262   unformat_input_t *i = vam->input;
20263   vl_api_flow_classify_dump_t *mp;
20264   vl_api_control_ping_t *mp_ping;
20265   u8 type = FLOW_CLASSIFY_N_TABLES;
20266   int ret;
20267
20268   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20269     ;
20270   else
20271     {
20272       errmsg ("classify table type must be specified");
20273       return -99;
20274     }
20275
20276   if (!vam->json_output)
20277     {
20278       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20279     }
20280
20281   M (FLOW_CLASSIFY_DUMP, mp);
20282   mp->type = type;
20283   /* send it... */
20284   S (mp);
20285
20286   /* Use a control ping for synchronization */
20287   MPING (CONTROL_PING, mp_ping);
20288   S (mp_ping);
20289
20290   /* Wait for a reply... */
20291   W (ret);
20292   return ret;
20293 }
20294
20295 static int
20296 api_feature_enable_disable (vat_main_t * vam)
20297 {
20298   unformat_input_t *i = vam->input;
20299   vl_api_feature_enable_disable_t *mp;
20300   u8 *arc_name = 0;
20301   u8 *feature_name = 0;
20302   u32 sw_if_index = ~0;
20303   u8 enable = 1;
20304   int ret;
20305
20306   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20307     {
20308       if (unformat (i, "arc_name %s", &arc_name))
20309         ;
20310       else if (unformat (i, "feature_name %s", &feature_name))
20311         ;
20312       else
20313         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20314         ;
20315       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20316         ;
20317       else if (unformat (i, "disable"))
20318         enable = 0;
20319       else
20320         break;
20321     }
20322
20323   if (arc_name == 0)
20324     {
20325       errmsg ("missing arc name");
20326       return -99;
20327     }
20328   if (vec_len (arc_name) > 63)
20329     {
20330       errmsg ("arc name too long");
20331     }
20332
20333   if (feature_name == 0)
20334     {
20335       errmsg ("missing feature name");
20336       return -99;
20337     }
20338   if (vec_len (feature_name) > 63)
20339     {
20340       errmsg ("feature name too long");
20341     }
20342
20343   if (sw_if_index == ~0)
20344     {
20345       errmsg ("missing interface name or sw_if_index");
20346       return -99;
20347     }
20348
20349   /* Construct the API message */
20350   M (FEATURE_ENABLE_DISABLE, mp);
20351   mp->sw_if_index = ntohl (sw_if_index);
20352   mp->enable = enable;
20353   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20354   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20355   vec_free (arc_name);
20356   vec_free (feature_name);
20357
20358   S (mp);
20359   W (ret);
20360   return ret;
20361 }
20362
20363 static int
20364 api_sw_interface_tag_add_del (vat_main_t * vam)
20365 {
20366   unformat_input_t *i = vam->input;
20367   vl_api_sw_interface_tag_add_del_t *mp;
20368   u32 sw_if_index = ~0;
20369   u8 *tag = 0;
20370   u8 enable = 1;
20371   int ret;
20372
20373   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20374     {
20375       if (unformat (i, "tag %s", &tag))
20376         ;
20377       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20378         ;
20379       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20380         ;
20381       else if (unformat (i, "del"))
20382         enable = 0;
20383       else
20384         break;
20385     }
20386
20387   if (sw_if_index == ~0)
20388     {
20389       errmsg ("missing interface name or sw_if_index");
20390       return -99;
20391     }
20392
20393   if (enable && (tag == 0))
20394     {
20395       errmsg ("no tag specified");
20396       return -99;
20397     }
20398
20399   /* Construct the API message */
20400   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20401   mp->sw_if_index = ntohl (sw_if_index);
20402   mp->is_add = enable;
20403   if (enable)
20404     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20405   vec_free (tag);
20406
20407   S (mp);
20408   W (ret);
20409   return ret;
20410 }
20411
20412 static void vl_api_l2_xconnect_details_t_handler
20413   (vl_api_l2_xconnect_details_t * mp)
20414 {
20415   vat_main_t *vam = &vat_main;
20416
20417   print (vam->ofp, "%15d%15d",
20418          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20419 }
20420
20421 static void vl_api_l2_xconnect_details_t_handler_json
20422   (vl_api_l2_xconnect_details_t * mp)
20423 {
20424   vat_main_t *vam = &vat_main;
20425   vat_json_node_t *node = NULL;
20426
20427   if (VAT_JSON_ARRAY != vam->json_tree.type)
20428     {
20429       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20430       vat_json_init_array (&vam->json_tree);
20431     }
20432   node = vat_json_array_add (&vam->json_tree);
20433
20434   vat_json_init_object (node);
20435   vat_json_object_add_uint (node, "rx_sw_if_index",
20436                             ntohl (mp->rx_sw_if_index));
20437   vat_json_object_add_uint (node, "tx_sw_if_index",
20438                             ntohl (mp->tx_sw_if_index));
20439 }
20440
20441 static int
20442 api_l2_xconnect_dump (vat_main_t * vam)
20443 {
20444   vl_api_l2_xconnect_dump_t *mp;
20445   vl_api_control_ping_t *mp_ping;
20446   int ret;
20447
20448   if (!vam->json_output)
20449     {
20450       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20451     }
20452
20453   M (L2_XCONNECT_DUMP, mp);
20454
20455   S (mp);
20456
20457   /* Use a control ping for synchronization */
20458   MPING (CONTROL_PING, mp_ping);
20459   S (mp_ping);
20460
20461   W (ret);
20462   return ret;
20463 }
20464
20465 static int
20466 api_sw_interface_set_mtu (vat_main_t * vam)
20467 {
20468   unformat_input_t *i = vam->input;
20469   vl_api_sw_interface_set_mtu_t *mp;
20470   u32 sw_if_index = ~0;
20471   u32 mtu = 0;
20472   int ret;
20473
20474   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20475     {
20476       if (unformat (i, "mtu %d", &mtu))
20477         ;
20478       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20479         ;
20480       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20481         ;
20482       else
20483         break;
20484     }
20485
20486   if (sw_if_index == ~0)
20487     {
20488       errmsg ("missing interface name or sw_if_index");
20489       return -99;
20490     }
20491
20492   if (mtu == 0)
20493     {
20494       errmsg ("no mtu specified");
20495       return -99;
20496     }
20497
20498   /* Construct the API message */
20499   M (SW_INTERFACE_SET_MTU, mp);
20500   mp->sw_if_index = ntohl (sw_if_index);
20501   mp->mtu = ntohs ((u16) mtu);
20502
20503   S (mp);
20504   W (ret);
20505   return ret;
20506 }
20507
20508 static int
20509 api_p2p_ethernet_add (vat_main_t * vam)
20510 {
20511   unformat_input_t *i = vam->input;
20512   vl_api_p2p_ethernet_add_t *mp;
20513   u32 parent_if_index = ~0;
20514   u32 sub_id = ~0;
20515   u8 remote_mac[6];
20516   u8 mac_set = 0;
20517   int ret;
20518
20519   memset (remote_mac, 0, sizeof (remote_mac));
20520   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20521     {
20522       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20523         ;
20524       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20525         ;
20526       else
20527         if (unformat
20528             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20529         mac_set++;
20530       else if (unformat (i, "sub_id %d", &sub_id))
20531         ;
20532       else
20533         {
20534           clib_warning ("parse error '%U'", format_unformat_error, i);
20535           return -99;
20536         }
20537     }
20538
20539   if (parent_if_index == ~0)
20540     {
20541       errmsg ("missing interface name or sw_if_index");
20542       return -99;
20543     }
20544   if (mac_set == 0)
20545     {
20546       errmsg ("missing remote mac address");
20547       return -99;
20548     }
20549   if (sub_id == ~0)
20550     {
20551       errmsg ("missing sub-interface id");
20552       return -99;
20553     }
20554
20555   M (P2P_ETHERNET_ADD, mp);
20556   mp->parent_if_index = ntohl (parent_if_index);
20557   mp->subif_id = ntohl (sub_id);
20558   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20559
20560   S (mp);
20561   W (ret);
20562   return ret;
20563 }
20564
20565 static int
20566 api_p2p_ethernet_del (vat_main_t * vam)
20567 {
20568   unformat_input_t *i = vam->input;
20569   vl_api_p2p_ethernet_del_t *mp;
20570   u32 parent_if_index = ~0;
20571   u8 remote_mac[6];
20572   u8 mac_set = 0;
20573   int ret;
20574
20575   memset (remote_mac, 0, sizeof (remote_mac));
20576   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20577     {
20578       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20579         ;
20580       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20581         ;
20582       else
20583         if (unformat
20584             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20585         mac_set++;
20586       else
20587         {
20588           clib_warning ("parse error '%U'", format_unformat_error, i);
20589           return -99;
20590         }
20591     }
20592
20593   if (parent_if_index == ~0)
20594     {
20595       errmsg ("missing interface name or sw_if_index");
20596       return -99;
20597     }
20598   if (mac_set == 0)
20599     {
20600       errmsg ("missing remote mac address");
20601       return -99;
20602     }
20603
20604   M (P2P_ETHERNET_DEL, mp);
20605   mp->parent_if_index = ntohl (parent_if_index);
20606   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20607
20608   S (mp);
20609   W (ret);
20610   return ret;
20611 }
20612
20613 static int
20614 api_lldp_config (vat_main_t * vam)
20615 {
20616   unformat_input_t *i = vam->input;
20617   vl_api_lldp_config_t *mp;
20618   int tx_hold = 0;
20619   int tx_interval = 0;
20620   u8 *sys_name = NULL;
20621   int ret;
20622
20623   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20624     {
20625       if (unformat (i, "system-name %s", &sys_name))
20626         ;
20627       else if (unformat (i, "tx-hold %d", &tx_hold))
20628         ;
20629       else if (unformat (i, "tx-interval %d", &tx_interval))
20630         ;
20631       else
20632         {
20633           clib_warning ("parse error '%U'", format_unformat_error, i);
20634           return -99;
20635         }
20636     }
20637
20638   vec_add1 (sys_name, 0);
20639
20640   M (LLDP_CONFIG, mp);
20641   mp->tx_hold = htonl (tx_hold);
20642   mp->tx_interval = htonl (tx_interval);
20643   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20644   vec_free (sys_name);
20645
20646   S (mp);
20647   W (ret);
20648   return ret;
20649 }
20650
20651 static int
20652 api_sw_interface_set_lldp (vat_main_t * vam)
20653 {
20654   unformat_input_t *i = vam->input;
20655   vl_api_sw_interface_set_lldp_t *mp;
20656   u32 sw_if_index = ~0;
20657   u32 enable = 1;
20658   u8 *port_desc = NULL, *mgmt_oid = NULL;
20659   ip4_address_t ip4_addr;
20660   ip6_address_t ip6_addr;
20661   int ret;
20662
20663   memset (&ip4_addr, 0, sizeof (ip4_addr));
20664   memset (&ip6_addr, 0, sizeof (ip6_addr));
20665
20666   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20667     {
20668       if (unformat (i, "disable"))
20669         enable = 0;
20670       else
20671         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20672         ;
20673       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20674         ;
20675       else if (unformat (i, "port-desc %s", &port_desc))
20676         ;
20677       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20678         ;
20679       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20680         ;
20681       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20682         ;
20683       else
20684         break;
20685     }
20686
20687   if (sw_if_index == ~0)
20688     {
20689       errmsg ("missing interface name or sw_if_index");
20690       return -99;
20691     }
20692
20693   /* Construct the API message */
20694   vec_add1 (port_desc, 0);
20695   vec_add1 (mgmt_oid, 0);
20696   M (SW_INTERFACE_SET_LLDP, mp);
20697   mp->sw_if_index = ntohl (sw_if_index);
20698   mp->enable = enable;
20699   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20700   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20701   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20702   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20703   vec_free (port_desc);
20704   vec_free (mgmt_oid);
20705
20706   S (mp);
20707   W (ret);
20708   return ret;
20709 }
20710
20711 static int
20712 api_tcp_configure_src_addresses (vat_main_t * vam)
20713 {
20714   vl_api_tcp_configure_src_addresses_t *mp;
20715   unformat_input_t *i = vam->input;
20716   ip4_address_t v4first, v4last;
20717   ip6_address_t v6first, v6last;
20718   u8 range_set = 0;
20719   u32 vrf_id = 0;
20720   int ret;
20721
20722   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20723     {
20724       if (unformat (i, "%U - %U",
20725                     unformat_ip4_address, &v4first,
20726                     unformat_ip4_address, &v4last))
20727         {
20728           if (range_set)
20729             {
20730               errmsg ("one range per message (range already set)");
20731               return -99;
20732             }
20733           range_set = 1;
20734         }
20735       else if (unformat (i, "%U - %U",
20736                          unformat_ip6_address, &v6first,
20737                          unformat_ip6_address, &v6last))
20738         {
20739           if (range_set)
20740             {
20741               errmsg ("one range per message (range already set)");
20742               return -99;
20743             }
20744           range_set = 2;
20745         }
20746       else if (unformat (i, "vrf %d", &vrf_id))
20747         ;
20748       else
20749         break;
20750     }
20751
20752   if (range_set == 0)
20753     {
20754       errmsg ("address range not set");
20755       return -99;
20756     }
20757
20758   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20759   mp->vrf_id = ntohl (vrf_id);
20760   /* ipv6? */
20761   if (range_set == 2)
20762     {
20763       mp->is_ipv6 = 1;
20764       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20765       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20766     }
20767   else
20768     {
20769       mp->is_ipv6 = 0;
20770       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20771       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20772     }
20773   S (mp);
20774   W (ret);
20775   return ret;
20776 }
20777
20778 static int
20779 api_app_namespace_add_del (vat_main_t * vam)
20780 {
20781   vl_api_app_namespace_add_del_t *mp;
20782   unformat_input_t *i = vam->input;
20783   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
20784   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
20785   u64 secret;
20786   int ret;
20787
20788   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20789     {
20790       if (unformat (i, "id %_%v%_", &ns_id))
20791         ;
20792       else if (unformat (i, "secret %lu", &secret))
20793         secret_set = 1;
20794       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20795         sw_if_index_set = 1;
20796       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
20797         ;
20798       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
20799         ;
20800       else
20801         break;
20802     }
20803   if (!ns_id || !secret_set || !sw_if_index_set)
20804     {
20805       errmsg ("namespace id, secret and sw_if_index must be set");
20806       return -99;
20807     }
20808   if (vec_len (ns_id) > 64)
20809     {
20810       errmsg ("namespace id too long");
20811       return -99;
20812     }
20813   M (APP_NAMESPACE_ADD_DEL, mp);
20814
20815   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
20816   mp->namespace_id_len = vec_len (ns_id);
20817   mp->secret = secret;
20818   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20819   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
20820   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
20821   vec_free (ns_id);
20822   S (mp);
20823   W (ret);
20824   return ret;
20825 }
20826
20827 static int
20828 api_memfd_segment_create (vat_main_t * vam)
20829 {
20830   unformat_input_t *i = vam->input;
20831   vl_api_memfd_segment_create_t *mp;
20832   u64 size = 64 << 20;
20833   int ret;
20834
20835 #if VPP_API_TEST_BUILTIN == 1
20836   errmsg ("memfd_segment_create (builtin) not supported");
20837   return -99;
20838 #endif
20839
20840   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20841     {
20842       if (unformat (i, "size %U", unformat_memory_size, &size))
20843         ;
20844       else
20845         break;
20846     }
20847
20848   M (MEMFD_SEGMENT_CREATE, mp);
20849   mp->requested_size = size;
20850   S (mp);
20851   W (ret);
20852   return ret;
20853 }
20854
20855 static int
20856 api_dns_enable_disable (vat_main_t * vam)
20857 {
20858   unformat_input_t *line_input = vam->input;
20859   vl_api_dns_enable_disable_t *mp;
20860   u8 enable_disable = 1;
20861   int ret;
20862
20863   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20864     {
20865       if (unformat (line_input, "disable"))
20866         enable_disable = 0;
20867       if (unformat (line_input, "enable"))
20868         enable_disable = 1;
20869       else
20870         break;
20871     }
20872
20873   /* Construct the API message */
20874   M (DNS_ENABLE_DISABLE, mp);
20875   mp->enable = enable_disable;
20876
20877   /* send it... */
20878   S (mp);
20879   /* Wait for the reply */
20880   W (ret);
20881   return ret;
20882 }
20883
20884 static int
20885 api_dns_resolve_name (vat_main_t * vam)
20886 {
20887   unformat_input_t *line_input = vam->input;
20888   vl_api_dns_resolve_name_t *mp;
20889   u8 *name = 0;
20890   int ret;
20891
20892   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20893     {
20894       if (unformat (line_input, "%s", &name))
20895         ;
20896       else
20897         break;
20898     }
20899
20900   if (vec_len (name) > 127)
20901     {
20902       errmsg ("name too long");
20903       return -99;
20904     }
20905
20906   /* Construct the API message */
20907   M (DNS_RESOLVE_NAME, mp);
20908   memcpy (mp->name, name, vec_len (name));
20909   vec_free (name);
20910
20911   /* send it... */
20912   S (mp);
20913   /* Wait for the reply */
20914   W (ret);
20915   return ret;
20916 }
20917
20918 static int
20919 api_dns_name_server_add_del (vat_main_t * vam)
20920 {
20921   unformat_input_t *i = vam->input;
20922   vl_api_dns_name_server_add_del_t *mp;
20923   u8 is_add = 1;
20924   ip6_address_t ip6_server;
20925   ip4_address_t ip4_server;
20926   int ip6_set = 0;
20927   int ip4_set = 0;
20928   int ret = 0;
20929
20930   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20931     {
20932       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
20933         ip6_set = 1;
20934       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
20935         ip4_set = 1;
20936       else if (unformat (i, "del"))
20937         is_add = 0;
20938       else
20939         {
20940           clib_warning ("parse error '%U'", format_unformat_error, i);
20941           return -99;
20942         }
20943     }
20944
20945   if (ip4_set && ip6_set)
20946     {
20947       errmsg ("Only one server address allowed per message");
20948       return -99;
20949     }
20950   if ((ip4_set + ip6_set) == 0)
20951     {
20952       errmsg ("Server address required");
20953       return -99;
20954     }
20955
20956   /* Construct the API message */
20957   M (DNS_NAME_SERVER_ADD_DEL, mp);
20958
20959   if (ip6_set)
20960     {
20961       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
20962       mp->is_ip6 = 1;
20963     }
20964   else
20965     {
20966       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
20967       mp->is_ip6 = 0;
20968     }
20969
20970   mp->is_add = is_add;
20971
20972   /* send it... */
20973   S (mp);
20974
20975   /* Wait for a reply, return good/bad news  */
20976   W (ret);
20977   return ret;
20978 }
20979
20980
20981 static int
20982 q_or_quit (vat_main_t * vam)
20983 {
20984 #if VPP_API_TEST_BUILTIN == 0
20985   longjmp (vam->jump_buf, 1);
20986 #endif
20987   return 0;                     /* not so much */
20988 }
20989
20990 static int
20991 q (vat_main_t * vam)
20992 {
20993   return q_or_quit (vam);
20994 }
20995
20996 static int
20997 quit (vat_main_t * vam)
20998 {
20999   return q_or_quit (vam);
21000 }
21001
21002 static int
21003 comment (vat_main_t * vam)
21004 {
21005   return 0;
21006 }
21007
21008 static int
21009 cmd_cmp (void *a1, void *a2)
21010 {
21011   u8 **c1 = a1;
21012   u8 **c2 = a2;
21013
21014   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21015 }
21016
21017 static int
21018 help (vat_main_t * vam)
21019 {
21020   u8 **cmds = 0;
21021   u8 *name = 0;
21022   hash_pair_t *p;
21023   unformat_input_t *i = vam->input;
21024   int j;
21025
21026   if (unformat (i, "%s", &name))
21027     {
21028       uword *hs;
21029
21030       vec_add1 (name, 0);
21031
21032       hs = hash_get_mem (vam->help_by_name, name);
21033       if (hs)
21034         print (vam->ofp, "usage: %s %s", name, hs[0]);
21035       else
21036         print (vam->ofp, "No such msg / command '%s'", name);
21037       vec_free (name);
21038       return 0;
21039     }
21040
21041   print (vam->ofp, "Help is available for the following:");
21042
21043     /* *INDENT-OFF* */
21044     hash_foreach_pair (p, vam->function_by_name,
21045     ({
21046       vec_add1 (cmds, (u8 *)(p->key));
21047     }));
21048     /* *INDENT-ON* */
21049
21050   vec_sort_with_function (cmds, cmd_cmp);
21051
21052   for (j = 0; j < vec_len (cmds); j++)
21053     print (vam->ofp, "%s", cmds[j]);
21054
21055   vec_free (cmds);
21056   return 0;
21057 }
21058
21059 static int
21060 set (vat_main_t * vam)
21061 {
21062   u8 *name = 0, *value = 0;
21063   unformat_input_t *i = vam->input;
21064
21065   if (unformat (i, "%s", &name))
21066     {
21067       /* The input buffer is a vector, not a string. */
21068       value = vec_dup (i->buffer);
21069       vec_delete (value, i->index, 0);
21070       /* Almost certainly has a trailing newline */
21071       if (value[vec_len (value) - 1] == '\n')
21072         value[vec_len (value) - 1] = 0;
21073       /* Make sure it's a proper string, one way or the other */
21074       vec_add1 (value, 0);
21075       (void) clib_macro_set_value (&vam->macro_main,
21076                                    (char *) name, (char *) value);
21077     }
21078   else
21079     errmsg ("usage: set <name> <value>");
21080
21081   vec_free (name);
21082   vec_free (value);
21083   return 0;
21084 }
21085
21086 static int
21087 unset (vat_main_t * vam)
21088 {
21089   u8 *name = 0;
21090
21091   if (unformat (vam->input, "%s", &name))
21092     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21093       errmsg ("unset: %s wasn't set", name);
21094   vec_free (name);
21095   return 0;
21096 }
21097
21098 typedef struct
21099 {
21100   u8 *name;
21101   u8 *value;
21102 } macro_sort_t;
21103
21104
21105 static int
21106 macro_sort_cmp (void *a1, void *a2)
21107 {
21108   macro_sort_t *s1 = a1;
21109   macro_sort_t *s2 = a2;
21110
21111   return strcmp ((char *) (s1->name), (char *) (s2->name));
21112 }
21113
21114 static int
21115 dump_macro_table (vat_main_t * vam)
21116 {
21117   macro_sort_t *sort_me = 0, *sm;
21118   int i;
21119   hash_pair_t *p;
21120
21121     /* *INDENT-OFF* */
21122     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21123     ({
21124       vec_add2 (sort_me, sm, 1);
21125       sm->name = (u8 *)(p->key);
21126       sm->value = (u8 *) (p->value[0]);
21127     }));
21128     /* *INDENT-ON* */
21129
21130   vec_sort_with_function (sort_me, macro_sort_cmp);
21131
21132   if (vec_len (sort_me))
21133     print (vam->ofp, "%-15s%s", "Name", "Value");
21134   else
21135     print (vam->ofp, "The macro table is empty...");
21136
21137   for (i = 0; i < vec_len (sort_me); i++)
21138     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21139   return 0;
21140 }
21141
21142 static int
21143 dump_node_table (vat_main_t * vam)
21144 {
21145   int i, j;
21146   vlib_node_t *node, *next_node;
21147
21148   if (vec_len (vam->graph_nodes) == 0)
21149     {
21150       print (vam->ofp, "Node table empty, issue get_node_graph...");
21151       return 0;
21152     }
21153
21154   for (i = 0; i < vec_len (vam->graph_nodes); i++)
21155     {
21156       node = vam->graph_nodes[i];
21157       print (vam->ofp, "[%d] %s", i, node->name);
21158       for (j = 0; j < vec_len (node->next_nodes); j++)
21159         {
21160           if (node->next_nodes[j] != ~0)
21161             {
21162               next_node = vam->graph_nodes[node->next_nodes[j]];
21163               print (vam->ofp, "  [%d] %s", j, next_node->name);
21164             }
21165         }
21166     }
21167   return 0;
21168 }
21169
21170 static int
21171 value_sort_cmp (void *a1, void *a2)
21172 {
21173   name_sort_t *n1 = a1;
21174   name_sort_t *n2 = a2;
21175
21176   if (n1->value < n2->value)
21177     return -1;
21178   if (n1->value > n2->value)
21179     return 1;
21180   return 0;
21181 }
21182
21183
21184 static int
21185 dump_msg_api_table (vat_main_t * vam)
21186 {
21187   api_main_t *am = &api_main;
21188   name_sort_t *nses = 0, *ns;
21189   hash_pair_t *hp;
21190   int i;
21191
21192   /* *INDENT-OFF* */
21193   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21194   ({
21195     vec_add2 (nses, ns, 1);
21196     ns->name = (u8 *)(hp->key);
21197     ns->value = (u32) hp->value[0];
21198   }));
21199   /* *INDENT-ON* */
21200
21201   vec_sort_with_function (nses, value_sort_cmp);
21202
21203   for (i = 0; i < vec_len (nses); i++)
21204     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21205   vec_free (nses);
21206   return 0;
21207 }
21208
21209 static int
21210 get_msg_id (vat_main_t * vam)
21211 {
21212   u8 *name_and_crc;
21213   u32 message_index;
21214
21215   if (unformat (vam->input, "%s", &name_and_crc))
21216     {
21217       message_index = vl_api_get_msg_index (name_and_crc);
21218       if (message_index == ~0)
21219         {
21220           print (vam->ofp, " '%s' not found", name_and_crc);
21221           return 0;
21222         }
21223       print (vam->ofp, " '%s' has message index %d",
21224              name_and_crc, message_index);
21225       return 0;
21226     }
21227   errmsg ("name_and_crc required...");
21228   return 0;
21229 }
21230
21231 static int
21232 search_node_table (vat_main_t * vam)
21233 {
21234   unformat_input_t *line_input = vam->input;
21235   u8 *node_to_find;
21236   int j;
21237   vlib_node_t *node, *next_node;
21238   uword *p;
21239
21240   if (vam->graph_node_index_by_name == 0)
21241     {
21242       print (vam->ofp, "Node table empty, issue get_node_graph...");
21243       return 0;
21244     }
21245
21246   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21247     {
21248       if (unformat (line_input, "%s", &node_to_find))
21249         {
21250           vec_add1 (node_to_find, 0);
21251           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21252           if (p == 0)
21253             {
21254               print (vam->ofp, "%s not found...", node_to_find);
21255               goto out;
21256             }
21257           node = vam->graph_nodes[p[0]];
21258           print (vam->ofp, "[%d] %s", p[0], node->name);
21259           for (j = 0; j < vec_len (node->next_nodes); j++)
21260             {
21261               if (node->next_nodes[j] != ~0)
21262                 {
21263                   next_node = vam->graph_nodes[node->next_nodes[j]];
21264                   print (vam->ofp, "  [%d] %s", j, next_node->name);
21265                 }
21266             }
21267         }
21268
21269       else
21270         {
21271           clib_warning ("parse error '%U'", format_unformat_error,
21272                         line_input);
21273           return -99;
21274         }
21275
21276     out:
21277       vec_free (node_to_find);
21278
21279     }
21280
21281   return 0;
21282 }
21283
21284
21285 static int
21286 script (vat_main_t * vam)
21287 {
21288 #if (VPP_API_TEST_BUILTIN==0)
21289   u8 *s = 0;
21290   char *save_current_file;
21291   unformat_input_t save_input;
21292   jmp_buf save_jump_buf;
21293   u32 save_line_number;
21294
21295   FILE *new_fp, *save_ifp;
21296
21297   if (unformat (vam->input, "%s", &s))
21298     {
21299       new_fp = fopen ((char *) s, "r");
21300       if (new_fp == 0)
21301         {
21302           errmsg ("Couldn't open script file %s", s);
21303           vec_free (s);
21304           return -99;
21305         }
21306     }
21307   else
21308     {
21309       errmsg ("Missing script name");
21310       return -99;
21311     }
21312
21313   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
21314   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
21315   save_ifp = vam->ifp;
21316   save_line_number = vam->input_line_number;
21317   save_current_file = (char *) vam->current_file;
21318
21319   vam->input_line_number = 0;
21320   vam->ifp = new_fp;
21321   vam->current_file = s;
21322   do_one_file (vam);
21323
21324   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
21325   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
21326   vam->ifp = save_ifp;
21327   vam->input_line_number = save_line_number;
21328   vam->current_file = (u8 *) save_current_file;
21329   vec_free (s);
21330
21331   return 0;
21332 #else
21333   clib_warning ("use the exec command...");
21334   return -99;
21335 #endif
21336 }
21337
21338 static int
21339 echo (vat_main_t * vam)
21340 {
21341   print (vam->ofp, "%v", vam->input->buffer);
21342   return 0;
21343 }
21344
21345 /* List of API message constructors, CLI names map to api_xxx */
21346 #define foreach_vpe_api_msg                                             \
21347 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
21348 _(sw_interface_dump,"")                                                 \
21349 _(sw_interface_set_flags,                                               \
21350   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
21351 _(sw_interface_add_del_address,                                         \
21352   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
21353 _(sw_interface_set_table,                                               \
21354   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
21355 _(sw_interface_set_mpls_enable,                                         \
21356   "<intfc> | sw_if_index [disable | dis]")                              \
21357 _(sw_interface_set_vpath,                                               \
21358   "<intfc> | sw_if_index <id> enable | disable")                        \
21359 _(sw_interface_set_vxlan_bypass,                                        \
21360   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21361 _(sw_interface_set_geneve_bypass,                                       \
21362   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21363 _(sw_interface_set_l2_xconnect,                                         \
21364   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21365   "enable | disable")                                                   \
21366 _(sw_interface_set_l2_bridge,                                           \
21367   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
21368   "[shg <split-horizon-group>] [bvi]\n"                                 \
21369   "enable | disable")                                                   \
21370 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
21371 _(bridge_domain_add_del,                                                \
21372   "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") \
21373 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
21374 _(l2fib_add_del,                                                        \
21375   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
21376 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
21377 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
21378 _(l2_flags,                                                             \
21379   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21380 _(bridge_flags,                                                         \
21381   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21382 _(tap_connect,                                                          \
21383   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
21384 _(tap_modify,                                                           \
21385   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
21386 _(tap_delete,                                                           \
21387   "<vpp-if-name> | sw_if_index <id>")                                   \
21388 _(sw_interface_tap_dump, "")                                            \
21389 _(ip_table_add_del,                                                     \
21390   "table-id <n> [ipv6]\n")                                              \
21391 _(ip_add_del_route,                                                     \
21392   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
21393   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
21394   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
21395   "[multipath] [count <n>]")                                            \
21396 _(ip_mroute_add_del,                                                    \
21397   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
21398   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
21399 _(mpls_table_add_del,                                                   \
21400   "table-id <n>\n")                                                     \
21401 _(mpls_route_add_del,                                                   \
21402   "<label> <eos> via <addr> [table-id <n>]\n"                           \
21403   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
21404   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
21405   "[multipath] [count <n>]")                                            \
21406 _(mpls_ip_bind_unbind,                                                  \
21407   "<label> <addr/len>")                                                 \
21408 _(mpls_tunnel_add_del,                                                  \
21409   " via <addr> [table-id <n>]\n"                                        \
21410   "sw_if_index <id>] [l2]  [del]")                                      \
21411 _(proxy_arp_add_del,                                                    \
21412   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
21413 _(proxy_arp_intfc_enable_disable,                                       \
21414   "<intfc> | sw_if_index <id> enable | disable")                        \
21415 _(sw_interface_set_unnumbered,                                          \
21416   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
21417 _(ip_neighbor_add_del,                                                  \
21418   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
21419   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
21420 _(reset_vrf, "vrf <id> [ipv6]")                                         \
21421 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
21422 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
21423   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
21424   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
21425   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
21426 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
21427 _(reset_fib, "vrf <n> [ipv6]")                                          \
21428 _(dhcp_proxy_config,                                                    \
21429   "svr <v46-address> src <v46-address>\n"                               \
21430    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
21431 _(dhcp_proxy_set_vss,                                                   \
21432   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
21433 _(dhcp_proxy_dump, "ip6")                                               \
21434 _(dhcp_client_config,                                                   \
21435   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
21436 _(set_ip_flow_hash,                                                     \
21437   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
21438 _(sw_interface_ip6_enable_disable,                                      \
21439   "<intfc> | sw_if_index <id> enable | disable")                        \
21440 _(sw_interface_ip6_set_link_local_address,                              \
21441   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
21442 _(ip6nd_proxy_add_del,                                                  \
21443   "<intfc> | sw_if_index <id> <ip6-address>")                           \
21444 _(ip6nd_proxy_dump, "")                                                 \
21445 _(sw_interface_ip6nd_ra_prefix,                                         \
21446   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
21447   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
21448   "[nolink] [isno]")                                                    \
21449 _(sw_interface_ip6nd_ra_config,                                         \
21450   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
21451   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
21452   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
21453 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
21454 _(l2_patch_add_del,                                                     \
21455   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21456   "enable | disable")                                                   \
21457 _(sr_localsid_add_del,                                                  \
21458   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
21459   "fib-table <num> (end.psp) sw_if_index <num>")                        \
21460 _(classify_add_del_table,                                               \
21461   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
21462   " [del] [del-chain] mask <mask-value>\n"                              \
21463   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
21464   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
21465 _(classify_add_del_session,                                             \
21466   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
21467   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
21468   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
21469   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
21470 _(classify_set_interface_ip_table,                                      \
21471   "<intfc> | sw_if_index <nn> table <nn>")                              \
21472 _(classify_set_interface_l2_tables,                                     \
21473   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21474   "  [other-table <nn>]")                                               \
21475 _(get_node_index, "node <node-name")                                    \
21476 _(add_node_next, "node <node-name> next <next-node-name>")              \
21477 _(l2tpv3_create_tunnel,                                                 \
21478   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
21479   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
21480   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
21481 _(l2tpv3_set_tunnel_cookies,                                            \
21482   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
21483   "[new_remote_cookie <nn>]\n")                                         \
21484 _(l2tpv3_interface_enable_disable,                                      \
21485   "<intfc> | sw_if_index <nn> enable | disable")                        \
21486 _(l2tpv3_set_lookup_key,                                                \
21487   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
21488 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
21489 _(vxlan_add_del_tunnel,                                                 \
21490   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21491   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21492   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21493 _(geneve_add_del_tunnel,                                                \
21494   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21495   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21496   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21497 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
21498 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
21499 _(gre_add_del_tunnel,                                                   \
21500   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
21501 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
21502 _(l2_fib_clear_table, "")                                               \
21503 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
21504 _(l2_interface_vlan_tag_rewrite,                                        \
21505   "<intfc> | sw_if_index <nn> \n"                                       \
21506   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
21507   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
21508 _(create_vhost_user_if,                                                 \
21509         "socket <filename> [server] [renumber <dev_instance>] "         \
21510         "[mac <mac_address>]")                                          \
21511 _(modify_vhost_user_if,                                                 \
21512         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
21513         "[server] [renumber <dev_instance>]")                           \
21514 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
21515 _(sw_interface_vhost_user_dump, "")                                     \
21516 _(show_version, "")                                                     \
21517 _(vxlan_gpe_add_del_tunnel,                                             \
21518   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
21519   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21520   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
21521   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
21522 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
21523 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
21524 _(interface_name_renumber,                                              \
21525   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
21526 _(input_acl_set_interface,                                              \
21527   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21528   "  [l2-table <nn>] [del]")                                            \
21529 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
21530 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
21531 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
21532 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
21533 _(ip_dump, "ipv4 | ipv6")                                               \
21534 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
21535 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
21536   "  spid_id <n> ")                                                     \
21537 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
21538   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
21539   "  integ_alg <alg> integ_key <hex>")                                  \
21540 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
21541   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
21542   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
21543   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
21544 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
21545 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
21546   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
21547   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
21548   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
21549 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
21550 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
21551 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
21552   "(auth_data 0x<data> | auth_data <data>)")                            \
21553 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
21554   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
21555 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
21556   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
21557   "(local|remote)")                                                     \
21558 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
21559 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
21560 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
21561 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
21562 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
21563 _(ikev2_initiate_sa_init, "<profile_name>")                             \
21564 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
21565 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
21566 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
21567 _(delete_loopback,"sw_if_index <nn>")                                   \
21568 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
21569 _(map_add_domain,                                                       \
21570   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
21571   "ip6-src <ip6addr> "                                                  \
21572   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
21573 _(map_del_domain, "index <n>")                                          \
21574 _(map_add_del_rule,                                                     \
21575   "index <n> psid <n> dst <ip6addr> [del]")                             \
21576 _(map_domain_dump, "")                                                  \
21577 _(map_rule_dump, "index <map-domain>")                                  \
21578 _(want_interface_events,  "enable|disable")                             \
21579 _(want_stats,"enable|disable")                                          \
21580 _(get_first_msg_id, "client <name>")                                    \
21581 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
21582 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
21583   "fib-id <nn> [ip4][ip6][default]")                                    \
21584 _(get_node_graph, " ")                                                  \
21585 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
21586 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
21587 _(ioam_disable, "")                                                     \
21588 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
21589                             " sw_if_index <sw_if_index> p <priority> "  \
21590                             "w <weight>] [del]")                        \
21591 _(one_add_del_locator, "locator-set <locator_name> "                    \
21592                         "iface <intf> | sw_if_index <sw_if_index> "     \
21593                         "p <priority> w <weight> [del]")                \
21594 _(one_add_del_local_eid,"vni <vni> eid "                                \
21595                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21596                          "locator-set <locator_name> [del]"             \
21597                          "[key-id sha1|sha256 secret-key <secret-key>]")\
21598 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
21599 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
21600 _(one_enable_disable, "enable|disable")                                 \
21601 _(one_map_register_enable_disable, "enable|disable")                    \
21602 _(one_map_register_fallback_threshold, "<value>")                       \
21603 _(one_rloc_probe_enable_disable, "enable|disable")                      \
21604 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
21605                                "[seid <seid>] "                         \
21606                                "rloc <locator> p <prio> "               \
21607                                "w <weight> [rloc <loc> ... ] "          \
21608                                "action <action> [del-all]")             \
21609 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
21610                           "<local-eid>")                                \
21611 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
21612 _(one_use_petr, "ip-address> | disable")                                \
21613 _(one_map_request_mode, "src-dst|dst-only")                             \
21614 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
21615 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
21616 _(one_locator_set_dump, "[local | remote]")                             \
21617 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
21618 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
21619                        "[local] | [remote]")                            \
21620 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
21621 _(one_ndp_bd_get, "")                                                   \
21622 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
21623 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
21624 _(one_l2_arp_bd_get, "")                                                \
21625 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
21626 _(one_stats_enable_disable, "enable|disalbe")                           \
21627 _(show_one_stats_enable_disable, "")                                    \
21628 _(one_eid_table_vni_dump, "")                                           \
21629 _(one_eid_table_map_dump, "l2|l3")                                      \
21630 _(one_map_resolver_dump, "")                                            \
21631 _(one_map_server_dump, "")                                              \
21632 _(one_adjacencies_get, "vni <vni>")                                     \
21633 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
21634 _(show_one_rloc_probe_state, "")                                        \
21635 _(show_one_map_register_state, "")                                      \
21636 _(show_one_status, "")                                                  \
21637 _(one_stats_dump, "")                                                   \
21638 _(one_stats_flush, "")                                                  \
21639 _(one_get_map_request_itr_rlocs, "")                                    \
21640 _(one_map_register_set_ttl, "<ttl>")                                    \
21641 _(one_set_transport_protocol, "udp|api")                                \
21642 _(one_get_transport_protocol, "")                                       \
21643 _(show_one_nsh_mapping, "")                                             \
21644 _(show_one_pitr, "")                                                    \
21645 _(show_one_use_petr, "")                                                \
21646 _(show_one_map_request_mode, "")                                        \
21647 _(show_one_map_register_ttl, "")                                        \
21648 _(show_one_map_register_fallback_threshold, "")                         \
21649 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
21650                             " sw_if_index <sw_if_index> p <priority> "  \
21651                             "w <weight>] [del]")                        \
21652 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
21653                         "iface <intf> | sw_if_index <sw_if_index> "     \
21654                         "p <priority> w <weight> [del]")                \
21655 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
21656                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21657                          "locator-set <locator_name> [del]"             \
21658                          "[key-id sha1|sha256 secret-key <secret-key>]") \
21659 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
21660 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
21661 _(lisp_enable_disable, "enable|disable")                                \
21662 _(lisp_map_register_enable_disable, "enable|disable")                   \
21663 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
21664 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
21665                                "[seid <seid>] "                         \
21666                                "rloc <locator> p <prio> "               \
21667                                "w <weight> [rloc <loc> ... ] "          \
21668                                "action <action> [del-all]")             \
21669 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
21670                           "<local-eid>")                                \
21671 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
21672 _(lisp_use_petr, "<ip-address> | disable")                              \
21673 _(lisp_map_request_mode, "src-dst|dst-only")                            \
21674 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
21675 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
21676 _(lisp_locator_set_dump, "[local | remote]")                            \
21677 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
21678 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
21679                        "[local] | [remote]")                            \
21680 _(lisp_eid_table_vni_dump, "")                                          \
21681 _(lisp_eid_table_map_dump, "l2|l3")                                     \
21682 _(lisp_map_resolver_dump, "")                                           \
21683 _(lisp_map_server_dump, "")                                             \
21684 _(lisp_adjacencies_get, "vni <vni>")                                    \
21685 _(gpe_fwd_entry_vnis_get, "")                                           \
21686 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
21687 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
21688                                 "[table <table-id>]")                   \
21689 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
21690 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
21691 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
21692 _(gpe_get_encap_mode, "")                                               \
21693 _(lisp_gpe_add_del_iface, "up|down")                                    \
21694 _(lisp_gpe_enable_disable, "enable|disable")                            \
21695 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
21696   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
21697 _(show_lisp_rloc_probe_state, "")                                       \
21698 _(show_lisp_map_register_state, "")                                     \
21699 _(show_lisp_status, "")                                                 \
21700 _(lisp_get_map_request_itr_rlocs, "")                                   \
21701 _(show_lisp_pitr, "")                                                   \
21702 _(show_lisp_use_petr, "")                                               \
21703 _(show_lisp_map_request_mode, "")                                       \
21704 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
21705 _(af_packet_delete, "name <host interface name>")                       \
21706 _(policer_add_del, "name <policer name> <params> [del]")                \
21707 _(policer_dump, "[name <policer name>]")                                \
21708 _(policer_classify_set_interface,                                       \
21709   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21710   "  [l2-table <nn>] [del]")                                            \
21711 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
21712 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
21713     "[master|slave]")                                                   \
21714 _(netmap_delete, "name <interface name>")                               \
21715 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
21716 _(mpls_fib_dump, "")                                                    \
21717 _(classify_table_ids, "")                                               \
21718 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
21719 _(classify_table_info, "table_id <nn>")                                 \
21720 _(classify_session_dump, "table_id <nn>")                               \
21721 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
21722     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
21723     "[template_interval <nn>] [udp_checksum]")                          \
21724 _(ipfix_exporter_dump, "")                                              \
21725 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
21726 _(ipfix_classify_stream_dump, "")                                       \
21727 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
21728 _(ipfix_classify_table_dump, "")                                        \
21729 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
21730 _(sw_interface_span_dump, "[l2]")                                           \
21731 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
21732 _(pg_create_interface, "if_id <nn>")                                    \
21733 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
21734 _(pg_enable_disable, "[stream <id>] disable")                           \
21735 _(ip_source_and_port_range_check_add_del,                               \
21736   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
21737 _(ip_source_and_port_range_check_interface_add_del,                     \
21738   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
21739   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
21740 _(ipsec_gre_add_del_tunnel,                                             \
21741   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
21742 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
21743 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
21744 _(l2_interface_pbb_tag_rewrite,                                         \
21745   "<intfc> | sw_if_index <nn> \n"                                       \
21746   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
21747   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
21748 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
21749 _(flow_classify_set_interface,                                          \
21750   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
21751 _(flow_classify_dump, "type [ip4|ip6]")                                 \
21752 _(ip_fib_dump, "")                                                      \
21753 _(ip_mfib_dump, "")                                                     \
21754 _(ip6_fib_dump, "")                                                     \
21755 _(ip6_mfib_dump, "")                                                    \
21756 _(feature_enable_disable, "arc_name <arc_name> "                        \
21757   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
21758 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
21759 "[disable]")                                                            \
21760 _(l2_xconnect_dump, "")                                                 \
21761 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
21762 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
21763 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
21764 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
21765 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
21766 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
21767 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
21768   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
21769 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
21770 _(memfd_segment_create,"size <nnn>")                                    \
21771 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
21772 _(dns_enable_disable, "[enable][disable]")                              \
21773 _(dns_name_server_add_del, "<ip-address> [del]")                        \
21774 _(dns_resolve_name, "<hostname>")
21775
21776 /* List of command functions, CLI names map directly to functions */
21777 #define foreach_cli_function                                    \
21778 _(comment, "usage: comment <ignore-rest-of-line>")              \
21779 _(dump_interface_table, "usage: dump_interface_table")          \
21780 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21781 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21782 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21783 _(dump_stats_table, "usage: dump_stats_table")                  \
21784 _(dump_macro_table, "usage: dump_macro_table ")                 \
21785 _(dump_node_table, "usage: dump_node_table")                    \
21786 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21787 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21788 _(echo, "usage: echo <message>")                                \
21789 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21790 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21791 _(help, "usage: help")                                          \
21792 _(q, "usage: quit")                                             \
21793 _(quit, "usage: quit")                                          \
21794 _(search_node_table, "usage: search_node_table <name>...")      \
21795 _(set, "usage: set <variable-name> <value>")                    \
21796 _(script, "usage: script <file-name>")                          \
21797 _(unset, "usage: unset <variable-name>")
21798 #define _(N,n)                                  \
21799     static void vl_api_##n##_t_handler_uni      \
21800     (vl_api_##n##_t * mp)                       \
21801     {                                           \
21802         vat_main_t * vam = &vat_main;           \
21803         if (vam->json_output) {                 \
21804             vl_api_##n##_t_handler_json(mp);    \
21805         } else {                                \
21806             vl_api_##n##_t_handler(mp);         \
21807         }                                       \
21808     }
21809 foreach_vpe_api_reply_msg;
21810 #if VPP_API_TEST_BUILTIN == 0
21811 foreach_standalone_reply_msg;
21812 #endif
21813 #undef _
21814
21815 void
21816 vat_api_hookup (vat_main_t * vam)
21817 {
21818 #define _(N,n)                                                  \
21819     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21820                            vl_api_##n##_t_handler_uni,          \
21821                            vl_noop_handler,                     \
21822                            vl_api_##n##_t_endian,               \
21823                            vl_api_##n##_t_print,                \
21824                            sizeof(vl_api_##n##_t), 1);
21825   foreach_vpe_api_reply_msg;
21826 #if VPP_API_TEST_BUILTIN == 0
21827   foreach_standalone_reply_msg;
21828 #endif
21829 #undef _
21830
21831 #if (VPP_API_TEST_BUILTIN==0)
21832   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
21833
21834   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
21835
21836   vam->function_by_name = hash_create_string (0, sizeof (uword));
21837
21838   vam->help_by_name = hash_create_string (0, sizeof (uword));
21839 #endif
21840
21841   /* API messages we can send */
21842 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
21843   foreach_vpe_api_msg;
21844 #undef _
21845
21846   /* Help strings */
21847 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21848   foreach_vpe_api_msg;
21849 #undef _
21850
21851   /* CLI functions */
21852 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
21853   foreach_cli_function;
21854 #undef _
21855
21856   /* Help strings */
21857 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21858   foreach_cli_function;
21859 #undef _
21860 }
21861
21862 #if VPP_API_TEST_BUILTIN
21863 static clib_error_t *
21864 vat_api_hookup_shim (vlib_main_t * vm)
21865 {
21866   vat_api_hookup (&vat_main);
21867   return 0;
21868 }
21869
21870 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
21871 #endif
21872
21873 /*
21874  * fd.io coding-style-patch-verification: ON
21875  *
21876  * Local Variables:
21877  * eval: (c-set-style "gnu")
21878  * End:
21879  */