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