ip: add container proxy api
[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 _(ip_container_proxy_add_del_reply)
5310
5311 #define _(n)                                    \
5312     static void vl_api_##n##_t_handler          \
5313     (vl_api_##n##_t * mp)                       \
5314     {                                           \
5315         vat_main_t * vam = &vat_main;           \
5316         i32 retval = ntohl(mp->retval);         \
5317         if (vam->async_mode) {                  \
5318             vam->async_errors += (retval < 0);  \
5319         } else {                                \
5320             vam->retval = retval;               \
5321             vam->result_ready = 1;              \
5322         }                                       \
5323     }
5324 foreach_standard_reply_retval_handler;
5325 #undef _
5326
5327 #define _(n)                                    \
5328     static void vl_api_##n##_t_handler_json     \
5329     (vl_api_##n##_t * mp)                       \
5330     {                                           \
5331         vat_main_t * vam = &vat_main;           \
5332         vat_json_node_t node;                   \
5333         vat_json_init_object(&node);            \
5334         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5335         vat_json_print(vam->ofp, &node);        \
5336         vam->retval = ntohl(mp->retval);        \
5337         vam->result_ready = 1;                  \
5338     }
5339 foreach_standard_reply_retval_handler;
5340 #undef _
5341
5342 /*
5343  * Table of message reply handlers, must include boilerplate handlers
5344  * we just generated
5345  */
5346
5347 #define foreach_vpe_api_reply_msg                                       \
5348 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5349 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5350 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5351 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5352 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5353 _(CLI_REPLY, cli_reply)                                                 \
5354 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5355 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5356   sw_interface_add_del_address_reply)                                   \
5357 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5358 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5359 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5360 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5361 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5362 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5363 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5364 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5365   sw_interface_set_l2_xconnect_reply)                                   \
5366 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5367   sw_interface_set_l2_bridge_reply)                                     \
5368 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5369 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5370 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5371 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5372 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5373 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5374 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5375 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5376 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5377 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5378 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5379 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5380 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5381 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5382 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5383 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5384 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5385 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5386 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5387 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5388   proxy_arp_intfc_enable_disable_reply)                                 \
5389 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5390 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5391   sw_interface_set_unnumbered_reply)                                    \
5392 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5393 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
5394 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5395 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5396 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5397 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5398 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5399 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5400 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5401 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5402 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5403 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5404   sw_interface_ip6_enable_disable_reply)                                \
5405 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5406   sw_interface_ip6_set_link_local_address_reply)                        \
5407 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5408 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5409 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5410   sw_interface_ip6nd_ra_prefix_reply)                                   \
5411 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5412   sw_interface_ip6nd_ra_config_reply)                                   \
5413 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5414 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5415 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5416 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5417 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5418 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5419 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5420 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5421 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5422 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5423 classify_set_interface_ip_table_reply)                                  \
5424 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5425   classify_set_interface_l2_tables_reply)                               \
5426 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5427 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5428 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5429 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5430 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5431   l2tpv3_interface_enable_disable_reply)                                \
5432 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5433 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5434 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5435 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5436 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5437 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5438 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5439 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5440 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5441 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5442 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5443 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5444 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5445 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5446 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5447 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5448 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5449 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
5450 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5451 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5452 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5453 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5454 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5455 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5456 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5457 _(L2_MACS_EVENT, l2_macs_event)                                         \
5458 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5459 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5460 _(IP_DETAILS, ip_details)                                               \
5461 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5462 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5463 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5464 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5465 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5466 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5467 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5468 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5469 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5470 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5471 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5472 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5473 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5474 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5475 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5476 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5477 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5478 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5479 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5480 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5481 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5482 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5483 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5484 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5485 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5486 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5487 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5488 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5489 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5490 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5491 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5492 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5493 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5494 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5495 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5496 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5497 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5498 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5499 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5500 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5501 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5502 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5503 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5504 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5505 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5506 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5507 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5508 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5509   one_map_register_enable_disable_reply)                                \
5510 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5511 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5512 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5513 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5514   one_map_register_fallback_threshold_reply)                            \
5515 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5516   one_rloc_probe_enable_disable_reply)                                  \
5517 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5518 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5519 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5520 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5521 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5522 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5523 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5524 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5525 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5526 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5527 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5528 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5529 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5530 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5531 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5532 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5533   show_one_stats_enable_disable_reply)                                  \
5534 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5535 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5536 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5537 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5538 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5539 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5540 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5541 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5542   one_enable_disable_pitr_mode_reply)                                   \
5543 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5544   one_enable_disable_petr_mode_reply)                                   \
5545 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5546 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5547 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5548 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5549 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5550 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5551 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5552 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5553 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5554 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5555 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5556 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5557   gpe_add_del_native_fwd_rpath_reply)                                   \
5558 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5559   gpe_fwd_entry_path_details)                                           \
5560 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5561 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5562   one_add_del_map_request_itr_rlocs_reply)                              \
5563 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5564   one_get_map_request_itr_rlocs_reply)                                  \
5565 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5566 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5567 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5568 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5569 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5570 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5571   show_one_map_register_state_reply)                                    \
5572 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5573 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5574   show_one_map_register_fallback_threshold_reply)                       \
5575 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5576 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5577 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5578 _(POLICER_DETAILS, policer_details)                                     \
5579 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5580 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5581 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5582 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5583 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5584 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5585 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5586 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5587 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5588 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5589 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5590 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5591 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5592 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5593 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5594 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5595 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5596 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5597 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5598 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5599 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5600 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5601 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5602 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5603 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5604  ip_source_and_port_range_check_add_del_reply)                          \
5605 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5606  ip_source_and_port_range_check_interface_add_del_reply)                \
5607 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5608 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5609 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5610 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5611 _(PUNT_REPLY, punt_reply)                                               \
5612 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5613 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5614 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5615 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5616 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5617 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5618 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5619 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5620 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5621 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5622 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5623 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5624 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5625 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5626 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5627 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5628 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5629 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5630 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5631 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5632 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5633
5634 #define foreach_standalone_reply_msg                                    \
5635 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5636 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5637 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5638 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5639 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5640 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5641 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
5642 _(MEMFD_SEGMENT_CREATE_REPLY, memfd_segment_create_reply)               \
5643
5644 typedef struct
5645 {
5646   u8 *name;
5647   u32 value;
5648 } name_sort_t;
5649
5650
5651 #define STR_VTR_OP_CASE(op)     \
5652     case L2_VTR_ ## op:         \
5653         return "" # op;
5654
5655 static const char *
5656 str_vtr_op (u32 vtr_op)
5657 {
5658   switch (vtr_op)
5659     {
5660       STR_VTR_OP_CASE (DISABLED);
5661       STR_VTR_OP_CASE (PUSH_1);
5662       STR_VTR_OP_CASE (PUSH_2);
5663       STR_VTR_OP_CASE (POP_1);
5664       STR_VTR_OP_CASE (POP_2);
5665       STR_VTR_OP_CASE (TRANSLATE_1_1);
5666       STR_VTR_OP_CASE (TRANSLATE_1_2);
5667       STR_VTR_OP_CASE (TRANSLATE_2_1);
5668       STR_VTR_OP_CASE (TRANSLATE_2_2);
5669     }
5670
5671   return "UNKNOWN";
5672 }
5673
5674 static int
5675 dump_sub_interface_table (vat_main_t * vam)
5676 {
5677   const sw_interface_subif_t *sub = NULL;
5678
5679   if (vam->json_output)
5680     {
5681       clib_warning
5682         ("JSON output supported only for VPE API calls and dump_stats_table");
5683       return -99;
5684     }
5685
5686   print (vam->ofp,
5687          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5688          "Interface", "sw_if_index",
5689          "sub id", "dot1ad", "tags", "outer id",
5690          "inner id", "exact", "default", "outer any", "inner any");
5691
5692   vec_foreach (sub, vam->sw_if_subif_table)
5693   {
5694     print (vam->ofp,
5695            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5696            sub->interface_name,
5697            sub->sw_if_index,
5698            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5699            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5700            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5701            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5702     if (sub->vtr_op != L2_VTR_DISABLED)
5703       {
5704         print (vam->ofp,
5705                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5706                "tag1: %d tag2: %d ]",
5707                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5708                sub->vtr_tag1, sub->vtr_tag2);
5709       }
5710   }
5711
5712   return 0;
5713 }
5714
5715 static int
5716 name_sort_cmp (void *a1, void *a2)
5717 {
5718   name_sort_t *n1 = a1;
5719   name_sort_t *n2 = a2;
5720
5721   return strcmp ((char *) n1->name, (char *) n2->name);
5722 }
5723
5724 static int
5725 dump_interface_table (vat_main_t * vam)
5726 {
5727   hash_pair_t *p;
5728   name_sort_t *nses = 0, *ns;
5729
5730   if (vam->json_output)
5731     {
5732       clib_warning
5733         ("JSON output supported only for VPE API calls and dump_stats_table");
5734       return -99;
5735     }
5736
5737   /* *INDENT-OFF* */
5738   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5739   ({
5740     vec_add2 (nses, ns, 1);
5741     ns->name = (u8 *)(p->key);
5742     ns->value = (u32) p->value[0];
5743   }));
5744   /* *INDENT-ON* */
5745
5746   vec_sort_with_function (nses, name_sort_cmp);
5747
5748   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5749   vec_foreach (ns, nses)
5750   {
5751     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5752   }
5753   vec_free (nses);
5754   return 0;
5755 }
5756
5757 static int
5758 dump_ip_table (vat_main_t * vam, int is_ipv6)
5759 {
5760   const ip_details_t *det = NULL;
5761   const ip_address_details_t *address = NULL;
5762   u32 i = ~0;
5763
5764   print (vam->ofp, "%-12s", "sw_if_index");
5765
5766   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5767   {
5768     i++;
5769     if (!det->present)
5770       {
5771         continue;
5772       }
5773     print (vam->ofp, "%-12d", i);
5774     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5775     if (!det->addr)
5776       {
5777         continue;
5778       }
5779     vec_foreach (address, det->addr)
5780     {
5781       print (vam->ofp,
5782              "            %-30U%-13d",
5783              is_ipv6 ? format_ip6_address : format_ip4_address,
5784              address->ip, address->prefix_length);
5785     }
5786   }
5787
5788   return 0;
5789 }
5790
5791 static int
5792 dump_ipv4_table (vat_main_t * vam)
5793 {
5794   if (vam->json_output)
5795     {
5796       clib_warning
5797         ("JSON output supported only for VPE API calls and dump_stats_table");
5798       return -99;
5799     }
5800
5801   return dump_ip_table (vam, 0);
5802 }
5803
5804 static int
5805 dump_ipv6_table (vat_main_t * vam)
5806 {
5807   if (vam->json_output)
5808     {
5809       clib_warning
5810         ("JSON output supported only for VPE API calls and dump_stats_table");
5811       return -99;
5812     }
5813
5814   return dump_ip_table (vam, 1);
5815 }
5816
5817 static char *
5818 counter_type_to_str (u8 counter_type, u8 is_combined)
5819 {
5820   if (!is_combined)
5821     {
5822       switch (counter_type)
5823         {
5824         case VNET_INTERFACE_COUNTER_DROP:
5825           return "drop";
5826         case VNET_INTERFACE_COUNTER_PUNT:
5827           return "punt";
5828         case VNET_INTERFACE_COUNTER_IP4:
5829           return "ip4";
5830         case VNET_INTERFACE_COUNTER_IP6:
5831           return "ip6";
5832         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5833           return "rx-no-buf";
5834         case VNET_INTERFACE_COUNTER_RX_MISS:
5835           return "rx-miss";
5836         case VNET_INTERFACE_COUNTER_RX_ERROR:
5837           return "rx-error";
5838         case VNET_INTERFACE_COUNTER_TX_ERROR:
5839           return "tx-error";
5840         default:
5841           return "INVALID-COUNTER-TYPE";
5842         }
5843     }
5844   else
5845     {
5846       switch (counter_type)
5847         {
5848         case VNET_INTERFACE_COUNTER_RX:
5849           return "rx";
5850         case VNET_INTERFACE_COUNTER_TX:
5851           return "tx";
5852         default:
5853           return "INVALID-COUNTER-TYPE";
5854         }
5855     }
5856 }
5857
5858 static int
5859 dump_stats_table (vat_main_t * vam)
5860 {
5861   vat_json_node_t node;
5862   vat_json_node_t *msg_array;
5863   vat_json_node_t *msg;
5864   vat_json_node_t *counter_array;
5865   vat_json_node_t *counter;
5866   interface_counter_t c;
5867   u64 packets;
5868   ip4_fib_counter_t *c4;
5869   ip6_fib_counter_t *c6;
5870   ip4_nbr_counter_t *n4;
5871   ip6_nbr_counter_t *n6;
5872   int i, j;
5873
5874   if (!vam->json_output)
5875     {
5876       clib_warning ("dump_stats_table supported only in JSON format");
5877       return -99;
5878     }
5879
5880   vat_json_init_object (&node);
5881
5882   /* interface counters */
5883   msg_array = vat_json_object_add (&node, "interface_counters");
5884   vat_json_init_array (msg_array);
5885   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5886     {
5887       msg = vat_json_array_add (msg_array);
5888       vat_json_init_object (msg);
5889       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5890                                        (u8 *) counter_type_to_str (i, 0));
5891       vat_json_object_add_int (msg, "is_combined", 0);
5892       counter_array = vat_json_object_add (msg, "data");
5893       vat_json_init_array (counter_array);
5894       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5895         {
5896           packets = vam->simple_interface_counters[i][j];
5897           vat_json_array_add_uint (counter_array, packets);
5898         }
5899     }
5900   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5901     {
5902       msg = vat_json_array_add (msg_array);
5903       vat_json_init_object (msg);
5904       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5905                                        (u8 *) counter_type_to_str (i, 1));
5906       vat_json_object_add_int (msg, "is_combined", 1);
5907       counter_array = vat_json_object_add (msg, "data");
5908       vat_json_init_array (counter_array);
5909       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5910         {
5911           c = vam->combined_interface_counters[i][j];
5912           counter = vat_json_array_add (counter_array);
5913           vat_json_init_object (counter);
5914           vat_json_object_add_uint (counter, "packets", c.packets);
5915           vat_json_object_add_uint (counter, "bytes", c.bytes);
5916         }
5917     }
5918
5919   /* ip4 fib counters */
5920   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
5921   vat_json_init_array (msg_array);
5922   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
5923     {
5924       msg = vat_json_array_add (msg_array);
5925       vat_json_init_object (msg);
5926       vat_json_object_add_uint (msg, "vrf_id",
5927                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
5928       counter_array = vat_json_object_add (msg, "c");
5929       vat_json_init_array (counter_array);
5930       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
5931         {
5932           counter = vat_json_array_add (counter_array);
5933           vat_json_init_object (counter);
5934           c4 = &vam->ip4_fib_counters[i][j];
5935           vat_json_object_add_ip4 (counter, "address", c4->address);
5936           vat_json_object_add_uint (counter, "address_length",
5937                                     c4->address_length);
5938           vat_json_object_add_uint (counter, "packets", c4->packets);
5939           vat_json_object_add_uint (counter, "bytes", c4->bytes);
5940         }
5941     }
5942
5943   /* ip6 fib counters */
5944   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
5945   vat_json_init_array (msg_array);
5946   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
5947     {
5948       msg = vat_json_array_add (msg_array);
5949       vat_json_init_object (msg);
5950       vat_json_object_add_uint (msg, "vrf_id",
5951                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
5952       counter_array = vat_json_object_add (msg, "c");
5953       vat_json_init_array (counter_array);
5954       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
5955         {
5956           counter = vat_json_array_add (counter_array);
5957           vat_json_init_object (counter);
5958           c6 = &vam->ip6_fib_counters[i][j];
5959           vat_json_object_add_ip6 (counter, "address", c6->address);
5960           vat_json_object_add_uint (counter, "address_length",
5961                                     c6->address_length);
5962           vat_json_object_add_uint (counter, "packets", c6->packets);
5963           vat_json_object_add_uint (counter, "bytes", c6->bytes);
5964         }
5965     }
5966
5967   /* ip4 nbr counters */
5968   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
5969   vat_json_init_array (msg_array);
5970   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
5971     {
5972       msg = vat_json_array_add (msg_array);
5973       vat_json_init_object (msg);
5974       vat_json_object_add_uint (msg, "sw_if_index", i);
5975       counter_array = vat_json_object_add (msg, "c");
5976       vat_json_init_array (counter_array);
5977       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
5978         {
5979           counter = vat_json_array_add (counter_array);
5980           vat_json_init_object (counter);
5981           n4 = &vam->ip4_nbr_counters[i][j];
5982           vat_json_object_add_ip4 (counter, "address", n4->address);
5983           vat_json_object_add_uint (counter, "link-type", n4->linkt);
5984           vat_json_object_add_uint (counter, "packets", n4->packets);
5985           vat_json_object_add_uint (counter, "bytes", n4->bytes);
5986         }
5987     }
5988
5989   /* ip6 nbr counters */
5990   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
5991   vat_json_init_array (msg_array);
5992   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
5993     {
5994       msg = vat_json_array_add (msg_array);
5995       vat_json_init_object (msg);
5996       vat_json_object_add_uint (msg, "sw_if_index", i);
5997       counter_array = vat_json_object_add (msg, "c");
5998       vat_json_init_array (counter_array);
5999       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6000         {
6001           counter = vat_json_array_add (counter_array);
6002           vat_json_init_object (counter);
6003           n6 = &vam->ip6_nbr_counters[i][j];
6004           vat_json_object_add_ip6 (counter, "address", n6->address);
6005           vat_json_object_add_uint (counter, "packets", n6->packets);
6006           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6007         }
6008     }
6009
6010   vat_json_print (vam->ofp, &node);
6011   vat_json_free (&node);
6012
6013   return 0;
6014 }
6015
6016 /*
6017  * Pass CLI buffers directly in the CLI_INBAND API message,
6018  * instead of an additional shared memory area.
6019  */
6020 static int
6021 exec_inband (vat_main_t * vam)
6022 {
6023   vl_api_cli_inband_t *mp;
6024   unformat_input_t *i = vam->input;
6025   int ret;
6026
6027   if (vec_len (i->buffer) == 0)
6028     return -1;
6029
6030   if (vam->exec_mode == 0 && unformat (i, "mode"))
6031     {
6032       vam->exec_mode = 1;
6033       return 0;
6034     }
6035   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6036     {
6037       vam->exec_mode = 0;
6038       return 0;
6039     }
6040
6041   /*
6042    * In order for the CLI command to work, it
6043    * must be a vector ending in \n, not a C-string ending
6044    * in \n\0.
6045    */
6046   u32 len = vec_len (vam->input->buffer);
6047   M2 (CLI_INBAND, mp, len);
6048   clib_memcpy (mp->cmd, vam->input->buffer, len);
6049   mp->length = htonl (len);
6050
6051   S (mp);
6052   W (ret);
6053   /* json responses may or may not include a useful reply... */
6054   if (vec_len (vam->cmd_reply))
6055     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6056   return ret;
6057 }
6058
6059 int
6060 exec (vat_main_t * vam)
6061 {
6062   return exec_inband (vam);
6063 }
6064
6065 static int
6066 api_create_loopback (vat_main_t * vam)
6067 {
6068   unformat_input_t *i = vam->input;
6069   vl_api_create_loopback_t *mp;
6070   vl_api_create_loopback_instance_t *mp_lbi;
6071   u8 mac_address[6];
6072   u8 mac_set = 0;
6073   u8 is_specified = 0;
6074   u32 user_instance = 0;
6075   int ret;
6076
6077   memset (mac_address, 0, sizeof (mac_address));
6078
6079   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6080     {
6081       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6082         mac_set = 1;
6083       if (unformat (i, "instance %d", &user_instance))
6084         is_specified = 1;
6085       else
6086         break;
6087     }
6088
6089   if (is_specified)
6090     {
6091       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6092       mp_lbi->is_specified = is_specified;
6093       if (is_specified)
6094         mp_lbi->user_instance = htonl (user_instance);
6095       if (mac_set)
6096         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6097       S (mp_lbi);
6098     }
6099   else
6100     {
6101       /* Construct the API message */
6102       M (CREATE_LOOPBACK, mp);
6103       if (mac_set)
6104         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6105       S (mp);
6106     }
6107
6108   W (ret);
6109   return ret;
6110 }
6111
6112 static int
6113 api_delete_loopback (vat_main_t * vam)
6114 {
6115   unformat_input_t *i = vam->input;
6116   vl_api_delete_loopback_t *mp;
6117   u32 sw_if_index = ~0;
6118   int ret;
6119
6120   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6121     {
6122       if (unformat (i, "sw_if_index %d", &sw_if_index))
6123         ;
6124       else
6125         break;
6126     }
6127
6128   if (sw_if_index == ~0)
6129     {
6130       errmsg ("missing sw_if_index");
6131       return -99;
6132     }
6133
6134   /* Construct the API message */
6135   M (DELETE_LOOPBACK, mp);
6136   mp->sw_if_index = ntohl (sw_if_index);
6137
6138   S (mp);
6139   W (ret);
6140   return ret;
6141 }
6142
6143 static int
6144 api_want_stats (vat_main_t * vam)
6145 {
6146   unformat_input_t *i = vam->input;
6147   vl_api_want_stats_t *mp;
6148   int enable = -1;
6149   int ret;
6150
6151   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6152     {
6153       if (unformat (i, "enable"))
6154         enable = 1;
6155       else if (unformat (i, "disable"))
6156         enable = 0;
6157       else
6158         break;
6159     }
6160
6161   if (enable == -1)
6162     {
6163       errmsg ("missing enable|disable");
6164       return -99;
6165     }
6166
6167   M (WANT_STATS, mp);
6168   mp->enable_disable = enable;
6169
6170   S (mp);
6171   W (ret);
6172   return ret;
6173 }
6174
6175 static int
6176 api_want_interface_events (vat_main_t * vam)
6177 {
6178   unformat_input_t *i = vam->input;
6179   vl_api_want_interface_events_t *mp;
6180   int enable = -1;
6181   int ret;
6182
6183   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6184     {
6185       if (unformat (i, "enable"))
6186         enable = 1;
6187       else if (unformat (i, "disable"))
6188         enable = 0;
6189       else
6190         break;
6191     }
6192
6193   if (enable == -1)
6194     {
6195       errmsg ("missing enable|disable");
6196       return -99;
6197     }
6198
6199   M (WANT_INTERFACE_EVENTS, mp);
6200   mp->enable_disable = enable;
6201
6202   vam->interface_event_display = enable;
6203
6204   S (mp);
6205   W (ret);
6206   return ret;
6207 }
6208
6209
6210 /* Note: non-static, called once to set up the initial intfc table */
6211 int
6212 api_sw_interface_dump (vat_main_t * vam)
6213 {
6214   vl_api_sw_interface_dump_t *mp;
6215   vl_api_control_ping_t *mp_ping;
6216   hash_pair_t *p;
6217   name_sort_t *nses = 0, *ns;
6218   sw_interface_subif_t *sub = NULL;
6219   int ret;
6220
6221   /* Toss the old name table */
6222   /* *INDENT-OFF* */
6223   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6224   ({
6225     vec_add2 (nses, ns, 1);
6226     ns->name = (u8 *)(p->key);
6227     ns->value = (u32) p->value[0];
6228   }));
6229   /* *INDENT-ON* */
6230
6231   hash_free (vam->sw_if_index_by_interface_name);
6232
6233   vec_foreach (ns, nses) vec_free (ns->name);
6234
6235   vec_free (nses);
6236
6237   vec_foreach (sub, vam->sw_if_subif_table)
6238   {
6239     vec_free (sub->interface_name);
6240   }
6241   vec_free (vam->sw_if_subif_table);
6242
6243   /* recreate the interface name hash table */
6244   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6245
6246   /* Get list of ethernets */
6247   M (SW_INTERFACE_DUMP, mp);
6248   mp->name_filter_valid = 1;
6249   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
6250   S (mp);
6251
6252   /* and local / loopback interfaces */
6253   M (SW_INTERFACE_DUMP, mp);
6254   mp->name_filter_valid = 1;
6255   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
6256   S (mp);
6257
6258   /* and packet-generator interfaces */
6259   M (SW_INTERFACE_DUMP, mp);
6260   mp->name_filter_valid = 1;
6261   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
6262   S (mp);
6263
6264   /* and vxlan-gpe tunnel interfaces */
6265   M (SW_INTERFACE_DUMP, mp);
6266   mp->name_filter_valid = 1;
6267   strncpy ((char *) mp->name_filter, "vxlan_gpe",
6268            sizeof (mp->name_filter) - 1);
6269   S (mp);
6270
6271   /* and vxlan tunnel interfaces */
6272   M (SW_INTERFACE_DUMP, mp);
6273   mp->name_filter_valid = 1;
6274   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
6275   S (mp);
6276
6277   /* and geneve tunnel interfaces */
6278   M (SW_INTERFACE_DUMP, mp);
6279   mp->name_filter_valid = 1;
6280   strncpy ((char *) mp->name_filter, "geneve", sizeof (mp->name_filter) - 1);
6281   S (mp);
6282
6283   /* and host (af_packet) interfaces */
6284   M (SW_INTERFACE_DUMP, mp);
6285   mp->name_filter_valid = 1;
6286   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
6287   S (mp);
6288
6289   /* and l2tpv3 tunnel interfaces */
6290   M (SW_INTERFACE_DUMP, mp);
6291   mp->name_filter_valid = 1;
6292   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
6293            sizeof (mp->name_filter) - 1);
6294   S (mp);
6295
6296   /* and GRE tunnel interfaces */
6297   M (SW_INTERFACE_DUMP, mp);
6298   mp->name_filter_valid = 1;
6299   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
6300   S (mp);
6301
6302   /* and LISP-GPE interfaces */
6303   M (SW_INTERFACE_DUMP, mp);
6304   mp->name_filter_valid = 1;
6305   strncpy ((char *) mp->name_filter, "lisp_gpe",
6306            sizeof (mp->name_filter) - 1);
6307   S (mp);
6308
6309   /* and IPSEC tunnel interfaces */
6310   M (SW_INTERFACE_DUMP, mp);
6311   mp->name_filter_valid = 1;
6312   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
6313   S (mp);
6314
6315   /* Use a control ping for synchronization */
6316   MPING (CONTROL_PING, mp_ping);
6317   S (mp_ping);
6318
6319   W (ret);
6320   return ret;
6321 }
6322
6323 static int
6324 api_sw_interface_set_flags (vat_main_t * vam)
6325 {
6326   unformat_input_t *i = vam->input;
6327   vl_api_sw_interface_set_flags_t *mp;
6328   u32 sw_if_index;
6329   u8 sw_if_index_set = 0;
6330   u8 admin_up = 0;
6331   int ret;
6332
6333   /* Parse args required to build the message */
6334   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6335     {
6336       if (unformat (i, "admin-up"))
6337         admin_up = 1;
6338       else if (unformat (i, "admin-down"))
6339         admin_up = 0;
6340       else
6341         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6342         sw_if_index_set = 1;
6343       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6344         sw_if_index_set = 1;
6345       else
6346         break;
6347     }
6348
6349   if (sw_if_index_set == 0)
6350     {
6351       errmsg ("missing interface name or sw_if_index");
6352       return -99;
6353     }
6354
6355   /* Construct the API message */
6356   M (SW_INTERFACE_SET_FLAGS, mp);
6357   mp->sw_if_index = ntohl (sw_if_index);
6358   mp->admin_up_down = admin_up;
6359
6360   /* send it... */
6361   S (mp);
6362
6363   /* Wait for a reply, return the good/bad news... */
6364   W (ret);
6365   return ret;
6366 }
6367
6368 static int
6369 api_sw_interface_set_rx_mode (vat_main_t * vam)
6370 {
6371   unformat_input_t *i = vam->input;
6372   vl_api_sw_interface_set_rx_mode_t *mp;
6373   u32 sw_if_index;
6374   u8 sw_if_index_set = 0;
6375   int ret;
6376   u8 queue_id_valid = 0;
6377   u32 queue_id;
6378   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6379
6380   /* Parse args required to build the message */
6381   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6382     {
6383       if (unformat (i, "queue %d", &queue_id))
6384         queue_id_valid = 1;
6385       else if (unformat (i, "polling"))
6386         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6387       else if (unformat (i, "interrupt"))
6388         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6389       else if (unformat (i, "adaptive"))
6390         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6391       else
6392         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6393         sw_if_index_set = 1;
6394       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6395         sw_if_index_set = 1;
6396       else
6397         break;
6398     }
6399
6400   if (sw_if_index_set == 0)
6401     {
6402       errmsg ("missing interface name or sw_if_index");
6403       return -99;
6404     }
6405   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6406     {
6407       errmsg ("missing rx-mode");
6408       return -99;
6409     }
6410
6411   /* Construct the API message */
6412   M (SW_INTERFACE_SET_RX_MODE, mp);
6413   mp->sw_if_index = ntohl (sw_if_index);
6414   mp->mode = mode;
6415   mp->queue_id_valid = queue_id_valid;
6416   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6417
6418   /* send it... */
6419   S (mp);
6420
6421   /* Wait for a reply, return the good/bad news... */
6422   W (ret);
6423   return ret;
6424 }
6425
6426 static int
6427 api_sw_interface_clear_stats (vat_main_t * vam)
6428 {
6429   unformat_input_t *i = vam->input;
6430   vl_api_sw_interface_clear_stats_t *mp;
6431   u32 sw_if_index;
6432   u8 sw_if_index_set = 0;
6433   int ret;
6434
6435   /* Parse args required to build the message */
6436   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6437     {
6438       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6439         sw_if_index_set = 1;
6440       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6441         sw_if_index_set = 1;
6442       else
6443         break;
6444     }
6445
6446   /* Construct the API message */
6447   M (SW_INTERFACE_CLEAR_STATS, mp);
6448
6449   if (sw_if_index_set == 1)
6450     mp->sw_if_index = ntohl (sw_if_index);
6451   else
6452     mp->sw_if_index = ~0;
6453
6454   /* send it... */
6455   S (mp);
6456
6457   /* Wait for a reply, return the good/bad news... */
6458   W (ret);
6459   return ret;
6460 }
6461
6462 static int
6463 api_sw_interface_add_del_address (vat_main_t * vam)
6464 {
6465   unformat_input_t *i = vam->input;
6466   vl_api_sw_interface_add_del_address_t *mp;
6467   u32 sw_if_index;
6468   u8 sw_if_index_set = 0;
6469   u8 is_add = 1, del_all = 0;
6470   u32 address_length = 0;
6471   u8 v4_address_set = 0;
6472   u8 v6_address_set = 0;
6473   ip4_address_t v4address;
6474   ip6_address_t v6address;
6475   int ret;
6476
6477   /* Parse args required to build the message */
6478   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6479     {
6480       if (unformat (i, "del-all"))
6481         del_all = 1;
6482       else if (unformat (i, "del"))
6483         is_add = 0;
6484       else
6485         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6486         sw_if_index_set = 1;
6487       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6488         sw_if_index_set = 1;
6489       else if (unformat (i, "%U/%d",
6490                          unformat_ip4_address, &v4address, &address_length))
6491         v4_address_set = 1;
6492       else if (unformat (i, "%U/%d",
6493                          unformat_ip6_address, &v6address, &address_length))
6494         v6_address_set = 1;
6495       else
6496         break;
6497     }
6498
6499   if (sw_if_index_set == 0)
6500     {
6501       errmsg ("missing interface name or sw_if_index");
6502       return -99;
6503     }
6504   if (v4_address_set && v6_address_set)
6505     {
6506       errmsg ("both v4 and v6 addresses set");
6507       return -99;
6508     }
6509   if (!v4_address_set && !v6_address_set && !del_all)
6510     {
6511       errmsg ("no addresses set");
6512       return -99;
6513     }
6514
6515   /* Construct the API message */
6516   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6517
6518   mp->sw_if_index = ntohl (sw_if_index);
6519   mp->is_add = is_add;
6520   mp->del_all = del_all;
6521   if (v6_address_set)
6522     {
6523       mp->is_ipv6 = 1;
6524       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6525     }
6526   else
6527     {
6528       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6529     }
6530   mp->address_length = address_length;
6531
6532   /* send it... */
6533   S (mp);
6534
6535   /* Wait for a reply, return good/bad news  */
6536   W (ret);
6537   return ret;
6538 }
6539
6540 static int
6541 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6542 {
6543   unformat_input_t *i = vam->input;
6544   vl_api_sw_interface_set_mpls_enable_t *mp;
6545   u32 sw_if_index;
6546   u8 sw_if_index_set = 0;
6547   u8 enable = 1;
6548   int ret;
6549
6550   /* Parse args required to build the message */
6551   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6552     {
6553       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6554         sw_if_index_set = 1;
6555       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6556         sw_if_index_set = 1;
6557       else if (unformat (i, "disable"))
6558         enable = 0;
6559       else if (unformat (i, "dis"))
6560         enable = 0;
6561       else
6562         break;
6563     }
6564
6565   if (sw_if_index_set == 0)
6566     {
6567       errmsg ("missing interface name or sw_if_index");
6568       return -99;
6569     }
6570
6571   /* Construct the API message */
6572   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6573
6574   mp->sw_if_index = ntohl (sw_if_index);
6575   mp->enable = enable;
6576
6577   /* send it... */
6578   S (mp);
6579
6580   /* Wait for a reply... */
6581   W (ret);
6582   return ret;
6583 }
6584
6585 static int
6586 api_sw_interface_set_table (vat_main_t * vam)
6587 {
6588   unformat_input_t *i = vam->input;
6589   vl_api_sw_interface_set_table_t *mp;
6590   u32 sw_if_index, vrf_id = 0;
6591   u8 sw_if_index_set = 0;
6592   u8 is_ipv6 = 0;
6593   int ret;
6594
6595   /* Parse args required to build the message */
6596   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6597     {
6598       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6599         sw_if_index_set = 1;
6600       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6601         sw_if_index_set = 1;
6602       else if (unformat (i, "vrf %d", &vrf_id))
6603         ;
6604       else if (unformat (i, "ipv6"))
6605         is_ipv6 = 1;
6606       else
6607         break;
6608     }
6609
6610   if (sw_if_index_set == 0)
6611     {
6612       errmsg ("missing interface name or sw_if_index");
6613       return -99;
6614     }
6615
6616   /* Construct the API message */
6617   M (SW_INTERFACE_SET_TABLE, mp);
6618
6619   mp->sw_if_index = ntohl (sw_if_index);
6620   mp->is_ipv6 = is_ipv6;
6621   mp->vrf_id = ntohl (vrf_id);
6622
6623   /* send it... */
6624   S (mp);
6625
6626   /* Wait for a reply... */
6627   W (ret);
6628   return ret;
6629 }
6630
6631 static void vl_api_sw_interface_get_table_reply_t_handler
6632   (vl_api_sw_interface_get_table_reply_t * mp)
6633 {
6634   vat_main_t *vam = &vat_main;
6635
6636   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6637
6638   vam->retval = ntohl (mp->retval);
6639   vam->result_ready = 1;
6640
6641 }
6642
6643 static void vl_api_sw_interface_get_table_reply_t_handler_json
6644   (vl_api_sw_interface_get_table_reply_t * mp)
6645 {
6646   vat_main_t *vam = &vat_main;
6647   vat_json_node_t node;
6648
6649   vat_json_init_object (&node);
6650   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6651   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6652
6653   vat_json_print (vam->ofp, &node);
6654   vat_json_free (&node);
6655
6656   vam->retval = ntohl (mp->retval);
6657   vam->result_ready = 1;
6658 }
6659
6660 static int
6661 api_sw_interface_get_table (vat_main_t * vam)
6662 {
6663   unformat_input_t *i = vam->input;
6664   vl_api_sw_interface_get_table_t *mp;
6665   u32 sw_if_index;
6666   u8 sw_if_index_set = 0;
6667   u8 is_ipv6 = 0;
6668   int ret;
6669
6670   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6671     {
6672       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6673         sw_if_index_set = 1;
6674       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6675         sw_if_index_set = 1;
6676       else if (unformat (i, "ipv6"))
6677         is_ipv6 = 1;
6678       else
6679         break;
6680     }
6681
6682   if (sw_if_index_set == 0)
6683     {
6684       errmsg ("missing interface name or sw_if_index");
6685       return -99;
6686     }
6687
6688   M (SW_INTERFACE_GET_TABLE, mp);
6689   mp->sw_if_index = htonl (sw_if_index);
6690   mp->is_ipv6 = is_ipv6;
6691
6692   S (mp);
6693   W (ret);
6694   return ret;
6695 }
6696
6697 static int
6698 api_sw_interface_set_vpath (vat_main_t * vam)
6699 {
6700   unformat_input_t *i = vam->input;
6701   vl_api_sw_interface_set_vpath_t *mp;
6702   u32 sw_if_index = 0;
6703   u8 sw_if_index_set = 0;
6704   u8 is_enable = 0;
6705   int ret;
6706
6707   /* Parse args required to build the message */
6708   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6709     {
6710       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6711         sw_if_index_set = 1;
6712       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6713         sw_if_index_set = 1;
6714       else if (unformat (i, "enable"))
6715         is_enable = 1;
6716       else if (unformat (i, "disable"))
6717         is_enable = 0;
6718       else
6719         break;
6720     }
6721
6722   if (sw_if_index_set == 0)
6723     {
6724       errmsg ("missing interface name or sw_if_index");
6725       return -99;
6726     }
6727
6728   /* Construct the API message */
6729   M (SW_INTERFACE_SET_VPATH, mp);
6730
6731   mp->sw_if_index = ntohl (sw_if_index);
6732   mp->enable = is_enable;
6733
6734   /* send it... */
6735   S (mp);
6736
6737   /* Wait for a reply... */
6738   W (ret);
6739   return ret;
6740 }
6741
6742 static int
6743 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6744 {
6745   unformat_input_t *i = vam->input;
6746   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6747   u32 sw_if_index = 0;
6748   u8 sw_if_index_set = 0;
6749   u8 is_enable = 1;
6750   u8 is_ipv6 = 0;
6751   int ret;
6752
6753   /* Parse args required to build the message */
6754   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6755     {
6756       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6757         sw_if_index_set = 1;
6758       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6759         sw_if_index_set = 1;
6760       else if (unformat (i, "enable"))
6761         is_enable = 1;
6762       else if (unformat (i, "disable"))
6763         is_enable = 0;
6764       else if (unformat (i, "ip4"))
6765         is_ipv6 = 0;
6766       else if (unformat (i, "ip6"))
6767         is_ipv6 = 1;
6768       else
6769         break;
6770     }
6771
6772   if (sw_if_index_set == 0)
6773     {
6774       errmsg ("missing interface name or sw_if_index");
6775       return -99;
6776     }
6777
6778   /* Construct the API message */
6779   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6780
6781   mp->sw_if_index = ntohl (sw_if_index);
6782   mp->enable = is_enable;
6783   mp->is_ipv6 = is_ipv6;
6784
6785   /* send it... */
6786   S (mp);
6787
6788   /* Wait for a reply... */
6789   W (ret);
6790   return ret;
6791 }
6792
6793 static int
6794 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6795 {
6796   unformat_input_t *i = vam->input;
6797   vl_api_sw_interface_set_geneve_bypass_t *mp;
6798   u32 sw_if_index = 0;
6799   u8 sw_if_index_set = 0;
6800   u8 is_enable = 1;
6801   u8 is_ipv6 = 0;
6802   int ret;
6803
6804   /* Parse args required to build the message */
6805   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6806     {
6807       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6808         sw_if_index_set = 1;
6809       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6810         sw_if_index_set = 1;
6811       else if (unformat (i, "enable"))
6812         is_enable = 1;
6813       else if (unformat (i, "disable"))
6814         is_enable = 0;
6815       else if (unformat (i, "ip4"))
6816         is_ipv6 = 0;
6817       else if (unformat (i, "ip6"))
6818         is_ipv6 = 1;
6819       else
6820         break;
6821     }
6822
6823   if (sw_if_index_set == 0)
6824     {
6825       errmsg ("missing interface name or sw_if_index");
6826       return -99;
6827     }
6828
6829   /* Construct the API message */
6830   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6831
6832   mp->sw_if_index = ntohl (sw_if_index);
6833   mp->enable = is_enable;
6834   mp->is_ipv6 = is_ipv6;
6835
6836   /* send it... */
6837   S (mp);
6838
6839   /* Wait for a reply... */
6840   W (ret);
6841   return ret;
6842 }
6843
6844 static int
6845 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6846 {
6847   unformat_input_t *i = vam->input;
6848   vl_api_sw_interface_set_l2_xconnect_t *mp;
6849   u32 rx_sw_if_index;
6850   u8 rx_sw_if_index_set = 0;
6851   u32 tx_sw_if_index;
6852   u8 tx_sw_if_index_set = 0;
6853   u8 enable = 1;
6854   int ret;
6855
6856   /* Parse args required to build the message */
6857   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6858     {
6859       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6860         rx_sw_if_index_set = 1;
6861       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6862         tx_sw_if_index_set = 1;
6863       else if (unformat (i, "rx"))
6864         {
6865           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6866             {
6867               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6868                             &rx_sw_if_index))
6869                 rx_sw_if_index_set = 1;
6870             }
6871           else
6872             break;
6873         }
6874       else if (unformat (i, "tx"))
6875         {
6876           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6877             {
6878               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6879                             &tx_sw_if_index))
6880                 tx_sw_if_index_set = 1;
6881             }
6882           else
6883             break;
6884         }
6885       else if (unformat (i, "enable"))
6886         enable = 1;
6887       else if (unformat (i, "disable"))
6888         enable = 0;
6889       else
6890         break;
6891     }
6892
6893   if (rx_sw_if_index_set == 0)
6894     {
6895       errmsg ("missing rx interface name or rx_sw_if_index");
6896       return -99;
6897     }
6898
6899   if (enable && (tx_sw_if_index_set == 0))
6900     {
6901       errmsg ("missing tx interface name or tx_sw_if_index");
6902       return -99;
6903     }
6904
6905   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6906
6907   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6908   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6909   mp->enable = enable;
6910
6911   S (mp);
6912   W (ret);
6913   return ret;
6914 }
6915
6916 static int
6917 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6918 {
6919   unformat_input_t *i = vam->input;
6920   vl_api_sw_interface_set_l2_bridge_t *mp;
6921   u32 rx_sw_if_index;
6922   u8 rx_sw_if_index_set = 0;
6923   u32 bd_id;
6924   u8 bd_id_set = 0;
6925   u8 bvi = 0;
6926   u32 shg = 0;
6927   u8 enable = 1;
6928   int ret;
6929
6930   /* Parse args required to build the message */
6931   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6932     {
6933       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6934         rx_sw_if_index_set = 1;
6935       else if (unformat (i, "bd_id %d", &bd_id))
6936         bd_id_set = 1;
6937       else
6938         if (unformat
6939             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6940         rx_sw_if_index_set = 1;
6941       else if (unformat (i, "shg %d", &shg))
6942         ;
6943       else if (unformat (i, "bvi"))
6944         bvi = 1;
6945       else if (unformat (i, "enable"))
6946         enable = 1;
6947       else if (unformat (i, "disable"))
6948         enable = 0;
6949       else
6950         break;
6951     }
6952
6953   if (rx_sw_if_index_set == 0)
6954     {
6955       errmsg ("missing rx interface name or sw_if_index");
6956       return -99;
6957     }
6958
6959   if (enable && (bd_id_set == 0))
6960     {
6961       errmsg ("missing bridge domain");
6962       return -99;
6963     }
6964
6965   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6966
6967   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6968   mp->bd_id = ntohl (bd_id);
6969   mp->shg = (u8) shg;
6970   mp->bvi = bvi;
6971   mp->enable = enable;
6972
6973   S (mp);
6974   W (ret);
6975   return ret;
6976 }
6977
6978 static int
6979 api_bridge_domain_dump (vat_main_t * vam)
6980 {
6981   unformat_input_t *i = vam->input;
6982   vl_api_bridge_domain_dump_t *mp;
6983   vl_api_control_ping_t *mp_ping;
6984   u32 bd_id = ~0;
6985   int ret;
6986
6987   /* Parse args required to build the message */
6988   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6989     {
6990       if (unformat (i, "bd_id %d", &bd_id))
6991         ;
6992       else
6993         break;
6994     }
6995
6996   M (BRIDGE_DOMAIN_DUMP, mp);
6997   mp->bd_id = ntohl (bd_id);
6998   S (mp);
6999
7000   /* Use a control ping for synchronization */
7001   MPING (CONTROL_PING, mp_ping);
7002   S (mp_ping);
7003
7004   W (ret);
7005   return ret;
7006 }
7007
7008 static int
7009 api_bridge_domain_add_del (vat_main_t * vam)
7010 {
7011   unformat_input_t *i = vam->input;
7012   vl_api_bridge_domain_add_del_t *mp;
7013   u32 bd_id = ~0;
7014   u8 is_add = 1;
7015   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7016   u8 *bd_tag = NULL;
7017   u32 mac_age = 0;
7018   int ret;
7019
7020   /* Parse args required to build the message */
7021   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7022     {
7023       if (unformat (i, "bd_id %d", &bd_id))
7024         ;
7025       else if (unformat (i, "flood %d", &flood))
7026         ;
7027       else if (unformat (i, "uu-flood %d", &uu_flood))
7028         ;
7029       else if (unformat (i, "forward %d", &forward))
7030         ;
7031       else if (unformat (i, "learn %d", &learn))
7032         ;
7033       else if (unformat (i, "arp-term %d", &arp_term))
7034         ;
7035       else if (unformat (i, "mac-age %d", &mac_age))
7036         ;
7037       else if (unformat (i, "bd-tag %s", &bd_tag))
7038         ;
7039       else if (unformat (i, "del"))
7040         {
7041           is_add = 0;
7042           flood = uu_flood = forward = learn = 0;
7043         }
7044       else
7045         break;
7046     }
7047
7048   if (bd_id == ~0)
7049     {
7050       errmsg ("missing bridge domain");
7051       ret = -99;
7052       goto done;
7053     }
7054
7055   if (mac_age > 255)
7056     {
7057       errmsg ("mac age must be less than 256 ");
7058       ret = -99;
7059       goto done;
7060     }
7061
7062   if ((bd_tag) && (strlen ((char *) bd_tag) > 63))
7063     {
7064       errmsg ("bd-tag cannot be longer than 63");
7065       ret = -99;
7066       goto done;
7067     }
7068
7069   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7070
7071   mp->bd_id = ntohl (bd_id);
7072   mp->flood = flood;
7073   mp->uu_flood = uu_flood;
7074   mp->forward = forward;
7075   mp->learn = learn;
7076   mp->arp_term = arp_term;
7077   mp->is_add = is_add;
7078   mp->mac_age = (u8) mac_age;
7079   if (bd_tag)
7080     strcpy ((char *) mp->bd_tag, (char *) bd_tag);
7081
7082   S (mp);
7083   W (ret);
7084
7085 done:
7086   vec_free (bd_tag);
7087   return ret;
7088 }
7089
7090 static int
7091 api_l2fib_flush_bd (vat_main_t * vam)
7092 {
7093   unformat_input_t *i = vam->input;
7094   vl_api_l2fib_flush_bd_t *mp;
7095   u32 bd_id = ~0;
7096   int ret;
7097
7098   /* Parse args required to build the message */
7099   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7100     {
7101       if (unformat (i, "bd_id %d", &bd_id));
7102       else
7103         break;
7104     }
7105
7106   if (bd_id == ~0)
7107     {
7108       errmsg ("missing bridge domain");
7109       return -99;
7110     }
7111
7112   M (L2FIB_FLUSH_BD, mp);
7113
7114   mp->bd_id = htonl (bd_id);
7115
7116   S (mp);
7117   W (ret);
7118   return ret;
7119 }
7120
7121 static int
7122 api_l2fib_flush_int (vat_main_t * vam)
7123 {
7124   unformat_input_t *i = vam->input;
7125   vl_api_l2fib_flush_int_t *mp;
7126   u32 sw_if_index = ~0;
7127   int ret;
7128
7129   /* Parse args required to build the message */
7130   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7131     {
7132       if (unformat (i, "sw_if_index %d", &sw_if_index));
7133       else
7134         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7135       else
7136         break;
7137     }
7138
7139   if (sw_if_index == ~0)
7140     {
7141       errmsg ("missing interface name or sw_if_index");
7142       return -99;
7143     }
7144
7145   M (L2FIB_FLUSH_INT, mp);
7146
7147   mp->sw_if_index = ntohl (sw_if_index);
7148
7149   S (mp);
7150   W (ret);
7151   return ret;
7152 }
7153
7154 static int
7155 api_l2fib_add_del (vat_main_t * vam)
7156 {
7157   unformat_input_t *i = vam->input;
7158   vl_api_l2fib_add_del_t *mp;
7159   f64 timeout;
7160   u8 mac[6] = { 0 };
7161   u8 mac_set = 0;
7162   u32 bd_id;
7163   u8 bd_id_set = 0;
7164   u32 sw_if_index = ~0;
7165   u8 sw_if_index_set = 0;
7166   u8 is_add = 1;
7167   u8 static_mac = 0;
7168   u8 filter_mac = 0;
7169   u8 bvi_mac = 0;
7170   int count = 1;
7171   f64 before = 0;
7172   int j;
7173
7174   /* Parse args required to build the message */
7175   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7176     {
7177       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7178         mac_set = 1;
7179       else if (unformat (i, "bd_id %d", &bd_id))
7180         bd_id_set = 1;
7181       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7182         sw_if_index_set = 1;
7183       else if (unformat (i, "sw_if"))
7184         {
7185           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7186             {
7187               if (unformat
7188                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7189                 sw_if_index_set = 1;
7190             }
7191           else
7192             break;
7193         }
7194       else if (unformat (i, "static"))
7195         static_mac = 1;
7196       else if (unformat (i, "filter"))
7197         {
7198           filter_mac = 1;
7199           static_mac = 1;
7200         }
7201       else if (unformat (i, "bvi"))
7202         {
7203           bvi_mac = 1;
7204           static_mac = 1;
7205         }
7206       else if (unformat (i, "del"))
7207         is_add = 0;
7208       else if (unformat (i, "count %d", &count))
7209         ;
7210       else
7211         break;
7212     }
7213
7214   if (mac_set == 0)
7215     {
7216       errmsg ("missing mac address");
7217       return -99;
7218     }
7219
7220   if (bd_id_set == 0)
7221     {
7222       errmsg ("missing bridge domain");
7223       return -99;
7224     }
7225
7226   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7227     {
7228       errmsg ("missing interface name or sw_if_index");
7229       return -99;
7230     }
7231
7232   if (count > 1)
7233     {
7234       /* Turn on async mode */
7235       vam->async_mode = 1;
7236       vam->async_errors = 0;
7237       before = vat_time_now (vam);
7238     }
7239
7240   for (j = 0; j < count; j++)
7241     {
7242       M (L2FIB_ADD_DEL, mp);
7243
7244       clib_memcpy (mp->mac, mac, 6);
7245       mp->bd_id = ntohl (bd_id);
7246       mp->is_add = is_add;
7247
7248       if (is_add)
7249         {
7250           mp->sw_if_index = ntohl (sw_if_index);
7251           mp->static_mac = static_mac;
7252           mp->filter_mac = filter_mac;
7253           mp->bvi_mac = bvi_mac;
7254         }
7255       increment_mac_address (mac);
7256       /* send it... */
7257       S (mp);
7258     }
7259
7260   if (count > 1)
7261     {
7262       vl_api_control_ping_t *mp_ping;
7263       f64 after;
7264
7265       /* Shut off async mode */
7266       vam->async_mode = 0;
7267
7268       MPING (CONTROL_PING, mp_ping);
7269       S (mp_ping);
7270
7271       timeout = vat_time_now (vam) + 1.0;
7272       while (vat_time_now (vam) < timeout)
7273         if (vam->result_ready == 1)
7274           goto out;
7275       vam->retval = -99;
7276
7277     out:
7278       if (vam->retval == -99)
7279         errmsg ("timeout");
7280
7281       if (vam->async_errors > 0)
7282         {
7283           errmsg ("%d asynchronous errors", vam->async_errors);
7284           vam->retval = -98;
7285         }
7286       vam->async_errors = 0;
7287       after = vat_time_now (vam);
7288
7289       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7290              count, after - before, count / (after - before));
7291     }
7292   else
7293     {
7294       int ret;
7295
7296       /* Wait for a reply... */
7297       W (ret);
7298       return ret;
7299     }
7300   /* Return the good/bad news */
7301   return (vam->retval);
7302 }
7303
7304 static int
7305 api_bridge_domain_set_mac_age (vat_main_t * vam)
7306 {
7307   unformat_input_t *i = vam->input;
7308   vl_api_bridge_domain_set_mac_age_t *mp;
7309   u32 bd_id = ~0;
7310   u32 mac_age = 0;
7311   int ret;
7312
7313   /* Parse args required to build the message */
7314   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7315     {
7316       if (unformat (i, "bd_id %d", &bd_id));
7317       else if (unformat (i, "mac-age %d", &mac_age));
7318       else
7319         break;
7320     }
7321
7322   if (bd_id == ~0)
7323     {
7324       errmsg ("missing bridge domain");
7325       return -99;
7326     }
7327
7328   if (mac_age > 255)
7329     {
7330       errmsg ("mac age must be less than 256 ");
7331       return -99;
7332     }
7333
7334   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7335
7336   mp->bd_id = htonl (bd_id);
7337   mp->mac_age = (u8) mac_age;
7338
7339   S (mp);
7340   W (ret);
7341   return ret;
7342 }
7343
7344 static int
7345 api_l2_flags (vat_main_t * vam)
7346 {
7347   unformat_input_t *i = vam->input;
7348   vl_api_l2_flags_t *mp;
7349   u32 sw_if_index;
7350   u32 flags = 0;
7351   u8 sw_if_index_set = 0;
7352   u8 is_set = 0;
7353   int ret;
7354
7355   /* Parse args required to build the message */
7356   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7357     {
7358       if (unformat (i, "sw_if_index %d", &sw_if_index))
7359         sw_if_index_set = 1;
7360       else if (unformat (i, "sw_if"))
7361         {
7362           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7363             {
7364               if (unformat
7365                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7366                 sw_if_index_set = 1;
7367             }
7368           else
7369             break;
7370         }
7371       else if (unformat (i, "learn"))
7372         flags |= L2_LEARN;
7373       else if (unformat (i, "forward"))
7374         flags |= L2_FWD;
7375       else if (unformat (i, "flood"))
7376         flags |= L2_FLOOD;
7377       else if (unformat (i, "uu-flood"))
7378         flags |= L2_UU_FLOOD;
7379       else if (unformat (i, "arp-term"))
7380         flags |= L2_ARP_TERM;
7381       else if (unformat (i, "off"))
7382         is_set = 0;
7383       else if (unformat (i, "disable"))
7384         is_set = 0;
7385       else
7386         break;
7387     }
7388
7389   if (sw_if_index_set == 0)
7390     {
7391       errmsg ("missing interface name or sw_if_index");
7392       return -99;
7393     }
7394
7395   M (L2_FLAGS, mp);
7396
7397   mp->sw_if_index = ntohl (sw_if_index);
7398   mp->feature_bitmap = ntohl (flags);
7399   mp->is_set = is_set;
7400
7401   S (mp);
7402   W (ret);
7403   return ret;
7404 }
7405
7406 static int
7407 api_bridge_flags (vat_main_t * vam)
7408 {
7409   unformat_input_t *i = vam->input;
7410   vl_api_bridge_flags_t *mp;
7411   u32 bd_id;
7412   u8 bd_id_set = 0;
7413   u8 is_set = 1;
7414   u32 flags = 0;
7415   int ret;
7416
7417   /* Parse args required to build the message */
7418   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7419     {
7420       if (unformat (i, "bd_id %d", &bd_id))
7421         bd_id_set = 1;
7422       else if (unformat (i, "learn"))
7423         flags |= L2_LEARN;
7424       else if (unformat (i, "forward"))
7425         flags |= L2_FWD;
7426       else if (unformat (i, "flood"))
7427         flags |= L2_FLOOD;
7428       else if (unformat (i, "uu-flood"))
7429         flags |= L2_UU_FLOOD;
7430       else if (unformat (i, "arp-term"))
7431         flags |= L2_ARP_TERM;
7432       else if (unformat (i, "off"))
7433         is_set = 0;
7434       else if (unformat (i, "disable"))
7435         is_set = 0;
7436       else
7437         break;
7438     }
7439
7440   if (bd_id_set == 0)
7441     {
7442       errmsg ("missing bridge domain");
7443       return -99;
7444     }
7445
7446   M (BRIDGE_FLAGS, mp);
7447
7448   mp->bd_id = ntohl (bd_id);
7449   mp->feature_bitmap = ntohl (flags);
7450   mp->is_set = is_set;
7451
7452   S (mp);
7453   W (ret);
7454   return ret;
7455 }
7456
7457 static int
7458 api_bd_ip_mac_add_del (vat_main_t * vam)
7459 {
7460   unformat_input_t *i = vam->input;
7461   vl_api_bd_ip_mac_add_del_t *mp;
7462   u32 bd_id;
7463   u8 is_ipv6 = 0;
7464   u8 is_add = 1;
7465   u8 bd_id_set = 0;
7466   u8 ip_set = 0;
7467   u8 mac_set = 0;
7468   ip4_address_t v4addr;
7469   ip6_address_t v6addr;
7470   u8 macaddr[6];
7471   int ret;
7472
7473
7474   /* Parse args required to build the message */
7475   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7476     {
7477       if (unformat (i, "bd_id %d", &bd_id))
7478         {
7479           bd_id_set++;
7480         }
7481       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7482         {
7483           ip_set++;
7484         }
7485       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7486         {
7487           ip_set++;
7488           is_ipv6++;
7489         }
7490       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7491         {
7492           mac_set++;
7493         }
7494       else if (unformat (i, "del"))
7495         is_add = 0;
7496       else
7497         break;
7498     }
7499
7500   if (bd_id_set == 0)
7501     {
7502       errmsg ("missing bridge domain");
7503       return -99;
7504     }
7505   else if (ip_set == 0)
7506     {
7507       errmsg ("missing IP address");
7508       return -99;
7509     }
7510   else if (mac_set == 0)
7511     {
7512       errmsg ("missing MAC address");
7513       return -99;
7514     }
7515
7516   M (BD_IP_MAC_ADD_DEL, mp);
7517
7518   mp->bd_id = ntohl (bd_id);
7519   mp->is_ipv6 = is_ipv6;
7520   mp->is_add = is_add;
7521   if (is_ipv6)
7522     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7523   else
7524     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7525   clib_memcpy (mp->mac_address, macaddr, 6);
7526   S (mp);
7527   W (ret);
7528   return ret;
7529 }
7530
7531 static int
7532 api_tap_connect (vat_main_t * vam)
7533 {
7534   unformat_input_t *i = vam->input;
7535   vl_api_tap_connect_t *mp;
7536   u8 mac_address[6];
7537   u8 random_mac = 1;
7538   u8 name_set = 0;
7539   u8 *tap_name;
7540   u8 *tag = 0;
7541   ip4_address_t ip4_address;
7542   u32 ip4_mask_width;
7543   int ip4_address_set = 0;
7544   ip6_address_t ip6_address;
7545   u32 ip6_mask_width;
7546   int ip6_address_set = 0;
7547   int ret;
7548
7549   memset (mac_address, 0, sizeof (mac_address));
7550
7551   /* Parse args required to build the message */
7552   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7553     {
7554       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7555         {
7556           random_mac = 0;
7557         }
7558       else if (unformat (i, "random-mac"))
7559         random_mac = 1;
7560       else if (unformat (i, "tapname %s", &tap_name))
7561         name_set = 1;
7562       else if (unformat (i, "tag %s", &tag))
7563         ;
7564       else if (unformat (i, "address %U/%d",
7565                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7566         ip4_address_set = 1;
7567       else if (unformat (i, "address %U/%d",
7568                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7569         ip6_address_set = 1;
7570       else
7571         break;
7572     }
7573
7574   if (name_set == 0)
7575     {
7576       errmsg ("missing tap name");
7577       return -99;
7578     }
7579   if (vec_len (tap_name) > 63)
7580     {
7581       errmsg ("tap name too long");
7582       return -99;
7583     }
7584   vec_add1 (tap_name, 0);
7585
7586   if (vec_len (tag) > 63)
7587     {
7588       errmsg ("tag too long");
7589       return -99;
7590     }
7591
7592   /* Construct the API message */
7593   M (TAP_CONNECT, mp);
7594
7595   mp->use_random_mac = random_mac;
7596   clib_memcpy (mp->mac_address, mac_address, 6);
7597   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7598   if (tag)
7599     clib_memcpy (mp->tag, tag, vec_len (tag));
7600
7601   if (ip4_address_set)
7602     {
7603       mp->ip4_address_set = 1;
7604       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7605       mp->ip4_mask_width = ip4_mask_width;
7606     }
7607   if (ip6_address_set)
7608     {
7609       mp->ip6_address_set = 1;
7610       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7611       mp->ip6_mask_width = ip6_mask_width;
7612     }
7613
7614   vec_free (tap_name);
7615   vec_free (tag);
7616
7617   /* send it... */
7618   S (mp);
7619
7620   /* Wait for a reply... */
7621   W (ret);
7622   return ret;
7623 }
7624
7625 static int
7626 api_tap_modify (vat_main_t * vam)
7627 {
7628   unformat_input_t *i = vam->input;
7629   vl_api_tap_modify_t *mp;
7630   u8 mac_address[6];
7631   u8 random_mac = 1;
7632   u8 name_set = 0;
7633   u8 *tap_name;
7634   u32 sw_if_index = ~0;
7635   u8 sw_if_index_set = 0;
7636   int ret;
7637
7638   memset (mac_address, 0, sizeof (mac_address));
7639
7640   /* Parse args required to build the message */
7641   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7642     {
7643       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7644         sw_if_index_set = 1;
7645       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7646         sw_if_index_set = 1;
7647       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7648         {
7649           random_mac = 0;
7650         }
7651       else if (unformat (i, "random-mac"))
7652         random_mac = 1;
7653       else if (unformat (i, "tapname %s", &tap_name))
7654         name_set = 1;
7655       else
7656         break;
7657     }
7658
7659   if (sw_if_index_set == 0)
7660     {
7661       errmsg ("missing vpp interface name");
7662       return -99;
7663     }
7664   if (name_set == 0)
7665     {
7666       errmsg ("missing tap name");
7667       return -99;
7668     }
7669   if (vec_len (tap_name) > 63)
7670     {
7671       errmsg ("tap name too long");
7672     }
7673   vec_add1 (tap_name, 0);
7674
7675   /* Construct the API message */
7676   M (TAP_MODIFY, mp);
7677
7678   mp->use_random_mac = random_mac;
7679   mp->sw_if_index = ntohl (sw_if_index);
7680   clib_memcpy (mp->mac_address, mac_address, 6);
7681   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7682   vec_free (tap_name);
7683
7684   /* send it... */
7685   S (mp);
7686
7687   /* Wait for a reply... */
7688   W (ret);
7689   return ret;
7690 }
7691
7692 static int
7693 api_tap_delete (vat_main_t * vam)
7694 {
7695   unformat_input_t *i = vam->input;
7696   vl_api_tap_delete_t *mp;
7697   u32 sw_if_index = ~0;
7698   u8 sw_if_index_set = 0;
7699   int ret;
7700
7701   /* Parse args required to build the message */
7702   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7703     {
7704       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7705         sw_if_index_set = 1;
7706       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7707         sw_if_index_set = 1;
7708       else
7709         break;
7710     }
7711
7712   if (sw_if_index_set == 0)
7713     {
7714       errmsg ("missing vpp interface name");
7715       return -99;
7716     }
7717
7718   /* Construct the API message */
7719   M (TAP_DELETE, mp);
7720
7721   mp->sw_if_index = ntohl (sw_if_index);
7722
7723   /* send it... */
7724   S (mp);
7725
7726   /* Wait for a reply... */
7727   W (ret);
7728   return ret;
7729 }
7730
7731 static int
7732 api_ip_table_add_del (vat_main_t * vam)
7733 {
7734   unformat_input_t *i = vam->input;
7735   vl_api_ip_table_add_del_t *mp;
7736   u32 table_id = ~0;
7737   u8 is_ipv6 = 0;
7738   u8 is_add = 1;
7739   int ret = 0;
7740
7741   /* Parse args required to build the message */
7742   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7743     {
7744       if (unformat (i, "ipv6"))
7745         is_ipv6 = 1;
7746       else if (unformat (i, "del"))
7747         is_add = 0;
7748       else if (unformat (i, "add"))
7749         is_add = 1;
7750       else if (unformat (i, "table %d", &table_id))
7751         ;
7752       else
7753         {
7754           clib_warning ("parse error '%U'", format_unformat_error, i);
7755           return -99;
7756         }
7757     }
7758
7759   if (~0 == table_id)
7760     {
7761       errmsg ("missing table-ID");
7762       return -99;
7763     }
7764
7765   /* Construct the API message */
7766   M (IP_TABLE_ADD_DEL, mp);
7767
7768   mp->table_id = ntohl (table_id);
7769   mp->is_ipv6 = is_ipv6;
7770   mp->is_add = is_add;
7771
7772   /* send it... */
7773   S (mp);
7774
7775   /* Wait for a reply... */
7776   W (ret);
7777
7778   return ret;
7779 }
7780
7781 static int
7782 api_ip_add_del_route (vat_main_t * vam)
7783 {
7784   unformat_input_t *i = vam->input;
7785   vl_api_ip_add_del_route_t *mp;
7786   u32 sw_if_index = ~0, vrf_id = 0;
7787   u8 is_ipv6 = 0;
7788   u8 is_local = 0, is_drop = 0;
7789   u8 is_unreach = 0, is_prohibit = 0;
7790   u8 create_vrf_if_needed = 0;
7791   u8 is_add = 1;
7792   u32 next_hop_weight = 1;
7793   u8 is_multipath = 0;
7794   u8 address_set = 0;
7795   u8 address_length_set = 0;
7796   u32 next_hop_table_id = 0;
7797   u32 resolve_attempts = 0;
7798   u32 dst_address_length = 0;
7799   u8 next_hop_set = 0;
7800   ip4_address_t v4_dst_address, v4_next_hop_address;
7801   ip6_address_t v6_dst_address, v6_next_hop_address;
7802   int count = 1;
7803   int j;
7804   f64 before = 0;
7805   u32 random_add_del = 0;
7806   u32 *random_vector = 0;
7807   uword *random_hash;
7808   u32 random_seed = 0xdeaddabe;
7809   u32 classify_table_index = ~0;
7810   u8 is_classify = 0;
7811   u8 resolve_host = 0, resolve_attached = 0;
7812   mpls_label_t *next_hop_out_label_stack = NULL;
7813   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7814   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7815
7816   /* Parse args required to build the message */
7817   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7818     {
7819       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7820         ;
7821       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7822         ;
7823       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
7824         {
7825           address_set = 1;
7826           is_ipv6 = 0;
7827         }
7828       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
7829         {
7830           address_set = 1;
7831           is_ipv6 = 1;
7832         }
7833       else if (unformat (i, "/%d", &dst_address_length))
7834         {
7835           address_length_set = 1;
7836         }
7837
7838       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
7839                                          &v4_next_hop_address))
7840         {
7841           next_hop_set = 1;
7842         }
7843       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
7844                                          &v6_next_hop_address))
7845         {
7846           next_hop_set = 1;
7847         }
7848       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
7849         ;
7850       else if (unformat (i, "weight %d", &next_hop_weight))
7851         ;
7852       else if (unformat (i, "drop"))
7853         {
7854           is_drop = 1;
7855         }
7856       else if (unformat (i, "null-send-unreach"))
7857         {
7858           is_unreach = 1;
7859         }
7860       else if (unformat (i, "null-send-prohibit"))
7861         {
7862           is_prohibit = 1;
7863         }
7864       else if (unformat (i, "local"))
7865         {
7866           is_local = 1;
7867         }
7868       else if (unformat (i, "classify %d", &classify_table_index))
7869         {
7870           is_classify = 1;
7871         }
7872       else if (unformat (i, "del"))
7873         is_add = 0;
7874       else if (unformat (i, "add"))
7875         is_add = 1;
7876       else if (unformat (i, "resolve-via-host"))
7877         resolve_host = 1;
7878       else if (unformat (i, "resolve-via-attached"))
7879         resolve_attached = 1;
7880       else if (unformat (i, "multipath"))
7881         is_multipath = 1;
7882       else if (unformat (i, "vrf %d", &vrf_id))
7883         ;
7884       else if (unformat (i, "create-vrf"))
7885         create_vrf_if_needed = 1;
7886       else if (unformat (i, "count %d", &count))
7887         ;
7888       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
7889         ;
7890       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7891         ;
7892       else if (unformat (i, "out-label %d", &next_hop_out_label))
7893         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7894       else if (unformat (i, "via-label %d", &next_hop_via_label))
7895         ;
7896       else if (unformat (i, "random"))
7897         random_add_del = 1;
7898       else if (unformat (i, "seed %d", &random_seed))
7899         ;
7900       else
7901         {
7902           clib_warning ("parse error '%U'", format_unformat_error, i);
7903           return -99;
7904         }
7905     }
7906
7907   if (!next_hop_set && !is_drop && !is_local &&
7908       !is_classify && !is_unreach && !is_prohibit &&
7909       MPLS_LABEL_INVALID == next_hop_via_label)
7910     {
7911       errmsg
7912         ("next hop / local / drop / unreach / prohibit / classify not set");
7913       return -99;
7914     }
7915
7916   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
7917     {
7918       errmsg ("next hop and next-hop via label set");
7919       return -99;
7920     }
7921   if (address_set == 0)
7922     {
7923       errmsg ("missing addresses");
7924       return -99;
7925     }
7926
7927   if (address_length_set == 0)
7928     {
7929       errmsg ("missing address length");
7930       return -99;
7931     }
7932
7933   /* Generate a pile of unique, random routes */
7934   if (random_add_del)
7935     {
7936       u32 this_random_address;
7937       random_hash = hash_create (count, sizeof (uword));
7938
7939       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
7940       for (j = 0; j <= count; j++)
7941         {
7942           do
7943             {
7944               this_random_address = random_u32 (&random_seed);
7945               this_random_address =
7946                 clib_host_to_net_u32 (this_random_address);
7947             }
7948           while (hash_get (random_hash, this_random_address));
7949           vec_add1 (random_vector, this_random_address);
7950           hash_set (random_hash, this_random_address, 1);
7951         }
7952       hash_free (random_hash);
7953       v4_dst_address.as_u32 = random_vector[0];
7954     }
7955
7956   if (count > 1)
7957     {
7958       /* Turn on async mode */
7959       vam->async_mode = 1;
7960       vam->async_errors = 0;
7961       before = vat_time_now (vam);
7962     }
7963
7964   for (j = 0; j < count; j++)
7965     {
7966       /* Construct the API message */
7967       M2 (IP_ADD_DEL_ROUTE, mp,
7968           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7969
7970       mp->next_hop_sw_if_index = ntohl (sw_if_index);
7971       mp->table_id = ntohl (vrf_id);
7972       mp->create_vrf_if_needed = create_vrf_if_needed;
7973
7974       mp->is_add = is_add;
7975       mp->is_drop = is_drop;
7976       mp->is_unreach = is_unreach;
7977       mp->is_prohibit = is_prohibit;
7978       mp->is_ipv6 = is_ipv6;
7979       mp->is_local = is_local;
7980       mp->is_classify = is_classify;
7981       mp->is_multipath = is_multipath;
7982       mp->is_resolve_host = resolve_host;
7983       mp->is_resolve_attached = resolve_attached;
7984       mp->next_hop_weight = next_hop_weight;
7985       mp->dst_address_length = dst_address_length;
7986       mp->next_hop_table_id = ntohl (next_hop_table_id);
7987       mp->classify_table_index = ntohl (classify_table_index);
7988       mp->next_hop_via_label = ntohl (next_hop_via_label);
7989       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7990       if (0 != mp->next_hop_n_out_labels)
7991         {
7992           memcpy (mp->next_hop_out_label_stack,
7993                   next_hop_out_label_stack,
7994                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7995           vec_free (next_hop_out_label_stack);
7996         }
7997
7998       if (is_ipv6)
7999         {
8000           clib_memcpy (mp->dst_address, &v6_dst_address,
8001                        sizeof (v6_dst_address));
8002           if (next_hop_set)
8003             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8004                          sizeof (v6_next_hop_address));
8005           increment_v6_address (&v6_dst_address);
8006         }
8007       else
8008         {
8009           clib_memcpy (mp->dst_address, &v4_dst_address,
8010                        sizeof (v4_dst_address));
8011           if (next_hop_set)
8012             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8013                          sizeof (v4_next_hop_address));
8014           if (random_add_del)
8015             v4_dst_address.as_u32 = random_vector[j + 1];
8016           else
8017             increment_v4_address (&v4_dst_address);
8018         }
8019       /* send it... */
8020       S (mp);
8021       /* If we receive SIGTERM, stop now... */
8022       if (vam->do_exit)
8023         break;
8024     }
8025
8026   /* When testing multiple add/del ops, use a control-ping to sync */
8027   if (count > 1)
8028     {
8029       vl_api_control_ping_t *mp_ping;
8030       f64 after;
8031       f64 timeout;
8032
8033       /* Shut off async mode */
8034       vam->async_mode = 0;
8035
8036       MPING (CONTROL_PING, mp_ping);
8037       S (mp_ping);
8038
8039       timeout = vat_time_now (vam) + 1.0;
8040       while (vat_time_now (vam) < timeout)
8041         if (vam->result_ready == 1)
8042           goto out;
8043       vam->retval = -99;
8044
8045     out:
8046       if (vam->retval == -99)
8047         errmsg ("timeout");
8048
8049       if (vam->async_errors > 0)
8050         {
8051           errmsg ("%d asynchronous errors", vam->async_errors);
8052           vam->retval = -98;
8053         }
8054       vam->async_errors = 0;
8055       after = vat_time_now (vam);
8056
8057       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8058       if (j > 0)
8059         count = j;
8060
8061       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8062              count, after - before, count / (after - before));
8063     }
8064   else
8065     {
8066       int ret;
8067
8068       /* Wait for a reply... */
8069       W (ret);
8070       return ret;
8071     }
8072
8073   /* Return the good/bad news */
8074   return (vam->retval);
8075 }
8076
8077 static int
8078 api_ip_mroute_add_del (vat_main_t * vam)
8079 {
8080   unformat_input_t *i = vam->input;
8081   vl_api_ip_mroute_add_del_t *mp;
8082   u32 sw_if_index = ~0, vrf_id = 0;
8083   u8 is_ipv6 = 0;
8084   u8 is_local = 0;
8085   u8 create_vrf_if_needed = 0;
8086   u8 is_add = 1;
8087   u8 address_set = 0;
8088   u32 grp_address_length = 0;
8089   ip4_address_t v4_grp_address, v4_src_address;
8090   ip6_address_t v6_grp_address, v6_src_address;
8091   mfib_itf_flags_t iflags = 0;
8092   mfib_entry_flags_t eflags = 0;
8093   int ret;
8094
8095   /* Parse args required to build the message */
8096   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8097     {
8098       if (unformat (i, "sw_if_index %d", &sw_if_index))
8099         ;
8100       else if (unformat (i, "%U %U",
8101                          unformat_ip4_address, &v4_src_address,
8102                          unformat_ip4_address, &v4_grp_address))
8103         {
8104           grp_address_length = 64;
8105           address_set = 1;
8106           is_ipv6 = 0;
8107         }
8108       else if (unformat (i, "%U %U",
8109                          unformat_ip6_address, &v6_src_address,
8110                          unformat_ip6_address, &v6_grp_address))
8111         {
8112           grp_address_length = 256;
8113           address_set = 1;
8114           is_ipv6 = 1;
8115         }
8116       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8117         {
8118           memset (&v4_src_address, 0, sizeof (v4_src_address));
8119           grp_address_length = 32;
8120           address_set = 1;
8121           is_ipv6 = 0;
8122         }
8123       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8124         {
8125           memset (&v6_src_address, 0, sizeof (v6_src_address));
8126           grp_address_length = 128;
8127           address_set = 1;
8128           is_ipv6 = 1;
8129         }
8130       else if (unformat (i, "/%d", &grp_address_length))
8131         ;
8132       else if (unformat (i, "local"))
8133         {
8134           is_local = 1;
8135         }
8136       else if (unformat (i, "del"))
8137         is_add = 0;
8138       else if (unformat (i, "add"))
8139         is_add = 1;
8140       else if (unformat (i, "vrf %d", &vrf_id))
8141         ;
8142       else if (unformat (i, "create-vrf"))
8143         create_vrf_if_needed = 1;
8144       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8145         ;
8146       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8147         ;
8148       else
8149         {
8150           clib_warning ("parse error '%U'", format_unformat_error, i);
8151           return -99;
8152         }
8153     }
8154
8155   if (address_set == 0)
8156     {
8157       errmsg ("missing addresses\n");
8158       return -99;
8159     }
8160
8161   /* Construct the API message */
8162   M (IP_MROUTE_ADD_DEL, mp);
8163
8164   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8165   mp->table_id = ntohl (vrf_id);
8166   mp->create_vrf_if_needed = create_vrf_if_needed;
8167
8168   mp->is_add = is_add;
8169   mp->is_ipv6 = is_ipv6;
8170   mp->is_local = is_local;
8171   mp->itf_flags = ntohl (iflags);
8172   mp->entry_flags = ntohl (eflags);
8173   mp->grp_address_length = grp_address_length;
8174   mp->grp_address_length = ntohs (mp->grp_address_length);
8175
8176   if (is_ipv6)
8177     {
8178       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8179       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8180     }
8181   else
8182     {
8183       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8184       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8185
8186     }
8187
8188   /* send it... */
8189   S (mp);
8190   /* Wait for a reply... */
8191   W (ret);
8192   return ret;
8193 }
8194
8195 static int
8196 api_mpls_table_add_del (vat_main_t * vam)
8197 {
8198   unformat_input_t *i = vam->input;
8199   vl_api_mpls_table_add_del_t *mp;
8200   u32 table_id = ~0;
8201   u8 is_add = 1;
8202   int ret = 0;
8203
8204   /* Parse args required to build the message */
8205   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8206     {
8207       if (unformat (i, "table %d", &table_id))
8208         ;
8209       else if (unformat (i, "del"))
8210         is_add = 0;
8211       else if (unformat (i, "add"))
8212         is_add = 1;
8213       else
8214         {
8215           clib_warning ("parse error '%U'", format_unformat_error, i);
8216           return -99;
8217         }
8218     }
8219
8220   if (~0 == table_id)
8221     {
8222       errmsg ("missing table-ID");
8223       return -99;
8224     }
8225
8226   /* Construct the API message */
8227   M (MPLS_TABLE_ADD_DEL, mp);
8228
8229   mp->mt_table_id = ntohl (table_id);
8230   mp->mt_is_add = is_add;
8231
8232   /* send it... */
8233   S (mp);
8234
8235   /* Wait for a reply... */
8236   W (ret);
8237
8238   return ret;
8239 }
8240
8241 static int
8242 api_mpls_route_add_del (vat_main_t * vam)
8243 {
8244   unformat_input_t *i = vam->input;
8245   vl_api_mpls_route_add_del_t *mp;
8246   u32 sw_if_index = ~0, table_id = 0;
8247   u8 create_table_if_needed = 0;
8248   u8 is_add = 1;
8249   u32 next_hop_weight = 1;
8250   u8 is_multipath = 0;
8251   u32 next_hop_table_id = 0;
8252   u8 next_hop_set = 0;
8253   ip4_address_t v4_next_hop_address = {
8254     .as_u32 = 0,
8255   };
8256   ip6_address_t v6_next_hop_address = { {0} };
8257   int count = 1;
8258   int j;
8259   f64 before = 0;
8260   u32 classify_table_index = ~0;
8261   u8 is_classify = 0;
8262   u8 resolve_host = 0, resolve_attached = 0;
8263   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8264   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8265   mpls_label_t *next_hop_out_label_stack = NULL;
8266   mpls_label_t local_label = MPLS_LABEL_INVALID;
8267   u8 is_eos = 0;
8268   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8269
8270   /* Parse args required to build the message */
8271   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8272     {
8273       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8274         ;
8275       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8276         ;
8277       else if (unformat (i, "%d", &local_label))
8278         ;
8279       else if (unformat (i, "eos"))
8280         is_eos = 1;
8281       else if (unformat (i, "non-eos"))
8282         is_eos = 0;
8283       else if (unformat (i, "via %U", unformat_ip4_address,
8284                          &v4_next_hop_address))
8285         {
8286           next_hop_set = 1;
8287           next_hop_proto = DPO_PROTO_IP4;
8288         }
8289       else if (unformat (i, "via %U", unformat_ip6_address,
8290                          &v6_next_hop_address))
8291         {
8292           next_hop_set = 1;
8293           next_hop_proto = DPO_PROTO_IP6;
8294         }
8295       else if (unformat (i, "weight %d", &next_hop_weight))
8296         ;
8297       else if (unformat (i, "create-table"))
8298         create_table_if_needed = 1;
8299       else if (unformat (i, "classify %d", &classify_table_index))
8300         {
8301           is_classify = 1;
8302         }
8303       else if (unformat (i, "del"))
8304         is_add = 0;
8305       else if (unformat (i, "add"))
8306         is_add = 1;
8307       else if (unformat (i, "resolve-via-host"))
8308         resolve_host = 1;
8309       else if (unformat (i, "resolve-via-attached"))
8310         resolve_attached = 1;
8311       else if (unformat (i, "multipath"))
8312         is_multipath = 1;
8313       else if (unformat (i, "count %d", &count))
8314         ;
8315       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8316         {
8317           next_hop_set = 1;
8318           next_hop_proto = DPO_PROTO_IP4;
8319         }
8320       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8321         {
8322           next_hop_set = 1;
8323           next_hop_proto = DPO_PROTO_IP6;
8324         }
8325       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8326         ;
8327       else if (unformat (i, "via-label %d", &next_hop_via_label))
8328         ;
8329       else if (unformat (i, "out-label %d", &next_hop_out_label))
8330         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8331       else
8332         {
8333           clib_warning ("parse error '%U'", format_unformat_error, i);
8334           return -99;
8335         }
8336     }
8337
8338   if (!next_hop_set && !is_classify)
8339     {
8340       errmsg ("next hop / classify not set");
8341       return -99;
8342     }
8343
8344   if (MPLS_LABEL_INVALID == local_label)
8345     {
8346       errmsg ("missing label");
8347       return -99;
8348     }
8349
8350   if (count > 1)
8351     {
8352       /* Turn on async mode */
8353       vam->async_mode = 1;
8354       vam->async_errors = 0;
8355       before = vat_time_now (vam);
8356     }
8357
8358   for (j = 0; j < count; j++)
8359     {
8360       /* Construct the API message */
8361       M2 (MPLS_ROUTE_ADD_DEL, mp,
8362           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8363
8364       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8365       mp->mr_table_id = ntohl (table_id);
8366       mp->mr_create_table_if_needed = create_table_if_needed;
8367
8368       mp->mr_is_add = is_add;
8369       mp->mr_next_hop_proto = next_hop_proto;
8370       mp->mr_is_classify = is_classify;
8371       mp->mr_is_multipath = is_multipath;
8372       mp->mr_is_resolve_host = resolve_host;
8373       mp->mr_is_resolve_attached = resolve_attached;
8374       mp->mr_next_hop_weight = next_hop_weight;
8375       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8376       mp->mr_classify_table_index = ntohl (classify_table_index);
8377       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8378       mp->mr_label = ntohl (local_label);
8379       mp->mr_eos = is_eos;
8380
8381       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8382       if (0 != mp->mr_next_hop_n_out_labels)
8383         {
8384           memcpy (mp->mr_next_hop_out_label_stack,
8385                   next_hop_out_label_stack,
8386                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8387           vec_free (next_hop_out_label_stack);
8388         }
8389
8390       if (next_hop_set)
8391         {
8392           if (DPO_PROTO_IP4 == next_hop_proto)
8393             {
8394               clib_memcpy (mp->mr_next_hop,
8395                            &v4_next_hop_address,
8396                            sizeof (v4_next_hop_address));
8397             }
8398           else if (DPO_PROTO_IP6 == next_hop_proto)
8399
8400             {
8401               clib_memcpy (mp->mr_next_hop,
8402                            &v6_next_hop_address,
8403                            sizeof (v6_next_hop_address));
8404             }
8405         }
8406       local_label++;
8407
8408       /* send it... */
8409       S (mp);
8410       /* If we receive SIGTERM, stop now... */
8411       if (vam->do_exit)
8412         break;
8413     }
8414
8415   /* When testing multiple add/del ops, use a control-ping to sync */
8416   if (count > 1)
8417     {
8418       vl_api_control_ping_t *mp_ping;
8419       f64 after;
8420       f64 timeout;
8421
8422       /* Shut off async mode */
8423       vam->async_mode = 0;
8424
8425       MPING (CONTROL_PING, mp_ping);
8426       S (mp_ping);
8427
8428       timeout = vat_time_now (vam) + 1.0;
8429       while (vat_time_now (vam) < timeout)
8430         if (vam->result_ready == 1)
8431           goto out;
8432       vam->retval = -99;
8433
8434     out:
8435       if (vam->retval == -99)
8436         errmsg ("timeout");
8437
8438       if (vam->async_errors > 0)
8439         {
8440           errmsg ("%d asynchronous errors", vam->async_errors);
8441           vam->retval = -98;
8442         }
8443       vam->async_errors = 0;
8444       after = vat_time_now (vam);
8445
8446       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8447       if (j > 0)
8448         count = j;
8449
8450       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8451              count, after - before, count / (after - before));
8452     }
8453   else
8454     {
8455       int ret;
8456
8457       /* Wait for a reply... */
8458       W (ret);
8459       return ret;
8460     }
8461
8462   /* Return the good/bad news */
8463   return (vam->retval);
8464 }
8465
8466 static int
8467 api_mpls_ip_bind_unbind (vat_main_t * vam)
8468 {
8469   unformat_input_t *i = vam->input;
8470   vl_api_mpls_ip_bind_unbind_t *mp;
8471   u32 ip_table_id = 0;
8472   u8 create_table_if_needed = 0;
8473   u8 is_bind = 1;
8474   u8 is_ip4 = 1;
8475   ip4_address_t v4_address;
8476   ip6_address_t v6_address;
8477   u32 address_length;
8478   u8 address_set = 0;
8479   mpls_label_t local_label = MPLS_LABEL_INVALID;
8480   int ret;
8481
8482   /* Parse args required to build the message */
8483   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8484     {
8485       if (unformat (i, "%U/%d", unformat_ip4_address,
8486                     &v4_address, &address_length))
8487         {
8488           is_ip4 = 1;
8489           address_set = 1;
8490         }
8491       else if (unformat (i, "%U/%d", unformat_ip6_address,
8492                          &v6_address, &address_length))
8493         {
8494           is_ip4 = 0;
8495           address_set = 1;
8496         }
8497       else if (unformat (i, "%d", &local_label))
8498         ;
8499       else if (unformat (i, "create-table"))
8500         create_table_if_needed = 1;
8501       else if (unformat (i, "table-id %d", &ip_table_id))
8502         ;
8503       else if (unformat (i, "unbind"))
8504         is_bind = 0;
8505       else if (unformat (i, "bind"))
8506         is_bind = 1;
8507       else
8508         {
8509           clib_warning ("parse error '%U'", format_unformat_error, i);
8510           return -99;
8511         }
8512     }
8513
8514   if (!address_set)
8515     {
8516       errmsg ("IP addres not set");
8517       return -99;
8518     }
8519
8520   if (MPLS_LABEL_INVALID == local_label)
8521     {
8522       errmsg ("missing label");
8523       return -99;
8524     }
8525
8526   /* Construct the API message */
8527   M (MPLS_IP_BIND_UNBIND, mp);
8528
8529   mp->mb_create_table_if_needed = create_table_if_needed;
8530   mp->mb_is_bind = is_bind;
8531   mp->mb_is_ip4 = is_ip4;
8532   mp->mb_ip_table_id = ntohl (ip_table_id);
8533   mp->mb_mpls_table_id = 0;
8534   mp->mb_label = ntohl (local_label);
8535   mp->mb_address_length = address_length;
8536
8537   if (is_ip4)
8538     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8539   else
8540     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8541
8542   /* send it... */
8543   S (mp);
8544
8545   /* Wait for a reply... */
8546   W (ret);
8547   return ret;
8548 }
8549
8550 static int
8551 api_proxy_arp_add_del (vat_main_t * vam)
8552 {
8553   unformat_input_t *i = vam->input;
8554   vl_api_proxy_arp_add_del_t *mp;
8555   u32 vrf_id = 0;
8556   u8 is_add = 1;
8557   ip4_address_t lo, hi;
8558   u8 range_set = 0;
8559   int ret;
8560
8561   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8562     {
8563       if (unformat (i, "vrf %d", &vrf_id))
8564         ;
8565       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
8566                          unformat_ip4_address, &hi))
8567         range_set = 1;
8568       else if (unformat (i, "del"))
8569         is_add = 0;
8570       else
8571         {
8572           clib_warning ("parse error '%U'", format_unformat_error, i);
8573           return -99;
8574         }
8575     }
8576
8577   if (range_set == 0)
8578     {
8579       errmsg ("address range not set");
8580       return -99;
8581     }
8582
8583   M (PROXY_ARP_ADD_DEL, mp);
8584
8585   mp->vrf_id = ntohl (vrf_id);
8586   mp->is_add = is_add;
8587   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
8588   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
8589
8590   S (mp);
8591   W (ret);
8592   return ret;
8593 }
8594
8595 static int
8596 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8597 {
8598   unformat_input_t *i = vam->input;
8599   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8600   u32 sw_if_index;
8601   u8 enable = 1;
8602   u8 sw_if_index_set = 0;
8603   int ret;
8604
8605   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8606     {
8607       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8608         sw_if_index_set = 1;
8609       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8610         sw_if_index_set = 1;
8611       else if (unformat (i, "enable"))
8612         enable = 1;
8613       else if (unformat (i, "disable"))
8614         enable = 0;
8615       else
8616         {
8617           clib_warning ("parse error '%U'", format_unformat_error, i);
8618           return -99;
8619         }
8620     }
8621
8622   if (sw_if_index_set == 0)
8623     {
8624       errmsg ("missing interface name or sw_if_index");
8625       return -99;
8626     }
8627
8628   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8629
8630   mp->sw_if_index = ntohl (sw_if_index);
8631   mp->enable_disable = enable;
8632
8633   S (mp);
8634   W (ret);
8635   return ret;
8636 }
8637
8638 static int
8639 api_mpls_tunnel_add_del (vat_main_t * vam)
8640 {
8641   unformat_input_t *i = vam->input;
8642   vl_api_mpls_tunnel_add_del_t *mp;
8643
8644   u8 is_add = 1;
8645   u8 l2_only = 0;
8646   u32 sw_if_index = ~0;
8647   u32 next_hop_sw_if_index = ~0;
8648   u32 next_hop_proto_is_ip4 = 1;
8649
8650   u32 next_hop_table_id = 0;
8651   ip4_address_t v4_next_hop_address = {
8652     .as_u32 = 0,
8653   };
8654   ip6_address_t v6_next_hop_address = { {0} };
8655   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
8656   int ret;
8657
8658   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8659     {
8660       if (unformat (i, "add"))
8661         is_add = 1;
8662       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8663         is_add = 0;
8664       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
8665         ;
8666       else if (unformat (i, "via %U",
8667                          unformat_ip4_address, &v4_next_hop_address))
8668         {
8669           next_hop_proto_is_ip4 = 1;
8670         }
8671       else if (unformat (i, "via %U",
8672                          unformat_ip6_address, &v6_next_hop_address))
8673         {
8674           next_hop_proto_is_ip4 = 0;
8675         }
8676       else if (unformat (i, "l2-only"))
8677         l2_only = 1;
8678       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8679         ;
8680       else if (unformat (i, "out-label %d", &next_hop_out_label))
8681         vec_add1 (labels, ntohl (next_hop_out_label));
8682       else
8683         {
8684           clib_warning ("parse error '%U'", format_unformat_error, i);
8685           return -99;
8686         }
8687     }
8688
8689   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
8690
8691   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
8692   mp->mt_sw_if_index = ntohl (sw_if_index);
8693   mp->mt_is_add = is_add;
8694   mp->mt_l2_only = l2_only;
8695   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
8696   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
8697
8698   mp->mt_next_hop_n_out_labels = vec_len (labels);
8699
8700   if (0 != mp->mt_next_hop_n_out_labels)
8701     {
8702       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
8703                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
8704       vec_free (labels);
8705     }
8706
8707   if (next_hop_proto_is_ip4)
8708     {
8709       clib_memcpy (mp->mt_next_hop,
8710                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8711     }
8712   else
8713     {
8714       clib_memcpy (mp->mt_next_hop,
8715                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8716     }
8717
8718   S (mp);
8719   W (ret);
8720   return ret;
8721 }
8722
8723 static int
8724 api_sw_interface_set_unnumbered (vat_main_t * vam)
8725 {
8726   unformat_input_t *i = vam->input;
8727   vl_api_sw_interface_set_unnumbered_t *mp;
8728   u32 sw_if_index;
8729   u32 unnum_sw_index = ~0;
8730   u8 is_add = 1;
8731   u8 sw_if_index_set = 0;
8732   int ret;
8733
8734   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8735     {
8736       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8737         sw_if_index_set = 1;
8738       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8739         sw_if_index_set = 1;
8740       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8741         ;
8742       else if (unformat (i, "del"))
8743         is_add = 0;
8744       else
8745         {
8746           clib_warning ("parse error '%U'", format_unformat_error, i);
8747           return -99;
8748         }
8749     }
8750
8751   if (sw_if_index_set == 0)
8752     {
8753       errmsg ("missing interface name or sw_if_index");
8754       return -99;
8755     }
8756
8757   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8758
8759   mp->sw_if_index = ntohl (sw_if_index);
8760   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8761   mp->is_add = is_add;
8762
8763   S (mp);
8764   W (ret);
8765   return ret;
8766 }
8767
8768 static int
8769 api_ip_neighbor_add_del (vat_main_t * vam)
8770 {
8771   unformat_input_t *i = vam->input;
8772   vl_api_ip_neighbor_add_del_t *mp;
8773   u32 sw_if_index;
8774   u8 sw_if_index_set = 0;
8775   u8 is_add = 1;
8776   u8 is_static = 0;
8777   u8 is_no_fib_entry = 0;
8778   u8 mac_address[6];
8779   u8 mac_set = 0;
8780   u8 v4_address_set = 0;
8781   u8 v6_address_set = 0;
8782   ip4_address_t v4address;
8783   ip6_address_t v6address;
8784   int ret;
8785
8786   memset (mac_address, 0, sizeof (mac_address));
8787
8788   /* Parse args required to build the message */
8789   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8790     {
8791       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8792         {
8793           mac_set = 1;
8794         }
8795       else if (unformat (i, "del"))
8796         is_add = 0;
8797       else
8798         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8799         sw_if_index_set = 1;
8800       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8801         sw_if_index_set = 1;
8802       else if (unformat (i, "is_static"))
8803         is_static = 1;
8804       else if (unformat (i, "no-fib-entry"))
8805         is_no_fib_entry = 1;
8806       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
8807         v4_address_set = 1;
8808       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
8809         v6_address_set = 1;
8810       else
8811         {
8812           clib_warning ("parse error '%U'", format_unformat_error, i);
8813           return -99;
8814         }
8815     }
8816
8817   if (sw_if_index_set == 0)
8818     {
8819       errmsg ("missing interface name or sw_if_index");
8820       return -99;
8821     }
8822   if (v4_address_set && v6_address_set)
8823     {
8824       errmsg ("both v4 and v6 addresses set");
8825       return -99;
8826     }
8827   if (!v4_address_set && !v6_address_set)
8828     {
8829       errmsg ("no address set");
8830       return -99;
8831     }
8832
8833   /* Construct the API message */
8834   M (IP_NEIGHBOR_ADD_DEL, mp);
8835
8836   mp->sw_if_index = ntohl (sw_if_index);
8837   mp->is_add = is_add;
8838   mp->is_static = is_static;
8839   mp->is_no_adj_fib = is_no_fib_entry;
8840   if (mac_set)
8841     clib_memcpy (mp->mac_address, mac_address, 6);
8842   if (v6_address_set)
8843     {
8844       mp->is_ipv6 = 1;
8845       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
8846     }
8847   else
8848     {
8849       /* mp->is_ipv6 = 0; via memset in M macro above */
8850       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
8851     }
8852
8853   /* send it... */
8854   S (mp);
8855
8856   /* Wait for a reply, return good/bad news  */
8857   W (ret);
8858   return ret;
8859 }
8860
8861 static int
8862 api_reset_vrf (vat_main_t * vam)
8863 {
8864   unformat_input_t *i = vam->input;
8865   vl_api_reset_vrf_t *mp;
8866   u32 vrf_id = 0;
8867   u8 is_ipv6 = 0;
8868   u8 vrf_id_set = 0;
8869   int ret;
8870
8871   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8872     {
8873       if (unformat (i, "vrf %d", &vrf_id))
8874         vrf_id_set = 1;
8875       else if (unformat (i, "ipv6"))
8876         is_ipv6 = 1;
8877       else
8878         {
8879           clib_warning ("parse error '%U'", format_unformat_error, i);
8880           return -99;
8881         }
8882     }
8883
8884   if (vrf_id_set == 0)
8885     {
8886       errmsg ("missing vrf id");
8887       return -99;
8888     }
8889
8890   M (RESET_VRF, mp);
8891
8892   mp->vrf_id = ntohl (vrf_id);
8893   mp->is_ipv6 = is_ipv6;
8894
8895   S (mp);
8896   W (ret);
8897   return ret;
8898 }
8899
8900 static int
8901 api_create_vlan_subif (vat_main_t * vam)
8902 {
8903   unformat_input_t *i = vam->input;
8904   vl_api_create_vlan_subif_t *mp;
8905   u32 sw_if_index;
8906   u8 sw_if_index_set = 0;
8907   u32 vlan_id;
8908   u8 vlan_id_set = 0;
8909   int ret;
8910
8911   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8912     {
8913       if (unformat (i, "sw_if_index %d", &sw_if_index))
8914         sw_if_index_set = 1;
8915       else
8916         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8917         sw_if_index_set = 1;
8918       else if (unformat (i, "vlan %d", &vlan_id))
8919         vlan_id_set = 1;
8920       else
8921         {
8922           clib_warning ("parse error '%U'", format_unformat_error, i);
8923           return -99;
8924         }
8925     }
8926
8927   if (sw_if_index_set == 0)
8928     {
8929       errmsg ("missing interface name or sw_if_index");
8930       return -99;
8931     }
8932
8933   if (vlan_id_set == 0)
8934     {
8935       errmsg ("missing vlan_id");
8936       return -99;
8937     }
8938   M (CREATE_VLAN_SUBIF, mp);
8939
8940   mp->sw_if_index = ntohl (sw_if_index);
8941   mp->vlan_id = ntohl (vlan_id);
8942
8943   S (mp);
8944   W (ret);
8945   return ret;
8946 }
8947
8948 #define foreach_create_subif_bit                \
8949 _(no_tags)                                      \
8950 _(one_tag)                                      \
8951 _(two_tags)                                     \
8952 _(dot1ad)                                       \
8953 _(exact_match)                                  \
8954 _(default_sub)                                  \
8955 _(outer_vlan_id_any)                            \
8956 _(inner_vlan_id_any)
8957
8958 static int
8959 api_create_subif (vat_main_t * vam)
8960 {
8961   unformat_input_t *i = vam->input;
8962   vl_api_create_subif_t *mp;
8963   u32 sw_if_index;
8964   u8 sw_if_index_set = 0;
8965   u32 sub_id;
8966   u8 sub_id_set = 0;
8967   u32 no_tags = 0;
8968   u32 one_tag = 0;
8969   u32 two_tags = 0;
8970   u32 dot1ad = 0;
8971   u32 exact_match = 0;
8972   u32 default_sub = 0;
8973   u32 outer_vlan_id_any = 0;
8974   u32 inner_vlan_id_any = 0;
8975   u32 tmp;
8976   u16 outer_vlan_id = 0;
8977   u16 inner_vlan_id = 0;
8978   int ret;
8979
8980   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8981     {
8982       if (unformat (i, "sw_if_index %d", &sw_if_index))
8983         sw_if_index_set = 1;
8984       else
8985         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8986         sw_if_index_set = 1;
8987       else if (unformat (i, "sub_id %d", &sub_id))
8988         sub_id_set = 1;
8989       else if (unformat (i, "outer_vlan_id %d", &tmp))
8990         outer_vlan_id = tmp;
8991       else if (unformat (i, "inner_vlan_id %d", &tmp))
8992         inner_vlan_id = tmp;
8993
8994 #define _(a) else if (unformat (i, #a)) a = 1 ;
8995       foreach_create_subif_bit
8996 #undef _
8997         else
8998         {
8999           clib_warning ("parse error '%U'", format_unformat_error, i);
9000           return -99;
9001         }
9002     }
9003
9004   if (sw_if_index_set == 0)
9005     {
9006       errmsg ("missing interface name or sw_if_index");
9007       return -99;
9008     }
9009
9010   if (sub_id_set == 0)
9011     {
9012       errmsg ("missing sub_id");
9013       return -99;
9014     }
9015   M (CREATE_SUBIF, mp);
9016
9017   mp->sw_if_index = ntohl (sw_if_index);
9018   mp->sub_id = ntohl (sub_id);
9019
9020 #define _(a) mp->a = a;
9021   foreach_create_subif_bit;
9022 #undef _
9023
9024   mp->outer_vlan_id = ntohs (outer_vlan_id);
9025   mp->inner_vlan_id = ntohs (inner_vlan_id);
9026
9027   S (mp);
9028   W (ret);
9029   return ret;
9030 }
9031
9032 static int
9033 api_oam_add_del (vat_main_t * vam)
9034 {
9035   unformat_input_t *i = vam->input;
9036   vl_api_oam_add_del_t *mp;
9037   u32 vrf_id = 0;
9038   u8 is_add = 1;
9039   ip4_address_t src, dst;
9040   u8 src_set = 0;
9041   u8 dst_set = 0;
9042   int ret;
9043
9044   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9045     {
9046       if (unformat (i, "vrf %d", &vrf_id))
9047         ;
9048       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9049         src_set = 1;
9050       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9051         dst_set = 1;
9052       else if (unformat (i, "del"))
9053         is_add = 0;
9054       else
9055         {
9056           clib_warning ("parse error '%U'", format_unformat_error, i);
9057           return -99;
9058         }
9059     }
9060
9061   if (src_set == 0)
9062     {
9063       errmsg ("missing src addr");
9064       return -99;
9065     }
9066
9067   if (dst_set == 0)
9068     {
9069       errmsg ("missing dst addr");
9070       return -99;
9071     }
9072
9073   M (OAM_ADD_DEL, mp);
9074
9075   mp->vrf_id = ntohl (vrf_id);
9076   mp->is_add = is_add;
9077   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9078   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9079
9080   S (mp);
9081   W (ret);
9082   return ret;
9083 }
9084
9085 static int
9086 api_reset_fib (vat_main_t * vam)
9087 {
9088   unformat_input_t *i = vam->input;
9089   vl_api_reset_fib_t *mp;
9090   u32 vrf_id = 0;
9091   u8 is_ipv6 = 0;
9092   u8 vrf_id_set = 0;
9093
9094   int ret;
9095   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9096     {
9097       if (unformat (i, "vrf %d", &vrf_id))
9098         vrf_id_set = 1;
9099       else if (unformat (i, "ipv6"))
9100         is_ipv6 = 1;
9101       else
9102         {
9103           clib_warning ("parse error '%U'", format_unformat_error, i);
9104           return -99;
9105         }
9106     }
9107
9108   if (vrf_id_set == 0)
9109     {
9110       errmsg ("missing vrf id");
9111       return -99;
9112     }
9113
9114   M (RESET_FIB, mp);
9115
9116   mp->vrf_id = ntohl (vrf_id);
9117   mp->is_ipv6 = is_ipv6;
9118
9119   S (mp);
9120   W (ret);
9121   return ret;
9122 }
9123
9124 static int
9125 api_dhcp_proxy_config (vat_main_t * vam)
9126 {
9127   unformat_input_t *i = vam->input;
9128   vl_api_dhcp_proxy_config_t *mp;
9129   u32 rx_vrf_id = 0;
9130   u32 server_vrf_id = 0;
9131   u8 is_add = 1;
9132   u8 v4_address_set = 0;
9133   u8 v6_address_set = 0;
9134   ip4_address_t v4address;
9135   ip6_address_t v6address;
9136   u8 v4_src_address_set = 0;
9137   u8 v6_src_address_set = 0;
9138   ip4_address_t v4srcaddress;
9139   ip6_address_t v6srcaddress;
9140   int ret;
9141
9142   /* Parse args required to build the message */
9143   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9144     {
9145       if (unformat (i, "del"))
9146         is_add = 0;
9147       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9148         ;
9149       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9150         ;
9151       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9152         v4_address_set = 1;
9153       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9154         v6_address_set = 1;
9155       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9156         v4_src_address_set = 1;
9157       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9158         v6_src_address_set = 1;
9159       else
9160         break;
9161     }
9162
9163   if (v4_address_set && v6_address_set)
9164     {
9165       errmsg ("both v4 and v6 server addresses set");
9166       return -99;
9167     }
9168   if (!v4_address_set && !v6_address_set)
9169     {
9170       errmsg ("no server addresses set");
9171       return -99;
9172     }
9173
9174   if (v4_src_address_set && v6_src_address_set)
9175     {
9176       errmsg ("both v4 and v6  src addresses set");
9177       return -99;
9178     }
9179   if (!v4_src_address_set && !v6_src_address_set)
9180     {
9181       errmsg ("no src addresses set");
9182       return -99;
9183     }
9184
9185   if (!(v4_src_address_set && v4_address_set) &&
9186       !(v6_src_address_set && v6_address_set))
9187     {
9188       errmsg ("no matching server and src addresses set");
9189       return -99;
9190     }
9191
9192   /* Construct the API message */
9193   M (DHCP_PROXY_CONFIG, mp);
9194
9195   mp->is_add = is_add;
9196   mp->rx_vrf_id = ntohl (rx_vrf_id);
9197   mp->server_vrf_id = ntohl (server_vrf_id);
9198   if (v6_address_set)
9199     {
9200       mp->is_ipv6 = 1;
9201       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9202       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9203     }
9204   else
9205     {
9206       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9207       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9208     }
9209
9210   /* send it... */
9211   S (mp);
9212
9213   /* Wait for a reply, return good/bad news  */
9214   W (ret);
9215   return ret;
9216 }
9217
9218 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9219 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9220
9221 static void
9222 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9223 {
9224   vat_main_t *vam = &vat_main;
9225   u32 i, count = mp->count;
9226   vl_api_dhcp_server_t *s;
9227
9228   if (mp->is_ipv6)
9229     print (vam->ofp,
9230            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
9231            ntohl (mp->rx_vrf_id),
9232            format_ip6_address, mp->dhcp_src_address,
9233            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9234   else
9235     print (vam->ofp,
9236            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
9237            ntohl (mp->rx_vrf_id),
9238            format_ip4_address, mp->dhcp_src_address,
9239            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9240
9241   for (i = 0; i < count; i++)
9242     {
9243       s = &mp->servers[i];
9244
9245       if (mp->is_ipv6)
9246         print (vam->ofp,
9247                " Server Table-ID %d, Server Address %U",
9248                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9249       else
9250         print (vam->ofp,
9251                " Server Table-ID %d, Server Address %U",
9252                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9253     }
9254 }
9255
9256 static void vl_api_dhcp_proxy_details_t_handler_json
9257   (vl_api_dhcp_proxy_details_t * mp)
9258 {
9259   vat_main_t *vam = &vat_main;
9260   vat_json_node_t *node = NULL;
9261   u32 i, count = mp->count;
9262   struct in_addr ip4;
9263   struct in6_addr ip6;
9264   vl_api_dhcp_server_t *s;
9265
9266   if (VAT_JSON_ARRAY != vam->json_tree.type)
9267     {
9268       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9269       vat_json_init_array (&vam->json_tree);
9270     }
9271   node = vat_json_array_add (&vam->json_tree);
9272
9273   vat_json_init_object (node);
9274   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9275   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9276   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9277
9278   if (mp->is_ipv6)
9279     {
9280       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9281       vat_json_object_add_ip6 (node, "src_address", ip6);
9282     }
9283   else
9284     {
9285       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9286       vat_json_object_add_ip4 (node, "src_address", ip4);
9287     }
9288
9289   for (i = 0; i < count; i++)
9290     {
9291       s = &mp->servers[i];
9292
9293       vat_json_object_add_uint (node, "server-table-id",
9294                                 ntohl (s->server_vrf_id));
9295
9296       if (mp->is_ipv6)
9297         {
9298           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9299           vat_json_object_add_ip4 (node, "src_address", ip4);
9300         }
9301       else
9302         {
9303           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9304           vat_json_object_add_ip6 (node, "server_address", ip6);
9305         }
9306     }
9307 }
9308
9309 static int
9310 api_dhcp_proxy_dump (vat_main_t * vam)
9311 {
9312   unformat_input_t *i = vam->input;
9313   vl_api_control_ping_t *mp_ping;
9314   vl_api_dhcp_proxy_dump_t *mp;
9315   u8 is_ipv6 = 0;
9316   int ret;
9317
9318   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9319     {
9320       if (unformat (i, "ipv6"))
9321         is_ipv6 = 1;
9322       else
9323         {
9324           clib_warning ("parse error '%U'", format_unformat_error, i);
9325           return -99;
9326         }
9327     }
9328
9329   M (DHCP_PROXY_DUMP, mp);
9330
9331   mp->is_ip6 = is_ipv6;
9332   S (mp);
9333
9334   /* Use a control ping for synchronization */
9335   MPING (CONTROL_PING, mp_ping);
9336   S (mp_ping);
9337
9338   W (ret);
9339   return ret;
9340 }
9341
9342 static int
9343 api_dhcp_proxy_set_vss (vat_main_t * vam)
9344 {
9345   unformat_input_t *i = vam->input;
9346   vl_api_dhcp_proxy_set_vss_t *mp;
9347   u8 is_ipv6 = 0;
9348   u8 is_add = 1;
9349   u32 tbl_id;
9350   u8 tbl_id_set = 0;
9351   u32 oui;
9352   u8 oui_set = 0;
9353   u32 fib_id;
9354   u8 fib_id_set = 0;
9355   int ret;
9356
9357   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9358     {
9359       if (unformat (i, "tbl_id %d", &tbl_id))
9360         tbl_id_set = 1;
9361       if (unformat (i, "fib_id %d", &fib_id))
9362         fib_id_set = 1;
9363       if (unformat (i, "oui %d", &oui))
9364         oui_set = 1;
9365       else if (unformat (i, "ipv6"))
9366         is_ipv6 = 1;
9367       else if (unformat (i, "del"))
9368         is_add = 0;
9369       else
9370         {
9371           clib_warning ("parse error '%U'", format_unformat_error, i);
9372           return -99;
9373         }
9374     }
9375
9376   if (tbl_id_set == 0)
9377     {
9378       errmsg ("missing tbl id");
9379       return -99;
9380     }
9381
9382   if (fib_id_set == 0)
9383     {
9384       errmsg ("missing fib id");
9385       return -99;
9386     }
9387   if (oui_set == 0)
9388     {
9389       errmsg ("missing oui");
9390       return -99;
9391     }
9392
9393   M (DHCP_PROXY_SET_VSS, mp);
9394   mp->tbl_id = ntohl (tbl_id);
9395   mp->fib_id = ntohl (fib_id);
9396   mp->oui = ntohl (oui);
9397   mp->is_ipv6 = is_ipv6;
9398   mp->is_add = is_add;
9399
9400   S (mp);
9401   W (ret);
9402   return ret;
9403 }
9404
9405 static int
9406 api_dhcp_client_config (vat_main_t * vam)
9407 {
9408   unformat_input_t *i = vam->input;
9409   vl_api_dhcp_client_config_t *mp;
9410   u32 sw_if_index;
9411   u8 sw_if_index_set = 0;
9412   u8 is_add = 1;
9413   u8 *hostname = 0;
9414   u8 disable_event = 0;
9415   int ret;
9416
9417   /* Parse args required to build the message */
9418   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9419     {
9420       if (unformat (i, "del"))
9421         is_add = 0;
9422       else
9423         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9424         sw_if_index_set = 1;
9425       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9426         sw_if_index_set = 1;
9427       else if (unformat (i, "hostname %s", &hostname))
9428         ;
9429       else if (unformat (i, "disable_event"))
9430         disable_event = 1;
9431       else
9432         break;
9433     }
9434
9435   if (sw_if_index_set == 0)
9436     {
9437       errmsg ("missing interface name or sw_if_index");
9438       return -99;
9439     }
9440
9441   if (vec_len (hostname) > 63)
9442     {
9443       errmsg ("hostname too long");
9444     }
9445   vec_add1 (hostname, 0);
9446
9447   /* Construct the API message */
9448   M (DHCP_CLIENT_CONFIG, mp);
9449
9450   mp->sw_if_index = htonl (sw_if_index);
9451   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
9452   vec_free (hostname);
9453   mp->is_add = is_add;
9454   mp->want_dhcp_event = disable_event ? 0 : 1;
9455   mp->pid = htonl (getpid ());
9456
9457   /* send it... */
9458   S (mp);
9459
9460   /* Wait for a reply, return good/bad news  */
9461   W (ret);
9462   return ret;
9463 }
9464
9465 static int
9466 api_set_ip_flow_hash (vat_main_t * vam)
9467 {
9468   unformat_input_t *i = vam->input;
9469   vl_api_set_ip_flow_hash_t *mp;
9470   u32 vrf_id = 0;
9471   u8 is_ipv6 = 0;
9472   u8 vrf_id_set = 0;
9473   u8 src = 0;
9474   u8 dst = 0;
9475   u8 sport = 0;
9476   u8 dport = 0;
9477   u8 proto = 0;
9478   u8 reverse = 0;
9479   int ret;
9480
9481   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9482     {
9483       if (unformat (i, "vrf %d", &vrf_id))
9484         vrf_id_set = 1;
9485       else if (unformat (i, "ipv6"))
9486         is_ipv6 = 1;
9487       else if (unformat (i, "src"))
9488         src = 1;
9489       else if (unformat (i, "dst"))
9490         dst = 1;
9491       else if (unformat (i, "sport"))
9492         sport = 1;
9493       else if (unformat (i, "dport"))
9494         dport = 1;
9495       else if (unformat (i, "proto"))
9496         proto = 1;
9497       else if (unformat (i, "reverse"))
9498         reverse = 1;
9499
9500       else
9501         {
9502           clib_warning ("parse error '%U'", format_unformat_error, i);
9503           return -99;
9504         }
9505     }
9506
9507   if (vrf_id_set == 0)
9508     {
9509       errmsg ("missing vrf id");
9510       return -99;
9511     }
9512
9513   M (SET_IP_FLOW_HASH, mp);
9514   mp->src = src;
9515   mp->dst = dst;
9516   mp->sport = sport;
9517   mp->dport = dport;
9518   mp->proto = proto;
9519   mp->reverse = reverse;
9520   mp->vrf_id = ntohl (vrf_id);
9521   mp->is_ipv6 = is_ipv6;
9522
9523   S (mp);
9524   W (ret);
9525   return ret;
9526 }
9527
9528 static int
9529 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9530 {
9531   unformat_input_t *i = vam->input;
9532   vl_api_sw_interface_ip6_enable_disable_t *mp;
9533   u32 sw_if_index;
9534   u8 sw_if_index_set = 0;
9535   u8 enable = 0;
9536   int ret;
9537
9538   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9539     {
9540       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9541         sw_if_index_set = 1;
9542       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9543         sw_if_index_set = 1;
9544       else if (unformat (i, "enable"))
9545         enable = 1;
9546       else if (unformat (i, "disable"))
9547         enable = 0;
9548       else
9549         {
9550           clib_warning ("parse error '%U'", format_unformat_error, i);
9551           return -99;
9552         }
9553     }
9554
9555   if (sw_if_index_set == 0)
9556     {
9557       errmsg ("missing interface name or sw_if_index");
9558       return -99;
9559     }
9560
9561   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9562
9563   mp->sw_if_index = ntohl (sw_if_index);
9564   mp->enable = enable;
9565
9566   S (mp);
9567   W (ret);
9568   return ret;
9569 }
9570
9571 static int
9572 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
9573 {
9574   unformat_input_t *i = vam->input;
9575   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
9576   u32 sw_if_index;
9577   u8 sw_if_index_set = 0;
9578   u8 v6_address_set = 0;
9579   ip6_address_t v6address;
9580   int ret;
9581
9582   /* Parse args required to build the message */
9583   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9584     {
9585       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9586         sw_if_index_set = 1;
9587       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9588         sw_if_index_set = 1;
9589       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9590         v6_address_set = 1;
9591       else
9592         break;
9593     }
9594
9595   if (sw_if_index_set == 0)
9596     {
9597       errmsg ("missing interface name or sw_if_index");
9598       return -99;
9599     }
9600   if (!v6_address_set)
9601     {
9602       errmsg ("no address set");
9603       return -99;
9604     }
9605
9606   /* Construct the API message */
9607   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
9608
9609   mp->sw_if_index = ntohl (sw_if_index);
9610   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9611
9612   /* send it... */
9613   S (mp);
9614
9615   /* Wait for a reply, return good/bad news  */
9616   W (ret);
9617   return ret;
9618 }
9619
9620 static int
9621 api_ip6nd_proxy_add_del (vat_main_t * vam)
9622 {
9623   unformat_input_t *i = vam->input;
9624   vl_api_ip6nd_proxy_add_del_t *mp;
9625   u32 sw_if_index = ~0;
9626   u8 v6_address_set = 0;
9627   ip6_address_t v6address;
9628   u8 is_del = 0;
9629   int ret;
9630
9631   /* Parse args required to build the message */
9632   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9633     {
9634       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9635         ;
9636       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9637         ;
9638       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9639         v6_address_set = 1;
9640       if (unformat (i, "del"))
9641         is_del = 1;
9642       else
9643         {
9644           clib_warning ("parse error '%U'", format_unformat_error, i);
9645           return -99;
9646         }
9647     }
9648
9649   if (sw_if_index == ~0)
9650     {
9651       errmsg ("missing interface name or sw_if_index");
9652       return -99;
9653     }
9654   if (!v6_address_set)
9655     {
9656       errmsg ("no address set");
9657       return -99;
9658     }
9659
9660   /* Construct the API message */
9661   M (IP6ND_PROXY_ADD_DEL, mp);
9662
9663   mp->is_del = is_del;
9664   mp->sw_if_index = ntohl (sw_if_index);
9665   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9666
9667   /* send it... */
9668   S (mp);
9669
9670   /* Wait for a reply, return good/bad news  */
9671   W (ret);
9672   return ret;
9673 }
9674
9675 static int
9676 api_ip6nd_proxy_dump (vat_main_t * vam)
9677 {
9678   vl_api_ip6nd_proxy_dump_t *mp;
9679   vl_api_control_ping_t *mp_ping;
9680   int ret;
9681
9682   M (IP6ND_PROXY_DUMP, mp);
9683
9684   S (mp);
9685
9686   /* Use a control ping for synchronization */
9687   MPING (CONTROL_PING, mp_ping);
9688   S (mp_ping);
9689
9690   W (ret);
9691   return ret;
9692 }
9693
9694 static void vl_api_ip6nd_proxy_details_t_handler
9695   (vl_api_ip6nd_proxy_details_t * mp)
9696 {
9697   vat_main_t *vam = &vat_main;
9698
9699   print (vam->ofp, "host %U sw_if_index %d",
9700          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
9701 }
9702
9703 static void vl_api_ip6nd_proxy_details_t_handler_json
9704   (vl_api_ip6nd_proxy_details_t * mp)
9705 {
9706   vat_main_t *vam = &vat_main;
9707   struct in6_addr ip6;
9708   vat_json_node_t *node = NULL;
9709
9710   if (VAT_JSON_ARRAY != vam->json_tree.type)
9711     {
9712       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9713       vat_json_init_array (&vam->json_tree);
9714     }
9715   node = vat_json_array_add (&vam->json_tree);
9716
9717   vat_json_init_object (node);
9718   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9719
9720   clib_memcpy (&ip6, mp->address, sizeof (ip6));
9721   vat_json_object_add_ip6 (node, "host", ip6);
9722 }
9723
9724 static int
9725 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9726 {
9727   unformat_input_t *i = vam->input;
9728   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9729   u32 sw_if_index;
9730   u8 sw_if_index_set = 0;
9731   u32 address_length = 0;
9732   u8 v6_address_set = 0;
9733   ip6_address_t v6address;
9734   u8 use_default = 0;
9735   u8 no_advertise = 0;
9736   u8 off_link = 0;
9737   u8 no_autoconfig = 0;
9738   u8 no_onlink = 0;
9739   u8 is_no = 0;
9740   u32 val_lifetime = 0;
9741   u32 pref_lifetime = 0;
9742   int ret;
9743
9744   /* Parse args required to build the message */
9745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9746     {
9747       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9748         sw_if_index_set = 1;
9749       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9750         sw_if_index_set = 1;
9751       else if (unformat (i, "%U/%d",
9752                          unformat_ip6_address, &v6address, &address_length))
9753         v6_address_set = 1;
9754       else if (unformat (i, "val_life %d", &val_lifetime))
9755         ;
9756       else if (unformat (i, "pref_life %d", &pref_lifetime))
9757         ;
9758       else if (unformat (i, "def"))
9759         use_default = 1;
9760       else if (unformat (i, "noadv"))
9761         no_advertise = 1;
9762       else if (unformat (i, "offl"))
9763         off_link = 1;
9764       else if (unformat (i, "noauto"))
9765         no_autoconfig = 1;
9766       else if (unformat (i, "nolink"))
9767         no_onlink = 1;
9768       else if (unformat (i, "isno"))
9769         is_no = 1;
9770       else
9771         {
9772           clib_warning ("parse error '%U'", format_unformat_error, i);
9773           return -99;
9774         }
9775     }
9776
9777   if (sw_if_index_set == 0)
9778     {
9779       errmsg ("missing interface name or sw_if_index");
9780       return -99;
9781     }
9782   if (!v6_address_set)
9783     {
9784       errmsg ("no address set");
9785       return -99;
9786     }
9787
9788   /* Construct the API message */
9789   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9790
9791   mp->sw_if_index = ntohl (sw_if_index);
9792   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9793   mp->address_length = address_length;
9794   mp->use_default = use_default;
9795   mp->no_advertise = no_advertise;
9796   mp->off_link = off_link;
9797   mp->no_autoconfig = no_autoconfig;
9798   mp->no_onlink = no_onlink;
9799   mp->is_no = is_no;
9800   mp->val_lifetime = ntohl (val_lifetime);
9801   mp->pref_lifetime = ntohl (pref_lifetime);
9802
9803   /* send it... */
9804   S (mp);
9805
9806   /* Wait for a reply, return good/bad news  */
9807   W (ret);
9808   return ret;
9809 }
9810
9811 static int
9812 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9813 {
9814   unformat_input_t *i = vam->input;
9815   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9816   u32 sw_if_index;
9817   u8 sw_if_index_set = 0;
9818   u8 suppress = 0;
9819   u8 managed = 0;
9820   u8 other = 0;
9821   u8 ll_option = 0;
9822   u8 send_unicast = 0;
9823   u8 cease = 0;
9824   u8 is_no = 0;
9825   u8 default_router = 0;
9826   u32 max_interval = 0;
9827   u32 min_interval = 0;
9828   u32 lifetime = 0;
9829   u32 initial_count = 0;
9830   u32 initial_interval = 0;
9831   int ret;
9832
9833
9834   /* Parse args required to build the message */
9835   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9836     {
9837       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9838         sw_if_index_set = 1;
9839       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9840         sw_if_index_set = 1;
9841       else if (unformat (i, "maxint %d", &max_interval))
9842         ;
9843       else if (unformat (i, "minint %d", &min_interval))
9844         ;
9845       else if (unformat (i, "life %d", &lifetime))
9846         ;
9847       else if (unformat (i, "count %d", &initial_count))
9848         ;
9849       else if (unformat (i, "interval %d", &initial_interval))
9850         ;
9851       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9852         suppress = 1;
9853       else if (unformat (i, "managed"))
9854         managed = 1;
9855       else if (unformat (i, "other"))
9856         other = 1;
9857       else if (unformat (i, "ll"))
9858         ll_option = 1;
9859       else if (unformat (i, "send"))
9860         send_unicast = 1;
9861       else if (unformat (i, "cease"))
9862         cease = 1;
9863       else if (unformat (i, "isno"))
9864         is_no = 1;
9865       else if (unformat (i, "def"))
9866         default_router = 1;
9867       else
9868         {
9869           clib_warning ("parse error '%U'", format_unformat_error, i);
9870           return -99;
9871         }
9872     }
9873
9874   if (sw_if_index_set == 0)
9875     {
9876       errmsg ("missing interface name or sw_if_index");
9877       return -99;
9878     }
9879
9880   /* Construct the API message */
9881   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9882
9883   mp->sw_if_index = ntohl (sw_if_index);
9884   mp->max_interval = ntohl (max_interval);
9885   mp->min_interval = ntohl (min_interval);
9886   mp->lifetime = ntohl (lifetime);
9887   mp->initial_count = ntohl (initial_count);
9888   mp->initial_interval = ntohl (initial_interval);
9889   mp->suppress = suppress;
9890   mp->managed = managed;
9891   mp->other = other;
9892   mp->ll_option = ll_option;
9893   mp->send_unicast = send_unicast;
9894   mp->cease = cease;
9895   mp->is_no = is_no;
9896   mp->default_router = default_router;
9897
9898   /* send it... */
9899   S (mp);
9900
9901   /* Wait for a reply, return good/bad news  */
9902   W (ret);
9903   return ret;
9904 }
9905
9906 static int
9907 api_set_arp_neighbor_limit (vat_main_t * vam)
9908 {
9909   unformat_input_t *i = vam->input;
9910   vl_api_set_arp_neighbor_limit_t *mp;
9911   u32 arp_nbr_limit;
9912   u8 limit_set = 0;
9913   u8 is_ipv6 = 0;
9914   int ret;
9915
9916   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9917     {
9918       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
9919         limit_set = 1;
9920       else if (unformat (i, "ipv6"))
9921         is_ipv6 = 1;
9922       else
9923         {
9924           clib_warning ("parse error '%U'", format_unformat_error, i);
9925           return -99;
9926         }
9927     }
9928
9929   if (limit_set == 0)
9930     {
9931       errmsg ("missing limit value");
9932       return -99;
9933     }
9934
9935   M (SET_ARP_NEIGHBOR_LIMIT, mp);
9936
9937   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
9938   mp->is_ipv6 = is_ipv6;
9939
9940   S (mp);
9941   W (ret);
9942   return ret;
9943 }
9944
9945 static int
9946 api_l2_patch_add_del (vat_main_t * vam)
9947 {
9948   unformat_input_t *i = vam->input;
9949   vl_api_l2_patch_add_del_t *mp;
9950   u32 rx_sw_if_index;
9951   u8 rx_sw_if_index_set = 0;
9952   u32 tx_sw_if_index;
9953   u8 tx_sw_if_index_set = 0;
9954   u8 is_add = 1;
9955   int ret;
9956
9957   /* Parse args required to build the message */
9958   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9959     {
9960       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9961         rx_sw_if_index_set = 1;
9962       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9963         tx_sw_if_index_set = 1;
9964       else if (unformat (i, "rx"))
9965         {
9966           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9967             {
9968               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9969                             &rx_sw_if_index))
9970                 rx_sw_if_index_set = 1;
9971             }
9972           else
9973             break;
9974         }
9975       else if (unformat (i, "tx"))
9976         {
9977           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9978             {
9979               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9980                             &tx_sw_if_index))
9981                 tx_sw_if_index_set = 1;
9982             }
9983           else
9984             break;
9985         }
9986       else if (unformat (i, "del"))
9987         is_add = 0;
9988       else
9989         break;
9990     }
9991
9992   if (rx_sw_if_index_set == 0)
9993     {
9994       errmsg ("missing rx interface name or rx_sw_if_index");
9995       return -99;
9996     }
9997
9998   if (tx_sw_if_index_set == 0)
9999     {
10000       errmsg ("missing tx interface name or tx_sw_if_index");
10001       return -99;
10002     }
10003
10004   M (L2_PATCH_ADD_DEL, mp);
10005
10006   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10007   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10008   mp->is_add = is_add;
10009
10010   S (mp);
10011   W (ret);
10012   return ret;
10013 }
10014
10015 u8 is_del;
10016 u8 localsid_addr[16];
10017 u8 end_psp;
10018 u8 behavior;
10019 u32 sw_if_index;
10020 u32 vlan_index;
10021 u32 fib_table;
10022 u8 nh_addr[16];
10023
10024 static int
10025 api_sr_localsid_add_del (vat_main_t * vam)
10026 {
10027   unformat_input_t *i = vam->input;
10028   vl_api_sr_localsid_add_del_t *mp;
10029
10030   u8 is_del;
10031   ip6_address_t localsid;
10032   u8 end_psp = 0;
10033   u8 behavior = ~0;
10034   u32 sw_if_index;
10035   u32 fib_table = ~(u32) 0;
10036   ip6_address_t next_hop;
10037
10038   bool nexthop_set = 0;
10039
10040   int ret;
10041
10042   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10043     {
10044       if (unformat (i, "del"))
10045         is_del = 1;
10046       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10047       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
10048         nexthop_set = 1;
10049       else if (unformat (i, "behavior %u", &behavior));
10050       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10051       else if (unformat (i, "fib-table %u", &fib_table));
10052       else if (unformat (i, "end.psp %u", &behavior));
10053       else
10054         break;
10055     }
10056
10057   M (SR_LOCALSID_ADD_DEL, mp);
10058
10059   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
10060   if (nexthop_set)
10061     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
10062   mp->behavior = behavior;
10063   mp->sw_if_index = ntohl (sw_if_index);
10064   mp->fib_table = ntohl (fib_table);
10065   mp->end_psp = end_psp;
10066   mp->is_del = is_del;
10067
10068   S (mp);
10069   W (ret);
10070   return ret;
10071 }
10072
10073 static int
10074 api_ioam_enable (vat_main_t * vam)
10075 {
10076   unformat_input_t *input = vam->input;
10077   vl_api_ioam_enable_t *mp;
10078   u32 id = 0;
10079   int has_trace_option = 0;
10080   int has_pot_option = 0;
10081   int has_seqno_option = 0;
10082   int has_analyse_option = 0;
10083   int ret;
10084
10085   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10086     {
10087       if (unformat (input, "trace"))
10088         has_trace_option = 1;
10089       else if (unformat (input, "pot"))
10090         has_pot_option = 1;
10091       else if (unformat (input, "seqno"))
10092         has_seqno_option = 1;
10093       else if (unformat (input, "analyse"))
10094         has_analyse_option = 1;
10095       else
10096         break;
10097     }
10098   M (IOAM_ENABLE, mp);
10099   mp->id = htons (id);
10100   mp->seqno = has_seqno_option;
10101   mp->analyse = has_analyse_option;
10102   mp->pot_enable = has_pot_option;
10103   mp->trace_enable = has_trace_option;
10104
10105   S (mp);
10106   W (ret);
10107   return ret;
10108 }
10109
10110
10111 static int
10112 api_ioam_disable (vat_main_t * vam)
10113 {
10114   vl_api_ioam_disable_t *mp;
10115   int ret;
10116
10117   M (IOAM_DISABLE, mp);
10118   S (mp);
10119   W (ret);
10120   return ret;
10121 }
10122
10123 #define foreach_tcp_proto_field                 \
10124 _(src_port)                                     \
10125 _(dst_port)
10126
10127 #define foreach_udp_proto_field                 \
10128 _(src_port)                                     \
10129 _(dst_port)
10130
10131 #define foreach_ip4_proto_field                 \
10132 _(src_address)                                  \
10133 _(dst_address)                                  \
10134 _(tos)                                          \
10135 _(length)                                       \
10136 _(fragment_id)                                  \
10137 _(ttl)                                          \
10138 _(protocol)                                     \
10139 _(checksum)
10140
10141 typedef struct
10142 {
10143   u16 src_port, dst_port;
10144 } tcpudp_header_t;
10145
10146 #if VPP_API_TEST_BUILTIN == 0
10147 uword
10148 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10149 {
10150   u8 **maskp = va_arg (*args, u8 **);
10151   u8 *mask = 0;
10152   u8 found_something = 0;
10153   tcp_header_t *tcp;
10154
10155 #define _(a) u8 a=0;
10156   foreach_tcp_proto_field;
10157 #undef _
10158
10159   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10160     {
10161       if (0);
10162 #define _(a) else if (unformat (input, #a)) a=1;
10163       foreach_tcp_proto_field
10164 #undef _
10165         else
10166         break;
10167     }
10168
10169 #define _(a) found_something += a;
10170   foreach_tcp_proto_field;
10171 #undef _
10172
10173   if (found_something == 0)
10174     return 0;
10175
10176   vec_validate (mask, sizeof (*tcp) - 1);
10177
10178   tcp = (tcp_header_t *) mask;
10179
10180 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
10181   foreach_tcp_proto_field;
10182 #undef _
10183
10184   *maskp = mask;
10185   return 1;
10186 }
10187
10188 uword
10189 unformat_udp_mask (unformat_input_t * input, va_list * args)
10190 {
10191   u8 **maskp = va_arg (*args, u8 **);
10192   u8 *mask = 0;
10193   u8 found_something = 0;
10194   udp_header_t *udp;
10195
10196 #define _(a) u8 a=0;
10197   foreach_udp_proto_field;
10198 #undef _
10199
10200   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10201     {
10202       if (0);
10203 #define _(a) else if (unformat (input, #a)) a=1;
10204       foreach_udp_proto_field
10205 #undef _
10206         else
10207         break;
10208     }
10209
10210 #define _(a) found_something += a;
10211   foreach_udp_proto_field;
10212 #undef _
10213
10214   if (found_something == 0)
10215     return 0;
10216
10217   vec_validate (mask, sizeof (*udp) - 1);
10218
10219   udp = (udp_header_t *) mask;
10220
10221 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
10222   foreach_udp_proto_field;
10223 #undef _
10224
10225   *maskp = mask;
10226   return 1;
10227 }
10228
10229 uword
10230 unformat_l4_mask (unformat_input_t * input, va_list * args)
10231 {
10232   u8 **maskp = va_arg (*args, u8 **);
10233   u16 src_port = 0, dst_port = 0;
10234   tcpudp_header_t *tcpudp;
10235
10236   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10237     {
10238       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10239         return 1;
10240       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10241         return 1;
10242       else if (unformat (input, "src_port"))
10243         src_port = 0xFFFF;
10244       else if (unformat (input, "dst_port"))
10245         dst_port = 0xFFFF;
10246       else
10247         return 0;
10248     }
10249
10250   if (!src_port && !dst_port)
10251     return 0;
10252
10253   u8 *mask = 0;
10254   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10255
10256   tcpudp = (tcpudp_header_t *) mask;
10257   tcpudp->src_port = src_port;
10258   tcpudp->dst_port = dst_port;
10259
10260   *maskp = mask;
10261
10262   return 1;
10263 }
10264
10265 uword
10266 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10267 {
10268   u8 **maskp = va_arg (*args, u8 **);
10269   u8 *mask = 0;
10270   u8 found_something = 0;
10271   ip4_header_t *ip;
10272
10273 #define _(a) u8 a=0;
10274   foreach_ip4_proto_field;
10275 #undef _
10276   u8 version = 0;
10277   u8 hdr_length = 0;
10278
10279
10280   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10281     {
10282       if (unformat (input, "version"))
10283         version = 1;
10284       else if (unformat (input, "hdr_length"))
10285         hdr_length = 1;
10286       else if (unformat (input, "src"))
10287         src_address = 1;
10288       else if (unformat (input, "dst"))
10289         dst_address = 1;
10290       else if (unformat (input, "proto"))
10291         protocol = 1;
10292
10293 #define _(a) else if (unformat (input, #a)) a=1;
10294       foreach_ip4_proto_field
10295 #undef _
10296         else
10297         break;
10298     }
10299
10300 #define _(a) found_something += a;
10301   foreach_ip4_proto_field;
10302 #undef _
10303
10304   if (found_something == 0)
10305     return 0;
10306
10307   vec_validate (mask, sizeof (*ip) - 1);
10308
10309   ip = (ip4_header_t *) mask;
10310
10311 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10312   foreach_ip4_proto_field;
10313 #undef _
10314
10315   ip->ip_version_and_header_length = 0;
10316
10317   if (version)
10318     ip->ip_version_and_header_length |= 0xF0;
10319
10320   if (hdr_length)
10321     ip->ip_version_and_header_length |= 0x0F;
10322
10323   *maskp = mask;
10324   return 1;
10325 }
10326
10327 #define foreach_ip6_proto_field                 \
10328 _(src_address)                                  \
10329 _(dst_address)                                  \
10330 _(payload_length)                               \
10331 _(hop_limit)                                    \
10332 _(protocol)
10333
10334 uword
10335 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10336 {
10337   u8 **maskp = va_arg (*args, u8 **);
10338   u8 *mask = 0;
10339   u8 found_something = 0;
10340   ip6_header_t *ip;
10341   u32 ip_version_traffic_class_and_flow_label;
10342
10343 #define _(a) u8 a=0;
10344   foreach_ip6_proto_field;
10345 #undef _
10346   u8 version = 0;
10347   u8 traffic_class = 0;
10348   u8 flow_label = 0;
10349
10350   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10351     {
10352       if (unformat (input, "version"))
10353         version = 1;
10354       else if (unformat (input, "traffic-class"))
10355         traffic_class = 1;
10356       else if (unformat (input, "flow-label"))
10357         flow_label = 1;
10358       else if (unformat (input, "src"))
10359         src_address = 1;
10360       else if (unformat (input, "dst"))
10361         dst_address = 1;
10362       else if (unformat (input, "proto"))
10363         protocol = 1;
10364
10365 #define _(a) else if (unformat (input, #a)) a=1;
10366       foreach_ip6_proto_field
10367 #undef _
10368         else
10369         break;
10370     }
10371
10372 #define _(a) found_something += a;
10373   foreach_ip6_proto_field;
10374 #undef _
10375
10376   if (found_something == 0)
10377     return 0;
10378
10379   vec_validate (mask, sizeof (*ip) - 1);
10380
10381   ip = (ip6_header_t *) mask;
10382
10383 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10384   foreach_ip6_proto_field;
10385 #undef _
10386
10387   ip_version_traffic_class_and_flow_label = 0;
10388
10389   if (version)
10390     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10391
10392   if (traffic_class)
10393     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10394
10395   if (flow_label)
10396     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10397
10398   ip->ip_version_traffic_class_and_flow_label =
10399     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10400
10401   *maskp = mask;
10402   return 1;
10403 }
10404
10405 uword
10406 unformat_l3_mask (unformat_input_t * input, va_list * args)
10407 {
10408   u8 **maskp = va_arg (*args, u8 **);
10409
10410   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10411     {
10412       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10413         return 1;
10414       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10415         return 1;
10416       else
10417         break;
10418     }
10419   return 0;
10420 }
10421
10422 uword
10423 unformat_l2_mask (unformat_input_t * input, va_list * args)
10424 {
10425   u8 **maskp = va_arg (*args, u8 **);
10426   u8 *mask = 0;
10427   u8 src = 0;
10428   u8 dst = 0;
10429   u8 proto = 0;
10430   u8 tag1 = 0;
10431   u8 tag2 = 0;
10432   u8 ignore_tag1 = 0;
10433   u8 ignore_tag2 = 0;
10434   u8 cos1 = 0;
10435   u8 cos2 = 0;
10436   u8 dot1q = 0;
10437   u8 dot1ad = 0;
10438   int len = 14;
10439
10440   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10441     {
10442       if (unformat (input, "src"))
10443         src = 1;
10444       else if (unformat (input, "dst"))
10445         dst = 1;
10446       else if (unformat (input, "proto"))
10447         proto = 1;
10448       else if (unformat (input, "tag1"))
10449         tag1 = 1;
10450       else if (unformat (input, "tag2"))
10451         tag2 = 1;
10452       else if (unformat (input, "ignore-tag1"))
10453         ignore_tag1 = 1;
10454       else if (unformat (input, "ignore-tag2"))
10455         ignore_tag2 = 1;
10456       else if (unformat (input, "cos1"))
10457         cos1 = 1;
10458       else if (unformat (input, "cos2"))
10459         cos2 = 1;
10460       else if (unformat (input, "dot1q"))
10461         dot1q = 1;
10462       else if (unformat (input, "dot1ad"))
10463         dot1ad = 1;
10464       else
10465         break;
10466     }
10467   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10468        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10469     return 0;
10470
10471   if (tag1 || ignore_tag1 || cos1 || dot1q)
10472     len = 18;
10473   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10474     len = 22;
10475
10476   vec_validate (mask, len - 1);
10477
10478   if (dst)
10479     memset (mask, 0xff, 6);
10480
10481   if (src)
10482     memset (mask + 6, 0xff, 6);
10483
10484   if (tag2 || dot1ad)
10485     {
10486       /* inner vlan tag */
10487       if (tag2)
10488         {
10489           mask[19] = 0xff;
10490           mask[18] = 0x0f;
10491         }
10492       if (cos2)
10493         mask[18] |= 0xe0;
10494       if (proto)
10495         mask[21] = mask[20] = 0xff;
10496       if (tag1)
10497         {
10498           mask[15] = 0xff;
10499           mask[14] = 0x0f;
10500         }
10501       if (cos1)
10502         mask[14] |= 0xe0;
10503       *maskp = mask;
10504       return 1;
10505     }
10506   if (tag1 | dot1q)
10507     {
10508       if (tag1)
10509         {
10510           mask[15] = 0xff;
10511           mask[14] = 0x0f;
10512         }
10513       if (cos1)
10514         mask[14] |= 0xe0;
10515       if (proto)
10516         mask[16] = mask[17] = 0xff;
10517
10518       *maskp = mask;
10519       return 1;
10520     }
10521   if (cos2)
10522     mask[18] |= 0xe0;
10523   if (cos1)
10524     mask[14] |= 0xe0;
10525   if (proto)
10526     mask[12] = mask[13] = 0xff;
10527
10528   *maskp = mask;
10529   return 1;
10530 }
10531
10532 uword
10533 unformat_classify_mask (unformat_input_t * input, va_list * args)
10534 {
10535   u8 **maskp = va_arg (*args, u8 **);
10536   u32 *skipp = va_arg (*args, u32 *);
10537   u32 *matchp = va_arg (*args, u32 *);
10538   u32 match;
10539   u8 *mask = 0;
10540   u8 *l2 = 0;
10541   u8 *l3 = 0;
10542   u8 *l4 = 0;
10543   int i;
10544
10545   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10546     {
10547       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10548         ;
10549       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10550         ;
10551       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10552         ;
10553       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10554         ;
10555       else
10556         break;
10557     }
10558
10559   if (l4 && !l3)
10560     {
10561       vec_free (mask);
10562       vec_free (l2);
10563       vec_free (l4);
10564       return 0;
10565     }
10566
10567   if (mask || l2 || l3 || l4)
10568     {
10569       if (l2 || l3 || l4)
10570         {
10571           /* "With a free Ethernet header in every package" */
10572           if (l2 == 0)
10573             vec_validate (l2, 13);
10574           mask = l2;
10575           if (vec_len (l3))
10576             {
10577               vec_append (mask, l3);
10578               vec_free (l3);
10579             }
10580           if (vec_len (l4))
10581             {
10582               vec_append (mask, l4);
10583               vec_free (l4);
10584             }
10585         }
10586
10587       /* Scan forward looking for the first significant mask octet */
10588       for (i = 0; i < vec_len (mask); i++)
10589         if (mask[i])
10590           break;
10591
10592       /* compute (skip, match) params */
10593       *skipp = i / sizeof (u32x4);
10594       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10595
10596       /* Pad mask to an even multiple of the vector size */
10597       while (vec_len (mask) % sizeof (u32x4))
10598         vec_add1 (mask, 0);
10599
10600       match = vec_len (mask) / sizeof (u32x4);
10601
10602       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10603         {
10604           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10605           if (*tmp || *(tmp + 1))
10606             break;
10607           match--;
10608         }
10609       if (match == 0)
10610         clib_warning ("BUG: match 0");
10611
10612       _vec_len (mask) = match * sizeof (u32x4);
10613
10614       *matchp = match;
10615       *maskp = mask;
10616
10617       return 1;
10618     }
10619
10620   return 0;
10621 }
10622 #endif /* VPP_API_TEST_BUILTIN */
10623
10624 #define foreach_l2_next                         \
10625 _(drop, DROP)                                   \
10626 _(ethernet, ETHERNET_INPUT)                     \
10627 _(ip4, IP4_INPUT)                               \
10628 _(ip6, IP6_INPUT)
10629
10630 uword
10631 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10632 {
10633   u32 *miss_next_indexp = va_arg (*args, u32 *);
10634   u32 next_index = 0;
10635   u32 tmp;
10636
10637 #define _(n,N) \
10638   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10639   foreach_l2_next;
10640 #undef _
10641
10642   if (unformat (input, "%d", &tmp))
10643     {
10644       next_index = tmp;
10645       goto out;
10646     }
10647
10648   return 0;
10649
10650 out:
10651   *miss_next_indexp = next_index;
10652   return 1;
10653 }
10654
10655 #define foreach_ip_next                         \
10656 _(drop, DROP)                                   \
10657 _(local, LOCAL)                                 \
10658 _(rewrite, REWRITE)
10659
10660 uword
10661 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10662 {
10663   u32 *miss_next_indexp = va_arg (*args, u32 *);
10664   u32 next_index = 0;
10665   u32 tmp;
10666
10667 #define _(n,N) \
10668   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10669   foreach_ip_next;
10670 #undef _
10671
10672   if (unformat (input, "%d", &tmp))
10673     {
10674       next_index = tmp;
10675       goto out;
10676     }
10677
10678   return 0;
10679
10680 out:
10681   *miss_next_indexp = next_index;
10682   return 1;
10683 }
10684
10685 #define foreach_acl_next                        \
10686 _(deny, DENY)
10687
10688 uword
10689 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10690 {
10691   u32 *miss_next_indexp = va_arg (*args, u32 *);
10692   u32 next_index = 0;
10693   u32 tmp;
10694
10695 #define _(n,N) \
10696   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10697   foreach_acl_next;
10698 #undef _
10699
10700   if (unformat (input, "permit"))
10701     {
10702       next_index = ~0;
10703       goto out;
10704     }
10705   else if (unformat (input, "%d", &tmp))
10706     {
10707       next_index = tmp;
10708       goto out;
10709     }
10710
10711   return 0;
10712
10713 out:
10714   *miss_next_indexp = next_index;
10715   return 1;
10716 }
10717
10718 uword
10719 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10720 {
10721   u32 *r = va_arg (*args, u32 *);
10722
10723   if (unformat (input, "conform-color"))
10724     *r = POLICE_CONFORM;
10725   else if (unformat (input, "exceed-color"))
10726     *r = POLICE_EXCEED;
10727   else
10728     return 0;
10729
10730   return 1;
10731 }
10732
10733 static int
10734 api_classify_add_del_table (vat_main_t * vam)
10735 {
10736   unformat_input_t *i = vam->input;
10737   vl_api_classify_add_del_table_t *mp;
10738
10739   u32 nbuckets = 2;
10740   u32 skip = ~0;
10741   u32 match = ~0;
10742   int is_add = 1;
10743   int del_chain = 0;
10744   u32 table_index = ~0;
10745   u32 next_table_index = ~0;
10746   u32 miss_next_index = ~0;
10747   u32 memory_size = 32 << 20;
10748   u8 *mask = 0;
10749   u32 current_data_flag = 0;
10750   int current_data_offset = 0;
10751   int ret;
10752
10753   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10754     {
10755       if (unformat (i, "del"))
10756         is_add = 0;
10757       else if (unformat (i, "del-chain"))
10758         {
10759           is_add = 0;
10760           del_chain = 1;
10761         }
10762       else if (unformat (i, "buckets %d", &nbuckets))
10763         ;
10764       else if (unformat (i, "memory_size %d", &memory_size))
10765         ;
10766       else if (unformat (i, "skip %d", &skip))
10767         ;
10768       else if (unformat (i, "match %d", &match))
10769         ;
10770       else if (unformat (i, "table %d", &table_index))
10771         ;
10772       else if (unformat (i, "mask %U", unformat_classify_mask,
10773                          &mask, &skip, &match))
10774         ;
10775       else if (unformat (i, "next-table %d", &next_table_index))
10776         ;
10777       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10778                          &miss_next_index))
10779         ;
10780       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10781                          &miss_next_index))
10782         ;
10783       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10784                          &miss_next_index))
10785         ;
10786       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10787         ;
10788       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10789         ;
10790       else
10791         break;
10792     }
10793
10794   if (is_add && mask == 0)
10795     {
10796       errmsg ("Mask required");
10797       return -99;
10798     }
10799
10800   if (is_add && skip == ~0)
10801     {
10802       errmsg ("skip count required");
10803       return -99;
10804     }
10805
10806   if (is_add && match == ~0)
10807     {
10808       errmsg ("match count required");
10809       return -99;
10810     }
10811
10812   if (!is_add && table_index == ~0)
10813     {
10814       errmsg ("table index required for delete");
10815       return -99;
10816     }
10817
10818   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10819
10820   mp->is_add = is_add;
10821   mp->del_chain = del_chain;
10822   mp->table_index = ntohl (table_index);
10823   mp->nbuckets = ntohl (nbuckets);
10824   mp->memory_size = ntohl (memory_size);
10825   mp->skip_n_vectors = ntohl (skip);
10826   mp->match_n_vectors = ntohl (match);
10827   mp->next_table_index = ntohl (next_table_index);
10828   mp->miss_next_index = ntohl (miss_next_index);
10829   mp->current_data_flag = ntohl (current_data_flag);
10830   mp->current_data_offset = ntohl (current_data_offset);
10831   clib_memcpy (mp->mask, mask, vec_len (mask));
10832
10833   vec_free (mask);
10834
10835   S (mp);
10836   W (ret);
10837   return ret;
10838 }
10839
10840 #if VPP_API_TEST_BUILTIN == 0
10841 uword
10842 unformat_l4_match (unformat_input_t * input, va_list * args)
10843 {
10844   u8 **matchp = va_arg (*args, u8 **);
10845
10846   u8 *proto_header = 0;
10847   int src_port = 0;
10848   int dst_port = 0;
10849
10850   tcpudp_header_t h;
10851
10852   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10853     {
10854       if (unformat (input, "src_port %d", &src_port))
10855         ;
10856       else if (unformat (input, "dst_port %d", &dst_port))
10857         ;
10858       else
10859         return 0;
10860     }
10861
10862   h.src_port = clib_host_to_net_u16 (src_port);
10863   h.dst_port = clib_host_to_net_u16 (dst_port);
10864   vec_validate (proto_header, sizeof (h) - 1);
10865   memcpy (proto_header, &h, sizeof (h));
10866
10867   *matchp = proto_header;
10868
10869   return 1;
10870 }
10871
10872 uword
10873 unformat_ip4_match (unformat_input_t * input, va_list * args)
10874 {
10875   u8 **matchp = va_arg (*args, u8 **);
10876   u8 *match = 0;
10877   ip4_header_t *ip;
10878   int version = 0;
10879   u32 version_val;
10880   int hdr_length = 0;
10881   u32 hdr_length_val;
10882   int src = 0, dst = 0;
10883   ip4_address_t src_val, dst_val;
10884   int proto = 0;
10885   u32 proto_val;
10886   int tos = 0;
10887   u32 tos_val;
10888   int length = 0;
10889   u32 length_val;
10890   int fragment_id = 0;
10891   u32 fragment_id_val;
10892   int ttl = 0;
10893   int ttl_val;
10894   int checksum = 0;
10895   u32 checksum_val;
10896
10897   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10898     {
10899       if (unformat (input, "version %d", &version_val))
10900         version = 1;
10901       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10902         hdr_length = 1;
10903       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10904         src = 1;
10905       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10906         dst = 1;
10907       else if (unformat (input, "proto %d", &proto_val))
10908         proto = 1;
10909       else if (unformat (input, "tos %d", &tos_val))
10910         tos = 1;
10911       else if (unformat (input, "length %d", &length_val))
10912         length = 1;
10913       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10914         fragment_id = 1;
10915       else if (unformat (input, "ttl %d", &ttl_val))
10916         ttl = 1;
10917       else if (unformat (input, "checksum %d", &checksum_val))
10918         checksum = 1;
10919       else
10920         break;
10921     }
10922
10923   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10924       + ttl + checksum == 0)
10925     return 0;
10926
10927   /*
10928    * Aligned because we use the real comparison functions
10929    */
10930   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10931
10932   ip = (ip4_header_t *) match;
10933
10934   /* These are realistically matched in practice */
10935   if (src)
10936     ip->src_address.as_u32 = src_val.as_u32;
10937
10938   if (dst)
10939     ip->dst_address.as_u32 = dst_val.as_u32;
10940
10941   if (proto)
10942     ip->protocol = proto_val;
10943
10944
10945   /* These are not, but they're included for completeness */
10946   if (version)
10947     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10948
10949   if (hdr_length)
10950     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10951
10952   if (tos)
10953     ip->tos = tos_val;
10954
10955   if (length)
10956     ip->length = clib_host_to_net_u16 (length_val);
10957
10958   if (ttl)
10959     ip->ttl = ttl_val;
10960
10961   if (checksum)
10962     ip->checksum = clib_host_to_net_u16 (checksum_val);
10963
10964   *matchp = match;
10965   return 1;
10966 }
10967
10968 uword
10969 unformat_ip6_match (unformat_input_t * input, va_list * args)
10970 {
10971   u8 **matchp = va_arg (*args, u8 **);
10972   u8 *match = 0;
10973   ip6_header_t *ip;
10974   int version = 0;
10975   u32 version_val;
10976   u8 traffic_class = 0;
10977   u32 traffic_class_val = 0;
10978   u8 flow_label = 0;
10979   u8 flow_label_val;
10980   int src = 0, dst = 0;
10981   ip6_address_t src_val, dst_val;
10982   int proto = 0;
10983   u32 proto_val;
10984   int payload_length = 0;
10985   u32 payload_length_val;
10986   int hop_limit = 0;
10987   int hop_limit_val;
10988   u32 ip_version_traffic_class_and_flow_label;
10989
10990   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10991     {
10992       if (unformat (input, "version %d", &version_val))
10993         version = 1;
10994       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10995         traffic_class = 1;
10996       else if (unformat (input, "flow_label %d", &flow_label_val))
10997         flow_label = 1;
10998       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10999         src = 1;
11000       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11001         dst = 1;
11002       else if (unformat (input, "proto %d", &proto_val))
11003         proto = 1;
11004       else if (unformat (input, "payload_length %d", &payload_length_val))
11005         payload_length = 1;
11006       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11007         hop_limit = 1;
11008       else
11009         break;
11010     }
11011
11012   if (version + traffic_class + flow_label + src + dst + proto +
11013       payload_length + hop_limit == 0)
11014     return 0;
11015
11016   /*
11017    * Aligned because we use the real comparison functions
11018    */
11019   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11020
11021   ip = (ip6_header_t *) match;
11022
11023   if (src)
11024     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11025
11026   if (dst)
11027     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11028
11029   if (proto)
11030     ip->protocol = proto_val;
11031
11032   ip_version_traffic_class_and_flow_label = 0;
11033
11034   if (version)
11035     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11036
11037   if (traffic_class)
11038     ip_version_traffic_class_and_flow_label |=
11039       (traffic_class_val & 0xFF) << 20;
11040
11041   if (flow_label)
11042     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11043
11044   ip->ip_version_traffic_class_and_flow_label =
11045     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11046
11047   if (payload_length)
11048     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11049
11050   if (hop_limit)
11051     ip->hop_limit = hop_limit_val;
11052
11053   *matchp = match;
11054   return 1;
11055 }
11056
11057 uword
11058 unformat_l3_match (unformat_input_t * input, va_list * args)
11059 {
11060   u8 **matchp = va_arg (*args, u8 **);
11061
11062   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11063     {
11064       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11065         return 1;
11066       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11067         return 1;
11068       else
11069         break;
11070     }
11071   return 0;
11072 }
11073
11074 uword
11075 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11076 {
11077   u8 *tagp = va_arg (*args, u8 *);
11078   u32 tag;
11079
11080   if (unformat (input, "%d", &tag))
11081     {
11082       tagp[0] = (tag >> 8) & 0x0F;
11083       tagp[1] = tag & 0xFF;
11084       return 1;
11085     }
11086
11087   return 0;
11088 }
11089
11090 uword
11091 unformat_l2_match (unformat_input_t * input, va_list * args)
11092 {
11093   u8 **matchp = va_arg (*args, u8 **);
11094   u8 *match = 0;
11095   u8 src = 0;
11096   u8 src_val[6];
11097   u8 dst = 0;
11098   u8 dst_val[6];
11099   u8 proto = 0;
11100   u16 proto_val;
11101   u8 tag1 = 0;
11102   u8 tag1_val[2];
11103   u8 tag2 = 0;
11104   u8 tag2_val[2];
11105   int len = 14;
11106   u8 ignore_tag1 = 0;
11107   u8 ignore_tag2 = 0;
11108   u8 cos1 = 0;
11109   u8 cos2 = 0;
11110   u32 cos1_val = 0;
11111   u32 cos2_val = 0;
11112
11113   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11114     {
11115       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11116         src = 1;
11117       else
11118         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11119         dst = 1;
11120       else if (unformat (input, "proto %U",
11121                          unformat_ethernet_type_host_byte_order, &proto_val))
11122         proto = 1;
11123       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11124         tag1 = 1;
11125       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11126         tag2 = 1;
11127       else if (unformat (input, "ignore-tag1"))
11128         ignore_tag1 = 1;
11129       else if (unformat (input, "ignore-tag2"))
11130         ignore_tag2 = 1;
11131       else if (unformat (input, "cos1 %d", &cos1_val))
11132         cos1 = 1;
11133       else if (unformat (input, "cos2 %d", &cos2_val))
11134         cos2 = 1;
11135       else
11136         break;
11137     }
11138   if ((src + dst + proto + tag1 + tag2 +
11139        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11140     return 0;
11141
11142   if (tag1 || ignore_tag1 || cos1)
11143     len = 18;
11144   if (tag2 || ignore_tag2 || cos2)
11145     len = 22;
11146
11147   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11148
11149   if (dst)
11150     clib_memcpy (match, dst_val, 6);
11151
11152   if (src)
11153     clib_memcpy (match + 6, src_val, 6);
11154
11155   if (tag2)
11156     {
11157       /* inner vlan tag */
11158       match[19] = tag2_val[1];
11159       match[18] = tag2_val[0];
11160       if (cos2)
11161         match[18] |= (cos2_val & 0x7) << 5;
11162       if (proto)
11163         {
11164           match[21] = proto_val & 0xff;
11165           match[20] = proto_val >> 8;
11166         }
11167       if (tag1)
11168         {
11169           match[15] = tag1_val[1];
11170           match[14] = tag1_val[0];
11171         }
11172       if (cos1)
11173         match[14] |= (cos1_val & 0x7) << 5;
11174       *matchp = match;
11175       return 1;
11176     }
11177   if (tag1)
11178     {
11179       match[15] = tag1_val[1];
11180       match[14] = tag1_val[0];
11181       if (proto)
11182         {
11183           match[17] = proto_val & 0xff;
11184           match[16] = proto_val >> 8;
11185         }
11186       if (cos1)
11187         match[14] |= (cos1_val & 0x7) << 5;
11188
11189       *matchp = match;
11190       return 1;
11191     }
11192   if (cos2)
11193     match[18] |= (cos2_val & 0x7) << 5;
11194   if (cos1)
11195     match[14] |= (cos1_val & 0x7) << 5;
11196   if (proto)
11197     {
11198       match[13] = proto_val & 0xff;
11199       match[12] = proto_val >> 8;
11200     }
11201
11202   *matchp = match;
11203   return 1;
11204 }
11205 #endif
11206
11207 uword
11208 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11209 {
11210   u8 **matchp = va_arg (*args, u8 **);
11211   u32 skip_n_vectors = va_arg (*args, u32);
11212   u32 match_n_vectors = va_arg (*args, u32);
11213
11214   u8 *match = 0;
11215   u8 *l2 = 0;
11216   u8 *l3 = 0;
11217   u8 *l4 = 0;
11218
11219   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11220     {
11221       if (unformat (input, "hex %U", unformat_hex_string, &match))
11222         ;
11223       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11224         ;
11225       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11226         ;
11227       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11228         ;
11229       else
11230         break;
11231     }
11232
11233   if (l4 && !l3)
11234     {
11235       vec_free (match);
11236       vec_free (l2);
11237       vec_free (l4);
11238       return 0;
11239     }
11240
11241   if (match || l2 || l3 || l4)
11242     {
11243       if (l2 || l3 || l4)
11244         {
11245           /* "Win a free Ethernet header in every packet" */
11246           if (l2 == 0)
11247             vec_validate_aligned (l2, 13, sizeof (u32x4));
11248           match = l2;
11249           if (vec_len (l3))
11250             {
11251               vec_append_aligned (match, l3, sizeof (u32x4));
11252               vec_free (l3);
11253             }
11254           if (vec_len (l4))
11255             {
11256               vec_append_aligned (match, l4, sizeof (u32x4));
11257               vec_free (l4);
11258             }
11259         }
11260
11261       /* Make sure the vector is big enough even if key is all 0's */
11262       vec_validate_aligned
11263         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11264          sizeof (u32x4));
11265
11266       /* Set size, include skipped vectors */
11267       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11268
11269       *matchp = match;
11270
11271       return 1;
11272     }
11273
11274   return 0;
11275 }
11276
11277 static int
11278 api_classify_add_del_session (vat_main_t * vam)
11279 {
11280   unformat_input_t *i = vam->input;
11281   vl_api_classify_add_del_session_t *mp;
11282   int is_add = 1;
11283   u32 table_index = ~0;
11284   u32 hit_next_index = ~0;
11285   u32 opaque_index = ~0;
11286   u8 *match = 0;
11287   i32 advance = 0;
11288   u32 skip_n_vectors = 0;
11289   u32 match_n_vectors = 0;
11290   u32 action = 0;
11291   u32 metadata = 0;
11292   int ret;
11293
11294   /*
11295    * Warning: you have to supply skip_n and match_n
11296    * because the API client cant simply look at the classify
11297    * table object.
11298    */
11299
11300   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11301     {
11302       if (unformat (i, "del"))
11303         is_add = 0;
11304       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11305                          &hit_next_index))
11306         ;
11307       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11308                          &hit_next_index))
11309         ;
11310       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11311                          &hit_next_index))
11312         ;
11313       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11314         ;
11315       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11316         ;
11317       else if (unformat (i, "opaque-index %d", &opaque_index))
11318         ;
11319       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11320         ;
11321       else if (unformat (i, "match_n %d", &match_n_vectors))
11322         ;
11323       else if (unformat (i, "match %U", api_unformat_classify_match,
11324                          &match, skip_n_vectors, match_n_vectors))
11325         ;
11326       else if (unformat (i, "advance %d", &advance))
11327         ;
11328       else if (unformat (i, "table-index %d", &table_index))
11329         ;
11330       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11331         action = 1;
11332       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11333         action = 2;
11334       else if (unformat (i, "action %d", &action))
11335         ;
11336       else if (unformat (i, "metadata %d", &metadata))
11337         ;
11338       else
11339         break;
11340     }
11341
11342   if (table_index == ~0)
11343     {
11344       errmsg ("Table index required");
11345       return -99;
11346     }
11347
11348   if (is_add && match == 0)
11349     {
11350       errmsg ("Match value required");
11351       return -99;
11352     }
11353
11354   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11355
11356   mp->is_add = is_add;
11357   mp->table_index = ntohl (table_index);
11358   mp->hit_next_index = ntohl (hit_next_index);
11359   mp->opaque_index = ntohl (opaque_index);
11360   mp->advance = ntohl (advance);
11361   mp->action = action;
11362   mp->metadata = ntohl (metadata);
11363   clib_memcpy (mp->match, match, vec_len (match));
11364   vec_free (match);
11365
11366   S (mp);
11367   W (ret);
11368   return ret;
11369 }
11370
11371 static int
11372 api_classify_set_interface_ip_table (vat_main_t * vam)
11373 {
11374   unformat_input_t *i = vam->input;
11375   vl_api_classify_set_interface_ip_table_t *mp;
11376   u32 sw_if_index;
11377   int sw_if_index_set;
11378   u32 table_index = ~0;
11379   u8 is_ipv6 = 0;
11380   int ret;
11381
11382   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11383     {
11384       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11385         sw_if_index_set = 1;
11386       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11387         sw_if_index_set = 1;
11388       else if (unformat (i, "table %d", &table_index))
11389         ;
11390       else
11391         {
11392           clib_warning ("parse error '%U'", format_unformat_error, i);
11393           return -99;
11394         }
11395     }
11396
11397   if (sw_if_index_set == 0)
11398     {
11399       errmsg ("missing interface name or sw_if_index");
11400       return -99;
11401     }
11402
11403
11404   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11405
11406   mp->sw_if_index = ntohl (sw_if_index);
11407   mp->table_index = ntohl (table_index);
11408   mp->is_ipv6 = is_ipv6;
11409
11410   S (mp);
11411   W (ret);
11412   return ret;
11413 }
11414
11415 static int
11416 api_classify_set_interface_l2_tables (vat_main_t * vam)
11417 {
11418   unformat_input_t *i = vam->input;
11419   vl_api_classify_set_interface_l2_tables_t *mp;
11420   u32 sw_if_index;
11421   int sw_if_index_set;
11422   u32 ip4_table_index = ~0;
11423   u32 ip6_table_index = ~0;
11424   u32 other_table_index = ~0;
11425   u32 is_input = 1;
11426   int ret;
11427
11428   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11429     {
11430       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11431         sw_if_index_set = 1;
11432       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11433         sw_if_index_set = 1;
11434       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11435         ;
11436       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11437         ;
11438       else if (unformat (i, "other-table %d", &other_table_index))
11439         ;
11440       else if (unformat (i, "is-input %d", &is_input))
11441         ;
11442       else
11443         {
11444           clib_warning ("parse error '%U'", format_unformat_error, i);
11445           return -99;
11446         }
11447     }
11448
11449   if (sw_if_index_set == 0)
11450     {
11451       errmsg ("missing interface name or sw_if_index");
11452       return -99;
11453     }
11454
11455
11456   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11457
11458   mp->sw_if_index = ntohl (sw_if_index);
11459   mp->ip4_table_index = ntohl (ip4_table_index);
11460   mp->ip6_table_index = ntohl (ip6_table_index);
11461   mp->other_table_index = ntohl (other_table_index);
11462   mp->is_input = (u8) is_input;
11463
11464   S (mp);
11465   W (ret);
11466   return ret;
11467 }
11468
11469 static int
11470 api_set_ipfix_exporter (vat_main_t * vam)
11471 {
11472   unformat_input_t *i = vam->input;
11473   vl_api_set_ipfix_exporter_t *mp;
11474   ip4_address_t collector_address;
11475   u8 collector_address_set = 0;
11476   u32 collector_port = ~0;
11477   ip4_address_t src_address;
11478   u8 src_address_set = 0;
11479   u32 vrf_id = ~0;
11480   u32 path_mtu = ~0;
11481   u32 template_interval = ~0;
11482   u8 udp_checksum = 0;
11483   int ret;
11484
11485   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11486     {
11487       if (unformat (i, "collector_address %U", unformat_ip4_address,
11488                     &collector_address))
11489         collector_address_set = 1;
11490       else if (unformat (i, "collector_port %d", &collector_port))
11491         ;
11492       else if (unformat (i, "src_address %U", unformat_ip4_address,
11493                          &src_address))
11494         src_address_set = 1;
11495       else if (unformat (i, "vrf_id %d", &vrf_id))
11496         ;
11497       else if (unformat (i, "path_mtu %d", &path_mtu))
11498         ;
11499       else if (unformat (i, "template_interval %d", &template_interval))
11500         ;
11501       else if (unformat (i, "udp_checksum"))
11502         udp_checksum = 1;
11503       else
11504         break;
11505     }
11506
11507   if (collector_address_set == 0)
11508     {
11509       errmsg ("collector_address required");
11510       return -99;
11511     }
11512
11513   if (src_address_set == 0)
11514     {
11515       errmsg ("src_address required");
11516       return -99;
11517     }
11518
11519   M (SET_IPFIX_EXPORTER, mp);
11520
11521   memcpy (mp->collector_address, collector_address.data,
11522           sizeof (collector_address.data));
11523   mp->collector_port = htons ((u16) collector_port);
11524   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11525   mp->vrf_id = htonl (vrf_id);
11526   mp->path_mtu = htonl (path_mtu);
11527   mp->template_interval = htonl (template_interval);
11528   mp->udp_checksum = udp_checksum;
11529
11530   S (mp);
11531   W (ret);
11532   return ret;
11533 }
11534
11535 static int
11536 api_set_ipfix_classify_stream (vat_main_t * vam)
11537 {
11538   unformat_input_t *i = vam->input;
11539   vl_api_set_ipfix_classify_stream_t *mp;
11540   u32 domain_id = 0;
11541   u32 src_port = UDP_DST_PORT_ipfix;
11542   int ret;
11543
11544   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11545     {
11546       if (unformat (i, "domain %d", &domain_id))
11547         ;
11548       else if (unformat (i, "src_port %d", &src_port))
11549         ;
11550       else
11551         {
11552           errmsg ("unknown input `%U'", format_unformat_error, i);
11553           return -99;
11554         }
11555     }
11556
11557   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11558
11559   mp->domain_id = htonl (domain_id);
11560   mp->src_port = htons ((u16) src_port);
11561
11562   S (mp);
11563   W (ret);
11564   return ret;
11565 }
11566
11567 static int
11568 api_ipfix_classify_table_add_del (vat_main_t * vam)
11569 {
11570   unformat_input_t *i = vam->input;
11571   vl_api_ipfix_classify_table_add_del_t *mp;
11572   int is_add = -1;
11573   u32 classify_table_index = ~0;
11574   u8 ip_version = 0;
11575   u8 transport_protocol = 255;
11576   int ret;
11577
11578   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11579     {
11580       if (unformat (i, "add"))
11581         is_add = 1;
11582       else if (unformat (i, "del"))
11583         is_add = 0;
11584       else if (unformat (i, "table %d", &classify_table_index))
11585         ;
11586       else if (unformat (i, "ip4"))
11587         ip_version = 4;
11588       else if (unformat (i, "ip6"))
11589         ip_version = 6;
11590       else if (unformat (i, "tcp"))
11591         transport_protocol = 6;
11592       else if (unformat (i, "udp"))
11593         transport_protocol = 17;
11594       else
11595         {
11596           errmsg ("unknown input `%U'", format_unformat_error, i);
11597           return -99;
11598         }
11599     }
11600
11601   if (is_add == -1)
11602     {
11603       errmsg ("expecting: add|del");
11604       return -99;
11605     }
11606   if (classify_table_index == ~0)
11607     {
11608       errmsg ("classifier table not specified");
11609       return -99;
11610     }
11611   if (ip_version == 0)
11612     {
11613       errmsg ("IP version not specified");
11614       return -99;
11615     }
11616
11617   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11618
11619   mp->is_add = is_add;
11620   mp->table_id = htonl (classify_table_index);
11621   mp->ip_version = ip_version;
11622   mp->transport_protocol = transport_protocol;
11623
11624   S (mp);
11625   W (ret);
11626   return ret;
11627 }
11628
11629 static int
11630 api_get_node_index (vat_main_t * vam)
11631 {
11632   unformat_input_t *i = vam->input;
11633   vl_api_get_node_index_t *mp;
11634   u8 *name = 0;
11635   int ret;
11636
11637   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11638     {
11639       if (unformat (i, "node %s", &name))
11640         ;
11641       else
11642         break;
11643     }
11644   if (name == 0)
11645     {
11646       errmsg ("node name required");
11647       return -99;
11648     }
11649   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11650     {
11651       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11652       return -99;
11653     }
11654
11655   M (GET_NODE_INDEX, mp);
11656   clib_memcpy (mp->node_name, name, vec_len (name));
11657   vec_free (name);
11658
11659   S (mp);
11660   W (ret);
11661   return ret;
11662 }
11663
11664 static int
11665 api_get_next_index (vat_main_t * vam)
11666 {
11667   unformat_input_t *i = vam->input;
11668   vl_api_get_next_index_t *mp;
11669   u8 *node_name = 0, *next_node_name = 0;
11670   int ret;
11671
11672   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11673     {
11674       if (unformat (i, "node-name %s", &node_name))
11675         ;
11676       else if (unformat (i, "next-node-name %s", &next_node_name))
11677         break;
11678     }
11679
11680   if (node_name == 0)
11681     {
11682       errmsg ("node name required");
11683       return -99;
11684     }
11685   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11686     {
11687       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11688       return -99;
11689     }
11690
11691   if (next_node_name == 0)
11692     {
11693       errmsg ("next node name required");
11694       return -99;
11695     }
11696   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11697     {
11698       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11699       return -99;
11700     }
11701
11702   M (GET_NEXT_INDEX, mp);
11703   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11704   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11705   vec_free (node_name);
11706   vec_free (next_node_name);
11707
11708   S (mp);
11709   W (ret);
11710   return ret;
11711 }
11712
11713 static int
11714 api_add_node_next (vat_main_t * vam)
11715 {
11716   unformat_input_t *i = vam->input;
11717   vl_api_add_node_next_t *mp;
11718   u8 *name = 0;
11719   u8 *next = 0;
11720   int ret;
11721
11722   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11723     {
11724       if (unformat (i, "node %s", &name))
11725         ;
11726       else if (unformat (i, "next %s", &next))
11727         ;
11728       else
11729         break;
11730     }
11731   if (name == 0)
11732     {
11733       errmsg ("node name required");
11734       return -99;
11735     }
11736   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11737     {
11738       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11739       return -99;
11740     }
11741   if (next == 0)
11742     {
11743       errmsg ("next node required");
11744       return -99;
11745     }
11746   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11747     {
11748       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11749       return -99;
11750     }
11751
11752   M (ADD_NODE_NEXT, mp);
11753   clib_memcpy (mp->node_name, name, vec_len (name));
11754   clib_memcpy (mp->next_name, next, vec_len (next));
11755   vec_free (name);
11756   vec_free (next);
11757
11758   S (mp);
11759   W (ret);
11760   return ret;
11761 }
11762
11763 static int
11764 api_l2tpv3_create_tunnel (vat_main_t * vam)
11765 {
11766   unformat_input_t *i = vam->input;
11767   ip6_address_t client_address, our_address;
11768   int client_address_set = 0;
11769   int our_address_set = 0;
11770   u32 local_session_id = 0;
11771   u32 remote_session_id = 0;
11772   u64 local_cookie = 0;
11773   u64 remote_cookie = 0;
11774   u8 l2_sublayer_present = 0;
11775   vl_api_l2tpv3_create_tunnel_t *mp;
11776   int ret;
11777
11778   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11779     {
11780       if (unformat (i, "client_address %U", unformat_ip6_address,
11781                     &client_address))
11782         client_address_set = 1;
11783       else if (unformat (i, "our_address %U", unformat_ip6_address,
11784                          &our_address))
11785         our_address_set = 1;
11786       else if (unformat (i, "local_session_id %d", &local_session_id))
11787         ;
11788       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11789         ;
11790       else if (unformat (i, "local_cookie %lld", &local_cookie))
11791         ;
11792       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11793         ;
11794       else if (unformat (i, "l2-sublayer-present"))
11795         l2_sublayer_present = 1;
11796       else
11797         break;
11798     }
11799
11800   if (client_address_set == 0)
11801     {
11802       errmsg ("client_address required");
11803       return -99;
11804     }
11805
11806   if (our_address_set == 0)
11807     {
11808       errmsg ("our_address required");
11809       return -99;
11810     }
11811
11812   M (L2TPV3_CREATE_TUNNEL, mp);
11813
11814   clib_memcpy (mp->client_address, client_address.as_u8,
11815                sizeof (mp->client_address));
11816
11817   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11818
11819   mp->local_session_id = ntohl (local_session_id);
11820   mp->remote_session_id = ntohl (remote_session_id);
11821   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11822   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11823   mp->l2_sublayer_present = l2_sublayer_present;
11824   mp->is_ipv6 = 1;
11825
11826   S (mp);
11827   W (ret);
11828   return ret;
11829 }
11830
11831 static int
11832 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11833 {
11834   unformat_input_t *i = vam->input;
11835   u32 sw_if_index;
11836   u8 sw_if_index_set = 0;
11837   u64 new_local_cookie = 0;
11838   u64 new_remote_cookie = 0;
11839   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11840   int ret;
11841
11842   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11843     {
11844       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11845         sw_if_index_set = 1;
11846       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11847         sw_if_index_set = 1;
11848       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11849         ;
11850       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11851         ;
11852       else
11853         break;
11854     }
11855
11856   if (sw_if_index_set == 0)
11857     {
11858       errmsg ("missing interface name or sw_if_index");
11859       return -99;
11860     }
11861
11862   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11863
11864   mp->sw_if_index = ntohl (sw_if_index);
11865   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11866   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11867
11868   S (mp);
11869   W (ret);
11870   return ret;
11871 }
11872
11873 static int
11874 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11875 {
11876   unformat_input_t *i = vam->input;
11877   vl_api_l2tpv3_interface_enable_disable_t *mp;
11878   u32 sw_if_index;
11879   u8 sw_if_index_set = 0;
11880   u8 enable_disable = 1;
11881   int ret;
11882
11883   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11884     {
11885       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11886         sw_if_index_set = 1;
11887       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11888         sw_if_index_set = 1;
11889       else if (unformat (i, "enable"))
11890         enable_disable = 1;
11891       else if (unformat (i, "disable"))
11892         enable_disable = 0;
11893       else
11894         break;
11895     }
11896
11897   if (sw_if_index_set == 0)
11898     {
11899       errmsg ("missing interface name or sw_if_index");
11900       return -99;
11901     }
11902
11903   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11904
11905   mp->sw_if_index = ntohl (sw_if_index);
11906   mp->enable_disable = enable_disable;
11907
11908   S (mp);
11909   W (ret);
11910   return ret;
11911 }
11912
11913 static int
11914 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11915 {
11916   unformat_input_t *i = vam->input;
11917   vl_api_l2tpv3_set_lookup_key_t *mp;
11918   u8 key = ~0;
11919   int ret;
11920
11921   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11922     {
11923       if (unformat (i, "lookup_v6_src"))
11924         key = L2T_LOOKUP_SRC_ADDRESS;
11925       else if (unformat (i, "lookup_v6_dst"))
11926         key = L2T_LOOKUP_DST_ADDRESS;
11927       else if (unformat (i, "lookup_session_id"))
11928         key = L2T_LOOKUP_SESSION_ID;
11929       else
11930         break;
11931     }
11932
11933   if (key == (u8) ~ 0)
11934     {
11935       errmsg ("l2tp session lookup key unset");
11936       return -99;
11937     }
11938
11939   M (L2TPV3_SET_LOOKUP_KEY, mp);
11940
11941   mp->key = key;
11942
11943   S (mp);
11944   W (ret);
11945   return ret;
11946 }
11947
11948 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11949   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11950 {
11951   vat_main_t *vam = &vat_main;
11952
11953   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11954          format_ip6_address, mp->our_address,
11955          format_ip6_address, mp->client_address,
11956          clib_net_to_host_u32 (mp->sw_if_index));
11957
11958   print (vam->ofp,
11959          "   local cookies %016llx %016llx remote cookie %016llx",
11960          clib_net_to_host_u64 (mp->local_cookie[0]),
11961          clib_net_to_host_u64 (mp->local_cookie[1]),
11962          clib_net_to_host_u64 (mp->remote_cookie));
11963
11964   print (vam->ofp, "   local session-id %d remote session-id %d",
11965          clib_net_to_host_u32 (mp->local_session_id),
11966          clib_net_to_host_u32 (mp->remote_session_id));
11967
11968   print (vam->ofp, "   l2 specific sublayer %s\n",
11969          mp->l2_sublayer_present ? "preset" : "absent");
11970
11971 }
11972
11973 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11974   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11975 {
11976   vat_main_t *vam = &vat_main;
11977   vat_json_node_t *node = NULL;
11978   struct in6_addr addr;
11979
11980   if (VAT_JSON_ARRAY != vam->json_tree.type)
11981     {
11982       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11983       vat_json_init_array (&vam->json_tree);
11984     }
11985   node = vat_json_array_add (&vam->json_tree);
11986
11987   vat_json_init_object (node);
11988
11989   clib_memcpy (&addr, mp->our_address, sizeof (addr));
11990   vat_json_object_add_ip6 (node, "our_address", addr);
11991   clib_memcpy (&addr, mp->client_address, sizeof (addr));
11992   vat_json_object_add_ip6 (node, "client_address", addr);
11993
11994   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11995   vat_json_init_array (lc);
11996   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11997   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11998   vat_json_object_add_uint (node, "remote_cookie",
11999                             clib_net_to_host_u64 (mp->remote_cookie));
12000
12001   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12002   vat_json_object_add_uint (node, "local_session_id",
12003                             clib_net_to_host_u32 (mp->local_session_id));
12004   vat_json_object_add_uint (node, "remote_session_id",
12005                             clib_net_to_host_u32 (mp->remote_session_id));
12006   vat_json_object_add_string_copy (node, "l2_sublayer",
12007                                    mp->l2_sublayer_present ? (u8 *) "present"
12008                                    : (u8 *) "absent");
12009 }
12010
12011 static int
12012 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12013 {
12014   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12015   vl_api_control_ping_t *mp_ping;
12016   int ret;
12017
12018   /* Get list of l2tpv3-tunnel interfaces */
12019   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12020   S (mp);
12021
12022   /* Use a control ping for synchronization */
12023   MPING (CONTROL_PING, mp_ping);
12024   S (mp_ping);
12025
12026   W (ret);
12027   return ret;
12028 }
12029
12030
12031 static void vl_api_sw_interface_tap_details_t_handler
12032   (vl_api_sw_interface_tap_details_t * mp)
12033 {
12034   vat_main_t *vam = &vat_main;
12035
12036   print (vam->ofp, "%-16s %d",
12037          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12038 }
12039
12040 static void vl_api_sw_interface_tap_details_t_handler_json
12041   (vl_api_sw_interface_tap_details_t * mp)
12042 {
12043   vat_main_t *vam = &vat_main;
12044   vat_json_node_t *node = NULL;
12045
12046   if (VAT_JSON_ARRAY != vam->json_tree.type)
12047     {
12048       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12049       vat_json_init_array (&vam->json_tree);
12050     }
12051   node = vat_json_array_add (&vam->json_tree);
12052
12053   vat_json_init_object (node);
12054   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12055   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12056 }
12057
12058 static int
12059 api_sw_interface_tap_dump (vat_main_t * vam)
12060 {
12061   vl_api_sw_interface_tap_dump_t *mp;
12062   vl_api_control_ping_t *mp_ping;
12063   int ret;
12064
12065   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12066   /* Get list of tap interfaces */
12067   M (SW_INTERFACE_TAP_DUMP, mp);
12068   S (mp);
12069
12070   /* Use a control ping for synchronization */
12071   MPING (CONTROL_PING, mp_ping);
12072   S (mp_ping);
12073
12074   W (ret);
12075   return ret;
12076 }
12077
12078 static uword unformat_vxlan_decap_next
12079   (unformat_input_t * input, va_list * args)
12080 {
12081   u32 *result = va_arg (*args, u32 *);
12082   u32 tmp;
12083
12084   if (unformat (input, "l2"))
12085     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12086   else if (unformat (input, "%d", &tmp))
12087     *result = tmp;
12088   else
12089     return 0;
12090   return 1;
12091 }
12092
12093 static int
12094 api_vxlan_add_del_tunnel (vat_main_t * vam)
12095 {
12096   unformat_input_t *line_input = vam->input;
12097   vl_api_vxlan_add_del_tunnel_t *mp;
12098   ip46_address_t src, dst;
12099   u8 is_add = 1;
12100   u8 ipv4_set = 0, ipv6_set = 0;
12101   u8 src_set = 0;
12102   u8 dst_set = 0;
12103   u8 grp_set = 0;
12104   u32 mcast_sw_if_index = ~0;
12105   u32 encap_vrf_id = 0;
12106   u32 decap_next_index = ~0;
12107   u32 vni = 0;
12108   int ret;
12109
12110   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12111   memset (&src, 0, sizeof src);
12112   memset (&dst, 0, sizeof dst);
12113
12114   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12115     {
12116       if (unformat (line_input, "del"))
12117         is_add = 0;
12118       else
12119         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12120         {
12121           ipv4_set = 1;
12122           src_set = 1;
12123         }
12124       else
12125         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12126         {
12127           ipv4_set = 1;
12128           dst_set = 1;
12129         }
12130       else
12131         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12132         {
12133           ipv6_set = 1;
12134           src_set = 1;
12135         }
12136       else
12137         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12138         {
12139           ipv6_set = 1;
12140           dst_set = 1;
12141         }
12142       else if (unformat (line_input, "group %U %U",
12143                          unformat_ip4_address, &dst.ip4,
12144                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12145         {
12146           grp_set = dst_set = 1;
12147           ipv4_set = 1;
12148         }
12149       else if (unformat (line_input, "group %U",
12150                          unformat_ip4_address, &dst.ip4))
12151         {
12152           grp_set = dst_set = 1;
12153           ipv4_set = 1;
12154         }
12155       else if (unformat (line_input, "group %U %U",
12156                          unformat_ip6_address, &dst.ip6,
12157                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12158         {
12159           grp_set = dst_set = 1;
12160           ipv6_set = 1;
12161         }
12162       else if (unformat (line_input, "group %U",
12163                          unformat_ip6_address, &dst.ip6))
12164         {
12165           grp_set = dst_set = 1;
12166           ipv6_set = 1;
12167         }
12168       else
12169         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12170         ;
12171       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12172         ;
12173       else if (unformat (line_input, "decap-next %U",
12174                          unformat_vxlan_decap_next, &decap_next_index))
12175         ;
12176       else if (unformat (line_input, "vni %d", &vni))
12177         ;
12178       else
12179         {
12180           errmsg ("parse error '%U'", format_unformat_error, line_input);
12181           return -99;
12182         }
12183     }
12184
12185   if (src_set == 0)
12186     {
12187       errmsg ("tunnel src address not specified");
12188       return -99;
12189     }
12190   if (dst_set == 0)
12191     {
12192       errmsg ("tunnel dst address not specified");
12193       return -99;
12194     }
12195
12196   if (grp_set && !ip46_address_is_multicast (&dst))
12197     {
12198       errmsg ("tunnel group address not multicast");
12199       return -99;
12200     }
12201   if (grp_set && mcast_sw_if_index == ~0)
12202     {
12203       errmsg ("tunnel nonexistent multicast device");
12204       return -99;
12205     }
12206   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12207     {
12208       errmsg ("tunnel dst address must be unicast");
12209       return -99;
12210     }
12211
12212
12213   if (ipv4_set && ipv6_set)
12214     {
12215       errmsg ("both IPv4 and IPv6 addresses specified");
12216       return -99;
12217     }
12218
12219   if ((vni == 0) || (vni >> 24))
12220     {
12221       errmsg ("vni not specified or out of range");
12222       return -99;
12223     }
12224
12225   M (VXLAN_ADD_DEL_TUNNEL, mp);
12226
12227   if (ipv6_set)
12228     {
12229       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12230       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12231     }
12232   else
12233     {
12234       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12235       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12236     }
12237   mp->encap_vrf_id = ntohl (encap_vrf_id);
12238   mp->decap_next_index = ntohl (decap_next_index);
12239   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12240   mp->vni = ntohl (vni);
12241   mp->is_add = is_add;
12242   mp->is_ipv6 = ipv6_set;
12243
12244   S (mp);
12245   W (ret);
12246   return ret;
12247 }
12248
12249 static void vl_api_vxlan_tunnel_details_t_handler
12250   (vl_api_vxlan_tunnel_details_t * mp)
12251 {
12252   vat_main_t *vam = &vat_main;
12253   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12254   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12255
12256   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12257          ntohl (mp->sw_if_index),
12258          format_ip46_address, &src, IP46_TYPE_ANY,
12259          format_ip46_address, &dst, IP46_TYPE_ANY,
12260          ntohl (mp->encap_vrf_id),
12261          ntohl (mp->decap_next_index), ntohl (mp->vni),
12262          ntohl (mp->mcast_sw_if_index));
12263 }
12264
12265 static void vl_api_vxlan_tunnel_details_t_handler_json
12266   (vl_api_vxlan_tunnel_details_t * mp)
12267 {
12268   vat_main_t *vam = &vat_main;
12269   vat_json_node_t *node = NULL;
12270
12271   if (VAT_JSON_ARRAY != vam->json_tree.type)
12272     {
12273       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12274       vat_json_init_array (&vam->json_tree);
12275     }
12276   node = vat_json_array_add (&vam->json_tree);
12277
12278   vat_json_init_object (node);
12279   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12280   if (mp->is_ipv6)
12281     {
12282       struct in6_addr ip6;
12283
12284       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12285       vat_json_object_add_ip6 (node, "src_address", ip6);
12286       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12287       vat_json_object_add_ip6 (node, "dst_address", ip6);
12288     }
12289   else
12290     {
12291       struct in_addr ip4;
12292
12293       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12294       vat_json_object_add_ip4 (node, "src_address", ip4);
12295       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12296       vat_json_object_add_ip4 (node, "dst_address", ip4);
12297     }
12298   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12299   vat_json_object_add_uint (node, "decap_next_index",
12300                             ntohl (mp->decap_next_index));
12301   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12302   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12303   vat_json_object_add_uint (node, "mcast_sw_if_index",
12304                             ntohl (mp->mcast_sw_if_index));
12305 }
12306
12307 static int
12308 api_vxlan_tunnel_dump (vat_main_t * vam)
12309 {
12310   unformat_input_t *i = vam->input;
12311   vl_api_vxlan_tunnel_dump_t *mp;
12312   vl_api_control_ping_t *mp_ping;
12313   u32 sw_if_index;
12314   u8 sw_if_index_set = 0;
12315   int ret;
12316
12317   /* Parse args required to build the message */
12318   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12319     {
12320       if (unformat (i, "sw_if_index %d", &sw_if_index))
12321         sw_if_index_set = 1;
12322       else
12323         break;
12324     }
12325
12326   if (sw_if_index_set == 0)
12327     {
12328       sw_if_index = ~0;
12329     }
12330
12331   if (!vam->json_output)
12332     {
12333       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12334              "sw_if_index", "src_address", "dst_address",
12335              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12336     }
12337
12338   /* Get list of vxlan-tunnel interfaces */
12339   M (VXLAN_TUNNEL_DUMP, mp);
12340
12341   mp->sw_if_index = htonl (sw_if_index);
12342
12343   S (mp);
12344
12345   /* Use a control ping for synchronization */
12346   MPING (CONTROL_PING, mp_ping);
12347   S (mp_ping);
12348
12349   W (ret);
12350   return ret;
12351 }
12352
12353 static uword unformat_geneve_decap_next
12354   (unformat_input_t * input, va_list * args)
12355 {
12356   u32 *result = va_arg (*args, u32 *);
12357   u32 tmp;
12358
12359   if (unformat (input, "l2"))
12360     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12361   else if (unformat (input, "%d", &tmp))
12362     *result = tmp;
12363   else
12364     return 0;
12365   return 1;
12366 }
12367
12368 static int
12369 api_geneve_add_del_tunnel (vat_main_t * vam)
12370 {
12371   unformat_input_t *line_input = vam->input;
12372   vl_api_geneve_add_del_tunnel_t *mp;
12373   ip46_address_t src, dst;
12374   u8 is_add = 1;
12375   u8 ipv4_set = 0, ipv6_set = 0;
12376   u8 src_set = 0;
12377   u8 dst_set = 0;
12378   u8 grp_set = 0;
12379   u32 mcast_sw_if_index = ~0;
12380   u32 encap_vrf_id = 0;
12381   u32 decap_next_index = ~0;
12382   u32 vni = 0;
12383   int ret;
12384
12385   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12386   memset (&src, 0, sizeof src);
12387   memset (&dst, 0, sizeof dst);
12388
12389   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12390     {
12391       if (unformat (line_input, "del"))
12392         is_add = 0;
12393       else
12394         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12395         {
12396           ipv4_set = 1;
12397           src_set = 1;
12398         }
12399       else
12400         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12401         {
12402           ipv4_set = 1;
12403           dst_set = 1;
12404         }
12405       else
12406         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12407         {
12408           ipv6_set = 1;
12409           src_set = 1;
12410         }
12411       else
12412         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12413         {
12414           ipv6_set = 1;
12415           dst_set = 1;
12416         }
12417       else if (unformat (line_input, "group %U %U",
12418                          unformat_ip4_address, &dst.ip4,
12419                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12420         {
12421           grp_set = dst_set = 1;
12422           ipv4_set = 1;
12423         }
12424       else if (unformat (line_input, "group %U",
12425                          unformat_ip4_address, &dst.ip4))
12426         {
12427           grp_set = dst_set = 1;
12428           ipv4_set = 1;
12429         }
12430       else if (unformat (line_input, "group %U %U",
12431                          unformat_ip6_address, &dst.ip6,
12432                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12433         {
12434           grp_set = dst_set = 1;
12435           ipv6_set = 1;
12436         }
12437       else if (unformat (line_input, "group %U",
12438                          unformat_ip6_address, &dst.ip6))
12439         {
12440           grp_set = dst_set = 1;
12441           ipv6_set = 1;
12442         }
12443       else
12444         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12445         ;
12446       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12447         ;
12448       else if (unformat (line_input, "decap-next %U",
12449                          unformat_geneve_decap_next, &decap_next_index))
12450         ;
12451       else if (unformat (line_input, "vni %d", &vni))
12452         ;
12453       else
12454         {
12455           errmsg ("parse error '%U'", format_unformat_error, line_input);
12456           return -99;
12457         }
12458     }
12459
12460   if (src_set == 0)
12461     {
12462       errmsg ("tunnel src address not specified");
12463       return -99;
12464     }
12465   if (dst_set == 0)
12466     {
12467       errmsg ("tunnel dst address not specified");
12468       return -99;
12469     }
12470
12471   if (grp_set && !ip46_address_is_multicast (&dst))
12472     {
12473       errmsg ("tunnel group address not multicast");
12474       return -99;
12475     }
12476   if (grp_set && mcast_sw_if_index == ~0)
12477     {
12478       errmsg ("tunnel nonexistent multicast device");
12479       return -99;
12480     }
12481   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12482     {
12483       errmsg ("tunnel dst address must be unicast");
12484       return -99;
12485     }
12486
12487
12488   if (ipv4_set && ipv6_set)
12489     {
12490       errmsg ("both IPv4 and IPv6 addresses specified");
12491       return -99;
12492     }
12493
12494   if ((vni == 0) || (vni >> 24))
12495     {
12496       errmsg ("vni not specified or out of range");
12497       return -99;
12498     }
12499
12500   M (GENEVE_ADD_DEL_TUNNEL, mp);
12501
12502   if (ipv6_set)
12503     {
12504       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12505       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12506     }
12507   else
12508     {
12509       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12510       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12511     }
12512   mp->encap_vrf_id = ntohl (encap_vrf_id);
12513   mp->decap_next_index = ntohl (decap_next_index);
12514   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12515   mp->vni = ntohl (vni);
12516   mp->is_add = is_add;
12517   mp->is_ipv6 = ipv6_set;
12518
12519   S (mp);
12520   W (ret);
12521   return ret;
12522 }
12523
12524 static void vl_api_geneve_tunnel_details_t_handler
12525   (vl_api_geneve_tunnel_details_t * mp)
12526 {
12527   vat_main_t *vam = &vat_main;
12528   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12529   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12530
12531   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12532          ntohl (mp->sw_if_index),
12533          format_ip46_address, &src, IP46_TYPE_ANY,
12534          format_ip46_address, &dst, IP46_TYPE_ANY,
12535          ntohl (mp->encap_vrf_id),
12536          ntohl (mp->decap_next_index), ntohl (mp->vni),
12537          ntohl (mp->mcast_sw_if_index));
12538 }
12539
12540 static void vl_api_geneve_tunnel_details_t_handler_json
12541   (vl_api_geneve_tunnel_details_t * mp)
12542 {
12543   vat_main_t *vam = &vat_main;
12544   vat_json_node_t *node = NULL;
12545
12546   if (VAT_JSON_ARRAY != vam->json_tree.type)
12547     {
12548       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12549       vat_json_init_array (&vam->json_tree);
12550     }
12551   node = vat_json_array_add (&vam->json_tree);
12552
12553   vat_json_init_object (node);
12554   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12555   if (mp->is_ipv6)
12556     {
12557       struct in6_addr ip6;
12558
12559       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12560       vat_json_object_add_ip6 (node, "src_address", ip6);
12561       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12562       vat_json_object_add_ip6 (node, "dst_address", ip6);
12563     }
12564   else
12565     {
12566       struct in_addr ip4;
12567
12568       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12569       vat_json_object_add_ip4 (node, "src_address", ip4);
12570       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12571       vat_json_object_add_ip4 (node, "dst_address", ip4);
12572     }
12573   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12574   vat_json_object_add_uint (node, "decap_next_index",
12575                             ntohl (mp->decap_next_index));
12576   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12577   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12578   vat_json_object_add_uint (node, "mcast_sw_if_index",
12579                             ntohl (mp->mcast_sw_if_index));
12580 }
12581
12582 static int
12583 api_geneve_tunnel_dump (vat_main_t * vam)
12584 {
12585   unformat_input_t *i = vam->input;
12586   vl_api_geneve_tunnel_dump_t *mp;
12587   vl_api_control_ping_t *mp_ping;
12588   u32 sw_if_index;
12589   u8 sw_if_index_set = 0;
12590   int ret;
12591
12592   /* Parse args required to build the message */
12593   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12594     {
12595       if (unformat (i, "sw_if_index %d", &sw_if_index))
12596         sw_if_index_set = 1;
12597       else
12598         break;
12599     }
12600
12601   if (sw_if_index_set == 0)
12602     {
12603       sw_if_index = ~0;
12604     }
12605
12606   if (!vam->json_output)
12607     {
12608       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12609              "sw_if_index", "local_address", "remote_address",
12610              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12611     }
12612
12613   /* Get list of geneve-tunnel interfaces */
12614   M (GENEVE_TUNNEL_DUMP, mp);
12615
12616   mp->sw_if_index = htonl (sw_if_index);
12617
12618   S (mp);
12619
12620   /* Use a control ping for synchronization */
12621   M (CONTROL_PING, mp_ping);
12622   S (mp_ping);
12623
12624   W (ret);
12625   return ret;
12626 }
12627
12628 static int
12629 api_gre_add_del_tunnel (vat_main_t * vam)
12630 {
12631   unformat_input_t *line_input = vam->input;
12632   vl_api_gre_add_del_tunnel_t *mp;
12633   ip4_address_t src4, dst4;
12634   ip6_address_t src6, dst6;
12635   u8 is_add = 1;
12636   u8 ipv4_set = 0;
12637   u8 ipv6_set = 0;
12638   u8 teb = 0;
12639   u8 src_set = 0;
12640   u8 dst_set = 0;
12641   u32 outer_fib_id = 0;
12642   int ret;
12643
12644   memset (&src4, 0, sizeof src4);
12645   memset (&dst4, 0, sizeof dst4);
12646   memset (&src6, 0, sizeof src6);
12647   memset (&dst6, 0, sizeof dst6);
12648
12649   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12650     {
12651       if (unformat (line_input, "del"))
12652         is_add = 0;
12653       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
12654         {
12655           src_set = 1;
12656           ipv4_set = 1;
12657         }
12658       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
12659         {
12660           dst_set = 1;
12661           ipv4_set = 1;
12662         }
12663       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
12664         {
12665           src_set = 1;
12666           ipv6_set = 1;
12667         }
12668       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
12669         {
12670           dst_set = 1;
12671           ipv6_set = 1;
12672         }
12673       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
12674         ;
12675       else if (unformat (line_input, "teb"))
12676         teb = 1;
12677       else
12678         {
12679           errmsg ("parse error '%U'", format_unformat_error, line_input);
12680           return -99;
12681         }
12682     }
12683
12684   if (src_set == 0)
12685     {
12686       errmsg ("tunnel src address not specified");
12687       return -99;
12688     }
12689   if (dst_set == 0)
12690     {
12691       errmsg ("tunnel dst address not specified");
12692       return -99;
12693     }
12694   if (ipv4_set && ipv6_set)
12695     {
12696       errmsg ("both IPv4 and IPv6 addresses specified");
12697       return -99;
12698     }
12699
12700
12701   M (GRE_ADD_DEL_TUNNEL, mp);
12702
12703   if (ipv4_set)
12704     {
12705       clib_memcpy (&mp->src_address, &src4, 4);
12706       clib_memcpy (&mp->dst_address, &dst4, 4);
12707     }
12708   else
12709     {
12710       clib_memcpy (&mp->src_address, &src6, 16);
12711       clib_memcpy (&mp->dst_address, &dst6, 16);
12712     }
12713   mp->outer_fib_id = ntohl (outer_fib_id);
12714   mp->is_add = is_add;
12715   mp->teb = teb;
12716   mp->is_ipv6 = ipv6_set;
12717
12718   S (mp);
12719   W (ret);
12720   return ret;
12721 }
12722
12723 static void vl_api_gre_tunnel_details_t_handler
12724   (vl_api_gre_tunnel_details_t * mp)
12725 {
12726   vat_main_t *vam = &vat_main;
12727   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
12728   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
12729
12730   print (vam->ofp, "%11d%24U%24U%6d%14d",
12731          ntohl (mp->sw_if_index),
12732          format_ip46_address, &src, IP46_TYPE_ANY,
12733          format_ip46_address, &dst, IP46_TYPE_ANY,
12734          mp->teb, ntohl (mp->outer_fib_id));
12735 }
12736
12737 static void vl_api_gre_tunnel_details_t_handler_json
12738   (vl_api_gre_tunnel_details_t * mp)
12739 {
12740   vat_main_t *vam = &vat_main;
12741   vat_json_node_t *node = NULL;
12742   struct in_addr ip4;
12743   struct in6_addr ip6;
12744
12745   if (VAT_JSON_ARRAY != vam->json_tree.type)
12746     {
12747       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12748       vat_json_init_array (&vam->json_tree);
12749     }
12750   node = vat_json_array_add (&vam->json_tree);
12751
12752   vat_json_init_object (node);
12753   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12754   if (!mp->is_ipv6)
12755     {
12756       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
12757       vat_json_object_add_ip4 (node, "src_address", ip4);
12758       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
12759       vat_json_object_add_ip4 (node, "dst_address", ip4);
12760     }
12761   else
12762     {
12763       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
12764       vat_json_object_add_ip6 (node, "src_address", ip6);
12765       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
12766       vat_json_object_add_ip6 (node, "dst_address", ip6);
12767     }
12768   vat_json_object_add_uint (node, "teb", mp->teb);
12769   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
12770   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
12771 }
12772
12773 static int
12774 api_gre_tunnel_dump (vat_main_t * vam)
12775 {
12776   unformat_input_t *i = vam->input;
12777   vl_api_gre_tunnel_dump_t *mp;
12778   vl_api_control_ping_t *mp_ping;
12779   u32 sw_if_index;
12780   u8 sw_if_index_set = 0;
12781   int ret;
12782
12783   /* Parse args required to build the message */
12784   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12785     {
12786       if (unformat (i, "sw_if_index %d", &sw_if_index))
12787         sw_if_index_set = 1;
12788       else
12789         break;
12790     }
12791
12792   if (sw_if_index_set == 0)
12793     {
12794       sw_if_index = ~0;
12795     }
12796
12797   if (!vam->json_output)
12798     {
12799       print (vam->ofp, "%11s%24s%24s%6s%14s",
12800              "sw_if_index", "src_address", "dst_address", "teb",
12801              "outer_fib_id");
12802     }
12803
12804   /* Get list of gre-tunnel interfaces */
12805   M (GRE_TUNNEL_DUMP, mp);
12806
12807   mp->sw_if_index = htonl (sw_if_index);
12808
12809   S (mp);
12810
12811   /* Use a control ping for synchronization */
12812   MPING (CONTROL_PING, mp_ping);
12813   S (mp_ping);
12814
12815   W (ret);
12816   return ret;
12817 }
12818
12819 static int
12820 api_l2_fib_clear_table (vat_main_t * vam)
12821 {
12822 //  unformat_input_t * i = vam->input;
12823   vl_api_l2_fib_clear_table_t *mp;
12824   int ret;
12825
12826   M (L2_FIB_CLEAR_TABLE, mp);
12827
12828   S (mp);
12829   W (ret);
12830   return ret;
12831 }
12832
12833 static int
12834 api_l2_interface_efp_filter (vat_main_t * vam)
12835 {
12836   unformat_input_t *i = vam->input;
12837   vl_api_l2_interface_efp_filter_t *mp;
12838   u32 sw_if_index;
12839   u8 enable = 1;
12840   u8 sw_if_index_set = 0;
12841   int ret;
12842
12843   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12844     {
12845       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12846         sw_if_index_set = 1;
12847       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12848         sw_if_index_set = 1;
12849       else if (unformat (i, "enable"))
12850         enable = 1;
12851       else if (unformat (i, "disable"))
12852         enable = 0;
12853       else
12854         {
12855           clib_warning ("parse error '%U'", format_unformat_error, i);
12856           return -99;
12857         }
12858     }
12859
12860   if (sw_if_index_set == 0)
12861     {
12862       errmsg ("missing sw_if_index");
12863       return -99;
12864     }
12865
12866   M (L2_INTERFACE_EFP_FILTER, mp);
12867
12868   mp->sw_if_index = ntohl (sw_if_index);
12869   mp->enable_disable = enable;
12870
12871   S (mp);
12872   W (ret);
12873   return ret;
12874 }
12875
12876 #define foreach_vtr_op                          \
12877 _("disable",  L2_VTR_DISABLED)                  \
12878 _("push-1",  L2_VTR_PUSH_1)                     \
12879 _("push-2",  L2_VTR_PUSH_2)                     \
12880 _("pop-1",  L2_VTR_POP_1)                       \
12881 _("pop-2",  L2_VTR_POP_2)                       \
12882 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12883 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12884 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12885 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12886
12887 static int
12888 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12889 {
12890   unformat_input_t *i = vam->input;
12891   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12892   u32 sw_if_index;
12893   u8 sw_if_index_set = 0;
12894   u8 vtr_op_set = 0;
12895   u32 vtr_op = 0;
12896   u32 push_dot1q = 1;
12897   u32 tag1 = ~0;
12898   u32 tag2 = ~0;
12899   int ret;
12900
12901   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12902     {
12903       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12904         sw_if_index_set = 1;
12905       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12906         sw_if_index_set = 1;
12907       else if (unformat (i, "vtr_op %d", &vtr_op))
12908         vtr_op_set = 1;
12909 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12910       foreach_vtr_op
12911 #undef _
12912         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12913         ;
12914       else if (unformat (i, "tag1 %d", &tag1))
12915         ;
12916       else if (unformat (i, "tag2 %d", &tag2))
12917         ;
12918       else
12919         {
12920           clib_warning ("parse error '%U'", format_unformat_error, i);
12921           return -99;
12922         }
12923     }
12924
12925   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12926     {
12927       errmsg ("missing vtr operation or sw_if_index");
12928       return -99;
12929     }
12930
12931   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12932   mp->sw_if_index = ntohl (sw_if_index);
12933   mp->vtr_op = ntohl (vtr_op);
12934   mp->push_dot1q = ntohl (push_dot1q);
12935   mp->tag1 = ntohl (tag1);
12936   mp->tag2 = ntohl (tag2);
12937
12938   S (mp);
12939   W (ret);
12940   return ret;
12941 }
12942
12943 static int
12944 api_create_vhost_user_if (vat_main_t * vam)
12945 {
12946   unformat_input_t *i = vam->input;
12947   vl_api_create_vhost_user_if_t *mp;
12948   u8 *file_name;
12949   u8 is_server = 0;
12950   u8 file_name_set = 0;
12951   u32 custom_dev_instance = ~0;
12952   u8 hwaddr[6];
12953   u8 use_custom_mac = 0;
12954   u8 *tag = 0;
12955   int ret;
12956
12957   /* Shut up coverity */
12958   memset (hwaddr, 0, sizeof (hwaddr));
12959
12960   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12961     {
12962       if (unformat (i, "socket %s", &file_name))
12963         {
12964           file_name_set = 1;
12965         }
12966       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12967         ;
12968       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12969         use_custom_mac = 1;
12970       else if (unformat (i, "server"))
12971         is_server = 1;
12972       else if (unformat (i, "tag %s", &tag))
12973         ;
12974       else
12975         break;
12976     }
12977
12978   if (file_name_set == 0)
12979     {
12980       errmsg ("missing socket file name");
12981       return -99;
12982     }
12983
12984   if (vec_len (file_name) > 255)
12985     {
12986       errmsg ("socket file name too long");
12987       return -99;
12988     }
12989   vec_add1 (file_name, 0);
12990
12991   M (CREATE_VHOST_USER_IF, mp);
12992
12993   mp->is_server = is_server;
12994   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12995   vec_free (file_name);
12996   if (custom_dev_instance != ~0)
12997     {
12998       mp->renumber = 1;
12999       mp->custom_dev_instance = ntohl (custom_dev_instance);
13000     }
13001   mp->use_custom_mac = use_custom_mac;
13002   clib_memcpy (mp->mac_address, hwaddr, 6);
13003   if (tag)
13004     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13005   vec_free (tag);
13006
13007   S (mp);
13008   W (ret);
13009   return ret;
13010 }
13011
13012 static int
13013 api_modify_vhost_user_if (vat_main_t * vam)
13014 {
13015   unformat_input_t *i = vam->input;
13016   vl_api_modify_vhost_user_if_t *mp;
13017   u8 *file_name;
13018   u8 is_server = 0;
13019   u8 file_name_set = 0;
13020   u32 custom_dev_instance = ~0;
13021   u8 sw_if_index_set = 0;
13022   u32 sw_if_index = (u32) ~ 0;
13023   int ret;
13024
13025   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13026     {
13027       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13028         sw_if_index_set = 1;
13029       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13030         sw_if_index_set = 1;
13031       else if (unformat (i, "socket %s", &file_name))
13032         {
13033           file_name_set = 1;
13034         }
13035       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13036         ;
13037       else if (unformat (i, "server"))
13038         is_server = 1;
13039       else
13040         break;
13041     }
13042
13043   if (sw_if_index_set == 0)
13044     {
13045       errmsg ("missing sw_if_index or interface name");
13046       return -99;
13047     }
13048
13049   if (file_name_set == 0)
13050     {
13051       errmsg ("missing socket file name");
13052       return -99;
13053     }
13054
13055   if (vec_len (file_name) > 255)
13056     {
13057       errmsg ("socket file name too long");
13058       return -99;
13059     }
13060   vec_add1 (file_name, 0);
13061
13062   M (MODIFY_VHOST_USER_IF, mp);
13063
13064   mp->sw_if_index = ntohl (sw_if_index);
13065   mp->is_server = is_server;
13066   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13067   vec_free (file_name);
13068   if (custom_dev_instance != ~0)
13069     {
13070       mp->renumber = 1;
13071       mp->custom_dev_instance = ntohl (custom_dev_instance);
13072     }
13073
13074   S (mp);
13075   W (ret);
13076   return ret;
13077 }
13078
13079 static int
13080 api_delete_vhost_user_if (vat_main_t * vam)
13081 {
13082   unformat_input_t *i = vam->input;
13083   vl_api_delete_vhost_user_if_t *mp;
13084   u32 sw_if_index = ~0;
13085   u8 sw_if_index_set = 0;
13086   int ret;
13087
13088   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13089     {
13090       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13091         sw_if_index_set = 1;
13092       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13093         sw_if_index_set = 1;
13094       else
13095         break;
13096     }
13097
13098   if (sw_if_index_set == 0)
13099     {
13100       errmsg ("missing sw_if_index or interface name");
13101       return -99;
13102     }
13103
13104
13105   M (DELETE_VHOST_USER_IF, mp);
13106
13107   mp->sw_if_index = ntohl (sw_if_index);
13108
13109   S (mp);
13110   W (ret);
13111   return ret;
13112 }
13113
13114 static void vl_api_sw_interface_vhost_user_details_t_handler
13115   (vl_api_sw_interface_vhost_user_details_t * mp)
13116 {
13117   vat_main_t *vam = &vat_main;
13118
13119   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13120          (char *) mp->interface_name,
13121          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13122          clib_net_to_host_u64 (mp->features), mp->is_server,
13123          ntohl (mp->num_regions), (char *) mp->sock_filename);
13124   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13125 }
13126
13127 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13128   (vl_api_sw_interface_vhost_user_details_t * mp)
13129 {
13130   vat_main_t *vam = &vat_main;
13131   vat_json_node_t *node = NULL;
13132
13133   if (VAT_JSON_ARRAY != vam->json_tree.type)
13134     {
13135       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13136       vat_json_init_array (&vam->json_tree);
13137     }
13138   node = vat_json_array_add (&vam->json_tree);
13139
13140   vat_json_init_object (node);
13141   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13142   vat_json_object_add_string_copy (node, "interface_name",
13143                                    mp->interface_name);
13144   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13145                             ntohl (mp->virtio_net_hdr_sz));
13146   vat_json_object_add_uint (node, "features",
13147                             clib_net_to_host_u64 (mp->features));
13148   vat_json_object_add_uint (node, "is_server", mp->is_server);
13149   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13150   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13151   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13152 }
13153
13154 static int
13155 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13156 {
13157   vl_api_sw_interface_vhost_user_dump_t *mp;
13158   vl_api_control_ping_t *mp_ping;
13159   int ret;
13160   print (vam->ofp,
13161          "Interface name            idx hdr_sz features server regions filename");
13162
13163   /* Get list of vhost-user interfaces */
13164   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13165   S (mp);
13166
13167   /* Use a control ping for synchronization */
13168   MPING (CONTROL_PING, mp_ping);
13169   S (mp_ping);
13170
13171   W (ret);
13172   return ret;
13173 }
13174
13175 static int
13176 api_show_version (vat_main_t * vam)
13177 {
13178   vl_api_show_version_t *mp;
13179   int ret;
13180
13181   M (SHOW_VERSION, mp);
13182
13183   S (mp);
13184   W (ret);
13185   return ret;
13186 }
13187
13188
13189 static int
13190 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13191 {
13192   unformat_input_t *line_input = vam->input;
13193   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13194   ip4_address_t local4, remote4;
13195   ip6_address_t local6, remote6;
13196   u8 is_add = 1;
13197   u8 ipv4_set = 0, ipv6_set = 0;
13198   u8 local_set = 0;
13199   u8 remote_set = 0;
13200   u8 grp_set = 0;
13201   u32 mcast_sw_if_index = ~0;
13202   u32 encap_vrf_id = 0;
13203   u32 decap_vrf_id = 0;
13204   u8 protocol = ~0;
13205   u32 vni;
13206   u8 vni_set = 0;
13207   int ret;
13208
13209   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13210   memset (&local4, 0, sizeof local4);
13211   memset (&remote4, 0, sizeof remote4);
13212   memset (&local6, 0, sizeof local6);
13213   memset (&remote6, 0, sizeof remote6);
13214
13215   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13216     {
13217       if (unformat (line_input, "del"))
13218         is_add = 0;
13219       else if (unformat (line_input, "local %U",
13220                          unformat_ip4_address, &local4))
13221         {
13222           local_set = 1;
13223           ipv4_set = 1;
13224         }
13225       else if (unformat (line_input, "remote %U",
13226                          unformat_ip4_address, &remote4))
13227         {
13228           remote_set = 1;
13229           ipv4_set = 1;
13230         }
13231       else if (unformat (line_input, "local %U",
13232                          unformat_ip6_address, &local6))
13233         {
13234           local_set = 1;
13235           ipv6_set = 1;
13236         }
13237       else if (unformat (line_input, "remote %U",
13238                          unformat_ip6_address, &remote6))
13239         {
13240           remote_set = 1;
13241           ipv6_set = 1;
13242         }
13243       else if (unformat (line_input, "group %U %U",
13244                          unformat_ip4_address, &remote4,
13245                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13246         {
13247           grp_set = remote_set = 1;
13248           ipv4_set = 1;
13249         }
13250       else if (unformat (line_input, "group %U",
13251                          unformat_ip4_address, &remote4))
13252         {
13253           grp_set = remote_set = 1;
13254           ipv4_set = 1;
13255         }
13256       else if (unformat (line_input, "group %U %U",
13257                          unformat_ip6_address, &remote6,
13258                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13259         {
13260           grp_set = remote_set = 1;
13261           ipv6_set = 1;
13262         }
13263       else if (unformat (line_input, "group %U",
13264                          unformat_ip6_address, &remote6))
13265         {
13266           grp_set = remote_set = 1;
13267           ipv6_set = 1;
13268         }
13269       else
13270         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13271         ;
13272       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13273         ;
13274       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13275         ;
13276       else if (unformat (line_input, "vni %d", &vni))
13277         vni_set = 1;
13278       else if (unformat (line_input, "next-ip4"))
13279         protocol = 1;
13280       else if (unformat (line_input, "next-ip6"))
13281         protocol = 2;
13282       else if (unformat (line_input, "next-ethernet"))
13283         protocol = 3;
13284       else if (unformat (line_input, "next-nsh"))
13285         protocol = 4;
13286       else
13287         {
13288           errmsg ("parse error '%U'", format_unformat_error, line_input);
13289           return -99;
13290         }
13291     }
13292
13293   if (local_set == 0)
13294     {
13295       errmsg ("tunnel local address not specified");
13296       return -99;
13297     }
13298   if (remote_set == 0)
13299     {
13300       errmsg ("tunnel remote address not specified");
13301       return -99;
13302     }
13303   if (grp_set && mcast_sw_if_index == ~0)
13304     {
13305       errmsg ("tunnel nonexistent multicast device");
13306       return -99;
13307     }
13308   if (ipv4_set && ipv6_set)
13309     {
13310       errmsg ("both IPv4 and IPv6 addresses specified");
13311       return -99;
13312     }
13313
13314   if (vni_set == 0)
13315     {
13316       errmsg ("vni not specified");
13317       return -99;
13318     }
13319
13320   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13321
13322
13323   if (ipv6_set)
13324     {
13325       clib_memcpy (&mp->local, &local6, sizeof (local6));
13326       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13327     }
13328   else
13329     {
13330       clib_memcpy (&mp->local, &local4, sizeof (local4));
13331       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13332     }
13333
13334   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13335   mp->encap_vrf_id = ntohl (encap_vrf_id);
13336   mp->decap_vrf_id = ntohl (decap_vrf_id);
13337   mp->protocol = protocol;
13338   mp->vni = ntohl (vni);
13339   mp->is_add = is_add;
13340   mp->is_ipv6 = ipv6_set;
13341
13342   S (mp);
13343   W (ret);
13344   return ret;
13345 }
13346
13347 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13348   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13349 {
13350   vat_main_t *vam = &vat_main;
13351   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13352   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13353
13354   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13355          ntohl (mp->sw_if_index),
13356          format_ip46_address, &local, IP46_TYPE_ANY,
13357          format_ip46_address, &remote, IP46_TYPE_ANY,
13358          ntohl (mp->vni), mp->protocol,
13359          ntohl (mp->mcast_sw_if_index),
13360          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13361 }
13362
13363
13364 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13365   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13366 {
13367   vat_main_t *vam = &vat_main;
13368   vat_json_node_t *node = NULL;
13369   struct in_addr ip4;
13370   struct in6_addr ip6;
13371
13372   if (VAT_JSON_ARRAY != vam->json_tree.type)
13373     {
13374       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13375       vat_json_init_array (&vam->json_tree);
13376     }
13377   node = vat_json_array_add (&vam->json_tree);
13378
13379   vat_json_init_object (node);
13380   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13381   if (mp->is_ipv6)
13382     {
13383       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13384       vat_json_object_add_ip6 (node, "local", ip6);
13385       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13386       vat_json_object_add_ip6 (node, "remote", ip6);
13387     }
13388   else
13389     {
13390       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13391       vat_json_object_add_ip4 (node, "local", ip4);
13392       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13393       vat_json_object_add_ip4 (node, "remote", ip4);
13394     }
13395   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13396   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13397   vat_json_object_add_uint (node, "mcast_sw_if_index",
13398                             ntohl (mp->mcast_sw_if_index));
13399   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13400   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13401   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13402 }
13403
13404 static int
13405 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13406 {
13407   unformat_input_t *i = vam->input;
13408   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13409   vl_api_control_ping_t *mp_ping;
13410   u32 sw_if_index;
13411   u8 sw_if_index_set = 0;
13412   int ret;
13413
13414   /* Parse args required to build the message */
13415   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13416     {
13417       if (unformat (i, "sw_if_index %d", &sw_if_index))
13418         sw_if_index_set = 1;
13419       else
13420         break;
13421     }
13422
13423   if (sw_if_index_set == 0)
13424     {
13425       sw_if_index = ~0;
13426     }
13427
13428   if (!vam->json_output)
13429     {
13430       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13431              "sw_if_index", "local", "remote", "vni",
13432              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13433     }
13434
13435   /* Get list of vxlan-tunnel interfaces */
13436   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13437
13438   mp->sw_if_index = htonl (sw_if_index);
13439
13440   S (mp);
13441
13442   /* Use a control ping for synchronization */
13443   MPING (CONTROL_PING, mp_ping);
13444   S (mp_ping);
13445
13446   W (ret);
13447   return ret;
13448 }
13449
13450 static void vl_api_l2_fib_table_details_t_handler
13451   (vl_api_l2_fib_table_details_t * mp)
13452 {
13453   vat_main_t *vam = &vat_main;
13454
13455   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13456          "       %d       %d     %d",
13457          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13458          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13459          mp->bvi_mac);
13460 }
13461
13462 static void vl_api_l2_fib_table_details_t_handler_json
13463   (vl_api_l2_fib_table_details_t * mp)
13464 {
13465   vat_main_t *vam = &vat_main;
13466   vat_json_node_t *node = NULL;
13467
13468   if (VAT_JSON_ARRAY != vam->json_tree.type)
13469     {
13470       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13471       vat_json_init_array (&vam->json_tree);
13472     }
13473   node = vat_json_array_add (&vam->json_tree);
13474
13475   vat_json_init_object (node);
13476   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13477   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13478   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13479   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13480   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13481   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13482 }
13483
13484 static int
13485 api_l2_fib_table_dump (vat_main_t * vam)
13486 {
13487   unformat_input_t *i = vam->input;
13488   vl_api_l2_fib_table_dump_t *mp;
13489   vl_api_control_ping_t *mp_ping;
13490   u32 bd_id;
13491   u8 bd_id_set = 0;
13492   int ret;
13493
13494   /* Parse args required to build the message */
13495   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13496     {
13497       if (unformat (i, "bd_id %d", &bd_id))
13498         bd_id_set = 1;
13499       else
13500         break;
13501     }
13502
13503   if (bd_id_set == 0)
13504     {
13505       errmsg ("missing bridge domain");
13506       return -99;
13507     }
13508
13509   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13510
13511   /* Get list of l2 fib entries */
13512   M (L2_FIB_TABLE_DUMP, mp);
13513
13514   mp->bd_id = ntohl (bd_id);
13515   S (mp);
13516
13517   /* Use a control ping for synchronization */
13518   MPING (CONTROL_PING, mp_ping);
13519   S (mp_ping);
13520
13521   W (ret);
13522   return ret;
13523 }
13524
13525
13526 static int
13527 api_interface_name_renumber (vat_main_t * vam)
13528 {
13529   unformat_input_t *line_input = vam->input;
13530   vl_api_interface_name_renumber_t *mp;
13531   u32 sw_if_index = ~0;
13532   u32 new_show_dev_instance = ~0;
13533   int ret;
13534
13535   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13536     {
13537       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13538                     &sw_if_index))
13539         ;
13540       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13541         ;
13542       else if (unformat (line_input, "new_show_dev_instance %d",
13543                          &new_show_dev_instance))
13544         ;
13545       else
13546         break;
13547     }
13548
13549   if (sw_if_index == ~0)
13550     {
13551       errmsg ("missing interface name or sw_if_index");
13552       return -99;
13553     }
13554
13555   if (new_show_dev_instance == ~0)
13556     {
13557       errmsg ("missing new_show_dev_instance");
13558       return -99;
13559     }
13560
13561   M (INTERFACE_NAME_RENUMBER, mp);
13562
13563   mp->sw_if_index = ntohl (sw_if_index);
13564   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13565
13566   S (mp);
13567   W (ret);
13568   return ret;
13569 }
13570
13571 static int
13572 api_want_ip4_arp_events (vat_main_t * vam)
13573 {
13574   unformat_input_t *line_input = vam->input;
13575   vl_api_want_ip4_arp_events_t *mp;
13576   ip4_address_t address;
13577   int address_set = 0;
13578   u32 enable_disable = 1;
13579   int ret;
13580
13581   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13582     {
13583       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
13584         address_set = 1;
13585       else if (unformat (line_input, "del"))
13586         enable_disable = 0;
13587       else
13588         break;
13589     }
13590
13591   if (address_set == 0)
13592     {
13593       errmsg ("missing addresses");
13594       return -99;
13595     }
13596
13597   M (WANT_IP4_ARP_EVENTS, mp);
13598   mp->enable_disable = enable_disable;
13599   mp->pid = htonl (getpid ());
13600   mp->address = address.as_u32;
13601
13602   S (mp);
13603   W (ret);
13604   return ret;
13605 }
13606
13607 static int
13608 api_want_ip6_nd_events (vat_main_t * vam)
13609 {
13610   unformat_input_t *line_input = vam->input;
13611   vl_api_want_ip6_nd_events_t *mp;
13612   ip6_address_t address;
13613   int address_set = 0;
13614   u32 enable_disable = 1;
13615   int ret;
13616
13617   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13618     {
13619       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
13620         address_set = 1;
13621       else if (unformat (line_input, "del"))
13622         enable_disable = 0;
13623       else
13624         break;
13625     }
13626
13627   if (address_set == 0)
13628     {
13629       errmsg ("missing addresses");
13630       return -99;
13631     }
13632
13633   M (WANT_IP6_ND_EVENTS, mp);
13634   mp->enable_disable = enable_disable;
13635   mp->pid = htonl (getpid ());
13636   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
13637
13638   S (mp);
13639   W (ret);
13640   return ret;
13641 }
13642
13643 static int
13644 api_want_l2_macs_events (vat_main_t * vam)
13645 {
13646   unformat_input_t *line_input = vam->input;
13647   vl_api_want_l2_macs_events_t *mp;
13648   u8 enable_disable = 1;
13649   u32 scan_delay = 0;
13650   u32 max_macs_in_event = 0;
13651   u32 learn_limit = 0;
13652   int ret;
13653
13654   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13655     {
13656       if (unformat (line_input, "learn-limit %d", &learn_limit))
13657         ;
13658       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13659         ;
13660       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13661         ;
13662       else if (unformat (line_input, "disable"))
13663         enable_disable = 0;
13664       else
13665         break;
13666     }
13667
13668   M (WANT_L2_MACS_EVENTS, mp);
13669   mp->enable_disable = enable_disable;
13670   mp->pid = htonl (getpid ());
13671   mp->learn_limit = htonl (learn_limit);
13672   mp->scan_delay = (u8) scan_delay;
13673   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13674   S (mp);
13675   W (ret);
13676   return ret;
13677 }
13678
13679 static int
13680 api_input_acl_set_interface (vat_main_t * vam)
13681 {
13682   unformat_input_t *i = vam->input;
13683   vl_api_input_acl_set_interface_t *mp;
13684   u32 sw_if_index;
13685   int sw_if_index_set;
13686   u32 ip4_table_index = ~0;
13687   u32 ip6_table_index = ~0;
13688   u32 l2_table_index = ~0;
13689   u8 is_add = 1;
13690   int ret;
13691
13692   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13693     {
13694       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13695         sw_if_index_set = 1;
13696       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13697         sw_if_index_set = 1;
13698       else if (unformat (i, "del"))
13699         is_add = 0;
13700       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13701         ;
13702       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13703         ;
13704       else if (unformat (i, "l2-table %d", &l2_table_index))
13705         ;
13706       else
13707         {
13708           clib_warning ("parse error '%U'", format_unformat_error, i);
13709           return -99;
13710         }
13711     }
13712
13713   if (sw_if_index_set == 0)
13714     {
13715       errmsg ("missing interface name or sw_if_index");
13716       return -99;
13717     }
13718
13719   M (INPUT_ACL_SET_INTERFACE, mp);
13720
13721   mp->sw_if_index = ntohl (sw_if_index);
13722   mp->ip4_table_index = ntohl (ip4_table_index);
13723   mp->ip6_table_index = ntohl (ip6_table_index);
13724   mp->l2_table_index = ntohl (l2_table_index);
13725   mp->is_add = is_add;
13726
13727   S (mp);
13728   W (ret);
13729   return ret;
13730 }
13731
13732 static int
13733 api_ip_address_dump (vat_main_t * vam)
13734 {
13735   unformat_input_t *i = vam->input;
13736   vl_api_ip_address_dump_t *mp;
13737   vl_api_control_ping_t *mp_ping;
13738   u32 sw_if_index = ~0;
13739   u8 sw_if_index_set = 0;
13740   u8 ipv4_set = 0;
13741   u8 ipv6_set = 0;
13742   int ret;
13743
13744   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13745     {
13746       if (unformat (i, "sw_if_index %d", &sw_if_index))
13747         sw_if_index_set = 1;
13748       else
13749         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13750         sw_if_index_set = 1;
13751       else if (unformat (i, "ipv4"))
13752         ipv4_set = 1;
13753       else if (unformat (i, "ipv6"))
13754         ipv6_set = 1;
13755       else
13756         break;
13757     }
13758
13759   if (ipv4_set && ipv6_set)
13760     {
13761       errmsg ("ipv4 and ipv6 flags cannot be both set");
13762       return -99;
13763     }
13764
13765   if ((!ipv4_set) && (!ipv6_set))
13766     {
13767       errmsg ("no ipv4 nor ipv6 flag set");
13768       return -99;
13769     }
13770
13771   if (sw_if_index_set == 0)
13772     {
13773       errmsg ("missing interface name or sw_if_index");
13774       return -99;
13775     }
13776
13777   vam->current_sw_if_index = sw_if_index;
13778   vam->is_ipv6 = ipv6_set;
13779
13780   M (IP_ADDRESS_DUMP, mp);
13781   mp->sw_if_index = ntohl (sw_if_index);
13782   mp->is_ipv6 = ipv6_set;
13783   S (mp);
13784
13785   /* Use a control ping for synchronization */
13786   MPING (CONTROL_PING, mp_ping);
13787   S (mp_ping);
13788
13789   W (ret);
13790   return ret;
13791 }
13792
13793 static int
13794 api_ip_dump (vat_main_t * vam)
13795 {
13796   vl_api_ip_dump_t *mp;
13797   vl_api_control_ping_t *mp_ping;
13798   unformat_input_t *in = vam->input;
13799   int ipv4_set = 0;
13800   int ipv6_set = 0;
13801   int is_ipv6;
13802   int i;
13803   int ret;
13804
13805   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13806     {
13807       if (unformat (in, "ipv4"))
13808         ipv4_set = 1;
13809       else if (unformat (in, "ipv6"))
13810         ipv6_set = 1;
13811       else
13812         break;
13813     }
13814
13815   if (ipv4_set && ipv6_set)
13816     {
13817       errmsg ("ipv4 and ipv6 flags cannot be both set");
13818       return -99;
13819     }
13820
13821   if ((!ipv4_set) && (!ipv6_set))
13822     {
13823       errmsg ("no ipv4 nor ipv6 flag set");
13824       return -99;
13825     }
13826
13827   is_ipv6 = ipv6_set;
13828   vam->is_ipv6 = is_ipv6;
13829
13830   /* free old data */
13831   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13832     {
13833       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13834     }
13835   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13836
13837   M (IP_DUMP, mp);
13838   mp->is_ipv6 = ipv6_set;
13839   S (mp);
13840
13841   /* Use a control ping for synchronization */
13842   MPING (CONTROL_PING, mp_ping);
13843   S (mp_ping);
13844
13845   W (ret);
13846   return ret;
13847 }
13848
13849 static int
13850 api_ipsec_spd_add_del (vat_main_t * vam)
13851 {
13852   unformat_input_t *i = vam->input;
13853   vl_api_ipsec_spd_add_del_t *mp;
13854   u32 spd_id = ~0;
13855   u8 is_add = 1;
13856   int ret;
13857
13858   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13859     {
13860       if (unformat (i, "spd_id %d", &spd_id))
13861         ;
13862       else if (unformat (i, "del"))
13863         is_add = 0;
13864       else
13865         {
13866           clib_warning ("parse error '%U'", format_unformat_error, i);
13867           return -99;
13868         }
13869     }
13870   if (spd_id == ~0)
13871     {
13872       errmsg ("spd_id must be set");
13873       return -99;
13874     }
13875
13876   M (IPSEC_SPD_ADD_DEL, mp);
13877
13878   mp->spd_id = ntohl (spd_id);
13879   mp->is_add = is_add;
13880
13881   S (mp);
13882   W (ret);
13883   return ret;
13884 }
13885
13886 static int
13887 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13888 {
13889   unformat_input_t *i = vam->input;
13890   vl_api_ipsec_interface_add_del_spd_t *mp;
13891   u32 sw_if_index;
13892   u8 sw_if_index_set = 0;
13893   u32 spd_id = (u32) ~ 0;
13894   u8 is_add = 1;
13895   int ret;
13896
13897   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13898     {
13899       if (unformat (i, "del"))
13900         is_add = 0;
13901       else if (unformat (i, "spd_id %d", &spd_id))
13902         ;
13903       else
13904         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13905         sw_if_index_set = 1;
13906       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13907         sw_if_index_set = 1;
13908       else
13909         {
13910           clib_warning ("parse error '%U'", format_unformat_error, i);
13911           return -99;
13912         }
13913
13914     }
13915
13916   if (spd_id == (u32) ~ 0)
13917     {
13918       errmsg ("spd_id must be set");
13919       return -99;
13920     }
13921
13922   if (sw_if_index_set == 0)
13923     {
13924       errmsg ("missing interface name or sw_if_index");
13925       return -99;
13926     }
13927
13928   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13929
13930   mp->spd_id = ntohl (spd_id);
13931   mp->sw_if_index = ntohl (sw_if_index);
13932   mp->is_add = is_add;
13933
13934   S (mp);
13935   W (ret);
13936   return ret;
13937 }
13938
13939 static int
13940 api_ipsec_spd_add_del_entry (vat_main_t * vam)
13941 {
13942   unformat_input_t *i = vam->input;
13943   vl_api_ipsec_spd_add_del_entry_t *mp;
13944   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
13945   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13946   i32 priority = 0;
13947   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13948   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13949   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
13950   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
13951   int ret;
13952
13953   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
13954   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
13955   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
13956   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
13957   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
13958   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
13959
13960   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13961     {
13962       if (unformat (i, "del"))
13963         is_add = 0;
13964       if (unformat (i, "outbound"))
13965         is_outbound = 1;
13966       if (unformat (i, "inbound"))
13967         is_outbound = 0;
13968       else if (unformat (i, "spd_id %d", &spd_id))
13969         ;
13970       else if (unformat (i, "sa_id %d", &sa_id))
13971         ;
13972       else if (unformat (i, "priority %d", &priority))
13973         ;
13974       else if (unformat (i, "protocol %d", &protocol))
13975         ;
13976       else if (unformat (i, "lport_start %d", &lport_start))
13977         ;
13978       else if (unformat (i, "lport_stop %d", &lport_stop))
13979         ;
13980       else if (unformat (i, "rport_start %d", &rport_start))
13981         ;
13982       else if (unformat (i, "rport_stop %d", &rport_stop))
13983         ;
13984       else
13985         if (unformat
13986             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
13987         {
13988           is_ipv6 = 0;
13989           is_ip_any = 0;
13990         }
13991       else
13992         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
13993         {
13994           is_ipv6 = 0;
13995           is_ip_any = 0;
13996         }
13997       else
13998         if (unformat
13999             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
14000         {
14001           is_ipv6 = 0;
14002           is_ip_any = 0;
14003         }
14004       else
14005         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
14006         {
14007           is_ipv6 = 0;
14008           is_ip_any = 0;
14009         }
14010       else
14011         if (unformat
14012             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
14013         {
14014           is_ipv6 = 1;
14015           is_ip_any = 0;
14016         }
14017       else
14018         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
14019         {
14020           is_ipv6 = 1;
14021           is_ip_any = 0;
14022         }
14023       else
14024         if (unformat
14025             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
14026         {
14027           is_ipv6 = 1;
14028           is_ip_any = 0;
14029         }
14030       else
14031         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
14032         {
14033           is_ipv6 = 1;
14034           is_ip_any = 0;
14035         }
14036       else
14037         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14038         {
14039           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14040             {
14041               clib_warning ("unsupported action: 'resolve'");
14042               return -99;
14043             }
14044         }
14045       else
14046         {
14047           clib_warning ("parse error '%U'", format_unformat_error, i);
14048           return -99;
14049         }
14050
14051     }
14052
14053   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
14054
14055   mp->spd_id = ntohl (spd_id);
14056   mp->priority = ntohl (priority);
14057   mp->is_outbound = is_outbound;
14058
14059   mp->is_ipv6 = is_ipv6;
14060   if (is_ipv6 || is_ip_any)
14061     {
14062       clib_memcpy (mp->remote_address_start, &raddr6_start,
14063                    sizeof (ip6_address_t));
14064       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
14065                    sizeof (ip6_address_t));
14066       clib_memcpy (mp->local_address_start, &laddr6_start,
14067                    sizeof (ip6_address_t));
14068       clib_memcpy (mp->local_address_stop, &laddr6_stop,
14069                    sizeof (ip6_address_t));
14070     }
14071   else
14072     {
14073       clib_memcpy (mp->remote_address_start, &raddr4_start,
14074                    sizeof (ip4_address_t));
14075       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
14076                    sizeof (ip4_address_t));
14077       clib_memcpy (mp->local_address_start, &laddr4_start,
14078                    sizeof (ip4_address_t));
14079       clib_memcpy (mp->local_address_stop, &laddr4_stop,
14080                    sizeof (ip4_address_t));
14081     }
14082   mp->protocol = (u8) protocol;
14083   mp->local_port_start = ntohs ((u16) lport_start);
14084   mp->local_port_stop = ntohs ((u16) lport_stop);
14085   mp->remote_port_start = ntohs ((u16) rport_start);
14086   mp->remote_port_stop = ntohs ((u16) rport_stop);
14087   mp->policy = (u8) policy;
14088   mp->sa_id = ntohl (sa_id);
14089   mp->is_add = is_add;
14090   mp->is_ip_any = is_ip_any;
14091   S (mp);
14092   W (ret);
14093   return ret;
14094 }
14095
14096 static int
14097 api_ipsec_sad_add_del_entry (vat_main_t * vam)
14098 {
14099   unformat_input_t *i = vam->input;
14100   vl_api_ipsec_sad_add_del_entry_t *mp;
14101   u32 sad_id = 0, spi = 0;
14102   u8 *ck = 0, *ik = 0;
14103   u8 is_add = 1;
14104
14105   u8 protocol = IPSEC_PROTOCOL_AH;
14106   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
14107   u32 crypto_alg = 0, integ_alg = 0;
14108   ip4_address_t tun_src4;
14109   ip4_address_t tun_dst4;
14110   ip6_address_t tun_src6;
14111   ip6_address_t tun_dst6;
14112   int ret;
14113
14114   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14115     {
14116       if (unformat (i, "del"))
14117         is_add = 0;
14118       else if (unformat (i, "sad_id %d", &sad_id))
14119         ;
14120       else if (unformat (i, "spi %d", &spi))
14121         ;
14122       else if (unformat (i, "esp"))
14123         protocol = IPSEC_PROTOCOL_ESP;
14124       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
14125         {
14126           is_tunnel = 1;
14127           is_tunnel_ipv6 = 0;
14128         }
14129       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
14130         {
14131           is_tunnel = 1;
14132           is_tunnel_ipv6 = 0;
14133         }
14134       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
14135         {
14136           is_tunnel = 1;
14137           is_tunnel_ipv6 = 1;
14138         }
14139       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
14140         {
14141           is_tunnel = 1;
14142           is_tunnel_ipv6 = 1;
14143         }
14144       else
14145         if (unformat
14146             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14147         {
14148           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14149               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14150             {
14151               clib_warning ("unsupported crypto-alg: '%U'",
14152                             format_ipsec_crypto_alg, crypto_alg);
14153               return -99;
14154             }
14155         }
14156       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14157         ;
14158       else
14159         if (unformat
14160             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14161         {
14162           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14163               integ_alg >= IPSEC_INTEG_N_ALG)
14164             {
14165               clib_warning ("unsupported integ-alg: '%U'",
14166                             format_ipsec_integ_alg, integ_alg);
14167               return -99;
14168             }
14169         }
14170       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14171         ;
14172       else
14173         {
14174           clib_warning ("parse error '%U'", format_unformat_error, i);
14175           return -99;
14176         }
14177
14178     }
14179
14180   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
14181
14182   mp->sad_id = ntohl (sad_id);
14183   mp->is_add = is_add;
14184   mp->protocol = protocol;
14185   mp->spi = ntohl (spi);
14186   mp->is_tunnel = is_tunnel;
14187   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
14188   mp->crypto_algorithm = crypto_alg;
14189   mp->integrity_algorithm = integ_alg;
14190   mp->crypto_key_length = vec_len (ck);
14191   mp->integrity_key_length = vec_len (ik);
14192
14193   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14194     mp->crypto_key_length = sizeof (mp->crypto_key);
14195
14196   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14197     mp->integrity_key_length = sizeof (mp->integrity_key);
14198
14199   if (ck)
14200     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14201   if (ik)
14202     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14203
14204   if (is_tunnel)
14205     {
14206       if (is_tunnel_ipv6)
14207         {
14208           clib_memcpy (mp->tunnel_src_address, &tun_src6,
14209                        sizeof (ip6_address_t));
14210           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
14211                        sizeof (ip6_address_t));
14212         }
14213       else
14214         {
14215           clib_memcpy (mp->tunnel_src_address, &tun_src4,
14216                        sizeof (ip4_address_t));
14217           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
14218                        sizeof (ip4_address_t));
14219         }
14220     }
14221
14222   S (mp);
14223   W (ret);
14224   return ret;
14225 }
14226
14227 static int
14228 api_ipsec_sa_set_key (vat_main_t * vam)
14229 {
14230   unformat_input_t *i = vam->input;
14231   vl_api_ipsec_sa_set_key_t *mp;
14232   u32 sa_id;
14233   u8 *ck = 0, *ik = 0;
14234   int ret;
14235
14236   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14237     {
14238       if (unformat (i, "sa_id %d", &sa_id))
14239         ;
14240       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14241         ;
14242       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14243         ;
14244       else
14245         {
14246           clib_warning ("parse error '%U'", format_unformat_error, i);
14247           return -99;
14248         }
14249     }
14250
14251   M (IPSEC_SA_SET_KEY, mp);
14252
14253   mp->sa_id = ntohl (sa_id);
14254   mp->crypto_key_length = vec_len (ck);
14255   mp->integrity_key_length = vec_len (ik);
14256
14257   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14258     mp->crypto_key_length = sizeof (mp->crypto_key);
14259
14260   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14261     mp->integrity_key_length = sizeof (mp->integrity_key);
14262
14263   if (ck)
14264     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14265   if (ik)
14266     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14267
14268   S (mp);
14269   W (ret);
14270   return ret;
14271 }
14272
14273 static int
14274 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14275 {
14276   unformat_input_t *i = vam->input;
14277   vl_api_ipsec_tunnel_if_add_del_t *mp;
14278   u32 local_spi = 0, remote_spi = 0;
14279   u32 crypto_alg = 0, integ_alg = 0;
14280   u8 *lck = NULL, *rck = NULL;
14281   u8 *lik = NULL, *rik = NULL;
14282   ip4_address_t local_ip = { {0} };
14283   ip4_address_t remote_ip = { {0} };
14284   u8 is_add = 1;
14285   u8 esn = 0;
14286   u8 anti_replay = 0;
14287   int ret;
14288
14289   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14290     {
14291       if (unformat (i, "del"))
14292         is_add = 0;
14293       else if (unformat (i, "esn"))
14294         esn = 1;
14295       else if (unformat (i, "anti_replay"))
14296         anti_replay = 1;
14297       else if (unformat (i, "local_spi %d", &local_spi))
14298         ;
14299       else if (unformat (i, "remote_spi %d", &remote_spi))
14300         ;
14301       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
14302         ;
14303       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
14304         ;
14305       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14306         ;
14307       else
14308         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14309         ;
14310       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14311         ;
14312       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14313         ;
14314       else
14315         if (unformat
14316             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14317         {
14318           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14319               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14320             {
14321               errmsg ("unsupported crypto-alg: '%U'\n",
14322                       format_ipsec_crypto_alg, crypto_alg);
14323               return -99;
14324             }
14325         }
14326       else
14327         if (unformat
14328             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14329         {
14330           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14331               integ_alg >= IPSEC_INTEG_N_ALG)
14332             {
14333               errmsg ("unsupported integ-alg: '%U'\n",
14334                       format_ipsec_integ_alg, integ_alg);
14335               return -99;
14336             }
14337         }
14338       else
14339         {
14340           errmsg ("parse error '%U'\n", format_unformat_error, i);
14341           return -99;
14342         }
14343     }
14344
14345   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14346
14347   mp->is_add = is_add;
14348   mp->esn = esn;
14349   mp->anti_replay = anti_replay;
14350
14351   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
14352   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
14353
14354   mp->local_spi = htonl (local_spi);
14355   mp->remote_spi = htonl (remote_spi);
14356   mp->crypto_alg = (u8) crypto_alg;
14357
14358   mp->local_crypto_key_len = 0;
14359   if (lck)
14360     {
14361       mp->local_crypto_key_len = vec_len (lck);
14362       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14363         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14364       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14365     }
14366
14367   mp->remote_crypto_key_len = 0;
14368   if (rck)
14369     {
14370       mp->remote_crypto_key_len = vec_len (rck);
14371       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14372         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14373       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14374     }
14375
14376   mp->integ_alg = (u8) integ_alg;
14377
14378   mp->local_integ_key_len = 0;
14379   if (lik)
14380     {
14381       mp->local_integ_key_len = vec_len (lik);
14382       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14383         mp->local_integ_key_len = sizeof (mp->local_integ_key);
14384       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14385     }
14386
14387   mp->remote_integ_key_len = 0;
14388   if (rik)
14389     {
14390       mp->remote_integ_key_len = vec_len (rik);
14391       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14392         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14393       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14394     }
14395
14396   S (mp);
14397   W (ret);
14398   return ret;
14399 }
14400
14401 static void
14402 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14403 {
14404   vat_main_t *vam = &vat_main;
14405
14406   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14407          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
14408          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
14409          "tunnel_src_addr %U tunnel_dst_addr %U "
14410          "salt %u seq_outbound %lu last_seq_inbound %lu "
14411          "replay_window %lu total_data_size %lu\n",
14412          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
14413          mp->protocol,
14414          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
14415          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
14416          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
14417          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14418          mp->tunnel_src_addr,
14419          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14420          mp->tunnel_dst_addr,
14421          ntohl (mp->salt),
14422          clib_net_to_host_u64 (mp->seq_outbound),
14423          clib_net_to_host_u64 (mp->last_seq_inbound),
14424          clib_net_to_host_u64 (mp->replay_window),
14425          clib_net_to_host_u64 (mp->total_data_size));
14426 }
14427
14428 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14429 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14430
14431 static void vl_api_ipsec_sa_details_t_handler_json
14432   (vl_api_ipsec_sa_details_t * mp)
14433 {
14434   vat_main_t *vam = &vat_main;
14435   vat_json_node_t *node = NULL;
14436   struct in_addr src_ip4, dst_ip4;
14437   struct in6_addr src_ip6, dst_ip6;
14438
14439   if (VAT_JSON_ARRAY != vam->json_tree.type)
14440     {
14441       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14442       vat_json_init_array (&vam->json_tree);
14443     }
14444   node = vat_json_array_add (&vam->json_tree);
14445
14446   vat_json_init_object (node);
14447   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
14448   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14449   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
14450   vat_json_object_add_uint (node, "proto", mp->protocol);
14451   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
14452   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
14453   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
14454   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
14455   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
14456   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
14457   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
14458                              mp->crypto_key_len);
14459   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
14460                              mp->integ_key_len);
14461   if (mp->is_tunnel_ip6)
14462     {
14463       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
14464       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
14465       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
14466       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
14467     }
14468   else
14469     {
14470       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
14471       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
14472       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
14473       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
14474     }
14475   vat_json_object_add_uint (node, "replay_window",
14476                             clib_net_to_host_u64 (mp->replay_window));
14477   vat_json_object_add_uint (node, "total_data_size",
14478                             clib_net_to_host_u64 (mp->total_data_size));
14479
14480 }
14481
14482 static int
14483 api_ipsec_sa_dump (vat_main_t * vam)
14484 {
14485   unformat_input_t *i = vam->input;
14486   vl_api_ipsec_sa_dump_t *mp;
14487   vl_api_control_ping_t *mp_ping;
14488   u32 sa_id = ~0;
14489   int ret;
14490
14491   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14492     {
14493       if (unformat (i, "sa_id %d", &sa_id))
14494         ;
14495       else
14496         {
14497           clib_warning ("parse error '%U'", format_unformat_error, i);
14498           return -99;
14499         }
14500     }
14501
14502   M (IPSEC_SA_DUMP, mp);
14503
14504   mp->sa_id = ntohl (sa_id);
14505
14506   S (mp);
14507
14508   /* Use a control ping for synchronization */
14509   M (CONTROL_PING, mp_ping);
14510   S (mp_ping);
14511
14512   W (ret);
14513   return ret;
14514 }
14515
14516 static int
14517 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
14518 {
14519   unformat_input_t *i = vam->input;
14520   vl_api_ipsec_tunnel_if_set_key_t *mp;
14521   u32 sw_if_index = ~0;
14522   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
14523   u8 *key = 0;
14524   u32 alg = ~0;
14525   int ret;
14526
14527   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14528     {
14529       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14530         ;
14531       else
14532         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
14533         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
14534       else
14535         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
14536         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
14537       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
14538         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
14539       else
14540         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
14541         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
14542       else if (unformat (i, "%U", unformat_hex_string, &key))
14543         ;
14544       else
14545         {
14546           clib_warning ("parse error '%U'", format_unformat_error, i);
14547           return -99;
14548         }
14549     }
14550
14551   if (sw_if_index == ~0)
14552     {
14553       errmsg ("interface must be specified");
14554       return -99;
14555     }
14556
14557   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
14558     {
14559       errmsg ("key type must be specified");
14560       return -99;
14561     }
14562
14563   if (alg == ~0)
14564     {
14565       errmsg ("algorithm must be specified");
14566       return -99;
14567     }
14568
14569   if (vec_len (key) == 0)
14570     {
14571       errmsg ("key must be specified");
14572       return -99;
14573     }
14574
14575   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
14576
14577   mp->sw_if_index = htonl (sw_if_index);
14578   mp->alg = alg;
14579   mp->key_type = key_type;
14580   mp->key_len = vec_len (key);
14581   clib_memcpy (mp->key, key, vec_len (key));
14582
14583   S (mp);
14584   W (ret);
14585
14586   return ret;
14587 }
14588
14589 static int
14590 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14591 {
14592   unformat_input_t *i = vam->input;
14593   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14594   u32 sw_if_index = ~0;
14595   u32 sa_id = ~0;
14596   u8 is_outbound = (u8) ~ 0;
14597   int ret;
14598
14599   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14600     {
14601       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14602         ;
14603       else if (unformat (i, "sa_id %d", &sa_id))
14604         ;
14605       else if (unformat (i, "outbound"))
14606         is_outbound = 1;
14607       else if (unformat (i, "inbound"))
14608         is_outbound = 0;
14609       else
14610         {
14611           clib_warning ("parse error '%U'", format_unformat_error, i);
14612           return -99;
14613         }
14614     }
14615
14616   if (sw_if_index == ~0)
14617     {
14618       errmsg ("interface must be specified");
14619       return -99;
14620     }
14621
14622   if (sa_id == ~0)
14623     {
14624       errmsg ("SA ID must be specified");
14625       return -99;
14626     }
14627
14628   M (IPSEC_TUNNEL_IF_SET_SA, mp);
14629
14630   mp->sw_if_index = htonl (sw_if_index);
14631   mp->sa_id = htonl (sa_id);
14632   mp->is_outbound = is_outbound;
14633
14634   S (mp);
14635   W (ret);
14636
14637   return ret;
14638 }
14639
14640 static int
14641 api_ikev2_profile_add_del (vat_main_t * vam)
14642 {
14643   unformat_input_t *i = vam->input;
14644   vl_api_ikev2_profile_add_del_t *mp;
14645   u8 is_add = 1;
14646   u8 *name = 0;
14647   int ret;
14648
14649   const char *valid_chars = "a-zA-Z0-9_";
14650
14651   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14652     {
14653       if (unformat (i, "del"))
14654         is_add = 0;
14655       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14656         vec_add1 (name, 0);
14657       else
14658         {
14659           errmsg ("parse error '%U'", format_unformat_error, i);
14660           return -99;
14661         }
14662     }
14663
14664   if (!vec_len (name))
14665     {
14666       errmsg ("profile name must be specified");
14667       return -99;
14668     }
14669
14670   if (vec_len (name) > 64)
14671     {
14672       errmsg ("profile name too long");
14673       return -99;
14674     }
14675
14676   M (IKEV2_PROFILE_ADD_DEL, mp);
14677
14678   clib_memcpy (mp->name, name, vec_len (name));
14679   mp->is_add = is_add;
14680   vec_free (name);
14681
14682   S (mp);
14683   W (ret);
14684   return ret;
14685 }
14686
14687 static int
14688 api_ikev2_profile_set_auth (vat_main_t * vam)
14689 {
14690   unformat_input_t *i = vam->input;
14691   vl_api_ikev2_profile_set_auth_t *mp;
14692   u8 *name = 0;
14693   u8 *data = 0;
14694   u32 auth_method = 0;
14695   u8 is_hex = 0;
14696   int ret;
14697
14698   const char *valid_chars = "a-zA-Z0-9_";
14699
14700   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14701     {
14702       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14703         vec_add1 (name, 0);
14704       else if (unformat (i, "auth_method %U",
14705                          unformat_ikev2_auth_method, &auth_method))
14706         ;
14707       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
14708         is_hex = 1;
14709       else if (unformat (i, "auth_data %v", &data))
14710         ;
14711       else
14712         {
14713           errmsg ("parse error '%U'", format_unformat_error, i);
14714           return -99;
14715         }
14716     }
14717
14718   if (!vec_len (name))
14719     {
14720       errmsg ("profile name must be specified");
14721       return -99;
14722     }
14723
14724   if (vec_len (name) > 64)
14725     {
14726       errmsg ("profile name too long");
14727       return -99;
14728     }
14729
14730   if (!vec_len (data))
14731     {
14732       errmsg ("auth_data must be specified");
14733       return -99;
14734     }
14735
14736   if (!auth_method)
14737     {
14738       errmsg ("auth_method must be specified");
14739       return -99;
14740     }
14741
14742   M (IKEV2_PROFILE_SET_AUTH, mp);
14743
14744   mp->is_hex = is_hex;
14745   mp->auth_method = (u8) auth_method;
14746   mp->data_len = vec_len (data);
14747   clib_memcpy (mp->name, name, vec_len (name));
14748   clib_memcpy (mp->data, data, vec_len (data));
14749   vec_free (name);
14750   vec_free (data);
14751
14752   S (mp);
14753   W (ret);
14754   return ret;
14755 }
14756
14757 static int
14758 api_ikev2_profile_set_id (vat_main_t * vam)
14759 {
14760   unformat_input_t *i = vam->input;
14761   vl_api_ikev2_profile_set_id_t *mp;
14762   u8 *name = 0;
14763   u8 *data = 0;
14764   u8 is_local = 0;
14765   u32 id_type = 0;
14766   ip4_address_t ip4;
14767   int ret;
14768
14769   const char *valid_chars = "a-zA-Z0-9_";
14770
14771   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14772     {
14773       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14774         vec_add1 (name, 0);
14775       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
14776         ;
14777       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
14778         {
14779           data = vec_new (u8, 4);
14780           clib_memcpy (data, ip4.as_u8, 4);
14781         }
14782       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
14783         ;
14784       else if (unformat (i, "id_data %v", &data))
14785         ;
14786       else if (unformat (i, "local"))
14787         is_local = 1;
14788       else if (unformat (i, "remote"))
14789         is_local = 0;
14790       else
14791         {
14792           errmsg ("parse error '%U'", format_unformat_error, i);
14793           return -99;
14794         }
14795     }
14796
14797   if (!vec_len (name))
14798     {
14799       errmsg ("profile name must be specified");
14800       return -99;
14801     }
14802
14803   if (vec_len (name) > 64)
14804     {
14805       errmsg ("profile name too long");
14806       return -99;
14807     }
14808
14809   if (!vec_len (data))
14810     {
14811       errmsg ("id_data must be specified");
14812       return -99;
14813     }
14814
14815   if (!id_type)
14816     {
14817       errmsg ("id_type must be specified");
14818       return -99;
14819     }
14820
14821   M (IKEV2_PROFILE_SET_ID, mp);
14822
14823   mp->is_local = is_local;
14824   mp->id_type = (u8) id_type;
14825   mp->data_len = vec_len (data);
14826   clib_memcpy (mp->name, name, vec_len (name));
14827   clib_memcpy (mp->data, data, vec_len (data));
14828   vec_free (name);
14829   vec_free (data);
14830
14831   S (mp);
14832   W (ret);
14833   return ret;
14834 }
14835
14836 static int
14837 api_ikev2_profile_set_ts (vat_main_t * vam)
14838 {
14839   unformat_input_t *i = vam->input;
14840   vl_api_ikev2_profile_set_ts_t *mp;
14841   u8 *name = 0;
14842   u8 is_local = 0;
14843   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
14844   ip4_address_t start_addr, end_addr;
14845
14846   const char *valid_chars = "a-zA-Z0-9_";
14847   int ret;
14848
14849   start_addr.as_u32 = 0;
14850   end_addr.as_u32 = (u32) ~ 0;
14851
14852   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14853     {
14854       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14855         vec_add1 (name, 0);
14856       else if (unformat (i, "protocol %d", &proto))
14857         ;
14858       else if (unformat (i, "start_port %d", &start_port))
14859         ;
14860       else if (unformat (i, "end_port %d", &end_port))
14861         ;
14862       else
14863         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
14864         ;
14865       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
14866         ;
14867       else if (unformat (i, "local"))
14868         is_local = 1;
14869       else if (unformat (i, "remote"))
14870         is_local = 0;
14871       else
14872         {
14873           errmsg ("parse error '%U'", format_unformat_error, i);
14874           return -99;
14875         }
14876     }
14877
14878   if (!vec_len (name))
14879     {
14880       errmsg ("profile name must be specified");
14881       return -99;
14882     }
14883
14884   if (vec_len (name) > 64)
14885     {
14886       errmsg ("profile name too long");
14887       return -99;
14888     }
14889
14890   M (IKEV2_PROFILE_SET_TS, mp);
14891
14892   mp->is_local = is_local;
14893   mp->proto = (u8) proto;
14894   mp->start_port = (u16) start_port;
14895   mp->end_port = (u16) end_port;
14896   mp->start_addr = start_addr.as_u32;
14897   mp->end_addr = end_addr.as_u32;
14898   clib_memcpy (mp->name, name, vec_len (name));
14899   vec_free (name);
14900
14901   S (mp);
14902   W (ret);
14903   return ret;
14904 }
14905
14906 static int
14907 api_ikev2_set_local_key (vat_main_t * vam)
14908 {
14909   unformat_input_t *i = vam->input;
14910   vl_api_ikev2_set_local_key_t *mp;
14911   u8 *file = 0;
14912   int ret;
14913
14914   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14915     {
14916       if (unformat (i, "file %v", &file))
14917         vec_add1 (file, 0);
14918       else
14919         {
14920           errmsg ("parse error '%U'", format_unformat_error, i);
14921           return -99;
14922         }
14923     }
14924
14925   if (!vec_len (file))
14926     {
14927       errmsg ("RSA key file must be specified");
14928       return -99;
14929     }
14930
14931   if (vec_len (file) > 256)
14932     {
14933       errmsg ("file name too long");
14934       return -99;
14935     }
14936
14937   M (IKEV2_SET_LOCAL_KEY, mp);
14938
14939   clib_memcpy (mp->key_file, file, vec_len (file));
14940   vec_free (file);
14941
14942   S (mp);
14943   W (ret);
14944   return ret;
14945 }
14946
14947 static int
14948 api_ikev2_set_responder (vat_main_t * vam)
14949 {
14950   unformat_input_t *i = vam->input;
14951   vl_api_ikev2_set_responder_t *mp;
14952   int ret;
14953   u8 *name = 0;
14954   u32 sw_if_index = ~0;
14955   ip4_address_t address;
14956
14957   const char *valid_chars = "a-zA-Z0-9_";
14958
14959   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14960     {
14961       if (unformat
14962           (i, "%U interface %d address %U", unformat_token, valid_chars,
14963            &name, &sw_if_index, unformat_ip4_address, &address))
14964         vec_add1 (name, 0);
14965       else
14966         {
14967           errmsg ("parse error '%U'", format_unformat_error, i);
14968           return -99;
14969         }
14970     }
14971
14972   if (!vec_len (name))
14973     {
14974       errmsg ("profile name must be specified");
14975       return -99;
14976     }
14977
14978   if (vec_len (name) > 64)
14979     {
14980       errmsg ("profile name too long");
14981       return -99;
14982     }
14983
14984   M (IKEV2_SET_RESPONDER, mp);
14985
14986   clib_memcpy (mp->name, name, vec_len (name));
14987   vec_free (name);
14988
14989   mp->sw_if_index = sw_if_index;
14990   clib_memcpy (mp->address, &address, sizeof (address));
14991
14992   S (mp);
14993   W (ret);
14994   return ret;
14995 }
14996
14997 static int
14998 api_ikev2_set_ike_transforms (vat_main_t * vam)
14999 {
15000   unformat_input_t *i = vam->input;
15001   vl_api_ikev2_set_ike_transforms_t *mp;
15002   int ret;
15003   u8 *name = 0;
15004   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15005
15006   const char *valid_chars = "a-zA-Z0-9_";
15007
15008   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15009     {
15010       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15011                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15012         vec_add1 (name, 0);
15013       else
15014         {
15015           errmsg ("parse error '%U'", format_unformat_error, i);
15016           return -99;
15017         }
15018     }
15019
15020   if (!vec_len (name))
15021     {
15022       errmsg ("profile name must be specified");
15023       return -99;
15024     }
15025
15026   if (vec_len (name) > 64)
15027     {
15028       errmsg ("profile name too long");
15029       return -99;
15030     }
15031
15032   M (IKEV2_SET_IKE_TRANSFORMS, mp);
15033
15034   clib_memcpy (mp->name, name, vec_len (name));
15035   vec_free (name);
15036   mp->crypto_alg = crypto_alg;
15037   mp->crypto_key_size = crypto_key_size;
15038   mp->integ_alg = integ_alg;
15039   mp->dh_group = dh_group;
15040
15041   S (mp);
15042   W (ret);
15043   return ret;
15044 }
15045
15046
15047 static int
15048 api_ikev2_set_esp_transforms (vat_main_t * vam)
15049 {
15050   unformat_input_t *i = vam->input;
15051   vl_api_ikev2_set_esp_transforms_t *mp;
15052   int ret;
15053   u8 *name = 0;
15054   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15055
15056   const char *valid_chars = "a-zA-Z0-9_";
15057
15058   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15059     {
15060       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15061                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15062         vec_add1 (name, 0);
15063       else
15064         {
15065           errmsg ("parse error '%U'", format_unformat_error, i);
15066           return -99;
15067         }
15068     }
15069
15070   if (!vec_len (name))
15071     {
15072       errmsg ("profile name must be specified");
15073       return -99;
15074     }
15075
15076   if (vec_len (name) > 64)
15077     {
15078       errmsg ("profile name too long");
15079       return -99;
15080     }
15081
15082   M (IKEV2_SET_ESP_TRANSFORMS, mp);
15083
15084   clib_memcpy (mp->name, name, vec_len (name));
15085   vec_free (name);
15086   mp->crypto_alg = crypto_alg;
15087   mp->crypto_key_size = crypto_key_size;
15088   mp->integ_alg = integ_alg;
15089   mp->dh_group = dh_group;
15090
15091   S (mp);
15092   W (ret);
15093   return ret;
15094 }
15095
15096 static int
15097 api_ikev2_set_sa_lifetime (vat_main_t * vam)
15098 {
15099   unformat_input_t *i = vam->input;
15100   vl_api_ikev2_set_sa_lifetime_t *mp;
15101   int ret;
15102   u8 *name = 0;
15103   u64 lifetime, lifetime_maxdata;
15104   u32 lifetime_jitter, handover;
15105
15106   const char *valid_chars = "a-zA-Z0-9_";
15107
15108   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15109     {
15110       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
15111                     &lifetime, &lifetime_jitter, &handover,
15112                     &lifetime_maxdata))
15113         vec_add1 (name, 0);
15114       else
15115         {
15116           errmsg ("parse error '%U'", format_unformat_error, i);
15117           return -99;
15118         }
15119     }
15120
15121   if (!vec_len (name))
15122     {
15123       errmsg ("profile name must be specified");
15124       return -99;
15125     }
15126
15127   if (vec_len (name) > 64)
15128     {
15129       errmsg ("profile name too long");
15130       return -99;
15131     }
15132
15133   M (IKEV2_SET_SA_LIFETIME, mp);
15134
15135   clib_memcpy (mp->name, name, vec_len (name));
15136   vec_free (name);
15137   mp->lifetime = lifetime;
15138   mp->lifetime_jitter = lifetime_jitter;
15139   mp->handover = handover;
15140   mp->lifetime_maxdata = lifetime_maxdata;
15141
15142   S (mp);
15143   W (ret);
15144   return ret;
15145 }
15146
15147 static int
15148 api_ikev2_initiate_sa_init (vat_main_t * vam)
15149 {
15150   unformat_input_t *i = vam->input;
15151   vl_api_ikev2_initiate_sa_init_t *mp;
15152   int ret;
15153   u8 *name = 0;
15154
15155   const char *valid_chars = "a-zA-Z0-9_";
15156
15157   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15158     {
15159       if (unformat (i, "%U", unformat_token, valid_chars, &name))
15160         vec_add1 (name, 0);
15161       else
15162         {
15163           errmsg ("parse error '%U'", format_unformat_error, i);
15164           return -99;
15165         }
15166     }
15167
15168   if (!vec_len (name))
15169     {
15170       errmsg ("profile name must be specified");
15171       return -99;
15172     }
15173
15174   if (vec_len (name) > 64)
15175     {
15176       errmsg ("profile name too long");
15177       return -99;
15178     }
15179
15180   M (IKEV2_INITIATE_SA_INIT, mp);
15181
15182   clib_memcpy (mp->name, name, vec_len (name));
15183   vec_free (name);
15184
15185   S (mp);
15186   W (ret);
15187   return ret;
15188 }
15189
15190 static int
15191 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
15192 {
15193   unformat_input_t *i = vam->input;
15194   vl_api_ikev2_initiate_del_ike_sa_t *mp;
15195   int ret;
15196   u64 ispi;
15197
15198
15199   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15200     {
15201       if (unformat (i, "%lx", &ispi))
15202         ;
15203       else
15204         {
15205           errmsg ("parse error '%U'", format_unformat_error, i);
15206           return -99;
15207         }
15208     }
15209
15210   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
15211
15212   mp->ispi = ispi;
15213
15214   S (mp);
15215   W (ret);
15216   return ret;
15217 }
15218
15219 static int
15220 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
15221 {
15222   unformat_input_t *i = vam->input;
15223   vl_api_ikev2_initiate_del_child_sa_t *mp;
15224   int ret;
15225   u32 ispi;
15226
15227
15228   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15229     {
15230       if (unformat (i, "%x", &ispi))
15231         ;
15232       else
15233         {
15234           errmsg ("parse error '%U'", format_unformat_error, i);
15235           return -99;
15236         }
15237     }
15238
15239   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
15240
15241   mp->ispi = ispi;
15242
15243   S (mp);
15244   W (ret);
15245   return ret;
15246 }
15247
15248 static int
15249 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
15250 {
15251   unformat_input_t *i = vam->input;
15252   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
15253   int ret;
15254   u32 ispi;
15255
15256
15257   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15258     {
15259       if (unformat (i, "%x", &ispi))
15260         ;
15261       else
15262         {
15263           errmsg ("parse error '%U'", format_unformat_error, i);
15264           return -99;
15265         }
15266     }
15267
15268   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
15269
15270   mp->ispi = ispi;
15271
15272   S (mp);
15273   W (ret);
15274   return ret;
15275 }
15276
15277 /*
15278  * MAP
15279  */
15280 static int
15281 api_map_add_domain (vat_main_t * vam)
15282 {
15283   unformat_input_t *i = vam->input;
15284   vl_api_map_add_domain_t *mp;
15285
15286   ip4_address_t ip4_prefix;
15287   ip6_address_t ip6_prefix;
15288   ip6_address_t ip6_src;
15289   u32 num_m_args = 0;
15290   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
15291     0, psid_length = 0;
15292   u8 is_translation = 0;
15293   u32 mtu = 0;
15294   u32 ip6_src_len = 128;
15295   int ret;
15296
15297   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15298     {
15299       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
15300                     &ip4_prefix, &ip4_prefix_len))
15301         num_m_args++;
15302       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
15303                          &ip6_prefix, &ip6_prefix_len))
15304         num_m_args++;
15305       else
15306         if (unformat
15307             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
15308              &ip6_src_len))
15309         num_m_args++;
15310       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
15311         num_m_args++;
15312       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
15313         num_m_args++;
15314       else if (unformat (i, "psid-offset %d", &psid_offset))
15315         num_m_args++;
15316       else if (unformat (i, "psid-len %d", &psid_length))
15317         num_m_args++;
15318       else if (unformat (i, "mtu %d", &mtu))
15319         num_m_args++;
15320       else if (unformat (i, "map-t"))
15321         is_translation = 1;
15322       else
15323         {
15324           clib_warning ("parse error '%U'", format_unformat_error, i);
15325           return -99;
15326         }
15327     }
15328
15329   if (num_m_args < 3)
15330     {
15331       errmsg ("mandatory argument(s) missing");
15332       return -99;
15333     }
15334
15335   /* Construct the API message */
15336   M (MAP_ADD_DOMAIN, mp);
15337
15338   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
15339   mp->ip4_prefix_len = ip4_prefix_len;
15340
15341   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
15342   mp->ip6_prefix_len = ip6_prefix_len;
15343
15344   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
15345   mp->ip6_src_prefix_len = ip6_src_len;
15346
15347   mp->ea_bits_len = ea_bits_len;
15348   mp->psid_offset = psid_offset;
15349   mp->psid_length = psid_length;
15350   mp->is_translation = is_translation;
15351   mp->mtu = htons (mtu);
15352
15353   /* send it... */
15354   S (mp);
15355
15356   /* Wait for a reply, return good/bad news  */
15357   W (ret);
15358   return ret;
15359 }
15360
15361 static int
15362 api_map_del_domain (vat_main_t * vam)
15363 {
15364   unformat_input_t *i = vam->input;
15365   vl_api_map_del_domain_t *mp;
15366
15367   u32 num_m_args = 0;
15368   u32 index;
15369   int ret;
15370
15371   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15372     {
15373       if (unformat (i, "index %d", &index))
15374         num_m_args++;
15375       else
15376         {
15377           clib_warning ("parse error '%U'", format_unformat_error, i);
15378           return -99;
15379         }
15380     }
15381
15382   if (num_m_args != 1)
15383     {
15384       errmsg ("mandatory argument(s) missing");
15385       return -99;
15386     }
15387
15388   /* Construct the API message */
15389   M (MAP_DEL_DOMAIN, mp);
15390
15391   mp->index = ntohl (index);
15392
15393   /* send it... */
15394   S (mp);
15395
15396   /* Wait for a reply, return good/bad news  */
15397   W (ret);
15398   return ret;
15399 }
15400
15401 static int
15402 api_map_add_del_rule (vat_main_t * vam)
15403 {
15404   unformat_input_t *i = vam->input;
15405   vl_api_map_add_del_rule_t *mp;
15406   u8 is_add = 1;
15407   ip6_address_t ip6_dst;
15408   u32 num_m_args = 0, index, psid = 0;
15409   int ret;
15410
15411   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15412     {
15413       if (unformat (i, "index %d", &index))
15414         num_m_args++;
15415       else if (unformat (i, "psid %d", &psid))
15416         num_m_args++;
15417       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
15418         num_m_args++;
15419       else if (unformat (i, "del"))
15420         {
15421           is_add = 0;
15422         }
15423       else
15424         {
15425           clib_warning ("parse error '%U'", format_unformat_error, i);
15426           return -99;
15427         }
15428     }
15429
15430   /* Construct the API message */
15431   M (MAP_ADD_DEL_RULE, mp);
15432
15433   mp->index = ntohl (index);
15434   mp->is_add = is_add;
15435   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
15436   mp->psid = ntohs (psid);
15437
15438   /* send it... */
15439   S (mp);
15440
15441   /* Wait for a reply, return good/bad news  */
15442   W (ret);
15443   return ret;
15444 }
15445
15446 static int
15447 api_map_domain_dump (vat_main_t * vam)
15448 {
15449   vl_api_map_domain_dump_t *mp;
15450   vl_api_control_ping_t *mp_ping;
15451   int ret;
15452
15453   /* Construct the API message */
15454   M (MAP_DOMAIN_DUMP, mp);
15455
15456   /* send it... */
15457   S (mp);
15458
15459   /* Use a control ping for synchronization */
15460   MPING (CONTROL_PING, mp_ping);
15461   S (mp_ping);
15462
15463   W (ret);
15464   return ret;
15465 }
15466
15467 static int
15468 api_map_rule_dump (vat_main_t * vam)
15469 {
15470   unformat_input_t *i = vam->input;
15471   vl_api_map_rule_dump_t *mp;
15472   vl_api_control_ping_t *mp_ping;
15473   u32 domain_index = ~0;
15474   int ret;
15475
15476   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15477     {
15478       if (unformat (i, "index %u", &domain_index))
15479         ;
15480       else
15481         break;
15482     }
15483
15484   if (domain_index == ~0)
15485     {
15486       clib_warning ("parse error: domain index expected");
15487       return -99;
15488     }
15489
15490   /* Construct the API message */
15491   M (MAP_RULE_DUMP, mp);
15492
15493   mp->domain_index = htonl (domain_index);
15494
15495   /* send it... */
15496   S (mp);
15497
15498   /* Use a control ping for synchronization */
15499   MPING (CONTROL_PING, mp_ping);
15500   S (mp_ping);
15501
15502   W (ret);
15503   return ret;
15504 }
15505
15506 static void vl_api_map_add_domain_reply_t_handler
15507   (vl_api_map_add_domain_reply_t * mp)
15508 {
15509   vat_main_t *vam = &vat_main;
15510   i32 retval = ntohl (mp->retval);
15511
15512   if (vam->async_mode)
15513     {
15514       vam->async_errors += (retval < 0);
15515     }
15516   else
15517     {
15518       vam->retval = retval;
15519       vam->result_ready = 1;
15520     }
15521 }
15522
15523 static void vl_api_map_add_domain_reply_t_handler_json
15524   (vl_api_map_add_domain_reply_t * mp)
15525 {
15526   vat_main_t *vam = &vat_main;
15527   vat_json_node_t node;
15528
15529   vat_json_init_object (&node);
15530   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
15531   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
15532
15533   vat_json_print (vam->ofp, &node);
15534   vat_json_free (&node);
15535
15536   vam->retval = ntohl (mp->retval);
15537   vam->result_ready = 1;
15538 }
15539
15540 static int
15541 api_get_first_msg_id (vat_main_t * vam)
15542 {
15543   vl_api_get_first_msg_id_t *mp;
15544   unformat_input_t *i = vam->input;
15545   u8 *name;
15546   u8 name_set = 0;
15547   int ret;
15548
15549   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15550     {
15551       if (unformat (i, "client %s", &name))
15552         name_set = 1;
15553       else
15554         break;
15555     }
15556
15557   if (name_set == 0)
15558     {
15559       errmsg ("missing client name");
15560       return -99;
15561     }
15562   vec_add1 (name, 0);
15563
15564   if (vec_len (name) > 63)
15565     {
15566       errmsg ("client name too long");
15567       return -99;
15568     }
15569
15570   M (GET_FIRST_MSG_ID, mp);
15571   clib_memcpy (mp->name, name, vec_len (name));
15572   S (mp);
15573   W (ret);
15574   return ret;
15575 }
15576
15577 static int
15578 api_cop_interface_enable_disable (vat_main_t * vam)
15579 {
15580   unformat_input_t *line_input = vam->input;
15581   vl_api_cop_interface_enable_disable_t *mp;
15582   u32 sw_if_index = ~0;
15583   u8 enable_disable = 1;
15584   int ret;
15585
15586   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15587     {
15588       if (unformat (line_input, "disable"))
15589         enable_disable = 0;
15590       if (unformat (line_input, "enable"))
15591         enable_disable = 1;
15592       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15593                          vam, &sw_if_index))
15594         ;
15595       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15596         ;
15597       else
15598         break;
15599     }
15600
15601   if (sw_if_index == ~0)
15602     {
15603       errmsg ("missing interface name or sw_if_index");
15604       return -99;
15605     }
15606
15607   /* Construct the API message */
15608   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15609   mp->sw_if_index = ntohl (sw_if_index);
15610   mp->enable_disable = enable_disable;
15611
15612   /* send it... */
15613   S (mp);
15614   /* Wait for the reply */
15615   W (ret);
15616   return ret;
15617 }
15618
15619 static int
15620 api_cop_whitelist_enable_disable (vat_main_t * vam)
15621 {
15622   unformat_input_t *line_input = vam->input;
15623   vl_api_cop_whitelist_enable_disable_t *mp;
15624   u32 sw_if_index = ~0;
15625   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15626   u32 fib_id = 0;
15627   int ret;
15628
15629   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15630     {
15631       if (unformat (line_input, "ip4"))
15632         ip4 = 1;
15633       else if (unformat (line_input, "ip6"))
15634         ip6 = 1;
15635       else if (unformat (line_input, "default"))
15636         default_cop = 1;
15637       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15638                          vam, &sw_if_index))
15639         ;
15640       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15641         ;
15642       else if (unformat (line_input, "fib-id %d", &fib_id))
15643         ;
15644       else
15645         break;
15646     }
15647
15648   if (sw_if_index == ~0)
15649     {
15650       errmsg ("missing interface name or sw_if_index");
15651       return -99;
15652     }
15653
15654   /* Construct the API message */
15655   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15656   mp->sw_if_index = ntohl (sw_if_index);
15657   mp->fib_id = ntohl (fib_id);
15658   mp->ip4 = ip4;
15659   mp->ip6 = ip6;
15660   mp->default_cop = default_cop;
15661
15662   /* send it... */
15663   S (mp);
15664   /* Wait for the reply */
15665   W (ret);
15666   return ret;
15667 }
15668
15669 static int
15670 api_get_node_graph (vat_main_t * vam)
15671 {
15672   vl_api_get_node_graph_t *mp;
15673   int ret;
15674
15675   M (GET_NODE_GRAPH, mp);
15676
15677   /* send it... */
15678   S (mp);
15679   /* Wait for the reply */
15680   W (ret);
15681   return ret;
15682 }
15683
15684 /* *INDENT-OFF* */
15685 /** Used for parsing LISP eids */
15686 typedef CLIB_PACKED(struct{
15687   u8 addr[16];   /**< eid address */
15688   u32 len;       /**< prefix length if IP */
15689   u8 type;      /**< type of eid */
15690 }) lisp_eid_vat_t;
15691 /* *INDENT-ON* */
15692
15693 static uword
15694 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15695 {
15696   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15697
15698   memset (a, 0, sizeof (a[0]));
15699
15700   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15701     {
15702       a->type = 0;              /* ipv4 type */
15703     }
15704   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15705     {
15706       a->type = 1;              /* ipv6 type */
15707     }
15708   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15709     {
15710       a->type = 2;              /* mac type */
15711     }
15712   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15713     {
15714       a->type = 3;              /* NSH type */
15715       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15716       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15717     }
15718   else
15719     {
15720       return 0;
15721     }
15722
15723   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15724     {
15725       return 0;
15726     }
15727
15728   return 1;
15729 }
15730
15731 static int
15732 lisp_eid_size_vat (u8 type)
15733 {
15734   switch (type)
15735     {
15736     case 0:
15737       return 4;
15738     case 1:
15739       return 16;
15740     case 2:
15741       return 6;
15742     case 3:
15743       return 5;
15744     }
15745   return 0;
15746 }
15747
15748 static void
15749 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15750 {
15751   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15752 }
15753
15754 static int
15755 api_one_add_del_locator_set (vat_main_t * vam)
15756 {
15757   unformat_input_t *input = vam->input;
15758   vl_api_one_add_del_locator_set_t *mp;
15759   u8 is_add = 1;
15760   u8 *locator_set_name = NULL;
15761   u8 locator_set_name_set = 0;
15762   vl_api_local_locator_t locator, *locators = 0;
15763   u32 sw_if_index, priority, weight;
15764   u32 data_len = 0;
15765
15766   int ret;
15767   /* Parse args required to build the message */
15768   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15769     {
15770       if (unformat (input, "del"))
15771         {
15772           is_add = 0;
15773         }
15774       else if (unformat (input, "locator-set %s", &locator_set_name))
15775         {
15776           locator_set_name_set = 1;
15777         }
15778       else if (unformat (input, "sw_if_index %u p %u w %u",
15779                          &sw_if_index, &priority, &weight))
15780         {
15781           locator.sw_if_index = htonl (sw_if_index);
15782           locator.priority = priority;
15783           locator.weight = weight;
15784           vec_add1 (locators, locator);
15785         }
15786       else
15787         if (unformat
15788             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15789              &sw_if_index, &priority, &weight))
15790         {
15791           locator.sw_if_index = htonl (sw_if_index);
15792           locator.priority = priority;
15793           locator.weight = weight;
15794           vec_add1 (locators, locator);
15795         }
15796       else
15797         break;
15798     }
15799
15800   if (locator_set_name_set == 0)
15801     {
15802       errmsg ("missing locator-set name");
15803       vec_free (locators);
15804       return -99;
15805     }
15806
15807   if (vec_len (locator_set_name) > 64)
15808     {
15809       errmsg ("locator-set name too long");
15810       vec_free (locator_set_name);
15811       vec_free (locators);
15812       return -99;
15813     }
15814   vec_add1 (locator_set_name, 0);
15815
15816   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15817
15818   /* Construct the API message */
15819   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15820
15821   mp->is_add = is_add;
15822   clib_memcpy (mp->locator_set_name, locator_set_name,
15823                vec_len (locator_set_name));
15824   vec_free (locator_set_name);
15825
15826   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15827   if (locators)
15828     clib_memcpy (mp->locators, locators, data_len);
15829   vec_free (locators);
15830
15831   /* send it... */
15832   S (mp);
15833
15834   /* Wait for a reply... */
15835   W (ret);
15836   return ret;
15837 }
15838
15839 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15840
15841 static int
15842 api_one_add_del_locator (vat_main_t * vam)
15843 {
15844   unformat_input_t *input = vam->input;
15845   vl_api_one_add_del_locator_t *mp;
15846   u32 tmp_if_index = ~0;
15847   u32 sw_if_index = ~0;
15848   u8 sw_if_index_set = 0;
15849   u8 sw_if_index_if_name_set = 0;
15850   u32 priority = ~0;
15851   u8 priority_set = 0;
15852   u32 weight = ~0;
15853   u8 weight_set = 0;
15854   u8 is_add = 1;
15855   u8 *locator_set_name = NULL;
15856   u8 locator_set_name_set = 0;
15857   int ret;
15858
15859   /* Parse args required to build the message */
15860   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15861     {
15862       if (unformat (input, "del"))
15863         {
15864           is_add = 0;
15865         }
15866       else if (unformat (input, "locator-set %s", &locator_set_name))
15867         {
15868           locator_set_name_set = 1;
15869         }
15870       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15871                          &tmp_if_index))
15872         {
15873           sw_if_index_if_name_set = 1;
15874           sw_if_index = tmp_if_index;
15875         }
15876       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15877         {
15878           sw_if_index_set = 1;
15879           sw_if_index = tmp_if_index;
15880         }
15881       else if (unformat (input, "p %d", &priority))
15882         {
15883           priority_set = 1;
15884         }
15885       else if (unformat (input, "w %d", &weight))
15886         {
15887           weight_set = 1;
15888         }
15889       else
15890         break;
15891     }
15892
15893   if (locator_set_name_set == 0)
15894     {
15895       errmsg ("missing locator-set name");
15896       return -99;
15897     }
15898
15899   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15900     {
15901       errmsg ("missing sw_if_index");
15902       vec_free (locator_set_name);
15903       return -99;
15904     }
15905
15906   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15907     {
15908       errmsg ("cannot use both params interface name and sw_if_index");
15909       vec_free (locator_set_name);
15910       return -99;
15911     }
15912
15913   if (priority_set == 0)
15914     {
15915       errmsg ("missing locator-set priority");
15916       vec_free (locator_set_name);
15917       return -99;
15918     }
15919
15920   if (weight_set == 0)
15921     {
15922       errmsg ("missing locator-set weight");
15923       vec_free (locator_set_name);
15924       return -99;
15925     }
15926
15927   if (vec_len (locator_set_name) > 64)
15928     {
15929       errmsg ("locator-set name too long");
15930       vec_free (locator_set_name);
15931       return -99;
15932     }
15933   vec_add1 (locator_set_name, 0);
15934
15935   /* Construct the API message */
15936   M (ONE_ADD_DEL_LOCATOR, mp);
15937
15938   mp->is_add = is_add;
15939   mp->sw_if_index = ntohl (sw_if_index);
15940   mp->priority = priority;
15941   mp->weight = weight;
15942   clib_memcpy (mp->locator_set_name, locator_set_name,
15943                vec_len (locator_set_name));
15944   vec_free (locator_set_name);
15945
15946   /* send it... */
15947   S (mp);
15948
15949   /* Wait for a reply... */
15950   W (ret);
15951   return ret;
15952 }
15953
15954 #define api_lisp_add_del_locator api_one_add_del_locator
15955
15956 uword
15957 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15958 {
15959   u32 *key_id = va_arg (*args, u32 *);
15960   u8 *s = 0;
15961
15962   if (unformat (input, "%s", &s))
15963     {
15964       if (!strcmp ((char *) s, "sha1"))
15965         key_id[0] = HMAC_SHA_1_96;
15966       else if (!strcmp ((char *) s, "sha256"))
15967         key_id[0] = HMAC_SHA_256_128;
15968       else
15969         {
15970           clib_warning ("invalid key_id: '%s'", s);
15971           key_id[0] = HMAC_NO_KEY;
15972         }
15973     }
15974   else
15975     return 0;
15976
15977   vec_free (s);
15978   return 1;
15979 }
15980
15981 static int
15982 api_one_add_del_local_eid (vat_main_t * vam)
15983 {
15984   unformat_input_t *input = vam->input;
15985   vl_api_one_add_del_local_eid_t *mp;
15986   u8 is_add = 1;
15987   u8 eid_set = 0;
15988   lisp_eid_vat_t _eid, *eid = &_eid;
15989   u8 *locator_set_name = 0;
15990   u8 locator_set_name_set = 0;
15991   u32 vni = 0;
15992   u16 key_id = 0;
15993   u8 *key = 0;
15994   int ret;
15995
15996   /* Parse args required to build the message */
15997   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15998     {
15999       if (unformat (input, "del"))
16000         {
16001           is_add = 0;
16002         }
16003       else if (unformat (input, "vni %d", &vni))
16004         {
16005           ;
16006         }
16007       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16008         {
16009           eid_set = 1;
16010         }
16011       else if (unformat (input, "locator-set %s", &locator_set_name))
16012         {
16013           locator_set_name_set = 1;
16014         }
16015       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
16016         ;
16017       else if (unformat (input, "secret-key %_%v%_", &key))
16018         ;
16019       else
16020         break;
16021     }
16022
16023   if (locator_set_name_set == 0)
16024     {
16025       errmsg ("missing locator-set name");
16026       return -99;
16027     }
16028
16029   if (0 == eid_set)
16030     {
16031       errmsg ("EID address not set!");
16032       vec_free (locator_set_name);
16033       return -99;
16034     }
16035
16036   if (key && (0 == key_id))
16037     {
16038       errmsg ("invalid key_id!");
16039       return -99;
16040     }
16041
16042   if (vec_len (key) > 64)
16043     {
16044       errmsg ("key too long");
16045       vec_free (key);
16046       return -99;
16047     }
16048
16049   if (vec_len (locator_set_name) > 64)
16050     {
16051       errmsg ("locator-set name too long");
16052       vec_free (locator_set_name);
16053       return -99;
16054     }
16055   vec_add1 (locator_set_name, 0);
16056
16057   /* Construct the API message */
16058   M (ONE_ADD_DEL_LOCAL_EID, mp);
16059
16060   mp->is_add = is_add;
16061   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16062   mp->eid_type = eid->type;
16063   mp->prefix_len = eid->len;
16064   mp->vni = clib_host_to_net_u32 (vni);
16065   mp->key_id = clib_host_to_net_u16 (key_id);
16066   clib_memcpy (mp->locator_set_name, locator_set_name,
16067                vec_len (locator_set_name));
16068   clib_memcpy (mp->key, key, vec_len (key));
16069
16070   vec_free (locator_set_name);
16071   vec_free (key);
16072
16073   /* send it... */
16074   S (mp);
16075
16076   /* Wait for a reply... */
16077   W (ret);
16078   return ret;
16079 }
16080
16081 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
16082
16083 static int
16084 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16085 {
16086   u32 dp_table = 0, vni = 0;;
16087   unformat_input_t *input = vam->input;
16088   vl_api_gpe_add_del_fwd_entry_t *mp;
16089   u8 is_add = 1;
16090   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
16091   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
16092   u8 rmt_eid_set = 0, lcl_eid_set = 0;
16093   u32 action = ~0, w;
16094   ip4_address_t rmt_rloc4, lcl_rloc4;
16095   ip6_address_t rmt_rloc6, lcl_rloc6;
16096   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
16097   int ret;
16098
16099   memset (&rloc, 0, sizeof (rloc));
16100
16101   /* Parse args required to build the message */
16102   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16103     {
16104       if (unformat (input, "del"))
16105         is_add = 0;
16106       else if (unformat (input, "add"))
16107         is_add = 1;
16108       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
16109         {
16110           rmt_eid_set = 1;
16111         }
16112       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
16113         {
16114           lcl_eid_set = 1;
16115         }
16116       else if (unformat (input, "vrf %d", &dp_table))
16117         ;
16118       else if (unformat (input, "bd %d", &dp_table))
16119         ;
16120       else if (unformat (input, "vni %d", &vni))
16121         ;
16122       else if (unformat (input, "w %d", &w))
16123         {
16124           if (!curr_rloc)
16125             {
16126               errmsg ("No RLOC configured for setting priority/weight!");
16127               return -99;
16128             }
16129           curr_rloc->weight = w;
16130         }
16131       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16132                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16133         {
16134           rloc.is_ip4 = 1;
16135
16136           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16137           rloc.weight = 0;
16138           vec_add1 (lcl_locs, rloc);
16139
16140           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16141           vec_add1 (rmt_locs, rloc);
16142           /* weight saved in rmt loc */
16143           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16144         }
16145       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16146                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16147         {
16148           rloc.is_ip4 = 0;
16149           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16150           rloc.weight = 0;
16151           vec_add1 (lcl_locs, rloc);
16152
16153           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16154           vec_add1 (rmt_locs, rloc);
16155           /* weight saved in rmt loc */
16156           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16157         }
16158       else if (unformat (input, "action %d", &action))
16159         {
16160           ;
16161         }
16162       else
16163         {
16164           clib_warning ("parse error '%U'", format_unformat_error, input);
16165           return -99;
16166         }
16167     }
16168
16169   if (!rmt_eid_set)
16170     {
16171       errmsg ("remote eid addresses not set");
16172       return -99;
16173     }
16174
16175   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16176     {
16177       errmsg ("eid types don't match");
16178       return -99;
16179     }
16180
16181   if (0 == rmt_locs && (u32) ~ 0 == action)
16182     {
16183       errmsg ("action not set for negative mapping");
16184       return -99;
16185     }
16186
16187   /* Construct the API message */
16188   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16189       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16190
16191   mp->is_add = is_add;
16192   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16193   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16194   mp->eid_type = rmt_eid->type;
16195   mp->dp_table = clib_host_to_net_u32 (dp_table);
16196   mp->vni = clib_host_to_net_u32 (vni);
16197   mp->rmt_len = rmt_eid->len;
16198   mp->lcl_len = lcl_eid->len;
16199   mp->action = action;
16200
16201   if (0 != rmt_locs && 0 != lcl_locs)
16202     {
16203       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16204       clib_memcpy (mp->locs, lcl_locs,
16205                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16206
16207       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16208       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16209                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16210     }
16211   vec_free (lcl_locs);
16212   vec_free (rmt_locs);
16213
16214   /* send it... */
16215   S (mp);
16216
16217   /* Wait for a reply... */
16218   W (ret);
16219   return ret;
16220 }
16221
16222 static int
16223 api_one_add_del_map_server (vat_main_t * vam)
16224 {
16225   unformat_input_t *input = vam->input;
16226   vl_api_one_add_del_map_server_t *mp;
16227   u8 is_add = 1;
16228   u8 ipv4_set = 0;
16229   u8 ipv6_set = 0;
16230   ip4_address_t ipv4;
16231   ip6_address_t ipv6;
16232   int ret;
16233
16234   /* Parse args required to build the message */
16235   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16236     {
16237       if (unformat (input, "del"))
16238         {
16239           is_add = 0;
16240         }
16241       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16242         {
16243           ipv4_set = 1;
16244         }
16245       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16246         {
16247           ipv6_set = 1;
16248         }
16249       else
16250         break;
16251     }
16252
16253   if (ipv4_set && ipv6_set)
16254     {
16255       errmsg ("both eid v4 and v6 addresses set");
16256       return -99;
16257     }
16258
16259   if (!ipv4_set && !ipv6_set)
16260     {
16261       errmsg ("eid addresses not set");
16262       return -99;
16263     }
16264
16265   /* Construct the API message */
16266   M (ONE_ADD_DEL_MAP_SERVER, mp);
16267
16268   mp->is_add = is_add;
16269   if (ipv6_set)
16270     {
16271       mp->is_ipv6 = 1;
16272       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16273     }
16274   else
16275     {
16276       mp->is_ipv6 = 0;
16277       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16278     }
16279
16280   /* send it... */
16281   S (mp);
16282
16283   /* Wait for a reply... */
16284   W (ret);
16285   return ret;
16286 }
16287
16288 #define api_lisp_add_del_map_server api_one_add_del_map_server
16289
16290 static int
16291 api_one_add_del_map_resolver (vat_main_t * vam)
16292 {
16293   unformat_input_t *input = vam->input;
16294   vl_api_one_add_del_map_resolver_t *mp;
16295   u8 is_add = 1;
16296   u8 ipv4_set = 0;
16297   u8 ipv6_set = 0;
16298   ip4_address_t ipv4;
16299   ip6_address_t ipv6;
16300   int ret;
16301
16302   /* Parse args required to build the message */
16303   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16304     {
16305       if (unformat (input, "del"))
16306         {
16307           is_add = 0;
16308         }
16309       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16310         {
16311           ipv4_set = 1;
16312         }
16313       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16314         {
16315           ipv6_set = 1;
16316         }
16317       else
16318         break;
16319     }
16320
16321   if (ipv4_set && ipv6_set)
16322     {
16323       errmsg ("both eid v4 and v6 addresses set");
16324       return -99;
16325     }
16326
16327   if (!ipv4_set && !ipv6_set)
16328     {
16329       errmsg ("eid addresses not set");
16330       return -99;
16331     }
16332
16333   /* Construct the API message */
16334   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16335
16336   mp->is_add = is_add;
16337   if (ipv6_set)
16338     {
16339       mp->is_ipv6 = 1;
16340       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16341     }
16342   else
16343     {
16344       mp->is_ipv6 = 0;
16345       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16346     }
16347
16348   /* send it... */
16349   S (mp);
16350
16351   /* Wait for a reply... */
16352   W (ret);
16353   return ret;
16354 }
16355
16356 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16357
16358 static int
16359 api_lisp_gpe_enable_disable (vat_main_t * vam)
16360 {
16361   unformat_input_t *input = vam->input;
16362   vl_api_gpe_enable_disable_t *mp;
16363   u8 is_set = 0;
16364   u8 is_en = 1;
16365   int ret;
16366
16367   /* Parse args required to build the message */
16368   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16369     {
16370       if (unformat (input, "enable"))
16371         {
16372           is_set = 1;
16373           is_en = 1;
16374         }
16375       else if (unformat (input, "disable"))
16376         {
16377           is_set = 1;
16378           is_en = 0;
16379         }
16380       else
16381         break;
16382     }
16383
16384   if (is_set == 0)
16385     {
16386       errmsg ("Value not set");
16387       return -99;
16388     }
16389
16390   /* Construct the API message */
16391   M (GPE_ENABLE_DISABLE, mp);
16392
16393   mp->is_en = is_en;
16394
16395   /* send it... */
16396   S (mp);
16397
16398   /* Wait for a reply... */
16399   W (ret);
16400   return ret;
16401 }
16402
16403 static int
16404 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16405 {
16406   unformat_input_t *input = vam->input;
16407   vl_api_one_rloc_probe_enable_disable_t *mp;
16408   u8 is_set = 0;
16409   u8 is_en = 0;
16410   int ret;
16411
16412   /* Parse args required to build the message */
16413   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16414     {
16415       if (unformat (input, "enable"))
16416         {
16417           is_set = 1;
16418           is_en = 1;
16419         }
16420       else if (unformat (input, "disable"))
16421         is_set = 1;
16422       else
16423         break;
16424     }
16425
16426   if (!is_set)
16427     {
16428       errmsg ("Value not set");
16429       return -99;
16430     }
16431
16432   /* Construct the API message */
16433   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16434
16435   mp->is_enabled = is_en;
16436
16437   /* send it... */
16438   S (mp);
16439
16440   /* Wait for a reply... */
16441   W (ret);
16442   return ret;
16443 }
16444
16445 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16446
16447 static int
16448 api_one_map_register_enable_disable (vat_main_t * vam)
16449 {
16450   unformat_input_t *input = vam->input;
16451   vl_api_one_map_register_enable_disable_t *mp;
16452   u8 is_set = 0;
16453   u8 is_en = 0;
16454   int ret;
16455
16456   /* Parse args required to build the message */
16457   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16458     {
16459       if (unformat (input, "enable"))
16460         {
16461           is_set = 1;
16462           is_en = 1;
16463         }
16464       else if (unformat (input, "disable"))
16465         is_set = 1;
16466       else
16467         break;
16468     }
16469
16470   if (!is_set)
16471     {
16472       errmsg ("Value not set");
16473       return -99;
16474     }
16475
16476   /* Construct the API message */
16477   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16478
16479   mp->is_enabled = is_en;
16480
16481   /* send it... */
16482   S (mp);
16483
16484   /* Wait for a reply... */
16485   W (ret);
16486   return ret;
16487 }
16488
16489 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16490
16491 static int
16492 api_one_enable_disable (vat_main_t * vam)
16493 {
16494   unformat_input_t *input = vam->input;
16495   vl_api_one_enable_disable_t *mp;
16496   u8 is_set = 0;
16497   u8 is_en = 0;
16498   int ret;
16499
16500   /* Parse args required to build the message */
16501   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16502     {
16503       if (unformat (input, "enable"))
16504         {
16505           is_set = 1;
16506           is_en = 1;
16507         }
16508       else if (unformat (input, "disable"))
16509         {
16510           is_set = 1;
16511         }
16512       else
16513         break;
16514     }
16515
16516   if (!is_set)
16517     {
16518       errmsg ("Value not set");
16519       return -99;
16520     }
16521
16522   /* Construct the API message */
16523   M (ONE_ENABLE_DISABLE, mp);
16524
16525   mp->is_en = is_en;
16526
16527   /* send it... */
16528   S (mp);
16529
16530   /* Wait for a reply... */
16531   W (ret);
16532   return ret;
16533 }
16534
16535 #define api_lisp_enable_disable api_one_enable_disable
16536
16537 static int
16538 api_one_enable_disable_xtr_mode (vat_main_t * vam)
16539 {
16540   unformat_input_t *input = vam->input;
16541   vl_api_one_enable_disable_xtr_mode_t *mp;
16542   u8 is_set = 0;
16543   u8 is_en = 0;
16544   int ret;
16545
16546   /* Parse args required to build the message */
16547   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16548     {
16549       if (unformat (input, "enable"))
16550         {
16551           is_set = 1;
16552           is_en = 1;
16553         }
16554       else if (unformat (input, "disable"))
16555         {
16556           is_set = 1;
16557         }
16558       else
16559         break;
16560     }
16561
16562   if (!is_set)
16563     {
16564       errmsg ("Value not set");
16565       return -99;
16566     }
16567
16568   /* Construct the API message */
16569   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16570
16571   mp->is_en = is_en;
16572
16573   /* send it... */
16574   S (mp);
16575
16576   /* Wait for a reply... */
16577   W (ret);
16578   return ret;
16579 }
16580
16581 static int
16582 api_one_show_xtr_mode (vat_main_t * vam)
16583 {
16584   vl_api_one_show_xtr_mode_t *mp;
16585   int ret;
16586
16587   /* Construct the API message */
16588   M (ONE_SHOW_XTR_MODE, mp);
16589
16590   /* send it... */
16591   S (mp);
16592
16593   /* Wait for a reply... */
16594   W (ret);
16595   return ret;
16596 }
16597
16598 static int
16599 api_one_enable_disable_pitr_mode (vat_main_t * vam)
16600 {
16601   unformat_input_t *input = vam->input;
16602   vl_api_one_enable_disable_pitr_mode_t *mp;
16603   u8 is_set = 0;
16604   u8 is_en = 0;
16605   int ret;
16606
16607   /* Parse args required to build the message */
16608   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16609     {
16610       if (unformat (input, "enable"))
16611         {
16612           is_set = 1;
16613           is_en = 1;
16614         }
16615       else if (unformat (input, "disable"))
16616         {
16617           is_set = 1;
16618         }
16619       else
16620         break;
16621     }
16622
16623   if (!is_set)
16624     {
16625       errmsg ("Value not set");
16626       return -99;
16627     }
16628
16629   /* Construct the API message */
16630   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
16631
16632   mp->is_en = is_en;
16633
16634   /* send it... */
16635   S (mp);
16636
16637   /* Wait for a reply... */
16638   W (ret);
16639   return ret;
16640 }
16641
16642 static int
16643 api_one_show_pitr_mode (vat_main_t * vam)
16644 {
16645   vl_api_one_show_pitr_mode_t *mp;
16646   int ret;
16647
16648   /* Construct the API message */
16649   M (ONE_SHOW_PITR_MODE, mp);
16650
16651   /* send it... */
16652   S (mp);
16653
16654   /* Wait for a reply... */
16655   W (ret);
16656   return ret;
16657 }
16658
16659 static int
16660 api_one_enable_disable_petr_mode (vat_main_t * vam)
16661 {
16662   unformat_input_t *input = vam->input;
16663   vl_api_one_enable_disable_petr_mode_t *mp;
16664   u8 is_set = 0;
16665   u8 is_en = 0;
16666   int ret;
16667
16668   /* Parse args required to build the message */
16669   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16670     {
16671       if (unformat (input, "enable"))
16672         {
16673           is_set = 1;
16674           is_en = 1;
16675         }
16676       else if (unformat (input, "disable"))
16677         {
16678           is_set = 1;
16679         }
16680       else
16681         break;
16682     }
16683
16684   if (!is_set)
16685     {
16686       errmsg ("Value not set");
16687       return -99;
16688     }
16689
16690   /* Construct the API message */
16691   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
16692
16693   mp->is_en = is_en;
16694
16695   /* send it... */
16696   S (mp);
16697
16698   /* Wait for a reply... */
16699   W (ret);
16700   return ret;
16701 }
16702
16703 static int
16704 api_one_show_petr_mode (vat_main_t * vam)
16705 {
16706   vl_api_one_show_petr_mode_t *mp;
16707   int ret;
16708
16709   /* Construct the API message */
16710   M (ONE_SHOW_PETR_MODE, mp);
16711
16712   /* send it... */
16713   S (mp);
16714
16715   /* Wait for a reply... */
16716   W (ret);
16717   return ret;
16718 }
16719
16720 static int
16721 api_show_one_map_register_state (vat_main_t * vam)
16722 {
16723   vl_api_show_one_map_register_state_t *mp;
16724   int ret;
16725
16726   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16727
16728   /* send */
16729   S (mp);
16730
16731   /* wait for reply */
16732   W (ret);
16733   return ret;
16734 }
16735
16736 #define api_show_lisp_map_register_state api_show_one_map_register_state
16737
16738 static int
16739 api_show_one_rloc_probe_state (vat_main_t * vam)
16740 {
16741   vl_api_show_one_rloc_probe_state_t *mp;
16742   int ret;
16743
16744   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16745
16746   /* send */
16747   S (mp);
16748
16749   /* wait for reply */
16750   W (ret);
16751   return ret;
16752 }
16753
16754 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16755
16756 static int
16757 api_one_add_del_ndp_entry (vat_main_t * vam)
16758 {
16759   vl_api_one_add_del_ndp_entry_t *mp;
16760   unformat_input_t *input = vam->input;
16761   u8 is_add = 1;
16762   u8 mac_set = 0;
16763   u8 bd_set = 0;
16764   u8 ip_set = 0;
16765   u8 mac[6] = { 0, };
16766   u8 ip6[16] = { 0, };
16767   u32 bd = ~0;
16768   int ret;
16769
16770   /* Parse args required to build the message */
16771   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16772     {
16773       if (unformat (input, "del"))
16774         is_add = 0;
16775       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16776         mac_set = 1;
16777       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16778         ip_set = 1;
16779       else if (unformat (input, "bd %d", &bd))
16780         bd_set = 1;
16781       else
16782         {
16783           errmsg ("parse error '%U'", format_unformat_error, input);
16784           return -99;
16785         }
16786     }
16787
16788   if (!bd_set || !ip_set || (!mac_set && is_add))
16789     {
16790       errmsg ("Missing BD, IP or MAC!");
16791       return -99;
16792     }
16793
16794   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16795   mp->is_add = is_add;
16796   clib_memcpy (mp->mac, mac, 6);
16797   mp->bd = clib_host_to_net_u32 (bd);
16798   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16799
16800   /* send */
16801   S (mp);
16802
16803   /* wait for reply */
16804   W (ret);
16805   return ret;
16806 }
16807
16808 static int
16809 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16810 {
16811   vl_api_one_add_del_l2_arp_entry_t *mp;
16812   unformat_input_t *input = vam->input;
16813   u8 is_add = 1;
16814   u8 mac_set = 0;
16815   u8 bd_set = 0;
16816   u8 ip_set = 0;
16817   u8 mac[6] = { 0, };
16818   u32 ip4 = 0, bd = ~0;
16819   int ret;
16820
16821   /* Parse args required to build the message */
16822   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16823     {
16824       if (unformat (input, "del"))
16825         is_add = 0;
16826       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16827         mac_set = 1;
16828       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16829         ip_set = 1;
16830       else if (unformat (input, "bd %d", &bd))
16831         bd_set = 1;
16832       else
16833         {
16834           errmsg ("parse error '%U'", format_unformat_error, input);
16835           return -99;
16836         }
16837     }
16838
16839   if (!bd_set || !ip_set || (!mac_set && is_add))
16840     {
16841       errmsg ("Missing BD, IP or MAC!");
16842       return -99;
16843     }
16844
16845   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16846   mp->is_add = is_add;
16847   clib_memcpy (mp->mac, mac, 6);
16848   mp->bd = clib_host_to_net_u32 (bd);
16849   mp->ip4 = ip4;
16850
16851   /* send */
16852   S (mp);
16853
16854   /* wait for reply */
16855   W (ret);
16856   return ret;
16857 }
16858
16859 static int
16860 api_one_ndp_bd_get (vat_main_t * vam)
16861 {
16862   vl_api_one_ndp_bd_get_t *mp;
16863   int ret;
16864
16865   M (ONE_NDP_BD_GET, mp);
16866
16867   /* send */
16868   S (mp);
16869
16870   /* wait for reply */
16871   W (ret);
16872   return ret;
16873 }
16874
16875 static int
16876 api_one_ndp_entries_get (vat_main_t * vam)
16877 {
16878   vl_api_one_ndp_entries_get_t *mp;
16879   unformat_input_t *input = vam->input;
16880   u8 bd_set = 0;
16881   u32 bd = ~0;
16882   int ret;
16883
16884   /* Parse args required to build the message */
16885   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16886     {
16887       if (unformat (input, "bd %d", &bd))
16888         bd_set = 1;
16889       else
16890         {
16891           errmsg ("parse error '%U'", format_unformat_error, input);
16892           return -99;
16893         }
16894     }
16895
16896   if (!bd_set)
16897     {
16898       errmsg ("Expected bridge domain!");
16899       return -99;
16900     }
16901
16902   M (ONE_NDP_ENTRIES_GET, mp);
16903   mp->bd = clib_host_to_net_u32 (bd);
16904
16905   /* send */
16906   S (mp);
16907
16908   /* wait for reply */
16909   W (ret);
16910   return ret;
16911 }
16912
16913 static int
16914 api_one_l2_arp_bd_get (vat_main_t * vam)
16915 {
16916   vl_api_one_l2_arp_bd_get_t *mp;
16917   int ret;
16918
16919   M (ONE_L2_ARP_BD_GET, mp);
16920
16921   /* send */
16922   S (mp);
16923
16924   /* wait for reply */
16925   W (ret);
16926   return ret;
16927 }
16928
16929 static int
16930 api_one_l2_arp_entries_get (vat_main_t * vam)
16931 {
16932   vl_api_one_l2_arp_entries_get_t *mp;
16933   unformat_input_t *input = vam->input;
16934   u8 bd_set = 0;
16935   u32 bd = ~0;
16936   int ret;
16937
16938   /* Parse args required to build the message */
16939   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16940     {
16941       if (unformat (input, "bd %d", &bd))
16942         bd_set = 1;
16943       else
16944         {
16945           errmsg ("parse error '%U'", format_unformat_error, input);
16946           return -99;
16947         }
16948     }
16949
16950   if (!bd_set)
16951     {
16952       errmsg ("Expected bridge domain!");
16953       return -99;
16954     }
16955
16956   M (ONE_L2_ARP_ENTRIES_GET, mp);
16957   mp->bd = clib_host_to_net_u32 (bd);
16958
16959   /* send */
16960   S (mp);
16961
16962   /* wait for reply */
16963   W (ret);
16964   return ret;
16965 }
16966
16967 static int
16968 api_one_stats_enable_disable (vat_main_t * vam)
16969 {
16970   vl_api_one_stats_enable_disable_t *mp;
16971   unformat_input_t *input = vam->input;
16972   u8 is_set = 0;
16973   u8 is_en = 0;
16974   int ret;
16975
16976   /* Parse args required to build the message */
16977   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16978     {
16979       if (unformat (input, "enable"))
16980         {
16981           is_set = 1;
16982           is_en = 1;
16983         }
16984       else if (unformat (input, "disable"))
16985         {
16986           is_set = 1;
16987         }
16988       else
16989         break;
16990     }
16991
16992   if (!is_set)
16993     {
16994       errmsg ("Value not set");
16995       return -99;
16996     }
16997
16998   M (ONE_STATS_ENABLE_DISABLE, mp);
16999   mp->is_en = is_en;
17000
17001   /* send */
17002   S (mp);
17003
17004   /* wait for reply */
17005   W (ret);
17006   return ret;
17007 }
17008
17009 static int
17010 api_show_one_stats_enable_disable (vat_main_t * vam)
17011 {
17012   vl_api_show_one_stats_enable_disable_t *mp;
17013   int ret;
17014
17015   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
17016
17017   /* send */
17018   S (mp);
17019
17020   /* wait for reply */
17021   W (ret);
17022   return ret;
17023 }
17024
17025 static int
17026 api_show_one_map_request_mode (vat_main_t * vam)
17027 {
17028   vl_api_show_one_map_request_mode_t *mp;
17029   int ret;
17030
17031   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
17032
17033   /* send */
17034   S (mp);
17035
17036   /* wait for reply */
17037   W (ret);
17038   return ret;
17039 }
17040
17041 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
17042
17043 static int
17044 api_one_map_request_mode (vat_main_t * vam)
17045 {
17046   unformat_input_t *input = vam->input;
17047   vl_api_one_map_request_mode_t *mp;
17048   u8 mode = 0;
17049   int ret;
17050
17051   /* Parse args required to build the message */
17052   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17053     {
17054       if (unformat (input, "dst-only"))
17055         mode = 0;
17056       else if (unformat (input, "src-dst"))
17057         mode = 1;
17058       else
17059         {
17060           errmsg ("parse error '%U'", format_unformat_error, input);
17061           return -99;
17062         }
17063     }
17064
17065   M (ONE_MAP_REQUEST_MODE, mp);
17066
17067   mp->mode = mode;
17068
17069   /* send */
17070   S (mp);
17071
17072   /* wait for reply */
17073   W (ret);
17074   return ret;
17075 }
17076
17077 #define api_lisp_map_request_mode api_one_map_request_mode
17078
17079 /**
17080  * Enable/disable ONE proxy ITR.
17081  *
17082  * @param vam vpp API test context
17083  * @return return code
17084  */
17085 static int
17086 api_one_pitr_set_locator_set (vat_main_t * vam)
17087 {
17088   u8 ls_name_set = 0;
17089   unformat_input_t *input = vam->input;
17090   vl_api_one_pitr_set_locator_set_t *mp;
17091   u8 is_add = 1;
17092   u8 *ls_name = 0;
17093   int ret;
17094
17095   /* Parse args required to build the message */
17096   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17097     {
17098       if (unformat (input, "del"))
17099         is_add = 0;
17100       else if (unformat (input, "locator-set %s", &ls_name))
17101         ls_name_set = 1;
17102       else
17103         {
17104           errmsg ("parse error '%U'", format_unformat_error, input);
17105           return -99;
17106         }
17107     }
17108
17109   if (!ls_name_set)
17110     {
17111       errmsg ("locator-set name not set!");
17112       return -99;
17113     }
17114
17115   M (ONE_PITR_SET_LOCATOR_SET, mp);
17116
17117   mp->is_add = is_add;
17118   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17119   vec_free (ls_name);
17120
17121   /* send */
17122   S (mp);
17123
17124   /* wait for reply */
17125   W (ret);
17126   return ret;
17127 }
17128
17129 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17130
17131 static int
17132 api_one_nsh_set_locator_set (vat_main_t * vam)
17133 {
17134   u8 ls_name_set = 0;
17135   unformat_input_t *input = vam->input;
17136   vl_api_one_nsh_set_locator_set_t *mp;
17137   u8 is_add = 1;
17138   u8 *ls_name = 0;
17139   int ret;
17140
17141   /* Parse args required to build the message */
17142   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17143     {
17144       if (unformat (input, "del"))
17145         is_add = 0;
17146       else if (unformat (input, "ls %s", &ls_name))
17147         ls_name_set = 1;
17148       else
17149         {
17150           errmsg ("parse error '%U'", format_unformat_error, input);
17151           return -99;
17152         }
17153     }
17154
17155   if (!ls_name_set && is_add)
17156     {
17157       errmsg ("locator-set name not set!");
17158       return -99;
17159     }
17160
17161   M (ONE_NSH_SET_LOCATOR_SET, mp);
17162
17163   mp->is_add = is_add;
17164   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17165   vec_free (ls_name);
17166
17167   /* send */
17168   S (mp);
17169
17170   /* wait for reply */
17171   W (ret);
17172   return ret;
17173 }
17174
17175 static int
17176 api_show_one_pitr (vat_main_t * vam)
17177 {
17178   vl_api_show_one_pitr_t *mp;
17179   int ret;
17180
17181   if (!vam->json_output)
17182     {
17183       print (vam->ofp, "%=20s", "lisp status:");
17184     }
17185
17186   M (SHOW_ONE_PITR, mp);
17187   /* send it... */
17188   S (mp);
17189
17190   /* Wait for a reply... */
17191   W (ret);
17192   return ret;
17193 }
17194
17195 #define api_show_lisp_pitr api_show_one_pitr
17196
17197 static int
17198 api_one_use_petr (vat_main_t * vam)
17199 {
17200   unformat_input_t *input = vam->input;
17201   vl_api_one_use_petr_t *mp;
17202   u8 is_add = 0;
17203   ip_address_t ip;
17204   int ret;
17205
17206   memset (&ip, 0, sizeof (ip));
17207
17208   /* Parse args required to build the message */
17209   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17210     {
17211       if (unformat (input, "disable"))
17212         is_add = 0;
17213       else
17214         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17215         {
17216           is_add = 1;
17217           ip_addr_version (&ip) = IP4;
17218         }
17219       else
17220         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17221         {
17222           is_add = 1;
17223           ip_addr_version (&ip) = IP6;
17224         }
17225       else
17226         {
17227           errmsg ("parse error '%U'", format_unformat_error, input);
17228           return -99;
17229         }
17230     }
17231
17232   M (ONE_USE_PETR, mp);
17233
17234   mp->is_add = is_add;
17235   if (is_add)
17236     {
17237       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17238       if (mp->is_ip4)
17239         clib_memcpy (mp->address, &ip, 4);
17240       else
17241         clib_memcpy (mp->address, &ip, 16);
17242     }
17243
17244   /* send */
17245   S (mp);
17246
17247   /* wait for reply */
17248   W (ret);
17249   return ret;
17250 }
17251
17252 #define api_lisp_use_petr api_one_use_petr
17253
17254 static int
17255 api_show_one_nsh_mapping (vat_main_t * vam)
17256 {
17257   vl_api_show_one_use_petr_t *mp;
17258   int ret;
17259
17260   if (!vam->json_output)
17261     {
17262       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17263     }
17264
17265   M (SHOW_ONE_NSH_MAPPING, mp);
17266   /* send it... */
17267   S (mp);
17268
17269   /* Wait for a reply... */
17270   W (ret);
17271   return ret;
17272 }
17273
17274 static int
17275 api_show_one_use_petr (vat_main_t * vam)
17276 {
17277   vl_api_show_one_use_petr_t *mp;
17278   int ret;
17279
17280   if (!vam->json_output)
17281     {
17282       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17283     }
17284
17285   M (SHOW_ONE_USE_PETR, mp);
17286   /* send it... */
17287   S (mp);
17288
17289   /* Wait for a reply... */
17290   W (ret);
17291   return ret;
17292 }
17293
17294 #define api_show_lisp_use_petr api_show_one_use_petr
17295
17296 /**
17297  * Add/delete mapping between vni and vrf
17298  */
17299 static int
17300 api_one_eid_table_add_del_map (vat_main_t * vam)
17301 {
17302   unformat_input_t *input = vam->input;
17303   vl_api_one_eid_table_add_del_map_t *mp;
17304   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17305   u32 vni, vrf, bd_index;
17306   int ret;
17307
17308   /* Parse args required to build the message */
17309   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17310     {
17311       if (unformat (input, "del"))
17312         is_add = 0;
17313       else if (unformat (input, "vrf %d", &vrf))
17314         vrf_set = 1;
17315       else if (unformat (input, "bd_index %d", &bd_index))
17316         bd_index_set = 1;
17317       else if (unformat (input, "vni %d", &vni))
17318         vni_set = 1;
17319       else
17320         break;
17321     }
17322
17323   if (!vni_set || (!vrf_set && !bd_index_set))
17324     {
17325       errmsg ("missing arguments!");
17326       return -99;
17327     }
17328
17329   if (vrf_set && bd_index_set)
17330     {
17331       errmsg ("error: both vrf and bd entered!");
17332       return -99;
17333     }
17334
17335   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
17336
17337   mp->is_add = is_add;
17338   mp->vni = htonl (vni);
17339   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
17340   mp->is_l2 = bd_index_set;
17341
17342   /* send */
17343   S (mp);
17344
17345   /* wait for reply */
17346   W (ret);
17347   return ret;
17348 }
17349
17350 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
17351
17352 uword
17353 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
17354 {
17355   u32 *action = va_arg (*args, u32 *);
17356   u8 *s = 0;
17357
17358   if (unformat (input, "%s", &s))
17359     {
17360       if (!strcmp ((char *) s, "no-action"))
17361         action[0] = 0;
17362       else if (!strcmp ((char *) s, "natively-forward"))
17363         action[0] = 1;
17364       else if (!strcmp ((char *) s, "send-map-request"))
17365         action[0] = 2;
17366       else if (!strcmp ((char *) s, "drop"))
17367         action[0] = 3;
17368       else
17369         {
17370           clib_warning ("invalid action: '%s'", s);
17371           action[0] = 3;
17372         }
17373     }
17374   else
17375     return 0;
17376
17377   vec_free (s);
17378   return 1;
17379 }
17380
17381 /**
17382  * Add/del remote mapping to/from ONE control plane
17383  *
17384  * @param vam vpp API test context
17385  * @return return code
17386  */
17387 static int
17388 api_one_add_del_remote_mapping (vat_main_t * vam)
17389 {
17390   unformat_input_t *input = vam->input;
17391   vl_api_one_add_del_remote_mapping_t *mp;
17392   u32 vni = 0;
17393   lisp_eid_vat_t _eid, *eid = &_eid;
17394   lisp_eid_vat_t _seid, *seid = &_seid;
17395   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
17396   u32 action = ~0, p, w, data_len;
17397   ip4_address_t rloc4;
17398   ip6_address_t rloc6;
17399   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
17400   int ret;
17401
17402   memset (&rloc, 0, sizeof (rloc));
17403
17404   /* Parse args required to build the message */
17405   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17406     {
17407       if (unformat (input, "del-all"))
17408         {
17409           del_all = 1;
17410         }
17411       else if (unformat (input, "del"))
17412         {
17413           is_add = 0;
17414         }
17415       else if (unformat (input, "add"))
17416         {
17417           is_add = 1;
17418         }
17419       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17420         {
17421           eid_set = 1;
17422         }
17423       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
17424         {
17425           seid_set = 1;
17426         }
17427       else if (unformat (input, "vni %d", &vni))
17428         {
17429           ;
17430         }
17431       else if (unformat (input, "p %d w %d", &p, &w))
17432         {
17433           if (!curr_rloc)
17434             {
17435               errmsg ("No RLOC configured for setting priority/weight!");
17436               return -99;
17437             }
17438           curr_rloc->priority = p;
17439           curr_rloc->weight = w;
17440         }
17441       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
17442         {
17443           rloc.is_ip4 = 1;
17444           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17445           vec_add1 (rlocs, rloc);
17446           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17447         }
17448       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
17449         {
17450           rloc.is_ip4 = 0;
17451           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17452           vec_add1 (rlocs, rloc);
17453           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17454         }
17455       else if (unformat (input, "action %U",
17456                          unformat_negative_mapping_action, &action))
17457         {
17458           ;
17459         }
17460       else
17461         {
17462           clib_warning ("parse error '%U'", format_unformat_error, input);
17463           return -99;
17464         }
17465     }
17466
17467   if (0 == eid_set)
17468     {
17469       errmsg ("missing params!");
17470       return -99;
17471     }
17472
17473   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17474     {
17475       errmsg ("no action set for negative map-reply!");
17476       return -99;
17477     }
17478
17479   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17480
17481   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17482   mp->is_add = is_add;
17483   mp->vni = htonl (vni);
17484   mp->action = (u8) action;
17485   mp->is_src_dst = seid_set;
17486   mp->eid_len = eid->len;
17487   mp->seid_len = seid->len;
17488   mp->del_all = del_all;
17489   mp->eid_type = eid->type;
17490   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17491   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17492
17493   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17494   clib_memcpy (mp->rlocs, rlocs, data_len);
17495   vec_free (rlocs);
17496
17497   /* send it... */
17498   S (mp);
17499
17500   /* Wait for a reply... */
17501   W (ret);
17502   return ret;
17503 }
17504
17505 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17506
17507 /**
17508  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17509  * forwarding entries in data-plane accordingly.
17510  *
17511  * @param vam vpp API test context
17512  * @return return code
17513  */
17514 static int
17515 api_one_add_del_adjacency (vat_main_t * vam)
17516 {
17517   unformat_input_t *input = vam->input;
17518   vl_api_one_add_del_adjacency_t *mp;
17519   u32 vni = 0;
17520   ip4_address_t leid4, reid4;
17521   ip6_address_t leid6, reid6;
17522   u8 reid_mac[6] = { 0 };
17523   u8 leid_mac[6] = { 0 };
17524   u8 reid_type, leid_type;
17525   u32 leid_len = 0, reid_len = 0, len;
17526   u8 is_add = 1;
17527   int ret;
17528
17529   leid_type = reid_type = (u8) ~ 0;
17530
17531   /* Parse args required to build the message */
17532   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17533     {
17534       if (unformat (input, "del"))
17535         {
17536           is_add = 0;
17537         }
17538       else if (unformat (input, "add"))
17539         {
17540           is_add = 1;
17541         }
17542       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17543                          &reid4, &len))
17544         {
17545           reid_type = 0;        /* ipv4 */
17546           reid_len = len;
17547         }
17548       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17549                          &reid6, &len))
17550         {
17551           reid_type = 1;        /* ipv6 */
17552           reid_len = len;
17553         }
17554       else if (unformat (input, "reid %U", unformat_ethernet_address,
17555                          reid_mac))
17556         {
17557           reid_type = 2;        /* mac */
17558         }
17559       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17560                          &leid4, &len))
17561         {
17562           leid_type = 0;        /* ipv4 */
17563           leid_len = len;
17564         }
17565       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17566                          &leid6, &len))
17567         {
17568           leid_type = 1;        /* ipv6 */
17569           leid_len = len;
17570         }
17571       else if (unformat (input, "leid %U", unformat_ethernet_address,
17572                          leid_mac))
17573         {
17574           leid_type = 2;        /* mac */
17575         }
17576       else if (unformat (input, "vni %d", &vni))
17577         {
17578           ;
17579         }
17580       else
17581         {
17582           errmsg ("parse error '%U'", format_unformat_error, input);
17583           return -99;
17584         }
17585     }
17586
17587   if ((u8) ~ 0 == reid_type)
17588     {
17589       errmsg ("missing params!");
17590       return -99;
17591     }
17592
17593   if (leid_type != reid_type)
17594     {
17595       errmsg ("remote and local EIDs are of different types!");
17596       return -99;
17597     }
17598
17599   M (ONE_ADD_DEL_ADJACENCY, mp);
17600   mp->is_add = is_add;
17601   mp->vni = htonl (vni);
17602   mp->leid_len = leid_len;
17603   mp->reid_len = reid_len;
17604   mp->eid_type = reid_type;
17605
17606   switch (mp->eid_type)
17607     {
17608     case 0:
17609       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17610       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17611       break;
17612     case 1:
17613       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17614       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17615       break;
17616     case 2:
17617       clib_memcpy (mp->leid, leid_mac, 6);
17618       clib_memcpy (mp->reid, reid_mac, 6);
17619       break;
17620     default:
17621       errmsg ("unknown EID type %d!", mp->eid_type);
17622       return 0;
17623     }
17624
17625   /* send it... */
17626   S (mp);
17627
17628   /* Wait for a reply... */
17629   W (ret);
17630   return ret;
17631 }
17632
17633 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17634
17635 uword
17636 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17637 {
17638   u32 *mode = va_arg (*args, u32 *);
17639
17640   if (unformat (input, "lisp"))
17641     *mode = 0;
17642   else if (unformat (input, "vxlan"))
17643     *mode = 1;
17644   else
17645     return 0;
17646
17647   return 1;
17648 }
17649
17650 static int
17651 api_gpe_get_encap_mode (vat_main_t * vam)
17652 {
17653   vl_api_gpe_get_encap_mode_t *mp;
17654   int ret;
17655
17656   /* Construct the API message */
17657   M (GPE_GET_ENCAP_MODE, mp);
17658
17659   /* send it... */
17660   S (mp);
17661
17662   /* Wait for a reply... */
17663   W (ret);
17664   return ret;
17665 }
17666
17667 static int
17668 api_gpe_set_encap_mode (vat_main_t * vam)
17669 {
17670   unformat_input_t *input = vam->input;
17671   vl_api_gpe_set_encap_mode_t *mp;
17672   int ret;
17673   u32 mode = 0;
17674
17675   /* Parse args required to build the message */
17676   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17677     {
17678       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17679         ;
17680       else
17681         break;
17682     }
17683
17684   /* Construct the API message */
17685   M (GPE_SET_ENCAP_MODE, mp);
17686
17687   mp->mode = mode;
17688
17689   /* send it... */
17690   S (mp);
17691
17692   /* Wait for a reply... */
17693   W (ret);
17694   return ret;
17695 }
17696
17697 static int
17698 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17699 {
17700   unformat_input_t *input = vam->input;
17701   vl_api_gpe_add_del_iface_t *mp;
17702   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17703   u32 dp_table = 0, vni = 0;
17704   int ret;
17705
17706   /* Parse args required to build the message */
17707   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17708     {
17709       if (unformat (input, "up"))
17710         {
17711           action_set = 1;
17712           is_add = 1;
17713         }
17714       else if (unformat (input, "down"))
17715         {
17716           action_set = 1;
17717           is_add = 0;
17718         }
17719       else if (unformat (input, "table_id %d", &dp_table))
17720         {
17721           dp_table_set = 1;
17722         }
17723       else if (unformat (input, "bd_id %d", &dp_table))
17724         {
17725           dp_table_set = 1;
17726           is_l2 = 1;
17727         }
17728       else if (unformat (input, "vni %d", &vni))
17729         {
17730           vni_set = 1;
17731         }
17732       else
17733         break;
17734     }
17735
17736   if (action_set == 0)
17737     {
17738       errmsg ("Action not set");
17739       return -99;
17740     }
17741   if (dp_table_set == 0 || vni_set == 0)
17742     {
17743       errmsg ("vni and dp_table must be set");
17744       return -99;
17745     }
17746
17747   /* Construct the API message */
17748   M (GPE_ADD_DEL_IFACE, mp);
17749
17750   mp->is_add = is_add;
17751   mp->dp_table = clib_host_to_net_u32 (dp_table);
17752   mp->is_l2 = is_l2;
17753   mp->vni = clib_host_to_net_u32 (vni);
17754
17755   /* send it... */
17756   S (mp);
17757
17758   /* Wait for a reply... */
17759   W (ret);
17760   return ret;
17761 }
17762
17763 static int
17764 api_one_map_register_fallback_threshold (vat_main_t * vam)
17765 {
17766   unformat_input_t *input = vam->input;
17767   vl_api_one_map_register_fallback_threshold_t *mp;
17768   u32 value = 0;
17769   u8 is_set = 0;
17770   int ret;
17771
17772   /* Parse args required to build the message */
17773   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17774     {
17775       if (unformat (input, "%u", &value))
17776         is_set = 1;
17777       else
17778         {
17779           clib_warning ("parse error '%U'", format_unformat_error, input);
17780           return -99;
17781         }
17782     }
17783
17784   if (!is_set)
17785     {
17786       errmsg ("fallback threshold value is missing!");
17787       return -99;
17788     }
17789
17790   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17791   mp->value = clib_host_to_net_u32 (value);
17792
17793   /* send it... */
17794   S (mp);
17795
17796   /* Wait for a reply... */
17797   W (ret);
17798   return ret;
17799 }
17800
17801 static int
17802 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17803 {
17804   vl_api_show_one_map_register_fallback_threshold_t *mp;
17805   int ret;
17806
17807   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17808
17809   /* send it... */
17810   S (mp);
17811
17812   /* Wait for a reply... */
17813   W (ret);
17814   return ret;
17815 }
17816
17817 uword
17818 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17819 {
17820   u32 *proto = va_arg (*args, u32 *);
17821
17822   if (unformat (input, "udp"))
17823     *proto = 1;
17824   else if (unformat (input, "api"))
17825     *proto = 2;
17826   else
17827     return 0;
17828
17829   return 1;
17830 }
17831
17832 static int
17833 api_one_set_transport_protocol (vat_main_t * vam)
17834 {
17835   unformat_input_t *input = vam->input;
17836   vl_api_one_set_transport_protocol_t *mp;
17837   u8 is_set = 0;
17838   u32 protocol = 0;
17839   int ret;
17840
17841   /* Parse args required to build the message */
17842   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17843     {
17844       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17845         is_set = 1;
17846       else
17847         {
17848           clib_warning ("parse error '%U'", format_unformat_error, input);
17849           return -99;
17850         }
17851     }
17852
17853   if (!is_set)
17854     {
17855       errmsg ("Transport protocol missing!");
17856       return -99;
17857     }
17858
17859   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17860   mp->protocol = (u8) protocol;
17861
17862   /* send it... */
17863   S (mp);
17864
17865   /* Wait for a reply... */
17866   W (ret);
17867   return ret;
17868 }
17869
17870 static int
17871 api_one_get_transport_protocol (vat_main_t * vam)
17872 {
17873   vl_api_one_get_transport_protocol_t *mp;
17874   int ret;
17875
17876   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17877
17878   /* send it... */
17879   S (mp);
17880
17881   /* Wait for a reply... */
17882   W (ret);
17883   return ret;
17884 }
17885
17886 static int
17887 api_one_map_register_set_ttl (vat_main_t * vam)
17888 {
17889   unformat_input_t *input = vam->input;
17890   vl_api_one_map_register_set_ttl_t *mp;
17891   u32 ttl = 0;
17892   u8 is_set = 0;
17893   int ret;
17894
17895   /* Parse args required to build the message */
17896   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17897     {
17898       if (unformat (input, "%u", &ttl))
17899         is_set = 1;
17900       else
17901         {
17902           clib_warning ("parse error '%U'", format_unformat_error, input);
17903           return -99;
17904         }
17905     }
17906
17907   if (!is_set)
17908     {
17909       errmsg ("TTL value missing!");
17910       return -99;
17911     }
17912
17913   M (ONE_MAP_REGISTER_SET_TTL, mp);
17914   mp->ttl = clib_host_to_net_u32 (ttl);
17915
17916   /* send it... */
17917   S (mp);
17918
17919   /* Wait for a reply... */
17920   W (ret);
17921   return ret;
17922 }
17923
17924 static int
17925 api_show_one_map_register_ttl (vat_main_t * vam)
17926 {
17927   vl_api_show_one_map_register_ttl_t *mp;
17928   int ret;
17929
17930   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17931
17932   /* send it... */
17933   S (mp);
17934
17935   /* Wait for a reply... */
17936   W (ret);
17937   return ret;
17938 }
17939
17940 /**
17941  * Add/del map request itr rlocs from ONE control plane and updates
17942  *
17943  * @param vam vpp API test context
17944  * @return return code
17945  */
17946 static int
17947 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17948 {
17949   unformat_input_t *input = vam->input;
17950   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17951   u8 *locator_set_name = 0;
17952   u8 locator_set_name_set = 0;
17953   u8 is_add = 1;
17954   int ret;
17955
17956   /* Parse args required to build the message */
17957   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17958     {
17959       if (unformat (input, "del"))
17960         {
17961           is_add = 0;
17962         }
17963       else if (unformat (input, "%_%v%_", &locator_set_name))
17964         {
17965           locator_set_name_set = 1;
17966         }
17967       else
17968         {
17969           clib_warning ("parse error '%U'", format_unformat_error, input);
17970           return -99;
17971         }
17972     }
17973
17974   if (is_add && !locator_set_name_set)
17975     {
17976       errmsg ("itr-rloc is not set!");
17977       return -99;
17978     }
17979
17980   if (is_add && vec_len (locator_set_name) > 64)
17981     {
17982       errmsg ("itr-rloc locator-set name too long");
17983       vec_free (locator_set_name);
17984       return -99;
17985     }
17986
17987   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17988   mp->is_add = is_add;
17989   if (is_add)
17990     {
17991       clib_memcpy (mp->locator_set_name, locator_set_name,
17992                    vec_len (locator_set_name));
17993     }
17994   else
17995     {
17996       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17997     }
17998   vec_free (locator_set_name);
17999
18000   /* send it... */
18001   S (mp);
18002
18003   /* Wait for a reply... */
18004   W (ret);
18005   return ret;
18006 }
18007
18008 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18009
18010 static int
18011 api_one_locator_dump (vat_main_t * vam)
18012 {
18013   unformat_input_t *input = vam->input;
18014   vl_api_one_locator_dump_t *mp;
18015   vl_api_control_ping_t *mp_ping;
18016   u8 is_index_set = 0, is_name_set = 0;
18017   u8 *ls_name = 0;
18018   u32 ls_index = ~0;
18019   int ret;
18020
18021   /* Parse args required to build the message */
18022   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18023     {
18024       if (unformat (input, "ls_name %_%v%_", &ls_name))
18025         {
18026           is_name_set = 1;
18027         }
18028       else if (unformat (input, "ls_index %d", &ls_index))
18029         {
18030           is_index_set = 1;
18031         }
18032       else
18033         {
18034           errmsg ("parse error '%U'", format_unformat_error, input);
18035           return -99;
18036         }
18037     }
18038
18039   if (!is_index_set && !is_name_set)
18040     {
18041       errmsg ("error: expected one of index or name!");
18042       return -99;
18043     }
18044
18045   if (is_index_set && is_name_set)
18046     {
18047       errmsg ("error: only one param expected!");
18048       return -99;
18049     }
18050
18051   if (vec_len (ls_name) > 62)
18052     {
18053       errmsg ("error: locator set name too long!");
18054       return -99;
18055     }
18056
18057   if (!vam->json_output)
18058     {
18059       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
18060     }
18061
18062   M (ONE_LOCATOR_DUMP, mp);
18063   mp->is_index_set = is_index_set;
18064
18065   if (is_index_set)
18066     mp->ls_index = clib_host_to_net_u32 (ls_index);
18067   else
18068     {
18069       vec_add1 (ls_name, 0);
18070       strncpy ((char *) mp->ls_name, (char *) ls_name,
18071                sizeof (mp->ls_name) - 1);
18072     }
18073
18074   /* send it... */
18075   S (mp);
18076
18077   /* Use a control ping for synchronization */
18078   MPING (CONTROL_PING, mp_ping);
18079   S (mp_ping);
18080
18081   /* Wait for a reply... */
18082   W (ret);
18083   return ret;
18084 }
18085
18086 #define api_lisp_locator_dump api_one_locator_dump
18087
18088 static int
18089 api_one_locator_set_dump (vat_main_t * vam)
18090 {
18091   vl_api_one_locator_set_dump_t *mp;
18092   vl_api_control_ping_t *mp_ping;
18093   unformat_input_t *input = vam->input;
18094   u8 filter = 0;
18095   int ret;
18096
18097   /* Parse args required to build the message */
18098   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18099     {
18100       if (unformat (input, "local"))
18101         {
18102           filter = 1;
18103         }
18104       else if (unformat (input, "remote"))
18105         {
18106           filter = 2;
18107         }
18108       else
18109         {
18110           errmsg ("parse error '%U'", format_unformat_error, input);
18111           return -99;
18112         }
18113     }
18114
18115   if (!vam->json_output)
18116     {
18117       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
18118     }
18119
18120   M (ONE_LOCATOR_SET_DUMP, mp);
18121
18122   mp->filter = filter;
18123
18124   /* send it... */
18125   S (mp);
18126
18127   /* Use a control ping for synchronization */
18128   MPING (CONTROL_PING, mp_ping);
18129   S (mp_ping);
18130
18131   /* Wait for a reply... */
18132   W (ret);
18133   return ret;
18134 }
18135
18136 #define api_lisp_locator_set_dump api_one_locator_set_dump
18137
18138 static int
18139 api_one_eid_table_map_dump (vat_main_t * vam)
18140 {
18141   u8 is_l2 = 0;
18142   u8 mode_set = 0;
18143   unformat_input_t *input = vam->input;
18144   vl_api_one_eid_table_map_dump_t *mp;
18145   vl_api_control_ping_t *mp_ping;
18146   int ret;
18147
18148   /* Parse args required to build the message */
18149   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18150     {
18151       if (unformat (input, "l2"))
18152         {
18153           is_l2 = 1;
18154           mode_set = 1;
18155         }
18156       else if (unformat (input, "l3"))
18157         {
18158           is_l2 = 0;
18159           mode_set = 1;
18160         }
18161       else
18162         {
18163           errmsg ("parse error '%U'", format_unformat_error, input);
18164           return -99;
18165         }
18166     }
18167
18168   if (!mode_set)
18169     {
18170       errmsg ("expected one of 'l2' or 'l3' parameter!");
18171       return -99;
18172     }
18173
18174   if (!vam->json_output)
18175     {
18176       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18177     }
18178
18179   M (ONE_EID_TABLE_MAP_DUMP, mp);
18180   mp->is_l2 = is_l2;
18181
18182   /* send it... */
18183   S (mp);
18184
18185   /* Use a control ping for synchronization */
18186   MPING (CONTROL_PING, mp_ping);
18187   S (mp_ping);
18188
18189   /* Wait for a reply... */
18190   W (ret);
18191   return ret;
18192 }
18193
18194 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18195
18196 static int
18197 api_one_eid_table_vni_dump (vat_main_t * vam)
18198 {
18199   vl_api_one_eid_table_vni_dump_t *mp;
18200   vl_api_control_ping_t *mp_ping;
18201   int ret;
18202
18203   if (!vam->json_output)
18204     {
18205       print (vam->ofp, "VNI");
18206     }
18207
18208   M (ONE_EID_TABLE_VNI_DUMP, mp);
18209
18210   /* send it... */
18211   S (mp);
18212
18213   /* Use a control ping for synchronization */
18214   MPING (CONTROL_PING, mp_ping);
18215   S (mp_ping);
18216
18217   /* Wait for a reply... */
18218   W (ret);
18219   return ret;
18220 }
18221
18222 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18223
18224 static int
18225 api_one_eid_table_dump (vat_main_t * vam)
18226 {
18227   unformat_input_t *i = vam->input;
18228   vl_api_one_eid_table_dump_t *mp;
18229   vl_api_control_ping_t *mp_ping;
18230   struct in_addr ip4;
18231   struct in6_addr ip6;
18232   u8 mac[6];
18233   u8 eid_type = ~0, eid_set = 0;
18234   u32 prefix_length = ~0, t, vni = 0;
18235   u8 filter = 0;
18236   int ret;
18237   lisp_nsh_api_t nsh;
18238
18239   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18240     {
18241       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18242         {
18243           eid_set = 1;
18244           eid_type = 0;
18245           prefix_length = t;
18246         }
18247       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18248         {
18249           eid_set = 1;
18250           eid_type = 1;
18251           prefix_length = t;
18252         }
18253       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18254         {
18255           eid_set = 1;
18256           eid_type = 2;
18257         }
18258       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18259         {
18260           eid_set = 1;
18261           eid_type = 3;
18262         }
18263       else if (unformat (i, "vni %d", &t))
18264         {
18265           vni = t;
18266         }
18267       else if (unformat (i, "local"))
18268         {
18269           filter = 1;
18270         }
18271       else if (unformat (i, "remote"))
18272         {
18273           filter = 2;
18274         }
18275       else
18276         {
18277           errmsg ("parse error '%U'", format_unformat_error, i);
18278           return -99;
18279         }
18280     }
18281
18282   if (!vam->json_output)
18283     {
18284       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18285              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18286     }
18287
18288   M (ONE_EID_TABLE_DUMP, mp);
18289
18290   mp->filter = filter;
18291   if (eid_set)
18292     {
18293       mp->eid_set = 1;
18294       mp->vni = htonl (vni);
18295       mp->eid_type = eid_type;
18296       switch (eid_type)
18297         {
18298         case 0:
18299           mp->prefix_length = prefix_length;
18300           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
18301           break;
18302         case 1:
18303           mp->prefix_length = prefix_length;
18304           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18305           break;
18306         case 2:
18307           clib_memcpy (mp->eid, mac, sizeof (mac));
18308           break;
18309         case 3:
18310           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18311           break;
18312         default:
18313           errmsg ("unknown EID type %d!", eid_type);
18314           return -99;
18315         }
18316     }
18317
18318   /* send it... */
18319   S (mp);
18320
18321   /* Use a control ping for synchronization */
18322   MPING (CONTROL_PING, mp_ping);
18323   S (mp_ping);
18324
18325   /* Wait for a reply... */
18326   W (ret);
18327   return ret;
18328 }
18329
18330 #define api_lisp_eid_table_dump api_one_eid_table_dump
18331
18332 static int
18333 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
18334 {
18335   unformat_input_t *i = vam->input;
18336   vl_api_gpe_fwd_entries_get_t *mp;
18337   u8 vni_set = 0;
18338   u32 vni = ~0;
18339   int ret;
18340
18341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18342     {
18343       if (unformat (i, "vni %d", &vni))
18344         {
18345           vni_set = 1;
18346         }
18347       else
18348         {
18349           errmsg ("parse error '%U'", format_unformat_error, i);
18350           return -99;
18351         }
18352     }
18353
18354   if (!vni_set)
18355     {
18356       errmsg ("vni not set!");
18357       return -99;
18358     }
18359
18360   if (!vam->json_output)
18361     {
18362       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
18363              "leid", "reid");
18364     }
18365
18366   M (GPE_FWD_ENTRIES_GET, mp);
18367   mp->vni = clib_host_to_net_u32 (vni);
18368
18369   /* send it... */
18370   S (mp);
18371
18372   /* Wait for a reply... */
18373   W (ret);
18374   return ret;
18375 }
18376
18377 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
18378 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
18379 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
18380 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
18381 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
18382 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
18383 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
18384 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
18385
18386 static int
18387 api_one_adjacencies_get (vat_main_t * vam)
18388 {
18389   unformat_input_t *i = vam->input;
18390   vl_api_one_adjacencies_get_t *mp;
18391   u8 vni_set = 0;
18392   u32 vni = ~0;
18393   int ret;
18394
18395   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18396     {
18397       if (unformat (i, "vni %d", &vni))
18398         {
18399           vni_set = 1;
18400         }
18401       else
18402         {
18403           errmsg ("parse error '%U'", format_unformat_error, i);
18404           return -99;
18405         }
18406     }
18407
18408   if (!vni_set)
18409     {
18410       errmsg ("vni not set!");
18411       return -99;
18412     }
18413
18414   if (!vam->json_output)
18415     {
18416       print (vam->ofp, "%s %40s", "leid", "reid");
18417     }
18418
18419   M (ONE_ADJACENCIES_GET, mp);
18420   mp->vni = clib_host_to_net_u32 (vni);
18421
18422   /* send it... */
18423   S (mp);
18424
18425   /* Wait for a reply... */
18426   W (ret);
18427   return ret;
18428 }
18429
18430 #define api_lisp_adjacencies_get api_one_adjacencies_get
18431
18432 static int
18433 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
18434 {
18435   unformat_input_t *i = vam->input;
18436   vl_api_gpe_native_fwd_rpaths_get_t *mp;
18437   int ret;
18438   u8 ip_family_set = 0, is_ip4 = 1;
18439
18440   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18441     {
18442       if (unformat (i, "ip4"))
18443         {
18444           ip_family_set = 1;
18445           is_ip4 = 1;
18446         }
18447       else if (unformat (i, "ip6"))
18448         {
18449           ip_family_set = 1;
18450           is_ip4 = 0;
18451         }
18452       else
18453         {
18454           errmsg ("parse error '%U'", format_unformat_error, i);
18455           return -99;
18456         }
18457     }
18458
18459   if (!ip_family_set)
18460     {
18461       errmsg ("ip family not set!");
18462       return -99;
18463     }
18464
18465   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18466   mp->is_ip4 = is_ip4;
18467
18468   /* send it... */
18469   S (mp);
18470
18471   /* Wait for a reply... */
18472   W (ret);
18473   return ret;
18474 }
18475
18476 static int
18477 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18478 {
18479   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18480   int ret;
18481
18482   if (!vam->json_output)
18483     {
18484       print (vam->ofp, "VNIs");
18485     }
18486
18487   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18488
18489   /* send it... */
18490   S (mp);
18491
18492   /* Wait for a reply... */
18493   W (ret);
18494   return ret;
18495 }
18496
18497 static int
18498 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18499 {
18500   unformat_input_t *i = vam->input;
18501   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18502   int ret = 0;
18503   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18504   struct in_addr ip4;
18505   struct in6_addr ip6;
18506   u32 table_id = 0, nh_sw_if_index = ~0;
18507
18508   memset (&ip4, 0, sizeof (ip4));
18509   memset (&ip6, 0, sizeof (ip6));
18510
18511   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18512     {
18513       if (unformat (i, "del"))
18514         is_add = 0;
18515       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18516                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18517         {
18518           ip_set = 1;
18519           is_ip4 = 1;
18520         }
18521       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18522                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18523         {
18524           ip_set = 1;
18525           is_ip4 = 0;
18526         }
18527       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18528         {
18529           ip_set = 1;
18530           is_ip4 = 1;
18531           nh_sw_if_index = ~0;
18532         }
18533       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18534         {
18535           ip_set = 1;
18536           is_ip4 = 0;
18537           nh_sw_if_index = ~0;
18538         }
18539       else if (unformat (i, "table %d", &table_id))
18540         ;
18541       else
18542         {
18543           errmsg ("parse error '%U'", format_unformat_error, i);
18544           return -99;
18545         }
18546     }
18547
18548   if (!ip_set)
18549     {
18550       errmsg ("nh addr not set!");
18551       return -99;
18552     }
18553
18554   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18555   mp->is_add = is_add;
18556   mp->table_id = clib_host_to_net_u32 (table_id);
18557   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18558   mp->is_ip4 = is_ip4;
18559   if (is_ip4)
18560     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18561   else
18562     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18563
18564   /* send it... */
18565   S (mp);
18566
18567   /* Wait for a reply... */
18568   W (ret);
18569   return ret;
18570 }
18571
18572 static int
18573 api_one_map_server_dump (vat_main_t * vam)
18574 {
18575   vl_api_one_map_server_dump_t *mp;
18576   vl_api_control_ping_t *mp_ping;
18577   int ret;
18578
18579   if (!vam->json_output)
18580     {
18581       print (vam->ofp, "%=20s", "Map server");
18582     }
18583
18584   M (ONE_MAP_SERVER_DUMP, mp);
18585   /* send it... */
18586   S (mp);
18587
18588   /* Use a control ping for synchronization */
18589   MPING (CONTROL_PING, mp_ping);
18590   S (mp_ping);
18591
18592   /* Wait for a reply... */
18593   W (ret);
18594   return ret;
18595 }
18596
18597 #define api_lisp_map_server_dump api_one_map_server_dump
18598
18599 static int
18600 api_one_map_resolver_dump (vat_main_t * vam)
18601 {
18602   vl_api_one_map_resolver_dump_t *mp;
18603   vl_api_control_ping_t *mp_ping;
18604   int ret;
18605
18606   if (!vam->json_output)
18607     {
18608       print (vam->ofp, "%=20s", "Map resolver");
18609     }
18610
18611   M (ONE_MAP_RESOLVER_DUMP, mp);
18612   /* send it... */
18613   S (mp);
18614
18615   /* Use a control ping for synchronization */
18616   MPING (CONTROL_PING, mp_ping);
18617   S (mp_ping);
18618
18619   /* Wait for a reply... */
18620   W (ret);
18621   return ret;
18622 }
18623
18624 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18625
18626 static int
18627 api_one_stats_flush (vat_main_t * vam)
18628 {
18629   vl_api_one_stats_flush_t *mp;
18630   int ret = 0;
18631
18632   M (ONE_STATS_FLUSH, mp);
18633   S (mp);
18634   W (ret);
18635   return ret;
18636 }
18637
18638 static int
18639 api_one_stats_dump (vat_main_t * vam)
18640 {
18641   vl_api_one_stats_dump_t *mp;
18642   vl_api_control_ping_t *mp_ping;
18643   int ret;
18644
18645   M (ONE_STATS_DUMP, mp);
18646   /* send it... */
18647   S (mp);
18648
18649   /* Use a control ping for synchronization */
18650   MPING (CONTROL_PING, mp_ping);
18651   S (mp_ping);
18652
18653   /* Wait for a reply... */
18654   W (ret);
18655   return ret;
18656 }
18657
18658 static int
18659 api_show_one_status (vat_main_t * vam)
18660 {
18661   vl_api_show_one_status_t *mp;
18662   int ret;
18663
18664   if (!vam->json_output)
18665     {
18666       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18667     }
18668
18669   M (SHOW_ONE_STATUS, mp);
18670   /* send it... */
18671   S (mp);
18672   /* Wait for a reply... */
18673   W (ret);
18674   return ret;
18675 }
18676
18677 #define api_show_lisp_status api_show_one_status
18678
18679 static int
18680 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18681 {
18682   vl_api_gpe_fwd_entry_path_dump_t *mp;
18683   vl_api_control_ping_t *mp_ping;
18684   unformat_input_t *i = vam->input;
18685   u32 fwd_entry_index = ~0;
18686   int ret;
18687
18688   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18689     {
18690       if (unformat (i, "index %d", &fwd_entry_index))
18691         ;
18692       else
18693         break;
18694     }
18695
18696   if (~0 == fwd_entry_index)
18697     {
18698       errmsg ("no index specified!");
18699       return -99;
18700     }
18701
18702   if (!vam->json_output)
18703     {
18704       print (vam->ofp, "first line");
18705     }
18706
18707   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18708
18709   /* send it... */
18710   S (mp);
18711   /* Use a control ping for synchronization */
18712   MPING (CONTROL_PING, mp_ping);
18713   S (mp_ping);
18714
18715   /* Wait for a reply... */
18716   W (ret);
18717   return ret;
18718 }
18719
18720 static int
18721 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18722 {
18723   vl_api_one_get_map_request_itr_rlocs_t *mp;
18724   int ret;
18725
18726   if (!vam->json_output)
18727     {
18728       print (vam->ofp, "%=20s", "itr-rlocs:");
18729     }
18730
18731   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18732   /* send it... */
18733   S (mp);
18734   /* Wait for a reply... */
18735   W (ret);
18736   return ret;
18737 }
18738
18739 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18740
18741 static int
18742 api_af_packet_create (vat_main_t * vam)
18743 {
18744   unformat_input_t *i = vam->input;
18745   vl_api_af_packet_create_t *mp;
18746   u8 *host_if_name = 0;
18747   u8 hw_addr[6];
18748   u8 random_hw_addr = 1;
18749   int ret;
18750
18751   memset (hw_addr, 0, sizeof (hw_addr));
18752
18753   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18754     {
18755       if (unformat (i, "name %s", &host_if_name))
18756         vec_add1 (host_if_name, 0);
18757       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18758         random_hw_addr = 0;
18759       else
18760         break;
18761     }
18762
18763   if (!vec_len (host_if_name))
18764     {
18765       errmsg ("host-interface name must be specified");
18766       return -99;
18767     }
18768
18769   if (vec_len (host_if_name) > 64)
18770     {
18771       errmsg ("host-interface name too long");
18772       return -99;
18773     }
18774
18775   M (AF_PACKET_CREATE, mp);
18776
18777   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18778   clib_memcpy (mp->hw_addr, hw_addr, 6);
18779   mp->use_random_hw_addr = random_hw_addr;
18780   vec_free (host_if_name);
18781
18782   S (mp);
18783
18784   /* *INDENT-OFF* */
18785   W2 (ret,
18786       ({
18787         if (ret == 0)
18788           fprintf (vam->ofp ? vam->ofp : stderr,
18789                    " new sw_if_index = %d\n", vam->sw_if_index);
18790       }));
18791   /* *INDENT-ON* */
18792   return ret;
18793 }
18794
18795 static int
18796 api_af_packet_delete (vat_main_t * vam)
18797 {
18798   unformat_input_t *i = vam->input;
18799   vl_api_af_packet_delete_t *mp;
18800   u8 *host_if_name = 0;
18801   int ret;
18802
18803   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18804     {
18805       if (unformat (i, "name %s", &host_if_name))
18806         vec_add1 (host_if_name, 0);
18807       else
18808         break;
18809     }
18810
18811   if (!vec_len (host_if_name))
18812     {
18813       errmsg ("host-interface name must be specified");
18814       return -99;
18815     }
18816
18817   if (vec_len (host_if_name) > 64)
18818     {
18819       errmsg ("host-interface name too long");
18820       return -99;
18821     }
18822
18823   M (AF_PACKET_DELETE, mp);
18824
18825   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18826   vec_free (host_if_name);
18827
18828   S (mp);
18829   W (ret);
18830   return ret;
18831 }
18832
18833 static int
18834 api_policer_add_del (vat_main_t * vam)
18835 {
18836   unformat_input_t *i = vam->input;
18837   vl_api_policer_add_del_t *mp;
18838   u8 is_add = 1;
18839   u8 *name = 0;
18840   u32 cir = 0;
18841   u32 eir = 0;
18842   u64 cb = 0;
18843   u64 eb = 0;
18844   u8 rate_type = 0;
18845   u8 round_type = 0;
18846   u8 type = 0;
18847   u8 color_aware = 0;
18848   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18849   int ret;
18850
18851   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18852   conform_action.dscp = 0;
18853   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18854   exceed_action.dscp = 0;
18855   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18856   violate_action.dscp = 0;
18857
18858   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18859     {
18860       if (unformat (i, "del"))
18861         is_add = 0;
18862       else if (unformat (i, "name %s", &name))
18863         vec_add1 (name, 0);
18864       else if (unformat (i, "cir %u", &cir))
18865         ;
18866       else if (unformat (i, "eir %u", &eir))
18867         ;
18868       else if (unformat (i, "cb %u", &cb))
18869         ;
18870       else if (unformat (i, "eb %u", &eb))
18871         ;
18872       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18873                          &rate_type))
18874         ;
18875       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18876                          &round_type))
18877         ;
18878       else if (unformat (i, "type %U", unformat_policer_type, &type))
18879         ;
18880       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18881                          &conform_action))
18882         ;
18883       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18884                          &exceed_action))
18885         ;
18886       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18887                          &violate_action))
18888         ;
18889       else if (unformat (i, "color-aware"))
18890         color_aware = 1;
18891       else
18892         break;
18893     }
18894
18895   if (!vec_len (name))
18896     {
18897       errmsg ("policer name must be specified");
18898       return -99;
18899     }
18900
18901   if (vec_len (name) > 64)
18902     {
18903       errmsg ("policer name too long");
18904       return -99;
18905     }
18906
18907   M (POLICER_ADD_DEL, mp);
18908
18909   clib_memcpy (mp->name, name, vec_len (name));
18910   vec_free (name);
18911   mp->is_add = is_add;
18912   mp->cir = ntohl (cir);
18913   mp->eir = ntohl (eir);
18914   mp->cb = clib_net_to_host_u64 (cb);
18915   mp->eb = clib_net_to_host_u64 (eb);
18916   mp->rate_type = rate_type;
18917   mp->round_type = round_type;
18918   mp->type = type;
18919   mp->conform_action_type = conform_action.action_type;
18920   mp->conform_dscp = conform_action.dscp;
18921   mp->exceed_action_type = exceed_action.action_type;
18922   mp->exceed_dscp = exceed_action.dscp;
18923   mp->violate_action_type = violate_action.action_type;
18924   mp->violate_dscp = violate_action.dscp;
18925   mp->color_aware = color_aware;
18926
18927   S (mp);
18928   W (ret);
18929   return ret;
18930 }
18931
18932 static int
18933 api_policer_dump (vat_main_t * vam)
18934 {
18935   unformat_input_t *i = vam->input;
18936   vl_api_policer_dump_t *mp;
18937   vl_api_control_ping_t *mp_ping;
18938   u8 *match_name = 0;
18939   u8 match_name_valid = 0;
18940   int ret;
18941
18942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18943     {
18944       if (unformat (i, "name %s", &match_name))
18945         {
18946           vec_add1 (match_name, 0);
18947           match_name_valid = 1;
18948         }
18949       else
18950         break;
18951     }
18952
18953   M (POLICER_DUMP, mp);
18954   mp->match_name_valid = match_name_valid;
18955   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18956   vec_free (match_name);
18957   /* send it... */
18958   S (mp);
18959
18960   /* Use a control ping for synchronization */
18961   MPING (CONTROL_PING, mp_ping);
18962   S (mp_ping);
18963
18964   /* Wait for a reply... */
18965   W (ret);
18966   return ret;
18967 }
18968
18969 static int
18970 api_policer_classify_set_interface (vat_main_t * vam)
18971 {
18972   unformat_input_t *i = vam->input;
18973   vl_api_policer_classify_set_interface_t *mp;
18974   u32 sw_if_index;
18975   int sw_if_index_set;
18976   u32 ip4_table_index = ~0;
18977   u32 ip6_table_index = ~0;
18978   u32 l2_table_index = ~0;
18979   u8 is_add = 1;
18980   int ret;
18981
18982   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18983     {
18984       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18985         sw_if_index_set = 1;
18986       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18987         sw_if_index_set = 1;
18988       else if (unformat (i, "del"))
18989         is_add = 0;
18990       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18991         ;
18992       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18993         ;
18994       else if (unformat (i, "l2-table %d", &l2_table_index))
18995         ;
18996       else
18997         {
18998           clib_warning ("parse error '%U'", format_unformat_error, i);
18999           return -99;
19000         }
19001     }
19002
19003   if (sw_if_index_set == 0)
19004     {
19005       errmsg ("missing interface name or sw_if_index");
19006       return -99;
19007     }
19008
19009   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
19010
19011   mp->sw_if_index = ntohl (sw_if_index);
19012   mp->ip4_table_index = ntohl (ip4_table_index);
19013   mp->ip6_table_index = ntohl (ip6_table_index);
19014   mp->l2_table_index = ntohl (l2_table_index);
19015   mp->is_add = is_add;
19016
19017   S (mp);
19018   W (ret);
19019   return ret;
19020 }
19021
19022 static int
19023 api_policer_classify_dump (vat_main_t * vam)
19024 {
19025   unformat_input_t *i = vam->input;
19026   vl_api_policer_classify_dump_t *mp;
19027   vl_api_control_ping_t *mp_ping;
19028   u8 type = POLICER_CLASSIFY_N_TABLES;
19029   int ret;
19030
19031   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
19032     ;
19033   else
19034     {
19035       errmsg ("classify table type must be specified");
19036       return -99;
19037     }
19038
19039   if (!vam->json_output)
19040     {
19041       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19042     }
19043
19044   M (POLICER_CLASSIFY_DUMP, mp);
19045   mp->type = type;
19046   /* send it... */
19047   S (mp);
19048
19049   /* Use a control ping for synchronization */
19050   MPING (CONTROL_PING, mp_ping);
19051   S (mp_ping);
19052
19053   /* Wait for a reply... */
19054   W (ret);
19055   return ret;
19056 }
19057
19058 static int
19059 api_netmap_create (vat_main_t * vam)
19060 {
19061   unformat_input_t *i = vam->input;
19062   vl_api_netmap_create_t *mp;
19063   u8 *if_name = 0;
19064   u8 hw_addr[6];
19065   u8 random_hw_addr = 1;
19066   u8 is_pipe = 0;
19067   u8 is_master = 0;
19068   int ret;
19069
19070   memset (hw_addr, 0, sizeof (hw_addr));
19071
19072   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19073     {
19074       if (unformat (i, "name %s", &if_name))
19075         vec_add1 (if_name, 0);
19076       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19077         random_hw_addr = 0;
19078       else if (unformat (i, "pipe"))
19079         is_pipe = 1;
19080       else if (unformat (i, "master"))
19081         is_master = 1;
19082       else if (unformat (i, "slave"))
19083         is_master = 0;
19084       else
19085         break;
19086     }
19087
19088   if (!vec_len (if_name))
19089     {
19090       errmsg ("interface name must be specified");
19091       return -99;
19092     }
19093
19094   if (vec_len (if_name) > 64)
19095     {
19096       errmsg ("interface name too long");
19097       return -99;
19098     }
19099
19100   M (NETMAP_CREATE, mp);
19101
19102   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19103   clib_memcpy (mp->hw_addr, hw_addr, 6);
19104   mp->use_random_hw_addr = random_hw_addr;
19105   mp->is_pipe = is_pipe;
19106   mp->is_master = is_master;
19107   vec_free (if_name);
19108
19109   S (mp);
19110   W (ret);
19111   return ret;
19112 }
19113
19114 static int
19115 api_netmap_delete (vat_main_t * vam)
19116 {
19117   unformat_input_t *i = vam->input;
19118   vl_api_netmap_delete_t *mp;
19119   u8 *if_name = 0;
19120   int ret;
19121
19122   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19123     {
19124       if (unformat (i, "name %s", &if_name))
19125         vec_add1 (if_name, 0);
19126       else
19127         break;
19128     }
19129
19130   if (!vec_len (if_name))
19131     {
19132       errmsg ("interface name must be specified");
19133       return -99;
19134     }
19135
19136   if (vec_len (if_name) > 64)
19137     {
19138       errmsg ("interface name too long");
19139       return -99;
19140     }
19141
19142   M (NETMAP_DELETE, mp);
19143
19144   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19145   vec_free (if_name);
19146
19147   S (mp);
19148   W (ret);
19149   return ret;
19150 }
19151
19152 static void
19153 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
19154 {
19155   if (fp->afi == IP46_TYPE_IP6)
19156     print (vam->ofp,
19157            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19158            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19159            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19160            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19161            format_ip6_address, fp->next_hop);
19162   else if (fp->afi == IP46_TYPE_IP4)
19163     print (vam->ofp,
19164            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19165            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19166            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19167            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19168            format_ip4_address, fp->next_hop);
19169 }
19170
19171 static void
19172 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19173                                  vl_api_fib_path2_t * fp)
19174 {
19175   struct in_addr ip4;
19176   struct in6_addr ip6;
19177
19178   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19179   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19180   vat_json_object_add_uint (node, "is_local", fp->is_local);
19181   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19182   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19183   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19184   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19185   if (fp->afi == IP46_TYPE_IP4)
19186     {
19187       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19188       vat_json_object_add_ip4 (node, "next_hop", ip4);
19189     }
19190   else if (fp->afi == IP46_TYPE_IP6)
19191     {
19192       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19193       vat_json_object_add_ip6 (node, "next_hop", ip6);
19194     }
19195 }
19196
19197 static void
19198 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19199 {
19200   vat_main_t *vam = &vat_main;
19201   int count = ntohl (mp->mt_count);
19202   vl_api_fib_path2_t *fp;
19203   i32 i;
19204
19205   print (vam->ofp, "[%d]: sw_if_index %d via:",
19206          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19207   fp = mp->mt_paths;
19208   for (i = 0; i < count; i++)
19209     {
19210       vl_api_mpls_fib_path_print (vam, fp);
19211       fp++;
19212     }
19213
19214   print (vam->ofp, "");
19215 }
19216
19217 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19218 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19219
19220 static void
19221 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19222 {
19223   vat_main_t *vam = &vat_main;
19224   vat_json_node_t *node = NULL;
19225   int count = ntohl (mp->mt_count);
19226   vl_api_fib_path2_t *fp;
19227   i32 i;
19228
19229   if (VAT_JSON_ARRAY != vam->json_tree.type)
19230     {
19231       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19232       vat_json_init_array (&vam->json_tree);
19233     }
19234   node = vat_json_array_add (&vam->json_tree);
19235
19236   vat_json_init_object (node);
19237   vat_json_object_add_uint (node, "tunnel_index",
19238                             ntohl (mp->mt_tunnel_index));
19239   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19240
19241   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
19242
19243   fp = mp->mt_paths;
19244   for (i = 0; i < count; i++)
19245     {
19246       vl_api_mpls_fib_path_json_print (node, fp);
19247       fp++;
19248     }
19249 }
19250
19251 static int
19252 api_mpls_tunnel_dump (vat_main_t * vam)
19253 {
19254   vl_api_mpls_tunnel_dump_t *mp;
19255   vl_api_control_ping_t *mp_ping;
19256   i32 index = -1;
19257   int ret;
19258
19259   /* Parse args required to build the message */
19260   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
19261     {
19262       if (!unformat (vam->input, "tunnel_index %d", &index))
19263         {
19264           index = -1;
19265           break;
19266         }
19267     }
19268
19269   print (vam->ofp, "  tunnel_index %d", index);
19270
19271   M (MPLS_TUNNEL_DUMP, mp);
19272   mp->tunnel_index = htonl (index);
19273   S (mp);
19274
19275   /* Use a control ping for synchronization */
19276   MPING (CONTROL_PING, mp_ping);
19277   S (mp_ping);
19278
19279   W (ret);
19280   return ret;
19281 }
19282
19283 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
19284 #define vl_api_mpls_fib_details_t_print vl_noop_handler
19285
19286
19287 static void
19288 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
19289 {
19290   vat_main_t *vam = &vat_main;
19291   int count = ntohl (mp->count);
19292   vl_api_fib_path2_t *fp;
19293   int i;
19294
19295   print (vam->ofp,
19296          "table-id %d, label %u, ess_bit %u",
19297          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
19298   fp = mp->path;
19299   for (i = 0; i < count; i++)
19300     {
19301       vl_api_mpls_fib_path_print (vam, fp);
19302       fp++;
19303     }
19304 }
19305
19306 static void vl_api_mpls_fib_details_t_handler_json
19307   (vl_api_mpls_fib_details_t * mp)
19308 {
19309   vat_main_t *vam = &vat_main;
19310   int count = ntohl (mp->count);
19311   vat_json_node_t *node = NULL;
19312   vl_api_fib_path2_t *fp;
19313   int i;
19314
19315   if (VAT_JSON_ARRAY != vam->json_tree.type)
19316     {
19317       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19318       vat_json_init_array (&vam->json_tree);
19319     }
19320   node = vat_json_array_add (&vam->json_tree);
19321
19322   vat_json_init_object (node);
19323   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19324   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
19325   vat_json_object_add_uint (node, "label", ntohl (mp->label));
19326   vat_json_object_add_uint (node, "path_count", count);
19327   fp = mp->path;
19328   for (i = 0; i < count; i++)
19329     {
19330       vl_api_mpls_fib_path_json_print (node, fp);
19331       fp++;
19332     }
19333 }
19334
19335 static int
19336 api_mpls_fib_dump (vat_main_t * vam)
19337 {
19338   vl_api_mpls_fib_dump_t *mp;
19339   vl_api_control_ping_t *mp_ping;
19340   int ret;
19341
19342   M (MPLS_FIB_DUMP, mp);
19343   S (mp);
19344
19345   /* Use a control ping for synchronization */
19346   MPING (CONTROL_PING, mp_ping);
19347   S (mp_ping);
19348
19349   W (ret);
19350   return ret;
19351 }
19352
19353 #define vl_api_ip_fib_details_t_endian vl_noop_handler
19354 #define vl_api_ip_fib_details_t_print vl_noop_handler
19355
19356 static void
19357 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
19358 {
19359   vat_main_t *vam = &vat_main;
19360   int count = ntohl (mp->count);
19361   vl_api_fib_path_t *fp;
19362   int i;
19363
19364   print (vam->ofp,
19365          "table-id %d, prefix %U/%d",
19366          ntohl (mp->table_id), format_ip4_address, mp->address,
19367          mp->address_length);
19368   fp = mp->path;
19369   for (i = 0; i < count; i++)
19370     {
19371       if (fp->afi == IP46_TYPE_IP6)
19372         print (vam->ofp,
19373                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19374                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19375                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19376                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19377                format_ip6_address, fp->next_hop);
19378       else if (fp->afi == IP46_TYPE_IP4)
19379         print (vam->ofp,
19380                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19381                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19382                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19383                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19384                format_ip4_address, fp->next_hop);
19385       fp++;
19386     }
19387 }
19388
19389 static void vl_api_ip_fib_details_t_handler_json
19390   (vl_api_ip_fib_details_t * mp)
19391 {
19392   vat_main_t *vam = &vat_main;
19393   int count = ntohl (mp->count);
19394   vat_json_node_t *node = NULL;
19395   struct in_addr ip4;
19396   struct in6_addr ip6;
19397   vl_api_fib_path_t *fp;
19398   int i;
19399
19400   if (VAT_JSON_ARRAY != vam->json_tree.type)
19401     {
19402       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19403       vat_json_init_array (&vam->json_tree);
19404     }
19405   node = vat_json_array_add (&vam->json_tree);
19406
19407   vat_json_init_object (node);
19408   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19409   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
19410   vat_json_object_add_ip4 (node, "prefix", ip4);
19411   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19412   vat_json_object_add_uint (node, "path_count", count);
19413   fp = mp->path;
19414   for (i = 0; i < count; i++)
19415     {
19416       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19417       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19418       vat_json_object_add_uint (node, "is_local", fp->is_local);
19419       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19420       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19421       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19422       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19423       if (fp->afi == IP46_TYPE_IP4)
19424         {
19425           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19426           vat_json_object_add_ip4 (node, "next_hop", ip4);
19427         }
19428       else if (fp->afi == IP46_TYPE_IP6)
19429         {
19430           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19431           vat_json_object_add_ip6 (node, "next_hop", ip6);
19432         }
19433     }
19434 }
19435
19436 static int
19437 api_ip_fib_dump (vat_main_t * vam)
19438 {
19439   vl_api_ip_fib_dump_t *mp;
19440   vl_api_control_ping_t *mp_ping;
19441   int ret;
19442
19443   M (IP_FIB_DUMP, mp);
19444   S (mp);
19445
19446   /* Use a control ping for synchronization */
19447   MPING (CONTROL_PING, mp_ping);
19448   S (mp_ping);
19449
19450   W (ret);
19451   return ret;
19452 }
19453
19454 static int
19455 api_ip_mfib_dump (vat_main_t * vam)
19456 {
19457   vl_api_ip_mfib_dump_t *mp;
19458   vl_api_control_ping_t *mp_ping;
19459   int ret;
19460
19461   M (IP_MFIB_DUMP, mp);
19462   S (mp);
19463
19464   /* Use a control ping for synchronization */
19465   MPING (CONTROL_PING, mp_ping);
19466   S (mp_ping);
19467
19468   W (ret);
19469   return ret;
19470 }
19471
19472 static void vl_api_ip_neighbor_details_t_handler
19473   (vl_api_ip_neighbor_details_t * mp)
19474 {
19475   vat_main_t *vam = &vat_main;
19476
19477   print (vam->ofp, "%c %U %U",
19478          (mp->is_static) ? 'S' : 'D',
19479          format_ethernet_address, &mp->mac_address,
19480          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
19481          &mp->ip_address);
19482 }
19483
19484 static void vl_api_ip_neighbor_details_t_handler_json
19485   (vl_api_ip_neighbor_details_t * mp)
19486 {
19487
19488   vat_main_t *vam = &vat_main;
19489   vat_json_node_t *node;
19490   struct in_addr ip4;
19491   struct in6_addr ip6;
19492
19493   if (VAT_JSON_ARRAY != vam->json_tree.type)
19494     {
19495       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19496       vat_json_init_array (&vam->json_tree);
19497     }
19498   node = vat_json_array_add (&vam->json_tree);
19499
19500   vat_json_init_object (node);
19501   vat_json_object_add_string_copy (node, "flag",
19502                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
19503                                    "dynamic");
19504
19505   vat_json_object_add_string_copy (node, "link_layer",
19506                                    format (0, "%U", format_ethernet_address,
19507                                            &mp->mac_address));
19508
19509   if (mp->is_ipv6)
19510     {
19511       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
19512       vat_json_object_add_ip6 (node, "ip_address", ip6);
19513     }
19514   else
19515     {
19516       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
19517       vat_json_object_add_ip4 (node, "ip_address", ip4);
19518     }
19519 }
19520
19521 static int
19522 api_ip_neighbor_dump (vat_main_t * vam)
19523 {
19524   unformat_input_t *i = vam->input;
19525   vl_api_ip_neighbor_dump_t *mp;
19526   vl_api_control_ping_t *mp_ping;
19527   u8 is_ipv6 = 0;
19528   u32 sw_if_index = ~0;
19529   int ret;
19530
19531   /* Parse args required to build the message */
19532   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19533     {
19534       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19535         ;
19536       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19537         ;
19538       else if (unformat (i, "ip6"))
19539         is_ipv6 = 1;
19540       else
19541         break;
19542     }
19543
19544   if (sw_if_index == ~0)
19545     {
19546       errmsg ("missing interface name or sw_if_index");
19547       return -99;
19548     }
19549
19550   M (IP_NEIGHBOR_DUMP, mp);
19551   mp->is_ipv6 = (u8) is_ipv6;
19552   mp->sw_if_index = ntohl (sw_if_index);
19553   S (mp);
19554
19555   /* Use a control ping for synchronization */
19556   MPING (CONTROL_PING, mp_ping);
19557   S (mp_ping);
19558
19559   W (ret);
19560   return ret;
19561 }
19562
19563 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
19564 #define vl_api_ip6_fib_details_t_print vl_noop_handler
19565
19566 static void
19567 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
19568 {
19569   vat_main_t *vam = &vat_main;
19570   int count = ntohl (mp->count);
19571   vl_api_fib_path_t *fp;
19572   int i;
19573
19574   print (vam->ofp,
19575          "table-id %d, prefix %U/%d",
19576          ntohl (mp->table_id), format_ip6_address, mp->address,
19577          mp->address_length);
19578   fp = mp->path;
19579   for (i = 0; i < count; i++)
19580     {
19581       if (fp->afi == IP46_TYPE_IP6)
19582         print (vam->ofp,
19583                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19584                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19585                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19586                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19587                format_ip6_address, fp->next_hop);
19588       else if (fp->afi == IP46_TYPE_IP4)
19589         print (vam->ofp,
19590                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19591                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19592                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19593                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19594                format_ip4_address, fp->next_hop);
19595       fp++;
19596     }
19597 }
19598
19599 static void vl_api_ip6_fib_details_t_handler_json
19600   (vl_api_ip6_fib_details_t * mp)
19601 {
19602   vat_main_t *vam = &vat_main;
19603   int count = ntohl (mp->count);
19604   vat_json_node_t *node = NULL;
19605   struct in_addr ip4;
19606   struct in6_addr ip6;
19607   vl_api_fib_path_t *fp;
19608   int i;
19609
19610   if (VAT_JSON_ARRAY != vam->json_tree.type)
19611     {
19612       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19613       vat_json_init_array (&vam->json_tree);
19614     }
19615   node = vat_json_array_add (&vam->json_tree);
19616
19617   vat_json_init_object (node);
19618   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19619   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
19620   vat_json_object_add_ip6 (node, "prefix", ip6);
19621   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19622   vat_json_object_add_uint (node, "path_count", count);
19623   fp = mp->path;
19624   for (i = 0; i < count; i++)
19625     {
19626       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19627       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19628       vat_json_object_add_uint (node, "is_local", fp->is_local);
19629       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19630       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19631       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19632       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19633       if (fp->afi == IP46_TYPE_IP4)
19634         {
19635           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19636           vat_json_object_add_ip4 (node, "next_hop", ip4);
19637         }
19638       else if (fp->afi == IP46_TYPE_IP6)
19639         {
19640           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19641           vat_json_object_add_ip6 (node, "next_hop", ip6);
19642         }
19643     }
19644 }
19645
19646 static int
19647 api_ip6_fib_dump (vat_main_t * vam)
19648 {
19649   vl_api_ip6_fib_dump_t *mp;
19650   vl_api_control_ping_t *mp_ping;
19651   int ret;
19652
19653   M (IP6_FIB_DUMP, mp);
19654   S (mp);
19655
19656   /* Use a control ping for synchronization */
19657   MPING (CONTROL_PING, mp_ping);
19658   S (mp_ping);
19659
19660   W (ret);
19661   return ret;
19662 }
19663
19664 static int
19665 api_ip6_mfib_dump (vat_main_t * vam)
19666 {
19667   vl_api_ip6_mfib_dump_t *mp;
19668   vl_api_control_ping_t *mp_ping;
19669   int ret;
19670
19671   M (IP6_MFIB_DUMP, mp);
19672   S (mp);
19673
19674   /* Use a control ping for synchronization */
19675   MPING (CONTROL_PING, mp_ping);
19676   S (mp_ping);
19677
19678   W (ret);
19679   return ret;
19680 }
19681
19682 int
19683 api_classify_table_ids (vat_main_t * vam)
19684 {
19685   vl_api_classify_table_ids_t *mp;
19686   int ret;
19687
19688   /* Construct the API message */
19689   M (CLASSIFY_TABLE_IDS, mp);
19690   mp->context = 0;
19691
19692   S (mp);
19693   W (ret);
19694   return ret;
19695 }
19696
19697 int
19698 api_classify_table_by_interface (vat_main_t * vam)
19699 {
19700   unformat_input_t *input = vam->input;
19701   vl_api_classify_table_by_interface_t *mp;
19702
19703   u32 sw_if_index = ~0;
19704   int ret;
19705   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19706     {
19707       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19708         ;
19709       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19710         ;
19711       else
19712         break;
19713     }
19714   if (sw_if_index == ~0)
19715     {
19716       errmsg ("missing interface name or sw_if_index");
19717       return -99;
19718     }
19719
19720   /* Construct the API message */
19721   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19722   mp->context = 0;
19723   mp->sw_if_index = ntohl (sw_if_index);
19724
19725   S (mp);
19726   W (ret);
19727   return ret;
19728 }
19729
19730 int
19731 api_classify_table_info (vat_main_t * vam)
19732 {
19733   unformat_input_t *input = vam->input;
19734   vl_api_classify_table_info_t *mp;
19735
19736   u32 table_id = ~0;
19737   int ret;
19738   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19739     {
19740       if (unformat (input, "table_id %d", &table_id))
19741         ;
19742       else
19743         break;
19744     }
19745   if (table_id == ~0)
19746     {
19747       errmsg ("missing table id");
19748       return -99;
19749     }
19750
19751   /* Construct the API message */
19752   M (CLASSIFY_TABLE_INFO, mp);
19753   mp->context = 0;
19754   mp->table_id = ntohl (table_id);
19755
19756   S (mp);
19757   W (ret);
19758   return ret;
19759 }
19760
19761 int
19762 api_classify_session_dump (vat_main_t * vam)
19763 {
19764   unformat_input_t *input = vam->input;
19765   vl_api_classify_session_dump_t *mp;
19766   vl_api_control_ping_t *mp_ping;
19767
19768   u32 table_id = ~0;
19769   int ret;
19770   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19771     {
19772       if (unformat (input, "table_id %d", &table_id))
19773         ;
19774       else
19775         break;
19776     }
19777   if (table_id == ~0)
19778     {
19779       errmsg ("missing table id");
19780       return -99;
19781     }
19782
19783   /* Construct the API message */
19784   M (CLASSIFY_SESSION_DUMP, mp);
19785   mp->context = 0;
19786   mp->table_id = ntohl (table_id);
19787   S (mp);
19788
19789   /* Use a control ping for synchronization */
19790   MPING (CONTROL_PING, mp_ping);
19791   S (mp_ping);
19792
19793   W (ret);
19794   return ret;
19795 }
19796
19797 static void
19798 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19799 {
19800   vat_main_t *vam = &vat_main;
19801
19802   print (vam->ofp, "collector_address %U, collector_port %d, "
19803          "src_address %U, vrf_id %d, path_mtu %u, "
19804          "template_interval %u, udp_checksum %d",
19805          format_ip4_address, mp->collector_address,
19806          ntohs (mp->collector_port),
19807          format_ip4_address, mp->src_address,
19808          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19809          ntohl (mp->template_interval), mp->udp_checksum);
19810
19811   vam->retval = 0;
19812   vam->result_ready = 1;
19813 }
19814
19815 static void
19816   vl_api_ipfix_exporter_details_t_handler_json
19817   (vl_api_ipfix_exporter_details_t * mp)
19818 {
19819   vat_main_t *vam = &vat_main;
19820   vat_json_node_t node;
19821   struct in_addr collector_address;
19822   struct in_addr src_address;
19823
19824   vat_json_init_object (&node);
19825   clib_memcpy (&collector_address, &mp->collector_address,
19826                sizeof (collector_address));
19827   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19828   vat_json_object_add_uint (&node, "collector_port",
19829                             ntohs (mp->collector_port));
19830   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19831   vat_json_object_add_ip4 (&node, "src_address", src_address);
19832   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19833   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19834   vat_json_object_add_uint (&node, "template_interval",
19835                             ntohl (mp->template_interval));
19836   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19837
19838   vat_json_print (vam->ofp, &node);
19839   vat_json_free (&node);
19840   vam->retval = 0;
19841   vam->result_ready = 1;
19842 }
19843
19844 int
19845 api_ipfix_exporter_dump (vat_main_t * vam)
19846 {
19847   vl_api_ipfix_exporter_dump_t *mp;
19848   int ret;
19849
19850   /* Construct the API message */
19851   M (IPFIX_EXPORTER_DUMP, mp);
19852   mp->context = 0;
19853
19854   S (mp);
19855   W (ret);
19856   return ret;
19857 }
19858
19859 static int
19860 api_ipfix_classify_stream_dump (vat_main_t * vam)
19861 {
19862   vl_api_ipfix_classify_stream_dump_t *mp;
19863   int ret;
19864
19865   /* Construct the API message */
19866   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19867   mp->context = 0;
19868
19869   S (mp);
19870   W (ret);
19871   return ret;
19872   /* NOTREACHED */
19873   return 0;
19874 }
19875
19876 static void
19877   vl_api_ipfix_classify_stream_details_t_handler
19878   (vl_api_ipfix_classify_stream_details_t * mp)
19879 {
19880   vat_main_t *vam = &vat_main;
19881   print (vam->ofp, "domain_id %d, src_port %d",
19882          ntohl (mp->domain_id), ntohs (mp->src_port));
19883   vam->retval = 0;
19884   vam->result_ready = 1;
19885 }
19886
19887 static void
19888   vl_api_ipfix_classify_stream_details_t_handler_json
19889   (vl_api_ipfix_classify_stream_details_t * mp)
19890 {
19891   vat_main_t *vam = &vat_main;
19892   vat_json_node_t node;
19893
19894   vat_json_init_object (&node);
19895   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19896   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19897
19898   vat_json_print (vam->ofp, &node);
19899   vat_json_free (&node);
19900   vam->retval = 0;
19901   vam->result_ready = 1;
19902 }
19903
19904 static int
19905 api_ipfix_classify_table_dump (vat_main_t * vam)
19906 {
19907   vl_api_ipfix_classify_table_dump_t *mp;
19908   vl_api_control_ping_t *mp_ping;
19909   int ret;
19910
19911   if (!vam->json_output)
19912     {
19913       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19914              "transport_protocol");
19915     }
19916
19917   /* Construct the API message */
19918   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19919
19920   /* send it... */
19921   S (mp);
19922
19923   /* Use a control ping for synchronization */
19924   MPING (CONTROL_PING, mp_ping);
19925   S (mp_ping);
19926
19927   W (ret);
19928   return ret;
19929 }
19930
19931 static void
19932   vl_api_ipfix_classify_table_details_t_handler
19933   (vl_api_ipfix_classify_table_details_t * mp)
19934 {
19935   vat_main_t *vam = &vat_main;
19936   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19937          mp->transport_protocol);
19938 }
19939
19940 static void
19941   vl_api_ipfix_classify_table_details_t_handler_json
19942   (vl_api_ipfix_classify_table_details_t * mp)
19943 {
19944   vat_json_node_t *node = NULL;
19945   vat_main_t *vam = &vat_main;
19946
19947   if (VAT_JSON_ARRAY != vam->json_tree.type)
19948     {
19949       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19950       vat_json_init_array (&vam->json_tree);
19951     }
19952
19953   node = vat_json_array_add (&vam->json_tree);
19954   vat_json_init_object (node);
19955
19956   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19957   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19958   vat_json_object_add_uint (node, "transport_protocol",
19959                             mp->transport_protocol);
19960 }
19961
19962 static int
19963 api_sw_interface_span_enable_disable (vat_main_t * vam)
19964 {
19965   unformat_input_t *i = vam->input;
19966   vl_api_sw_interface_span_enable_disable_t *mp;
19967   u32 src_sw_if_index = ~0;
19968   u32 dst_sw_if_index = ~0;
19969   u8 state = 3;
19970   int ret;
19971   u8 is_l2 = 0;
19972
19973   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19974     {
19975       if (unformat
19976           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19977         ;
19978       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19979         ;
19980       else
19981         if (unformat
19982             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19983         ;
19984       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19985         ;
19986       else if (unformat (i, "disable"))
19987         state = 0;
19988       else if (unformat (i, "rx"))
19989         state = 1;
19990       else if (unformat (i, "tx"))
19991         state = 2;
19992       else if (unformat (i, "both"))
19993         state = 3;
19994       else if (unformat (i, "l2"))
19995         is_l2 = 1;
19996       else
19997         break;
19998     }
19999
20000   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
20001
20002   mp->sw_if_index_from = htonl (src_sw_if_index);
20003   mp->sw_if_index_to = htonl (dst_sw_if_index);
20004   mp->state = state;
20005   mp->is_l2 = is_l2;
20006
20007   S (mp);
20008   W (ret);
20009   return ret;
20010 }
20011
20012 static void
20013 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
20014                                             * mp)
20015 {
20016   vat_main_t *vam = &vat_main;
20017   u8 *sw_if_from_name = 0;
20018   u8 *sw_if_to_name = 0;
20019   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20020   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20021   char *states[] = { "none", "rx", "tx", "both" };
20022   hash_pair_t *p;
20023
20024   /* *INDENT-OFF* */
20025   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20026   ({
20027     if ((u32) p->value[0] == sw_if_index_from)
20028       {
20029         sw_if_from_name = (u8 *)(p->key);
20030         if (sw_if_to_name)
20031           break;
20032       }
20033     if ((u32) p->value[0] == sw_if_index_to)
20034       {
20035         sw_if_to_name = (u8 *)(p->key);
20036         if (sw_if_from_name)
20037           break;
20038       }
20039   }));
20040   /* *INDENT-ON* */
20041   print (vam->ofp, "%20s => %20s (%s)",
20042          sw_if_from_name, sw_if_to_name, states[mp->state]);
20043 }
20044
20045 static void
20046   vl_api_sw_interface_span_details_t_handler_json
20047   (vl_api_sw_interface_span_details_t * mp)
20048 {
20049   vat_main_t *vam = &vat_main;
20050   vat_json_node_t *node = NULL;
20051   u8 *sw_if_from_name = 0;
20052   u8 *sw_if_to_name = 0;
20053   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20054   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20055   hash_pair_t *p;
20056
20057   /* *INDENT-OFF* */
20058   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20059   ({
20060     if ((u32) p->value[0] == sw_if_index_from)
20061       {
20062         sw_if_from_name = (u8 *)(p->key);
20063         if (sw_if_to_name)
20064           break;
20065       }
20066     if ((u32) p->value[0] == sw_if_index_to)
20067       {
20068         sw_if_to_name = (u8 *)(p->key);
20069         if (sw_if_from_name)
20070           break;
20071       }
20072   }));
20073   /* *INDENT-ON* */
20074
20075   if (VAT_JSON_ARRAY != vam->json_tree.type)
20076     {
20077       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20078       vat_json_init_array (&vam->json_tree);
20079     }
20080   node = vat_json_array_add (&vam->json_tree);
20081
20082   vat_json_init_object (node);
20083   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
20084   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
20085   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
20086   if (0 != sw_if_to_name)
20087     {
20088       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
20089     }
20090   vat_json_object_add_uint (node, "state", mp->state);
20091 }
20092
20093 static int
20094 api_sw_interface_span_dump (vat_main_t * vam)
20095 {
20096   unformat_input_t *input = vam->input;
20097   vl_api_sw_interface_span_dump_t *mp;
20098   vl_api_control_ping_t *mp_ping;
20099   u8 is_l2 = 0;
20100   int ret;
20101
20102   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20103     {
20104       if (unformat (input, "l2"))
20105         is_l2 = 1;
20106       else
20107         break;
20108     }
20109
20110   M (SW_INTERFACE_SPAN_DUMP, mp);
20111   mp->is_l2 = is_l2;
20112   S (mp);
20113
20114   /* Use a control ping for synchronization */
20115   MPING (CONTROL_PING, mp_ping);
20116   S (mp_ping);
20117
20118   W (ret);
20119   return ret;
20120 }
20121
20122 int
20123 api_pg_create_interface (vat_main_t * vam)
20124 {
20125   unformat_input_t *input = vam->input;
20126   vl_api_pg_create_interface_t *mp;
20127
20128   u32 if_id = ~0;
20129   int ret;
20130   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20131     {
20132       if (unformat (input, "if_id %d", &if_id))
20133         ;
20134       else
20135         break;
20136     }
20137   if (if_id == ~0)
20138     {
20139       errmsg ("missing pg interface index");
20140       return -99;
20141     }
20142
20143   /* Construct the API message */
20144   M (PG_CREATE_INTERFACE, mp);
20145   mp->context = 0;
20146   mp->interface_id = ntohl (if_id);
20147
20148   S (mp);
20149   W (ret);
20150   return ret;
20151 }
20152
20153 int
20154 api_pg_capture (vat_main_t * vam)
20155 {
20156   unformat_input_t *input = vam->input;
20157   vl_api_pg_capture_t *mp;
20158
20159   u32 if_id = ~0;
20160   u8 enable = 1;
20161   u32 count = 1;
20162   u8 pcap_file_set = 0;
20163   u8 *pcap_file = 0;
20164   int ret;
20165   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20166     {
20167       if (unformat (input, "if_id %d", &if_id))
20168         ;
20169       else if (unformat (input, "pcap %s", &pcap_file))
20170         pcap_file_set = 1;
20171       else if (unformat (input, "count %d", &count))
20172         ;
20173       else if (unformat (input, "disable"))
20174         enable = 0;
20175       else
20176         break;
20177     }
20178   if (if_id == ~0)
20179     {
20180       errmsg ("missing pg interface index");
20181       return -99;
20182     }
20183   if (pcap_file_set > 0)
20184     {
20185       if (vec_len (pcap_file) > 255)
20186         {
20187           errmsg ("pcap file name is too long");
20188           return -99;
20189         }
20190     }
20191
20192   u32 name_len = vec_len (pcap_file);
20193   /* Construct the API message */
20194   M (PG_CAPTURE, mp);
20195   mp->context = 0;
20196   mp->interface_id = ntohl (if_id);
20197   mp->is_enabled = enable;
20198   mp->count = ntohl (count);
20199   mp->pcap_name_length = ntohl (name_len);
20200   if (pcap_file_set != 0)
20201     {
20202       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20203     }
20204   vec_free (pcap_file);
20205
20206   S (mp);
20207   W (ret);
20208   return ret;
20209 }
20210
20211 int
20212 api_pg_enable_disable (vat_main_t * vam)
20213 {
20214   unformat_input_t *input = vam->input;
20215   vl_api_pg_enable_disable_t *mp;
20216
20217   u8 enable = 1;
20218   u8 stream_name_set = 0;
20219   u8 *stream_name = 0;
20220   int ret;
20221   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20222     {
20223       if (unformat (input, "stream %s", &stream_name))
20224         stream_name_set = 1;
20225       else if (unformat (input, "disable"))
20226         enable = 0;
20227       else
20228         break;
20229     }
20230
20231   if (stream_name_set > 0)
20232     {
20233       if (vec_len (stream_name) > 255)
20234         {
20235           errmsg ("stream name too long");
20236           return -99;
20237         }
20238     }
20239
20240   u32 name_len = vec_len (stream_name);
20241   /* Construct the API message */
20242   M (PG_ENABLE_DISABLE, mp);
20243   mp->context = 0;
20244   mp->is_enabled = enable;
20245   if (stream_name_set != 0)
20246     {
20247       mp->stream_name_length = ntohl (name_len);
20248       clib_memcpy (mp->stream_name, stream_name, name_len);
20249     }
20250   vec_free (stream_name);
20251
20252   S (mp);
20253   W (ret);
20254   return ret;
20255 }
20256
20257 int
20258 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
20259 {
20260   unformat_input_t *input = vam->input;
20261   vl_api_ip_source_and_port_range_check_add_del_t *mp;
20262
20263   u16 *low_ports = 0;
20264   u16 *high_ports = 0;
20265   u16 this_low;
20266   u16 this_hi;
20267   ip4_address_t ip4_addr;
20268   ip6_address_t ip6_addr;
20269   u32 length;
20270   u32 tmp, tmp2;
20271   u8 prefix_set = 0;
20272   u32 vrf_id = ~0;
20273   u8 is_add = 1;
20274   u8 is_ipv6 = 0;
20275   int ret;
20276
20277   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20278     {
20279       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
20280         {
20281           prefix_set = 1;
20282         }
20283       else
20284         if (unformat
20285             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
20286         {
20287           prefix_set = 1;
20288           is_ipv6 = 1;
20289         }
20290       else if (unformat (input, "vrf %d", &vrf_id))
20291         ;
20292       else if (unformat (input, "del"))
20293         is_add = 0;
20294       else if (unformat (input, "port %d", &tmp))
20295         {
20296           if (tmp == 0 || tmp > 65535)
20297             {
20298               errmsg ("port %d out of range", tmp);
20299               return -99;
20300             }
20301           this_low = tmp;
20302           this_hi = this_low + 1;
20303           vec_add1 (low_ports, this_low);
20304           vec_add1 (high_ports, this_hi);
20305         }
20306       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
20307         {
20308           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
20309             {
20310               errmsg ("incorrect range parameters");
20311               return -99;
20312             }
20313           this_low = tmp;
20314           /* Note: in debug CLI +1 is added to high before
20315              passing to real fn that does "the work"
20316              (ip_source_and_port_range_check_add_del).
20317              This fn is a wrapper around the binary API fn a
20318              control plane will call, which expects this increment
20319              to have occurred. Hence letting the binary API control
20320              plane fn do the increment for consistency between VAT
20321              and other control planes.
20322            */
20323           this_hi = tmp2;
20324           vec_add1 (low_ports, this_low);
20325           vec_add1 (high_ports, this_hi);
20326         }
20327       else
20328         break;
20329     }
20330
20331   if (prefix_set == 0)
20332     {
20333       errmsg ("<address>/<mask> not specified");
20334       return -99;
20335     }
20336
20337   if (vrf_id == ~0)
20338     {
20339       errmsg ("VRF ID required, not specified");
20340       return -99;
20341     }
20342
20343   if (vrf_id == 0)
20344     {
20345       errmsg
20346         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20347       return -99;
20348     }
20349
20350   if (vec_len (low_ports) == 0)
20351     {
20352       errmsg ("At least one port or port range required");
20353       return -99;
20354     }
20355
20356   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
20357
20358   mp->is_add = is_add;
20359
20360   if (is_ipv6)
20361     {
20362       mp->is_ipv6 = 1;
20363       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
20364     }
20365   else
20366     {
20367       mp->is_ipv6 = 0;
20368       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
20369     }
20370
20371   mp->mask_length = length;
20372   mp->number_of_ranges = vec_len (low_ports);
20373
20374   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
20375   vec_free (low_ports);
20376
20377   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20378   vec_free (high_ports);
20379
20380   mp->vrf_id = ntohl (vrf_id);
20381
20382   S (mp);
20383   W (ret);
20384   return ret;
20385 }
20386
20387 int
20388 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20389 {
20390   unformat_input_t *input = vam->input;
20391   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20392   u32 sw_if_index = ~0;
20393   int vrf_set = 0;
20394   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20395   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20396   u8 is_add = 1;
20397   int ret;
20398
20399   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20400     {
20401       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20402         ;
20403       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20404         ;
20405       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20406         vrf_set = 1;
20407       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20408         vrf_set = 1;
20409       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20410         vrf_set = 1;
20411       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20412         vrf_set = 1;
20413       else if (unformat (input, "del"))
20414         is_add = 0;
20415       else
20416         break;
20417     }
20418
20419   if (sw_if_index == ~0)
20420     {
20421       errmsg ("Interface required but not specified");
20422       return -99;
20423     }
20424
20425   if (vrf_set == 0)
20426     {
20427       errmsg ("VRF ID required but not specified");
20428       return -99;
20429     }
20430
20431   if (tcp_out_vrf_id == 0
20432       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20433     {
20434       errmsg
20435         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20436       return -99;
20437     }
20438
20439   /* Construct the API message */
20440   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20441
20442   mp->sw_if_index = ntohl (sw_if_index);
20443   mp->is_add = is_add;
20444   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20445   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20446   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20447   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20448
20449   /* send it... */
20450   S (mp);
20451
20452   /* Wait for a reply... */
20453   W (ret);
20454   return ret;
20455 }
20456
20457 static int
20458 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
20459 {
20460   unformat_input_t *i = vam->input;
20461   vl_api_ipsec_gre_add_del_tunnel_t *mp;
20462   u32 local_sa_id = 0;
20463   u32 remote_sa_id = 0;
20464   ip4_address_t src_address;
20465   ip4_address_t dst_address;
20466   u8 is_add = 1;
20467   int ret;
20468
20469   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20470     {
20471       if (unformat (i, "local_sa %d", &local_sa_id))
20472         ;
20473       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20474         ;
20475       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
20476         ;
20477       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
20478         ;
20479       else if (unformat (i, "del"))
20480         is_add = 0;
20481       else
20482         {
20483           clib_warning ("parse error '%U'", format_unformat_error, i);
20484           return -99;
20485         }
20486     }
20487
20488   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
20489
20490   mp->local_sa_id = ntohl (local_sa_id);
20491   mp->remote_sa_id = ntohl (remote_sa_id);
20492   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
20493   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
20494   mp->is_add = is_add;
20495
20496   S (mp);
20497   W (ret);
20498   return ret;
20499 }
20500
20501 static int
20502 api_punt (vat_main_t * vam)
20503 {
20504   unformat_input_t *i = vam->input;
20505   vl_api_punt_t *mp;
20506   u32 ipv = ~0;
20507   u32 protocol = ~0;
20508   u32 port = ~0;
20509   int is_add = 1;
20510   int ret;
20511
20512   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20513     {
20514       if (unformat (i, "ip %d", &ipv))
20515         ;
20516       else if (unformat (i, "protocol %d", &protocol))
20517         ;
20518       else if (unformat (i, "port %d", &port))
20519         ;
20520       else if (unformat (i, "del"))
20521         is_add = 0;
20522       else
20523         {
20524           clib_warning ("parse error '%U'", format_unformat_error, i);
20525           return -99;
20526         }
20527     }
20528
20529   M (PUNT, mp);
20530
20531   mp->is_add = (u8) is_add;
20532   mp->ipv = (u8) ipv;
20533   mp->l4_protocol = (u8) protocol;
20534   mp->l4_port = htons ((u16) port);
20535
20536   S (mp);
20537   W (ret);
20538   return ret;
20539 }
20540
20541 static void vl_api_ipsec_gre_tunnel_details_t_handler
20542   (vl_api_ipsec_gre_tunnel_details_t * mp)
20543 {
20544   vat_main_t *vam = &vat_main;
20545
20546   print (vam->ofp, "%11d%15U%15U%14d%14d",
20547          ntohl (mp->sw_if_index),
20548          format_ip4_address, &mp->src_address,
20549          format_ip4_address, &mp->dst_address,
20550          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
20551 }
20552
20553 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
20554   (vl_api_ipsec_gre_tunnel_details_t * mp)
20555 {
20556   vat_main_t *vam = &vat_main;
20557   vat_json_node_t *node = NULL;
20558   struct in_addr ip4;
20559
20560   if (VAT_JSON_ARRAY != vam->json_tree.type)
20561     {
20562       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20563       vat_json_init_array (&vam->json_tree);
20564     }
20565   node = vat_json_array_add (&vam->json_tree);
20566
20567   vat_json_init_object (node);
20568   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
20569   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
20570   vat_json_object_add_ip4 (node, "src_address", ip4);
20571   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
20572   vat_json_object_add_ip4 (node, "dst_address", ip4);
20573   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
20574   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
20575 }
20576
20577 static int
20578 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
20579 {
20580   unformat_input_t *i = vam->input;
20581   vl_api_ipsec_gre_tunnel_dump_t *mp;
20582   vl_api_control_ping_t *mp_ping;
20583   u32 sw_if_index;
20584   u8 sw_if_index_set = 0;
20585   int ret;
20586
20587   /* Parse args required to build the message */
20588   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20589     {
20590       if (unformat (i, "sw_if_index %d", &sw_if_index))
20591         sw_if_index_set = 1;
20592       else
20593         break;
20594     }
20595
20596   if (sw_if_index_set == 0)
20597     {
20598       sw_if_index = ~0;
20599     }
20600
20601   if (!vam->json_output)
20602     {
20603       print (vam->ofp, "%11s%15s%15s%14s%14s",
20604              "sw_if_index", "src_address", "dst_address",
20605              "local_sa_id", "remote_sa_id");
20606     }
20607
20608   /* Get list of gre-tunnel interfaces */
20609   M (IPSEC_GRE_TUNNEL_DUMP, mp);
20610
20611   mp->sw_if_index = htonl (sw_if_index);
20612
20613   S (mp);
20614
20615   /* Use a control ping for synchronization */
20616   MPING (CONTROL_PING, mp_ping);
20617   S (mp_ping);
20618
20619   W (ret);
20620   return ret;
20621 }
20622
20623 static int
20624 api_delete_subif (vat_main_t * vam)
20625 {
20626   unformat_input_t *i = vam->input;
20627   vl_api_delete_subif_t *mp;
20628   u32 sw_if_index = ~0;
20629   int ret;
20630
20631   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20632     {
20633       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20634         ;
20635       if (unformat (i, "sw_if_index %d", &sw_if_index))
20636         ;
20637       else
20638         break;
20639     }
20640
20641   if (sw_if_index == ~0)
20642     {
20643       errmsg ("missing sw_if_index");
20644       return -99;
20645     }
20646
20647   /* Construct the API message */
20648   M (DELETE_SUBIF, mp);
20649   mp->sw_if_index = ntohl (sw_if_index);
20650
20651   S (mp);
20652   W (ret);
20653   return ret;
20654 }
20655
20656 #define foreach_pbb_vtr_op      \
20657 _("disable",  L2_VTR_DISABLED)  \
20658 _("pop",  L2_VTR_POP_2)         \
20659 _("push",  L2_VTR_PUSH_2)
20660
20661 static int
20662 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20663 {
20664   unformat_input_t *i = vam->input;
20665   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20666   u32 sw_if_index = ~0, vtr_op = ~0;
20667   u16 outer_tag = ~0;
20668   u8 dmac[6], smac[6];
20669   u8 dmac_set = 0, smac_set = 0;
20670   u16 vlanid = 0;
20671   u32 sid = ~0;
20672   u32 tmp;
20673   int ret;
20674
20675   /* Shut up coverity */
20676   memset (dmac, 0, sizeof (dmac));
20677   memset (smac, 0, sizeof (smac));
20678
20679   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20680     {
20681       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20682         ;
20683       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20684         ;
20685       else if (unformat (i, "vtr_op %d", &vtr_op))
20686         ;
20687 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20688       foreach_pbb_vtr_op
20689 #undef _
20690         else if (unformat (i, "translate_pbb_stag"))
20691         {
20692           if (unformat (i, "%d", &tmp))
20693             {
20694               vtr_op = L2_VTR_TRANSLATE_2_1;
20695               outer_tag = tmp;
20696             }
20697           else
20698             {
20699               errmsg
20700                 ("translate_pbb_stag operation requires outer tag definition");
20701               return -99;
20702             }
20703         }
20704       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20705         dmac_set++;
20706       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20707         smac_set++;
20708       else if (unformat (i, "sid %d", &sid))
20709         ;
20710       else if (unformat (i, "vlanid %d", &tmp))
20711         vlanid = tmp;
20712       else
20713         {
20714           clib_warning ("parse error '%U'", format_unformat_error, i);
20715           return -99;
20716         }
20717     }
20718
20719   if ((sw_if_index == ~0) || (vtr_op == ~0))
20720     {
20721       errmsg ("missing sw_if_index or vtr operation");
20722       return -99;
20723     }
20724   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20725       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20726     {
20727       errmsg
20728         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20729       return -99;
20730     }
20731
20732   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20733   mp->sw_if_index = ntohl (sw_if_index);
20734   mp->vtr_op = ntohl (vtr_op);
20735   mp->outer_tag = ntohs (outer_tag);
20736   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20737   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20738   mp->b_vlanid = ntohs (vlanid);
20739   mp->i_sid = ntohl (sid);
20740
20741   S (mp);
20742   W (ret);
20743   return ret;
20744 }
20745
20746 static int
20747 api_flow_classify_set_interface (vat_main_t * vam)
20748 {
20749   unformat_input_t *i = vam->input;
20750   vl_api_flow_classify_set_interface_t *mp;
20751   u32 sw_if_index;
20752   int sw_if_index_set;
20753   u32 ip4_table_index = ~0;
20754   u32 ip6_table_index = ~0;
20755   u8 is_add = 1;
20756   int ret;
20757
20758   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20759     {
20760       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20761         sw_if_index_set = 1;
20762       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20763         sw_if_index_set = 1;
20764       else if (unformat (i, "del"))
20765         is_add = 0;
20766       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20767         ;
20768       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20769         ;
20770       else
20771         {
20772           clib_warning ("parse error '%U'", format_unformat_error, i);
20773           return -99;
20774         }
20775     }
20776
20777   if (sw_if_index_set == 0)
20778     {
20779       errmsg ("missing interface name or sw_if_index");
20780       return -99;
20781     }
20782
20783   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20784
20785   mp->sw_if_index = ntohl (sw_if_index);
20786   mp->ip4_table_index = ntohl (ip4_table_index);
20787   mp->ip6_table_index = ntohl (ip6_table_index);
20788   mp->is_add = is_add;
20789
20790   S (mp);
20791   W (ret);
20792   return ret;
20793 }
20794
20795 static int
20796 api_flow_classify_dump (vat_main_t * vam)
20797 {
20798   unformat_input_t *i = vam->input;
20799   vl_api_flow_classify_dump_t *mp;
20800   vl_api_control_ping_t *mp_ping;
20801   u8 type = FLOW_CLASSIFY_N_TABLES;
20802   int ret;
20803
20804   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20805     ;
20806   else
20807     {
20808       errmsg ("classify table type must be specified");
20809       return -99;
20810     }
20811
20812   if (!vam->json_output)
20813     {
20814       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20815     }
20816
20817   M (FLOW_CLASSIFY_DUMP, mp);
20818   mp->type = type;
20819   /* send it... */
20820   S (mp);
20821
20822   /* Use a control ping for synchronization */
20823   MPING (CONTROL_PING, mp_ping);
20824   S (mp_ping);
20825
20826   /* Wait for a reply... */
20827   W (ret);
20828   return ret;
20829 }
20830
20831 static int
20832 api_feature_enable_disable (vat_main_t * vam)
20833 {
20834   unformat_input_t *i = vam->input;
20835   vl_api_feature_enable_disable_t *mp;
20836   u8 *arc_name = 0;
20837   u8 *feature_name = 0;
20838   u32 sw_if_index = ~0;
20839   u8 enable = 1;
20840   int ret;
20841
20842   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20843     {
20844       if (unformat (i, "arc_name %s", &arc_name))
20845         ;
20846       else if (unformat (i, "feature_name %s", &feature_name))
20847         ;
20848       else
20849         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20850         ;
20851       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20852         ;
20853       else if (unformat (i, "disable"))
20854         enable = 0;
20855       else
20856         break;
20857     }
20858
20859   if (arc_name == 0)
20860     {
20861       errmsg ("missing arc name");
20862       return -99;
20863     }
20864   if (vec_len (arc_name) > 63)
20865     {
20866       errmsg ("arc name too long");
20867     }
20868
20869   if (feature_name == 0)
20870     {
20871       errmsg ("missing feature name");
20872       return -99;
20873     }
20874   if (vec_len (feature_name) > 63)
20875     {
20876       errmsg ("feature name too long");
20877     }
20878
20879   if (sw_if_index == ~0)
20880     {
20881       errmsg ("missing interface name or sw_if_index");
20882       return -99;
20883     }
20884
20885   /* Construct the API message */
20886   M (FEATURE_ENABLE_DISABLE, mp);
20887   mp->sw_if_index = ntohl (sw_if_index);
20888   mp->enable = enable;
20889   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20890   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20891   vec_free (arc_name);
20892   vec_free (feature_name);
20893
20894   S (mp);
20895   W (ret);
20896   return ret;
20897 }
20898
20899 static int
20900 api_sw_interface_tag_add_del (vat_main_t * vam)
20901 {
20902   unformat_input_t *i = vam->input;
20903   vl_api_sw_interface_tag_add_del_t *mp;
20904   u32 sw_if_index = ~0;
20905   u8 *tag = 0;
20906   u8 enable = 1;
20907   int ret;
20908
20909   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20910     {
20911       if (unformat (i, "tag %s", &tag))
20912         ;
20913       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20914         ;
20915       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20916         ;
20917       else if (unformat (i, "del"))
20918         enable = 0;
20919       else
20920         break;
20921     }
20922
20923   if (sw_if_index == ~0)
20924     {
20925       errmsg ("missing interface name or sw_if_index");
20926       return -99;
20927     }
20928
20929   if (enable && (tag == 0))
20930     {
20931       errmsg ("no tag specified");
20932       return -99;
20933     }
20934
20935   /* Construct the API message */
20936   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20937   mp->sw_if_index = ntohl (sw_if_index);
20938   mp->is_add = enable;
20939   if (enable)
20940     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20941   vec_free (tag);
20942
20943   S (mp);
20944   W (ret);
20945   return ret;
20946 }
20947
20948 static void vl_api_l2_xconnect_details_t_handler
20949   (vl_api_l2_xconnect_details_t * mp)
20950 {
20951   vat_main_t *vam = &vat_main;
20952
20953   print (vam->ofp, "%15d%15d",
20954          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20955 }
20956
20957 static void vl_api_l2_xconnect_details_t_handler_json
20958   (vl_api_l2_xconnect_details_t * mp)
20959 {
20960   vat_main_t *vam = &vat_main;
20961   vat_json_node_t *node = NULL;
20962
20963   if (VAT_JSON_ARRAY != vam->json_tree.type)
20964     {
20965       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20966       vat_json_init_array (&vam->json_tree);
20967     }
20968   node = vat_json_array_add (&vam->json_tree);
20969
20970   vat_json_init_object (node);
20971   vat_json_object_add_uint (node, "rx_sw_if_index",
20972                             ntohl (mp->rx_sw_if_index));
20973   vat_json_object_add_uint (node, "tx_sw_if_index",
20974                             ntohl (mp->tx_sw_if_index));
20975 }
20976
20977 static int
20978 api_l2_xconnect_dump (vat_main_t * vam)
20979 {
20980   vl_api_l2_xconnect_dump_t *mp;
20981   vl_api_control_ping_t *mp_ping;
20982   int ret;
20983
20984   if (!vam->json_output)
20985     {
20986       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20987     }
20988
20989   M (L2_XCONNECT_DUMP, mp);
20990
20991   S (mp);
20992
20993   /* Use a control ping for synchronization */
20994   MPING (CONTROL_PING, mp_ping);
20995   S (mp_ping);
20996
20997   W (ret);
20998   return ret;
20999 }
21000
21001 static int
21002 api_sw_interface_set_mtu (vat_main_t * vam)
21003 {
21004   unformat_input_t *i = vam->input;
21005   vl_api_sw_interface_set_mtu_t *mp;
21006   u32 sw_if_index = ~0;
21007   u32 mtu = 0;
21008   int ret;
21009
21010   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21011     {
21012       if (unformat (i, "mtu %d", &mtu))
21013         ;
21014       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21015         ;
21016       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21017         ;
21018       else
21019         break;
21020     }
21021
21022   if (sw_if_index == ~0)
21023     {
21024       errmsg ("missing interface name or sw_if_index");
21025       return -99;
21026     }
21027
21028   if (mtu == 0)
21029     {
21030       errmsg ("no mtu specified");
21031       return -99;
21032     }
21033
21034   /* Construct the API message */
21035   M (SW_INTERFACE_SET_MTU, mp);
21036   mp->sw_if_index = ntohl (sw_if_index);
21037   mp->mtu = ntohs ((u16) mtu);
21038
21039   S (mp);
21040   W (ret);
21041   return ret;
21042 }
21043
21044 static int
21045 api_p2p_ethernet_add (vat_main_t * vam)
21046 {
21047   unformat_input_t *i = vam->input;
21048   vl_api_p2p_ethernet_add_t *mp;
21049   u32 parent_if_index = ~0;
21050   u32 sub_id = ~0;
21051   u8 remote_mac[6];
21052   u8 mac_set = 0;
21053   int ret;
21054
21055   memset (remote_mac, 0, sizeof (remote_mac));
21056   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21057     {
21058       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21059         ;
21060       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21061         ;
21062       else
21063         if (unformat
21064             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21065         mac_set++;
21066       else if (unformat (i, "sub_id %d", &sub_id))
21067         ;
21068       else
21069         {
21070           clib_warning ("parse error '%U'", format_unformat_error, i);
21071           return -99;
21072         }
21073     }
21074
21075   if (parent_if_index == ~0)
21076     {
21077       errmsg ("missing interface name or sw_if_index");
21078       return -99;
21079     }
21080   if (mac_set == 0)
21081     {
21082       errmsg ("missing remote mac address");
21083       return -99;
21084     }
21085   if (sub_id == ~0)
21086     {
21087       errmsg ("missing sub-interface id");
21088       return -99;
21089     }
21090
21091   M (P2P_ETHERNET_ADD, mp);
21092   mp->parent_if_index = ntohl (parent_if_index);
21093   mp->subif_id = ntohl (sub_id);
21094   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21095
21096   S (mp);
21097   W (ret);
21098   return ret;
21099 }
21100
21101 static int
21102 api_p2p_ethernet_del (vat_main_t * vam)
21103 {
21104   unformat_input_t *i = vam->input;
21105   vl_api_p2p_ethernet_del_t *mp;
21106   u32 parent_if_index = ~0;
21107   u8 remote_mac[6];
21108   u8 mac_set = 0;
21109   int ret;
21110
21111   memset (remote_mac, 0, sizeof (remote_mac));
21112   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21113     {
21114       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21115         ;
21116       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21117         ;
21118       else
21119         if (unformat
21120             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21121         mac_set++;
21122       else
21123         {
21124           clib_warning ("parse error '%U'", format_unformat_error, i);
21125           return -99;
21126         }
21127     }
21128
21129   if (parent_if_index == ~0)
21130     {
21131       errmsg ("missing interface name or sw_if_index");
21132       return -99;
21133     }
21134   if (mac_set == 0)
21135     {
21136       errmsg ("missing remote mac address");
21137       return -99;
21138     }
21139
21140   M (P2P_ETHERNET_DEL, mp);
21141   mp->parent_if_index = ntohl (parent_if_index);
21142   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21143
21144   S (mp);
21145   W (ret);
21146   return ret;
21147 }
21148
21149 static int
21150 api_lldp_config (vat_main_t * vam)
21151 {
21152   unformat_input_t *i = vam->input;
21153   vl_api_lldp_config_t *mp;
21154   int tx_hold = 0;
21155   int tx_interval = 0;
21156   u8 *sys_name = NULL;
21157   int ret;
21158
21159   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21160     {
21161       if (unformat (i, "system-name %s", &sys_name))
21162         ;
21163       else if (unformat (i, "tx-hold %d", &tx_hold))
21164         ;
21165       else if (unformat (i, "tx-interval %d", &tx_interval))
21166         ;
21167       else
21168         {
21169           clib_warning ("parse error '%U'", format_unformat_error, i);
21170           return -99;
21171         }
21172     }
21173
21174   vec_add1 (sys_name, 0);
21175
21176   M (LLDP_CONFIG, mp);
21177   mp->tx_hold = htonl (tx_hold);
21178   mp->tx_interval = htonl (tx_interval);
21179   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21180   vec_free (sys_name);
21181
21182   S (mp);
21183   W (ret);
21184   return ret;
21185 }
21186
21187 static int
21188 api_sw_interface_set_lldp (vat_main_t * vam)
21189 {
21190   unformat_input_t *i = vam->input;
21191   vl_api_sw_interface_set_lldp_t *mp;
21192   u32 sw_if_index = ~0;
21193   u32 enable = 1;
21194   u8 *port_desc = NULL, *mgmt_oid = NULL;
21195   ip4_address_t ip4_addr;
21196   ip6_address_t ip6_addr;
21197   int ret;
21198
21199   memset (&ip4_addr, 0, sizeof (ip4_addr));
21200   memset (&ip6_addr, 0, sizeof (ip6_addr));
21201
21202   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21203     {
21204       if (unformat (i, "disable"))
21205         enable = 0;
21206       else
21207         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21208         ;
21209       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21210         ;
21211       else if (unformat (i, "port-desc %s", &port_desc))
21212         ;
21213       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21214         ;
21215       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21216         ;
21217       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21218         ;
21219       else
21220         break;
21221     }
21222
21223   if (sw_if_index == ~0)
21224     {
21225       errmsg ("missing interface name or sw_if_index");
21226       return -99;
21227     }
21228
21229   /* Construct the API message */
21230   vec_add1 (port_desc, 0);
21231   vec_add1 (mgmt_oid, 0);
21232   M (SW_INTERFACE_SET_LLDP, mp);
21233   mp->sw_if_index = ntohl (sw_if_index);
21234   mp->enable = enable;
21235   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
21236   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
21237   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
21238   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
21239   vec_free (port_desc);
21240   vec_free (mgmt_oid);
21241
21242   S (mp);
21243   W (ret);
21244   return ret;
21245 }
21246
21247 static int
21248 api_tcp_configure_src_addresses (vat_main_t * vam)
21249 {
21250   vl_api_tcp_configure_src_addresses_t *mp;
21251   unformat_input_t *i = vam->input;
21252   ip4_address_t v4first, v4last;
21253   ip6_address_t v6first, v6last;
21254   u8 range_set = 0;
21255   u32 vrf_id = 0;
21256   int ret;
21257
21258   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21259     {
21260       if (unformat (i, "%U - %U",
21261                     unformat_ip4_address, &v4first,
21262                     unformat_ip4_address, &v4last))
21263         {
21264           if (range_set)
21265             {
21266               errmsg ("one range per message (range already set)");
21267               return -99;
21268             }
21269           range_set = 1;
21270         }
21271       else if (unformat (i, "%U - %U",
21272                          unformat_ip6_address, &v6first,
21273                          unformat_ip6_address, &v6last))
21274         {
21275           if (range_set)
21276             {
21277               errmsg ("one range per message (range already set)");
21278               return -99;
21279             }
21280           range_set = 2;
21281         }
21282       else if (unformat (i, "vrf %d", &vrf_id))
21283         ;
21284       else
21285         break;
21286     }
21287
21288   if (range_set == 0)
21289     {
21290       errmsg ("address range not set");
21291       return -99;
21292     }
21293
21294   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
21295   mp->vrf_id = ntohl (vrf_id);
21296   /* ipv6? */
21297   if (range_set == 2)
21298     {
21299       mp->is_ipv6 = 1;
21300       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
21301       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
21302     }
21303   else
21304     {
21305       mp->is_ipv6 = 0;
21306       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
21307       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
21308     }
21309   S (mp);
21310   W (ret);
21311   return ret;
21312 }
21313
21314 static int
21315 api_app_namespace_add_del (vat_main_t * vam)
21316 {
21317   vl_api_app_namespace_add_del_t *mp;
21318   unformat_input_t *i = vam->input;
21319   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
21320   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
21321   u64 secret;
21322   int ret;
21323
21324   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21325     {
21326       if (unformat (i, "id %_%v%_", &ns_id))
21327         ;
21328       else if (unformat (i, "secret %lu", &secret))
21329         secret_set = 1;
21330       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21331         sw_if_index_set = 1;
21332       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
21333         ;
21334       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
21335         ;
21336       else
21337         break;
21338     }
21339   if (!ns_id || !secret_set || !sw_if_index_set)
21340     {
21341       errmsg ("namespace id, secret and sw_if_index must be set");
21342       return -99;
21343     }
21344   if (vec_len (ns_id) > 64)
21345     {
21346       errmsg ("namespace id too long");
21347       return -99;
21348     }
21349   M (APP_NAMESPACE_ADD_DEL, mp);
21350
21351   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
21352   mp->namespace_id_len = vec_len (ns_id);
21353   mp->secret = clib_host_to_net_u64 (secret);
21354   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21355   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
21356   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
21357   vec_free (ns_id);
21358   S (mp);
21359   W (ret);
21360   return ret;
21361 }
21362
21363 static int
21364 api_memfd_segment_create (vat_main_t * vam)
21365 {
21366 #if VPP_API_TEST_BUILTIN == 0
21367   unformat_input_t *i = vam->input;
21368   vl_api_memfd_segment_create_t *mp;
21369   u64 size = 64 << 20;
21370   int ret;
21371
21372   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21373     {
21374       if (unformat (i, "size %U", unformat_memory_size, &size))
21375         ;
21376       else
21377         break;
21378     }
21379
21380   M (MEMFD_SEGMENT_CREATE, mp);
21381   mp->requested_size = size;
21382   S (mp);
21383   W (ret);
21384   return ret;
21385
21386 #else
21387   errmsg ("memfd_segment_create (builtin) not supported");
21388   return -99;
21389 #endif
21390 }
21391
21392 static int
21393 api_dns_enable_disable (vat_main_t * vam)
21394 {
21395   unformat_input_t *line_input = vam->input;
21396   vl_api_dns_enable_disable_t *mp;
21397   u8 enable_disable = 1;
21398   int ret;
21399
21400   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21401     {
21402       if (unformat (line_input, "disable"))
21403         enable_disable = 0;
21404       if (unformat (line_input, "enable"))
21405         enable_disable = 1;
21406       else
21407         break;
21408     }
21409
21410   /* Construct the API message */
21411   M (DNS_ENABLE_DISABLE, mp);
21412   mp->enable = enable_disable;
21413
21414   /* send it... */
21415   S (mp);
21416   /* Wait for the reply */
21417   W (ret);
21418   return ret;
21419 }
21420
21421 static int
21422 api_dns_resolve_name (vat_main_t * vam)
21423 {
21424   unformat_input_t *line_input = vam->input;
21425   vl_api_dns_resolve_name_t *mp;
21426   u8 *name = 0;
21427   int ret;
21428
21429   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21430     {
21431       if (unformat (line_input, "%s", &name))
21432         ;
21433       else
21434         break;
21435     }
21436
21437   if (vec_len (name) > 127)
21438     {
21439       errmsg ("name too long");
21440       return -99;
21441     }
21442
21443   /* Construct the API message */
21444   M (DNS_RESOLVE_NAME, mp);
21445   memcpy (mp->name, name, vec_len (name));
21446   vec_free (name);
21447
21448   /* send it... */
21449   S (mp);
21450   /* Wait for the reply */
21451   W (ret);
21452   return ret;
21453 }
21454
21455 static int
21456 api_dns_resolve_ip (vat_main_t * vam)
21457 {
21458   unformat_input_t *line_input = vam->input;
21459   vl_api_dns_resolve_ip_t *mp;
21460   int is_ip6 = -1;
21461   ip4_address_t addr4;
21462   ip6_address_t addr6;
21463   int ret;
21464
21465   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21466     {
21467       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21468         is_ip6 = 1;
21469       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21470         is_ip6 = 0;
21471       else
21472         break;
21473     }
21474
21475   if (is_ip6 == -1)
21476     {
21477       errmsg ("missing address");
21478       return -99;
21479     }
21480
21481   /* Construct the API message */
21482   M (DNS_RESOLVE_IP, mp);
21483   mp->is_ip6 = is_ip6;
21484   if (is_ip6)
21485     memcpy (mp->address, &addr6, sizeof (addr6));
21486   else
21487     memcpy (mp->address, &addr4, sizeof (addr4));
21488
21489   /* send it... */
21490   S (mp);
21491   /* Wait for the reply */
21492   W (ret);
21493   return ret;
21494 }
21495
21496 static int
21497 api_dns_name_server_add_del (vat_main_t * vam)
21498 {
21499   unformat_input_t *i = vam->input;
21500   vl_api_dns_name_server_add_del_t *mp;
21501   u8 is_add = 1;
21502   ip6_address_t ip6_server;
21503   ip4_address_t ip4_server;
21504   int ip6_set = 0;
21505   int ip4_set = 0;
21506   int ret = 0;
21507
21508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21509     {
21510       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21511         ip6_set = 1;
21512       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21513         ip4_set = 1;
21514       else if (unformat (i, "del"))
21515         is_add = 0;
21516       else
21517         {
21518           clib_warning ("parse error '%U'", format_unformat_error, i);
21519           return -99;
21520         }
21521     }
21522
21523   if (ip4_set && ip6_set)
21524     {
21525       errmsg ("Only one server address allowed per message");
21526       return -99;
21527     }
21528   if ((ip4_set + ip6_set) == 0)
21529     {
21530       errmsg ("Server address required");
21531       return -99;
21532     }
21533
21534   /* Construct the API message */
21535   M (DNS_NAME_SERVER_ADD_DEL, mp);
21536
21537   if (ip6_set)
21538     {
21539       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21540       mp->is_ip6 = 1;
21541     }
21542   else
21543     {
21544       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21545       mp->is_ip6 = 0;
21546     }
21547
21548   mp->is_add = is_add;
21549
21550   /* send it... */
21551   S (mp);
21552
21553   /* Wait for a reply, return good/bad news  */
21554   W (ret);
21555   return ret;
21556 }
21557
21558 static void
21559 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
21560 {
21561   vat_main_t *vam = &vat_main;
21562
21563   if (mp->is_ip4)
21564     {
21565       print (vam->ofp,
21566              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21567              mp->appns_index, mp->transport_proto, mp->scope,
21568              format_ip4_address, &mp->lcl_ip, mp->lcl_plen, mp->lcl_port,
21569              format_ip4_address, &mp->rmt_ip, mp->rmt_plen, mp->rmt_port,
21570              mp->action_index, mp->tag);
21571     }
21572   else
21573     {
21574       print (vam->ofp,
21575              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21576              mp->appns_index, mp->transport_proto, mp->scope,
21577              format_ip6_address, &mp->lcl_ip, mp->lcl_plen, mp->lcl_port,
21578              format_ip6_address, &mp->rmt_ip, mp->rmt_plen, mp->rmt_port,
21579              mp->action_index, mp->tag);
21580     }
21581 }
21582
21583 static void
21584 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
21585                                              mp)
21586 {
21587   vat_main_t *vam = &vat_main;
21588   vat_json_node_t *node = NULL;
21589   struct in6_addr ip6;
21590   struct in_addr ip4;
21591
21592   if (VAT_JSON_ARRAY != vam->json_tree.type)
21593     {
21594       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21595       vat_json_init_array (&vam->json_tree);
21596     }
21597   node = vat_json_array_add (&vam->json_tree);
21598   vat_json_init_object (node);
21599
21600   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
21601   vat_json_object_add_uint (node, "appns_index",
21602                             clib_net_to_host_u32 (mp->appns_index));
21603   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
21604   vat_json_object_add_uint (node, "scope", mp->scope);
21605   vat_json_object_add_uint (node, "action_index",
21606                             clib_net_to_host_u32 (mp->action_index));
21607   vat_json_object_add_uint (node, "lcl_port",
21608                             clib_net_to_host_u16 (mp->lcl_port));
21609   vat_json_object_add_uint (node, "rmt_port",
21610                             clib_net_to_host_u16 (mp->rmt_port));
21611   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
21612   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
21613   vat_json_object_add_string_copy (node, "tag", mp->tag);
21614   if (mp->is_ip4)
21615     {
21616       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
21617       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
21618       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
21619       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
21620     }
21621   else
21622     {
21623       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
21624       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
21625       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
21626       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
21627     }
21628 }
21629
21630 static int
21631 api_session_rule_add_del (vat_main_t * vam)
21632 {
21633   vl_api_session_rule_add_del_t *mp;
21634   unformat_input_t *i = vam->input;
21635   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
21636   u32 appns_index = 0, scope = 0;
21637   ip4_address_t lcl_ip4, rmt_ip4;
21638   ip6_address_t lcl_ip6, rmt_ip6;
21639   u8 is_ip4 = 1, conn_set = 0;
21640   u8 is_add = 1, *tag = 0;
21641   int ret;
21642
21643   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21644     {
21645       if (unformat (i, "del"))
21646         is_add = 0;
21647       else if (unformat (i, "add"))
21648         ;
21649       else if (unformat (i, "proto tcp"))
21650         proto = 0;
21651       else if (unformat (i, "proto udp"))
21652         proto = 1;
21653       else if (unformat (i, "appns %d", &appns_index))
21654         ;
21655       else if (unformat (i, "scope %d", &scope))
21656         ;
21657       else if (unformat (i, "tag %_%v%_", &tag))
21658         ;
21659       else
21660         if (unformat
21661             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
21662              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
21663              &rmt_port))
21664         {
21665           is_ip4 = 1;
21666           conn_set = 1;
21667         }
21668       else
21669         if (unformat
21670             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
21671              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
21672              &rmt_port))
21673         {
21674           is_ip4 = 0;
21675           conn_set = 1;
21676         }
21677       else if (unformat (i, "action %d", &action))
21678         ;
21679       else
21680         break;
21681     }
21682   if (proto == ~0 || !conn_set || action == ~0)
21683     {
21684       errmsg ("transport proto, connection and action must be set");
21685       return -99;
21686     }
21687
21688   if (scope > 3)
21689     {
21690       errmsg ("scope should be 0-3");
21691       return -99;
21692     }
21693
21694   M (SESSION_RULE_ADD_DEL, mp);
21695
21696   mp->is_ip4 = is_ip4;
21697   mp->transport_proto = proto;
21698   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
21699   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
21700   mp->lcl_plen = lcl_plen;
21701   mp->rmt_plen = rmt_plen;
21702   mp->action_index = clib_host_to_net_u32 (action);
21703   mp->appns_index = clib_host_to_net_u32 (appns_index);
21704   mp->scope = scope;
21705   mp->is_add = is_add;
21706   if (is_ip4)
21707     {
21708       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
21709       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
21710     }
21711   else
21712     {
21713       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
21714       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
21715     }
21716   if (tag)
21717     {
21718       clib_memcpy (mp->tag, tag, vec_len (tag));
21719       vec_free (tag);
21720     }
21721
21722   S (mp);
21723   W (ret);
21724   return ret;
21725 }
21726
21727 static int
21728 api_session_rules_dump (vat_main_t * vam)
21729 {
21730   vl_api_session_rules_dump_t *mp;
21731   vl_api_control_ping_t *mp_ping;
21732   int ret;
21733
21734   if (!vam->json_output)
21735     {
21736       print (vam->ofp, "%=20s", "Session Rules");
21737     }
21738
21739   M (SESSION_RULES_DUMP, mp);
21740   /* send it... */
21741   S (mp);
21742
21743   /* Use a control ping for synchronization */
21744   MPING (CONTROL_PING, mp_ping);
21745   S (mp_ping);
21746
21747   /* Wait for a reply... */
21748   W (ret);
21749   return ret;
21750 }
21751
21752 static int
21753 api_ip_container_proxy_add_del (vat_main_t * vam)
21754 {
21755   vl_api_ip_container_proxy_add_del_t *mp;
21756   unformat_input_t *i = vam->input;
21757   u32 plen = ~0, sw_if_index = ~0;
21758   ip4_address_t ip4;
21759   ip6_address_t ip6;
21760   u8 is_ip4 = 1;
21761   u8 is_add = 1;
21762   int ret;
21763
21764   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21765     {
21766       if (unformat (i, "del"))
21767         is_add = 0;
21768       else if (unformat (i, "add"))
21769         ;
21770       if (unformat (i, "%U", unformat_ip4_address, &ip4))
21771         {
21772           is_ip4 = 1;
21773           plen = 32;
21774         }
21775       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
21776         {
21777           is_ip4 = 0;
21778           plen = 128;
21779         }
21780       else if (unformat (i, "sw_if_index %u", &sw_if_index))
21781         ;
21782       else
21783         break;
21784     }
21785   if (sw_if_index == ~0 || plen == ~0)
21786     {
21787       errmsg ("address and sw_if_index must be set");
21788       return -99;
21789     }
21790
21791   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
21792
21793   mp->is_ip4 = is_ip4;
21794   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21795   mp->plen = plen;
21796   mp->is_add = is_add;
21797   if (is_ip4)
21798     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
21799   else
21800     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
21801
21802   S (mp);
21803   W (ret);
21804   return ret;
21805 }
21806
21807 static int
21808 q_or_quit (vat_main_t * vam)
21809 {
21810 #if VPP_API_TEST_BUILTIN == 0
21811   longjmp (vam->jump_buf, 1);
21812 #endif
21813   return 0;                     /* not so much */
21814 }
21815
21816 static int
21817 q (vat_main_t * vam)
21818 {
21819   return q_or_quit (vam);
21820 }
21821
21822 static int
21823 quit (vat_main_t * vam)
21824 {
21825   return q_or_quit (vam);
21826 }
21827
21828 static int
21829 comment (vat_main_t * vam)
21830 {
21831   return 0;
21832 }
21833
21834 static int
21835 cmd_cmp (void *a1, void *a2)
21836 {
21837   u8 **c1 = a1;
21838   u8 **c2 = a2;
21839
21840   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21841 }
21842
21843 static int
21844 help (vat_main_t * vam)
21845 {
21846   u8 **cmds = 0;
21847   u8 *name = 0;
21848   hash_pair_t *p;
21849   unformat_input_t *i = vam->input;
21850   int j;
21851
21852   if (unformat (i, "%s", &name))
21853     {
21854       uword *hs;
21855
21856       vec_add1 (name, 0);
21857
21858       hs = hash_get_mem (vam->help_by_name, name);
21859       if (hs)
21860         print (vam->ofp, "usage: %s %s", name, hs[0]);
21861       else
21862         print (vam->ofp, "No such msg / command '%s'", name);
21863       vec_free (name);
21864       return 0;
21865     }
21866
21867   print (vam->ofp, "Help is available for the following:");
21868
21869     /* *INDENT-OFF* */
21870     hash_foreach_pair (p, vam->function_by_name,
21871     ({
21872       vec_add1 (cmds, (u8 *)(p->key));
21873     }));
21874     /* *INDENT-ON* */
21875
21876   vec_sort_with_function (cmds, cmd_cmp);
21877
21878   for (j = 0; j < vec_len (cmds); j++)
21879     print (vam->ofp, "%s", cmds[j]);
21880
21881   vec_free (cmds);
21882   return 0;
21883 }
21884
21885 static int
21886 set (vat_main_t * vam)
21887 {
21888   u8 *name = 0, *value = 0;
21889   unformat_input_t *i = vam->input;
21890
21891   if (unformat (i, "%s", &name))
21892     {
21893       /* The input buffer is a vector, not a string. */
21894       value = vec_dup (i->buffer);
21895       vec_delete (value, i->index, 0);
21896       /* Almost certainly has a trailing newline */
21897       if (value[vec_len (value) - 1] == '\n')
21898         value[vec_len (value) - 1] = 0;
21899       /* Make sure it's a proper string, one way or the other */
21900       vec_add1 (value, 0);
21901       (void) clib_macro_set_value (&vam->macro_main,
21902                                    (char *) name, (char *) value);
21903     }
21904   else
21905     errmsg ("usage: set <name> <value>");
21906
21907   vec_free (name);
21908   vec_free (value);
21909   return 0;
21910 }
21911
21912 static int
21913 unset (vat_main_t * vam)
21914 {
21915   u8 *name = 0;
21916
21917   if (unformat (vam->input, "%s", &name))
21918     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21919       errmsg ("unset: %s wasn't set", name);
21920   vec_free (name);
21921   return 0;
21922 }
21923
21924 typedef struct
21925 {
21926   u8 *name;
21927   u8 *value;
21928 } macro_sort_t;
21929
21930
21931 static int
21932 macro_sort_cmp (void *a1, void *a2)
21933 {
21934   macro_sort_t *s1 = a1;
21935   macro_sort_t *s2 = a2;
21936
21937   return strcmp ((char *) (s1->name), (char *) (s2->name));
21938 }
21939
21940 static int
21941 dump_macro_table (vat_main_t * vam)
21942 {
21943   macro_sort_t *sort_me = 0, *sm;
21944   int i;
21945   hash_pair_t *p;
21946
21947     /* *INDENT-OFF* */
21948     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21949     ({
21950       vec_add2 (sort_me, sm, 1);
21951       sm->name = (u8 *)(p->key);
21952       sm->value = (u8 *) (p->value[0]);
21953     }));
21954     /* *INDENT-ON* */
21955
21956   vec_sort_with_function (sort_me, macro_sort_cmp);
21957
21958   if (vec_len (sort_me))
21959     print (vam->ofp, "%-15s%s", "Name", "Value");
21960   else
21961     print (vam->ofp, "The macro table is empty...");
21962
21963   for (i = 0; i < vec_len (sort_me); i++)
21964     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21965   return 0;
21966 }
21967
21968 static int
21969 dump_node_table (vat_main_t * vam)
21970 {
21971   int i, j;
21972   vlib_node_t *node, *next_node;
21973
21974   if (vec_len (vam->graph_nodes) == 0)
21975     {
21976       print (vam->ofp, "Node table empty, issue get_node_graph...");
21977       return 0;
21978     }
21979
21980   for (i = 0; i < vec_len (vam->graph_nodes); i++)
21981     {
21982       node = vam->graph_nodes[i];
21983       print (vam->ofp, "[%d] %s", i, node->name);
21984       for (j = 0; j < vec_len (node->next_nodes); j++)
21985         {
21986           if (node->next_nodes[j] != ~0)
21987             {
21988               next_node = vam->graph_nodes[node->next_nodes[j]];
21989               print (vam->ofp, "  [%d] %s", j, next_node->name);
21990             }
21991         }
21992     }
21993   return 0;
21994 }
21995
21996 static int
21997 value_sort_cmp (void *a1, void *a2)
21998 {
21999   name_sort_t *n1 = a1;
22000   name_sort_t *n2 = a2;
22001
22002   if (n1->value < n2->value)
22003     return -1;
22004   if (n1->value > n2->value)
22005     return 1;
22006   return 0;
22007 }
22008
22009
22010 static int
22011 dump_msg_api_table (vat_main_t * vam)
22012 {
22013   api_main_t *am = &api_main;
22014   name_sort_t *nses = 0, *ns;
22015   hash_pair_t *hp;
22016   int i;
22017
22018   /* *INDENT-OFF* */
22019   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
22020   ({
22021     vec_add2 (nses, ns, 1);
22022     ns->name = (u8 *)(hp->key);
22023     ns->value = (u32) hp->value[0];
22024   }));
22025   /* *INDENT-ON* */
22026
22027   vec_sort_with_function (nses, value_sort_cmp);
22028
22029   for (i = 0; i < vec_len (nses); i++)
22030     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
22031   vec_free (nses);
22032   return 0;
22033 }
22034
22035 static int
22036 get_msg_id (vat_main_t * vam)
22037 {
22038   u8 *name_and_crc;
22039   u32 message_index;
22040
22041   if (unformat (vam->input, "%s", &name_and_crc))
22042     {
22043       message_index = vl_api_get_msg_index (name_and_crc);
22044       if (message_index == ~0)
22045         {
22046           print (vam->ofp, " '%s' not found", name_and_crc);
22047           return 0;
22048         }
22049       print (vam->ofp, " '%s' has message index %d",
22050              name_and_crc, message_index);
22051       return 0;
22052     }
22053   errmsg ("name_and_crc required...");
22054   return 0;
22055 }
22056
22057 static int
22058 search_node_table (vat_main_t * vam)
22059 {
22060   unformat_input_t *line_input = vam->input;
22061   u8 *node_to_find;
22062   int j;
22063   vlib_node_t *node, *next_node;
22064   uword *p;
22065
22066   if (vam->graph_node_index_by_name == 0)
22067     {
22068       print (vam->ofp, "Node table empty, issue get_node_graph...");
22069       return 0;
22070     }
22071
22072   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22073     {
22074       if (unformat (line_input, "%s", &node_to_find))
22075         {
22076           vec_add1 (node_to_find, 0);
22077           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
22078           if (p == 0)
22079             {
22080               print (vam->ofp, "%s not found...", node_to_find);
22081               goto out;
22082             }
22083           node = vam->graph_nodes[p[0]];
22084           print (vam->ofp, "[%d] %s", p[0], node->name);
22085           for (j = 0; j < vec_len (node->next_nodes); j++)
22086             {
22087               if (node->next_nodes[j] != ~0)
22088                 {
22089                   next_node = vam->graph_nodes[node->next_nodes[j]];
22090                   print (vam->ofp, "  [%d] %s", j, next_node->name);
22091                 }
22092             }
22093         }
22094
22095       else
22096         {
22097           clib_warning ("parse error '%U'", format_unformat_error,
22098                         line_input);
22099           return -99;
22100         }
22101
22102     out:
22103       vec_free (node_to_find);
22104
22105     }
22106
22107   return 0;
22108 }
22109
22110
22111 static int
22112 script (vat_main_t * vam)
22113 {
22114 #if (VPP_API_TEST_BUILTIN==0)
22115   u8 *s = 0;
22116   char *save_current_file;
22117   unformat_input_t save_input;
22118   jmp_buf save_jump_buf;
22119   u32 save_line_number;
22120
22121   FILE *new_fp, *save_ifp;
22122
22123   if (unformat (vam->input, "%s", &s))
22124     {
22125       new_fp = fopen ((char *) s, "r");
22126       if (new_fp == 0)
22127         {
22128           errmsg ("Couldn't open script file %s", s);
22129           vec_free (s);
22130           return -99;
22131         }
22132     }
22133   else
22134     {
22135       errmsg ("Missing script name");
22136       return -99;
22137     }
22138
22139   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
22140   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
22141   save_ifp = vam->ifp;
22142   save_line_number = vam->input_line_number;
22143   save_current_file = (char *) vam->current_file;
22144
22145   vam->input_line_number = 0;
22146   vam->ifp = new_fp;
22147   vam->current_file = s;
22148   do_one_file (vam);
22149
22150   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
22151   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
22152   vam->ifp = save_ifp;
22153   vam->input_line_number = save_line_number;
22154   vam->current_file = (u8 *) save_current_file;
22155   vec_free (s);
22156
22157   return 0;
22158 #else
22159   clib_warning ("use the exec command...");
22160   return -99;
22161 #endif
22162 }
22163
22164 static int
22165 echo (vat_main_t * vam)
22166 {
22167   print (vam->ofp, "%v", vam->input->buffer);
22168   return 0;
22169 }
22170
22171 /* List of API message constructors, CLI names map to api_xxx */
22172 #define foreach_vpe_api_msg                                             \
22173 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
22174 _(sw_interface_dump,"")                                                 \
22175 _(sw_interface_set_flags,                                               \
22176   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
22177 _(sw_interface_add_del_address,                                         \
22178   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
22179 _(sw_interface_set_rx_mode,                                             \
22180   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
22181 _(sw_interface_set_table,                                               \
22182   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
22183 _(sw_interface_set_mpls_enable,                                         \
22184   "<intfc> | sw_if_index [disable | dis]")                              \
22185 _(sw_interface_set_vpath,                                               \
22186   "<intfc> | sw_if_index <id> enable | disable")                        \
22187 _(sw_interface_set_vxlan_bypass,                                        \
22188   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22189 _(sw_interface_set_geneve_bypass,                                       \
22190   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22191 _(sw_interface_set_l2_xconnect,                                         \
22192   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22193   "enable | disable")                                                   \
22194 _(sw_interface_set_l2_bridge,                                           \
22195   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
22196   "[shg <split-horizon-group>] [bvi]\n"                                 \
22197   "enable | disable")                                                   \
22198 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
22199 _(bridge_domain_add_del,                                                \
22200   "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") \
22201 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
22202 _(l2fib_add_del,                                                        \
22203   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
22204 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
22205 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
22206 _(l2_flags,                                                             \
22207   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22208 _(bridge_flags,                                                         \
22209   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22210 _(tap_connect,                                                          \
22211   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
22212 _(tap_modify,                                                           \
22213   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
22214 _(tap_delete,                                                           \
22215   "<vpp-if-name> | sw_if_index <id>")                                   \
22216 _(sw_interface_tap_dump, "")                                            \
22217 _(ip_table_add_del,                                                     \
22218   "table-id <n> [ipv6]\n")                                              \
22219 _(ip_add_del_route,                                                     \
22220   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
22221   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22222   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22223   "[multipath] [count <n>]")                                            \
22224 _(ip_mroute_add_del,                                                    \
22225   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
22226   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
22227 _(mpls_table_add_del,                                                   \
22228   "table-id <n>\n")                                                     \
22229 _(mpls_route_add_del,                                                   \
22230   "<label> <eos> via <addr> [table-id <n>]\n"                           \
22231   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22232   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22233   "[multipath] [count <n>]")                                            \
22234 _(mpls_ip_bind_unbind,                                                  \
22235   "<label> <addr/len>")                                                 \
22236 _(mpls_tunnel_add_del,                                                  \
22237   " via <addr> [table-id <n>]\n"                                        \
22238   "sw_if_index <id>] [l2]  [del]")                                      \
22239 _(proxy_arp_add_del,                                                    \
22240   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
22241 _(proxy_arp_intfc_enable_disable,                                       \
22242   "<intfc> | sw_if_index <id> enable | disable")                        \
22243 _(sw_interface_set_unnumbered,                                          \
22244   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
22245 _(ip_neighbor_add_del,                                                  \
22246   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
22247   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
22248 _(reset_vrf, "vrf <id> [ipv6]")                                         \
22249 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
22250 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
22251   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
22252   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
22253   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
22254 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
22255 _(reset_fib, "vrf <n> [ipv6]")                                          \
22256 _(dhcp_proxy_config,                                                    \
22257   "svr <v46-address> src <v46-address>\n"                               \
22258    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
22259 _(dhcp_proxy_set_vss,                                                   \
22260   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
22261 _(dhcp_proxy_dump, "ip6")                                               \
22262 _(dhcp_client_config,                                                   \
22263   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
22264 _(set_ip_flow_hash,                                                     \
22265   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
22266 _(sw_interface_ip6_enable_disable,                                      \
22267   "<intfc> | sw_if_index <id> enable | disable")                        \
22268 _(sw_interface_ip6_set_link_local_address,                              \
22269   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
22270 _(ip6nd_proxy_add_del,                                                  \
22271   "<intfc> | sw_if_index <id> <ip6-address>")                           \
22272 _(ip6nd_proxy_dump, "")                                                 \
22273 _(sw_interface_ip6nd_ra_prefix,                                         \
22274   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
22275   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
22276   "[nolink] [isno]")                                                    \
22277 _(sw_interface_ip6nd_ra_config,                                         \
22278   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
22279   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
22280   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
22281 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
22282 _(l2_patch_add_del,                                                     \
22283   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22284   "enable | disable")                                                   \
22285 _(sr_localsid_add_del,                                                  \
22286   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
22287   "fib-table <num> (end.psp) sw_if_index <num>")                        \
22288 _(classify_add_del_table,                                               \
22289   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
22290   " [del] [del-chain] mask <mask-value>\n"                              \
22291   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
22292   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
22293 _(classify_add_del_session,                                             \
22294   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
22295   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
22296   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
22297   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
22298 _(classify_set_interface_ip_table,                                      \
22299   "<intfc> | sw_if_index <nn> table <nn>")                              \
22300 _(classify_set_interface_l2_tables,                                     \
22301   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22302   "  [other-table <nn>]")                                               \
22303 _(get_node_index, "node <node-name")                                    \
22304 _(add_node_next, "node <node-name> next <next-node-name>")              \
22305 _(l2tpv3_create_tunnel,                                                 \
22306   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
22307   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
22308   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
22309 _(l2tpv3_set_tunnel_cookies,                                            \
22310   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
22311   "[new_remote_cookie <nn>]\n")                                         \
22312 _(l2tpv3_interface_enable_disable,                                      \
22313   "<intfc> | sw_if_index <nn> enable | disable")                        \
22314 _(l2tpv3_set_lookup_key,                                                \
22315   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
22316 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
22317 _(vxlan_add_del_tunnel,                                                 \
22318   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22319   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22320   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22321 _(geneve_add_del_tunnel,                                                \
22322   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22323   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22324   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22325 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22326 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22327 _(gre_add_del_tunnel,                                                   \
22328   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
22329 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22330 _(l2_fib_clear_table, "")                                               \
22331 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22332 _(l2_interface_vlan_tag_rewrite,                                        \
22333   "<intfc> | sw_if_index <nn> \n"                                       \
22334   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22335   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22336 _(create_vhost_user_if,                                                 \
22337         "socket <filename> [server] [renumber <dev_instance>] "         \
22338         "[mac <mac_address>]")                                          \
22339 _(modify_vhost_user_if,                                                 \
22340         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22341         "[server] [renumber <dev_instance>]")                           \
22342 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22343 _(sw_interface_vhost_user_dump, "")                                     \
22344 _(show_version, "")                                                     \
22345 _(vxlan_gpe_add_del_tunnel,                                             \
22346   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22347   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22348   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22349   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22350 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22351 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22352 _(interface_name_renumber,                                              \
22353   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22354 _(input_acl_set_interface,                                              \
22355   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22356   "  [l2-table <nn>] [del]")                                            \
22357 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22358 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22359 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22360 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22361 _(ip_dump, "ipv4 | ipv6")                                               \
22362 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22363 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22364   "  spid_id <n> ")                                                     \
22365 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22366   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22367   "  integ_alg <alg> integ_key <hex>")                                  \
22368 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
22369   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22370   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22371   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22372 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
22373 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22374   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22375   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22376   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
22377 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22378 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
22379   "  <alg> <hex>\n")                                                    \
22380 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22381 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
22382 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
22383   "(auth_data 0x<data> | auth_data <data>)")                            \
22384 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
22385   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
22386 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
22387   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
22388   "(local|remote)")                                                     \
22389 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
22390 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
22391 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22392 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22393 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
22394 _(ikev2_initiate_sa_init, "<profile_name>")                             \
22395 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
22396 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
22397 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
22398 _(delete_loopback,"sw_if_index <nn>")                                   \
22399 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22400 _(map_add_domain,                                                       \
22401   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
22402   "ip6-src <ip6addr> "                                                  \
22403   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
22404 _(map_del_domain, "index <n>")                                          \
22405 _(map_add_del_rule,                                                     \
22406   "index <n> psid <n> dst <ip6addr> [del]")                             \
22407 _(map_domain_dump, "")                                                  \
22408 _(map_rule_dump, "index <map-domain>")                                  \
22409 _(want_interface_events,  "enable|disable")                             \
22410 _(want_stats,"enable|disable")                                          \
22411 _(get_first_msg_id, "client <name>")                                    \
22412 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22413 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22414   "fib-id <nn> [ip4][ip6][default]")                                    \
22415 _(get_node_graph, " ")                                                  \
22416 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22417 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22418 _(ioam_disable, "")                                                     \
22419 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22420                             " sw_if_index <sw_if_index> p <priority> "  \
22421                             "w <weight>] [del]")                        \
22422 _(one_add_del_locator, "locator-set <locator_name> "                    \
22423                         "iface <intf> | sw_if_index <sw_if_index> "     \
22424                         "p <priority> w <weight> [del]")                \
22425 _(one_add_del_local_eid,"vni <vni> eid "                                \
22426                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22427                          "locator-set <locator_name> [del]"             \
22428                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22429 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22430 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22431 _(one_enable_disable, "enable|disable")                                 \
22432 _(one_map_register_enable_disable, "enable|disable")                    \
22433 _(one_map_register_fallback_threshold, "<value>")                       \
22434 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22435 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22436                                "[seid <seid>] "                         \
22437                                "rloc <locator> p <prio> "               \
22438                                "w <weight> [rloc <loc> ... ] "          \
22439                                "action <action> [del-all]")             \
22440 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22441                           "<local-eid>")                                \
22442 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22443 _(one_use_petr, "ip-address> | disable")                                \
22444 _(one_map_request_mode, "src-dst|dst-only")                             \
22445 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22446 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22447 _(one_locator_set_dump, "[local | remote]")                             \
22448 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22449 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22450                        "[local] | [remote]")                            \
22451 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22452 _(one_ndp_bd_get, "")                                                   \
22453 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22454 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22455 _(one_l2_arp_bd_get, "")                                                \
22456 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22457 _(one_stats_enable_disable, "enable|disalbe")                           \
22458 _(show_one_stats_enable_disable, "")                                    \
22459 _(one_eid_table_vni_dump, "")                                           \
22460 _(one_eid_table_map_dump, "l2|l3")                                      \
22461 _(one_map_resolver_dump, "")                                            \
22462 _(one_map_server_dump, "")                                              \
22463 _(one_adjacencies_get, "vni <vni>")                                     \
22464 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22465 _(show_one_rloc_probe_state, "")                                        \
22466 _(show_one_map_register_state, "")                                      \
22467 _(show_one_status, "")                                                  \
22468 _(one_stats_dump, "")                                                   \
22469 _(one_stats_flush, "")                                                  \
22470 _(one_get_map_request_itr_rlocs, "")                                    \
22471 _(one_map_register_set_ttl, "<ttl>")                                    \
22472 _(one_set_transport_protocol, "udp|api")                                \
22473 _(one_get_transport_protocol, "")                                       \
22474 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22475 _(one_show_xtr_mode, "")                                                \
22476 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22477 _(one_show_pitr_mode, "")                                               \
22478 _(one_enable_disable_petr_mode, "enable|disable")                       \
22479 _(one_show_petr_mode, "")                                               \
22480 _(show_one_nsh_mapping, "")                                             \
22481 _(show_one_pitr, "")                                                    \
22482 _(show_one_use_petr, "")                                                \
22483 _(show_one_map_request_mode, "")                                        \
22484 _(show_one_map_register_ttl, "")                                        \
22485 _(show_one_map_register_fallback_threshold, "")                         \
22486 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22487                             " sw_if_index <sw_if_index> p <priority> "  \
22488                             "w <weight>] [del]")                        \
22489 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22490                         "iface <intf> | sw_if_index <sw_if_index> "     \
22491                         "p <priority> w <weight> [del]")                \
22492 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22493                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22494                          "locator-set <locator_name> [del]"             \
22495                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22496 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22497 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22498 _(lisp_enable_disable, "enable|disable")                                \
22499 _(lisp_map_register_enable_disable, "enable|disable")                   \
22500 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22501 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22502                                "[seid <seid>] "                         \
22503                                "rloc <locator> p <prio> "               \
22504                                "w <weight> [rloc <loc> ... ] "          \
22505                                "action <action> [del-all]")             \
22506 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22507                           "<local-eid>")                                \
22508 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22509 _(lisp_use_petr, "<ip-address> | disable")                              \
22510 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22511 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22512 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22513 _(lisp_locator_set_dump, "[local | remote]")                            \
22514 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22515 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22516                        "[local] | [remote]")                            \
22517 _(lisp_eid_table_vni_dump, "")                                          \
22518 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22519 _(lisp_map_resolver_dump, "")                                           \
22520 _(lisp_map_server_dump, "")                                             \
22521 _(lisp_adjacencies_get, "vni <vni>")                                    \
22522 _(gpe_fwd_entry_vnis_get, "")                                           \
22523 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22524 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22525                                 "[table <table-id>]")                   \
22526 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22527 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22528 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22529 _(gpe_get_encap_mode, "")                                               \
22530 _(lisp_gpe_add_del_iface, "up|down")                                    \
22531 _(lisp_gpe_enable_disable, "enable|disable")                            \
22532 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22533   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22534 _(show_lisp_rloc_probe_state, "")                                       \
22535 _(show_lisp_map_register_state, "")                                     \
22536 _(show_lisp_status, "")                                                 \
22537 _(lisp_get_map_request_itr_rlocs, "")                                   \
22538 _(show_lisp_pitr, "")                                                   \
22539 _(show_lisp_use_petr, "")                                               \
22540 _(show_lisp_map_request_mode, "")                                       \
22541 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22542 _(af_packet_delete, "name <host interface name>")                       \
22543 _(policer_add_del, "name <policer name> <params> [del]")                \
22544 _(policer_dump, "[name <policer name>]")                                \
22545 _(policer_classify_set_interface,                                       \
22546   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22547   "  [l2-table <nn>] [del]")                                            \
22548 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22549 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22550     "[master|slave]")                                                   \
22551 _(netmap_delete, "name <interface name>")                               \
22552 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22553 _(mpls_fib_dump, "")                                                    \
22554 _(classify_table_ids, "")                                               \
22555 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22556 _(classify_table_info, "table_id <nn>")                                 \
22557 _(classify_session_dump, "table_id <nn>")                               \
22558 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22559     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22560     "[template_interval <nn>] [udp_checksum]")                          \
22561 _(ipfix_exporter_dump, "")                                              \
22562 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22563 _(ipfix_classify_stream_dump, "")                                       \
22564 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22565 _(ipfix_classify_table_dump, "")                                        \
22566 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22567 _(sw_interface_span_dump, "[l2]")                                           \
22568 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22569 _(pg_create_interface, "if_id <nn>")                                    \
22570 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22571 _(pg_enable_disable, "[stream <id>] disable")                           \
22572 _(ip_source_and_port_range_check_add_del,                               \
22573   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22574 _(ip_source_and_port_range_check_interface_add_del,                     \
22575   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
22576   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
22577 _(ipsec_gre_add_del_tunnel,                                             \
22578   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
22579 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
22580 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
22581 _(l2_interface_pbb_tag_rewrite,                                         \
22582   "<intfc> | sw_if_index <nn> \n"                                       \
22583   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
22584   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
22585 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
22586 _(flow_classify_set_interface,                                          \
22587   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
22588 _(flow_classify_dump, "type [ip4|ip6]")                                 \
22589 _(ip_fib_dump, "")                                                      \
22590 _(ip_mfib_dump, "")                                                     \
22591 _(ip6_fib_dump, "")                                                     \
22592 _(ip6_mfib_dump, "")                                                    \
22593 _(feature_enable_disable, "arc_name <arc_name> "                        \
22594   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
22595 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
22596 "[disable]")                                                            \
22597 _(l2_xconnect_dump, "")                                                 \
22598 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
22599 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
22600 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
22601 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
22602 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
22603 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
22604 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
22605   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
22606 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
22607 _(memfd_segment_create,"size <nnn>")                                    \
22608 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
22609 _(dns_enable_disable, "[enable][disable]")                              \
22610 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22611 _(dns_resolve_name, "<hostname>")                                       \
22612 _(dns_resolve_ip, "<ip4|ip6>")                                          \
22613 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22614 _(dns_resolve_name, "<hostname>")                                       \
22615 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
22616   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
22617 _(session_rules_dump, "")                                               \
22618 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
22619
22620 /* List of command functions, CLI names map directly to functions */
22621 #define foreach_cli_function                                    \
22622 _(comment, "usage: comment <ignore-rest-of-line>")              \
22623 _(dump_interface_table, "usage: dump_interface_table")          \
22624 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
22625 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
22626 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
22627 _(dump_stats_table, "usage: dump_stats_table")                  \
22628 _(dump_macro_table, "usage: dump_macro_table ")                 \
22629 _(dump_node_table, "usage: dump_node_table")                    \
22630 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
22631 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
22632 _(echo, "usage: echo <message>")                                \
22633 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
22634 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
22635 _(help, "usage: help")                                          \
22636 _(q, "usage: quit")                                             \
22637 _(quit, "usage: quit")                                          \
22638 _(search_node_table, "usage: search_node_table <name>...")      \
22639 _(set, "usage: set <variable-name> <value>")                    \
22640 _(script, "usage: script <file-name>")                          \
22641 _(unset, "usage: unset <variable-name>")
22642 #define _(N,n)                                  \
22643     static void vl_api_##n##_t_handler_uni      \
22644     (vl_api_##n##_t * mp)                       \
22645     {                                           \
22646         vat_main_t * vam = &vat_main;           \
22647         if (vam->json_output) {                 \
22648             vl_api_##n##_t_handler_json(mp);    \
22649         } else {                                \
22650             vl_api_##n##_t_handler(mp);         \
22651         }                                       \
22652     }
22653 foreach_vpe_api_reply_msg;
22654 #if VPP_API_TEST_BUILTIN == 0
22655 foreach_standalone_reply_msg;
22656 #endif
22657 #undef _
22658
22659 void
22660 vat_api_hookup (vat_main_t * vam)
22661 {
22662 #define _(N,n)                                                  \
22663     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22664                            vl_api_##n##_t_handler_uni,          \
22665                            vl_noop_handler,                     \
22666                            vl_api_##n##_t_endian,               \
22667                            vl_api_##n##_t_print,                \
22668                            sizeof(vl_api_##n##_t), 1);
22669   foreach_vpe_api_reply_msg;
22670 #if VPP_API_TEST_BUILTIN == 0
22671   foreach_standalone_reply_msg;
22672 #endif
22673 #undef _
22674
22675 #if (VPP_API_TEST_BUILTIN==0)
22676   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22677
22678   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22679
22680   vam->function_by_name = hash_create_string (0, sizeof (uword));
22681
22682   vam->help_by_name = hash_create_string (0, sizeof (uword));
22683 #endif
22684
22685   /* API messages we can send */
22686 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22687   foreach_vpe_api_msg;
22688 #undef _
22689
22690   /* Help strings */
22691 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22692   foreach_vpe_api_msg;
22693 #undef _
22694
22695   /* CLI functions */
22696 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22697   foreach_cli_function;
22698 #undef _
22699
22700   /* Help strings */
22701 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22702   foreach_cli_function;
22703 #undef _
22704 }
22705
22706 #if VPP_API_TEST_BUILTIN
22707 static clib_error_t *
22708 vat_api_hookup_shim (vlib_main_t * vm)
22709 {
22710   vat_api_hookup (&vat_main);
22711   return 0;
22712 }
22713
22714 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22715 #endif
22716
22717 /*
22718  * fd.io coding-style-patch-verification: ON
22719  *
22720  * Local Variables:
22721  * eval: (c-set-style "gnu")
22722  * End:
22723  */