session: add rule tags
[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 (u8 * mac)
722 {
723   u64 tmp = *((u64 *) mac);
724   tmp = clib_net_to_host_u64 (tmp);
725   tmp += 1 << 16;               /* skip unused (least significant) octets */
726   tmp = clib_host_to_net_u64 (tmp);
727
728   clib_memcpy (mac, &tmp, 6);
729 }
730
731 static void vl_api_create_loopback_reply_t_handler
732   (vl_api_create_loopback_reply_t * mp)
733 {
734   vat_main_t *vam = &vat_main;
735   i32 retval = ntohl (mp->retval);
736
737   vam->retval = retval;
738   vam->regenerate_interface_table = 1;
739   vam->sw_if_index = ntohl (mp->sw_if_index);
740   vam->result_ready = 1;
741 }
742
743 static void vl_api_create_loopback_reply_t_handler_json
744   (vl_api_create_loopback_reply_t * mp)
745 {
746   vat_main_t *vam = &vat_main;
747   vat_json_node_t node;
748
749   vat_json_init_object (&node);
750   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
751   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
752
753   vat_json_print (vam->ofp, &node);
754   vat_json_free (&node);
755   vam->retval = ntohl (mp->retval);
756   vam->result_ready = 1;
757 }
758
759 static void vl_api_create_loopback_instance_reply_t_handler
760   (vl_api_create_loopback_instance_reply_t * mp)
761 {
762   vat_main_t *vam = &vat_main;
763   i32 retval = ntohl (mp->retval);
764
765   vam->retval = retval;
766   vam->regenerate_interface_table = 1;
767   vam->sw_if_index = ntohl (mp->sw_if_index);
768   vam->result_ready = 1;
769 }
770
771 static void vl_api_create_loopback_instance_reply_t_handler_json
772   (vl_api_create_loopback_instance_reply_t * mp)
773 {
774   vat_main_t *vam = &vat_main;
775   vat_json_node_t node;
776
777   vat_json_init_object (&node);
778   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
779   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
780
781   vat_json_print (vam->ofp, &node);
782   vat_json_free (&node);
783   vam->retval = ntohl (mp->retval);
784   vam->result_ready = 1;
785 }
786
787 static void vl_api_af_packet_create_reply_t_handler
788   (vl_api_af_packet_create_reply_t * mp)
789 {
790   vat_main_t *vam = &vat_main;
791   i32 retval = ntohl (mp->retval);
792
793   vam->retval = retval;
794   vam->regenerate_interface_table = 1;
795   vam->sw_if_index = ntohl (mp->sw_if_index);
796   vam->result_ready = 1;
797 }
798
799 static void vl_api_af_packet_create_reply_t_handler_json
800   (vl_api_af_packet_create_reply_t * mp)
801 {
802   vat_main_t *vam = &vat_main;
803   vat_json_node_t node;
804
805   vat_json_init_object (&node);
806   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
807   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
808
809   vat_json_print (vam->ofp, &node);
810   vat_json_free (&node);
811
812   vam->retval = ntohl (mp->retval);
813   vam->result_ready = 1;
814 }
815
816 static void vl_api_create_vlan_subif_reply_t_handler
817   (vl_api_create_vlan_subif_reply_t * mp)
818 {
819   vat_main_t *vam = &vat_main;
820   i32 retval = ntohl (mp->retval);
821
822   vam->retval = retval;
823   vam->regenerate_interface_table = 1;
824   vam->sw_if_index = ntohl (mp->sw_if_index);
825   vam->result_ready = 1;
826 }
827
828 static void vl_api_create_vlan_subif_reply_t_handler_json
829   (vl_api_create_vlan_subif_reply_t * mp)
830 {
831   vat_main_t *vam = &vat_main;
832   vat_json_node_t node;
833
834   vat_json_init_object (&node);
835   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
836   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
837
838   vat_json_print (vam->ofp, &node);
839   vat_json_free (&node);
840
841   vam->retval = ntohl (mp->retval);
842   vam->result_ready = 1;
843 }
844
845 static void vl_api_create_subif_reply_t_handler
846   (vl_api_create_subif_reply_t * mp)
847 {
848   vat_main_t *vam = &vat_main;
849   i32 retval = ntohl (mp->retval);
850
851   vam->retval = retval;
852   vam->regenerate_interface_table = 1;
853   vam->sw_if_index = ntohl (mp->sw_if_index);
854   vam->result_ready = 1;
855 }
856
857 static void vl_api_create_subif_reply_t_handler_json
858   (vl_api_create_subif_reply_t * mp)
859 {
860   vat_main_t *vam = &vat_main;
861   vat_json_node_t node;
862
863   vat_json_init_object (&node);
864   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
865   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
866
867   vat_json_print (vam->ofp, &node);
868   vat_json_free (&node);
869
870   vam->retval = ntohl (mp->retval);
871   vam->result_ready = 1;
872 }
873
874 static void vl_api_interface_name_renumber_reply_t_handler
875   (vl_api_interface_name_renumber_reply_t * mp)
876 {
877   vat_main_t *vam = &vat_main;
878   i32 retval = ntohl (mp->retval);
879
880   vam->retval = retval;
881   vam->regenerate_interface_table = 1;
882   vam->result_ready = 1;
883 }
884
885 static void vl_api_interface_name_renumber_reply_t_handler_json
886   (vl_api_interface_name_renumber_reply_t * mp)
887 {
888   vat_main_t *vam = &vat_main;
889   vat_json_node_t node;
890
891   vat_json_init_object (&node);
892   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
893
894   vat_json_print (vam->ofp, &node);
895   vat_json_free (&node);
896
897   vam->retval = ntohl (mp->retval);
898   vam->result_ready = 1;
899 }
900
901 /*
902  * Special-case: build the interface table, maintain
903  * the next loopback sw_if_index vbl.
904  */
905 static void vl_api_sw_interface_details_t_handler
906   (vl_api_sw_interface_details_t * mp)
907 {
908   vat_main_t *vam = &vat_main;
909   u8 *s = format (0, "%s%c", mp->interface_name, 0);
910
911   hash_set_mem (vam->sw_if_index_by_interface_name, s,
912                 ntohl (mp->sw_if_index));
913
914   /* In sub interface case, fill the sub interface table entry */
915   if (mp->sw_if_index != mp->sup_sw_if_index)
916     {
917       sw_interface_subif_t *sub = NULL;
918
919       vec_add2 (vam->sw_if_subif_table, sub, 1);
920
921       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
922       strncpy ((char *) sub->interface_name, (char *) s,
923                vec_len (sub->interface_name));
924       sub->sw_if_index = ntohl (mp->sw_if_index);
925       sub->sub_id = ntohl (mp->sub_id);
926
927       sub->sub_dot1ad = mp->sub_dot1ad;
928       sub->sub_number_of_tags = mp->sub_number_of_tags;
929       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
930       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
931       sub->sub_exact_match = mp->sub_exact_match;
932       sub->sub_default = mp->sub_default;
933       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
934       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
935
936       /* vlan tag rewrite */
937       sub->vtr_op = ntohl (mp->vtr_op);
938       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
939       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
940       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
941     }
942 }
943
944 static void vl_api_sw_interface_details_t_handler_json
945   (vl_api_sw_interface_details_t * mp)
946 {
947   vat_main_t *vam = &vat_main;
948   vat_json_node_t *node = NULL;
949
950   if (VAT_JSON_ARRAY != vam->json_tree.type)
951     {
952       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
953       vat_json_init_array (&vam->json_tree);
954     }
955   node = vat_json_array_add (&vam->json_tree);
956
957   vat_json_init_object (node);
958   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
959   vat_json_object_add_uint (node, "sup_sw_if_index",
960                             ntohl (mp->sup_sw_if_index));
961   vat_json_object_add_uint (node, "l2_address_length",
962                             ntohl (mp->l2_address_length));
963   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
964                              sizeof (mp->l2_address));
965   vat_json_object_add_string_copy (node, "interface_name",
966                                    mp->interface_name);
967   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
968   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
969   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
970   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
971   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
972   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
973   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
974   vat_json_object_add_uint (node, "sub_number_of_tags",
975                             mp->sub_number_of_tags);
976   vat_json_object_add_uint (node, "sub_outer_vlan_id",
977                             ntohs (mp->sub_outer_vlan_id));
978   vat_json_object_add_uint (node, "sub_inner_vlan_id",
979                             ntohs (mp->sub_inner_vlan_id));
980   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
981   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
982   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
983                             mp->sub_outer_vlan_id_any);
984   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
985                             mp->sub_inner_vlan_id_any);
986   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
987   vat_json_object_add_uint (node, "vtr_push_dot1q",
988                             ntohl (mp->vtr_push_dot1q));
989   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
990   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
991   if (mp->sub_dot1ah)
992     {
993       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
994                                        format (0, "%U",
995                                                format_ethernet_address,
996                                                &mp->b_dmac));
997       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
998                                        format (0, "%U",
999                                                format_ethernet_address,
1000                                                &mp->b_smac));
1001       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1002       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1003     }
1004 }
1005
1006 #if VPP_API_TEST_BUILTIN == 0
1007 static void vl_api_sw_interface_event_t_handler
1008   (vl_api_sw_interface_event_t * mp)
1009 {
1010   vat_main_t *vam = &vat_main;
1011   if (vam->interface_event_display)
1012     errmsg ("interface flags: sw_if_index %d %s %s",
1013             ntohl (mp->sw_if_index),
1014             mp->admin_up_down ? "admin-up" : "admin-down",
1015             mp->link_up_down ? "link-up" : "link-down");
1016 }
1017 #endif
1018
1019 static void vl_api_sw_interface_event_t_handler_json
1020   (vl_api_sw_interface_event_t * mp)
1021 {
1022   /* JSON output not supported */
1023 }
1024
1025 static void
1026 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1027 {
1028   vat_main_t *vam = &vat_main;
1029   i32 retval = ntohl (mp->retval);
1030
1031   vam->retval = retval;
1032   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1033   vam->result_ready = 1;
1034 }
1035
1036 static void
1037 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1038 {
1039   vat_main_t *vam = &vat_main;
1040   vat_json_node_t node;
1041   api_main_t *am = &api_main;
1042   void *oldheap;
1043   u8 *reply;
1044
1045   vat_json_init_object (&node);
1046   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1047   vat_json_object_add_uint (&node, "reply_in_shmem",
1048                             ntohl (mp->reply_in_shmem));
1049   /* Toss the shared-memory original... */
1050   pthread_mutex_lock (&am->vlib_rp->mutex);
1051   oldheap = svm_push_data_heap (am->vlib_rp);
1052
1053   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1054   vec_free (reply);
1055
1056   svm_pop_heap (oldheap);
1057   pthread_mutex_unlock (&am->vlib_rp->mutex);
1058
1059   vat_json_print (vam->ofp, &node);
1060   vat_json_free (&node);
1061
1062   vam->retval = ntohl (mp->retval);
1063   vam->result_ready = 1;
1064 }
1065
1066 static void
1067 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1068 {
1069   vat_main_t *vam = &vat_main;
1070   i32 retval = ntohl (mp->retval);
1071   u32 length = ntohl (mp->length);
1072
1073   vec_reset_length (vam->cmd_reply);
1074
1075   vam->retval = retval;
1076   if (retval == 0)
1077     {
1078       vec_validate (vam->cmd_reply, length);
1079       clib_memcpy ((char *) (vam->cmd_reply), mp->reply, length);
1080       vam->cmd_reply[length] = 0;
1081     }
1082   vam->result_ready = 1;
1083 }
1084
1085 static void
1086 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1087 {
1088   vat_main_t *vam = &vat_main;
1089   vat_json_node_t node;
1090
1091   vec_reset_length (vam->cmd_reply);
1092
1093   vat_json_init_object (&node);
1094   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1095   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1096
1097   vat_json_print (vam->ofp, &node);
1098   vat_json_free (&node);
1099
1100   vam->retval = ntohl (mp->retval);
1101   vam->result_ready = 1;
1102 }
1103
1104 static void vl_api_classify_add_del_table_reply_t_handler
1105   (vl_api_classify_add_del_table_reply_t * mp)
1106 {
1107   vat_main_t *vam = &vat_main;
1108   i32 retval = ntohl (mp->retval);
1109   if (vam->async_mode)
1110     {
1111       vam->async_errors += (retval < 0);
1112     }
1113   else
1114     {
1115       vam->retval = retval;
1116       if (retval == 0 &&
1117           ((mp->new_table_index != 0xFFFFFFFF) ||
1118            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1119            (mp->match_n_vectors != 0xFFFFFFFF)))
1120         /*
1121          * Note: this is just barely thread-safe, depends on
1122          * the main thread spinning waiting for an answer...
1123          */
1124         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1125                 ntohl (mp->new_table_index),
1126                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1127       vam->result_ready = 1;
1128     }
1129 }
1130
1131 static void vl_api_classify_add_del_table_reply_t_handler_json
1132   (vl_api_classify_add_del_table_reply_t * mp)
1133 {
1134   vat_main_t *vam = &vat_main;
1135   vat_json_node_t node;
1136
1137   vat_json_init_object (&node);
1138   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1139   vat_json_object_add_uint (&node, "new_table_index",
1140                             ntohl (mp->new_table_index));
1141   vat_json_object_add_uint (&node, "skip_n_vectors",
1142                             ntohl (mp->skip_n_vectors));
1143   vat_json_object_add_uint (&node, "match_n_vectors",
1144                             ntohl (mp->match_n_vectors));
1145
1146   vat_json_print (vam->ofp, &node);
1147   vat_json_free (&node);
1148
1149   vam->retval = ntohl (mp->retval);
1150   vam->result_ready = 1;
1151 }
1152
1153 static void vl_api_get_node_index_reply_t_handler
1154   (vl_api_get_node_index_reply_t * mp)
1155 {
1156   vat_main_t *vam = &vat_main;
1157   i32 retval = ntohl (mp->retval);
1158   if (vam->async_mode)
1159     {
1160       vam->async_errors += (retval < 0);
1161     }
1162   else
1163     {
1164       vam->retval = retval;
1165       if (retval == 0)
1166         errmsg ("node index %d", ntohl (mp->node_index));
1167       vam->result_ready = 1;
1168     }
1169 }
1170
1171 static void vl_api_get_node_index_reply_t_handler_json
1172   (vl_api_get_node_index_reply_t * mp)
1173 {
1174   vat_main_t *vam = &vat_main;
1175   vat_json_node_t node;
1176
1177   vat_json_init_object (&node);
1178   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1179   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1180
1181   vat_json_print (vam->ofp, &node);
1182   vat_json_free (&node);
1183
1184   vam->retval = ntohl (mp->retval);
1185   vam->result_ready = 1;
1186 }
1187
1188 static void vl_api_get_next_index_reply_t_handler
1189   (vl_api_get_next_index_reply_t * mp)
1190 {
1191   vat_main_t *vam = &vat_main;
1192   i32 retval = ntohl (mp->retval);
1193   if (vam->async_mode)
1194     {
1195       vam->async_errors += (retval < 0);
1196     }
1197   else
1198     {
1199       vam->retval = retval;
1200       if (retval == 0)
1201         errmsg ("next node index %d", ntohl (mp->next_index));
1202       vam->result_ready = 1;
1203     }
1204 }
1205
1206 static void vl_api_get_next_index_reply_t_handler_json
1207   (vl_api_get_next_index_reply_t * mp)
1208 {
1209   vat_main_t *vam = &vat_main;
1210   vat_json_node_t node;
1211
1212   vat_json_init_object (&node);
1213   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1214   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1215
1216   vat_json_print (vam->ofp, &node);
1217   vat_json_free (&node);
1218
1219   vam->retval = ntohl (mp->retval);
1220   vam->result_ready = 1;
1221 }
1222
1223 static void vl_api_add_node_next_reply_t_handler
1224   (vl_api_add_node_next_reply_t * mp)
1225 {
1226   vat_main_t *vam = &vat_main;
1227   i32 retval = ntohl (mp->retval);
1228   if (vam->async_mode)
1229     {
1230       vam->async_errors += (retval < 0);
1231     }
1232   else
1233     {
1234       vam->retval = retval;
1235       if (retval == 0)
1236         errmsg ("next index %d", ntohl (mp->next_index));
1237       vam->result_ready = 1;
1238     }
1239 }
1240
1241 static void vl_api_add_node_next_reply_t_handler_json
1242   (vl_api_add_node_next_reply_t * mp)
1243 {
1244   vat_main_t *vam = &vat_main;
1245   vat_json_node_t node;
1246
1247   vat_json_init_object (&node);
1248   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1249   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1250
1251   vat_json_print (vam->ofp, &node);
1252   vat_json_free (&node);
1253
1254   vam->retval = ntohl (mp->retval);
1255   vam->result_ready = 1;
1256 }
1257
1258 static void vl_api_show_version_reply_t_handler
1259   (vl_api_show_version_reply_t * mp)
1260 {
1261   vat_main_t *vam = &vat_main;
1262   i32 retval = ntohl (mp->retval);
1263
1264   if (retval >= 0)
1265     {
1266       errmsg ("        program: %s", mp->program);
1267       errmsg ("        version: %s", mp->version);
1268       errmsg ("     build date: %s", mp->build_date);
1269       errmsg ("build directory: %s", mp->build_directory);
1270     }
1271   vam->retval = retval;
1272   vam->result_ready = 1;
1273 }
1274
1275 static void vl_api_show_version_reply_t_handler_json
1276   (vl_api_show_version_reply_t * mp)
1277 {
1278   vat_main_t *vam = &vat_main;
1279   vat_json_node_t node;
1280
1281   vat_json_init_object (&node);
1282   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1283   vat_json_object_add_string_copy (&node, "program", mp->program);
1284   vat_json_object_add_string_copy (&node, "version", mp->version);
1285   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1286   vat_json_object_add_string_copy (&node, "build_directory",
1287                                    mp->build_directory);
1288
1289   vat_json_print (vam->ofp, &node);
1290   vat_json_free (&node);
1291
1292   vam->retval = ntohl (mp->retval);
1293   vam->result_ready = 1;
1294 }
1295
1296 static void
1297 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1298 {
1299   u32 sw_if_index = ntohl (mp->sw_if_index);
1300   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1301           mp->mac_ip ? "mac/ip binding" : "address resolution",
1302           ntohl (mp->pid), format_ip4_address, &mp->address,
1303           format_ethernet_address, mp->new_mac, sw_if_index);
1304 }
1305
1306 static void
1307 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1308 {
1309   /* JSON output not supported */
1310 }
1311
1312 static void
1313 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1314 {
1315   u32 sw_if_index = ntohl (mp->sw_if_index);
1316   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1317           mp->mac_ip ? "mac/ip binding" : "address resolution",
1318           ntohl (mp->pid), format_ip6_address, mp->address,
1319           format_ethernet_address, mp->new_mac, sw_if_index);
1320 }
1321
1322 static void
1323 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1324 {
1325   /* JSON output not supported */
1326 }
1327
1328 static void
1329 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1330 {
1331   u32 n_macs = ntohl (mp->n_macs);
1332   errmsg ("L2MAC event recived with pid %d cl-idx %d for %d macs: \n",
1333           ntohl (mp->pid), mp->client_index, n_macs);
1334   int i;
1335   for (i = 0; i < n_macs; i++)
1336     {
1337       vl_api_mac_entry_t *mac = &mp->mac[i];
1338       errmsg (" [%d] sw_if_index %d  mac_addr %U  is_del %d \n",
1339               i + 1, ntohl (mac->sw_if_index),
1340               format_ethernet_address, mac->mac_addr, mac->is_del);
1341       if (i == 1000)
1342         break;
1343     }
1344 }
1345
1346 static void
1347 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1348 {
1349   /* JSON output not supported */
1350 }
1351
1352 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1353 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1354
1355 /*
1356  * Special-case: build the bridge domain table, maintain
1357  * the next bd id vbl.
1358  */
1359 static void vl_api_bridge_domain_details_t_handler
1360   (vl_api_bridge_domain_details_t * mp)
1361 {
1362   vat_main_t *vam = &vat_main;
1363   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1364   int i;
1365
1366   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1367          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1368
1369   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1370          ntohl (mp->bd_id), mp->learn, mp->forward,
1371          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1372
1373   if (n_sw_ifs)
1374     {
1375       vl_api_bridge_domain_sw_if_t *sw_ifs;
1376       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1377              "Interface Name");
1378
1379       sw_ifs = mp->sw_if_details;
1380       for (i = 0; i < n_sw_ifs; i++)
1381         {
1382           u8 *sw_if_name = 0;
1383           u32 sw_if_index;
1384           hash_pair_t *p;
1385
1386           sw_if_index = ntohl (sw_ifs->sw_if_index);
1387
1388           /* *INDENT-OFF* */
1389           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1390                              ({
1391                                if ((u32) p->value[0] == sw_if_index)
1392                                  {
1393                                    sw_if_name = (u8 *)(p->key);
1394                                    break;
1395                                  }
1396                              }));
1397           /* *INDENT-ON* */
1398           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1399                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1400                  "sw_if_index not found!");
1401
1402           sw_ifs++;
1403         }
1404     }
1405 }
1406
1407 static void vl_api_bridge_domain_details_t_handler_json
1408   (vl_api_bridge_domain_details_t * mp)
1409 {
1410   vat_main_t *vam = &vat_main;
1411   vat_json_node_t *node, *array = NULL;
1412   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1413
1414   if (VAT_JSON_ARRAY != vam->json_tree.type)
1415     {
1416       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1417       vat_json_init_array (&vam->json_tree);
1418     }
1419   node = vat_json_array_add (&vam->json_tree);
1420
1421   vat_json_init_object (node);
1422   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1423   vat_json_object_add_uint (node, "flood", mp->flood);
1424   vat_json_object_add_uint (node, "forward", mp->forward);
1425   vat_json_object_add_uint (node, "learn", mp->learn);
1426   vat_json_object_add_uint (node, "bvi_sw_if_index",
1427                             ntohl (mp->bvi_sw_if_index));
1428   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1429   array = vat_json_object_add (node, "sw_if");
1430   vat_json_init_array (array);
1431
1432
1433
1434   if (n_sw_ifs)
1435     {
1436       vl_api_bridge_domain_sw_if_t *sw_ifs;
1437       int i;
1438
1439       sw_ifs = mp->sw_if_details;
1440       for (i = 0; i < n_sw_ifs; i++)
1441         {
1442           node = vat_json_array_add (array);
1443           vat_json_init_object (node);
1444           vat_json_object_add_uint (node, "sw_if_index",
1445                                     ntohl (sw_ifs->sw_if_index));
1446           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1447           sw_ifs++;
1448         }
1449     }
1450 }
1451
1452 static void vl_api_control_ping_reply_t_handler
1453   (vl_api_control_ping_reply_t * mp)
1454 {
1455   vat_main_t *vam = &vat_main;
1456   i32 retval = ntohl (mp->retval);
1457   if (vam->async_mode)
1458     {
1459       vam->async_errors += (retval < 0);
1460     }
1461   else
1462     {
1463       vam->retval = retval;
1464       vam->result_ready = 1;
1465     }
1466   vam->socket_client_main.control_pings_outstanding--;
1467 }
1468
1469 static void vl_api_control_ping_reply_t_handler_json
1470   (vl_api_control_ping_reply_t * mp)
1471 {
1472   vat_main_t *vam = &vat_main;
1473   i32 retval = ntohl (mp->retval);
1474
1475   if (VAT_JSON_NONE != vam->json_tree.type)
1476     {
1477       vat_json_print (vam->ofp, &vam->json_tree);
1478       vat_json_free (&vam->json_tree);
1479       vam->json_tree.type = VAT_JSON_NONE;
1480     }
1481   else
1482     {
1483       /* just print [] */
1484       vat_json_init_array (&vam->json_tree);
1485       vat_json_print (vam->ofp, &vam->json_tree);
1486       vam->json_tree.type = VAT_JSON_NONE;
1487     }
1488
1489   vam->retval = retval;
1490   vam->result_ready = 1;
1491 }
1492
1493 static void
1494   vl_api_bridge_domain_set_mac_age_reply_t_handler
1495   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1496 {
1497   vat_main_t *vam = &vat_main;
1498   i32 retval = ntohl (mp->retval);
1499   if (vam->async_mode)
1500     {
1501       vam->async_errors += (retval < 0);
1502     }
1503   else
1504     {
1505       vam->retval = retval;
1506       vam->result_ready = 1;
1507     }
1508 }
1509
1510 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1511   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1512 {
1513   vat_main_t *vam = &vat_main;
1514   vat_json_node_t node;
1515
1516   vat_json_init_object (&node);
1517   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1518
1519   vat_json_print (vam->ofp, &node);
1520   vat_json_free (&node);
1521
1522   vam->retval = ntohl (mp->retval);
1523   vam->result_ready = 1;
1524 }
1525
1526 static void
1527 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1528 {
1529   vat_main_t *vam = &vat_main;
1530   i32 retval = ntohl (mp->retval);
1531   if (vam->async_mode)
1532     {
1533       vam->async_errors += (retval < 0);
1534     }
1535   else
1536     {
1537       vam->retval = retval;
1538       vam->result_ready = 1;
1539     }
1540 }
1541
1542 static void vl_api_l2_flags_reply_t_handler_json
1543   (vl_api_l2_flags_reply_t * mp)
1544 {
1545   vat_main_t *vam = &vat_main;
1546   vat_json_node_t node;
1547
1548   vat_json_init_object (&node);
1549   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1550   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1551                             ntohl (mp->resulting_feature_bitmap));
1552
1553   vat_json_print (vam->ofp, &node);
1554   vat_json_free (&node);
1555
1556   vam->retval = ntohl (mp->retval);
1557   vam->result_ready = 1;
1558 }
1559
1560 static void vl_api_bridge_flags_reply_t_handler
1561   (vl_api_bridge_flags_reply_t * mp)
1562 {
1563   vat_main_t *vam = &vat_main;
1564   i32 retval = ntohl (mp->retval);
1565   if (vam->async_mode)
1566     {
1567       vam->async_errors += (retval < 0);
1568     }
1569   else
1570     {
1571       vam->retval = retval;
1572       vam->result_ready = 1;
1573     }
1574 }
1575
1576 static void vl_api_bridge_flags_reply_t_handler_json
1577   (vl_api_bridge_flags_reply_t * mp)
1578 {
1579   vat_main_t *vam = &vat_main;
1580   vat_json_node_t node;
1581
1582   vat_json_init_object (&node);
1583   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1584   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1585                             ntohl (mp->resulting_feature_bitmap));
1586
1587   vat_json_print (vam->ofp, &node);
1588   vat_json_free (&node);
1589
1590   vam->retval = ntohl (mp->retval);
1591   vam->result_ready = 1;
1592 }
1593
1594 static void vl_api_tap_connect_reply_t_handler
1595   (vl_api_tap_connect_reply_t * mp)
1596 {
1597   vat_main_t *vam = &vat_main;
1598   i32 retval = ntohl (mp->retval);
1599   if (vam->async_mode)
1600     {
1601       vam->async_errors += (retval < 0);
1602     }
1603   else
1604     {
1605       vam->retval = retval;
1606       vam->sw_if_index = ntohl (mp->sw_if_index);
1607       vam->result_ready = 1;
1608     }
1609
1610 }
1611
1612 static void vl_api_tap_connect_reply_t_handler_json
1613   (vl_api_tap_connect_reply_t * mp)
1614 {
1615   vat_main_t *vam = &vat_main;
1616   vat_json_node_t node;
1617
1618   vat_json_init_object (&node);
1619   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1620   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1621
1622   vat_json_print (vam->ofp, &node);
1623   vat_json_free (&node);
1624
1625   vam->retval = ntohl (mp->retval);
1626   vam->result_ready = 1;
1627
1628 }
1629
1630 static void
1631 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1632 {
1633   vat_main_t *vam = &vat_main;
1634   i32 retval = ntohl (mp->retval);
1635   if (vam->async_mode)
1636     {
1637       vam->async_errors += (retval < 0);
1638     }
1639   else
1640     {
1641       vam->retval = retval;
1642       vam->sw_if_index = ntohl (mp->sw_if_index);
1643       vam->result_ready = 1;
1644     }
1645 }
1646
1647 static void vl_api_tap_modify_reply_t_handler_json
1648   (vl_api_tap_modify_reply_t * mp)
1649 {
1650   vat_main_t *vam = &vat_main;
1651   vat_json_node_t node;
1652
1653   vat_json_init_object (&node);
1654   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1655   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1656
1657   vat_json_print (vam->ofp, &node);
1658   vat_json_free (&node);
1659
1660   vam->retval = ntohl (mp->retval);
1661   vam->result_ready = 1;
1662 }
1663
1664 static void
1665 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1666 {
1667   vat_main_t *vam = &vat_main;
1668   i32 retval = ntohl (mp->retval);
1669   if (vam->async_mode)
1670     {
1671       vam->async_errors += (retval < 0);
1672     }
1673   else
1674     {
1675       vam->retval = retval;
1676       vam->result_ready = 1;
1677     }
1678 }
1679
1680 static void vl_api_tap_delete_reply_t_handler_json
1681   (vl_api_tap_delete_reply_t * mp)
1682 {
1683   vat_main_t *vam = &vat_main;
1684   vat_json_node_t node;
1685
1686   vat_json_init_object (&node);
1687   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1688
1689   vat_json_print (vam->ofp, &node);
1690   vat_json_free (&node);
1691
1692   vam->retval = ntohl (mp->retval);
1693   vam->result_ready = 1;
1694 }
1695
1696 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1697   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1698 {
1699   vat_main_t *vam = &vat_main;
1700   i32 retval = ntohl (mp->retval);
1701   if (vam->async_mode)
1702     {
1703       vam->async_errors += (retval < 0);
1704     }
1705   else
1706     {
1707       vam->retval = retval;
1708       vam->result_ready = 1;
1709     }
1710 }
1711
1712 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1713   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1714 {
1715   vat_main_t *vam = &vat_main;
1716   vat_json_node_t node;
1717
1718   vat_json_init_object (&node);
1719   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1720   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1721                             ntohl (mp->sw_if_index));
1722
1723   vat_json_print (vam->ofp, &node);
1724   vat_json_free (&node);
1725
1726   vam->retval = ntohl (mp->retval);
1727   vam->result_ready = 1;
1728 }
1729
1730 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1731   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1732 {
1733   vat_main_t *vam = &vat_main;
1734   i32 retval = ntohl (mp->retval);
1735   if (vam->async_mode)
1736     {
1737       vam->async_errors += (retval < 0);
1738     }
1739   else
1740     {
1741       vam->retval = retval;
1742       vam->sw_if_index = ntohl (mp->sw_if_index);
1743       vam->result_ready = 1;
1744     }
1745 }
1746
1747 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1748   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1749 {
1750   vat_main_t *vam = &vat_main;
1751   vat_json_node_t node;
1752
1753   vat_json_init_object (&node);
1754   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1755   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1756
1757   vat_json_print (vam->ofp, &node);
1758   vat_json_free (&node);
1759
1760   vam->retval = ntohl (mp->retval);
1761   vam->result_ready = 1;
1762 }
1763
1764 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
1765   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1766 {
1767   vat_main_t *vam = &vat_main;
1768   i32 retval = ntohl (mp->retval);
1769   if (vam->async_mode)
1770     {
1771       vam->async_errors += (retval < 0);
1772     }
1773   else
1774     {
1775       vam->retval = retval;
1776       vam->result_ready = 1;
1777     }
1778 }
1779
1780 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
1781   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1782 {
1783   vat_main_t *vam = &vat_main;
1784   vat_json_node_t node;
1785
1786   vat_json_init_object (&node);
1787   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1788   vat_json_object_add_uint (&node, "fwd_entry_index",
1789                             clib_net_to_host_u32 (mp->fwd_entry_index));
1790
1791   vat_json_print (vam->ofp, &node);
1792   vat_json_free (&node);
1793
1794   vam->retval = ntohl (mp->retval);
1795   vam->result_ready = 1;
1796 }
1797
1798 u8 *
1799 format_lisp_transport_protocol (u8 * s, va_list * args)
1800 {
1801   u32 proto = va_arg (*args, u32);
1802
1803   switch (proto)
1804     {
1805     case 1:
1806       return format (s, "udp");
1807     case 2:
1808       return format (s, "api");
1809     default:
1810       return 0;
1811     }
1812   return 0;
1813 }
1814
1815 static void vl_api_one_get_transport_protocol_reply_t_handler
1816   (vl_api_one_get_transport_protocol_reply_t * mp)
1817 {
1818   vat_main_t *vam = &vat_main;
1819   i32 retval = ntohl (mp->retval);
1820   if (vam->async_mode)
1821     {
1822       vam->async_errors += (retval < 0);
1823     }
1824   else
1825     {
1826       u32 proto = mp->protocol;
1827       print (vam->ofp, "Transport protocol: %U",
1828              format_lisp_transport_protocol, proto);
1829       vam->retval = retval;
1830       vam->result_ready = 1;
1831     }
1832 }
1833
1834 static void vl_api_one_get_transport_protocol_reply_t_handler_json
1835   (vl_api_one_get_transport_protocol_reply_t * mp)
1836 {
1837   vat_main_t *vam = &vat_main;
1838   vat_json_node_t node;
1839   u8 *s;
1840
1841   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
1842   vec_add1 (s, 0);
1843
1844   vat_json_init_object (&node);
1845   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1846   vat_json_object_add_string_copy (&node, "transport-protocol", s);
1847
1848   vec_free (s);
1849   vat_json_print (vam->ofp, &node);
1850   vat_json_free (&node);
1851
1852   vam->retval = ntohl (mp->retval);
1853   vam->result_ready = 1;
1854 }
1855
1856 static void vl_api_one_add_del_locator_set_reply_t_handler
1857   (vl_api_one_add_del_locator_set_reply_t * mp)
1858 {
1859   vat_main_t *vam = &vat_main;
1860   i32 retval = ntohl (mp->retval);
1861   if (vam->async_mode)
1862     {
1863       vam->async_errors += (retval < 0);
1864     }
1865   else
1866     {
1867       vam->retval = retval;
1868       vam->result_ready = 1;
1869     }
1870 }
1871
1872 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1873   (vl_api_one_add_del_locator_set_reply_t * mp)
1874 {
1875   vat_main_t *vam = &vat_main;
1876   vat_json_node_t node;
1877
1878   vat_json_init_object (&node);
1879   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1880   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1881
1882   vat_json_print (vam->ofp, &node);
1883   vat_json_free (&node);
1884
1885   vam->retval = ntohl (mp->retval);
1886   vam->result_ready = 1;
1887 }
1888
1889 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1890   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1891 {
1892   vat_main_t *vam = &vat_main;
1893   i32 retval = ntohl (mp->retval);
1894   if (vam->async_mode)
1895     {
1896       vam->async_errors += (retval < 0);
1897     }
1898   else
1899     {
1900       vam->retval = retval;
1901       vam->sw_if_index = ntohl (mp->sw_if_index);
1902       vam->result_ready = 1;
1903     }
1904 }
1905
1906 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1907   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1908 {
1909   vat_main_t *vam = &vat_main;
1910   vat_json_node_t node;
1911
1912   vat_json_init_object (&node);
1913   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1914   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1915
1916   vat_json_print (vam->ofp, &node);
1917   vat_json_free (&node);
1918
1919   vam->retval = ntohl (mp->retval);
1920   vam->result_ready = 1;
1921 }
1922
1923 static void vl_api_geneve_add_del_tunnel_reply_t_handler
1924   (vl_api_geneve_add_del_tunnel_reply_t * mp)
1925 {
1926   vat_main_t *vam = &vat_main;
1927   i32 retval = ntohl (mp->retval);
1928   if (vam->async_mode)
1929     {
1930       vam->async_errors += (retval < 0);
1931     }
1932   else
1933     {
1934       vam->retval = retval;
1935       vam->sw_if_index = ntohl (mp->sw_if_index);
1936       vam->result_ready = 1;
1937     }
1938 }
1939
1940 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
1941   (vl_api_geneve_add_del_tunnel_reply_t * mp)
1942 {
1943   vat_main_t *vam = &vat_main;
1944   vat_json_node_t node;
1945
1946   vat_json_init_object (&node);
1947   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1948   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1949
1950   vat_json_print (vam->ofp, &node);
1951   vat_json_free (&node);
1952
1953   vam->retval = ntohl (mp->retval);
1954   vam->result_ready = 1;
1955 }
1956
1957 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
1958   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
1959 {
1960   vat_main_t *vam = &vat_main;
1961   i32 retval = ntohl (mp->retval);
1962   if (vam->async_mode)
1963     {
1964       vam->async_errors += (retval < 0);
1965     }
1966   else
1967     {
1968       vam->retval = retval;
1969       vam->sw_if_index = ntohl (mp->sw_if_index);
1970       vam->result_ready = 1;
1971     }
1972 }
1973
1974 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
1975   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
1976 {
1977   vat_main_t *vam = &vat_main;
1978   vat_json_node_t node;
1979
1980   vat_json_init_object (&node);
1981   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1982   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1983
1984   vat_json_print (vam->ofp, &node);
1985   vat_json_free (&node);
1986
1987   vam->retval = ntohl (mp->retval);
1988   vam->result_ready = 1;
1989 }
1990
1991 static void vl_api_gre_add_del_tunnel_reply_t_handler
1992   (vl_api_gre_add_del_tunnel_reply_t * mp)
1993 {
1994   vat_main_t *vam = &vat_main;
1995   i32 retval = ntohl (mp->retval);
1996   if (vam->async_mode)
1997     {
1998       vam->async_errors += (retval < 0);
1999     }
2000   else
2001     {
2002       vam->retval = retval;
2003       vam->sw_if_index = ntohl (mp->sw_if_index);
2004       vam->result_ready = 1;
2005     }
2006 }
2007
2008 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2009   (vl_api_gre_add_del_tunnel_reply_t * mp)
2010 {
2011   vat_main_t *vam = &vat_main;
2012   vat_json_node_t node;
2013
2014   vat_json_init_object (&node);
2015   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2016   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2017
2018   vat_json_print (vam->ofp, &node);
2019   vat_json_free (&node);
2020
2021   vam->retval = ntohl (mp->retval);
2022   vam->result_ready = 1;
2023 }
2024
2025 static void vl_api_create_vhost_user_if_reply_t_handler
2026   (vl_api_create_vhost_user_if_reply_t * mp)
2027 {
2028   vat_main_t *vam = &vat_main;
2029   i32 retval = ntohl (mp->retval);
2030   if (vam->async_mode)
2031     {
2032       vam->async_errors += (retval < 0);
2033     }
2034   else
2035     {
2036       vam->retval = retval;
2037       vam->sw_if_index = ntohl (mp->sw_if_index);
2038       vam->result_ready = 1;
2039     }
2040 }
2041
2042 static void vl_api_create_vhost_user_if_reply_t_handler_json
2043   (vl_api_create_vhost_user_if_reply_t * mp)
2044 {
2045   vat_main_t *vam = &vat_main;
2046   vat_json_node_t node;
2047
2048   vat_json_init_object (&node);
2049   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2050   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2051
2052   vat_json_print (vam->ofp, &node);
2053   vat_json_free (&node);
2054
2055   vam->retval = ntohl (mp->retval);
2056   vam->result_ready = 1;
2057 }
2058
2059 static clib_error_t *
2060 receive_fd_msg (int socket_fd, int *my_fd)
2061 {
2062   char msgbuf[16];
2063   char ctl[CMSG_SPACE (sizeof (int)) + CMSG_SPACE (sizeof (struct ucred))];
2064   struct msghdr mh = { 0 };
2065   struct iovec iov[1];
2066   ssize_t size;
2067   struct ucred *cr = 0;
2068   struct cmsghdr *cmsg;
2069   pid_t pid __attribute__ ((unused));
2070   uid_t uid __attribute__ ((unused));
2071   gid_t gid __attribute__ ((unused));
2072
2073   iov[0].iov_base = msgbuf;
2074   iov[0].iov_len = 5;
2075   mh.msg_iov = iov;
2076   mh.msg_iovlen = 1;
2077   mh.msg_control = ctl;
2078   mh.msg_controllen = sizeof (ctl);
2079
2080   memset (ctl, 0, sizeof (ctl));
2081
2082   /* receive the incoming message */
2083   size = recvmsg (socket_fd, &mh, 0);
2084   if (size != 5)
2085     {
2086       return (size == 0) ? clib_error_return (0, "disconnected") :
2087         clib_error_return_unix (0, "recvmsg: malformed message (fd %d)",
2088                                 socket_fd);
2089     }
2090
2091   cmsg = CMSG_FIRSTHDR (&mh);
2092   while (cmsg)
2093     {
2094       if (cmsg->cmsg_level == SOL_SOCKET)
2095         {
2096           if (cmsg->cmsg_type == SCM_CREDENTIALS)
2097             {
2098               cr = (struct ucred *) CMSG_DATA (cmsg);
2099               uid = cr->uid;
2100               gid = cr->gid;
2101               pid = cr->pid;
2102             }
2103           else if (cmsg->cmsg_type == SCM_RIGHTS)
2104             {
2105               clib_memcpy (my_fd, CMSG_DATA (cmsg), sizeof (int));
2106             }
2107         }
2108       cmsg = CMSG_NXTHDR (&mh, cmsg);
2109     }
2110   return 0;
2111 }
2112
2113 static void vl_api_memfd_segment_create_reply_t_handler
2114   (vl_api_memfd_segment_create_reply_t * mp)
2115 {
2116   /* Dont bother in the builtin version */
2117 #if VPP_API_TEST_BUILTIN == 0
2118   vat_main_t *vam = &vat_main;
2119   api_main_t *am = &api_main;
2120   socket_client_main_t *scm = &vam->socket_client_main;
2121   int my_fd = -1;
2122   clib_error_t *error;
2123   memfd_private_t memfd;
2124   i32 retval = ntohl (mp->retval);
2125
2126   if (retval == 0)
2127     {
2128       error = receive_fd_msg (scm->socket_fd, &my_fd);
2129       if (error)
2130         {
2131           retval = -99;
2132           goto out;
2133         }
2134
2135       memset (&memfd, 0, sizeof (memfd));
2136       memfd.fd = my_fd;
2137
2138       vam->client_index_invalid = 1;
2139
2140       /* Note: this closes memfd.fd */
2141       retval = memfd_slave_init (&memfd);
2142       if (retval)
2143         clib_warning ("WARNING: segment map returned %d", retval);
2144
2145       /* Pivot to the memory client segment that vpp just created */
2146
2147       am->vlib_rp = (void *) (memfd.requested_va + MMAP_PAGESIZE);
2148
2149       am->shmem_hdr = (void *) am->vlib_rp->user_ctx;
2150
2151       vl_client_install_client_message_handlers ();
2152
2153       vl_client_connect_to_vlib_no_map ("pvt",
2154                                         "vpp_api_test(p)",
2155                                         32 /* input_queue_length */ );
2156       vam->vl_input_queue = am->shmem_hdr->vl_input_queue;
2157
2158       vl_socket_client_enable_disable (&vam->socket_client_main,
2159                                        0 /* disable socket */ );
2160     }
2161
2162 out:
2163   if (vam->async_mode)
2164     {
2165       vam->async_errors += (retval < 0);
2166     }
2167   else
2168     {
2169       vam->retval = retval;
2170       vam->result_ready = 1;
2171     }
2172 #endif
2173 }
2174
2175 static void vl_api_memfd_segment_create_reply_t_handler_json
2176   (vl_api_memfd_segment_create_reply_t * mp)
2177 {
2178   clib_warning ("no");
2179 }
2180
2181 static void vl_api_dns_resolve_name_reply_t_handler
2182   (vl_api_dns_resolve_name_reply_t * mp)
2183 {
2184   vat_main_t *vam = &vat_main;
2185   i32 retval = ntohl (mp->retval);
2186   if (vam->async_mode)
2187     {
2188       vam->async_errors += (retval < 0);
2189     }
2190   else
2191     {
2192       vam->retval = retval;
2193       vam->result_ready = 1;
2194
2195       if (retval == 0)
2196         {
2197           if (mp->ip4_set)
2198             clib_warning ("ip4 address %U", format_ip4_address,
2199                           (ip4_address_t *) mp->ip4_address);
2200           if (mp->ip6_set)
2201             clib_warning ("ip6 address %U", format_ip6_address,
2202                           (ip6_address_t *) mp->ip6_address);
2203         }
2204       else
2205         clib_warning ("retval %d", retval);
2206     }
2207 }
2208
2209 static void vl_api_dns_resolve_name_reply_t_handler_json
2210   (vl_api_dns_resolve_name_reply_t * mp)
2211 {
2212   clib_warning ("not implemented");
2213 }
2214
2215 static void vl_api_dns_resolve_ip_reply_t_handler
2216   (vl_api_dns_resolve_ip_reply_t * mp)
2217 {
2218   vat_main_t *vam = &vat_main;
2219   i32 retval = ntohl (mp->retval);
2220   if (vam->async_mode)
2221     {
2222       vam->async_errors += (retval < 0);
2223     }
2224   else
2225     {
2226       vam->retval = retval;
2227       vam->result_ready = 1;
2228
2229       if (retval == 0)
2230         {
2231           clib_warning ("canonical name %s", mp->name);
2232         }
2233       else
2234         clib_warning ("retval %d", retval);
2235     }
2236 }
2237
2238 static void vl_api_dns_resolve_ip_reply_t_handler_json
2239   (vl_api_dns_resolve_ip_reply_t * mp)
2240 {
2241   clib_warning ("not implemented");
2242 }
2243
2244
2245 static void vl_api_ip_address_details_t_handler
2246   (vl_api_ip_address_details_t * mp)
2247 {
2248   vat_main_t *vam = &vat_main;
2249   static ip_address_details_t empty_ip_address_details = { {0} };
2250   ip_address_details_t *address = NULL;
2251   ip_details_t *current_ip_details = NULL;
2252   ip_details_t *details = NULL;
2253
2254   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2255
2256   if (!details || vam->current_sw_if_index >= vec_len (details)
2257       || !details[vam->current_sw_if_index].present)
2258     {
2259       errmsg ("ip address details arrived but not stored");
2260       errmsg ("ip_dump should be called first");
2261       return;
2262     }
2263
2264   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2265
2266 #define addresses (current_ip_details->addr)
2267
2268   vec_validate_init_empty (addresses, vec_len (addresses),
2269                            empty_ip_address_details);
2270
2271   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2272
2273   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2274   address->prefix_length = mp->prefix_length;
2275 #undef addresses
2276 }
2277
2278 static void vl_api_ip_address_details_t_handler_json
2279   (vl_api_ip_address_details_t * mp)
2280 {
2281   vat_main_t *vam = &vat_main;
2282   vat_json_node_t *node = NULL;
2283   struct in6_addr ip6;
2284   struct in_addr ip4;
2285
2286   if (VAT_JSON_ARRAY != vam->json_tree.type)
2287     {
2288       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2289       vat_json_init_array (&vam->json_tree);
2290     }
2291   node = vat_json_array_add (&vam->json_tree);
2292
2293   vat_json_init_object (node);
2294   if (vam->is_ipv6)
2295     {
2296       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2297       vat_json_object_add_ip6 (node, "ip", ip6);
2298     }
2299   else
2300     {
2301       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2302       vat_json_object_add_ip4 (node, "ip", ip4);
2303     }
2304   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2305 }
2306
2307 static void
2308 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2309 {
2310   vat_main_t *vam = &vat_main;
2311   static ip_details_t empty_ip_details = { 0 };
2312   ip_details_t *ip = NULL;
2313   u32 sw_if_index = ~0;
2314
2315   sw_if_index = ntohl (mp->sw_if_index);
2316
2317   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2318                            sw_if_index, empty_ip_details);
2319
2320   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2321                          sw_if_index);
2322
2323   ip->present = 1;
2324 }
2325
2326 static void
2327 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2328 {
2329   vat_main_t *vam = &vat_main;
2330
2331   if (VAT_JSON_ARRAY != vam->json_tree.type)
2332     {
2333       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2334       vat_json_init_array (&vam->json_tree);
2335     }
2336   vat_json_array_add_uint (&vam->json_tree,
2337                            clib_net_to_host_u32 (mp->sw_if_index));
2338 }
2339
2340 static void vl_api_map_domain_details_t_handler_json
2341   (vl_api_map_domain_details_t * mp)
2342 {
2343   vat_json_node_t *node = NULL;
2344   vat_main_t *vam = &vat_main;
2345   struct in6_addr ip6;
2346   struct in_addr ip4;
2347
2348   if (VAT_JSON_ARRAY != vam->json_tree.type)
2349     {
2350       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2351       vat_json_init_array (&vam->json_tree);
2352     }
2353
2354   node = vat_json_array_add (&vam->json_tree);
2355   vat_json_init_object (node);
2356
2357   vat_json_object_add_uint (node, "domain_index",
2358                             clib_net_to_host_u32 (mp->domain_index));
2359   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
2360   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
2361   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
2362   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
2363   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
2364   vat_json_object_add_ip6 (node, "ip6_src", ip6);
2365   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
2366   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
2367   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
2368   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
2369   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
2370   vat_json_object_add_int (node, "psid_length", mp->psid_length);
2371   vat_json_object_add_uint (node, "flags", mp->flags);
2372   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
2373   vat_json_object_add_int (node, "is_translation", mp->is_translation);
2374 }
2375
2376 static void vl_api_map_domain_details_t_handler
2377   (vl_api_map_domain_details_t * mp)
2378 {
2379   vat_main_t *vam = &vat_main;
2380
2381   if (mp->is_translation)
2382     {
2383       print (vam->ofp,
2384              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2385              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2386              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2387              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2388              clib_net_to_host_u32 (mp->domain_index));
2389     }
2390   else
2391     {
2392       print (vam->ofp,
2393              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2394              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2395              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2396              format_ip6_address, mp->ip6_src,
2397              clib_net_to_host_u32 (mp->domain_index));
2398     }
2399   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2400          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2401          mp->is_translation ? "map-t" : "");
2402 }
2403
2404 static void vl_api_map_rule_details_t_handler_json
2405   (vl_api_map_rule_details_t * mp)
2406 {
2407   struct in6_addr ip6;
2408   vat_json_node_t *node = NULL;
2409   vat_main_t *vam = &vat_main;
2410
2411   if (VAT_JSON_ARRAY != vam->json_tree.type)
2412     {
2413       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2414       vat_json_init_array (&vam->json_tree);
2415     }
2416
2417   node = vat_json_array_add (&vam->json_tree);
2418   vat_json_init_object (node);
2419
2420   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2421   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2422   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2423 }
2424
2425 static void
2426 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2427 {
2428   vat_main_t *vam = &vat_main;
2429   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2430          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2431 }
2432
2433 static void
2434 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2435 {
2436   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2437           "router_addr %U host_mac %U",
2438           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2439           format_ip4_address, &mp->host_address,
2440           format_ip4_address, &mp->router_address,
2441           format_ethernet_address, mp->host_mac);
2442 }
2443
2444 static void vl_api_dhcp_compl_event_t_handler_json
2445   (vl_api_dhcp_compl_event_t * mp)
2446 {
2447   /* JSON output not supported */
2448 }
2449
2450 static void
2451 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2452                               u32 counter)
2453 {
2454   vat_main_t *vam = &vat_main;
2455   static u64 default_counter = 0;
2456
2457   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2458                            NULL);
2459   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2460                            sw_if_index, default_counter);
2461   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2462 }
2463
2464 static void
2465 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2466                                 interface_counter_t counter)
2467 {
2468   vat_main_t *vam = &vat_main;
2469   static interface_counter_t default_counter = { 0, };
2470
2471   vec_validate_init_empty (vam->combined_interface_counters,
2472                            vnet_counter_type, NULL);
2473   vec_validate_init_empty (vam->combined_interface_counters
2474                            [vnet_counter_type], sw_if_index, default_counter);
2475   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2476 }
2477
2478 static void vl_api_vnet_interface_simple_counters_t_handler
2479   (vl_api_vnet_interface_simple_counters_t * mp)
2480 {
2481   /* not supported */
2482 }
2483
2484 static void vl_api_vnet_interface_combined_counters_t_handler
2485   (vl_api_vnet_interface_combined_counters_t * mp)
2486 {
2487   /* not supported */
2488 }
2489
2490 static void vl_api_vnet_interface_simple_counters_t_handler_json
2491   (vl_api_vnet_interface_simple_counters_t * mp)
2492 {
2493   u64 *v_packets;
2494   u64 packets;
2495   u32 count;
2496   u32 first_sw_if_index;
2497   int i;
2498
2499   count = ntohl (mp->count);
2500   first_sw_if_index = ntohl (mp->first_sw_if_index);
2501
2502   v_packets = (u64 *) & mp->data;
2503   for (i = 0; i < count; i++)
2504     {
2505       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2506       set_simple_interface_counter (mp->vnet_counter_type,
2507                                     first_sw_if_index + i, packets);
2508       v_packets++;
2509     }
2510 }
2511
2512 static void vl_api_vnet_interface_combined_counters_t_handler_json
2513   (vl_api_vnet_interface_combined_counters_t * mp)
2514 {
2515   interface_counter_t counter;
2516   vlib_counter_t *v;
2517   u32 first_sw_if_index;
2518   int i;
2519   u32 count;
2520
2521   count = ntohl (mp->count);
2522   first_sw_if_index = ntohl (mp->first_sw_if_index);
2523
2524   v = (vlib_counter_t *) & mp->data;
2525   for (i = 0; i < count; i++)
2526     {
2527       counter.packets =
2528         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2529       counter.bytes =
2530         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2531       set_combined_interface_counter (mp->vnet_counter_type,
2532                                       first_sw_if_index + i, counter);
2533       v++;
2534     }
2535 }
2536
2537 static u32
2538 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2539 {
2540   vat_main_t *vam = &vat_main;
2541   u32 i;
2542
2543   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2544     {
2545       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2546         {
2547           return i;
2548         }
2549     }
2550   return ~0;
2551 }
2552
2553 static u32
2554 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2555 {
2556   vat_main_t *vam = &vat_main;
2557   u32 i;
2558
2559   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2560     {
2561       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2562         {
2563           return i;
2564         }
2565     }
2566   return ~0;
2567 }
2568
2569 static void vl_api_vnet_ip4_fib_counters_t_handler
2570   (vl_api_vnet_ip4_fib_counters_t * mp)
2571 {
2572   /* not supported */
2573 }
2574
2575 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2576   (vl_api_vnet_ip4_fib_counters_t * mp)
2577 {
2578   vat_main_t *vam = &vat_main;
2579   vl_api_ip4_fib_counter_t *v;
2580   ip4_fib_counter_t *counter;
2581   struct in_addr ip4;
2582   u32 vrf_id;
2583   u32 vrf_index;
2584   u32 count;
2585   int i;
2586
2587   vrf_id = ntohl (mp->vrf_id);
2588   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2589   if (~0 == vrf_index)
2590     {
2591       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2592       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2593       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2594       vec_validate (vam->ip4_fib_counters, vrf_index);
2595       vam->ip4_fib_counters[vrf_index] = NULL;
2596     }
2597
2598   vec_free (vam->ip4_fib_counters[vrf_index]);
2599   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2600   count = ntohl (mp->count);
2601   for (i = 0; i < count; i++)
2602     {
2603       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2604       counter = &vam->ip4_fib_counters[vrf_index][i];
2605       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2606       counter->address = ip4;
2607       counter->address_length = v->address_length;
2608       counter->packets = clib_net_to_host_u64 (v->packets);
2609       counter->bytes = clib_net_to_host_u64 (v->bytes);
2610       v++;
2611     }
2612 }
2613
2614 static void vl_api_vnet_ip4_nbr_counters_t_handler
2615   (vl_api_vnet_ip4_nbr_counters_t * mp)
2616 {
2617   /* not supported */
2618 }
2619
2620 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2621   (vl_api_vnet_ip4_nbr_counters_t * mp)
2622 {
2623   vat_main_t *vam = &vat_main;
2624   vl_api_ip4_nbr_counter_t *v;
2625   ip4_nbr_counter_t *counter;
2626   u32 sw_if_index;
2627   u32 count;
2628   int i;
2629
2630   sw_if_index = ntohl (mp->sw_if_index);
2631   count = ntohl (mp->count);
2632   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2633
2634   if (mp->begin)
2635     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2636
2637   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2638   for (i = 0; i < count; i++)
2639     {
2640       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2641       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2642       counter->address.s_addr = v->address;
2643       counter->packets = clib_net_to_host_u64 (v->packets);
2644       counter->bytes = clib_net_to_host_u64 (v->bytes);
2645       counter->linkt = v->link_type;
2646       v++;
2647     }
2648 }
2649
2650 static void vl_api_vnet_ip6_fib_counters_t_handler
2651   (vl_api_vnet_ip6_fib_counters_t * mp)
2652 {
2653   /* not supported */
2654 }
2655
2656 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2657   (vl_api_vnet_ip6_fib_counters_t * mp)
2658 {
2659   vat_main_t *vam = &vat_main;
2660   vl_api_ip6_fib_counter_t *v;
2661   ip6_fib_counter_t *counter;
2662   struct in6_addr ip6;
2663   u32 vrf_id;
2664   u32 vrf_index;
2665   u32 count;
2666   int i;
2667
2668   vrf_id = ntohl (mp->vrf_id);
2669   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2670   if (~0 == vrf_index)
2671     {
2672       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2673       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2674       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2675       vec_validate (vam->ip6_fib_counters, vrf_index);
2676       vam->ip6_fib_counters[vrf_index] = NULL;
2677     }
2678
2679   vec_free (vam->ip6_fib_counters[vrf_index]);
2680   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2681   count = ntohl (mp->count);
2682   for (i = 0; i < count; i++)
2683     {
2684       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2685       counter = &vam->ip6_fib_counters[vrf_index][i];
2686       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2687       counter->address = ip6;
2688       counter->address_length = v->address_length;
2689       counter->packets = clib_net_to_host_u64 (v->packets);
2690       counter->bytes = clib_net_to_host_u64 (v->bytes);
2691       v++;
2692     }
2693 }
2694
2695 static void vl_api_vnet_ip6_nbr_counters_t_handler
2696   (vl_api_vnet_ip6_nbr_counters_t * mp)
2697 {
2698   /* not supported */
2699 }
2700
2701 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2702   (vl_api_vnet_ip6_nbr_counters_t * mp)
2703 {
2704   vat_main_t *vam = &vat_main;
2705   vl_api_ip6_nbr_counter_t *v;
2706   ip6_nbr_counter_t *counter;
2707   struct in6_addr ip6;
2708   u32 sw_if_index;
2709   u32 count;
2710   int i;
2711
2712   sw_if_index = ntohl (mp->sw_if_index);
2713   count = ntohl (mp->count);
2714   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2715
2716   if (mp->begin)
2717     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2718
2719   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2720   for (i = 0; i < count; i++)
2721     {
2722       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2723       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2724       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2725       counter->address = ip6;
2726       counter->packets = clib_net_to_host_u64 (v->packets);
2727       counter->bytes = clib_net_to_host_u64 (v->bytes);
2728       v++;
2729     }
2730 }
2731
2732 static void vl_api_get_first_msg_id_reply_t_handler
2733   (vl_api_get_first_msg_id_reply_t * mp)
2734 {
2735   vat_main_t *vam = &vat_main;
2736   i32 retval = ntohl (mp->retval);
2737
2738   if (vam->async_mode)
2739     {
2740       vam->async_errors += (retval < 0);
2741     }
2742   else
2743     {
2744       vam->retval = retval;
2745       vam->result_ready = 1;
2746     }
2747   if (retval >= 0)
2748     {
2749       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2750     }
2751 }
2752
2753 static void vl_api_get_first_msg_id_reply_t_handler_json
2754   (vl_api_get_first_msg_id_reply_t * mp)
2755 {
2756   vat_main_t *vam = &vat_main;
2757   vat_json_node_t node;
2758
2759   vat_json_init_object (&node);
2760   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2761   vat_json_object_add_uint (&node, "first_msg_id",
2762                             (uint) ntohs (mp->first_msg_id));
2763
2764   vat_json_print (vam->ofp, &node);
2765   vat_json_free (&node);
2766
2767   vam->retval = ntohl (mp->retval);
2768   vam->result_ready = 1;
2769 }
2770
2771 static void vl_api_get_node_graph_reply_t_handler
2772   (vl_api_get_node_graph_reply_t * mp)
2773 {
2774   vat_main_t *vam = &vat_main;
2775   api_main_t *am = &api_main;
2776   i32 retval = ntohl (mp->retval);
2777   u8 *pvt_copy, *reply;
2778   void *oldheap;
2779   vlib_node_t *node;
2780   int i;
2781
2782   if (vam->async_mode)
2783     {
2784       vam->async_errors += (retval < 0);
2785     }
2786   else
2787     {
2788       vam->retval = retval;
2789       vam->result_ready = 1;
2790     }
2791
2792   /* "Should never happen..." */
2793   if (retval != 0)
2794     return;
2795
2796   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2797   pvt_copy = vec_dup (reply);
2798
2799   /* Toss the shared-memory original... */
2800   pthread_mutex_lock (&am->vlib_rp->mutex);
2801   oldheap = svm_push_data_heap (am->vlib_rp);
2802
2803   vec_free (reply);
2804
2805   svm_pop_heap (oldheap);
2806   pthread_mutex_unlock (&am->vlib_rp->mutex);
2807
2808   if (vam->graph_nodes)
2809     {
2810       hash_free (vam->graph_node_index_by_name);
2811
2812       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2813         {
2814           node = vam->graph_nodes[i];
2815           vec_free (node->name);
2816           vec_free (node->next_nodes);
2817           vec_free (node);
2818         }
2819       vec_free (vam->graph_nodes);
2820     }
2821
2822   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2823   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2824   vec_free (pvt_copy);
2825
2826   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2827     {
2828       node = vam->graph_nodes[i];
2829       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2830     }
2831 }
2832
2833 static void vl_api_get_node_graph_reply_t_handler_json
2834   (vl_api_get_node_graph_reply_t * mp)
2835 {
2836   vat_main_t *vam = &vat_main;
2837   api_main_t *am = &api_main;
2838   void *oldheap;
2839   vat_json_node_t node;
2840   u8 *reply;
2841
2842   /* $$$$ make this real? */
2843   vat_json_init_object (&node);
2844   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2845   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2846
2847   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2848
2849   /* Toss the shared-memory original... */
2850   pthread_mutex_lock (&am->vlib_rp->mutex);
2851   oldheap = svm_push_data_heap (am->vlib_rp);
2852
2853   vec_free (reply);
2854
2855   svm_pop_heap (oldheap);
2856   pthread_mutex_unlock (&am->vlib_rp->mutex);
2857
2858   vat_json_print (vam->ofp, &node);
2859   vat_json_free (&node);
2860
2861   vam->retval = ntohl (mp->retval);
2862   vam->result_ready = 1;
2863 }
2864
2865 static void
2866 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2867 {
2868   vat_main_t *vam = &vat_main;
2869   u8 *s = 0;
2870
2871   if (mp->local)
2872     {
2873       s = format (s, "%=16d%=16d%=16d",
2874                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2875     }
2876   else
2877     {
2878       s = format (s, "%=16U%=16d%=16d",
2879                   mp->is_ipv6 ? format_ip6_address :
2880                   format_ip4_address,
2881                   mp->ip_address, mp->priority, mp->weight);
2882     }
2883
2884   print (vam->ofp, "%v", s);
2885   vec_free (s);
2886 }
2887
2888 static void
2889 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2890 {
2891   vat_main_t *vam = &vat_main;
2892   vat_json_node_t *node = NULL;
2893   struct in6_addr ip6;
2894   struct in_addr ip4;
2895
2896   if (VAT_JSON_ARRAY != vam->json_tree.type)
2897     {
2898       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2899       vat_json_init_array (&vam->json_tree);
2900     }
2901   node = vat_json_array_add (&vam->json_tree);
2902   vat_json_init_object (node);
2903
2904   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2905   vat_json_object_add_uint (node, "priority", mp->priority);
2906   vat_json_object_add_uint (node, "weight", mp->weight);
2907
2908   if (mp->local)
2909     vat_json_object_add_uint (node, "sw_if_index",
2910                               clib_net_to_host_u32 (mp->sw_if_index));
2911   else
2912     {
2913       if (mp->is_ipv6)
2914         {
2915           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2916           vat_json_object_add_ip6 (node, "address", ip6);
2917         }
2918       else
2919         {
2920           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2921           vat_json_object_add_ip4 (node, "address", ip4);
2922         }
2923     }
2924 }
2925
2926 static void
2927 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2928                                           mp)
2929 {
2930   vat_main_t *vam = &vat_main;
2931   u8 *ls_name = 0;
2932
2933   ls_name = format (0, "%s", mp->ls_name);
2934
2935   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2936          ls_name);
2937   vec_free (ls_name);
2938 }
2939
2940 static void
2941   vl_api_one_locator_set_details_t_handler_json
2942   (vl_api_one_locator_set_details_t * mp)
2943 {
2944   vat_main_t *vam = &vat_main;
2945   vat_json_node_t *node = 0;
2946   u8 *ls_name = 0;
2947
2948   ls_name = format (0, "%s", mp->ls_name);
2949   vec_add1 (ls_name, 0);
2950
2951   if (VAT_JSON_ARRAY != vam->json_tree.type)
2952     {
2953       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2954       vat_json_init_array (&vam->json_tree);
2955     }
2956   node = vat_json_array_add (&vam->json_tree);
2957
2958   vat_json_init_object (node);
2959   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2960   vat_json_object_add_uint (node, "ls_index",
2961                             clib_net_to_host_u32 (mp->ls_index));
2962   vec_free (ls_name);
2963 }
2964
2965 typedef struct
2966 {
2967   u32 spi;
2968   u8 si;
2969 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2970
2971 uword
2972 unformat_nsh_address (unformat_input_t * input, va_list * args)
2973 {
2974   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2975   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2976 }
2977
2978 u8 *
2979 format_nsh_address_vat (u8 * s, va_list * args)
2980 {
2981   nsh_t *a = va_arg (*args, nsh_t *);
2982   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2983 }
2984
2985 static u8 *
2986 format_lisp_flat_eid (u8 * s, va_list * args)
2987 {
2988   u32 type = va_arg (*args, u32);
2989   u8 *eid = va_arg (*args, u8 *);
2990   u32 eid_len = va_arg (*args, u32);
2991
2992   switch (type)
2993     {
2994     case 0:
2995       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2996     case 1:
2997       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2998     case 2:
2999       return format (s, "%U", format_ethernet_address, eid);
3000     case 3:
3001       return format (s, "%U", format_nsh_address_vat, eid);
3002     }
3003   return 0;
3004 }
3005
3006 static u8 *
3007 format_lisp_eid_vat (u8 * s, va_list * args)
3008 {
3009   u32 type = va_arg (*args, u32);
3010   u8 *eid = va_arg (*args, u8 *);
3011   u32 eid_len = va_arg (*args, u32);
3012   u8 *seid = va_arg (*args, u8 *);
3013   u32 seid_len = va_arg (*args, u32);
3014   u32 is_src_dst = va_arg (*args, u32);
3015
3016   if (is_src_dst)
3017     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
3018
3019   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
3020
3021   return s;
3022 }
3023
3024 static void
3025 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
3026 {
3027   vat_main_t *vam = &vat_main;
3028   u8 *s = 0, *eid = 0;
3029
3030   if (~0 == mp->locator_set_index)
3031     s = format (0, "action: %d", mp->action);
3032   else
3033     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3034
3035   eid = format (0, "%U", format_lisp_eid_vat,
3036                 mp->eid_type,
3037                 mp->eid,
3038                 mp->eid_prefix_len,
3039                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3040   vec_add1 (eid, 0);
3041
3042   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3043          clib_net_to_host_u32 (mp->vni),
3044          eid,
3045          mp->is_local ? "local" : "remote",
3046          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3047          clib_net_to_host_u16 (mp->key_id), mp->key);
3048
3049   vec_free (s);
3050   vec_free (eid);
3051 }
3052
3053 static void
3054 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3055                                              * mp)
3056 {
3057   vat_main_t *vam = &vat_main;
3058   vat_json_node_t *node = 0;
3059   u8 *eid = 0;
3060
3061   if (VAT_JSON_ARRAY != vam->json_tree.type)
3062     {
3063       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3064       vat_json_init_array (&vam->json_tree);
3065     }
3066   node = vat_json_array_add (&vam->json_tree);
3067
3068   vat_json_init_object (node);
3069   if (~0 == mp->locator_set_index)
3070     vat_json_object_add_uint (node, "action", mp->action);
3071   else
3072     vat_json_object_add_uint (node, "locator_set_index",
3073                               clib_net_to_host_u32 (mp->locator_set_index));
3074
3075   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3076   if (mp->eid_type == 3)
3077     {
3078       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3079       vat_json_init_object (nsh_json);
3080       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3081       vat_json_object_add_uint (nsh_json, "spi",
3082                                 clib_net_to_host_u32 (nsh->spi));
3083       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3084     }
3085   else
3086     {
3087       eid = format (0, "%U", format_lisp_eid_vat,
3088                     mp->eid_type,
3089                     mp->eid,
3090                     mp->eid_prefix_len,
3091                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3092       vec_add1 (eid, 0);
3093       vat_json_object_add_string_copy (node, "eid", eid);
3094       vec_free (eid);
3095     }
3096   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3097   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3098   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3099
3100   if (mp->key_id)
3101     {
3102       vat_json_object_add_uint (node, "key_id",
3103                                 clib_net_to_host_u16 (mp->key_id));
3104       vat_json_object_add_string_copy (node, "key", mp->key);
3105     }
3106 }
3107
3108 static void
3109 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3110 {
3111   vat_main_t *vam = &vat_main;
3112   u8 *seid = 0, *deid = 0;
3113   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3114
3115   deid = format (0, "%U", format_lisp_eid_vat,
3116                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3117
3118   seid = format (0, "%U", format_lisp_eid_vat,
3119                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3120
3121   vec_add1 (deid, 0);
3122   vec_add1 (seid, 0);
3123
3124   if (mp->is_ip4)
3125     format_ip_address_fcn = format_ip4_address;
3126   else
3127     format_ip_address_fcn = format_ip6_address;
3128
3129
3130   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3131          clib_net_to_host_u32 (mp->vni),
3132          seid, deid,
3133          format_ip_address_fcn, mp->lloc,
3134          format_ip_address_fcn, mp->rloc,
3135          clib_net_to_host_u32 (mp->pkt_count),
3136          clib_net_to_host_u32 (mp->bytes));
3137
3138   vec_free (deid);
3139   vec_free (seid);
3140 }
3141
3142 static void
3143 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3144 {
3145   struct in6_addr ip6;
3146   struct in_addr ip4;
3147   vat_main_t *vam = &vat_main;
3148   vat_json_node_t *node = 0;
3149   u8 *deid = 0, *seid = 0;
3150
3151   if (VAT_JSON_ARRAY != vam->json_tree.type)
3152     {
3153       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3154       vat_json_init_array (&vam->json_tree);
3155     }
3156   node = vat_json_array_add (&vam->json_tree);
3157
3158   vat_json_init_object (node);
3159   deid = format (0, "%U", format_lisp_eid_vat,
3160                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3161
3162   seid = format (0, "%U", format_lisp_eid_vat,
3163                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3164
3165   vec_add1 (deid, 0);
3166   vec_add1 (seid, 0);
3167
3168   vat_json_object_add_string_copy (node, "seid", seid);
3169   vat_json_object_add_string_copy (node, "deid", deid);
3170   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3171
3172   if (mp->is_ip4)
3173     {
3174       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3175       vat_json_object_add_ip4 (node, "lloc", ip4);
3176       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3177       vat_json_object_add_ip4 (node, "rloc", ip4);
3178     }
3179   else
3180     {
3181       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3182       vat_json_object_add_ip6 (node, "lloc", ip6);
3183       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3184       vat_json_object_add_ip6 (node, "rloc", ip6);
3185     }
3186   vat_json_object_add_uint (node, "pkt_count",
3187                             clib_net_to_host_u32 (mp->pkt_count));
3188   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3189
3190   vec_free (deid);
3191   vec_free (seid);
3192 }
3193
3194 static void
3195   vl_api_one_eid_table_map_details_t_handler
3196   (vl_api_one_eid_table_map_details_t * mp)
3197 {
3198   vat_main_t *vam = &vat_main;
3199
3200   u8 *line = format (0, "%=10d%=10d",
3201                      clib_net_to_host_u32 (mp->vni),
3202                      clib_net_to_host_u32 (mp->dp_table));
3203   print (vam->ofp, "%v", line);
3204   vec_free (line);
3205 }
3206
3207 static void
3208   vl_api_one_eid_table_map_details_t_handler_json
3209   (vl_api_one_eid_table_map_details_t * mp)
3210 {
3211   vat_main_t *vam = &vat_main;
3212   vat_json_node_t *node = NULL;
3213
3214   if (VAT_JSON_ARRAY != vam->json_tree.type)
3215     {
3216       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3217       vat_json_init_array (&vam->json_tree);
3218     }
3219   node = vat_json_array_add (&vam->json_tree);
3220   vat_json_init_object (node);
3221   vat_json_object_add_uint (node, "dp_table",
3222                             clib_net_to_host_u32 (mp->dp_table));
3223   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3224 }
3225
3226 static void
3227   vl_api_one_eid_table_vni_details_t_handler
3228   (vl_api_one_eid_table_vni_details_t * mp)
3229 {
3230   vat_main_t *vam = &vat_main;
3231
3232   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3233   print (vam->ofp, "%v", line);
3234   vec_free (line);
3235 }
3236
3237 static void
3238   vl_api_one_eid_table_vni_details_t_handler_json
3239   (vl_api_one_eid_table_vni_details_t * mp)
3240 {
3241   vat_main_t *vam = &vat_main;
3242   vat_json_node_t *node = NULL;
3243
3244   if (VAT_JSON_ARRAY != vam->json_tree.type)
3245     {
3246       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3247       vat_json_init_array (&vam->json_tree);
3248     }
3249   node = vat_json_array_add (&vam->json_tree);
3250   vat_json_init_object (node);
3251   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3252 }
3253
3254 static void
3255   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3256   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3257 {
3258   vat_main_t *vam = &vat_main;
3259   int retval = clib_net_to_host_u32 (mp->retval);
3260
3261   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3262   print (vam->ofp, "fallback threshold value: %d", mp->value);
3263
3264   vam->retval = retval;
3265   vam->result_ready = 1;
3266 }
3267
3268 static void
3269   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3270   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3271 {
3272   vat_main_t *vam = &vat_main;
3273   vat_json_node_t _node, *node = &_node;
3274   int retval = clib_net_to_host_u32 (mp->retval);
3275
3276   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3277   vat_json_init_object (node);
3278   vat_json_object_add_uint (node, "value", mp->value);
3279
3280   vat_json_print (vam->ofp, node);
3281   vat_json_free (node);
3282
3283   vam->retval = retval;
3284   vam->result_ready = 1;
3285 }
3286
3287 static void
3288   vl_api_show_one_map_register_state_reply_t_handler
3289   (vl_api_show_one_map_register_state_reply_t * mp)
3290 {
3291   vat_main_t *vam = &vat_main;
3292   int retval = clib_net_to_host_u32 (mp->retval);
3293
3294   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3295
3296   vam->retval = retval;
3297   vam->result_ready = 1;
3298 }
3299
3300 static void
3301   vl_api_show_one_map_register_state_reply_t_handler_json
3302   (vl_api_show_one_map_register_state_reply_t * mp)
3303 {
3304   vat_main_t *vam = &vat_main;
3305   vat_json_node_t _node, *node = &_node;
3306   int retval = clib_net_to_host_u32 (mp->retval);
3307
3308   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3309
3310   vat_json_init_object (node);
3311   vat_json_object_add_string_copy (node, "state", s);
3312
3313   vat_json_print (vam->ofp, node);
3314   vat_json_free (node);
3315
3316   vam->retval = retval;
3317   vam->result_ready = 1;
3318   vec_free (s);
3319 }
3320
3321 static void
3322   vl_api_show_one_rloc_probe_state_reply_t_handler
3323   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3324 {
3325   vat_main_t *vam = &vat_main;
3326   int retval = clib_net_to_host_u32 (mp->retval);
3327
3328   if (retval)
3329     goto end;
3330
3331   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3332 end:
3333   vam->retval = retval;
3334   vam->result_ready = 1;
3335 }
3336
3337 static void
3338   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3339   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3340 {
3341   vat_main_t *vam = &vat_main;
3342   vat_json_node_t _node, *node = &_node;
3343   int retval = clib_net_to_host_u32 (mp->retval);
3344
3345   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3346   vat_json_init_object (node);
3347   vat_json_object_add_string_copy (node, "state", s);
3348
3349   vat_json_print (vam->ofp, node);
3350   vat_json_free (node);
3351
3352   vam->retval = retval;
3353   vam->result_ready = 1;
3354   vec_free (s);
3355 }
3356
3357 static void
3358   vl_api_show_one_stats_enable_disable_reply_t_handler
3359   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3360 {
3361   vat_main_t *vam = &vat_main;
3362   int retval = clib_net_to_host_u32 (mp->retval);
3363
3364   if (retval)
3365     goto end;
3366
3367   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3368 end:
3369   vam->retval = retval;
3370   vam->result_ready = 1;
3371 }
3372
3373 static void
3374   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3375   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3376 {
3377   vat_main_t *vam = &vat_main;
3378   vat_json_node_t _node, *node = &_node;
3379   int retval = clib_net_to_host_u32 (mp->retval);
3380
3381   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3382   vat_json_init_object (node);
3383   vat_json_object_add_string_copy (node, "state", s);
3384
3385   vat_json_print (vam->ofp, node);
3386   vat_json_free (node);
3387
3388   vam->retval = retval;
3389   vam->result_ready = 1;
3390   vec_free (s);
3391 }
3392
3393 static void
3394 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3395 {
3396   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3397   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3398   e->vni = clib_net_to_host_u32 (e->vni);
3399 }
3400
3401 static void
3402   gpe_fwd_entries_get_reply_t_net_to_host
3403   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3404 {
3405   u32 i;
3406
3407   mp->count = clib_net_to_host_u32 (mp->count);
3408   for (i = 0; i < mp->count; i++)
3409     {
3410       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3411     }
3412 }
3413
3414 static u8 *
3415 format_gpe_encap_mode (u8 * s, va_list * args)
3416 {
3417   u32 mode = va_arg (*args, u32);
3418
3419   switch (mode)
3420     {
3421     case 0:
3422       return format (s, "lisp");
3423     case 1:
3424       return format (s, "vxlan");
3425     }
3426   return 0;
3427 }
3428
3429 static void
3430   vl_api_gpe_get_encap_mode_reply_t_handler
3431   (vl_api_gpe_get_encap_mode_reply_t * mp)
3432 {
3433   vat_main_t *vam = &vat_main;
3434
3435   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3436   vam->retval = ntohl (mp->retval);
3437   vam->result_ready = 1;
3438 }
3439
3440 static void
3441   vl_api_gpe_get_encap_mode_reply_t_handler_json
3442   (vl_api_gpe_get_encap_mode_reply_t * mp)
3443 {
3444   vat_main_t *vam = &vat_main;
3445   vat_json_node_t node;
3446
3447   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3448   vec_add1 (encap_mode, 0);
3449
3450   vat_json_init_object (&node);
3451   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3452
3453   vec_free (encap_mode);
3454   vat_json_print (vam->ofp, &node);
3455   vat_json_free (&node);
3456
3457   vam->retval = ntohl (mp->retval);
3458   vam->result_ready = 1;
3459 }
3460
3461 static void
3462   vl_api_gpe_fwd_entry_path_details_t_handler
3463   (vl_api_gpe_fwd_entry_path_details_t * mp)
3464 {
3465   vat_main_t *vam = &vat_main;
3466   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3467
3468   if (mp->lcl_loc.is_ip4)
3469     format_ip_address_fcn = format_ip4_address;
3470   else
3471     format_ip_address_fcn = format_ip6_address;
3472
3473   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3474          format_ip_address_fcn, &mp->lcl_loc,
3475          format_ip_address_fcn, &mp->rmt_loc);
3476 }
3477
3478 static void
3479 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3480 {
3481   struct in6_addr ip6;
3482   struct in_addr ip4;
3483
3484   if (loc->is_ip4)
3485     {
3486       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3487       vat_json_object_add_ip4 (n, "address", ip4);
3488     }
3489   else
3490     {
3491       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3492       vat_json_object_add_ip6 (n, "address", ip6);
3493     }
3494   vat_json_object_add_uint (n, "weight", loc->weight);
3495 }
3496
3497 static void
3498   vl_api_gpe_fwd_entry_path_details_t_handler_json
3499   (vl_api_gpe_fwd_entry_path_details_t * mp)
3500 {
3501   vat_main_t *vam = &vat_main;
3502   vat_json_node_t *node = NULL;
3503   vat_json_node_t *loc_node;
3504
3505   if (VAT_JSON_ARRAY != vam->json_tree.type)
3506     {
3507       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3508       vat_json_init_array (&vam->json_tree);
3509     }
3510   node = vat_json_array_add (&vam->json_tree);
3511   vat_json_init_object (node);
3512
3513   loc_node = vat_json_object_add (node, "local_locator");
3514   vat_json_init_object (loc_node);
3515   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3516
3517   loc_node = vat_json_object_add (node, "remote_locator");
3518   vat_json_init_object (loc_node);
3519   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3520 }
3521
3522 static void
3523   vl_api_gpe_fwd_entries_get_reply_t_handler
3524   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3525 {
3526   vat_main_t *vam = &vat_main;
3527   u32 i;
3528   int retval = clib_net_to_host_u32 (mp->retval);
3529   vl_api_gpe_fwd_entry_t *e;
3530
3531   if (retval)
3532     goto end;
3533
3534   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3535
3536   for (i = 0; i < mp->count; i++)
3537     {
3538       e = &mp->entries[i];
3539       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3540              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3541              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3542     }
3543
3544 end:
3545   vam->retval = retval;
3546   vam->result_ready = 1;
3547 }
3548
3549 static void
3550   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3551   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3552 {
3553   u8 *s = 0;
3554   vat_main_t *vam = &vat_main;
3555   vat_json_node_t *e = 0, root;
3556   u32 i;
3557   int retval = clib_net_to_host_u32 (mp->retval);
3558   vl_api_gpe_fwd_entry_t *fwd;
3559
3560   if (retval)
3561     goto end;
3562
3563   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3564   vat_json_init_array (&root);
3565
3566   for (i = 0; i < mp->count; i++)
3567     {
3568       e = vat_json_array_add (&root);
3569       fwd = &mp->entries[i];
3570
3571       vat_json_init_object (e);
3572       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3573       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3574       vat_json_object_add_int (e, "vni", fwd->vni);
3575       vat_json_object_add_int (e, "action", fwd->action);
3576
3577       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3578                   fwd->leid_prefix_len);
3579       vec_add1 (s, 0);
3580       vat_json_object_add_string_copy (e, "leid", s);
3581       vec_free (s);
3582
3583       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3584                   fwd->reid_prefix_len);
3585       vec_add1 (s, 0);
3586       vat_json_object_add_string_copy (e, "reid", s);
3587       vec_free (s);
3588     }
3589
3590   vat_json_print (vam->ofp, &root);
3591   vat_json_free (&root);
3592
3593 end:
3594   vam->retval = retval;
3595   vam->result_ready = 1;
3596 }
3597
3598 static void
3599   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3600   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3601 {
3602   vat_main_t *vam = &vat_main;
3603   u32 i, n;
3604   int retval = clib_net_to_host_u32 (mp->retval);
3605   vl_api_gpe_native_fwd_rpath_t *r;
3606
3607   if (retval)
3608     goto end;
3609
3610   n = clib_net_to_host_u32 (mp->count);
3611
3612   for (i = 0; i < n; i++)
3613     {
3614       r = &mp->entries[i];
3615       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3616              clib_net_to_host_u32 (r->fib_index),
3617              clib_net_to_host_u32 (r->nh_sw_if_index),
3618              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3619     }
3620
3621 end:
3622   vam->retval = retval;
3623   vam->result_ready = 1;
3624 }
3625
3626 static void
3627   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3628   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3629 {
3630   vat_main_t *vam = &vat_main;
3631   vat_json_node_t root, *e;
3632   u32 i, n;
3633   int retval = clib_net_to_host_u32 (mp->retval);
3634   vl_api_gpe_native_fwd_rpath_t *r;
3635   u8 *s;
3636
3637   if (retval)
3638     goto end;
3639
3640   n = clib_net_to_host_u32 (mp->count);
3641   vat_json_init_array (&root);
3642
3643   for (i = 0; i < n; i++)
3644     {
3645       e = vat_json_array_add (&root);
3646       vat_json_init_object (e);
3647       r = &mp->entries[i];
3648       s =
3649         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3650                 r->nh_addr);
3651       vec_add1 (s, 0);
3652       vat_json_object_add_string_copy (e, "ip4", s);
3653       vec_free (s);
3654
3655       vat_json_object_add_uint (e, "fib_index",
3656                                 clib_net_to_host_u32 (r->fib_index));
3657       vat_json_object_add_uint (e, "nh_sw_if_index",
3658                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3659     }
3660
3661   vat_json_print (vam->ofp, &root);
3662   vat_json_free (&root);
3663
3664 end:
3665   vam->retval = retval;
3666   vam->result_ready = 1;
3667 }
3668
3669 static void
3670   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3671   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3672 {
3673   vat_main_t *vam = &vat_main;
3674   u32 i, n;
3675   int retval = clib_net_to_host_u32 (mp->retval);
3676
3677   if (retval)
3678     goto end;
3679
3680   n = clib_net_to_host_u32 (mp->count);
3681
3682   for (i = 0; i < n; i++)
3683     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3684
3685 end:
3686   vam->retval = retval;
3687   vam->result_ready = 1;
3688 }
3689
3690 static void
3691   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3692   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3693 {
3694   vat_main_t *vam = &vat_main;
3695   vat_json_node_t root;
3696   u32 i, n;
3697   int retval = clib_net_to_host_u32 (mp->retval);
3698
3699   if (retval)
3700     goto end;
3701
3702   n = clib_net_to_host_u32 (mp->count);
3703   vat_json_init_array (&root);
3704
3705   for (i = 0; i < n; i++)
3706     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3707
3708   vat_json_print (vam->ofp, &root);
3709   vat_json_free (&root);
3710
3711 end:
3712   vam->retval = retval;
3713   vam->result_ready = 1;
3714 }
3715
3716 static void
3717   vl_api_one_ndp_entries_get_reply_t_handler
3718   (vl_api_one_ndp_entries_get_reply_t * mp)
3719 {
3720   vat_main_t *vam = &vat_main;
3721   u32 i, n;
3722   int retval = clib_net_to_host_u32 (mp->retval);
3723
3724   if (retval)
3725     goto end;
3726
3727   n = clib_net_to_host_u32 (mp->count);
3728
3729   for (i = 0; i < n; i++)
3730     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3731            format_ethernet_address, mp->entries[i].mac);
3732
3733 end:
3734   vam->retval = retval;
3735   vam->result_ready = 1;
3736 }
3737
3738 static void
3739   vl_api_one_ndp_entries_get_reply_t_handler_json
3740   (vl_api_one_ndp_entries_get_reply_t * mp)
3741 {
3742   u8 *s = 0;
3743   vat_main_t *vam = &vat_main;
3744   vat_json_node_t *e = 0, root;
3745   u32 i, n;
3746   int retval = clib_net_to_host_u32 (mp->retval);
3747   vl_api_one_ndp_entry_t *arp_entry;
3748
3749   if (retval)
3750     goto end;
3751
3752   n = clib_net_to_host_u32 (mp->count);
3753   vat_json_init_array (&root);
3754
3755   for (i = 0; i < n; i++)
3756     {
3757       e = vat_json_array_add (&root);
3758       arp_entry = &mp->entries[i];
3759
3760       vat_json_init_object (e);
3761       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3762       vec_add1 (s, 0);
3763
3764       vat_json_object_add_string_copy (e, "mac", s);
3765       vec_free (s);
3766
3767       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3768       vec_add1 (s, 0);
3769       vat_json_object_add_string_copy (e, "ip6", s);
3770       vec_free (s);
3771     }
3772
3773   vat_json_print (vam->ofp, &root);
3774   vat_json_free (&root);
3775
3776 end:
3777   vam->retval = retval;
3778   vam->result_ready = 1;
3779 }
3780
3781 static void
3782   vl_api_one_l2_arp_entries_get_reply_t_handler
3783   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3784 {
3785   vat_main_t *vam = &vat_main;
3786   u32 i, n;
3787   int retval = clib_net_to_host_u32 (mp->retval);
3788
3789   if (retval)
3790     goto end;
3791
3792   n = clib_net_to_host_u32 (mp->count);
3793
3794   for (i = 0; i < n; i++)
3795     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3796            format_ethernet_address, mp->entries[i].mac);
3797
3798 end:
3799   vam->retval = retval;
3800   vam->result_ready = 1;
3801 }
3802
3803 static void
3804   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3805   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3806 {
3807   u8 *s = 0;
3808   vat_main_t *vam = &vat_main;
3809   vat_json_node_t *e = 0, root;
3810   u32 i, n;
3811   int retval = clib_net_to_host_u32 (mp->retval);
3812   vl_api_one_l2_arp_entry_t *arp_entry;
3813
3814   if (retval)
3815     goto end;
3816
3817   n = clib_net_to_host_u32 (mp->count);
3818   vat_json_init_array (&root);
3819
3820   for (i = 0; i < n; i++)
3821     {
3822       e = vat_json_array_add (&root);
3823       arp_entry = &mp->entries[i];
3824
3825       vat_json_init_object (e);
3826       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3827       vec_add1 (s, 0);
3828
3829       vat_json_object_add_string_copy (e, "mac", s);
3830       vec_free (s);
3831
3832       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3833       vec_add1 (s, 0);
3834       vat_json_object_add_string_copy (e, "ip4", s);
3835       vec_free (s);
3836     }
3837
3838   vat_json_print (vam->ofp, &root);
3839   vat_json_free (&root);
3840
3841 end:
3842   vam->retval = retval;
3843   vam->result_ready = 1;
3844 }
3845
3846 static void
3847 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3848 {
3849   vat_main_t *vam = &vat_main;
3850   u32 i, n;
3851   int retval = clib_net_to_host_u32 (mp->retval);
3852
3853   if (retval)
3854     goto end;
3855
3856   n = clib_net_to_host_u32 (mp->count);
3857
3858   for (i = 0; i < n; i++)
3859     {
3860       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3861     }
3862
3863 end:
3864   vam->retval = retval;
3865   vam->result_ready = 1;
3866 }
3867
3868 static void
3869   vl_api_one_ndp_bd_get_reply_t_handler_json
3870   (vl_api_one_ndp_bd_get_reply_t * mp)
3871 {
3872   vat_main_t *vam = &vat_main;
3873   vat_json_node_t root;
3874   u32 i, n;
3875   int retval = clib_net_to_host_u32 (mp->retval);
3876
3877   if (retval)
3878     goto end;
3879
3880   n = clib_net_to_host_u32 (mp->count);
3881   vat_json_init_array (&root);
3882
3883   for (i = 0; i < n; i++)
3884     {
3885       vat_json_array_add_uint (&root,
3886                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3887     }
3888
3889   vat_json_print (vam->ofp, &root);
3890   vat_json_free (&root);
3891
3892 end:
3893   vam->retval = retval;
3894   vam->result_ready = 1;
3895 }
3896
3897 static void
3898   vl_api_one_l2_arp_bd_get_reply_t_handler
3899   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3900 {
3901   vat_main_t *vam = &vat_main;
3902   u32 i, n;
3903   int retval = clib_net_to_host_u32 (mp->retval);
3904
3905   if (retval)
3906     goto end;
3907
3908   n = clib_net_to_host_u32 (mp->count);
3909
3910   for (i = 0; i < n; i++)
3911     {
3912       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3913     }
3914
3915 end:
3916   vam->retval = retval;
3917   vam->result_ready = 1;
3918 }
3919
3920 static void
3921   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3922   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3923 {
3924   vat_main_t *vam = &vat_main;
3925   vat_json_node_t root;
3926   u32 i, n;
3927   int retval = clib_net_to_host_u32 (mp->retval);
3928
3929   if (retval)
3930     goto end;
3931
3932   n = clib_net_to_host_u32 (mp->count);
3933   vat_json_init_array (&root);
3934
3935   for (i = 0; i < n; i++)
3936     {
3937       vat_json_array_add_uint (&root,
3938                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3939     }
3940
3941   vat_json_print (vam->ofp, &root);
3942   vat_json_free (&root);
3943
3944 end:
3945   vam->retval = retval;
3946   vam->result_ready = 1;
3947 }
3948
3949 static void
3950   vl_api_one_adjacencies_get_reply_t_handler
3951   (vl_api_one_adjacencies_get_reply_t * mp)
3952 {
3953   vat_main_t *vam = &vat_main;
3954   u32 i, n;
3955   int retval = clib_net_to_host_u32 (mp->retval);
3956   vl_api_one_adjacency_t *a;
3957
3958   if (retval)
3959     goto end;
3960
3961   n = clib_net_to_host_u32 (mp->count);
3962
3963   for (i = 0; i < n; i++)
3964     {
3965       a = &mp->adjacencies[i];
3966       print (vam->ofp, "%U %40U",
3967              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3968              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3969     }
3970
3971 end:
3972   vam->retval = retval;
3973   vam->result_ready = 1;
3974 }
3975
3976 static void
3977   vl_api_one_adjacencies_get_reply_t_handler_json
3978   (vl_api_one_adjacencies_get_reply_t * mp)
3979 {
3980   u8 *s = 0;
3981   vat_main_t *vam = &vat_main;
3982   vat_json_node_t *e = 0, root;
3983   u32 i, n;
3984   int retval = clib_net_to_host_u32 (mp->retval);
3985   vl_api_one_adjacency_t *a;
3986
3987   if (retval)
3988     goto end;
3989
3990   n = clib_net_to_host_u32 (mp->count);
3991   vat_json_init_array (&root);
3992
3993   for (i = 0; i < n; i++)
3994     {
3995       e = vat_json_array_add (&root);
3996       a = &mp->adjacencies[i];
3997
3998       vat_json_init_object (e);
3999       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
4000                   a->leid_prefix_len);
4001       vec_add1 (s, 0);
4002       vat_json_object_add_string_copy (e, "leid", s);
4003       vec_free (s);
4004
4005       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
4006                   a->reid_prefix_len);
4007       vec_add1 (s, 0);
4008       vat_json_object_add_string_copy (e, "reid", s);
4009       vec_free (s);
4010     }
4011
4012   vat_json_print (vam->ofp, &root);
4013   vat_json_free (&root);
4014
4015 end:
4016   vam->retval = retval;
4017   vam->result_ready = 1;
4018 }
4019
4020 static void
4021 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
4022 {
4023   vat_main_t *vam = &vat_main;
4024
4025   print (vam->ofp, "%=20U",
4026          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4027          mp->ip_address);
4028 }
4029
4030 static void
4031   vl_api_one_map_server_details_t_handler_json
4032   (vl_api_one_map_server_details_t * mp)
4033 {
4034   vat_main_t *vam = &vat_main;
4035   vat_json_node_t *node = NULL;
4036   struct in6_addr ip6;
4037   struct in_addr ip4;
4038
4039   if (VAT_JSON_ARRAY != vam->json_tree.type)
4040     {
4041       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4042       vat_json_init_array (&vam->json_tree);
4043     }
4044   node = vat_json_array_add (&vam->json_tree);
4045
4046   vat_json_init_object (node);
4047   if (mp->is_ipv6)
4048     {
4049       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4050       vat_json_object_add_ip6 (node, "map-server", ip6);
4051     }
4052   else
4053     {
4054       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4055       vat_json_object_add_ip4 (node, "map-server", ip4);
4056     }
4057 }
4058
4059 static void
4060 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4061                                            * mp)
4062 {
4063   vat_main_t *vam = &vat_main;
4064
4065   print (vam->ofp, "%=20U",
4066          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4067          mp->ip_address);
4068 }
4069
4070 static void
4071   vl_api_one_map_resolver_details_t_handler_json
4072   (vl_api_one_map_resolver_details_t * mp)
4073 {
4074   vat_main_t *vam = &vat_main;
4075   vat_json_node_t *node = NULL;
4076   struct in6_addr ip6;
4077   struct in_addr ip4;
4078
4079   if (VAT_JSON_ARRAY != vam->json_tree.type)
4080     {
4081       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4082       vat_json_init_array (&vam->json_tree);
4083     }
4084   node = vat_json_array_add (&vam->json_tree);
4085
4086   vat_json_init_object (node);
4087   if (mp->is_ipv6)
4088     {
4089       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4090       vat_json_object_add_ip6 (node, "map resolver", ip6);
4091     }
4092   else
4093     {
4094       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4095       vat_json_object_add_ip4 (node, "map resolver", ip4);
4096     }
4097 }
4098
4099 static void
4100 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4101 {
4102   vat_main_t *vam = &vat_main;
4103   i32 retval = ntohl (mp->retval);
4104
4105   if (0 <= retval)
4106     {
4107       print (vam->ofp, "feature: %s\ngpe: %s",
4108              mp->feature_status ? "enabled" : "disabled",
4109              mp->gpe_status ? "enabled" : "disabled");
4110     }
4111
4112   vam->retval = retval;
4113   vam->result_ready = 1;
4114 }
4115
4116 static void
4117   vl_api_show_one_status_reply_t_handler_json
4118   (vl_api_show_one_status_reply_t * mp)
4119 {
4120   vat_main_t *vam = &vat_main;
4121   vat_json_node_t node;
4122   u8 *gpe_status = NULL;
4123   u8 *feature_status = NULL;
4124
4125   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4126   feature_status = format (0, "%s",
4127                            mp->feature_status ? "enabled" : "disabled");
4128   vec_add1 (gpe_status, 0);
4129   vec_add1 (feature_status, 0);
4130
4131   vat_json_init_object (&node);
4132   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4133   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4134
4135   vec_free (gpe_status);
4136   vec_free (feature_status);
4137
4138   vat_json_print (vam->ofp, &node);
4139   vat_json_free (&node);
4140
4141   vam->retval = ntohl (mp->retval);
4142   vam->result_ready = 1;
4143 }
4144
4145 static void
4146   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4147   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4148 {
4149   vat_main_t *vam = &vat_main;
4150   i32 retval = ntohl (mp->retval);
4151
4152   if (retval >= 0)
4153     {
4154       print (vam->ofp, "%=20s", mp->locator_set_name);
4155     }
4156
4157   vam->retval = retval;
4158   vam->result_ready = 1;
4159 }
4160
4161 static void
4162   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4163   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4164 {
4165   vat_main_t *vam = &vat_main;
4166   vat_json_node_t *node = NULL;
4167
4168   if (VAT_JSON_ARRAY != vam->json_tree.type)
4169     {
4170       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4171       vat_json_init_array (&vam->json_tree);
4172     }
4173   node = vat_json_array_add (&vam->json_tree);
4174
4175   vat_json_init_object (node);
4176   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4177
4178   vat_json_print (vam->ofp, node);
4179   vat_json_free (node);
4180
4181   vam->retval = ntohl (mp->retval);
4182   vam->result_ready = 1;
4183 }
4184
4185 static u8 *
4186 format_lisp_map_request_mode (u8 * s, va_list * args)
4187 {
4188   u32 mode = va_arg (*args, u32);
4189
4190   switch (mode)
4191     {
4192     case 0:
4193       return format (0, "dst-only");
4194     case 1:
4195       return format (0, "src-dst");
4196     }
4197   return 0;
4198 }
4199
4200 static void
4201   vl_api_show_one_map_request_mode_reply_t_handler
4202   (vl_api_show_one_map_request_mode_reply_t * mp)
4203 {
4204   vat_main_t *vam = &vat_main;
4205   i32 retval = ntohl (mp->retval);
4206
4207   if (0 <= retval)
4208     {
4209       u32 mode = mp->mode;
4210       print (vam->ofp, "map_request_mode: %U",
4211              format_lisp_map_request_mode, mode);
4212     }
4213
4214   vam->retval = retval;
4215   vam->result_ready = 1;
4216 }
4217
4218 static void
4219   vl_api_show_one_map_request_mode_reply_t_handler_json
4220   (vl_api_show_one_map_request_mode_reply_t * mp)
4221 {
4222   vat_main_t *vam = &vat_main;
4223   vat_json_node_t node;
4224   u8 *s = 0;
4225   u32 mode;
4226
4227   mode = mp->mode;
4228   s = format (0, "%U", format_lisp_map_request_mode, mode);
4229   vec_add1 (s, 0);
4230
4231   vat_json_init_object (&node);
4232   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4233   vat_json_print (vam->ofp, &node);
4234   vat_json_free (&node);
4235
4236   vec_free (s);
4237   vam->retval = ntohl (mp->retval);
4238   vam->result_ready = 1;
4239 }
4240
4241 static void
4242   vl_api_one_show_xtr_mode_reply_t_handler
4243   (vl_api_one_show_xtr_mode_reply_t * mp)
4244 {
4245   vat_main_t *vam = &vat_main;
4246   i32 retval = ntohl (mp->retval);
4247
4248   if (0 <= retval)
4249     {
4250       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4251     }
4252
4253   vam->retval = retval;
4254   vam->result_ready = 1;
4255 }
4256
4257 static void
4258   vl_api_one_show_xtr_mode_reply_t_handler_json
4259   (vl_api_one_show_xtr_mode_reply_t * mp)
4260 {
4261   vat_main_t *vam = &vat_main;
4262   vat_json_node_t node;
4263   u8 *status = 0;
4264
4265   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4266   vec_add1 (status, 0);
4267
4268   vat_json_init_object (&node);
4269   vat_json_object_add_string_copy (&node, "status", status);
4270
4271   vec_free (status);
4272
4273   vat_json_print (vam->ofp, &node);
4274   vat_json_free (&node);
4275
4276   vam->retval = ntohl (mp->retval);
4277   vam->result_ready = 1;
4278 }
4279
4280 static void
4281   vl_api_one_show_pitr_mode_reply_t_handler
4282   (vl_api_one_show_pitr_mode_reply_t * mp)
4283 {
4284   vat_main_t *vam = &vat_main;
4285   i32 retval = ntohl (mp->retval);
4286
4287   if (0 <= retval)
4288     {
4289       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4290     }
4291
4292   vam->retval = retval;
4293   vam->result_ready = 1;
4294 }
4295
4296 static void
4297   vl_api_one_show_pitr_mode_reply_t_handler_json
4298   (vl_api_one_show_pitr_mode_reply_t * mp)
4299 {
4300   vat_main_t *vam = &vat_main;
4301   vat_json_node_t node;
4302   u8 *status = 0;
4303
4304   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4305   vec_add1 (status, 0);
4306
4307   vat_json_init_object (&node);
4308   vat_json_object_add_string_copy (&node, "status", status);
4309
4310   vec_free (status);
4311
4312   vat_json_print (vam->ofp, &node);
4313   vat_json_free (&node);
4314
4315   vam->retval = ntohl (mp->retval);
4316   vam->result_ready = 1;
4317 }
4318
4319 static void
4320   vl_api_one_show_petr_mode_reply_t_handler
4321   (vl_api_one_show_petr_mode_reply_t * mp)
4322 {
4323   vat_main_t *vam = &vat_main;
4324   i32 retval = ntohl (mp->retval);
4325
4326   if (0 <= retval)
4327     {
4328       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4329     }
4330
4331   vam->retval = retval;
4332   vam->result_ready = 1;
4333 }
4334
4335 static void
4336   vl_api_one_show_petr_mode_reply_t_handler_json
4337   (vl_api_one_show_petr_mode_reply_t * mp)
4338 {
4339   vat_main_t *vam = &vat_main;
4340   vat_json_node_t node;
4341   u8 *status = 0;
4342
4343   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4344   vec_add1 (status, 0);
4345
4346   vat_json_init_object (&node);
4347   vat_json_object_add_string_copy (&node, "status", status);
4348
4349   vec_free (status);
4350
4351   vat_json_print (vam->ofp, &node);
4352   vat_json_free (&node);
4353
4354   vam->retval = ntohl (mp->retval);
4355   vam->result_ready = 1;
4356 }
4357
4358 static void
4359   vl_api_show_one_use_petr_reply_t_handler
4360   (vl_api_show_one_use_petr_reply_t * mp)
4361 {
4362   vat_main_t *vam = &vat_main;
4363   i32 retval = ntohl (mp->retval);
4364
4365   if (0 <= retval)
4366     {
4367       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4368       if (mp->status)
4369         {
4370           print (vam->ofp, "Proxy-ETR address; %U",
4371                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4372                  mp->address);
4373         }
4374     }
4375
4376   vam->retval = retval;
4377   vam->result_ready = 1;
4378 }
4379
4380 static void
4381   vl_api_show_one_use_petr_reply_t_handler_json
4382   (vl_api_show_one_use_petr_reply_t * mp)
4383 {
4384   vat_main_t *vam = &vat_main;
4385   vat_json_node_t node;
4386   u8 *status = 0;
4387   struct in_addr ip4;
4388   struct in6_addr ip6;
4389
4390   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4391   vec_add1 (status, 0);
4392
4393   vat_json_init_object (&node);
4394   vat_json_object_add_string_copy (&node, "status", status);
4395   if (mp->status)
4396     {
4397       if (mp->is_ip4)
4398         {
4399           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4400           vat_json_object_add_ip6 (&node, "address", ip6);
4401         }
4402       else
4403         {
4404           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4405           vat_json_object_add_ip4 (&node, "address", ip4);
4406         }
4407     }
4408
4409   vec_free (status);
4410
4411   vat_json_print (vam->ofp, &node);
4412   vat_json_free (&node);
4413
4414   vam->retval = ntohl (mp->retval);
4415   vam->result_ready = 1;
4416 }
4417
4418 static void
4419   vl_api_show_one_nsh_mapping_reply_t_handler
4420   (vl_api_show_one_nsh_mapping_reply_t * mp)
4421 {
4422   vat_main_t *vam = &vat_main;
4423   i32 retval = ntohl (mp->retval);
4424
4425   if (0 <= retval)
4426     {
4427       print (vam->ofp, "%-20s%-16s",
4428              mp->is_set ? "set" : "not-set",
4429              mp->is_set ? (char *) mp->locator_set_name : "");
4430     }
4431
4432   vam->retval = retval;
4433   vam->result_ready = 1;
4434 }
4435
4436 static void
4437   vl_api_show_one_nsh_mapping_reply_t_handler_json
4438   (vl_api_show_one_nsh_mapping_reply_t * mp)
4439 {
4440   vat_main_t *vam = &vat_main;
4441   vat_json_node_t node;
4442   u8 *status = 0;
4443
4444   status = format (0, "%s", mp->is_set ? "yes" : "no");
4445   vec_add1 (status, 0);
4446
4447   vat_json_init_object (&node);
4448   vat_json_object_add_string_copy (&node, "is_set", status);
4449   if (mp->is_set)
4450     {
4451       vat_json_object_add_string_copy (&node, "locator_set",
4452                                        mp->locator_set_name);
4453     }
4454
4455   vec_free (status);
4456
4457   vat_json_print (vam->ofp, &node);
4458   vat_json_free (&node);
4459
4460   vam->retval = ntohl (mp->retval);
4461   vam->result_ready = 1;
4462 }
4463
4464 static void
4465   vl_api_show_one_map_register_ttl_reply_t_handler
4466   (vl_api_show_one_map_register_ttl_reply_t * mp)
4467 {
4468   vat_main_t *vam = &vat_main;
4469   i32 retval = ntohl (mp->retval);
4470
4471   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4472
4473   if (0 <= retval)
4474     {
4475       print (vam->ofp, "ttl: %u", mp->ttl);
4476     }
4477
4478   vam->retval = retval;
4479   vam->result_ready = 1;
4480 }
4481
4482 static void
4483   vl_api_show_one_map_register_ttl_reply_t_handler_json
4484   (vl_api_show_one_map_register_ttl_reply_t * mp)
4485 {
4486   vat_main_t *vam = &vat_main;
4487   vat_json_node_t node;
4488
4489   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4490   vat_json_init_object (&node);
4491   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4492
4493   vat_json_print (vam->ofp, &node);
4494   vat_json_free (&node);
4495
4496   vam->retval = ntohl (mp->retval);
4497   vam->result_ready = 1;
4498 }
4499
4500 static void
4501 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4502 {
4503   vat_main_t *vam = &vat_main;
4504   i32 retval = ntohl (mp->retval);
4505
4506   if (0 <= retval)
4507     {
4508       print (vam->ofp, "%-20s%-16s",
4509              mp->status ? "enabled" : "disabled",
4510              mp->status ? (char *) mp->locator_set_name : "");
4511     }
4512
4513   vam->retval = retval;
4514   vam->result_ready = 1;
4515 }
4516
4517 static void
4518 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4519 {
4520   vat_main_t *vam = &vat_main;
4521   vat_json_node_t node;
4522   u8 *status = 0;
4523
4524   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4525   vec_add1 (status, 0);
4526
4527   vat_json_init_object (&node);
4528   vat_json_object_add_string_copy (&node, "status", status);
4529   if (mp->status)
4530     {
4531       vat_json_object_add_string_copy (&node, "locator_set",
4532                                        mp->locator_set_name);
4533     }
4534
4535   vec_free (status);
4536
4537   vat_json_print (vam->ofp, &node);
4538   vat_json_free (&node);
4539
4540   vam->retval = ntohl (mp->retval);
4541   vam->result_ready = 1;
4542 }
4543
4544 static u8 *
4545 format_policer_type (u8 * s, va_list * va)
4546 {
4547   u32 i = va_arg (*va, u32);
4548
4549   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4550     s = format (s, "1r2c");
4551   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4552     s = format (s, "1r3c");
4553   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4554     s = format (s, "2r3c-2698");
4555   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4556     s = format (s, "2r3c-4115");
4557   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4558     s = format (s, "2r3c-mef5cf1");
4559   else
4560     s = format (s, "ILLEGAL");
4561   return s;
4562 }
4563
4564 static u8 *
4565 format_policer_rate_type (u8 * s, va_list * va)
4566 {
4567   u32 i = va_arg (*va, u32);
4568
4569   if (i == SSE2_QOS_RATE_KBPS)
4570     s = format (s, "kbps");
4571   else if (i == SSE2_QOS_RATE_PPS)
4572     s = format (s, "pps");
4573   else
4574     s = format (s, "ILLEGAL");
4575   return s;
4576 }
4577
4578 static u8 *
4579 format_policer_round_type (u8 * s, va_list * va)
4580 {
4581   u32 i = va_arg (*va, u32);
4582
4583   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4584     s = format (s, "closest");
4585   else if (i == SSE2_QOS_ROUND_TO_UP)
4586     s = format (s, "up");
4587   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4588     s = format (s, "down");
4589   else
4590     s = format (s, "ILLEGAL");
4591   return s;
4592 }
4593
4594 static u8 *
4595 format_policer_action_type (u8 * s, va_list * va)
4596 {
4597   u32 i = va_arg (*va, u32);
4598
4599   if (i == SSE2_QOS_ACTION_DROP)
4600     s = format (s, "drop");
4601   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4602     s = format (s, "transmit");
4603   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4604     s = format (s, "mark-and-transmit");
4605   else
4606     s = format (s, "ILLEGAL");
4607   return s;
4608 }
4609
4610 static u8 *
4611 format_dscp (u8 * s, va_list * va)
4612 {
4613   u32 i = va_arg (*va, u32);
4614   char *t = 0;
4615
4616   switch (i)
4617     {
4618 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4619       foreach_vnet_dscp
4620 #undef _
4621     default:
4622       return format (s, "ILLEGAL");
4623     }
4624   s = format (s, "%s", t);
4625   return s;
4626 }
4627
4628 static void
4629 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4630 {
4631   vat_main_t *vam = &vat_main;
4632   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4633
4634   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4635     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4636   else
4637     conform_dscp_str = format (0, "");
4638
4639   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4640     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4641   else
4642     exceed_dscp_str = format (0, "");
4643
4644   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4645     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4646   else
4647     violate_dscp_str = format (0, "");
4648
4649   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4650          "rate type %U, round type %U, %s rate, %s color-aware, "
4651          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4652          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4653          "conform action %U%s, exceed action %U%s, violate action %U%s",
4654          mp->name,
4655          format_policer_type, mp->type,
4656          ntohl (mp->cir),
4657          ntohl (mp->eir),
4658          clib_net_to_host_u64 (mp->cb),
4659          clib_net_to_host_u64 (mp->eb),
4660          format_policer_rate_type, mp->rate_type,
4661          format_policer_round_type, mp->round_type,
4662          mp->single_rate ? "single" : "dual",
4663          mp->color_aware ? "is" : "not",
4664          ntohl (mp->cir_tokens_per_period),
4665          ntohl (mp->pir_tokens_per_period),
4666          ntohl (mp->scale),
4667          ntohl (mp->current_limit),
4668          ntohl (mp->current_bucket),
4669          ntohl (mp->extended_limit),
4670          ntohl (mp->extended_bucket),
4671          clib_net_to_host_u64 (mp->last_update_time),
4672          format_policer_action_type, mp->conform_action_type,
4673          conform_dscp_str,
4674          format_policer_action_type, mp->exceed_action_type,
4675          exceed_dscp_str,
4676          format_policer_action_type, mp->violate_action_type,
4677          violate_dscp_str);
4678
4679   vec_free (conform_dscp_str);
4680   vec_free (exceed_dscp_str);
4681   vec_free (violate_dscp_str);
4682 }
4683
4684 static void vl_api_policer_details_t_handler_json
4685   (vl_api_policer_details_t * mp)
4686 {
4687   vat_main_t *vam = &vat_main;
4688   vat_json_node_t *node;
4689   u8 *rate_type_str, *round_type_str, *type_str;
4690   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4691
4692   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4693   round_type_str =
4694     format (0, "%U", format_policer_round_type, mp->round_type);
4695   type_str = format (0, "%U", format_policer_type, mp->type);
4696   conform_action_str = format (0, "%U", format_policer_action_type,
4697                                mp->conform_action_type);
4698   exceed_action_str = format (0, "%U", format_policer_action_type,
4699                               mp->exceed_action_type);
4700   violate_action_str = format (0, "%U", format_policer_action_type,
4701                                mp->violate_action_type);
4702
4703   if (VAT_JSON_ARRAY != vam->json_tree.type)
4704     {
4705       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4706       vat_json_init_array (&vam->json_tree);
4707     }
4708   node = vat_json_array_add (&vam->json_tree);
4709
4710   vat_json_init_object (node);
4711   vat_json_object_add_string_copy (node, "name", mp->name);
4712   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4713   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4714   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4715   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4716   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4717   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4718   vat_json_object_add_string_copy (node, "type", type_str);
4719   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4720   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4721   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4722   vat_json_object_add_uint (node, "cir_tokens_per_period",
4723                             ntohl (mp->cir_tokens_per_period));
4724   vat_json_object_add_uint (node, "eir_tokens_per_period",
4725                             ntohl (mp->pir_tokens_per_period));
4726   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4727   vat_json_object_add_uint (node, "current_bucket",
4728                             ntohl (mp->current_bucket));
4729   vat_json_object_add_uint (node, "extended_limit",
4730                             ntohl (mp->extended_limit));
4731   vat_json_object_add_uint (node, "extended_bucket",
4732                             ntohl (mp->extended_bucket));
4733   vat_json_object_add_uint (node, "last_update_time",
4734                             ntohl (mp->last_update_time));
4735   vat_json_object_add_string_copy (node, "conform_action",
4736                                    conform_action_str);
4737   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4738     {
4739       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4740       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4741       vec_free (dscp_str);
4742     }
4743   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4744   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4745     {
4746       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4747       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4748       vec_free (dscp_str);
4749     }
4750   vat_json_object_add_string_copy (node, "violate_action",
4751                                    violate_action_str);
4752   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4753     {
4754       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4755       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4756       vec_free (dscp_str);
4757     }
4758
4759   vec_free (rate_type_str);
4760   vec_free (round_type_str);
4761   vec_free (type_str);
4762   vec_free (conform_action_str);
4763   vec_free (exceed_action_str);
4764   vec_free (violate_action_str);
4765 }
4766
4767 static void
4768 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4769                                            mp)
4770 {
4771   vat_main_t *vam = &vat_main;
4772   int i, count = ntohl (mp->count);
4773
4774   if (count > 0)
4775     print (vam->ofp, "classify table ids (%d) : ", count);
4776   for (i = 0; i < count; i++)
4777     {
4778       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4779       print (vam->ofp, (i < count - 1) ? "," : "");
4780     }
4781   vam->retval = ntohl (mp->retval);
4782   vam->result_ready = 1;
4783 }
4784
4785 static void
4786   vl_api_classify_table_ids_reply_t_handler_json
4787   (vl_api_classify_table_ids_reply_t * mp)
4788 {
4789   vat_main_t *vam = &vat_main;
4790   int i, count = ntohl (mp->count);
4791
4792   if (count > 0)
4793     {
4794       vat_json_node_t node;
4795
4796       vat_json_init_object (&node);
4797       for (i = 0; i < count; i++)
4798         {
4799           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4800         }
4801       vat_json_print (vam->ofp, &node);
4802       vat_json_free (&node);
4803     }
4804   vam->retval = ntohl (mp->retval);
4805   vam->result_ready = 1;
4806 }
4807
4808 static void
4809   vl_api_classify_table_by_interface_reply_t_handler
4810   (vl_api_classify_table_by_interface_reply_t * mp)
4811 {
4812   vat_main_t *vam = &vat_main;
4813   u32 table_id;
4814
4815   table_id = ntohl (mp->l2_table_id);
4816   if (table_id != ~0)
4817     print (vam->ofp, "l2 table id : %d", table_id);
4818   else
4819     print (vam->ofp, "l2 table id : No input ACL tables configured");
4820   table_id = ntohl (mp->ip4_table_id);
4821   if (table_id != ~0)
4822     print (vam->ofp, "ip4 table id : %d", table_id);
4823   else
4824     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4825   table_id = ntohl (mp->ip6_table_id);
4826   if (table_id != ~0)
4827     print (vam->ofp, "ip6 table id : %d", table_id);
4828   else
4829     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4830   vam->retval = ntohl (mp->retval);
4831   vam->result_ready = 1;
4832 }
4833
4834 static void
4835   vl_api_classify_table_by_interface_reply_t_handler_json
4836   (vl_api_classify_table_by_interface_reply_t * mp)
4837 {
4838   vat_main_t *vam = &vat_main;
4839   vat_json_node_t node;
4840
4841   vat_json_init_object (&node);
4842
4843   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4844   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4845   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4846
4847   vat_json_print (vam->ofp, &node);
4848   vat_json_free (&node);
4849
4850   vam->retval = ntohl (mp->retval);
4851   vam->result_ready = 1;
4852 }
4853
4854 static void vl_api_policer_add_del_reply_t_handler
4855   (vl_api_policer_add_del_reply_t * mp)
4856 {
4857   vat_main_t *vam = &vat_main;
4858   i32 retval = ntohl (mp->retval);
4859   if (vam->async_mode)
4860     {
4861       vam->async_errors += (retval < 0);
4862     }
4863   else
4864     {
4865       vam->retval = retval;
4866       vam->result_ready = 1;
4867       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4868         /*
4869          * Note: this is just barely thread-safe, depends on
4870          * the main thread spinning waiting for an answer...
4871          */
4872         errmsg ("policer index %d", ntohl (mp->policer_index));
4873     }
4874 }
4875
4876 static void vl_api_policer_add_del_reply_t_handler_json
4877   (vl_api_policer_add_del_reply_t * mp)
4878 {
4879   vat_main_t *vam = &vat_main;
4880   vat_json_node_t node;
4881
4882   vat_json_init_object (&node);
4883   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4884   vat_json_object_add_uint (&node, "policer_index",
4885                             ntohl (mp->policer_index));
4886
4887   vat_json_print (vam->ofp, &node);
4888   vat_json_free (&node);
4889
4890   vam->retval = ntohl (mp->retval);
4891   vam->result_ready = 1;
4892 }
4893
4894 /* Format hex dump. */
4895 u8 *
4896 format_hex_bytes (u8 * s, va_list * va)
4897 {
4898   u8 *bytes = va_arg (*va, u8 *);
4899   int n_bytes = va_arg (*va, int);
4900   uword i;
4901
4902   /* Print short or long form depending on byte count. */
4903   uword short_form = n_bytes <= 32;
4904   u32 indent = format_get_indent (s);
4905
4906   if (n_bytes == 0)
4907     return s;
4908
4909   for (i = 0; i < n_bytes; i++)
4910     {
4911       if (!short_form && (i % 32) == 0)
4912         s = format (s, "%08x: ", i);
4913       s = format (s, "%02x", bytes[i]);
4914       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4915         s = format (s, "\n%U", format_white_space, indent);
4916     }
4917
4918   return s;
4919 }
4920
4921 static void
4922 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4923                                             * mp)
4924 {
4925   vat_main_t *vam = &vat_main;
4926   i32 retval = ntohl (mp->retval);
4927   if (retval == 0)
4928     {
4929       print (vam->ofp, "classify table info :");
4930       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4931              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4932              ntohl (mp->miss_next_index));
4933       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4934              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4935              ntohl (mp->match_n_vectors));
4936       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4937              ntohl (mp->mask_length));
4938     }
4939   vam->retval = retval;
4940   vam->result_ready = 1;
4941 }
4942
4943 static void
4944   vl_api_classify_table_info_reply_t_handler_json
4945   (vl_api_classify_table_info_reply_t * mp)
4946 {
4947   vat_main_t *vam = &vat_main;
4948   vat_json_node_t node;
4949
4950   i32 retval = ntohl (mp->retval);
4951   if (retval == 0)
4952     {
4953       vat_json_init_object (&node);
4954
4955       vat_json_object_add_int (&node, "sessions",
4956                                ntohl (mp->active_sessions));
4957       vat_json_object_add_int (&node, "nexttbl",
4958                                ntohl (mp->next_table_index));
4959       vat_json_object_add_int (&node, "nextnode",
4960                                ntohl (mp->miss_next_index));
4961       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4962       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4963       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4964       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4965                       ntohl (mp->mask_length), 0);
4966       vat_json_object_add_string_copy (&node, "mask", s);
4967
4968       vat_json_print (vam->ofp, &node);
4969       vat_json_free (&node);
4970     }
4971   vam->retval = ntohl (mp->retval);
4972   vam->result_ready = 1;
4973 }
4974
4975 static void
4976 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4977                                            mp)
4978 {
4979   vat_main_t *vam = &vat_main;
4980
4981   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4982          ntohl (mp->hit_next_index), ntohl (mp->advance),
4983          ntohl (mp->opaque_index));
4984   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4985          ntohl (mp->match_length));
4986 }
4987
4988 static void
4989   vl_api_classify_session_details_t_handler_json
4990   (vl_api_classify_session_details_t * mp)
4991 {
4992   vat_main_t *vam = &vat_main;
4993   vat_json_node_t *node = NULL;
4994
4995   if (VAT_JSON_ARRAY != vam->json_tree.type)
4996     {
4997       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4998       vat_json_init_array (&vam->json_tree);
4999     }
5000   node = vat_json_array_add (&vam->json_tree);
5001
5002   vat_json_init_object (node);
5003   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
5004   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
5005   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
5006   u8 *s =
5007     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
5008             0);
5009   vat_json_object_add_string_copy (node, "match", s);
5010 }
5011
5012 static void vl_api_pg_create_interface_reply_t_handler
5013   (vl_api_pg_create_interface_reply_t * mp)
5014 {
5015   vat_main_t *vam = &vat_main;
5016
5017   vam->retval = ntohl (mp->retval);
5018   vam->result_ready = 1;
5019 }
5020
5021 static void vl_api_pg_create_interface_reply_t_handler_json
5022   (vl_api_pg_create_interface_reply_t * mp)
5023 {
5024   vat_main_t *vam = &vat_main;
5025   vat_json_node_t node;
5026
5027   i32 retval = ntohl (mp->retval);
5028   if (retval == 0)
5029     {
5030       vat_json_init_object (&node);
5031
5032       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
5033
5034       vat_json_print (vam->ofp, &node);
5035       vat_json_free (&node);
5036     }
5037   vam->retval = ntohl (mp->retval);
5038   vam->result_ready = 1;
5039 }
5040
5041 static void vl_api_policer_classify_details_t_handler
5042   (vl_api_policer_classify_details_t * mp)
5043 {
5044   vat_main_t *vam = &vat_main;
5045
5046   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5047          ntohl (mp->table_index));
5048 }
5049
5050 static void vl_api_policer_classify_details_t_handler_json
5051   (vl_api_policer_classify_details_t * mp)
5052 {
5053   vat_main_t *vam = &vat_main;
5054   vat_json_node_t *node;
5055
5056   if (VAT_JSON_ARRAY != vam->json_tree.type)
5057     {
5058       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5059       vat_json_init_array (&vam->json_tree);
5060     }
5061   node = vat_json_array_add (&vam->json_tree);
5062
5063   vat_json_init_object (node);
5064   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5065   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5066 }
5067
5068 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
5069   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5070 {
5071   vat_main_t *vam = &vat_main;
5072   i32 retval = ntohl (mp->retval);
5073   if (vam->async_mode)
5074     {
5075       vam->async_errors += (retval < 0);
5076     }
5077   else
5078     {
5079       vam->retval = retval;
5080       vam->sw_if_index = ntohl (mp->sw_if_index);
5081       vam->result_ready = 1;
5082     }
5083 }
5084
5085 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
5086   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
5087 {
5088   vat_main_t *vam = &vat_main;
5089   vat_json_node_t node;
5090
5091   vat_json_init_object (&node);
5092   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5093   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
5094
5095   vat_json_print (vam->ofp, &node);
5096   vat_json_free (&node);
5097
5098   vam->retval = ntohl (mp->retval);
5099   vam->result_ready = 1;
5100 }
5101
5102 static void vl_api_flow_classify_details_t_handler
5103   (vl_api_flow_classify_details_t * mp)
5104 {
5105   vat_main_t *vam = &vat_main;
5106
5107   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5108          ntohl (mp->table_index));
5109 }
5110
5111 static void vl_api_flow_classify_details_t_handler_json
5112   (vl_api_flow_classify_details_t * mp)
5113 {
5114   vat_main_t *vam = &vat_main;
5115   vat_json_node_t *node;
5116
5117   if (VAT_JSON_ARRAY != vam->json_tree.type)
5118     {
5119       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5120       vat_json_init_array (&vam->json_tree);
5121     }
5122   node = vat_json_array_add (&vam->json_tree);
5123
5124   vat_json_init_object (node);
5125   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5126   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5127 }
5128
5129 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
5130 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
5131 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
5132 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
5133 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
5134 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
5135 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
5136 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
5137 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
5138 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
5139 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
5140 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
5141 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5142 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5143 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5144 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5145 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5146 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5147 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5148 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5149 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5150 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5151
5152 /*
5153  * Generate boilerplate reply handlers, which
5154  * dig the return value out of the xxx_reply_t API message,
5155  * stick it into vam->retval, and set vam->result_ready
5156  *
5157  * Could also do this by pointing N message decode slots at
5158  * a single function, but that could break in subtle ways.
5159  */
5160
5161 #define foreach_standard_reply_retval_handler           \
5162 _(sw_interface_set_flags_reply)                         \
5163 _(sw_interface_add_del_address_reply)                   \
5164 _(sw_interface_set_rx_mode_reply)                       \
5165 _(sw_interface_set_table_reply)                         \
5166 _(sw_interface_set_mpls_enable_reply)                   \
5167 _(sw_interface_set_vpath_reply)                         \
5168 _(sw_interface_set_vxlan_bypass_reply)                  \
5169 _(sw_interface_set_geneve_bypass_reply)                 \
5170 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5171 _(sw_interface_set_l2_bridge_reply)                     \
5172 _(bridge_domain_add_del_reply)                          \
5173 _(sw_interface_set_l2_xconnect_reply)                   \
5174 _(l2fib_add_del_reply)                                  \
5175 _(l2fib_flush_int_reply)                                \
5176 _(l2fib_flush_bd_reply)                                 \
5177 _(ip_add_del_route_reply)                               \
5178 _(ip_table_add_del_reply)                               \
5179 _(ip_mroute_add_del_reply)                              \
5180 _(mpls_route_add_del_reply)                             \
5181 _(mpls_table_add_del_reply)                             \
5182 _(mpls_ip_bind_unbind_reply)                            \
5183 _(proxy_arp_add_del_reply)                              \
5184 _(proxy_arp_intfc_enable_disable_reply)                 \
5185 _(sw_interface_set_unnumbered_reply)                    \
5186 _(ip_neighbor_add_del_reply)                            \
5187 _(reset_vrf_reply)                                      \
5188 _(oam_add_del_reply)                                    \
5189 _(reset_fib_reply)                                      \
5190 _(dhcp_proxy_config_reply)                              \
5191 _(dhcp_proxy_set_vss_reply)                             \
5192 _(dhcp_client_config_reply)                             \
5193 _(set_ip_flow_hash_reply)                               \
5194 _(sw_interface_ip6_enable_disable_reply)                \
5195 _(sw_interface_ip6_set_link_local_address_reply)        \
5196 _(ip6nd_proxy_add_del_reply)                            \
5197 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5198 _(sw_interface_ip6nd_ra_config_reply)                   \
5199 _(set_arp_neighbor_limit_reply)                         \
5200 _(l2_patch_add_del_reply)                               \
5201 _(sr_policy_add_reply)                                  \
5202 _(sr_policy_mod_reply)                                  \
5203 _(sr_policy_del_reply)                                  \
5204 _(sr_localsid_add_del_reply)                            \
5205 _(sr_steering_add_del_reply)                            \
5206 _(classify_add_del_session_reply)                       \
5207 _(classify_set_interface_ip_table_reply)                \
5208 _(classify_set_interface_l2_tables_reply)               \
5209 _(l2tpv3_set_tunnel_cookies_reply)                      \
5210 _(l2tpv3_interface_enable_disable_reply)                \
5211 _(l2tpv3_set_lookup_key_reply)                          \
5212 _(l2_fib_clear_table_reply)                             \
5213 _(l2_interface_efp_filter_reply)                        \
5214 _(l2_interface_vlan_tag_rewrite_reply)                  \
5215 _(modify_vhost_user_if_reply)                           \
5216 _(delete_vhost_user_if_reply)                           \
5217 _(want_ip4_arp_events_reply)                            \
5218 _(want_ip6_nd_events_reply)                             \
5219 _(want_l2_macs_events_reply)                            \
5220 _(input_acl_set_interface_reply)                        \
5221 _(ipsec_spd_add_del_reply)                              \
5222 _(ipsec_interface_add_del_spd_reply)                    \
5223 _(ipsec_spd_add_del_entry_reply)                        \
5224 _(ipsec_sad_add_del_entry_reply)                        \
5225 _(ipsec_sa_set_key_reply)                               \
5226 _(ipsec_tunnel_if_add_del_reply)                        \
5227 _(ipsec_tunnel_if_set_key_reply)                        \
5228 _(ipsec_tunnel_if_set_sa_reply)                         \
5229 _(ikev2_profile_add_del_reply)                          \
5230 _(ikev2_profile_set_auth_reply)                         \
5231 _(ikev2_profile_set_id_reply)                           \
5232 _(ikev2_profile_set_ts_reply)                           \
5233 _(ikev2_set_local_key_reply)                            \
5234 _(ikev2_set_responder_reply)                            \
5235 _(ikev2_set_ike_transforms_reply)                       \
5236 _(ikev2_set_esp_transforms_reply)                       \
5237 _(ikev2_set_sa_lifetime_reply)                          \
5238 _(ikev2_initiate_sa_init_reply)                         \
5239 _(ikev2_initiate_del_ike_sa_reply)                      \
5240 _(ikev2_initiate_del_child_sa_reply)                    \
5241 _(ikev2_initiate_rekey_child_sa_reply)                  \
5242 _(delete_loopback_reply)                                \
5243 _(bd_ip_mac_add_del_reply)                              \
5244 _(map_del_domain_reply)                                 \
5245 _(map_add_del_rule_reply)                               \
5246 _(want_interface_events_reply)                          \
5247 _(want_stats_reply)                                     \
5248 _(cop_interface_enable_disable_reply)                   \
5249 _(cop_whitelist_enable_disable_reply)                   \
5250 _(sw_interface_clear_stats_reply)                       \
5251 _(ioam_enable_reply)                                    \
5252 _(ioam_disable_reply)                                   \
5253 _(one_add_del_locator_reply)                            \
5254 _(one_add_del_local_eid_reply)                          \
5255 _(one_add_del_remote_mapping_reply)                     \
5256 _(one_add_del_adjacency_reply)                          \
5257 _(one_add_del_map_resolver_reply)                       \
5258 _(one_add_del_map_server_reply)                         \
5259 _(one_enable_disable_reply)                             \
5260 _(one_rloc_probe_enable_disable_reply)                  \
5261 _(one_map_register_enable_disable_reply)                \
5262 _(one_map_register_set_ttl_reply)                       \
5263 _(one_set_transport_protocol_reply)                     \
5264 _(one_map_register_fallback_threshold_reply)            \
5265 _(one_pitr_set_locator_set_reply)                       \
5266 _(one_map_request_mode_reply)                           \
5267 _(one_add_del_map_request_itr_rlocs_reply)              \
5268 _(one_eid_table_add_del_map_reply)                      \
5269 _(one_use_petr_reply)                                   \
5270 _(one_stats_enable_disable_reply)                       \
5271 _(one_add_del_l2_arp_entry_reply)                       \
5272 _(one_add_del_ndp_entry_reply)                          \
5273 _(one_stats_flush_reply)                                \
5274 _(one_enable_disable_xtr_mode_reply)                    \
5275 _(one_enable_disable_pitr_mode_reply)                   \
5276 _(one_enable_disable_petr_mode_reply)                   \
5277 _(gpe_enable_disable_reply)                             \
5278 _(gpe_set_encap_mode_reply)                             \
5279 _(gpe_add_del_iface_reply)                              \
5280 _(gpe_add_del_native_fwd_rpath_reply)                   \
5281 _(af_packet_delete_reply)                               \
5282 _(policer_classify_set_interface_reply)                 \
5283 _(netmap_create_reply)                                  \
5284 _(netmap_delete_reply)                                  \
5285 _(set_ipfix_exporter_reply)                             \
5286 _(set_ipfix_classify_stream_reply)                      \
5287 _(ipfix_classify_table_add_del_reply)                   \
5288 _(flow_classify_set_interface_reply)                    \
5289 _(sw_interface_span_enable_disable_reply)               \
5290 _(pg_capture_reply)                                     \
5291 _(pg_enable_disable_reply)                              \
5292 _(ip_source_and_port_range_check_add_del_reply)         \
5293 _(ip_source_and_port_range_check_interface_add_del_reply)\
5294 _(delete_subif_reply)                                   \
5295 _(l2_interface_pbb_tag_rewrite_reply)                   \
5296 _(punt_reply)                                           \
5297 _(feature_enable_disable_reply)                         \
5298 _(sw_interface_tag_add_del_reply)                       \
5299 _(sw_interface_set_mtu_reply)                           \
5300 _(p2p_ethernet_add_reply)                               \
5301 _(p2p_ethernet_del_reply)                               \
5302 _(lldp_config_reply)                                    \
5303 _(sw_interface_set_lldp_reply)                          \
5304 _(tcp_configure_src_addresses_reply)                    \
5305 _(app_namespace_add_del_reply)                          \
5306 _(dns_enable_disable_reply)                             \
5307 _(dns_name_server_add_del_reply)                        \
5308 _(session_rule_add_del_reply)
5309
5310 #define _(n)                                    \
5311     static void vl_api_##n##_t_handler          \
5312     (vl_api_##n##_t * mp)                       \
5313     {                                           \
5314         vat_main_t * vam = &vat_main;           \
5315         i32 retval = ntohl(mp->retval);         \
5316         if (vam->async_mode) {                  \
5317             vam->async_errors += (retval < 0);  \
5318         } else {                                \
5319             vam->retval = retval;               \
5320             vam->result_ready = 1;              \
5321         }                                       \
5322     }
5323 foreach_standard_reply_retval_handler;
5324 #undef _
5325
5326 #define _(n)                                    \
5327     static void vl_api_##n##_t_handler_json     \
5328     (vl_api_##n##_t * mp)                       \
5329     {                                           \
5330         vat_main_t * vam = &vat_main;           \
5331         vat_json_node_t node;                   \
5332         vat_json_init_object(&node);            \
5333         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5334         vat_json_print(vam->ofp, &node);        \
5335         vam->retval = ntohl(mp->retval);        \
5336         vam->result_ready = 1;                  \
5337     }
5338 foreach_standard_reply_retval_handler;
5339 #undef _
5340
5341 /*
5342  * Table of message reply handlers, must include boilerplate handlers
5343  * we just generated
5344  */
5345
5346 #define foreach_vpe_api_reply_msg                                       \
5347 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5348 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5349 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5350 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5351 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5352 _(CLI_REPLY, cli_reply)                                                 \
5353 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5354 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5355   sw_interface_add_del_address_reply)                                   \
5356 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5357 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5358 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5359 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5360 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5361 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5362 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5363 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5364   sw_interface_set_l2_xconnect_reply)                                   \
5365 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5366   sw_interface_set_l2_bridge_reply)                                     \
5367 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5368 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5369 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5370 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5371 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5372 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5373 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5374 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5375 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5376 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5377 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5378 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5379 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5380 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5381 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5382 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5383 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5384 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5385 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5386 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5387   proxy_arp_intfc_enable_disable_reply)                                 \
5388 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5389 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5390   sw_interface_set_unnumbered_reply)                                    \
5391 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5392 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
5393 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5394 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5395 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5396 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5397 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5398 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5399 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5400 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5401 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5402 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5403   sw_interface_ip6_enable_disable_reply)                                \
5404 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5405   sw_interface_ip6_set_link_local_address_reply)                        \
5406 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5407 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5408 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5409   sw_interface_ip6nd_ra_prefix_reply)                                   \
5410 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5411   sw_interface_ip6nd_ra_config_reply)                                   \
5412 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5413 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5414 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5415 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5416 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5417 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5418 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5419 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5420 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5421 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5422 classify_set_interface_ip_table_reply)                                  \
5423 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5424   classify_set_interface_l2_tables_reply)                               \
5425 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5426 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5427 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5428 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5429 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5430   l2tpv3_interface_enable_disable_reply)                                \
5431 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5432 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5433 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5434 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5435 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5436 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5437 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5438 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5439 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5440 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5441 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5442 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5443 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5444 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5445 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5446 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5447 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5448 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
5449 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5450 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5451 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5452 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5453 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5454 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5455 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5456 _(L2_MACS_EVENT, l2_macs_event)                                         \
5457 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5458 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5459 _(IP_DETAILS, ip_details)                                               \
5460 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5461 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5462 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5463 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5464 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5465 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5466 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5467 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5468 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5469 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5470 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5471 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5472 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5473 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5474 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5475 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5476 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5477 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5478 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5479 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5480 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5481 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5482 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5483 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5484 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5485 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5486 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5487 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5488 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5489 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5490 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5491 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5492 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5493 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5494 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5495 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5496 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5497 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5498 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5499 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5500 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5501 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5502 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5503 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5504 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5505 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5506 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5507 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5508   one_map_register_enable_disable_reply)                                \
5509 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5510 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5511 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5512 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5513   one_map_register_fallback_threshold_reply)                            \
5514 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5515   one_rloc_probe_enable_disable_reply)                                  \
5516 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5517 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5518 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5519 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5520 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5521 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5522 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5523 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5524 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5525 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5526 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5527 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5528 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5529 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5530 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5531 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5532   show_one_stats_enable_disable_reply)                                  \
5533 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5534 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5535 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5536 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5537 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5538 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5539 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5540 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5541   one_enable_disable_pitr_mode_reply)                                   \
5542 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5543   one_enable_disable_petr_mode_reply)                                   \
5544 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5545 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5546 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5547 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5548 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5549 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5550 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5551 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5552 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5553 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5554 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5555 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5556   gpe_add_del_native_fwd_rpath_reply)                                   \
5557 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5558   gpe_fwd_entry_path_details)                                           \
5559 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5560 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5561   one_add_del_map_request_itr_rlocs_reply)                              \
5562 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5563   one_get_map_request_itr_rlocs_reply)                                  \
5564 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5565 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5566 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5567 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5568 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5569 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5570   show_one_map_register_state_reply)                                    \
5571 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5572 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5573   show_one_map_register_fallback_threshold_reply)                       \
5574 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5575 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5576 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5577 _(POLICER_DETAILS, policer_details)                                     \
5578 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5579 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5580 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5581 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5582 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5583 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5584 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5585 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5586 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5587 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5588 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5589 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5590 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5591 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5592 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5593 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5594 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5595 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5596 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5597 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5598 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5599 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5600 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5601 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5602 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5603  ip_source_and_port_range_check_add_del_reply)                          \
5604 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5605  ip_source_and_port_range_check_interface_add_del_reply)                \
5606 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5607 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5608 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5609 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5610 _(PUNT_REPLY, punt_reply)                                               \
5611 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5612 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5613 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5614 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5615 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5616 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5617 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5618 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5619 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5620 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5621 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5622 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5623 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5624 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5625 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5626 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5627 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5628 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5629 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5630 _(SESSION_RULES_DETAILS, session_rules_details)
5631
5632 #define foreach_standalone_reply_msg                                    \
5633 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5634 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5635 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5636 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5637 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5638 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5639 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
5640 _(MEMFD_SEGMENT_CREATE_REPLY, memfd_segment_create_reply)               \
5641
5642 typedef struct
5643 {
5644   u8 *name;
5645   u32 value;
5646 } name_sort_t;
5647
5648
5649 #define STR_VTR_OP_CASE(op)     \
5650     case L2_VTR_ ## op:         \
5651         return "" # op;
5652
5653 static const char *
5654 str_vtr_op (u32 vtr_op)
5655 {
5656   switch (vtr_op)
5657     {
5658       STR_VTR_OP_CASE (DISABLED);
5659       STR_VTR_OP_CASE (PUSH_1);
5660       STR_VTR_OP_CASE (PUSH_2);
5661       STR_VTR_OP_CASE (POP_1);
5662       STR_VTR_OP_CASE (POP_2);
5663       STR_VTR_OP_CASE (TRANSLATE_1_1);
5664       STR_VTR_OP_CASE (TRANSLATE_1_2);
5665       STR_VTR_OP_CASE (TRANSLATE_2_1);
5666       STR_VTR_OP_CASE (TRANSLATE_2_2);
5667     }
5668
5669   return "UNKNOWN";
5670 }
5671
5672 static int
5673 dump_sub_interface_table (vat_main_t * vam)
5674 {
5675   const sw_interface_subif_t *sub = NULL;
5676
5677   if (vam->json_output)
5678     {
5679       clib_warning
5680         ("JSON output supported only for VPE API calls and dump_stats_table");
5681       return -99;
5682     }
5683
5684   print (vam->ofp,
5685          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5686          "Interface", "sw_if_index",
5687          "sub id", "dot1ad", "tags", "outer id",
5688          "inner id", "exact", "default", "outer any", "inner any");
5689
5690   vec_foreach (sub, vam->sw_if_subif_table)
5691   {
5692     print (vam->ofp,
5693            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5694            sub->interface_name,
5695            sub->sw_if_index,
5696            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5697            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5698            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5699            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5700     if (sub->vtr_op != L2_VTR_DISABLED)
5701       {
5702         print (vam->ofp,
5703                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5704                "tag1: %d tag2: %d ]",
5705                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5706                sub->vtr_tag1, sub->vtr_tag2);
5707       }
5708   }
5709
5710   return 0;
5711 }
5712
5713 static int
5714 name_sort_cmp (void *a1, void *a2)
5715 {
5716   name_sort_t *n1 = a1;
5717   name_sort_t *n2 = a2;
5718
5719   return strcmp ((char *) n1->name, (char *) n2->name);
5720 }
5721
5722 static int
5723 dump_interface_table (vat_main_t * vam)
5724 {
5725   hash_pair_t *p;
5726   name_sort_t *nses = 0, *ns;
5727
5728   if (vam->json_output)
5729     {
5730       clib_warning
5731         ("JSON output supported only for VPE API calls and dump_stats_table");
5732       return -99;
5733     }
5734
5735   /* *INDENT-OFF* */
5736   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5737   ({
5738     vec_add2 (nses, ns, 1);
5739     ns->name = (u8 *)(p->key);
5740     ns->value = (u32) p->value[0];
5741   }));
5742   /* *INDENT-ON* */
5743
5744   vec_sort_with_function (nses, name_sort_cmp);
5745
5746   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5747   vec_foreach (ns, nses)
5748   {
5749     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5750   }
5751   vec_free (nses);
5752   return 0;
5753 }
5754
5755 static int
5756 dump_ip_table (vat_main_t * vam, int is_ipv6)
5757 {
5758   const ip_details_t *det = NULL;
5759   const ip_address_details_t *address = NULL;
5760   u32 i = ~0;
5761
5762   print (vam->ofp, "%-12s", "sw_if_index");
5763
5764   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5765   {
5766     i++;
5767     if (!det->present)
5768       {
5769         continue;
5770       }
5771     print (vam->ofp, "%-12d", i);
5772     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5773     if (!det->addr)
5774       {
5775         continue;
5776       }
5777     vec_foreach (address, det->addr)
5778     {
5779       print (vam->ofp,
5780              "            %-30U%-13d",
5781              is_ipv6 ? format_ip6_address : format_ip4_address,
5782              address->ip, address->prefix_length);
5783     }
5784   }
5785
5786   return 0;
5787 }
5788
5789 static int
5790 dump_ipv4_table (vat_main_t * vam)
5791 {
5792   if (vam->json_output)
5793     {
5794       clib_warning
5795         ("JSON output supported only for VPE API calls and dump_stats_table");
5796       return -99;
5797     }
5798
5799   return dump_ip_table (vam, 0);
5800 }
5801
5802 static int
5803 dump_ipv6_table (vat_main_t * vam)
5804 {
5805   if (vam->json_output)
5806     {
5807       clib_warning
5808         ("JSON output supported only for VPE API calls and dump_stats_table");
5809       return -99;
5810     }
5811
5812   return dump_ip_table (vam, 1);
5813 }
5814
5815 static char *
5816 counter_type_to_str (u8 counter_type, u8 is_combined)
5817 {
5818   if (!is_combined)
5819     {
5820       switch (counter_type)
5821         {
5822         case VNET_INTERFACE_COUNTER_DROP:
5823           return "drop";
5824         case VNET_INTERFACE_COUNTER_PUNT:
5825           return "punt";
5826         case VNET_INTERFACE_COUNTER_IP4:
5827           return "ip4";
5828         case VNET_INTERFACE_COUNTER_IP6:
5829           return "ip6";
5830         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5831           return "rx-no-buf";
5832         case VNET_INTERFACE_COUNTER_RX_MISS:
5833           return "rx-miss";
5834         case VNET_INTERFACE_COUNTER_RX_ERROR:
5835           return "rx-error";
5836         case VNET_INTERFACE_COUNTER_TX_ERROR:
5837           return "tx-error";
5838         default:
5839           return "INVALID-COUNTER-TYPE";
5840         }
5841     }
5842   else
5843     {
5844       switch (counter_type)
5845         {
5846         case VNET_INTERFACE_COUNTER_RX:
5847           return "rx";
5848         case VNET_INTERFACE_COUNTER_TX:
5849           return "tx";
5850         default:
5851           return "INVALID-COUNTER-TYPE";
5852         }
5853     }
5854 }
5855
5856 static int
5857 dump_stats_table (vat_main_t * vam)
5858 {
5859   vat_json_node_t node;
5860   vat_json_node_t *msg_array;
5861   vat_json_node_t *msg;
5862   vat_json_node_t *counter_array;
5863   vat_json_node_t *counter;
5864   interface_counter_t c;
5865   u64 packets;
5866   ip4_fib_counter_t *c4;
5867   ip6_fib_counter_t *c6;
5868   ip4_nbr_counter_t *n4;
5869   ip6_nbr_counter_t *n6;
5870   int i, j;
5871
5872   if (!vam->json_output)
5873     {
5874       clib_warning ("dump_stats_table supported only in JSON format");
5875       return -99;
5876     }
5877
5878   vat_json_init_object (&node);
5879
5880   /* interface counters */
5881   msg_array = vat_json_object_add (&node, "interface_counters");
5882   vat_json_init_array (msg_array);
5883   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5884     {
5885       msg = vat_json_array_add (msg_array);
5886       vat_json_init_object (msg);
5887       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5888                                        (u8 *) counter_type_to_str (i, 0));
5889       vat_json_object_add_int (msg, "is_combined", 0);
5890       counter_array = vat_json_object_add (msg, "data");
5891       vat_json_init_array (counter_array);
5892       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5893         {
5894           packets = vam->simple_interface_counters[i][j];
5895           vat_json_array_add_uint (counter_array, packets);
5896         }
5897     }
5898   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5899     {
5900       msg = vat_json_array_add (msg_array);
5901       vat_json_init_object (msg);
5902       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5903                                        (u8 *) counter_type_to_str (i, 1));
5904       vat_json_object_add_int (msg, "is_combined", 1);
5905       counter_array = vat_json_object_add (msg, "data");
5906       vat_json_init_array (counter_array);
5907       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5908         {
5909           c = vam->combined_interface_counters[i][j];
5910           counter = vat_json_array_add (counter_array);
5911           vat_json_init_object (counter);
5912           vat_json_object_add_uint (counter, "packets", c.packets);
5913           vat_json_object_add_uint (counter, "bytes", c.bytes);
5914         }
5915     }
5916
5917   /* ip4 fib counters */
5918   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
5919   vat_json_init_array (msg_array);
5920   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
5921     {
5922       msg = vat_json_array_add (msg_array);
5923       vat_json_init_object (msg);
5924       vat_json_object_add_uint (msg, "vrf_id",
5925                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
5926       counter_array = vat_json_object_add (msg, "c");
5927       vat_json_init_array (counter_array);
5928       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
5929         {
5930           counter = vat_json_array_add (counter_array);
5931           vat_json_init_object (counter);
5932           c4 = &vam->ip4_fib_counters[i][j];
5933           vat_json_object_add_ip4 (counter, "address", c4->address);
5934           vat_json_object_add_uint (counter, "address_length",
5935                                     c4->address_length);
5936           vat_json_object_add_uint (counter, "packets", c4->packets);
5937           vat_json_object_add_uint (counter, "bytes", c4->bytes);
5938         }
5939     }
5940
5941   /* ip6 fib counters */
5942   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
5943   vat_json_init_array (msg_array);
5944   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
5945     {
5946       msg = vat_json_array_add (msg_array);
5947       vat_json_init_object (msg);
5948       vat_json_object_add_uint (msg, "vrf_id",
5949                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
5950       counter_array = vat_json_object_add (msg, "c");
5951       vat_json_init_array (counter_array);
5952       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
5953         {
5954           counter = vat_json_array_add (counter_array);
5955           vat_json_init_object (counter);
5956           c6 = &vam->ip6_fib_counters[i][j];
5957           vat_json_object_add_ip6 (counter, "address", c6->address);
5958           vat_json_object_add_uint (counter, "address_length",
5959                                     c6->address_length);
5960           vat_json_object_add_uint (counter, "packets", c6->packets);
5961           vat_json_object_add_uint (counter, "bytes", c6->bytes);
5962         }
5963     }
5964
5965   /* ip4 nbr counters */
5966   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
5967   vat_json_init_array (msg_array);
5968   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
5969     {
5970       msg = vat_json_array_add (msg_array);
5971       vat_json_init_object (msg);
5972       vat_json_object_add_uint (msg, "sw_if_index", i);
5973       counter_array = vat_json_object_add (msg, "c");
5974       vat_json_init_array (counter_array);
5975       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
5976         {
5977           counter = vat_json_array_add (counter_array);
5978           vat_json_init_object (counter);
5979           n4 = &vam->ip4_nbr_counters[i][j];
5980           vat_json_object_add_ip4 (counter, "address", n4->address);
5981           vat_json_object_add_uint (counter, "link-type", n4->linkt);
5982           vat_json_object_add_uint (counter, "packets", n4->packets);
5983           vat_json_object_add_uint (counter, "bytes", n4->bytes);
5984         }
5985     }
5986
5987   /* ip6 nbr counters */
5988   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
5989   vat_json_init_array (msg_array);
5990   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
5991     {
5992       msg = vat_json_array_add (msg_array);
5993       vat_json_init_object (msg);
5994       vat_json_object_add_uint (msg, "sw_if_index", i);
5995       counter_array = vat_json_object_add (msg, "c");
5996       vat_json_init_array (counter_array);
5997       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
5998         {
5999           counter = vat_json_array_add (counter_array);
6000           vat_json_init_object (counter);
6001           n6 = &vam->ip6_nbr_counters[i][j];
6002           vat_json_object_add_ip6 (counter, "address", n6->address);
6003           vat_json_object_add_uint (counter, "packets", n6->packets);
6004           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6005         }
6006     }
6007
6008   vat_json_print (vam->ofp, &node);
6009   vat_json_free (&node);
6010
6011   return 0;
6012 }
6013
6014 /*
6015  * Pass CLI buffers directly in the CLI_INBAND API message,
6016  * instead of an additional shared memory area.
6017  */
6018 static int
6019 exec_inband (vat_main_t * vam)
6020 {
6021   vl_api_cli_inband_t *mp;
6022   unformat_input_t *i = vam->input;
6023   int ret;
6024
6025   if (vec_len (i->buffer) == 0)
6026     return -1;
6027
6028   if (vam->exec_mode == 0 && unformat (i, "mode"))
6029     {
6030       vam->exec_mode = 1;
6031       return 0;
6032     }
6033   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6034     {
6035       vam->exec_mode = 0;
6036       return 0;
6037     }
6038
6039   /*
6040    * In order for the CLI command to work, it
6041    * must be a vector ending in \n, not a C-string ending
6042    * in \n\0.
6043    */
6044   u32 len = vec_len (vam->input->buffer);
6045   M2 (CLI_INBAND, mp, len);
6046   clib_memcpy (mp->cmd, vam->input->buffer, len);
6047   mp->length = htonl (len);
6048
6049   S (mp);
6050   W (ret);
6051   /* json responses may or may not include a useful reply... */
6052   if (vec_len (vam->cmd_reply))
6053     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6054   return ret;
6055 }
6056
6057 int
6058 exec (vat_main_t * vam)
6059 {
6060   return exec_inband (vam);
6061 }
6062
6063 static int
6064 api_create_loopback (vat_main_t * vam)
6065 {
6066   unformat_input_t *i = vam->input;
6067   vl_api_create_loopback_t *mp;
6068   vl_api_create_loopback_instance_t *mp_lbi;
6069   u8 mac_address[6];
6070   u8 mac_set = 0;
6071   u8 is_specified = 0;
6072   u32 user_instance = 0;
6073   int ret;
6074
6075   memset (mac_address, 0, sizeof (mac_address));
6076
6077   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6078     {
6079       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6080         mac_set = 1;
6081       if (unformat (i, "instance %d", &user_instance))
6082         is_specified = 1;
6083       else
6084         break;
6085     }
6086
6087   if (is_specified)
6088     {
6089       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6090       mp_lbi->is_specified = is_specified;
6091       if (is_specified)
6092         mp_lbi->user_instance = htonl (user_instance);
6093       if (mac_set)
6094         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6095       S (mp_lbi);
6096     }
6097   else
6098     {
6099       /* Construct the API message */
6100       M (CREATE_LOOPBACK, mp);
6101       if (mac_set)
6102         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6103       S (mp);
6104     }
6105
6106   W (ret);
6107   return ret;
6108 }
6109
6110 static int
6111 api_delete_loopback (vat_main_t * vam)
6112 {
6113   unformat_input_t *i = vam->input;
6114   vl_api_delete_loopback_t *mp;
6115   u32 sw_if_index = ~0;
6116   int ret;
6117
6118   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6119     {
6120       if (unformat (i, "sw_if_index %d", &sw_if_index))
6121         ;
6122       else
6123         break;
6124     }
6125
6126   if (sw_if_index == ~0)
6127     {
6128       errmsg ("missing sw_if_index");
6129       return -99;
6130     }
6131
6132   /* Construct the API message */
6133   M (DELETE_LOOPBACK, mp);
6134   mp->sw_if_index = ntohl (sw_if_index);
6135
6136   S (mp);
6137   W (ret);
6138   return ret;
6139 }
6140
6141 static int
6142 api_want_stats (vat_main_t * vam)
6143 {
6144   unformat_input_t *i = vam->input;
6145   vl_api_want_stats_t *mp;
6146   int enable = -1;
6147   int ret;
6148
6149   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6150     {
6151       if (unformat (i, "enable"))
6152         enable = 1;
6153       else if (unformat (i, "disable"))
6154         enable = 0;
6155       else
6156         break;
6157     }
6158
6159   if (enable == -1)
6160     {
6161       errmsg ("missing enable|disable");
6162       return -99;
6163     }
6164
6165   M (WANT_STATS, mp);
6166   mp->enable_disable = enable;
6167
6168   S (mp);
6169   W (ret);
6170   return ret;
6171 }
6172
6173 static int
6174 api_want_interface_events (vat_main_t * vam)
6175 {
6176   unformat_input_t *i = vam->input;
6177   vl_api_want_interface_events_t *mp;
6178   int enable = -1;
6179   int ret;
6180
6181   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6182     {
6183       if (unformat (i, "enable"))
6184         enable = 1;
6185       else if (unformat (i, "disable"))
6186         enable = 0;
6187       else
6188         break;
6189     }
6190
6191   if (enable == -1)
6192     {
6193       errmsg ("missing enable|disable");
6194       return -99;
6195     }
6196
6197   M (WANT_INTERFACE_EVENTS, mp);
6198   mp->enable_disable = enable;
6199
6200   vam->interface_event_display = enable;
6201
6202   S (mp);
6203   W (ret);
6204   return ret;
6205 }
6206
6207
6208 /* Note: non-static, called once to set up the initial intfc table */
6209 int
6210 api_sw_interface_dump (vat_main_t * vam)
6211 {
6212   vl_api_sw_interface_dump_t *mp;
6213   vl_api_control_ping_t *mp_ping;
6214   hash_pair_t *p;
6215   name_sort_t *nses = 0, *ns;
6216   sw_interface_subif_t *sub = NULL;
6217   int ret;
6218
6219   /* Toss the old name table */
6220   /* *INDENT-OFF* */
6221   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6222   ({
6223     vec_add2 (nses, ns, 1);
6224     ns->name = (u8 *)(p->key);
6225     ns->value = (u32) p->value[0];
6226   }));
6227   /* *INDENT-ON* */
6228
6229   hash_free (vam->sw_if_index_by_interface_name);
6230
6231   vec_foreach (ns, nses) vec_free (ns->name);
6232
6233   vec_free (nses);
6234
6235   vec_foreach (sub, vam->sw_if_subif_table)
6236   {
6237     vec_free (sub->interface_name);
6238   }
6239   vec_free (vam->sw_if_subif_table);
6240
6241   /* recreate the interface name hash table */
6242   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6243
6244   /* Get list of ethernets */
6245   M (SW_INTERFACE_DUMP, mp);
6246   mp->name_filter_valid = 1;
6247   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
6248   S (mp);
6249
6250   /* and local / loopback interfaces */
6251   M (SW_INTERFACE_DUMP, mp);
6252   mp->name_filter_valid = 1;
6253   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
6254   S (mp);
6255
6256   /* and packet-generator interfaces */
6257   M (SW_INTERFACE_DUMP, mp);
6258   mp->name_filter_valid = 1;
6259   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
6260   S (mp);
6261
6262   /* and vxlan-gpe tunnel interfaces */
6263   M (SW_INTERFACE_DUMP, mp);
6264   mp->name_filter_valid = 1;
6265   strncpy ((char *) mp->name_filter, "vxlan_gpe",
6266            sizeof (mp->name_filter) - 1);
6267   S (mp);
6268
6269   /* and vxlan tunnel interfaces */
6270   M (SW_INTERFACE_DUMP, mp);
6271   mp->name_filter_valid = 1;
6272   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
6273   S (mp);
6274
6275   /* and geneve tunnel interfaces */
6276   M (SW_INTERFACE_DUMP, mp);
6277   mp->name_filter_valid = 1;
6278   strncpy ((char *) mp->name_filter, "geneve", sizeof (mp->name_filter) - 1);
6279   S (mp);
6280
6281   /* and host (af_packet) interfaces */
6282   M (SW_INTERFACE_DUMP, mp);
6283   mp->name_filter_valid = 1;
6284   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
6285   S (mp);
6286
6287   /* and l2tpv3 tunnel interfaces */
6288   M (SW_INTERFACE_DUMP, mp);
6289   mp->name_filter_valid = 1;
6290   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
6291            sizeof (mp->name_filter) - 1);
6292   S (mp);
6293
6294   /* and GRE tunnel interfaces */
6295   M (SW_INTERFACE_DUMP, mp);
6296   mp->name_filter_valid = 1;
6297   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
6298   S (mp);
6299
6300   /* and LISP-GPE interfaces */
6301   M (SW_INTERFACE_DUMP, mp);
6302   mp->name_filter_valid = 1;
6303   strncpy ((char *) mp->name_filter, "lisp_gpe",
6304            sizeof (mp->name_filter) - 1);
6305   S (mp);
6306
6307   /* and IPSEC tunnel interfaces */
6308   M (SW_INTERFACE_DUMP, mp);
6309   mp->name_filter_valid = 1;
6310   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
6311   S (mp);
6312
6313   /* Use a control ping for synchronization */
6314   MPING (CONTROL_PING, mp_ping);
6315   S (mp_ping);
6316
6317   W (ret);
6318   return ret;
6319 }
6320
6321 static int
6322 api_sw_interface_set_flags (vat_main_t * vam)
6323 {
6324   unformat_input_t *i = vam->input;
6325   vl_api_sw_interface_set_flags_t *mp;
6326   u32 sw_if_index;
6327   u8 sw_if_index_set = 0;
6328   u8 admin_up = 0;
6329   int ret;
6330
6331   /* Parse args required to build the message */
6332   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6333     {
6334       if (unformat (i, "admin-up"))
6335         admin_up = 1;
6336       else if (unformat (i, "admin-down"))
6337         admin_up = 0;
6338       else
6339         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6340         sw_if_index_set = 1;
6341       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6342         sw_if_index_set = 1;
6343       else
6344         break;
6345     }
6346
6347   if (sw_if_index_set == 0)
6348     {
6349       errmsg ("missing interface name or sw_if_index");
6350       return -99;
6351     }
6352
6353   /* Construct the API message */
6354   M (SW_INTERFACE_SET_FLAGS, mp);
6355   mp->sw_if_index = ntohl (sw_if_index);
6356   mp->admin_up_down = admin_up;
6357
6358   /* send it... */
6359   S (mp);
6360
6361   /* Wait for a reply, return the good/bad news... */
6362   W (ret);
6363   return ret;
6364 }
6365
6366 static int
6367 api_sw_interface_set_rx_mode (vat_main_t * vam)
6368 {
6369   unformat_input_t *i = vam->input;
6370   vl_api_sw_interface_set_rx_mode_t *mp;
6371   u32 sw_if_index;
6372   u8 sw_if_index_set = 0;
6373   int ret;
6374   u8 queue_id_valid = 0;
6375   u32 queue_id;
6376   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6377
6378   /* Parse args required to build the message */
6379   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6380     {
6381       if (unformat (i, "queue %d", &queue_id))
6382         queue_id_valid = 1;
6383       else if (unformat (i, "polling"))
6384         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6385       else if (unformat (i, "interrupt"))
6386         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6387       else if (unformat (i, "adaptive"))
6388         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6389       else
6390         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6391         sw_if_index_set = 1;
6392       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6393         sw_if_index_set = 1;
6394       else
6395         break;
6396     }
6397
6398   if (sw_if_index_set == 0)
6399     {
6400       errmsg ("missing interface name or sw_if_index");
6401       return -99;
6402     }
6403   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6404     {
6405       errmsg ("missing rx-mode");
6406       return -99;
6407     }
6408
6409   /* Construct the API message */
6410   M (SW_INTERFACE_SET_RX_MODE, mp);
6411   mp->sw_if_index = ntohl (sw_if_index);
6412   mp->mode = mode;
6413   mp->queue_id_valid = queue_id_valid;
6414   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6415
6416   /* send it... */
6417   S (mp);
6418
6419   /* Wait for a reply, return the good/bad news... */
6420   W (ret);
6421   return ret;
6422 }
6423
6424 static int
6425 api_sw_interface_clear_stats (vat_main_t * vam)
6426 {
6427   unformat_input_t *i = vam->input;
6428   vl_api_sw_interface_clear_stats_t *mp;
6429   u32 sw_if_index;
6430   u8 sw_if_index_set = 0;
6431   int ret;
6432
6433   /* Parse args required to build the message */
6434   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6435     {
6436       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6437         sw_if_index_set = 1;
6438       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6439         sw_if_index_set = 1;
6440       else
6441         break;
6442     }
6443
6444   /* Construct the API message */
6445   M (SW_INTERFACE_CLEAR_STATS, mp);
6446
6447   if (sw_if_index_set == 1)
6448     mp->sw_if_index = ntohl (sw_if_index);
6449   else
6450     mp->sw_if_index = ~0;
6451
6452   /* send it... */
6453   S (mp);
6454
6455   /* Wait for a reply, return the good/bad news... */
6456   W (ret);
6457   return ret;
6458 }
6459
6460 static int
6461 api_sw_interface_add_del_address (vat_main_t * vam)
6462 {
6463   unformat_input_t *i = vam->input;
6464   vl_api_sw_interface_add_del_address_t *mp;
6465   u32 sw_if_index;
6466   u8 sw_if_index_set = 0;
6467   u8 is_add = 1, del_all = 0;
6468   u32 address_length = 0;
6469   u8 v4_address_set = 0;
6470   u8 v6_address_set = 0;
6471   ip4_address_t v4address;
6472   ip6_address_t v6address;
6473   int ret;
6474
6475   /* Parse args required to build the message */
6476   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6477     {
6478       if (unformat (i, "del-all"))
6479         del_all = 1;
6480       else if (unformat (i, "del"))
6481         is_add = 0;
6482       else
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, "%U/%d",
6488                          unformat_ip4_address, &v4address, &address_length))
6489         v4_address_set = 1;
6490       else if (unformat (i, "%U/%d",
6491                          unformat_ip6_address, &v6address, &address_length))
6492         v6_address_set = 1;
6493       else
6494         break;
6495     }
6496
6497   if (sw_if_index_set == 0)
6498     {
6499       errmsg ("missing interface name or sw_if_index");
6500       return -99;
6501     }
6502   if (v4_address_set && v6_address_set)
6503     {
6504       errmsg ("both v4 and v6 addresses set");
6505       return -99;
6506     }
6507   if (!v4_address_set && !v6_address_set && !del_all)
6508     {
6509       errmsg ("no addresses set");
6510       return -99;
6511     }
6512
6513   /* Construct the API message */
6514   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6515
6516   mp->sw_if_index = ntohl (sw_if_index);
6517   mp->is_add = is_add;
6518   mp->del_all = del_all;
6519   if (v6_address_set)
6520     {
6521       mp->is_ipv6 = 1;
6522       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6523     }
6524   else
6525     {
6526       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6527     }
6528   mp->address_length = address_length;
6529
6530   /* send it... */
6531   S (mp);
6532
6533   /* Wait for a reply, return good/bad news  */
6534   W (ret);
6535   return ret;
6536 }
6537
6538 static int
6539 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6540 {
6541   unformat_input_t *i = vam->input;
6542   vl_api_sw_interface_set_mpls_enable_t *mp;
6543   u32 sw_if_index;
6544   u8 sw_if_index_set = 0;
6545   u8 enable = 1;
6546   int ret;
6547
6548   /* Parse args required to build the message */
6549   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6550     {
6551       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6552         sw_if_index_set = 1;
6553       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6554         sw_if_index_set = 1;
6555       else if (unformat (i, "disable"))
6556         enable = 0;
6557       else if (unformat (i, "dis"))
6558         enable = 0;
6559       else
6560         break;
6561     }
6562
6563   if (sw_if_index_set == 0)
6564     {
6565       errmsg ("missing interface name or sw_if_index");
6566       return -99;
6567     }
6568
6569   /* Construct the API message */
6570   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6571
6572   mp->sw_if_index = ntohl (sw_if_index);
6573   mp->enable = enable;
6574
6575   /* send it... */
6576   S (mp);
6577
6578   /* Wait for a reply... */
6579   W (ret);
6580   return ret;
6581 }
6582
6583 static int
6584 api_sw_interface_set_table (vat_main_t * vam)
6585 {
6586   unformat_input_t *i = vam->input;
6587   vl_api_sw_interface_set_table_t *mp;
6588   u32 sw_if_index, vrf_id = 0;
6589   u8 sw_if_index_set = 0;
6590   u8 is_ipv6 = 0;
6591   int ret;
6592
6593   /* Parse args required to build the message */
6594   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6595     {
6596       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6597         sw_if_index_set = 1;
6598       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6599         sw_if_index_set = 1;
6600       else if (unformat (i, "vrf %d", &vrf_id))
6601         ;
6602       else if (unformat (i, "ipv6"))
6603         is_ipv6 = 1;
6604       else
6605         break;
6606     }
6607
6608   if (sw_if_index_set == 0)
6609     {
6610       errmsg ("missing interface name or sw_if_index");
6611       return -99;
6612     }
6613
6614   /* Construct the API message */
6615   M (SW_INTERFACE_SET_TABLE, mp);
6616
6617   mp->sw_if_index = ntohl (sw_if_index);
6618   mp->is_ipv6 = is_ipv6;
6619   mp->vrf_id = ntohl (vrf_id);
6620
6621   /* send it... */
6622   S (mp);
6623
6624   /* Wait for a reply... */
6625   W (ret);
6626   return ret;
6627 }
6628
6629 static void vl_api_sw_interface_get_table_reply_t_handler
6630   (vl_api_sw_interface_get_table_reply_t * mp)
6631 {
6632   vat_main_t *vam = &vat_main;
6633
6634   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6635
6636   vam->retval = ntohl (mp->retval);
6637   vam->result_ready = 1;
6638
6639 }
6640
6641 static void vl_api_sw_interface_get_table_reply_t_handler_json
6642   (vl_api_sw_interface_get_table_reply_t * mp)
6643 {
6644   vat_main_t *vam = &vat_main;
6645   vat_json_node_t node;
6646
6647   vat_json_init_object (&node);
6648   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6649   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6650
6651   vat_json_print (vam->ofp, &node);
6652   vat_json_free (&node);
6653
6654   vam->retval = ntohl (mp->retval);
6655   vam->result_ready = 1;
6656 }
6657
6658 static int
6659 api_sw_interface_get_table (vat_main_t * vam)
6660 {
6661   unformat_input_t *i = vam->input;
6662   vl_api_sw_interface_get_table_t *mp;
6663   u32 sw_if_index;
6664   u8 sw_if_index_set = 0;
6665   u8 is_ipv6 = 0;
6666   int ret;
6667
6668   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6669     {
6670       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6671         sw_if_index_set = 1;
6672       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6673         sw_if_index_set = 1;
6674       else if (unformat (i, "ipv6"))
6675         is_ipv6 = 1;
6676       else
6677         break;
6678     }
6679
6680   if (sw_if_index_set == 0)
6681     {
6682       errmsg ("missing interface name or sw_if_index");
6683       return -99;
6684     }
6685
6686   M (SW_INTERFACE_GET_TABLE, mp);
6687   mp->sw_if_index = htonl (sw_if_index);
6688   mp->is_ipv6 = is_ipv6;
6689
6690   S (mp);
6691   W (ret);
6692   return ret;
6693 }
6694
6695 static int
6696 api_sw_interface_set_vpath (vat_main_t * vam)
6697 {
6698   unformat_input_t *i = vam->input;
6699   vl_api_sw_interface_set_vpath_t *mp;
6700   u32 sw_if_index = 0;
6701   u8 sw_if_index_set = 0;
6702   u8 is_enable = 0;
6703   int ret;
6704
6705   /* Parse args required to build the message */
6706   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6707     {
6708       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6709         sw_if_index_set = 1;
6710       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6711         sw_if_index_set = 1;
6712       else if (unformat (i, "enable"))
6713         is_enable = 1;
6714       else if (unformat (i, "disable"))
6715         is_enable = 0;
6716       else
6717         break;
6718     }
6719
6720   if (sw_if_index_set == 0)
6721     {
6722       errmsg ("missing interface name or sw_if_index");
6723       return -99;
6724     }
6725
6726   /* Construct the API message */
6727   M (SW_INTERFACE_SET_VPATH, mp);
6728
6729   mp->sw_if_index = ntohl (sw_if_index);
6730   mp->enable = is_enable;
6731
6732   /* send it... */
6733   S (mp);
6734
6735   /* Wait for a reply... */
6736   W (ret);
6737   return ret;
6738 }
6739
6740 static int
6741 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6742 {
6743   unformat_input_t *i = vam->input;
6744   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6745   u32 sw_if_index = 0;
6746   u8 sw_if_index_set = 0;
6747   u8 is_enable = 1;
6748   u8 is_ipv6 = 0;
6749   int ret;
6750
6751   /* Parse args required to build the message */
6752   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6753     {
6754       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6755         sw_if_index_set = 1;
6756       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6757         sw_if_index_set = 1;
6758       else if (unformat (i, "enable"))
6759         is_enable = 1;
6760       else if (unformat (i, "disable"))
6761         is_enable = 0;
6762       else if (unformat (i, "ip4"))
6763         is_ipv6 = 0;
6764       else if (unformat (i, "ip6"))
6765         is_ipv6 = 1;
6766       else
6767         break;
6768     }
6769
6770   if (sw_if_index_set == 0)
6771     {
6772       errmsg ("missing interface name or sw_if_index");
6773       return -99;
6774     }
6775
6776   /* Construct the API message */
6777   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6778
6779   mp->sw_if_index = ntohl (sw_if_index);
6780   mp->enable = is_enable;
6781   mp->is_ipv6 = is_ipv6;
6782
6783   /* send it... */
6784   S (mp);
6785
6786   /* Wait for a reply... */
6787   W (ret);
6788   return ret;
6789 }
6790
6791 static int
6792 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6793 {
6794   unformat_input_t *i = vam->input;
6795   vl_api_sw_interface_set_geneve_bypass_t *mp;
6796   u32 sw_if_index = 0;
6797   u8 sw_if_index_set = 0;
6798   u8 is_enable = 1;
6799   u8 is_ipv6 = 0;
6800   int ret;
6801
6802   /* Parse args required to build the message */
6803   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6804     {
6805       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6806         sw_if_index_set = 1;
6807       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6808         sw_if_index_set = 1;
6809       else if (unformat (i, "enable"))
6810         is_enable = 1;
6811       else if (unformat (i, "disable"))
6812         is_enable = 0;
6813       else if (unformat (i, "ip4"))
6814         is_ipv6 = 0;
6815       else if (unformat (i, "ip6"))
6816         is_ipv6 = 1;
6817       else
6818         break;
6819     }
6820
6821   if (sw_if_index_set == 0)
6822     {
6823       errmsg ("missing interface name or sw_if_index");
6824       return -99;
6825     }
6826
6827   /* Construct the API message */
6828   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6829
6830   mp->sw_if_index = ntohl (sw_if_index);
6831   mp->enable = is_enable;
6832   mp->is_ipv6 = is_ipv6;
6833
6834   /* send it... */
6835   S (mp);
6836
6837   /* Wait for a reply... */
6838   W (ret);
6839   return ret;
6840 }
6841
6842 static int
6843 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6844 {
6845   unformat_input_t *i = vam->input;
6846   vl_api_sw_interface_set_l2_xconnect_t *mp;
6847   u32 rx_sw_if_index;
6848   u8 rx_sw_if_index_set = 0;
6849   u32 tx_sw_if_index;
6850   u8 tx_sw_if_index_set = 0;
6851   u8 enable = 1;
6852   int ret;
6853
6854   /* Parse args required to build the message */
6855   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6856     {
6857       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6858         rx_sw_if_index_set = 1;
6859       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6860         tx_sw_if_index_set = 1;
6861       else if (unformat (i, "rx"))
6862         {
6863           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6864             {
6865               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6866                             &rx_sw_if_index))
6867                 rx_sw_if_index_set = 1;
6868             }
6869           else
6870             break;
6871         }
6872       else if (unformat (i, "tx"))
6873         {
6874           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6875             {
6876               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6877                             &tx_sw_if_index))
6878                 tx_sw_if_index_set = 1;
6879             }
6880           else
6881             break;
6882         }
6883       else if (unformat (i, "enable"))
6884         enable = 1;
6885       else if (unformat (i, "disable"))
6886         enable = 0;
6887       else
6888         break;
6889     }
6890
6891   if (rx_sw_if_index_set == 0)
6892     {
6893       errmsg ("missing rx interface name or rx_sw_if_index");
6894       return -99;
6895     }
6896
6897   if (enable && (tx_sw_if_index_set == 0))
6898     {
6899       errmsg ("missing tx interface name or tx_sw_if_index");
6900       return -99;
6901     }
6902
6903   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6904
6905   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6906   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6907   mp->enable = enable;
6908
6909   S (mp);
6910   W (ret);
6911   return ret;
6912 }
6913
6914 static int
6915 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6916 {
6917   unformat_input_t *i = vam->input;
6918   vl_api_sw_interface_set_l2_bridge_t *mp;
6919   u32 rx_sw_if_index;
6920   u8 rx_sw_if_index_set = 0;
6921   u32 bd_id;
6922   u8 bd_id_set = 0;
6923   u8 bvi = 0;
6924   u32 shg = 0;
6925   u8 enable = 1;
6926   int ret;
6927
6928   /* Parse args required to build the message */
6929   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6930     {
6931       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6932         rx_sw_if_index_set = 1;
6933       else if (unformat (i, "bd_id %d", &bd_id))
6934         bd_id_set = 1;
6935       else
6936         if (unformat
6937             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6938         rx_sw_if_index_set = 1;
6939       else if (unformat (i, "shg %d", &shg))
6940         ;
6941       else if (unformat (i, "bvi"))
6942         bvi = 1;
6943       else if (unformat (i, "enable"))
6944         enable = 1;
6945       else if (unformat (i, "disable"))
6946         enable = 0;
6947       else
6948         break;
6949     }
6950
6951   if (rx_sw_if_index_set == 0)
6952     {
6953       errmsg ("missing rx interface name or sw_if_index");
6954       return -99;
6955     }
6956
6957   if (enable && (bd_id_set == 0))
6958     {
6959       errmsg ("missing bridge domain");
6960       return -99;
6961     }
6962
6963   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6964
6965   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6966   mp->bd_id = ntohl (bd_id);
6967   mp->shg = (u8) shg;
6968   mp->bvi = bvi;
6969   mp->enable = enable;
6970
6971   S (mp);
6972   W (ret);
6973   return ret;
6974 }
6975
6976 static int
6977 api_bridge_domain_dump (vat_main_t * vam)
6978 {
6979   unformat_input_t *i = vam->input;
6980   vl_api_bridge_domain_dump_t *mp;
6981   vl_api_control_ping_t *mp_ping;
6982   u32 bd_id = ~0;
6983   int ret;
6984
6985   /* Parse args required to build the message */
6986   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6987     {
6988       if (unformat (i, "bd_id %d", &bd_id))
6989         ;
6990       else
6991         break;
6992     }
6993
6994   M (BRIDGE_DOMAIN_DUMP, mp);
6995   mp->bd_id = ntohl (bd_id);
6996   S (mp);
6997
6998   /* Use a control ping for synchronization */
6999   MPING (CONTROL_PING, mp_ping);
7000   S (mp_ping);
7001
7002   W (ret);
7003   return ret;
7004 }
7005
7006 static int
7007 api_bridge_domain_add_del (vat_main_t * vam)
7008 {
7009   unformat_input_t *i = vam->input;
7010   vl_api_bridge_domain_add_del_t *mp;
7011   u32 bd_id = ~0;
7012   u8 is_add = 1;
7013   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7014   u8 *bd_tag = NULL;
7015   u32 mac_age = 0;
7016   int ret;
7017
7018   /* Parse args required to build the message */
7019   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7020     {
7021       if (unformat (i, "bd_id %d", &bd_id))
7022         ;
7023       else if (unformat (i, "flood %d", &flood))
7024         ;
7025       else if (unformat (i, "uu-flood %d", &uu_flood))
7026         ;
7027       else if (unformat (i, "forward %d", &forward))
7028         ;
7029       else if (unformat (i, "learn %d", &learn))
7030         ;
7031       else if (unformat (i, "arp-term %d", &arp_term))
7032         ;
7033       else if (unformat (i, "mac-age %d", &mac_age))
7034         ;
7035       else if (unformat (i, "bd-tag %s", &bd_tag))
7036         ;
7037       else if (unformat (i, "del"))
7038         {
7039           is_add = 0;
7040           flood = uu_flood = forward = learn = 0;
7041         }
7042       else
7043         break;
7044     }
7045
7046   if (bd_id == ~0)
7047     {
7048       errmsg ("missing bridge domain");
7049       ret = -99;
7050       goto done;
7051     }
7052
7053   if (mac_age > 255)
7054     {
7055       errmsg ("mac age must be less than 256 ");
7056       ret = -99;
7057       goto done;
7058     }
7059
7060   if ((bd_tag) && (strlen ((char *) bd_tag) > 63))
7061     {
7062       errmsg ("bd-tag cannot be longer than 63");
7063       ret = -99;
7064       goto done;
7065     }
7066
7067   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7068
7069   mp->bd_id = ntohl (bd_id);
7070   mp->flood = flood;
7071   mp->uu_flood = uu_flood;
7072   mp->forward = forward;
7073   mp->learn = learn;
7074   mp->arp_term = arp_term;
7075   mp->is_add = is_add;
7076   mp->mac_age = (u8) mac_age;
7077   if (bd_tag)
7078     strcpy ((char *) mp->bd_tag, (char *) bd_tag);
7079
7080   S (mp);
7081   W (ret);
7082
7083 done:
7084   vec_free (bd_tag);
7085   return ret;
7086 }
7087
7088 static int
7089 api_l2fib_flush_bd (vat_main_t * vam)
7090 {
7091   unformat_input_t *i = vam->input;
7092   vl_api_l2fib_flush_bd_t *mp;
7093   u32 bd_id = ~0;
7094   int ret;
7095
7096   /* Parse args required to build the message */
7097   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7098     {
7099       if (unformat (i, "bd_id %d", &bd_id));
7100       else
7101         break;
7102     }
7103
7104   if (bd_id == ~0)
7105     {
7106       errmsg ("missing bridge domain");
7107       return -99;
7108     }
7109
7110   M (L2FIB_FLUSH_BD, mp);
7111
7112   mp->bd_id = htonl (bd_id);
7113
7114   S (mp);
7115   W (ret);
7116   return ret;
7117 }
7118
7119 static int
7120 api_l2fib_flush_int (vat_main_t * vam)
7121 {
7122   unformat_input_t *i = vam->input;
7123   vl_api_l2fib_flush_int_t *mp;
7124   u32 sw_if_index = ~0;
7125   int ret;
7126
7127   /* Parse args required to build the message */
7128   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7129     {
7130       if (unformat (i, "sw_if_index %d", &sw_if_index));
7131       else
7132         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7133       else
7134         break;
7135     }
7136
7137   if (sw_if_index == ~0)
7138     {
7139       errmsg ("missing interface name or sw_if_index");
7140       return -99;
7141     }
7142
7143   M (L2FIB_FLUSH_INT, mp);
7144
7145   mp->sw_if_index = ntohl (sw_if_index);
7146
7147   S (mp);
7148   W (ret);
7149   return ret;
7150 }
7151
7152 static int
7153 api_l2fib_add_del (vat_main_t * vam)
7154 {
7155   unformat_input_t *i = vam->input;
7156   vl_api_l2fib_add_del_t *mp;
7157   f64 timeout;
7158   u8 mac[6] = { 0 };
7159   u8 mac_set = 0;
7160   u32 bd_id;
7161   u8 bd_id_set = 0;
7162   u32 sw_if_index = ~0;
7163   u8 sw_if_index_set = 0;
7164   u8 is_add = 1;
7165   u8 static_mac = 0;
7166   u8 filter_mac = 0;
7167   u8 bvi_mac = 0;
7168   int count = 1;
7169   f64 before = 0;
7170   int j;
7171
7172   /* Parse args required to build the message */
7173   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7174     {
7175       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7176         mac_set = 1;
7177       else if (unformat (i, "bd_id %d", &bd_id))
7178         bd_id_set = 1;
7179       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7180         sw_if_index_set = 1;
7181       else if (unformat (i, "sw_if"))
7182         {
7183           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7184             {
7185               if (unformat
7186                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7187                 sw_if_index_set = 1;
7188             }
7189           else
7190             break;
7191         }
7192       else if (unformat (i, "static"))
7193         static_mac = 1;
7194       else if (unformat (i, "filter"))
7195         {
7196           filter_mac = 1;
7197           static_mac = 1;
7198         }
7199       else if (unformat (i, "bvi"))
7200         {
7201           bvi_mac = 1;
7202           static_mac = 1;
7203         }
7204       else if (unformat (i, "del"))
7205         is_add = 0;
7206       else if (unformat (i, "count %d", &count))
7207         ;
7208       else
7209         break;
7210     }
7211
7212   if (mac_set == 0)
7213     {
7214       errmsg ("missing mac address");
7215       return -99;
7216     }
7217
7218   if (bd_id_set == 0)
7219     {
7220       errmsg ("missing bridge domain");
7221       return -99;
7222     }
7223
7224   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7225     {
7226       errmsg ("missing interface name or sw_if_index");
7227       return -99;
7228     }
7229
7230   if (count > 1)
7231     {
7232       /* Turn on async mode */
7233       vam->async_mode = 1;
7234       vam->async_errors = 0;
7235       before = vat_time_now (vam);
7236     }
7237
7238   for (j = 0; j < count; j++)
7239     {
7240       M (L2FIB_ADD_DEL, mp);
7241
7242       clib_memcpy (mp->mac, mac, 6);
7243       mp->bd_id = ntohl (bd_id);
7244       mp->is_add = is_add;
7245
7246       if (is_add)
7247         {
7248           mp->sw_if_index = ntohl (sw_if_index);
7249           mp->static_mac = static_mac;
7250           mp->filter_mac = filter_mac;
7251           mp->bvi_mac = bvi_mac;
7252         }
7253       increment_mac_address (mac);
7254       /* send it... */
7255       S (mp);
7256     }
7257
7258   if (count > 1)
7259     {
7260       vl_api_control_ping_t *mp_ping;
7261       f64 after;
7262
7263       /* Shut off async mode */
7264       vam->async_mode = 0;
7265
7266       MPING (CONTROL_PING, mp_ping);
7267       S (mp_ping);
7268
7269       timeout = vat_time_now (vam) + 1.0;
7270       while (vat_time_now (vam) < timeout)
7271         if (vam->result_ready == 1)
7272           goto out;
7273       vam->retval = -99;
7274
7275     out:
7276       if (vam->retval == -99)
7277         errmsg ("timeout");
7278
7279       if (vam->async_errors > 0)
7280         {
7281           errmsg ("%d asynchronous errors", vam->async_errors);
7282           vam->retval = -98;
7283         }
7284       vam->async_errors = 0;
7285       after = vat_time_now (vam);
7286
7287       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7288              count, after - before, count / (after - before));
7289     }
7290   else
7291     {
7292       int ret;
7293
7294       /* Wait for a reply... */
7295       W (ret);
7296       return ret;
7297     }
7298   /* Return the good/bad news */
7299   return (vam->retval);
7300 }
7301
7302 static int
7303 api_bridge_domain_set_mac_age (vat_main_t * vam)
7304 {
7305   unformat_input_t *i = vam->input;
7306   vl_api_bridge_domain_set_mac_age_t *mp;
7307   u32 bd_id = ~0;
7308   u32 mac_age = 0;
7309   int ret;
7310
7311   /* Parse args required to build the message */
7312   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7313     {
7314       if (unformat (i, "bd_id %d", &bd_id));
7315       else if (unformat (i, "mac-age %d", &mac_age));
7316       else
7317         break;
7318     }
7319
7320   if (bd_id == ~0)
7321     {
7322       errmsg ("missing bridge domain");
7323       return -99;
7324     }
7325
7326   if (mac_age > 255)
7327     {
7328       errmsg ("mac age must be less than 256 ");
7329       return -99;
7330     }
7331
7332   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7333
7334   mp->bd_id = htonl (bd_id);
7335   mp->mac_age = (u8) mac_age;
7336
7337   S (mp);
7338   W (ret);
7339   return ret;
7340 }
7341
7342 static int
7343 api_l2_flags (vat_main_t * vam)
7344 {
7345   unformat_input_t *i = vam->input;
7346   vl_api_l2_flags_t *mp;
7347   u32 sw_if_index;
7348   u32 flags = 0;
7349   u8 sw_if_index_set = 0;
7350   u8 is_set = 0;
7351   int ret;
7352
7353   /* Parse args required to build the message */
7354   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7355     {
7356       if (unformat (i, "sw_if_index %d", &sw_if_index))
7357         sw_if_index_set = 1;
7358       else if (unformat (i, "sw_if"))
7359         {
7360           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7361             {
7362               if (unformat
7363                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7364                 sw_if_index_set = 1;
7365             }
7366           else
7367             break;
7368         }
7369       else if (unformat (i, "learn"))
7370         flags |= L2_LEARN;
7371       else if (unformat (i, "forward"))
7372         flags |= L2_FWD;
7373       else if (unformat (i, "flood"))
7374         flags |= L2_FLOOD;
7375       else if (unformat (i, "uu-flood"))
7376         flags |= L2_UU_FLOOD;
7377       else if (unformat (i, "arp-term"))
7378         flags |= L2_ARP_TERM;
7379       else if (unformat (i, "off"))
7380         is_set = 0;
7381       else if (unformat (i, "disable"))
7382         is_set = 0;
7383       else
7384         break;
7385     }
7386
7387   if (sw_if_index_set == 0)
7388     {
7389       errmsg ("missing interface name or sw_if_index");
7390       return -99;
7391     }
7392
7393   M (L2_FLAGS, mp);
7394
7395   mp->sw_if_index = ntohl (sw_if_index);
7396   mp->feature_bitmap = ntohl (flags);
7397   mp->is_set = is_set;
7398
7399   S (mp);
7400   W (ret);
7401   return ret;
7402 }
7403
7404 static int
7405 api_bridge_flags (vat_main_t * vam)
7406 {
7407   unformat_input_t *i = vam->input;
7408   vl_api_bridge_flags_t *mp;
7409   u32 bd_id;
7410   u8 bd_id_set = 0;
7411   u8 is_set = 1;
7412   u32 flags = 0;
7413   int ret;
7414
7415   /* Parse args required to build the message */
7416   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7417     {
7418       if (unformat (i, "bd_id %d", &bd_id))
7419         bd_id_set = 1;
7420       else if (unformat (i, "learn"))
7421         flags |= L2_LEARN;
7422       else if (unformat (i, "forward"))
7423         flags |= L2_FWD;
7424       else if (unformat (i, "flood"))
7425         flags |= L2_FLOOD;
7426       else if (unformat (i, "uu-flood"))
7427         flags |= L2_UU_FLOOD;
7428       else if (unformat (i, "arp-term"))
7429         flags |= L2_ARP_TERM;
7430       else if (unformat (i, "off"))
7431         is_set = 0;
7432       else if (unformat (i, "disable"))
7433         is_set = 0;
7434       else
7435         break;
7436     }
7437
7438   if (bd_id_set == 0)
7439     {
7440       errmsg ("missing bridge domain");
7441       return -99;
7442     }
7443
7444   M (BRIDGE_FLAGS, mp);
7445
7446   mp->bd_id = ntohl (bd_id);
7447   mp->feature_bitmap = ntohl (flags);
7448   mp->is_set = is_set;
7449
7450   S (mp);
7451   W (ret);
7452   return ret;
7453 }
7454
7455 static int
7456 api_bd_ip_mac_add_del (vat_main_t * vam)
7457 {
7458   unformat_input_t *i = vam->input;
7459   vl_api_bd_ip_mac_add_del_t *mp;
7460   u32 bd_id;
7461   u8 is_ipv6 = 0;
7462   u8 is_add = 1;
7463   u8 bd_id_set = 0;
7464   u8 ip_set = 0;
7465   u8 mac_set = 0;
7466   ip4_address_t v4addr;
7467   ip6_address_t v6addr;
7468   u8 macaddr[6];
7469   int ret;
7470
7471
7472   /* Parse args required to build the message */
7473   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7474     {
7475       if (unformat (i, "bd_id %d", &bd_id))
7476         {
7477           bd_id_set++;
7478         }
7479       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7480         {
7481           ip_set++;
7482         }
7483       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7484         {
7485           ip_set++;
7486           is_ipv6++;
7487         }
7488       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7489         {
7490           mac_set++;
7491         }
7492       else if (unformat (i, "del"))
7493         is_add = 0;
7494       else
7495         break;
7496     }
7497
7498   if (bd_id_set == 0)
7499     {
7500       errmsg ("missing bridge domain");
7501       return -99;
7502     }
7503   else if (ip_set == 0)
7504     {
7505       errmsg ("missing IP address");
7506       return -99;
7507     }
7508   else if (mac_set == 0)
7509     {
7510       errmsg ("missing MAC address");
7511       return -99;
7512     }
7513
7514   M (BD_IP_MAC_ADD_DEL, mp);
7515
7516   mp->bd_id = ntohl (bd_id);
7517   mp->is_ipv6 = is_ipv6;
7518   mp->is_add = is_add;
7519   if (is_ipv6)
7520     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7521   else
7522     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7523   clib_memcpy (mp->mac_address, macaddr, 6);
7524   S (mp);
7525   W (ret);
7526   return ret;
7527 }
7528
7529 static int
7530 api_tap_connect (vat_main_t * vam)
7531 {
7532   unformat_input_t *i = vam->input;
7533   vl_api_tap_connect_t *mp;
7534   u8 mac_address[6];
7535   u8 random_mac = 1;
7536   u8 name_set = 0;
7537   u8 *tap_name;
7538   u8 *tag = 0;
7539   ip4_address_t ip4_address;
7540   u32 ip4_mask_width;
7541   int ip4_address_set = 0;
7542   ip6_address_t ip6_address;
7543   u32 ip6_mask_width;
7544   int ip6_address_set = 0;
7545   int ret;
7546
7547   memset (mac_address, 0, sizeof (mac_address));
7548
7549   /* Parse args required to build the message */
7550   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7551     {
7552       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7553         {
7554           random_mac = 0;
7555         }
7556       else if (unformat (i, "random-mac"))
7557         random_mac = 1;
7558       else if (unformat (i, "tapname %s", &tap_name))
7559         name_set = 1;
7560       else if (unformat (i, "tag %s", &tag))
7561         ;
7562       else if (unformat (i, "address %U/%d",
7563                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7564         ip4_address_set = 1;
7565       else if (unformat (i, "address %U/%d",
7566                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7567         ip6_address_set = 1;
7568       else
7569         break;
7570     }
7571
7572   if (name_set == 0)
7573     {
7574       errmsg ("missing tap name");
7575       return -99;
7576     }
7577   if (vec_len (tap_name) > 63)
7578     {
7579       errmsg ("tap name too long");
7580       return -99;
7581     }
7582   vec_add1 (tap_name, 0);
7583
7584   if (vec_len (tag) > 63)
7585     {
7586       errmsg ("tag too long");
7587       return -99;
7588     }
7589
7590   /* Construct the API message */
7591   M (TAP_CONNECT, mp);
7592
7593   mp->use_random_mac = random_mac;
7594   clib_memcpy (mp->mac_address, mac_address, 6);
7595   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7596   if (tag)
7597     clib_memcpy (mp->tag, tag, vec_len (tag));
7598
7599   if (ip4_address_set)
7600     {
7601       mp->ip4_address_set = 1;
7602       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7603       mp->ip4_mask_width = ip4_mask_width;
7604     }
7605   if (ip6_address_set)
7606     {
7607       mp->ip6_address_set = 1;
7608       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7609       mp->ip6_mask_width = ip6_mask_width;
7610     }
7611
7612   vec_free (tap_name);
7613   vec_free (tag);
7614
7615   /* send it... */
7616   S (mp);
7617
7618   /* Wait for a reply... */
7619   W (ret);
7620   return ret;
7621 }
7622
7623 static int
7624 api_tap_modify (vat_main_t * vam)
7625 {
7626   unformat_input_t *i = vam->input;
7627   vl_api_tap_modify_t *mp;
7628   u8 mac_address[6];
7629   u8 random_mac = 1;
7630   u8 name_set = 0;
7631   u8 *tap_name;
7632   u32 sw_if_index = ~0;
7633   u8 sw_if_index_set = 0;
7634   int ret;
7635
7636   memset (mac_address, 0, sizeof (mac_address));
7637
7638   /* Parse args required to build the message */
7639   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7640     {
7641       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7642         sw_if_index_set = 1;
7643       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7644         sw_if_index_set = 1;
7645       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7646         {
7647           random_mac = 0;
7648         }
7649       else if (unformat (i, "random-mac"))
7650         random_mac = 1;
7651       else if (unformat (i, "tapname %s", &tap_name))
7652         name_set = 1;
7653       else
7654         break;
7655     }
7656
7657   if (sw_if_index_set == 0)
7658     {
7659       errmsg ("missing vpp interface name");
7660       return -99;
7661     }
7662   if (name_set == 0)
7663     {
7664       errmsg ("missing tap name");
7665       return -99;
7666     }
7667   if (vec_len (tap_name) > 63)
7668     {
7669       errmsg ("tap name too long");
7670     }
7671   vec_add1 (tap_name, 0);
7672
7673   /* Construct the API message */
7674   M (TAP_MODIFY, mp);
7675
7676   mp->use_random_mac = random_mac;
7677   mp->sw_if_index = ntohl (sw_if_index);
7678   clib_memcpy (mp->mac_address, mac_address, 6);
7679   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7680   vec_free (tap_name);
7681
7682   /* send it... */
7683   S (mp);
7684
7685   /* Wait for a reply... */
7686   W (ret);
7687   return ret;
7688 }
7689
7690 static int
7691 api_tap_delete (vat_main_t * vam)
7692 {
7693   unformat_input_t *i = vam->input;
7694   vl_api_tap_delete_t *mp;
7695   u32 sw_if_index = ~0;
7696   u8 sw_if_index_set = 0;
7697   int ret;
7698
7699   /* Parse args required to build the message */
7700   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7701     {
7702       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7703         sw_if_index_set = 1;
7704       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7705         sw_if_index_set = 1;
7706       else
7707         break;
7708     }
7709
7710   if (sw_if_index_set == 0)
7711     {
7712       errmsg ("missing vpp interface name");
7713       return -99;
7714     }
7715
7716   /* Construct the API message */
7717   M (TAP_DELETE, mp);
7718
7719   mp->sw_if_index = ntohl (sw_if_index);
7720
7721   /* send it... */
7722   S (mp);
7723
7724   /* Wait for a reply... */
7725   W (ret);
7726   return ret;
7727 }
7728
7729 static int
7730 api_ip_table_add_del (vat_main_t * vam)
7731 {
7732   unformat_input_t *i = vam->input;
7733   vl_api_ip_table_add_del_t *mp;
7734   u32 table_id = ~0;
7735   u8 is_ipv6 = 0;
7736   u8 is_add = 1;
7737   int ret = 0;
7738
7739   /* Parse args required to build the message */
7740   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7741     {
7742       if (unformat (i, "ipv6"))
7743         is_ipv6 = 1;
7744       else if (unformat (i, "del"))
7745         is_add = 0;
7746       else if (unformat (i, "add"))
7747         is_add = 1;
7748       else if (unformat (i, "table %d", &table_id))
7749         ;
7750       else
7751         {
7752           clib_warning ("parse error '%U'", format_unformat_error, i);
7753           return -99;
7754         }
7755     }
7756
7757   if (~0 == table_id)
7758     {
7759       errmsg ("missing table-ID");
7760       return -99;
7761     }
7762
7763   /* Construct the API message */
7764   M (IP_TABLE_ADD_DEL, mp);
7765
7766   mp->table_id = ntohl (table_id);
7767   mp->is_ipv6 = is_ipv6;
7768   mp->is_add = is_add;
7769
7770   /* send it... */
7771   S (mp);
7772
7773   /* Wait for a reply... */
7774   W (ret);
7775
7776   return ret;
7777 }
7778
7779 static int
7780 api_ip_add_del_route (vat_main_t * vam)
7781 {
7782   unformat_input_t *i = vam->input;
7783   vl_api_ip_add_del_route_t *mp;
7784   u32 sw_if_index = ~0, vrf_id = 0;
7785   u8 is_ipv6 = 0;
7786   u8 is_local = 0, is_drop = 0;
7787   u8 is_unreach = 0, is_prohibit = 0;
7788   u8 create_vrf_if_needed = 0;
7789   u8 is_add = 1;
7790   u32 next_hop_weight = 1;
7791   u8 is_multipath = 0;
7792   u8 address_set = 0;
7793   u8 address_length_set = 0;
7794   u32 next_hop_table_id = 0;
7795   u32 resolve_attempts = 0;
7796   u32 dst_address_length = 0;
7797   u8 next_hop_set = 0;
7798   ip4_address_t v4_dst_address, v4_next_hop_address;
7799   ip6_address_t v6_dst_address, v6_next_hop_address;
7800   int count = 1;
7801   int j;
7802   f64 before = 0;
7803   u32 random_add_del = 0;
7804   u32 *random_vector = 0;
7805   uword *random_hash;
7806   u32 random_seed = 0xdeaddabe;
7807   u32 classify_table_index = ~0;
7808   u8 is_classify = 0;
7809   u8 resolve_host = 0, resolve_attached = 0;
7810   mpls_label_t *next_hop_out_label_stack = NULL;
7811   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7812   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7813
7814   /* Parse args required to build the message */
7815   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7816     {
7817       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7818         ;
7819       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7820         ;
7821       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
7822         {
7823           address_set = 1;
7824           is_ipv6 = 0;
7825         }
7826       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
7827         {
7828           address_set = 1;
7829           is_ipv6 = 1;
7830         }
7831       else if (unformat (i, "/%d", &dst_address_length))
7832         {
7833           address_length_set = 1;
7834         }
7835
7836       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
7837                                          &v4_next_hop_address))
7838         {
7839           next_hop_set = 1;
7840         }
7841       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
7842                                          &v6_next_hop_address))
7843         {
7844           next_hop_set = 1;
7845         }
7846       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
7847         ;
7848       else if (unformat (i, "weight %d", &next_hop_weight))
7849         ;
7850       else if (unformat (i, "drop"))
7851         {
7852           is_drop = 1;
7853         }
7854       else if (unformat (i, "null-send-unreach"))
7855         {
7856           is_unreach = 1;
7857         }
7858       else if (unformat (i, "null-send-prohibit"))
7859         {
7860           is_prohibit = 1;
7861         }
7862       else if (unformat (i, "local"))
7863         {
7864           is_local = 1;
7865         }
7866       else if (unformat (i, "classify %d", &classify_table_index))
7867         {
7868           is_classify = 1;
7869         }
7870       else if (unformat (i, "del"))
7871         is_add = 0;
7872       else if (unformat (i, "add"))
7873         is_add = 1;
7874       else if (unformat (i, "resolve-via-host"))
7875         resolve_host = 1;
7876       else if (unformat (i, "resolve-via-attached"))
7877         resolve_attached = 1;
7878       else if (unformat (i, "multipath"))
7879         is_multipath = 1;
7880       else if (unformat (i, "vrf %d", &vrf_id))
7881         ;
7882       else if (unformat (i, "create-vrf"))
7883         create_vrf_if_needed = 1;
7884       else if (unformat (i, "count %d", &count))
7885         ;
7886       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
7887         ;
7888       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7889         ;
7890       else if (unformat (i, "out-label %d", &next_hop_out_label))
7891         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7892       else if (unformat (i, "via-label %d", &next_hop_via_label))
7893         ;
7894       else if (unformat (i, "random"))
7895         random_add_del = 1;
7896       else if (unformat (i, "seed %d", &random_seed))
7897         ;
7898       else
7899         {
7900           clib_warning ("parse error '%U'", format_unformat_error, i);
7901           return -99;
7902         }
7903     }
7904
7905   if (!next_hop_set && !is_drop && !is_local &&
7906       !is_classify && !is_unreach && !is_prohibit &&
7907       MPLS_LABEL_INVALID == next_hop_via_label)
7908     {
7909       errmsg
7910         ("next hop / local / drop / unreach / prohibit / classify not set");
7911       return -99;
7912     }
7913
7914   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
7915     {
7916       errmsg ("next hop and next-hop via label set");
7917       return -99;
7918     }
7919   if (address_set == 0)
7920     {
7921       errmsg ("missing addresses");
7922       return -99;
7923     }
7924
7925   if (address_length_set == 0)
7926     {
7927       errmsg ("missing address length");
7928       return -99;
7929     }
7930
7931   /* Generate a pile of unique, random routes */
7932   if (random_add_del)
7933     {
7934       u32 this_random_address;
7935       random_hash = hash_create (count, sizeof (uword));
7936
7937       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
7938       for (j = 0; j <= count; j++)
7939         {
7940           do
7941             {
7942               this_random_address = random_u32 (&random_seed);
7943               this_random_address =
7944                 clib_host_to_net_u32 (this_random_address);
7945             }
7946           while (hash_get (random_hash, this_random_address));
7947           vec_add1 (random_vector, this_random_address);
7948           hash_set (random_hash, this_random_address, 1);
7949         }
7950       hash_free (random_hash);
7951       v4_dst_address.as_u32 = random_vector[0];
7952     }
7953
7954   if (count > 1)
7955     {
7956       /* Turn on async mode */
7957       vam->async_mode = 1;
7958       vam->async_errors = 0;
7959       before = vat_time_now (vam);
7960     }
7961
7962   for (j = 0; j < count; j++)
7963     {
7964       /* Construct the API message */
7965       M2 (IP_ADD_DEL_ROUTE, mp,
7966           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7967
7968       mp->next_hop_sw_if_index = ntohl (sw_if_index);
7969       mp->table_id = ntohl (vrf_id);
7970       mp->create_vrf_if_needed = create_vrf_if_needed;
7971
7972       mp->is_add = is_add;
7973       mp->is_drop = is_drop;
7974       mp->is_unreach = is_unreach;
7975       mp->is_prohibit = is_prohibit;
7976       mp->is_ipv6 = is_ipv6;
7977       mp->is_local = is_local;
7978       mp->is_classify = is_classify;
7979       mp->is_multipath = is_multipath;
7980       mp->is_resolve_host = resolve_host;
7981       mp->is_resolve_attached = resolve_attached;
7982       mp->next_hop_weight = next_hop_weight;
7983       mp->dst_address_length = dst_address_length;
7984       mp->next_hop_table_id = ntohl (next_hop_table_id);
7985       mp->classify_table_index = ntohl (classify_table_index);
7986       mp->next_hop_via_label = ntohl (next_hop_via_label);
7987       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7988       if (0 != mp->next_hop_n_out_labels)
7989         {
7990           memcpy (mp->next_hop_out_label_stack,
7991                   next_hop_out_label_stack,
7992                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7993           vec_free (next_hop_out_label_stack);
7994         }
7995
7996       if (is_ipv6)
7997         {
7998           clib_memcpy (mp->dst_address, &v6_dst_address,
7999                        sizeof (v6_dst_address));
8000           if (next_hop_set)
8001             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8002                          sizeof (v6_next_hop_address));
8003           increment_v6_address (&v6_dst_address);
8004         }
8005       else
8006         {
8007           clib_memcpy (mp->dst_address, &v4_dst_address,
8008                        sizeof (v4_dst_address));
8009           if (next_hop_set)
8010             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8011                          sizeof (v4_next_hop_address));
8012           if (random_add_del)
8013             v4_dst_address.as_u32 = random_vector[j + 1];
8014           else
8015             increment_v4_address (&v4_dst_address);
8016         }
8017       /* send it... */
8018       S (mp);
8019       /* If we receive SIGTERM, stop now... */
8020       if (vam->do_exit)
8021         break;
8022     }
8023
8024   /* When testing multiple add/del ops, use a control-ping to sync */
8025   if (count > 1)
8026     {
8027       vl_api_control_ping_t *mp_ping;
8028       f64 after;
8029       f64 timeout;
8030
8031       /* Shut off async mode */
8032       vam->async_mode = 0;
8033
8034       MPING (CONTROL_PING, mp_ping);
8035       S (mp_ping);
8036
8037       timeout = vat_time_now (vam) + 1.0;
8038       while (vat_time_now (vam) < timeout)
8039         if (vam->result_ready == 1)
8040           goto out;
8041       vam->retval = -99;
8042
8043     out:
8044       if (vam->retval == -99)
8045         errmsg ("timeout");
8046
8047       if (vam->async_errors > 0)
8048         {
8049           errmsg ("%d asynchronous errors", vam->async_errors);
8050           vam->retval = -98;
8051         }
8052       vam->async_errors = 0;
8053       after = vat_time_now (vam);
8054
8055       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8056       if (j > 0)
8057         count = j;
8058
8059       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8060              count, after - before, count / (after - before));
8061     }
8062   else
8063     {
8064       int ret;
8065
8066       /* Wait for a reply... */
8067       W (ret);
8068       return ret;
8069     }
8070
8071   /* Return the good/bad news */
8072   return (vam->retval);
8073 }
8074
8075 static int
8076 api_ip_mroute_add_del (vat_main_t * vam)
8077 {
8078   unformat_input_t *i = vam->input;
8079   vl_api_ip_mroute_add_del_t *mp;
8080   u32 sw_if_index = ~0, vrf_id = 0;
8081   u8 is_ipv6 = 0;
8082   u8 is_local = 0;
8083   u8 create_vrf_if_needed = 0;
8084   u8 is_add = 1;
8085   u8 address_set = 0;
8086   u32 grp_address_length = 0;
8087   ip4_address_t v4_grp_address, v4_src_address;
8088   ip6_address_t v6_grp_address, v6_src_address;
8089   mfib_itf_flags_t iflags = 0;
8090   mfib_entry_flags_t eflags = 0;
8091   int ret;
8092
8093   /* Parse args required to build the message */
8094   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8095     {
8096       if (unformat (i, "sw_if_index %d", &sw_if_index))
8097         ;
8098       else if (unformat (i, "%U %U",
8099                          unformat_ip4_address, &v4_src_address,
8100                          unformat_ip4_address, &v4_grp_address))
8101         {
8102           grp_address_length = 64;
8103           address_set = 1;
8104           is_ipv6 = 0;
8105         }
8106       else if (unformat (i, "%U %U",
8107                          unformat_ip6_address, &v6_src_address,
8108                          unformat_ip6_address, &v6_grp_address))
8109         {
8110           grp_address_length = 256;
8111           address_set = 1;
8112           is_ipv6 = 1;
8113         }
8114       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8115         {
8116           memset (&v4_src_address, 0, sizeof (v4_src_address));
8117           grp_address_length = 32;
8118           address_set = 1;
8119           is_ipv6 = 0;
8120         }
8121       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8122         {
8123           memset (&v6_src_address, 0, sizeof (v6_src_address));
8124           grp_address_length = 128;
8125           address_set = 1;
8126           is_ipv6 = 1;
8127         }
8128       else if (unformat (i, "/%d", &grp_address_length))
8129         ;
8130       else if (unformat (i, "local"))
8131         {
8132           is_local = 1;
8133         }
8134       else if (unformat (i, "del"))
8135         is_add = 0;
8136       else if (unformat (i, "add"))
8137         is_add = 1;
8138       else if (unformat (i, "vrf %d", &vrf_id))
8139         ;
8140       else if (unformat (i, "create-vrf"))
8141         create_vrf_if_needed = 1;
8142       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8143         ;
8144       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8145         ;
8146       else
8147         {
8148           clib_warning ("parse error '%U'", format_unformat_error, i);
8149           return -99;
8150         }
8151     }
8152
8153   if (address_set == 0)
8154     {
8155       errmsg ("missing addresses\n");
8156       return -99;
8157     }
8158
8159   /* Construct the API message */
8160   M (IP_MROUTE_ADD_DEL, mp);
8161
8162   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8163   mp->table_id = ntohl (vrf_id);
8164   mp->create_vrf_if_needed = create_vrf_if_needed;
8165
8166   mp->is_add = is_add;
8167   mp->is_ipv6 = is_ipv6;
8168   mp->is_local = is_local;
8169   mp->itf_flags = ntohl (iflags);
8170   mp->entry_flags = ntohl (eflags);
8171   mp->grp_address_length = grp_address_length;
8172   mp->grp_address_length = ntohs (mp->grp_address_length);
8173
8174   if (is_ipv6)
8175     {
8176       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8177       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8178     }
8179   else
8180     {
8181       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8182       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8183
8184     }
8185
8186   /* send it... */
8187   S (mp);
8188   /* Wait for a reply... */
8189   W (ret);
8190   return ret;
8191 }
8192
8193 static int
8194 api_mpls_table_add_del (vat_main_t * vam)
8195 {
8196   unformat_input_t *i = vam->input;
8197   vl_api_mpls_table_add_del_t *mp;
8198   u32 table_id = ~0;
8199   u8 is_add = 1;
8200   int ret = 0;
8201
8202   /* Parse args required to build the message */
8203   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8204     {
8205       if (unformat (i, "table %d", &table_id))
8206         ;
8207       else if (unformat (i, "del"))
8208         is_add = 0;
8209       else if (unformat (i, "add"))
8210         is_add = 1;
8211       else
8212         {
8213           clib_warning ("parse error '%U'", format_unformat_error, i);
8214           return -99;
8215         }
8216     }
8217
8218   if (~0 == table_id)
8219     {
8220       errmsg ("missing table-ID");
8221       return -99;
8222     }
8223
8224   /* Construct the API message */
8225   M (MPLS_TABLE_ADD_DEL, mp);
8226
8227   mp->mt_table_id = ntohl (table_id);
8228   mp->mt_is_add = is_add;
8229
8230   /* send it... */
8231   S (mp);
8232
8233   /* Wait for a reply... */
8234   W (ret);
8235
8236   return ret;
8237 }
8238
8239 static int
8240 api_mpls_route_add_del (vat_main_t * vam)
8241 {
8242   unformat_input_t *i = vam->input;
8243   vl_api_mpls_route_add_del_t *mp;
8244   u32 sw_if_index = ~0, table_id = 0;
8245   u8 create_table_if_needed = 0;
8246   u8 is_add = 1;
8247   u32 next_hop_weight = 1;
8248   u8 is_multipath = 0;
8249   u32 next_hop_table_id = 0;
8250   u8 next_hop_set = 0;
8251   ip4_address_t v4_next_hop_address = {
8252     .as_u32 = 0,
8253   };
8254   ip6_address_t v6_next_hop_address = { {0} };
8255   int count = 1;
8256   int j;
8257   f64 before = 0;
8258   u32 classify_table_index = ~0;
8259   u8 is_classify = 0;
8260   u8 resolve_host = 0, resolve_attached = 0;
8261   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8262   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8263   mpls_label_t *next_hop_out_label_stack = NULL;
8264   mpls_label_t local_label = MPLS_LABEL_INVALID;
8265   u8 is_eos = 0;
8266   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8267
8268   /* Parse args required to build the message */
8269   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8270     {
8271       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8272         ;
8273       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8274         ;
8275       else if (unformat (i, "%d", &local_label))
8276         ;
8277       else if (unformat (i, "eos"))
8278         is_eos = 1;
8279       else if (unformat (i, "non-eos"))
8280         is_eos = 0;
8281       else if (unformat (i, "via %U", unformat_ip4_address,
8282                          &v4_next_hop_address))
8283         {
8284           next_hop_set = 1;
8285           next_hop_proto = DPO_PROTO_IP4;
8286         }
8287       else if (unformat (i, "via %U", unformat_ip6_address,
8288                          &v6_next_hop_address))
8289         {
8290           next_hop_set = 1;
8291           next_hop_proto = DPO_PROTO_IP6;
8292         }
8293       else if (unformat (i, "weight %d", &next_hop_weight))
8294         ;
8295       else if (unformat (i, "create-table"))
8296         create_table_if_needed = 1;
8297       else if (unformat (i, "classify %d", &classify_table_index))
8298         {
8299           is_classify = 1;
8300         }
8301       else if (unformat (i, "del"))
8302         is_add = 0;
8303       else if (unformat (i, "add"))
8304         is_add = 1;
8305       else if (unformat (i, "resolve-via-host"))
8306         resolve_host = 1;
8307       else if (unformat (i, "resolve-via-attached"))
8308         resolve_attached = 1;
8309       else if (unformat (i, "multipath"))
8310         is_multipath = 1;
8311       else if (unformat (i, "count %d", &count))
8312         ;
8313       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8314         {
8315           next_hop_set = 1;
8316           next_hop_proto = DPO_PROTO_IP4;
8317         }
8318       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8319         {
8320           next_hop_set = 1;
8321           next_hop_proto = DPO_PROTO_IP6;
8322         }
8323       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8324         ;
8325       else if (unformat (i, "via-label %d", &next_hop_via_label))
8326         ;
8327       else if (unformat (i, "out-label %d", &next_hop_out_label))
8328         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8329       else
8330         {
8331           clib_warning ("parse error '%U'", format_unformat_error, i);
8332           return -99;
8333         }
8334     }
8335
8336   if (!next_hop_set && !is_classify)
8337     {
8338       errmsg ("next hop / classify not set");
8339       return -99;
8340     }
8341
8342   if (MPLS_LABEL_INVALID == local_label)
8343     {
8344       errmsg ("missing label");
8345       return -99;
8346     }
8347
8348   if (count > 1)
8349     {
8350       /* Turn on async mode */
8351       vam->async_mode = 1;
8352       vam->async_errors = 0;
8353       before = vat_time_now (vam);
8354     }
8355
8356   for (j = 0; j < count; j++)
8357     {
8358       /* Construct the API message */
8359       M2 (MPLS_ROUTE_ADD_DEL, mp,
8360           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8361
8362       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8363       mp->mr_table_id = ntohl (table_id);
8364       mp->mr_create_table_if_needed = create_table_if_needed;
8365
8366       mp->mr_is_add = is_add;
8367       mp->mr_next_hop_proto = next_hop_proto;
8368       mp->mr_is_classify = is_classify;
8369       mp->mr_is_multipath = is_multipath;
8370       mp->mr_is_resolve_host = resolve_host;
8371       mp->mr_is_resolve_attached = resolve_attached;
8372       mp->mr_next_hop_weight = next_hop_weight;
8373       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8374       mp->mr_classify_table_index = ntohl (classify_table_index);
8375       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8376       mp->mr_label = ntohl (local_label);
8377       mp->mr_eos = is_eos;
8378
8379       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8380       if (0 != mp->mr_next_hop_n_out_labels)
8381         {
8382           memcpy (mp->mr_next_hop_out_label_stack,
8383                   next_hop_out_label_stack,
8384                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8385           vec_free (next_hop_out_label_stack);
8386         }
8387
8388       if (next_hop_set)
8389         {
8390           if (DPO_PROTO_IP4 == next_hop_proto)
8391             {
8392               clib_memcpy (mp->mr_next_hop,
8393                            &v4_next_hop_address,
8394                            sizeof (v4_next_hop_address));
8395             }
8396           else if (DPO_PROTO_IP6 == next_hop_proto)
8397
8398             {
8399               clib_memcpy (mp->mr_next_hop,
8400                            &v6_next_hop_address,
8401                            sizeof (v6_next_hop_address));
8402             }
8403         }
8404       local_label++;
8405
8406       /* send it... */
8407       S (mp);
8408       /* If we receive SIGTERM, stop now... */
8409       if (vam->do_exit)
8410         break;
8411     }
8412
8413   /* When testing multiple add/del ops, use a control-ping to sync */
8414   if (count > 1)
8415     {
8416       vl_api_control_ping_t *mp_ping;
8417       f64 after;
8418       f64 timeout;
8419
8420       /* Shut off async mode */
8421       vam->async_mode = 0;
8422
8423       MPING (CONTROL_PING, mp_ping);
8424       S (mp_ping);
8425
8426       timeout = vat_time_now (vam) + 1.0;
8427       while (vat_time_now (vam) < timeout)
8428         if (vam->result_ready == 1)
8429           goto out;
8430       vam->retval = -99;
8431
8432     out:
8433       if (vam->retval == -99)
8434         errmsg ("timeout");
8435
8436       if (vam->async_errors > 0)
8437         {
8438           errmsg ("%d asynchronous errors", vam->async_errors);
8439           vam->retval = -98;
8440         }
8441       vam->async_errors = 0;
8442       after = vat_time_now (vam);
8443
8444       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8445       if (j > 0)
8446         count = j;
8447
8448       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8449              count, after - before, count / (after - before));
8450     }
8451   else
8452     {
8453       int ret;
8454
8455       /* Wait for a reply... */
8456       W (ret);
8457       return ret;
8458     }
8459
8460   /* Return the good/bad news */
8461   return (vam->retval);
8462 }
8463
8464 static int
8465 api_mpls_ip_bind_unbind (vat_main_t * vam)
8466 {
8467   unformat_input_t *i = vam->input;
8468   vl_api_mpls_ip_bind_unbind_t *mp;
8469   u32 ip_table_id = 0;
8470   u8 create_table_if_needed = 0;
8471   u8 is_bind = 1;
8472   u8 is_ip4 = 1;
8473   ip4_address_t v4_address;
8474   ip6_address_t v6_address;
8475   u32 address_length;
8476   u8 address_set = 0;
8477   mpls_label_t local_label = MPLS_LABEL_INVALID;
8478   int ret;
8479
8480   /* Parse args required to build the message */
8481   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8482     {
8483       if (unformat (i, "%U/%d", unformat_ip4_address,
8484                     &v4_address, &address_length))
8485         {
8486           is_ip4 = 1;
8487           address_set = 1;
8488         }
8489       else if (unformat (i, "%U/%d", unformat_ip6_address,
8490                          &v6_address, &address_length))
8491         {
8492           is_ip4 = 0;
8493           address_set = 1;
8494         }
8495       else if (unformat (i, "%d", &local_label))
8496         ;
8497       else if (unformat (i, "create-table"))
8498         create_table_if_needed = 1;
8499       else if (unformat (i, "table-id %d", &ip_table_id))
8500         ;
8501       else if (unformat (i, "unbind"))
8502         is_bind = 0;
8503       else if (unformat (i, "bind"))
8504         is_bind = 1;
8505       else
8506         {
8507           clib_warning ("parse error '%U'", format_unformat_error, i);
8508           return -99;
8509         }
8510     }
8511
8512   if (!address_set)
8513     {
8514       errmsg ("IP addres not set");
8515       return -99;
8516     }
8517
8518   if (MPLS_LABEL_INVALID == local_label)
8519     {
8520       errmsg ("missing label");
8521       return -99;
8522     }
8523
8524   /* Construct the API message */
8525   M (MPLS_IP_BIND_UNBIND, mp);
8526
8527   mp->mb_create_table_if_needed = create_table_if_needed;
8528   mp->mb_is_bind = is_bind;
8529   mp->mb_is_ip4 = is_ip4;
8530   mp->mb_ip_table_id = ntohl (ip_table_id);
8531   mp->mb_mpls_table_id = 0;
8532   mp->mb_label = ntohl (local_label);
8533   mp->mb_address_length = address_length;
8534
8535   if (is_ip4)
8536     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8537   else
8538     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8539
8540   /* send it... */
8541   S (mp);
8542
8543   /* Wait for a reply... */
8544   W (ret);
8545   return ret;
8546 }
8547
8548 static int
8549 api_proxy_arp_add_del (vat_main_t * vam)
8550 {
8551   unformat_input_t *i = vam->input;
8552   vl_api_proxy_arp_add_del_t *mp;
8553   u32 vrf_id = 0;
8554   u8 is_add = 1;
8555   ip4_address_t lo, hi;
8556   u8 range_set = 0;
8557   int ret;
8558
8559   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8560     {
8561       if (unformat (i, "vrf %d", &vrf_id))
8562         ;
8563       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
8564                          unformat_ip4_address, &hi))
8565         range_set = 1;
8566       else if (unformat (i, "del"))
8567         is_add = 0;
8568       else
8569         {
8570           clib_warning ("parse error '%U'", format_unformat_error, i);
8571           return -99;
8572         }
8573     }
8574
8575   if (range_set == 0)
8576     {
8577       errmsg ("address range not set");
8578       return -99;
8579     }
8580
8581   M (PROXY_ARP_ADD_DEL, mp);
8582
8583   mp->vrf_id = ntohl (vrf_id);
8584   mp->is_add = is_add;
8585   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
8586   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
8587
8588   S (mp);
8589   W (ret);
8590   return ret;
8591 }
8592
8593 static int
8594 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8595 {
8596   unformat_input_t *i = vam->input;
8597   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8598   u32 sw_if_index;
8599   u8 enable = 1;
8600   u8 sw_if_index_set = 0;
8601   int ret;
8602
8603   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8604     {
8605       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8606         sw_if_index_set = 1;
8607       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8608         sw_if_index_set = 1;
8609       else if (unformat (i, "enable"))
8610         enable = 1;
8611       else if (unformat (i, "disable"))
8612         enable = 0;
8613       else
8614         {
8615           clib_warning ("parse error '%U'", format_unformat_error, i);
8616           return -99;
8617         }
8618     }
8619
8620   if (sw_if_index_set == 0)
8621     {
8622       errmsg ("missing interface name or sw_if_index");
8623       return -99;
8624     }
8625
8626   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8627
8628   mp->sw_if_index = ntohl (sw_if_index);
8629   mp->enable_disable = enable;
8630
8631   S (mp);
8632   W (ret);
8633   return ret;
8634 }
8635
8636 static int
8637 api_mpls_tunnel_add_del (vat_main_t * vam)
8638 {
8639   unformat_input_t *i = vam->input;
8640   vl_api_mpls_tunnel_add_del_t *mp;
8641
8642   u8 is_add = 1;
8643   u8 l2_only = 0;
8644   u32 sw_if_index = ~0;
8645   u32 next_hop_sw_if_index = ~0;
8646   u32 next_hop_proto_is_ip4 = 1;
8647
8648   u32 next_hop_table_id = 0;
8649   ip4_address_t v4_next_hop_address = {
8650     .as_u32 = 0,
8651   };
8652   ip6_address_t v6_next_hop_address = { {0} };
8653   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
8654   int ret;
8655
8656   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8657     {
8658       if (unformat (i, "add"))
8659         is_add = 1;
8660       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8661         is_add = 0;
8662       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
8663         ;
8664       else if (unformat (i, "via %U",
8665                          unformat_ip4_address, &v4_next_hop_address))
8666         {
8667           next_hop_proto_is_ip4 = 1;
8668         }
8669       else if (unformat (i, "via %U",
8670                          unformat_ip6_address, &v6_next_hop_address))
8671         {
8672           next_hop_proto_is_ip4 = 0;
8673         }
8674       else if (unformat (i, "l2-only"))
8675         l2_only = 1;
8676       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8677         ;
8678       else if (unformat (i, "out-label %d", &next_hop_out_label))
8679         vec_add1 (labels, ntohl (next_hop_out_label));
8680       else
8681         {
8682           clib_warning ("parse error '%U'", format_unformat_error, i);
8683           return -99;
8684         }
8685     }
8686
8687   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
8688
8689   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
8690   mp->mt_sw_if_index = ntohl (sw_if_index);
8691   mp->mt_is_add = is_add;
8692   mp->mt_l2_only = l2_only;
8693   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
8694   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
8695
8696   mp->mt_next_hop_n_out_labels = vec_len (labels);
8697
8698   if (0 != mp->mt_next_hop_n_out_labels)
8699     {
8700       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
8701                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
8702       vec_free (labels);
8703     }
8704
8705   if (next_hop_proto_is_ip4)
8706     {
8707       clib_memcpy (mp->mt_next_hop,
8708                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8709     }
8710   else
8711     {
8712       clib_memcpy (mp->mt_next_hop,
8713                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8714     }
8715
8716   S (mp);
8717   W (ret);
8718   return ret;
8719 }
8720
8721 static int
8722 api_sw_interface_set_unnumbered (vat_main_t * vam)
8723 {
8724   unformat_input_t *i = vam->input;
8725   vl_api_sw_interface_set_unnumbered_t *mp;
8726   u32 sw_if_index;
8727   u32 unnum_sw_index = ~0;
8728   u8 is_add = 1;
8729   u8 sw_if_index_set = 0;
8730   int ret;
8731
8732   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8733     {
8734       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8735         sw_if_index_set = 1;
8736       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8737         sw_if_index_set = 1;
8738       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8739         ;
8740       else if (unformat (i, "del"))
8741         is_add = 0;
8742       else
8743         {
8744           clib_warning ("parse error '%U'", format_unformat_error, i);
8745           return -99;
8746         }
8747     }
8748
8749   if (sw_if_index_set == 0)
8750     {
8751       errmsg ("missing interface name or sw_if_index");
8752       return -99;
8753     }
8754
8755   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8756
8757   mp->sw_if_index = ntohl (sw_if_index);
8758   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8759   mp->is_add = is_add;
8760
8761   S (mp);
8762   W (ret);
8763   return ret;
8764 }
8765
8766 static int
8767 api_ip_neighbor_add_del (vat_main_t * vam)
8768 {
8769   unformat_input_t *i = vam->input;
8770   vl_api_ip_neighbor_add_del_t *mp;
8771   u32 sw_if_index;
8772   u8 sw_if_index_set = 0;
8773   u8 is_add = 1;
8774   u8 is_static = 0;
8775   u8 is_no_fib_entry = 0;
8776   u8 mac_address[6];
8777   u8 mac_set = 0;
8778   u8 v4_address_set = 0;
8779   u8 v6_address_set = 0;
8780   ip4_address_t v4address;
8781   ip6_address_t v6address;
8782   int ret;
8783
8784   memset (mac_address, 0, sizeof (mac_address));
8785
8786   /* Parse args required to build the message */
8787   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8788     {
8789       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8790         {
8791           mac_set = 1;
8792         }
8793       else if (unformat (i, "del"))
8794         is_add = 0;
8795       else
8796         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8797         sw_if_index_set = 1;
8798       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8799         sw_if_index_set = 1;
8800       else if (unformat (i, "is_static"))
8801         is_static = 1;
8802       else if (unformat (i, "no-fib-entry"))
8803         is_no_fib_entry = 1;
8804       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
8805         v4_address_set = 1;
8806       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
8807         v6_address_set = 1;
8808       else
8809         {
8810           clib_warning ("parse error '%U'", format_unformat_error, i);
8811           return -99;
8812         }
8813     }
8814
8815   if (sw_if_index_set == 0)
8816     {
8817       errmsg ("missing interface name or sw_if_index");
8818       return -99;
8819     }
8820   if (v4_address_set && v6_address_set)
8821     {
8822       errmsg ("both v4 and v6 addresses set");
8823       return -99;
8824     }
8825   if (!v4_address_set && !v6_address_set)
8826     {
8827       errmsg ("no address set");
8828       return -99;
8829     }
8830
8831   /* Construct the API message */
8832   M (IP_NEIGHBOR_ADD_DEL, mp);
8833
8834   mp->sw_if_index = ntohl (sw_if_index);
8835   mp->is_add = is_add;
8836   mp->is_static = is_static;
8837   mp->is_no_adj_fib = is_no_fib_entry;
8838   if (mac_set)
8839     clib_memcpy (mp->mac_address, mac_address, 6);
8840   if (v6_address_set)
8841     {
8842       mp->is_ipv6 = 1;
8843       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
8844     }
8845   else
8846     {
8847       /* mp->is_ipv6 = 0; via memset in M macro above */
8848       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
8849     }
8850
8851   /* send it... */
8852   S (mp);
8853
8854   /* Wait for a reply, return good/bad news  */
8855   W (ret);
8856   return ret;
8857 }
8858
8859 static int
8860 api_reset_vrf (vat_main_t * vam)
8861 {
8862   unformat_input_t *i = vam->input;
8863   vl_api_reset_vrf_t *mp;
8864   u32 vrf_id = 0;
8865   u8 is_ipv6 = 0;
8866   u8 vrf_id_set = 0;
8867   int ret;
8868
8869   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8870     {
8871       if (unformat (i, "vrf %d", &vrf_id))
8872         vrf_id_set = 1;
8873       else if (unformat (i, "ipv6"))
8874         is_ipv6 = 1;
8875       else
8876         {
8877           clib_warning ("parse error '%U'", format_unformat_error, i);
8878           return -99;
8879         }
8880     }
8881
8882   if (vrf_id_set == 0)
8883     {
8884       errmsg ("missing vrf id");
8885       return -99;
8886     }
8887
8888   M (RESET_VRF, mp);
8889
8890   mp->vrf_id = ntohl (vrf_id);
8891   mp->is_ipv6 = is_ipv6;
8892
8893   S (mp);
8894   W (ret);
8895   return ret;
8896 }
8897
8898 static int
8899 api_create_vlan_subif (vat_main_t * vam)
8900 {
8901   unformat_input_t *i = vam->input;
8902   vl_api_create_vlan_subif_t *mp;
8903   u32 sw_if_index;
8904   u8 sw_if_index_set = 0;
8905   u32 vlan_id;
8906   u8 vlan_id_set = 0;
8907   int ret;
8908
8909   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8910     {
8911       if (unformat (i, "sw_if_index %d", &sw_if_index))
8912         sw_if_index_set = 1;
8913       else
8914         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8915         sw_if_index_set = 1;
8916       else if (unformat (i, "vlan %d", &vlan_id))
8917         vlan_id_set = 1;
8918       else
8919         {
8920           clib_warning ("parse error '%U'", format_unformat_error, i);
8921           return -99;
8922         }
8923     }
8924
8925   if (sw_if_index_set == 0)
8926     {
8927       errmsg ("missing interface name or sw_if_index");
8928       return -99;
8929     }
8930
8931   if (vlan_id_set == 0)
8932     {
8933       errmsg ("missing vlan_id");
8934       return -99;
8935     }
8936   M (CREATE_VLAN_SUBIF, mp);
8937
8938   mp->sw_if_index = ntohl (sw_if_index);
8939   mp->vlan_id = ntohl (vlan_id);
8940
8941   S (mp);
8942   W (ret);
8943   return ret;
8944 }
8945
8946 #define foreach_create_subif_bit                \
8947 _(no_tags)                                      \
8948 _(one_tag)                                      \
8949 _(two_tags)                                     \
8950 _(dot1ad)                                       \
8951 _(exact_match)                                  \
8952 _(default_sub)                                  \
8953 _(outer_vlan_id_any)                            \
8954 _(inner_vlan_id_any)
8955
8956 static int
8957 api_create_subif (vat_main_t * vam)
8958 {
8959   unformat_input_t *i = vam->input;
8960   vl_api_create_subif_t *mp;
8961   u32 sw_if_index;
8962   u8 sw_if_index_set = 0;
8963   u32 sub_id;
8964   u8 sub_id_set = 0;
8965   u32 no_tags = 0;
8966   u32 one_tag = 0;
8967   u32 two_tags = 0;
8968   u32 dot1ad = 0;
8969   u32 exact_match = 0;
8970   u32 default_sub = 0;
8971   u32 outer_vlan_id_any = 0;
8972   u32 inner_vlan_id_any = 0;
8973   u32 tmp;
8974   u16 outer_vlan_id = 0;
8975   u16 inner_vlan_id = 0;
8976   int ret;
8977
8978   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8979     {
8980       if (unformat (i, "sw_if_index %d", &sw_if_index))
8981         sw_if_index_set = 1;
8982       else
8983         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8984         sw_if_index_set = 1;
8985       else if (unformat (i, "sub_id %d", &sub_id))
8986         sub_id_set = 1;
8987       else if (unformat (i, "outer_vlan_id %d", &tmp))
8988         outer_vlan_id = tmp;
8989       else if (unformat (i, "inner_vlan_id %d", &tmp))
8990         inner_vlan_id = tmp;
8991
8992 #define _(a) else if (unformat (i, #a)) a = 1 ;
8993       foreach_create_subif_bit
8994 #undef _
8995         else
8996         {
8997           clib_warning ("parse error '%U'", format_unformat_error, i);
8998           return -99;
8999         }
9000     }
9001
9002   if (sw_if_index_set == 0)
9003     {
9004       errmsg ("missing interface name or sw_if_index");
9005       return -99;
9006     }
9007
9008   if (sub_id_set == 0)
9009     {
9010       errmsg ("missing sub_id");
9011       return -99;
9012     }
9013   M (CREATE_SUBIF, mp);
9014
9015   mp->sw_if_index = ntohl (sw_if_index);
9016   mp->sub_id = ntohl (sub_id);
9017
9018 #define _(a) mp->a = a;
9019   foreach_create_subif_bit;
9020 #undef _
9021
9022   mp->outer_vlan_id = ntohs (outer_vlan_id);
9023   mp->inner_vlan_id = ntohs (inner_vlan_id);
9024
9025   S (mp);
9026   W (ret);
9027   return ret;
9028 }
9029
9030 static int
9031 api_oam_add_del (vat_main_t * vam)
9032 {
9033   unformat_input_t *i = vam->input;
9034   vl_api_oam_add_del_t *mp;
9035   u32 vrf_id = 0;
9036   u8 is_add = 1;
9037   ip4_address_t src, dst;
9038   u8 src_set = 0;
9039   u8 dst_set = 0;
9040   int ret;
9041
9042   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9043     {
9044       if (unformat (i, "vrf %d", &vrf_id))
9045         ;
9046       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9047         src_set = 1;
9048       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9049         dst_set = 1;
9050       else if (unformat (i, "del"))
9051         is_add = 0;
9052       else
9053         {
9054           clib_warning ("parse error '%U'", format_unformat_error, i);
9055           return -99;
9056         }
9057     }
9058
9059   if (src_set == 0)
9060     {
9061       errmsg ("missing src addr");
9062       return -99;
9063     }
9064
9065   if (dst_set == 0)
9066     {
9067       errmsg ("missing dst addr");
9068       return -99;
9069     }
9070
9071   M (OAM_ADD_DEL, mp);
9072
9073   mp->vrf_id = ntohl (vrf_id);
9074   mp->is_add = is_add;
9075   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9076   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9077
9078   S (mp);
9079   W (ret);
9080   return ret;
9081 }
9082
9083 static int
9084 api_reset_fib (vat_main_t * vam)
9085 {
9086   unformat_input_t *i = vam->input;
9087   vl_api_reset_fib_t *mp;
9088   u32 vrf_id = 0;
9089   u8 is_ipv6 = 0;
9090   u8 vrf_id_set = 0;
9091
9092   int ret;
9093   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9094     {
9095       if (unformat (i, "vrf %d", &vrf_id))
9096         vrf_id_set = 1;
9097       else 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   if (vrf_id_set == 0)
9107     {
9108       errmsg ("missing vrf id");
9109       return -99;
9110     }
9111
9112   M (RESET_FIB, mp);
9113
9114   mp->vrf_id = ntohl (vrf_id);
9115   mp->is_ipv6 = is_ipv6;
9116
9117   S (mp);
9118   W (ret);
9119   return ret;
9120 }
9121
9122 static int
9123 api_dhcp_proxy_config (vat_main_t * vam)
9124 {
9125   unformat_input_t *i = vam->input;
9126   vl_api_dhcp_proxy_config_t *mp;
9127   u32 rx_vrf_id = 0;
9128   u32 server_vrf_id = 0;
9129   u8 is_add = 1;
9130   u8 v4_address_set = 0;
9131   u8 v6_address_set = 0;
9132   ip4_address_t v4address;
9133   ip6_address_t v6address;
9134   u8 v4_src_address_set = 0;
9135   u8 v6_src_address_set = 0;
9136   ip4_address_t v4srcaddress;
9137   ip6_address_t v6srcaddress;
9138   int ret;
9139
9140   /* Parse args required to build the message */
9141   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9142     {
9143       if (unformat (i, "del"))
9144         is_add = 0;
9145       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9146         ;
9147       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9148         ;
9149       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9150         v4_address_set = 1;
9151       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9152         v6_address_set = 1;
9153       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9154         v4_src_address_set = 1;
9155       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9156         v6_src_address_set = 1;
9157       else
9158         break;
9159     }
9160
9161   if (v4_address_set && v6_address_set)
9162     {
9163       errmsg ("both v4 and v6 server addresses set");
9164       return -99;
9165     }
9166   if (!v4_address_set && !v6_address_set)
9167     {
9168       errmsg ("no server addresses set");
9169       return -99;
9170     }
9171
9172   if (v4_src_address_set && v6_src_address_set)
9173     {
9174       errmsg ("both v4 and v6  src addresses set");
9175       return -99;
9176     }
9177   if (!v4_src_address_set && !v6_src_address_set)
9178     {
9179       errmsg ("no src addresses set");
9180       return -99;
9181     }
9182
9183   if (!(v4_src_address_set && v4_address_set) &&
9184       !(v6_src_address_set && v6_address_set))
9185     {
9186       errmsg ("no matching server and src addresses set");
9187       return -99;
9188     }
9189
9190   /* Construct the API message */
9191   M (DHCP_PROXY_CONFIG, mp);
9192
9193   mp->is_add = is_add;
9194   mp->rx_vrf_id = ntohl (rx_vrf_id);
9195   mp->server_vrf_id = ntohl (server_vrf_id);
9196   if (v6_address_set)
9197     {
9198       mp->is_ipv6 = 1;
9199       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9200       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9201     }
9202   else
9203     {
9204       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9205       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9206     }
9207
9208   /* send it... */
9209   S (mp);
9210
9211   /* Wait for a reply, return good/bad news  */
9212   W (ret);
9213   return ret;
9214 }
9215
9216 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9217 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9218
9219 static void
9220 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9221 {
9222   vat_main_t *vam = &vat_main;
9223   u32 i, count = mp->count;
9224   vl_api_dhcp_server_t *s;
9225
9226   if (mp->is_ipv6)
9227     print (vam->ofp,
9228            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
9229            ntohl (mp->rx_vrf_id),
9230            format_ip6_address, mp->dhcp_src_address,
9231            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9232   else
9233     print (vam->ofp,
9234            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
9235            ntohl (mp->rx_vrf_id),
9236            format_ip4_address, mp->dhcp_src_address,
9237            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9238
9239   for (i = 0; i < count; i++)
9240     {
9241       s = &mp->servers[i];
9242
9243       if (mp->is_ipv6)
9244         print (vam->ofp,
9245                " Server Table-ID %d, Server Address %U",
9246                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9247       else
9248         print (vam->ofp,
9249                " Server Table-ID %d, Server Address %U",
9250                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9251     }
9252 }
9253
9254 static void vl_api_dhcp_proxy_details_t_handler_json
9255   (vl_api_dhcp_proxy_details_t * mp)
9256 {
9257   vat_main_t *vam = &vat_main;
9258   vat_json_node_t *node = NULL;
9259   u32 i, count = mp->count;
9260   struct in_addr ip4;
9261   struct in6_addr ip6;
9262   vl_api_dhcp_server_t *s;
9263
9264   if (VAT_JSON_ARRAY != vam->json_tree.type)
9265     {
9266       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9267       vat_json_init_array (&vam->json_tree);
9268     }
9269   node = vat_json_array_add (&vam->json_tree);
9270
9271   vat_json_init_object (node);
9272   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9273   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9274   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9275
9276   if (mp->is_ipv6)
9277     {
9278       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9279       vat_json_object_add_ip6 (node, "src_address", ip6);
9280     }
9281   else
9282     {
9283       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9284       vat_json_object_add_ip4 (node, "src_address", ip4);
9285     }
9286
9287   for (i = 0; i < count; i++)
9288     {
9289       s = &mp->servers[i];
9290
9291       vat_json_object_add_uint (node, "server-table-id",
9292                                 ntohl (s->server_vrf_id));
9293
9294       if (mp->is_ipv6)
9295         {
9296           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9297           vat_json_object_add_ip4 (node, "src_address", ip4);
9298         }
9299       else
9300         {
9301           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9302           vat_json_object_add_ip6 (node, "server_address", ip6);
9303         }
9304     }
9305 }
9306
9307 static int
9308 api_dhcp_proxy_dump (vat_main_t * vam)
9309 {
9310   unformat_input_t *i = vam->input;
9311   vl_api_control_ping_t *mp_ping;
9312   vl_api_dhcp_proxy_dump_t *mp;
9313   u8 is_ipv6 = 0;
9314   int ret;
9315
9316   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9317     {
9318       if (unformat (i, "ipv6"))
9319         is_ipv6 = 1;
9320       else
9321         {
9322           clib_warning ("parse error '%U'", format_unformat_error, i);
9323           return -99;
9324         }
9325     }
9326
9327   M (DHCP_PROXY_DUMP, mp);
9328
9329   mp->is_ip6 = is_ipv6;
9330   S (mp);
9331
9332   /* Use a control ping for synchronization */
9333   MPING (CONTROL_PING, mp_ping);
9334   S (mp_ping);
9335
9336   W (ret);
9337   return ret;
9338 }
9339
9340 static int
9341 api_dhcp_proxy_set_vss (vat_main_t * vam)
9342 {
9343   unformat_input_t *i = vam->input;
9344   vl_api_dhcp_proxy_set_vss_t *mp;
9345   u8 is_ipv6 = 0;
9346   u8 is_add = 1;
9347   u32 tbl_id;
9348   u8 tbl_id_set = 0;
9349   u32 oui;
9350   u8 oui_set = 0;
9351   u32 fib_id;
9352   u8 fib_id_set = 0;
9353   int ret;
9354
9355   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9356     {
9357       if (unformat (i, "tbl_id %d", &tbl_id))
9358         tbl_id_set = 1;
9359       if (unformat (i, "fib_id %d", &fib_id))
9360         fib_id_set = 1;
9361       if (unformat (i, "oui %d", &oui))
9362         oui_set = 1;
9363       else if (unformat (i, "ipv6"))
9364         is_ipv6 = 1;
9365       else if (unformat (i, "del"))
9366         is_add = 0;
9367       else
9368         {
9369           clib_warning ("parse error '%U'", format_unformat_error, i);
9370           return -99;
9371         }
9372     }
9373
9374   if (tbl_id_set == 0)
9375     {
9376       errmsg ("missing tbl id");
9377       return -99;
9378     }
9379
9380   if (fib_id_set == 0)
9381     {
9382       errmsg ("missing fib id");
9383       return -99;
9384     }
9385   if (oui_set == 0)
9386     {
9387       errmsg ("missing oui");
9388       return -99;
9389     }
9390
9391   M (DHCP_PROXY_SET_VSS, mp);
9392   mp->tbl_id = ntohl (tbl_id);
9393   mp->fib_id = ntohl (fib_id);
9394   mp->oui = ntohl (oui);
9395   mp->is_ipv6 = is_ipv6;
9396   mp->is_add = is_add;
9397
9398   S (mp);
9399   W (ret);
9400   return ret;
9401 }
9402
9403 static int
9404 api_dhcp_client_config (vat_main_t * vam)
9405 {
9406   unformat_input_t *i = vam->input;
9407   vl_api_dhcp_client_config_t *mp;
9408   u32 sw_if_index;
9409   u8 sw_if_index_set = 0;
9410   u8 is_add = 1;
9411   u8 *hostname = 0;
9412   u8 disable_event = 0;
9413   int ret;
9414
9415   /* Parse args required to build the message */
9416   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9417     {
9418       if (unformat (i, "del"))
9419         is_add = 0;
9420       else
9421         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9422         sw_if_index_set = 1;
9423       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9424         sw_if_index_set = 1;
9425       else if (unformat (i, "hostname %s", &hostname))
9426         ;
9427       else if (unformat (i, "disable_event"))
9428         disable_event = 1;
9429       else
9430         break;
9431     }
9432
9433   if (sw_if_index_set == 0)
9434     {
9435       errmsg ("missing interface name or sw_if_index");
9436       return -99;
9437     }
9438
9439   if (vec_len (hostname) > 63)
9440     {
9441       errmsg ("hostname too long");
9442     }
9443   vec_add1 (hostname, 0);
9444
9445   /* Construct the API message */
9446   M (DHCP_CLIENT_CONFIG, mp);
9447
9448   mp->sw_if_index = htonl (sw_if_index);
9449   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
9450   vec_free (hostname);
9451   mp->is_add = is_add;
9452   mp->want_dhcp_event = disable_event ? 0 : 1;
9453   mp->pid = htonl (getpid ());
9454
9455   /* send it... */
9456   S (mp);
9457
9458   /* Wait for a reply, return good/bad news  */
9459   W (ret);
9460   return ret;
9461 }
9462
9463 static int
9464 api_set_ip_flow_hash (vat_main_t * vam)
9465 {
9466   unformat_input_t *i = vam->input;
9467   vl_api_set_ip_flow_hash_t *mp;
9468   u32 vrf_id = 0;
9469   u8 is_ipv6 = 0;
9470   u8 vrf_id_set = 0;
9471   u8 src = 0;
9472   u8 dst = 0;
9473   u8 sport = 0;
9474   u8 dport = 0;
9475   u8 proto = 0;
9476   u8 reverse = 0;
9477   int ret;
9478
9479   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9480     {
9481       if (unformat (i, "vrf %d", &vrf_id))
9482         vrf_id_set = 1;
9483       else if (unformat (i, "ipv6"))
9484         is_ipv6 = 1;
9485       else if (unformat (i, "src"))
9486         src = 1;
9487       else if (unformat (i, "dst"))
9488         dst = 1;
9489       else if (unformat (i, "sport"))
9490         sport = 1;
9491       else if (unformat (i, "dport"))
9492         dport = 1;
9493       else if (unformat (i, "proto"))
9494         proto = 1;
9495       else if (unformat (i, "reverse"))
9496         reverse = 1;
9497
9498       else
9499         {
9500           clib_warning ("parse error '%U'", format_unformat_error, i);
9501           return -99;
9502         }
9503     }
9504
9505   if (vrf_id_set == 0)
9506     {
9507       errmsg ("missing vrf id");
9508       return -99;
9509     }
9510
9511   M (SET_IP_FLOW_HASH, mp);
9512   mp->src = src;
9513   mp->dst = dst;
9514   mp->sport = sport;
9515   mp->dport = dport;
9516   mp->proto = proto;
9517   mp->reverse = reverse;
9518   mp->vrf_id = ntohl (vrf_id);
9519   mp->is_ipv6 = is_ipv6;
9520
9521   S (mp);
9522   W (ret);
9523   return ret;
9524 }
9525
9526 static int
9527 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9528 {
9529   unformat_input_t *i = vam->input;
9530   vl_api_sw_interface_ip6_enable_disable_t *mp;
9531   u32 sw_if_index;
9532   u8 sw_if_index_set = 0;
9533   u8 enable = 0;
9534   int ret;
9535
9536   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9537     {
9538       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9539         sw_if_index_set = 1;
9540       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9541         sw_if_index_set = 1;
9542       else if (unformat (i, "enable"))
9543         enable = 1;
9544       else if (unformat (i, "disable"))
9545         enable = 0;
9546       else
9547         {
9548           clib_warning ("parse error '%U'", format_unformat_error, i);
9549           return -99;
9550         }
9551     }
9552
9553   if (sw_if_index_set == 0)
9554     {
9555       errmsg ("missing interface name or sw_if_index");
9556       return -99;
9557     }
9558
9559   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9560
9561   mp->sw_if_index = ntohl (sw_if_index);
9562   mp->enable = enable;
9563
9564   S (mp);
9565   W (ret);
9566   return ret;
9567 }
9568
9569 static int
9570 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
9571 {
9572   unformat_input_t *i = vam->input;
9573   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
9574   u32 sw_if_index;
9575   u8 sw_if_index_set = 0;
9576   u8 v6_address_set = 0;
9577   ip6_address_t v6address;
9578   int ret;
9579
9580   /* Parse args required to build the message */
9581   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9582     {
9583       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9584         sw_if_index_set = 1;
9585       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9586         sw_if_index_set = 1;
9587       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9588         v6_address_set = 1;
9589       else
9590         break;
9591     }
9592
9593   if (sw_if_index_set == 0)
9594     {
9595       errmsg ("missing interface name or sw_if_index");
9596       return -99;
9597     }
9598   if (!v6_address_set)
9599     {
9600       errmsg ("no address set");
9601       return -99;
9602     }
9603
9604   /* Construct the API message */
9605   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
9606
9607   mp->sw_if_index = ntohl (sw_if_index);
9608   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9609
9610   /* send it... */
9611   S (mp);
9612
9613   /* Wait for a reply, return good/bad news  */
9614   W (ret);
9615   return ret;
9616 }
9617
9618 static int
9619 api_ip6nd_proxy_add_del (vat_main_t * vam)
9620 {
9621   unformat_input_t *i = vam->input;
9622   vl_api_ip6nd_proxy_add_del_t *mp;
9623   u32 sw_if_index = ~0;
9624   u8 v6_address_set = 0;
9625   ip6_address_t v6address;
9626   u8 is_del = 0;
9627   int ret;
9628
9629   /* Parse args required to build the message */
9630   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9631     {
9632       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9633         ;
9634       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9635         ;
9636       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9637         v6_address_set = 1;
9638       if (unformat (i, "del"))
9639         is_del = 1;
9640       else
9641         {
9642           clib_warning ("parse error '%U'", format_unformat_error, i);
9643           return -99;
9644         }
9645     }
9646
9647   if (sw_if_index == ~0)
9648     {
9649       errmsg ("missing interface name or sw_if_index");
9650       return -99;
9651     }
9652   if (!v6_address_set)
9653     {
9654       errmsg ("no address set");
9655       return -99;
9656     }
9657
9658   /* Construct the API message */
9659   M (IP6ND_PROXY_ADD_DEL, mp);
9660
9661   mp->is_del = is_del;
9662   mp->sw_if_index = ntohl (sw_if_index);
9663   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9664
9665   /* send it... */
9666   S (mp);
9667
9668   /* Wait for a reply, return good/bad news  */
9669   W (ret);
9670   return ret;
9671 }
9672
9673 static int
9674 api_ip6nd_proxy_dump (vat_main_t * vam)
9675 {
9676   vl_api_ip6nd_proxy_dump_t *mp;
9677   vl_api_control_ping_t *mp_ping;
9678   int ret;
9679
9680   M (IP6ND_PROXY_DUMP, mp);
9681
9682   S (mp);
9683
9684   /* Use a control ping for synchronization */
9685   MPING (CONTROL_PING, mp_ping);
9686   S (mp_ping);
9687
9688   W (ret);
9689   return ret;
9690 }
9691
9692 static void vl_api_ip6nd_proxy_details_t_handler
9693   (vl_api_ip6nd_proxy_details_t * mp)
9694 {
9695   vat_main_t *vam = &vat_main;
9696
9697   print (vam->ofp, "host %U sw_if_index %d",
9698          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
9699 }
9700
9701 static void vl_api_ip6nd_proxy_details_t_handler_json
9702   (vl_api_ip6nd_proxy_details_t * mp)
9703 {
9704   vat_main_t *vam = &vat_main;
9705   struct in6_addr ip6;
9706   vat_json_node_t *node = NULL;
9707
9708   if (VAT_JSON_ARRAY != vam->json_tree.type)
9709     {
9710       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9711       vat_json_init_array (&vam->json_tree);
9712     }
9713   node = vat_json_array_add (&vam->json_tree);
9714
9715   vat_json_init_object (node);
9716   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9717
9718   clib_memcpy (&ip6, mp->address, sizeof (ip6));
9719   vat_json_object_add_ip6 (node, "host", ip6);
9720 }
9721
9722 static int
9723 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9724 {
9725   unformat_input_t *i = vam->input;
9726   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9727   u32 sw_if_index;
9728   u8 sw_if_index_set = 0;
9729   u32 address_length = 0;
9730   u8 v6_address_set = 0;
9731   ip6_address_t v6address;
9732   u8 use_default = 0;
9733   u8 no_advertise = 0;
9734   u8 off_link = 0;
9735   u8 no_autoconfig = 0;
9736   u8 no_onlink = 0;
9737   u8 is_no = 0;
9738   u32 val_lifetime = 0;
9739   u32 pref_lifetime = 0;
9740   int ret;
9741
9742   /* Parse args required to build the message */
9743   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9744     {
9745       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9746         sw_if_index_set = 1;
9747       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9748         sw_if_index_set = 1;
9749       else if (unformat (i, "%U/%d",
9750                          unformat_ip6_address, &v6address, &address_length))
9751         v6_address_set = 1;
9752       else if (unformat (i, "val_life %d", &val_lifetime))
9753         ;
9754       else if (unformat (i, "pref_life %d", &pref_lifetime))
9755         ;
9756       else if (unformat (i, "def"))
9757         use_default = 1;
9758       else if (unformat (i, "noadv"))
9759         no_advertise = 1;
9760       else if (unformat (i, "offl"))
9761         off_link = 1;
9762       else if (unformat (i, "noauto"))
9763         no_autoconfig = 1;
9764       else if (unformat (i, "nolink"))
9765         no_onlink = 1;
9766       else if (unformat (i, "isno"))
9767         is_no = 1;
9768       else
9769         {
9770           clib_warning ("parse error '%U'", format_unformat_error, i);
9771           return -99;
9772         }
9773     }
9774
9775   if (sw_if_index_set == 0)
9776     {
9777       errmsg ("missing interface name or sw_if_index");
9778       return -99;
9779     }
9780   if (!v6_address_set)
9781     {
9782       errmsg ("no address set");
9783       return -99;
9784     }
9785
9786   /* Construct the API message */
9787   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9788
9789   mp->sw_if_index = ntohl (sw_if_index);
9790   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9791   mp->address_length = address_length;
9792   mp->use_default = use_default;
9793   mp->no_advertise = no_advertise;
9794   mp->off_link = off_link;
9795   mp->no_autoconfig = no_autoconfig;
9796   mp->no_onlink = no_onlink;
9797   mp->is_no = is_no;
9798   mp->val_lifetime = ntohl (val_lifetime);
9799   mp->pref_lifetime = ntohl (pref_lifetime);
9800
9801   /* send it... */
9802   S (mp);
9803
9804   /* Wait for a reply, return good/bad news  */
9805   W (ret);
9806   return ret;
9807 }
9808
9809 static int
9810 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9811 {
9812   unformat_input_t *i = vam->input;
9813   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9814   u32 sw_if_index;
9815   u8 sw_if_index_set = 0;
9816   u8 suppress = 0;
9817   u8 managed = 0;
9818   u8 other = 0;
9819   u8 ll_option = 0;
9820   u8 send_unicast = 0;
9821   u8 cease = 0;
9822   u8 is_no = 0;
9823   u8 default_router = 0;
9824   u32 max_interval = 0;
9825   u32 min_interval = 0;
9826   u32 lifetime = 0;
9827   u32 initial_count = 0;
9828   u32 initial_interval = 0;
9829   int ret;
9830
9831
9832   /* Parse args required to build the message */
9833   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9834     {
9835       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9836         sw_if_index_set = 1;
9837       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9838         sw_if_index_set = 1;
9839       else if (unformat (i, "maxint %d", &max_interval))
9840         ;
9841       else if (unformat (i, "minint %d", &min_interval))
9842         ;
9843       else if (unformat (i, "life %d", &lifetime))
9844         ;
9845       else if (unformat (i, "count %d", &initial_count))
9846         ;
9847       else if (unformat (i, "interval %d", &initial_interval))
9848         ;
9849       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9850         suppress = 1;
9851       else if (unformat (i, "managed"))
9852         managed = 1;
9853       else if (unformat (i, "other"))
9854         other = 1;
9855       else if (unformat (i, "ll"))
9856         ll_option = 1;
9857       else if (unformat (i, "send"))
9858         send_unicast = 1;
9859       else if (unformat (i, "cease"))
9860         cease = 1;
9861       else if (unformat (i, "isno"))
9862         is_no = 1;
9863       else if (unformat (i, "def"))
9864         default_router = 1;
9865       else
9866         {
9867           clib_warning ("parse error '%U'", format_unformat_error, i);
9868           return -99;
9869         }
9870     }
9871
9872   if (sw_if_index_set == 0)
9873     {
9874       errmsg ("missing interface name or sw_if_index");
9875       return -99;
9876     }
9877
9878   /* Construct the API message */
9879   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9880
9881   mp->sw_if_index = ntohl (sw_if_index);
9882   mp->max_interval = ntohl (max_interval);
9883   mp->min_interval = ntohl (min_interval);
9884   mp->lifetime = ntohl (lifetime);
9885   mp->initial_count = ntohl (initial_count);
9886   mp->initial_interval = ntohl (initial_interval);
9887   mp->suppress = suppress;
9888   mp->managed = managed;
9889   mp->other = other;
9890   mp->ll_option = ll_option;
9891   mp->send_unicast = send_unicast;
9892   mp->cease = cease;
9893   mp->is_no = is_no;
9894   mp->default_router = default_router;
9895
9896   /* send it... */
9897   S (mp);
9898
9899   /* Wait for a reply, return good/bad news  */
9900   W (ret);
9901   return ret;
9902 }
9903
9904 static int
9905 api_set_arp_neighbor_limit (vat_main_t * vam)
9906 {
9907   unformat_input_t *i = vam->input;
9908   vl_api_set_arp_neighbor_limit_t *mp;
9909   u32 arp_nbr_limit;
9910   u8 limit_set = 0;
9911   u8 is_ipv6 = 0;
9912   int ret;
9913
9914   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9915     {
9916       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
9917         limit_set = 1;
9918       else if (unformat (i, "ipv6"))
9919         is_ipv6 = 1;
9920       else
9921         {
9922           clib_warning ("parse error '%U'", format_unformat_error, i);
9923           return -99;
9924         }
9925     }
9926
9927   if (limit_set == 0)
9928     {
9929       errmsg ("missing limit value");
9930       return -99;
9931     }
9932
9933   M (SET_ARP_NEIGHBOR_LIMIT, mp);
9934
9935   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
9936   mp->is_ipv6 = is_ipv6;
9937
9938   S (mp);
9939   W (ret);
9940   return ret;
9941 }
9942
9943 static int
9944 api_l2_patch_add_del (vat_main_t * vam)
9945 {
9946   unformat_input_t *i = vam->input;
9947   vl_api_l2_patch_add_del_t *mp;
9948   u32 rx_sw_if_index;
9949   u8 rx_sw_if_index_set = 0;
9950   u32 tx_sw_if_index;
9951   u8 tx_sw_if_index_set = 0;
9952   u8 is_add = 1;
9953   int ret;
9954
9955   /* Parse args required to build the message */
9956   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9957     {
9958       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9959         rx_sw_if_index_set = 1;
9960       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9961         tx_sw_if_index_set = 1;
9962       else if (unformat (i, "rx"))
9963         {
9964           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9965             {
9966               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9967                             &rx_sw_if_index))
9968                 rx_sw_if_index_set = 1;
9969             }
9970           else
9971             break;
9972         }
9973       else if (unformat (i, "tx"))
9974         {
9975           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9976             {
9977               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9978                             &tx_sw_if_index))
9979                 tx_sw_if_index_set = 1;
9980             }
9981           else
9982             break;
9983         }
9984       else if (unformat (i, "del"))
9985         is_add = 0;
9986       else
9987         break;
9988     }
9989
9990   if (rx_sw_if_index_set == 0)
9991     {
9992       errmsg ("missing rx interface name or rx_sw_if_index");
9993       return -99;
9994     }
9995
9996   if (tx_sw_if_index_set == 0)
9997     {
9998       errmsg ("missing tx interface name or tx_sw_if_index");
9999       return -99;
10000     }
10001
10002   M (L2_PATCH_ADD_DEL, mp);
10003
10004   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10005   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10006   mp->is_add = is_add;
10007
10008   S (mp);
10009   W (ret);
10010   return ret;
10011 }
10012
10013 u8 is_del;
10014 u8 localsid_addr[16];
10015 u8 end_psp;
10016 u8 behavior;
10017 u32 sw_if_index;
10018 u32 vlan_index;
10019 u32 fib_table;
10020 u8 nh_addr[16];
10021
10022 static int
10023 api_sr_localsid_add_del (vat_main_t * vam)
10024 {
10025   unformat_input_t *i = vam->input;
10026   vl_api_sr_localsid_add_del_t *mp;
10027
10028   u8 is_del;
10029   ip6_address_t localsid;
10030   u8 end_psp = 0;
10031   u8 behavior = ~0;
10032   u32 sw_if_index;
10033   u32 fib_table = ~(u32) 0;
10034   ip6_address_t next_hop;
10035
10036   bool nexthop_set = 0;
10037
10038   int ret;
10039
10040   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10041     {
10042       if (unformat (i, "del"))
10043         is_del = 1;
10044       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10045       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
10046         nexthop_set = 1;
10047       else if (unformat (i, "behavior %u", &behavior));
10048       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10049       else if (unformat (i, "fib-table %u", &fib_table));
10050       else if (unformat (i, "end.psp %u", &behavior));
10051       else
10052         break;
10053     }
10054
10055   M (SR_LOCALSID_ADD_DEL, mp);
10056
10057   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
10058   if (nexthop_set)
10059     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
10060   mp->behavior = behavior;
10061   mp->sw_if_index = ntohl (sw_if_index);
10062   mp->fib_table = ntohl (fib_table);
10063   mp->end_psp = end_psp;
10064   mp->is_del = is_del;
10065
10066   S (mp);
10067   W (ret);
10068   return ret;
10069 }
10070
10071 static int
10072 api_ioam_enable (vat_main_t * vam)
10073 {
10074   unformat_input_t *input = vam->input;
10075   vl_api_ioam_enable_t *mp;
10076   u32 id = 0;
10077   int has_trace_option = 0;
10078   int has_pot_option = 0;
10079   int has_seqno_option = 0;
10080   int has_analyse_option = 0;
10081   int ret;
10082
10083   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10084     {
10085       if (unformat (input, "trace"))
10086         has_trace_option = 1;
10087       else if (unformat (input, "pot"))
10088         has_pot_option = 1;
10089       else if (unformat (input, "seqno"))
10090         has_seqno_option = 1;
10091       else if (unformat (input, "analyse"))
10092         has_analyse_option = 1;
10093       else
10094         break;
10095     }
10096   M (IOAM_ENABLE, mp);
10097   mp->id = htons (id);
10098   mp->seqno = has_seqno_option;
10099   mp->analyse = has_analyse_option;
10100   mp->pot_enable = has_pot_option;
10101   mp->trace_enable = has_trace_option;
10102
10103   S (mp);
10104   W (ret);
10105   return ret;
10106 }
10107
10108
10109 static int
10110 api_ioam_disable (vat_main_t * vam)
10111 {
10112   vl_api_ioam_disable_t *mp;
10113   int ret;
10114
10115   M (IOAM_DISABLE, mp);
10116   S (mp);
10117   W (ret);
10118   return ret;
10119 }
10120
10121 #define foreach_tcp_proto_field                 \
10122 _(src_port)                                     \
10123 _(dst_port)
10124
10125 #define foreach_udp_proto_field                 \
10126 _(src_port)                                     \
10127 _(dst_port)
10128
10129 #define foreach_ip4_proto_field                 \
10130 _(src_address)                                  \
10131 _(dst_address)                                  \
10132 _(tos)                                          \
10133 _(length)                                       \
10134 _(fragment_id)                                  \
10135 _(ttl)                                          \
10136 _(protocol)                                     \
10137 _(checksum)
10138
10139 typedef struct
10140 {
10141   u16 src_port, dst_port;
10142 } tcpudp_header_t;
10143
10144 #if VPP_API_TEST_BUILTIN == 0
10145 uword
10146 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10147 {
10148   u8 **maskp = va_arg (*args, u8 **);
10149   u8 *mask = 0;
10150   u8 found_something = 0;
10151   tcp_header_t *tcp;
10152
10153 #define _(a) u8 a=0;
10154   foreach_tcp_proto_field;
10155 #undef _
10156
10157   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10158     {
10159       if (0);
10160 #define _(a) else if (unformat (input, #a)) a=1;
10161       foreach_tcp_proto_field
10162 #undef _
10163         else
10164         break;
10165     }
10166
10167 #define _(a) found_something += a;
10168   foreach_tcp_proto_field;
10169 #undef _
10170
10171   if (found_something == 0)
10172     return 0;
10173
10174   vec_validate (mask, sizeof (*tcp) - 1);
10175
10176   tcp = (tcp_header_t *) mask;
10177
10178 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
10179   foreach_tcp_proto_field;
10180 #undef _
10181
10182   *maskp = mask;
10183   return 1;
10184 }
10185
10186 uword
10187 unformat_udp_mask (unformat_input_t * input, va_list * args)
10188 {
10189   u8 **maskp = va_arg (*args, u8 **);
10190   u8 *mask = 0;
10191   u8 found_something = 0;
10192   udp_header_t *udp;
10193
10194 #define _(a) u8 a=0;
10195   foreach_udp_proto_field;
10196 #undef _
10197
10198   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10199     {
10200       if (0);
10201 #define _(a) else if (unformat (input, #a)) a=1;
10202       foreach_udp_proto_field
10203 #undef _
10204         else
10205         break;
10206     }
10207
10208 #define _(a) found_something += a;
10209   foreach_udp_proto_field;
10210 #undef _
10211
10212   if (found_something == 0)
10213     return 0;
10214
10215   vec_validate (mask, sizeof (*udp) - 1);
10216
10217   udp = (udp_header_t *) mask;
10218
10219 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
10220   foreach_udp_proto_field;
10221 #undef _
10222
10223   *maskp = mask;
10224   return 1;
10225 }
10226
10227 uword
10228 unformat_l4_mask (unformat_input_t * input, va_list * args)
10229 {
10230   u8 **maskp = va_arg (*args, u8 **);
10231   u16 src_port = 0, dst_port = 0;
10232   tcpudp_header_t *tcpudp;
10233
10234   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10235     {
10236       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10237         return 1;
10238       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10239         return 1;
10240       else if (unformat (input, "src_port"))
10241         src_port = 0xFFFF;
10242       else if (unformat (input, "dst_port"))
10243         dst_port = 0xFFFF;
10244       else
10245         return 0;
10246     }
10247
10248   if (!src_port && !dst_port)
10249     return 0;
10250
10251   u8 *mask = 0;
10252   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10253
10254   tcpudp = (tcpudp_header_t *) mask;
10255   tcpudp->src_port = src_port;
10256   tcpudp->dst_port = dst_port;
10257
10258   *maskp = mask;
10259
10260   return 1;
10261 }
10262
10263 uword
10264 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10265 {
10266   u8 **maskp = va_arg (*args, u8 **);
10267   u8 *mask = 0;
10268   u8 found_something = 0;
10269   ip4_header_t *ip;
10270
10271 #define _(a) u8 a=0;
10272   foreach_ip4_proto_field;
10273 #undef _
10274   u8 version = 0;
10275   u8 hdr_length = 0;
10276
10277
10278   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10279     {
10280       if (unformat (input, "version"))
10281         version = 1;
10282       else if (unformat (input, "hdr_length"))
10283         hdr_length = 1;
10284       else if (unformat (input, "src"))
10285         src_address = 1;
10286       else if (unformat (input, "dst"))
10287         dst_address = 1;
10288       else if (unformat (input, "proto"))
10289         protocol = 1;
10290
10291 #define _(a) else if (unformat (input, #a)) a=1;
10292       foreach_ip4_proto_field
10293 #undef _
10294         else
10295         break;
10296     }
10297
10298 #define _(a) found_something += a;
10299   foreach_ip4_proto_field;
10300 #undef _
10301
10302   if (found_something == 0)
10303     return 0;
10304
10305   vec_validate (mask, sizeof (*ip) - 1);
10306
10307   ip = (ip4_header_t *) mask;
10308
10309 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10310   foreach_ip4_proto_field;
10311 #undef _
10312
10313   ip->ip_version_and_header_length = 0;
10314
10315   if (version)
10316     ip->ip_version_and_header_length |= 0xF0;
10317
10318   if (hdr_length)
10319     ip->ip_version_and_header_length |= 0x0F;
10320
10321   *maskp = mask;
10322   return 1;
10323 }
10324
10325 #define foreach_ip6_proto_field                 \
10326 _(src_address)                                  \
10327 _(dst_address)                                  \
10328 _(payload_length)                               \
10329 _(hop_limit)                                    \
10330 _(protocol)
10331
10332 uword
10333 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10334 {
10335   u8 **maskp = va_arg (*args, u8 **);
10336   u8 *mask = 0;
10337   u8 found_something = 0;
10338   ip6_header_t *ip;
10339   u32 ip_version_traffic_class_and_flow_label;
10340
10341 #define _(a) u8 a=0;
10342   foreach_ip6_proto_field;
10343 #undef _
10344   u8 version = 0;
10345   u8 traffic_class = 0;
10346   u8 flow_label = 0;
10347
10348   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10349     {
10350       if (unformat (input, "version"))
10351         version = 1;
10352       else if (unformat (input, "traffic-class"))
10353         traffic_class = 1;
10354       else if (unformat (input, "flow-label"))
10355         flow_label = 1;
10356       else if (unformat (input, "src"))
10357         src_address = 1;
10358       else if (unformat (input, "dst"))
10359         dst_address = 1;
10360       else if (unformat (input, "proto"))
10361         protocol = 1;
10362
10363 #define _(a) else if (unformat (input, #a)) a=1;
10364       foreach_ip6_proto_field
10365 #undef _
10366         else
10367         break;
10368     }
10369
10370 #define _(a) found_something += a;
10371   foreach_ip6_proto_field;
10372 #undef _
10373
10374   if (found_something == 0)
10375     return 0;
10376
10377   vec_validate (mask, sizeof (*ip) - 1);
10378
10379   ip = (ip6_header_t *) mask;
10380
10381 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10382   foreach_ip6_proto_field;
10383 #undef _
10384
10385   ip_version_traffic_class_and_flow_label = 0;
10386
10387   if (version)
10388     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10389
10390   if (traffic_class)
10391     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10392
10393   if (flow_label)
10394     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10395
10396   ip->ip_version_traffic_class_and_flow_label =
10397     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10398
10399   *maskp = mask;
10400   return 1;
10401 }
10402
10403 uword
10404 unformat_l3_mask (unformat_input_t * input, va_list * args)
10405 {
10406   u8 **maskp = va_arg (*args, u8 **);
10407
10408   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10409     {
10410       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10411         return 1;
10412       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10413         return 1;
10414       else
10415         break;
10416     }
10417   return 0;
10418 }
10419
10420 uword
10421 unformat_l2_mask (unformat_input_t * input, va_list * args)
10422 {
10423   u8 **maskp = va_arg (*args, u8 **);
10424   u8 *mask = 0;
10425   u8 src = 0;
10426   u8 dst = 0;
10427   u8 proto = 0;
10428   u8 tag1 = 0;
10429   u8 tag2 = 0;
10430   u8 ignore_tag1 = 0;
10431   u8 ignore_tag2 = 0;
10432   u8 cos1 = 0;
10433   u8 cos2 = 0;
10434   u8 dot1q = 0;
10435   u8 dot1ad = 0;
10436   int len = 14;
10437
10438   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10439     {
10440       if (unformat (input, "src"))
10441         src = 1;
10442       else if (unformat (input, "dst"))
10443         dst = 1;
10444       else if (unformat (input, "proto"))
10445         proto = 1;
10446       else if (unformat (input, "tag1"))
10447         tag1 = 1;
10448       else if (unformat (input, "tag2"))
10449         tag2 = 1;
10450       else if (unformat (input, "ignore-tag1"))
10451         ignore_tag1 = 1;
10452       else if (unformat (input, "ignore-tag2"))
10453         ignore_tag2 = 1;
10454       else if (unformat (input, "cos1"))
10455         cos1 = 1;
10456       else if (unformat (input, "cos2"))
10457         cos2 = 1;
10458       else if (unformat (input, "dot1q"))
10459         dot1q = 1;
10460       else if (unformat (input, "dot1ad"))
10461         dot1ad = 1;
10462       else
10463         break;
10464     }
10465   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10466        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10467     return 0;
10468
10469   if (tag1 || ignore_tag1 || cos1 || dot1q)
10470     len = 18;
10471   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10472     len = 22;
10473
10474   vec_validate (mask, len - 1);
10475
10476   if (dst)
10477     memset (mask, 0xff, 6);
10478
10479   if (src)
10480     memset (mask + 6, 0xff, 6);
10481
10482   if (tag2 || dot1ad)
10483     {
10484       /* inner vlan tag */
10485       if (tag2)
10486         {
10487           mask[19] = 0xff;
10488           mask[18] = 0x0f;
10489         }
10490       if (cos2)
10491         mask[18] |= 0xe0;
10492       if (proto)
10493         mask[21] = mask[20] = 0xff;
10494       if (tag1)
10495         {
10496           mask[15] = 0xff;
10497           mask[14] = 0x0f;
10498         }
10499       if (cos1)
10500         mask[14] |= 0xe0;
10501       *maskp = mask;
10502       return 1;
10503     }
10504   if (tag1 | dot1q)
10505     {
10506       if (tag1)
10507         {
10508           mask[15] = 0xff;
10509           mask[14] = 0x0f;
10510         }
10511       if (cos1)
10512         mask[14] |= 0xe0;
10513       if (proto)
10514         mask[16] = mask[17] = 0xff;
10515
10516       *maskp = mask;
10517       return 1;
10518     }
10519   if (cos2)
10520     mask[18] |= 0xe0;
10521   if (cos1)
10522     mask[14] |= 0xe0;
10523   if (proto)
10524     mask[12] = mask[13] = 0xff;
10525
10526   *maskp = mask;
10527   return 1;
10528 }
10529
10530 uword
10531 unformat_classify_mask (unformat_input_t * input, va_list * args)
10532 {
10533   u8 **maskp = va_arg (*args, u8 **);
10534   u32 *skipp = va_arg (*args, u32 *);
10535   u32 *matchp = va_arg (*args, u32 *);
10536   u32 match;
10537   u8 *mask = 0;
10538   u8 *l2 = 0;
10539   u8 *l3 = 0;
10540   u8 *l4 = 0;
10541   int i;
10542
10543   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10544     {
10545       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10546         ;
10547       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10548         ;
10549       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10550         ;
10551       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10552         ;
10553       else
10554         break;
10555     }
10556
10557   if (l4 && !l3)
10558     {
10559       vec_free (mask);
10560       vec_free (l2);
10561       vec_free (l4);
10562       return 0;
10563     }
10564
10565   if (mask || l2 || l3 || l4)
10566     {
10567       if (l2 || l3 || l4)
10568         {
10569           /* "With a free Ethernet header in every package" */
10570           if (l2 == 0)
10571             vec_validate (l2, 13);
10572           mask = l2;
10573           if (vec_len (l3))
10574             {
10575               vec_append (mask, l3);
10576               vec_free (l3);
10577             }
10578           if (vec_len (l4))
10579             {
10580               vec_append (mask, l4);
10581               vec_free (l4);
10582             }
10583         }
10584
10585       /* Scan forward looking for the first significant mask octet */
10586       for (i = 0; i < vec_len (mask); i++)
10587         if (mask[i])
10588           break;
10589
10590       /* compute (skip, match) params */
10591       *skipp = i / sizeof (u32x4);
10592       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10593
10594       /* Pad mask to an even multiple of the vector size */
10595       while (vec_len (mask) % sizeof (u32x4))
10596         vec_add1 (mask, 0);
10597
10598       match = vec_len (mask) / sizeof (u32x4);
10599
10600       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10601         {
10602           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10603           if (*tmp || *(tmp + 1))
10604             break;
10605           match--;
10606         }
10607       if (match == 0)
10608         clib_warning ("BUG: match 0");
10609
10610       _vec_len (mask) = match * sizeof (u32x4);
10611
10612       *matchp = match;
10613       *maskp = mask;
10614
10615       return 1;
10616     }
10617
10618   return 0;
10619 }
10620 #endif /* VPP_API_TEST_BUILTIN */
10621
10622 #define foreach_l2_next                         \
10623 _(drop, DROP)                                   \
10624 _(ethernet, ETHERNET_INPUT)                     \
10625 _(ip4, IP4_INPUT)                               \
10626 _(ip6, IP6_INPUT)
10627
10628 uword
10629 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10630 {
10631   u32 *miss_next_indexp = va_arg (*args, u32 *);
10632   u32 next_index = 0;
10633   u32 tmp;
10634
10635 #define _(n,N) \
10636   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10637   foreach_l2_next;
10638 #undef _
10639
10640   if (unformat (input, "%d", &tmp))
10641     {
10642       next_index = tmp;
10643       goto out;
10644     }
10645
10646   return 0;
10647
10648 out:
10649   *miss_next_indexp = next_index;
10650   return 1;
10651 }
10652
10653 #define foreach_ip_next                         \
10654 _(drop, DROP)                                   \
10655 _(local, LOCAL)                                 \
10656 _(rewrite, REWRITE)
10657
10658 uword
10659 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10660 {
10661   u32 *miss_next_indexp = va_arg (*args, u32 *);
10662   u32 next_index = 0;
10663   u32 tmp;
10664
10665 #define _(n,N) \
10666   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10667   foreach_ip_next;
10668 #undef _
10669
10670   if (unformat (input, "%d", &tmp))
10671     {
10672       next_index = tmp;
10673       goto out;
10674     }
10675
10676   return 0;
10677
10678 out:
10679   *miss_next_indexp = next_index;
10680   return 1;
10681 }
10682
10683 #define foreach_acl_next                        \
10684 _(deny, DENY)
10685
10686 uword
10687 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10688 {
10689   u32 *miss_next_indexp = va_arg (*args, u32 *);
10690   u32 next_index = 0;
10691   u32 tmp;
10692
10693 #define _(n,N) \
10694   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10695   foreach_acl_next;
10696 #undef _
10697
10698   if (unformat (input, "permit"))
10699     {
10700       next_index = ~0;
10701       goto out;
10702     }
10703   else if (unformat (input, "%d", &tmp))
10704     {
10705       next_index = tmp;
10706       goto out;
10707     }
10708
10709   return 0;
10710
10711 out:
10712   *miss_next_indexp = next_index;
10713   return 1;
10714 }
10715
10716 uword
10717 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10718 {
10719   u32 *r = va_arg (*args, u32 *);
10720
10721   if (unformat (input, "conform-color"))
10722     *r = POLICE_CONFORM;
10723   else if (unformat (input, "exceed-color"))
10724     *r = POLICE_EXCEED;
10725   else
10726     return 0;
10727
10728   return 1;
10729 }
10730
10731 static int
10732 api_classify_add_del_table (vat_main_t * vam)
10733 {
10734   unformat_input_t *i = vam->input;
10735   vl_api_classify_add_del_table_t *mp;
10736
10737   u32 nbuckets = 2;
10738   u32 skip = ~0;
10739   u32 match = ~0;
10740   int is_add = 1;
10741   int del_chain = 0;
10742   u32 table_index = ~0;
10743   u32 next_table_index = ~0;
10744   u32 miss_next_index = ~0;
10745   u32 memory_size = 32 << 20;
10746   u8 *mask = 0;
10747   u32 current_data_flag = 0;
10748   int current_data_offset = 0;
10749   int ret;
10750
10751   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10752     {
10753       if (unformat (i, "del"))
10754         is_add = 0;
10755       else if (unformat (i, "del-chain"))
10756         {
10757           is_add = 0;
10758           del_chain = 1;
10759         }
10760       else if (unformat (i, "buckets %d", &nbuckets))
10761         ;
10762       else if (unformat (i, "memory_size %d", &memory_size))
10763         ;
10764       else if (unformat (i, "skip %d", &skip))
10765         ;
10766       else if (unformat (i, "match %d", &match))
10767         ;
10768       else if (unformat (i, "table %d", &table_index))
10769         ;
10770       else if (unformat (i, "mask %U", unformat_classify_mask,
10771                          &mask, &skip, &match))
10772         ;
10773       else if (unformat (i, "next-table %d", &next_table_index))
10774         ;
10775       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10776                          &miss_next_index))
10777         ;
10778       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10779                          &miss_next_index))
10780         ;
10781       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10782                          &miss_next_index))
10783         ;
10784       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10785         ;
10786       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10787         ;
10788       else
10789         break;
10790     }
10791
10792   if (is_add && mask == 0)
10793     {
10794       errmsg ("Mask required");
10795       return -99;
10796     }
10797
10798   if (is_add && skip == ~0)
10799     {
10800       errmsg ("skip count required");
10801       return -99;
10802     }
10803
10804   if (is_add && match == ~0)
10805     {
10806       errmsg ("match count required");
10807       return -99;
10808     }
10809
10810   if (!is_add && table_index == ~0)
10811     {
10812       errmsg ("table index required for delete");
10813       return -99;
10814     }
10815
10816   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10817
10818   mp->is_add = is_add;
10819   mp->del_chain = del_chain;
10820   mp->table_index = ntohl (table_index);
10821   mp->nbuckets = ntohl (nbuckets);
10822   mp->memory_size = ntohl (memory_size);
10823   mp->skip_n_vectors = ntohl (skip);
10824   mp->match_n_vectors = ntohl (match);
10825   mp->next_table_index = ntohl (next_table_index);
10826   mp->miss_next_index = ntohl (miss_next_index);
10827   mp->current_data_flag = ntohl (current_data_flag);
10828   mp->current_data_offset = ntohl (current_data_offset);
10829   clib_memcpy (mp->mask, mask, vec_len (mask));
10830
10831   vec_free (mask);
10832
10833   S (mp);
10834   W (ret);
10835   return ret;
10836 }
10837
10838 #if VPP_API_TEST_BUILTIN == 0
10839 uword
10840 unformat_l4_match (unformat_input_t * input, va_list * args)
10841 {
10842   u8 **matchp = va_arg (*args, u8 **);
10843
10844   u8 *proto_header = 0;
10845   int src_port = 0;
10846   int dst_port = 0;
10847
10848   tcpudp_header_t h;
10849
10850   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10851     {
10852       if (unformat (input, "src_port %d", &src_port))
10853         ;
10854       else if (unformat (input, "dst_port %d", &dst_port))
10855         ;
10856       else
10857         return 0;
10858     }
10859
10860   h.src_port = clib_host_to_net_u16 (src_port);
10861   h.dst_port = clib_host_to_net_u16 (dst_port);
10862   vec_validate (proto_header, sizeof (h) - 1);
10863   memcpy (proto_header, &h, sizeof (h));
10864
10865   *matchp = proto_header;
10866
10867   return 1;
10868 }
10869
10870 uword
10871 unformat_ip4_match (unformat_input_t * input, va_list * args)
10872 {
10873   u8 **matchp = va_arg (*args, u8 **);
10874   u8 *match = 0;
10875   ip4_header_t *ip;
10876   int version = 0;
10877   u32 version_val;
10878   int hdr_length = 0;
10879   u32 hdr_length_val;
10880   int src = 0, dst = 0;
10881   ip4_address_t src_val, dst_val;
10882   int proto = 0;
10883   u32 proto_val;
10884   int tos = 0;
10885   u32 tos_val;
10886   int length = 0;
10887   u32 length_val;
10888   int fragment_id = 0;
10889   u32 fragment_id_val;
10890   int ttl = 0;
10891   int ttl_val;
10892   int checksum = 0;
10893   u32 checksum_val;
10894
10895   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10896     {
10897       if (unformat (input, "version %d", &version_val))
10898         version = 1;
10899       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10900         hdr_length = 1;
10901       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10902         src = 1;
10903       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10904         dst = 1;
10905       else if (unformat (input, "proto %d", &proto_val))
10906         proto = 1;
10907       else if (unformat (input, "tos %d", &tos_val))
10908         tos = 1;
10909       else if (unformat (input, "length %d", &length_val))
10910         length = 1;
10911       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10912         fragment_id = 1;
10913       else if (unformat (input, "ttl %d", &ttl_val))
10914         ttl = 1;
10915       else if (unformat (input, "checksum %d", &checksum_val))
10916         checksum = 1;
10917       else
10918         break;
10919     }
10920
10921   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10922       + ttl + checksum == 0)
10923     return 0;
10924
10925   /*
10926    * Aligned because we use the real comparison functions
10927    */
10928   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10929
10930   ip = (ip4_header_t *) match;
10931
10932   /* These are realistically matched in practice */
10933   if (src)
10934     ip->src_address.as_u32 = src_val.as_u32;
10935
10936   if (dst)
10937     ip->dst_address.as_u32 = dst_val.as_u32;
10938
10939   if (proto)
10940     ip->protocol = proto_val;
10941
10942
10943   /* These are not, but they're included for completeness */
10944   if (version)
10945     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10946
10947   if (hdr_length)
10948     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10949
10950   if (tos)
10951     ip->tos = tos_val;
10952
10953   if (length)
10954     ip->length = clib_host_to_net_u16 (length_val);
10955
10956   if (ttl)
10957     ip->ttl = ttl_val;
10958
10959   if (checksum)
10960     ip->checksum = clib_host_to_net_u16 (checksum_val);
10961
10962   *matchp = match;
10963   return 1;
10964 }
10965
10966 uword
10967 unformat_ip6_match (unformat_input_t * input, va_list * args)
10968 {
10969   u8 **matchp = va_arg (*args, u8 **);
10970   u8 *match = 0;
10971   ip6_header_t *ip;
10972   int version = 0;
10973   u32 version_val;
10974   u8 traffic_class = 0;
10975   u32 traffic_class_val = 0;
10976   u8 flow_label = 0;
10977   u8 flow_label_val;
10978   int src = 0, dst = 0;
10979   ip6_address_t src_val, dst_val;
10980   int proto = 0;
10981   u32 proto_val;
10982   int payload_length = 0;
10983   u32 payload_length_val;
10984   int hop_limit = 0;
10985   int hop_limit_val;
10986   u32 ip_version_traffic_class_and_flow_label;
10987
10988   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10989     {
10990       if (unformat (input, "version %d", &version_val))
10991         version = 1;
10992       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10993         traffic_class = 1;
10994       else if (unformat (input, "flow_label %d", &flow_label_val))
10995         flow_label = 1;
10996       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10997         src = 1;
10998       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10999         dst = 1;
11000       else if (unformat (input, "proto %d", &proto_val))
11001         proto = 1;
11002       else if (unformat (input, "payload_length %d", &payload_length_val))
11003         payload_length = 1;
11004       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11005         hop_limit = 1;
11006       else
11007         break;
11008     }
11009
11010   if (version + traffic_class + flow_label + src + dst + proto +
11011       payload_length + hop_limit == 0)
11012     return 0;
11013
11014   /*
11015    * Aligned because we use the real comparison functions
11016    */
11017   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11018
11019   ip = (ip6_header_t *) match;
11020
11021   if (src)
11022     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11023
11024   if (dst)
11025     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11026
11027   if (proto)
11028     ip->protocol = proto_val;
11029
11030   ip_version_traffic_class_and_flow_label = 0;
11031
11032   if (version)
11033     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11034
11035   if (traffic_class)
11036     ip_version_traffic_class_and_flow_label |=
11037       (traffic_class_val & 0xFF) << 20;
11038
11039   if (flow_label)
11040     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11041
11042   ip->ip_version_traffic_class_and_flow_label =
11043     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11044
11045   if (payload_length)
11046     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11047
11048   if (hop_limit)
11049     ip->hop_limit = hop_limit_val;
11050
11051   *matchp = match;
11052   return 1;
11053 }
11054
11055 uword
11056 unformat_l3_match (unformat_input_t * input, va_list * args)
11057 {
11058   u8 **matchp = va_arg (*args, u8 **);
11059
11060   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11061     {
11062       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11063         return 1;
11064       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11065         return 1;
11066       else
11067         break;
11068     }
11069   return 0;
11070 }
11071
11072 uword
11073 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11074 {
11075   u8 *tagp = va_arg (*args, u8 *);
11076   u32 tag;
11077
11078   if (unformat (input, "%d", &tag))
11079     {
11080       tagp[0] = (tag >> 8) & 0x0F;
11081       tagp[1] = tag & 0xFF;
11082       return 1;
11083     }
11084
11085   return 0;
11086 }
11087
11088 uword
11089 unformat_l2_match (unformat_input_t * input, va_list * args)
11090 {
11091   u8 **matchp = va_arg (*args, u8 **);
11092   u8 *match = 0;
11093   u8 src = 0;
11094   u8 src_val[6];
11095   u8 dst = 0;
11096   u8 dst_val[6];
11097   u8 proto = 0;
11098   u16 proto_val;
11099   u8 tag1 = 0;
11100   u8 tag1_val[2];
11101   u8 tag2 = 0;
11102   u8 tag2_val[2];
11103   int len = 14;
11104   u8 ignore_tag1 = 0;
11105   u8 ignore_tag2 = 0;
11106   u8 cos1 = 0;
11107   u8 cos2 = 0;
11108   u32 cos1_val = 0;
11109   u32 cos2_val = 0;
11110
11111   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11112     {
11113       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11114         src = 1;
11115       else
11116         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11117         dst = 1;
11118       else if (unformat (input, "proto %U",
11119                          unformat_ethernet_type_host_byte_order, &proto_val))
11120         proto = 1;
11121       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11122         tag1 = 1;
11123       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11124         tag2 = 1;
11125       else if (unformat (input, "ignore-tag1"))
11126         ignore_tag1 = 1;
11127       else if (unformat (input, "ignore-tag2"))
11128         ignore_tag2 = 1;
11129       else if (unformat (input, "cos1 %d", &cos1_val))
11130         cos1 = 1;
11131       else if (unformat (input, "cos2 %d", &cos2_val))
11132         cos2 = 1;
11133       else
11134         break;
11135     }
11136   if ((src + dst + proto + tag1 + tag2 +
11137        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11138     return 0;
11139
11140   if (tag1 || ignore_tag1 || cos1)
11141     len = 18;
11142   if (tag2 || ignore_tag2 || cos2)
11143     len = 22;
11144
11145   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11146
11147   if (dst)
11148     clib_memcpy (match, dst_val, 6);
11149
11150   if (src)
11151     clib_memcpy (match + 6, src_val, 6);
11152
11153   if (tag2)
11154     {
11155       /* inner vlan tag */
11156       match[19] = tag2_val[1];
11157       match[18] = tag2_val[0];
11158       if (cos2)
11159         match[18] |= (cos2_val & 0x7) << 5;
11160       if (proto)
11161         {
11162           match[21] = proto_val & 0xff;
11163           match[20] = proto_val >> 8;
11164         }
11165       if (tag1)
11166         {
11167           match[15] = tag1_val[1];
11168           match[14] = tag1_val[0];
11169         }
11170       if (cos1)
11171         match[14] |= (cos1_val & 0x7) << 5;
11172       *matchp = match;
11173       return 1;
11174     }
11175   if (tag1)
11176     {
11177       match[15] = tag1_val[1];
11178       match[14] = tag1_val[0];
11179       if (proto)
11180         {
11181           match[17] = proto_val & 0xff;
11182           match[16] = proto_val >> 8;
11183         }
11184       if (cos1)
11185         match[14] |= (cos1_val & 0x7) << 5;
11186
11187       *matchp = match;
11188       return 1;
11189     }
11190   if (cos2)
11191     match[18] |= (cos2_val & 0x7) << 5;
11192   if (cos1)
11193     match[14] |= (cos1_val & 0x7) << 5;
11194   if (proto)
11195     {
11196       match[13] = proto_val & 0xff;
11197       match[12] = proto_val >> 8;
11198     }
11199
11200   *matchp = match;
11201   return 1;
11202 }
11203 #endif
11204
11205 uword
11206 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11207 {
11208   u8 **matchp = va_arg (*args, u8 **);
11209   u32 skip_n_vectors = va_arg (*args, u32);
11210   u32 match_n_vectors = va_arg (*args, u32);
11211
11212   u8 *match = 0;
11213   u8 *l2 = 0;
11214   u8 *l3 = 0;
11215   u8 *l4 = 0;
11216
11217   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11218     {
11219       if (unformat (input, "hex %U", unformat_hex_string, &match))
11220         ;
11221       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11222         ;
11223       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11224         ;
11225       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11226         ;
11227       else
11228         break;
11229     }
11230
11231   if (l4 && !l3)
11232     {
11233       vec_free (match);
11234       vec_free (l2);
11235       vec_free (l4);
11236       return 0;
11237     }
11238
11239   if (match || l2 || l3 || l4)
11240     {
11241       if (l2 || l3 || l4)
11242         {
11243           /* "Win a free Ethernet header in every packet" */
11244           if (l2 == 0)
11245             vec_validate_aligned (l2, 13, sizeof (u32x4));
11246           match = l2;
11247           if (vec_len (l3))
11248             {
11249               vec_append_aligned (match, l3, sizeof (u32x4));
11250               vec_free (l3);
11251             }
11252           if (vec_len (l4))
11253             {
11254               vec_append_aligned (match, l4, sizeof (u32x4));
11255               vec_free (l4);
11256             }
11257         }
11258
11259       /* Make sure the vector is big enough even if key is all 0's */
11260       vec_validate_aligned
11261         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11262          sizeof (u32x4));
11263
11264       /* Set size, include skipped vectors */
11265       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11266
11267       *matchp = match;
11268
11269       return 1;
11270     }
11271
11272   return 0;
11273 }
11274
11275 static int
11276 api_classify_add_del_session (vat_main_t * vam)
11277 {
11278   unformat_input_t *i = vam->input;
11279   vl_api_classify_add_del_session_t *mp;
11280   int is_add = 1;
11281   u32 table_index = ~0;
11282   u32 hit_next_index = ~0;
11283   u32 opaque_index = ~0;
11284   u8 *match = 0;
11285   i32 advance = 0;
11286   u32 skip_n_vectors = 0;
11287   u32 match_n_vectors = 0;
11288   u32 action = 0;
11289   u32 metadata = 0;
11290   int ret;
11291
11292   /*
11293    * Warning: you have to supply skip_n and match_n
11294    * because the API client cant simply look at the classify
11295    * table object.
11296    */
11297
11298   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11299     {
11300       if (unformat (i, "del"))
11301         is_add = 0;
11302       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11303                          &hit_next_index))
11304         ;
11305       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11306                          &hit_next_index))
11307         ;
11308       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11309                          &hit_next_index))
11310         ;
11311       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11312         ;
11313       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11314         ;
11315       else if (unformat (i, "opaque-index %d", &opaque_index))
11316         ;
11317       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11318         ;
11319       else if (unformat (i, "match_n %d", &match_n_vectors))
11320         ;
11321       else if (unformat (i, "match %U", api_unformat_classify_match,
11322                          &match, skip_n_vectors, match_n_vectors))
11323         ;
11324       else if (unformat (i, "advance %d", &advance))
11325         ;
11326       else if (unformat (i, "table-index %d", &table_index))
11327         ;
11328       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11329         action = 1;
11330       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11331         action = 2;
11332       else if (unformat (i, "action %d", &action))
11333         ;
11334       else if (unformat (i, "metadata %d", &metadata))
11335         ;
11336       else
11337         break;
11338     }
11339
11340   if (table_index == ~0)
11341     {
11342       errmsg ("Table index required");
11343       return -99;
11344     }
11345
11346   if (is_add && match == 0)
11347     {
11348       errmsg ("Match value required");
11349       return -99;
11350     }
11351
11352   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11353
11354   mp->is_add = is_add;
11355   mp->table_index = ntohl (table_index);
11356   mp->hit_next_index = ntohl (hit_next_index);
11357   mp->opaque_index = ntohl (opaque_index);
11358   mp->advance = ntohl (advance);
11359   mp->action = action;
11360   mp->metadata = ntohl (metadata);
11361   clib_memcpy (mp->match, match, vec_len (match));
11362   vec_free (match);
11363
11364   S (mp);
11365   W (ret);
11366   return ret;
11367 }
11368
11369 static int
11370 api_classify_set_interface_ip_table (vat_main_t * vam)
11371 {
11372   unformat_input_t *i = vam->input;
11373   vl_api_classify_set_interface_ip_table_t *mp;
11374   u32 sw_if_index;
11375   int sw_if_index_set;
11376   u32 table_index = ~0;
11377   u8 is_ipv6 = 0;
11378   int ret;
11379
11380   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11381     {
11382       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11383         sw_if_index_set = 1;
11384       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11385         sw_if_index_set = 1;
11386       else if (unformat (i, "table %d", &table_index))
11387         ;
11388       else
11389         {
11390           clib_warning ("parse error '%U'", format_unformat_error, i);
11391           return -99;
11392         }
11393     }
11394
11395   if (sw_if_index_set == 0)
11396     {
11397       errmsg ("missing interface name or sw_if_index");
11398       return -99;
11399     }
11400
11401
11402   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11403
11404   mp->sw_if_index = ntohl (sw_if_index);
11405   mp->table_index = ntohl (table_index);
11406   mp->is_ipv6 = is_ipv6;
11407
11408   S (mp);
11409   W (ret);
11410   return ret;
11411 }
11412
11413 static int
11414 api_classify_set_interface_l2_tables (vat_main_t * vam)
11415 {
11416   unformat_input_t *i = vam->input;
11417   vl_api_classify_set_interface_l2_tables_t *mp;
11418   u32 sw_if_index;
11419   int sw_if_index_set;
11420   u32 ip4_table_index = ~0;
11421   u32 ip6_table_index = ~0;
11422   u32 other_table_index = ~0;
11423   u32 is_input = 1;
11424   int ret;
11425
11426   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11427     {
11428       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11429         sw_if_index_set = 1;
11430       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11431         sw_if_index_set = 1;
11432       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11433         ;
11434       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11435         ;
11436       else if (unformat (i, "other-table %d", &other_table_index))
11437         ;
11438       else if (unformat (i, "is-input %d", &is_input))
11439         ;
11440       else
11441         {
11442           clib_warning ("parse error '%U'", format_unformat_error, i);
11443           return -99;
11444         }
11445     }
11446
11447   if (sw_if_index_set == 0)
11448     {
11449       errmsg ("missing interface name or sw_if_index");
11450       return -99;
11451     }
11452
11453
11454   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11455
11456   mp->sw_if_index = ntohl (sw_if_index);
11457   mp->ip4_table_index = ntohl (ip4_table_index);
11458   mp->ip6_table_index = ntohl (ip6_table_index);
11459   mp->other_table_index = ntohl (other_table_index);
11460   mp->is_input = (u8) is_input;
11461
11462   S (mp);
11463   W (ret);
11464   return ret;
11465 }
11466
11467 static int
11468 api_set_ipfix_exporter (vat_main_t * vam)
11469 {
11470   unformat_input_t *i = vam->input;
11471   vl_api_set_ipfix_exporter_t *mp;
11472   ip4_address_t collector_address;
11473   u8 collector_address_set = 0;
11474   u32 collector_port = ~0;
11475   ip4_address_t src_address;
11476   u8 src_address_set = 0;
11477   u32 vrf_id = ~0;
11478   u32 path_mtu = ~0;
11479   u32 template_interval = ~0;
11480   u8 udp_checksum = 0;
11481   int ret;
11482
11483   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11484     {
11485       if (unformat (i, "collector_address %U", unformat_ip4_address,
11486                     &collector_address))
11487         collector_address_set = 1;
11488       else if (unformat (i, "collector_port %d", &collector_port))
11489         ;
11490       else if (unformat (i, "src_address %U", unformat_ip4_address,
11491                          &src_address))
11492         src_address_set = 1;
11493       else if (unformat (i, "vrf_id %d", &vrf_id))
11494         ;
11495       else if (unformat (i, "path_mtu %d", &path_mtu))
11496         ;
11497       else if (unformat (i, "template_interval %d", &template_interval))
11498         ;
11499       else if (unformat (i, "udp_checksum"))
11500         udp_checksum = 1;
11501       else
11502         break;
11503     }
11504
11505   if (collector_address_set == 0)
11506     {
11507       errmsg ("collector_address required");
11508       return -99;
11509     }
11510
11511   if (src_address_set == 0)
11512     {
11513       errmsg ("src_address required");
11514       return -99;
11515     }
11516
11517   M (SET_IPFIX_EXPORTER, mp);
11518
11519   memcpy (mp->collector_address, collector_address.data,
11520           sizeof (collector_address.data));
11521   mp->collector_port = htons ((u16) collector_port);
11522   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11523   mp->vrf_id = htonl (vrf_id);
11524   mp->path_mtu = htonl (path_mtu);
11525   mp->template_interval = htonl (template_interval);
11526   mp->udp_checksum = udp_checksum;
11527
11528   S (mp);
11529   W (ret);
11530   return ret;
11531 }
11532
11533 static int
11534 api_set_ipfix_classify_stream (vat_main_t * vam)
11535 {
11536   unformat_input_t *i = vam->input;
11537   vl_api_set_ipfix_classify_stream_t *mp;
11538   u32 domain_id = 0;
11539   u32 src_port = UDP_DST_PORT_ipfix;
11540   int ret;
11541
11542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11543     {
11544       if (unformat (i, "domain %d", &domain_id))
11545         ;
11546       else if (unformat (i, "src_port %d", &src_port))
11547         ;
11548       else
11549         {
11550           errmsg ("unknown input `%U'", format_unformat_error, i);
11551           return -99;
11552         }
11553     }
11554
11555   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11556
11557   mp->domain_id = htonl (domain_id);
11558   mp->src_port = htons ((u16) src_port);
11559
11560   S (mp);
11561   W (ret);
11562   return ret;
11563 }
11564
11565 static int
11566 api_ipfix_classify_table_add_del (vat_main_t * vam)
11567 {
11568   unformat_input_t *i = vam->input;
11569   vl_api_ipfix_classify_table_add_del_t *mp;
11570   int is_add = -1;
11571   u32 classify_table_index = ~0;
11572   u8 ip_version = 0;
11573   u8 transport_protocol = 255;
11574   int ret;
11575
11576   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11577     {
11578       if (unformat (i, "add"))
11579         is_add = 1;
11580       else if (unformat (i, "del"))
11581         is_add = 0;
11582       else if (unformat (i, "table %d", &classify_table_index))
11583         ;
11584       else if (unformat (i, "ip4"))
11585         ip_version = 4;
11586       else if (unformat (i, "ip6"))
11587         ip_version = 6;
11588       else if (unformat (i, "tcp"))
11589         transport_protocol = 6;
11590       else if (unformat (i, "udp"))
11591         transport_protocol = 17;
11592       else
11593         {
11594           errmsg ("unknown input `%U'", format_unformat_error, i);
11595           return -99;
11596         }
11597     }
11598
11599   if (is_add == -1)
11600     {
11601       errmsg ("expecting: add|del");
11602       return -99;
11603     }
11604   if (classify_table_index == ~0)
11605     {
11606       errmsg ("classifier table not specified");
11607       return -99;
11608     }
11609   if (ip_version == 0)
11610     {
11611       errmsg ("IP version not specified");
11612       return -99;
11613     }
11614
11615   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11616
11617   mp->is_add = is_add;
11618   mp->table_id = htonl (classify_table_index);
11619   mp->ip_version = ip_version;
11620   mp->transport_protocol = transport_protocol;
11621
11622   S (mp);
11623   W (ret);
11624   return ret;
11625 }
11626
11627 static int
11628 api_get_node_index (vat_main_t * vam)
11629 {
11630   unformat_input_t *i = vam->input;
11631   vl_api_get_node_index_t *mp;
11632   u8 *name = 0;
11633   int ret;
11634
11635   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11636     {
11637       if (unformat (i, "node %s", &name))
11638         ;
11639       else
11640         break;
11641     }
11642   if (name == 0)
11643     {
11644       errmsg ("node name required");
11645       return -99;
11646     }
11647   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11648     {
11649       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11650       return -99;
11651     }
11652
11653   M (GET_NODE_INDEX, mp);
11654   clib_memcpy (mp->node_name, name, vec_len (name));
11655   vec_free (name);
11656
11657   S (mp);
11658   W (ret);
11659   return ret;
11660 }
11661
11662 static int
11663 api_get_next_index (vat_main_t * vam)
11664 {
11665   unformat_input_t *i = vam->input;
11666   vl_api_get_next_index_t *mp;
11667   u8 *node_name = 0, *next_node_name = 0;
11668   int ret;
11669
11670   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11671     {
11672       if (unformat (i, "node-name %s", &node_name))
11673         ;
11674       else if (unformat (i, "next-node-name %s", &next_node_name))
11675         break;
11676     }
11677
11678   if (node_name == 0)
11679     {
11680       errmsg ("node name required");
11681       return -99;
11682     }
11683   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11684     {
11685       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11686       return -99;
11687     }
11688
11689   if (next_node_name == 0)
11690     {
11691       errmsg ("next node name required");
11692       return -99;
11693     }
11694   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11695     {
11696       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11697       return -99;
11698     }
11699
11700   M (GET_NEXT_INDEX, mp);
11701   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11702   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11703   vec_free (node_name);
11704   vec_free (next_node_name);
11705
11706   S (mp);
11707   W (ret);
11708   return ret;
11709 }
11710
11711 static int
11712 api_add_node_next (vat_main_t * vam)
11713 {
11714   unformat_input_t *i = vam->input;
11715   vl_api_add_node_next_t *mp;
11716   u8 *name = 0;
11717   u8 *next = 0;
11718   int ret;
11719
11720   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11721     {
11722       if (unformat (i, "node %s", &name))
11723         ;
11724       else if (unformat (i, "next %s", &next))
11725         ;
11726       else
11727         break;
11728     }
11729   if (name == 0)
11730     {
11731       errmsg ("node name required");
11732       return -99;
11733     }
11734   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11735     {
11736       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11737       return -99;
11738     }
11739   if (next == 0)
11740     {
11741       errmsg ("next node required");
11742       return -99;
11743     }
11744   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11745     {
11746       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11747       return -99;
11748     }
11749
11750   M (ADD_NODE_NEXT, mp);
11751   clib_memcpy (mp->node_name, name, vec_len (name));
11752   clib_memcpy (mp->next_name, next, vec_len (next));
11753   vec_free (name);
11754   vec_free (next);
11755
11756   S (mp);
11757   W (ret);
11758   return ret;
11759 }
11760
11761 static int
11762 api_l2tpv3_create_tunnel (vat_main_t * vam)
11763 {
11764   unformat_input_t *i = vam->input;
11765   ip6_address_t client_address, our_address;
11766   int client_address_set = 0;
11767   int our_address_set = 0;
11768   u32 local_session_id = 0;
11769   u32 remote_session_id = 0;
11770   u64 local_cookie = 0;
11771   u64 remote_cookie = 0;
11772   u8 l2_sublayer_present = 0;
11773   vl_api_l2tpv3_create_tunnel_t *mp;
11774   int ret;
11775
11776   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11777     {
11778       if (unformat (i, "client_address %U", unformat_ip6_address,
11779                     &client_address))
11780         client_address_set = 1;
11781       else if (unformat (i, "our_address %U", unformat_ip6_address,
11782                          &our_address))
11783         our_address_set = 1;
11784       else if (unformat (i, "local_session_id %d", &local_session_id))
11785         ;
11786       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11787         ;
11788       else if (unformat (i, "local_cookie %lld", &local_cookie))
11789         ;
11790       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11791         ;
11792       else if (unformat (i, "l2-sublayer-present"))
11793         l2_sublayer_present = 1;
11794       else
11795         break;
11796     }
11797
11798   if (client_address_set == 0)
11799     {
11800       errmsg ("client_address required");
11801       return -99;
11802     }
11803
11804   if (our_address_set == 0)
11805     {
11806       errmsg ("our_address required");
11807       return -99;
11808     }
11809
11810   M (L2TPV3_CREATE_TUNNEL, mp);
11811
11812   clib_memcpy (mp->client_address, client_address.as_u8,
11813                sizeof (mp->client_address));
11814
11815   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11816
11817   mp->local_session_id = ntohl (local_session_id);
11818   mp->remote_session_id = ntohl (remote_session_id);
11819   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11820   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11821   mp->l2_sublayer_present = l2_sublayer_present;
11822   mp->is_ipv6 = 1;
11823
11824   S (mp);
11825   W (ret);
11826   return ret;
11827 }
11828
11829 static int
11830 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11831 {
11832   unformat_input_t *i = vam->input;
11833   u32 sw_if_index;
11834   u8 sw_if_index_set = 0;
11835   u64 new_local_cookie = 0;
11836   u64 new_remote_cookie = 0;
11837   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11838   int ret;
11839
11840   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11841     {
11842       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11843         sw_if_index_set = 1;
11844       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11845         sw_if_index_set = 1;
11846       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11847         ;
11848       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11849         ;
11850       else
11851         break;
11852     }
11853
11854   if (sw_if_index_set == 0)
11855     {
11856       errmsg ("missing interface name or sw_if_index");
11857       return -99;
11858     }
11859
11860   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11861
11862   mp->sw_if_index = ntohl (sw_if_index);
11863   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11864   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11865
11866   S (mp);
11867   W (ret);
11868   return ret;
11869 }
11870
11871 static int
11872 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11873 {
11874   unformat_input_t *i = vam->input;
11875   vl_api_l2tpv3_interface_enable_disable_t *mp;
11876   u32 sw_if_index;
11877   u8 sw_if_index_set = 0;
11878   u8 enable_disable = 1;
11879   int ret;
11880
11881   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11882     {
11883       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11884         sw_if_index_set = 1;
11885       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11886         sw_if_index_set = 1;
11887       else if (unformat (i, "enable"))
11888         enable_disable = 1;
11889       else if (unformat (i, "disable"))
11890         enable_disable = 0;
11891       else
11892         break;
11893     }
11894
11895   if (sw_if_index_set == 0)
11896     {
11897       errmsg ("missing interface name or sw_if_index");
11898       return -99;
11899     }
11900
11901   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11902
11903   mp->sw_if_index = ntohl (sw_if_index);
11904   mp->enable_disable = enable_disable;
11905
11906   S (mp);
11907   W (ret);
11908   return ret;
11909 }
11910
11911 static int
11912 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11913 {
11914   unformat_input_t *i = vam->input;
11915   vl_api_l2tpv3_set_lookup_key_t *mp;
11916   u8 key = ~0;
11917   int ret;
11918
11919   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11920     {
11921       if (unformat (i, "lookup_v6_src"))
11922         key = L2T_LOOKUP_SRC_ADDRESS;
11923       else if (unformat (i, "lookup_v6_dst"))
11924         key = L2T_LOOKUP_DST_ADDRESS;
11925       else if (unformat (i, "lookup_session_id"))
11926         key = L2T_LOOKUP_SESSION_ID;
11927       else
11928         break;
11929     }
11930
11931   if (key == (u8) ~ 0)
11932     {
11933       errmsg ("l2tp session lookup key unset");
11934       return -99;
11935     }
11936
11937   M (L2TPV3_SET_LOOKUP_KEY, mp);
11938
11939   mp->key = key;
11940
11941   S (mp);
11942   W (ret);
11943   return ret;
11944 }
11945
11946 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11947   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11948 {
11949   vat_main_t *vam = &vat_main;
11950
11951   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11952          format_ip6_address, mp->our_address,
11953          format_ip6_address, mp->client_address,
11954          clib_net_to_host_u32 (mp->sw_if_index));
11955
11956   print (vam->ofp,
11957          "   local cookies %016llx %016llx remote cookie %016llx",
11958          clib_net_to_host_u64 (mp->local_cookie[0]),
11959          clib_net_to_host_u64 (mp->local_cookie[1]),
11960          clib_net_to_host_u64 (mp->remote_cookie));
11961
11962   print (vam->ofp, "   local session-id %d remote session-id %d",
11963          clib_net_to_host_u32 (mp->local_session_id),
11964          clib_net_to_host_u32 (mp->remote_session_id));
11965
11966   print (vam->ofp, "   l2 specific sublayer %s\n",
11967          mp->l2_sublayer_present ? "preset" : "absent");
11968
11969 }
11970
11971 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11972   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11973 {
11974   vat_main_t *vam = &vat_main;
11975   vat_json_node_t *node = NULL;
11976   struct in6_addr addr;
11977
11978   if (VAT_JSON_ARRAY != vam->json_tree.type)
11979     {
11980       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11981       vat_json_init_array (&vam->json_tree);
11982     }
11983   node = vat_json_array_add (&vam->json_tree);
11984
11985   vat_json_init_object (node);
11986
11987   clib_memcpy (&addr, mp->our_address, sizeof (addr));
11988   vat_json_object_add_ip6 (node, "our_address", addr);
11989   clib_memcpy (&addr, mp->client_address, sizeof (addr));
11990   vat_json_object_add_ip6 (node, "client_address", addr);
11991
11992   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11993   vat_json_init_array (lc);
11994   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11995   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11996   vat_json_object_add_uint (node, "remote_cookie",
11997                             clib_net_to_host_u64 (mp->remote_cookie));
11998
11999   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12000   vat_json_object_add_uint (node, "local_session_id",
12001                             clib_net_to_host_u32 (mp->local_session_id));
12002   vat_json_object_add_uint (node, "remote_session_id",
12003                             clib_net_to_host_u32 (mp->remote_session_id));
12004   vat_json_object_add_string_copy (node, "l2_sublayer",
12005                                    mp->l2_sublayer_present ? (u8 *) "present"
12006                                    : (u8 *) "absent");
12007 }
12008
12009 static int
12010 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12011 {
12012   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12013   vl_api_control_ping_t *mp_ping;
12014   int ret;
12015
12016   /* Get list of l2tpv3-tunnel interfaces */
12017   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12018   S (mp);
12019
12020   /* Use a control ping for synchronization */
12021   MPING (CONTROL_PING, mp_ping);
12022   S (mp_ping);
12023
12024   W (ret);
12025   return ret;
12026 }
12027
12028
12029 static void vl_api_sw_interface_tap_details_t_handler
12030   (vl_api_sw_interface_tap_details_t * mp)
12031 {
12032   vat_main_t *vam = &vat_main;
12033
12034   print (vam->ofp, "%-16s %d",
12035          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12036 }
12037
12038 static void vl_api_sw_interface_tap_details_t_handler_json
12039   (vl_api_sw_interface_tap_details_t * mp)
12040 {
12041   vat_main_t *vam = &vat_main;
12042   vat_json_node_t *node = NULL;
12043
12044   if (VAT_JSON_ARRAY != vam->json_tree.type)
12045     {
12046       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12047       vat_json_init_array (&vam->json_tree);
12048     }
12049   node = vat_json_array_add (&vam->json_tree);
12050
12051   vat_json_init_object (node);
12052   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12053   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12054 }
12055
12056 static int
12057 api_sw_interface_tap_dump (vat_main_t * vam)
12058 {
12059   vl_api_sw_interface_tap_dump_t *mp;
12060   vl_api_control_ping_t *mp_ping;
12061   int ret;
12062
12063   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12064   /* Get list of tap interfaces */
12065   M (SW_INTERFACE_TAP_DUMP, mp);
12066   S (mp);
12067
12068   /* Use a control ping for synchronization */
12069   MPING (CONTROL_PING, mp_ping);
12070   S (mp_ping);
12071
12072   W (ret);
12073   return ret;
12074 }
12075
12076 static uword unformat_vxlan_decap_next
12077   (unformat_input_t * input, va_list * args)
12078 {
12079   u32 *result = va_arg (*args, u32 *);
12080   u32 tmp;
12081
12082   if (unformat (input, "l2"))
12083     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12084   else if (unformat (input, "%d", &tmp))
12085     *result = tmp;
12086   else
12087     return 0;
12088   return 1;
12089 }
12090
12091 static int
12092 api_vxlan_add_del_tunnel (vat_main_t * vam)
12093 {
12094   unformat_input_t *line_input = vam->input;
12095   vl_api_vxlan_add_del_tunnel_t *mp;
12096   ip46_address_t src, dst;
12097   u8 is_add = 1;
12098   u8 ipv4_set = 0, ipv6_set = 0;
12099   u8 src_set = 0;
12100   u8 dst_set = 0;
12101   u8 grp_set = 0;
12102   u32 mcast_sw_if_index = ~0;
12103   u32 encap_vrf_id = 0;
12104   u32 decap_next_index = ~0;
12105   u32 vni = 0;
12106   int ret;
12107
12108   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12109   memset (&src, 0, sizeof src);
12110   memset (&dst, 0, sizeof dst);
12111
12112   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12113     {
12114       if (unformat (line_input, "del"))
12115         is_add = 0;
12116       else
12117         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12118         {
12119           ipv4_set = 1;
12120           src_set = 1;
12121         }
12122       else
12123         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12124         {
12125           ipv4_set = 1;
12126           dst_set = 1;
12127         }
12128       else
12129         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12130         {
12131           ipv6_set = 1;
12132           src_set = 1;
12133         }
12134       else
12135         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12136         {
12137           ipv6_set = 1;
12138           dst_set = 1;
12139         }
12140       else if (unformat (line_input, "group %U %U",
12141                          unformat_ip4_address, &dst.ip4,
12142                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12143         {
12144           grp_set = dst_set = 1;
12145           ipv4_set = 1;
12146         }
12147       else if (unformat (line_input, "group %U",
12148                          unformat_ip4_address, &dst.ip4))
12149         {
12150           grp_set = dst_set = 1;
12151           ipv4_set = 1;
12152         }
12153       else if (unformat (line_input, "group %U %U",
12154                          unformat_ip6_address, &dst.ip6,
12155                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12156         {
12157           grp_set = dst_set = 1;
12158           ipv6_set = 1;
12159         }
12160       else if (unformat (line_input, "group %U",
12161                          unformat_ip6_address, &dst.ip6))
12162         {
12163           grp_set = dst_set = 1;
12164           ipv6_set = 1;
12165         }
12166       else
12167         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12168         ;
12169       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12170         ;
12171       else if (unformat (line_input, "decap-next %U",
12172                          unformat_vxlan_decap_next, &decap_next_index))
12173         ;
12174       else if (unformat (line_input, "vni %d", &vni))
12175         ;
12176       else
12177         {
12178           errmsg ("parse error '%U'", format_unformat_error, line_input);
12179           return -99;
12180         }
12181     }
12182
12183   if (src_set == 0)
12184     {
12185       errmsg ("tunnel src address not specified");
12186       return -99;
12187     }
12188   if (dst_set == 0)
12189     {
12190       errmsg ("tunnel dst address not specified");
12191       return -99;
12192     }
12193
12194   if (grp_set && !ip46_address_is_multicast (&dst))
12195     {
12196       errmsg ("tunnel group address not multicast");
12197       return -99;
12198     }
12199   if (grp_set && mcast_sw_if_index == ~0)
12200     {
12201       errmsg ("tunnel nonexistent multicast device");
12202       return -99;
12203     }
12204   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12205     {
12206       errmsg ("tunnel dst address must be unicast");
12207       return -99;
12208     }
12209
12210
12211   if (ipv4_set && ipv6_set)
12212     {
12213       errmsg ("both IPv4 and IPv6 addresses specified");
12214       return -99;
12215     }
12216
12217   if ((vni == 0) || (vni >> 24))
12218     {
12219       errmsg ("vni not specified or out of range");
12220       return -99;
12221     }
12222
12223   M (VXLAN_ADD_DEL_TUNNEL, mp);
12224
12225   if (ipv6_set)
12226     {
12227       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12228       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12229     }
12230   else
12231     {
12232       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12233       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12234     }
12235   mp->encap_vrf_id = ntohl (encap_vrf_id);
12236   mp->decap_next_index = ntohl (decap_next_index);
12237   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12238   mp->vni = ntohl (vni);
12239   mp->is_add = is_add;
12240   mp->is_ipv6 = ipv6_set;
12241
12242   S (mp);
12243   W (ret);
12244   return ret;
12245 }
12246
12247 static void vl_api_vxlan_tunnel_details_t_handler
12248   (vl_api_vxlan_tunnel_details_t * mp)
12249 {
12250   vat_main_t *vam = &vat_main;
12251   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12252   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12253
12254   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12255          ntohl (mp->sw_if_index),
12256          format_ip46_address, &src, IP46_TYPE_ANY,
12257          format_ip46_address, &dst, IP46_TYPE_ANY,
12258          ntohl (mp->encap_vrf_id),
12259          ntohl (mp->decap_next_index), ntohl (mp->vni),
12260          ntohl (mp->mcast_sw_if_index));
12261 }
12262
12263 static void vl_api_vxlan_tunnel_details_t_handler_json
12264   (vl_api_vxlan_tunnel_details_t * mp)
12265 {
12266   vat_main_t *vam = &vat_main;
12267   vat_json_node_t *node = NULL;
12268
12269   if (VAT_JSON_ARRAY != vam->json_tree.type)
12270     {
12271       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12272       vat_json_init_array (&vam->json_tree);
12273     }
12274   node = vat_json_array_add (&vam->json_tree);
12275
12276   vat_json_init_object (node);
12277   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12278   if (mp->is_ipv6)
12279     {
12280       struct in6_addr ip6;
12281
12282       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12283       vat_json_object_add_ip6 (node, "src_address", ip6);
12284       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12285       vat_json_object_add_ip6 (node, "dst_address", ip6);
12286     }
12287   else
12288     {
12289       struct in_addr ip4;
12290
12291       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12292       vat_json_object_add_ip4 (node, "src_address", ip4);
12293       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12294       vat_json_object_add_ip4 (node, "dst_address", ip4);
12295     }
12296   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12297   vat_json_object_add_uint (node, "decap_next_index",
12298                             ntohl (mp->decap_next_index));
12299   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12300   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12301   vat_json_object_add_uint (node, "mcast_sw_if_index",
12302                             ntohl (mp->mcast_sw_if_index));
12303 }
12304
12305 static int
12306 api_vxlan_tunnel_dump (vat_main_t * vam)
12307 {
12308   unformat_input_t *i = vam->input;
12309   vl_api_vxlan_tunnel_dump_t *mp;
12310   vl_api_control_ping_t *mp_ping;
12311   u32 sw_if_index;
12312   u8 sw_if_index_set = 0;
12313   int ret;
12314
12315   /* Parse args required to build the message */
12316   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12317     {
12318       if (unformat (i, "sw_if_index %d", &sw_if_index))
12319         sw_if_index_set = 1;
12320       else
12321         break;
12322     }
12323
12324   if (sw_if_index_set == 0)
12325     {
12326       sw_if_index = ~0;
12327     }
12328
12329   if (!vam->json_output)
12330     {
12331       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12332              "sw_if_index", "src_address", "dst_address",
12333              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12334     }
12335
12336   /* Get list of vxlan-tunnel interfaces */
12337   M (VXLAN_TUNNEL_DUMP, mp);
12338
12339   mp->sw_if_index = htonl (sw_if_index);
12340
12341   S (mp);
12342
12343   /* Use a control ping for synchronization */
12344   MPING (CONTROL_PING, mp_ping);
12345   S (mp_ping);
12346
12347   W (ret);
12348   return ret;
12349 }
12350
12351 static uword unformat_geneve_decap_next
12352   (unformat_input_t * input, va_list * args)
12353 {
12354   u32 *result = va_arg (*args, u32 *);
12355   u32 tmp;
12356
12357   if (unformat (input, "l2"))
12358     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12359   else if (unformat (input, "%d", &tmp))
12360     *result = tmp;
12361   else
12362     return 0;
12363   return 1;
12364 }
12365
12366 static int
12367 api_geneve_add_del_tunnel (vat_main_t * vam)
12368 {
12369   unformat_input_t *line_input = vam->input;
12370   vl_api_geneve_add_del_tunnel_t *mp;
12371   ip46_address_t src, dst;
12372   u8 is_add = 1;
12373   u8 ipv4_set = 0, ipv6_set = 0;
12374   u8 src_set = 0;
12375   u8 dst_set = 0;
12376   u8 grp_set = 0;
12377   u32 mcast_sw_if_index = ~0;
12378   u32 encap_vrf_id = 0;
12379   u32 decap_next_index = ~0;
12380   u32 vni = 0;
12381   int ret;
12382
12383   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12384   memset (&src, 0, sizeof src);
12385   memset (&dst, 0, sizeof dst);
12386
12387   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12388     {
12389       if (unformat (line_input, "del"))
12390         is_add = 0;
12391       else
12392         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12393         {
12394           ipv4_set = 1;
12395           src_set = 1;
12396         }
12397       else
12398         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12399         {
12400           ipv4_set = 1;
12401           dst_set = 1;
12402         }
12403       else
12404         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12405         {
12406           ipv6_set = 1;
12407           src_set = 1;
12408         }
12409       else
12410         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12411         {
12412           ipv6_set = 1;
12413           dst_set = 1;
12414         }
12415       else if (unformat (line_input, "group %U %U",
12416                          unformat_ip4_address, &dst.ip4,
12417                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12418         {
12419           grp_set = dst_set = 1;
12420           ipv4_set = 1;
12421         }
12422       else if (unformat (line_input, "group %U",
12423                          unformat_ip4_address, &dst.ip4))
12424         {
12425           grp_set = dst_set = 1;
12426           ipv4_set = 1;
12427         }
12428       else if (unformat (line_input, "group %U %U",
12429                          unformat_ip6_address, &dst.ip6,
12430                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12431         {
12432           grp_set = dst_set = 1;
12433           ipv6_set = 1;
12434         }
12435       else if (unformat (line_input, "group %U",
12436                          unformat_ip6_address, &dst.ip6))
12437         {
12438           grp_set = dst_set = 1;
12439           ipv6_set = 1;
12440         }
12441       else
12442         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12443         ;
12444       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12445         ;
12446       else if (unformat (line_input, "decap-next %U",
12447                          unformat_geneve_decap_next, &decap_next_index))
12448         ;
12449       else if (unformat (line_input, "vni %d", &vni))
12450         ;
12451       else
12452         {
12453           errmsg ("parse error '%U'", format_unformat_error, line_input);
12454           return -99;
12455         }
12456     }
12457
12458   if (src_set == 0)
12459     {
12460       errmsg ("tunnel src address not specified");
12461       return -99;
12462     }
12463   if (dst_set == 0)
12464     {
12465       errmsg ("tunnel dst address not specified");
12466       return -99;
12467     }
12468
12469   if (grp_set && !ip46_address_is_multicast (&dst))
12470     {
12471       errmsg ("tunnel group address not multicast");
12472       return -99;
12473     }
12474   if (grp_set && mcast_sw_if_index == ~0)
12475     {
12476       errmsg ("tunnel nonexistent multicast device");
12477       return -99;
12478     }
12479   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12480     {
12481       errmsg ("tunnel dst address must be unicast");
12482       return -99;
12483     }
12484
12485
12486   if (ipv4_set && ipv6_set)
12487     {
12488       errmsg ("both IPv4 and IPv6 addresses specified");
12489       return -99;
12490     }
12491
12492   if ((vni == 0) || (vni >> 24))
12493     {
12494       errmsg ("vni not specified or out of range");
12495       return -99;
12496     }
12497
12498   M (GENEVE_ADD_DEL_TUNNEL, mp);
12499
12500   if (ipv6_set)
12501     {
12502       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12503       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12504     }
12505   else
12506     {
12507       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12508       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12509     }
12510   mp->encap_vrf_id = ntohl (encap_vrf_id);
12511   mp->decap_next_index = ntohl (decap_next_index);
12512   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12513   mp->vni = ntohl (vni);
12514   mp->is_add = is_add;
12515   mp->is_ipv6 = ipv6_set;
12516
12517   S (mp);
12518   W (ret);
12519   return ret;
12520 }
12521
12522 static void vl_api_geneve_tunnel_details_t_handler
12523   (vl_api_geneve_tunnel_details_t * mp)
12524 {
12525   vat_main_t *vam = &vat_main;
12526   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12527   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12528
12529   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12530          ntohl (mp->sw_if_index),
12531          format_ip46_address, &src, IP46_TYPE_ANY,
12532          format_ip46_address, &dst, IP46_TYPE_ANY,
12533          ntohl (mp->encap_vrf_id),
12534          ntohl (mp->decap_next_index), ntohl (mp->vni),
12535          ntohl (mp->mcast_sw_if_index));
12536 }
12537
12538 static void vl_api_geneve_tunnel_details_t_handler_json
12539   (vl_api_geneve_tunnel_details_t * mp)
12540 {
12541   vat_main_t *vam = &vat_main;
12542   vat_json_node_t *node = NULL;
12543
12544   if (VAT_JSON_ARRAY != vam->json_tree.type)
12545     {
12546       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12547       vat_json_init_array (&vam->json_tree);
12548     }
12549   node = vat_json_array_add (&vam->json_tree);
12550
12551   vat_json_init_object (node);
12552   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12553   if (mp->is_ipv6)
12554     {
12555       struct in6_addr ip6;
12556
12557       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12558       vat_json_object_add_ip6 (node, "src_address", ip6);
12559       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12560       vat_json_object_add_ip6 (node, "dst_address", ip6);
12561     }
12562   else
12563     {
12564       struct in_addr ip4;
12565
12566       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12567       vat_json_object_add_ip4 (node, "src_address", ip4);
12568       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12569       vat_json_object_add_ip4 (node, "dst_address", ip4);
12570     }
12571   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12572   vat_json_object_add_uint (node, "decap_next_index",
12573                             ntohl (mp->decap_next_index));
12574   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12575   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12576   vat_json_object_add_uint (node, "mcast_sw_if_index",
12577                             ntohl (mp->mcast_sw_if_index));
12578 }
12579
12580 static int
12581 api_geneve_tunnel_dump (vat_main_t * vam)
12582 {
12583   unformat_input_t *i = vam->input;
12584   vl_api_geneve_tunnel_dump_t *mp;
12585   vl_api_control_ping_t *mp_ping;
12586   u32 sw_if_index;
12587   u8 sw_if_index_set = 0;
12588   int ret;
12589
12590   /* Parse args required to build the message */
12591   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12592     {
12593       if (unformat (i, "sw_if_index %d", &sw_if_index))
12594         sw_if_index_set = 1;
12595       else
12596         break;
12597     }
12598
12599   if (sw_if_index_set == 0)
12600     {
12601       sw_if_index = ~0;
12602     }
12603
12604   if (!vam->json_output)
12605     {
12606       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12607              "sw_if_index", "local_address", "remote_address",
12608              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12609     }
12610
12611   /* Get list of geneve-tunnel interfaces */
12612   M (GENEVE_TUNNEL_DUMP, mp);
12613
12614   mp->sw_if_index = htonl (sw_if_index);
12615
12616   S (mp);
12617
12618   /* Use a control ping for synchronization */
12619   M (CONTROL_PING, mp_ping);
12620   S (mp_ping);
12621
12622   W (ret);
12623   return ret;
12624 }
12625
12626 static int
12627 api_gre_add_del_tunnel (vat_main_t * vam)
12628 {
12629   unformat_input_t *line_input = vam->input;
12630   vl_api_gre_add_del_tunnel_t *mp;
12631   ip4_address_t src4, dst4;
12632   ip6_address_t src6, dst6;
12633   u8 is_add = 1;
12634   u8 ipv4_set = 0;
12635   u8 ipv6_set = 0;
12636   u8 teb = 0;
12637   u8 src_set = 0;
12638   u8 dst_set = 0;
12639   u32 outer_fib_id = 0;
12640   int ret;
12641
12642   memset (&src4, 0, sizeof src4);
12643   memset (&dst4, 0, sizeof dst4);
12644   memset (&src6, 0, sizeof src6);
12645   memset (&dst6, 0, sizeof dst6);
12646
12647   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12648     {
12649       if (unformat (line_input, "del"))
12650         is_add = 0;
12651       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
12652         {
12653           src_set = 1;
12654           ipv4_set = 1;
12655         }
12656       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
12657         {
12658           dst_set = 1;
12659           ipv4_set = 1;
12660         }
12661       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
12662         {
12663           src_set = 1;
12664           ipv6_set = 1;
12665         }
12666       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
12667         {
12668           dst_set = 1;
12669           ipv6_set = 1;
12670         }
12671       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
12672         ;
12673       else if (unformat (line_input, "teb"))
12674         teb = 1;
12675       else
12676         {
12677           errmsg ("parse error '%U'", format_unformat_error, line_input);
12678           return -99;
12679         }
12680     }
12681
12682   if (src_set == 0)
12683     {
12684       errmsg ("tunnel src address not specified");
12685       return -99;
12686     }
12687   if (dst_set == 0)
12688     {
12689       errmsg ("tunnel dst address not specified");
12690       return -99;
12691     }
12692   if (ipv4_set && ipv6_set)
12693     {
12694       errmsg ("both IPv4 and IPv6 addresses specified");
12695       return -99;
12696     }
12697
12698
12699   M (GRE_ADD_DEL_TUNNEL, mp);
12700
12701   if (ipv4_set)
12702     {
12703       clib_memcpy (&mp->src_address, &src4, 4);
12704       clib_memcpy (&mp->dst_address, &dst4, 4);
12705     }
12706   else
12707     {
12708       clib_memcpy (&mp->src_address, &src6, 16);
12709       clib_memcpy (&mp->dst_address, &dst6, 16);
12710     }
12711   mp->outer_fib_id = ntohl (outer_fib_id);
12712   mp->is_add = is_add;
12713   mp->teb = teb;
12714   mp->is_ipv6 = ipv6_set;
12715
12716   S (mp);
12717   W (ret);
12718   return ret;
12719 }
12720
12721 static void vl_api_gre_tunnel_details_t_handler
12722   (vl_api_gre_tunnel_details_t * mp)
12723 {
12724   vat_main_t *vam = &vat_main;
12725   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
12726   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
12727
12728   print (vam->ofp, "%11d%24U%24U%6d%14d",
12729          ntohl (mp->sw_if_index),
12730          format_ip46_address, &src, IP46_TYPE_ANY,
12731          format_ip46_address, &dst, IP46_TYPE_ANY,
12732          mp->teb, ntohl (mp->outer_fib_id));
12733 }
12734
12735 static void vl_api_gre_tunnel_details_t_handler_json
12736   (vl_api_gre_tunnel_details_t * mp)
12737 {
12738   vat_main_t *vam = &vat_main;
12739   vat_json_node_t *node = NULL;
12740   struct in_addr ip4;
12741   struct in6_addr ip6;
12742
12743   if (VAT_JSON_ARRAY != vam->json_tree.type)
12744     {
12745       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12746       vat_json_init_array (&vam->json_tree);
12747     }
12748   node = vat_json_array_add (&vam->json_tree);
12749
12750   vat_json_init_object (node);
12751   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12752   if (!mp->is_ipv6)
12753     {
12754       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
12755       vat_json_object_add_ip4 (node, "src_address", ip4);
12756       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
12757       vat_json_object_add_ip4 (node, "dst_address", ip4);
12758     }
12759   else
12760     {
12761       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
12762       vat_json_object_add_ip6 (node, "src_address", ip6);
12763       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
12764       vat_json_object_add_ip6 (node, "dst_address", ip6);
12765     }
12766   vat_json_object_add_uint (node, "teb", mp->teb);
12767   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
12768   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
12769 }
12770
12771 static int
12772 api_gre_tunnel_dump (vat_main_t * vam)
12773 {
12774   unformat_input_t *i = vam->input;
12775   vl_api_gre_tunnel_dump_t *mp;
12776   vl_api_control_ping_t *mp_ping;
12777   u32 sw_if_index;
12778   u8 sw_if_index_set = 0;
12779   int ret;
12780
12781   /* Parse args required to build the message */
12782   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12783     {
12784       if (unformat (i, "sw_if_index %d", &sw_if_index))
12785         sw_if_index_set = 1;
12786       else
12787         break;
12788     }
12789
12790   if (sw_if_index_set == 0)
12791     {
12792       sw_if_index = ~0;
12793     }
12794
12795   if (!vam->json_output)
12796     {
12797       print (vam->ofp, "%11s%24s%24s%6s%14s",
12798              "sw_if_index", "src_address", "dst_address", "teb",
12799              "outer_fib_id");
12800     }
12801
12802   /* Get list of gre-tunnel interfaces */
12803   M (GRE_TUNNEL_DUMP, mp);
12804
12805   mp->sw_if_index = htonl (sw_if_index);
12806
12807   S (mp);
12808
12809   /* Use a control ping for synchronization */
12810   MPING (CONTROL_PING, mp_ping);
12811   S (mp_ping);
12812
12813   W (ret);
12814   return ret;
12815 }
12816
12817 static int
12818 api_l2_fib_clear_table (vat_main_t * vam)
12819 {
12820 //  unformat_input_t * i = vam->input;
12821   vl_api_l2_fib_clear_table_t *mp;
12822   int ret;
12823
12824   M (L2_FIB_CLEAR_TABLE, mp);
12825
12826   S (mp);
12827   W (ret);
12828   return ret;
12829 }
12830
12831 static int
12832 api_l2_interface_efp_filter (vat_main_t * vam)
12833 {
12834   unformat_input_t *i = vam->input;
12835   vl_api_l2_interface_efp_filter_t *mp;
12836   u32 sw_if_index;
12837   u8 enable = 1;
12838   u8 sw_if_index_set = 0;
12839   int ret;
12840
12841   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12842     {
12843       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12844         sw_if_index_set = 1;
12845       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12846         sw_if_index_set = 1;
12847       else if (unformat (i, "enable"))
12848         enable = 1;
12849       else if (unformat (i, "disable"))
12850         enable = 0;
12851       else
12852         {
12853           clib_warning ("parse error '%U'", format_unformat_error, i);
12854           return -99;
12855         }
12856     }
12857
12858   if (sw_if_index_set == 0)
12859     {
12860       errmsg ("missing sw_if_index");
12861       return -99;
12862     }
12863
12864   M (L2_INTERFACE_EFP_FILTER, mp);
12865
12866   mp->sw_if_index = ntohl (sw_if_index);
12867   mp->enable_disable = enable;
12868
12869   S (mp);
12870   W (ret);
12871   return ret;
12872 }
12873
12874 #define foreach_vtr_op                          \
12875 _("disable",  L2_VTR_DISABLED)                  \
12876 _("push-1",  L2_VTR_PUSH_1)                     \
12877 _("push-2",  L2_VTR_PUSH_2)                     \
12878 _("pop-1",  L2_VTR_POP_1)                       \
12879 _("pop-2",  L2_VTR_POP_2)                       \
12880 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12881 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12882 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12883 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12884
12885 static int
12886 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12887 {
12888   unformat_input_t *i = vam->input;
12889   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12890   u32 sw_if_index;
12891   u8 sw_if_index_set = 0;
12892   u8 vtr_op_set = 0;
12893   u32 vtr_op = 0;
12894   u32 push_dot1q = 1;
12895   u32 tag1 = ~0;
12896   u32 tag2 = ~0;
12897   int ret;
12898
12899   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12900     {
12901       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12902         sw_if_index_set = 1;
12903       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12904         sw_if_index_set = 1;
12905       else if (unformat (i, "vtr_op %d", &vtr_op))
12906         vtr_op_set = 1;
12907 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12908       foreach_vtr_op
12909 #undef _
12910         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12911         ;
12912       else if (unformat (i, "tag1 %d", &tag1))
12913         ;
12914       else if (unformat (i, "tag2 %d", &tag2))
12915         ;
12916       else
12917         {
12918           clib_warning ("parse error '%U'", format_unformat_error, i);
12919           return -99;
12920         }
12921     }
12922
12923   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12924     {
12925       errmsg ("missing vtr operation or sw_if_index");
12926       return -99;
12927     }
12928
12929   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12930   mp->sw_if_index = ntohl (sw_if_index);
12931   mp->vtr_op = ntohl (vtr_op);
12932   mp->push_dot1q = ntohl (push_dot1q);
12933   mp->tag1 = ntohl (tag1);
12934   mp->tag2 = ntohl (tag2);
12935
12936   S (mp);
12937   W (ret);
12938   return ret;
12939 }
12940
12941 static int
12942 api_create_vhost_user_if (vat_main_t * vam)
12943 {
12944   unformat_input_t *i = vam->input;
12945   vl_api_create_vhost_user_if_t *mp;
12946   u8 *file_name;
12947   u8 is_server = 0;
12948   u8 file_name_set = 0;
12949   u32 custom_dev_instance = ~0;
12950   u8 hwaddr[6];
12951   u8 use_custom_mac = 0;
12952   u8 *tag = 0;
12953   int ret;
12954
12955   /* Shut up coverity */
12956   memset (hwaddr, 0, sizeof (hwaddr));
12957
12958   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12959     {
12960       if (unformat (i, "socket %s", &file_name))
12961         {
12962           file_name_set = 1;
12963         }
12964       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12965         ;
12966       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12967         use_custom_mac = 1;
12968       else if (unformat (i, "server"))
12969         is_server = 1;
12970       else if (unformat (i, "tag %s", &tag))
12971         ;
12972       else
12973         break;
12974     }
12975
12976   if (file_name_set == 0)
12977     {
12978       errmsg ("missing socket file name");
12979       return -99;
12980     }
12981
12982   if (vec_len (file_name) > 255)
12983     {
12984       errmsg ("socket file name too long");
12985       return -99;
12986     }
12987   vec_add1 (file_name, 0);
12988
12989   M (CREATE_VHOST_USER_IF, mp);
12990
12991   mp->is_server = is_server;
12992   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12993   vec_free (file_name);
12994   if (custom_dev_instance != ~0)
12995     {
12996       mp->renumber = 1;
12997       mp->custom_dev_instance = ntohl (custom_dev_instance);
12998     }
12999   mp->use_custom_mac = use_custom_mac;
13000   clib_memcpy (mp->mac_address, hwaddr, 6);
13001   if (tag)
13002     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13003   vec_free (tag);
13004
13005   S (mp);
13006   W (ret);
13007   return ret;
13008 }
13009
13010 static int
13011 api_modify_vhost_user_if (vat_main_t * vam)
13012 {
13013   unformat_input_t *i = vam->input;
13014   vl_api_modify_vhost_user_if_t *mp;
13015   u8 *file_name;
13016   u8 is_server = 0;
13017   u8 file_name_set = 0;
13018   u32 custom_dev_instance = ~0;
13019   u8 sw_if_index_set = 0;
13020   u32 sw_if_index = (u32) ~ 0;
13021   int ret;
13022
13023   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13024     {
13025       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13026         sw_if_index_set = 1;
13027       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13028         sw_if_index_set = 1;
13029       else if (unformat (i, "socket %s", &file_name))
13030         {
13031           file_name_set = 1;
13032         }
13033       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13034         ;
13035       else if (unformat (i, "server"))
13036         is_server = 1;
13037       else
13038         break;
13039     }
13040
13041   if (sw_if_index_set == 0)
13042     {
13043       errmsg ("missing sw_if_index or interface name");
13044       return -99;
13045     }
13046
13047   if (file_name_set == 0)
13048     {
13049       errmsg ("missing socket file name");
13050       return -99;
13051     }
13052
13053   if (vec_len (file_name) > 255)
13054     {
13055       errmsg ("socket file name too long");
13056       return -99;
13057     }
13058   vec_add1 (file_name, 0);
13059
13060   M (MODIFY_VHOST_USER_IF, mp);
13061
13062   mp->sw_if_index = ntohl (sw_if_index);
13063   mp->is_server = is_server;
13064   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13065   vec_free (file_name);
13066   if (custom_dev_instance != ~0)
13067     {
13068       mp->renumber = 1;
13069       mp->custom_dev_instance = ntohl (custom_dev_instance);
13070     }
13071
13072   S (mp);
13073   W (ret);
13074   return ret;
13075 }
13076
13077 static int
13078 api_delete_vhost_user_if (vat_main_t * vam)
13079 {
13080   unformat_input_t *i = vam->input;
13081   vl_api_delete_vhost_user_if_t *mp;
13082   u32 sw_if_index = ~0;
13083   u8 sw_if_index_set = 0;
13084   int ret;
13085
13086   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13087     {
13088       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13089         sw_if_index_set = 1;
13090       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13091         sw_if_index_set = 1;
13092       else
13093         break;
13094     }
13095
13096   if (sw_if_index_set == 0)
13097     {
13098       errmsg ("missing sw_if_index or interface name");
13099       return -99;
13100     }
13101
13102
13103   M (DELETE_VHOST_USER_IF, mp);
13104
13105   mp->sw_if_index = ntohl (sw_if_index);
13106
13107   S (mp);
13108   W (ret);
13109   return ret;
13110 }
13111
13112 static void vl_api_sw_interface_vhost_user_details_t_handler
13113   (vl_api_sw_interface_vhost_user_details_t * mp)
13114 {
13115   vat_main_t *vam = &vat_main;
13116
13117   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13118          (char *) mp->interface_name,
13119          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13120          clib_net_to_host_u64 (mp->features), mp->is_server,
13121          ntohl (mp->num_regions), (char *) mp->sock_filename);
13122   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13123 }
13124
13125 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13126   (vl_api_sw_interface_vhost_user_details_t * mp)
13127 {
13128   vat_main_t *vam = &vat_main;
13129   vat_json_node_t *node = NULL;
13130
13131   if (VAT_JSON_ARRAY != vam->json_tree.type)
13132     {
13133       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13134       vat_json_init_array (&vam->json_tree);
13135     }
13136   node = vat_json_array_add (&vam->json_tree);
13137
13138   vat_json_init_object (node);
13139   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13140   vat_json_object_add_string_copy (node, "interface_name",
13141                                    mp->interface_name);
13142   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13143                             ntohl (mp->virtio_net_hdr_sz));
13144   vat_json_object_add_uint (node, "features",
13145                             clib_net_to_host_u64 (mp->features));
13146   vat_json_object_add_uint (node, "is_server", mp->is_server);
13147   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13148   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13149   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13150 }
13151
13152 static int
13153 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13154 {
13155   vl_api_sw_interface_vhost_user_dump_t *mp;
13156   vl_api_control_ping_t *mp_ping;
13157   int ret;
13158   print (vam->ofp,
13159          "Interface name            idx hdr_sz features server regions filename");
13160
13161   /* Get list of vhost-user interfaces */
13162   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13163   S (mp);
13164
13165   /* Use a control ping for synchronization */
13166   MPING (CONTROL_PING, mp_ping);
13167   S (mp_ping);
13168
13169   W (ret);
13170   return ret;
13171 }
13172
13173 static int
13174 api_show_version (vat_main_t * vam)
13175 {
13176   vl_api_show_version_t *mp;
13177   int ret;
13178
13179   M (SHOW_VERSION, mp);
13180
13181   S (mp);
13182   W (ret);
13183   return ret;
13184 }
13185
13186
13187 static int
13188 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13189 {
13190   unformat_input_t *line_input = vam->input;
13191   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13192   ip4_address_t local4, remote4;
13193   ip6_address_t local6, remote6;
13194   u8 is_add = 1;
13195   u8 ipv4_set = 0, ipv6_set = 0;
13196   u8 local_set = 0;
13197   u8 remote_set = 0;
13198   u8 grp_set = 0;
13199   u32 mcast_sw_if_index = ~0;
13200   u32 encap_vrf_id = 0;
13201   u32 decap_vrf_id = 0;
13202   u8 protocol = ~0;
13203   u32 vni;
13204   u8 vni_set = 0;
13205   int ret;
13206
13207   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13208   memset (&local4, 0, sizeof local4);
13209   memset (&remote4, 0, sizeof remote4);
13210   memset (&local6, 0, sizeof local6);
13211   memset (&remote6, 0, sizeof remote6);
13212
13213   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13214     {
13215       if (unformat (line_input, "del"))
13216         is_add = 0;
13217       else if (unformat (line_input, "local %U",
13218                          unformat_ip4_address, &local4))
13219         {
13220           local_set = 1;
13221           ipv4_set = 1;
13222         }
13223       else if (unformat (line_input, "remote %U",
13224                          unformat_ip4_address, &remote4))
13225         {
13226           remote_set = 1;
13227           ipv4_set = 1;
13228         }
13229       else if (unformat (line_input, "local %U",
13230                          unformat_ip6_address, &local6))
13231         {
13232           local_set = 1;
13233           ipv6_set = 1;
13234         }
13235       else if (unformat (line_input, "remote %U",
13236                          unformat_ip6_address, &remote6))
13237         {
13238           remote_set = 1;
13239           ipv6_set = 1;
13240         }
13241       else if (unformat (line_input, "group %U %U",
13242                          unformat_ip4_address, &remote4,
13243                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13244         {
13245           grp_set = remote_set = 1;
13246           ipv4_set = 1;
13247         }
13248       else if (unformat (line_input, "group %U",
13249                          unformat_ip4_address, &remote4))
13250         {
13251           grp_set = remote_set = 1;
13252           ipv4_set = 1;
13253         }
13254       else if (unformat (line_input, "group %U %U",
13255                          unformat_ip6_address, &remote6,
13256                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13257         {
13258           grp_set = remote_set = 1;
13259           ipv6_set = 1;
13260         }
13261       else if (unformat (line_input, "group %U",
13262                          unformat_ip6_address, &remote6))
13263         {
13264           grp_set = remote_set = 1;
13265           ipv6_set = 1;
13266         }
13267       else
13268         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13269         ;
13270       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13271         ;
13272       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13273         ;
13274       else if (unformat (line_input, "vni %d", &vni))
13275         vni_set = 1;
13276       else if (unformat (line_input, "next-ip4"))
13277         protocol = 1;
13278       else if (unformat (line_input, "next-ip6"))
13279         protocol = 2;
13280       else if (unformat (line_input, "next-ethernet"))
13281         protocol = 3;
13282       else if (unformat (line_input, "next-nsh"))
13283         protocol = 4;
13284       else
13285         {
13286           errmsg ("parse error '%U'", format_unformat_error, line_input);
13287           return -99;
13288         }
13289     }
13290
13291   if (local_set == 0)
13292     {
13293       errmsg ("tunnel local address not specified");
13294       return -99;
13295     }
13296   if (remote_set == 0)
13297     {
13298       errmsg ("tunnel remote address not specified");
13299       return -99;
13300     }
13301   if (grp_set && mcast_sw_if_index == ~0)
13302     {
13303       errmsg ("tunnel nonexistent multicast device");
13304       return -99;
13305     }
13306   if (ipv4_set && ipv6_set)
13307     {
13308       errmsg ("both IPv4 and IPv6 addresses specified");
13309       return -99;
13310     }
13311
13312   if (vni_set == 0)
13313     {
13314       errmsg ("vni not specified");
13315       return -99;
13316     }
13317
13318   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13319
13320
13321   if (ipv6_set)
13322     {
13323       clib_memcpy (&mp->local, &local6, sizeof (local6));
13324       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13325     }
13326   else
13327     {
13328       clib_memcpy (&mp->local, &local4, sizeof (local4));
13329       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13330     }
13331
13332   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13333   mp->encap_vrf_id = ntohl (encap_vrf_id);
13334   mp->decap_vrf_id = ntohl (decap_vrf_id);
13335   mp->protocol = protocol;
13336   mp->vni = ntohl (vni);
13337   mp->is_add = is_add;
13338   mp->is_ipv6 = ipv6_set;
13339
13340   S (mp);
13341   W (ret);
13342   return ret;
13343 }
13344
13345 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13346   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13347 {
13348   vat_main_t *vam = &vat_main;
13349   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13350   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13351
13352   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13353          ntohl (mp->sw_if_index),
13354          format_ip46_address, &local, IP46_TYPE_ANY,
13355          format_ip46_address, &remote, IP46_TYPE_ANY,
13356          ntohl (mp->vni), mp->protocol,
13357          ntohl (mp->mcast_sw_if_index),
13358          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13359 }
13360
13361
13362 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13363   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13364 {
13365   vat_main_t *vam = &vat_main;
13366   vat_json_node_t *node = NULL;
13367   struct in_addr ip4;
13368   struct in6_addr ip6;
13369
13370   if (VAT_JSON_ARRAY != vam->json_tree.type)
13371     {
13372       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13373       vat_json_init_array (&vam->json_tree);
13374     }
13375   node = vat_json_array_add (&vam->json_tree);
13376
13377   vat_json_init_object (node);
13378   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13379   if (mp->is_ipv6)
13380     {
13381       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13382       vat_json_object_add_ip6 (node, "local", ip6);
13383       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13384       vat_json_object_add_ip6 (node, "remote", ip6);
13385     }
13386   else
13387     {
13388       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13389       vat_json_object_add_ip4 (node, "local", ip4);
13390       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13391       vat_json_object_add_ip4 (node, "remote", ip4);
13392     }
13393   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13394   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13395   vat_json_object_add_uint (node, "mcast_sw_if_index",
13396                             ntohl (mp->mcast_sw_if_index));
13397   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13398   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13399   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13400 }
13401
13402 static int
13403 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13404 {
13405   unformat_input_t *i = vam->input;
13406   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13407   vl_api_control_ping_t *mp_ping;
13408   u32 sw_if_index;
13409   u8 sw_if_index_set = 0;
13410   int ret;
13411
13412   /* Parse args required to build the message */
13413   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13414     {
13415       if (unformat (i, "sw_if_index %d", &sw_if_index))
13416         sw_if_index_set = 1;
13417       else
13418         break;
13419     }
13420
13421   if (sw_if_index_set == 0)
13422     {
13423       sw_if_index = ~0;
13424     }
13425
13426   if (!vam->json_output)
13427     {
13428       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13429              "sw_if_index", "local", "remote", "vni",
13430              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13431     }
13432
13433   /* Get list of vxlan-tunnel interfaces */
13434   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13435
13436   mp->sw_if_index = htonl (sw_if_index);
13437
13438   S (mp);
13439
13440   /* Use a control ping for synchronization */
13441   MPING (CONTROL_PING, mp_ping);
13442   S (mp_ping);
13443
13444   W (ret);
13445   return ret;
13446 }
13447
13448 static void vl_api_l2_fib_table_details_t_handler
13449   (vl_api_l2_fib_table_details_t * mp)
13450 {
13451   vat_main_t *vam = &vat_main;
13452
13453   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13454          "       %d       %d     %d",
13455          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13456          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13457          mp->bvi_mac);
13458 }
13459
13460 static void vl_api_l2_fib_table_details_t_handler_json
13461   (vl_api_l2_fib_table_details_t * mp)
13462 {
13463   vat_main_t *vam = &vat_main;
13464   vat_json_node_t *node = NULL;
13465
13466   if (VAT_JSON_ARRAY != vam->json_tree.type)
13467     {
13468       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13469       vat_json_init_array (&vam->json_tree);
13470     }
13471   node = vat_json_array_add (&vam->json_tree);
13472
13473   vat_json_init_object (node);
13474   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13475   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13476   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13477   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13478   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13479   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13480 }
13481
13482 static int
13483 api_l2_fib_table_dump (vat_main_t * vam)
13484 {
13485   unformat_input_t *i = vam->input;
13486   vl_api_l2_fib_table_dump_t *mp;
13487   vl_api_control_ping_t *mp_ping;
13488   u32 bd_id;
13489   u8 bd_id_set = 0;
13490   int ret;
13491
13492   /* Parse args required to build the message */
13493   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13494     {
13495       if (unformat (i, "bd_id %d", &bd_id))
13496         bd_id_set = 1;
13497       else
13498         break;
13499     }
13500
13501   if (bd_id_set == 0)
13502     {
13503       errmsg ("missing bridge domain");
13504       return -99;
13505     }
13506
13507   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13508
13509   /* Get list of l2 fib entries */
13510   M (L2_FIB_TABLE_DUMP, mp);
13511
13512   mp->bd_id = ntohl (bd_id);
13513   S (mp);
13514
13515   /* Use a control ping for synchronization */
13516   MPING (CONTROL_PING, mp_ping);
13517   S (mp_ping);
13518
13519   W (ret);
13520   return ret;
13521 }
13522
13523
13524 static int
13525 api_interface_name_renumber (vat_main_t * vam)
13526 {
13527   unformat_input_t *line_input = vam->input;
13528   vl_api_interface_name_renumber_t *mp;
13529   u32 sw_if_index = ~0;
13530   u32 new_show_dev_instance = ~0;
13531   int ret;
13532
13533   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13534     {
13535       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13536                     &sw_if_index))
13537         ;
13538       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13539         ;
13540       else if (unformat (line_input, "new_show_dev_instance %d",
13541                          &new_show_dev_instance))
13542         ;
13543       else
13544         break;
13545     }
13546
13547   if (sw_if_index == ~0)
13548     {
13549       errmsg ("missing interface name or sw_if_index");
13550       return -99;
13551     }
13552
13553   if (new_show_dev_instance == ~0)
13554     {
13555       errmsg ("missing new_show_dev_instance");
13556       return -99;
13557     }
13558
13559   M (INTERFACE_NAME_RENUMBER, mp);
13560
13561   mp->sw_if_index = ntohl (sw_if_index);
13562   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13563
13564   S (mp);
13565   W (ret);
13566   return ret;
13567 }
13568
13569 static int
13570 api_want_ip4_arp_events (vat_main_t * vam)
13571 {
13572   unformat_input_t *line_input = vam->input;
13573   vl_api_want_ip4_arp_events_t *mp;
13574   ip4_address_t address;
13575   int address_set = 0;
13576   u32 enable_disable = 1;
13577   int ret;
13578
13579   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13580     {
13581       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
13582         address_set = 1;
13583       else if (unformat (line_input, "del"))
13584         enable_disable = 0;
13585       else
13586         break;
13587     }
13588
13589   if (address_set == 0)
13590     {
13591       errmsg ("missing addresses");
13592       return -99;
13593     }
13594
13595   M (WANT_IP4_ARP_EVENTS, mp);
13596   mp->enable_disable = enable_disable;
13597   mp->pid = htonl (getpid ());
13598   mp->address = address.as_u32;
13599
13600   S (mp);
13601   W (ret);
13602   return ret;
13603 }
13604
13605 static int
13606 api_want_ip6_nd_events (vat_main_t * vam)
13607 {
13608   unformat_input_t *line_input = vam->input;
13609   vl_api_want_ip6_nd_events_t *mp;
13610   ip6_address_t address;
13611   int address_set = 0;
13612   u32 enable_disable = 1;
13613   int ret;
13614
13615   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13616     {
13617       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
13618         address_set = 1;
13619       else if (unformat (line_input, "del"))
13620         enable_disable = 0;
13621       else
13622         break;
13623     }
13624
13625   if (address_set == 0)
13626     {
13627       errmsg ("missing addresses");
13628       return -99;
13629     }
13630
13631   M (WANT_IP6_ND_EVENTS, mp);
13632   mp->enable_disable = enable_disable;
13633   mp->pid = htonl (getpid ());
13634   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
13635
13636   S (mp);
13637   W (ret);
13638   return ret;
13639 }
13640
13641 static int
13642 api_want_l2_macs_events (vat_main_t * vam)
13643 {
13644   unformat_input_t *line_input = vam->input;
13645   vl_api_want_l2_macs_events_t *mp;
13646   u8 enable_disable = 1;
13647   u32 scan_delay = 0;
13648   u32 max_macs_in_event = 0;
13649   u32 learn_limit = 0;
13650   int ret;
13651
13652   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13653     {
13654       if (unformat (line_input, "learn-limit %d", &learn_limit))
13655         ;
13656       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13657         ;
13658       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13659         ;
13660       else if (unformat (line_input, "disable"))
13661         enable_disable = 0;
13662       else
13663         break;
13664     }
13665
13666   M (WANT_L2_MACS_EVENTS, mp);
13667   mp->enable_disable = enable_disable;
13668   mp->pid = htonl (getpid ());
13669   mp->learn_limit = htonl (learn_limit);
13670   mp->scan_delay = (u8) scan_delay;
13671   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13672   S (mp);
13673   W (ret);
13674   return ret;
13675 }
13676
13677 static int
13678 api_input_acl_set_interface (vat_main_t * vam)
13679 {
13680   unformat_input_t *i = vam->input;
13681   vl_api_input_acl_set_interface_t *mp;
13682   u32 sw_if_index;
13683   int sw_if_index_set;
13684   u32 ip4_table_index = ~0;
13685   u32 ip6_table_index = ~0;
13686   u32 l2_table_index = ~0;
13687   u8 is_add = 1;
13688   int ret;
13689
13690   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13691     {
13692       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13693         sw_if_index_set = 1;
13694       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13695         sw_if_index_set = 1;
13696       else if (unformat (i, "del"))
13697         is_add = 0;
13698       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13699         ;
13700       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13701         ;
13702       else if (unformat (i, "l2-table %d", &l2_table_index))
13703         ;
13704       else
13705         {
13706           clib_warning ("parse error '%U'", format_unformat_error, i);
13707           return -99;
13708         }
13709     }
13710
13711   if (sw_if_index_set == 0)
13712     {
13713       errmsg ("missing interface name or sw_if_index");
13714       return -99;
13715     }
13716
13717   M (INPUT_ACL_SET_INTERFACE, mp);
13718
13719   mp->sw_if_index = ntohl (sw_if_index);
13720   mp->ip4_table_index = ntohl (ip4_table_index);
13721   mp->ip6_table_index = ntohl (ip6_table_index);
13722   mp->l2_table_index = ntohl (l2_table_index);
13723   mp->is_add = is_add;
13724
13725   S (mp);
13726   W (ret);
13727   return ret;
13728 }
13729
13730 static int
13731 api_ip_address_dump (vat_main_t * vam)
13732 {
13733   unformat_input_t *i = vam->input;
13734   vl_api_ip_address_dump_t *mp;
13735   vl_api_control_ping_t *mp_ping;
13736   u32 sw_if_index = ~0;
13737   u8 sw_if_index_set = 0;
13738   u8 ipv4_set = 0;
13739   u8 ipv6_set = 0;
13740   int ret;
13741
13742   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13743     {
13744       if (unformat (i, "sw_if_index %d", &sw_if_index))
13745         sw_if_index_set = 1;
13746       else
13747         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13748         sw_if_index_set = 1;
13749       else if (unformat (i, "ipv4"))
13750         ipv4_set = 1;
13751       else if (unformat (i, "ipv6"))
13752         ipv6_set = 1;
13753       else
13754         break;
13755     }
13756
13757   if (ipv4_set && ipv6_set)
13758     {
13759       errmsg ("ipv4 and ipv6 flags cannot be both set");
13760       return -99;
13761     }
13762
13763   if ((!ipv4_set) && (!ipv6_set))
13764     {
13765       errmsg ("no ipv4 nor ipv6 flag set");
13766       return -99;
13767     }
13768
13769   if (sw_if_index_set == 0)
13770     {
13771       errmsg ("missing interface name or sw_if_index");
13772       return -99;
13773     }
13774
13775   vam->current_sw_if_index = sw_if_index;
13776   vam->is_ipv6 = ipv6_set;
13777
13778   M (IP_ADDRESS_DUMP, mp);
13779   mp->sw_if_index = ntohl (sw_if_index);
13780   mp->is_ipv6 = ipv6_set;
13781   S (mp);
13782
13783   /* Use a control ping for synchronization */
13784   MPING (CONTROL_PING, mp_ping);
13785   S (mp_ping);
13786
13787   W (ret);
13788   return ret;
13789 }
13790
13791 static int
13792 api_ip_dump (vat_main_t * vam)
13793 {
13794   vl_api_ip_dump_t *mp;
13795   vl_api_control_ping_t *mp_ping;
13796   unformat_input_t *in = vam->input;
13797   int ipv4_set = 0;
13798   int ipv6_set = 0;
13799   int is_ipv6;
13800   int i;
13801   int ret;
13802
13803   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13804     {
13805       if (unformat (in, "ipv4"))
13806         ipv4_set = 1;
13807       else if (unformat (in, "ipv6"))
13808         ipv6_set = 1;
13809       else
13810         break;
13811     }
13812
13813   if (ipv4_set && ipv6_set)
13814     {
13815       errmsg ("ipv4 and ipv6 flags cannot be both set");
13816       return -99;
13817     }
13818
13819   if ((!ipv4_set) && (!ipv6_set))
13820     {
13821       errmsg ("no ipv4 nor ipv6 flag set");
13822       return -99;
13823     }
13824
13825   is_ipv6 = ipv6_set;
13826   vam->is_ipv6 = is_ipv6;
13827
13828   /* free old data */
13829   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13830     {
13831       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13832     }
13833   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13834
13835   M (IP_DUMP, mp);
13836   mp->is_ipv6 = ipv6_set;
13837   S (mp);
13838
13839   /* Use a control ping for synchronization */
13840   MPING (CONTROL_PING, mp_ping);
13841   S (mp_ping);
13842
13843   W (ret);
13844   return ret;
13845 }
13846
13847 static int
13848 api_ipsec_spd_add_del (vat_main_t * vam)
13849 {
13850   unformat_input_t *i = vam->input;
13851   vl_api_ipsec_spd_add_del_t *mp;
13852   u32 spd_id = ~0;
13853   u8 is_add = 1;
13854   int ret;
13855
13856   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13857     {
13858       if (unformat (i, "spd_id %d", &spd_id))
13859         ;
13860       else if (unformat (i, "del"))
13861         is_add = 0;
13862       else
13863         {
13864           clib_warning ("parse error '%U'", format_unformat_error, i);
13865           return -99;
13866         }
13867     }
13868   if (spd_id == ~0)
13869     {
13870       errmsg ("spd_id must be set");
13871       return -99;
13872     }
13873
13874   M (IPSEC_SPD_ADD_DEL, mp);
13875
13876   mp->spd_id = ntohl (spd_id);
13877   mp->is_add = is_add;
13878
13879   S (mp);
13880   W (ret);
13881   return ret;
13882 }
13883
13884 static int
13885 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13886 {
13887   unformat_input_t *i = vam->input;
13888   vl_api_ipsec_interface_add_del_spd_t *mp;
13889   u32 sw_if_index;
13890   u8 sw_if_index_set = 0;
13891   u32 spd_id = (u32) ~ 0;
13892   u8 is_add = 1;
13893   int ret;
13894
13895   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13896     {
13897       if (unformat (i, "del"))
13898         is_add = 0;
13899       else if (unformat (i, "spd_id %d", &spd_id))
13900         ;
13901       else
13902         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13903         sw_if_index_set = 1;
13904       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13905         sw_if_index_set = 1;
13906       else
13907         {
13908           clib_warning ("parse error '%U'", format_unformat_error, i);
13909           return -99;
13910         }
13911
13912     }
13913
13914   if (spd_id == (u32) ~ 0)
13915     {
13916       errmsg ("spd_id must be set");
13917       return -99;
13918     }
13919
13920   if (sw_if_index_set == 0)
13921     {
13922       errmsg ("missing interface name or sw_if_index");
13923       return -99;
13924     }
13925
13926   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13927
13928   mp->spd_id = ntohl (spd_id);
13929   mp->sw_if_index = ntohl (sw_if_index);
13930   mp->is_add = is_add;
13931
13932   S (mp);
13933   W (ret);
13934   return ret;
13935 }
13936
13937 static int
13938 api_ipsec_spd_add_del_entry (vat_main_t * vam)
13939 {
13940   unformat_input_t *i = vam->input;
13941   vl_api_ipsec_spd_add_del_entry_t *mp;
13942   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
13943   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13944   i32 priority = 0;
13945   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13946   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13947   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
13948   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
13949   int ret;
13950
13951   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
13952   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
13953   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
13954   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
13955   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
13956   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
13957
13958   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13959     {
13960       if (unformat (i, "del"))
13961         is_add = 0;
13962       if (unformat (i, "outbound"))
13963         is_outbound = 1;
13964       if (unformat (i, "inbound"))
13965         is_outbound = 0;
13966       else if (unformat (i, "spd_id %d", &spd_id))
13967         ;
13968       else if (unformat (i, "sa_id %d", &sa_id))
13969         ;
13970       else if (unformat (i, "priority %d", &priority))
13971         ;
13972       else if (unformat (i, "protocol %d", &protocol))
13973         ;
13974       else if (unformat (i, "lport_start %d", &lport_start))
13975         ;
13976       else if (unformat (i, "lport_stop %d", &lport_stop))
13977         ;
13978       else if (unformat (i, "rport_start %d", &rport_start))
13979         ;
13980       else if (unformat (i, "rport_stop %d", &rport_stop))
13981         ;
13982       else
13983         if (unformat
13984             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
13985         {
13986           is_ipv6 = 0;
13987           is_ip_any = 0;
13988         }
13989       else
13990         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
13991         {
13992           is_ipv6 = 0;
13993           is_ip_any = 0;
13994         }
13995       else
13996         if (unformat
13997             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
13998         {
13999           is_ipv6 = 0;
14000           is_ip_any = 0;
14001         }
14002       else
14003         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
14004         {
14005           is_ipv6 = 0;
14006           is_ip_any = 0;
14007         }
14008       else
14009         if (unformat
14010             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
14011         {
14012           is_ipv6 = 1;
14013           is_ip_any = 0;
14014         }
14015       else
14016         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
14017         {
14018           is_ipv6 = 1;
14019           is_ip_any = 0;
14020         }
14021       else
14022         if (unformat
14023             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
14024         {
14025           is_ipv6 = 1;
14026           is_ip_any = 0;
14027         }
14028       else
14029         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
14030         {
14031           is_ipv6 = 1;
14032           is_ip_any = 0;
14033         }
14034       else
14035         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14036         {
14037           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14038             {
14039               clib_warning ("unsupported action: 'resolve'");
14040               return -99;
14041             }
14042         }
14043       else
14044         {
14045           clib_warning ("parse error '%U'", format_unformat_error, i);
14046           return -99;
14047         }
14048
14049     }
14050
14051   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
14052
14053   mp->spd_id = ntohl (spd_id);
14054   mp->priority = ntohl (priority);
14055   mp->is_outbound = is_outbound;
14056
14057   mp->is_ipv6 = is_ipv6;
14058   if (is_ipv6 || is_ip_any)
14059     {
14060       clib_memcpy (mp->remote_address_start, &raddr6_start,
14061                    sizeof (ip6_address_t));
14062       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
14063                    sizeof (ip6_address_t));
14064       clib_memcpy (mp->local_address_start, &laddr6_start,
14065                    sizeof (ip6_address_t));
14066       clib_memcpy (mp->local_address_stop, &laddr6_stop,
14067                    sizeof (ip6_address_t));
14068     }
14069   else
14070     {
14071       clib_memcpy (mp->remote_address_start, &raddr4_start,
14072                    sizeof (ip4_address_t));
14073       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
14074                    sizeof (ip4_address_t));
14075       clib_memcpy (mp->local_address_start, &laddr4_start,
14076                    sizeof (ip4_address_t));
14077       clib_memcpy (mp->local_address_stop, &laddr4_stop,
14078                    sizeof (ip4_address_t));
14079     }
14080   mp->protocol = (u8) protocol;
14081   mp->local_port_start = ntohs ((u16) lport_start);
14082   mp->local_port_stop = ntohs ((u16) lport_stop);
14083   mp->remote_port_start = ntohs ((u16) rport_start);
14084   mp->remote_port_stop = ntohs ((u16) rport_stop);
14085   mp->policy = (u8) policy;
14086   mp->sa_id = ntohl (sa_id);
14087   mp->is_add = is_add;
14088   mp->is_ip_any = is_ip_any;
14089   S (mp);
14090   W (ret);
14091   return ret;
14092 }
14093
14094 static int
14095 api_ipsec_sad_add_del_entry (vat_main_t * vam)
14096 {
14097   unformat_input_t *i = vam->input;
14098   vl_api_ipsec_sad_add_del_entry_t *mp;
14099   u32 sad_id = 0, spi = 0;
14100   u8 *ck = 0, *ik = 0;
14101   u8 is_add = 1;
14102
14103   u8 protocol = IPSEC_PROTOCOL_AH;
14104   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
14105   u32 crypto_alg = 0, integ_alg = 0;
14106   ip4_address_t tun_src4;
14107   ip4_address_t tun_dst4;
14108   ip6_address_t tun_src6;
14109   ip6_address_t tun_dst6;
14110   int ret;
14111
14112   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14113     {
14114       if (unformat (i, "del"))
14115         is_add = 0;
14116       else if (unformat (i, "sad_id %d", &sad_id))
14117         ;
14118       else if (unformat (i, "spi %d", &spi))
14119         ;
14120       else if (unformat (i, "esp"))
14121         protocol = IPSEC_PROTOCOL_ESP;
14122       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
14123         {
14124           is_tunnel = 1;
14125           is_tunnel_ipv6 = 0;
14126         }
14127       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
14128         {
14129           is_tunnel = 1;
14130           is_tunnel_ipv6 = 0;
14131         }
14132       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
14133         {
14134           is_tunnel = 1;
14135           is_tunnel_ipv6 = 1;
14136         }
14137       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
14138         {
14139           is_tunnel = 1;
14140           is_tunnel_ipv6 = 1;
14141         }
14142       else
14143         if (unformat
14144             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14145         {
14146           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14147               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14148             {
14149               clib_warning ("unsupported crypto-alg: '%U'",
14150                             format_ipsec_crypto_alg, crypto_alg);
14151               return -99;
14152             }
14153         }
14154       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14155         ;
14156       else
14157         if (unformat
14158             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14159         {
14160           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14161               integ_alg >= IPSEC_INTEG_N_ALG)
14162             {
14163               clib_warning ("unsupported integ-alg: '%U'",
14164                             format_ipsec_integ_alg, integ_alg);
14165               return -99;
14166             }
14167         }
14168       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14169         ;
14170       else
14171         {
14172           clib_warning ("parse error '%U'", format_unformat_error, i);
14173           return -99;
14174         }
14175
14176     }
14177
14178   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
14179
14180   mp->sad_id = ntohl (sad_id);
14181   mp->is_add = is_add;
14182   mp->protocol = protocol;
14183   mp->spi = ntohl (spi);
14184   mp->is_tunnel = is_tunnel;
14185   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
14186   mp->crypto_algorithm = crypto_alg;
14187   mp->integrity_algorithm = integ_alg;
14188   mp->crypto_key_length = vec_len (ck);
14189   mp->integrity_key_length = vec_len (ik);
14190
14191   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14192     mp->crypto_key_length = sizeof (mp->crypto_key);
14193
14194   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14195     mp->integrity_key_length = sizeof (mp->integrity_key);
14196
14197   if (ck)
14198     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14199   if (ik)
14200     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14201
14202   if (is_tunnel)
14203     {
14204       if (is_tunnel_ipv6)
14205         {
14206           clib_memcpy (mp->tunnel_src_address, &tun_src6,
14207                        sizeof (ip6_address_t));
14208           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
14209                        sizeof (ip6_address_t));
14210         }
14211       else
14212         {
14213           clib_memcpy (mp->tunnel_src_address, &tun_src4,
14214                        sizeof (ip4_address_t));
14215           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
14216                        sizeof (ip4_address_t));
14217         }
14218     }
14219
14220   S (mp);
14221   W (ret);
14222   return ret;
14223 }
14224
14225 static int
14226 api_ipsec_sa_set_key (vat_main_t * vam)
14227 {
14228   unformat_input_t *i = vam->input;
14229   vl_api_ipsec_sa_set_key_t *mp;
14230   u32 sa_id;
14231   u8 *ck = 0, *ik = 0;
14232   int ret;
14233
14234   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14235     {
14236       if (unformat (i, "sa_id %d", &sa_id))
14237         ;
14238       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14239         ;
14240       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14241         ;
14242       else
14243         {
14244           clib_warning ("parse error '%U'", format_unformat_error, i);
14245           return -99;
14246         }
14247     }
14248
14249   M (IPSEC_SA_SET_KEY, mp);
14250
14251   mp->sa_id = ntohl (sa_id);
14252   mp->crypto_key_length = vec_len (ck);
14253   mp->integrity_key_length = vec_len (ik);
14254
14255   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14256     mp->crypto_key_length = sizeof (mp->crypto_key);
14257
14258   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14259     mp->integrity_key_length = sizeof (mp->integrity_key);
14260
14261   if (ck)
14262     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14263   if (ik)
14264     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14265
14266   S (mp);
14267   W (ret);
14268   return ret;
14269 }
14270
14271 static int
14272 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14273 {
14274   unformat_input_t *i = vam->input;
14275   vl_api_ipsec_tunnel_if_add_del_t *mp;
14276   u32 local_spi = 0, remote_spi = 0;
14277   u32 crypto_alg = 0, integ_alg = 0;
14278   u8 *lck = NULL, *rck = NULL;
14279   u8 *lik = NULL, *rik = NULL;
14280   ip4_address_t local_ip = { {0} };
14281   ip4_address_t remote_ip = { {0} };
14282   u8 is_add = 1;
14283   u8 esn = 0;
14284   u8 anti_replay = 0;
14285   int ret;
14286
14287   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14288     {
14289       if (unformat (i, "del"))
14290         is_add = 0;
14291       else if (unformat (i, "esn"))
14292         esn = 1;
14293       else if (unformat (i, "anti_replay"))
14294         anti_replay = 1;
14295       else if (unformat (i, "local_spi %d", &local_spi))
14296         ;
14297       else if (unformat (i, "remote_spi %d", &remote_spi))
14298         ;
14299       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
14300         ;
14301       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
14302         ;
14303       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14304         ;
14305       else
14306         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14307         ;
14308       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14309         ;
14310       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14311         ;
14312       else
14313         if (unformat
14314             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14315         {
14316           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14317               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14318             {
14319               errmsg ("unsupported crypto-alg: '%U'\n",
14320                       format_ipsec_crypto_alg, crypto_alg);
14321               return -99;
14322             }
14323         }
14324       else
14325         if (unformat
14326             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14327         {
14328           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14329               integ_alg >= IPSEC_INTEG_N_ALG)
14330             {
14331               errmsg ("unsupported integ-alg: '%U'\n",
14332                       format_ipsec_integ_alg, integ_alg);
14333               return -99;
14334             }
14335         }
14336       else
14337         {
14338           errmsg ("parse error '%U'\n", format_unformat_error, i);
14339           return -99;
14340         }
14341     }
14342
14343   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14344
14345   mp->is_add = is_add;
14346   mp->esn = esn;
14347   mp->anti_replay = anti_replay;
14348
14349   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
14350   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
14351
14352   mp->local_spi = htonl (local_spi);
14353   mp->remote_spi = htonl (remote_spi);
14354   mp->crypto_alg = (u8) crypto_alg;
14355
14356   mp->local_crypto_key_len = 0;
14357   if (lck)
14358     {
14359       mp->local_crypto_key_len = vec_len (lck);
14360       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14361         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14362       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14363     }
14364
14365   mp->remote_crypto_key_len = 0;
14366   if (rck)
14367     {
14368       mp->remote_crypto_key_len = vec_len (rck);
14369       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14370         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14371       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14372     }
14373
14374   mp->integ_alg = (u8) integ_alg;
14375
14376   mp->local_integ_key_len = 0;
14377   if (lik)
14378     {
14379       mp->local_integ_key_len = vec_len (lik);
14380       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14381         mp->local_integ_key_len = sizeof (mp->local_integ_key);
14382       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14383     }
14384
14385   mp->remote_integ_key_len = 0;
14386   if (rik)
14387     {
14388       mp->remote_integ_key_len = vec_len (rik);
14389       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14390         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14391       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14392     }
14393
14394   S (mp);
14395   W (ret);
14396   return ret;
14397 }
14398
14399 static void
14400 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14401 {
14402   vat_main_t *vam = &vat_main;
14403
14404   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14405          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
14406          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
14407          "tunnel_src_addr %U tunnel_dst_addr %U "
14408          "salt %u seq_outbound %lu last_seq_inbound %lu "
14409          "replay_window %lu total_data_size %lu\n",
14410          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
14411          mp->protocol,
14412          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
14413          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
14414          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
14415          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14416          mp->tunnel_src_addr,
14417          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14418          mp->tunnel_dst_addr,
14419          ntohl (mp->salt),
14420          clib_net_to_host_u64 (mp->seq_outbound),
14421          clib_net_to_host_u64 (mp->last_seq_inbound),
14422          clib_net_to_host_u64 (mp->replay_window),
14423          clib_net_to_host_u64 (mp->total_data_size));
14424 }
14425
14426 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14427 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14428
14429 static void vl_api_ipsec_sa_details_t_handler_json
14430   (vl_api_ipsec_sa_details_t * mp)
14431 {
14432   vat_main_t *vam = &vat_main;
14433   vat_json_node_t *node = NULL;
14434   struct in_addr src_ip4, dst_ip4;
14435   struct in6_addr src_ip6, dst_ip6;
14436
14437   if (VAT_JSON_ARRAY != vam->json_tree.type)
14438     {
14439       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14440       vat_json_init_array (&vam->json_tree);
14441     }
14442   node = vat_json_array_add (&vam->json_tree);
14443
14444   vat_json_init_object (node);
14445   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
14446   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14447   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
14448   vat_json_object_add_uint (node, "proto", mp->protocol);
14449   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
14450   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
14451   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
14452   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
14453   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
14454   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
14455   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
14456                              mp->crypto_key_len);
14457   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
14458                              mp->integ_key_len);
14459   if (mp->is_tunnel_ip6)
14460     {
14461       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
14462       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
14463       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
14464       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
14465     }
14466   else
14467     {
14468       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
14469       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
14470       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
14471       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
14472     }
14473   vat_json_object_add_uint (node, "replay_window",
14474                             clib_net_to_host_u64 (mp->replay_window));
14475   vat_json_object_add_uint (node, "total_data_size",
14476                             clib_net_to_host_u64 (mp->total_data_size));
14477
14478 }
14479
14480 static int
14481 api_ipsec_sa_dump (vat_main_t * vam)
14482 {
14483   unformat_input_t *i = vam->input;
14484   vl_api_ipsec_sa_dump_t *mp;
14485   vl_api_control_ping_t *mp_ping;
14486   u32 sa_id = ~0;
14487   int ret;
14488
14489   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14490     {
14491       if (unformat (i, "sa_id %d", &sa_id))
14492         ;
14493       else
14494         {
14495           clib_warning ("parse error '%U'", format_unformat_error, i);
14496           return -99;
14497         }
14498     }
14499
14500   M (IPSEC_SA_DUMP, mp);
14501
14502   mp->sa_id = ntohl (sa_id);
14503
14504   S (mp);
14505
14506   /* Use a control ping for synchronization */
14507   M (CONTROL_PING, mp_ping);
14508   S (mp_ping);
14509
14510   W (ret);
14511   return ret;
14512 }
14513
14514 static int
14515 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
14516 {
14517   unformat_input_t *i = vam->input;
14518   vl_api_ipsec_tunnel_if_set_key_t *mp;
14519   u32 sw_if_index = ~0;
14520   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
14521   u8 *key = 0;
14522   u32 alg = ~0;
14523   int ret;
14524
14525   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14526     {
14527       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14528         ;
14529       else
14530         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
14531         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
14532       else
14533         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
14534         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
14535       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
14536         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
14537       else
14538         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
14539         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
14540       else if (unformat (i, "%U", unformat_hex_string, &key))
14541         ;
14542       else
14543         {
14544           clib_warning ("parse error '%U'", format_unformat_error, i);
14545           return -99;
14546         }
14547     }
14548
14549   if (sw_if_index == ~0)
14550     {
14551       errmsg ("interface must be specified");
14552       return -99;
14553     }
14554
14555   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
14556     {
14557       errmsg ("key type must be specified");
14558       return -99;
14559     }
14560
14561   if (alg == ~0)
14562     {
14563       errmsg ("algorithm must be specified");
14564       return -99;
14565     }
14566
14567   if (vec_len (key) == 0)
14568     {
14569       errmsg ("key must be specified");
14570       return -99;
14571     }
14572
14573   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
14574
14575   mp->sw_if_index = htonl (sw_if_index);
14576   mp->alg = alg;
14577   mp->key_type = key_type;
14578   mp->key_len = vec_len (key);
14579   clib_memcpy (mp->key, key, vec_len (key));
14580
14581   S (mp);
14582   W (ret);
14583
14584   return ret;
14585 }
14586
14587 static int
14588 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14589 {
14590   unformat_input_t *i = vam->input;
14591   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14592   u32 sw_if_index = ~0;
14593   u32 sa_id = ~0;
14594   u8 is_outbound = (u8) ~ 0;
14595   int ret;
14596
14597   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14598     {
14599       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14600         ;
14601       else if (unformat (i, "sa_id %d", &sa_id))
14602         ;
14603       else if (unformat (i, "outbound"))
14604         is_outbound = 1;
14605       else if (unformat (i, "inbound"))
14606         is_outbound = 0;
14607       else
14608         {
14609           clib_warning ("parse error '%U'", format_unformat_error, i);
14610           return -99;
14611         }
14612     }
14613
14614   if (sw_if_index == ~0)
14615     {
14616       errmsg ("interface must be specified");
14617       return -99;
14618     }
14619
14620   if (sa_id == ~0)
14621     {
14622       errmsg ("SA ID must be specified");
14623       return -99;
14624     }
14625
14626   M (IPSEC_TUNNEL_IF_SET_SA, mp);
14627
14628   mp->sw_if_index = htonl (sw_if_index);
14629   mp->sa_id = htonl (sa_id);
14630   mp->is_outbound = is_outbound;
14631
14632   S (mp);
14633   W (ret);
14634
14635   return ret;
14636 }
14637
14638 static int
14639 api_ikev2_profile_add_del (vat_main_t * vam)
14640 {
14641   unformat_input_t *i = vam->input;
14642   vl_api_ikev2_profile_add_del_t *mp;
14643   u8 is_add = 1;
14644   u8 *name = 0;
14645   int ret;
14646
14647   const char *valid_chars = "a-zA-Z0-9_";
14648
14649   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14650     {
14651       if (unformat (i, "del"))
14652         is_add = 0;
14653       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14654         vec_add1 (name, 0);
14655       else
14656         {
14657           errmsg ("parse error '%U'", format_unformat_error, i);
14658           return -99;
14659         }
14660     }
14661
14662   if (!vec_len (name))
14663     {
14664       errmsg ("profile name must be specified");
14665       return -99;
14666     }
14667
14668   if (vec_len (name) > 64)
14669     {
14670       errmsg ("profile name too long");
14671       return -99;
14672     }
14673
14674   M (IKEV2_PROFILE_ADD_DEL, mp);
14675
14676   clib_memcpy (mp->name, name, vec_len (name));
14677   mp->is_add = is_add;
14678   vec_free (name);
14679
14680   S (mp);
14681   W (ret);
14682   return ret;
14683 }
14684
14685 static int
14686 api_ikev2_profile_set_auth (vat_main_t * vam)
14687 {
14688   unformat_input_t *i = vam->input;
14689   vl_api_ikev2_profile_set_auth_t *mp;
14690   u8 *name = 0;
14691   u8 *data = 0;
14692   u32 auth_method = 0;
14693   u8 is_hex = 0;
14694   int ret;
14695
14696   const char *valid_chars = "a-zA-Z0-9_";
14697
14698   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14699     {
14700       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14701         vec_add1 (name, 0);
14702       else if (unformat (i, "auth_method %U",
14703                          unformat_ikev2_auth_method, &auth_method))
14704         ;
14705       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
14706         is_hex = 1;
14707       else if (unformat (i, "auth_data %v", &data))
14708         ;
14709       else
14710         {
14711           errmsg ("parse error '%U'", format_unformat_error, i);
14712           return -99;
14713         }
14714     }
14715
14716   if (!vec_len (name))
14717     {
14718       errmsg ("profile name must be specified");
14719       return -99;
14720     }
14721
14722   if (vec_len (name) > 64)
14723     {
14724       errmsg ("profile name too long");
14725       return -99;
14726     }
14727
14728   if (!vec_len (data))
14729     {
14730       errmsg ("auth_data must be specified");
14731       return -99;
14732     }
14733
14734   if (!auth_method)
14735     {
14736       errmsg ("auth_method must be specified");
14737       return -99;
14738     }
14739
14740   M (IKEV2_PROFILE_SET_AUTH, mp);
14741
14742   mp->is_hex = is_hex;
14743   mp->auth_method = (u8) auth_method;
14744   mp->data_len = vec_len (data);
14745   clib_memcpy (mp->name, name, vec_len (name));
14746   clib_memcpy (mp->data, data, vec_len (data));
14747   vec_free (name);
14748   vec_free (data);
14749
14750   S (mp);
14751   W (ret);
14752   return ret;
14753 }
14754
14755 static int
14756 api_ikev2_profile_set_id (vat_main_t * vam)
14757 {
14758   unformat_input_t *i = vam->input;
14759   vl_api_ikev2_profile_set_id_t *mp;
14760   u8 *name = 0;
14761   u8 *data = 0;
14762   u8 is_local = 0;
14763   u32 id_type = 0;
14764   ip4_address_t ip4;
14765   int ret;
14766
14767   const char *valid_chars = "a-zA-Z0-9_";
14768
14769   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14770     {
14771       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14772         vec_add1 (name, 0);
14773       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
14774         ;
14775       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
14776         {
14777           data = vec_new (u8, 4);
14778           clib_memcpy (data, ip4.as_u8, 4);
14779         }
14780       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
14781         ;
14782       else if (unformat (i, "id_data %v", &data))
14783         ;
14784       else if (unformat (i, "local"))
14785         is_local = 1;
14786       else if (unformat (i, "remote"))
14787         is_local = 0;
14788       else
14789         {
14790           errmsg ("parse error '%U'", format_unformat_error, i);
14791           return -99;
14792         }
14793     }
14794
14795   if (!vec_len (name))
14796     {
14797       errmsg ("profile name must be specified");
14798       return -99;
14799     }
14800
14801   if (vec_len (name) > 64)
14802     {
14803       errmsg ("profile name too long");
14804       return -99;
14805     }
14806
14807   if (!vec_len (data))
14808     {
14809       errmsg ("id_data must be specified");
14810       return -99;
14811     }
14812
14813   if (!id_type)
14814     {
14815       errmsg ("id_type must be specified");
14816       return -99;
14817     }
14818
14819   M (IKEV2_PROFILE_SET_ID, mp);
14820
14821   mp->is_local = is_local;
14822   mp->id_type = (u8) id_type;
14823   mp->data_len = vec_len (data);
14824   clib_memcpy (mp->name, name, vec_len (name));
14825   clib_memcpy (mp->data, data, vec_len (data));
14826   vec_free (name);
14827   vec_free (data);
14828
14829   S (mp);
14830   W (ret);
14831   return ret;
14832 }
14833
14834 static int
14835 api_ikev2_profile_set_ts (vat_main_t * vam)
14836 {
14837   unformat_input_t *i = vam->input;
14838   vl_api_ikev2_profile_set_ts_t *mp;
14839   u8 *name = 0;
14840   u8 is_local = 0;
14841   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
14842   ip4_address_t start_addr, end_addr;
14843
14844   const char *valid_chars = "a-zA-Z0-9_";
14845   int ret;
14846
14847   start_addr.as_u32 = 0;
14848   end_addr.as_u32 = (u32) ~ 0;
14849
14850   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14851     {
14852       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14853         vec_add1 (name, 0);
14854       else if (unformat (i, "protocol %d", &proto))
14855         ;
14856       else if (unformat (i, "start_port %d", &start_port))
14857         ;
14858       else if (unformat (i, "end_port %d", &end_port))
14859         ;
14860       else
14861         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
14862         ;
14863       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
14864         ;
14865       else if (unformat (i, "local"))
14866         is_local = 1;
14867       else if (unformat (i, "remote"))
14868         is_local = 0;
14869       else
14870         {
14871           errmsg ("parse error '%U'", format_unformat_error, i);
14872           return -99;
14873         }
14874     }
14875
14876   if (!vec_len (name))
14877     {
14878       errmsg ("profile name must be specified");
14879       return -99;
14880     }
14881
14882   if (vec_len (name) > 64)
14883     {
14884       errmsg ("profile name too long");
14885       return -99;
14886     }
14887
14888   M (IKEV2_PROFILE_SET_TS, mp);
14889
14890   mp->is_local = is_local;
14891   mp->proto = (u8) proto;
14892   mp->start_port = (u16) start_port;
14893   mp->end_port = (u16) end_port;
14894   mp->start_addr = start_addr.as_u32;
14895   mp->end_addr = end_addr.as_u32;
14896   clib_memcpy (mp->name, name, vec_len (name));
14897   vec_free (name);
14898
14899   S (mp);
14900   W (ret);
14901   return ret;
14902 }
14903
14904 static int
14905 api_ikev2_set_local_key (vat_main_t * vam)
14906 {
14907   unformat_input_t *i = vam->input;
14908   vl_api_ikev2_set_local_key_t *mp;
14909   u8 *file = 0;
14910   int ret;
14911
14912   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14913     {
14914       if (unformat (i, "file %v", &file))
14915         vec_add1 (file, 0);
14916       else
14917         {
14918           errmsg ("parse error '%U'", format_unformat_error, i);
14919           return -99;
14920         }
14921     }
14922
14923   if (!vec_len (file))
14924     {
14925       errmsg ("RSA key file must be specified");
14926       return -99;
14927     }
14928
14929   if (vec_len (file) > 256)
14930     {
14931       errmsg ("file name too long");
14932       return -99;
14933     }
14934
14935   M (IKEV2_SET_LOCAL_KEY, mp);
14936
14937   clib_memcpy (mp->key_file, file, vec_len (file));
14938   vec_free (file);
14939
14940   S (mp);
14941   W (ret);
14942   return ret;
14943 }
14944
14945 static int
14946 api_ikev2_set_responder (vat_main_t * vam)
14947 {
14948   unformat_input_t *i = vam->input;
14949   vl_api_ikev2_set_responder_t *mp;
14950   int ret;
14951   u8 *name = 0;
14952   u32 sw_if_index = ~0;
14953   ip4_address_t address;
14954
14955   const char *valid_chars = "a-zA-Z0-9_";
14956
14957   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14958     {
14959       if (unformat
14960           (i, "%U interface %d address %U", unformat_token, valid_chars,
14961            &name, &sw_if_index, unformat_ip4_address, &address))
14962         vec_add1 (name, 0);
14963       else
14964         {
14965           errmsg ("parse error '%U'", format_unformat_error, i);
14966           return -99;
14967         }
14968     }
14969
14970   if (!vec_len (name))
14971     {
14972       errmsg ("profile name must be specified");
14973       return -99;
14974     }
14975
14976   if (vec_len (name) > 64)
14977     {
14978       errmsg ("profile name too long");
14979       return -99;
14980     }
14981
14982   M (IKEV2_SET_RESPONDER, mp);
14983
14984   clib_memcpy (mp->name, name, vec_len (name));
14985   vec_free (name);
14986
14987   mp->sw_if_index = sw_if_index;
14988   clib_memcpy (mp->address, &address, sizeof (address));
14989
14990   S (mp);
14991   W (ret);
14992   return ret;
14993 }
14994
14995 static int
14996 api_ikev2_set_ike_transforms (vat_main_t * vam)
14997 {
14998   unformat_input_t *i = vam->input;
14999   vl_api_ikev2_set_ike_transforms_t *mp;
15000   int ret;
15001   u8 *name = 0;
15002   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15003
15004   const char *valid_chars = "a-zA-Z0-9_";
15005
15006   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15007     {
15008       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15009                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15010         vec_add1 (name, 0);
15011       else
15012         {
15013           errmsg ("parse error '%U'", format_unformat_error, i);
15014           return -99;
15015         }
15016     }
15017
15018   if (!vec_len (name))
15019     {
15020       errmsg ("profile name must be specified");
15021       return -99;
15022     }
15023
15024   if (vec_len (name) > 64)
15025     {
15026       errmsg ("profile name too long");
15027       return -99;
15028     }
15029
15030   M (IKEV2_SET_IKE_TRANSFORMS, mp);
15031
15032   clib_memcpy (mp->name, name, vec_len (name));
15033   vec_free (name);
15034   mp->crypto_alg = crypto_alg;
15035   mp->crypto_key_size = crypto_key_size;
15036   mp->integ_alg = integ_alg;
15037   mp->dh_group = dh_group;
15038
15039   S (mp);
15040   W (ret);
15041   return ret;
15042 }
15043
15044
15045 static int
15046 api_ikev2_set_esp_transforms (vat_main_t * vam)
15047 {
15048   unformat_input_t *i = vam->input;
15049   vl_api_ikev2_set_esp_transforms_t *mp;
15050   int ret;
15051   u8 *name = 0;
15052   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15053
15054   const char *valid_chars = "a-zA-Z0-9_";
15055
15056   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15057     {
15058       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15059                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15060         vec_add1 (name, 0);
15061       else
15062         {
15063           errmsg ("parse error '%U'", format_unformat_error, i);
15064           return -99;
15065         }
15066     }
15067
15068   if (!vec_len (name))
15069     {
15070       errmsg ("profile name must be specified");
15071       return -99;
15072     }
15073
15074   if (vec_len (name) > 64)
15075     {
15076       errmsg ("profile name too long");
15077       return -99;
15078     }
15079
15080   M (IKEV2_SET_ESP_TRANSFORMS, mp);
15081
15082   clib_memcpy (mp->name, name, vec_len (name));
15083   vec_free (name);
15084   mp->crypto_alg = crypto_alg;
15085   mp->crypto_key_size = crypto_key_size;
15086   mp->integ_alg = integ_alg;
15087   mp->dh_group = dh_group;
15088
15089   S (mp);
15090   W (ret);
15091   return ret;
15092 }
15093
15094 static int
15095 api_ikev2_set_sa_lifetime (vat_main_t * vam)
15096 {
15097   unformat_input_t *i = vam->input;
15098   vl_api_ikev2_set_sa_lifetime_t *mp;
15099   int ret;
15100   u8 *name = 0;
15101   u64 lifetime, lifetime_maxdata;
15102   u32 lifetime_jitter, handover;
15103
15104   const char *valid_chars = "a-zA-Z0-9_";
15105
15106   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15107     {
15108       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
15109                     &lifetime, &lifetime_jitter, &handover,
15110                     &lifetime_maxdata))
15111         vec_add1 (name, 0);
15112       else
15113         {
15114           errmsg ("parse error '%U'", format_unformat_error, i);
15115           return -99;
15116         }
15117     }
15118
15119   if (!vec_len (name))
15120     {
15121       errmsg ("profile name must be specified");
15122       return -99;
15123     }
15124
15125   if (vec_len (name) > 64)
15126     {
15127       errmsg ("profile name too long");
15128       return -99;
15129     }
15130
15131   M (IKEV2_SET_SA_LIFETIME, mp);
15132
15133   clib_memcpy (mp->name, name, vec_len (name));
15134   vec_free (name);
15135   mp->lifetime = lifetime;
15136   mp->lifetime_jitter = lifetime_jitter;
15137   mp->handover = handover;
15138   mp->lifetime_maxdata = lifetime_maxdata;
15139
15140   S (mp);
15141   W (ret);
15142   return ret;
15143 }
15144
15145 static int
15146 api_ikev2_initiate_sa_init (vat_main_t * vam)
15147 {
15148   unformat_input_t *i = vam->input;
15149   vl_api_ikev2_initiate_sa_init_t *mp;
15150   int ret;
15151   u8 *name = 0;
15152
15153   const char *valid_chars = "a-zA-Z0-9_";
15154
15155   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15156     {
15157       if (unformat (i, "%U", unformat_token, valid_chars, &name))
15158         vec_add1 (name, 0);
15159       else
15160         {
15161           errmsg ("parse error '%U'", format_unformat_error, i);
15162           return -99;
15163         }
15164     }
15165
15166   if (!vec_len (name))
15167     {
15168       errmsg ("profile name must be specified");
15169       return -99;
15170     }
15171
15172   if (vec_len (name) > 64)
15173     {
15174       errmsg ("profile name too long");
15175       return -99;
15176     }
15177
15178   M (IKEV2_INITIATE_SA_INIT, mp);
15179
15180   clib_memcpy (mp->name, name, vec_len (name));
15181   vec_free (name);
15182
15183   S (mp);
15184   W (ret);
15185   return ret;
15186 }
15187
15188 static int
15189 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
15190 {
15191   unformat_input_t *i = vam->input;
15192   vl_api_ikev2_initiate_del_ike_sa_t *mp;
15193   int ret;
15194   u64 ispi;
15195
15196
15197   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15198     {
15199       if (unformat (i, "%lx", &ispi))
15200         ;
15201       else
15202         {
15203           errmsg ("parse error '%U'", format_unformat_error, i);
15204           return -99;
15205         }
15206     }
15207
15208   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
15209
15210   mp->ispi = ispi;
15211
15212   S (mp);
15213   W (ret);
15214   return ret;
15215 }
15216
15217 static int
15218 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
15219 {
15220   unformat_input_t *i = vam->input;
15221   vl_api_ikev2_initiate_del_child_sa_t *mp;
15222   int ret;
15223   u32 ispi;
15224
15225
15226   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15227     {
15228       if (unformat (i, "%x", &ispi))
15229         ;
15230       else
15231         {
15232           errmsg ("parse error '%U'", format_unformat_error, i);
15233           return -99;
15234         }
15235     }
15236
15237   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
15238
15239   mp->ispi = ispi;
15240
15241   S (mp);
15242   W (ret);
15243   return ret;
15244 }
15245
15246 static int
15247 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
15248 {
15249   unformat_input_t *i = vam->input;
15250   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
15251   int ret;
15252   u32 ispi;
15253
15254
15255   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15256     {
15257       if (unformat (i, "%x", &ispi))
15258         ;
15259       else
15260         {
15261           errmsg ("parse error '%U'", format_unformat_error, i);
15262           return -99;
15263         }
15264     }
15265
15266   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
15267
15268   mp->ispi = ispi;
15269
15270   S (mp);
15271   W (ret);
15272   return ret;
15273 }
15274
15275 /*
15276  * MAP
15277  */
15278 static int
15279 api_map_add_domain (vat_main_t * vam)
15280 {
15281   unformat_input_t *i = vam->input;
15282   vl_api_map_add_domain_t *mp;
15283
15284   ip4_address_t ip4_prefix;
15285   ip6_address_t ip6_prefix;
15286   ip6_address_t ip6_src;
15287   u32 num_m_args = 0;
15288   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
15289     0, psid_length = 0;
15290   u8 is_translation = 0;
15291   u32 mtu = 0;
15292   u32 ip6_src_len = 128;
15293   int ret;
15294
15295   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15296     {
15297       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
15298                     &ip4_prefix, &ip4_prefix_len))
15299         num_m_args++;
15300       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
15301                          &ip6_prefix, &ip6_prefix_len))
15302         num_m_args++;
15303       else
15304         if (unformat
15305             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
15306              &ip6_src_len))
15307         num_m_args++;
15308       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
15309         num_m_args++;
15310       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
15311         num_m_args++;
15312       else if (unformat (i, "psid-offset %d", &psid_offset))
15313         num_m_args++;
15314       else if (unformat (i, "psid-len %d", &psid_length))
15315         num_m_args++;
15316       else if (unformat (i, "mtu %d", &mtu))
15317         num_m_args++;
15318       else if (unformat (i, "map-t"))
15319         is_translation = 1;
15320       else
15321         {
15322           clib_warning ("parse error '%U'", format_unformat_error, i);
15323           return -99;
15324         }
15325     }
15326
15327   if (num_m_args < 3)
15328     {
15329       errmsg ("mandatory argument(s) missing");
15330       return -99;
15331     }
15332
15333   /* Construct the API message */
15334   M (MAP_ADD_DOMAIN, mp);
15335
15336   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
15337   mp->ip4_prefix_len = ip4_prefix_len;
15338
15339   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
15340   mp->ip6_prefix_len = ip6_prefix_len;
15341
15342   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
15343   mp->ip6_src_prefix_len = ip6_src_len;
15344
15345   mp->ea_bits_len = ea_bits_len;
15346   mp->psid_offset = psid_offset;
15347   mp->psid_length = psid_length;
15348   mp->is_translation = is_translation;
15349   mp->mtu = htons (mtu);
15350
15351   /* send it... */
15352   S (mp);
15353
15354   /* Wait for a reply, return good/bad news  */
15355   W (ret);
15356   return ret;
15357 }
15358
15359 static int
15360 api_map_del_domain (vat_main_t * vam)
15361 {
15362   unformat_input_t *i = vam->input;
15363   vl_api_map_del_domain_t *mp;
15364
15365   u32 num_m_args = 0;
15366   u32 index;
15367   int ret;
15368
15369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15370     {
15371       if (unformat (i, "index %d", &index))
15372         num_m_args++;
15373       else
15374         {
15375           clib_warning ("parse error '%U'", format_unformat_error, i);
15376           return -99;
15377         }
15378     }
15379
15380   if (num_m_args != 1)
15381     {
15382       errmsg ("mandatory argument(s) missing");
15383       return -99;
15384     }
15385
15386   /* Construct the API message */
15387   M (MAP_DEL_DOMAIN, mp);
15388
15389   mp->index = ntohl (index);
15390
15391   /* send it... */
15392   S (mp);
15393
15394   /* Wait for a reply, return good/bad news  */
15395   W (ret);
15396   return ret;
15397 }
15398
15399 static int
15400 api_map_add_del_rule (vat_main_t * vam)
15401 {
15402   unformat_input_t *i = vam->input;
15403   vl_api_map_add_del_rule_t *mp;
15404   u8 is_add = 1;
15405   ip6_address_t ip6_dst;
15406   u32 num_m_args = 0, index, psid = 0;
15407   int ret;
15408
15409   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15410     {
15411       if (unformat (i, "index %d", &index))
15412         num_m_args++;
15413       else if (unformat (i, "psid %d", &psid))
15414         num_m_args++;
15415       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
15416         num_m_args++;
15417       else if (unformat (i, "del"))
15418         {
15419           is_add = 0;
15420         }
15421       else
15422         {
15423           clib_warning ("parse error '%U'", format_unformat_error, i);
15424           return -99;
15425         }
15426     }
15427
15428   /* Construct the API message */
15429   M (MAP_ADD_DEL_RULE, mp);
15430
15431   mp->index = ntohl (index);
15432   mp->is_add = is_add;
15433   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
15434   mp->psid = ntohs (psid);
15435
15436   /* send it... */
15437   S (mp);
15438
15439   /* Wait for a reply, return good/bad news  */
15440   W (ret);
15441   return ret;
15442 }
15443
15444 static int
15445 api_map_domain_dump (vat_main_t * vam)
15446 {
15447   vl_api_map_domain_dump_t *mp;
15448   vl_api_control_ping_t *mp_ping;
15449   int ret;
15450
15451   /* Construct the API message */
15452   M (MAP_DOMAIN_DUMP, mp);
15453
15454   /* send it... */
15455   S (mp);
15456
15457   /* Use a control ping for synchronization */
15458   MPING (CONTROL_PING, mp_ping);
15459   S (mp_ping);
15460
15461   W (ret);
15462   return ret;
15463 }
15464
15465 static int
15466 api_map_rule_dump (vat_main_t * vam)
15467 {
15468   unformat_input_t *i = vam->input;
15469   vl_api_map_rule_dump_t *mp;
15470   vl_api_control_ping_t *mp_ping;
15471   u32 domain_index = ~0;
15472   int ret;
15473
15474   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15475     {
15476       if (unformat (i, "index %u", &domain_index))
15477         ;
15478       else
15479         break;
15480     }
15481
15482   if (domain_index == ~0)
15483     {
15484       clib_warning ("parse error: domain index expected");
15485       return -99;
15486     }
15487
15488   /* Construct the API message */
15489   M (MAP_RULE_DUMP, mp);
15490
15491   mp->domain_index = htonl (domain_index);
15492
15493   /* send it... */
15494   S (mp);
15495
15496   /* Use a control ping for synchronization */
15497   MPING (CONTROL_PING, mp_ping);
15498   S (mp_ping);
15499
15500   W (ret);
15501   return ret;
15502 }
15503
15504 static void vl_api_map_add_domain_reply_t_handler
15505   (vl_api_map_add_domain_reply_t * mp)
15506 {
15507   vat_main_t *vam = &vat_main;
15508   i32 retval = ntohl (mp->retval);
15509
15510   if (vam->async_mode)
15511     {
15512       vam->async_errors += (retval < 0);
15513     }
15514   else
15515     {
15516       vam->retval = retval;
15517       vam->result_ready = 1;
15518     }
15519 }
15520
15521 static void vl_api_map_add_domain_reply_t_handler_json
15522   (vl_api_map_add_domain_reply_t * mp)
15523 {
15524   vat_main_t *vam = &vat_main;
15525   vat_json_node_t node;
15526
15527   vat_json_init_object (&node);
15528   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
15529   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
15530
15531   vat_json_print (vam->ofp, &node);
15532   vat_json_free (&node);
15533
15534   vam->retval = ntohl (mp->retval);
15535   vam->result_ready = 1;
15536 }
15537
15538 static int
15539 api_get_first_msg_id (vat_main_t * vam)
15540 {
15541   vl_api_get_first_msg_id_t *mp;
15542   unformat_input_t *i = vam->input;
15543   u8 *name;
15544   u8 name_set = 0;
15545   int ret;
15546
15547   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15548     {
15549       if (unformat (i, "client %s", &name))
15550         name_set = 1;
15551       else
15552         break;
15553     }
15554
15555   if (name_set == 0)
15556     {
15557       errmsg ("missing client name");
15558       return -99;
15559     }
15560   vec_add1 (name, 0);
15561
15562   if (vec_len (name) > 63)
15563     {
15564       errmsg ("client name too long");
15565       return -99;
15566     }
15567
15568   M (GET_FIRST_MSG_ID, mp);
15569   clib_memcpy (mp->name, name, vec_len (name));
15570   S (mp);
15571   W (ret);
15572   return ret;
15573 }
15574
15575 static int
15576 api_cop_interface_enable_disable (vat_main_t * vam)
15577 {
15578   unformat_input_t *line_input = vam->input;
15579   vl_api_cop_interface_enable_disable_t *mp;
15580   u32 sw_if_index = ~0;
15581   u8 enable_disable = 1;
15582   int ret;
15583
15584   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15585     {
15586       if (unformat (line_input, "disable"))
15587         enable_disable = 0;
15588       if (unformat (line_input, "enable"))
15589         enable_disable = 1;
15590       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15591                          vam, &sw_if_index))
15592         ;
15593       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15594         ;
15595       else
15596         break;
15597     }
15598
15599   if (sw_if_index == ~0)
15600     {
15601       errmsg ("missing interface name or sw_if_index");
15602       return -99;
15603     }
15604
15605   /* Construct the API message */
15606   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15607   mp->sw_if_index = ntohl (sw_if_index);
15608   mp->enable_disable = enable_disable;
15609
15610   /* send it... */
15611   S (mp);
15612   /* Wait for the reply */
15613   W (ret);
15614   return ret;
15615 }
15616
15617 static int
15618 api_cop_whitelist_enable_disable (vat_main_t * vam)
15619 {
15620   unformat_input_t *line_input = vam->input;
15621   vl_api_cop_whitelist_enable_disable_t *mp;
15622   u32 sw_if_index = ~0;
15623   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15624   u32 fib_id = 0;
15625   int ret;
15626
15627   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15628     {
15629       if (unformat (line_input, "ip4"))
15630         ip4 = 1;
15631       else if (unformat (line_input, "ip6"))
15632         ip6 = 1;
15633       else if (unformat (line_input, "default"))
15634         default_cop = 1;
15635       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15636                          vam, &sw_if_index))
15637         ;
15638       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15639         ;
15640       else if (unformat (line_input, "fib-id %d", &fib_id))
15641         ;
15642       else
15643         break;
15644     }
15645
15646   if (sw_if_index == ~0)
15647     {
15648       errmsg ("missing interface name or sw_if_index");
15649       return -99;
15650     }
15651
15652   /* Construct the API message */
15653   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15654   mp->sw_if_index = ntohl (sw_if_index);
15655   mp->fib_id = ntohl (fib_id);
15656   mp->ip4 = ip4;
15657   mp->ip6 = ip6;
15658   mp->default_cop = default_cop;
15659
15660   /* send it... */
15661   S (mp);
15662   /* Wait for the reply */
15663   W (ret);
15664   return ret;
15665 }
15666
15667 static int
15668 api_get_node_graph (vat_main_t * vam)
15669 {
15670   vl_api_get_node_graph_t *mp;
15671   int ret;
15672
15673   M (GET_NODE_GRAPH, mp);
15674
15675   /* send it... */
15676   S (mp);
15677   /* Wait for the reply */
15678   W (ret);
15679   return ret;
15680 }
15681
15682 /* *INDENT-OFF* */
15683 /** Used for parsing LISP eids */
15684 typedef CLIB_PACKED(struct{
15685   u8 addr[16];   /**< eid address */
15686   u32 len;       /**< prefix length if IP */
15687   u8 type;      /**< type of eid */
15688 }) lisp_eid_vat_t;
15689 /* *INDENT-ON* */
15690
15691 static uword
15692 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15693 {
15694   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15695
15696   memset (a, 0, sizeof (a[0]));
15697
15698   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15699     {
15700       a->type = 0;              /* ipv4 type */
15701     }
15702   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15703     {
15704       a->type = 1;              /* ipv6 type */
15705     }
15706   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15707     {
15708       a->type = 2;              /* mac type */
15709     }
15710   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15711     {
15712       a->type = 3;              /* NSH type */
15713       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15714       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15715     }
15716   else
15717     {
15718       return 0;
15719     }
15720
15721   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15722     {
15723       return 0;
15724     }
15725
15726   return 1;
15727 }
15728
15729 static int
15730 lisp_eid_size_vat (u8 type)
15731 {
15732   switch (type)
15733     {
15734     case 0:
15735       return 4;
15736     case 1:
15737       return 16;
15738     case 2:
15739       return 6;
15740     case 3:
15741       return 5;
15742     }
15743   return 0;
15744 }
15745
15746 static void
15747 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15748 {
15749   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15750 }
15751
15752 static int
15753 api_one_add_del_locator_set (vat_main_t * vam)
15754 {
15755   unformat_input_t *input = vam->input;
15756   vl_api_one_add_del_locator_set_t *mp;
15757   u8 is_add = 1;
15758   u8 *locator_set_name = NULL;
15759   u8 locator_set_name_set = 0;
15760   vl_api_local_locator_t locator, *locators = 0;
15761   u32 sw_if_index, priority, weight;
15762   u32 data_len = 0;
15763
15764   int ret;
15765   /* Parse args required to build the message */
15766   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15767     {
15768       if (unformat (input, "del"))
15769         {
15770           is_add = 0;
15771         }
15772       else if (unformat (input, "locator-set %s", &locator_set_name))
15773         {
15774           locator_set_name_set = 1;
15775         }
15776       else if (unformat (input, "sw_if_index %u p %u w %u",
15777                          &sw_if_index, &priority, &weight))
15778         {
15779           locator.sw_if_index = htonl (sw_if_index);
15780           locator.priority = priority;
15781           locator.weight = weight;
15782           vec_add1 (locators, locator);
15783         }
15784       else
15785         if (unformat
15786             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15787              &sw_if_index, &priority, &weight))
15788         {
15789           locator.sw_if_index = htonl (sw_if_index);
15790           locator.priority = priority;
15791           locator.weight = weight;
15792           vec_add1 (locators, locator);
15793         }
15794       else
15795         break;
15796     }
15797
15798   if (locator_set_name_set == 0)
15799     {
15800       errmsg ("missing locator-set name");
15801       vec_free (locators);
15802       return -99;
15803     }
15804
15805   if (vec_len (locator_set_name) > 64)
15806     {
15807       errmsg ("locator-set name too long");
15808       vec_free (locator_set_name);
15809       vec_free (locators);
15810       return -99;
15811     }
15812   vec_add1 (locator_set_name, 0);
15813
15814   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15815
15816   /* Construct the API message */
15817   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15818
15819   mp->is_add = is_add;
15820   clib_memcpy (mp->locator_set_name, locator_set_name,
15821                vec_len (locator_set_name));
15822   vec_free (locator_set_name);
15823
15824   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15825   if (locators)
15826     clib_memcpy (mp->locators, locators, data_len);
15827   vec_free (locators);
15828
15829   /* send it... */
15830   S (mp);
15831
15832   /* Wait for a reply... */
15833   W (ret);
15834   return ret;
15835 }
15836
15837 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15838
15839 static int
15840 api_one_add_del_locator (vat_main_t * vam)
15841 {
15842   unformat_input_t *input = vam->input;
15843   vl_api_one_add_del_locator_t *mp;
15844   u32 tmp_if_index = ~0;
15845   u32 sw_if_index = ~0;
15846   u8 sw_if_index_set = 0;
15847   u8 sw_if_index_if_name_set = 0;
15848   u32 priority = ~0;
15849   u8 priority_set = 0;
15850   u32 weight = ~0;
15851   u8 weight_set = 0;
15852   u8 is_add = 1;
15853   u8 *locator_set_name = NULL;
15854   u8 locator_set_name_set = 0;
15855   int ret;
15856
15857   /* Parse args required to build the message */
15858   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15859     {
15860       if (unformat (input, "del"))
15861         {
15862           is_add = 0;
15863         }
15864       else if (unformat (input, "locator-set %s", &locator_set_name))
15865         {
15866           locator_set_name_set = 1;
15867         }
15868       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15869                          &tmp_if_index))
15870         {
15871           sw_if_index_if_name_set = 1;
15872           sw_if_index = tmp_if_index;
15873         }
15874       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15875         {
15876           sw_if_index_set = 1;
15877           sw_if_index = tmp_if_index;
15878         }
15879       else if (unformat (input, "p %d", &priority))
15880         {
15881           priority_set = 1;
15882         }
15883       else if (unformat (input, "w %d", &weight))
15884         {
15885           weight_set = 1;
15886         }
15887       else
15888         break;
15889     }
15890
15891   if (locator_set_name_set == 0)
15892     {
15893       errmsg ("missing locator-set name");
15894       return -99;
15895     }
15896
15897   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15898     {
15899       errmsg ("missing sw_if_index");
15900       vec_free (locator_set_name);
15901       return -99;
15902     }
15903
15904   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15905     {
15906       errmsg ("cannot use both params interface name and sw_if_index");
15907       vec_free (locator_set_name);
15908       return -99;
15909     }
15910
15911   if (priority_set == 0)
15912     {
15913       errmsg ("missing locator-set priority");
15914       vec_free (locator_set_name);
15915       return -99;
15916     }
15917
15918   if (weight_set == 0)
15919     {
15920       errmsg ("missing locator-set weight");
15921       vec_free (locator_set_name);
15922       return -99;
15923     }
15924
15925   if (vec_len (locator_set_name) > 64)
15926     {
15927       errmsg ("locator-set name too long");
15928       vec_free (locator_set_name);
15929       return -99;
15930     }
15931   vec_add1 (locator_set_name, 0);
15932
15933   /* Construct the API message */
15934   M (ONE_ADD_DEL_LOCATOR, mp);
15935
15936   mp->is_add = is_add;
15937   mp->sw_if_index = ntohl (sw_if_index);
15938   mp->priority = priority;
15939   mp->weight = weight;
15940   clib_memcpy (mp->locator_set_name, locator_set_name,
15941                vec_len (locator_set_name));
15942   vec_free (locator_set_name);
15943
15944   /* send it... */
15945   S (mp);
15946
15947   /* Wait for a reply... */
15948   W (ret);
15949   return ret;
15950 }
15951
15952 #define api_lisp_add_del_locator api_one_add_del_locator
15953
15954 uword
15955 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15956 {
15957   u32 *key_id = va_arg (*args, u32 *);
15958   u8 *s = 0;
15959
15960   if (unformat (input, "%s", &s))
15961     {
15962       if (!strcmp ((char *) s, "sha1"))
15963         key_id[0] = HMAC_SHA_1_96;
15964       else if (!strcmp ((char *) s, "sha256"))
15965         key_id[0] = HMAC_SHA_256_128;
15966       else
15967         {
15968           clib_warning ("invalid key_id: '%s'", s);
15969           key_id[0] = HMAC_NO_KEY;
15970         }
15971     }
15972   else
15973     return 0;
15974
15975   vec_free (s);
15976   return 1;
15977 }
15978
15979 static int
15980 api_one_add_del_local_eid (vat_main_t * vam)
15981 {
15982   unformat_input_t *input = vam->input;
15983   vl_api_one_add_del_local_eid_t *mp;
15984   u8 is_add = 1;
15985   u8 eid_set = 0;
15986   lisp_eid_vat_t _eid, *eid = &_eid;
15987   u8 *locator_set_name = 0;
15988   u8 locator_set_name_set = 0;
15989   u32 vni = 0;
15990   u16 key_id = 0;
15991   u8 *key = 0;
15992   int ret;
15993
15994   /* Parse args required to build the message */
15995   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15996     {
15997       if (unformat (input, "del"))
15998         {
15999           is_add = 0;
16000         }
16001       else if (unformat (input, "vni %d", &vni))
16002         {
16003           ;
16004         }
16005       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16006         {
16007           eid_set = 1;
16008         }
16009       else if (unformat (input, "locator-set %s", &locator_set_name))
16010         {
16011           locator_set_name_set = 1;
16012         }
16013       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
16014         ;
16015       else if (unformat (input, "secret-key %_%v%_", &key))
16016         ;
16017       else
16018         break;
16019     }
16020
16021   if (locator_set_name_set == 0)
16022     {
16023       errmsg ("missing locator-set name");
16024       return -99;
16025     }
16026
16027   if (0 == eid_set)
16028     {
16029       errmsg ("EID address not set!");
16030       vec_free (locator_set_name);
16031       return -99;
16032     }
16033
16034   if (key && (0 == key_id))
16035     {
16036       errmsg ("invalid key_id!");
16037       return -99;
16038     }
16039
16040   if (vec_len (key) > 64)
16041     {
16042       errmsg ("key too long");
16043       vec_free (key);
16044       return -99;
16045     }
16046
16047   if (vec_len (locator_set_name) > 64)
16048     {
16049       errmsg ("locator-set name too long");
16050       vec_free (locator_set_name);
16051       return -99;
16052     }
16053   vec_add1 (locator_set_name, 0);
16054
16055   /* Construct the API message */
16056   M (ONE_ADD_DEL_LOCAL_EID, mp);
16057
16058   mp->is_add = is_add;
16059   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16060   mp->eid_type = eid->type;
16061   mp->prefix_len = eid->len;
16062   mp->vni = clib_host_to_net_u32 (vni);
16063   mp->key_id = clib_host_to_net_u16 (key_id);
16064   clib_memcpy (mp->locator_set_name, locator_set_name,
16065                vec_len (locator_set_name));
16066   clib_memcpy (mp->key, key, vec_len (key));
16067
16068   vec_free (locator_set_name);
16069   vec_free (key);
16070
16071   /* send it... */
16072   S (mp);
16073
16074   /* Wait for a reply... */
16075   W (ret);
16076   return ret;
16077 }
16078
16079 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
16080
16081 static int
16082 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16083 {
16084   u32 dp_table = 0, vni = 0;;
16085   unformat_input_t *input = vam->input;
16086   vl_api_gpe_add_del_fwd_entry_t *mp;
16087   u8 is_add = 1;
16088   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
16089   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
16090   u8 rmt_eid_set = 0, lcl_eid_set = 0;
16091   u32 action = ~0, w;
16092   ip4_address_t rmt_rloc4, lcl_rloc4;
16093   ip6_address_t rmt_rloc6, lcl_rloc6;
16094   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
16095   int ret;
16096
16097   memset (&rloc, 0, sizeof (rloc));
16098
16099   /* Parse args required to build the message */
16100   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16101     {
16102       if (unformat (input, "del"))
16103         is_add = 0;
16104       else if (unformat (input, "add"))
16105         is_add = 1;
16106       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
16107         {
16108           rmt_eid_set = 1;
16109         }
16110       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
16111         {
16112           lcl_eid_set = 1;
16113         }
16114       else if (unformat (input, "vrf %d", &dp_table))
16115         ;
16116       else if (unformat (input, "bd %d", &dp_table))
16117         ;
16118       else if (unformat (input, "vni %d", &vni))
16119         ;
16120       else if (unformat (input, "w %d", &w))
16121         {
16122           if (!curr_rloc)
16123             {
16124               errmsg ("No RLOC configured for setting priority/weight!");
16125               return -99;
16126             }
16127           curr_rloc->weight = w;
16128         }
16129       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16130                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16131         {
16132           rloc.is_ip4 = 1;
16133
16134           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16135           rloc.weight = 0;
16136           vec_add1 (lcl_locs, rloc);
16137
16138           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16139           vec_add1 (rmt_locs, rloc);
16140           /* weight saved in rmt loc */
16141           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16142         }
16143       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16144                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16145         {
16146           rloc.is_ip4 = 0;
16147           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16148           rloc.weight = 0;
16149           vec_add1 (lcl_locs, rloc);
16150
16151           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16152           vec_add1 (rmt_locs, rloc);
16153           /* weight saved in rmt loc */
16154           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16155         }
16156       else if (unformat (input, "action %d", &action))
16157         {
16158           ;
16159         }
16160       else
16161         {
16162           clib_warning ("parse error '%U'", format_unformat_error, input);
16163           return -99;
16164         }
16165     }
16166
16167   if (!rmt_eid_set)
16168     {
16169       errmsg ("remote eid addresses not set");
16170       return -99;
16171     }
16172
16173   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16174     {
16175       errmsg ("eid types don't match");
16176       return -99;
16177     }
16178
16179   if (0 == rmt_locs && (u32) ~ 0 == action)
16180     {
16181       errmsg ("action not set for negative mapping");
16182       return -99;
16183     }
16184
16185   /* Construct the API message */
16186   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16187       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16188
16189   mp->is_add = is_add;
16190   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16191   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16192   mp->eid_type = rmt_eid->type;
16193   mp->dp_table = clib_host_to_net_u32 (dp_table);
16194   mp->vni = clib_host_to_net_u32 (vni);
16195   mp->rmt_len = rmt_eid->len;
16196   mp->lcl_len = lcl_eid->len;
16197   mp->action = action;
16198
16199   if (0 != rmt_locs && 0 != lcl_locs)
16200     {
16201       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16202       clib_memcpy (mp->locs, lcl_locs,
16203                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16204
16205       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16206       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16207                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16208     }
16209   vec_free (lcl_locs);
16210   vec_free (rmt_locs);
16211
16212   /* send it... */
16213   S (mp);
16214
16215   /* Wait for a reply... */
16216   W (ret);
16217   return ret;
16218 }
16219
16220 static int
16221 api_one_add_del_map_server (vat_main_t * vam)
16222 {
16223   unformat_input_t *input = vam->input;
16224   vl_api_one_add_del_map_server_t *mp;
16225   u8 is_add = 1;
16226   u8 ipv4_set = 0;
16227   u8 ipv6_set = 0;
16228   ip4_address_t ipv4;
16229   ip6_address_t ipv6;
16230   int ret;
16231
16232   /* Parse args required to build the message */
16233   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16234     {
16235       if (unformat (input, "del"))
16236         {
16237           is_add = 0;
16238         }
16239       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16240         {
16241           ipv4_set = 1;
16242         }
16243       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16244         {
16245           ipv6_set = 1;
16246         }
16247       else
16248         break;
16249     }
16250
16251   if (ipv4_set && ipv6_set)
16252     {
16253       errmsg ("both eid v4 and v6 addresses set");
16254       return -99;
16255     }
16256
16257   if (!ipv4_set && !ipv6_set)
16258     {
16259       errmsg ("eid addresses not set");
16260       return -99;
16261     }
16262
16263   /* Construct the API message */
16264   M (ONE_ADD_DEL_MAP_SERVER, mp);
16265
16266   mp->is_add = is_add;
16267   if (ipv6_set)
16268     {
16269       mp->is_ipv6 = 1;
16270       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16271     }
16272   else
16273     {
16274       mp->is_ipv6 = 0;
16275       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16276     }
16277
16278   /* send it... */
16279   S (mp);
16280
16281   /* Wait for a reply... */
16282   W (ret);
16283   return ret;
16284 }
16285
16286 #define api_lisp_add_del_map_server api_one_add_del_map_server
16287
16288 static int
16289 api_one_add_del_map_resolver (vat_main_t * vam)
16290 {
16291   unformat_input_t *input = vam->input;
16292   vl_api_one_add_del_map_resolver_t *mp;
16293   u8 is_add = 1;
16294   u8 ipv4_set = 0;
16295   u8 ipv6_set = 0;
16296   ip4_address_t ipv4;
16297   ip6_address_t ipv6;
16298   int ret;
16299
16300   /* Parse args required to build the message */
16301   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16302     {
16303       if (unformat (input, "del"))
16304         {
16305           is_add = 0;
16306         }
16307       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16308         {
16309           ipv4_set = 1;
16310         }
16311       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16312         {
16313           ipv6_set = 1;
16314         }
16315       else
16316         break;
16317     }
16318
16319   if (ipv4_set && ipv6_set)
16320     {
16321       errmsg ("both eid v4 and v6 addresses set");
16322       return -99;
16323     }
16324
16325   if (!ipv4_set && !ipv6_set)
16326     {
16327       errmsg ("eid addresses not set");
16328       return -99;
16329     }
16330
16331   /* Construct the API message */
16332   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16333
16334   mp->is_add = is_add;
16335   if (ipv6_set)
16336     {
16337       mp->is_ipv6 = 1;
16338       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16339     }
16340   else
16341     {
16342       mp->is_ipv6 = 0;
16343       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16344     }
16345
16346   /* send it... */
16347   S (mp);
16348
16349   /* Wait for a reply... */
16350   W (ret);
16351   return ret;
16352 }
16353
16354 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16355
16356 static int
16357 api_lisp_gpe_enable_disable (vat_main_t * vam)
16358 {
16359   unformat_input_t *input = vam->input;
16360   vl_api_gpe_enable_disable_t *mp;
16361   u8 is_set = 0;
16362   u8 is_en = 1;
16363   int ret;
16364
16365   /* Parse args required to build the message */
16366   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16367     {
16368       if (unformat (input, "enable"))
16369         {
16370           is_set = 1;
16371           is_en = 1;
16372         }
16373       else if (unformat (input, "disable"))
16374         {
16375           is_set = 1;
16376           is_en = 0;
16377         }
16378       else
16379         break;
16380     }
16381
16382   if (is_set == 0)
16383     {
16384       errmsg ("Value not set");
16385       return -99;
16386     }
16387
16388   /* Construct the API message */
16389   M (GPE_ENABLE_DISABLE, mp);
16390
16391   mp->is_en = is_en;
16392
16393   /* send it... */
16394   S (mp);
16395
16396   /* Wait for a reply... */
16397   W (ret);
16398   return ret;
16399 }
16400
16401 static int
16402 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16403 {
16404   unformat_input_t *input = vam->input;
16405   vl_api_one_rloc_probe_enable_disable_t *mp;
16406   u8 is_set = 0;
16407   u8 is_en = 0;
16408   int ret;
16409
16410   /* Parse args required to build the message */
16411   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16412     {
16413       if (unformat (input, "enable"))
16414         {
16415           is_set = 1;
16416           is_en = 1;
16417         }
16418       else if (unformat (input, "disable"))
16419         is_set = 1;
16420       else
16421         break;
16422     }
16423
16424   if (!is_set)
16425     {
16426       errmsg ("Value not set");
16427       return -99;
16428     }
16429
16430   /* Construct the API message */
16431   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16432
16433   mp->is_enabled = is_en;
16434
16435   /* send it... */
16436   S (mp);
16437
16438   /* Wait for a reply... */
16439   W (ret);
16440   return ret;
16441 }
16442
16443 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16444
16445 static int
16446 api_one_map_register_enable_disable (vat_main_t * vam)
16447 {
16448   unformat_input_t *input = vam->input;
16449   vl_api_one_map_register_enable_disable_t *mp;
16450   u8 is_set = 0;
16451   u8 is_en = 0;
16452   int ret;
16453
16454   /* Parse args required to build the message */
16455   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16456     {
16457       if (unformat (input, "enable"))
16458         {
16459           is_set = 1;
16460           is_en = 1;
16461         }
16462       else if (unformat (input, "disable"))
16463         is_set = 1;
16464       else
16465         break;
16466     }
16467
16468   if (!is_set)
16469     {
16470       errmsg ("Value not set");
16471       return -99;
16472     }
16473
16474   /* Construct the API message */
16475   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16476
16477   mp->is_enabled = is_en;
16478
16479   /* send it... */
16480   S (mp);
16481
16482   /* Wait for a reply... */
16483   W (ret);
16484   return ret;
16485 }
16486
16487 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16488
16489 static int
16490 api_one_enable_disable (vat_main_t * vam)
16491 {
16492   unformat_input_t *input = vam->input;
16493   vl_api_one_enable_disable_t *mp;
16494   u8 is_set = 0;
16495   u8 is_en = 0;
16496   int ret;
16497
16498   /* Parse args required to build the message */
16499   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16500     {
16501       if (unformat (input, "enable"))
16502         {
16503           is_set = 1;
16504           is_en = 1;
16505         }
16506       else if (unformat (input, "disable"))
16507         {
16508           is_set = 1;
16509         }
16510       else
16511         break;
16512     }
16513
16514   if (!is_set)
16515     {
16516       errmsg ("Value not set");
16517       return -99;
16518     }
16519
16520   /* Construct the API message */
16521   M (ONE_ENABLE_DISABLE, mp);
16522
16523   mp->is_en = is_en;
16524
16525   /* send it... */
16526   S (mp);
16527
16528   /* Wait for a reply... */
16529   W (ret);
16530   return ret;
16531 }
16532
16533 #define api_lisp_enable_disable api_one_enable_disable
16534
16535 static int
16536 api_one_enable_disable_xtr_mode (vat_main_t * vam)
16537 {
16538   unformat_input_t *input = vam->input;
16539   vl_api_one_enable_disable_xtr_mode_t *mp;
16540   u8 is_set = 0;
16541   u8 is_en = 0;
16542   int ret;
16543
16544   /* Parse args required to build the message */
16545   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16546     {
16547       if (unformat (input, "enable"))
16548         {
16549           is_set = 1;
16550           is_en = 1;
16551         }
16552       else if (unformat (input, "disable"))
16553         {
16554           is_set = 1;
16555         }
16556       else
16557         break;
16558     }
16559
16560   if (!is_set)
16561     {
16562       errmsg ("Value not set");
16563       return -99;
16564     }
16565
16566   /* Construct the API message */
16567   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16568
16569   mp->is_en = is_en;
16570
16571   /* send it... */
16572   S (mp);
16573
16574   /* Wait for a reply... */
16575   W (ret);
16576   return ret;
16577 }
16578
16579 static int
16580 api_one_show_xtr_mode (vat_main_t * vam)
16581 {
16582   vl_api_one_show_xtr_mode_t *mp;
16583   int ret;
16584
16585   /* Construct the API message */
16586   M (ONE_SHOW_XTR_MODE, mp);
16587
16588   /* send it... */
16589   S (mp);
16590
16591   /* Wait for a reply... */
16592   W (ret);
16593   return ret;
16594 }
16595
16596 static int
16597 api_one_enable_disable_pitr_mode (vat_main_t * vam)
16598 {
16599   unformat_input_t *input = vam->input;
16600   vl_api_one_enable_disable_pitr_mode_t *mp;
16601   u8 is_set = 0;
16602   u8 is_en = 0;
16603   int ret;
16604
16605   /* Parse args required to build the message */
16606   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16607     {
16608       if (unformat (input, "enable"))
16609         {
16610           is_set = 1;
16611           is_en = 1;
16612         }
16613       else if (unformat (input, "disable"))
16614         {
16615           is_set = 1;
16616         }
16617       else
16618         break;
16619     }
16620
16621   if (!is_set)
16622     {
16623       errmsg ("Value not set");
16624       return -99;
16625     }
16626
16627   /* Construct the API message */
16628   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
16629
16630   mp->is_en = is_en;
16631
16632   /* send it... */
16633   S (mp);
16634
16635   /* Wait for a reply... */
16636   W (ret);
16637   return ret;
16638 }
16639
16640 static int
16641 api_one_show_pitr_mode (vat_main_t * vam)
16642 {
16643   vl_api_one_show_pitr_mode_t *mp;
16644   int ret;
16645
16646   /* Construct the API message */
16647   M (ONE_SHOW_PITR_MODE, mp);
16648
16649   /* send it... */
16650   S (mp);
16651
16652   /* Wait for a reply... */
16653   W (ret);
16654   return ret;
16655 }
16656
16657 static int
16658 api_one_enable_disable_petr_mode (vat_main_t * vam)
16659 {
16660   unformat_input_t *input = vam->input;
16661   vl_api_one_enable_disable_petr_mode_t *mp;
16662   u8 is_set = 0;
16663   u8 is_en = 0;
16664   int ret;
16665
16666   /* Parse args required to build the message */
16667   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16668     {
16669       if (unformat (input, "enable"))
16670         {
16671           is_set = 1;
16672           is_en = 1;
16673         }
16674       else if (unformat (input, "disable"))
16675         {
16676           is_set = 1;
16677         }
16678       else
16679         break;
16680     }
16681
16682   if (!is_set)
16683     {
16684       errmsg ("Value not set");
16685       return -99;
16686     }
16687
16688   /* Construct the API message */
16689   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
16690
16691   mp->is_en = is_en;
16692
16693   /* send it... */
16694   S (mp);
16695
16696   /* Wait for a reply... */
16697   W (ret);
16698   return ret;
16699 }
16700
16701 static int
16702 api_one_show_petr_mode (vat_main_t * vam)
16703 {
16704   vl_api_one_show_petr_mode_t *mp;
16705   int ret;
16706
16707   /* Construct the API message */
16708   M (ONE_SHOW_PETR_MODE, mp);
16709
16710   /* send it... */
16711   S (mp);
16712
16713   /* Wait for a reply... */
16714   W (ret);
16715   return ret;
16716 }
16717
16718 static int
16719 api_show_one_map_register_state (vat_main_t * vam)
16720 {
16721   vl_api_show_one_map_register_state_t *mp;
16722   int ret;
16723
16724   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16725
16726   /* send */
16727   S (mp);
16728
16729   /* wait for reply */
16730   W (ret);
16731   return ret;
16732 }
16733
16734 #define api_show_lisp_map_register_state api_show_one_map_register_state
16735
16736 static int
16737 api_show_one_rloc_probe_state (vat_main_t * vam)
16738 {
16739   vl_api_show_one_rloc_probe_state_t *mp;
16740   int ret;
16741
16742   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16743
16744   /* send */
16745   S (mp);
16746
16747   /* wait for reply */
16748   W (ret);
16749   return ret;
16750 }
16751
16752 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16753
16754 static int
16755 api_one_add_del_ndp_entry (vat_main_t * vam)
16756 {
16757   vl_api_one_add_del_ndp_entry_t *mp;
16758   unformat_input_t *input = vam->input;
16759   u8 is_add = 1;
16760   u8 mac_set = 0;
16761   u8 bd_set = 0;
16762   u8 ip_set = 0;
16763   u8 mac[6] = { 0, };
16764   u8 ip6[16] = { 0, };
16765   u32 bd = ~0;
16766   int ret;
16767
16768   /* Parse args required to build the message */
16769   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16770     {
16771       if (unformat (input, "del"))
16772         is_add = 0;
16773       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16774         mac_set = 1;
16775       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16776         ip_set = 1;
16777       else if (unformat (input, "bd %d", &bd))
16778         bd_set = 1;
16779       else
16780         {
16781           errmsg ("parse error '%U'", format_unformat_error, input);
16782           return -99;
16783         }
16784     }
16785
16786   if (!bd_set || !ip_set || (!mac_set && is_add))
16787     {
16788       errmsg ("Missing BD, IP or MAC!");
16789       return -99;
16790     }
16791
16792   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16793   mp->is_add = is_add;
16794   clib_memcpy (mp->mac, mac, 6);
16795   mp->bd = clib_host_to_net_u32 (bd);
16796   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16797
16798   /* send */
16799   S (mp);
16800
16801   /* wait for reply */
16802   W (ret);
16803   return ret;
16804 }
16805
16806 static int
16807 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16808 {
16809   vl_api_one_add_del_l2_arp_entry_t *mp;
16810   unformat_input_t *input = vam->input;
16811   u8 is_add = 1;
16812   u8 mac_set = 0;
16813   u8 bd_set = 0;
16814   u8 ip_set = 0;
16815   u8 mac[6] = { 0, };
16816   u32 ip4 = 0, bd = ~0;
16817   int ret;
16818
16819   /* Parse args required to build the message */
16820   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16821     {
16822       if (unformat (input, "del"))
16823         is_add = 0;
16824       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16825         mac_set = 1;
16826       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16827         ip_set = 1;
16828       else if (unformat (input, "bd %d", &bd))
16829         bd_set = 1;
16830       else
16831         {
16832           errmsg ("parse error '%U'", format_unformat_error, input);
16833           return -99;
16834         }
16835     }
16836
16837   if (!bd_set || !ip_set || (!mac_set && is_add))
16838     {
16839       errmsg ("Missing BD, IP or MAC!");
16840       return -99;
16841     }
16842
16843   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16844   mp->is_add = is_add;
16845   clib_memcpy (mp->mac, mac, 6);
16846   mp->bd = clib_host_to_net_u32 (bd);
16847   mp->ip4 = ip4;
16848
16849   /* send */
16850   S (mp);
16851
16852   /* wait for reply */
16853   W (ret);
16854   return ret;
16855 }
16856
16857 static int
16858 api_one_ndp_bd_get (vat_main_t * vam)
16859 {
16860   vl_api_one_ndp_bd_get_t *mp;
16861   int ret;
16862
16863   M (ONE_NDP_BD_GET, mp);
16864
16865   /* send */
16866   S (mp);
16867
16868   /* wait for reply */
16869   W (ret);
16870   return ret;
16871 }
16872
16873 static int
16874 api_one_ndp_entries_get (vat_main_t * vam)
16875 {
16876   vl_api_one_ndp_entries_get_t *mp;
16877   unformat_input_t *input = vam->input;
16878   u8 bd_set = 0;
16879   u32 bd = ~0;
16880   int ret;
16881
16882   /* Parse args required to build the message */
16883   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16884     {
16885       if (unformat (input, "bd %d", &bd))
16886         bd_set = 1;
16887       else
16888         {
16889           errmsg ("parse error '%U'", format_unformat_error, input);
16890           return -99;
16891         }
16892     }
16893
16894   if (!bd_set)
16895     {
16896       errmsg ("Expected bridge domain!");
16897       return -99;
16898     }
16899
16900   M (ONE_NDP_ENTRIES_GET, mp);
16901   mp->bd = clib_host_to_net_u32 (bd);
16902
16903   /* send */
16904   S (mp);
16905
16906   /* wait for reply */
16907   W (ret);
16908   return ret;
16909 }
16910
16911 static int
16912 api_one_l2_arp_bd_get (vat_main_t * vam)
16913 {
16914   vl_api_one_l2_arp_bd_get_t *mp;
16915   int ret;
16916
16917   M (ONE_L2_ARP_BD_GET, mp);
16918
16919   /* send */
16920   S (mp);
16921
16922   /* wait for reply */
16923   W (ret);
16924   return ret;
16925 }
16926
16927 static int
16928 api_one_l2_arp_entries_get (vat_main_t * vam)
16929 {
16930   vl_api_one_l2_arp_entries_get_t *mp;
16931   unformat_input_t *input = vam->input;
16932   u8 bd_set = 0;
16933   u32 bd = ~0;
16934   int ret;
16935
16936   /* Parse args required to build the message */
16937   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16938     {
16939       if (unformat (input, "bd %d", &bd))
16940         bd_set = 1;
16941       else
16942         {
16943           errmsg ("parse error '%U'", format_unformat_error, input);
16944           return -99;
16945         }
16946     }
16947
16948   if (!bd_set)
16949     {
16950       errmsg ("Expected bridge domain!");
16951       return -99;
16952     }
16953
16954   M (ONE_L2_ARP_ENTRIES_GET, mp);
16955   mp->bd = clib_host_to_net_u32 (bd);
16956
16957   /* send */
16958   S (mp);
16959
16960   /* wait for reply */
16961   W (ret);
16962   return ret;
16963 }
16964
16965 static int
16966 api_one_stats_enable_disable (vat_main_t * vam)
16967 {
16968   vl_api_one_stats_enable_disable_t *mp;
16969   unformat_input_t *input = vam->input;
16970   u8 is_set = 0;
16971   u8 is_en = 0;
16972   int ret;
16973
16974   /* Parse args required to build the message */
16975   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16976     {
16977       if (unformat (input, "enable"))
16978         {
16979           is_set = 1;
16980           is_en = 1;
16981         }
16982       else if (unformat (input, "disable"))
16983         {
16984           is_set = 1;
16985         }
16986       else
16987         break;
16988     }
16989
16990   if (!is_set)
16991     {
16992       errmsg ("Value not set");
16993       return -99;
16994     }
16995
16996   M (ONE_STATS_ENABLE_DISABLE, mp);
16997   mp->is_en = is_en;
16998
16999   /* send */
17000   S (mp);
17001
17002   /* wait for reply */
17003   W (ret);
17004   return ret;
17005 }
17006
17007 static int
17008 api_show_one_stats_enable_disable (vat_main_t * vam)
17009 {
17010   vl_api_show_one_stats_enable_disable_t *mp;
17011   int ret;
17012
17013   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
17014
17015   /* send */
17016   S (mp);
17017
17018   /* wait for reply */
17019   W (ret);
17020   return ret;
17021 }
17022
17023 static int
17024 api_show_one_map_request_mode (vat_main_t * vam)
17025 {
17026   vl_api_show_one_map_request_mode_t *mp;
17027   int ret;
17028
17029   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
17030
17031   /* send */
17032   S (mp);
17033
17034   /* wait for reply */
17035   W (ret);
17036   return ret;
17037 }
17038
17039 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
17040
17041 static int
17042 api_one_map_request_mode (vat_main_t * vam)
17043 {
17044   unformat_input_t *input = vam->input;
17045   vl_api_one_map_request_mode_t *mp;
17046   u8 mode = 0;
17047   int ret;
17048
17049   /* Parse args required to build the message */
17050   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17051     {
17052       if (unformat (input, "dst-only"))
17053         mode = 0;
17054       else if (unformat (input, "src-dst"))
17055         mode = 1;
17056       else
17057         {
17058           errmsg ("parse error '%U'", format_unformat_error, input);
17059           return -99;
17060         }
17061     }
17062
17063   M (ONE_MAP_REQUEST_MODE, mp);
17064
17065   mp->mode = mode;
17066
17067   /* send */
17068   S (mp);
17069
17070   /* wait for reply */
17071   W (ret);
17072   return ret;
17073 }
17074
17075 #define api_lisp_map_request_mode api_one_map_request_mode
17076
17077 /**
17078  * Enable/disable ONE proxy ITR.
17079  *
17080  * @param vam vpp API test context
17081  * @return return code
17082  */
17083 static int
17084 api_one_pitr_set_locator_set (vat_main_t * vam)
17085 {
17086   u8 ls_name_set = 0;
17087   unformat_input_t *input = vam->input;
17088   vl_api_one_pitr_set_locator_set_t *mp;
17089   u8 is_add = 1;
17090   u8 *ls_name = 0;
17091   int ret;
17092
17093   /* Parse args required to build the message */
17094   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17095     {
17096       if (unformat (input, "del"))
17097         is_add = 0;
17098       else if (unformat (input, "locator-set %s", &ls_name))
17099         ls_name_set = 1;
17100       else
17101         {
17102           errmsg ("parse error '%U'", format_unformat_error, input);
17103           return -99;
17104         }
17105     }
17106
17107   if (!ls_name_set)
17108     {
17109       errmsg ("locator-set name not set!");
17110       return -99;
17111     }
17112
17113   M (ONE_PITR_SET_LOCATOR_SET, mp);
17114
17115   mp->is_add = is_add;
17116   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17117   vec_free (ls_name);
17118
17119   /* send */
17120   S (mp);
17121
17122   /* wait for reply */
17123   W (ret);
17124   return ret;
17125 }
17126
17127 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17128
17129 static int
17130 api_one_nsh_set_locator_set (vat_main_t * vam)
17131 {
17132   u8 ls_name_set = 0;
17133   unformat_input_t *input = vam->input;
17134   vl_api_one_nsh_set_locator_set_t *mp;
17135   u8 is_add = 1;
17136   u8 *ls_name = 0;
17137   int ret;
17138
17139   /* Parse args required to build the message */
17140   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17141     {
17142       if (unformat (input, "del"))
17143         is_add = 0;
17144       else if (unformat (input, "ls %s", &ls_name))
17145         ls_name_set = 1;
17146       else
17147         {
17148           errmsg ("parse error '%U'", format_unformat_error, input);
17149           return -99;
17150         }
17151     }
17152
17153   if (!ls_name_set && is_add)
17154     {
17155       errmsg ("locator-set name not set!");
17156       return -99;
17157     }
17158
17159   M (ONE_NSH_SET_LOCATOR_SET, mp);
17160
17161   mp->is_add = is_add;
17162   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17163   vec_free (ls_name);
17164
17165   /* send */
17166   S (mp);
17167
17168   /* wait for reply */
17169   W (ret);
17170   return ret;
17171 }
17172
17173 static int
17174 api_show_one_pitr (vat_main_t * vam)
17175 {
17176   vl_api_show_one_pitr_t *mp;
17177   int ret;
17178
17179   if (!vam->json_output)
17180     {
17181       print (vam->ofp, "%=20s", "lisp status:");
17182     }
17183
17184   M (SHOW_ONE_PITR, mp);
17185   /* send it... */
17186   S (mp);
17187
17188   /* Wait for a reply... */
17189   W (ret);
17190   return ret;
17191 }
17192
17193 #define api_show_lisp_pitr api_show_one_pitr
17194
17195 static int
17196 api_one_use_petr (vat_main_t * vam)
17197 {
17198   unformat_input_t *input = vam->input;
17199   vl_api_one_use_petr_t *mp;
17200   u8 is_add = 0;
17201   ip_address_t ip;
17202   int ret;
17203
17204   memset (&ip, 0, sizeof (ip));
17205
17206   /* Parse args required to build the message */
17207   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17208     {
17209       if (unformat (input, "disable"))
17210         is_add = 0;
17211       else
17212         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17213         {
17214           is_add = 1;
17215           ip_addr_version (&ip) = IP4;
17216         }
17217       else
17218         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17219         {
17220           is_add = 1;
17221           ip_addr_version (&ip) = IP6;
17222         }
17223       else
17224         {
17225           errmsg ("parse error '%U'", format_unformat_error, input);
17226           return -99;
17227         }
17228     }
17229
17230   M (ONE_USE_PETR, mp);
17231
17232   mp->is_add = is_add;
17233   if (is_add)
17234     {
17235       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17236       if (mp->is_ip4)
17237         clib_memcpy (mp->address, &ip, 4);
17238       else
17239         clib_memcpy (mp->address, &ip, 16);
17240     }
17241
17242   /* send */
17243   S (mp);
17244
17245   /* wait for reply */
17246   W (ret);
17247   return ret;
17248 }
17249
17250 #define api_lisp_use_petr api_one_use_petr
17251
17252 static int
17253 api_show_one_nsh_mapping (vat_main_t * vam)
17254 {
17255   vl_api_show_one_use_petr_t *mp;
17256   int ret;
17257
17258   if (!vam->json_output)
17259     {
17260       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17261     }
17262
17263   M (SHOW_ONE_NSH_MAPPING, mp);
17264   /* send it... */
17265   S (mp);
17266
17267   /* Wait for a reply... */
17268   W (ret);
17269   return ret;
17270 }
17271
17272 static int
17273 api_show_one_use_petr (vat_main_t * vam)
17274 {
17275   vl_api_show_one_use_petr_t *mp;
17276   int ret;
17277
17278   if (!vam->json_output)
17279     {
17280       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17281     }
17282
17283   M (SHOW_ONE_USE_PETR, mp);
17284   /* send it... */
17285   S (mp);
17286
17287   /* Wait for a reply... */
17288   W (ret);
17289   return ret;
17290 }
17291
17292 #define api_show_lisp_use_petr api_show_one_use_petr
17293
17294 /**
17295  * Add/delete mapping between vni and vrf
17296  */
17297 static int
17298 api_one_eid_table_add_del_map (vat_main_t * vam)
17299 {
17300   unformat_input_t *input = vam->input;
17301   vl_api_one_eid_table_add_del_map_t *mp;
17302   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17303   u32 vni, vrf, bd_index;
17304   int ret;
17305
17306   /* Parse args required to build the message */
17307   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17308     {
17309       if (unformat (input, "del"))
17310         is_add = 0;
17311       else if (unformat (input, "vrf %d", &vrf))
17312         vrf_set = 1;
17313       else if (unformat (input, "bd_index %d", &bd_index))
17314         bd_index_set = 1;
17315       else if (unformat (input, "vni %d", &vni))
17316         vni_set = 1;
17317       else
17318         break;
17319     }
17320
17321   if (!vni_set || (!vrf_set && !bd_index_set))
17322     {
17323       errmsg ("missing arguments!");
17324       return -99;
17325     }
17326
17327   if (vrf_set && bd_index_set)
17328     {
17329       errmsg ("error: both vrf and bd entered!");
17330       return -99;
17331     }
17332
17333   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
17334
17335   mp->is_add = is_add;
17336   mp->vni = htonl (vni);
17337   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
17338   mp->is_l2 = bd_index_set;
17339
17340   /* send */
17341   S (mp);
17342
17343   /* wait for reply */
17344   W (ret);
17345   return ret;
17346 }
17347
17348 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
17349
17350 uword
17351 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
17352 {
17353   u32 *action = va_arg (*args, u32 *);
17354   u8 *s = 0;
17355
17356   if (unformat (input, "%s", &s))
17357     {
17358       if (!strcmp ((char *) s, "no-action"))
17359         action[0] = 0;
17360       else if (!strcmp ((char *) s, "natively-forward"))
17361         action[0] = 1;
17362       else if (!strcmp ((char *) s, "send-map-request"))
17363         action[0] = 2;
17364       else if (!strcmp ((char *) s, "drop"))
17365         action[0] = 3;
17366       else
17367         {
17368           clib_warning ("invalid action: '%s'", s);
17369           action[0] = 3;
17370         }
17371     }
17372   else
17373     return 0;
17374
17375   vec_free (s);
17376   return 1;
17377 }
17378
17379 /**
17380  * Add/del remote mapping to/from ONE control plane
17381  *
17382  * @param vam vpp API test context
17383  * @return return code
17384  */
17385 static int
17386 api_one_add_del_remote_mapping (vat_main_t * vam)
17387 {
17388   unformat_input_t *input = vam->input;
17389   vl_api_one_add_del_remote_mapping_t *mp;
17390   u32 vni = 0;
17391   lisp_eid_vat_t _eid, *eid = &_eid;
17392   lisp_eid_vat_t _seid, *seid = &_seid;
17393   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
17394   u32 action = ~0, p, w, data_len;
17395   ip4_address_t rloc4;
17396   ip6_address_t rloc6;
17397   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
17398   int ret;
17399
17400   memset (&rloc, 0, sizeof (rloc));
17401
17402   /* Parse args required to build the message */
17403   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17404     {
17405       if (unformat (input, "del-all"))
17406         {
17407           del_all = 1;
17408         }
17409       else if (unformat (input, "del"))
17410         {
17411           is_add = 0;
17412         }
17413       else if (unformat (input, "add"))
17414         {
17415           is_add = 1;
17416         }
17417       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17418         {
17419           eid_set = 1;
17420         }
17421       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
17422         {
17423           seid_set = 1;
17424         }
17425       else if (unformat (input, "vni %d", &vni))
17426         {
17427           ;
17428         }
17429       else if (unformat (input, "p %d w %d", &p, &w))
17430         {
17431           if (!curr_rloc)
17432             {
17433               errmsg ("No RLOC configured for setting priority/weight!");
17434               return -99;
17435             }
17436           curr_rloc->priority = p;
17437           curr_rloc->weight = w;
17438         }
17439       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
17440         {
17441           rloc.is_ip4 = 1;
17442           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17443           vec_add1 (rlocs, rloc);
17444           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17445         }
17446       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
17447         {
17448           rloc.is_ip4 = 0;
17449           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17450           vec_add1 (rlocs, rloc);
17451           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17452         }
17453       else if (unformat (input, "action %U",
17454                          unformat_negative_mapping_action, &action))
17455         {
17456           ;
17457         }
17458       else
17459         {
17460           clib_warning ("parse error '%U'", format_unformat_error, input);
17461           return -99;
17462         }
17463     }
17464
17465   if (0 == eid_set)
17466     {
17467       errmsg ("missing params!");
17468       return -99;
17469     }
17470
17471   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17472     {
17473       errmsg ("no action set for negative map-reply!");
17474       return -99;
17475     }
17476
17477   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17478
17479   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17480   mp->is_add = is_add;
17481   mp->vni = htonl (vni);
17482   mp->action = (u8) action;
17483   mp->is_src_dst = seid_set;
17484   mp->eid_len = eid->len;
17485   mp->seid_len = seid->len;
17486   mp->del_all = del_all;
17487   mp->eid_type = eid->type;
17488   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17489   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17490
17491   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17492   clib_memcpy (mp->rlocs, rlocs, data_len);
17493   vec_free (rlocs);
17494
17495   /* send it... */
17496   S (mp);
17497
17498   /* Wait for a reply... */
17499   W (ret);
17500   return ret;
17501 }
17502
17503 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17504
17505 /**
17506  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17507  * forwarding entries in data-plane accordingly.
17508  *
17509  * @param vam vpp API test context
17510  * @return return code
17511  */
17512 static int
17513 api_one_add_del_adjacency (vat_main_t * vam)
17514 {
17515   unformat_input_t *input = vam->input;
17516   vl_api_one_add_del_adjacency_t *mp;
17517   u32 vni = 0;
17518   ip4_address_t leid4, reid4;
17519   ip6_address_t leid6, reid6;
17520   u8 reid_mac[6] = { 0 };
17521   u8 leid_mac[6] = { 0 };
17522   u8 reid_type, leid_type;
17523   u32 leid_len = 0, reid_len = 0, len;
17524   u8 is_add = 1;
17525   int ret;
17526
17527   leid_type = reid_type = (u8) ~ 0;
17528
17529   /* Parse args required to build the message */
17530   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17531     {
17532       if (unformat (input, "del"))
17533         {
17534           is_add = 0;
17535         }
17536       else if (unformat (input, "add"))
17537         {
17538           is_add = 1;
17539         }
17540       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17541                          &reid4, &len))
17542         {
17543           reid_type = 0;        /* ipv4 */
17544           reid_len = len;
17545         }
17546       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17547                          &reid6, &len))
17548         {
17549           reid_type = 1;        /* ipv6 */
17550           reid_len = len;
17551         }
17552       else if (unformat (input, "reid %U", unformat_ethernet_address,
17553                          reid_mac))
17554         {
17555           reid_type = 2;        /* mac */
17556         }
17557       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17558                          &leid4, &len))
17559         {
17560           leid_type = 0;        /* ipv4 */
17561           leid_len = len;
17562         }
17563       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17564                          &leid6, &len))
17565         {
17566           leid_type = 1;        /* ipv6 */
17567           leid_len = len;
17568         }
17569       else if (unformat (input, "leid %U", unformat_ethernet_address,
17570                          leid_mac))
17571         {
17572           leid_type = 2;        /* mac */
17573         }
17574       else if (unformat (input, "vni %d", &vni))
17575         {
17576           ;
17577         }
17578       else
17579         {
17580           errmsg ("parse error '%U'", format_unformat_error, input);
17581           return -99;
17582         }
17583     }
17584
17585   if ((u8) ~ 0 == reid_type)
17586     {
17587       errmsg ("missing params!");
17588       return -99;
17589     }
17590
17591   if (leid_type != reid_type)
17592     {
17593       errmsg ("remote and local EIDs are of different types!");
17594       return -99;
17595     }
17596
17597   M (ONE_ADD_DEL_ADJACENCY, mp);
17598   mp->is_add = is_add;
17599   mp->vni = htonl (vni);
17600   mp->leid_len = leid_len;
17601   mp->reid_len = reid_len;
17602   mp->eid_type = reid_type;
17603
17604   switch (mp->eid_type)
17605     {
17606     case 0:
17607       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17608       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17609       break;
17610     case 1:
17611       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17612       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17613       break;
17614     case 2:
17615       clib_memcpy (mp->leid, leid_mac, 6);
17616       clib_memcpy (mp->reid, reid_mac, 6);
17617       break;
17618     default:
17619       errmsg ("unknown EID type %d!", mp->eid_type);
17620       return 0;
17621     }
17622
17623   /* send it... */
17624   S (mp);
17625
17626   /* Wait for a reply... */
17627   W (ret);
17628   return ret;
17629 }
17630
17631 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17632
17633 uword
17634 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17635 {
17636   u32 *mode = va_arg (*args, u32 *);
17637
17638   if (unformat (input, "lisp"))
17639     *mode = 0;
17640   else if (unformat (input, "vxlan"))
17641     *mode = 1;
17642   else
17643     return 0;
17644
17645   return 1;
17646 }
17647
17648 static int
17649 api_gpe_get_encap_mode (vat_main_t * vam)
17650 {
17651   vl_api_gpe_get_encap_mode_t *mp;
17652   int ret;
17653
17654   /* Construct the API message */
17655   M (GPE_GET_ENCAP_MODE, mp);
17656
17657   /* send it... */
17658   S (mp);
17659
17660   /* Wait for a reply... */
17661   W (ret);
17662   return ret;
17663 }
17664
17665 static int
17666 api_gpe_set_encap_mode (vat_main_t * vam)
17667 {
17668   unformat_input_t *input = vam->input;
17669   vl_api_gpe_set_encap_mode_t *mp;
17670   int ret;
17671   u32 mode = 0;
17672
17673   /* Parse args required to build the message */
17674   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17675     {
17676       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17677         ;
17678       else
17679         break;
17680     }
17681
17682   /* Construct the API message */
17683   M (GPE_SET_ENCAP_MODE, mp);
17684
17685   mp->mode = mode;
17686
17687   /* send it... */
17688   S (mp);
17689
17690   /* Wait for a reply... */
17691   W (ret);
17692   return ret;
17693 }
17694
17695 static int
17696 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17697 {
17698   unformat_input_t *input = vam->input;
17699   vl_api_gpe_add_del_iface_t *mp;
17700   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17701   u32 dp_table = 0, vni = 0;
17702   int ret;
17703
17704   /* Parse args required to build the message */
17705   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17706     {
17707       if (unformat (input, "up"))
17708         {
17709           action_set = 1;
17710           is_add = 1;
17711         }
17712       else if (unformat (input, "down"))
17713         {
17714           action_set = 1;
17715           is_add = 0;
17716         }
17717       else if (unformat (input, "table_id %d", &dp_table))
17718         {
17719           dp_table_set = 1;
17720         }
17721       else if (unformat (input, "bd_id %d", &dp_table))
17722         {
17723           dp_table_set = 1;
17724           is_l2 = 1;
17725         }
17726       else if (unformat (input, "vni %d", &vni))
17727         {
17728           vni_set = 1;
17729         }
17730       else
17731         break;
17732     }
17733
17734   if (action_set == 0)
17735     {
17736       errmsg ("Action not set");
17737       return -99;
17738     }
17739   if (dp_table_set == 0 || vni_set == 0)
17740     {
17741       errmsg ("vni and dp_table must be set");
17742       return -99;
17743     }
17744
17745   /* Construct the API message */
17746   M (GPE_ADD_DEL_IFACE, mp);
17747
17748   mp->is_add = is_add;
17749   mp->dp_table = clib_host_to_net_u32 (dp_table);
17750   mp->is_l2 = is_l2;
17751   mp->vni = clib_host_to_net_u32 (vni);
17752
17753   /* send it... */
17754   S (mp);
17755
17756   /* Wait for a reply... */
17757   W (ret);
17758   return ret;
17759 }
17760
17761 static int
17762 api_one_map_register_fallback_threshold (vat_main_t * vam)
17763 {
17764   unformat_input_t *input = vam->input;
17765   vl_api_one_map_register_fallback_threshold_t *mp;
17766   u32 value = 0;
17767   u8 is_set = 0;
17768   int ret;
17769
17770   /* Parse args required to build the message */
17771   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17772     {
17773       if (unformat (input, "%u", &value))
17774         is_set = 1;
17775       else
17776         {
17777           clib_warning ("parse error '%U'", format_unformat_error, input);
17778           return -99;
17779         }
17780     }
17781
17782   if (!is_set)
17783     {
17784       errmsg ("fallback threshold value is missing!");
17785       return -99;
17786     }
17787
17788   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17789   mp->value = clib_host_to_net_u32 (value);
17790
17791   /* send it... */
17792   S (mp);
17793
17794   /* Wait for a reply... */
17795   W (ret);
17796   return ret;
17797 }
17798
17799 static int
17800 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17801 {
17802   vl_api_show_one_map_register_fallback_threshold_t *mp;
17803   int ret;
17804
17805   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17806
17807   /* send it... */
17808   S (mp);
17809
17810   /* Wait for a reply... */
17811   W (ret);
17812   return ret;
17813 }
17814
17815 uword
17816 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17817 {
17818   u32 *proto = va_arg (*args, u32 *);
17819
17820   if (unformat (input, "udp"))
17821     *proto = 1;
17822   else if (unformat (input, "api"))
17823     *proto = 2;
17824   else
17825     return 0;
17826
17827   return 1;
17828 }
17829
17830 static int
17831 api_one_set_transport_protocol (vat_main_t * vam)
17832 {
17833   unformat_input_t *input = vam->input;
17834   vl_api_one_set_transport_protocol_t *mp;
17835   u8 is_set = 0;
17836   u32 protocol = 0;
17837   int ret;
17838
17839   /* Parse args required to build the message */
17840   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17841     {
17842       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17843         is_set = 1;
17844       else
17845         {
17846           clib_warning ("parse error '%U'", format_unformat_error, input);
17847           return -99;
17848         }
17849     }
17850
17851   if (!is_set)
17852     {
17853       errmsg ("Transport protocol missing!");
17854       return -99;
17855     }
17856
17857   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17858   mp->protocol = (u8) protocol;
17859
17860   /* send it... */
17861   S (mp);
17862
17863   /* Wait for a reply... */
17864   W (ret);
17865   return ret;
17866 }
17867
17868 static int
17869 api_one_get_transport_protocol (vat_main_t * vam)
17870 {
17871   vl_api_one_get_transport_protocol_t *mp;
17872   int ret;
17873
17874   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17875
17876   /* send it... */
17877   S (mp);
17878
17879   /* Wait for a reply... */
17880   W (ret);
17881   return ret;
17882 }
17883
17884 static int
17885 api_one_map_register_set_ttl (vat_main_t * vam)
17886 {
17887   unformat_input_t *input = vam->input;
17888   vl_api_one_map_register_set_ttl_t *mp;
17889   u32 ttl = 0;
17890   u8 is_set = 0;
17891   int ret;
17892
17893   /* Parse args required to build the message */
17894   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17895     {
17896       if (unformat (input, "%u", &ttl))
17897         is_set = 1;
17898       else
17899         {
17900           clib_warning ("parse error '%U'", format_unformat_error, input);
17901           return -99;
17902         }
17903     }
17904
17905   if (!is_set)
17906     {
17907       errmsg ("TTL value missing!");
17908       return -99;
17909     }
17910
17911   M (ONE_MAP_REGISTER_SET_TTL, mp);
17912   mp->ttl = clib_host_to_net_u32 (ttl);
17913
17914   /* send it... */
17915   S (mp);
17916
17917   /* Wait for a reply... */
17918   W (ret);
17919   return ret;
17920 }
17921
17922 static int
17923 api_show_one_map_register_ttl (vat_main_t * vam)
17924 {
17925   vl_api_show_one_map_register_ttl_t *mp;
17926   int ret;
17927
17928   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17929
17930   /* send it... */
17931   S (mp);
17932
17933   /* Wait for a reply... */
17934   W (ret);
17935   return ret;
17936 }
17937
17938 /**
17939  * Add/del map request itr rlocs from ONE control plane and updates
17940  *
17941  * @param vam vpp API test context
17942  * @return return code
17943  */
17944 static int
17945 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17946 {
17947   unformat_input_t *input = vam->input;
17948   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17949   u8 *locator_set_name = 0;
17950   u8 locator_set_name_set = 0;
17951   u8 is_add = 1;
17952   int ret;
17953
17954   /* Parse args required to build the message */
17955   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17956     {
17957       if (unformat (input, "del"))
17958         {
17959           is_add = 0;
17960         }
17961       else if (unformat (input, "%_%v%_", &locator_set_name))
17962         {
17963           locator_set_name_set = 1;
17964         }
17965       else
17966         {
17967           clib_warning ("parse error '%U'", format_unformat_error, input);
17968           return -99;
17969         }
17970     }
17971
17972   if (is_add && !locator_set_name_set)
17973     {
17974       errmsg ("itr-rloc is not set!");
17975       return -99;
17976     }
17977
17978   if (is_add && vec_len (locator_set_name) > 64)
17979     {
17980       errmsg ("itr-rloc locator-set name too long");
17981       vec_free (locator_set_name);
17982       return -99;
17983     }
17984
17985   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17986   mp->is_add = is_add;
17987   if (is_add)
17988     {
17989       clib_memcpy (mp->locator_set_name, locator_set_name,
17990                    vec_len (locator_set_name));
17991     }
17992   else
17993     {
17994       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17995     }
17996   vec_free (locator_set_name);
17997
17998   /* send it... */
17999   S (mp);
18000
18001   /* Wait for a reply... */
18002   W (ret);
18003   return ret;
18004 }
18005
18006 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18007
18008 static int
18009 api_one_locator_dump (vat_main_t * vam)
18010 {
18011   unformat_input_t *input = vam->input;
18012   vl_api_one_locator_dump_t *mp;
18013   vl_api_control_ping_t *mp_ping;
18014   u8 is_index_set = 0, is_name_set = 0;
18015   u8 *ls_name = 0;
18016   u32 ls_index = ~0;
18017   int ret;
18018
18019   /* Parse args required to build the message */
18020   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18021     {
18022       if (unformat (input, "ls_name %_%v%_", &ls_name))
18023         {
18024           is_name_set = 1;
18025         }
18026       else if (unformat (input, "ls_index %d", &ls_index))
18027         {
18028           is_index_set = 1;
18029         }
18030       else
18031         {
18032           errmsg ("parse error '%U'", format_unformat_error, input);
18033           return -99;
18034         }
18035     }
18036
18037   if (!is_index_set && !is_name_set)
18038     {
18039       errmsg ("error: expected one of index or name!");
18040       return -99;
18041     }
18042
18043   if (is_index_set && is_name_set)
18044     {
18045       errmsg ("error: only one param expected!");
18046       return -99;
18047     }
18048
18049   if (vec_len (ls_name) > 62)
18050     {
18051       errmsg ("error: locator set name too long!");
18052       return -99;
18053     }
18054
18055   if (!vam->json_output)
18056     {
18057       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
18058     }
18059
18060   M (ONE_LOCATOR_DUMP, mp);
18061   mp->is_index_set = is_index_set;
18062
18063   if (is_index_set)
18064     mp->ls_index = clib_host_to_net_u32 (ls_index);
18065   else
18066     {
18067       vec_add1 (ls_name, 0);
18068       strncpy ((char *) mp->ls_name, (char *) ls_name,
18069                sizeof (mp->ls_name) - 1);
18070     }
18071
18072   /* send it... */
18073   S (mp);
18074
18075   /* Use a control ping for synchronization */
18076   MPING (CONTROL_PING, mp_ping);
18077   S (mp_ping);
18078
18079   /* Wait for a reply... */
18080   W (ret);
18081   return ret;
18082 }
18083
18084 #define api_lisp_locator_dump api_one_locator_dump
18085
18086 static int
18087 api_one_locator_set_dump (vat_main_t * vam)
18088 {
18089   vl_api_one_locator_set_dump_t *mp;
18090   vl_api_control_ping_t *mp_ping;
18091   unformat_input_t *input = vam->input;
18092   u8 filter = 0;
18093   int ret;
18094
18095   /* Parse args required to build the message */
18096   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18097     {
18098       if (unformat (input, "local"))
18099         {
18100           filter = 1;
18101         }
18102       else if (unformat (input, "remote"))
18103         {
18104           filter = 2;
18105         }
18106       else
18107         {
18108           errmsg ("parse error '%U'", format_unformat_error, input);
18109           return -99;
18110         }
18111     }
18112
18113   if (!vam->json_output)
18114     {
18115       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
18116     }
18117
18118   M (ONE_LOCATOR_SET_DUMP, mp);
18119
18120   mp->filter = filter;
18121
18122   /* send it... */
18123   S (mp);
18124
18125   /* Use a control ping for synchronization */
18126   MPING (CONTROL_PING, mp_ping);
18127   S (mp_ping);
18128
18129   /* Wait for a reply... */
18130   W (ret);
18131   return ret;
18132 }
18133
18134 #define api_lisp_locator_set_dump api_one_locator_set_dump
18135
18136 static int
18137 api_one_eid_table_map_dump (vat_main_t * vam)
18138 {
18139   u8 is_l2 = 0;
18140   u8 mode_set = 0;
18141   unformat_input_t *input = vam->input;
18142   vl_api_one_eid_table_map_dump_t *mp;
18143   vl_api_control_ping_t *mp_ping;
18144   int ret;
18145
18146   /* Parse args required to build the message */
18147   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18148     {
18149       if (unformat (input, "l2"))
18150         {
18151           is_l2 = 1;
18152           mode_set = 1;
18153         }
18154       else if (unformat (input, "l3"))
18155         {
18156           is_l2 = 0;
18157           mode_set = 1;
18158         }
18159       else
18160         {
18161           errmsg ("parse error '%U'", format_unformat_error, input);
18162           return -99;
18163         }
18164     }
18165
18166   if (!mode_set)
18167     {
18168       errmsg ("expected one of 'l2' or 'l3' parameter!");
18169       return -99;
18170     }
18171
18172   if (!vam->json_output)
18173     {
18174       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18175     }
18176
18177   M (ONE_EID_TABLE_MAP_DUMP, mp);
18178   mp->is_l2 = is_l2;
18179
18180   /* send it... */
18181   S (mp);
18182
18183   /* Use a control ping for synchronization */
18184   MPING (CONTROL_PING, mp_ping);
18185   S (mp_ping);
18186
18187   /* Wait for a reply... */
18188   W (ret);
18189   return ret;
18190 }
18191
18192 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18193
18194 static int
18195 api_one_eid_table_vni_dump (vat_main_t * vam)
18196 {
18197   vl_api_one_eid_table_vni_dump_t *mp;
18198   vl_api_control_ping_t *mp_ping;
18199   int ret;
18200
18201   if (!vam->json_output)
18202     {
18203       print (vam->ofp, "VNI");
18204     }
18205
18206   M (ONE_EID_TABLE_VNI_DUMP, mp);
18207
18208   /* send it... */
18209   S (mp);
18210
18211   /* Use a control ping for synchronization */
18212   MPING (CONTROL_PING, mp_ping);
18213   S (mp_ping);
18214
18215   /* Wait for a reply... */
18216   W (ret);
18217   return ret;
18218 }
18219
18220 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18221
18222 static int
18223 api_one_eid_table_dump (vat_main_t * vam)
18224 {
18225   unformat_input_t *i = vam->input;
18226   vl_api_one_eid_table_dump_t *mp;
18227   vl_api_control_ping_t *mp_ping;
18228   struct in_addr ip4;
18229   struct in6_addr ip6;
18230   u8 mac[6];
18231   u8 eid_type = ~0, eid_set = 0;
18232   u32 prefix_length = ~0, t, vni = 0;
18233   u8 filter = 0;
18234   int ret;
18235   lisp_nsh_api_t nsh;
18236
18237   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18238     {
18239       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18240         {
18241           eid_set = 1;
18242           eid_type = 0;
18243           prefix_length = t;
18244         }
18245       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18246         {
18247           eid_set = 1;
18248           eid_type = 1;
18249           prefix_length = t;
18250         }
18251       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18252         {
18253           eid_set = 1;
18254           eid_type = 2;
18255         }
18256       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18257         {
18258           eid_set = 1;
18259           eid_type = 3;
18260         }
18261       else if (unformat (i, "vni %d", &t))
18262         {
18263           vni = t;
18264         }
18265       else if (unformat (i, "local"))
18266         {
18267           filter = 1;
18268         }
18269       else if (unformat (i, "remote"))
18270         {
18271           filter = 2;
18272         }
18273       else
18274         {
18275           errmsg ("parse error '%U'", format_unformat_error, i);
18276           return -99;
18277         }
18278     }
18279
18280   if (!vam->json_output)
18281     {
18282       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18283              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18284     }
18285
18286   M (ONE_EID_TABLE_DUMP, mp);
18287
18288   mp->filter = filter;
18289   if (eid_set)
18290     {
18291       mp->eid_set = 1;
18292       mp->vni = htonl (vni);
18293       mp->eid_type = eid_type;
18294       switch (eid_type)
18295         {
18296         case 0:
18297           mp->prefix_length = prefix_length;
18298           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
18299           break;
18300         case 1:
18301           mp->prefix_length = prefix_length;
18302           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18303           break;
18304         case 2:
18305           clib_memcpy (mp->eid, mac, sizeof (mac));
18306           break;
18307         case 3:
18308           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18309           break;
18310         default:
18311           errmsg ("unknown EID type %d!", eid_type);
18312           return -99;
18313         }
18314     }
18315
18316   /* send it... */
18317   S (mp);
18318
18319   /* Use a control ping for synchronization */
18320   MPING (CONTROL_PING, mp_ping);
18321   S (mp_ping);
18322
18323   /* Wait for a reply... */
18324   W (ret);
18325   return ret;
18326 }
18327
18328 #define api_lisp_eid_table_dump api_one_eid_table_dump
18329
18330 static int
18331 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
18332 {
18333   unformat_input_t *i = vam->input;
18334   vl_api_gpe_fwd_entries_get_t *mp;
18335   u8 vni_set = 0;
18336   u32 vni = ~0;
18337   int ret;
18338
18339   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18340     {
18341       if (unformat (i, "vni %d", &vni))
18342         {
18343           vni_set = 1;
18344         }
18345       else
18346         {
18347           errmsg ("parse error '%U'", format_unformat_error, i);
18348           return -99;
18349         }
18350     }
18351
18352   if (!vni_set)
18353     {
18354       errmsg ("vni not set!");
18355       return -99;
18356     }
18357
18358   if (!vam->json_output)
18359     {
18360       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
18361              "leid", "reid");
18362     }
18363
18364   M (GPE_FWD_ENTRIES_GET, mp);
18365   mp->vni = clib_host_to_net_u32 (vni);
18366
18367   /* send it... */
18368   S (mp);
18369
18370   /* Wait for a reply... */
18371   W (ret);
18372   return ret;
18373 }
18374
18375 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
18376 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
18377 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
18378 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
18379 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
18380 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
18381 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
18382 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
18383
18384 static int
18385 api_one_adjacencies_get (vat_main_t * vam)
18386 {
18387   unformat_input_t *i = vam->input;
18388   vl_api_one_adjacencies_get_t *mp;
18389   u8 vni_set = 0;
18390   u32 vni = ~0;
18391   int ret;
18392
18393   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18394     {
18395       if (unformat (i, "vni %d", &vni))
18396         {
18397           vni_set = 1;
18398         }
18399       else
18400         {
18401           errmsg ("parse error '%U'", format_unformat_error, i);
18402           return -99;
18403         }
18404     }
18405
18406   if (!vni_set)
18407     {
18408       errmsg ("vni not set!");
18409       return -99;
18410     }
18411
18412   if (!vam->json_output)
18413     {
18414       print (vam->ofp, "%s %40s", "leid", "reid");
18415     }
18416
18417   M (ONE_ADJACENCIES_GET, mp);
18418   mp->vni = clib_host_to_net_u32 (vni);
18419
18420   /* send it... */
18421   S (mp);
18422
18423   /* Wait for a reply... */
18424   W (ret);
18425   return ret;
18426 }
18427
18428 #define api_lisp_adjacencies_get api_one_adjacencies_get
18429
18430 static int
18431 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
18432 {
18433   unformat_input_t *i = vam->input;
18434   vl_api_gpe_native_fwd_rpaths_get_t *mp;
18435   int ret;
18436   u8 ip_family_set = 0, is_ip4 = 1;
18437
18438   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18439     {
18440       if (unformat (i, "ip4"))
18441         {
18442           ip_family_set = 1;
18443           is_ip4 = 1;
18444         }
18445       else if (unformat (i, "ip6"))
18446         {
18447           ip_family_set = 1;
18448           is_ip4 = 0;
18449         }
18450       else
18451         {
18452           errmsg ("parse error '%U'", format_unformat_error, i);
18453           return -99;
18454         }
18455     }
18456
18457   if (!ip_family_set)
18458     {
18459       errmsg ("ip family not set!");
18460       return -99;
18461     }
18462
18463   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18464   mp->is_ip4 = is_ip4;
18465
18466   /* send it... */
18467   S (mp);
18468
18469   /* Wait for a reply... */
18470   W (ret);
18471   return ret;
18472 }
18473
18474 static int
18475 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18476 {
18477   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18478   int ret;
18479
18480   if (!vam->json_output)
18481     {
18482       print (vam->ofp, "VNIs");
18483     }
18484
18485   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18486
18487   /* send it... */
18488   S (mp);
18489
18490   /* Wait for a reply... */
18491   W (ret);
18492   return ret;
18493 }
18494
18495 static int
18496 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18497 {
18498   unformat_input_t *i = vam->input;
18499   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18500   int ret = 0;
18501   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18502   struct in_addr ip4;
18503   struct in6_addr ip6;
18504   u32 table_id = 0, nh_sw_if_index = ~0;
18505
18506   memset (&ip4, 0, sizeof (ip4));
18507   memset (&ip6, 0, sizeof (ip6));
18508
18509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18510     {
18511       if (unformat (i, "del"))
18512         is_add = 0;
18513       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18514                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18515         {
18516           ip_set = 1;
18517           is_ip4 = 1;
18518         }
18519       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18520                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18521         {
18522           ip_set = 1;
18523           is_ip4 = 0;
18524         }
18525       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18526         {
18527           ip_set = 1;
18528           is_ip4 = 1;
18529           nh_sw_if_index = ~0;
18530         }
18531       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18532         {
18533           ip_set = 1;
18534           is_ip4 = 0;
18535           nh_sw_if_index = ~0;
18536         }
18537       else if (unformat (i, "table %d", &table_id))
18538         ;
18539       else
18540         {
18541           errmsg ("parse error '%U'", format_unformat_error, i);
18542           return -99;
18543         }
18544     }
18545
18546   if (!ip_set)
18547     {
18548       errmsg ("nh addr not set!");
18549       return -99;
18550     }
18551
18552   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18553   mp->is_add = is_add;
18554   mp->table_id = clib_host_to_net_u32 (table_id);
18555   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18556   mp->is_ip4 = is_ip4;
18557   if (is_ip4)
18558     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18559   else
18560     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18561
18562   /* send it... */
18563   S (mp);
18564
18565   /* Wait for a reply... */
18566   W (ret);
18567   return ret;
18568 }
18569
18570 static int
18571 api_one_map_server_dump (vat_main_t * vam)
18572 {
18573   vl_api_one_map_server_dump_t *mp;
18574   vl_api_control_ping_t *mp_ping;
18575   int ret;
18576
18577   if (!vam->json_output)
18578     {
18579       print (vam->ofp, "%=20s", "Map server");
18580     }
18581
18582   M (ONE_MAP_SERVER_DUMP, mp);
18583   /* send it... */
18584   S (mp);
18585
18586   /* Use a control ping for synchronization */
18587   MPING (CONTROL_PING, mp_ping);
18588   S (mp_ping);
18589
18590   /* Wait for a reply... */
18591   W (ret);
18592   return ret;
18593 }
18594
18595 #define api_lisp_map_server_dump api_one_map_server_dump
18596
18597 static int
18598 api_one_map_resolver_dump (vat_main_t * vam)
18599 {
18600   vl_api_one_map_resolver_dump_t *mp;
18601   vl_api_control_ping_t *mp_ping;
18602   int ret;
18603
18604   if (!vam->json_output)
18605     {
18606       print (vam->ofp, "%=20s", "Map resolver");
18607     }
18608
18609   M (ONE_MAP_RESOLVER_DUMP, mp);
18610   /* send it... */
18611   S (mp);
18612
18613   /* Use a control ping for synchronization */
18614   MPING (CONTROL_PING, mp_ping);
18615   S (mp_ping);
18616
18617   /* Wait for a reply... */
18618   W (ret);
18619   return ret;
18620 }
18621
18622 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18623
18624 static int
18625 api_one_stats_flush (vat_main_t * vam)
18626 {
18627   vl_api_one_stats_flush_t *mp;
18628   int ret = 0;
18629
18630   M (ONE_STATS_FLUSH, mp);
18631   S (mp);
18632   W (ret);
18633   return ret;
18634 }
18635
18636 static int
18637 api_one_stats_dump (vat_main_t * vam)
18638 {
18639   vl_api_one_stats_dump_t *mp;
18640   vl_api_control_ping_t *mp_ping;
18641   int ret;
18642
18643   M (ONE_STATS_DUMP, mp);
18644   /* send it... */
18645   S (mp);
18646
18647   /* Use a control ping for synchronization */
18648   MPING (CONTROL_PING, mp_ping);
18649   S (mp_ping);
18650
18651   /* Wait for a reply... */
18652   W (ret);
18653   return ret;
18654 }
18655
18656 static int
18657 api_show_one_status (vat_main_t * vam)
18658 {
18659   vl_api_show_one_status_t *mp;
18660   int ret;
18661
18662   if (!vam->json_output)
18663     {
18664       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18665     }
18666
18667   M (SHOW_ONE_STATUS, mp);
18668   /* send it... */
18669   S (mp);
18670   /* Wait for a reply... */
18671   W (ret);
18672   return ret;
18673 }
18674
18675 #define api_show_lisp_status api_show_one_status
18676
18677 static int
18678 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18679 {
18680   vl_api_gpe_fwd_entry_path_dump_t *mp;
18681   vl_api_control_ping_t *mp_ping;
18682   unformat_input_t *i = vam->input;
18683   u32 fwd_entry_index = ~0;
18684   int ret;
18685
18686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18687     {
18688       if (unformat (i, "index %d", &fwd_entry_index))
18689         ;
18690       else
18691         break;
18692     }
18693
18694   if (~0 == fwd_entry_index)
18695     {
18696       errmsg ("no index specified!");
18697       return -99;
18698     }
18699
18700   if (!vam->json_output)
18701     {
18702       print (vam->ofp, "first line");
18703     }
18704
18705   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18706
18707   /* send it... */
18708   S (mp);
18709   /* Use a control ping for synchronization */
18710   MPING (CONTROL_PING, mp_ping);
18711   S (mp_ping);
18712
18713   /* Wait for a reply... */
18714   W (ret);
18715   return ret;
18716 }
18717
18718 static int
18719 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18720 {
18721   vl_api_one_get_map_request_itr_rlocs_t *mp;
18722   int ret;
18723
18724   if (!vam->json_output)
18725     {
18726       print (vam->ofp, "%=20s", "itr-rlocs:");
18727     }
18728
18729   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18730   /* send it... */
18731   S (mp);
18732   /* Wait for a reply... */
18733   W (ret);
18734   return ret;
18735 }
18736
18737 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18738
18739 static int
18740 api_af_packet_create (vat_main_t * vam)
18741 {
18742   unformat_input_t *i = vam->input;
18743   vl_api_af_packet_create_t *mp;
18744   u8 *host_if_name = 0;
18745   u8 hw_addr[6];
18746   u8 random_hw_addr = 1;
18747   int ret;
18748
18749   memset (hw_addr, 0, sizeof (hw_addr));
18750
18751   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18752     {
18753       if (unformat (i, "name %s", &host_if_name))
18754         vec_add1 (host_if_name, 0);
18755       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18756         random_hw_addr = 0;
18757       else
18758         break;
18759     }
18760
18761   if (!vec_len (host_if_name))
18762     {
18763       errmsg ("host-interface name must be specified");
18764       return -99;
18765     }
18766
18767   if (vec_len (host_if_name) > 64)
18768     {
18769       errmsg ("host-interface name too long");
18770       return -99;
18771     }
18772
18773   M (AF_PACKET_CREATE, mp);
18774
18775   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18776   clib_memcpy (mp->hw_addr, hw_addr, 6);
18777   mp->use_random_hw_addr = random_hw_addr;
18778   vec_free (host_if_name);
18779
18780   S (mp);
18781
18782   /* *INDENT-OFF* */
18783   W2 (ret,
18784       ({
18785         if (ret == 0)
18786           fprintf (vam->ofp ? vam->ofp : stderr,
18787                    " new sw_if_index = %d\n", vam->sw_if_index);
18788       }));
18789   /* *INDENT-ON* */
18790   return ret;
18791 }
18792
18793 static int
18794 api_af_packet_delete (vat_main_t * vam)
18795 {
18796   unformat_input_t *i = vam->input;
18797   vl_api_af_packet_delete_t *mp;
18798   u8 *host_if_name = 0;
18799   int ret;
18800
18801   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18802     {
18803       if (unformat (i, "name %s", &host_if_name))
18804         vec_add1 (host_if_name, 0);
18805       else
18806         break;
18807     }
18808
18809   if (!vec_len (host_if_name))
18810     {
18811       errmsg ("host-interface name must be specified");
18812       return -99;
18813     }
18814
18815   if (vec_len (host_if_name) > 64)
18816     {
18817       errmsg ("host-interface name too long");
18818       return -99;
18819     }
18820
18821   M (AF_PACKET_DELETE, mp);
18822
18823   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18824   vec_free (host_if_name);
18825
18826   S (mp);
18827   W (ret);
18828   return ret;
18829 }
18830
18831 static int
18832 api_policer_add_del (vat_main_t * vam)
18833 {
18834   unformat_input_t *i = vam->input;
18835   vl_api_policer_add_del_t *mp;
18836   u8 is_add = 1;
18837   u8 *name = 0;
18838   u32 cir = 0;
18839   u32 eir = 0;
18840   u64 cb = 0;
18841   u64 eb = 0;
18842   u8 rate_type = 0;
18843   u8 round_type = 0;
18844   u8 type = 0;
18845   u8 color_aware = 0;
18846   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18847   int ret;
18848
18849   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18850   conform_action.dscp = 0;
18851   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18852   exceed_action.dscp = 0;
18853   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18854   violate_action.dscp = 0;
18855
18856   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18857     {
18858       if (unformat (i, "del"))
18859         is_add = 0;
18860       else if (unformat (i, "name %s", &name))
18861         vec_add1 (name, 0);
18862       else if (unformat (i, "cir %u", &cir))
18863         ;
18864       else if (unformat (i, "eir %u", &eir))
18865         ;
18866       else if (unformat (i, "cb %u", &cb))
18867         ;
18868       else if (unformat (i, "eb %u", &eb))
18869         ;
18870       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18871                          &rate_type))
18872         ;
18873       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18874                          &round_type))
18875         ;
18876       else if (unformat (i, "type %U", unformat_policer_type, &type))
18877         ;
18878       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18879                          &conform_action))
18880         ;
18881       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18882                          &exceed_action))
18883         ;
18884       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18885                          &violate_action))
18886         ;
18887       else if (unformat (i, "color-aware"))
18888         color_aware = 1;
18889       else
18890         break;
18891     }
18892
18893   if (!vec_len (name))
18894     {
18895       errmsg ("policer name must be specified");
18896       return -99;
18897     }
18898
18899   if (vec_len (name) > 64)
18900     {
18901       errmsg ("policer name too long");
18902       return -99;
18903     }
18904
18905   M (POLICER_ADD_DEL, mp);
18906
18907   clib_memcpy (mp->name, name, vec_len (name));
18908   vec_free (name);
18909   mp->is_add = is_add;
18910   mp->cir = ntohl (cir);
18911   mp->eir = ntohl (eir);
18912   mp->cb = clib_net_to_host_u64 (cb);
18913   mp->eb = clib_net_to_host_u64 (eb);
18914   mp->rate_type = rate_type;
18915   mp->round_type = round_type;
18916   mp->type = type;
18917   mp->conform_action_type = conform_action.action_type;
18918   mp->conform_dscp = conform_action.dscp;
18919   mp->exceed_action_type = exceed_action.action_type;
18920   mp->exceed_dscp = exceed_action.dscp;
18921   mp->violate_action_type = violate_action.action_type;
18922   mp->violate_dscp = violate_action.dscp;
18923   mp->color_aware = color_aware;
18924
18925   S (mp);
18926   W (ret);
18927   return ret;
18928 }
18929
18930 static int
18931 api_policer_dump (vat_main_t * vam)
18932 {
18933   unformat_input_t *i = vam->input;
18934   vl_api_policer_dump_t *mp;
18935   vl_api_control_ping_t *mp_ping;
18936   u8 *match_name = 0;
18937   u8 match_name_valid = 0;
18938   int ret;
18939
18940   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18941     {
18942       if (unformat (i, "name %s", &match_name))
18943         {
18944           vec_add1 (match_name, 0);
18945           match_name_valid = 1;
18946         }
18947       else
18948         break;
18949     }
18950
18951   M (POLICER_DUMP, mp);
18952   mp->match_name_valid = match_name_valid;
18953   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18954   vec_free (match_name);
18955   /* send it... */
18956   S (mp);
18957
18958   /* Use a control ping for synchronization */
18959   MPING (CONTROL_PING, mp_ping);
18960   S (mp_ping);
18961
18962   /* Wait for a reply... */
18963   W (ret);
18964   return ret;
18965 }
18966
18967 static int
18968 api_policer_classify_set_interface (vat_main_t * vam)
18969 {
18970   unformat_input_t *i = vam->input;
18971   vl_api_policer_classify_set_interface_t *mp;
18972   u32 sw_if_index;
18973   int sw_if_index_set;
18974   u32 ip4_table_index = ~0;
18975   u32 ip6_table_index = ~0;
18976   u32 l2_table_index = ~0;
18977   u8 is_add = 1;
18978   int ret;
18979
18980   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18981     {
18982       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18983         sw_if_index_set = 1;
18984       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18985         sw_if_index_set = 1;
18986       else if (unformat (i, "del"))
18987         is_add = 0;
18988       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18989         ;
18990       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18991         ;
18992       else if (unformat (i, "l2-table %d", &l2_table_index))
18993         ;
18994       else
18995         {
18996           clib_warning ("parse error '%U'", format_unformat_error, i);
18997           return -99;
18998         }
18999     }
19000
19001   if (sw_if_index_set == 0)
19002     {
19003       errmsg ("missing interface name or sw_if_index");
19004       return -99;
19005     }
19006
19007   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
19008
19009   mp->sw_if_index = ntohl (sw_if_index);
19010   mp->ip4_table_index = ntohl (ip4_table_index);
19011   mp->ip6_table_index = ntohl (ip6_table_index);
19012   mp->l2_table_index = ntohl (l2_table_index);
19013   mp->is_add = is_add;
19014
19015   S (mp);
19016   W (ret);
19017   return ret;
19018 }
19019
19020 static int
19021 api_policer_classify_dump (vat_main_t * vam)
19022 {
19023   unformat_input_t *i = vam->input;
19024   vl_api_policer_classify_dump_t *mp;
19025   vl_api_control_ping_t *mp_ping;
19026   u8 type = POLICER_CLASSIFY_N_TABLES;
19027   int ret;
19028
19029   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
19030     ;
19031   else
19032     {
19033       errmsg ("classify table type must be specified");
19034       return -99;
19035     }
19036
19037   if (!vam->json_output)
19038     {
19039       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19040     }
19041
19042   M (POLICER_CLASSIFY_DUMP, mp);
19043   mp->type = type;
19044   /* send it... */
19045   S (mp);
19046
19047   /* Use a control ping for synchronization */
19048   MPING (CONTROL_PING, mp_ping);
19049   S (mp_ping);
19050
19051   /* Wait for a reply... */
19052   W (ret);
19053   return ret;
19054 }
19055
19056 static int
19057 api_netmap_create (vat_main_t * vam)
19058 {
19059   unformat_input_t *i = vam->input;
19060   vl_api_netmap_create_t *mp;
19061   u8 *if_name = 0;
19062   u8 hw_addr[6];
19063   u8 random_hw_addr = 1;
19064   u8 is_pipe = 0;
19065   u8 is_master = 0;
19066   int ret;
19067
19068   memset (hw_addr, 0, sizeof (hw_addr));
19069
19070   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19071     {
19072       if (unformat (i, "name %s", &if_name))
19073         vec_add1 (if_name, 0);
19074       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19075         random_hw_addr = 0;
19076       else if (unformat (i, "pipe"))
19077         is_pipe = 1;
19078       else if (unformat (i, "master"))
19079         is_master = 1;
19080       else if (unformat (i, "slave"))
19081         is_master = 0;
19082       else
19083         break;
19084     }
19085
19086   if (!vec_len (if_name))
19087     {
19088       errmsg ("interface name must be specified");
19089       return -99;
19090     }
19091
19092   if (vec_len (if_name) > 64)
19093     {
19094       errmsg ("interface name too long");
19095       return -99;
19096     }
19097
19098   M (NETMAP_CREATE, mp);
19099
19100   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19101   clib_memcpy (mp->hw_addr, hw_addr, 6);
19102   mp->use_random_hw_addr = random_hw_addr;
19103   mp->is_pipe = is_pipe;
19104   mp->is_master = is_master;
19105   vec_free (if_name);
19106
19107   S (mp);
19108   W (ret);
19109   return ret;
19110 }
19111
19112 static int
19113 api_netmap_delete (vat_main_t * vam)
19114 {
19115   unformat_input_t *i = vam->input;
19116   vl_api_netmap_delete_t *mp;
19117   u8 *if_name = 0;
19118   int ret;
19119
19120   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19121     {
19122       if (unformat (i, "name %s", &if_name))
19123         vec_add1 (if_name, 0);
19124       else
19125         break;
19126     }
19127
19128   if (!vec_len (if_name))
19129     {
19130       errmsg ("interface name must be specified");
19131       return -99;
19132     }
19133
19134   if (vec_len (if_name) > 64)
19135     {
19136       errmsg ("interface name too long");
19137       return -99;
19138     }
19139
19140   M (NETMAP_DELETE, mp);
19141
19142   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19143   vec_free (if_name);
19144
19145   S (mp);
19146   W (ret);
19147   return ret;
19148 }
19149
19150 static void
19151 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
19152 {
19153   if (fp->afi == IP46_TYPE_IP6)
19154     print (vam->ofp,
19155            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19156            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19157            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19158            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19159            format_ip6_address, fp->next_hop);
19160   else if (fp->afi == IP46_TYPE_IP4)
19161     print (vam->ofp,
19162            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19163            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19164            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19165            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19166            format_ip4_address, fp->next_hop);
19167 }
19168
19169 static void
19170 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19171                                  vl_api_fib_path2_t * fp)
19172 {
19173   struct in_addr ip4;
19174   struct in6_addr ip6;
19175
19176   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19177   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19178   vat_json_object_add_uint (node, "is_local", fp->is_local);
19179   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19180   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19181   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19182   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19183   if (fp->afi == IP46_TYPE_IP4)
19184     {
19185       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19186       vat_json_object_add_ip4 (node, "next_hop", ip4);
19187     }
19188   else if (fp->afi == IP46_TYPE_IP6)
19189     {
19190       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19191       vat_json_object_add_ip6 (node, "next_hop", ip6);
19192     }
19193 }
19194
19195 static void
19196 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19197 {
19198   vat_main_t *vam = &vat_main;
19199   int count = ntohl (mp->mt_count);
19200   vl_api_fib_path2_t *fp;
19201   i32 i;
19202
19203   print (vam->ofp, "[%d]: sw_if_index %d via:",
19204          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19205   fp = mp->mt_paths;
19206   for (i = 0; i < count; i++)
19207     {
19208       vl_api_mpls_fib_path_print (vam, fp);
19209       fp++;
19210     }
19211
19212   print (vam->ofp, "");
19213 }
19214
19215 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19216 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19217
19218 static void
19219 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19220 {
19221   vat_main_t *vam = &vat_main;
19222   vat_json_node_t *node = NULL;
19223   int count = ntohl (mp->mt_count);
19224   vl_api_fib_path2_t *fp;
19225   i32 i;
19226
19227   if (VAT_JSON_ARRAY != vam->json_tree.type)
19228     {
19229       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19230       vat_json_init_array (&vam->json_tree);
19231     }
19232   node = vat_json_array_add (&vam->json_tree);
19233
19234   vat_json_init_object (node);
19235   vat_json_object_add_uint (node, "tunnel_index",
19236                             ntohl (mp->mt_tunnel_index));
19237   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19238
19239   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
19240
19241   fp = mp->mt_paths;
19242   for (i = 0; i < count; i++)
19243     {
19244       vl_api_mpls_fib_path_json_print (node, fp);
19245       fp++;
19246     }
19247 }
19248
19249 static int
19250 api_mpls_tunnel_dump (vat_main_t * vam)
19251 {
19252   vl_api_mpls_tunnel_dump_t *mp;
19253   vl_api_control_ping_t *mp_ping;
19254   i32 index = -1;
19255   int ret;
19256
19257   /* Parse args required to build the message */
19258   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
19259     {
19260       if (!unformat (vam->input, "tunnel_index %d", &index))
19261         {
19262           index = -1;
19263           break;
19264         }
19265     }
19266
19267   print (vam->ofp, "  tunnel_index %d", index);
19268
19269   M (MPLS_TUNNEL_DUMP, mp);
19270   mp->tunnel_index = htonl (index);
19271   S (mp);
19272
19273   /* Use a control ping for synchronization */
19274   MPING (CONTROL_PING, mp_ping);
19275   S (mp_ping);
19276
19277   W (ret);
19278   return ret;
19279 }
19280
19281 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
19282 #define vl_api_mpls_fib_details_t_print vl_noop_handler
19283
19284
19285 static void
19286 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
19287 {
19288   vat_main_t *vam = &vat_main;
19289   int count = ntohl (mp->count);
19290   vl_api_fib_path2_t *fp;
19291   int i;
19292
19293   print (vam->ofp,
19294          "table-id %d, label %u, ess_bit %u",
19295          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
19296   fp = mp->path;
19297   for (i = 0; i < count; i++)
19298     {
19299       vl_api_mpls_fib_path_print (vam, fp);
19300       fp++;
19301     }
19302 }
19303
19304 static void vl_api_mpls_fib_details_t_handler_json
19305   (vl_api_mpls_fib_details_t * mp)
19306 {
19307   vat_main_t *vam = &vat_main;
19308   int count = ntohl (mp->count);
19309   vat_json_node_t *node = NULL;
19310   vl_api_fib_path2_t *fp;
19311   int i;
19312
19313   if (VAT_JSON_ARRAY != vam->json_tree.type)
19314     {
19315       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19316       vat_json_init_array (&vam->json_tree);
19317     }
19318   node = vat_json_array_add (&vam->json_tree);
19319
19320   vat_json_init_object (node);
19321   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19322   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
19323   vat_json_object_add_uint (node, "label", ntohl (mp->label));
19324   vat_json_object_add_uint (node, "path_count", count);
19325   fp = mp->path;
19326   for (i = 0; i < count; i++)
19327     {
19328       vl_api_mpls_fib_path_json_print (node, fp);
19329       fp++;
19330     }
19331 }
19332
19333 static int
19334 api_mpls_fib_dump (vat_main_t * vam)
19335 {
19336   vl_api_mpls_fib_dump_t *mp;
19337   vl_api_control_ping_t *mp_ping;
19338   int ret;
19339
19340   M (MPLS_FIB_DUMP, mp);
19341   S (mp);
19342
19343   /* Use a control ping for synchronization */
19344   MPING (CONTROL_PING, mp_ping);
19345   S (mp_ping);
19346
19347   W (ret);
19348   return ret;
19349 }
19350
19351 #define vl_api_ip_fib_details_t_endian vl_noop_handler
19352 #define vl_api_ip_fib_details_t_print vl_noop_handler
19353
19354 static void
19355 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
19356 {
19357   vat_main_t *vam = &vat_main;
19358   int count = ntohl (mp->count);
19359   vl_api_fib_path_t *fp;
19360   int i;
19361
19362   print (vam->ofp,
19363          "table-id %d, prefix %U/%d",
19364          ntohl (mp->table_id), format_ip4_address, mp->address,
19365          mp->address_length);
19366   fp = mp->path;
19367   for (i = 0; i < count; i++)
19368     {
19369       if (fp->afi == IP46_TYPE_IP6)
19370         print (vam->ofp,
19371                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19372                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19373                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19374                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19375                format_ip6_address, fp->next_hop);
19376       else if (fp->afi == IP46_TYPE_IP4)
19377         print (vam->ofp,
19378                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19379                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19380                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19381                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19382                format_ip4_address, fp->next_hop);
19383       fp++;
19384     }
19385 }
19386
19387 static void vl_api_ip_fib_details_t_handler_json
19388   (vl_api_ip_fib_details_t * mp)
19389 {
19390   vat_main_t *vam = &vat_main;
19391   int count = ntohl (mp->count);
19392   vat_json_node_t *node = NULL;
19393   struct in_addr ip4;
19394   struct in6_addr ip6;
19395   vl_api_fib_path_t *fp;
19396   int i;
19397
19398   if (VAT_JSON_ARRAY != vam->json_tree.type)
19399     {
19400       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19401       vat_json_init_array (&vam->json_tree);
19402     }
19403   node = vat_json_array_add (&vam->json_tree);
19404
19405   vat_json_init_object (node);
19406   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19407   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
19408   vat_json_object_add_ip4 (node, "prefix", ip4);
19409   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19410   vat_json_object_add_uint (node, "path_count", count);
19411   fp = mp->path;
19412   for (i = 0; i < count; i++)
19413     {
19414       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19415       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19416       vat_json_object_add_uint (node, "is_local", fp->is_local);
19417       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19418       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19419       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19420       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19421       if (fp->afi == IP46_TYPE_IP4)
19422         {
19423           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19424           vat_json_object_add_ip4 (node, "next_hop", ip4);
19425         }
19426       else if (fp->afi == IP46_TYPE_IP6)
19427         {
19428           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19429           vat_json_object_add_ip6 (node, "next_hop", ip6);
19430         }
19431     }
19432 }
19433
19434 static int
19435 api_ip_fib_dump (vat_main_t * vam)
19436 {
19437   vl_api_ip_fib_dump_t *mp;
19438   vl_api_control_ping_t *mp_ping;
19439   int ret;
19440
19441   M (IP_FIB_DUMP, mp);
19442   S (mp);
19443
19444   /* Use a control ping for synchronization */
19445   MPING (CONTROL_PING, mp_ping);
19446   S (mp_ping);
19447
19448   W (ret);
19449   return ret;
19450 }
19451
19452 static int
19453 api_ip_mfib_dump (vat_main_t * vam)
19454 {
19455   vl_api_ip_mfib_dump_t *mp;
19456   vl_api_control_ping_t *mp_ping;
19457   int ret;
19458
19459   M (IP_MFIB_DUMP, mp);
19460   S (mp);
19461
19462   /* Use a control ping for synchronization */
19463   MPING (CONTROL_PING, mp_ping);
19464   S (mp_ping);
19465
19466   W (ret);
19467   return ret;
19468 }
19469
19470 static void vl_api_ip_neighbor_details_t_handler
19471   (vl_api_ip_neighbor_details_t * mp)
19472 {
19473   vat_main_t *vam = &vat_main;
19474
19475   print (vam->ofp, "%c %U %U",
19476          (mp->is_static) ? 'S' : 'D',
19477          format_ethernet_address, &mp->mac_address,
19478          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
19479          &mp->ip_address);
19480 }
19481
19482 static void vl_api_ip_neighbor_details_t_handler_json
19483   (vl_api_ip_neighbor_details_t * mp)
19484 {
19485
19486   vat_main_t *vam = &vat_main;
19487   vat_json_node_t *node;
19488   struct in_addr ip4;
19489   struct in6_addr ip6;
19490
19491   if (VAT_JSON_ARRAY != vam->json_tree.type)
19492     {
19493       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19494       vat_json_init_array (&vam->json_tree);
19495     }
19496   node = vat_json_array_add (&vam->json_tree);
19497
19498   vat_json_init_object (node);
19499   vat_json_object_add_string_copy (node, "flag",
19500                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
19501                                    "dynamic");
19502
19503   vat_json_object_add_string_copy (node, "link_layer",
19504                                    format (0, "%U", format_ethernet_address,
19505                                            &mp->mac_address));
19506
19507   if (mp->is_ipv6)
19508     {
19509       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
19510       vat_json_object_add_ip6 (node, "ip_address", ip6);
19511     }
19512   else
19513     {
19514       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
19515       vat_json_object_add_ip4 (node, "ip_address", ip4);
19516     }
19517 }
19518
19519 static int
19520 api_ip_neighbor_dump (vat_main_t * vam)
19521 {
19522   unformat_input_t *i = vam->input;
19523   vl_api_ip_neighbor_dump_t *mp;
19524   vl_api_control_ping_t *mp_ping;
19525   u8 is_ipv6 = 0;
19526   u32 sw_if_index = ~0;
19527   int ret;
19528
19529   /* Parse args required to build the message */
19530   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19531     {
19532       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19533         ;
19534       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19535         ;
19536       else if (unformat (i, "ip6"))
19537         is_ipv6 = 1;
19538       else
19539         break;
19540     }
19541
19542   if (sw_if_index == ~0)
19543     {
19544       errmsg ("missing interface name or sw_if_index");
19545       return -99;
19546     }
19547
19548   M (IP_NEIGHBOR_DUMP, mp);
19549   mp->is_ipv6 = (u8) is_ipv6;
19550   mp->sw_if_index = ntohl (sw_if_index);
19551   S (mp);
19552
19553   /* Use a control ping for synchronization */
19554   MPING (CONTROL_PING, mp_ping);
19555   S (mp_ping);
19556
19557   W (ret);
19558   return ret;
19559 }
19560
19561 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
19562 #define vl_api_ip6_fib_details_t_print vl_noop_handler
19563
19564 static void
19565 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
19566 {
19567   vat_main_t *vam = &vat_main;
19568   int count = ntohl (mp->count);
19569   vl_api_fib_path_t *fp;
19570   int i;
19571
19572   print (vam->ofp,
19573          "table-id %d, prefix %U/%d",
19574          ntohl (mp->table_id), format_ip6_address, mp->address,
19575          mp->address_length);
19576   fp = mp->path;
19577   for (i = 0; i < count; i++)
19578     {
19579       if (fp->afi == IP46_TYPE_IP6)
19580         print (vam->ofp,
19581                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19582                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19583                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19584                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19585                format_ip6_address, fp->next_hop);
19586       else if (fp->afi == IP46_TYPE_IP4)
19587         print (vam->ofp,
19588                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19589                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19590                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19591                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19592                format_ip4_address, fp->next_hop);
19593       fp++;
19594     }
19595 }
19596
19597 static void vl_api_ip6_fib_details_t_handler_json
19598   (vl_api_ip6_fib_details_t * mp)
19599 {
19600   vat_main_t *vam = &vat_main;
19601   int count = ntohl (mp->count);
19602   vat_json_node_t *node = NULL;
19603   struct in_addr ip4;
19604   struct in6_addr ip6;
19605   vl_api_fib_path_t *fp;
19606   int i;
19607
19608   if (VAT_JSON_ARRAY != vam->json_tree.type)
19609     {
19610       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19611       vat_json_init_array (&vam->json_tree);
19612     }
19613   node = vat_json_array_add (&vam->json_tree);
19614
19615   vat_json_init_object (node);
19616   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19617   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
19618   vat_json_object_add_ip6 (node, "prefix", ip6);
19619   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19620   vat_json_object_add_uint (node, "path_count", count);
19621   fp = mp->path;
19622   for (i = 0; i < count; i++)
19623     {
19624       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19625       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19626       vat_json_object_add_uint (node, "is_local", fp->is_local);
19627       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19628       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19629       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19630       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19631       if (fp->afi == IP46_TYPE_IP4)
19632         {
19633           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19634           vat_json_object_add_ip4 (node, "next_hop", ip4);
19635         }
19636       else if (fp->afi == IP46_TYPE_IP6)
19637         {
19638           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19639           vat_json_object_add_ip6 (node, "next_hop", ip6);
19640         }
19641     }
19642 }
19643
19644 static int
19645 api_ip6_fib_dump (vat_main_t * vam)
19646 {
19647   vl_api_ip6_fib_dump_t *mp;
19648   vl_api_control_ping_t *mp_ping;
19649   int ret;
19650
19651   M (IP6_FIB_DUMP, mp);
19652   S (mp);
19653
19654   /* Use a control ping for synchronization */
19655   MPING (CONTROL_PING, mp_ping);
19656   S (mp_ping);
19657
19658   W (ret);
19659   return ret;
19660 }
19661
19662 static int
19663 api_ip6_mfib_dump (vat_main_t * vam)
19664 {
19665   vl_api_ip6_mfib_dump_t *mp;
19666   vl_api_control_ping_t *mp_ping;
19667   int ret;
19668
19669   M (IP6_MFIB_DUMP, mp);
19670   S (mp);
19671
19672   /* Use a control ping for synchronization */
19673   MPING (CONTROL_PING, mp_ping);
19674   S (mp_ping);
19675
19676   W (ret);
19677   return ret;
19678 }
19679
19680 int
19681 api_classify_table_ids (vat_main_t * vam)
19682 {
19683   vl_api_classify_table_ids_t *mp;
19684   int ret;
19685
19686   /* Construct the API message */
19687   M (CLASSIFY_TABLE_IDS, mp);
19688   mp->context = 0;
19689
19690   S (mp);
19691   W (ret);
19692   return ret;
19693 }
19694
19695 int
19696 api_classify_table_by_interface (vat_main_t * vam)
19697 {
19698   unformat_input_t *input = vam->input;
19699   vl_api_classify_table_by_interface_t *mp;
19700
19701   u32 sw_if_index = ~0;
19702   int ret;
19703   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19704     {
19705       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19706         ;
19707       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19708         ;
19709       else
19710         break;
19711     }
19712   if (sw_if_index == ~0)
19713     {
19714       errmsg ("missing interface name or sw_if_index");
19715       return -99;
19716     }
19717
19718   /* Construct the API message */
19719   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19720   mp->context = 0;
19721   mp->sw_if_index = ntohl (sw_if_index);
19722
19723   S (mp);
19724   W (ret);
19725   return ret;
19726 }
19727
19728 int
19729 api_classify_table_info (vat_main_t * vam)
19730 {
19731   unformat_input_t *input = vam->input;
19732   vl_api_classify_table_info_t *mp;
19733
19734   u32 table_id = ~0;
19735   int ret;
19736   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19737     {
19738       if (unformat (input, "table_id %d", &table_id))
19739         ;
19740       else
19741         break;
19742     }
19743   if (table_id == ~0)
19744     {
19745       errmsg ("missing table id");
19746       return -99;
19747     }
19748
19749   /* Construct the API message */
19750   M (CLASSIFY_TABLE_INFO, mp);
19751   mp->context = 0;
19752   mp->table_id = ntohl (table_id);
19753
19754   S (mp);
19755   W (ret);
19756   return ret;
19757 }
19758
19759 int
19760 api_classify_session_dump (vat_main_t * vam)
19761 {
19762   unformat_input_t *input = vam->input;
19763   vl_api_classify_session_dump_t *mp;
19764   vl_api_control_ping_t *mp_ping;
19765
19766   u32 table_id = ~0;
19767   int ret;
19768   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19769     {
19770       if (unformat (input, "table_id %d", &table_id))
19771         ;
19772       else
19773         break;
19774     }
19775   if (table_id == ~0)
19776     {
19777       errmsg ("missing table id");
19778       return -99;
19779     }
19780
19781   /* Construct the API message */
19782   M (CLASSIFY_SESSION_DUMP, mp);
19783   mp->context = 0;
19784   mp->table_id = ntohl (table_id);
19785   S (mp);
19786
19787   /* Use a control ping for synchronization */
19788   MPING (CONTROL_PING, mp_ping);
19789   S (mp_ping);
19790
19791   W (ret);
19792   return ret;
19793 }
19794
19795 static void
19796 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19797 {
19798   vat_main_t *vam = &vat_main;
19799
19800   print (vam->ofp, "collector_address %U, collector_port %d, "
19801          "src_address %U, vrf_id %d, path_mtu %u, "
19802          "template_interval %u, udp_checksum %d",
19803          format_ip4_address, mp->collector_address,
19804          ntohs (mp->collector_port),
19805          format_ip4_address, mp->src_address,
19806          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19807          ntohl (mp->template_interval), mp->udp_checksum);
19808
19809   vam->retval = 0;
19810   vam->result_ready = 1;
19811 }
19812
19813 static void
19814   vl_api_ipfix_exporter_details_t_handler_json
19815   (vl_api_ipfix_exporter_details_t * mp)
19816 {
19817   vat_main_t *vam = &vat_main;
19818   vat_json_node_t node;
19819   struct in_addr collector_address;
19820   struct in_addr src_address;
19821
19822   vat_json_init_object (&node);
19823   clib_memcpy (&collector_address, &mp->collector_address,
19824                sizeof (collector_address));
19825   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19826   vat_json_object_add_uint (&node, "collector_port",
19827                             ntohs (mp->collector_port));
19828   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19829   vat_json_object_add_ip4 (&node, "src_address", src_address);
19830   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19831   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19832   vat_json_object_add_uint (&node, "template_interval",
19833                             ntohl (mp->template_interval));
19834   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19835
19836   vat_json_print (vam->ofp, &node);
19837   vat_json_free (&node);
19838   vam->retval = 0;
19839   vam->result_ready = 1;
19840 }
19841
19842 int
19843 api_ipfix_exporter_dump (vat_main_t * vam)
19844 {
19845   vl_api_ipfix_exporter_dump_t *mp;
19846   int ret;
19847
19848   /* Construct the API message */
19849   M (IPFIX_EXPORTER_DUMP, mp);
19850   mp->context = 0;
19851
19852   S (mp);
19853   W (ret);
19854   return ret;
19855 }
19856
19857 static int
19858 api_ipfix_classify_stream_dump (vat_main_t * vam)
19859 {
19860   vl_api_ipfix_classify_stream_dump_t *mp;
19861   int ret;
19862
19863   /* Construct the API message */
19864   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19865   mp->context = 0;
19866
19867   S (mp);
19868   W (ret);
19869   return ret;
19870   /* NOTREACHED */
19871   return 0;
19872 }
19873
19874 static void
19875   vl_api_ipfix_classify_stream_details_t_handler
19876   (vl_api_ipfix_classify_stream_details_t * mp)
19877 {
19878   vat_main_t *vam = &vat_main;
19879   print (vam->ofp, "domain_id %d, src_port %d",
19880          ntohl (mp->domain_id), ntohs (mp->src_port));
19881   vam->retval = 0;
19882   vam->result_ready = 1;
19883 }
19884
19885 static void
19886   vl_api_ipfix_classify_stream_details_t_handler_json
19887   (vl_api_ipfix_classify_stream_details_t * mp)
19888 {
19889   vat_main_t *vam = &vat_main;
19890   vat_json_node_t node;
19891
19892   vat_json_init_object (&node);
19893   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19894   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19895
19896   vat_json_print (vam->ofp, &node);
19897   vat_json_free (&node);
19898   vam->retval = 0;
19899   vam->result_ready = 1;
19900 }
19901
19902 static int
19903 api_ipfix_classify_table_dump (vat_main_t * vam)
19904 {
19905   vl_api_ipfix_classify_table_dump_t *mp;
19906   vl_api_control_ping_t *mp_ping;
19907   int ret;
19908
19909   if (!vam->json_output)
19910     {
19911       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19912              "transport_protocol");
19913     }
19914
19915   /* Construct the API message */
19916   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19917
19918   /* send it... */
19919   S (mp);
19920
19921   /* Use a control ping for synchronization */
19922   MPING (CONTROL_PING, mp_ping);
19923   S (mp_ping);
19924
19925   W (ret);
19926   return ret;
19927 }
19928
19929 static void
19930   vl_api_ipfix_classify_table_details_t_handler
19931   (vl_api_ipfix_classify_table_details_t * mp)
19932 {
19933   vat_main_t *vam = &vat_main;
19934   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19935          mp->transport_protocol);
19936 }
19937
19938 static void
19939   vl_api_ipfix_classify_table_details_t_handler_json
19940   (vl_api_ipfix_classify_table_details_t * mp)
19941 {
19942   vat_json_node_t *node = NULL;
19943   vat_main_t *vam = &vat_main;
19944
19945   if (VAT_JSON_ARRAY != vam->json_tree.type)
19946     {
19947       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19948       vat_json_init_array (&vam->json_tree);
19949     }
19950
19951   node = vat_json_array_add (&vam->json_tree);
19952   vat_json_init_object (node);
19953
19954   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19955   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19956   vat_json_object_add_uint (node, "transport_protocol",
19957                             mp->transport_protocol);
19958 }
19959
19960 static int
19961 api_sw_interface_span_enable_disable (vat_main_t * vam)
19962 {
19963   unformat_input_t *i = vam->input;
19964   vl_api_sw_interface_span_enable_disable_t *mp;
19965   u32 src_sw_if_index = ~0;
19966   u32 dst_sw_if_index = ~0;
19967   u8 state = 3;
19968   int ret;
19969   u8 is_l2 = 0;
19970
19971   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19972     {
19973       if (unformat
19974           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19975         ;
19976       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19977         ;
19978       else
19979         if (unformat
19980             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19981         ;
19982       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19983         ;
19984       else if (unformat (i, "disable"))
19985         state = 0;
19986       else if (unformat (i, "rx"))
19987         state = 1;
19988       else if (unformat (i, "tx"))
19989         state = 2;
19990       else if (unformat (i, "both"))
19991         state = 3;
19992       else if (unformat (i, "l2"))
19993         is_l2 = 1;
19994       else
19995         break;
19996     }
19997
19998   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19999
20000   mp->sw_if_index_from = htonl (src_sw_if_index);
20001   mp->sw_if_index_to = htonl (dst_sw_if_index);
20002   mp->state = state;
20003   mp->is_l2 = is_l2;
20004
20005   S (mp);
20006   W (ret);
20007   return ret;
20008 }
20009
20010 static void
20011 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
20012                                             * mp)
20013 {
20014   vat_main_t *vam = &vat_main;
20015   u8 *sw_if_from_name = 0;
20016   u8 *sw_if_to_name = 0;
20017   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20018   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20019   char *states[] = { "none", "rx", "tx", "both" };
20020   hash_pair_t *p;
20021
20022   /* *INDENT-OFF* */
20023   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20024   ({
20025     if ((u32) p->value[0] == sw_if_index_from)
20026       {
20027         sw_if_from_name = (u8 *)(p->key);
20028         if (sw_if_to_name)
20029           break;
20030       }
20031     if ((u32) p->value[0] == sw_if_index_to)
20032       {
20033         sw_if_to_name = (u8 *)(p->key);
20034         if (sw_if_from_name)
20035           break;
20036       }
20037   }));
20038   /* *INDENT-ON* */
20039   print (vam->ofp, "%20s => %20s (%s)",
20040          sw_if_from_name, sw_if_to_name, states[mp->state]);
20041 }
20042
20043 static void
20044   vl_api_sw_interface_span_details_t_handler_json
20045   (vl_api_sw_interface_span_details_t * mp)
20046 {
20047   vat_main_t *vam = &vat_main;
20048   vat_json_node_t *node = NULL;
20049   u8 *sw_if_from_name = 0;
20050   u8 *sw_if_to_name = 0;
20051   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20052   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20053   hash_pair_t *p;
20054
20055   /* *INDENT-OFF* */
20056   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20057   ({
20058     if ((u32) p->value[0] == sw_if_index_from)
20059       {
20060         sw_if_from_name = (u8 *)(p->key);
20061         if (sw_if_to_name)
20062           break;
20063       }
20064     if ((u32) p->value[0] == sw_if_index_to)
20065       {
20066         sw_if_to_name = (u8 *)(p->key);
20067         if (sw_if_from_name)
20068           break;
20069       }
20070   }));
20071   /* *INDENT-ON* */
20072
20073   if (VAT_JSON_ARRAY != vam->json_tree.type)
20074     {
20075       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20076       vat_json_init_array (&vam->json_tree);
20077     }
20078   node = vat_json_array_add (&vam->json_tree);
20079
20080   vat_json_init_object (node);
20081   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
20082   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
20083   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
20084   if (0 != sw_if_to_name)
20085     {
20086       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
20087     }
20088   vat_json_object_add_uint (node, "state", mp->state);
20089 }
20090
20091 static int
20092 api_sw_interface_span_dump (vat_main_t * vam)
20093 {
20094   unformat_input_t *input = vam->input;
20095   vl_api_sw_interface_span_dump_t *mp;
20096   vl_api_control_ping_t *mp_ping;
20097   u8 is_l2 = 0;
20098   int ret;
20099
20100   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20101     {
20102       if (unformat (input, "l2"))
20103         is_l2 = 1;
20104       else
20105         break;
20106     }
20107
20108   M (SW_INTERFACE_SPAN_DUMP, mp);
20109   mp->is_l2 = is_l2;
20110   S (mp);
20111
20112   /* Use a control ping for synchronization */
20113   MPING (CONTROL_PING, mp_ping);
20114   S (mp_ping);
20115
20116   W (ret);
20117   return ret;
20118 }
20119
20120 int
20121 api_pg_create_interface (vat_main_t * vam)
20122 {
20123   unformat_input_t *input = vam->input;
20124   vl_api_pg_create_interface_t *mp;
20125
20126   u32 if_id = ~0;
20127   int ret;
20128   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20129     {
20130       if (unformat (input, "if_id %d", &if_id))
20131         ;
20132       else
20133         break;
20134     }
20135   if (if_id == ~0)
20136     {
20137       errmsg ("missing pg interface index");
20138       return -99;
20139     }
20140
20141   /* Construct the API message */
20142   M (PG_CREATE_INTERFACE, mp);
20143   mp->context = 0;
20144   mp->interface_id = ntohl (if_id);
20145
20146   S (mp);
20147   W (ret);
20148   return ret;
20149 }
20150
20151 int
20152 api_pg_capture (vat_main_t * vam)
20153 {
20154   unformat_input_t *input = vam->input;
20155   vl_api_pg_capture_t *mp;
20156
20157   u32 if_id = ~0;
20158   u8 enable = 1;
20159   u32 count = 1;
20160   u8 pcap_file_set = 0;
20161   u8 *pcap_file = 0;
20162   int ret;
20163   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20164     {
20165       if (unformat (input, "if_id %d", &if_id))
20166         ;
20167       else if (unformat (input, "pcap %s", &pcap_file))
20168         pcap_file_set = 1;
20169       else if (unformat (input, "count %d", &count))
20170         ;
20171       else if (unformat (input, "disable"))
20172         enable = 0;
20173       else
20174         break;
20175     }
20176   if (if_id == ~0)
20177     {
20178       errmsg ("missing pg interface index");
20179       return -99;
20180     }
20181   if (pcap_file_set > 0)
20182     {
20183       if (vec_len (pcap_file) > 255)
20184         {
20185           errmsg ("pcap file name is too long");
20186           return -99;
20187         }
20188     }
20189
20190   u32 name_len = vec_len (pcap_file);
20191   /* Construct the API message */
20192   M (PG_CAPTURE, mp);
20193   mp->context = 0;
20194   mp->interface_id = ntohl (if_id);
20195   mp->is_enabled = enable;
20196   mp->count = ntohl (count);
20197   mp->pcap_name_length = ntohl (name_len);
20198   if (pcap_file_set != 0)
20199     {
20200       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20201     }
20202   vec_free (pcap_file);
20203
20204   S (mp);
20205   W (ret);
20206   return ret;
20207 }
20208
20209 int
20210 api_pg_enable_disable (vat_main_t * vam)
20211 {
20212   unformat_input_t *input = vam->input;
20213   vl_api_pg_enable_disable_t *mp;
20214
20215   u8 enable = 1;
20216   u8 stream_name_set = 0;
20217   u8 *stream_name = 0;
20218   int ret;
20219   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20220     {
20221       if (unformat (input, "stream %s", &stream_name))
20222         stream_name_set = 1;
20223       else if (unformat (input, "disable"))
20224         enable = 0;
20225       else
20226         break;
20227     }
20228
20229   if (stream_name_set > 0)
20230     {
20231       if (vec_len (stream_name) > 255)
20232         {
20233           errmsg ("stream name too long");
20234           return -99;
20235         }
20236     }
20237
20238   u32 name_len = vec_len (stream_name);
20239   /* Construct the API message */
20240   M (PG_ENABLE_DISABLE, mp);
20241   mp->context = 0;
20242   mp->is_enabled = enable;
20243   if (stream_name_set != 0)
20244     {
20245       mp->stream_name_length = ntohl (name_len);
20246       clib_memcpy (mp->stream_name, stream_name, name_len);
20247     }
20248   vec_free (stream_name);
20249
20250   S (mp);
20251   W (ret);
20252   return ret;
20253 }
20254
20255 int
20256 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
20257 {
20258   unformat_input_t *input = vam->input;
20259   vl_api_ip_source_and_port_range_check_add_del_t *mp;
20260
20261   u16 *low_ports = 0;
20262   u16 *high_ports = 0;
20263   u16 this_low;
20264   u16 this_hi;
20265   ip4_address_t ip4_addr;
20266   ip6_address_t ip6_addr;
20267   u32 length;
20268   u32 tmp, tmp2;
20269   u8 prefix_set = 0;
20270   u32 vrf_id = ~0;
20271   u8 is_add = 1;
20272   u8 is_ipv6 = 0;
20273   int ret;
20274
20275   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20276     {
20277       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
20278         {
20279           prefix_set = 1;
20280         }
20281       else
20282         if (unformat
20283             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
20284         {
20285           prefix_set = 1;
20286           is_ipv6 = 1;
20287         }
20288       else if (unformat (input, "vrf %d", &vrf_id))
20289         ;
20290       else if (unformat (input, "del"))
20291         is_add = 0;
20292       else if (unformat (input, "port %d", &tmp))
20293         {
20294           if (tmp == 0 || tmp > 65535)
20295             {
20296               errmsg ("port %d out of range", tmp);
20297               return -99;
20298             }
20299           this_low = tmp;
20300           this_hi = this_low + 1;
20301           vec_add1 (low_ports, this_low);
20302           vec_add1 (high_ports, this_hi);
20303         }
20304       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
20305         {
20306           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
20307             {
20308               errmsg ("incorrect range parameters");
20309               return -99;
20310             }
20311           this_low = tmp;
20312           /* Note: in debug CLI +1 is added to high before
20313              passing to real fn that does "the work"
20314              (ip_source_and_port_range_check_add_del).
20315              This fn is a wrapper around the binary API fn a
20316              control plane will call, which expects this increment
20317              to have occurred. Hence letting the binary API control
20318              plane fn do the increment for consistency between VAT
20319              and other control planes.
20320            */
20321           this_hi = tmp2;
20322           vec_add1 (low_ports, this_low);
20323           vec_add1 (high_ports, this_hi);
20324         }
20325       else
20326         break;
20327     }
20328
20329   if (prefix_set == 0)
20330     {
20331       errmsg ("<address>/<mask> not specified");
20332       return -99;
20333     }
20334
20335   if (vrf_id == ~0)
20336     {
20337       errmsg ("VRF ID required, not specified");
20338       return -99;
20339     }
20340
20341   if (vrf_id == 0)
20342     {
20343       errmsg
20344         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20345       return -99;
20346     }
20347
20348   if (vec_len (low_ports) == 0)
20349     {
20350       errmsg ("At least one port or port range required");
20351       return -99;
20352     }
20353
20354   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
20355
20356   mp->is_add = is_add;
20357
20358   if (is_ipv6)
20359     {
20360       mp->is_ipv6 = 1;
20361       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
20362     }
20363   else
20364     {
20365       mp->is_ipv6 = 0;
20366       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
20367     }
20368
20369   mp->mask_length = length;
20370   mp->number_of_ranges = vec_len (low_ports);
20371
20372   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
20373   vec_free (low_ports);
20374
20375   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20376   vec_free (high_ports);
20377
20378   mp->vrf_id = ntohl (vrf_id);
20379
20380   S (mp);
20381   W (ret);
20382   return ret;
20383 }
20384
20385 int
20386 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20387 {
20388   unformat_input_t *input = vam->input;
20389   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20390   u32 sw_if_index = ~0;
20391   int vrf_set = 0;
20392   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20393   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20394   u8 is_add = 1;
20395   int ret;
20396
20397   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20398     {
20399       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20400         ;
20401       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20402         ;
20403       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20404         vrf_set = 1;
20405       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20406         vrf_set = 1;
20407       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20408         vrf_set = 1;
20409       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20410         vrf_set = 1;
20411       else if (unformat (input, "del"))
20412         is_add = 0;
20413       else
20414         break;
20415     }
20416
20417   if (sw_if_index == ~0)
20418     {
20419       errmsg ("Interface required but not specified");
20420       return -99;
20421     }
20422
20423   if (vrf_set == 0)
20424     {
20425       errmsg ("VRF ID required but not specified");
20426       return -99;
20427     }
20428
20429   if (tcp_out_vrf_id == 0
20430       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20431     {
20432       errmsg
20433         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20434       return -99;
20435     }
20436
20437   /* Construct the API message */
20438   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20439
20440   mp->sw_if_index = ntohl (sw_if_index);
20441   mp->is_add = is_add;
20442   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20443   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20444   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20445   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20446
20447   /* send it... */
20448   S (mp);
20449
20450   /* Wait for a reply... */
20451   W (ret);
20452   return ret;
20453 }
20454
20455 static int
20456 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
20457 {
20458   unformat_input_t *i = vam->input;
20459   vl_api_ipsec_gre_add_del_tunnel_t *mp;
20460   u32 local_sa_id = 0;
20461   u32 remote_sa_id = 0;
20462   ip4_address_t src_address;
20463   ip4_address_t dst_address;
20464   u8 is_add = 1;
20465   int ret;
20466
20467   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20468     {
20469       if (unformat (i, "local_sa %d", &local_sa_id))
20470         ;
20471       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20472         ;
20473       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
20474         ;
20475       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
20476         ;
20477       else if (unformat (i, "del"))
20478         is_add = 0;
20479       else
20480         {
20481           clib_warning ("parse error '%U'", format_unformat_error, i);
20482           return -99;
20483         }
20484     }
20485
20486   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
20487
20488   mp->local_sa_id = ntohl (local_sa_id);
20489   mp->remote_sa_id = ntohl (remote_sa_id);
20490   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
20491   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
20492   mp->is_add = is_add;
20493
20494   S (mp);
20495   W (ret);
20496   return ret;
20497 }
20498
20499 static int
20500 api_punt (vat_main_t * vam)
20501 {
20502   unformat_input_t *i = vam->input;
20503   vl_api_punt_t *mp;
20504   u32 ipv = ~0;
20505   u32 protocol = ~0;
20506   u32 port = ~0;
20507   int is_add = 1;
20508   int ret;
20509
20510   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20511     {
20512       if (unformat (i, "ip %d", &ipv))
20513         ;
20514       else if (unformat (i, "protocol %d", &protocol))
20515         ;
20516       else if (unformat (i, "port %d", &port))
20517         ;
20518       else if (unformat (i, "del"))
20519         is_add = 0;
20520       else
20521         {
20522           clib_warning ("parse error '%U'", format_unformat_error, i);
20523           return -99;
20524         }
20525     }
20526
20527   M (PUNT, mp);
20528
20529   mp->is_add = (u8) is_add;
20530   mp->ipv = (u8) ipv;
20531   mp->l4_protocol = (u8) protocol;
20532   mp->l4_port = htons ((u16) port);
20533
20534   S (mp);
20535   W (ret);
20536   return ret;
20537 }
20538
20539 static void vl_api_ipsec_gre_tunnel_details_t_handler
20540   (vl_api_ipsec_gre_tunnel_details_t * mp)
20541 {
20542   vat_main_t *vam = &vat_main;
20543
20544   print (vam->ofp, "%11d%15U%15U%14d%14d",
20545          ntohl (mp->sw_if_index),
20546          format_ip4_address, &mp->src_address,
20547          format_ip4_address, &mp->dst_address,
20548          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
20549 }
20550
20551 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
20552   (vl_api_ipsec_gre_tunnel_details_t * mp)
20553 {
20554   vat_main_t *vam = &vat_main;
20555   vat_json_node_t *node = NULL;
20556   struct in_addr ip4;
20557
20558   if (VAT_JSON_ARRAY != vam->json_tree.type)
20559     {
20560       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20561       vat_json_init_array (&vam->json_tree);
20562     }
20563   node = vat_json_array_add (&vam->json_tree);
20564
20565   vat_json_init_object (node);
20566   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
20567   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
20568   vat_json_object_add_ip4 (node, "src_address", ip4);
20569   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
20570   vat_json_object_add_ip4 (node, "dst_address", ip4);
20571   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
20572   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
20573 }
20574
20575 static int
20576 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
20577 {
20578   unformat_input_t *i = vam->input;
20579   vl_api_ipsec_gre_tunnel_dump_t *mp;
20580   vl_api_control_ping_t *mp_ping;
20581   u32 sw_if_index;
20582   u8 sw_if_index_set = 0;
20583   int ret;
20584
20585   /* Parse args required to build the message */
20586   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20587     {
20588       if (unformat (i, "sw_if_index %d", &sw_if_index))
20589         sw_if_index_set = 1;
20590       else
20591         break;
20592     }
20593
20594   if (sw_if_index_set == 0)
20595     {
20596       sw_if_index = ~0;
20597     }
20598
20599   if (!vam->json_output)
20600     {
20601       print (vam->ofp, "%11s%15s%15s%14s%14s",
20602              "sw_if_index", "src_address", "dst_address",
20603              "local_sa_id", "remote_sa_id");
20604     }
20605
20606   /* Get list of gre-tunnel interfaces */
20607   M (IPSEC_GRE_TUNNEL_DUMP, mp);
20608
20609   mp->sw_if_index = htonl (sw_if_index);
20610
20611   S (mp);
20612
20613   /* Use a control ping for synchronization */
20614   MPING (CONTROL_PING, mp_ping);
20615   S (mp_ping);
20616
20617   W (ret);
20618   return ret;
20619 }
20620
20621 static int
20622 api_delete_subif (vat_main_t * vam)
20623 {
20624   unformat_input_t *i = vam->input;
20625   vl_api_delete_subif_t *mp;
20626   u32 sw_if_index = ~0;
20627   int ret;
20628
20629   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20630     {
20631       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20632         ;
20633       if (unformat (i, "sw_if_index %d", &sw_if_index))
20634         ;
20635       else
20636         break;
20637     }
20638
20639   if (sw_if_index == ~0)
20640     {
20641       errmsg ("missing sw_if_index");
20642       return -99;
20643     }
20644
20645   /* Construct the API message */
20646   M (DELETE_SUBIF, mp);
20647   mp->sw_if_index = ntohl (sw_if_index);
20648
20649   S (mp);
20650   W (ret);
20651   return ret;
20652 }
20653
20654 #define foreach_pbb_vtr_op      \
20655 _("disable",  L2_VTR_DISABLED)  \
20656 _("pop",  L2_VTR_POP_2)         \
20657 _("push",  L2_VTR_PUSH_2)
20658
20659 static int
20660 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20661 {
20662   unformat_input_t *i = vam->input;
20663   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20664   u32 sw_if_index = ~0, vtr_op = ~0;
20665   u16 outer_tag = ~0;
20666   u8 dmac[6], smac[6];
20667   u8 dmac_set = 0, smac_set = 0;
20668   u16 vlanid = 0;
20669   u32 sid = ~0;
20670   u32 tmp;
20671   int ret;
20672
20673   /* Shut up coverity */
20674   memset (dmac, 0, sizeof (dmac));
20675   memset (smac, 0, sizeof (smac));
20676
20677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20678     {
20679       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20680         ;
20681       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20682         ;
20683       else if (unformat (i, "vtr_op %d", &vtr_op))
20684         ;
20685 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20686       foreach_pbb_vtr_op
20687 #undef _
20688         else if (unformat (i, "translate_pbb_stag"))
20689         {
20690           if (unformat (i, "%d", &tmp))
20691             {
20692               vtr_op = L2_VTR_TRANSLATE_2_1;
20693               outer_tag = tmp;
20694             }
20695           else
20696             {
20697               errmsg
20698                 ("translate_pbb_stag operation requires outer tag definition");
20699               return -99;
20700             }
20701         }
20702       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20703         dmac_set++;
20704       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20705         smac_set++;
20706       else if (unformat (i, "sid %d", &sid))
20707         ;
20708       else if (unformat (i, "vlanid %d", &tmp))
20709         vlanid = tmp;
20710       else
20711         {
20712           clib_warning ("parse error '%U'", format_unformat_error, i);
20713           return -99;
20714         }
20715     }
20716
20717   if ((sw_if_index == ~0) || (vtr_op == ~0))
20718     {
20719       errmsg ("missing sw_if_index or vtr operation");
20720       return -99;
20721     }
20722   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20723       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20724     {
20725       errmsg
20726         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20727       return -99;
20728     }
20729
20730   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20731   mp->sw_if_index = ntohl (sw_if_index);
20732   mp->vtr_op = ntohl (vtr_op);
20733   mp->outer_tag = ntohs (outer_tag);
20734   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20735   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20736   mp->b_vlanid = ntohs (vlanid);
20737   mp->i_sid = ntohl (sid);
20738
20739   S (mp);
20740   W (ret);
20741   return ret;
20742 }
20743
20744 static int
20745 api_flow_classify_set_interface (vat_main_t * vam)
20746 {
20747   unformat_input_t *i = vam->input;
20748   vl_api_flow_classify_set_interface_t *mp;
20749   u32 sw_if_index;
20750   int sw_if_index_set;
20751   u32 ip4_table_index = ~0;
20752   u32 ip6_table_index = ~0;
20753   u8 is_add = 1;
20754   int ret;
20755
20756   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20757     {
20758       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20759         sw_if_index_set = 1;
20760       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20761         sw_if_index_set = 1;
20762       else if (unformat (i, "del"))
20763         is_add = 0;
20764       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20765         ;
20766       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20767         ;
20768       else
20769         {
20770           clib_warning ("parse error '%U'", format_unformat_error, i);
20771           return -99;
20772         }
20773     }
20774
20775   if (sw_if_index_set == 0)
20776     {
20777       errmsg ("missing interface name or sw_if_index");
20778       return -99;
20779     }
20780
20781   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20782
20783   mp->sw_if_index = ntohl (sw_if_index);
20784   mp->ip4_table_index = ntohl (ip4_table_index);
20785   mp->ip6_table_index = ntohl (ip6_table_index);
20786   mp->is_add = is_add;
20787
20788   S (mp);
20789   W (ret);
20790   return ret;
20791 }
20792
20793 static int
20794 api_flow_classify_dump (vat_main_t * vam)
20795 {
20796   unformat_input_t *i = vam->input;
20797   vl_api_flow_classify_dump_t *mp;
20798   vl_api_control_ping_t *mp_ping;
20799   u8 type = FLOW_CLASSIFY_N_TABLES;
20800   int ret;
20801
20802   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20803     ;
20804   else
20805     {
20806       errmsg ("classify table type must be specified");
20807       return -99;
20808     }
20809
20810   if (!vam->json_output)
20811     {
20812       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20813     }
20814
20815   M (FLOW_CLASSIFY_DUMP, mp);
20816   mp->type = type;
20817   /* send it... */
20818   S (mp);
20819
20820   /* Use a control ping for synchronization */
20821   MPING (CONTROL_PING, mp_ping);
20822   S (mp_ping);
20823
20824   /* Wait for a reply... */
20825   W (ret);
20826   return ret;
20827 }
20828
20829 static int
20830 api_feature_enable_disable (vat_main_t * vam)
20831 {
20832   unformat_input_t *i = vam->input;
20833   vl_api_feature_enable_disable_t *mp;
20834   u8 *arc_name = 0;
20835   u8 *feature_name = 0;
20836   u32 sw_if_index = ~0;
20837   u8 enable = 1;
20838   int ret;
20839
20840   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20841     {
20842       if (unformat (i, "arc_name %s", &arc_name))
20843         ;
20844       else if (unformat (i, "feature_name %s", &feature_name))
20845         ;
20846       else
20847         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20848         ;
20849       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20850         ;
20851       else if (unformat (i, "disable"))
20852         enable = 0;
20853       else
20854         break;
20855     }
20856
20857   if (arc_name == 0)
20858     {
20859       errmsg ("missing arc name");
20860       return -99;
20861     }
20862   if (vec_len (arc_name) > 63)
20863     {
20864       errmsg ("arc name too long");
20865     }
20866
20867   if (feature_name == 0)
20868     {
20869       errmsg ("missing feature name");
20870       return -99;
20871     }
20872   if (vec_len (feature_name) > 63)
20873     {
20874       errmsg ("feature name too long");
20875     }
20876
20877   if (sw_if_index == ~0)
20878     {
20879       errmsg ("missing interface name or sw_if_index");
20880       return -99;
20881     }
20882
20883   /* Construct the API message */
20884   M (FEATURE_ENABLE_DISABLE, mp);
20885   mp->sw_if_index = ntohl (sw_if_index);
20886   mp->enable = enable;
20887   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20888   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20889   vec_free (arc_name);
20890   vec_free (feature_name);
20891
20892   S (mp);
20893   W (ret);
20894   return ret;
20895 }
20896
20897 static int
20898 api_sw_interface_tag_add_del (vat_main_t * vam)
20899 {
20900   unformat_input_t *i = vam->input;
20901   vl_api_sw_interface_tag_add_del_t *mp;
20902   u32 sw_if_index = ~0;
20903   u8 *tag = 0;
20904   u8 enable = 1;
20905   int ret;
20906
20907   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20908     {
20909       if (unformat (i, "tag %s", &tag))
20910         ;
20911       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20912         ;
20913       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20914         ;
20915       else if (unformat (i, "del"))
20916         enable = 0;
20917       else
20918         break;
20919     }
20920
20921   if (sw_if_index == ~0)
20922     {
20923       errmsg ("missing interface name or sw_if_index");
20924       return -99;
20925     }
20926
20927   if (enable && (tag == 0))
20928     {
20929       errmsg ("no tag specified");
20930       return -99;
20931     }
20932
20933   /* Construct the API message */
20934   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20935   mp->sw_if_index = ntohl (sw_if_index);
20936   mp->is_add = enable;
20937   if (enable)
20938     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20939   vec_free (tag);
20940
20941   S (mp);
20942   W (ret);
20943   return ret;
20944 }
20945
20946 static void vl_api_l2_xconnect_details_t_handler
20947   (vl_api_l2_xconnect_details_t * mp)
20948 {
20949   vat_main_t *vam = &vat_main;
20950
20951   print (vam->ofp, "%15d%15d",
20952          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20953 }
20954
20955 static void vl_api_l2_xconnect_details_t_handler_json
20956   (vl_api_l2_xconnect_details_t * mp)
20957 {
20958   vat_main_t *vam = &vat_main;
20959   vat_json_node_t *node = NULL;
20960
20961   if (VAT_JSON_ARRAY != vam->json_tree.type)
20962     {
20963       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20964       vat_json_init_array (&vam->json_tree);
20965     }
20966   node = vat_json_array_add (&vam->json_tree);
20967
20968   vat_json_init_object (node);
20969   vat_json_object_add_uint (node, "rx_sw_if_index",
20970                             ntohl (mp->rx_sw_if_index));
20971   vat_json_object_add_uint (node, "tx_sw_if_index",
20972                             ntohl (mp->tx_sw_if_index));
20973 }
20974
20975 static int
20976 api_l2_xconnect_dump (vat_main_t * vam)
20977 {
20978   vl_api_l2_xconnect_dump_t *mp;
20979   vl_api_control_ping_t *mp_ping;
20980   int ret;
20981
20982   if (!vam->json_output)
20983     {
20984       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20985     }
20986
20987   M (L2_XCONNECT_DUMP, mp);
20988
20989   S (mp);
20990
20991   /* Use a control ping for synchronization */
20992   MPING (CONTROL_PING, mp_ping);
20993   S (mp_ping);
20994
20995   W (ret);
20996   return ret;
20997 }
20998
20999 static int
21000 api_sw_interface_set_mtu (vat_main_t * vam)
21001 {
21002   unformat_input_t *i = vam->input;
21003   vl_api_sw_interface_set_mtu_t *mp;
21004   u32 sw_if_index = ~0;
21005   u32 mtu = 0;
21006   int ret;
21007
21008   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21009     {
21010       if (unformat (i, "mtu %d", &mtu))
21011         ;
21012       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21013         ;
21014       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21015         ;
21016       else
21017         break;
21018     }
21019
21020   if (sw_if_index == ~0)
21021     {
21022       errmsg ("missing interface name or sw_if_index");
21023       return -99;
21024     }
21025
21026   if (mtu == 0)
21027     {
21028       errmsg ("no mtu specified");
21029       return -99;
21030     }
21031
21032   /* Construct the API message */
21033   M (SW_INTERFACE_SET_MTU, mp);
21034   mp->sw_if_index = ntohl (sw_if_index);
21035   mp->mtu = ntohs ((u16) mtu);
21036
21037   S (mp);
21038   W (ret);
21039   return ret;
21040 }
21041
21042 static int
21043 api_p2p_ethernet_add (vat_main_t * vam)
21044 {
21045   unformat_input_t *i = vam->input;
21046   vl_api_p2p_ethernet_add_t *mp;
21047   u32 parent_if_index = ~0;
21048   u32 sub_id = ~0;
21049   u8 remote_mac[6];
21050   u8 mac_set = 0;
21051   int ret;
21052
21053   memset (remote_mac, 0, sizeof (remote_mac));
21054   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21055     {
21056       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21057         ;
21058       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21059         ;
21060       else
21061         if (unformat
21062             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21063         mac_set++;
21064       else if (unformat (i, "sub_id %d", &sub_id))
21065         ;
21066       else
21067         {
21068           clib_warning ("parse error '%U'", format_unformat_error, i);
21069           return -99;
21070         }
21071     }
21072
21073   if (parent_if_index == ~0)
21074     {
21075       errmsg ("missing interface name or sw_if_index");
21076       return -99;
21077     }
21078   if (mac_set == 0)
21079     {
21080       errmsg ("missing remote mac address");
21081       return -99;
21082     }
21083   if (sub_id == ~0)
21084     {
21085       errmsg ("missing sub-interface id");
21086       return -99;
21087     }
21088
21089   M (P2P_ETHERNET_ADD, mp);
21090   mp->parent_if_index = ntohl (parent_if_index);
21091   mp->subif_id = ntohl (sub_id);
21092   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21093
21094   S (mp);
21095   W (ret);
21096   return ret;
21097 }
21098
21099 static int
21100 api_p2p_ethernet_del (vat_main_t * vam)
21101 {
21102   unformat_input_t *i = vam->input;
21103   vl_api_p2p_ethernet_del_t *mp;
21104   u32 parent_if_index = ~0;
21105   u8 remote_mac[6];
21106   u8 mac_set = 0;
21107   int ret;
21108
21109   memset (remote_mac, 0, sizeof (remote_mac));
21110   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21111     {
21112       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21113         ;
21114       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21115         ;
21116       else
21117         if (unformat
21118             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21119         mac_set++;
21120       else
21121         {
21122           clib_warning ("parse error '%U'", format_unformat_error, i);
21123           return -99;
21124         }
21125     }
21126
21127   if (parent_if_index == ~0)
21128     {
21129       errmsg ("missing interface name or sw_if_index");
21130       return -99;
21131     }
21132   if (mac_set == 0)
21133     {
21134       errmsg ("missing remote mac address");
21135       return -99;
21136     }
21137
21138   M (P2P_ETHERNET_DEL, mp);
21139   mp->parent_if_index = ntohl (parent_if_index);
21140   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21141
21142   S (mp);
21143   W (ret);
21144   return ret;
21145 }
21146
21147 static int
21148 api_lldp_config (vat_main_t * vam)
21149 {
21150   unformat_input_t *i = vam->input;
21151   vl_api_lldp_config_t *mp;
21152   int tx_hold = 0;
21153   int tx_interval = 0;
21154   u8 *sys_name = NULL;
21155   int ret;
21156
21157   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21158     {
21159       if (unformat (i, "system-name %s", &sys_name))
21160         ;
21161       else if (unformat (i, "tx-hold %d", &tx_hold))
21162         ;
21163       else if (unformat (i, "tx-interval %d", &tx_interval))
21164         ;
21165       else
21166         {
21167           clib_warning ("parse error '%U'", format_unformat_error, i);
21168           return -99;
21169         }
21170     }
21171
21172   vec_add1 (sys_name, 0);
21173
21174   M (LLDP_CONFIG, mp);
21175   mp->tx_hold = htonl (tx_hold);
21176   mp->tx_interval = htonl (tx_interval);
21177   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21178   vec_free (sys_name);
21179
21180   S (mp);
21181   W (ret);
21182   return ret;
21183 }
21184
21185 static int
21186 api_sw_interface_set_lldp (vat_main_t * vam)
21187 {
21188   unformat_input_t *i = vam->input;
21189   vl_api_sw_interface_set_lldp_t *mp;
21190   u32 sw_if_index = ~0;
21191   u32 enable = 1;
21192   u8 *port_desc = NULL, *mgmt_oid = NULL;
21193   ip4_address_t ip4_addr;
21194   ip6_address_t ip6_addr;
21195   int ret;
21196
21197   memset (&ip4_addr, 0, sizeof (ip4_addr));
21198   memset (&ip6_addr, 0, sizeof (ip6_addr));
21199
21200   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21201     {
21202       if (unformat (i, "disable"))
21203         enable = 0;
21204       else
21205         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21206         ;
21207       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21208         ;
21209       else if (unformat (i, "port-desc %s", &port_desc))
21210         ;
21211       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21212         ;
21213       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21214         ;
21215       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21216         ;
21217       else
21218         break;
21219     }
21220
21221   if (sw_if_index == ~0)
21222     {
21223       errmsg ("missing interface name or sw_if_index");
21224       return -99;
21225     }
21226
21227   /* Construct the API message */
21228   vec_add1 (port_desc, 0);
21229   vec_add1 (mgmt_oid, 0);
21230   M (SW_INTERFACE_SET_LLDP, mp);
21231   mp->sw_if_index = ntohl (sw_if_index);
21232   mp->enable = enable;
21233   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
21234   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
21235   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
21236   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
21237   vec_free (port_desc);
21238   vec_free (mgmt_oid);
21239
21240   S (mp);
21241   W (ret);
21242   return ret;
21243 }
21244
21245 static int
21246 api_tcp_configure_src_addresses (vat_main_t * vam)
21247 {
21248   vl_api_tcp_configure_src_addresses_t *mp;
21249   unformat_input_t *i = vam->input;
21250   ip4_address_t v4first, v4last;
21251   ip6_address_t v6first, v6last;
21252   u8 range_set = 0;
21253   u32 vrf_id = 0;
21254   int ret;
21255
21256   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21257     {
21258       if (unformat (i, "%U - %U",
21259                     unformat_ip4_address, &v4first,
21260                     unformat_ip4_address, &v4last))
21261         {
21262           if (range_set)
21263             {
21264               errmsg ("one range per message (range already set)");
21265               return -99;
21266             }
21267           range_set = 1;
21268         }
21269       else if (unformat (i, "%U - %U",
21270                          unformat_ip6_address, &v6first,
21271                          unformat_ip6_address, &v6last))
21272         {
21273           if (range_set)
21274             {
21275               errmsg ("one range per message (range already set)");
21276               return -99;
21277             }
21278           range_set = 2;
21279         }
21280       else if (unformat (i, "vrf %d", &vrf_id))
21281         ;
21282       else
21283         break;
21284     }
21285
21286   if (range_set == 0)
21287     {
21288       errmsg ("address range not set");
21289       return -99;
21290     }
21291
21292   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
21293   mp->vrf_id = ntohl (vrf_id);
21294   /* ipv6? */
21295   if (range_set == 2)
21296     {
21297       mp->is_ipv6 = 1;
21298       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
21299       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
21300     }
21301   else
21302     {
21303       mp->is_ipv6 = 0;
21304       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
21305       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
21306     }
21307   S (mp);
21308   W (ret);
21309   return ret;
21310 }
21311
21312 static int
21313 api_app_namespace_add_del (vat_main_t * vam)
21314 {
21315   vl_api_app_namespace_add_del_t *mp;
21316   unformat_input_t *i = vam->input;
21317   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
21318   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
21319   u64 secret;
21320   int ret;
21321
21322   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21323     {
21324       if (unformat (i, "id %_%v%_", &ns_id))
21325         ;
21326       else if (unformat (i, "secret %lu", &secret))
21327         secret_set = 1;
21328       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21329         sw_if_index_set = 1;
21330       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
21331         ;
21332       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
21333         ;
21334       else
21335         break;
21336     }
21337   if (!ns_id || !secret_set || !sw_if_index_set)
21338     {
21339       errmsg ("namespace id, secret and sw_if_index must be set");
21340       return -99;
21341     }
21342   if (vec_len (ns_id) > 64)
21343     {
21344       errmsg ("namespace id too long");
21345       return -99;
21346     }
21347   M (APP_NAMESPACE_ADD_DEL, mp);
21348
21349   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
21350   mp->namespace_id_len = vec_len (ns_id);
21351   mp->secret = clib_host_to_net_u64 (secret);
21352   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21353   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
21354   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
21355   vec_free (ns_id);
21356   S (mp);
21357   W (ret);
21358   return ret;
21359 }
21360
21361 static int
21362 api_memfd_segment_create (vat_main_t * vam)
21363 {
21364 #if VPP_API_TEST_BUILTIN == 0
21365   unformat_input_t *i = vam->input;
21366   vl_api_memfd_segment_create_t *mp;
21367   u64 size = 64 << 20;
21368   int ret;
21369
21370   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21371     {
21372       if (unformat (i, "size %U", unformat_memory_size, &size))
21373         ;
21374       else
21375         break;
21376     }
21377
21378   M (MEMFD_SEGMENT_CREATE, mp);
21379   mp->requested_size = size;
21380   S (mp);
21381   W (ret);
21382   return ret;
21383
21384 #else
21385   errmsg ("memfd_segment_create (builtin) not supported");
21386   return -99;
21387 #endif
21388 }
21389
21390 static int
21391 api_dns_enable_disable (vat_main_t * vam)
21392 {
21393   unformat_input_t *line_input = vam->input;
21394   vl_api_dns_enable_disable_t *mp;
21395   u8 enable_disable = 1;
21396   int ret;
21397
21398   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21399     {
21400       if (unformat (line_input, "disable"))
21401         enable_disable = 0;
21402       if (unformat (line_input, "enable"))
21403         enable_disable = 1;
21404       else
21405         break;
21406     }
21407
21408   /* Construct the API message */
21409   M (DNS_ENABLE_DISABLE, mp);
21410   mp->enable = enable_disable;
21411
21412   /* send it... */
21413   S (mp);
21414   /* Wait for the reply */
21415   W (ret);
21416   return ret;
21417 }
21418
21419 static int
21420 api_dns_resolve_name (vat_main_t * vam)
21421 {
21422   unformat_input_t *line_input = vam->input;
21423   vl_api_dns_resolve_name_t *mp;
21424   u8 *name = 0;
21425   int ret;
21426
21427   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21428     {
21429       if (unformat (line_input, "%s", &name))
21430         ;
21431       else
21432         break;
21433     }
21434
21435   if (vec_len (name) > 127)
21436     {
21437       errmsg ("name too long");
21438       return -99;
21439     }
21440
21441   /* Construct the API message */
21442   M (DNS_RESOLVE_NAME, mp);
21443   memcpy (mp->name, name, vec_len (name));
21444   vec_free (name);
21445
21446   /* send it... */
21447   S (mp);
21448   /* Wait for the reply */
21449   W (ret);
21450   return ret;
21451 }
21452
21453 static int
21454 api_dns_resolve_ip (vat_main_t * vam)
21455 {
21456   unformat_input_t *line_input = vam->input;
21457   vl_api_dns_resolve_ip_t *mp;
21458   int is_ip6 = -1;
21459   ip4_address_t addr4;
21460   ip6_address_t addr6;
21461   int ret;
21462
21463   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21464     {
21465       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21466         is_ip6 = 1;
21467       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21468         is_ip6 = 0;
21469       else
21470         break;
21471     }
21472
21473   if (is_ip6 == -1)
21474     {
21475       errmsg ("missing address");
21476       return -99;
21477     }
21478
21479   /* Construct the API message */
21480   M (DNS_RESOLVE_IP, mp);
21481   mp->is_ip6 = is_ip6;
21482   if (is_ip6)
21483     memcpy (mp->address, &addr6, sizeof (addr6));
21484   else
21485     memcpy (mp->address, &addr4, sizeof (addr4));
21486
21487   /* send it... */
21488   S (mp);
21489   /* Wait for the reply */
21490   W (ret);
21491   return ret;
21492 }
21493
21494 static int
21495 api_dns_name_server_add_del (vat_main_t * vam)
21496 {
21497   unformat_input_t *i = vam->input;
21498   vl_api_dns_name_server_add_del_t *mp;
21499   u8 is_add = 1;
21500   ip6_address_t ip6_server;
21501   ip4_address_t ip4_server;
21502   int ip6_set = 0;
21503   int ip4_set = 0;
21504   int ret = 0;
21505
21506   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21507     {
21508       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21509         ip6_set = 1;
21510       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21511         ip4_set = 1;
21512       else if (unformat (i, "del"))
21513         is_add = 0;
21514       else
21515         {
21516           clib_warning ("parse error '%U'", format_unformat_error, i);
21517           return -99;
21518         }
21519     }
21520
21521   if (ip4_set && ip6_set)
21522     {
21523       errmsg ("Only one server address allowed per message");
21524       return -99;
21525     }
21526   if ((ip4_set + ip6_set) == 0)
21527     {
21528       errmsg ("Server address required");
21529       return -99;
21530     }
21531
21532   /* Construct the API message */
21533   M (DNS_NAME_SERVER_ADD_DEL, mp);
21534
21535   if (ip6_set)
21536     {
21537       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21538       mp->is_ip6 = 1;
21539     }
21540   else
21541     {
21542       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21543       mp->is_ip6 = 0;
21544     }
21545
21546   mp->is_add = is_add;
21547
21548   /* send it... */
21549   S (mp);
21550
21551   /* Wait for a reply, return good/bad news  */
21552   W (ret);
21553   return ret;
21554 }
21555
21556 static void
21557 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
21558 {
21559   vat_main_t *vam = &vat_main;
21560
21561   if (mp->is_ip4)
21562     {
21563       print (vam->ofp,
21564              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21565              mp->appns_index, mp->transport_proto, mp->scope,
21566              format_ip4_address, &mp->lcl_ip, mp->lcl_plen, mp->lcl_port,
21567              format_ip4_address, &mp->rmt_ip, mp->rmt_plen, mp->rmt_port,
21568              mp->action_index, mp->tag);
21569     }
21570   else
21571     {
21572       print (vam->ofp,
21573              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21574              mp->appns_index, mp->transport_proto, mp->scope,
21575              format_ip6_address, &mp->lcl_ip, mp->lcl_plen, mp->lcl_port,
21576              format_ip6_address, &mp->rmt_ip, mp->rmt_plen, mp->rmt_port,
21577              mp->action_index, mp->tag);
21578     }
21579 }
21580
21581 static void
21582 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
21583                                              mp)
21584 {
21585   vat_main_t *vam = &vat_main;
21586   vat_json_node_t *node = NULL;
21587   struct in6_addr ip6;
21588   struct in_addr ip4;
21589
21590   if (VAT_JSON_ARRAY != vam->json_tree.type)
21591     {
21592       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21593       vat_json_init_array (&vam->json_tree);
21594     }
21595   node = vat_json_array_add (&vam->json_tree);
21596   vat_json_init_object (node);
21597
21598   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
21599   vat_json_object_add_uint (node, "appns_index",
21600                             clib_net_to_host_u32 (mp->appns_index));
21601   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
21602   vat_json_object_add_uint (node, "scope", mp->scope);
21603   vat_json_object_add_uint (node, "action_index",
21604                             clib_net_to_host_u32 (mp->action_index));
21605   vat_json_object_add_uint (node, "lcl_port",
21606                             clib_net_to_host_u16 (mp->lcl_port));
21607   vat_json_object_add_uint (node, "rmt_port",
21608                             clib_net_to_host_u16 (mp->rmt_port));
21609   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
21610   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
21611   vat_json_object_add_string_copy (node, "tag", mp->tag);
21612   if (mp->is_ip4)
21613     {
21614       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
21615       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
21616       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
21617       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
21618     }
21619   else
21620     {
21621       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
21622       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
21623       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
21624       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
21625     }
21626 }
21627
21628 static int
21629 api_session_rule_add_del (vat_main_t * vam)
21630 {
21631   vl_api_session_rule_add_del_t *mp;
21632   unformat_input_t *i = vam->input;
21633   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
21634   u32 appns_index = 0, scope = 0;
21635   ip4_address_t lcl_ip4, rmt_ip4;
21636   ip6_address_t lcl_ip6, rmt_ip6;
21637   u8 is_ip4 = 1, conn_set = 0;
21638   u8 is_add = 1, *tag = 0;
21639   int ret;
21640
21641   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21642     {
21643       if (unformat (i, "del"))
21644         is_add = 0;
21645       else if (unformat (i, "add"))
21646         ;
21647       else if (unformat (i, "proto tcp"))
21648         proto = 0;
21649       else if (unformat (i, "proto udp"))
21650         proto = 1;
21651       else if (unformat (i, "appns %d", &appns_index))
21652         ;
21653       else if (unformat (i, "scope %d", &scope))
21654         ;
21655       else if (unformat (i, "tag %_%v%_", &tag))
21656         ;
21657       else
21658         if (unformat
21659             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
21660              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
21661              &rmt_port))
21662         {
21663           is_ip4 = 1;
21664           conn_set = 1;
21665         }
21666       else
21667         if (unformat
21668             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
21669              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
21670              &rmt_port))
21671         {
21672           is_ip4 = 0;
21673           conn_set = 1;
21674         }
21675       else if (unformat (i, "action %d", &action))
21676         ;
21677       else
21678         break;
21679     }
21680   if (proto == ~0 || !conn_set || action == ~0)
21681     {
21682       errmsg ("transport proto, connection and action must be set");
21683       return -99;
21684     }
21685
21686   if (scope > 3)
21687     {
21688       errmsg ("scope should be 0-3");
21689       return -99;
21690     }
21691
21692   M (SESSION_RULE_ADD_DEL, mp);
21693
21694   mp->is_ip4 = is_ip4;
21695   mp->transport_proto = proto;
21696   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
21697   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
21698   mp->lcl_plen = lcl_plen;
21699   mp->rmt_plen = rmt_plen;
21700   mp->action_index = clib_host_to_net_u32 (action);
21701   mp->appns_index = clib_host_to_net_u32 (appns_index);
21702   mp->scope = scope;
21703   mp->is_add = is_add;
21704   if (is_ip4)
21705     {
21706       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
21707       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
21708     }
21709   else
21710     {
21711       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
21712       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
21713     }
21714   if (tag)
21715     {
21716       clib_memcpy (mp->tag, tag, vec_len (tag));
21717       vec_free (tag);
21718     }
21719
21720   S (mp);
21721   W (ret);
21722   return ret;
21723 }
21724
21725 static int
21726 api_session_rules_dump (vat_main_t * vam)
21727 {
21728   vl_api_session_rules_dump_t *mp;
21729   vl_api_control_ping_t *mp_ping;
21730   int ret;
21731
21732   if (!vam->json_output)
21733     {
21734       print (vam->ofp, "%=20s", "Session Rules");
21735     }
21736
21737   M (SESSION_RULES_DUMP, mp);
21738   /* send it... */
21739   S (mp);
21740
21741   /* Use a control ping for synchronization */
21742   MPING (CONTROL_PING, mp_ping);
21743   S (mp_ping);
21744
21745   /* Wait for a reply... */
21746   W (ret);
21747   return ret;
21748 }
21749
21750 static int
21751 q_or_quit (vat_main_t * vam)
21752 {
21753 #if VPP_API_TEST_BUILTIN == 0
21754   longjmp (vam->jump_buf, 1);
21755 #endif
21756   return 0;                     /* not so much */
21757 }
21758
21759 static int
21760 q (vat_main_t * vam)
21761 {
21762   return q_or_quit (vam);
21763 }
21764
21765 static int
21766 quit (vat_main_t * vam)
21767 {
21768   return q_or_quit (vam);
21769 }
21770
21771 static int
21772 comment (vat_main_t * vam)
21773 {
21774   return 0;
21775 }
21776
21777 static int
21778 cmd_cmp (void *a1, void *a2)
21779 {
21780   u8 **c1 = a1;
21781   u8 **c2 = a2;
21782
21783   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21784 }
21785
21786 static int
21787 help (vat_main_t * vam)
21788 {
21789   u8 **cmds = 0;
21790   u8 *name = 0;
21791   hash_pair_t *p;
21792   unformat_input_t *i = vam->input;
21793   int j;
21794
21795   if (unformat (i, "%s", &name))
21796     {
21797       uword *hs;
21798
21799       vec_add1 (name, 0);
21800
21801       hs = hash_get_mem (vam->help_by_name, name);
21802       if (hs)
21803         print (vam->ofp, "usage: %s %s", name, hs[0]);
21804       else
21805         print (vam->ofp, "No such msg / command '%s'", name);
21806       vec_free (name);
21807       return 0;
21808     }
21809
21810   print (vam->ofp, "Help is available for the following:");
21811
21812     /* *INDENT-OFF* */
21813     hash_foreach_pair (p, vam->function_by_name,
21814     ({
21815       vec_add1 (cmds, (u8 *)(p->key));
21816     }));
21817     /* *INDENT-ON* */
21818
21819   vec_sort_with_function (cmds, cmd_cmp);
21820
21821   for (j = 0; j < vec_len (cmds); j++)
21822     print (vam->ofp, "%s", cmds[j]);
21823
21824   vec_free (cmds);
21825   return 0;
21826 }
21827
21828 static int
21829 set (vat_main_t * vam)
21830 {
21831   u8 *name = 0, *value = 0;
21832   unformat_input_t *i = vam->input;
21833
21834   if (unformat (i, "%s", &name))
21835     {
21836       /* The input buffer is a vector, not a string. */
21837       value = vec_dup (i->buffer);
21838       vec_delete (value, i->index, 0);
21839       /* Almost certainly has a trailing newline */
21840       if (value[vec_len (value) - 1] == '\n')
21841         value[vec_len (value) - 1] = 0;
21842       /* Make sure it's a proper string, one way or the other */
21843       vec_add1 (value, 0);
21844       (void) clib_macro_set_value (&vam->macro_main,
21845                                    (char *) name, (char *) value);
21846     }
21847   else
21848     errmsg ("usage: set <name> <value>");
21849
21850   vec_free (name);
21851   vec_free (value);
21852   return 0;
21853 }
21854
21855 static int
21856 unset (vat_main_t * vam)
21857 {
21858   u8 *name = 0;
21859
21860   if (unformat (vam->input, "%s", &name))
21861     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21862       errmsg ("unset: %s wasn't set", name);
21863   vec_free (name);
21864   return 0;
21865 }
21866
21867 typedef struct
21868 {
21869   u8 *name;
21870   u8 *value;
21871 } macro_sort_t;
21872
21873
21874 static int
21875 macro_sort_cmp (void *a1, void *a2)
21876 {
21877   macro_sort_t *s1 = a1;
21878   macro_sort_t *s2 = a2;
21879
21880   return strcmp ((char *) (s1->name), (char *) (s2->name));
21881 }
21882
21883 static int
21884 dump_macro_table (vat_main_t * vam)
21885 {
21886   macro_sort_t *sort_me = 0, *sm;
21887   int i;
21888   hash_pair_t *p;
21889
21890     /* *INDENT-OFF* */
21891     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21892     ({
21893       vec_add2 (sort_me, sm, 1);
21894       sm->name = (u8 *)(p->key);
21895       sm->value = (u8 *) (p->value[0]);
21896     }));
21897     /* *INDENT-ON* */
21898
21899   vec_sort_with_function (sort_me, macro_sort_cmp);
21900
21901   if (vec_len (sort_me))
21902     print (vam->ofp, "%-15s%s", "Name", "Value");
21903   else
21904     print (vam->ofp, "The macro table is empty...");
21905
21906   for (i = 0; i < vec_len (sort_me); i++)
21907     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21908   return 0;
21909 }
21910
21911 static int
21912 dump_node_table (vat_main_t * vam)
21913 {
21914   int i, j;
21915   vlib_node_t *node, *next_node;
21916
21917   if (vec_len (vam->graph_nodes) == 0)
21918     {
21919       print (vam->ofp, "Node table empty, issue get_node_graph...");
21920       return 0;
21921     }
21922
21923   for (i = 0; i < vec_len (vam->graph_nodes); i++)
21924     {
21925       node = vam->graph_nodes[i];
21926       print (vam->ofp, "[%d] %s", i, node->name);
21927       for (j = 0; j < vec_len (node->next_nodes); j++)
21928         {
21929           if (node->next_nodes[j] != ~0)
21930             {
21931               next_node = vam->graph_nodes[node->next_nodes[j]];
21932               print (vam->ofp, "  [%d] %s", j, next_node->name);
21933             }
21934         }
21935     }
21936   return 0;
21937 }
21938
21939 static int
21940 value_sort_cmp (void *a1, void *a2)
21941 {
21942   name_sort_t *n1 = a1;
21943   name_sort_t *n2 = a2;
21944
21945   if (n1->value < n2->value)
21946     return -1;
21947   if (n1->value > n2->value)
21948     return 1;
21949   return 0;
21950 }
21951
21952
21953 static int
21954 dump_msg_api_table (vat_main_t * vam)
21955 {
21956   api_main_t *am = &api_main;
21957   name_sort_t *nses = 0, *ns;
21958   hash_pair_t *hp;
21959   int i;
21960
21961   /* *INDENT-OFF* */
21962   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21963   ({
21964     vec_add2 (nses, ns, 1);
21965     ns->name = (u8 *)(hp->key);
21966     ns->value = (u32) hp->value[0];
21967   }));
21968   /* *INDENT-ON* */
21969
21970   vec_sort_with_function (nses, value_sort_cmp);
21971
21972   for (i = 0; i < vec_len (nses); i++)
21973     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21974   vec_free (nses);
21975   return 0;
21976 }
21977
21978 static int
21979 get_msg_id (vat_main_t * vam)
21980 {
21981   u8 *name_and_crc;
21982   u32 message_index;
21983
21984   if (unformat (vam->input, "%s", &name_and_crc))
21985     {
21986       message_index = vl_api_get_msg_index (name_and_crc);
21987       if (message_index == ~0)
21988         {
21989           print (vam->ofp, " '%s' not found", name_and_crc);
21990           return 0;
21991         }
21992       print (vam->ofp, " '%s' has message index %d",
21993              name_and_crc, message_index);
21994       return 0;
21995     }
21996   errmsg ("name_and_crc required...");
21997   return 0;
21998 }
21999
22000 static int
22001 search_node_table (vat_main_t * vam)
22002 {
22003   unformat_input_t *line_input = vam->input;
22004   u8 *node_to_find;
22005   int j;
22006   vlib_node_t *node, *next_node;
22007   uword *p;
22008
22009   if (vam->graph_node_index_by_name == 0)
22010     {
22011       print (vam->ofp, "Node table empty, issue get_node_graph...");
22012       return 0;
22013     }
22014
22015   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22016     {
22017       if (unformat (line_input, "%s", &node_to_find))
22018         {
22019           vec_add1 (node_to_find, 0);
22020           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
22021           if (p == 0)
22022             {
22023               print (vam->ofp, "%s not found...", node_to_find);
22024               goto out;
22025             }
22026           node = vam->graph_nodes[p[0]];
22027           print (vam->ofp, "[%d] %s", p[0], node->name);
22028           for (j = 0; j < vec_len (node->next_nodes); j++)
22029             {
22030               if (node->next_nodes[j] != ~0)
22031                 {
22032                   next_node = vam->graph_nodes[node->next_nodes[j]];
22033                   print (vam->ofp, "  [%d] %s", j, next_node->name);
22034                 }
22035             }
22036         }
22037
22038       else
22039         {
22040           clib_warning ("parse error '%U'", format_unformat_error,
22041                         line_input);
22042           return -99;
22043         }
22044
22045     out:
22046       vec_free (node_to_find);
22047
22048     }
22049
22050   return 0;
22051 }
22052
22053
22054 static int
22055 script (vat_main_t * vam)
22056 {
22057 #if (VPP_API_TEST_BUILTIN==0)
22058   u8 *s = 0;
22059   char *save_current_file;
22060   unformat_input_t save_input;
22061   jmp_buf save_jump_buf;
22062   u32 save_line_number;
22063
22064   FILE *new_fp, *save_ifp;
22065
22066   if (unformat (vam->input, "%s", &s))
22067     {
22068       new_fp = fopen ((char *) s, "r");
22069       if (new_fp == 0)
22070         {
22071           errmsg ("Couldn't open script file %s", s);
22072           vec_free (s);
22073           return -99;
22074         }
22075     }
22076   else
22077     {
22078       errmsg ("Missing script name");
22079       return -99;
22080     }
22081
22082   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
22083   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
22084   save_ifp = vam->ifp;
22085   save_line_number = vam->input_line_number;
22086   save_current_file = (char *) vam->current_file;
22087
22088   vam->input_line_number = 0;
22089   vam->ifp = new_fp;
22090   vam->current_file = s;
22091   do_one_file (vam);
22092
22093   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
22094   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
22095   vam->ifp = save_ifp;
22096   vam->input_line_number = save_line_number;
22097   vam->current_file = (u8 *) save_current_file;
22098   vec_free (s);
22099
22100   return 0;
22101 #else
22102   clib_warning ("use the exec command...");
22103   return -99;
22104 #endif
22105 }
22106
22107 static int
22108 echo (vat_main_t * vam)
22109 {
22110   print (vam->ofp, "%v", vam->input->buffer);
22111   return 0;
22112 }
22113
22114 /* List of API message constructors, CLI names map to api_xxx */
22115 #define foreach_vpe_api_msg                                             \
22116 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
22117 _(sw_interface_dump,"")                                                 \
22118 _(sw_interface_set_flags,                                               \
22119   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
22120 _(sw_interface_add_del_address,                                         \
22121   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
22122 _(sw_interface_set_rx_mode,                                             \
22123   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
22124 _(sw_interface_set_table,                                               \
22125   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
22126 _(sw_interface_set_mpls_enable,                                         \
22127   "<intfc> | sw_if_index [disable | dis]")                              \
22128 _(sw_interface_set_vpath,                                               \
22129   "<intfc> | sw_if_index <id> enable | disable")                        \
22130 _(sw_interface_set_vxlan_bypass,                                        \
22131   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22132 _(sw_interface_set_geneve_bypass,                                       \
22133   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22134 _(sw_interface_set_l2_xconnect,                                         \
22135   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22136   "enable | disable")                                                   \
22137 _(sw_interface_set_l2_bridge,                                           \
22138   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
22139   "[shg <split-horizon-group>] [bvi]\n"                                 \
22140   "enable | disable")                                                   \
22141 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
22142 _(bridge_domain_add_del,                                                \
22143   "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") \
22144 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
22145 _(l2fib_add_del,                                                        \
22146   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
22147 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
22148 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
22149 _(l2_flags,                                                             \
22150   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22151 _(bridge_flags,                                                         \
22152   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22153 _(tap_connect,                                                          \
22154   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
22155 _(tap_modify,                                                           \
22156   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
22157 _(tap_delete,                                                           \
22158   "<vpp-if-name> | sw_if_index <id>")                                   \
22159 _(sw_interface_tap_dump, "")                                            \
22160 _(ip_table_add_del,                                                     \
22161   "table-id <n> [ipv6]\n")                                              \
22162 _(ip_add_del_route,                                                     \
22163   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
22164   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22165   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22166   "[multipath] [count <n>]")                                            \
22167 _(ip_mroute_add_del,                                                    \
22168   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
22169   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
22170 _(mpls_table_add_del,                                                   \
22171   "table-id <n>\n")                                                     \
22172 _(mpls_route_add_del,                                                   \
22173   "<label> <eos> via <addr> [table-id <n>]\n"                           \
22174   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22175   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22176   "[multipath] [count <n>]")                                            \
22177 _(mpls_ip_bind_unbind,                                                  \
22178   "<label> <addr/len>")                                                 \
22179 _(mpls_tunnel_add_del,                                                  \
22180   " via <addr> [table-id <n>]\n"                                        \
22181   "sw_if_index <id>] [l2]  [del]")                                      \
22182 _(proxy_arp_add_del,                                                    \
22183   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
22184 _(proxy_arp_intfc_enable_disable,                                       \
22185   "<intfc> | sw_if_index <id> enable | disable")                        \
22186 _(sw_interface_set_unnumbered,                                          \
22187   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
22188 _(ip_neighbor_add_del,                                                  \
22189   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
22190   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
22191 _(reset_vrf, "vrf <id> [ipv6]")                                         \
22192 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
22193 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
22194   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
22195   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
22196   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
22197 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
22198 _(reset_fib, "vrf <n> [ipv6]")                                          \
22199 _(dhcp_proxy_config,                                                    \
22200   "svr <v46-address> src <v46-address>\n"                               \
22201    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
22202 _(dhcp_proxy_set_vss,                                                   \
22203   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
22204 _(dhcp_proxy_dump, "ip6")                                               \
22205 _(dhcp_client_config,                                                   \
22206   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
22207 _(set_ip_flow_hash,                                                     \
22208   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
22209 _(sw_interface_ip6_enable_disable,                                      \
22210   "<intfc> | sw_if_index <id> enable | disable")                        \
22211 _(sw_interface_ip6_set_link_local_address,                              \
22212   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
22213 _(ip6nd_proxy_add_del,                                                  \
22214   "<intfc> | sw_if_index <id> <ip6-address>")                           \
22215 _(ip6nd_proxy_dump, "")                                                 \
22216 _(sw_interface_ip6nd_ra_prefix,                                         \
22217   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
22218   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
22219   "[nolink] [isno]")                                                    \
22220 _(sw_interface_ip6nd_ra_config,                                         \
22221   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
22222   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
22223   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
22224 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
22225 _(l2_patch_add_del,                                                     \
22226   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22227   "enable | disable")                                                   \
22228 _(sr_localsid_add_del,                                                  \
22229   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
22230   "fib-table <num> (end.psp) sw_if_index <num>")                        \
22231 _(classify_add_del_table,                                               \
22232   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
22233   " [del] [del-chain] mask <mask-value>\n"                              \
22234   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
22235   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
22236 _(classify_add_del_session,                                             \
22237   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
22238   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
22239   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
22240   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
22241 _(classify_set_interface_ip_table,                                      \
22242   "<intfc> | sw_if_index <nn> table <nn>")                              \
22243 _(classify_set_interface_l2_tables,                                     \
22244   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22245   "  [other-table <nn>]")                                               \
22246 _(get_node_index, "node <node-name")                                    \
22247 _(add_node_next, "node <node-name> next <next-node-name>")              \
22248 _(l2tpv3_create_tunnel,                                                 \
22249   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
22250   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
22251   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
22252 _(l2tpv3_set_tunnel_cookies,                                            \
22253   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
22254   "[new_remote_cookie <nn>]\n")                                         \
22255 _(l2tpv3_interface_enable_disable,                                      \
22256   "<intfc> | sw_if_index <nn> enable | disable")                        \
22257 _(l2tpv3_set_lookup_key,                                                \
22258   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
22259 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
22260 _(vxlan_add_del_tunnel,                                                 \
22261   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22262   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22263   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22264 _(geneve_add_del_tunnel,                                                \
22265   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22266   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22267   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22268 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22269 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22270 _(gre_add_del_tunnel,                                                   \
22271   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
22272 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22273 _(l2_fib_clear_table, "")                                               \
22274 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22275 _(l2_interface_vlan_tag_rewrite,                                        \
22276   "<intfc> | sw_if_index <nn> \n"                                       \
22277   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22278   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22279 _(create_vhost_user_if,                                                 \
22280         "socket <filename> [server] [renumber <dev_instance>] "         \
22281         "[mac <mac_address>]")                                          \
22282 _(modify_vhost_user_if,                                                 \
22283         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22284         "[server] [renumber <dev_instance>]")                           \
22285 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22286 _(sw_interface_vhost_user_dump, "")                                     \
22287 _(show_version, "")                                                     \
22288 _(vxlan_gpe_add_del_tunnel,                                             \
22289   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22290   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22291   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22292   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22293 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22294 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22295 _(interface_name_renumber,                                              \
22296   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22297 _(input_acl_set_interface,                                              \
22298   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22299   "  [l2-table <nn>] [del]")                                            \
22300 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22301 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22302 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22303 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22304 _(ip_dump, "ipv4 | ipv6")                                               \
22305 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22306 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22307   "  spid_id <n> ")                                                     \
22308 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22309   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22310   "  integ_alg <alg> integ_key <hex>")                                  \
22311 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
22312   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22313   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22314   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22315 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
22316 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22317   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22318   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22319   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
22320 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22321 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
22322   "  <alg> <hex>\n")                                                    \
22323 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22324 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
22325 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
22326   "(auth_data 0x<data> | auth_data <data>)")                            \
22327 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
22328   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
22329 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
22330   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
22331   "(local|remote)")                                                     \
22332 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
22333 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
22334 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22335 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22336 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
22337 _(ikev2_initiate_sa_init, "<profile_name>")                             \
22338 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
22339 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
22340 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
22341 _(delete_loopback,"sw_if_index <nn>")                                   \
22342 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22343 _(map_add_domain,                                                       \
22344   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
22345   "ip6-src <ip6addr> "                                                  \
22346   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
22347 _(map_del_domain, "index <n>")                                          \
22348 _(map_add_del_rule,                                                     \
22349   "index <n> psid <n> dst <ip6addr> [del]")                             \
22350 _(map_domain_dump, "")                                                  \
22351 _(map_rule_dump, "index <map-domain>")                                  \
22352 _(want_interface_events,  "enable|disable")                             \
22353 _(want_stats,"enable|disable")                                          \
22354 _(get_first_msg_id, "client <name>")                                    \
22355 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22356 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22357   "fib-id <nn> [ip4][ip6][default]")                                    \
22358 _(get_node_graph, " ")                                                  \
22359 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22360 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22361 _(ioam_disable, "")                                                     \
22362 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22363                             " sw_if_index <sw_if_index> p <priority> "  \
22364                             "w <weight>] [del]")                        \
22365 _(one_add_del_locator, "locator-set <locator_name> "                    \
22366                         "iface <intf> | sw_if_index <sw_if_index> "     \
22367                         "p <priority> w <weight> [del]")                \
22368 _(one_add_del_local_eid,"vni <vni> eid "                                \
22369                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22370                          "locator-set <locator_name> [del]"             \
22371                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22372 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22373 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22374 _(one_enable_disable, "enable|disable")                                 \
22375 _(one_map_register_enable_disable, "enable|disable")                    \
22376 _(one_map_register_fallback_threshold, "<value>")                       \
22377 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22378 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22379                                "[seid <seid>] "                         \
22380                                "rloc <locator> p <prio> "               \
22381                                "w <weight> [rloc <loc> ... ] "          \
22382                                "action <action> [del-all]")             \
22383 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22384                           "<local-eid>")                                \
22385 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22386 _(one_use_petr, "ip-address> | disable")                                \
22387 _(one_map_request_mode, "src-dst|dst-only")                             \
22388 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22389 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22390 _(one_locator_set_dump, "[local | remote]")                             \
22391 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22392 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22393                        "[local] | [remote]")                            \
22394 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22395 _(one_ndp_bd_get, "")                                                   \
22396 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22397 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22398 _(one_l2_arp_bd_get, "")                                                \
22399 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22400 _(one_stats_enable_disable, "enable|disalbe")                           \
22401 _(show_one_stats_enable_disable, "")                                    \
22402 _(one_eid_table_vni_dump, "")                                           \
22403 _(one_eid_table_map_dump, "l2|l3")                                      \
22404 _(one_map_resolver_dump, "")                                            \
22405 _(one_map_server_dump, "")                                              \
22406 _(one_adjacencies_get, "vni <vni>")                                     \
22407 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22408 _(show_one_rloc_probe_state, "")                                        \
22409 _(show_one_map_register_state, "")                                      \
22410 _(show_one_status, "")                                                  \
22411 _(one_stats_dump, "")                                                   \
22412 _(one_stats_flush, "")                                                  \
22413 _(one_get_map_request_itr_rlocs, "")                                    \
22414 _(one_map_register_set_ttl, "<ttl>")                                    \
22415 _(one_set_transport_protocol, "udp|api")                                \
22416 _(one_get_transport_protocol, "")                                       \
22417 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22418 _(one_show_xtr_mode, "")                                                \
22419 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22420 _(one_show_pitr_mode, "")                                               \
22421 _(one_enable_disable_petr_mode, "enable|disable")                       \
22422 _(one_show_petr_mode, "")                                               \
22423 _(show_one_nsh_mapping, "")                                             \
22424 _(show_one_pitr, "")                                                    \
22425 _(show_one_use_petr, "")                                                \
22426 _(show_one_map_request_mode, "")                                        \
22427 _(show_one_map_register_ttl, "")                                        \
22428 _(show_one_map_register_fallback_threshold, "")                         \
22429 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22430                             " sw_if_index <sw_if_index> p <priority> "  \
22431                             "w <weight>] [del]")                        \
22432 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22433                         "iface <intf> | sw_if_index <sw_if_index> "     \
22434                         "p <priority> w <weight> [del]")                \
22435 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22436                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22437                          "locator-set <locator_name> [del]"             \
22438                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22439 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22440 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22441 _(lisp_enable_disable, "enable|disable")                                \
22442 _(lisp_map_register_enable_disable, "enable|disable")                   \
22443 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22444 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22445                                "[seid <seid>] "                         \
22446                                "rloc <locator> p <prio> "               \
22447                                "w <weight> [rloc <loc> ... ] "          \
22448                                "action <action> [del-all]")             \
22449 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22450                           "<local-eid>")                                \
22451 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22452 _(lisp_use_petr, "<ip-address> | disable")                              \
22453 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22454 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22455 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22456 _(lisp_locator_set_dump, "[local | remote]")                            \
22457 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22458 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22459                        "[local] | [remote]")                            \
22460 _(lisp_eid_table_vni_dump, "")                                          \
22461 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22462 _(lisp_map_resolver_dump, "")                                           \
22463 _(lisp_map_server_dump, "")                                             \
22464 _(lisp_adjacencies_get, "vni <vni>")                                    \
22465 _(gpe_fwd_entry_vnis_get, "")                                           \
22466 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22467 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22468                                 "[table <table-id>]")                   \
22469 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22470 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22471 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22472 _(gpe_get_encap_mode, "")                                               \
22473 _(lisp_gpe_add_del_iface, "up|down")                                    \
22474 _(lisp_gpe_enable_disable, "enable|disable")                            \
22475 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22476   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22477 _(show_lisp_rloc_probe_state, "")                                       \
22478 _(show_lisp_map_register_state, "")                                     \
22479 _(show_lisp_status, "")                                                 \
22480 _(lisp_get_map_request_itr_rlocs, "")                                   \
22481 _(show_lisp_pitr, "")                                                   \
22482 _(show_lisp_use_petr, "")                                               \
22483 _(show_lisp_map_request_mode, "")                                       \
22484 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22485 _(af_packet_delete, "name <host interface name>")                       \
22486 _(policer_add_del, "name <policer name> <params> [del]")                \
22487 _(policer_dump, "[name <policer name>]")                                \
22488 _(policer_classify_set_interface,                                       \
22489   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22490   "  [l2-table <nn>] [del]")                                            \
22491 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22492 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22493     "[master|slave]")                                                   \
22494 _(netmap_delete, "name <interface name>")                               \
22495 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22496 _(mpls_fib_dump, "")                                                    \
22497 _(classify_table_ids, "")                                               \
22498 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22499 _(classify_table_info, "table_id <nn>")                                 \
22500 _(classify_session_dump, "table_id <nn>")                               \
22501 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22502     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22503     "[template_interval <nn>] [udp_checksum]")                          \
22504 _(ipfix_exporter_dump, "")                                              \
22505 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22506 _(ipfix_classify_stream_dump, "")                                       \
22507 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22508 _(ipfix_classify_table_dump, "")                                        \
22509 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22510 _(sw_interface_span_dump, "[l2]")                                           \
22511 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22512 _(pg_create_interface, "if_id <nn>")                                    \
22513 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22514 _(pg_enable_disable, "[stream <id>] disable")                           \
22515 _(ip_source_and_port_range_check_add_del,                               \
22516   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22517 _(ip_source_and_port_range_check_interface_add_del,                     \
22518   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
22519   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
22520 _(ipsec_gre_add_del_tunnel,                                             \
22521   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
22522 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
22523 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
22524 _(l2_interface_pbb_tag_rewrite,                                         \
22525   "<intfc> | sw_if_index <nn> \n"                                       \
22526   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
22527   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
22528 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
22529 _(flow_classify_set_interface,                                          \
22530   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
22531 _(flow_classify_dump, "type [ip4|ip6]")                                 \
22532 _(ip_fib_dump, "")                                                      \
22533 _(ip_mfib_dump, "")                                                     \
22534 _(ip6_fib_dump, "")                                                     \
22535 _(ip6_mfib_dump, "")                                                    \
22536 _(feature_enable_disable, "arc_name <arc_name> "                        \
22537   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
22538 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
22539 "[disable]")                                                            \
22540 _(l2_xconnect_dump, "")                                                 \
22541 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
22542 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
22543 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
22544 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
22545 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
22546 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
22547 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
22548   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
22549 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
22550 _(memfd_segment_create,"size <nnn>")                                    \
22551 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
22552 _(dns_enable_disable, "[enable][disable]")                              \
22553 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22554 _(dns_resolve_name, "<hostname>")                                       \
22555 _(dns_resolve_ip, "<ip4|ip6>")                                          \
22556 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22557 _(dns_resolve_name, "<hostname>")                                       \
22558 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
22559   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
22560 _(session_rules_dump, "")                                               \
22561
22562 /* List of command functions, CLI names map directly to functions */
22563 #define foreach_cli_function                                    \
22564 _(comment, "usage: comment <ignore-rest-of-line>")              \
22565 _(dump_interface_table, "usage: dump_interface_table")          \
22566 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
22567 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
22568 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
22569 _(dump_stats_table, "usage: dump_stats_table")                  \
22570 _(dump_macro_table, "usage: dump_macro_table ")                 \
22571 _(dump_node_table, "usage: dump_node_table")                    \
22572 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
22573 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
22574 _(echo, "usage: echo <message>")                                \
22575 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
22576 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
22577 _(help, "usage: help")                                          \
22578 _(q, "usage: quit")                                             \
22579 _(quit, "usage: quit")                                          \
22580 _(search_node_table, "usage: search_node_table <name>...")      \
22581 _(set, "usage: set <variable-name> <value>")                    \
22582 _(script, "usage: script <file-name>")                          \
22583 _(unset, "usage: unset <variable-name>")
22584 #define _(N,n)                                  \
22585     static void vl_api_##n##_t_handler_uni      \
22586     (vl_api_##n##_t * mp)                       \
22587     {                                           \
22588         vat_main_t * vam = &vat_main;           \
22589         if (vam->json_output) {                 \
22590             vl_api_##n##_t_handler_json(mp);    \
22591         } else {                                \
22592             vl_api_##n##_t_handler(mp);         \
22593         }                                       \
22594     }
22595 foreach_vpe_api_reply_msg;
22596 #if VPP_API_TEST_BUILTIN == 0
22597 foreach_standalone_reply_msg;
22598 #endif
22599 #undef _
22600
22601 void
22602 vat_api_hookup (vat_main_t * vam)
22603 {
22604 #define _(N,n)                                                  \
22605     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22606                            vl_api_##n##_t_handler_uni,          \
22607                            vl_noop_handler,                     \
22608                            vl_api_##n##_t_endian,               \
22609                            vl_api_##n##_t_print,                \
22610                            sizeof(vl_api_##n##_t), 1);
22611   foreach_vpe_api_reply_msg;
22612 #if VPP_API_TEST_BUILTIN == 0
22613   foreach_standalone_reply_msg;
22614 #endif
22615 #undef _
22616
22617 #if (VPP_API_TEST_BUILTIN==0)
22618   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22619
22620   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22621
22622   vam->function_by_name = hash_create_string (0, sizeof (uword));
22623
22624   vam->help_by_name = hash_create_string (0, sizeof (uword));
22625 #endif
22626
22627   /* API messages we can send */
22628 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22629   foreach_vpe_api_msg;
22630 #undef _
22631
22632   /* Help strings */
22633 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22634   foreach_vpe_api_msg;
22635 #undef _
22636
22637   /* CLI functions */
22638 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22639   foreach_cli_function;
22640 #undef _
22641
22642   /* Help strings */
22643 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22644   foreach_cli_function;
22645 #undef _
22646 }
22647
22648 #if VPP_API_TEST_BUILTIN
22649 static clib_error_t *
22650 vat_api_hookup_shim (vlib_main_t * vm)
22651 {
22652   vat_api_hookup (&vat_main);
22653   return 0;
22654 }
22655
22656 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22657 #endif
22658
22659 /*
22660  * fd.io coding-style-patch-verification: ON
22661  *
22662  * Local Variables:
22663  * eval: (c-set-style "gnu")
22664  * End:
22665  */