session: add app ns index to ns create 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 _(bier_route_add_del_reply)                             \
5184 _(bier_table_add_del_reply)                             \
5185 _(proxy_arp_add_del_reply)                              \
5186 _(proxy_arp_intfc_enable_disable_reply)                 \
5187 _(sw_interface_set_unnumbered_reply)                    \
5188 _(ip_neighbor_add_del_reply)                            \
5189 _(reset_vrf_reply)                                      \
5190 _(oam_add_del_reply)                                    \
5191 _(reset_fib_reply)                                      \
5192 _(dhcp_proxy_config_reply)                              \
5193 _(dhcp_proxy_set_vss_reply)                             \
5194 _(dhcp_client_config_reply)                             \
5195 _(set_ip_flow_hash_reply)                               \
5196 _(sw_interface_ip6_enable_disable_reply)                \
5197 _(sw_interface_ip6_set_link_local_address_reply)        \
5198 _(ip6nd_proxy_add_del_reply)                            \
5199 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5200 _(sw_interface_ip6nd_ra_config_reply)                   \
5201 _(set_arp_neighbor_limit_reply)                         \
5202 _(l2_patch_add_del_reply)                               \
5203 _(sr_policy_add_reply)                                  \
5204 _(sr_policy_mod_reply)                                  \
5205 _(sr_policy_del_reply)                                  \
5206 _(sr_localsid_add_del_reply)                            \
5207 _(sr_steering_add_del_reply)                            \
5208 _(classify_add_del_session_reply)                       \
5209 _(classify_set_interface_ip_table_reply)                \
5210 _(classify_set_interface_l2_tables_reply)               \
5211 _(l2tpv3_set_tunnel_cookies_reply)                      \
5212 _(l2tpv3_interface_enable_disable_reply)                \
5213 _(l2tpv3_set_lookup_key_reply)                          \
5214 _(l2_fib_clear_table_reply)                             \
5215 _(l2_interface_efp_filter_reply)                        \
5216 _(l2_interface_vlan_tag_rewrite_reply)                  \
5217 _(modify_vhost_user_if_reply)                           \
5218 _(delete_vhost_user_if_reply)                           \
5219 _(want_ip4_arp_events_reply)                            \
5220 _(want_ip6_nd_events_reply)                             \
5221 _(want_l2_macs_events_reply)                            \
5222 _(input_acl_set_interface_reply)                        \
5223 _(ipsec_spd_add_del_reply)                              \
5224 _(ipsec_interface_add_del_spd_reply)                    \
5225 _(ipsec_spd_add_del_entry_reply)                        \
5226 _(ipsec_sad_add_del_entry_reply)                        \
5227 _(ipsec_sa_set_key_reply)                               \
5228 _(ipsec_tunnel_if_add_del_reply)                        \
5229 _(ipsec_tunnel_if_set_key_reply)                        \
5230 _(ipsec_tunnel_if_set_sa_reply)                         \
5231 _(ikev2_profile_add_del_reply)                          \
5232 _(ikev2_profile_set_auth_reply)                         \
5233 _(ikev2_profile_set_id_reply)                           \
5234 _(ikev2_profile_set_ts_reply)                           \
5235 _(ikev2_set_local_key_reply)                            \
5236 _(ikev2_set_responder_reply)                            \
5237 _(ikev2_set_ike_transforms_reply)                       \
5238 _(ikev2_set_esp_transforms_reply)                       \
5239 _(ikev2_set_sa_lifetime_reply)                          \
5240 _(ikev2_initiate_sa_init_reply)                         \
5241 _(ikev2_initiate_del_ike_sa_reply)                      \
5242 _(ikev2_initiate_del_child_sa_reply)                    \
5243 _(ikev2_initiate_rekey_child_sa_reply)                  \
5244 _(delete_loopback_reply)                                \
5245 _(bd_ip_mac_add_del_reply)                              \
5246 _(map_del_domain_reply)                                 \
5247 _(map_add_del_rule_reply)                               \
5248 _(want_interface_events_reply)                          \
5249 _(want_stats_reply)                                     \
5250 _(cop_interface_enable_disable_reply)                   \
5251 _(cop_whitelist_enable_disable_reply)                   \
5252 _(sw_interface_clear_stats_reply)                       \
5253 _(ioam_enable_reply)                                    \
5254 _(ioam_disable_reply)                                   \
5255 _(one_add_del_locator_reply)                            \
5256 _(one_add_del_local_eid_reply)                          \
5257 _(one_add_del_remote_mapping_reply)                     \
5258 _(one_add_del_adjacency_reply)                          \
5259 _(one_add_del_map_resolver_reply)                       \
5260 _(one_add_del_map_server_reply)                         \
5261 _(one_enable_disable_reply)                             \
5262 _(one_rloc_probe_enable_disable_reply)                  \
5263 _(one_map_register_enable_disable_reply)                \
5264 _(one_map_register_set_ttl_reply)                       \
5265 _(one_set_transport_protocol_reply)                     \
5266 _(one_map_register_fallback_threshold_reply)            \
5267 _(one_pitr_set_locator_set_reply)                       \
5268 _(one_map_request_mode_reply)                           \
5269 _(one_add_del_map_request_itr_rlocs_reply)              \
5270 _(one_eid_table_add_del_map_reply)                      \
5271 _(one_use_petr_reply)                                   \
5272 _(one_stats_enable_disable_reply)                       \
5273 _(one_add_del_l2_arp_entry_reply)                       \
5274 _(one_add_del_ndp_entry_reply)                          \
5275 _(one_stats_flush_reply)                                \
5276 _(one_enable_disable_xtr_mode_reply)                    \
5277 _(one_enable_disable_pitr_mode_reply)                   \
5278 _(one_enable_disable_petr_mode_reply)                   \
5279 _(gpe_enable_disable_reply)                             \
5280 _(gpe_set_encap_mode_reply)                             \
5281 _(gpe_add_del_iface_reply)                              \
5282 _(gpe_add_del_native_fwd_rpath_reply)                   \
5283 _(af_packet_delete_reply)                               \
5284 _(policer_classify_set_interface_reply)                 \
5285 _(netmap_create_reply)                                  \
5286 _(netmap_delete_reply)                                  \
5287 _(set_ipfix_exporter_reply)                             \
5288 _(set_ipfix_classify_stream_reply)                      \
5289 _(ipfix_classify_table_add_del_reply)                   \
5290 _(flow_classify_set_interface_reply)                    \
5291 _(sw_interface_span_enable_disable_reply)               \
5292 _(pg_capture_reply)                                     \
5293 _(pg_enable_disable_reply)                              \
5294 _(ip_source_and_port_range_check_add_del_reply)         \
5295 _(ip_source_and_port_range_check_interface_add_del_reply)\
5296 _(delete_subif_reply)                                   \
5297 _(l2_interface_pbb_tag_rewrite_reply)                   \
5298 _(punt_reply)                                           \
5299 _(feature_enable_disable_reply)                         \
5300 _(sw_interface_tag_add_del_reply)                       \
5301 _(sw_interface_set_mtu_reply)                           \
5302 _(p2p_ethernet_add_reply)                               \
5303 _(p2p_ethernet_del_reply)                               \
5304 _(lldp_config_reply)                                    \
5305 _(sw_interface_set_lldp_reply)                          \
5306 _(tcp_configure_src_addresses_reply)                    \
5307 _(dns_enable_disable_reply)                             \
5308 _(dns_name_server_add_del_reply)                        \
5309 _(session_rule_add_del_reply)                           \
5310 _(ip_container_proxy_add_del_reply)
5311
5312 #define _(n)                                    \
5313     static void vl_api_##n##_t_handler          \
5314     (vl_api_##n##_t * mp)                       \
5315     {                                           \
5316         vat_main_t * vam = &vat_main;           \
5317         i32 retval = ntohl(mp->retval);         \
5318         if (vam->async_mode) {                  \
5319             vam->async_errors += (retval < 0);  \
5320         } else {                                \
5321             vam->retval = retval;               \
5322             vam->result_ready = 1;              \
5323         }                                       \
5324     }
5325 foreach_standard_reply_retval_handler;
5326 #undef _
5327
5328 #define _(n)                                    \
5329     static void vl_api_##n##_t_handler_json     \
5330     (vl_api_##n##_t * mp)                       \
5331     {                                           \
5332         vat_main_t * vam = &vat_main;           \
5333         vat_json_node_t node;                   \
5334         vat_json_init_object(&node);            \
5335         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5336         vat_json_print(vam->ofp, &node);        \
5337         vam->retval = ntohl(mp->retval);        \
5338         vam->result_ready = 1;                  \
5339     }
5340 foreach_standard_reply_retval_handler;
5341 #undef _
5342
5343 /*
5344  * Table of message reply handlers, must include boilerplate handlers
5345  * we just generated
5346  */
5347
5348 #define foreach_vpe_api_reply_msg                                       \
5349 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5350 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5351 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5352 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5353 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5354 _(CLI_REPLY, cli_reply)                                                 \
5355 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5356 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5357   sw_interface_add_del_address_reply)                                   \
5358 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5359 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5360 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5361 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5362 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5363 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5364 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5365 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5366   sw_interface_set_l2_xconnect_reply)                                   \
5367 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5368   sw_interface_set_l2_bridge_reply)                                     \
5369 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5370 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5371 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5372 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5373 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5374 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5375 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5376 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5377 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5378 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5379 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5380 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5381 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5382 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5383 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5384 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5385 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5386 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5387 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5388 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5389 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5390 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5391   proxy_arp_intfc_enable_disable_reply)                                 \
5392 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5393 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5394   sw_interface_set_unnumbered_reply)                                    \
5395 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5396 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
5397 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5398 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5399 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5400 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5401 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5402 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5403 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5404 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5405 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5406 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5407   sw_interface_ip6_enable_disable_reply)                                \
5408 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5409   sw_interface_ip6_set_link_local_address_reply)                        \
5410 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5411 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5412 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5413   sw_interface_ip6nd_ra_prefix_reply)                                   \
5414 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5415   sw_interface_ip6nd_ra_config_reply)                                   \
5416 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5417 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5418 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5419 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5420 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5421 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5422 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5423 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5424 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5425 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5426 classify_set_interface_ip_table_reply)                                  \
5427 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5428   classify_set_interface_l2_tables_reply)                               \
5429 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5430 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5431 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5432 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5433 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5434   l2tpv3_interface_enable_disable_reply)                                \
5435 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5436 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5437 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5438 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5439 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5440 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5441 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5442 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5443 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5444 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5445 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5446 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5447 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5448 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5449 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5450 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5451 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5452 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
5453 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5454 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5455 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5456 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5457 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5458 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5459 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5460 _(L2_MACS_EVENT, l2_macs_event)                                         \
5461 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5462 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5463 _(IP_DETAILS, ip_details)                                               \
5464 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5465 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5466 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5467 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5468 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5469 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5470 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5471 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5472 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5473 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5474 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5475 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5476 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5477 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5478 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5479 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5480 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5481 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5482 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5483 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5484 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5485 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5486 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5487 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5488 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5489 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5490 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5491 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5492 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5493 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5494 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5495 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5496 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5497 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5498 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5499 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5500 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5501 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5502 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5503 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5504 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5505 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5506 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5507 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5508 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5509 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5510 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5511 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5512   one_map_register_enable_disable_reply)                                \
5513 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5514 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5515 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5516 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5517   one_map_register_fallback_threshold_reply)                            \
5518 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5519   one_rloc_probe_enable_disable_reply)                                  \
5520 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5521 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5522 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5523 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5524 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5525 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5526 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5527 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5528 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5529 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5530 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5531 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5532 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5533 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5534 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5535 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5536   show_one_stats_enable_disable_reply)                                  \
5537 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5538 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5539 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5540 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5541 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5542 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5543 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5544 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5545   one_enable_disable_pitr_mode_reply)                                   \
5546 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5547   one_enable_disable_petr_mode_reply)                                   \
5548 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5549 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5550 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5551 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5552 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5553 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5554 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5555 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5556 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5557 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5558 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5559 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5560   gpe_add_del_native_fwd_rpath_reply)                                   \
5561 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5562   gpe_fwd_entry_path_details)                                           \
5563 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5564 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5565   one_add_del_map_request_itr_rlocs_reply)                              \
5566 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5567   one_get_map_request_itr_rlocs_reply)                                  \
5568 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5569 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5570 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5571 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5572 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5573 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5574   show_one_map_register_state_reply)                                    \
5575 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5576 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5577   show_one_map_register_fallback_threshold_reply)                       \
5578 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5579 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5580 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5581 _(POLICER_DETAILS, policer_details)                                     \
5582 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5583 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5584 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5585 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5586 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5587 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5588 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5589 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5590 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5591 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5592 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5593 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5594 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5595 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5596 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5597 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5598 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5599 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5600 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5601 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5602 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5603 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5604 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5605 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5606 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5607  ip_source_and_port_range_check_add_del_reply)                          \
5608 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5609  ip_source_and_port_range_check_interface_add_del_reply)                \
5610 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5611 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5612 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5613 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5614 _(PUNT_REPLY, punt_reply)                                               \
5615 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5616 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5617 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5618 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5619 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5620 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5621 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5622 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5623 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5624 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5625 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5626 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5627 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5628 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5629 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5630 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5631 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5632 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5633 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5634 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5635 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5636
5637 #define foreach_standalone_reply_msg                                    \
5638 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5639 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5640 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5641 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5642 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5643 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5644 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
5645 _(MEMFD_SEGMENT_CREATE_REPLY, memfd_segment_create_reply)               \
5646
5647 typedef struct
5648 {
5649   u8 *name;
5650   u32 value;
5651 } name_sort_t;
5652
5653
5654 #define STR_VTR_OP_CASE(op)     \
5655     case L2_VTR_ ## op:         \
5656         return "" # op;
5657
5658 static const char *
5659 str_vtr_op (u32 vtr_op)
5660 {
5661   switch (vtr_op)
5662     {
5663       STR_VTR_OP_CASE (DISABLED);
5664       STR_VTR_OP_CASE (PUSH_1);
5665       STR_VTR_OP_CASE (PUSH_2);
5666       STR_VTR_OP_CASE (POP_1);
5667       STR_VTR_OP_CASE (POP_2);
5668       STR_VTR_OP_CASE (TRANSLATE_1_1);
5669       STR_VTR_OP_CASE (TRANSLATE_1_2);
5670       STR_VTR_OP_CASE (TRANSLATE_2_1);
5671       STR_VTR_OP_CASE (TRANSLATE_2_2);
5672     }
5673
5674   return "UNKNOWN";
5675 }
5676
5677 static int
5678 dump_sub_interface_table (vat_main_t * vam)
5679 {
5680   const sw_interface_subif_t *sub = NULL;
5681
5682   if (vam->json_output)
5683     {
5684       clib_warning
5685         ("JSON output supported only for VPE API calls and dump_stats_table");
5686       return -99;
5687     }
5688
5689   print (vam->ofp,
5690          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5691          "Interface", "sw_if_index",
5692          "sub id", "dot1ad", "tags", "outer id",
5693          "inner id", "exact", "default", "outer any", "inner any");
5694
5695   vec_foreach (sub, vam->sw_if_subif_table)
5696   {
5697     print (vam->ofp,
5698            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5699            sub->interface_name,
5700            sub->sw_if_index,
5701            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5702            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5703            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5704            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5705     if (sub->vtr_op != L2_VTR_DISABLED)
5706       {
5707         print (vam->ofp,
5708                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5709                "tag1: %d tag2: %d ]",
5710                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5711                sub->vtr_tag1, sub->vtr_tag2);
5712       }
5713   }
5714
5715   return 0;
5716 }
5717
5718 static int
5719 name_sort_cmp (void *a1, void *a2)
5720 {
5721   name_sort_t *n1 = a1;
5722   name_sort_t *n2 = a2;
5723
5724   return strcmp ((char *) n1->name, (char *) n2->name);
5725 }
5726
5727 static int
5728 dump_interface_table (vat_main_t * vam)
5729 {
5730   hash_pair_t *p;
5731   name_sort_t *nses = 0, *ns;
5732
5733   if (vam->json_output)
5734     {
5735       clib_warning
5736         ("JSON output supported only for VPE API calls and dump_stats_table");
5737       return -99;
5738     }
5739
5740   /* *INDENT-OFF* */
5741   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5742   ({
5743     vec_add2 (nses, ns, 1);
5744     ns->name = (u8 *)(p->key);
5745     ns->value = (u32) p->value[0];
5746   }));
5747   /* *INDENT-ON* */
5748
5749   vec_sort_with_function (nses, name_sort_cmp);
5750
5751   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5752   vec_foreach (ns, nses)
5753   {
5754     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5755   }
5756   vec_free (nses);
5757   return 0;
5758 }
5759
5760 static int
5761 dump_ip_table (vat_main_t * vam, int is_ipv6)
5762 {
5763   const ip_details_t *det = NULL;
5764   const ip_address_details_t *address = NULL;
5765   u32 i = ~0;
5766
5767   print (vam->ofp, "%-12s", "sw_if_index");
5768
5769   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5770   {
5771     i++;
5772     if (!det->present)
5773       {
5774         continue;
5775       }
5776     print (vam->ofp, "%-12d", i);
5777     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5778     if (!det->addr)
5779       {
5780         continue;
5781       }
5782     vec_foreach (address, det->addr)
5783     {
5784       print (vam->ofp,
5785              "            %-30U%-13d",
5786              is_ipv6 ? format_ip6_address : format_ip4_address,
5787              address->ip, address->prefix_length);
5788     }
5789   }
5790
5791   return 0;
5792 }
5793
5794 static int
5795 dump_ipv4_table (vat_main_t * vam)
5796 {
5797   if (vam->json_output)
5798     {
5799       clib_warning
5800         ("JSON output supported only for VPE API calls and dump_stats_table");
5801       return -99;
5802     }
5803
5804   return dump_ip_table (vam, 0);
5805 }
5806
5807 static int
5808 dump_ipv6_table (vat_main_t * vam)
5809 {
5810   if (vam->json_output)
5811     {
5812       clib_warning
5813         ("JSON output supported only for VPE API calls and dump_stats_table");
5814       return -99;
5815     }
5816
5817   return dump_ip_table (vam, 1);
5818 }
5819
5820 static char *
5821 counter_type_to_str (u8 counter_type, u8 is_combined)
5822 {
5823   if (!is_combined)
5824     {
5825       switch (counter_type)
5826         {
5827         case VNET_INTERFACE_COUNTER_DROP:
5828           return "drop";
5829         case VNET_INTERFACE_COUNTER_PUNT:
5830           return "punt";
5831         case VNET_INTERFACE_COUNTER_IP4:
5832           return "ip4";
5833         case VNET_INTERFACE_COUNTER_IP6:
5834           return "ip6";
5835         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5836           return "rx-no-buf";
5837         case VNET_INTERFACE_COUNTER_RX_MISS:
5838           return "rx-miss";
5839         case VNET_INTERFACE_COUNTER_RX_ERROR:
5840           return "rx-error";
5841         case VNET_INTERFACE_COUNTER_TX_ERROR:
5842           return "tx-error";
5843         default:
5844           return "INVALID-COUNTER-TYPE";
5845         }
5846     }
5847   else
5848     {
5849       switch (counter_type)
5850         {
5851         case VNET_INTERFACE_COUNTER_RX:
5852           return "rx";
5853         case VNET_INTERFACE_COUNTER_TX:
5854           return "tx";
5855         default:
5856           return "INVALID-COUNTER-TYPE";
5857         }
5858     }
5859 }
5860
5861 static int
5862 dump_stats_table (vat_main_t * vam)
5863 {
5864   vat_json_node_t node;
5865   vat_json_node_t *msg_array;
5866   vat_json_node_t *msg;
5867   vat_json_node_t *counter_array;
5868   vat_json_node_t *counter;
5869   interface_counter_t c;
5870   u64 packets;
5871   ip4_fib_counter_t *c4;
5872   ip6_fib_counter_t *c6;
5873   ip4_nbr_counter_t *n4;
5874   ip6_nbr_counter_t *n6;
5875   int i, j;
5876
5877   if (!vam->json_output)
5878     {
5879       clib_warning ("dump_stats_table supported only in JSON format");
5880       return -99;
5881     }
5882
5883   vat_json_init_object (&node);
5884
5885   /* interface counters */
5886   msg_array = vat_json_object_add (&node, "interface_counters");
5887   vat_json_init_array (msg_array);
5888   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5889     {
5890       msg = vat_json_array_add (msg_array);
5891       vat_json_init_object (msg);
5892       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5893                                        (u8 *) counter_type_to_str (i, 0));
5894       vat_json_object_add_int (msg, "is_combined", 0);
5895       counter_array = vat_json_object_add (msg, "data");
5896       vat_json_init_array (counter_array);
5897       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5898         {
5899           packets = vam->simple_interface_counters[i][j];
5900           vat_json_array_add_uint (counter_array, packets);
5901         }
5902     }
5903   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5904     {
5905       msg = vat_json_array_add (msg_array);
5906       vat_json_init_object (msg);
5907       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5908                                        (u8 *) counter_type_to_str (i, 1));
5909       vat_json_object_add_int (msg, "is_combined", 1);
5910       counter_array = vat_json_object_add (msg, "data");
5911       vat_json_init_array (counter_array);
5912       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5913         {
5914           c = vam->combined_interface_counters[i][j];
5915           counter = vat_json_array_add (counter_array);
5916           vat_json_init_object (counter);
5917           vat_json_object_add_uint (counter, "packets", c.packets);
5918           vat_json_object_add_uint (counter, "bytes", c.bytes);
5919         }
5920     }
5921
5922   /* ip4 fib counters */
5923   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
5924   vat_json_init_array (msg_array);
5925   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
5926     {
5927       msg = vat_json_array_add (msg_array);
5928       vat_json_init_object (msg);
5929       vat_json_object_add_uint (msg, "vrf_id",
5930                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
5931       counter_array = vat_json_object_add (msg, "c");
5932       vat_json_init_array (counter_array);
5933       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
5934         {
5935           counter = vat_json_array_add (counter_array);
5936           vat_json_init_object (counter);
5937           c4 = &vam->ip4_fib_counters[i][j];
5938           vat_json_object_add_ip4 (counter, "address", c4->address);
5939           vat_json_object_add_uint (counter, "address_length",
5940                                     c4->address_length);
5941           vat_json_object_add_uint (counter, "packets", c4->packets);
5942           vat_json_object_add_uint (counter, "bytes", c4->bytes);
5943         }
5944     }
5945
5946   /* ip6 fib counters */
5947   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
5948   vat_json_init_array (msg_array);
5949   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
5950     {
5951       msg = vat_json_array_add (msg_array);
5952       vat_json_init_object (msg);
5953       vat_json_object_add_uint (msg, "vrf_id",
5954                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
5955       counter_array = vat_json_object_add (msg, "c");
5956       vat_json_init_array (counter_array);
5957       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
5958         {
5959           counter = vat_json_array_add (counter_array);
5960           vat_json_init_object (counter);
5961           c6 = &vam->ip6_fib_counters[i][j];
5962           vat_json_object_add_ip6 (counter, "address", c6->address);
5963           vat_json_object_add_uint (counter, "address_length",
5964                                     c6->address_length);
5965           vat_json_object_add_uint (counter, "packets", c6->packets);
5966           vat_json_object_add_uint (counter, "bytes", c6->bytes);
5967         }
5968     }
5969
5970   /* ip4 nbr counters */
5971   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
5972   vat_json_init_array (msg_array);
5973   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
5974     {
5975       msg = vat_json_array_add (msg_array);
5976       vat_json_init_object (msg);
5977       vat_json_object_add_uint (msg, "sw_if_index", i);
5978       counter_array = vat_json_object_add (msg, "c");
5979       vat_json_init_array (counter_array);
5980       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
5981         {
5982           counter = vat_json_array_add (counter_array);
5983           vat_json_init_object (counter);
5984           n4 = &vam->ip4_nbr_counters[i][j];
5985           vat_json_object_add_ip4 (counter, "address", n4->address);
5986           vat_json_object_add_uint (counter, "link-type", n4->linkt);
5987           vat_json_object_add_uint (counter, "packets", n4->packets);
5988           vat_json_object_add_uint (counter, "bytes", n4->bytes);
5989         }
5990     }
5991
5992   /* ip6 nbr counters */
5993   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
5994   vat_json_init_array (msg_array);
5995   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
5996     {
5997       msg = vat_json_array_add (msg_array);
5998       vat_json_init_object (msg);
5999       vat_json_object_add_uint (msg, "sw_if_index", i);
6000       counter_array = vat_json_object_add (msg, "c");
6001       vat_json_init_array (counter_array);
6002       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
6003         {
6004           counter = vat_json_array_add (counter_array);
6005           vat_json_init_object (counter);
6006           n6 = &vam->ip6_nbr_counters[i][j];
6007           vat_json_object_add_ip6 (counter, "address", n6->address);
6008           vat_json_object_add_uint (counter, "packets", n6->packets);
6009           vat_json_object_add_uint (counter, "bytes", n6->bytes);
6010         }
6011     }
6012
6013   vat_json_print (vam->ofp, &node);
6014   vat_json_free (&node);
6015
6016   return 0;
6017 }
6018
6019 /*
6020  * Pass CLI buffers directly in the CLI_INBAND API message,
6021  * instead of an additional shared memory area.
6022  */
6023 static int
6024 exec_inband (vat_main_t * vam)
6025 {
6026   vl_api_cli_inband_t *mp;
6027   unformat_input_t *i = vam->input;
6028   int ret;
6029
6030   if (vec_len (i->buffer) == 0)
6031     return -1;
6032
6033   if (vam->exec_mode == 0 && unformat (i, "mode"))
6034     {
6035       vam->exec_mode = 1;
6036       return 0;
6037     }
6038   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
6039     {
6040       vam->exec_mode = 0;
6041       return 0;
6042     }
6043
6044   /*
6045    * In order for the CLI command to work, it
6046    * must be a vector ending in \n, not a C-string ending
6047    * in \n\0.
6048    */
6049   u32 len = vec_len (vam->input->buffer);
6050   M2 (CLI_INBAND, mp, len);
6051   clib_memcpy (mp->cmd, vam->input->buffer, len);
6052   mp->length = htonl (len);
6053
6054   S (mp);
6055   W (ret);
6056   /* json responses may or may not include a useful reply... */
6057   if (vec_len (vam->cmd_reply))
6058     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
6059   return ret;
6060 }
6061
6062 int
6063 exec (vat_main_t * vam)
6064 {
6065   return exec_inband (vam);
6066 }
6067
6068 static int
6069 api_create_loopback (vat_main_t * vam)
6070 {
6071   unformat_input_t *i = vam->input;
6072   vl_api_create_loopback_t *mp;
6073   vl_api_create_loopback_instance_t *mp_lbi;
6074   u8 mac_address[6];
6075   u8 mac_set = 0;
6076   u8 is_specified = 0;
6077   u32 user_instance = 0;
6078   int ret;
6079
6080   memset (mac_address, 0, sizeof (mac_address));
6081
6082   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6083     {
6084       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6085         mac_set = 1;
6086       if (unformat (i, "instance %d", &user_instance))
6087         is_specified = 1;
6088       else
6089         break;
6090     }
6091
6092   if (is_specified)
6093     {
6094       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
6095       mp_lbi->is_specified = is_specified;
6096       if (is_specified)
6097         mp_lbi->user_instance = htonl (user_instance);
6098       if (mac_set)
6099         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
6100       S (mp_lbi);
6101     }
6102   else
6103     {
6104       /* Construct the API message */
6105       M (CREATE_LOOPBACK, mp);
6106       if (mac_set)
6107         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
6108       S (mp);
6109     }
6110
6111   W (ret);
6112   return ret;
6113 }
6114
6115 static int
6116 api_delete_loopback (vat_main_t * vam)
6117 {
6118   unformat_input_t *i = vam->input;
6119   vl_api_delete_loopback_t *mp;
6120   u32 sw_if_index = ~0;
6121   int ret;
6122
6123   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6124     {
6125       if (unformat (i, "sw_if_index %d", &sw_if_index))
6126         ;
6127       else
6128         break;
6129     }
6130
6131   if (sw_if_index == ~0)
6132     {
6133       errmsg ("missing sw_if_index");
6134       return -99;
6135     }
6136
6137   /* Construct the API message */
6138   M (DELETE_LOOPBACK, mp);
6139   mp->sw_if_index = ntohl (sw_if_index);
6140
6141   S (mp);
6142   W (ret);
6143   return ret;
6144 }
6145
6146 static int
6147 api_want_stats (vat_main_t * vam)
6148 {
6149   unformat_input_t *i = vam->input;
6150   vl_api_want_stats_t *mp;
6151   int enable = -1;
6152   int ret;
6153
6154   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6155     {
6156       if (unformat (i, "enable"))
6157         enable = 1;
6158       else if (unformat (i, "disable"))
6159         enable = 0;
6160       else
6161         break;
6162     }
6163
6164   if (enable == -1)
6165     {
6166       errmsg ("missing enable|disable");
6167       return -99;
6168     }
6169
6170   M (WANT_STATS, mp);
6171   mp->enable_disable = enable;
6172
6173   S (mp);
6174   W (ret);
6175   return ret;
6176 }
6177
6178 static int
6179 api_want_interface_events (vat_main_t * vam)
6180 {
6181   unformat_input_t *i = vam->input;
6182   vl_api_want_interface_events_t *mp;
6183   int enable = -1;
6184   int ret;
6185
6186   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6187     {
6188       if (unformat (i, "enable"))
6189         enable = 1;
6190       else if (unformat (i, "disable"))
6191         enable = 0;
6192       else
6193         break;
6194     }
6195
6196   if (enable == -1)
6197     {
6198       errmsg ("missing enable|disable");
6199       return -99;
6200     }
6201
6202   M (WANT_INTERFACE_EVENTS, mp);
6203   mp->enable_disable = enable;
6204
6205   vam->interface_event_display = enable;
6206
6207   S (mp);
6208   W (ret);
6209   return ret;
6210 }
6211
6212
6213 /* Note: non-static, called once to set up the initial intfc table */
6214 int
6215 api_sw_interface_dump (vat_main_t * vam)
6216 {
6217   vl_api_sw_interface_dump_t *mp;
6218   vl_api_control_ping_t *mp_ping;
6219   hash_pair_t *p;
6220   name_sort_t *nses = 0, *ns;
6221   sw_interface_subif_t *sub = NULL;
6222   int ret;
6223
6224   /* Toss the old name table */
6225   /* *INDENT-OFF* */
6226   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6227   ({
6228     vec_add2 (nses, ns, 1);
6229     ns->name = (u8 *)(p->key);
6230     ns->value = (u32) p->value[0];
6231   }));
6232   /* *INDENT-ON* */
6233
6234   hash_free (vam->sw_if_index_by_interface_name);
6235
6236   vec_foreach (ns, nses) vec_free (ns->name);
6237
6238   vec_free (nses);
6239
6240   vec_foreach (sub, vam->sw_if_subif_table)
6241   {
6242     vec_free (sub->interface_name);
6243   }
6244   vec_free (vam->sw_if_subif_table);
6245
6246   /* recreate the interface name hash table */
6247   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6248
6249   /* Get list of ethernets */
6250   M (SW_INTERFACE_DUMP, mp);
6251   mp->name_filter_valid = 1;
6252   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
6253   S (mp);
6254
6255   /* and local / loopback interfaces */
6256   M (SW_INTERFACE_DUMP, mp);
6257   mp->name_filter_valid = 1;
6258   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
6259   S (mp);
6260
6261   /* and packet-generator interfaces */
6262   M (SW_INTERFACE_DUMP, mp);
6263   mp->name_filter_valid = 1;
6264   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
6265   S (mp);
6266
6267   /* and vxlan-gpe tunnel interfaces */
6268   M (SW_INTERFACE_DUMP, mp);
6269   mp->name_filter_valid = 1;
6270   strncpy ((char *) mp->name_filter, "vxlan_gpe",
6271            sizeof (mp->name_filter) - 1);
6272   S (mp);
6273
6274   /* and vxlan tunnel interfaces */
6275   M (SW_INTERFACE_DUMP, mp);
6276   mp->name_filter_valid = 1;
6277   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
6278   S (mp);
6279
6280   /* and geneve tunnel interfaces */
6281   M (SW_INTERFACE_DUMP, mp);
6282   mp->name_filter_valid = 1;
6283   strncpy ((char *) mp->name_filter, "geneve", sizeof (mp->name_filter) - 1);
6284   S (mp);
6285
6286   /* and host (af_packet) interfaces */
6287   M (SW_INTERFACE_DUMP, mp);
6288   mp->name_filter_valid = 1;
6289   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
6290   S (mp);
6291
6292   /* and l2tpv3 tunnel interfaces */
6293   M (SW_INTERFACE_DUMP, mp);
6294   mp->name_filter_valid = 1;
6295   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
6296            sizeof (mp->name_filter) - 1);
6297   S (mp);
6298
6299   /* and GRE tunnel interfaces */
6300   M (SW_INTERFACE_DUMP, mp);
6301   mp->name_filter_valid = 1;
6302   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
6303   S (mp);
6304
6305   /* and LISP-GPE interfaces */
6306   M (SW_INTERFACE_DUMP, mp);
6307   mp->name_filter_valid = 1;
6308   strncpy ((char *) mp->name_filter, "lisp_gpe",
6309            sizeof (mp->name_filter) - 1);
6310   S (mp);
6311
6312   /* and IPSEC tunnel interfaces */
6313   M (SW_INTERFACE_DUMP, mp);
6314   mp->name_filter_valid = 1;
6315   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
6316   S (mp);
6317
6318   /* Use a control ping for synchronization */
6319   MPING (CONTROL_PING, mp_ping);
6320   S (mp_ping);
6321
6322   W (ret);
6323   return ret;
6324 }
6325
6326 static int
6327 api_sw_interface_set_flags (vat_main_t * vam)
6328 {
6329   unformat_input_t *i = vam->input;
6330   vl_api_sw_interface_set_flags_t *mp;
6331   u32 sw_if_index;
6332   u8 sw_if_index_set = 0;
6333   u8 admin_up = 0;
6334   int ret;
6335
6336   /* Parse args required to build the message */
6337   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6338     {
6339       if (unformat (i, "admin-up"))
6340         admin_up = 1;
6341       else if (unformat (i, "admin-down"))
6342         admin_up = 0;
6343       else
6344         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6345         sw_if_index_set = 1;
6346       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6347         sw_if_index_set = 1;
6348       else
6349         break;
6350     }
6351
6352   if (sw_if_index_set == 0)
6353     {
6354       errmsg ("missing interface name or sw_if_index");
6355       return -99;
6356     }
6357
6358   /* Construct the API message */
6359   M (SW_INTERFACE_SET_FLAGS, mp);
6360   mp->sw_if_index = ntohl (sw_if_index);
6361   mp->admin_up_down = admin_up;
6362
6363   /* send it... */
6364   S (mp);
6365
6366   /* Wait for a reply, return the good/bad news... */
6367   W (ret);
6368   return ret;
6369 }
6370
6371 static int
6372 api_sw_interface_set_rx_mode (vat_main_t * vam)
6373 {
6374   unformat_input_t *i = vam->input;
6375   vl_api_sw_interface_set_rx_mode_t *mp;
6376   u32 sw_if_index;
6377   u8 sw_if_index_set = 0;
6378   int ret;
6379   u8 queue_id_valid = 0;
6380   u32 queue_id;
6381   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6382
6383   /* Parse args required to build the message */
6384   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6385     {
6386       if (unformat (i, "queue %d", &queue_id))
6387         queue_id_valid = 1;
6388       else if (unformat (i, "polling"))
6389         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6390       else if (unformat (i, "interrupt"))
6391         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6392       else if (unformat (i, "adaptive"))
6393         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6394       else
6395         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6396         sw_if_index_set = 1;
6397       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6398         sw_if_index_set = 1;
6399       else
6400         break;
6401     }
6402
6403   if (sw_if_index_set == 0)
6404     {
6405       errmsg ("missing interface name or sw_if_index");
6406       return -99;
6407     }
6408   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6409     {
6410       errmsg ("missing rx-mode");
6411       return -99;
6412     }
6413
6414   /* Construct the API message */
6415   M (SW_INTERFACE_SET_RX_MODE, mp);
6416   mp->sw_if_index = ntohl (sw_if_index);
6417   mp->mode = mode;
6418   mp->queue_id_valid = queue_id_valid;
6419   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6420
6421   /* send it... */
6422   S (mp);
6423
6424   /* Wait for a reply, return the good/bad news... */
6425   W (ret);
6426   return ret;
6427 }
6428
6429 static int
6430 api_sw_interface_clear_stats (vat_main_t * vam)
6431 {
6432   unformat_input_t *i = vam->input;
6433   vl_api_sw_interface_clear_stats_t *mp;
6434   u32 sw_if_index;
6435   u8 sw_if_index_set = 0;
6436   int ret;
6437
6438   /* Parse args required to build the message */
6439   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6440     {
6441       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6442         sw_if_index_set = 1;
6443       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6444         sw_if_index_set = 1;
6445       else
6446         break;
6447     }
6448
6449   /* Construct the API message */
6450   M (SW_INTERFACE_CLEAR_STATS, mp);
6451
6452   if (sw_if_index_set == 1)
6453     mp->sw_if_index = ntohl (sw_if_index);
6454   else
6455     mp->sw_if_index = ~0;
6456
6457   /* send it... */
6458   S (mp);
6459
6460   /* Wait for a reply, return the good/bad news... */
6461   W (ret);
6462   return ret;
6463 }
6464
6465 static int
6466 api_sw_interface_add_del_address (vat_main_t * vam)
6467 {
6468   unformat_input_t *i = vam->input;
6469   vl_api_sw_interface_add_del_address_t *mp;
6470   u32 sw_if_index;
6471   u8 sw_if_index_set = 0;
6472   u8 is_add = 1, del_all = 0;
6473   u32 address_length = 0;
6474   u8 v4_address_set = 0;
6475   u8 v6_address_set = 0;
6476   ip4_address_t v4address;
6477   ip6_address_t v6address;
6478   int ret;
6479
6480   /* Parse args required to build the message */
6481   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6482     {
6483       if (unformat (i, "del-all"))
6484         del_all = 1;
6485       else if (unformat (i, "del"))
6486         is_add = 0;
6487       else
6488         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6489         sw_if_index_set = 1;
6490       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6491         sw_if_index_set = 1;
6492       else if (unformat (i, "%U/%d",
6493                          unformat_ip4_address, &v4address, &address_length))
6494         v4_address_set = 1;
6495       else if (unformat (i, "%U/%d",
6496                          unformat_ip6_address, &v6address, &address_length))
6497         v6_address_set = 1;
6498       else
6499         break;
6500     }
6501
6502   if (sw_if_index_set == 0)
6503     {
6504       errmsg ("missing interface name or sw_if_index");
6505       return -99;
6506     }
6507   if (v4_address_set && v6_address_set)
6508     {
6509       errmsg ("both v4 and v6 addresses set");
6510       return -99;
6511     }
6512   if (!v4_address_set && !v6_address_set && !del_all)
6513     {
6514       errmsg ("no addresses set");
6515       return -99;
6516     }
6517
6518   /* Construct the API message */
6519   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6520
6521   mp->sw_if_index = ntohl (sw_if_index);
6522   mp->is_add = is_add;
6523   mp->del_all = del_all;
6524   if (v6_address_set)
6525     {
6526       mp->is_ipv6 = 1;
6527       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6528     }
6529   else
6530     {
6531       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6532     }
6533   mp->address_length = address_length;
6534
6535   /* send it... */
6536   S (mp);
6537
6538   /* Wait for a reply, return good/bad news  */
6539   W (ret);
6540   return ret;
6541 }
6542
6543 static int
6544 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6545 {
6546   unformat_input_t *i = vam->input;
6547   vl_api_sw_interface_set_mpls_enable_t *mp;
6548   u32 sw_if_index;
6549   u8 sw_if_index_set = 0;
6550   u8 enable = 1;
6551   int ret;
6552
6553   /* Parse args required to build the message */
6554   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6555     {
6556       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6557         sw_if_index_set = 1;
6558       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6559         sw_if_index_set = 1;
6560       else if (unformat (i, "disable"))
6561         enable = 0;
6562       else if (unformat (i, "dis"))
6563         enable = 0;
6564       else
6565         break;
6566     }
6567
6568   if (sw_if_index_set == 0)
6569     {
6570       errmsg ("missing interface name or sw_if_index");
6571       return -99;
6572     }
6573
6574   /* Construct the API message */
6575   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6576
6577   mp->sw_if_index = ntohl (sw_if_index);
6578   mp->enable = enable;
6579
6580   /* send it... */
6581   S (mp);
6582
6583   /* Wait for a reply... */
6584   W (ret);
6585   return ret;
6586 }
6587
6588 static int
6589 api_sw_interface_set_table (vat_main_t * vam)
6590 {
6591   unformat_input_t *i = vam->input;
6592   vl_api_sw_interface_set_table_t *mp;
6593   u32 sw_if_index, vrf_id = 0;
6594   u8 sw_if_index_set = 0;
6595   u8 is_ipv6 = 0;
6596   int ret;
6597
6598   /* Parse args required to build the message */
6599   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6600     {
6601       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6602         sw_if_index_set = 1;
6603       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6604         sw_if_index_set = 1;
6605       else if (unformat (i, "vrf %d", &vrf_id))
6606         ;
6607       else if (unformat (i, "ipv6"))
6608         is_ipv6 = 1;
6609       else
6610         break;
6611     }
6612
6613   if (sw_if_index_set == 0)
6614     {
6615       errmsg ("missing interface name or sw_if_index");
6616       return -99;
6617     }
6618
6619   /* Construct the API message */
6620   M (SW_INTERFACE_SET_TABLE, mp);
6621
6622   mp->sw_if_index = ntohl (sw_if_index);
6623   mp->is_ipv6 = is_ipv6;
6624   mp->vrf_id = ntohl (vrf_id);
6625
6626   /* send it... */
6627   S (mp);
6628
6629   /* Wait for a reply... */
6630   W (ret);
6631   return ret;
6632 }
6633
6634 static void vl_api_sw_interface_get_table_reply_t_handler
6635   (vl_api_sw_interface_get_table_reply_t * mp)
6636 {
6637   vat_main_t *vam = &vat_main;
6638
6639   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6640
6641   vam->retval = ntohl (mp->retval);
6642   vam->result_ready = 1;
6643
6644 }
6645
6646 static void vl_api_sw_interface_get_table_reply_t_handler_json
6647   (vl_api_sw_interface_get_table_reply_t * mp)
6648 {
6649   vat_main_t *vam = &vat_main;
6650   vat_json_node_t node;
6651
6652   vat_json_init_object (&node);
6653   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6654   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6655
6656   vat_json_print (vam->ofp, &node);
6657   vat_json_free (&node);
6658
6659   vam->retval = ntohl (mp->retval);
6660   vam->result_ready = 1;
6661 }
6662
6663 static int
6664 api_sw_interface_get_table (vat_main_t * vam)
6665 {
6666   unformat_input_t *i = vam->input;
6667   vl_api_sw_interface_get_table_t *mp;
6668   u32 sw_if_index;
6669   u8 sw_if_index_set = 0;
6670   u8 is_ipv6 = 0;
6671   int ret;
6672
6673   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6674     {
6675       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6676         sw_if_index_set = 1;
6677       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6678         sw_if_index_set = 1;
6679       else if (unformat (i, "ipv6"))
6680         is_ipv6 = 1;
6681       else
6682         break;
6683     }
6684
6685   if (sw_if_index_set == 0)
6686     {
6687       errmsg ("missing interface name or sw_if_index");
6688       return -99;
6689     }
6690
6691   M (SW_INTERFACE_GET_TABLE, mp);
6692   mp->sw_if_index = htonl (sw_if_index);
6693   mp->is_ipv6 = is_ipv6;
6694
6695   S (mp);
6696   W (ret);
6697   return ret;
6698 }
6699
6700 static int
6701 api_sw_interface_set_vpath (vat_main_t * vam)
6702 {
6703   unformat_input_t *i = vam->input;
6704   vl_api_sw_interface_set_vpath_t *mp;
6705   u32 sw_if_index = 0;
6706   u8 sw_if_index_set = 0;
6707   u8 is_enable = 0;
6708   int ret;
6709
6710   /* Parse args required to build the message */
6711   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6712     {
6713       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6714         sw_if_index_set = 1;
6715       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6716         sw_if_index_set = 1;
6717       else if (unformat (i, "enable"))
6718         is_enable = 1;
6719       else if (unformat (i, "disable"))
6720         is_enable = 0;
6721       else
6722         break;
6723     }
6724
6725   if (sw_if_index_set == 0)
6726     {
6727       errmsg ("missing interface name or sw_if_index");
6728       return -99;
6729     }
6730
6731   /* Construct the API message */
6732   M (SW_INTERFACE_SET_VPATH, mp);
6733
6734   mp->sw_if_index = ntohl (sw_if_index);
6735   mp->enable = is_enable;
6736
6737   /* send it... */
6738   S (mp);
6739
6740   /* Wait for a reply... */
6741   W (ret);
6742   return ret;
6743 }
6744
6745 static int
6746 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6747 {
6748   unformat_input_t *i = vam->input;
6749   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6750   u32 sw_if_index = 0;
6751   u8 sw_if_index_set = 0;
6752   u8 is_enable = 1;
6753   u8 is_ipv6 = 0;
6754   int ret;
6755
6756   /* Parse args required to build the message */
6757   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6758     {
6759       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6760         sw_if_index_set = 1;
6761       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6762         sw_if_index_set = 1;
6763       else if (unformat (i, "enable"))
6764         is_enable = 1;
6765       else if (unformat (i, "disable"))
6766         is_enable = 0;
6767       else if (unformat (i, "ip4"))
6768         is_ipv6 = 0;
6769       else if (unformat (i, "ip6"))
6770         is_ipv6 = 1;
6771       else
6772         break;
6773     }
6774
6775   if (sw_if_index_set == 0)
6776     {
6777       errmsg ("missing interface name or sw_if_index");
6778       return -99;
6779     }
6780
6781   /* Construct the API message */
6782   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6783
6784   mp->sw_if_index = ntohl (sw_if_index);
6785   mp->enable = is_enable;
6786   mp->is_ipv6 = is_ipv6;
6787
6788   /* send it... */
6789   S (mp);
6790
6791   /* Wait for a reply... */
6792   W (ret);
6793   return ret;
6794 }
6795
6796 static int
6797 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6798 {
6799   unformat_input_t *i = vam->input;
6800   vl_api_sw_interface_set_geneve_bypass_t *mp;
6801   u32 sw_if_index = 0;
6802   u8 sw_if_index_set = 0;
6803   u8 is_enable = 1;
6804   u8 is_ipv6 = 0;
6805   int ret;
6806
6807   /* Parse args required to build the message */
6808   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6809     {
6810       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6811         sw_if_index_set = 1;
6812       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6813         sw_if_index_set = 1;
6814       else if (unformat (i, "enable"))
6815         is_enable = 1;
6816       else if (unformat (i, "disable"))
6817         is_enable = 0;
6818       else if (unformat (i, "ip4"))
6819         is_ipv6 = 0;
6820       else if (unformat (i, "ip6"))
6821         is_ipv6 = 1;
6822       else
6823         break;
6824     }
6825
6826   if (sw_if_index_set == 0)
6827     {
6828       errmsg ("missing interface name or sw_if_index");
6829       return -99;
6830     }
6831
6832   /* Construct the API message */
6833   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6834
6835   mp->sw_if_index = ntohl (sw_if_index);
6836   mp->enable = is_enable;
6837   mp->is_ipv6 = is_ipv6;
6838
6839   /* send it... */
6840   S (mp);
6841
6842   /* Wait for a reply... */
6843   W (ret);
6844   return ret;
6845 }
6846
6847 static int
6848 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6849 {
6850   unformat_input_t *i = vam->input;
6851   vl_api_sw_interface_set_l2_xconnect_t *mp;
6852   u32 rx_sw_if_index;
6853   u8 rx_sw_if_index_set = 0;
6854   u32 tx_sw_if_index;
6855   u8 tx_sw_if_index_set = 0;
6856   u8 enable = 1;
6857   int ret;
6858
6859   /* Parse args required to build the message */
6860   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6861     {
6862       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6863         rx_sw_if_index_set = 1;
6864       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6865         tx_sw_if_index_set = 1;
6866       else if (unformat (i, "rx"))
6867         {
6868           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6869             {
6870               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6871                             &rx_sw_if_index))
6872                 rx_sw_if_index_set = 1;
6873             }
6874           else
6875             break;
6876         }
6877       else if (unformat (i, "tx"))
6878         {
6879           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6880             {
6881               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6882                             &tx_sw_if_index))
6883                 tx_sw_if_index_set = 1;
6884             }
6885           else
6886             break;
6887         }
6888       else if (unformat (i, "enable"))
6889         enable = 1;
6890       else if (unformat (i, "disable"))
6891         enable = 0;
6892       else
6893         break;
6894     }
6895
6896   if (rx_sw_if_index_set == 0)
6897     {
6898       errmsg ("missing rx interface name or rx_sw_if_index");
6899       return -99;
6900     }
6901
6902   if (enable && (tx_sw_if_index_set == 0))
6903     {
6904       errmsg ("missing tx interface name or tx_sw_if_index");
6905       return -99;
6906     }
6907
6908   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6909
6910   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6911   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6912   mp->enable = enable;
6913
6914   S (mp);
6915   W (ret);
6916   return ret;
6917 }
6918
6919 static int
6920 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6921 {
6922   unformat_input_t *i = vam->input;
6923   vl_api_sw_interface_set_l2_bridge_t *mp;
6924   u32 rx_sw_if_index;
6925   u8 rx_sw_if_index_set = 0;
6926   u32 bd_id;
6927   u8 bd_id_set = 0;
6928   u8 bvi = 0;
6929   u32 shg = 0;
6930   u8 enable = 1;
6931   int ret;
6932
6933   /* Parse args required to build the message */
6934   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6935     {
6936       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6937         rx_sw_if_index_set = 1;
6938       else if (unformat (i, "bd_id %d", &bd_id))
6939         bd_id_set = 1;
6940       else
6941         if (unformat
6942             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6943         rx_sw_if_index_set = 1;
6944       else if (unformat (i, "shg %d", &shg))
6945         ;
6946       else if (unformat (i, "bvi"))
6947         bvi = 1;
6948       else if (unformat (i, "enable"))
6949         enable = 1;
6950       else if (unformat (i, "disable"))
6951         enable = 0;
6952       else
6953         break;
6954     }
6955
6956   if (rx_sw_if_index_set == 0)
6957     {
6958       errmsg ("missing rx interface name or sw_if_index");
6959       return -99;
6960     }
6961
6962   if (enable && (bd_id_set == 0))
6963     {
6964       errmsg ("missing bridge domain");
6965       return -99;
6966     }
6967
6968   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6969
6970   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6971   mp->bd_id = ntohl (bd_id);
6972   mp->shg = (u8) shg;
6973   mp->bvi = bvi;
6974   mp->enable = enable;
6975
6976   S (mp);
6977   W (ret);
6978   return ret;
6979 }
6980
6981 static int
6982 api_bridge_domain_dump (vat_main_t * vam)
6983 {
6984   unformat_input_t *i = vam->input;
6985   vl_api_bridge_domain_dump_t *mp;
6986   vl_api_control_ping_t *mp_ping;
6987   u32 bd_id = ~0;
6988   int ret;
6989
6990   /* Parse args required to build the message */
6991   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6992     {
6993       if (unformat (i, "bd_id %d", &bd_id))
6994         ;
6995       else
6996         break;
6997     }
6998
6999   M (BRIDGE_DOMAIN_DUMP, mp);
7000   mp->bd_id = ntohl (bd_id);
7001   S (mp);
7002
7003   /* Use a control ping for synchronization */
7004   MPING (CONTROL_PING, mp_ping);
7005   S (mp_ping);
7006
7007   W (ret);
7008   return ret;
7009 }
7010
7011 static int
7012 api_bridge_domain_add_del (vat_main_t * vam)
7013 {
7014   unformat_input_t *i = vam->input;
7015   vl_api_bridge_domain_add_del_t *mp;
7016   u32 bd_id = ~0;
7017   u8 is_add = 1;
7018   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
7019   u8 *bd_tag = NULL;
7020   u32 mac_age = 0;
7021   int ret;
7022
7023   /* Parse args required to build the message */
7024   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7025     {
7026       if (unformat (i, "bd_id %d", &bd_id))
7027         ;
7028       else if (unformat (i, "flood %d", &flood))
7029         ;
7030       else if (unformat (i, "uu-flood %d", &uu_flood))
7031         ;
7032       else if (unformat (i, "forward %d", &forward))
7033         ;
7034       else if (unformat (i, "learn %d", &learn))
7035         ;
7036       else if (unformat (i, "arp-term %d", &arp_term))
7037         ;
7038       else if (unformat (i, "mac-age %d", &mac_age))
7039         ;
7040       else if (unformat (i, "bd-tag %s", &bd_tag))
7041         ;
7042       else if (unformat (i, "del"))
7043         {
7044           is_add = 0;
7045           flood = uu_flood = forward = learn = 0;
7046         }
7047       else
7048         break;
7049     }
7050
7051   if (bd_id == ~0)
7052     {
7053       errmsg ("missing bridge domain");
7054       ret = -99;
7055       goto done;
7056     }
7057
7058   if (mac_age > 255)
7059     {
7060       errmsg ("mac age must be less than 256 ");
7061       ret = -99;
7062       goto done;
7063     }
7064
7065   if ((bd_tag) && (strlen ((char *) bd_tag) > 63))
7066     {
7067       errmsg ("bd-tag cannot be longer than 63");
7068       ret = -99;
7069       goto done;
7070     }
7071
7072   M (BRIDGE_DOMAIN_ADD_DEL, mp);
7073
7074   mp->bd_id = ntohl (bd_id);
7075   mp->flood = flood;
7076   mp->uu_flood = uu_flood;
7077   mp->forward = forward;
7078   mp->learn = learn;
7079   mp->arp_term = arp_term;
7080   mp->is_add = is_add;
7081   mp->mac_age = (u8) mac_age;
7082   if (bd_tag)
7083     strcpy ((char *) mp->bd_tag, (char *) bd_tag);
7084
7085   S (mp);
7086   W (ret);
7087
7088 done:
7089   vec_free (bd_tag);
7090   return ret;
7091 }
7092
7093 static int
7094 api_l2fib_flush_bd (vat_main_t * vam)
7095 {
7096   unformat_input_t *i = vam->input;
7097   vl_api_l2fib_flush_bd_t *mp;
7098   u32 bd_id = ~0;
7099   int ret;
7100
7101   /* Parse args required to build the message */
7102   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7103     {
7104       if (unformat (i, "bd_id %d", &bd_id));
7105       else
7106         break;
7107     }
7108
7109   if (bd_id == ~0)
7110     {
7111       errmsg ("missing bridge domain");
7112       return -99;
7113     }
7114
7115   M (L2FIB_FLUSH_BD, mp);
7116
7117   mp->bd_id = htonl (bd_id);
7118
7119   S (mp);
7120   W (ret);
7121   return ret;
7122 }
7123
7124 static int
7125 api_l2fib_flush_int (vat_main_t * vam)
7126 {
7127   unformat_input_t *i = vam->input;
7128   vl_api_l2fib_flush_int_t *mp;
7129   u32 sw_if_index = ~0;
7130   int ret;
7131
7132   /* Parse args required to build the message */
7133   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7134     {
7135       if (unformat (i, "sw_if_index %d", &sw_if_index));
7136       else
7137         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7138       else
7139         break;
7140     }
7141
7142   if (sw_if_index == ~0)
7143     {
7144       errmsg ("missing interface name or sw_if_index");
7145       return -99;
7146     }
7147
7148   M (L2FIB_FLUSH_INT, mp);
7149
7150   mp->sw_if_index = ntohl (sw_if_index);
7151
7152   S (mp);
7153   W (ret);
7154   return ret;
7155 }
7156
7157 static int
7158 api_l2fib_add_del (vat_main_t * vam)
7159 {
7160   unformat_input_t *i = vam->input;
7161   vl_api_l2fib_add_del_t *mp;
7162   f64 timeout;
7163   u8 mac[6] = { 0 };
7164   u8 mac_set = 0;
7165   u32 bd_id;
7166   u8 bd_id_set = 0;
7167   u32 sw_if_index = ~0;
7168   u8 sw_if_index_set = 0;
7169   u8 is_add = 1;
7170   u8 static_mac = 0;
7171   u8 filter_mac = 0;
7172   u8 bvi_mac = 0;
7173   int count = 1;
7174   f64 before = 0;
7175   int j;
7176
7177   /* Parse args required to build the message */
7178   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7179     {
7180       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
7181         mac_set = 1;
7182       else if (unformat (i, "bd_id %d", &bd_id))
7183         bd_id_set = 1;
7184       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7185         sw_if_index_set = 1;
7186       else if (unformat (i, "sw_if"))
7187         {
7188           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7189             {
7190               if (unformat
7191                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7192                 sw_if_index_set = 1;
7193             }
7194           else
7195             break;
7196         }
7197       else if (unformat (i, "static"))
7198         static_mac = 1;
7199       else if (unformat (i, "filter"))
7200         {
7201           filter_mac = 1;
7202           static_mac = 1;
7203         }
7204       else if (unformat (i, "bvi"))
7205         {
7206           bvi_mac = 1;
7207           static_mac = 1;
7208         }
7209       else if (unformat (i, "del"))
7210         is_add = 0;
7211       else if (unformat (i, "count %d", &count))
7212         ;
7213       else
7214         break;
7215     }
7216
7217   if (mac_set == 0)
7218     {
7219       errmsg ("missing mac address");
7220       return -99;
7221     }
7222
7223   if (bd_id_set == 0)
7224     {
7225       errmsg ("missing bridge domain");
7226       return -99;
7227     }
7228
7229   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7230     {
7231       errmsg ("missing interface name or sw_if_index");
7232       return -99;
7233     }
7234
7235   if (count > 1)
7236     {
7237       /* Turn on async mode */
7238       vam->async_mode = 1;
7239       vam->async_errors = 0;
7240       before = vat_time_now (vam);
7241     }
7242
7243   for (j = 0; j < count; j++)
7244     {
7245       M (L2FIB_ADD_DEL, mp);
7246
7247       clib_memcpy (mp->mac, mac, 6);
7248       mp->bd_id = ntohl (bd_id);
7249       mp->is_add = is_add;
7250
7251       if (is_add)
7252         {
7253           mp->sw_if_index = ntohl (sw_if_index);
7254           mp->static_mac = static_mac;
7255           mp->filter_mac = filter_mac;
7256           mp->bvi_mac = bvi_mac;
7257         }
7258       increment_mac_address (mac);
7259       /* send it... */
7260       S (mp);
7261     }
7262
7263   if (count > 1)
7264     {
7265       vl_api_control_ping_t *mp_ping;
7266       f64 after;
7267
7268       /* Shut off async mode */
7269       vam->async_mode = 0;
7270
7271       MPING (CONTROL_PING, mp_ping);
7272       S (mp_ping);
7273
7274       timeout = vat_time_now (vam) + 1.0;
7275       while (vat_time_now (vam) < timeout)
7276         if (vam->result_ready == 1)
7277           goto out;
7278       vam->retval = -99;
7279
7280     out:
7281       if (vam->retval == -99)
7282         errmsg ("timeout");
7283
7284       if (vam->async_errors > 0)
7285         {
7286           errmsg ("%d asynchronous errors", vam->async_errors);
7287           vam->retval = -98;
7288         }
7289       vam->async_errors = 0;
7290       after = vat_time_now (vam);
7291
7292       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7293              count, after - before, count / (after - before));
7294     }
7295   else
7296     {
7297       int ret;
7298
7299       /* Wait for a reply... */
7300       W (ret);
7301       return ret;
7302     }
7303   /* Return the good/bad news */
7304   return (vam->retval);
7305 }
7306
7307 static int
7308 api_bridge_domain_set_mac_age (vat_main_t * vam)
7309 {
7310   unformat_input_t *i = vam->input;
7311   vl_api_bridge_domain_set_mac_age_t *mp;
7312   u32 bd_id = ~0;
7313   u32 mac_age = 0;
7314   int ret;
7315
7316   /* Parse args required to build the message */
7317   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7318     {
7319       if (unformat (i, "bd_id %d", &bd_id));
7320       else if (unformat (i, "mac-age %d", &mac_age));
7321       else
7322         break;
7323     }
7324
7325   if (bd_id == ~0)
7326     {
7327       errmsg ("missing bridge domain");
7328       return -99;
7329     }
7330
7331   if (mac_age > 255)
7332     {
7333       errmsg ("mac age must be less than 256 ");
7334       return -99;
7335     }
7336
7337   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7338
7339   mp->bd_id = htonl (bd_id);
7340   mp->mac_age = (u8) mac_age;
7341
7342   S (mp);
7343   W (ret);
7344   return ret;
7345 }
7346
7347 static int
7348 api_l2_flags (vat_main_t * vam)
7349 {
7350   unformat_input_t *i = vam->input;
7351   vl_api_l2_flags_t *mp;
7352   u32 sw_if_index;
7353   u32 flags = 0;
7354   u8 sw_if_index_set = 0;
7355   u8 is_set = 0;
7356   int ret;
7357
7358   /* Parse args required to build the message */
7359   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7360     {
7361       if (unformat (i, "sw_if_index %d", &sw_if_index))
7362         sw_if_index_set = 1;
7363       else if (unformat (i, "sw_if"))
7364         {
7365           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7366             {
7367               if (unformat
7368                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7369                 sw_if_index_set = 1;
7370             }
7371           else
7372             break;
7373         }
7374       else if (unformat (i, "learn"))
7375         flags |= L2_LEARN;
7376       else if (unformat (i, "forward"))
7377         flags |= L2_FWD;
7378       else if (unformat (i, "flood"))
7379         flags |= L2_FLOOD;
7380       else if (unformat (i, "uu-flood"))
7381         flags |= L2_UU_FLOOD;
7382       else if (unformat (i, "arp-term"))
7383         flags |= L2_ARP_TERM;
7384       else if (unformat (i, "off"))
7385         is_set = 0;
7386       else if (unformat (i, "disable"))
7387         is_set = 0;
7388       else
7389         break;
7390     }
7391
7392   if (sw_if_index_set == 0)
7393     {
7394       errmsg ("missing interface name or sw_if_index");
7395       return -99;
7396     }
7397
7398   M (L2_FLAGS, mp);
7399
7400   mp->sw_if_index = ntohl (sw_if_index);
7401   mp->feature_bitmap = ntohl (flags);
7402   mp->is_set = is_set;
7403
7404   S (mp);
7405   W (ret);
7406   return ret;
7407 }
7408
7409 static int
7410 api_bridge_flags (vat_main_t * vam)
7411 {
7412   unformat_input_t *i = vam->input;
7413   vl_api_bridge_flags_t *mp;
7414   u32 bd_id;
7415   u8 bd_id_set = 0;
7416   u8 is_set = 1;
7417   u32 flags = 0;
7418   int ret;
7419
7420   /* Parse args required to build the message */
7421   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7422     {
7423       if (unformat (i, "bd_id %d", &bd_id))
7424         bd_id_set = 1;
7425       else if (unformat (i, "learn"))
7426         flags |= L2_LEARN;
7427       else if (unformat (i, "forward"))
7428         flags |= L2_FWD;
7429       else if (unformat (i, "flood"))
7430         flags |= L2_FLOOD;
7431       else if (unformat (i, "uu-flood"))
7432         flags |= L2_UU_FLOOD;
7433       else if (unformat (i, "arp-term"))
7434         flags |= L2_ARP_TERM;
7435       else if (unformat (i, "off"))
7436         is_set = 0;
7437       else if (unformat (i, "disable"))
7438         is_set = 0;
7439       else
7440         break;
7441     }
7442
7443   if (bd_id_set == 0)
7444     {
7445       errmsg ("missing bridge domain");
7446       return -99;
7447     }
7448
7449   M (BRIDGE_FLAGS, mp);
7450
7451   mp->bd_id = ntohl (bd_id);
7452   mp->feature_bitmap = ntohl (flags);
7453   mp->is_set = is_set;
7454
7455   S (mp);
7456   W (ret);
7457   return ret;
7458 }
7459
7460 static int
7461 api_bd_ip_mac_add_del (vat_main_t * vam)
7462 {
7463   unformat_input_t *i = vam->input;
7464   vl_api_bd_ip_mac_add_del_t *mp;
7465   u32 bd_id;
7466   u8 is_ipv6 = 0;
7467   u8 is_add = 1;
7468   u8 bd_id_set = 0;
7469   u8 ip_set = 0;
7470   u8 mac_set = 0;
7471   ip4_address_t v4addr;
7472   ip6_address_t v6addr;
7473   u8 macaddr[6];
7474   int ret;
7475
7476
7477   /* Parse args required to build the message */
7478   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7479     {
7480       if (unformat (i, "bd_id %d", &bd_id))
7481         {
7482           bd_id_set++;
7483         }
7484       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7485         {
7486           ip_set++;
7487         }
7488       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7489         {
7490           ip_set++;
7491           is_ipv6++;
7492         }
7493       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7494         {
7495           mac_set++;
7496         }
7497       else if (unformat (i, "del"))
7498         is_add = 0;
7499       else
7500         break;
7501     }
7502
7503   if (bd_id_set == 0)
7504     {
7505       errmsg ("missing bridge domain");
7506       return -99;
7507     }
7508   else if (ip_set == 0)
7509     {
7510       errmsg ("missing IP address");
7511       return -99;
7512     }
7513   else if (mac_set == 0)
7514     {
7515       errmsg ("missing MAC address");
7516       return -99;
7517     }
7518
7519   M (BD_IP_MAC_ADD_DEL, mp);
7520
7521   mp->bd_id = ntohl (bd_id);
7522   mp->is_ipv6 = is_ipv6;
7523   mp->is_add = is_add;
7524   if (is_ipv6)
7525     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7526   else
7527     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7528   clib_memcpy (mp->mac_address, macaddr, 6);
7529   S (mp);
7530   W (ret);
7531   return ret;
7532 }
7533
7534 static int
7535 api_tap_connect (vat_main_t * vam)
7536 {
7537   unformat_input_t *i = vam->input;
7538   vl_api_tap_connect_t *mp;
7539   u8 mac_address[6];
7540   u8 random_mac = 1;
7541   u8 name_set = 0;
7542   u8 *tap_name;
7543   u8 *tag = 0;
7544   ip4_address_t ip4_address;
7545   u32 ip4_mask_width;
7546   int ip4_address_set = 0;
7547   ip6_address_t ip6_address;
7548   u32 ip6_mask_width;
7549   int ip6_address_set = 0;
7550   int ret;
7551
7552   memset (mac_address, 0, sizeof (mac_address));
7553
7554   /* Parse args required to build the message */
7555   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7556     {
7557       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7558         {
7559           random_mac = 0;
7560         }
7561       else if (unformat (i, "random-mac"))
7562         random_mac = 1;
7563       else if (unformat (i, "tapname %s", &tap_name))
7564         name_set = 1;
7565       else if (unformat (i, "tag %s", &tag))
7566         ;
7567       else if (unformat (i, "address %U/%d",
7568                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7569         ip4_address_set = 1;
7570       else if (unformat (i, "address %U/%d",
7571                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7572         ip6_address_set = 1;
7573       else
7574         break;
7575     }
7576
7577   if (name_set == 0)
7578     {
7579       errmsg ("missing tap name");
7580       return -99;
7581     }
7582   if (vec_len (tap_name) > 63)
7583     {
7584       errmsg ("tap name too long");
7585       return -99;
7586     }
7587   vec_add1 (tap_name, 0);
7588
7589   if (vec_len (tag) > 63)
7590     {
7591       errmsg ("tag too long");
7592       return -99;
7593     }
7594
7595   /* Construct the API message */
7596   M (TAP_CONNECT, mp);
7597
7598   mp->use_random_mac = random_mac;
7599   clib_memcpy (mp->mac_address, mac_address, 6);
7600   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7601   if (tag)
7602     clib_memcpy (mp->tag, tag, vec_len (tag));
7603
7604   if (ip4_address_set)
7605     {
7606       mp->ip4_address_set = 1;
7607       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7608       mp->ip4_mask_width = ip4_mask_width;
7609     }
7610   if (ip6_address_set)
7611     {
7612       mp->ip6_address_set = 1;
7613       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7614       mp->ip6_mask_width = ip6_mask_width;
7615     }
7616
7617   vec_free (tap_name);
7618   vec_free (tag);
7619
7620   /* send it... */
7621   S (mp);
7622
7623   /* Wait for a reply... */
7624   W (ret);
7625   return ret;
7626 }
7627
7628 static int
7629 api_tap_modify (vat_main_t * vam)
7630 {
7631   unformat_input_t *i = vam->input;
7632   vl_api_tap_modify_t *mp;
7633   u8 mac_address[6];
7634   u8 random_mac = 1;
7635   u8 name_set = 0;
7636   u8 *tap_name;
7637   u32 sw_if_index = ~0;
7638   u8 sw_if_index_set = 0;
7639   int ret;
7640
7641   memset (mac_address, 0, sizeof (mac_address));
7642
7643   /* Parse args required to build the message */
7644   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7645     {
7646       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7647         sw_if_index_set = 1;
7648       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7649         sw_if_index_set = 1;
7650       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7651         {
7652           random_mac = 0;
7653         }
7654       else if (unformat (i, "random-mac"))
7655         random_mac = 1;
7656       else if (unformat (i, "tapname %s", &tap_name))
7657         name_set = 1;
7658       else
7659         break;
7660     }
7661
7662   if (sw_if_index_set == 0)
7663     {
7664       errmsg ("missing vpp interface name");
7665       return -99;
7666     }
7667   if (name_set == 0)
7668     {
7669       errmsg ("missing tap name");
7670       return -99;
7671     }
7672   if (vec_len (tap_name) > 63)
7673     {
7674       errmsg ("tap name too long");
7675     }
7676   vec_add1 (tap_name, 0);
7677
7678   /* Construct the API message */
7679   M (TAP_MODIFY, mp);
7680
7681   mp->use_random_mac = random_mac;
7682   mp->sw_if_index = ntohl (sw_if_index);
7683   clib_memcpy (mp->mac_address, mac_address, 6);
7684   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7685   vec_free (tap_name);
7686
7687   /* send it... */
7688   S (mp);
7689
7690   /* Wait for a reply... */
7691   W (ret);
7692   return ret;
7693 }
7694
7695 static int
7696 api_tap_delete (vat_main_t * vam)
7697 {
7698   unformat_input_t *i = vam->input;
7699   vl_api_tap_delete_t *mp;
7700   u32 sw_if_index = ~0;
7701   u8 sw_if_index_set = 0;
7702   int ret;
7703
7704   /* Parse args required to build the message */
7705   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7706     {
7707       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7708         sw_if_index_set = 1;
7709       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7710         sw_if_index_set = 1;
7711       else
7712         break;
7713     }
7714
7715   if (sw_if_index_set == 0)
7716     {
7717       errmsg ("missing vpp interface name");
7718       return -99;
7719     }
7720
7721   /* Construct the API message */
7722   M (TAP_DELETE, mp);
7723
7724   mp->sw_if_index = ntohl (sw_if_index);
7725
7726   /* send it... */
7727   S (mp);
7728
7729   /* Wait for a reply... */
7730   W (ret);
7731   return ret;
7732 }
7733
7734 static int
7735 api_ip_table_add_del (vat_main_t * vam)
7736 {
7737   unformat_input_t *i = vam->input;
7738   vl_api_ip_table_add_del_t *mp;
7739   u32 table_id = ~0;
7740   u8 is_ipv6 = 0;
7741   u8 is_add = 1;
7742   int ret = 0;
7743
7744   /* Parse args required to build the message */
7745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7746     {
7747       if (unformat (i, "ipv6"))
7748         is_ipv6 = 1;
7749       else if (unformat (i, "del"))
7750         is_add = 0;
7751       else if (unformat (i, "add"))
7752         is_add = 1;
7753       else if (unformat (i, "table %d", &table_id))
7754         ;
7755       else
7756         {
7757           clib_warning ("parse error '%U'", format_unformat_error, i);
7758           return -99;
7759         }
7760     }
7761
7762   if (~0 == table_id)
7763     {
7764       errmsg ("missing table-ID");
7765       return -99;
7766     }
7767
7768   /* Construct the API message */
7769   M (IP_TABLE_ADD_DEL, mp);
7770
7771   mp->table_id = ntohl (table_id);
7772   mp->is_ipv6 = is_ipv6;
7773   mp->is_add = is_add;
7774
7775   /* send it... */
7776   S (mp);
7777
7778   /* Wait for a reply... */
7779   W (ret);
7780
7781   return ret;
7782 }
7783
7784 static int
7785 api_ip_add_del_route (vat_main_t * vam)
7786 {
7787   unformat_input_t *i = vam->input;
7788   vl_api_ip_add_del_route_t *mp;
7789   u32 sw_if_index = ~0, vrf_id = 0;
7790   u8 is_ipv6 = 0;
7791   u8 is_local = 0, is_drop = 0;
7792   u8 is_unreach = 0, is_prohibit = 0;
7793   u8 create_vrf_if_needed = 0;
7794   u8 is_add = 1;
7795   u32 next_hop_weight = 1;
7796   u8 is_multipath = 0;
7797   u8 address_set = 0;
7798   u8 address_length_set = 0;
7799   u32 next_hop_table_id = 0;
7800   u32 resolve_attempts = 0;
7801   u32 dst_address_length = 0;
7802   u8 next_hop_set = 0;
7803   ip4_address_t v4_dst_address, v4_next_hop_address;
7804   ip6_address_t v6_dst_address, v6_next_hop_address;
7805   int count = 1;
7806   int j;
7807   f64 before = 0;
7808   u32 random_add_del = 0;
7809   u32 *random_vector = 0;
7810   uword *random_hash;
7811   u32 random_seed = 0xdeaddabe;
7812   u32 classify_table_index = ~0;
7813   u8 is_classify = 0;
7814   u8 resolve_host = 0, resolve_attached = 0;
7815   mpls_label_t *next_hop_out_label_stack = NULL;
7816   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7817   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7818
7819   /* Parse args required to build the message */
7820   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7821     {
7822       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7823         ;
7824       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7825         ;
7826       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
7827         {
7828           address_set = 1;
7829           is_ipv6 = 0;
7830         }
7831       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
7832         {
7833           address_set = 1;
7834           is_ipv6 = 1;
7835         }
7836       else if (unformat (i, "/%d", &dst_address_length))
7837         {
7838           address_length_set = 1;
7839         }
7840
7841       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
7842                                          &v4_next_hop_address))
7843         {
7844           next_hop_set = 1;
7845         }
7846       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
7847                                          &v6_next_hop_address))
7848         {
7849           next_hop_set = 1;
7850         }
7851       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
7852         ;
7853       else if (unformat (i, "weight %d", &next_hop_weight))
7854         ;
7855       else if (unformat (i, "drop"))
7856         {
7857           is_drop = 1;
7858         }
7859       else if (unformat (i, "null-send-unreach"))
7860         {
7861           is_unreach = 1;
7862         }
7863       else if (unformat (i, "null-send-prohibit"))
7864         {
7865           is_prohibit = 1;
7866         }
7867       else if (unformat (i, "local"))
7868         {
7869           is_local = 1;
7870         }
7871       else if (unformat (i, "classify %d", &classify_table_index))
7872         {
7873           is_classify = 1;
7874         }
7875       else if (unformat (i, "del"))
7876         is_add = 0;
7877       else if (unformat (i, "add"))
7878         is_add = 1;
7879       else if (unformat (i, "resolve-via-host"))
7880         resolve_host = 1;
7881       else if (unformat (i, "resolve-via-attached"))
7882         resolve_attached = 1;
7883       else if (unformat (i, "multipath"))
7884         is_multipath = 1;
7885       else if (unformat (i, "vrf %d", &vrf_id))
7886         ;
7887       else if (unformat (i, "create-vrf"))
7888         create_vrf_if_needed = 1;
7889       else if (unformat (i, "count %d", &count))
7890         ;
7891       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
7892         ;
7893       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7894         ;
7895       else if (unformat (i, "out-label %d", &next_hop_out_label))
7896         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7897       else if (unformat (i, "via-label %d", &next_hop_via_label))
7898         ;
7899       else if (unformat (i, "random"))
7900         random_add_del = 1;
7901       else if (unformat (i, "seed %d", &random_seed))
7902         ;
7903       else
7904         {
7905           clib_warning ("parse error '%U'", format_unformat_error, i);
7906           return -99;
7907         }
7908     }
7909
7910   if (!next_hop_set && !is_drop && !is_local &&
7911       !is_classify && !is_unreach && !is_prohibit &&
7912       MPLS_LABEL_INVALID == next_hop_via_label)
7913     {
7914       errmsg
7915         ("next hop / local / drop / unreach / prohibit / classify not set");
7916       return -99;
7917     }
7918
7919   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
7920     {
7921       errmsg ("next hop and next-hop via label set");
7922       return -99;
7923     }
7924   if (address_set == 0)
7925     {
7926       errmsg ("missing addresses");
7927       return -99;
7928     }
7929
7930   if (address_length_set == 0)
7931     {
7932       errmsg ("missing address length");
7933       return -99;
7934     }
7935
7936   /* Generate a pile of unique, random routes */
7937   if (random_add_del)
7938     {
7939       u32 this_random_address;
7940       random_hash = hash_create (count, sizeof (uword));
7941
7942       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
7943       for (j = 0; j <= count; j++)
7944         {
7945           do
7946             {
7947               this_random_address = random_u32 (&random_seed);
7948               this_random_address =
7949                 clib_host_to_net_u32 (this_random_address);
7950             }
7951           while (hash_get (random_hash, this_random_address));
7952           vec_add1 (random_vector, this_random_address);
7953           hash_set (random_hash, this_random_address, 1);
7954         }
7955       hash_free (random_hash);
7956       v4_dst_address.as_u32 = random_vector[0];
7957     }
7958
7959   if (count > 1)
7960     {
7961       /* Turn on async mode */
7962       vam->async_mode = 1;
7963       vam->async_errors = 0;
7964       before = vat_time_now (vam);
7965     }
7966
7967   for (j = 0; j < count; j++)
7968     {
7969       /* Construct the API message */
7970       M2 (IP_ADD_DEL_ROUTE, mp,
7971           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7972
7973       mp->next_hop_sw_if_index = ntohl (sw_if_index);
7974       mp->table_id = ntohl (vrf_id);
7975       mp->create_vrf_if_needed = create_vrf_if_needed;
7976
7977       mp->is_add = is_add;
7978       mp->is_drop = is_drop;
7979       mp->is_unreach = is_unreach;
7980       mp->is_prohibit = is_prohibit;
7981       mp->is_ipv6 = is_ipv6;
7982       mp->is_local = is_local;
7983       mp->is_classify = is_classify;
7984       mp->is_multipath = is_multipath;
7985       mp->is_resolve_host = resolve_host;
7986       mp->is_resolve_attached = resolve_attached;
7987       mp->next_hop_weight = next_hop_weight;
7988       mp->dst_address_length = dst_address_length;
7989       mp->next_hop_table_id = ntohl (next_hop_table_id);
7990       mp->classify_table_index = ntohl (classify_table_index);
7991       mp->next_hop_via_label = ntohl (next_hop_via_label);
7992       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7993       if (0 != mp->next_hop_n_out_labels)
7994         {
7995           memcpy (mp->next_hop_out_label_stack,
7996                   next_hop_out_label_stack,
7997                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7998           vec_free (next_hop_out_label_stack);
7999         }
8000
8001       if (is_ipv6)
8002         {
8003           clib_memcpy (mp->dst_address, &v6_dst_address,
8004                        sizeof (v6_dst_address));
8005           if (next_hop_set)
8006             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
8007                          sizeof (v6_next_hop_address));
8008           increment_v6_address (&v6_dst_address);
8009         }
8010       else
8011         {
8012           clib_memcpy (mp->dst_address, &v4_dst_address,
8013                        sizeof (v4_dst_address));
8014           if (next_hop_set)
8015             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
8016                          sizeof (v4_next_hop_address));
8017           if (random_add_del)
8018             v4_dst_address.as_u32 = random_vector[j + 1];
8019           else
8020             increment_v4_address (&v4_dst_address);
8021         }
8022       /* send it... */
8023       S (mp);
8024       /* If we receive SIGTERM, stop now... */
8025       if (vam->do_exit)
8026         break;
8027     }
8028
8029   /* When testing multiple add/del ops, use a control-ping to sync */
8030   if (count > 1)
8031     {
8032       vl_api_control_ping_t *mp_ping;
8033       f64 after;
8034       f64 timeout;
8035
8036       /* Shut off async mode */
8037       vam->async_mode = 0;
8038
8039       MPING (CONTROL_PING, mp_ping);
8040       S (mp_ping);
8041
8042       timeout = vat_time_now (vam) + 1.0;
8043       while (vat_time_now (vam) < timeout)
8044         if (vam->result_ready == 1)
8045           goto out;
8046       vam->retval = -99;
8047
8048     out:
8049       if (vam->retval == -99)
8050         errmsg ("timeout");
8051
8052       if (vam->async_errors > 0)
8053         {
8054           errmsg ("%d asynchronous errors", vam->async_errors);
8055           vam->retval = -98;
8056         }
8057       vam->async_errors = 0;
8058       after = vat_time_now (vam);
8059
8060       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8061       if (j > 0)
8062         count = j;
8063
8064       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8065              count, after - before, count / (after - before));
8066     }
8067   else
8068     {
8069       int ret;
8070
8071       /* Wait for a reply... */
8072       W (ret);
8073       return ret;
8074     }
8075
8076   /* Return the good/bad news */
8077   return (vam->retval);
8078 }
8079
8080 static int
8081 api_ip_mroute_add_del (vat_main_t * vam)
8082 {
8083   unformat_input_t *i = vam->input;
8084   vl_api_ip_mroute_add_del_t *mp;
8085   u32 sw_if_index = ~0, vrf_id = 0;
8086   u8 is_ipv6 = 0;
8087   u8 is_local = 0;
8088   u8 create_vrf_if_needed = 0;
8089   u8 is_add = 1;
8090   u8 address_set = 0;
8091   u32 grp_address_length = 0;
8092   ip4_address_t v4_grp_address, v4_src_address;
8093   ip6_address_t v6_grp_address, v6_src_address;
8094   mfib_itf_flags_t iflags = 0;
8095   mfib_entry_flags_t eflags = 0;
8096   int ret;
8097
8098   /* Parse args required to build the message */
8099   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8100     {
8101       if (unformat (i, "sw_if_index %d", &sw_if_index))
8102         ;
8103       else if (unformat (i, "%U %U",
8104                          unformat_ip4_address, &v4_src_address,
8105                          unformat_ip4_address, &v4_grp_address))
8106         {
8107           grp_address_length = 64;
8108           address_set = 1;
8109           is_ipv6 = 0;
8110         }
8111       else if (unformat (i, "%U %U",
8112                          unformat_ip6_address, &v6_src_address,
8113                          unformat_ip6_address, &v6_grp_address))
8114         {
8115           grp_address_length = 256;
8116           address_set = 1;
8117           is_ipv6 = 1;
8118         }
8119       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
8120         {
8121           memset (&v4_src_address, 0, sizeof (v4_src_address));
8122           grp_address_length = 32;
8123           address_set = 1;
8124           is_ipv6 = 0;
8125         }
8126       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
8127         {
8128           memset (&v6_src_address, 0, sizeof (v6_src_address));
8129           grp_address_length = 128;
8130           address_set = 1;
8131           is_ipv6 = 1;
8132         }
8133       else if (unformat (i, "/%d", &grp_address_length))
8134         ;
8135       else if (unformat (i, "local"))
8136         {
8137           is_local = 1;
8138         }
8139       else if (unformat (i, "del"))
8140         is_add = 0;
8141       else if (unformat (i, "add"))
8142         is_add = 1;
8143       else if (unformat (i, "vrf %d", &vrf_id))
8144         ;
8145       else if (unformat (i, "create-vrf"))
8146         create_vrf_if_needed = 1;
8147       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8148         ;
8149       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8150         ;
8151       else
8152         {
8153           clib_warning ("parse error '%U'", format_unformat_error, i);
8154           return -99;
8155         }
8156     }
8157
8158   if (address_set == 0)
8159     {
8160       errmsg ("missing addresses\n");
8161       return -99;
8162     }
8163
8164   /* Construct the API message */
8165   M (IP_MROUTE_ADD_DEL, mp);
8166
8167   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8168   mp->table_id = ntohl (vrf_id);
8169   mp->create_vrf_if_needed = create_vrf_if_needed;
8170
8171   mp->is_add = is_add;
8172   mp->is_ipv6 = is_ipv6;
8173   mp->is_local = is_local;
8174   mp->itf_flags = ntohl (iflags);
8175   mp->entry_flags = ntohl (eflags);
8176   mp->grp_address_length = grp_address_length;
8177   mp->grp_address_length = ntohs (mp->grp_address_length);
8178
8179   if (is_ipv6)
8180     {
8181       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8182       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8183     }
8184   else
8185     {
8186       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8187       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8188
8189     }
8190
8191   /* send it... */
8192   S (mp);
8193   /* Wait for a reply... */
8194   W (ret);
8195   return ret;
8196 }
8197
8198 static int
8199 api_mpls_table_add_del (vat_main_t * vam)
8200 {
8201   unformat_input_t *i = vam->input;
8202   vl_api_mpls_table_add_del_t *mp;
8203   u32 table_id = ~0;
8204   u8 is_add = 1;
8205   int ret = 0;
8206
8207   /* Parse args required to build the message */
8208   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8209     {
8210       if (unformat (i, "table %d", &table_id))
8211         ;
8212       else if (unformat (i, "del"))
8213         is_add = 0;
8214       else if (unformat (i, "add"))
8215         is_add = 1;
8216       else
8217         {
8218           clib_warning ("parse error '%U'", format_unformat_error, i);
8219           return -99;
8220         }
8221     }
8222
8223   if (~0 == table_id)
8224     {
8225       errmsg ("missing table-ID");
8226       return -99;
8227     }
8228
8229   /* Construct the API message */
8230   M (MPLS_TABLE_ADD_DEL, mp);
8231
8232   mp->mt_table_id = ntohl (table_id);
8233   mp->mt_is_add = is_add;
8234
8235   /* send it... */
8236   S (mp);
8237
8238   /* Wait for a reply... */
8239   W (ret);
8240
8241   return ret;
8242 }
8243
8244 static int
8245 api_mpls_route_add_del (vat_main_t * vam)
8246 {
8247   unformat_input_t *i = vam->input;
8248   vl_api_mpls_route_add_del_t *mp;
8249   u32 sw_if_index = ~0, table_id = 0;
8250   u8 create_table_if_needed = 0;
8251   u8 is_add = 1;
8252   u32 next_hop_weight = 1;
8253   u8 is_multipath = 0;
8254   u32 next_hop_table_id = 0;
8255   u8 next_hop_set = 0;
8256   ip4_address_t v4_next_hop_address = {
8257     .as_u32 = 0,
8258   };
8259   ip6_address_t v6_next_hop_address = { {0} };
8260   int count = 1;
8261   int j;
8262   f64 before = 0;
8263   u32 classify_table_index = ~0;
8264   u8 is_classify = 0;
8265   u8 resolve_host = 0, resolve_attached = 0;
8266   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8267   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8268   mpls_label_t *next_hop_out_label_stack = NULL;
8269   mpls_label_t local_label = MPLS_LABEL_INVALID;
8270   u8 is_eos = 0;
8271   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8272
8273   /* Parse args required to build the message */
8274   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8275     {
8276       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8277         ;
8278       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8279         ;
8280       else if (unformat (i, "%d", &local_label))
8281         ;
8282       else if (unformat (i, "eos"))
8283         is_eos = 1;
8284       else if (unformat (i, "non-eos"))
8285         is_eos = 0;
8286       else if (unformat (i, "via %U", unformat_ip4_address,
8287                          &v4_next_hop_address))
8288         {
8289           next_hop_set = 1;
8290           next_hop_proto = DPO_PROTO_IP4;
8291         }
8292       else if (unformat (i, "via %U", unformat_ip6_address,
8293                          &v6_next_hop_address))
8294         {
8295           next_hop_set = 1;
8296           next_hop_proto = DPO_PROTO_IP6;
8297         }
8298       else if (unformat (i, "weight %d", &next_hop_weight))
8299         ;
8300       else if (unformat (i, "create-table"))
8301         create_table_if_needed = 1;
8302       else if (unformat (i, "classify %d", &classify_table_index))
8303         {
8304           is_classify = 1;
8305         }
8306       else if (unformat (i, "del"))
8307         is_add = 0;
8308       else if (unformat (i, "add"))
8309         is_add = 1;
8310       else if (unformat (i, "resolve-via-host"))
8311         resolve_host = 1;
8312       else if (unformat (i, "resolve-via-attached"))
8313         resolve_attached = 1;
8314       else if (unformat (i, "multipath"))
8315         is_multipath = 1;
8316       else if (unformat (i, "count %d", &count))
8317         ;
8318       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8319         {
8320           next_hop_set = 1;
8321           next_hop_proto = DPO_PROTO_IP4;
8322         }
8323       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8324         {
8325           next_hop_set = 1;
8326           next_hop_proto = DPO_PROTO_IP6;
8327         }
8328       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8329         ;
8330       else if (unformat (i, "via-label %d", &next_hop_via_label))
8331         ;
8332       else if (unformat (i, "out-label %d", &next_hop_out_label))
8333         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8334       else
8335         {
8336           clib_warning ("parse error '%U'", format_unformat_error, i);
8337           return -99;
8338         }
8339     }
8340
8341   if (!next_hop_set && !is_classify)
8342     {
8343       errmsg ("next hop / classify not set");
8344       return -99;
8345     }
8346
8347   if (MPLS_LABEL_INVALID == local_label)
8348     {
8349       errmsg ("missing label");
8350       return -99;
8351     }
8352
8353   if (count > 1)
8354     {
8355       /* Turn on async mode */
8356       vam->async_mode = 1;
8357       vam->async_errors = 0;
8358       before = vat_time_now (vam);
8359     }
8360
8361   for (j = 0; j < count; j++)
8362     {
8363       /* Construct the API message */
8364       M2 (MPLS_ROUTE_ADD_DEL, mp,
8365           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8366
8367       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8368       mp->mr_table_id = ntohl (table_id);
8369       mp->mr_create_table_if_needed = create_table_if_needed;
8370
8371       mp->mr_is_add = is_add;
8372       mp->mr_next_hop_proto = next_hop_proto;
8373       mp->mr_is_classify = is_classify;
8374       mp->mr_is_multipath = is_multipath;
8375       mp->mr_is_resolve_host = resolve_host;
8376       mp->mr_is_resolve_attached = resolve_attached;
8377       mp->mr_next_hop_weight = next_hop_weight;
8378       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8379       mp->mr_classify_table_index = ntohl (classify_table_index);
8380       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8381       mp->mr_label = ntohl (local_label);
8382       mp->mr_eos = is_eos;
8383
8384       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8385       if (0 != mp->mr_next_hop_n_out_labels)
8386         {
8387           memcpy (mp->mr_next_hop_out_label_stack,
8388                   next_hop_out_label_stack,
8389                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8390           vec_free (next_hop_out_label_stack);
8391         }
8392
8393       if (next_hop_set)
8394         {
8395           if (DPO_PROTO_IP4 == next_hop_proto)
8396             {
8397               clib_memcpy (mp->mr_next_hop,
8398                            &v4_next_hop_address,
8399                            sizeof (v4_next_hop_address));
8400             }
8401           else if (DPO_PROTO_IP6 == next_hop_proto)
8402
8403             {
8404               clib_memcpy (mp->mr_next_hop,
8405                            &v6_next_hop_address,
8406                            sizeof (v6_next_hop_address));
8407             }
8408         }
8409       local_label++;
8410
8411       /* send it... */
8412       S (mp);
8413       /* If we receive SIGTERM, stop now... */
8414       if (vam->do_exit)
8415         break;
8416     }
8417
8418   /* When testing multiple add/del ops, use a control-ping to sync */
8419   if (count > 1)
8420     {
8421       vl_api_control_ping_t *mp_ping;
8422       f64 after;
8423       f64 timeout;
8424
8425       /* Shut off async mode */
8426       vam->async_mode = 0;
8427
8428       MPING (CONTROL_PING, mp_ping);
8429       S (mp_ping);
8430
8431       timeout = vat_time_now (vam) + 1.0;
8432       while (vat_time_now (vam) < timeout)
8433         if (vam->result_ready == 1)
8434           goto out;
8435       vam->retval = -99;
8436
8437     out:
8438       if (vam->retval == -99)
8439         errmsg ("timeout");
8440
8441       if (vam->async_errors > 0)
8442         {
8443           errmsg ("%d asynchronous errors", vam->async_errors);
8444           vam->retval = -98;
8445         }
8446       vam->async_errors = 0;
8447       after = vat_time_now (vam);
8448
8449       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8450       if (j > 0)
8451         count = j;
8452
8453       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8454              count, after - before, count / (after - before));
8455     }
8456   else
8457     {
8458       int ret;
8459
8460       /* Wait for a reply... */
8461       W (ret);
8462       return ret;
8463     }
8464
8465   /* Return the good/bad news */
8466   return (vam->retval);
8467 }
8468
8469 static int
8470 api_mpls_ip_bind_unbind (vat_main_t * vam)
8471 {
8472   unformat_input_t *i = vam->input;
8473   vl_api_mpls_ip_bind_unbind_t *mp;
8474   u32 ip_table_id = 0;
8475   u8 create_table_if_needed = 0;
8476   u8 is_bind = 1;
8477   u8 is_ip4 = 1;
8478   ip4_address_t v4_address;
8479   ip6_address_t v6_address;
8480   u32 address_length;
8481   u8 address_set = 0;
8482   mpls_label_t local_label = MPLS_LABEL_INVALID;
8483   int ret;
8484
8485   /* Parse args required to build the message */
8486   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8487     {
8488       if (unformat (i, "%U/%d", unformat_ip4_address,
8489                     &v4_address, &address_length))
8490         {
8491           is_ip4 = 1;
8492           address_set = 1;
8493         }
8494       else if (unformat (i, "%U/%d", unformat_ip6_address,
8495                          &v6_address, &address_length))
8496         {
8497           is_ip4 = 0;
8498           address_set = 1;
8499         }
8500       else if (unformat (i, "%d", &local_label))
8501         ;
8502       else if (unformat (i, "create-table"))
8503         create_table_if_needed = 1;
8504       else if (unformat (i, "table-id %d", &ip_table_id))
8505         ;
8506       else if (unformat (i, "unbind"))
8507         is_bind = 0;
8508       else if (unformat (i, "bind"))
8509         is_bind = 1;
8510       else
8511         {
8512           clib_warning ("parse error '%U'", format_unformat_error, i);
8513           return -99;
8514         }
8515     }
8516
8517   if (!address_set)
8518     {
8519       errmsg ("IP addres not set");
8520       return -99;
8521     }
8522
8523   if (MPLS_LABEL_INVALID == local_label)
8524     {
8525       errmsg ("missing label");
8526       return -99;
8527     }
8528
8529   /* Construct the API message */
8530   M (MPLS_IP_BIND_UNBIND, mp);
8531
8532   mp->mb_create_table_if_needed = create_table_if_needed;
8533   mp->mb_is_bind = is_bind;
8534   mp->mb_is_ip4 = is_ip4;
8535   mp->mb_ip_table_id = ntohl (ip_table_id);
8536   mp->mb_mpls_table_id = 0;
8537   mp->mb_label = ntohl (local_label);
8538   mp->mb_address_length = address_length;
8539
8540   if (is_ip4)
8541     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8542   else
8543     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8544
8545   /* send it... */
8546   S (mp);
8547
8548   /* Wait for a reply... */
8549   W (ret);
8550   return ret;
8551 }
8552
8553 static int
8554 api_bier_table_add_del (vat_main_t * vam)
8555 {
8556   unformat_input_t *i = vam->input;
8557   vl_api_bier_table_add_del_t *mp;
8558   u8 is_add = 1;
8559   u32 set = 0, sub_domain = 0, hdr_len = 3;
8560   mpls_label_t local_label = MPLS_LABEL_INVALID;
8561   int ret;
8562
8563   /* Parse args required to build the message */
8564   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8565     {
8566       if (unformat (i, "sub-domain %d", &sub_domain))
8567         ;
8568       else if (unformat (i, "set %d", &set))
8569         ;
8570       else if (unformat (i, "label %d", &local_label))
8571         ;
8572       else if (unformat (i, "hdr-len %d", &hdr_len))
8573         ;
8574       else if (unformat (i, "add"))
8575         is_add = 1;
8576       else if (unformat (i, "del"))
8577         is_add = 0;
8578       else
8579         {
8580           clib_warning ("parse error '%U'", format_unformat_error, i);
8581           return -99;
8582         }
8583     }
8584
8585   if (MPLS_LABEL_INVALID == local_label)
8586     {
8587       errmsg ("missing label\n");
8588       return -99;
8589     }
8590
8591   /* Construct the API message */
8592   M (BIER_TABLE_ADD_DEL, mp);
8593
8594   mp->bt_is_add = is_add;
8595   mp->bt_label = ntohl (local_label);
8596   mp->bt_tbl_id.bt_set = set;
8597   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8598   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8599
8600   /* send it... */
8601   S (mp);
8602
8603   /* Wait for a reply... */
8604   W (ret);
8605
8606   return (ret);
8607 }
8608
8609 static int
8610 api_bier_route_add_del (vat_main_t * vam)
8611 {
8612   unformat_input_t *i = vam->input;
8613   vl_api_bier_route_add_del_t *mp;
8614   u8 is_add = 1;
8615   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8616   ip4_address_t v4_next_hop_address;
8617   ip6_address_t v6_next_hop_address;
8618   u8 next_hop_set = 0;
8619   u8 next_hop_proto_is_ip4 = 1;
8620   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8621   int ret;
8622
8623   /* Parse args required to build the message */
8624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8625     {
8626       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8627         {
8628           next_hop_proto_is_ip4 = 1;
8629           next_hop_set = 1;
8630         }
8631       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8632         {
8633           next_hop_proto_is_ip4 = 0;
8634           next_hop_set = 1;
8635         }
8636       if (unformat (i, "sub-domain %d", &sub_domain))
8637         ;
8638       else if (unformat (i, "set %d", &set))
8639         ;
8640       else if (unformat (i, "hdr-len %d", &hdr_len))
8641         ;
8642       else if (unformat (i, "bp %d", &bp))
8643         ;
8644       else if (unformat (i, "add"))
8645         is_add = 1;
8646       else if (unformat (i, "del"))
8647         is_add = 0;
8648       else if (unformat (i, "out-label %d", &next_hop_out_label))
8649         ;
8650       else
8651         {
8652           clib_warning ("parse error '%U'", format_unformat_error, i);
8653           return -99;
8654         }
8655     }
8656
8657   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8658     {
8659       errmsg ("next hop / label set\n");
8660       return -99;
8661     }
8662   if (0 == bp)
8663     {
8664       errmsg ("bit=position not set\n");
8665       return -99;
8666     }
8667
8668   /* Construct the API message */
8669   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path3_t));
8670
8671   mp->br_is_add = is_add;
8672   mp->br_tbl_id.bt_set = set;
8673   mp->br_tbl_id.bt_sub_domain = sub_domain;
8674   mp->br_tbl_id.bt_hdr_len_id = hdr_len;
8675   mp->br_bp = ntohs (bp);
8676   mp->br_n_paths = 1;
8677   mp->br_paths[0].n_labels = 1;
8678   mp->br_paths[0].label_stack[0] = ntohl (next_hop_out_label);
8679   mp->br_paths[0].afi = (next_hop_proto_is_ip4 ? 0 : 1);
8680
8681   if (next_hop_proto_is_ip4)
8682     {
8683       clib_memcpy (mp->br_paths[0].next_hop,
8684                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8685     }
8686   else
8687     {
8688       clib_memcpy (mp->br_paths[0].next_hop,
8689                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8690     }
8691
8692   /* send it... */
8693   S (mp);
8694
8695   /* Wait for a reply... */
8696   W (ret);
8697
8698   return (ret);
8699 }
8700
8701 static int
8702 api_proxy_arp_add_del (vat_main_t * vam)
8703 {
8704   unformat_input_t *i = vam->input;
8705   vl_api_proxy_arp_add_del_t *mp;
8706   u32 vrf_id = 0;
8707   u8 is_add = 1;
8708   ip4_address_t lo, hi;
8709   u8 range_set = 0;
8710   int ret;
8711
8712   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8713     {
8714       if (unformat (i, "vrf %d", &vrf_id))
8715         ;
8716       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
8717                          unformat_ip4_address, &hi))
8718         range_set = 1;
8719       else if (unformat (i, "del"))
8720         is_add = 0;
8721       else
8722         {
8723           clib_warning ("parse error '%U'", format_unformat_error, i);
8724           return -99;
8725         }
8726     }
8727
8728   if (range_set == 0)
8729     {
8730       errmsg ("address range not set");
8731       return -99;
8732     }
8733
8734   M (PROXY_ARP_ADD_DEL, mp);
8735
8736   mp->vrf_id = ntohl (vrf_id);
8737   mp->is_add = is_add;
8738   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
8739   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
8740
8741   S (mp);
8742   W (ret);
8743   return ret;
8744 }
8745
8746 static int
8747 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8748 {
8749   unformat_input_t *i = vam->input;
8750   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8751   u32 sw_if_index;
8752   u8 enable = 1;
8753   u8 sw_if_index_set = 0;
8754   int ret;
8755
8756   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8757     {
8758       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8759         sw_if_index_set = 1;
8760       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8761         sw_if_index_set = 1;
8762       else if (unformat (i, "enable"))
8763         enable = 1;
8764       else if (unformat (i, "disable"))
8765         enable = 0;
8766       else
8767         {
8768           clib_warning ("parse error '%U'", format_unformat_error, i);
8769           return -99;
8770         }
8771     }
8772
8773   if (sw_if_index_set == 0)
8774     {
8775       errmsg ("missing interface name or sw_if_index");
8776       return -99;
8777     }
8778
8779   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8780
8781   mp->sw_if_index = ntohl (sw_if_index);
8782   mp->enable_disable = enable;
8783
8784   S (mp);
8785   W (ret);
8786   return ret;
8787 }
8788
8789 static int
8790 api_mpls_tunnel_add_del (vat_main_t * vam)
8791 {
8792   unformat_input_t *i = vam->input;
8793   vl_api_mpls_tunnel_add_del_t *mp;
8794
8795   u8 is_add = 1;
8796   u8 l2_only = 0;
8797   u32 sw_if_index = ~0;
8798   u32 next_hop_sw_if_index = ~0;
8799   u32 next_hop_proto_is_ip4 = 1;
8800
8801   u32 next_hop_table_id = 0;
8802   ip4_address_t v4_next_hop_address = {
8803     .as_u32 = 0,
8804   };
8805   ip6_address_t v6_next_hop_address = { {0} };
8806   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
8807   int ret;
8808
8809   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8810     {
8811       if (unformat (i, "add"))
8812         is_add = 1;
8813       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8814         is_add = 0;
8815       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
8816         ;
8817       else if (unformat (i, "via %U",
8818                          unformat_ip4_address, &v4_next_hop_address))
8819         {
8820           next_hop_proto_is_ip4 = 1;
8821         }
8822       else if (unformat (i, "via %U",
8823                          unformat_ip6_address, &v6_next_hop_address))
8824         {
8825           next_hop_proto_is_ip4 = 0;
8826         }
8827       else if (unformat (i, "l2-only"))
8828         l2_only = 1;
8829       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8830         ;
8831       else if (unformat (i, "out-label %d", &next_hop_out_label))
8832         vec_add1 (labels, ntohl (next_hop_out_label));
8833       else
8834         {
8835           clib_warning ("parse error '%U'", format_unformat_error, i);
8836           return -99;
8837         }
8838     }
8839
8840   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
8841
8842   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
8843   mp->mt_sw_if_index = ntohl (sw_if_index);
8844   mp->mt_is_add = is_add;
8845   mp->mt_l2_only = l2_only;
8846   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
8847   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
8848
8849   mp->mt_next_hop_n_out_labels = vec_len (labels);
8850
8851   if (0 != mp->mt_next_hop_n_out_labels)
8852     {
8853       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
8854                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
8855       vec_free (labels);
8856     }
8857
8858   if (next_hop_proto_is_ip4)
8859     {
8860       clib_memcpy (mp->mt_next_hop,
8861                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8862     }
8863   else
8864     {
8865       clib_memcpy (mp->mt_next_hop,
8866                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8867     }
8868
8869   S (mp);
8870   W (ret);
8871   return ret;
8872 }
8873
8874 static int
8875 api_sw_interface_set_unnumbered (vat_main_t * vam)
8876 {
8877   unformat_input_t *i = vam->input;
8878   vl_api_sw_interface_set_unnumbered_t *mp;
8879   u32 sw_if_index;
8880   u32 unnum_sw_index = ~0;
8881   u8 is_add = 1;
8882   u8 sw_if_index_set = 0;
8883   int ret;
8884
8885   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8886     {
8887       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8888         sw_if_index_set = 1;
8889       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8890         sw_if_index_set = 1;
8891       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8892         ;
8893       else if (unformat (i, "del"))
8894         is_add = 0;
8895       else
8896         {
8897           clib_warning ("parse error '%U'", format_unformat_error, i);
8898           return -99;
8899         }
8900     }
8901
8902   if (sw_if_index_set == 0)
8903     {
8904       errmsg ("missing interface name or sw_if_index");
8905       return -99;
8906     }
8907
8908   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8909
8910   mp->sw_if_index = ntohl (sw_if_index);
8911   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8912   mp->is_add = is_add;
8913
8914   S (mp);
8915   W (ret);
8916   return ret;
8917 }
8918
8919 static int
8920 api_ip_neighbor_add_del (vat_main_t * vam)
8921 {
8922   unformat_input_t *i = vam->input;
8923   vl_api_ip_neighbor_add_del_t *mp;
8924   u32 sw_if_index;
8925   u8 sw_if_index_set = 0;
8926   u8 is_add = 1;
8927   u8 is_static = 0;
8928   u8 is_no_fib_entry = 0;
8929   u8 mac_address[6];
8930   u8 mac_set = 0;
8931   u8 v4_address_set = 0;
8932   u8 v6_address_set = 0;
8933   ip4_address_t v4address;
8934   ip6_address_t v6address;
8935   int ret;
8936
8937   memset (mac_address, 0, sizeof (mac_address));
8938
8939   /* Parse args required to build the message */
8940   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8941     {
8942       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8943         {
8944           mac_set = 1;
8945         }
8946       else if (unformat (i, "del"))
8947         is_add = 0;
8948       else
8949         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8950         sw_if_index_set = 1;
8951       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8952         sw_if_index_set = 1;
8953       else if (unformat (i, "is_static"))
8954         is_static = 1;
8955       else if (unformat (i, "no-fib-entry"))
8956         is_no_fib_entry = 1;
8957       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
8958         v4_address_set = 1;
8959       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
8960         v6_address_set = 1;
8961       else
8962         {
8963           clib_warning ("parse error '%U'", format_unformat_error, i);
8964           return -99;
8965         }
8966     }
8967
8968   if (sw_if_index_set == 0)
8969     {
8970       errmsg ("missing interface name or sw_if_index");
8971       return -99;
8972     }
8973   if (v4_address_set && v6_address_set)
8974     {
8975       errmsg ("both v4 and v6 addresses set");
8976       return -99;
8977     }
8978   if (!v4_address_set && !v6_address_set)
8979     {
8980       errmsg ("no address set");
8981       return -99;
8982     }
8983
8984   /* Construct the API message */
8985   M (IP_NEIGHBOR_ADD_DEL, mp);
8986
8987   mp->sw_if_index = ntohl (sw_if_index);
8988   mp->is_add = is_add;
8989   mp->is_static = is_static;
8990   mp->is_no_adj_fib = is_no_fib_entry;
8991   if (mac_set)
8992     clib_memcpy (mp->mac_address, mac_address, 6);
8993   if (v6_address_set)
8994     {
8995       mp->is_ipv6 = 1;
8996       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
8997     }
8998   else
8999     {
9000       /* mp->is_ipv6 = 0; via memset in M macro above */
9001       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
9002     }
9003
9004   /* send it... */
9005   S (mp);
9006
9007   /* Wait for a reply, return good/bad news  */
9008   W (ret);
9009   return ret;
9010 }
9011
9012 static int
9013 api_reset_vrf (vat_main_t * vam)
9014 {
9015   unformat_input_t *i = vam->input;
9016   vl_api_reset_vrf_t *mp;
9017   u32 vrf_id = 0;
9018   u8 is_ipv6 = 0;
9019   u8 vrf_id_set = 0;
9020   int ret;
9021
9022   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9023     {
9024       if (unformat (i, "vrf %d", &vrf_id))
9025         vrf_id_set = 1;
9026       else if (unformat (i, "ipv6"))
9027         is_ipv6 = 1;
9028       else
9029         {
9030           clib_warning ("parse error '%U'", format_unformat_error, i);
9031           return -99;
9032         }
9033     }
9034
9035   if (vrf_id_set == 0)
9036     {
9037       errmsg ("missing vrf id");
9038       return -99;
9039     }
9040
9041   M (RESET_VRF, mp);
9042
9043   mp->vrf_id = ntohl (vrf_id);
9044   mp->is_ipv6 = is_ipv6;
9045
9046   S (mp);
9047   W (ret);
9048   return ret;
9049 }
9050
9051 static int
9052 api_create_vlan_subif (vat_main_t * vam)
9053 {
9054   unformat_input_t *i = vam->input;
9055   vl_api_create_vlan_subif_t *mp;
9056   u32 sw_if_index;
9057   u8 sw_if_index_set = 0;
9058   u32 vlan_id;
9059   u8 vlan_id_set = 0;
9060   int ret;
9061
9062   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9063     {
9064       if (unformat (i, "sw_if_index %d", &sw_if_index))
9065         sw_if_index_set = 1;
9066       else
9067         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9068         sw_if_index_set = 1;
9069       else if (unformat (i, "vlan %d", &vlan_id))
9070         vlan_id_set = 1;
9071       else
9072         {
9073           clib_warning ("parse error '%U'", format_unformat_error, i);
9074           return -99;
9075         }
9076     }
9077
9078   if (sw_if_index_set == 0)
9079     {
9080       errmsg ("missing interface name or sw_if_index");
9081       return -99;
9082     }
9083
9084   if (vlan_id_set == 0)
9085     {
9086       errmsg ("missing vlan_id");
9087       return -99;
9088     }
9089   M (CREATE_VLAN_SUBIF, mp);
9090
9091   mp->sw_if_index = ntohl (sw_if_index);
9092   mp->vlan_id = ntohl (vlan_id);
9093
9094   S (mp);
9095   W (ret);
9096   return ret;
9097 }
9098
9099 #define foreach_create_subif_bit                \
9100 _(no_tags)                                      \
9101 _(one_tag)                                      \
9102 _(two_tags)                                     \
9103 _(dot1ad)                                       \
9104 _(exact_match)                                  \
9105 _(default_sub)                                  \
9106 _(outer_vlan_id_any)                            \
9107 _(inner_vlan_id_any)
9108
9109 static int
9110 api_create_subif (vat_main_t * vam)
9111 {
9112   unformat_input_t *i = vam->input;
9113   vl_api_create_subif_t *mp;
9114   u32 sw_if_index;
9115   u8 sw_if_index_set = 0;
9116   u32 sub_id;
9117   u8 sub_id_set = 0;
9118   u32 no_tags = 0;
9119   u32 one_tag = 0;
9120   u32 two_tags = 0;
9121   u32 dot1ad = 0;
9122   u32 exact_match = 0;
9123   u32 default_sub = 0;
9124   u32 outer_vlan_id_any = 0;
9125   u32 inner_vlan_id_any = 0;
9126   u32 tmp;
9127   u16 outer_vlan_id = 0;
9128   u16 inner_vlan_id = 0;
9129   int ret;
9130
9131   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9132     {
9133       if (unformat (i, "sw_if_index %d", &sw_if_index))
9134         sw_if_index_set = 1;
9135       else
9136         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9137         sw_if_index_set = 1;
9138       else if (unformat (i, "sub_id %d", &sub_id))
9139         sub_id_set = 1;
9140       else if (unformat (i, "outer_vlan_id %d", &tmp))
9141         outer_vlan_id = tmp;
9142       else if (unformat (i, "inner_vlan_id %d", &tmp))
9143         inner_vlan_id = tmp;
9144
9145 #define _(a) else if (unformat (i, #a)) a = 1 ;
9146       foreach_create_subif_bit
9147 #undef _
9148         else
9149         {
9150           clib_warning ("parse error '%U'", format_unformat_error, i);
9151           return -99;
9152         }
9153     }
9154
9155   if (sw_if_index_set == 0)
9156     {
9157       errmsg ("missing interface name or sw_if_index");
9158       return -99;
9159     }
9160
9161   if (sub_id_set == 0)
9162     {
9163       errmsg ("missing sub_id");
9164       return -99;
9165     }
9166   M (CREATE_SUBIF, mp);
9167
9168   mp->sw_if_index = ntohl (sw_if_index);
9169   mp->sub_id = ntohl (sub_id);
9170
9171 #define _(a) mp->a = a;
9172   foreach_create_subif_bit;
9173 #undef _
9174
9175   mp->outer_vlan_id = ntohs (outer_vlan_id);
9176   mp->inner_vlan_id = ntohs (inner_vlan_id);
9177
9178   S (mp);
9179   W (ret);
9180   return ret;
9181 }
9182
9183 static int
9184 api_oam_add_del (vat_main_t * vam)
9185 {
9186   unformat_input_t *i = vam->input;
9187   vl_api_oam_add_del_t *mp;
9188   u32 vrf_id = 0;
9189   u8 is_add = 1;
9190   ip4_address_t src, dst;
9191   u8 src_set = 0;
9192   u8 dst_set = 0;
9193   int ret;
9194
9195   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9196     {
9197       if (unformat (i, "vrf %d", &vrf_id))
9198         ;
9199       else if (unformat (i, "src %U", unformat_ip4_address, &src))
9200         src_set = 1;
9201       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
9202         dst_set = 1;
9203       else if (unformat (i, "del"))
9204         is_add = 0;
9205       else
9206         {
9207           clib_warning ("parse error '%U'", format_unformat_error, i);
9208           return -99;
9209         }
9210     }
9211
9212   if (src_set == 0)
9213     {
9214       errmsg ("missing src addr");
9215       return -99;
9216     }
9217
9218   if (dst_set == 0)
9219     {
9220       errmsg ("missing dst addr");
9221       return -99;
9222     }
9223
9224   M (OAM_ADD_DEL, mp);
9225
9226   mp->vrf_id = ntohl (vrf_id);
9227   mp->is_add = is_add;
9228   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
9229   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
9230
9231   S (mp);
9232   W (ret);
9233   return ret;
9234 }
9235
9236 static int
9237 api_reset_fib (vat_main_t * vam)
9238 {
9239   unformat_input_t *i = vam->input;
9240   vl_api_reset_fib_t *mp;
9241   u32 vrf_id = 0;
9242   u8 is_ipv6 = 0;
9243   u8 vrf_id_set = 0;
9244
9245   int ret;
9246   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9247     {
9248       if (unformat (i, "vrf %d", &vrf_id))
9249         vrf_id_set = 1;
9250       else if (unformat (i, "ipv6"))
9251         is_ipv6 = 1;
9252       else
9253         {
9254           clib_warning ("parse error '%U'", format_unformat_error, i);
9255           return -99;
9256         }
9257     }
9258
9259   if (vrf_id_set == 0)
9260     {
9261       errmsg ("missing vrf id");
9262       return -99;
9263     }
9264
9265   M (RESET_FIB, mp);
9266
9267   mp->vrf_id = ntohl (vrf_id);
9268   mp->is_ipv6 = is_ipv6;
9269
9270   S (mp);
9271   W (ret);
9272   return ret;
9273 }
9274
9275 static int
9276 api_dhcp_proxy_config (vat_main_t * vam)
9277 {
9278   unformat_input_t *i = vam->input;
9279   vl_api_dhcp_proxy_config_t *mp;
9280   u32 rx_vrf_id = 0;
9281   u32 server_vrf_id = 0;
9282   u8 is_add = 1;
9283   u8 v4_address_set = 0;
9284   u8 v6_address_set = 0;
9285   ip4_address_t v4address;
9286   ip6_address_t v6address;
9287   u8 v4_src_address_set = 0;
9288   u8 v6_src_address_set = 0;
9289   ip4_address_t v4srcaddress;
9290   ip6_address_t v6srcaddress;
9291   int ret;
9292
9293   /* Parse args required to build the message */
9294   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9295     {
9296       if (unformat (i, "del"))
9297         is_add = 0;
9298       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9299         ;
9300       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9301         ;
9302       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9303         v4_address_set = 1;
9304       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9305         v6_address_set = 1;
9306       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9307         v4_src_address_set = 1;
9308       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9309         v6_src_address_set = 1;
9310       else
9311         break;
9312     }
9313
9314   if (v4_address_set && v6_address_set)
9315     {
9316       errmsg ("both v4 and v6 server addresses set");
9317       return -99;
9318     }
9319   if (!v4_address_set && !v6_address_set)
9320     {
9321       errmsg ("no server addresses set");
9322       return -99;
9323     }
9324
9325   if (v4_src_address_set && v6_src_address_set)
9326     {
9327       errmsg ("both v4 and v6  src addresses set");
9328       return -99;
9329     }
9330   if (!v4_src_address_set && !v6_src_address_set)
9331     {
9332       errmsg ("no src addresses set");
9333       return -99;
9334     }
9335
9336   if (!(v4_src_address_set && v4_address_set) &&
9337       !(v6_src_address_set && v6_address_set))
9338     {
9339       errmsg ("no matching server and src addresses set");
9340       return -99;
9341     }
9342
9343   /* Construct the API message */
9344   M (DHCP_PROXY_CONFIG, mp);
9345
9346   mp->is_add = is_add;
9347   mp->rx_vrf_id = ntohl (rx_vrf_id);
9348   mp->server_vrf_id = ntohl (server_vrf_id);
9349   if (v6_address_set)
9350     {
9351       mp->is_ipv6 = 1;
9352       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9353       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9354     }
9355   else
9356     {
9357       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9358       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9359     }
9360
9361   /* send it... */
9362   S (mp);
9363
9364   /* Wait for a reply, return good/bad news  */
9365   W (ret);
9366   return ret;
9367 }
9368
9369 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9370 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9371
9372 static void
9373 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9374 {
9375   vat_main_t *vam = &vat_main;
9376   u32 i, count = mp->count;
9377   vl_api_dhcp_server_t *s;
9378
9379   if (mp->is_ipv6)
9380     print (vam->ofp,
9381            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
9382            ntohl (mp->rx_vrf_id),
9383            format_ip6_address, mp->dhcp_src_address,
9384            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9385   else
9386     print (vam->ofp,
9387            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
9388            ntohl (mp->rx_vrf_id),
9389            format_ip4_address, mp->dhcp_src_address,
9390            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9391
9392   for (i = 0; i < count; i++)
9393     {
9394       s = &mp->servers[i];
9395
9396       if (mp->is_ipv6)
9397         print (vam->ofp,
9398                " Server Table-ID %d, Server Address %U",
9399                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9400       else
9401         print (vam->ofp,
9402                " Server Table-ID %d, Server Address %U",
9403                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9404     }
9405 }
9406
9407 static void vl_api_dhcp_proxy_details_t_handler_json
9408   (vl_api_dhcp_proxy_details_t * mp)
9409 {
9410   vat_main_t *vam = &vat_main;
9411   vat_json_node_t *node = NULL;
9412   u32 i, count = mp->count;
9413   struct in_addr ip4;
9414   struct in6_addr ip6;
9415   vl_api_dhcp_server_t *s;
9416
9417   if (VAT_JSON_ARRAY != vam->json_tree.type)
9418     {
9419       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9420       vat_json_init_array (&vam->json_tree);
9421     }
9422   node = vat_json_array_add (&vam->json_tree);
9423
9424   vat_json_init_object (node);
9425   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9426   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9427   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9428
9429   if (mp->is_ipv6)
9430     {
9431       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9432       vat_json_object_add_ip6 (node, "src_address", ip6);
9433     }
9434   else
9435     {
9436       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9437       vat_json_object_add_ip4 (node, "src_address", ip4);
9438     }
9439
9440   for (i = 0; i < count; i++)
9441     {
9442       s = &mp->servers[i];
9443
9444       vat_json_object_add_uint (node, "server-table-id",
9445                                 ntohl (s->server_vrf_id));
9446
9447       if (mp->is_ipv6)
9448         {
9449           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9450           vat_json_object_add_ip4 (node, "src_address", ip4);
9451         }
9452       else
9453         {
9454           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9455           vat_json_object_add_ip6 (node, "server_address", ip6);
9456         }
9457     }
9458 }
9459
9460 static int
9461 api_dhcp_proxy_dump (vat_main_t * vam)
9462 {
9463   unformat_input_t *i = vam->input;
9464   vl_api_control_ping_t *mp_ping;
9465   vl_api_dhcp_proxy_dump_t *mp;
9466   u8 is_ipv6 = 0;
9467   int ret;
9468
9469   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9470     {
9471       if (unformat (i, "ipv6"))
9472         is_ipv6 = 1;
9473       else
9474         {
9475           clib_warning ("parse error '%U'", format_unformat_error, i);
9476           return -99;
9477         }
9478     }
9479
9480   M (DHCP_PROXY_DUMP, mp);
9481
9482   mp->is_ip6 = is_ipv6;
9483   S (mp);
9484
9485   /* Use a control ping for synchronization */
9486   MPING (CONTROL_PING, mp_ping);
9487   S (mp_ping);
9488
9489   W (ret);
9490   return ret;
9491 }
9492
9493 static int
9494 api_dhcp_proxy_set_vss (vat_main_t * vam)
9495 {
9496   unformat_input_t *i = vam->input;
9497   vl_api_dhcp_proxy_set_vss_t *mp;
9498   u8 is_ipv6 = 0;
9499   u8 is_add = 1;
9500   u32 tbl_id;
9501   u8 tbl_id_set = 0;
9502   u32 oui;
9503   u8 oui_set = 0;
9504   u32 fib_id;
9505   u8 fib_id_set = 0;
9506   int ret;
9507
9508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9509     {
9510       if (unformat (i, "tbl_id %d", &tbl_id))
9511         tbl_id_set = 1;
9512       if (unformat (i, "fib_id %d", &fib_id))
9513         fib_id_set = 1;
9514       if (unformat (i, "oui %d", &oui))
9515         oui_set = 1;
9516       else if (unformat (i, "ipv6"))
9517         is_ipv6 = 1;
9518       else if (unformat (i, "del"))
9519         is_add = 0;
9520       else
9521         {
9522           clib_warning ("parse error '%U'", format_unformat_error, i);
9523           return -99;
9524         }
9525     }
9526
9527   if (tbl_id_set == 0)
9528     {
9529       errmsg ("missing tbl id");
9530       return -99;
9531     }
9532
9533   if (fib_id_set == 0)
9534     {
9535       errmsg ("missing fib id");
9536       return -99;
9537     }
9538   if (oui_set == 0)
9539     {
9540       errmsg ("missing oui");
9541       return -99;
9542     }
9543
9544   M (DHCP_PROXY_SET_VSS, mp);
9545   mp->tbl_id = ntohl (tbl_id);
9546   mp->fib_id = ntohl (fib_id);
9547   mp->oui = ntohl (oui);
9548   mp->is_ipv6 = is_ipv6;
9549   mp->is_add = is_add;
9550
9551   S (mp);
9552   W (ret);
9553   return ret;
9554 }
9555
9556 static int
9557 api_dhcp_client_config (vat_main_t * vam)
9558 {
9559   unformat_input_t *i = vam->input;
9560   vl_api_dhcp_client_config_t *mp;
9561   u32 sw_if_index;
9562   u8 sw_if_index_set = 0;
9563   u8 is_add = 1;
9564   u8 *hostname = 0;
9565   u8 disable_event = 0;
9566   int ret;
9567
9568   /* Parse args required to build the message */
9569   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9570     {
9571       if (unformat (i, "del"))
9572         is_add = 0;
9573       else
9574         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9575         sw_if_index_set = 1;
9576       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9577         sw_if_index_set = 1;
9578       else if (unformat (i, "hostname %s", &hostname))
9579         ;
9580       else if (unformat (i, "disable_event"))
9581         disable_event = 1;
9582       else
9583         break;
9584     }
9585
9586   if (sw_if_index_set == 0)
9587     {
9588       errmsg ("missing interface name or sw_if_index");
9589       return -99;
9590     }
9591
9592   if (vec_len (hostname) > 63)
9593     {
9594       errmsg ("hostname too long");
9595     }
9596   vec_add1 (hostname, 0);
9597
9598   /* Construct the API message */
9599   M (DHCP_CLIENT_CONFIG, mp);
9600
9601   mp->sw_if_index = htonl (sw_if_index);
9602   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
9603   vec_free (hostname);
9604   mp->is_add = is_add;
9605   mp->want_dhcp_event = disable_event ? 0 : 1;
9606   mp->pid = htonl (getpid ());
9607
9608   /* send it... */
9609   S (mp);
9610
9611   /* Wait for a reply, return good/bad news  */
9612   W (ret);
9613   return ret;
9614 }
9615
9616 static int
9617 api_set_ip_flow_hash (vat_main_t * vam)
9618 {
9619   unformat_input_t *i = vam->input;
9620   vl_api_set_ip_flow_hash_t *mp;
9621   u32 vrf_id = 0;
9622   u8 is_ipv6 = 0;
9623   u8 vrf_id_set = 0;
9624   u8 src = 0;
9625   u8 dst = 0;
9626   u8 sport = 0;
9627   u8 dport = 0;
9628   u8 proto = 0;
9629   u8 reverse = 0;
9630   int ret;
9631
9632   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9633     {
9634       if (unformat (i, "vrf %d", &vrf_id))
9635         vrf_id_set = 1;
9636       else if (unformat (i, "ipv6"))
9637         is_ipv6 = 1;
9638       else if (unformat (i, "src"))
9639         src = 1;
9640       else if (unformat (i, "dst"))
9641         dst = 1;
9642       else if (unformat (i, "sport"))
9643         sport = 1;
9644       else if (unformat (i, "dport"))
9645         dport = 1;
9646       else if (unformat (i, "proto"))
9647         proto = 1;
9648       else if (unformat (i, "reverse"))
9649         reverse = 1;
9650
9651       else
9652         {
9653           clib_warning ("parse error '%U'", format_unformat_error, i);
9654           return -99;
9655         }
9656     }
9657
9658   if (vrf_id_set == 0)
9659     {
9660       errmsg ("missing vrf id");
9661       return -99;
9662     }
9663
9664   M (SET_IP_FLOW_HASH, mp);
9665   mp->src = src;
9666   mp->dst = dst;
9667   mp->sport = sport;
9668   mp->dport = dport;
9669   mp->proto = proto;
9670   mp->reverse = reverse;
9671   mp->vrf_id = ntohl (vrf_id);
9672   mp->is_ipv6 = is_ipv6;
9673
9674   S (mp);
9675   W (ret);
9676   return ret;
9677 }
9678
9679 static int
9680 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9681 {
9682   unformat_input_t *i = vam->input;
9683   vl_api_sw_interface_ip6_enable_disable_t *mp;
9684   u32 sw_if_index;
9685   u8 sw_if_index_set = 0;
9686   u8 enable = 0;
9687   int ret;
9688
9689   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9690     {
9691       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9692         sw_if_index_set = 1;
9693       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9694         sw_if_index_set = 1;
9695       else if (unformat (i, "enable"))
9696         enable = 1;
9697       else if (unformat (i, "disable"))
9698         enable = 0;
9699       else
9700         {
9701           clib_warning ("parse error '%U'", format_unformat_error, i);
9702           return -99;
9703         }
9704     }
9705
9706   if (sw_if_index_set == 0)
9707     {
9708       errmsg ("missing interface name or sw_if_index");
9709       return -99;
9710     }
9711
9712   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9713
9714   mp->sw_if_index = ntohl (sw_if_index);
9715   mp->enable = enable;
9716
9717   S (mp);
9718   W (ret);
9719   return ret;
9720 }
9721
9722 static int
9723 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
9724 {
9725   unformat_input_t *i = vam->input;
9726   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
9727   u32 sw_if_index;
9728   u8 sw_if_index_set = 0;
9729   u8 v6_address_set = 0;
9730   ip6_address_t v6address;
9731   int ret;
9732
9733   /* Parse args required to build the message */
9734   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9735     {
9736       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9737         sw_if_index_set = 1;
9738       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9739         sw_if_index_set = 1;
9740       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9741         v6_address_set = 1;
9742       else
9743         break;
9744     }
9745
9746   if (sw_if_index_set == 0)
9747     {
9748       errmsg ("missing interface name or sw_if_index");
9749       return -99;
9750     }
9751   if (!v6_address_set)
9752     {
9753       errmsg ("no address set");
9754       return -99;
9755     }
9756
9757   /* Construct the API message */
9758   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
9759
9760   mp->sw_if_index = ntohl (sw_if_index);
9761   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9762
9763   /* send it... */
9764   S (mp);
9765
9766   /* Wait for a reply, return good/bad news  */
9767   W (ret);
9768   return ret;
9769 }
9770
9771 static int
9772 api_ip6nd_proxy_add_del (vat_main_t * vam)
9773 {
9774   unformat_input_t *i = vam->input;
9775   vl_api_ip6nd_proxy_add_del_t *mp;
9776   u32 sw_if_index = ~0;
9777   u8 v6_address_set = 0;
9778   ip6_address_t v6address;
9779   u8 is_del = 0;
9780   int ret;
9781
9782   /* Parse args required to build the message */
9783   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9784     {
9785       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9786         ;
9787       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9788         ;
9789       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9790         v6_address_set = 1;
9791       if (unformat (i, "del"))
9792         is_del = 1;
9793       else
9794         {
9795           clib_warning ("parse error '%U'", format_unformat_error, i);
9796           return -99;
9797         }
9798     }
9799
9800   if (sw_if_index == ~0)
9801     {
9802       errmsg ("missing interface name or sw_if_index");
9803       return -99;
9804     }
9805   if (!v6_address_set)
9806     {
9807       errmsg ("no address set");
9808       return -99;
9809     }
9810
9811   /* Construct the API message */
9812   M (IP6ND_PROXY_ADD_DEL, mp);
9813
9814   mp->is_del = is_del;
9815   mp->sw_if_index = ntohl (sw_if_index);
9816   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9817
9818   /* send it... */
9819   S (mp);
9820
9821   /* Wait for a reply, return good/bad news  */
9822   W (ret);
9823   return ret;
9824 }
9825
9826 static int
9827 api_ip6nd_proxy_dump (vat_main_t * vam)
9828 {
9829   vl_api_ip6nd_proxy_dump_t *mp;
9830   vl_api_control_ping_t *mp_ping;
9831   int ret;
9832
9833   M (IP6ND_PROXY_DUMP, mp);
9834
9835   S (mp);
9836
9837   /* Use a control ping for synchronization */
9838   MPING (CONTROL_PING, mp_ping);
9839   S (mp_ping);
9840
9841   W (ret);
9842   return ret;
9843 }
9844
9845 static void vl_api_ip6nd_proxy_details_t_handler
9846   (vl_api_ip6nd_proxy_details_t * mp)
9847 {
9848   vat_main_t *vam = &vat_main;
9849
9850   print (vam->ofp, "host %U sw_if_index %d",
9851          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
9852 }
9853
9854 static void vl_api_ip6nd_proxy_details_t_handler_json
9855   (vl_api_ip6nd_proxy_details_t * mp)
9856 {
9857   vat_main_t *vam = &vat_main;
9858   struct in6_addr ip6;
9859   vat_json_node_t *node = NULL;
9860
9861   if (VAT_JSON_ARRAY != vam->json_tree.type)
9862     {
9863       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9864       vat_json_init_array (&vam->json_tree);
9865     }
9866   node = vat_json_array_add (&vam->json_tree);
9867
9868   vat_json_init_object (node);
9869   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9870
9871   clib_memcpy (&ip6, mp->address, sizeof (ip6));
9872   vat_json_object_add_ip6 (node, "host", ip6);
9873 }
9874
9875 static int
9876 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9877 {
9878   unformat_input_t *i = vam->input;
9879   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9880   u32 sw_if_index;
9881   u8 sw_if_index_set = 0;
9882   u32 address_length = 0;
9883   u8 v6_address_set = 0;
9884   ip6_address_t v6address;
9885   u8 use_default = 0;
9886   u8 no_advertise = 0;
9887   u8 off_link = 0;
9888   u8 no_autoconfig = 0;
9889   u8 no_onlink = 0;
9890   u8 is_no = 0;
9891   u32 val_lifetime = 0;
9892   u32 pref_lifetime = 0;
9893   int ret;
9894
9895   /* Parse args required to build the message */
9896   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9897     {
9898       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9899         sw_if_index_set = 1;
9900       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9901         sw_if_index_set = 1;
9902       else if (unformat (i, "%U/%d",
9903                          unformat_ip6_address, &v6address, &address_length))
9904         v6_address_set = 1;
9905       else if (unformat (i, "val_life %d", &val_lifetime))
9906         ;
9907       else if (unformat (i, "pref_life %d", &pref_lifetime))
9908         ;
9909       else if (unformat (i, "def"))
9910         use_default = 1;
9911       else if (unformat (i, "noadv"))
9912         no_advertise = 1;
9913       else if (unformat (i, "offl"))
9914         off_link = 1;
9915       else if (unformat (i, "noauto"))
9916         no_autoconfig = 1;
9917       else if (unformat (i, "nolink"))
9918         no_onlink = 1;
9919       else if (unformat (i, "isno"))
9920         is_no = 1;
9921       else
9922         {
9923           clib_warning ("parse error '%U'", format_unformat_error, i);
9924           return -99;
9925         }
9926     }
9927
9928   if (sw_if_index_set == 0)
9929     {
9930       errmsg ("missing interface name or sw_if_index");
9931       return -99;
9932     }
9933   if (!v6_address_set)
9934     {
9935       errmsg ("no address set");
9936       return -99;
9937     }
9938
9939   /* Construct the API message */
9940   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9941
9942   mp->sw_if_index = ntohl (sw_if_index);
9943   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9944   mp->address_length = address_length;
9945   mp->use_default = use_default;
9946   mp->no_advertise = no_advertise;
9947   mp->off_link = off_link;
9948   mp->no_autoconfig = no_autoconfig;
9949   mp->no_onlink = no_onlink;
9950   mp->is_no = is_no;
9951   mp->val_lifetime = ntohl (val_lifetime);
9952   mp->pref_lifetime = ntohl (pref_lifetime);
9953
9954   /* send it... */
9955   S (mp);
9956
9957   /* Wait for a reply, return good/bad news  */
9958   W (ret);
9959   return ret;
9960 }
9961
9962 static int
9963 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9964 {
9965   unformat_input_t *i = vam->input;
9966   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9967   u32 sw_if_index;
9968   u8 sw_if_index_set = 0;
9969   u8 suppress = 0;
9970   u8 managed = 0;
9971   u8 other = 0;
9972   u8 ll_option = 0;
9973   u8 send_unicast = 0;
9974   u8 cease = 0;
9975   u8 is_no = 0;
9976   u8 default_router = 0;
9977   u32 max_interval = 0;
9978   u32 min_interval = 0;
9979   u32 lifetime = 0;
9980   u32 initial_count = 0;
9981   u32 initial_interval = 0;
9982   int ret;
9983
9984
9985   /* Parse args required to build the message */
9986   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9987     {
9988       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9989         sw_if_index_set = 1;
9990       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9991         sw_if_index_set = 1;
9992       else if (unformat (i, "maxint %d", &max_interval))
9993         ;
9994       else if (unformat (i, "minint %d", &min_interval))
9995         ;
9996       else if (unformat (i, "life %d", &lifetime))
9997         ;
9998       else if (unformat (i, "count %d", &initial_count))
9999         ;
10000       else if (unformat (i, "interval %d", &initial_interval))
10001         ;
10002       else if (unformat (i, "suppress") || unformat (i, "surpress"))
10003         suppress = 1;
10004       else if (unformat (i, "managed"))
10005         managed = 1;
10006       else if (unformat (i, "other"))
10007         other = 1;
10008       else if (unformat (i, "ll"))
10009         ll_option = 1;
10010       else if (unformat (i, "send"))
10011         send_unicast = 1;
10012       else if (unformat (i, "cease"))
10013         cease = 1;
10014       else if (unformat (i, "isno"))
10015         is_no = 1;
10016       else if (unformat (i, "def"))
10017         default_router = 1;
10018       else
10019         {
10020           clib_warning ("parse error '%U'", format_unformat_error, i);
10021           return -99;
10022         }
10023     }
10024
10025   if (sw_if_index_set == 0)
10026     {
10027       errmsg ("missing interface name or sw_if_index");
10028       return -99;
10029     }
10030
10031   /* Construct the API message */
10032   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
10033
10034   mp->sw_if_index = ntohl (sw_if_index);
10035   mp->max_interval = ntohl (max_interval);
10036   mp->min_interval = ntohl (min_interval);
10037   mp->lifetime = ntohl (lifetime);
10038   mp->initial_count = ntohl (initial_count);
10039   mp->initial_interval = ntohl (initial_interval);
10040   mp->suppress = suppress;
10041   mp->managed = managed;
10042   mp->other = other;
10043   mp->ll_option = ll_option;
10044   mp->send_unicast = send_unicast;
10045   mp->cease = cease;
10046   mp->is_no = is_no;
10047   mp->default_router = default_router;
10048
10049   /* send it... */
10050   S (mp);
10051
10052   /* Wait for a reply, return good/bad news  */
10053   W (ret);
10054   return ret;
10055 }
10056
10057 static int
10058 api_set_arp_neighbor_limit (vat_main_t * vam)
10059 {
10060   unformat_input_t *i = vam->input;
10061   vl_api_set_arp_neighbor_limit_t *mp;
10062   u32 arp_nbr_limit;
10063   u8 limit_set = 0;
10064   u8 is_ipv6 = 0;
10065   int ret;
10066
10067   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10068     {
10069       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
10070         limit_set = 1;
10071       else if (unformat (i, "ipv6"))
10072         is_ipv6 = 1;
10073       else
10074         {
10075           clib_warning ("parse error '%U'", format_unformat_error, i);
10076           return -99;
10077         }
10078     }
10079
10080   if (limit_set == 0)
10081     {
10082       errmsg ("missing limit value");
10083       return -99;
10084     }
10085
10086   M (SET_ARP_NEIGHBOR_LIMIT, mp);
10087
10088   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
10089   mp->is_ipv6 = is_ipv6;
10090
10091   S (mp);
10092   W (ret);
10093   return ret;
10094 }
10095
10096 static int
10097 api_l2_patch_add_del (vat_main_t * vam)
10098 {
10099   unformat_input_t *i = vam->input;
10100   vl_api_l2_patch_add_del_t *mp;
10101   u32 rx_sw_if_index;
10102   u8 rx_sw_if_index_set = 0;
10103   u32 tx_sw_if_index;
10104   u8 tx_sw_if_index_set = 0;
10105   u8 is_add = 1;
10106   int ret;
10107
10108   /* Parse args required to build the message */
10109   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10110     {
10111       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
10112         rx_sw_if_index_set = 1;
10113       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
10114         tx_sw_if_index_set = 1;
10115       else if (unformat (i, "rx"))
10116         {
10117           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10118             {
10119               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10120                             &rx_sw_if_index))
10121                 rx_sw_if_index_set = 1;
10122             }
10123           else
10124             break;
10125         }
10126       else if (unformat (i, "tx"))
10127         {
10128           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10129             {
10130               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
10131                             &tx_sw_if_index))
10132                 tx_sw_if_index_set = 1;
10133             }
10134           else
10135             break;
10136         }
10137       else if (unformat (i, "del"))
10138         is_add = 0;
10139       else
10140         break;
10141     }
10142
10143   if (rx_sw_if_index_set == 0)
10144     {
10145       errmsg ("missing rx interface name or rx_sw_if_index");
10146       return -99;
10147     }
10148
10149   if (tx_sw_if_index_set == 0)
10150     {
10151       errmsg ("missing tx interface name or tx_sw_if_index");
10152       return -99;
10153     }
10154
10155   M (L2_PATCH_ADD_DEL, mp);
10156
10157   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
10158   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
10159   mp->is_add = is_add;
10160
10161   S (mp);
10162   W (ret);
10163   return ret;
10164 }
10165
10166 u8 is_del;
10167 u8 localsid_addr[16];
10168 u8 end_psp;
10169 u8 behavior;
10170 u32 sw_if_index;
10171 u32 vlan_index;
10172 u32 fib_table;
10173 u8 nh_addr[16];
10174
10175 static int
10176 api_sr_localsid_add_del (vat_main_t * vam)
10177 {
10178   unformat_input_t *i = vam->input;
10179   vl_api_sr_localsid_add_del_t *mp;
10180
10181   u8 is_del;
10182   ip6_address_t localsid;
10183   u8 end_psp = 0;
10184   u8 behavior = ~0;
10185   u32 sw_if_index;
10186   u32 fib_table = ~(u32) 0;
10187   ip6_address_t next_hop;
10188
10189   bool nexthop_set = 0;
10190
10191   int ret;
10192
10193   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10194     {
10195       if (unformat (i, "del"))
10196         is_del = 1;
10197       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
10198       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
10199         nexthop_set = 1;
10200       else if (unformat (i, "behavior %u", &behavior));
10201       else if (unformat (i, "sw_if_index %u", &sw_if_index));
10202       else if (unformat (i, "fib-table %u", &fib_table));
10203       else if (unformat (i, "end.psp %u", &behavior));
10204       else
10205         break;
10206     }
10207
10208   M (SR_LOCALSID_ADD_DEL, mp);
10209
10210   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
10211   if (nexthop_set)
10212     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
10213   mp->behavior = behavior;
10214   mp->sw_if_index = ntohl (sw_if_index);
10215   mp->fib_table = ntohl (fib_table);
10216   mp->end_psp = end_psp;
10217   mp->is_del = is_del;
10218
10219   S (mp);
10220   W (ret);
10221   return ret;
10222 }
10223
10224 static int
10225 api_ioam_enable (vat_main_t * vam)
10226 {
10227   unformat_input_t *input = vam->input;
10228   vl_api_ioam_enable_t *mp;
10229   u32 id = 0;
10230   int has_trace_option = 0;
10231   int has_pot_option = 0;
10232   int has_seqno_option = 0;
10233   int has_analyse_option = 0;
10234   int ret;
10235
10236   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10237     {
10238       if (unformat (input, "trace"))
10239         has_trace_option = 1;
10240       else if (unformat (input, "pot"))
10241         has_pot_option = 1;
10242       else if (unformat (input, "seqno"))
10243         has_seqno_option = 1;
10244       else if (unformat (input, "analyse"))
10245         has_analyse_option = 1;
10246       else
10247         break;
10248     }
10249   M (IOAM_ENABLE, mp);
10250   mp->id = htons (id);
10251   mp->seqno = has_seqno_option;
10252   mp->analyse = has_analyse_option;
10253   mp->pot_enable = has_pot_option;
10254   mp->trace_enable = has_trace_option;
10255
10256   S (mp);
10257   W (ret);
10258   return ret;
10259 }
10260
10261
10262 static int
10263 api_ioam_disable (vat_main_t * vam)
10264 {
10265   vl_api_ioam_disable_t *mp;
10266   int ret;
10267
10268   M (IOAM_DISABLE, mp);
10269   S (mp);
10270   W (ret);
10271   return ret;
10272 }
10273
10274 #define foreach_tcp_proto_field                 \
10275 _(src_port)                                     \
10276 _(dst_port)
10277
10278 #define foreach_udp_proto_field                 \
10279 _(src_port)                                     \
10280 _(dst_port)
10281
10282 #define foreach_ip4_proto_field                 \
10283 _(src_address)                                  \
10284 _(dst_address)                                  \
10285 _(tos)                                          \
10286 _(length)                                       \
10287 _(fragment_id)                                  \
10288 _(ttl)                                          \
10289 _(protocol)                                     \
10290 _(checksum)
10291
10292 typedef struct
10293 {
10294   u16 src_port, dst_port;
10295 } tcpudp_header_t;
10296
10297 #if VPP_API_TEST_BUILTIN == 0
10298 uword
10299 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10300 {
10301   u8 **maskp = va_arg (*args, u8 **);
10302   u8 *mask = 0;
10303   u8 found_something = 0;
10304   tcp_header_t *tcp;
10305
10306 #define _(a) u8 a=0;
10307   foreach_tcp_proto_field;
10308 #undef _
10309
10310   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10311     {
10312       if (0);
10313 #define _(a) else if (unformat (input, #a)) a=1;
10314       foreach_tcp_proto_field
10315 #undef _
10316         else
10317         break;
10318     }
10319
10320 #define _(a) found_something += a;
10321   foreach_tcp_proto_field;
10322 #undef _
10323
10324   if (found_something == 0)
10325     return 0;
10326
10327   vec_validate (mask, sizeof (*tcp) - 1);
10328
10329   tcp = (tcp_header_t *) mask;
10330
10331 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
10332   foreach_tcp_proto_field;
10333 #undef _
10334
10335   *maskp = mask;
10336   return 1;
10337 }
10338
10339 uword
10340 unformat_udp_mask (unformat_input_t * input, va_list * args)
10341 {
10342   u8 **maskp = va_arg (*args, u8 **);
10343   u8 *mask = 0;
10344   u8 found_something = 0;
10345   udp_header_t *udp;
10346
10347 #define _(a) u8 a=0;
10348   foreach_udp_proto_field;
10349 #undef _
10350
10351   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10352     {
10353       if (0);
10354 #define _(a) else if (unformat (input, #a)) a=1;
10355       foreach_udp_proto_field
10356 #undef _
10357         else
10358         break;
10359     }
10360
10361 #define _(a) found_something += a;
10362   foreach_udp_proto_field;
10363 #undef _
10364
10365   if (found_something == 0)
10366     return 0;
10367
10368   vec_validate (mask, sizeof (*udp) - 1);
10369
10370   udp = (udp_header_t *) mask;
10371
10372 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
10373   foreach_udp_proto_field;
10374 #undef _
10375
10376   *maskp = mask;
10377   return 1;
10378 }
10379
10380 uword
10381 unformat_l4_mask (unformat_input_t * input, va_list * args)
10382 {
10383   u8 **maskp = va_arg (*args, u8 **);
10384   u16 src_port = 0, dst_port = 0;
10385   tcpudp_header_t *tcpudp;
10386
10387   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10388     {
10389       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10390         return 1;
10391       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10392         return 1;
10393       else if (unformat (input, "src_port"))
10394         src_port = 0xFFFF;
10395       else if (unformat (input, "dst_port"))
10396         dst_port = 0xFFFF;
10397       else
10398         return 0;
10399     }
10400
10401   if (!src_port && !dst_port)
10402     return 0;
10403
10404   u8 *mask = 0;
10405   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10406
10407   tcpudp = (tcpudp_header_t *) mask;
10408   tcpudp->src_port = src_port;
10409   tcpudp->dst_port = dst_port;
10410
10411   *maskp = mask;
10412
10413   return 1;
10414 }
10415
10416 uword
10417 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10418 {
10419   u8 **maskp = va_arg (*args, u8 **);
10420   u8 *mask = 0;
10421   u8 found_something = 0;
10422   ip4_header_t *ip;
10423
10424 #define _(a) u8 a=0;
10425   foreach_ip4_proto_field;
10426 #undef _
10427   u8 version = 0;
10428   u8 hdr_length = 0;
10429
10430
10431   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10432     {
10433       if (unformat (input, "version"))
10434         version = 1;
10435       else if (unformat (input, "hdr_length"))
10436         hdr_length = 1;
10437       else if (unformat (input, "src"))
10438         src_address = 1;
10439       else if (unformat (input, "dst"))
10440         dst_address = 1;
10441       else if (unformat (input, "proto"))
10442         protocol = 1;
10443
10444 #define _(a) else if (unformat (input, #a)) a=1;
10445       foreach_ip4_proto_field
10446 #undef _
10447         else
10448         break;
10449     }
10450
10451 #define _(a) found_something += a;
10452   foreach_ip4_proto_field;
10453 #undef _
10454
10455   if (found_something == 0)
10456     return 0;
10457
10458   vec_validate (mask, sizeof (*ip) - 1);
10459
10460   ip = (ip4_header_t *) mask;
10461
10462 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10463   foreach_ip4_proto_field;
10464 #undef _
10465
10466   ip->ip_version_and_header_length = 0;
10467
10468   if (version)
10469     ip->ip_version_and_header_length |= 0xF0;
10470
10471   if (hdr_length)
10472     ip->ip_version_and_header_length |= 0x0F;
10473
10474   *maskp = mask;
10475   return 1;
10476 }
10477
10478 #define foreach_ip6_proto_field                 \
10479 _(src_address)                                  \
10480 _(dst_address)                                  \
10481 _(payload_length)                               \
10482 _(hop_limit)                                    \
10483 _(protocol)
10484
10485 uword
10486 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10487 {
10488   u8 **maskp = va_arg (*args, u8 **);
10489   u8 *mask = 0;
10490   u8 found_something = 0;
10491   ip6_header_t *ip;
10492   u32 ip_version_traffic_class_and_flow_label;
10493
10494 #define _(a) u8 a=0;
10495   foreach_ip6_proto_field;
10496 #undef _
10497   u8 version = 0;
10498   u8 traffic_class = 0;
10499   u8 flow_label = 0;
10500
10501   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10502     {
10503       if (unformat (input, "version"))
10504         version = 1;
10505       else if (unformat (input, "traffic-class"))
10506         traffic_class = 1;
10507       else if (unformat (input, "flow-label"))
10508         flow_label = 1;
10509       else if (unformat (input, "src"))
10510         src_address = 1;
10511       else if (unformat (input, "dst"))
10512         dst_address = 1;
10513       else if (unformat (input, "proto"))
10514         protocol = 1;
10515
10516 #define _(a) else if (unformat (input, #a)) a=1;
10517       foreach_ip6_proto_field
10518 #undef _
10519         else
10520         break;
10521     }
10522
10523 #define _(a) found_something += a;
10524   foreach_ip6_proto_field;
10525 #undef _
10526
10527   if (found_something == 0)
10528     return 0;
10529
10530   vec_validate (mask, sizeof (*ip) - 1);
10531
10532   ip = (ip6_header_t *) mask;
10533
10534 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10535   foreach_ip6_proto_field;
10536 #undef _
10537
10538   ip_version_traffic_class_and_flow_label = 0;
10539
10540   if (version)
10541     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10542
10543   if (traffic_class)
10544     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10545
10546   if (flow_label)
10547     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10548
10549   ip->ip_version_traffic_class_and_flow_label =
10550     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10551
10552   *maskp = mask;
10553   return 1;
10554 }
10555
10556 uword
10557 unformat_l3_mask (unformat_input_t * input, va_list * args)
10558 {
10559   u8 **maskp = va_arg (*args, u8 **);
10560
10561   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10562     {
10563       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10564         return 1;
10565       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10566         return 1;
10567       else
10568         break;
10569     }
10570   return 0;
10571 }
10572
10573 uword
10574 unformat_l2_mask (unformat_input_t * input, va_list * args)
10575 {
10576   u8 **maskp = va_arg (*args, u8 **);
10577   u8 *mask = 0;
10578   u8 src = 0;
10579   u8 dst = 0;
10580   u8 proto = 0;
10581   u8 tag1 = 0;
10582   u8 tag2 = 0;
10583   u8 ignore_tag1 = 0;
10584   u8 ignore_tag2 = 0;
10585   u8 cos1 = 0;
10586   u8 cos2 = 0;
10587   u8 dot1q = 0;
10588   u8 dot1ad = 0;
10589   int len = 14;
10590
10591   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10592     {
10593       if (unformat (input, "src"))
10594         src = 1;
10595       else if (unformat (input, "dst"))
10596         dst = 1;
10597       else if (unformat (input, "proto"))
10598         proto = 1;
10599       else if (unformat (input, "tag1"))
10600         tag1 = 1;
10601       else if (unformat (input, "tag2"))
10602         tag2 = 1;
10603       else if (unformat (input, "ignore-tag1"))
10604         ignore_tag1 = 1;
10605       else if (unformat (input, "ignore-tag2"))
10606         ignore_tag2 = 1;
10607       else if (unformat (input, "cos1"))
10608         cos1 = 1;
10609       else if (unformat (input, "cos2"))
10610         cos2 = 1;
10611       else if (unformat (input, "dot1q"))
10612         dot1q = 1;
10613       else if (unformat (input, "dot1ad"))
10614         dot1ad = 1;
10615       else
10616         break;
10617     }
10618   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10619        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10620     return 0;
10621
10622   if (tag1 || ignore_tag1 || cos1 || dot1q)
10623     len = 18;
10624   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10625     len = 22;
10626
10627   vec_validate (mask, len - 1);
10628
10629   if (dst)
10630     memset (mask, 0xff, 6);
10631
10632   if (src)
10633     memset (mask + 6, 0xff, 6);
10634
10635   if (tag2 || dot1ad)
10636     {
10637       /* inner vlan tag */
10638       if (tag2)
10639         {
10640           mask[19] = 0xff;
10641           mask[18] = 0x0f;
10642         }
10643       if (cos2)
10644         mask[18] |= 0xe0;
10645       if (proto)
10646         mask[21] = mask[20] = 0xff;
10647       if (tag1)
10648         {
10649           mask[15] = 0xff;
10650           mask[14] = 0x0f;
10651         }
10652       if (cos1)
10653         mask[14] |= 0xe0;
10654       *maskp = mask;
10655       return 1;
10656     }
10657   if (tag1 | dot1q)
10658     {
10659       if (tag1)
10660         {
10661           mask[15] = 0xff;
10662           mask[14] = 0x0f;
10663         }
10664       if (cos1)
10665         mask[14] |= 0xe0;
10666       if (proto)
10667         mask[16] = mask[17] = 0xff;
10668
10669       *maskp = mask;
10670       return 1;
10671     }
10672   if (cos2)
10673     mask[18] |= 0xe0;
10674   if (cos1)
10675     mask[14] |= 0xe0;
10676   if (proto)
10677     mask[12] = mask[13] = 0xff;
10678
10679   *maskp = mask;
10680   return 1;
10681 }
10682
10683 uword
10684 unformat_classify_mask (unformat_input_t * input, va_list * args)
10685 {
10686   u8 **maskp = va_arg (*args, u8 **);
10687   u32 *skipp = va_arg (*args, u32 *);
10688   u32 *matchp = va_arg (*args, u32 *);
10689   u32 match;
10690   u8 *mask = 0;
10691   u8 *l2 = 0;
10692   u8 *l3 = 0;
10693   u8 *l4 = 0;
10694   int i;
10695
10696   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10697     {
10698       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10699         ;
10700       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10701         ;
10702       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10703         ;
10704       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10705         ;
10706       else
10707         break;
10708     }
10709
10710   if (l4 && !l3)
10711     {
10712       vec_free (mask);
10713       vec_free (l2);
10714       vec_free (l4);
10715       return 0;
10716     }
10717
10718   if (mask || l2 || l3 || l4)
10719     {
10720       if (l2 || l3 || l4)
10721         {
10722           /* "With a free Ethernet header in every package" */
10723           if (l2 == 0)
10724             vec_validate (l2, 13);
10725           mask = l2;
10726           if (vec_len (l3))
10727             {
10728               vec_append (mask, l3);
10729               vec_free (l3);
10730             }
10731           if (vec_len (l4))
10732             {
10733               vec_append (mask, l4);
10734               vec_free (l4);
10735             }
10736         }
10737
10738       /* Scan forward looking for the first significant mask octet */
10739       for (i = 0; i < vec_len (mask); i++)
10740         if (mask[i])
10741           break;
10742
10743       /* compute (skip, match) params */
10744       *skipp = i / sizeof (u32x4);
10745       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10746
10747       /* Pad mask to an even multiple of the vector size */
10748       while (vec_len (mask) % sizeof (u32x4))
10749         vec_add1 (mask, 0);
10750
10751       match = vec_len (mask) / sizeof (u32x4);
10752
10753       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10754         {
10755           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10756           if (*tmp || *(tmp + 1))
10757             break;
10758           match--;
10759         }
10760       if (match == 0)
10761         clib_warning ("BUG: match 0");
10762
10763       _vec_len (mask) = match * sizeof (u32x4);
10764
10765       *matchp = match;
10766       *maskp = mask;
10767
10768       return 1;
10769     }
10770
10771   return 0;
10772 }
10773 #endif /* VPP_API_TEST_BUILTIN */
10774
10775 #define foreach_l2_next                         \
10776 _(drop, DROP)                                   \
10777 _(ethernet, ETHERNET_INPUT)                     \
10778 _(ip4, IP4_INPUT)                               \
10779 _(ip6, IP6_INPUT)
10780
10781 uword
10782 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10783 {
10784   u32 *miss_next_indexp = va_arg (*args, u32 *);
10785   u32 next_index = 0;
10786   u32 tmp;
10787
10788 #define _(n,N) \
10789   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10790   foreach_l2_next;
10791 #undef _
10792
10793   if (unformat (input, "%d", &tmp))
10794     {
10795       next_index = tmp;
10796       goto out;
10797     }
10798
10799   return 0;
10800
10801 out:
10802   *miss_next_indexp = next_index;
10803   return 1;
10804 }
10805
10806 #define foreach_ip_next                         \
10807 _(drop, DROP)                                   \
10808 _(local, LOCAL)                                 \
10809 _(rewrite, REWRITE)
10810
10811 uword
10812 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10813 {
10814   u32 *miss_next_indexp = va_arg (*args, u32 *);
10815   u32 next_index = 0;
10816   u32 tmp;
10817
10818 #define _(n,N) \
10819   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10820   foreach_ip_next;
10821 #undef _
10822
10823   if (unformat (input, "%d", &tmp))
10824     {
10825       next_index = tmp;
10826       goto out;
10827     }
10828
10829   return 0;
10830
10831 out:
10832   *miss_next_indexp = next_index;
10833   return 1;
10834 }
10835
10836 #define foreach_acl_next                        \
10837 _(deny, DENY)
10838
10839 uword
10840 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10841 {
10842   u32 *miss_next_indexp = va_arg (*args, u32 *);
10843   u32 next_index = 0;
10844   u32 tmp;
10845
10846 #define _(n,N) \
10847   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10848   foreach_acl_next;
10849 #undef _
10850
10851   if (unformat (input, "permit"))
10852     {
10853       next_index = ~0;
10854       goto out;
10855     }
10856   else if (unformat (input, "%d", &tmp))
10857     {
10858       next_index = tmp;
10859       goto out;
10860     }
10861
10862   return 0;
10863
10864 out:
10865   *miss_next_indexp = next_index;
10866   return 1;
10867 }
10868
10869 uword
10870 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10871 {
10872   u32 *r = va_arg (*args, u32 *);
10873
10874   if (unformat (input, "conform-color"))
10875     *r = POLICE_CONFORM;
10876   else if (unformat (input, "exceed-color"))
10877     *r = POLICE_EXCEED;
10878   else
10879     return 0;
10880
10881   return 1;
10882 }
10883
10884 static int
10885 api_classify_add_del_table (vat_main_t * vam)
10886 {
10887   unformat_input_t *i = vam->input;
10888   vl_api_classify_add_del_table_t *mp;
10889
10890   u32 nbuckets = 2;
10891   u32 skip = ~0;
10892   u32 match = ~0;
10893   int is_add = 1;
10894   int del_chain = 0;
10895   u32 table_index = ~0;
10896   u32 next_table_index = ~0;
10897   u32 miss_next_index = ~0;
10898   u32 memory_size = 32 << 20;
10899   u8 *mask = 0;
10900   u32 current_data_flag = 0;
10901   int current_data_offset = 0;
10902   int ret;
10903
10904   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10905     {
10906       if (unformat (i, "del"))
10907         is_add = 0;
10908       else if (unformat (i, "del-chain"))
10909         {
10910           is_add = 0;
10911           del_chain = 1;
10912         }
10913       else if (unformat (i, "buckets %d", &nbuckets))
10914         ;
10915       else if (unformat (i, "memory_size %d", &memory_size))
10916         ;
10917       else if (unformat (i, "skip %d", &skip))
10918         ;
10919       else if (unformat (i, "match %d", &match))
10920         ;
10921       else if (unformat (i, "table %d", &table_index))
10922         ;
10923       else if (unformat (i, "mask %U", unformat_classify_mask,
10924                          &mask, &skip, &match))
10925         ;
10926       else if (unformat (i, "next-table %d", &next_table_index))
10927         ;
10928       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10929                          &miss_next_index))
10930         ;
10931       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10932                          &miss_next_index))
10933         ;
10934       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10935                          &miss_next_index))
10936         ;
10937       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10938         ;
10939       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10940         ;
10941       else
10942         break;
10943     }
10944
10945   if (is_add && mask == 0)
10946     {
10947       errmsg ("Mask required");
10948       return -99;
10949     }
10950
10951   if (is_add && skip == ~0)
10952     {
10953       errmsg ("skip count required");
10954       return -99;
10955     }
10956
10957   if (is_add && match == ~0)
10958     {
10959       errmsg ("match count required");
10960       return -99;
10961     }
10962
10963   if (!is_add && table_index == ~0)
10964     {
10965       errmsg ("table index required for delete");
10966       return -99;
10967     }
10968
10969   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10970
10971   mp->is_add = is_add;
10972   mp->del_chain = del_chain;
10973   mp->table_index = ntohl (table_index);
10974   mp->nbuckets = ntohl (nbuckets);
10975   mp->memory_size = ntohl (memory_size);
10976   mp->skip_n_vectors = ntohl (skip);
10977   mp->match_n_vectors = ntohl (match);
10978   mp->next_table_index = ntohl (next_table_index);
10979   mp->miss_next_index = ntohl (miss_next_index);
10980   mp->current_data_flag = ntohl (current_data_flag);
10981   mp->current_data_offset = ntohl (current_data_offset);
10982   clib_memcpy (mp->mask, mask, vec_len (mask));
10983
10984   vec_free (mask);
10985
10986   S (mp);
10987   W (ret);
10988   return ret;
10989 }
10990
10991 #if VPP_API_TEST_BUILTIN == 0
10992 uword
10993 unformat_l4_match (unformat_input_t * input, va_list * args)
10994 {
10995   u8 **matchp = va_arg (*args, u8 **);
10996
10997   u8 *proto_header = 0;
10998   int src_port = 0;
10999   int dst_port = 0;
11000
11001   tcpudp_header_t h;
11002
11003   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11004     {
11005       if (unformat (input, "src_port %d", &src_port))
11006         ;
11007       else if (unformat (input, "dst_port %d", &dst_port))
11008         ;
11009       else
11010         return 0;
11011     }
11012
11013   h.src_port = clib_host_to_net_u16 (src_port);
11014   h.dst_port = clib_host_to_net_u16 (dst_port);
11015   vec_validate (proto_header, sizeof (h) - 1);
11016   memcpy (proto_header, &h, sizeof (h));
11017
11018   *matchp = proto_header;
11019
11020   return 1;
11021 }
11022
11023 uword
11024 unformat_ip4_match (unformat_input_t * input, va_list * args)
11025 {
11026   u8 **matchp = va_arg (*args, u8 **);
11027   u8 *match = 0;
11028   ip4_header_t *ip;
11029   int version = 0;
11030   u32 version_val;
11031   int hdr_length = 0;
11032   u32 hdr_length_val;
11033   int src = 0, dst = 0;
11034   ip4_address_t src_val, dst_val;
11035   int proto = 0;
11036   u32 proto_val;
11037   int tos = 0;
11038   u32 tos_val;
11039   int length = 0;
11040   u32 length_val;
11041   int fragment_id = 0;
11042   u32 fragment_id_val;
11043   int ttl = 0;
11044   int ttl_val;
11045   int checksum = 0;
11046   u32 checksum_val;
11047
11048   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11049     {
11050       if (unformat (input, "version %d", &version_val))
11051         version = 1;
11052       else if (unformat (input, "hdr_length %d", &hdr_length_val))
11053         hdr_length = 1;
11054       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
11055         src = 1;
11056       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
11057         dst = 1;
11058       else if (unformat (input, "proto %d", &proto_val))
11059         proto = 1;
11060       else if (unformat (input, "tos %d", &tos_val))
11061         tos = 1;
11062       else if (unformat (input, "length %d", &length_val))
11063         length = 1;
11064       else if (unformat (input, "fragment_id %d", &fragment_id_val))
11065         fragment_id = 1;
11066       else if (unformat (input, "ttl %d", &ttl_val))
11067         ttl = 1;
11068       else if (unformat (input, "checksum %d", &checksum_val))
11069         checksum = 1;
11070       else
11071         break;
11072     }
11073
11074   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
11075       + ttl + checksum == 0)
11076     return 0;
11077
11078   /*
11079    * Aligned because we use the real comparison functions
11080    */
11081   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11082
11083   ip = (ip4_header_t *) match;
11084
11085   /* These are realistically matched in practice */
11086   if (src)
11087     ip->src_address.as_u32 = src_val.as_u32;
11088
11089   if (dst)
11090     ip->dst_address.as_u32 = dst_val.as_u32;
11091
11092   if (proto)
11093     ip->protocol = proto_val;
11094
11095
11096   /* These are not, but they're included for completeness */
11097   if (version)
11098     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
11099
11100   if (hdr_length)
11101     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
11102
11103   if (tos)
11104     ip->tos = tos_val;
11105
11106   if (length)
11107     ip->length = clib_host_to_net_u16 (length_val);
11108
11109   if (ttl)
11110     ip->ttl = ttl_val;
11111
11112   if (checksum)
11113     ip->checksum = clib_host_to_net_u16 (checksum_val);
11114
11115   *matchp = match;
11116   return 1;
11117 }
11118
11119 uword
11120 unformat_ip6_match (unformat_input_t * input, va_list * args)
11121 {
11122   u8 **matchp = va_arg (*args, u8 **);
11123   u8 *match = 0;
11124   ip6_header_t *ip;
11125   int version = 0;
11126   u32 version_val;
11127   u8 traffic_class = 0;
11128   u32 traffic_class_val = 0;
11129   u8 flow_label = 0;
11130   u8 flow_label_val;
11131   int src = 0, dst = 0;
11132   ip6_address_t src_val, dst_val;
11133   int proto = 0;
11134   u32 proto_val;
11135   int payload_length = 0;
11136   u32 payload_length_val;
11137   int hop_limit = 0;
11138   int hop_limit_val;
11139   u32 ip_version_traffic_class_and_flow_label;
11140
11141   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11142     {
11143       if (unformat (input, "version %d", &version_val))
11144         version = 1;
11145       else if (unformat (input, "traffic_class %d", &traffic_class_val))
11146         traffic_class = 1;
11147       else if (unformat (input, "flow_label %d", &flow_label_val))
11148         flow_label = 1;
11149       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
11150         src = 1;
11151       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
11152         dst = 1;
11153       else if (unformat (input, "proto %d", &proto_val))
11154         proto = 1;
11155       else if (unformat (input, "payload_length %d", &payload_length_val))
11156         payload_length = 1;
11157       else if (unformat (input, "hop_limit %d", &hop_limit_val))
11158         hop_limit = 1;
11159       else
11160         break;
11161     }
11162
11163   if (version + traffic_class + flow_label + src + dst + proto +
11164       payload_length + hop_limit == 0)
11165     return 0;
11166
11167   /*
11168    * Aligned because we use the real comparison functions
11169    */
11170   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
11171
11172   ip = (ip6_header_t *) match;
11173
11174   if (src)
11175     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
11176
11177   if (dst)
11178     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
11179
11180   if (proto)
11181     ip->protocol = proto_val;
11182
11183   ip_version_traffic_class_and_flow_label = 0;
11184
11185   if (version)
11186     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
11187
11188   if (traffic_class)
11189     ip_version_traffic_class_and_flow_label |=
11190       (traffic_class_val & 0xFF) << 20;
11191
11192   if (flow_label)
11193     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
11194
11195   ip->ip_version_traffic_class_and_flow_label =
11196     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
11197
11198   if (payload_length)
11199     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
11200
11201   if (hop_limit)
11202     ip->hop_limit = hop_limit_val;
11203
11204   *matchp = match;
11205   return 1;
11206 }
11207
11208 uword
11209 unformat_l3_match (unformat_input_t * input, va_list * args)
11210 {
11211   u8 **matchp = va_arg (*args, u8 **);
11212
11213   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11214     {
11215       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
11216         return 1;
11217       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
11218         return 1;
11219       else
11220         break;
11221     }
11222   return 0;
11223 }
11224
11225 uword
11226 unformat_vlan_tag (unformat_input_t * input, va_list * args)
11227 {
11228   u8 *tagp = va_arg (*args, u8 *);
11229   u32 tag;
11230
11231   if (unformat (input, "%d", &tag))
11232     {
11233       tagp[0] = (tag >> 8) & 0x0F;
11234       tagp[1] = tag & 0xFF;
11235       return 1;
11236     }
11237
11238   return 0;
11239 }
11240
11241 uword
11242 unformat_l2_match (unformat_input_t * input, va_list * args)
11243 {
11244   u8 **matchp = va_arg (*args, u8 **);
11245   u8 *match = 0;
11246   u8 src = 0;
11247   u8 src_val[6];
11248   u8 dst = 0;
11249   u8 dst_val[6];
11250   u8 proto = 0;
11251   u16 proto_val;
11252   u8 tag1 = 0;
11253   u8 tag1_val[2];
11254   u8 tag2 = 0;
11255   u8 tag2_val[2];
11256   int len = 14;
11257   u8 ignore_tag1 = 0;
11258   u8 ignore_tag2 = 0;
11259   u8 cos1 = 0;
11260   u8 cos2 = 0;
11261   u32 cos1_val = 0;
11262   u32 cos2_val = 0;
11263
11264   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11265     {
11266       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
11267         src = 1;
11268       else
11269         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
11270         dst = 1;
11271       else if (unformat (input, "proto %U",
11272                          unformat_ethernet_type_host_byte_order, &proto_val))
11273         proto = 1;
11274       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
11275         tag1 = 1;
11276       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
11277         tag2 = 1;
11278       else if (unformat (input, "ignore-tag1"))
11279         ignore_tag1 = 1;
11280       else if (unformat (input, "ignore-tag2"))
11281         ignore_tag2 = 1;
11282       else if (unformat (input, "cos1 %d", &cos1_val))
11283         cos1 = 1;
11284       else if (unformat (input, "cos2 %d", &cos2_val))
11285         cos2 = 1;
11286       else
11287         break;
11288     }
11289   if ((src + dst + proto + tag1 + tag2 +
11290        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11291     return 0;
11292
11293   if (tag1 || ignore_tag1 || cos1)
11294     len = 18;
11295   if (tag2 || ignore_tag2 || cos2)
11296     len = 22;
11297
11298   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11299
11300   if (dst)
11301     clib_memcpy (match, dst_val, 6);
11302
11303   if (src)
11304     clib_memcpy (match + 6, src_val, 6);
11305
11306   if (tag2)
11307     {
11308       /* inner vlan tag */
11309       match[19] = tag2_val[1];
11310       match[18] = tag2_val[0];
11311       if (cos2)
11312         match[18] |= (cos2_val & 0x7) << 5;
11313       if (proto)
11314         {
11315           match[21] = proto_val & 0xff;
11316           match[20] = proto_val >> 8;
11317         }
11318       if (tag1)
11319         {
11320           match[15] = tag1_val[1];
11321           match[14] = tag1_val[0];
11322         }
11323       if (cos1)
11324         match[14] |= (cos1_val & 0x7) << 5;
11325       *matchp = match;
11326       return 1;
11327     }
11328   if (tag1)
11329     {
11330       match[15] = tag1_val[1];
11331       match[14] = tag1_val[0];
11332       if (proto)
11333         {
11334           match[17] = proto_val & 0xff;
11335           match[16] = proto_val >> 8;
11336         }
11337       if (cos1)
11338         match[14] |= (cos1_val & 0x7) << 5;
11339
11340       *matchp = match;
11341       return 1;
11342     }
11343   if (cos2)
11344     match[18] |= (cos2_val & 0x7) << 5;
11345   if (cos1)
11346     match[14] |= (cos1_val & 0x7) << 5;
11347   if (proto)
11348     {
11349       match[13] = proto_val & 0xff;
11350       match[12] = proto_val >> 8;
11351     }
11352
11353   *matchp = match;
11354   return 1;
11355 }
11356 #endif
11357
11358 uword
11359 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11360 {
11361   u8 **matchp = va_arg (*args, u8 **);
11362   u32 skip_n_vectors = va_arg (*args, u32);
11363   u32 match_n_vectors = va_arg (*args, u32);
11364
11365   u8 *match = 0;
11366   u8 *l2 = 0;
11367   u8 *l3 = 0;
11368   u8 *l4 = 0;
11369
11370   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11371     {
11372       if (unformat (input, "hex %U", unformat_hex_string, &match))
11373         ;
11374       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11375         ;
11376       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11377         ;
11378       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11379         ;
11380       else
11381         break;
11382     }
11383
11384   if (l4 && !l3)
11385     {
11386       vec_free (match);
11387       vec_free (l2);
11388       vec_free (l4);
11389       return 0;
11390     }
11391
11392   if (match || l2 || l3 || l4)
11393     {
11394       if (l2 || l3 || l4)
11395         {
11396           /* "Win a free Ethernet header in every packet" */
11397           if (l2 == 0)
11398             vec_validate_aligned (l2, 13, sizeof (u32x4));
11399           match = l2;
11400           if (vec_len (l3))
11401             {
11402               vec_append_aligned (match, l3, sizeof (u32x4));
11403               vec_free (l3);
11404             }
11405           if (vec_len (l4))
11406             {
11407               vec_append_aligned (match, l4, sizeof (u32x4));
11408               vec_free (l4);
11409             }
11410         }
11411
11412       /* Make sure the vector is big enough even if key is all 0's */
11413       vec_validate_aligned
11414         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11415          sizeof (u32x4));
11416
11417       /* Set size, include skipped vectors */
11418       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11419
11420       *matchp = match;
11421
11422       return 1;
11423     }
11424
11425   return 0;
11426 }
11427
11428 static int
11429 api_classify_add_del_session (vat_main_t * vam)
11430 {
11431   unformat_input_t *i = vam->input;
11432   vl_api_classify_add_del_session_t *mp;
11433   int is_add = 1;
11434   u32 table_index = ~0;
11435   u32 hit_next_index = ~0;
11436   u32 opaque_index = ~0;
11437   u8 *match = 0;
11438   i32 advance = 0;
11439   u32 skip_n_vectors = 0;
11440   u32 match_n_vectors = 0;
11441   u32 action = 0;
11442   u32 metadata = 0;
11443   int ret;
11444
11445   /*
11446    * Warning: you have to supply skip_n and match_n
11447    * because the API client cant simply look at the classify
11448    * table object.
11449    */
11450
11451   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11452     {
11453       if (unformat (i, "del"))
11454         is_add = 0;
11455       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11456                          &hit_next_index))
11457         ;
11458       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11459                          &hit_next_index))
11460         ;
11461       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11462                          &hit_next_index))
11463         ;
11464       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11465         ;
11466       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11467         ;
11468       else if (unformat (i, "opaque-index %d", &opaque_index))
11469         ;
11470       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11471         ;
11472       else if (unformat (i, "match_n %d", &match_n_vectors))
11473         ;
11474       else if (unformat (i, "match %U", api_unformat_classify_match,
11475                          &match, skip_n_vectors, match_n_vectors))
11476         ;
11477       else if (unformat (i, "advance %d", &advance))
11478         ;
11479       else if (unformat (i, "table-index %d", &table_index))
11480         ;
11481       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11482         action = 1;
11483       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11484         action = 2;
11485       else if (unformat (i, "action %d", &action))
11486         ;
11487       else if (unformat (i, "metadata %d", &metadata))
11488         ;
11489       else
11490         break;
11491     }
11492
11493   if (table_index == ~0)
11494     {
11495       errmsg ("Table index required");
11496       return -99;
11497     }
11498
11499   if (is_add && match == 0)
11500     {
11501       errmsg ("Match value required");
11502       return -99;
11503     }
11504
11505   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11506
11507   mp->is_add = is_add;
11508   mp->table_index = ntohl (table_index);
11509   mp->hit_next_index = ntohl (hit_next_index);
11510   mp->opaque_index = ntohl (opaque_index);
11511   mp->advance = ntohl (advance);
11512   mp->action = action;
11513   mp->metadata = ntohl (metadata);
11514   clib_memcpy (mp->match, match, vec_len (match));
11515   vec_free (match);
11516
11517   S (mp);
11518   W (ret);
11519   return ret;
11520 }
11521
11522 static int
11523 api_classify_set_interface_ip_table (vat_main_t * vam)
11524 {
11525   unformat_input_t *i = vam->input;
11526   vl_api_classify_set_interface_ip_table_t *mp;
11527   u32 sw_if_index;
11528   int sw_if_index_set;
11529   u32 table_index = ~0;
11530   u8 is_ipv6 = 0;
11531   int ret;
11532
11533   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11534     {
11535       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11536         sw_if_index_set = 1;
11537       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11538         sw_if_index_set = 1;
11539       else if (unformat (i, "table %d", &table_index))
11540         ;
11541       else
11542         {
11543           clib_warning ("parse error '%U'", format_unformat_error, i);
11544           return -99;
11545         }
11546     }
11547
11548   if (sw_if_index_set == 0)
11549     {
11550       errmsg ("missing interface name or sw_if_index");
11551       return -99;
11552     }
11553
11554
11555   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11556
11557   mp->sw_if_index = ntohl (sw_if_index);
11558   mp->table_index = ntohl (table_index);
11559   mp->is_ipv6 = is_ipv6;
11560
11561   S (mp);
11562   W (ret);
11563   return ret;
11564 }
11565
11566 static int
11567 api_classify_set_interface_l2_tables (vat_main_t * vam)
11568 {
11569   unformat_input_t *i = vam->input;
11570   vl_api_classify_set_interface_l2_tables_t *mp;
11571   u32 sw_if_index;
11572   int sw_if_index_set;
11573   u32 ip4_table_index = ~0;
11574   u32 ip6_table_index = ~0;
11575   u32 other_table_index = ~0;
11576   u32 is_input = 1;
11577   int ret;
11578
11579   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11580     {
11581       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11582         sw_if_index_set = 1;
11583       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11584         sw_if_index_set = 1;
11585       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11586         ;
11587       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11588         ;
11589       else if (unformat (i, "other-table %d", &other_table_index))
11590         ;
11591       else if (unformat (i, "is-input %d", &is_input))
11592         ;
11593       else
11594         {
11595           clib_warning ("parse error '%U'", format_unformat_error, i);
11596           return -99;
11597         }
11598     }
11599
11600   if (sw_if_index_set == 0)
11601     {
11602       errmsg ("missing interface name or sw_if_index");
11603       return -99;
11604     }
11605
11606
11607   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11608
11609   mp->sw_if_index = ntohl (sw_if_index);
11610   mp->ip4_table_index = ntohl (ip4_table_index);
11611   mp->ip6_table_index = ntohl (ip6_table_index);
11612   mp->other_table_index = ntohl (other_table_index);
11613   mp->is_input = (u8) is_input;
11614
11615   S (mp);
11616   W (ret);
11617   return ret;
11618 }
11619
11620 static int
11621 api_set_ipfix_exporter (vat_main_t * vam)
11622 {
11623   unformat_input_t *i = vam->input;
11624   vl_api_set_ipfix_exporter_t *mp;
11625   ip4_address_t collector_address;
11626   u8 collector_address_set = 0;
11627   u32 collector_port = ~0;
11628   ip4_address_t src_address;
11629   u8 src_address_set = 0;
11630   u32 vrf_id = ~0;
11631   u32 path_mtu = ~0;
11632   u32 template_interval = ~0;
11633   u8 udp_checksum = 0;
11634   int ret;
11635
11636   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11637     {
11638       if (unformat (i, "collector_address %U", unformat_ip4_address,
11639                     &collector_address))
11640         collector_address_set = 1;
11641       else if (unformat (i, "collector_port %d", &collector_port))
11642         ;
11643       else if (unformat (i, "src_address %U", unformat_ip4_address,
11644                          &src_address))
11645         src_address_set = 1;
11646       else if (unformat (i, "vrf_id %d", &vrf_id))
11647         ;
11648       else if (unformat (i, "path_mtu %d", &path_mtu))
11649         ;
11650       else if (unformat (i, "template_interval %d", &template_interval))
11651         ;
11652       else if (unformat (i, "udp_checksum"))
11653         udp_checksum = 1;
11654       else
11655         break;
11656     }
11657
11658   if (collector_address_set == 0)
11659     {
11660       errmsg ("collector_address required");
11661       return -99;
11662     }
11663
11664   if (src_address_set == 0)
11665     {
11666       errmsg ("src_address required");
11667       return -99;
11668     }
11669
11670   M (SET_IPFIX_EXPORTER, mp);
11671
11672   memcpy (mp->collector_address, collector_address.data,
11673           sizeof (collector_address.data));
11674   mp->collector_port = htons ((u16) collector_port);
11675   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11676   mp->vrf_id = htonl (vrf_id);
11677   mp->path_mtu = htonl (path_mtu);
11678   mp->template_interval = htonl (template_interval);
11679   mp->udp_checksum = udp_checksum;
11680
11681   S (mp);
11682   W (ret);
11683   return ret;
11684 }
11685
11686 static int
11687 api_set_ipfix_classify_stream (vat_main_t * vam)
11688 {
11689   unformat_input_t *i = vam->input;
11690   vl_api_set_ipfix_classify_stream_t *mp;
11691   u32 domain_id = 0;
11692   u32 src_port = UDP_DST_PORT_ipfix;
11693   int ret;
11694
11695   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11696     {
11697       if (unformat (i, "domain %d", &domain_id))
11698         ;
11699       else if (unformat (i, "src_port %d", &src_port))
11700         ;
11701       else
11702         {
11703           errmsg ("unknown input `%U'", format_unformat_error, i);
11704           return -99;
11705         }
11706     }
11707
11708   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11709
11710   mp->domain_id = htonl (domain_id);
11711   mp->src_port = htons ((u16) src_port);
11712
11713   S (mp);
11714   W (ret);
11715   return ret;
11716 }
11717
11718 static int
11719 api_ipfix_classify_table_add_del (vat_main_t * vam)
11720 {
11721   unformat_input_t *i = vam->input;
11722   vl_api_ipfix_classify_table_add_del_t *mp;
11723   int is_add = -1;
11724   u32 classify_table_index = ~0;
11725   u8 ip_version = 0;
11726   u8 transport_protocol = 255;
11727   int ret;
11728
11729   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11730     {
11731       if (unformat (i, "add"))
11732         is_add = 1;
11733       else if (unformat (i, "del"))
11734         is_add = 0;
11735       else if (unformat (i, "table %d", &classify_table_index))
11736         ;
11737       else if (unformat (i, "ip4"))
11738         ip_version = 4;
11739       else if (unformat (i, "ip6"))
11740         ip_version = 6;
11741       else if (unformat (i, "tcp"))
11742         transport_protocol = 6;
11743       else if (unformat (i, "udp"))
11744         transport_protocol = 17;
11745       else
11746         {
11747           errmsg ("unknown input `%U'", format_unformat_error, i);
11748           return -99;
11749         }
11750     }
11751
11752   if (is_add == -1)
11753     {
11754       errmsg ("expecting: add|del");
11755       return -99;
11756     }
11757   if (classify_table_index == ~0)
11758     {
11759       errmsg ("classifier table not specified");
11760       return -99;
11761     }
11762   if (ip_version == 0)
11763     {
11764       errmsg ("IP version not specified");
11765       return -99;
11766     }
11767
11768   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11769
11770   mp->is_add = is_add;
11771   mp->table_id = htonl (classify_table_index);
11772   mp->ip_version = ip_version;
11773   mp->transport_protocol = transport_protocol;
11774
11775   S (mp);
11776   W (ret);
11777   return ret;
11778 }
11779
11780 static int
11781 api_get_node_index (vat_main_t * vam)
11782 {
11783   unformat_input_t *i = vam->input;
11784   vl_api_get_node_index_t *mp;
11785   u8 *name = 0;
11786   int ret;
11787
11788   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11789     {
11790       if (unformat (i, "node %s", &name))
11791         ;
11792       else
11793         break;
11794     }
11795   if (name == 0)
11796     {
11797       errmsg ("node name required");
11798       return -99;
11799     }
11800   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11801     {
11802       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11803       return -99;
11804     }
11805
11806   M (GET_NODE_INDEX, mp);
11807   clib_memcpy (mp->node_name, name, vec_len (name));
11808   vec_free (name);
11809
11810   S (mp);
11811   W (ret);
11812   return ret;
11813 }
11814
11815 static int
11816 api_get_next_index (vat_main_t * vam)
11817 {
11818   unformat_input_t *i = vam->input;
11819   vl_api_get_next_index_t *mp;
11820   u8 *node_name = 0, *next_node_name = 0;
11821   int ret;
11822
11823   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11824     {
11825       if (unformat (i, "node-name %s", &node_name))
11826         ;
11827       else if (unformat (i, "next-node-name %s", &next_node_name))
11828         break;
11829     }
11830
11831   if (node_name == 0)
11832     {
11833       errmsg ("node name required");
11834       return -99;
11835     }
11836   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11837     {
11838       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11839       return -99;
11840     }
11841
11842   if (next_node_name == 0)
11843     {
11844       errmsg ("next node name required");
11845       return -99;
11846     }
11847   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11848     {
11849       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11850       return -99;
11851     }
11852
11853   M (GET_NEXT_INDEX, mp);
11854   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11855   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11856   vec_free (node_name);
11857   vec_free (next_node_name);
11858
11859   S (mp);
11860   W (ret);
11861   return ret;
11862 }
11863
11864 static int
11865 api_add_node_next (vat_main_t * vam)
11866 {
11867   unformat_input_t *i = vam->input;
11868   vl_api_add_node_next_t *mp;
11869   u8 *name = 0;
11870   u8 *next = 0;
11871   int ret;
11872
11873   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11874     {
11875       if (unformat (i, "node %s", &name))
11876         ;
11877       else if (unformat (i, "next %s", &next))
11878         ;
11879       else
11880         break;
11881     }
11882   if (name == 0)
11883     {
11884       errmsg ("node name required");
11885       return -99;
11886     }
11887   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11888     {
11889       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11890       return -99;
11891     }
11892   if (next == 0)
11893     {
11894       errmsg ("next node required");
11895       return -99;
11896     }
11897   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11898     {
11899       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11900       return -99;
11901     }
11902
11903   M (ADD_NODE_NEXT, mp);
11904   clib_memcpy (mp->node_name, name, vec_len (name));
11905   clib_memcpy (mp->next_name, next, vec_len (next));
11906   vec_free (name);
11907   vec_free (next);
11908
11909   S (mp);
11910   W (ret);
11911   return ret;
11912 }
11913
11914 static int
11915 api_l2tpv3_create_tunnel (vat_main_t * vam)
11916 {
11917   unformat_input_t *i = vam->input;
11918   ip6_address_t client_address, our_address;
11919   int client_address_set = 0;
11920   int our_address_set = 0;
11921   u32 local_session_id = 0;
11922   u32 remote_session_id = 0;
11923   u64 local_cookie = 0;
11924   u64 remote_cookie = 0;
11925   u8 l2_sublayer_present = 0;
11926   vl_api_l2tpv3_create_tunnel_t *mp;
11927   int ret;
11928
11929   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11930     {
11931       if (unformat (i, "client_address %U", unformat_ip6_address,
11932                     &client_address))
11933         client_address_set = 1;
11934       else if (unformat (i, "our_address %U", unformat_ip6_address,
11935                          &our_address))
11936         our_address_set = 1;
11937       else if (unformat (i, "local_session_id %d", &local_session_id))
11938         ;
11939       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11940         ;
11941       else if (unformat (i, "local_cookie %lld", &local_cookie))
11942         ;
11943       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11944         ;
11945       else if (unformat (i, "l2-sublayer-present"))
11946         l2_sublayer_present = 1;
11947       else
11948         break;
11949     }
11950
11951   if (client_address_set == 0)
11952     {
11953       errmsg ("client_address required");
11954       return -99;
11955     }
11956
11957   if (our_address_set == 0)
11958     {
11959       errmsg ("our_address required");
11960       return -99;
11961     }
11962
11963   M (L2TPV3_CREATE_TUNNEL, mp);
11964
11965   clib_memcpy (mp->client_address, client_address.as_u8,
11966                sizeof (mp->client_address));
11967
11968   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11969
11970   mp->local_session_id = ntohl (local_session_id);
11971   mp->remote_session_id = ntohl (remote_session_id);
11972   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11973   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11974   mp->l2_sublayer_present = l2_sublayer_present;
11975   mp->is_ipv6 = 1;
11976
11977   S (mp);
11978   W (ret);
11979   return ret;
11980 }
11981
11982 static int
11983 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11984 {
11985   unformat_input_t *i = vam->input;
11986   u32 sw_if_index;
11987   u8 sw_if_index_set = 0;
11988   u64 new_local_cookie = 0;
11989   u64 new_remote_cookie = 0;
11990   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11991   int ret;
11992
11993   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11994     {
11995       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11996         sw_if_index_set = 1;
11997       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11998         sw_if_index_set = 1;
11999       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
12000         ;
12001       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
12002         ;
12003       else
12004         break;
12005     }
12006
12007   if (sw_if_index_set == 0)
12008     {
12009       errmsg ("missing interface name or sw_if_index");
12010       return -99;
12011     }
12012
12013   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
12014
12015   mp->sw_if_index = ntohl (sw_if_index);
12016   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
12017   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
12018
12019   S (mp);
12020   W (ret);
12021   return ret;
12022 }
12023
12024 static int
12025 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
12026 {
12027   unformat_input_t *i = vam->input;
12028   vl_api_l2tpv3_interface_enable_disable_t *mp;
12029   u32 sw_if_index;
12030   u8 sw_if_index_set = 0;
12031   u8 enable_disable = 1;
12032   int ret;
12033
12034   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12035     {
12036       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12037         sw_if_index_set = 1;
12038       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12039         sw_if_index_set = 1;
12040       else if (unformat (i, "enable"))
12041         enable_disable = 1;
12042       else if (unformat (i, "disable"))
12043         enable_disable = 0;
12044       else
12045         break;
12046     }
12047
12048   if (sw_if_index_set == 0)
12049     {
12050       errmsg ("missing interface name or sw_if_index");
12051       return -99;
12052     }
12053
12054   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
12055
12056   mp->sw_if_index = ntohl (sw_if_index);
12057   mp->enable_disable = enable_disable;
12058
12059   S (mp);
12060   W (ret);
12061   return ret;
12062 }
12063
12064 static int
12065 api_l2tpv3_set_lookup_key (vat_main_t * vam)
12066 {
12067   unformat_input_t *i = vam->input;
12068   vl_api_l2tpv3_set_lookup_key_t *mp;
12069   u8 key = ~0;
12070   int ret;
12071
12072   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12073     {
12074       if (unformat (i, "lookup_v6_src"))
12075         key = L2T_LOOKUP_SRC_ADDRESS;
12076       else if (unformat (i, "lookup_v6_dst"))
12077         key = L2T_LOOKUP_DST_ADDRESS;
12078       else if (unformat (i, "lookup_session_id"))
12079         key = L2T_LOOKUP_SESSION_ID;
12080       else
12081         break;
12082     }
12083
12084   if (key == (u8) ~ 0)
12085     {
12086       errmsg ("l2tp session lookup key unset");
12087       return -99;
12088     }
12089
12090   M (L2TPV3_SET_LOOKUP_KEY, mp);
12091
12092   mp->key = key;
12093
12094   S (mp);
12095   W (ret);
12096   return ret;
12097 }
12098
12099 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
12100   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12101 {
12102   vat_main_t *vam = &vat_main;
12103
12104   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
12105          format_ip6_address, mp->our_address,
12106          format_ip6_address, mp->client_address,
12107          clib_net_to_host_u32 (mp->sw_if_index));
12108
12109   print (vam->ofp,
12110          "   local cookies %016llx %016llx remote cookie %016llx",
12111          clib_net_to_host_u64 (mp->local_cookie[0]),
12112          clib_net_to_host_u64 (mp->local_cookie[1]),
12113          clib_net_to_host_u64 (mp->remote_cookie));
12114
12115   print (vam->ofp, "   local session-id %d remote session-id %d",
12116          clib_net_to_host_u32 (mp->local_session_id),
12117          clib_net_to_host_u32 (mp->remote_session_id));
12118
12119   print (vam->ofp, "   l2 specific sublayer %s\n",
12120          mp->l2_sublayer_present ? "preset" : "absent");
12121
12122 }
12123
12124 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
12125   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
12126 {
12127   vat_main_t *vam = &vat_main;
12128   vat_json_node_t *node = NULL;
12129   struct in6_addr addr;
12130
12131   if (VAT_JSON_ARRAY != vam->json_tree.type)
12132     {
12133       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12134       vat_json_init_array (&vam->json_tree);
12135     }
12136   node = vat_json_array_add (&vam->json_tree);
12137
12138   vat_json_init_object (node);
12139
12140   clib_memcpy (&addr, mp->our_address, sizeof (addr));
12141   vat_json_object_add_ip6 (node, "our_address", addr);
12142   clib_memcpy (&addr, mp->client_address, sizeof (addr));
12143   vat_json_object_add_ip6 (node, "client_address", addr);
12144
12145   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
12146   vat_json_init_array (lc);
12147   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
12148   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
12149   vat_json_object_add_uint (node, "remote_cookie",
12150                             clib_net_to_host_u64 (mp->remote_cookie));
12151
12152   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
12153   vat_json_object_add_uint (node, "local_session_id",
12154                             clib_net_to_host_u32 (mp->local_session_id));
12155   vat_json_object_add_uint (node, "remote_session_id",
12156                             clib_net_to_host_u32 (mp->remote_session_id));
12157   vat_json_object_add_string_copy (node, "l2_sublayer",
12158                                    mp->l2_sublayer_present ? (u8 *) "present"
12159                                    : (u8 *) "absent");
12160 }
12161
12162 static int
12163 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
12164 {
12165   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
12166   vl_api_control_ping_t *mp_ping;
12167   int ret;
12168
12169   /* Get list of l2tpv3-tunnel interfaces */
12170   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
12171   S (mp);
12172
12173   /* Use a control ping for synchronization */
12174   MPING (CONTROL_PING, mp_ping);
12175   S (mp_ping);
12176
12177   W (ret);
12178   return ret;
12179 }
12180
12181
12182 static void vl_api_sw_interface_tap_details_t_handler
12183   (vl_api_sw_interface_tap_details_t * mp)
12184 {
12185   vat_main_t *vam = &vat_main;
12186
12187   print (vam->ofp, "%-16s %d",
12188          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
12189 }
12190
12191 static void vl_api_sw_interface_tap_details_t_handler_json
12192   (vl_api_sw_interface_tap_details_t * mp)
12193 {
12194   vat_main_t *vam = &vat_main;
12195   vat_json_node_t *node = NULL;
12196
12197   if (VAT_JSON_ARRAY != vam->json_tree.type)
12198     {
12199       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12200       vat_json_init_array (&vam->json_tree);
12201     }
12202   node = vat_json_array_add (&vam->json_tree);
12203
12204   vat_json_init_object (node);
12205   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12206   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
12207 }
12208
12209 static int
12210 api_sw_interface_tap_dump (vat_main_t * vam)
12211 {
12212   vl_api_sw_interface_tap_dump_t *mp;
12213   vl_api_control_ping_t *mp_ping;
12214   int ret;
12215
12216   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
12217   /* Get list of tap interfaces */
12218   M (SW_INTERFACE_TAP_DUMP, mp);
12219   S (mp);
12220
12221   /* Use a control ping for synchronization */
12222   MPING (CONTROL_PING, mp_ping);
12223   S (mp_ping);
12224
12225   W (ret);
12226   return ret;
12227 }
12228
12229 static uword unformat_vxlan_decap_next
12230   (unformat_input_t * input, va_list * args)
12231 {
12232   u32 *result = va_arg (*args, u32 *);
12233   u32 tmp;
12234
12235   if (unformat (input, "l2"))
12236     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12237   else if (unformat (input, "%d", &tmp))
12238     *result = tmp;
12239   else
12240     return 0;
12241   return 1;
12242 }
12243
12244 static int
12245 api_vxlan_add_del_tunnel (vat_main_t * vam)
12246 {
12247   unformat_input_t *line_input = vam->input;
12248   vl_api_vxlan_add_del_tunnel_t *mp;
12249   ip46_address_t src, dst;
12250   u8 is_add = 1;
12251   u8 ipv4_set = 0, ipv6_set = 0;
12252   u8 src_set = 0;
12253   u8 dst_set = 0;
12254   u8 grp_set = 0;
12255   u32 mcast_sw_if_index = ~0;
12256   u32 encap_vrf_id = 0;
12257   u32 decap_next_index = ~0;
12258   u32 vni = 0;
12259   int ret;
12260
12261   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12262   memset (&src, 0, sizeof src);
12263   memset (&dst, 0, sizeof dst);
12264
12265   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12266     {
12267       if (unformat (line_input, "del"))
12268         is_add = 0;
12269       else
12270         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12271         {
12272           ipv4_set = 1;
12273           src_set = 1;
12274         }
12275       else
12276         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12277         {
12278           ipv4_set = 1;
12279           dst_set = 1;
12280         }
12281       else
12282         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12283         {
12284           ipv6_set = 1;
12285           src_set = 1;
12286         }
12287       else
12288         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12289         {
12290           ipv6_set = 1;
12291           dst_set = 1;
12292         }
12293       else if (unformat (line_input, "group %U %U",
12294                          unformat_ip4_address, &dst.ip4,
12295                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12296         {
12297           grp_set = dst_set = 1;
12298           ipv4_set = 1;
12299         }
12300       else if (unformat (line_input, "group %U",
12301                          unformat_ip4_address, &dst.ip4))
12302         {
12303           grp_set = dst_set = 1;
12304           ipv4_set = 1;
12305         }
12306       else if (unformat (line_input, "group %U %U",
12307                          unformat_ip6_address, &dst.ip6,
12308                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12309         {
12310           grp_set = dst_set = 1;
12311           ipv6_set = 1;
12312         }
12313       else if (unformat (line_input, "group %U",
12314                          unformat_ip6_address, &dst.ip6))
12315         {
12316           grp_set = dst_set = 1;
12317           ipv6_set = 1;
12318         }
12319       else
12320         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12321         ;
12322       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12323         ;
12324       else if (unformat (line_input, "decap-next %U",
12325                          unformat_vxlan_decap_next, &decap_next_index))
12326         ;
12327       else if (unformat (line_input, "vni %d", &vni))
12328         ;
12329       else
12330         {
12331           errmsg ("parse error '%U'", format_unformat_error, line_input);
12332           return -99;
12333         }
12334     }
12335
12336   if (src_set == 0)
12337     {
12338       errmsg ("tunnel src address not specified");
12339       return -99;
12340     }
12341   if (dst_set == 0)
12342     {
12343       errmsg ("tunnel dst address not specified");
12344       return -99;
12345     }
12346
12347   if (grp_set && !ip46_address_is_multicast (&dst))
12348     {
12349       errmsg ("tunnel group address not multicast");
12350       return -99;
12351     }
12352   if (grp_set && mcast_sw_if_index == ~0)
12353     {
12354       errmsg ("tunnel nonexistent multicast device");
12355       return -99;
12356     }
12357   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12358     {
12359       errmsg ("tunnel dst address must be unicast");
12360       return -99;
12361     }
12362
12363
12364   if (ipv4_set && ipv6_set)
12365     {
12366       errmsg ("both IPv4 and IPv6 addresses specified");
12367       return -99;
12368     }
12369
12370   if ((vni == 0) || (vni >> 24))
12371     {
12372       errmsg ("vni not specified or out of range");
12373       return -99;
12374     }
12375
12376   M (VXLAN_ADD_DEL_TUNNEL, mp);
12377
12378   if (ipv6_set)
12379     {
12380       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12381       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12382     }
12383   else
12384     {
12385       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12386       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12387     }
12388   mp->encap_vrf_id = ntohl (encap_vrf_id);
12389   mp->decap_next_index = ntohl (decap_next_index);
12390   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12391   mp->vni = ntohl (vni);
12392   mp->is_add = is_add;
12393   mp->is_ipv6 = ipv6_set;
12394
12395   S (mp);
12396   W (ret);
12397   return ret;
12398 }
12399
12400 static void vl_api_vxlan_tunnel_details_t_handler
12401   (vl_api_vxlan_tunnel_details_t * mp)
12402 {
12403   vat_main_t *vam = &vat_main;
12404   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12405   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12406
12407   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12408          ntohl (mp->sw_if_index),
12409          format_ip46_address, &src, IP46_TYPE_ANY,
12410          format_ip46_address, &dst, IP46_TYPE_ANY,
12411          ntohl (mp->encap_vrf_id),
12412          ntohl (mp->decap_next_index), ntohl (mp->vni),
12413          ntohl (mp->mcast_sw_if_index));
12414 }
12415
12416 static void vl_api_vxlan_tunnel_details_t_handler_json
12417   (vl_api_vxlan_tunnel_details_t * mp)
12418 {
12419   vat_main_t *vam = &vat_main;
12420   vat_json_node_t *node = NULL;
12421
12422   if (VAT_JSON_ARRAY != vam->json_tree.type)
12423     {
12424       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12425       vat_json_init_array (&vam->json_tree);
12426     }
12427   node = vat_json_array_add (&vam->json_tree);
12428
12429   vat_json_init_object (node);
12430   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12431   if (mp->is_ipv6)
12432     {
12433       struct in6_addr ip6;
12434
12435       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12436       vat_json_object_add_ip6 (node, "src_address", ip6);
12437       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12438       vat_json_object_add_ip6 (node, "dst_address", ip6);
12439     }
12440   else
12441     {
12442       struct in_addr ip4;
12443
12444       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12445       vat_json_object_add_ip4 (node, "src_address", ip4);
12446       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12447       vat_json_object_add_ip4 (node, "dst_address", ip4);
12448     }
12449   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12450   vat_json_object_add_uint (node, "decap_next_index",
12451                             ntohl (mp->decap_next_index));
12452   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12453   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12454   vat_json_object_add_uint (node, "mcast_sw_if_index",
12455                             ntohl (mp->mcast_sw_if_index));
12456 }
12457
12458 static int
12459 api_vxlan_tunnel_dump (vat_main_t * vam)
12460 {
12461   unformat_input_t *i = vam->input;
12462   vl_api_vxlan_tunnel_dump_t *mp;
12463   vl_api_control_ping_t *mp_ping;
12464   u32 sw_if_index;
12465   u8 sw_if_index_set = 0;
12466   int ret;
12467
12468   /* Parse args required to build the message */
12469   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12470     {
12471       if (unformat (i, "sw_if_index %d", &sw_if_index))
12472         sw_if_index_set = 1;
12473       else
12474         break;
12475     }
12476
12477   if (sw_if_index_set == 0)
12478     {
12479       sw_if_index = ~0;
12480     }
12481
12482   if (!vam->json_output)
12483     {
12484       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12485              "sw_if_index", "src_address", "dst_address",
12486              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12487     }
12488
12489   /* Get list of vxlan-tunnel interfaces */
12490   M (VXLAN_TUNNEL_DUMP, mp);
12491
12492   mp->sw_if_index = htonl (sw_if_index);
12493
12494   S (mp);
12495
12496   /* Use a control ping for synchronization */
12497   MPING (CONTROL_PING, mp_ping);
12498   S (mp_ping);
12499
12500   W (ret);
12501   return ret;
12502 }
12503
12504 static uword unformat_geneve_decap_next
12505   (unformat_input_t * input, va_list * args)
12506 {
12507   u32 *result = va_arg (*args, u32 *);
12508   u32 tmp;
12509
12510   if (unformat (input, "l2"))
12511     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12512   else if (unformat (input, "%d", &tmp))
12513     *result = tmp;
12514   else
12515     return 0;
12516   return 1;
12517 }
12518
12519 static int
12520 api_geneve_add_del_tunnel (vat_main_t * vam)
12521 {
12522   unformat_input_t *line_input = vam->input;
12523   vl_api_geneve_add_del_tunnel_t *mp;
12524   ip46_address_t src, dst;
12525   u8 is_add = 1;
12526   u8 ipv4_set = 0, ipv6_set = 0;
12527   u8 src_set = 0;
12528   u8 dst_set = 0;
12529   u8 grp_set = 0;
12530   u32 mcast_sw_if_index = ~0;
12531   u32 encap_vrf_id = 0;
12532   u32 decap_next_index = ~0;
12533   u32 vni = 0;
12534   int ret;
12535
12536   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12537   memset (&src, 0, sizeof src);
12538   memset (&dst, 0, sizeof dst);
12539
12540   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12541     {
12542       if (unformat (line_input, "del"))
12543         is_add = 0;
12544       else
12545         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12546         {
12547           ipv4_set = 1;
12548           src_set = 1;
12549         }
12550       else
12551         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12552         {
12553           ipv4_set = 1;
12554           dst_set = 1;
12555         }
12556       else
12557         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12558         {
12559           ipv6_set = 1;
12560           src_set = 1;
12561         }
12562       else
12563         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12564         {
12565           ipv6_set = 1;
12566           dst_set = 1;
12567         }
12568       else if (unformat (line_input, "group %U %U",
12569                          unformat_ip4_address, &dst.ip4,
12570                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12571         {
12572           grp_set = dst_set = 1;
12573           ipv4_set = 1;
12574         }
12575       else if (unformat (line_input, "group %U",
12576                          unformat_ip4_address, &dst.ip4))
12577         {
12578           grp_set = dst_set = 1;
12579           ipv4_set = 1;
12580         }
12581       else if (unformat (line_input, "group %U %U",
12582                          unformat_ip6_address, &dst.ip6,
12583                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12584         {
12585           grp_set = dst_set = 1;
12586           ipv6_set = 1;
12587         }
12588       else if (unformat (line_input, "group %U",
12589                          unformat_ip6_address, &dst.ip6))
12590         {
12591           grp_set = dst_set = 1;
12592           ipv6_set = 1;
12593         }
12594       else
12595         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12596         ;
12597       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12598         ;
12599       else if (unformat (line_input, "decap-next %U",
12600                          unformat_geneve_decap_next, &decap_next_index))
12601         ;
12602       else if (unformat (line_input, "vni %d", &vni))
12603         ;
12604       else
12605         {
12606           errmsg ("parse error '%U'", format_unformat_error, line_input);
12607           return -99;
12608         }
12609     }
12610
12611   if (src_set == 0)
12612     {
12613       errmsg ("tunnel src address not specified");
12614       return -99;
12615     }
12616   if (dst_set == 0)
12617     {
12618       errmsg ("tunnel dst address not specified");
12619       return -99;
12620     }
12621
12622   if (grp_set && !ip46_address_is_multicast (&dst))
12623     {
12624       errmsg ("tunnel group address not multicast");
12625       return -99;
12626     }
12627   if (grp_set && mcast_sw_if_index == ~0)
12628     {
12629       errmsg ("tunnel nonexistent multicast device");
12630       return -99;
12631     }
12632   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12633     {
12634       errmsg ("tunnel dst address must be unicast");
12635       return -99;
12636     }
12637
12638
12639   if (ipv4_set && ipv6_set)
12640     {
12641       errmsg ("both IPv4 and IPv6 addresses specified");
12642       return -99;
12643     }
12644
12645   if ((vni == 0) || (vni >> 24))
12646     {
12647       errmsg ("vni not specified or out of range");
12648       return -99;
12649     }
12650
12651   M (GENEVE_ADD_DEL_TUNNEL, mp);
12652
12653   if (ipv6_set)
12654     {
12655       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12656       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12657     }
12658   else
12659     {
12660       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12661       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12662     }
12663   mp->encap_vrf_id = ntohl (encap_vrf_id);
12664   mp->decap_next_index = ntohl (decap_next_index);
12665   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12666   mp->vni = ntohl (vni);
12667   mp->is_add = is_add;
12668   mp->is_ipv6 = ipv6_set;
12669
12670   S (mp);
12671   W (ret);
12672   return ret;
12673 }
12674
12675 static void vl_api_geneve_tunnel_details_t_handler
12676   (vl_api_geneve_tunnel_details_t * mp)
12677 {
12678   vat_main_t *vam = &vat_main;
12679   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12680   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12681
12682   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12683          ntohl (mp->sw_if_index),
12684          format_ip46_address, &src, IP46_TYPE_ANY,
12685          format_ip46_address, &dst, IP46_TYPE_ANY,
12686          ntohl (mp->encap_vrf_id),
12687          ntohl (mp->decap_next_index), ntohl (mp->vni),
12688          ntohl (mp->mcast_sw_if_index));
12689 }
12690
12691 static void vl_api_geneve_tunnel_details_t_handler_json
12692   (vl_api_geneve_tunnel_details_t * mp)
12693 {
12694   vat_main_t *vam = &vat_main;
12695   vat_json_node_t *node = NULL;
12696
12697   if (VAT_JSON_ARRAY != vam->json_tree.type)
12698     {
12699       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12700       vat_json_init_array (&vam->json_tree);
12701     }
12702   node = vat_json_array_add (&vam->json_tree);
12703
12704   vat_json_init_object (node);
12705   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12706   if (mp->is_ipv6)
12707     {
12708       struct in6_addr ip6;
12709
12710       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12711       vat_json_object_add_ip6 (node, "src_address", ip6);
12712       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12713       vat_json_object_add_ip6 (node, "dst_address", ip6);
12714     }
12715   else
12716     {
12717       struct in_addr ip4;
12718
12719       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12720       vat_json_object_add_ip4 (node, "src_address", ip4);
12721       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12722       vat_json_object_add_ip4 (node, "dst_address", ip4);
12723     }
12724   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12725   vat_json_object_add_uint (node, "decap_next_index",
12726                             ntohl (mp->decap_next_index));
12727   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12728   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12729   vat_json_object_add_uint (node, "mcast_sw_if_index",
12730                             ntohl (mp->mcast_sw_if_index));
12731 }
12732
12733 static int
12734 api_geneve_tunnel_dump (vat_main_t * vam)
12735 {
12736   unformat_input_t *i = vam->input;
12737   vl_api_geneve_tunnel_dump_t *mp;
12738   vl_api_control_ping_t *mp_ping;
12739   u32 sw_if_index;
12740   u8 sw_if_index_set = 0;
12741   int ret;
12742
12743   /* Parse args required to build the message */
12744   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12745     {
12746       if (unformat (i, "sw_if_index %d", &sw_if_index))
12747         sw_if_index_set = 1;
12748       else
12749         break;
12750     }
12751
12752   if (sw_if_index_set == 0)
12753     {
12754       sw_if_index = ~0;
12755     }
12756
12757   if (!vam->json_output)
12758     {
12759       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12760              "sw_if_index", "local_address", "remote_address",
12761              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12762     }
12763
12764   /* Get list of geneve-tunnel interfaces */
12765   M (GENEVE_TUNNEL_DUMP, mp);
12766
12767   mp->sw_if_index = htonl (sw_if_index);
12768
12769   S (mp);
12770
12771   /* Use a control ping for synchronization */
12772   M (CONTROL_PING, mp_ping);
12773   S (mp_ping);
12774
12775   W (ret);
12776   return ret;
12777 }
12778
12779 static int
12780 api_gre_add_del_tunnel (vat_main_t * vam)
12781 {
12782   unformat_input_t *line_input = vam->input;
12783   vl_api_gre_add_del_tunnel_t *mp;
12784   ip4_address_t src4, dst4;
12785   ip6_address_t src6, dst6;
12786   u8 is_add = 1;
12787   u8 ipv4_set = 0;
12788   u8 ipv6_set = 0;
12789   u8 teb = 0;
12790   u8 src_set = 0;
12791   u8 dst_set = 0;
12792   u32 outer_fib_id = 0;
12793   int ret;
12794
12795   memset (&src4, 0, sizeof src4);
12796   memset (&dst4, 0, sizeof dst4);
12797   memset (&src6, 0, sizeof src6);
12798   memset (&dst6, 0, sizeof dst6);
12799
12800   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12801     {
12802       if (unformat (line_input, "del"))
12803         is_add = 0;
12804       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
12805         {
12806           src_set = 1;
12807           ipv4_set = 1;
12808         }
12809       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
12810         {
12811           dst_set = 1;
12812           ipv4_set = 1;
12813         }
12814       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
12815         {
12816           src_set = 1;
12817           ipv6_set = 1;
12818         }
12819       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
12820         {
12821           dst_set = 1;
12822           ipv6_set = 1;
12823         }
12824       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
12825         ;
12826       else if (unformat (line_input, "teb"))
12827         teb = 1;
12828       else
12829         {
12830           errmsg ("parse error '%U'", format_unformat_error, line_input);
12831           return -99;
12832         }
12833     }
12834
12835   if (src_set == 0)
12836     {
12837       errmsg ("tunnel src address not specified");
12838       return -99;
12839     }
12840   if (dst_set == 0)
12841     {
12842       errmsg ("tunnel dst address not specified");
12843       return -99;
12844     }
12845   if (ipv4_set && ipv6_set)
12846     {
12847       errmsg ("both IPv4 and IPv6 addresses specified");
12848       return -99;
12849     }
12850
12851
12852   M (GRE_ADD_DEL_TUNNEL, mp);
12853
12854   if (ipv4_set)
12855     {
12856       clib_memcpy (&mp->src_address, &src4, 4);
12857       clib_memcpy (&mp->dst_address, &dst4, 4);
12858     }
12859   else
12860     {
12861       clib_memcpy (&mp->src_address, &src6, 16);
12862       clib_memcpy (&mp->dst_address, &dst6, 16);
12863     }
12864   mp->outer_fib_id = ntohl (outer_fib_id);
12865   mp->is_add = is_add;
12866   mp->teb = teb;
12867   mp->is_ipv6 = ipv6_set;
12868
12869   S (mp);
12870   W (ret);
12871   return ret;
12872 }
12873
12874 static void vl_api_gre_tunnel_details_t_handler
12875   (vl_api_gre_tunnel_details_t * mp)
12876 {
12877   vat_main_t *vam = &vat_main;
12878   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
12879   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
12880
12881   print (vam->ofp, "%11d%24U%24U%6d%14d",
12882          ntohl (mp->sw_if_index),
12883          format_ip46_address, &src, IP46_TYPE_ANY,
12884          format_ip46_address, &dst, IP46_TYPE_ANY,
12885          mp->teb, ntohl (mp->outer_fib_id));
12886 }
12887
12888 static void vl_api_gre_tunnel_details_t_handler_json
12889   (vl_api_gre_tunnel_details_t * mp)
12890 {
12891   vat_main_t *vam = &vat_main;
12892   vat_json_node_t *node = NULL;
12893   struct in_addr ip4;
12894   struct in6_addr ip6;
12895
12896   if (VAT_JSON_ARRAY != vam->json_tree.type)
12897     {
12898       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12899       vat_json_init_array (&vam->json_tree);
12900     }
12901   node = vat_json_array_add (&vam->json_tree);
12902
12903   vat_json_init_object (node);
12904   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12905   if (!mp->is_ipv6)
12906     {
12907       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
12908       vat_json_object_add_ip4 (node, "src_address", ip4);
12909       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
12910       vat_json_object_add_ip4 (node, "dst_address", ip4);
12911     }
12912   else
12913     {
12914       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
12915       vat_json_object_add_ip6 (node, "src_address", ip6);
12916       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
12917       vat_json_object_add_ip6 (node, "dst_address", ip6);
12918     }
12919   vat_json_object_add_uint (node, "teb", mp->teb);
12920   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
12921   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
12922 }
12923
12924 static int
12925 api_gre_tunnel_dump (vat_main_t * vam)
12926 {
12927   unformat_input_t *i = vam->input;
12928   vl_api_gre_tunnel_dump_t *mp;
12929   vl_api_control_ping_t *mp_ping;
12930   u32 sw_if_index;
12931   u8 sw_if_index_set = 0;
12932   int ret;
12933
12934   /* Parse args required to build the message */
12935   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12936     {
12937       if (unformat (i, "sw_if_index %d", &sw_if_index))
12938         sw_if_index_set = 1;
12939       else
12940         break;
12941     }
12942
12943   if (sw_if_index_set == 0)
12944     {
12945       sw_if_index = ~0;
12946     }
12947
12948   if (!vam->json_output)
12949     {
12950       print (vam->ofp, "%11s%24s%24s%6s%14s",
12951              "sw_if_index", "src_address", "dst_address", "teb",
12952              "outer_fib_id");
12953     }
12954
12955   /* Get list of gre-tunnel interfaces */
12956   M (GRE_TUNNEL_DUMP, mp);
12957
12958   mp->sw_if_index = htonl (sw_if_index);
12959
12960   S (mp);
12961
12962   /* Use a control ping for synchronization */
12963   MPING (CONTROL_PING, mp_ping);
12964   S (mp_ping);
12965
12966   W (ret);
12967   return ret;
12968 }
12969
12970 static int
12971 api_l2_fib_clear_table (vat_main_t * vam)
12972 {
12973 //  unformat_input_t * i = vam->input;
12974   vl_api_l2_fib_clear_table_t *mp;
12975   int ret;
12976
12977   M (L2_FIB_CLEAR_TABLE, mp);
12978
12979   S (mp);
12980   W (ret);
12981   return ret;
12982 }
12983
12984 static int
12985 api_l2_interface_efp_filter (vat_main_t * vam)
12986 {
12987   unformat_input_t *i = vam->input;
12988   vl_api_l2_interface_efp_filter_t *mp;
12989   u32 sw_if_index;
12990   u8 enable = 1;
12991   u8 sw_if_index_set = 0;
12992   int ret;
12993
12994   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12995     {
12996       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12997         sw_if_index_set = 1;
12998       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12999         sw_if_index_set = 1;
13000       else if (unformat (i, "enable"))
13001         enable = 1;
13002       else if (unformat (i, "disable"))
13003         enable = 0;
13004       else
13005         {
13006           clib_warning ("parse error '%U'", format_unformat_error, i);
13007           return -99;
13008         }
13009     }
13010
13011   if (sw_if_index_set == 0)
13012     {
13013       errmsg ("missing sw_if_index");
13014       return -99;
13015     }
13016
13017   M (L2_INTERFACE_EFP_FILTER, mp);
13018
13019   mp->sw_if_index = ntohl (sw_if_index);
13020   mp->enable_disable = enable;
13021
13022   S (mp);
13023   W (ret);
13024   return ret;
13025 }
13026
13027 #define foreach_vtr_op                          \
13028 _("disable",  L2_VTR_DISABLED)                  \
13029 _("push-1",  L2_VTR_PUSH_1)                     \
13030 _("push-2",  L2_VTR_PUSH_2)                     \
13031 _("pop-1",  L2_VTR_POP_1)                       \
13032 _("pop-2",  L2_VTR_POP_2)                       \
13033 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
13034 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
13035 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
13036 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
13037
13038 static int
13039 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
13040 {
13041   unformat_input_t *i = vam->input;
13042   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
13043   u32 sw_if_index;
13044   u8 sw_if_index_set = 0;
13045   u8 vtr_op_set = 0;
13046   u32 vtr_op = 0;
13047   u32 push_dot1q = 1;
13048   u32 tag1 = ~0;
13049   u32 tag2 = ~0;
13050   int ret;
13051
13052   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13053     {
13054       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13055         sw_if_index_set = 1;
13056       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13057         sw_if_index_set = 1;
13058       else if (unformat (i, "vtr_op %d", &vtr_op))
13059         vtr_op_set = 1;
13060 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
13061       foreach_vtr_op
13062 #undef _
13063         else if (unformat (i, "push_dot1q %d", &push_dot1q))
13064         ;
13065       else if (unformat (i, "tag1 %d", &tag1))
13066         ;
13067       else if (unformat (i, "tag2 %d", &tag2))
13068         ;
13069       else
13070         {
13071           clib_warning ("parse error '%U'", format_unformat_error, i);
13072           return -99;
13073         }
13074     }
13075
13076   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
13077     {
13078       errmsg ("missing vtr operation or sw_if_index");
13079       return -99;
13080     }
13081
13082   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
13083   mp->sw_if_index = ntohl (sw_if_index);
13084   mp->vtr_op = ntohl (vtr_op);
13085   mp->push_dot1q = ntohl (push_dot1q);
13086   mp->tag1 = ntohl (tag1);
13087   mp->tag2 = ntohl (tag2);
13088
13089   S (mp);
13090   W (ret);
13091   return ret;
13092 }
13093
13094 static int
13095 api_create_vhost_user_if (vat_main_t * vam)
13096 {
13097   unformat_input_t *i = vam->input;
13098   vl_api_create_vhost_user_if_t *mp;
13099   u8 *file_name;
13100   u8 is_server = 0;
13101   u8 file_name_set = 0;
13102   u32 custom_dev_instance = ~0;
13103   u8 hwaddr[6];
13104   u8 use_custom_mac = 0;
13105   u8 *tag = 0;
13106   int ret;
13107
13108   /* Shut up coverity */
13109   memset (hwaddr, 0, sizeof (hwaddr));
13110
13111   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13112     {
13113       if (unformat (i, "socket %s", &file_name))
13114         {
13115           file_name_set = 1;
13116         }
13117       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13118         ;
13119       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
13120         use_custom_mac = 1;
13121       else if (unformat (i, "server"))
13122         is_server = 1;
13123       else if (unformat (i, "tag %s", &tag))
13124         ;
13125       else
13126         break;
13127     }
13128
13129   if (file_name_set == 0)
13130     {
13131       errmsg ("missing socket file name");
13132       return -99;
13133     }
13134
13135   if (vec_len (file_name) > 255)
13136     {
13137       errmsg ("socket file name too long");
13138       return -99;
13139     }
13140   vec_add1 (file_name, 0);
13141
13142   M (CREATE_VHOST_USER_IF, mp);
13143
13144   mp->is_server = is_server;
13145   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13146   vec_free (file_name);
13147   if (custom_dev_instance != ~0)
13148     {
13149       mp->renumber = 1;
13150       mp->custom_dev_instance = ntohl (custom_dev_instance);
13151     }
13152   mp->use_custom_mac = use_custom_mac;
13153   clib_memcpy (mp->mac_address, hwaddr, 6);
13154   if (tag)
13155     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13156   vec_free (tag);
13157
13158   S (mp);
13159   W (ret);
13160   return ret;
13161 }
13162
13163 static int
13164 api_modify_vhost_user_if (vat_main_t * vam)
13165 {
13166   unformat_input_t *i = vam->input;
13167   vl_api_modify_vhost_user_if_t *mp;
13168   u8 *file_name;
13169   u8 is_server = 0;
13170   u8 file_name_set = 0;
13171   u32 custom_dev_instance = ~0;
13172   u8 sw_if_index_set = 0;
13173   u32 sw_if_index = (u32) ~ 0;
13174   int ret;
13175
13176   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13177     {
13178       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13179         sw_if_index_set = 1;
13180       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13181         sw_if_index_set = 1;
13182       else if (unformat (i, "socket %s", &file_name))
13183         {
13184           file_name_set = 1;
13185         }
13186       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13187         ;
13188       else if (unformat (i, "server"))
13189         is_server = 1;
13190       else
13191         break;
13192     }
13193
13194   if (sw_if_index_set == 0)
13195     {
13196       errmsg ("missing sw_if_index or interface name");
13197       return -99;
13198     }
13199
13200   if (file_name_set == 0)
13201     {
13202       errmsg ("missing socket file name");
13203       return -99;
13204     }
13205
13206   if (vec_len (file_name) > 255)
13207     {
13208       errmsg ("socket file name too long");
13209       return -99;
13210     }
13211   vec_add1 (file_name, 0);
13212
13213   M (MODIFY_VHOST_USER_IF, mp);
13214
13215   mp->sw_if_index = ntohl (sw_if_index);
13216   mp->is_server = is_server;
13217   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13218   vec_free (file_name);
13219   if (custom_dev_instance != ~0)
13220     {
13221       mp->renumber = 1;
13222       mp->custom_dev_instance = ntohl (custom_dev_instance);
13223     }
13224
13225   S (mp);
13226   W (ret);
13227   return ret;
13228 }
13229
13230 static int
13231 api_delete_vhost_user_if (vat_main_t * vam)
13232 {
13233   unformat_input_t *i = vam->input;
13234   vl_api_delete_vhost_user_if_t *mp;
13235   u32 sw_if_index = ~0;
13236   u8 sw_if_index_set = 0;
13237   int ret;
13238
13239   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13240     {
13241       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13242         sw_if_index_set = 1;
13243       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13244         sw_if_index_set = 1;
13245       else
13246         break;
13247     }
13248
13249   if (sw_if_index_set == 0)
13250     {
13251       errmsg ("missing sw_if_index or interface name");
13252       return -99;
13253     }
13254
13255
13256   M (DELETE_VHOST_USER_IF, mp);
13257
13258   mp->sw_if_index = ntohl (sw_if_index);
13259
13260   S (mp);
13261   W (ret);
13262   return ret;
13263 }
13264
13265 static void vl_api_sw_interface_vhost_user_details_t_handler
13266   (vl_api_sw_interface_vhost_user_details_t * mp)
13267 {
13268   vat_main_t *vam = &vat_main;
13269
13270   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13271          (char *) mp->interface_name,
13272          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13273          clib_net_to_host_u64 (mp->features), mp->is_server,
13274          ntohl (mp->num_regions), (char *) mp->sock_filename);
13275   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13276 }
13277
13278 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13279   (vl_api_sw_interface_vhost_user_details_t * mp)
13280 {
13281   vat_main_t *vam = &vat_main;
13282   vat_json_node_t *node = NULL;
13283
13284   if (VAT_JSON_ARRAY != vam->json_tree.type)
13285     {
13286       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13287       vat_json_init_array (&vam->json_tree);
13288     }
13289   node = vat_json_array_add (&vam->json_tree);
13290
13291   vat_json_init_object (node);
13292   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13293   vat_json_object_add_string_copy (node, "interface_name",
13294                                    mp->interface_name);
13295   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13296                             ntohl (mp->virtio_net_hdr_sz));
13297   vat_json_object_add_uint (node, "features",
13298                             clib_net_to_host_u64 (mp->features));
13299   vat_json_object_add_uint (node, "is_server", mp->is_server);
13300   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13301   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13302   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13303 }
13304
13305 static int
13306 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13307 {
13308   vl_api_sw_interface_vhost_user_dump_t *mp;
13309   vl_api_control_ping_t *mp_ping;
13310   int ret;
13311   print (vam->ofp,
13312          "Interface name            idx hdr_sz features server regions filename");
13313
13314   /* Get list of vhost-user interfaces */
13315   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13316   S (mp);
13317
13318   /* Use a control ping for synchronization */
13319   MPING (CONTROL_PING, mp_ping);
13320   S (mp_ping);
13321
13322   W (ret);
13323   return ret;
13324 }
13325
13326 static int
13327 api_show_version (vat_main_t * vam)
13328 {
13329   vl_api_show_version_t *mp;
13330   int ret;
13331
13332   M (SHOW_VERSION, mp);
13333
13334   S (mp);
13335   W (ret);
13336   return ret;
13337 }
13338
13339
13340 static int
13341 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13342 {
13343   unformat_input_t *line_input = vam->input;
13344   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13345   ip4_address_t local4, remote4;
13346   ip6_address_t local6, remote6;
13347   u8 is_add = 1;
13348   u8 ipv4_set = 0, ipv6_set = 0;
13349   u8 local_set = 0;
13350   u8 remote_set = 0;
13351   u8 grp_set = 0;
13352   u32 mcast_sw_if_index = ~0;
13353   u32 encap_vrf_id = 0;
13354   u32 decap_vrf_id = 0;
13355   u8 protocol = ~0;
13356   u32 vni;
13357   u8 vni_set = 0;
13358   int ret;
13359
13360   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13361   memset (&local4, 0, sizeof local4);
13362   memset (&remote4, 0, sizeof remote4);
13363   memset (&local6, 0, sizeof local6);
13364   memset (&remote6, 0, sizeof remote6);
13365
13366   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13367     {
13368       if (unformat (line_input, "del"))
13369         is_add = 0;
13370       else if (unformat (line_input, "local %U",
13371                          unformat_ip4_address, &local4))
13372         {
13373           local_set = 1;
13374           ipv4_set = 1;
13375         }
13376       else if (unformat (line_input, "remote %U",
13377                          unformat_ip4_address, &remote4))
13378         {
13379           remote_set = 1;
13380           ipv4_set = 1;
13381         }
13382       else if (unformat (line_input, "local %U",
13383                          unformat_ip6_address, &local6))
13384         {
13385           local_set = 1;
13386           ipv6_set = 1;
13387         }
13388       else if (unformat (line_input, "remote %U",
13389                          unformat_ip6_address, &remote6))
13390         {
13391           remote_set = 1;
13392           ipv6_set = 1;
13393         }
13394       else if (unformat (line_input, "group %U %U",
13395                          unformat_ip4_address, &remote4,
13396                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13397         {
13398           grp_set = remote_set = 1;
13399           ipv4_set = 1;
13400         }
13401       else if (unformat (line_input, "group %U",
13402                          unformat_ip4_address, &remote4))
13403         {
13404           grp_set = remote_set = 1;
13405           ipv4_set = 1;
13406         }
13407       else if (unformat (line_input, "group %U %U",
13408                          unformat_ip6_address, &remote6,
13409                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13410         {
13411           grp_set = remote_set = 1;
13412           ipv6_set = 1;
13413         }
13414       else if (unformat (line_input, "group %U",
13415                          unformat_ip6_address, &remote6))
13416         {
13417           grp_set = remote_set = 1;
13418           ipv6_set = 1;
13419         }
13420       else
13421         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13422         ;
13423       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13424         ;
13425       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13426         ;
13427       else if (unformat (line_input, "vni %d", &vni))
13428         vni_set = 1;
13429       else if (unformat (line_input, "next-ip4"))
13430         protocol = 1;
13431       else if (unformat (line_input, "next-ip6"))
13432         protocol = 2;
13433       else if (unformat (line_input, "next-ethernet"))
13434         protocol = 3;
13435       else if (unformat (line_input, "next-nsh"))
13436         protocol = 4;
13437       else
13438         {
13439           errmsg ("parse error '%U'", format_unformat_error, line_input);
13440           return -99;
13441         }
13442     }
13443
13444   if (local_set == 0)
13445     {
13446       errmsg ("tunnel local address not specified");
13447       return -99;
13448     }
13449   if (remote_set == 0)
13450     {
13451       errmsg ("tunnel remote address not specified");
13452       return -99;
13453     }
13454   if (grp_set && mcast_sw_if_index == ~0)
13455     {
13456       errmsg ("tunnel nonexistent multicast device");
13457       return -99;
13458     }
13459   if (ipv4_set && ipv6_set)
13460     {
13461       errmsg ("both IPv4 and IPv6 addresses specified");
13462       return -99;
13463     }
13464
13465   if (vni_set == 0)
13466     {
13467       errmsg ("vni not specified");
13468       return -99;
13469     }
13470
13471   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13472
13473
13474   if (ipv6_set)
13475     {
13476       clib_memcpy (&mp->local, &local6, sizeof (local6));
13477       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13478     }
13479   else
13480     {
13481       clib_memcpy (&mp->local, &local4, sizeof (local4));
13482       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13483     }
13484
13485   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13486   mp->encap_vrf_id = ntohl (encap_vrf_id);
13487   mp->decap_vrf_id = ntohl (decap_vrf_id);
13488   mp->protocol = protocol;
13489   mp->vni = ntohl (vni);
13490   mp->is_add = is_add;
13491   mp->is_ipv6 = ipv6_set;
13492
13493   S (mp);
13494   W (ret);
13495   return ret;
13496 }
13497
13498 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13499   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13500 {
13501   vat_main_t *vam = &vat_main;
13502   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13503   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13504
13505   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13506          ntohl (mp->sw_if_index),
13507          format_ip46_address, &local, IP46_TYPE_ANY,
13508          format_ip46_address, &remote, IP46_TYPE_ANY,
13509          ntohl (mp->vni), mp->protocol,
13510          ntohl (mp->mcast_sw_if_index),
13511          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13512 }
13513
13514
13515 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13516   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13517 {
13518   vat_main_t *vam = &vat_main;
13519   vat_json_node_t *node = NULL;
13520   struct in_addr ip4;
13521   struct in6_addr ip6;
13522
13523   if (VAT_JSON_ARRAY != vam->json_tree.type)
13524     {
13525       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13526       vat_json_init_array (&vam->json_tree);
13527     }
13528   node = vat_json_array_add (&vam->json_tree);
13529
13530   vat_json_init_object (node);
13531   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13532   if (mp->is_ipv6)
13533     {
13534       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13535       vat_json_object_add_ip6 (node, "local", ip6);
13536       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13537       vat_json_object_add_ip6 (node, "remote", ip6);
13538     }
13539   else
13540     {
13541       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13542       vat_json_object_add_ip4 (node, "local", ip4);
13543       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13544       vat_json_object_add_ip4 (node, "remote", ip4);
13545     }
13546   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13547   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13548   vat_json_object_add_uint (node, "mcast_sw_if_index",
13549                             ntohl (mp->mcast_sw_if_index));
13550   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13551   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13552   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13553 }
13554
13555 static int
13556 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13557 {
13558   unformat_input_t *i = vam->input;
13559   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13560   vl_api_control_ping_t *mp_ping;
13561   u32 sw_if_index;
13562   u8 sw_if_index_set = 0;
13563   int ret;
13564
13565   /* Parse args required to build the message */
13566   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13567     {
13568       if (unformat (i, "sw_if_index %d", &sw_if_index))
13569         sw_if_index_set = 1;
13570       else
13571         break;
13572     }
13573
13574   if (sw_if_index_set == 0)
13575     {
13576       sw_if_index = ~0;
13577     }
13578
13579   if (!vam->json_output)
13580     {
13581       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13582              "sw_if_index", "local", "remote", "vni",
13583              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13584     }
13585
13586   /* Get list of vxlan-tunnel interfaces */
13587   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13588
13589   mp->sw_if_index = htonl (sw_if_index);
13590
13591   S (mp);
13592
13593   /* Use a control ping for synchronization */
13594   MPING (CONTROL_PING, mp_ping);
13595   S (mp_ping);
13596
13597   W (ret);
13598   return ret;
13599 }
13600
13601 static void vl_api_l2_fib_table_details_t_handler
13602   (vl_api_l2_fib_table_details_t * mp)
13603 {
13604   vat_main_t *vam = &vat_main;
13605
13606   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13607          "       %d       %d     %d",
13608          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13609          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13610          mp->bvi_mac);
13611 }
13612
13613 static void vl_api_l2_fib_table_details_t_handler_json
13614   (vl_api_l2_fib_table_details_t * mp)
13615 {
13616   vat_main_t *vam = &vat_main;
13617   vat_json_node_t *node = NULL;
13618
13619   if (VAT_JSON_ARRAY != vam->json_tree.type)
13620     {
13621       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13622       vat_json_init_array (&vam->json_tree);
13623     }
13624   node = vat_json_array_add (&vam->json_tree);
13625
13626   vat_json_init_object (node);
13627   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13628   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13629   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13630   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13631   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13632   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13633 }
13634
13635 static int
13636 api_l2_fib_table_dump (vat_main_t * vam)
13637 {
13638   unformat_input_t *i = vam->input;
13639   vl_api_l2_fib_table_dump_t *mp;
13640   vl_api_control_ping_t *mp_ping;
13641   u32 bd_id;
13642   u8 bd_id_set = 0;
13643   int ret;
13644
13645   /* Parse args required to build the message */
13646   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13647     {
13648       if (unformat (i, "bd_id %d", &bd_id))
13649         bd_id_set = 1;
13650       else
13651         break;
13652     }
13653
13654   if (bd_id_set == 0)
13655     {
13656       errmsg ("missing bridge domain");
13657       return -99;
13658     }
13659
13660   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13661
13662   /* Get list of l2 fib entries */
13663   M (L2_FIB_TABLE_DUMP, mp);
13664
13665   mp->bd_id = ntohl (bd_id);
13666   S (mp);
13667
13668   /* Use a control ping for synchronization */
13669   MPING (CONTROL_PING, mp_ping);
13670   S (mp_ping);
13671
13672   W (ret);
13673   return ret;
13674 }
13675
13676
13677 static int
13678 api_interface_name_renumber (vat_main_t * vam)
13679 {
13680   unformat_input_t *line_input = vam->input;
13681   vl_api_interface_name_renumber_t *mp;
13682   u32 sw_if_index = ~0;
13683   u32 new_show_dev_instance = ~0;
13684   int ret;
13685
13686   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13687     {
13688       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13689                     &sw_if_index))
13690         ;
13691       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13692         ;
13693       else if (unformat (line_input, "new_show_dev_instance %d",
13694                          &new_show_dev_instance))
13695         ;
13696       else
13697         break;
13698     }
13699
13700   if (sw_if_index == ~0)
13701     {
13702       errmsg ("missing interface name or sw_if_index");
13703       return -99;
13704     }
13705
13706   if (new_show_dev_instance == ~0)
13707     {
13708       errmsg ("missing new_show_dev_instance");
13709       return -99;
13710     }
13711
13712   M (INTERFACE_NAME_RENUMBER, mp);
13713
13714   mp->sw_if_index = ntohl (sw_if_index);
13715   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13716
13717   S (mp);
13718   W (ret);
13719   return ret;
13720 }
13721
13722 static int
13723 api_want_ip4_arp_events (vat_main_t * vam)
13724 {
13725   unformat_input_t *line_input = vam->input;
13726   vl_api_want_ip4_arp_events_t *mp;
13727   ip4_address_t address;
13728   int address_set = 0;
13729   u32 enable_disable = 1;
13730   int ret;
13731
13732   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13733     {
13734       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
13735         address_set = 1;
13736       else if (unformat (line_input, "del"))
13737         enable_disable = 0;
13738       else
13739         break;
13740     }
13741
13742   if (address_set == 0)
13743     {
13744       errmsg ("missing addresses");
13745       return -99;
13746     }
13747
13748   M (WANT_IP4_ARP_EVENTS, mp);
13749   mp->enable_disable = enable_disable;
13750   mp->pid = htonl (getpid ());
13751   mp->address = address.as_u32;
13752
13753   S (mp);
13754   W (ret);
13755   return ret;
13756 }
13757
13758 static int
13759 api_want_ip6_nd_events (vat_main_t * vam)
13760 {
13761   unformat_input_t *line_input = vam->input;
13762   vl_api_want_ip6_nd_events_t *mp;
13763   ip6_address_t address;
13764   int address_set = 0;
13765   u32 enable_disable = 1;
13766   int ret;
13767
13768   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13769     {
13770       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
13771         address_set = 1;
13772       else if (unformat (line_input, "del"))
13773         enable_disable = 0;
13774       else
13775         break;
13776     }
13777
13778   if (address_set == 0)
13779     {
13780       errmsg ("missing addresses");
13781       return -99;
13782     }
13783
13784   M (WANT_IP6_ND_EVENTS, mp);
13785   mp->enable_disable = enable_disable;
13786   mp->pid = htonl (getpid ());
13787   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
13788
13789   S (mp);
13790   W (ret);
13791   return ret;
13792 }
13793
13794 static int
13795 api_want_l2_macs_events (vat_main_t * vam)
13796 {
13797   unformat_input_t *line_input = vam->input;
13798   vl_api_want_l2_macs_events_t *mp;
13799   u8 enable_disable = 1;
13800   u32 scan_delay = 0;
13801   u32 max_macs_in_event = 0;
13802   u32 learn_limit = 0;
13803   int ret;
13804
13805   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13806     {
13807       if (unformat (line_input, "learn-limit %d", &learn_limit))
13808         ;
13809       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13810         ;
13811       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13812         ;
13813       else if (unformat (line_input, "disable"))
13814         enable_disable = 0;
13815       else
13816         break;
13817     }
13818
13819   M (WANT_L2_MACS_EVENTS, mp);
13820   mp->enable_disable = enable_disable;
13821   mp->pid = htonl (getpid ());
13822   mp->learn_limit = htonl (learn_limit);
13823   mp->scan_delay = (u8) scan_delay;
13824   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13825   S (mp);
13826   W (ret);
13827   return ret;
13828 }
13829
13830 static int
13831 api_input_acl_set_interface (vat_main_t * vam)
13832 {
13833   unformat_input_t *i = vam->input;
13834   vl_api_input_acl_set_interface_t *mp;
13835   u32 sw_if_index;
13836   int sw_if_index_set;
13837   u32 ip4_table_index = ~0;
13838   u32 ip6_table_index = ~0;
13839   u32 l2_table_index = ~0;
13840   u8 is_add = 1;
13841   int ret;
13842
13843   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13844     {
13845       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13846         sw_if_index_set = 1;
13847       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13848         sw_if_index_set = 1;
13849       else if (unformat (i, "del"))
13850         is_add = 0;
13851       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13852         ;
13853       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13854         ;
13855       else if (unformat (i, "l2-table %d", &l2_table_index))
13856         ;
13857       else
13858         {
13859           clib_warning ("parse error '%U'", format_unformat_error, i);
13860           return -99;
13861         }
13862     }
13863
13864   if (sw_if_index_set == 0)
13865     {
13866       errmsg ("missing interface name or sw_if_index");
13867       return -99;
13868     }
13869
13870   M (INPUT_ACL_SET_INTERFACE, mp);
13871
13872   mp->sw_if_index = ntohl (sw_if_index);
13873   mp->ip4_table_index = ntohl (ip4_table_index);
13874   mp->ip6_table_index = ntohl (ip6_table_index);
13875   mp->l2_table_index = ntohl (l2_table_index);
13876   mp->is_add = is_add;
13877
13878   S (mp);
13879   W (ret);
13880   return ret;
13881 }
13882
13883 static int
13884 api_ip_address_dump (vat_main_t * vam)
13885 {
13886   unformat_input_t *i = vam->input;
13887   vl_api_ip_address_dump_t *mp;
13888   vl_api_control_ping_t *mp_ping;
13889   u32 sw_if_index = ~0;
13890   u8 sw_if_index_set = 0;
13891   u8 ipv4_set = 0;
13892   u8 ipv6_set = 0;
13893   int ret;
13894
13895   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13896     {
13897       if (unformat (i, "sw_if_index %d", &sw_if_index))
13898         sw_if_index_set = 1;
13899       else
13900         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13901         sw_if_index_set = 1;
13902       else if (unformat (i, "ipv4"))
13903         ipv4_set = 1;
13904       else if (unformat (i, "ipv6"))
13905         ipv6_set = 1;
13906       else
13907         break;
13908     }
13909
13910   if (ipv4_set && ipv6_set)
13911     {
13912       errmsg ("ipv4 and ipv6 flags cannot be both set");
13913       return -99;
13914     }
13915
13916   if ((!ipv4_set) && (!ipv6_set))
13917     {
13918       errmsg ("no ipv4 nor ipv6 flag 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   vam->current_sw_if_index = sw_if_index;
13929   vam->is_ipv6 = ipv6_set;
13930
13931   M (IP_ADDRESS_DUMP, mp);
13932   mp->sw_if_index = ntohl (sw_if_index);
13933   mp->is_ipv6 = ipv6_set;
13934   S (mp);
13935
13936   /* Use a control ping for synchronization */
13937   MPING (CONTROL_PING, mp_ping);
13938   S (mp_ping);
13939
13940   W (ret);
13941   return ret;
13942 }
13943
13944 static int
13945 api_ip_dump (vat_main_t * vam)
13946 {
13947   vl_api_ip_dump_t *mp;
13948   vl_api_control_ping_t *mp_ping;
13949   unformat_input_t *in = vam->input;
13950   int ipv4_set = 0;
13951   int ipv6_set = 0;
13952   int is_ipv6;
13953   int i;
13954   int ret;
13955
13956   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13957     {
13958       if (unformat (in, "ipv4"))
13959         ipv4_set = 1;
13960       else if (unformat (in, "ipv6"))
13961         ipv6_set = 1;
13962       else
13963         break;
13964     }
13965
13966   if (ipv4_set && ipv6_set)
13967     {
13968       errmsg ("ipv4 and ipv6 flags cannot be both set");
13969       return -99;
13970     }
13971
13972   if ((!ipv4_set) && (!ipv6_set))
13973     {
13974       errmsg ("no ipv4 nor ipv6 flag set");
13975       return -99;
13976     }
13977
13978   is_ipv6 = ipv6_set;
13979   vam->is_ipv6 = is_ipv6;
13980
13981   /* free old data */
13982   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13983     {
13984       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13985     }
13986   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13987
13988   M (IP_DUMP, mp);
13989   mp->is_ipv6 = ipv6_set;
13990   S (mp);
13991
13992   /* Use a control ping for synchronization */
13993   MPING (CONTROL_PING, mp_ping);
13994   S (mp_ping);
13995
13996   W (ret);
13997   return ret;
13998 }
13999
14000 static int
14001 api_ipsec_spd_add_del (vat_main_t * vam)
14002 {
14003   unformat_input_t *i = vam->input;
14004   vl_api_ipsec_spd_add_del_t *mp;
14005   u32 spd_id = ~0;
14006   u8 is_add = 1;
14007   int ret;
14008
14009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14010     {
14011       if (unformat (i, "spd_id %d", &spd_id))
14012         ;
14013       else if (unformat (i, "del"))
14014         is_add = 0;
14015       else
14016         {
14017           clib_warning ("parse error '%U'", format_unformat_error, i);
14018           return -99;
14019         }
14020     }
14021   if (spd_id == ~0)
14022     {
14023       errmsg ("spd_id must be set");
14024       return -99;
14025     }
14026
14027   M (IPSEC_SPD_ADD_DEL, mp);
14028
14029   mp->spd_id = ntohl (spd_id);
14030   mp->is_add = is_add;
14031
14032   S (mp);
14033   W (ret);
14034   return ret;
14035 }
14036
14037 static int
14038 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14039 {
14040   unformat_input_t *i = vam->input;
14041   vl_api_ipsec_interface_add_del_spd_t *mp;
14042   u32 sw_if_index;
14043   u8 sw_if_index_set = 0;
14044   u32 spd_id = (u32) ~ 0;
14045   u8 is_add = 1;
14046   int ret;
14047
14048   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14049     {
14050       if (unformat (i, "del"))
14051         is_add = 0;
14052       else if (unformat (i, "spd_id %d", &spd_id))
14053         ;
14054       else
14055         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14056         sw_if_index_set = 1;
14057       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14058         sw_if_index_set = 1;
14059       else
14060         {
14061           clib_warning ("parse error '%U'", format_unformat_error, i);
14062           return -99;
14063         }
14064
14065     }
14066
14067   if (spd_id == (u32) ~ 0)
14068     {
14069       errmsg ("spd_id must be set");
14070       return -99;
14071     }
14072
14073   if (sw_if_index_set == 0)
14074     {
14075       errmsg ("missing interface name or sw_if_index");
14076       return -99;
14077     }
14078
14079   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14080
14081   mp->spd_id = ntohl (spd_id);
14082   mp->sw_if_index = ntohl (sw_if_index);
14083   mp->is_add = is_add;
14084
14085   S (mp);
14086   W (ret);
14087   return ret;
14088 }
14089
14090 static int
14091 api_ipsec_spd_add_del_entry (vat_main_t * vam)
14092 {
14093   unformat_input_t *i = vam->input;
14094   vl_api_ipsec_spd_add_del_entry_t *mp;
14095   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
14096   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14097   i32 priority = 0;
14098   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14099   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14100   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
14101   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
14102   int ret;
14103
14104   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
14105   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
14106   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
14107   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
14108   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
14109   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
14110
14111   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14112     {
14113       if (unformat (i, "del"))
14114         is_add = 0;
14115       if (unformat (i, "outbound"))
14116         is_outbound = 1;
14117       if (unformat (i, "inbound"))
14118         is_outbound = 0;
14119       else if (unformat (i, "spd_id %d", &spd_id))
14120         ;
14121       else if (unformat (i, "sa_id %d", &sa_id))
14122         ;
14123       else if (unformat (i, "priority %d", &priority))
14124         ;
14125       else if (unformat (i, "protocol %d", &protocol))
14126         ;
14127       else if (unformat (i, "lport_start %d", &lport_start))
14128         ;
14129       else if (unformat (i, "lport_stop %d", &lport_stop))
14130         ;
14131       else if (unformat (i, "rport_start %d", &rport_start))
14132         ;
14133       else if (unformat (i, "rport_stop %d", &rport_stop))
14134         ;
14135       else
14136         if (unformat
14137             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
14138         {
14139           is_ipv6 = 0;
14140           is_ip_any = 0;
14141         }
14142       else
14143         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
14144         {
14145           is_ipv6 = 0;
14146           is_ip_any = 0;
14147         }
14148       else
14149         if (unformat
14150             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
14151         {
14152           is_ipv6 = 0;
14153           is_ip_any = 0;
14154         }
14155       else
14156         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
14157         {
14158           is_ipv6 = 0;
14159           is_ip_any = 0;
14160         }
14161       else
14162         if (unformat
14163             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
14164         {
14165           is_ipv6 = 1;
14166           is_ip_any = 0;
14167         }
14168       else
14169         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
14170         {
14171           is_ipv6 = 1;
14172           is_ip_any = 0;
14173         }
14174       else
14175         if (unformat
14176             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
14177         {
14178           is_ipv6 = 1;
14179           is_ip_any = 0;
14180         }
14181       else
14182         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
14183         {
14184           is_ipv6 = 1;
14185           is_ip_any = 0;
14186         }
14187       else
14188         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14189         {
14190           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14191             {
14192               clib_warning ("unsupported action: 'resolve'");
14193               return -99;
14194             }
14195         }
14196       else
14197         {
14198           clib_warning ("parse error '%U'", format_unformat_error, i);
14199           return -99;
14200         }
14201
14202     }
14203
14204   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
14205
14206   mp->spd_id = ntohl (spd_id);
14207   mp->priority = ntohl (priority);
14208   mp->is_outbound = is_outbound;
14209
14210   mp->is_ipv6 = is_ipv6;
14211   if (is_ipv6 || is_ip_any)
14212     {
14213       clib_memcpy (mp->remote_address_start, &raddr6_start,
14214                    sizeof (ip6_address_t));
14215       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
14216                    sizeof (ip6_address_t));
14217       clib_memcpy (mp->local_address_start, &laddr6_start,
14218                    sizeof (ip6_address_t));
14219       clib_memcpy (mp->local_address_stop, &laddr6_stop,
14220                    sizeof (ip6_address_t));
14221     }
14222   else
14223     {
14224       clib_memcpy (mp->remote_address_start, &raddr4_start,
14225                    sizeof (ip4_address_t));
14226       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
14227                    sizeof (ip4_address_t));
14228       clib_memcpy (mp->local_address_start, &laddr4_start,
14229                    sizeof (ip4_address_t));
14230       clib_memcpy (mp->local_address_stop, &laddr4_stop,
14231                    sizeof (ip4_address_t));
14232     }
14233   mp->protocol = (u8) protocol;
14234   mp->local_port_start = ntohs ((u16) lport_start);
14235   mp->local_port_stop = ntohs ((u16) lport_stop);
14236   mp->remote_port_start = ntohs ((u16) rport_start);
14237   mp->remote_port_stop = ntohs ((u16) rport_stop);
14238   mp->policy = (u8) policy;
14239   mp->sa_id = ntohl (sa_id);
14240   mp->is_add = is_add;
14241   mp->is_ip_any = is_ip_any;
14242   S (mp);
14243   W (ret);
14244   return ret;
14245 }
14246
14247 static int
14248 api_ipsec_sad_add_del_entry (vat_main_t * vam)
14249 {
14250   unformat_input_t *i = vam->input;
14251   vl_api_ipsec_sad_add_del_entry_t *mp;
14252   u32 sad_id = 0, spi = 0;
14253   u8 *ck = 0, *ik = 0;
14254   u8 is_add = 1;
14255
14256   u8 protocol = IPSEC_PROTOCOL_AH;
14257   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
14258   u32 crypto_alg = 0, integ_alg = 0;
14259   ip4_address_t tun_src4;
14260   ip4_address_t tun_dst4;
14261   ip6_address_t tun_src6;
14262   ip6_address_t tun_dst6;
14263   int ret;
14264
14265   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14266     {
14267       if (unformat (i, "del"))
14268         is_add = 0;
14269       else if (unformat (i, "sad_id %d", &sad_id))
14270         ;
14271       else if (unformat (i, "spi %d", &spi))
14272         ;
14273       else if (unformat (i, "esp"))
14274         protocol = IPSEC_PROTOCOL_ESP;
14275       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
14276         {
14277           is_tunnel = 1;
14278           is_tunnel_ipv6 = 0;
14279         }
14280       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
14281         {
14282           is_tunnel = 1;
14283           is_tunnel_ipv6 = 0;
14284         }
14285       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
14286         {
14287           is_tunnel = 1;
14288           is_tunnel_ipv6 = 1;
14289         }
14290       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
14291         {
14292           is_tunnel = 1;
14293           is_tunnel_ipv6 = 1;
14294         }
14295       else
14296         if (unformat
14297             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14298         {
14299           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14300               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14301             {
14302               clib_warning ("unsupported crypto-alg: '%U'",
14303                             format_ipsec_crypto_alg, crypto_alg);
14304               return -99;
14305             }
14306         }
14307       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14308         ;
14309       else
14310         if (unformat
14311             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14312         {
14313           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14314               integ_alg >= IPSEC_INTEG_N_ALG)
14315             {
14316               clib_warning ("unsupported integ-alg: '%U'",
14317                             format_ipsec_integ_alg, integ_alg);
14318               return -99;
14319             }
14320         }
14321       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14322         ;
14323       else
14324         {
14325           clib_warning ("parse error '%U'", format_unformat_error, i);
14326           return -99;
14327         }
14328
14329     }
14330
14331   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
14332
14333   mp->sad_id = ntohl (sad_id);
14334   mp->is_add = is_add;
14335   mp->protocol = protocol;
14336   mp->spi = ntohl (spi);
14337   mp->is_tunnel = is_tunnel;
14338   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
14339   mp->crypto_algorithm = crypto_alg;
14340   mp->integrity_algorithm = integ_alg;
14341   mp->crypto_key_length = vec_len (ck);
14342   mp->integrity_key_length = vec_len (ik);
14343
14344   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14345     mp->crypto_key_length = sizeof (mp->crypto_key);
14346
14347   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14348     mp->integrity_key_length = sizeof (mp->integrity_key);
14349
14350   if (ck)
14351     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14352   if (ik)
14353     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14354
14355   if (is_tunnel)
14356     {
14357       if (is_tunnel_ipv6)
14358         {
14359           clib_memcpy (mp->tunnel_src_address, &tun_src6,
14360                        sizeof (ip6_address_t));
14361           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
14362                        sizeof (ip6_address_t));
14363         }
14364       else
14365         {
14366           clib_memcpy (mp->tunnel_src_address, &tun_src4,
14367                        sizeof (ip4_address_t));
14368           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
14369                        sizeof (ip4_address_t));
14370         }
14371     }
14372
14373   S (mp);
14374   W (ret);
14375   return ret;
14376 }
14377
14378 static int
14379 api_ipsec_sa_set_key (vat_main_t * vam)
14380 {
14381   unformat_input_t *i = vam->input;
14382   vl_api_ipsec_sa_set_key_t *mp;
14383   u32 sa_id;
14384   u8 *ck = 0, *ik = 0;
14385   int ret;
14386
14387   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14388     {
14389       if (unformat (i, "sa_id %d", &sa_id))
14390         ;
14391       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14392         ;
14393       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14394         ;
14395       else
14396         {
14397           clib_warning ("parse error '%U'", format_unformat_error, i);
14398           return -99;
14399         }
14400     }
14401
14402   M (IPSEC_SA_SET_KEY, mp);
14403
14404   mp->sa_id = ntohl (sa_id);
14405   mp->crypto_key_length = vec_len (ck);
14406   mp->integrity_key_length = vec_len (ik);
14407
14408   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14409     mp->crypto_key_length = sizeof (mp->crypto_key);
14410
14411   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14412     mp->integrity_key_length = sizeof (mp->integrity_key);
14413
14414   if (ck)
14415     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14416   if (ik)
14417     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14418
14419   S (mp);
14420   W (ret);
14421   return ret;
14422 }
14423
14424 static int
14425 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14426 {
14427   unformat_input_t *i = vam->input;
14428   vl_api_ipsec_tunnel_if_add_del_t *mp;
14429   u32 local_spi = 0, remote_spi = 0;
14430   u32 crypto_alg = 0, integ_alg = 0;
14431   u8 *lck = NULL, *rck = NULL;
14432   u8 *lik = NULL, *rik = NULL;
14433   ip4_address_t local_ip = { {0} };
14434   ip4_address_t remote_ip = { {0} };
14435   u8 is_add = 1;
14436   u8 esn = 0;
14437   u8 anti_replay = 0;
14438   int ret;
14439
14440   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14441     {
14442       if (unformat (i, "del"))
14443         is_add = 0;
14444       else if (unformat (i, "esn"))
14445         esn = 1;
14446       else if (unformat (i, "anti_replay"))
14447         anti_replay = 1;
14448       else if (unformat (i, "local_spi %d", &local_spi))
14449         ;
14450       else if (unformat (i, "remote_spi %d", &remote_spi))
14451         ;
14452       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
14453         ;
14454       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
14455         ;
14456       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14457         ;
14458       else
14459         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14460         ;
14461       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14462         ;
14463       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14464         ;
14465       else
14466         if (unformat
14467             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14468         {
14469           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14470               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14471             {
14472               errmsg ("unsupported crypto-alg: '%U'\n",
14473                       format_ipsec_crypto_alg, crypto_alg);
14474               return -99;
14475             }
14476         }
14477       else
14478         if (unformat
14479             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14480         {
14481           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14482               integ_alg >= IPSEC_INTEG_N_ALG)
14483             {
14484               errmsg ("unsupported integ-alg: '%U'\n",
14485                       format_ipsec_integ_alg, integ_alg);
14486               return -99;
14487             }
14488         }
14489       else
14490         {
14491           errmsg ("parse error '%U'\n", format_unformat_error, i);
14492           return -99;
14493         }
14494     }
14495
14496   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14497
14498   mp->is_add = is_add;
14499   mp->esn = esn;
14500   mp->anti_replay = anti_replay;
14501
14502   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
14503   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
14504
14505   mp->local_spi = htonl (local_spi);
14506   mp->remote_spi = htonl (remote_spi);
14507   mp->crypto_alg = (u8) crypto_alg;
14508
14509   mp->local_crypto_key_len = 0;
14510   if (lck)
14511     {
14512       mp->local_crypto_key_len = vec_len (lck);
14513       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14514         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14515       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14516     }
14517
14518   mp->remote_crypto_key_len = 0;
14519   if (rck)
14520     {
14521       mp->remote_crypto_key_len = vec_len (rck);
14522       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14523         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14524       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14525     }
14526
14527   mp->integ_alg = (u8) integ_alg;
14528
14529   mp->local_integ_key_len = 0;
14530   if (lik)
14531     {
14532       mp->local_integ_key_len = vec_len (lik);
14533       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14534         mp->local_integ_key_len = sizeof (mp->local_integ_key);
14535       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14536     }
14537
14538   mp->remote_integ_key_len = 0;
14539   if (rik)
14540     {
14541       mp->remote_integ_key_len = vec_len (rik);
14542       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14543         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14544       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14545     }
14546
14547   S (mp);
14548   W (ret);
14549   return ret;
14550 }
14551
14552 static void
14553 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14554 {
14555   vat_main_t *vam = &vat_main;
14556
14557   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14558          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
14559          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
14560          "tunnel_src_addr %U tunnel_dst_addr %U "
14561          "salt %u seq_outbound %lu last_seq_inbound %lu "
14562          "replay_window %lu total_data_size %lu\n",
14563          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
14564          mp->protocol,
14565          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
14566          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
14567          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
14568          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14569          mp->tunnel_src_addr,
14570          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14571          mp->tunnel_dst_addr,
14572          ntohl (mp->salt),
14573          clib_net_to_host_u64 (mp->seq_outbound),
14574          clib_net_to_host_u64 (mp->last_seq_inbound),
14575          clib_net_to_host_u64 (mp->replay_window),
14576          clib_net_to_host_u64 (mp->total_data_size));
14577 }
14578
14579 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14580 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14581
14582 static void vl_api_ipsec_sa_details_t_handler_json
14583   (vl_api_ipsec_sa_details_t * mp)
14584 {
14585   vat_main_t *vam = &vat_main;
14586   vat_json_node_t *node = NULL;
14587   struct in_addr src_ip4, dst_ip4;
14588   struct in6_addr src_ip6, dst_ip6;
14589
14590   if (VAT_JSON_ARRAY != vam->json_tree.type)
14591     {
14592       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14593       vat_json_init_array (&vam->json_tree);
14594     }
14595   node = vat_json_array_add (&vam->json_tree);
14596
14597   vat_json_init_object (node);
14598   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
14599   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14600   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
14601   vat_json_object_add_uint (node, "proto", mp->protocol);
14602   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
14603   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
14604   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
14605   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
14606   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
14607   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
14608   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
14609                              mp->crypto_key_len);
14610   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
14611                              mp->integ_key_len);
14612   if (mp->is_tunnel_ip6)
14613     {
14614       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
14615       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
14616       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
14617       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
14618     }
14619   else
14620     {
14621       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
14622       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
14623       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
14624       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
14625     }
14626   vat_json_object_add_uint (node, "replay_window",
14627                             clib_net_to_host_u64 (mp->replay_window));
14628   vat_json_object_add_uint (node, "total_data_size",
14629                             clib_net_to_host_u64 (mp->total_data_size));
14630
14631 }
14632
14633 static int
14634 api_ipsec_sa_dump (vat_main_t * vam)
14635 {
14636   unformat_input_t *i = vam->input;
14637   vl_api_ipsec_sa_dump_t *mp;
14638   vl_api_control_ping_t *mp_ping;
14639   u32 sa_id = ~0;
14640   int ret;
14641
14642   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14643     {
14644       if (unformat (i, "sa_id %d", &sa_id))
14645         ;
14646       else
14647         {
14648           clib_warning ("parse error '%U'", format_unformat_error, i);
14649           return -99;
14650         }
14651     }
14652
14653   M (IPSEC_SA_DUMP, mp);
14654
14655   mp->sa_id = ntohl (sa_id);
14656
14657   S (mp);
14658
14659   /* Use a control ping for synchronization */
14660   M (CONTROL_PING, mp_ping);
14661   S (mp_ping);
14662
14663   W (ret);
14664   return ret;
14665 }
14666
14667 static int
14668 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
14669 {
14670   unformat_input_t *i = vam->input;
14671   vl_api_ipsec_tunnel_if_set_key_t *mp;
14672   u32 sw_if_index = ~0;
14673   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
14674   u8 *key = 0;
14675   u32 alg = ~0;
14676   int ret;
14677
14678   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14679     {
14680       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14681         ;
14682       else
14683         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
14684         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
14685       else
14686         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
14687         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
14688       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
14689         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
14690       else
14691         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
14692         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
14693       else if (unformat (i, "%U", unformat_hex_string, &key))
14694         ;
14695       else
14696         {
14697           clib_warning ("parse error '%U'", format_unformat_error, i);
14698           return -99;
14699         }
14700     }
14701
14702   if (sw_if_index == ~0)
14703     {
14704       errmsg ("interface must be specified");
14705       return -99;
14706     }
14707
14708   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
14709     {
14710       errmsg ("key type must be specified");
14711       return -99;
14712     }
14713
14714   if (alg == ~0)
14715     {
14716       errmsg ("algorithm must be specified");
14717       return -99;
14718     }
14719
14720   if (vec_len (key) == 0)
14721     {
14722       errmsg ("key must be specified");
14723       return -99;
14724     }
14725
14726   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
14727
14728   mp->sw_if_index = htonl (sw_if_index);
14729   mp->alg = alg;
14730   mp->key_type = key_type;
14731   mp->key_len = vec_len (key);
14732   clib_memcpy (mp->key, key, vec_len (key));
14733
14734   S (mp);
14735   W (ret);
14736
14737   return ret;
14738 }
14739
14740 static int
14741 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14742 {
14743   unformat_input_t *i = vam->input;
14744   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14745   u32 sw_if_index = ~0;
14746   u32 sa_id = ~0;
14747   u8 is_outbound = (u8) ~ 0;
14748   int ret;
14749
14750   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14751     {
14752       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14753         ;
14754       else if (unformat (i, "sa_id %d", &sa_id))
14755         ;
14756       else if (unformat (i, "outbound"))
14757         is_outbound = 1;
14758       else if (unformat (i, "inbound"))
14759         is_outbound = 0;
14760       else
14761         {
14762           clib_warning ("parse error '%U'", format_unformat_error, i);
14763           return -99;
14764         }
14765     }
14766
14767   if (sw_if_index == ~0)
14768     {
14769       errmsg ("interface must be specified");
14770       return -99;
14771     }
14772
14773   if (sa_id == ~0)
14774     {
14775       errmsg ("SA ID must be specified");
14776       return -99;
14777     }
14778
14779   M (IPSEC_TUNNEL_IF_SET_SA, mp);
14780
14781   mp->sw_if_index = htonl (sw_if_index);
14782   mp->sa_id = htonl (sa_id);
14783   mp->is_outbound = is_outbound;
14784
14785   S (mp);
14786   W (ret);
14787
14788   return ret;
14789 }
14790
14791 static int
14792 api_ikev2_profile_add_del (vat_main_t * vam)
14793 {
14794   unformat_input_t *i = vam->input;
14795   vl_api_ikev2_profile_add_del_t *mp;
14796   u8 is_add = 1;
14797   u8 *name = 0;
14798   int ret;
14799
14800   const char *valid_chars = "a-zA-Z0-9_";
14801
14802   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14803     {
14804       if (unformat (i, "del"))
14805         is_add = 0;
14806       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14807         vec_add1 (name, 0);
14808       else
14809         {
14810           errmsg ("parse error '%U'", format_unformat_error, i);
14811           return -99;
14812         }
14813     }
14814
14815   if (!vec_len (name))
14816     {
14817       errmsg ("profile name must be specified");
14818       return -99;
14819     }
14820
14821   if (vec_len (name) > 64)
14822     {
14823       errmsg ("profile name too long");
14824       return -99;
14825     }
14826
14827   M (IKEV2_PROFILE_ADD_DEL, mp);
14828
14829   clib_memcpy (mp->name, name, vec_len (name));
14830   mp->is_add = is_add;
14831   vec_free (name);
14832
14833   S (mp);
14834   W (ret);
14835   return ret;
14836 }
14837
14838 static int
14839 api_ikev2_profile_set_auth (vat_main_t * vam)
14840 {
14841   unformat_input_t *i = vam->input;
14842   vl_api_ikev2_profile_set_auth_t *mp;
14843   u8 *name = 0;
14844   u8 *data = 0;
14845   u32 auth_method = 0;
14846   u8 is_hex = 0;
14847   int ret;
14848
14849   const char *valid_chars = "a-zA-Z0-9_";
14850
14851   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14852     {
14853       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14854         vec_add1 (name, 0);
14855       else if (unformat (i, "auth_method %U",
14856                          unformat_ikev2_auth_method, &auth_method))
14857         ;
14858       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
14859         is_hex = 1;
14860       else if (unformat (i, "auth_data %v", &data))
14861         ;
14862       else
14863         {
14864           errmsg ("parse error '%U'", format_unformat_error, i);
14865           return -99;
14866         }
14867     }
14868
14869   if (!vec_len (name))
14870     {
14871       errmsg ("profile name must be specified");
14872       return -99;
14873     }
14874
14875   if (vec_len (name) > 64)
14876     {
14877       errmsg ("profile name too long");
14878       return -99;
14879     }
14880
14881   if (!vec_len (data))
14882     {
14883       errmsg ("auth_data must be specified");
14884       return -99;
14885     }
14886
14887   if (!auth_method)
14888     {
14889       errmsg ("auth_method must be specified");
14890       return -99;
14891     }
14892
14893   M (IKEV2_PROFILE_SET_AUTH, mp);
14894
14895   mp->is_hex = is_hex;
14896   mp->auth_method = (u8) auth_method;
14897   mp->data_len = vec_len (data);
14898   clib_memcpy (mp->name, name, vec_len (name));
14899   clib_memcpy (mp->data, data, vec_len (data));
14900   vec_free (name);
14901   vec_free (data);
14902
14903   S (mp);
14904   W (ret);
14905   return ret;
14906 }
14907
14908 static int
14909 api_ikev2_profile_set_id (vat_main_t * vam)
14910 {
14911   unformat_input_t *i = vam->input;
14912   vl_api_ikev2_profile_set_id_t *mp;
14913   u8 *name = 0;
14914   u8 *data = 0;
14915   u8 is_local = 0;
14916   u32 id_type = 0;
14917   ip4_address_t ip4;
14918   int ret;
14919
14920   const char *valid_chars = "a-zA-Z0-9_";
14921
14922   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14923     {
14924       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14925         vec_add1 (name, 0);
14926       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
14927         ;
14928       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
14929         {
14930           data = vec_new (u8, 4);
14931           clib_memcpy (data, ip4.as_u8, 4);
14932         }
14933       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
14934         ;
14935       else if (unformat (i, "id_data %v", &data))
14936         ;
14937       else if (unformat (i, "local"))
14938         is_local = 1;
14939       else if (unformat (i, "remote"))
14940         is_local = 0;
14941       else
14942         {
14943           errmsg ("parse error '%U'", format_unformat_error, i);
14944           return -99;
14945         }
14946     }
14947
14948   if (!vec_len (name))
14949     {
14950       errmsg ("profile name must be specified");
14951       return -99;
14952     }
14953
14954   if (vec_len (name) > 64)
14955     {
14956       errmsg ("profile name too long");
14957       return -99;
14958     }
14959
14960   if (!vec_len (data))
14961     {
14962       errmsg ("id_data must be specified");
14963       return -99;
14964     }
14965
14966   if (!id_type)
14967     {
14968       errmsg ("id_type must be specified");
14969       return -99;
14970     }
14971
14972   M (IKEV2_PROFILE_SET_ID, mp);
14973
14974   mp->is_local = is_local;
14975   mp->id_type = (u8) id_type;
14976   mp->data_len = vec_len (data);
14977   clib_memcpy (mp->name, name, vec_len (name));
14978   clib_memcpy (mp->data, data, vec_len (data));
14979   vec_free (name);
14980   vec_free (data);
14981
14982   S (mp);
14983   W (ret);
14984   return ret;
14985 }
14986
14987 static int
14988 api_ikev2_profile_set_ts (vat_main_t * vam)
14989 {
14990   unformat_input_t *i = vam->input;
14991   vl_api_ikev2_profile_set_ts_t *mp;
14992   u8 *name = 0;
14993   u8 is_local = 0;
14994   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
14995   ip4_address_t start_addr, end_addr;
14996
14997   const char *valid_chars = "a-zA-Z0-9_";
14998   int ret;
14999
15000   start_addr.as_u32 = 0;
15001   end_addr.as_u32 = (u32) ~ 0;
15002
15003   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15004     {
15005       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
15006         vec_add1 (name, 0);
15007       else if (unformat (i, "protocol %d", &proto))
15008         ;
15009       else if (unformat (i, "start_port %d", &start_port))
15010         ;
15011       else if (unformat (i, "end_port %d", &end_port))
15012         ;
15013       else
15014         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
15015         ;
15016       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
15017         ;
15018       else if (unformat (i, "local"))
15019         is_local = 1;
15020       else if (unformat (i, "remote"))
15021         is_local = 0;
15022       else
15023         {
15024           errmsg ("parse error '%U'", format_unformat_error, i);
15025           return -99;
15026         }
15027     }
15028
15029   if (!vec_len (name))
15030     {
15031       errmsg ("profile name must be specified");
15032       return -99;
15033     }
15034
15035   if (vec_len (name) > 64)
15036     {
15037       errmsg ("profile name too long");
15038       return -99;
15039     }
15040
15041   M (IKEV2_PROFILE_SET_TS, mp);
15042
15043   mp->is_local = is_local;
15044   mp->proto = (u8) proto;
15045   mp->start_port = (u16) start_port;
15046   mp->end_port = (u16) end_port;
15047   mp->start_addr = start_addr.as_u32;
15048   mp->end_addr = end_addr.as_u32;
15049   clib_memcpy (mp->name, name, vec_len (name));
15050   vec_free (name);
15051
15052   S (mp);
15053   W (ret);
15054   return ret;
15055 }
15056
15057 static int
15058 api_ikev2_set_local_key (vat_main_t * vam)
15059 {
15060   unformat_input_t *i = vam->input;
15061   vl_api_ikev2_set_local_key_t *mp;
15062   u8 *file = 0;
15063   int ret;
15064
15065   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15066     {
15067       if (unformat (i, "file %v", &file))
15068         vec_add1 (file, 0);
15069       else
15070         {
15071           errmsg ("parse error '%U'", format_unformat_error, i);
15072           return -99;
15073         }
15074     }
15075
15076   if (!vec_len (file))
15077     {
15078       errmsg ("RSA key file must be specified");
15079       return -99;
15080     }
15081
15082   if (vec_len (file) > 256)
15083     {
15084       errmsg ("file name too long");
15085       return -99;
15086     }
15087
15088   M (IKEV2_SET_LOCAL_KEY, mp);
15089
15090   clib_memcpy (mp->key_file, file, vec_len (file));
15091   vec_free (file);
15092
15093   S (mp);
15094   W (ret);
15095   return ret;
15096 }
15097
15098 static int
15099 api_ikev2_set_responder (vat_main_t * vam)
15100 {
15101   unformat_input_t *i = vam->input;
15102   vl_api_ikev2_set_responder_t *mp;
15103   int ret;
15104   u8 *name = 0;
15105   u32 sw_if_index = ~0;
15106   ip4_address_t address;
15107
15108   const char *valid_chars = "a-zA-Z0-9_";
15109
15110   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15111     {
15112       if (unformat
15113           (i, "%U interface %d address %U", unformat_token, valid_chars,
15114            &name, &sw_if_index, unformat_ip4_address, &address))
15115         vec_add1 (name, 0);
15116       else
15117         {
15118           errmsg ("parse error '%U'", format_unformat_error, i);
15119           return -99;
15120         }
15121     }
15122
15123   if (!vec_len (name))
15124     {
15125       errmsg ("profile name must be specified");
15126       return -99;
15127     }
15128
15129   if (vec_len (name) > 64)
15130     {
15131       errmsg ("profile name too long");
15132       return -99;
15133     }
15134
15135   M (IKEV2_SET_RESPONDER, mp);
15136
15137   clib_memcpy (mp->name, name, vec_len (name));
15138   vec_free (name);
15139
15140   mp->sw_if_index = sw_if_index;
15141   clib_memcpy (mp->address, &address, sizeof (address));
15142
15143   S (mp);
15144   W (ret);
15145   return ret;
15146 }
15147
15148 static int
15149 api_ikev2_set_ike_transforms (vat_main_t * vam)
15150 {
15151   unformat_input_t *i = vam->input;
15152   vl_api_ikev2_set_ike_transforms_t *mp;
15153   int ret;
15154   u8 *name = 0;
15155   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15156
15157   const char *valid_chars = "a-zA-Z0-9_";
15158
15159   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15160     {
15161       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15162                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15163         vec_add1 (name, 0);
15164       else
15165         {
15166           errmsg ("parse error '%U'", format_unformat_error, i);
15167           return -99;
15168         }
15169     }
15170
15171   if (!vec_len (name))
15172     {
15173       errmsg ("profile name must be specified");
15174       return -99;
15175     }
15176
15177   if (vec_len (name) > 64)
15178     {
15179       errmsg ("profile name too long");
15180       return -99;
15181     }
15182
15183   M (IKEV2_SET_IKE_TRANSFORMS, mp);
15184
15185   clib_memcpy (mp->name, name, vec_len (name));
15186   vec_free (name);
15187   mp->crypto_alg = crypto_alg;
15188   mp->crypto_key_size = crypto_key_size;
15189   mp->integ_alg = integ_alg;
15190   mp->dh_group = dh_group;
15191
15192   S (mp);
15193   W (ret);
15194   return ret;
15195 }
15196
15197
15198 static int
15199 api_ikev2_set_esp_transforms (vat_main_t * vam)
15200 {
15201   unformat_input_t *i = vam->input;
15202   vl_api_ikev2_set_esp_transforms_t *mp;
15203   int ret;
15204   u8 *name = 0;
15205   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
15206
15207   const char *valid_chars = "a-zA-Z0-9_";
15208
15209   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15210     {
15211       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
15212                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
15213         vec_add1 (name, 0);
15214       else
15215         {
15216           errmsg ("parse error '%U'", format_unformat_error, i);
15217           return -99;
15218         }
15219     }
15220
15221   if (!vec_len (name))
15222     {
15223       errmsg ("profile name must be specified");
15224       return -99;
15225     }
15226
15227   if (vec_len (name) > 64)
15228     {
15229       errmsg ("profile name too long");
15230       return -99;
15231     }
15232
15233   M (IKEV2_SET_ESP_TRANSFORMS, mp);
15234
15235   clib_memcpy (mp->name, name, vec_len (name));
15236   vec_free (name);
15237   mp->crypto_alg = crypto_alg;
15238   mp->crypto_key_size = crypto_key_size;
15239   mp->integ_alg = integ_alg;
15240   mp->dh_group = dh_group;
15241
15242   S (mp);
15243   W (ret);
15244   return ret;
15245 }
15246
15247 static int
15248 api_ikev2_set_sa_lifetime (vat_main_t * vam)
15249 {
15250   unformat_input_t *i = vam->input;
15251   vl_api_ikev2_set_sa_lifetime_t *mp;
15252   int ret;
15253   u8 *name = 0;
15254   u64 lifetime, lifetime_maxdata;
15255   u32 lifetime_jitter, handover;
15256
15257   const char *valid_chars = "a-zA-Z0-9_";
15258
15259   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15260     {
15261       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
15262                     &lifetime, &lifetime_jitter, &handover,
15263                     &lifetime_maxdata))
15264         vec_add1 (name, 0);
15265       else
15266         {
15267           errmsg ("parse error '%U'", format_unformat_error, i);
15268           return -99;
15269         }
15270     }
15271
15272   if (!vec_len (name))
15273     {
15274       errmsg ("profile name must be specified");
15275       return -99;
15276     }
15277
15278   if (vec_len (name) > 64)
15279     {
15280       errmsg ("profile name too long");
15281       return -99;
15282     }
15283
15284   M (IKEV2_SET_SA_LIFETIME, mp);
15285
15286   clib_memcpy (mp->name, name, vec_len (name));
15287   vec_free (name);
15288   mp->lifetime = lifetime;
15289   mp->lifetime_jitter = lifetime_jitter;
15290   mp->handover = handover;
15291   mp->lifetime_maxdata = lifetime_maxdata;
15292
15293   S (mp);
15294   W (ret);
15295   return ret;
15296 }
15297
15298 static int
15299 api_ikev2_initiate_sa_init (vat_main_t * vam)
15300 {
15301   unformat_input_t *i = vam->input;
15302   vl_api_ikev2_initiate_sa_init_t *mp;
15303   int ret;
15304   u8 *name = 0;
15305
15306   const char *valid_chars = "a-zA-Z0-9_";
15307
15308   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15309     {
15310       if (unformat (i, "%U", unformat_token, valid_chars, &name))
15311         vec_add1 (name, 0);
15312       else
15313         {
15314           errmsg ("parse error '%U'", format_unformat_error, i);
15315           return -99;
15316         }
15317     }
15318
15319   if (!vec_len (name))
15320     {
15321       errmsg ("profile name must be specified");
15322       return -99;
15323     }
15324
15325   if (vec_len (name) > 64)
15326     {
15327       errmsg ("profile name too long");
15328       return -99;
15329     }
15330
15331   M (IKEV2_INITIATE_SA_INIT, mp);
15332
15333   clib_memcpy (mp->name, name, vec_len (name));
15334   vec_free (name);
15335
15336   S (mp);
15337   W (ret);
15338   return ret;
15339 }
15340
15341 static int
15342 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
15343 {
15344   unformat_input_t *i = vam->input;
15345   vl_api_ikev2_initiate_del_ike_sa_t *mp;
15346   int ret;
15347   u64 ispi;
15348
15349
15350   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15351     {
15352       if (unformat (i, "%lx", &ispi))
15353         ;
15354       else
15355         {
15356           errmsg ("parse error '%U'", format_unformat_error, i);
15357           return -99;
15358         }
15359     }
15360
15361   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
15362
15363   mp->ispi = ispi;
15364
15365   S (mp);
15366   W (ret);
15367   return ret;
15368 }
15369
15370 static int
15371 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
15372 {
15373   unformat_input_t *i = vam->input;
15374   vl_api_ikev2_initiate_del_child_sa_t *mp;
15375   int ret;
15376   u32 ispi;
15377
15378
15379   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15380     {
15381       if (unformat (i, "%x", &ispi))
15382         ;
15383       else
15384         {
15385           errmsg ("parse error '%U'", format_unformat_error, i);
15386           return -99;
15387         }
15388     }
15389
15390   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
15391
15392   mp->ispi = ispi;
15393
15394   S (mp);
15395   W (ret);
15396   return ret;
15397 }
15398
15399 static int
15400 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
15401 {
15402   unformat_input_t *i = vam->input;
15403   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
15404   int ret;
15405   u32 ispi;
15406
15407
15408   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15409     {
15410       if (unformat (i, "%x", &ispi))
15411         ;
15412       else
15413         {
15414           errmsg ("parse error '%U'", format_unformat_error, i);
15415           return -99;
15416         }
15417     }
15418
15419   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
15420
15421   mp->ispi = ispi;
15422
15423   S (mp);
15424   W (ret);
15425   return ret;
15426 }
15427
15428 /*
15429  * MAP
15430  */
15431 static int
15432 api_map_add_domain (vat_main_t * vam)
15433 {
15434   unformat_input_t *i = vam->input;
15435   vl_api_map_add_domain_t *mp;
15436
15437   ip4_address_t ip4_prefix;
15438   ip6_address_t ip6_prefix;
15439   ip6_address_t ip6_src;
15440   u32 num_m_args = 0;
15441   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
15442     0, psid_length = 0;
15443   u8 is_translation = 0;
15444   u32 mtu = 0;
15445   u32 ip6_src_len = 128;
15446   int ret;
15447
15448   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15449     {
15450       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
15451                     &ip4_prefix, &ip4_prefix_len))
15452         num_m_args++;
15453       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
15454                          &ip6_prefix, &ip6_prefix_len))
15455         num_m_args++;
15456       else
15457         if (unformat
15458             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
15459              &ip6_src_len))
15460         num_m_args++;
15461       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
15462         num_m_args++;
15463       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
15464         num_m_args++;
15465       else if (unformat (i, "psid-offset %d", &psid_offset))
15466         num_m_args++;
15467       else if (unformat (i, "psid-len %d", &psid_length))
15468         num_m_args++;
15469       else if (unformat (i, "mtu %d", &mtu))
15470         num_m_args++;
15471       else if (unformat (i, "map-t"))
15472         is_translation = 1;
15473       else
15474         {
15475           clib_warning ("parse error '%U'", format_unformat_error, i);
15476           return -99;
15477         }
15478     }
15479
15480   if (num_m_args < 3)
15481     {
15482       errmsg ("mandatory argument(s) missing");
15483       return -99;
15484     }
15485
15486   /* Construct the API message */
15487   M (MAP_ADD_DOMAIN, mp);
15488
15489   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
15490   mp->ip4_prefix_len = ip4_prefix_len;
15491
15492   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
15493   mp->ip6_prefix_len = ip6_prefix_len;
15494
15495   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
15496   mp->ip6_src_prefix_len = ip6_src_len;
15497
15498   mp->ea_bits_len = ea_bits_len;
15499   mp->psid_offset = psid_offset;
15500   mp->psid_length = psid_length;
15501   mp->is_translation = is_translation;
15502   mp->mtu = htons (mtu);
15503
15504   /* send it... */
15505   S (mp);
15506
15507   /* Wait for a reply, return good/bad news  */
15508   W (ret);
15509   return ret;
15510 }
15511
15512 static int
15513 api_map_del_domain (vat_main_t * vam)
15514 {
15515   unformat_input_t *i = vam->input;
15516   vl_api_map_del_domain_t *mp;
15517
15518   u32 num_m_args = 0;
15519   u32 index;
15520   int ret;
15521
15522   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15523     {
15524       if (unformat (i, "index %d", &index))
15525         num_m_args++;
15526       else
15527         {
15528           clib_warning ("parse error '%U'", format_unformat_error, i);
15529           return -99;
15530         }
15531     }
15532
15533   if (num_m_args != 1)
15534     {
15535       errmsg ("mandatory argument(s) missing");
15536       return -99;
15537     }
15538
15539   /* Construct the API message */
15540   M (MAP_DEL_DOMAIN, mp);
15541
15542   mp->index = ntohl (index);
15543
15544   /* send it... */
15545   S (mp);
15546
15547   /* Wait for a reply, return good/bad news  */
15548   W (ret);
15549   return ret;
15550 }
15551
15552 static int
15553 api_map_add_del_rule (vat_main_t * vam)
15554 {
15555   unformat_input_t *i = vam->input;
15556   vl_api_map_add_del_rule_t *mp;
15557   u8 is_add = 1;
15558   ip6_address_t ip6_dst;
15559   u32 num_m_args = 0, index, psid = 0;
15560   int ret;
15561
15562   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15563     {
15564       if (unformat (i, "index %d", &index))
15565         num_m_args++;
15566       else if (unformat (i, "psid %d", &psid))
15567         num_m_args++;
15568       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
15569         num_m_args++;
15570       else if (unformat (i, "del"))
15571         {
15572           is_add = 0;
15573         }
15574       else
15575         {
15576           clib_warning ("parse error '%U'", format_unformat_error, i);
15577           return -99;
15578         }
15579     }
15580
15581   /* Construct the API message */
15582   M (MAP_ADD_DEL_RULE, mp);
15583
15584   mp->index = ntohl (index);
15585   mp->is_add = is_add;
15586   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
15587   mp->psid = ntohs (psid);
15588
15589   /* send it... */
15590   S (mp);
15591
15592   /* Wait for a reply, return good/bad news  */
15593   W (ret);
15594   return ret;
15595 }
15596
15597 static int
15598 api_map_domain_dump (vat_main_t * vam)
15599 {
15600   vl_api_map_domain_dump_t *mp;
15601   vl_api_control_ping_t *mp_ping;
15602   int ret;
15603
15604   /* Construct the API message */
15605   M (MAP_DOMAIN_DUMP, mp);
15606
15607   /* send it... */
15608   S (mp);
15609
15610   /* Use a control ping for synchronization */
15611   MPING (CONTROL_PING, mp_ping);
15612   S (mp_ping);
15613
15614   W (ret);
15615   return ret;
15616 }
15617
15618 static int
15619 api_map_rule_dump (vat_main_t * vam)
15620 {
15621   unformat_input_t *i = vam->input;
15622   vl_api_map_rule_dump_t *mp;
15623   vl_api_control_ping_t *mp_ping;
15624   u32 domain_index = ~0;
15625   int ret;
15626
15627   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15628     {
15629       if (unformat (i, "index %u", &domain_index))
15630         ;
15631       else
15632         break;
15633     }
15634
15635   if (domain_index == ~0)
15636     {
15637       clib_warning ("parse error: domain index expected");
15638       return -99;
15639     }
15640
15641   /* Construct the API message */
15642   M (MAP_RULE_DUMP, mp);
15643
15644   mp->domain_index = htonl (domain_index);
15645
15646   /* send it... */
15647   S (mp);
15648
15649   /* Use a control ping for synchronization */
15650   MPING (CONTROL_PING, mp_ping);
15651   S (mp_ping);
15652
15653   W (ret);
15654   return ret;
15655 }
15656
15657 static void vl_api_map_add_domain_reply_t_handler
15658   (vl_api_map_add_domain_reply_t * mp)
15659 {
15660   vat_main_t *vam = &vat_main;
15661   i32 retval = ntohl (mp->retval);
15662
15663   if (vam->async_mode)
15664     {
15665       vam->async_errors += (retval < 0);
15666     }
15667   else
15668     {
15669       vam->retval = retval;
15670       vam->result_ready = 1;
15671     }
15672 }
15673
15674 static void vl_api_map_add_domain_reply_t_handler_json
15675   (vl_api_map_add_domain_reply_t * mp)
15676 {
15677   vat_main_t *vam = &vat_main;
15678   vat_json_node_t node;
15679
15680   vat_json_init_object (&node);
15681   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
15682   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
15683
15684   vat_json_print (vam->ofp, &node);
15685   vat_json_free (&node);
15686
15687   vam->retval = ntohl (mp->retval);
15688   vam->result_ready = 1;
15689 }
15690
15691 static int
15692 api_get_first_msg_id (vat_main_t * vam)
15693 {
15694   vl_api_get_first_msg_id_t *mp;
15695   unformat_input_t *i = vam->input;
15696   u8 *name;
15697   u8 name_set = 0;
15698   int ret;
15699
15700   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15701     {
15702       if (unformat (i, "client %s", &name))
15703         name_set = 1;
15704       else
15705         break;
15706     }
15707
15708   if (name_set == 0)
15709     {
15710       errmsg ("missing client name");
15711       return -99;
15712     }
15713   vec_add1 (name, 0);
15714
15715   if (vec_len (name) > 63)
15716     {
15717       errmsg ("client name too long");
15718       return -99;
15719     }
15720
15721   M (GET_FIRST_MSG_ID, mp);
15722   clib_memcpy (mp->name, name, vec_len (name));
15723   S (mp);
15724   W (ret);
15725   return ret;
15726 }
15727
15728 static int
15729 api_cop_interface_enable_disable (vat_main_t * vam)
15730 {
15731   unformat_input_t *line_input = vam->input;
15732   vl_api_cop_interface_enable_disable_t *mp;
15733   u32 sw_if_index = ~0;
15734   u8 enable_disable = 1;
15735   int ret;
15736
15737   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15738     {
15739       if (unformat (line_input, "disable"))
15740         enable_disable = 0;
15741       if (unformat (line_input, "enable"))
15742         enable_disable = 1;
15743       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15744                          vam, &sw_if_index))
15745         ;
15746       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15747         ;
15748       else
15749         break;
15750     }
15751
15752   if (sw_if_index == ~0)
15753     {
15754       errmsg ("missing interface name or sw_if_index");
15755       return -99;
15756     }
15757
15758   /* Construct the API message */
15759   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15760   mp->sw_if_index = ntohl (sw_if_index);
15761   mp->enable_disable = enable_disable;
15762
15763   /* send it... */
15764   S (mp);
15765   /* Wait for the reply */
15766   W (ret);
15767   return ret;
15768 }
15769
15770 static int
15771 api_cop_whitelist_enable_disable (vat_main_t * vam)
15772 {
15773   unformat_input_t *line_input = vam->input;
15774   vl_api_cop_whitelist_enable_disable_t *mp;
15775   u32 sw_if_index = ~0;
15776   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15777   u32 fib_id = 0;
15778   int ret;
15779
15780   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15781     {
15782       if (unformat (line_input, "ip4"))
15783         ip4 = 1;
15784       else if (unformat (line_input, "ip6"))
15785         ip6 = 1;
15786       else if (unformat (line_input, "default"))
15787         default_cop = 1;
15788       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15789                          vam, &sw_if_index))
15790         ;
15791       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15792         ;
15793       else if (unformat (line_input, "fib-id %d", &fib_id))
15794         ;
15795       else
15796         break;
15797     }
15798
15799   if (sw_if_index == ~0)
15800     {
15801       errmsg ("missing interface name or sw_if_index");
15802       return -99;
15803     }
15804
15805   /* Construct the API message */
15806   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15807   mp->sw_if_index = ntohl (sw_if_index);
15808   mp->fib_id = ntohl (fib_id);
15809   mp->ip4 = ip4;
15810   mp->ip6 = ip6;
15811   mp->default_cop = default_cop;
15812
15813   /* send it... */
15814   S (mp);
15815   /* Wait for the reply */
15816   W (ret);
15817   return ret;
15818 }
15819
15820 static int
15821 api_get_node_graph (vat_main_t * vam)
15822 {
15823   vl_api_get_node_graph_t *mp;
15824   int ret;
15825
15826   M (GET_NODE_GRAPH, mp);
15827
15828   /* send it... */
15829   S (mp);
15830   /* Wait for the reply */
15831   W (ret);
15832   return ret;
15833 }
15834
15835 /* *INDENT-OFF* */
15836 /** Used for parsing LISP eids */
15837 typedef CLIB_PACKED(struct{
15838   u8 addr[16];   /**< eid address */
15839   u32 len;       /**< prefix length if IP */
15840   u8 type;      /**< type of eid */
15841 }) lisp_eid_vat_t;
15842 /* *INDENT-ON* */
15843
15844 static uword
15845 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15846 {
15847   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15848
15849   memset (a, 0, sizeof (a[0]));
15850
15851   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15852     {
15853       a->type = 0;              /* ipv4 type */
15854     }
15855   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15856     {
15857       a->type = 1;              /* ipv6 type */
15858     }
15859   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15860     {
15861       a->type = 2;              /* mac type */
15862     }
15863   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15864     {
15865       a->type = 3;              /* NSH type */
15866       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15867       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15868     }
15869   else
15870     {
15871       return 0;
15872     }
15873
15874   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15875     {
15876       return 0;
15877     }
15878
15879   return 1;
15880 }
15881
15882 static int
15883 lisp_eid_size_vat (u8 type)
15884 {
15885   switch (type)
15886     {
15887     case 0:
15888       return 4;
15889     case 1:
15890       return 16;
15891     case 2:
15892       return 6;
15893     case 3:
15894       return 5;
15895     }
15896   return 0;
15897 }
15898
15899 static void
15900 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15901 {
15902   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15903 }
15904
15905 static int
15906 api_one_add_del_locator_set (vat_main_t * vam)
15907 {
15908   unformat_input_t *input = vam->input;
15909   vl_api_one_add_del_locator_set_t *mp;
15910   u8 is_add = 1;
15911   u8 *locator_set_name = NULL;
15912   u8 locator_set_name_set = 0;
15913   vl_api_local_locator_t locator, *locators = 0;
15914   u32 sw_if_index, priority, weight;
15915   u32 data_len = 0;
15916
15917   int ret;
15918   /* Parse args required to build the message */
15919   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15920     {
15921       if (unformat (input, "del"))
15922         {
15923           is_add = 0;
15924         }
15925       else if (unformat (input, "locator-set %s", &locator_set_name))
15926         {
15927           locator_set_name_set = 1;
15928         }
15929       else if (unformat (input, "sw_if_index %u p %u w %u",
15930                          &sw_if_index, &priority, &weight))
15931         {
15932           locator.sw_if_index = htonl (sw_if_index);
15933           locator.priority = priority;
15934           locator.weight = weight;
15935           vec_add1 (locators, locator);
15936         }
15937       else
15938         if (unformat
15939             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15940              &sw_if_index, &priority, &weight))
15941         {
15942           locator.sw_if_index = htonl (sw_if_index);
15943           locator.priority = priority;
15944           locator.weight = weight;
15945           vec_add1 (locators, locator);
15946         }
15947       else
15948         break;
15949     }
15950
15951   if (locator_set_name_set == 0)
15952     {
15953       errmsg ("missing locator-set name");
15954       vec_free (locators);
15955       return -99;
15956     }
15957
15958   if (vec_len (locator_set_name) > 64)
15959     {
15960       errmsg ("locator-set name too long");
15961       vec_free (locator_set_name);
15962       vec_free (locators);
15963       return -99;
15964     }
15965   vec_add1 (locator_set_name, 0);
15966
15967   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15968
15969   /* Construct the API message */
15970   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15971
15972   mp->is_add = is_add;
15973   clib_memcpy (mp->locator_set_name, locator_set_name,
15974                vec_len (locator_set_name));
15975   vec_free (locator_set_name);
15976
15977   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15978   if (locators)
15979     clib_memcpy (mp->locators, locators, data_len);
15980   vec_free (locators);
15981
15982   /* send it... */
15983   S (mp);
15984
15985   /* Wait for a reply... */
15986   W (ret);
15987   return ret;
15988 }
15989
15990 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15991
15992 static int
15993 api_one_add_del_locator (vat_main_t * vam)
15994 {
15995   unformat_input_t *input = vam->input;
15996   vl_api_one_add_del_locator_t *mp;
15997   u32 tmp_if_index = ~0;
15998   u32 sw_if_index = ~0;
15999   u8 sw_if_index_set = 0;
16000   u8 sw_if_index_if_name_set = 0;
16001   u32 priority = ~0;
16002   u8 priority_set = 0;
16003   u32 weight = ~0;
16004   u8 weight_set = 0;
16005   u8 is_add = 1;
16006   u8 *locator_set_name = NULL;
16007   u8 locator_set_name_set = 0;
16008   int ret;
16009
16010   /* Parse args required to build the message */
16011   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16012     {
16013       if (unformat (input, "del"))
16014         {
16015           is_add = 0;
16016         }
16017       else if (unformat (input, "locator-set %s", &locator_set_name))
16018         {
16019           locator_set_name_set = 1;
16020         }
16021       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
16022                          &tmp_if_index))
16023         {
16024           sw_if_index_if_name_set = 1;
16025           sw_if_index = tmp_if_index;
16026         }
16027       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
16028         {
16029           sw_if_index_set = 1;
16030           sw_if_index = tmp_if_index;
16031         }
16032       else if (unformat (input, "p %d", &priority))
16033         {
16034           priority_set = 1;
16035         }
16036       else if (unformat (input, "w %d", &weight))
16037         {
16038           weight_set = 1;
16039         }
16040       else
16041         break;
16042     }
16043
16044   if (locator_set_name_set == 0)
16045     {
16046       errmsg ("missing locator-set name");
16047       return -99;
16048     }
16049
16050   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
16051     {
16052       errmsg ("missing sw_if_index");
16053       vec_free (locator_set_name);
16054       return -99;
16055     }
16056
16057   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
16058     {
16059       errmsg ("cannot use both params interface name and sw_if_index");
16060       vec_free (locator_set_name);
16061       return -99;
16062     }
16063
16064   if (priority_set == 0)
16065     {
16066       errmsg ("missing locator-set priority");
16067       vec_free (locator_set_name);
16068       return -99;
16069     }
16070
16071   if (weight_set == 0)
16072     {
16073       errmsg ("missing locator-set weight");
16074       vec_free (locator_set_name);
16075       return -99;
16076     }
16077
16078   if (vec_len (locator_set_name) > 64)
16079     {
16080       errmsg ("locator-set name too long");
16081       vec_free (locator_set_name);
16082       return -99;
16083     }
16084   vec_add1 (locator_set_name, 0);
16085
16086   /* Construct the API message */
16087   M (ONE_ADD_DEL_LOCATOR, mp);
16088
16089   mp->is_add = is_add;
16090   mp->sw_if_index = ntohl (sw_if_index);
16091   mp->priority = priority;
16092   mp->weight = weight;
16093   clib_memcpy (mp->locator_set_name, locator_set_name,
16094                vec_len (locator_set_name));
16095   vec_free (locator_set_name);
16096
16097   /* send it... */
16098   S (mp);
16099
16100   /* Wait for a reply... */
16101   W (ret);
16102   return ret;
16103 }
16104
16105 #define api_lisp_add_del_locator api_one_add_del_locator
16106
16107 uword
16108 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
16109 {
16110   u32 *key_id = va_arg (*args, u32 *);
16111   u8 *s = 0;
16112
16113   if (unformat (input, "%s", &s))
16114     {
16115       if (!strcmp ((char *) s, "sha1"))
16116         key_id[0] = HMAC_SHA_1_96;
16117       else if (!strcmp ((char *) s, "sha256"))
16118         key_id[0] = HMAC_SHA_256_128;
16119       else
16120         {
16121           clib_warning ("invalid key_id: '%s'", s);
16122           key_id[0] = HMAC_NO_KEY;
16123         }
16124     }
16125   else
16126     return 0;
16127
16128   vec_free (s);
16129   return 1;
16130 }
16131
16132 static int
16133 api_one_add_del_local_eid (vat_main_t * vam)
16134 {
16135   unformat_input_t *input = vam->input;
16136   vl_api_one_add_del_local_eid_t *mp;
16137   u8 is_add = 1;
16138   u8 eid_set = 0;
16139   lisp_eid_vat_t _eid, *eid = &_eid;
16140   u8 *locator_set_name = 0;
16141   u8 locator_set_name_set = 0;
16142   u32 vni = 0;
16143   u16 key_id = 0;
16144   u8 *key = 0;
16145   int ret;
16146
16147   /* Parse args required to build the message */
16148   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16149     {
16150       if (unformat (input, "del"))
16151         {
16152           is_add = 0;
16153         }
16154       else if (unformat (input, "vni %d", &vni))
16155         {
16156           ;
16157         }
16158       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16159         {
16160           eid_set = 1;
16161         }
16162       else if (unformat (input, "locator-set %s", &locator_set_name))
16163         {
16164           locator_set_name_set = 1;
16165         }
16166       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
16167         ;
16168       else if (unformat (input, "secret-key %_%v%_", &key))
16169         ;
16170       else
16171         break;
16172     }
16173
16174   if (locator_set_name_set == 0)
16175     {
16176       errmsg ("missing locator-set name");
16177       return -99;
16178     }
16179
16180   if (0 == eid_set)
16181     {
16182       errmsg ("EID address not set!");
16183       vec_free (locator_set_name);
16184       return -99;
16185     }
16186
16187   if (key && (0 == key_id))
16188     {
16189       errmsg ("invalid key_id!");
16190       return -99;
16191     }
16192
16193   if (vec_len (key) > 64)
16194     {
16195       errmsg ("key too long");
16196       vec_free (key);
16197       return -99;
16198     }
16199
16200   if (vec_len (locator_set_name) > 64)
16201     {
16202       errmsg ("locator-set name too long");
16203       vec_free (locator_set_name);
16204       return -99;
16205     }
16206   vec_add1 (locator_set_name, 0);
16207
16208   /* Construct the API message */
16209   M (ONE_ADD_DEL_LOCAL_EID, mp);
16210
16211   mp->is_add = is_add;
16212   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16213   mp->eid_type = eid->type;
16214   mp->prefix_len = eid->len;
16215   mp->vni = clib_host_to_net_u32 (vni);
16216   mp->key_id = clib_host_to_net_u16 (key_id);
16217   clib_memcpy (mp->locator_set_name, locator_set_name,
16218                vec_len (locator_set_name));
16219   clib_memcpy (mp->key, key, vec_len (key));
16220
16221   vec_free (locator_set_name);
16222   vec_free (key);
16223
16224   /* send it... */
16225   S (mp);
16226
16227   /* Wait for a reply... */
16228   W (ret);
16229   return ret;
16230 }
16231
16232 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
16233
16234 static int
16235 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
16236 {
16237   u32 dp_table = 0, vni = 0;;
16238   unformat_input_t *input = vam->input;
16239   vl_api_gpe_add_del_fwd_entry_t *mp;
16240   u8 is_add = 1;
16241   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
16242   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
16243   u8 rmt_eid_set = 0, lcl_eid_set = 0;
16244   u32 action = ~0, w;
16245   ip4_address_t rmt_rloc4, lcl_rloc4;
16246   ip6_address_t rmt_rloc6, lcl_rloc6;
16247   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
16248   int ret;
16249
16250   memset (&rloc, 0, sizeof (rloc));
16251
16252   /* Parse args required to build the message */
16253   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16254     {
16255       if (unformat (input, "del"))
16256         is_add = 0;
16257       else if (unformat (input, "add"))
16258         is_add = 1;
16259       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
16260         {
16261           rmt_eid_set = 1;
16262         }
16263       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
16264         {
16265           lcl_eid_set = 1;
16266         }
16267       else if (unformat (input, "vrf %d", &dp_table))
16268         ;
16269       else if (unformat (input, "bd %d", &dp_table))
16270         ;
16271       else if (unformat (input, "vni %d", &vni))
16272         ;
16273       else if (unformat (input, "w %d", &w))
16274         {
16275           if (!curr_rloc)
16276             {
16277               errmsg ("No RLOC configured for setting priority/weight!");
16278               return -99;
16279             }
16280           curr_rloc->weight = w;
16281         }
16282       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16283                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16284         {
16285           rloc.is_ip4 = 1;
16286
16287           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16288           rloc.weight = 0;
16289           vec_add1 (lcl_locs, rloc);
16290
16291           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16292           vec_add1 (rmt_locs, rloc);
16293           /* weight saved in rmt loc */
16294           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16295         }
16296       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16297                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16298         {
16299           rloc.is_ip4 = 0;
16300           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16301           rloc.weight = 0;
16302           vec_add1 (lcl_locs, rloc);
16303
16304           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16305           vec_add1 (rmt_locs, rloc);
16306           /* weight saved in rmt loc */
16307           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16308         }
16309       else if (unformat (input, "action %d", &action))
16310         {
16311           ;
16312         }
16313       else
16314         {
16315           clib_warning ("parse error '%U'", format_unformat_error, input);
16316           return -99;
16317         }
16318     }
16319
16320   if (!rmt_eid_set)
16321     {
16322       errmsg ("remote eid addresses not set");
16323       return -99;
16324     }
16325
16326   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16327     {
16328       errmsg ("eid types don't match");
16329       return -99;
16330     }
16331
16332   if (0 == rmt_locs && (u32) ~ 0 == action)
16333     {
16334       errmsg ("action not set for negative mapping");
16335       return -99;
16336     }
16337
16338   /* Construct the API message */
16339   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16340       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16341
16342   mp->is_add = is_add;
16343   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16344   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16345   mp->eid_type = rmt_eid->type;
16346   mp->dp_table = clib_host_to_net_u32 (dp_table);
16347   mp->vni = clib_host_to_net_u32 (vni);
16348   mp->rmt_len = rmt_eid->len;
16349   mp->lcl_len = lcl_eid->len;
16350   mp->action = action;
16351
16352   if (0 != rmt_locs && 0 != lcl_locs)
16353     {
16354       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16355       clib_memcpy (mp->locs, lcl_locs,
16356                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16357
16358       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16359       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16360                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16361     }
16362   vec_free (lcl_locs);
16363   vec_free (rmt_locs);
16364
16365   /* send it... */
16366   S (mp);
16367
16368   /* Wait for a reply... */
16369   W (ret);
16370   return ret;
16371 }
16372
16373 static int
16374 api_one_add_del_map_server (vat_main_t * vam)
16375 {
16376   unformat_input_t *input = vam->input;
16377   vl_api_one_add_del_map_server_t *mp;
16378   u8 is_add = 1;
16379   u8 ipv4_set = 0;
16380   u8 ipv6_set = 0;
16381   ip4_address_t ipv4;
16382   ip6_address_t ipv6;
16383   int ret;
16384
16385   /* Parse args required to build the message */
16386   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16387     {
16388       if (unformat (input, "del"))
16389         {
16390           is_add = 0;
16391         }
16392       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16393         {
16394           ipv4_set = 1;
16395         }
16396       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16397         {
16398           ipv6_set = 1;
16399         }
16400       else
16401         break;
16402     }
16403
16404   if (ipv4_set && ipv6_set)
16405     {
16406       errmsg ("both eid v4 and v6 addresses set");
16407       return -99;
16408     }
16409
16410   if (!ipv4_set && !ipv6_set)
16411     {
16412       errmsg ("eid addresses not set");
16413       return -99;
16414     }
16415
16416   /* Construct the API message */
16417   M (ONE_ADD_DEL_MAP_SERVER, mp);
16418
16419   mp->is_add = is_add;
16420   if (ipv6_set)
16421     {
16422       mp->is_ipv6 = 1;
16423       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16424     }
16425   else
16426     {
16427       mp->is_ipv6 = 0;
16428       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16429     }
16430
16431   /* send it... */
16432   S (mp);
16433
16434   /* Wait for a reply... */
16435   W (ret);
16436   return ret;
16437 }
16438
16439 #define api_lisp_add_del_map_server api_one_add_del_map_server
16440
16441 static int
16442 api_one_add_del_map_resolver (vat_main_t * vam)
16443 {
16444   unformat_input_t *input = vam->input;
16445   vl_api_one_add_del_map_resolver_t *mp;
16446   u8 is_add = 1;
16447   u8 ipv4_set = 0;
16448   u8 ipv6_set = 0;
16449   ip4_address_t ipv4;
16450   ip6_address_t ipv6;
16451   int ret;
16452
16453   /* Parse args required to build the message */
16454   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16455     {
16456       if (unformat (input, "del"))
16457         {
16458           is_add = 0;
16459         }
16460       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16461         {
16462           ipv4_set = 1;
16463         }
16464       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16465         {
16466           ipv6_set = 1;
16467         }
16468       else
16469         break;
16470     }
16471
16472   if (ipv4_set && ipv6_set)
16473     {
16474       errmsg ("both eid v4 and v6 addresses set");
16475       return -99;
16476     }
16477
16478   if (!ipv4_set && !ipv6_set)
16479     {
16480       errmsg ("eid addresses not set");
16481       return -99;
16482     }
16483
16484   /* Construct the API message */
16485   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16486
16487   mp->is_add = is_add;
16488   if (ipv6_set)
16489     {
16490       mp->is_ipv6 = 1;
16491       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16492     }
16493   else
16494     {
16495       mp->is_ipv6 = 0;
16496       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16497     }
16498
16499   /* send it... */
16500   S (mp);
16501
16502   /* Wait for a reply... */
16503   W (ret);
16504   return ret;
16505 }
16506
16507 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16508
16509 static int
16510 api_lisp_gpe_enable_disable (vat_main_t * vam)
16511 {
16512   unformat_input_t *input = vam->input;
16513   vl_api_gpe_enable_disable_t *mp;
16514   u8 is_set = 0;
16515   u8 is_en = 1;
16516   int ret;
16517
16518   /* Parse args required to build the message */
16519   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16520     {
16521       if (unformat (input, "enable"))
16522         {
16523           is_set = 1;
16524           is_en = 1;
16525         }
16526       else if (unformat (input, "disable"))
16527         {
16528           is_set = 1;
16529           is_en = 0;
16530         }
16531       else
16532         break;
16533     }
16534
16535   if (is_set == 0)
16536     {
16537       errmsg ("Value not set");
16538       return -99;
16539     }
16540
16541   /* Construct the API message */
16542   M (GPE_ENABLE_DISABLE, mp);
16543
16544   mp->is_en = is_en;
16545
16546   /* send it... */
16547   S (mp);
16548
16549   /* Wait for a reply... */
16550   W (ret);
16551   return ret;
16552 }
16553
16554 static int
16555 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16556 {
16557   unformat_input_t *input = vam->input;
16558   vl_api_one_rloc_probe_enable_disable_t *mp;
16559   u8 is_set = 0;
16560   u8 is_en = 0;
16561   int ret;
16562
16563   /* Parse args required to build the message */
16564   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16565     {
16566       if (unformat (input, "enable"))
16567         {
16568           is_set = 1;
16569           is_en = 1;
16570         }
16571       else if (unformat (input, "disable"))
16572         is_set = 1;
16573       else
16574         break;
16575     }
16576
16577   if (!is_set)
16578     {
16579       errmsg ("Value not set");
16580       return -99;
16581     }
16582
16583   /* Construct the API message */
16584   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16585
16586   mp->is_enabled = is_en;
16587
16588   /* send it... */
16589   S (mp);
16590
16591   /* Wait for a reply... */
16592   W (ret);
16593   return ret;
16594 }
16595
16596 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16597
16598 static int
16599 api_one_map_register_enable_disable (vat_main_t * vam)
16600 {
16601   unformat_input_t *input = vam->input;
16602   vl_api_one_map_register_enable_disable_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         is_set = 1;
16617       else
16618         break;
16619     }
16620
16621   if (!is_set)
16622     {
16623       errmsg ("Value not set");
16624       return -99;
16625     }
16626
16627   /* Construct the API message */
16628   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16629
16630   mp->is_enabled = is_en;
16631
16632   /* send it... */
16633   S (mp);
16634
16635   /* Wait for a reply... */
16636   W (ret);
16637   return ret;
16638 }
16639
16640 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16641
16642 static int
16643 api_one_enable_disable (vat_main_t * vam)
16644 {
16645   unformat_input_t *input = vam->input;
16646   vl_api_one_enable_disable_t *mp;
16647   u8 is_set = 0;
16648   u8 is_en = 0;
16649   int ret;
16650
16651   /* Parse args required to build the message */
16652   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16653     {
16654       if (unformat (input, "enable"))
16655         {
16656           is_set = 1;
16657           is_en = 1;
16658         }
16659       else if (unformat (input, "disable"))
16660         {
16661           is_set = 1;
16662         }
16663       else
16664         break;
16665     }
16666
16667   if (!is_set)
16668     {
16669       errmsg ("Value not set");
16670       return -99;
16671     }
16672
16673   /* Construct the API message */
16674   M (ONE_ENABLE_DISABLE, mp);
16675
16676   mp->is_en = is_en;
16677
16678   /* send it... */
16679   S (mp);
16680
16681   /* Wait for a reply... */
16682   W (ret);
16683   return ret;
16684 }
16685
16686 #define api_lisp_enable_disable api_one_enable_disable
16687
16688 static int
16689 api_one_enable_disable_xtr_mode (vat_main_t * vam)
16690 {
16691   unformat_input_t *input = vam->input;
16692   vl_api_one_enable_disable_xtr_mode_t *mp;
16693   u8 is_set = 0;
16694   u8 is_en = 0;
16695   int ret;
16696
16697   /* Parse args required to build the message */
16698   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16699     {
16700       if (unformat (input, "enable"))
16701         {
16702           is_set = 1;
16703           is_en = 1;
16704         }
16705       else if (unformat (input, "disable"))
16706         {
16707           is_set = 1;
16708         }
16709       else
16710         break;
16711     }
16712
16713   if (!is_set)
16714     {
16715       errmsg ("Value not set");
16716       return -99;
16717     }
16718
16719   /* Construct the API message */
16720   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
16721
16722   mp->is_en = is_en;
16723
16724   /* send it... */
16725   S (mp);
16726
16727   /* Wait for a reply... */
16728   W (ret);
16729   return ret;
16730 }
16731
16732 static int
16733 api_one_show_xtr_mode (vat_main_t * vam)
16734 {
16735   vl_api_one_show_xtr_mode_t *mp;
16736   int ret;
16737
16738   /* Construct the API message */
16739   M (ONE_SHOW_XTR_MODE, mp);
16740
16741   /* send it... */
16742   S (mp);
16743
16744   /* Wait for a reply... */
16745   W (ret);
16746   return ret;
16747 }
16748
16749 static int
16750 api_one_enable_disable_pitr_mode (vat_main_t * vam)
16751 {
16752   unformat_input_t *input = vam->input;
16753   vl_api_one_enable_disable_pitr_mode_t *mp;
16754   u8 is_set = 0;
16755   u8 is_en = 0;
16756   int ret;
16757
16758   /* Parse args required to build the message */
16759   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16760     {
16761       if (unformat (input, "enable"))
16762         {
16763           is_set = 1;
16764           is_en = 1;
16765         }
16766       else if (unformat (input, "disable"))
16767         {
16768           is_set = 1;
16769         }
16770       else
16771         break;
16772     }
16773
16774   if (!is_set)
16775     {
16776       errmsg ("Value not set");
16777       return -99;
16778     }
16779
16780   /* Construct the API message */
16781   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
16782
16783   mp->is_en = is_en;
16784
16785   /* send it... */
16786   S (mp);
16787
16788   /* Wait for a reply... */
16789   W (ret);
16790   return ret;
16791 }
16792
16793 static int
16794 api_one_show_pitr_mode (vat_main_t * vam)
16795 {
16796   vl_api_one_show_pitr_mode_t *mp;
16797   int ret;
16798
16799   /* Construct the API message */
16800   M (ONE_SHOW_PITR_MODE, mp);
16801
16802   /* send it... */
16803   S (mp);
16804
16805   /* Wait for a reply... */
16806   W (ret);
16807   return ret;
16808 }
16809
16810 static int
16811 api_one_enable_disable_petr_mode (vat_main_t * vam)
16812 {
16813   unformat_input_t *input = vam->input;
16814   vl_api_one_enable_disable_petr_mode_t *mp;
16815   u8 is_set = 0;
16816   u8 is_en = 0;
16817   int ret;
16818
16819   /* Parse args required to build the message */
16820   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16821     {
16822       if (unformat (input, "enable"))
16823         {
16824           is_set = 1;
16825           is_en = 1;
16826         }
16827       else if (unformat (input, "disable"))
16828         {
16829           is_set = 1;
16830         }
16831       else
16832         break;
16833     }
16834
16835   if (!is_set)
16836     {
16837       errmsg ("Value not set");
16838       return -99;
16839     }
16840
16841   /* Construct the API message */
16842   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
16843
16844   mp->is_en = is_en;
16845
16846   /* send it... */
16847   S (mp);
16848
16849   /* Wait for a reply... */
16850   W (ret);
16851   return ret;
16852 }
16853
16854 static int
16855 api_one_show_petr_mode (vat_main_t * vam)
16856 {
16857   vl_api_one_show_petr_mode_t *mp;
16858   int ret;
16859
16860   /* Construct the API message */
16861   M (ONE_SHOW_PETR_MODE, mp);
16862
16863   /* send it... */
16864   S (mp);
16865
16866   /* Wait for a reply... */
16867   W (ret);
16868   return ret;
16869 }
16870
16871 static int
16872 api_show_one_map_register_state (vat_main_t * vam)
16873 {
16874   vl_api_show_one_map_register_state_t *mp;
16875   int ret;
16876
16877   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16878
16879   /* send */
16880   S (mp);
16881
16882   /* wait for reply */
16883   W (ret);
16884   return ret;
16885 }
16886
16887 #define api_show_lisp_map_register_state api_show_one_map_register_state
16888
16889 static int
16890 api_show_one_rloc_probe_state (vat_main_t * vam)
16891 {
16892   vl_api_show_one_rloc_probe_state_t *mp;
16893   int ret;
16894
16895   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16896
16897   /* send */
16898   S (mp);
16899
16900   /* wait for reply */
16901   W (ret);
16902   return ret;
16903 }
16904
16905 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16906
16907 static int
16908 api_one_add_del_ndp_entry (vat_main_t * vam)
16909 {
16910   vl_api_one_add_del_ndp_entry_t *mp;
16911   unformat_input_t *input = vam->input;
16912   u8 is_add = 1;
16913   u8 mac_set = 0;
16914   u8 bd_set = 0;
16915   u8 ip_set = 0;
16916   u8 mac[6] = { 0, };
16917   u8 ip6[16] = { 0, };
16918   u32 bd = ~0;
16919   int ret;
16920
16921   /* Parse args required to build the message */
16922   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16923     {
16924       if (unformat (input, "del"))
16925         is_add = 0;
16926       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16927         mac_set = 1;
16928       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16929         ip_set = 1;
16930       else if (unformat (input, "bd %d", &bd))
16931         bd_set = 1;
16932       else
16933         {
16934           errmsg ("parse error '%U'", format_unformat_error, input);
16935           return -99;
16936         }
16937     }
16938
16939   if (!bd_set || !ip_set || (!mac_set && is_add))
16940     {
16941       errmsg ("Missing BD, IP or MAC!");
16942       return -99;
16943     }
16944
16945   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16946   mp->is_add = is_add;
16947   clib_memcpy (mp->mac, mac, 6);
16948   mp->bd = clib_host_to_net_u32 (bd);
16949   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16950
16951   /* send */
16952   S (mp);
16953
16954   /* wait for reply */
16955   W (ret);
16956   return ret;
16957 }
16958
16959 static int
16960 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16961 {
16962   vl_api_one_add_del_l2_arp_entry_t *mp;
16963   unformat_input_t *input = vam->input;
16964   u8 is_add = 1;
16965   u8 mac_set = 0;
16966   u8 bd_set = 0;
16967   u8 ip_set = 0;
16968   u8 mac[6] = { 0, };
16969   u32 ip4 = 0, bd = ~0;
16970   int ret;
16971
16972   /* Parse args required to build the message */
16973   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16974     {
16975       if (unformat (input, "del"))
16976         is_add = 0;
16977       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16978         mac_set = 1;
16979       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16980         ip_set = 1;
16981       else if (unformat (input, "bd %d", &bd))
16982         bd_set = 1;
16983       else
16984         {
16985           errmsg ("parse error '%U'", format_unformat_error, input);
16986           return -99;
16987         }
16988     }
16989
16990   if (!bd_set || !ip_set || (!mac_set && is_add))
16991     {
16992       errmsg ("Missing BD, IP or MAC!");
16993       return -99;
16994     }
16995
16996   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16997   mp->is_add = is_add;
16998   clib_memcpy (mp->mac, mac, 6);
16999   mp->bd = clib_host_to_net_u32 (bd);
17000   mp->ip4 = ip4;
17001
17002   /* send */
17003   S (mp);
17004
17005   /* wait for reply */
17006   W (ret);
17007   return ret;
17008 }
17009
17010 static int
17011 api_one_ndp_bd_get (vat_main_t * vam)
17012 {
17013   vl_api_one_ndp_bd_get_t *mp;
17014   int ret;
17015
17016   M (ONE_NDP_BD_GET, mp);
17017
17018   /* send */
17019   S (mp);
17020
17021   /* wait for reply */
17022   W (ret);
17023   return ret;
17024 }
17025
17026 static int
17027 api_one_ndp_entries_get (vat_main_t * vam)
17028 {
17029   vl_api_one_ndp_entries_get_t *mp;
17030   unformat_input_t *input = vam->input;
17031   u8 bd_set = 0;
17032   u32 bd = ~0;
17033   int ret;
17034
17035   /* Parse args required to build the message */
17036   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17037     {
17038       if (unformat (input, "bd %d", &bd))
17039         bd_set = 1;
17040       else
17041         {
17042           errmsg ("parse error '%U'", format_unformat_error, input);
17043           return -99;
17044         }
17045     }
17046
17047   if (!bd_set)
17048     {
17049       errmsg ("Expected bridge domain!");
17050       return -99;
17051     }
17052
17053   M (ONE_NDP_ENTRIES_GET, mp);
17054   mp->bd = clib_host_to_net_u32 (bd);
17055
17056   /* send */
17057   S (mp);
17058
17059   /* wait for reply */
17060   W (ret);
17061   return ret;
17062 }
17063
17064 static int
17065 api_one_l2_arp_bd_get (vat_main_t * vam)
17066 {
17067   vl_api_one_l2_arp_bd_get_t *mp;
17068   int ret;
17069
17070   M (ONE_L2_ARP_BD_GET, mp);
17071
17072   /* send */
17073   S (mp);
17074
17075   /* wait for reply */
17076   W (ret);
17077   return ret;
17078 }
17079
17080 static int
17081 api_one_l2_arp_entries_get (vat_main_t * vam)
17082 {
17083   vl_api_one_l2_arp_entries_get_t *mp;
17084   unformat_input_t *input = vam->input;
17085   u8 bd_set = 0;
17086   u32 bd = ~0;
17087   int ret;
17088
17089   /* Parse args required to build the message */
17090   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17091     {
17092       if (unformat (input, "bd %d", &bd))
17093         bd_set = 1;
17094       else
17095         {
17096           errmsg ("parse error '%U'", format_unformat_error, input);
17097           return -99;
17098         }
17099     }
17100
17101   if (!bd_set)
17102     {
17103       errmsg ("Expected bridge domain!");
17104       return -99;
17105     }
17106
17107   M (ONE_L2_ARP_ENTRIES_GET, mp);
17108   mp->bd = clib_host_to_net_u32 (bd);
17109
17110   /* send */
17111   S (mp);
17112
17113   /* wait for reply */
17114   W (ret);
17115   return ret;
17116 }
17117
17118 static int
17119 api_one_stats_enable_disable (vat_main_t * vam)
17120 {
17121   vl_api_one_stats_enable_disable_t *mp;
17122   unformat_input_t *input = vam->input;
17123   u8 is_set = 0;
17124   u8 is_en = 0;
17125   int ret;
17126
17127   /* Parse args required to build the message */
17128   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17129     {
17130       if (unformat (input, "enable"))
17131         {
17132           is_set = 1;
17133           is_en = 1;
17134         }
17135       else if (unformat (input, "disable"))
17136         {
17137           is_set = 1;
17138         }
17139       else
17140         break;
17141     }
17142
17143   if (!is_set)
17144     {
17145       errmsg ("Value not set");
17146       return -99;
17147     }
17148
17149   M (ONE_STATS_ENABLE_DISABLE, mp);
17150   mp->is_en = is_en;
17151
17152   /* send */
17153   S (mp);
17154
17155   /* wait for reply */
17156   W (ret);
17157   return ret;
17158 }
17159
17160 static int
17161 api_show_one_stats_enable_disable (vat_main_t * vam)
17162 {
17163   vl_api_show_one_stats_enable_disable_t *mp;
17164   int ret;
17165
17166   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
17167
17168   /* send */
17169   S (mp);
17170
17171   /* wait for reply */
17172   W (ret);
17173   return ret;
17174 }
17175
17176 static int
17177 api_show_one_map_request_mode (vat_main_t * vam)
17178 {
17179   vl_api_show_one_map_request_mode_t *mp;
17180   int ret;
17181
17182   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
17183
17184   /* send */
17185   S (mp);
17186
17187   /* wait for reply */
17188   W (ret);
17189   return ret;
17190 }
17191
17192 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
17193
17194 static int
17195 api_one_map_request_mode (vat_main_t * vam)
17196 {
17197   unformat_input_t *input = vam->input;
17198   vl_api_one_map_request_mode_t *mp;
17199   u8 mode = 0;
17200   int ret;
17201
17202   /* Parse args required to build the message */
17203   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17204     {
17205       if (unformat (input, "dst-only"))
17206         mode = 0;
17207       else if (unformat (input, "src-dst"))
17208         mode = 1;
17209       else
17210         {
17211           errmsg ("parse error '%U'", format_unformat_error, input);
17212           return -99;
17213         }
17214     }
17215
17216   M (ONE_MAP_REQUEST_MODE, mp);
17217
17218   mp->mode = mode;
17219
17220   /* send */
17221   S (mp);
17222
17223   /* wait for reply */
17224   W (ret);
17225   return ret;
17226 }
17227
17228 #define api_lisp_map_request_mode api_one_map_request_mode
17229
17230 /**
17231  * Enable/disable ONE proxy ITR.
17232  *
17233  * @param vam vpp API test context
17234  * @return return code
17235  */
17236 static int
17237 api_one_pitr_set_locator_set (vat_main_t * vam)
17238 {
17239   u8 ls_name_set = 0;
17240   unformat_input_t *input = vam->input;
17241   vl_api_one_pitr_set_locator_set_t *mp;
17242   u8 is_add = 1;
17243   u8 *ls_name = 0;
17244   int ret;
17245
17246   /* Parse args required to build the message */
17247   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17248     {
17249       if (unformat (input, "del"))
17250         is_add = 0;
17251       else if (unformat (input, "locator-set %s", &ls_name))
17252         ls_name_set = 1;
17253       else
17254         {
17255           errmsg ("parse error '%U'", format_unformat_error, input);
17256           return -99;
17257         }
17258     }
17259
17260   if (!ls_name_set)
17261     {
17262       errmsg ("locator-set name not set!");
17263       return -99;
17264     }
17265
17266   M (ONE_PITR_SET_LOCATOR_SET, mp);
17267
17268   mp->is_add = is_add;
17269   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17270   vec_free (ls_name);
17271
17272   /* send */
17273   S (mp);
17274
17275   /* wait for reply */
17276   W (ret);
17277   return ret;
17278 }
17279
17280 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
17281
17282 static int
17283 api_one_nsh_set_locator_set (vat_main_t * vam)
17284 {
17285   u8 ls_name_set = 0;
17286   unformat_input_t *input = vam->input;
17287   vl_api_one_nsh_set_locator_set_t *mp;
17288   u8 is_add = 1;
17289   u8 *ls_name = 0;
17290   int ret;
17291
17292   /* Parse args required to build the message */
17293   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17294     {
17295       if (unformat (input, "del"))
17296         is_add = 0;
17297       else if (unformat (input, "ls %s", &ls_name))
17298         ls_name_set = 1;
17299       else
17300         {
17301           errmsg ("parse error '%U'", format_unformat_error, input);
17302           return -99;
17303         }
17304     }
17305
17306   if (!ls_name_set && is_add)
17307     {
17308       errmsg ("locator-set name not set!");
17309       return -99;
17310     }
17311
17312   M (ONE_NSH_SET_LOCATOR_SET, mp);
17313
17314   mp->is_add = is_add;
17315   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
17316   vec_free (ls_name);
17317
17318   /* send */
17319   S (mp);
17320
17321   /* wait for reply */
17322   W (ret);
17323   return ret;
17324 }
17325
17326 static int
17327 api_show_one_pitr (vat_main_t * vam)
17328 {
17329   vl_api_show_one_pitr_t *mp;
17330   int ret;
17331
17332   if (!vam->json_output)
17333     {
17334       print (vam->ofp, "%=20s", "lisp status:");
17335     }
17336
17337   M (SHOW_ONE_PITR, mp);
17338   /* send it... */
17339   S (mp);
17340
17341   /* Wait for a reply... */
17342   W (ret);
17343   return ret;
17344 }
17345
17346 #define api_show_lisp_pitr api_show_one_pitr
17347
17348 static int
17349 api_one_use_petr (vat_main_t * vam)
17350 {
17351   unformat_input_t *input = vam->input;
17352   vl_api_one_use_petr_t *mp;
17353   u8 is_add = 0;
17354   ip_address_t ip;
17355   int ret;
17356
17357   memset (&ip, 0, sizeof (ip));
17358
17359   /* Parse args required to build the message */
17360   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17361     {
17362       if (unformat (input, "disable"))
17363         is_add = 0;
17364       else
17365         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
17366         {
17367           is_add = 1;
17368           ip_addr_version (&ip) = IP4;
17369         }
17370       else
17371         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
17372         {
17373           is_add = 1;
17374           ip_addr_version (&ip) = IP6;
17375         }
17376       else
17377         {
17378           errmsg ("parse error '%U'", format_unformat_error, input);
17379           return -99;
17380         }
17381     }
17382
17383   M (ONE_USE_PETR, mp);
17384
17385   mp->is_add = is_add;
17386   if (is_add)
17387     {
17388       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
17389       if (mp->is_ip4)
17390         clib_memcpy (mp->address, &ip, 4);
17391       else
17392         clib_memcpy (mp->address, &ip, 16);
17393     }
17394
17395   /* send */
17396   S (mp);
17397
17398   /* wait for reply */
17399   W (ret);
17400   return ret;
17401 }
17402
17403 #define api_lisp_use_petr api_one_use_petr
17404
17405 static int
17406 api_show_one_nsh_mapping (vat_main_t * vam)
17407 {
17408   vl_api_show_one_use_petr_t *mp;
17409   int ret;
17410
17411   if (!vam->json_output)
17412     {
17413       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
17414     }
17415
17416   M (SHOW_ONE_NSH_MAPPING, mp);
17417   /* send it... */
17418   S (mp);
17419
17420   /* Wait for a reply... */
17421   W (ret);
17422   return ret;
17423 }
17424
17425 static int
17426 api_show_one_use_petr (vat_main_t * vam)
17427 {
17428   vl_api_show_one_use_petr_t *mp;
17429   int ret;
17430
17431   if (!vam->json_output)
17432     {
17433       print (vam->ofp, "%=20s", "Proxy-ETR status:");
17434     }
17435
17436   M (SHOW_ONE_USE_PETR, mp);
17437   /* send it... */
17438   S (mp);
17439
17440   /* Wait for a reply... */
17441   W (ret);
17442   return ret;
17443 }
17444
17445 #define api_show_lisp_use_petr api_show_one_use_petr
17446
17447 /**
17448  * Add/delete mapping between vni and vrf
17449  */
17450 static int
17451 api_one_eid_table_add_del_map (vat_main_t * vam)
17452 {
17453   unformat_input_t *input = vam->input;
17454   vl_api_one_eid_table_add_del_map_t *mp;
17455   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17456   u32 vni, vrf, bd_index;
17457   int ret;
17458
17459   /* Parse args required to build the message */
17460   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17461     {
17462       if (unformat (input, "del"))
17463         is_add = 0;
17464       else if (unformat (input, "vrf %d", &vrf))
17465         vrf_set = 1;
17466       else if (unformat (input, "bd_index %d", &bd_index))
17467         bd_index_set = 1;
17468       else if (unformat (input, "vni %d", &vni))
17469         vni_set = 1;
17470       else
17471         break;
17472     }
17473
17474   if (!vni_set || (!vrf_set && !bd_index_set))
17475     {
17476       errmsg ("missing arguments!");
17477       return -99;
17478     }
17479
17480   if (vrf_set && bd_index_set)
17481     {
17482       errmsg ("error: both vrf and bd entered!");
17483       return -99;
17484     }
17485
17486   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
17487
17488   mp->is_add = is_add;
17489   mp->vni = htonl (vni);
17490   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
17491   mp->is_l2 = bd_index_set;
17492
17493   /* send */
17494   S (mp);
17495
17496   /* wait for reply */
17497   W (ret);
17498   return ret;
17499 }
17500
17501 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
17502
17503 uword
17504 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
17505 {
17506   u32 *action = va_arg (*args, u32 *);
17507   u8 *s = 0;
17508
17509   if (unformat (input, "%s", &s))
17510     {
17511       if (!strcmp ((char *) s, "no-action"))
17512         action[0] = 0;
17513       else if (!strcmp ((char *) s, "natively-forward"))
17514         action[0] = 1;
17515       else if (!strcmp ((char *) s, "send-map-request"))
17516         action[0] = 2;
17517       else if (!strcmp ((char *) s, "drop"))
17518         action[0] = 3;
17519       else
17520         {
17521           clib_warning ("invalid action: '%s'", s);
17522           action[0] = 3;
17523         }
17524     }
17525   else
17526     return 0;
17527
17528   vec_free (s);
17529   return 1;
17530 }
17531
17532 /**
17533  * Add/del remote mapping to/from ONE control plane
17534  *
17535  * @param vam vpp API test context
17536  * @return return code
17537  */
17538 static int
17539 api_one_add_del_remote_mapping (vat_main_t * vam)
17540 {
17541   unformat_input_t *input = vam->input;
17542   vl_api_one_add_del_remote_mapping_t *mp;
17543   u32 vni = 0;
17544   lisp_eid_vat_t _eid, *eid = &_eid;
17545   lisp_eid_vat_t _seid, *seid = &_seid;
17546   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
17547   u32 action = ~0, p, w, data_len;
17548   ip4_address_t rloc4;
17549   ip6_address_t rloc6;
17550   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
17551   int ret;
17552
17553   memset (&rloc, 0, sizeof (rloc));
17554
17555   /* Parse args required to build the message */
17556   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17557     {
17558       if (unformat (input, "del-all"))
17559         {
17560           del_all = 1;
17561         }
17562       else if (unformat (input, "del"))
17563         {
17564           is_add = 0;
17565         }
17566       else if (unformat (input, "add"))
17567         {
17568           is_add = 1;
17569         }
17570       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17571         {
17572           eid_set = 1;
17573         }
17574       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
17575         {
17576           seid_set = 1;
17577         }
17578       else if (unformat (input, "vni %d", &vni))
17579         {
17580           ;
17581         }
17582       else if (unformat (input, "p %d w %d", &p, &w))
17583         {
17584           if (!curr_rloc)
17585             {
17586               errmsg ("No RLOC configured for setting priority/weight!");
17587               return -99;
17588             }
17589           curr_rloc->priority = p;
17590           curr_rloc->weight = w;
17591         }
17592       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
17593         {
17594           rloc.is_ip4 = 1;
17595           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17596           vec_add1 (rlocs, rloc);
17597           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17598         }
17599       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
17600         {
17601           rloc.is_ip4 = 0;
17602           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17603           vec_add1 (rlocs, rloc);
17604           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17605         }
17606       else if (unformat (input, "action %U",
17607                          unformat_negative_mapping_action, &action))
17608         {
17609           ;
17610         }
17611       else
17612         {
17613           clib_warning ("parse error '%U'", format_unformat_error, input);
17614           return -99;
17615         }
17616     }
17617
17618   if (0 == eid_set)
17619     {
17620       errmsg ("missing params!");
17621       return -99;
17622     }
17623
17624   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17625     {
17626       errmsg ("no action set for negative map-reply!");
17627       return -99;
17628     }
17629
17630   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17631
17632   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17633   mp->is_add = is_add;
17634   mp->vni = htonl (vni);
17635   mp->action = (u8) action;
17636   mp->is_src_dst = seid_set;
17637   mp->eid_len = eid->len;
17638   mp->seid_len = seid->len;
17639   mp->del_all = del_all;
17640   mp->eid_type = eid->type;
17641   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17642   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17643
17644   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17645   clib_memcpy (mp->rlocs, rlocs, data_len);
17646   vec_free (rlocs);
17647
17648   /* send it... */
17649   S (mp);
17650
17651   /* Wait for a reply... */
17652   W (ret);
17653   return ret;
17654 }
17655
17656 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17657
17658 /**
17659  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17660  * forwarding entries in data-plane accordingly.
17661  *
17662  * @param vam vpp API test context
17663  * @return return code
17664  */
17665 static int
17666 api_one_add_del_adjacency (vat_main_t * vam)
17667 {
17668   unformat_input_t *input = vam->input;
17669   vl_api_one_add_del_adjacency_t *mp;
17670   u32 vni = 0;
17671   ip4_address_t leid4, reid4;
17672   ip6_address_t leid6, reid6;
17673   u8 reid_mac[6] = { 0 };
17674   u8 leid_mac[6] = { 0 };
17675   u8 reid_type, leid_type;
17676   u32 leid_len = 0, reid_len = 0, len;
17677   u8 is_add = 1;
17678   int ret;
17679
17680   leid_type = reid_type = (u8) ~ 0;
17681
17682   /* Parse args required to build the message */
17683   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17684     {
17685       if (unformat (input, "del"))
17686         {
17687           is_add = 0;
17688         }
17689       else if (unformat (input, "add"))
17690         {
17691           is_add = 1;
17692         }
17693       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17694                          &reid4, &len))
17695         {
17696           reid_type = 0;        /* ipv4 */
17697           reid_len = len;
17698         }
17699       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17700                          &reid6, &len))
17701         {
17702           reid_type = 1;        /* ipv6 */
17703           reid_len = len;
17704         }
17705       else if (unformat (input, "reid %U", unformat_ethernet_address,
17706                          reid_mac))
17707         {
17708           reid_type = 2;        /* mac */
17709         }
17710       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17711                          &leid4, &len))
17712         {
17713           leid_type = 0;        /* ipv4 */
17714           leid_len = len;
17715         }
17716       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17717                          &leid6, &len))
17718         {
17719           leid_type = 1;        /* ipv6 */
17720           leid_len = len;
17721         }
17722       else if (unformat (input, "leid %U", unformat_ethernet_address,
17723                          leid_mac))
17724         {
17725           leid_type = 2;        /* mac */
17726         }
17727       else if (unformat (input, "vni %d", &vni))
17728         {
17729           ;
17730         }
17731       else
17732         {
17733           errmsg ("parse error '%U'", format_unformat_error, input);
17734           return -99;
17735         }
17736     }
17737
17738   if ((u8) ~ 0 == reid_type)
17739     {
17740       errmsg ("missing params!");
17741       return -99;
17742     }
17743
17744   if (leid_type != reid_type)
17745     {
17746       errmsg ("remote and local EIDs are of different types!");
17747       return -99;
17748     }
17749
17750   M (ONE_ADD_DEL_ADJACENCY, mp);
17751   mp->is_add = is_add;
17752   mp->vni = htonl (vni);
17753   mp->leid_len = leid_len;
17754   mp->reid_len = reid_len;
17755   mp->eid_type = reid_type;
17756
17757   switch (mp->eid_type)
17758     {
17759     case 0:
17760       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17761       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17762       break;
17763     case 1:
17764       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17765       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17766       break;
17767     case 2:
17768       clib_memcpy (mp->leid, leid_mac, 6);
17769       clib_memcpy (mp->reid, reid_mac, 6);
17770       break;
17771     default:
17772       errmsg ("unknown EID type %d!", mp->eid_type);
17773       return 0;
17774     }
17775
17776   /* send it... */
17777   S (mp);
17778
17779   /* Wait for a reply... */
17780   W (ret);
17781   return ret;
17782 }
17783
17784 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17785
17786 uword
17787 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17788 {
17789   u32 *mode = va_arg (*args, u32 *);
17790
17791   if (unformat (input, "lisp"))
17792     *mode = 0;
17793   else if (unformat (input, "vxlan"))
17794     *mode = 1;
17795   else
17796     return 0;
17797
17798   return 1;
17799 }
17800
17801 static int
17802 api_gpe_get_encap_mode (vat_main_t * vam)
17803 {
17804   vl_api_gpe_get_encap_mode_t *mp;
17805   int ret;
17806
17807   /* Construct the API message */
17808   M (GPE_GET_ENCAP_MODE, mp);
17809
17810   /* send it... */
17811   S (mp);
17812
17813   /* Wait for a reply... */
17814   W (ret);
17815   return ret;
17816 }
17817
17818 static int
17819 api_gpe_set_encap_mode (vat_main_t * vam)
17820 {
17821   unformat_input_t *input = vam->input;
17822   vl_api_gpe_set_encap_mode_t *mp;
17823   int ret;
17824   u32 mode = 0;
17825
17826   /* Parse args required to build the message */
17827   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17828     {
17829       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17830         ;
17831       else
17832         break;
17833     }
17834
17835   /* Construct the API message */
17836   M (GPE_SET_ENCAP_MODE, mp);
17837
17838   mp->mode = mode;
17839
17840   /* send it... */
17841   S (mp);
17842
17843   /* Wait for a reply... */
17844   W (ret);
17845   return ret;
17846 }
17847
17848 static int
17849 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17850 {
17851   unformat_input_t *input = vam->input;
17852   vl_api_gpe_add_del_iface_t *mp;
17853   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17854   u32 dp_table = 0, vni = 0;
17855   int ret;
17856
17857   /* Parse args required to build the message */
17858   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17859     {
17860       if (unformat (input, "up"))
17861         {
17862           action_set = 1;
17863           is_add = 1;
17864         }
17865       else if (unformat (input, "down"))
17866         {
17867           action_set = 1;
17868           is_add = 0;
17869         }
17870       else if (unformat (input, "table_id %d", &dp_table))
17871         {
17872           dp_table_set = 1;
17873         }
17874       else if (unformat (input, "bd_id %d", &dp_table))
17875         {
17876           dp_table_set = 1;
17877           is_l2 = 1;
17878         }
17879       else if (unformat (input, "vni %d", &vni))
17880         {
17881           vni_set = 1;
17882         }
17883       else
17884         break;
17885     }
17886
17887   if (action_set == 0)
17888     {
17889       errmsg ("Action not set");
17890       return -99;
17891     }
17892   if (dp_table_set == 0 || vni_set == 0)
17893     {
17894       errmsg ("vni and dp_table must be set");
17895       return -99;
17896     }
17897
17898   /* Construct the API message */
17899   M (GPE_ADD_DEL_IFACE, mp);
17900
17901   mp->is_add = is_add;
17902   mp->dp_table = clib_host_to_net_u32 (dp_table);
17903   mp->is_l2 = is_l2;
17904   mp->vni = clib_host_to_net_u32 (vni);
17905
17906   /* send it... */
17907   S (mp);
17908
17909   /* Wait for a reply... */
17910   W (ret);
17911   return ret;
17912 }
17913
17914 static int
17915 api_one_map_register_fallback_threshold (vat_main_t * vam)
17916 {
17917   unformat_input_t *input = vam->input;
17918   vl_api_one_map_register_fallback_threshold_t *mp;
17919   u32 value = 0;
17920   u8 is_set = 0;
17921   int ret;
17922
17923   /* Parse args required to build the message */
17924   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17925     {
17926       if (unformat (input, "%u", &value))
17927         is_set = 1;
17928       else
17929         {
17930           clib_warning ("parse error '%U'", format_unformat_error, input);
17931           return -99;
17932         }
17933     }
17934
17935   if (!is_set)
17936     {
17937       errmsg ("fallback threshold value is missing!");
17938       return -99;
17939     }
17940
17941   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17942   mp->value = clib_host_to_net_u32 (value);
17943
17944   /* send it... */
17945   S (mp);
17946
17947   /* Wait for a reply... */
17948   W (ret);
17949   return ret;
17950 }
17951
17952 static int
17953 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17954 {
17955   vl_api_show_one_map_register_fallback_threshold_t *mp;
17956   int ret;
17957
17958   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17959
17960   /* send it... */
17961   S (mp);
17962
17963   /* Wait for a reply... */
17964   W (ret);
17965   return ret;
17966 }
17967
17968 uword
17969 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17970 {
17971   u32 *proto = va_arg (*args, u32 *);
17972
17973   if (unformat (input, "udp"))
17974     *proto = 1;
17975   else if (unformat (input, "api"))
17976     *proto = 2;
17977   else
17978     return 0;
17979
17980   return 1;
17981 }
17982
17983 static int
17984 api_one_set_transport_protocol (vat_main_t * vam)
17985 {
17986   unformat_input_t *input = vam->input;
17987   vl_api_one_set_transport_protocol_t *mp;
17988   u8 is_set = 0;
17989   u32 protocol = 0;
17990   int ret;
17991
17992   /* Parse args required to build the message */
17993   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17994     {
17995       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17996         is_set = 1;
17997       else
17998         {
17999           clib_warning ("parse error '%U'", format_unformat_error, input);
18000           return -99;
18001         }
18002     }
18003
18004   if (!is_set)
18005     {
18006       errmsg ("Transport protocol missing!");
18007       return -99;
18008     }
18009
18010   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
18011   mp->protocol = (u8) protocol;
18012
18013   /* send it... */
18014   S (mp);
18015
18016   /* Wait for a reply... */
18017   W (ret);
18018   return ret;
18019 }
18020
18021 static int
18022 api_one_get_transport_protocol (vat_main_t * vam)
18023 {
18024   vl_api_one_get_transport_protocol_t *mp;
18025   int ret;
18026
18027   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
18028
18029   /* send it... */
18030   S (mp);
18031
18032   /* Wait for a reply... */
18033   W (ret);
18034   return ret;
18035 }
18036
18037 static int
18038 api_one_map_register_set_ttl (vat_main_t * vam)
18039 {
18040   unformat_input_t *input = vam->input;
18041   vl_api_one_map_register_set_ttl_t *mp;
18042   u32 ttl = 0;
18043   u8 is_set = 0;
18044   int ret;
18045
18046   /* Parse args required to build the message */
18047   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18048     {
18049       if (unformat (input, "%u", &ttl))
18050         is_set = 1;
18051       else
18052         {
18053           clib_warning ("parse error '%U'", format_unformat_error, input);
18054           return -99;
18055         }
18056     }
18057
18058   if (!is_set)
18059     {
18060       errmsg ("TTL value missing!");
18061       return -99;
18062     }
18063
18064   M (ONE_MAP_REGISTER_SET_TTL, mp);
18065   mp->ttl = clib_host_to_net_u32 (ttl);
18066
18067   /* send it... */
18068   S (mp);
18069
18070   /* Wait for a reply... */
18071   W (ret);
18072   return ret;
18073 }
18074
18075 static int
18076 api_show_one_map_register_ttl (vat_main_t * vam)
18077 {
18078   vl_api_show_one_map_register_ttl_t *mp;
18079   int ret;
18080
18081   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
18082
18083   /* send it... */
18084   S (mp);
18085
18086   /* Wait for a reply... */
18087   W (ret);
18088   return ret;
18089 }
18090
18091 /**
18092  * Add/del map request itr rlocs from ONE control plane and updates
18093  *
18094  * @param vam vpp API test context
18095  * @return return code
18096  */
18097 static int
18098 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
18099 {
18100   unformat_input_t *input = vam->input;
18101   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
18102   u8 *locator_set_name = 0;
18103   u8 locator_set_name_set = 0;
18104   u8 is_add = 1;
18105   int ret;
18106
18107   /* Parse args required to build the message */
18108   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18109     {
18110       if (unformat (input, "del"))
18111         {
18112           is_add = 0;
18113         }
18114       else if (unformat (input, "%_%v%_", &locator_set_name))
18115         {
18116           locator_set_name_set = 1;
18117         }
18118       else
18119         {
18120           clib_warning ("parse error '%U'", format_unformat_error, input);
18121           return -99;
18122         }
18123     }
18124
18125   if (is_add && !locator_set_name_set)
18126     {
18127       errmsg ("itr-rloc is not set!");
18128       return -99;
18129     }
18130
18131   if (is_add && vec_len (locator_set_name) > 64)
18132     {
18133       errmsg ("itr-rloc locator-set name too long");
18134       vec_free (locator_set_name);
18135       return -99;
18136     }
18137
18138   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
18139   mp->is_add = is_add;
18140   if (is_add)
18141     {
18142       clib_memcpy (mp->locator_set_name, locator_set_name,
18143                    vec_len (locator_set_name));
18144     }
18145   else
18146     {
18147       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
18148     }
18149   vec_free (locator_set_name);
18150
18151   /* send it... */
18152   S (mp);
18153
18154   /* Wait for a reply... */
18155   W (ret);
18156   return ret;
18157 }
18158
18159 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
18160
18161 static int
18162 api_one_locator_dump (vat_main_t * vam)
18163 {
18164   unformat_input_t *input = vam->input;
18165   vl_api_one_locator_dump_t *mp;
18166   vl_api_control_ping_t *mp_ping;
18167   u8 is_index_set = 0, is_name_set = 0;
18168   u8 *ls_name = 0;
18169   u32 ls_index = ~0;
18170   int ret;
18171
18172   /* Parse args required to build the message */
18173   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18174     {
18175       if (unformat (input, "ls_name %_%v%_", &ls_name))
18176         {
18177           is_name_set = 1;
18178         }
18179       else if (unformat (input, "ls_index %d", &ls_index))
18180         {
18181           is_index_set = 1;
18182         }
18183       else
18184         {
18185           errmsg ("parse error '%U'", format_unformat_error, input);
18186           return -99;
18187         }
18188     }
18189
18190   if (!is_index_set && !is_name_set)
18191     {
18192       errmsg ("error: expected one of index or name!");
18193       return -99;
18194     }
18195
18196   if (is_index_set && is_name_set)
18197     {
18198       errmsg ("error: only one param expected!");
18199       return -99;
18200     }
18201
18202   if (vec_len (ls_name) > 62)
18203     {
18204       errmsg ("error: locator set name too long!");
18205       return -99;
18206     }
18207
18208   if (!vam->json_output)
18209     {
18210       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
18211     }
18212
18213   M (ONE_LOCATOR_DUMP, mp);
18214   mp->is_index_set = is_index_set;
18215
18216   if (is_index_set)
18217     mp->ls_index = clib_host_to_net_u32 (ls_index);
18218   else
18219     {
18220       vec_add1 (ls_name, 0);
18221       strncpy ((char *) mp->ls_name, (char *) ls_name,
18222                sizeof (mp->ls_name) - 1);
18223     }
18224
18225   /* send it... */
18226   S (mp);
18227
18228   /* Use a control ping for synchronization */
18229   MPING (CONTROL_PING, mp_ping);
18230   S (mp_ping);
18231
18232   /* Wait for a reply... */
18233   W (ret);
18234   return ret;
18235 }
18236
18237 #define api_lisp_locator_dump api_one_locator_dump
18238
18239 static int
18240 api_one_locator_set_dump (vat_main_t * vam)
18241 {
18242   vl_api_one_locator_set_dump_t *mp;
18243   vl_api_control_ping_t *mp_ping;
18244   unformat_input_t *input = vam->input;
18245   u8 filter = 0;
18246   int ret;
18247
18248   /* Parse args required to build the message */
18249   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18250     {
18251       if (unformat (input, "local"))
18252         {
18253           filter = 1;
18254         }
18255       else if (unformat (input, "remote"))
18256         {
18257           filter = 2;
18258         }
18259       else
18260         {
18261           errmsg ("parse error '%U'", format_unformat_error, input);
18262           return -99;
18263         }
18264     }
18265
18266   if (!vam->json_output)
18267     {
18268       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
18269     }
18270
18271   M (ONE_LOCATOR_SET_DUMP, mp);
18272
18273   mp->filter = filter;
18274
18275   /* send it... */
18276   S (mp);
18277
18278   /* Use a control ping for synchronization */
18279   MPING (CONTROL_PING, mp_ping);
18280   S (mp_ping);
18281
18282   /* Wait for a reply... */
18283   W (ret);
18284   return ret;
18285 }
18286
18287 #define api_lisp_locator_set_dump api_one_locator_set_dump
18288
18289 static int
18290 api_one_eid_table_map_dump (vat_main_t * vam)
18291 {
18292   u8 is_l2 = 0;
18293   u8 mode_set = 0;
18294   unformat_input_t *input = vam->input;
18295   vl_api_one_eid_table_map_dump_t *mp;
18296   vl_api_control_ping_t *mp_ping;
18297   int ret;
18298
18299   /* Parse args required to build the message */
18300   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18301     {
18302       if (unformat (input, "l2"))
18303         {
18304           is_l2 = 1;
18305           mode_set = 1;
18306         }
18307       else if (unformat (input, "l3"))
18308         {
18309           is_l2 = 0;
18310           mode_set = 1;
18311         }
18312       else
18313         {
18314           errmsg ("parse error '%U'", format_unformat_error, input);
18315           return -99;
18316         }
18317     }
18318
18319   if (!mode_set)
18320     {
18321       errmsg ("expected one of 'l2' or 'l3' parameter!");
18322       return -99;
18323     }
18324
18325   if (!vam->json_output)
18326     {
18327       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
18328     }
18329
18330   M (ONE_EID_TABLE_MAP_DUMP, mp);
18331   mp->is_l2 = is_l2;
18332
18333   /* send it... */
18334   S (mp);
18335
18336   /* Use a control ping for synchronization */
18337   MPING (CONTROL_PING, mp_ping);
18338   S (mp_ping);
18339
18340   /* Wait for a reply... */
18341   W (ret);
18342   return ret;
18343 }
18344
18345 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
18346
18347 static int
18348 api_one_eid_table_vni_dump (vat_main_t * vam)
18349 {
18350   vl_api_one_eid_table_vni_dump_t *mp;
18351   vl_api_control_ping_t *mp_ping;
18352   int ret;
18353
18354   if (!vam->json_output)
18355     {
18356       print (vam->ofp, "VNI");
18357     }
18358
18359   M (ONE_EID_TABLE_VNI_DUMP, mp);
18360
18361   /* send it... */
18362   S (mp);
18363
18364   /* Use a control ping for synchronization */
18365   MPING (CONTROL_PING, mp_ping);
18366   S (mp_ping);
18367
18368   /* Wait for a reply... */
18369   W (ret);
18370   return ret;
18371 }
18372
18373 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
18374
18375 static int
18376 api_one_eid_table_dump (vat_main_t * vam)
18377 {
18378   unformat_input_t *i = vam->input;
18379   vl_api_one_eid_table_dump_t *mp;
18380   vl_api_control_ping_t *mp_ping;
18381   struct in_addr ip4;
18382   struct in6_addr ip6;
18383   u8 mac[6];
18384   u8 eid_type = ~0, eid_set = 0;
18385   u32 prefix_length = ~0, t, vni = 0;
18386   u8 filter = 0;
18387   int ret;
18388   lisp_nsh_api_t nsh;
18389
18390   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18391     {
18392       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
18393         {
18394           eid_set = 1;
18395           eid_type = 0;
18396           prefix_length = t;
18397         }
18398       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
18399         {
18400           eid_set = 1;
18401           eid_type = 1;
18402           prefix_length = t;
18403         }
18404       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
18405         {
18406           eid_set = 1;
18407           eid_type = 2;
18408         }
18409       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
18410         {
18411           eid_set = 1;
18412           eid_type = 3;
18413         }
18414       else if (unformat (i, "vni %d", &t))
18415         {
18416           vni = t;
18417         }
18418       else if (unformat (i, "local"))
18419         {
18420           filter = 1;
18421         }
18422       else if (unformat (i, "remote"))
18423         {
18424           filter = 2;
18425         }
18426       else
18427         {
18428           errmsg ("parse error '%U'", format_unformat_error, i);
18429           return -99;
18430         }
18431     }
18432
18433   if (!vam->json_output)
18434     {
18435       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
18436              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
18437     }
18438
18439   M (ONE_EID_TABLE_DUMP, mp);
18440
18441   mp->filter = filter;
18442   if (eid_set)
18443     {
18444       mp->eid_set = 1;
18445       mp->vni = htonl (vni);
18446       mp->eid_type = eid_type;
18447       switch (eid_type)
18448         {
18449         case 0:
18450           mp->prefix_length = prefix_length;
18451           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
18452           break;
18453         case 1:
18454           mp->prefix_length = prefix_length;
18455           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18456           break;
18457         case 2:
18458           clib_memcpy (mp->eid, mac, sizeof (mac));
18459           break;
18460         case 3:
18461           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18462           break;
18463         default:
18464           errmsg ("unknown EID type %d!", eid_type);
18465           return -99;
18466         }
18467     }
18468
18469   /* send it... */
18470   S (mp);
18471
18472   /* Use a control ping for synchronization */
18473   MPING (CONTROL_PING, mp_ping);
18474   S (mp_ping);
18475
18476   /* Wait for a reply... */
18477   W (ret);
18478   return ret;
18479 }
18480
18481 #define api_lisp_eid_table_dump api_one_eid_table_dump
18482
18483 static int
18484 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
18485 {
18486   unformat_input_t *i = vam->input;
18487   vl_api_gpe_fwd_entries_get_t *mp;
18488   u8 vni_set = 0;
18489   u32 vni = ~0;
18490   int ret;
18491
18492   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18493     {
18494       if (unformat (i, "vni %d", &vni))
18495         {
18496           vni_set = 1;
18497         }
18498       else
18499         {
18500           errmsg ("parse error '%U'", format_unformat_error, i);
18501           return -99;
18502         }
18503     }
18504
18505   if (!vni_set)
18506     {
18507       errmsg ("vni not set!");
18508       return -99;
18509     }
18510
18511   if (!vam->json_output)
18512     {
18513       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
18514              "leid", "reid");
18515     }
18516
18517   M (GPE_FWD_ENTRIES_GET, mp);
18518   mp->vni = clib_host_to_net_u32 (vni);
18519
18520   /* send it... */
18521   S (mp);
18522
18523   /* Wait for a reply... */
18524   W (ret);
18525   return ret;
18526 }
18527
18528 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
18529 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
18530 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
18531 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
18532 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
18533 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
18534 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
18535 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
18536
18537 static int
18538 api_one_adjacencies_get (vat_main_t * vam)
18539 {
18540   unformat_input_t *i = vam->input;
18541   vl_api_one_adjacencies_get_t *mp;
18542   u8 vni_set = 0;
18543   u32 vni = ~0;
18544   int ret;
18545
18546   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18547     {
18548       if (unformat (i, "vni %d", &vni))
18549         {
18550           vni_set = 1;
18551         }
18552       else
18553         {
18554           errmsg ("parse error '%U'", format_unformat_error, i);
18555           return -99;
18556         }
18557     }
18558
18559   if (!vni_set)
18560     {
18561       errmsg ("vni not set!");
18562       return -99;
18563     }
18564
18565   if (!vam->json_output)
18566     {
18567       print (vam->ofp, "%s %40s", "leid", "reid");
18568     }
18569
18570   M (ONE_ADJACENCIES_GET, mp);
18571   mp->vni = clib_host_to_net_u32 (vni);
18572
18573   /* send it... */
18574   S (mp);
18575
18576   /* Wait for a reply... */
18577   W (ret);
18578   return ret;
18579 }
18580
18581 #define api_lisp_adjacencies_get api_one_adjacencies_get
18582
18583 static int
18584 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
18585 {
18586   unformat_input_t *i = vam->input;
18587   vl_api_gpe_native_fwd_rpaths_get_t *mp;
18588   int ret;
18589   u8 ip_family_set = 0, is_ip4 = 1;
18590
18591   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18592     {
18593       if (unformat (i, "ip4"))
18594         {
18595           ip_family_set = 1;
18596           is_ip4 = 1;
18597         }
18598       else if (unformat (i, "ip6"))
18599         {
18600           ip_family_set = 1;
18601           is_ip4 = 0;
18602         }
18603       else
18604         {
18605           errmsg ("parse error '%U'", format_unformat_error, i);
18606           return -99;
18607         }
18608     }
18609
18610   if (!ip_family_set)
18611     {
18612       errmsg ("ip family not set!");
18613       return -99;
18614     }
18615
18616   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18617   mp->is_ip4 = is_ip4;
18618
18619   /* send it... */
18620   S (mp);
18621
18622   /* Wait for a reply... */
18623   W (ret);
18624   return ret;
18625 }
18626
18627 static int
18628 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18629 {
18630   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18631   int ret;
18632
18633   if (!vam->json_output)
18634     {
18635       print (vam->ofp, "VNIs");
18636     }
18637
18638   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18639
18640   /* send it... */
18641   S (mp);
18642
18643   /* Wait for a reply... */
18644   W (ret);
18645   return ret;
18646 }
18647
18648 static int
18649 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18650 {
18651   unformat_input_t *i = vam->input;
18652   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18653   int ret = 0;
18654   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18655   struct in_addr ip4;
18656   struct in6_addr ip6;
18657   u32 table_id = 0, nh_sw_if_index = ~0;
18658
18659   memset (&ip4, 0, sizeof (ip4));
18660   memset (&ip6, 0, sizeof (ip6));
18661
18662   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18663     {
18664       if (unformat (i, "del"))
18665         is_add = 0;
18666       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18667                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18668         {
18669           ip_set = 1;
18670           is_ip4 = 1;
18671         }
18672       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18673                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18674         {
18675           ip_set = 1;
18676           is_ip4 = 0;
18677         }
18678       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18679         {
18680           ip_set = 1;
18681           is_ip4 = 1;
18682           nh_sw_if_index = ~0;
18683         }
18684       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18685         {
18686           ip_set = 1;
18687           is_ip4 = 0;
18688           nh_sw_if_index = ~0;
18689         }
18690       else if (unformat (i, "table %d", &table_id))
18691         ;
18692       else
18693         {
18694           errmsg ("parse error '%U'", format_unformat_error, i);
18695           return -99;
18696         }
18697     }
18698
18699   if (!ip_set)
18700     {
18701       errmsg ("nh addr not set!");
18702       return -99;
18703     }
18704
18705   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18706   mp->is_add = is_add;
18707   mp->table_id = clib_host_to_net_u32 (table_id);
18708   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18709   mp->is_ip4 = is_ip4;
18710   if (is_ip4)
18711     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18712   else
18713     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18714
18715   /* send it... */
18716   S (mp);
18717
18718   /* Wait for a reply... */
18719   W (ret);
18720   return ret;
18721 }
18722
18723 static int
18724 api_one_map_server_dump (vat_main_t * vam)
18725 {
18726   vl_api_one_map_server_dump_t *mp;
18727   vl_api_control_ping_t *mp_ping;
18728   int ret;
18729
18730   if (!vam->json_output)
18731     {
18732       print (vam->ofp, "%=20s", "Map server");
18733     }
18734
18735   M (ONE_MAP_SERVER_DUMP, mp);
18736   /* send it... */
18737   S (mp);
18738
18739   /* Use a control ping for synchronization */
18740   MPING (CONTROL_PING, mp_ping);
18741   S (mp_ping);
18742
18743   /* Wait for a reply... */
18744   W (ret);
18745   return ret;
18746 }
18747
18748 #define api_lisp_map_server_dump api_one_map_server_dump
18749
18750 static int
18751 api_one_map_resolver_dump (vat_main_t * vam)
18752 {
18753   vl_api_one_map_resolver_dump_t *mp;
18754   vl_api_control_ping_t *mp_ping;
18755   int ret;
18756
18757   if (!vam->json_output)
18758     {
18759       print (vam->ofp, "%=20s", "Map resolver");
18760     }
18761
18762   M (ONE_MAP_RESOLVER_DUMP, mp);
18763   /* send it... */
18764   S (mp);
18765
18766   /* Use a control ping for synchronization */
18767   MPING (CONTROL_PING, mp_ping);
18768   S (mp_ping);
18769
18770   /* Wait for a reply... */
18771   W (ret);
18772   return ret;
18773 }
18774
18775 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18776
18777 static int
18778 api_one_stats_flush (vat_main_t * vam)
18779 {
18780   vl_api_one_stats_flush_t *mp;
18781   int ret = 0;
18782
18783   M (ONE_STATS_FLUSH, mp);
18784   S (mp);
18785   W (ret);
18786   return ret;
18787 }
18788
18789 static int
18790 api_one_stats_dump (vat_main_t * vam)
18791 {
18792   vl_api_one_stats_dump_t *mp;
18793   vl_api_control_ping_t *mp_ping;
18794   int ret;
18795
18796   M (ONE_STATS_DUMP, mp);
18797   /* send it... */
18798   S (mp);
18799
18800   /* Use a control ping for synchronization */
18801   MPING (CONTROL_PING, mp_ping);
18802   S (mp_ping);
18803
18804   /* Wait for a reply... */
18805   W (ret);
18806   return ret;
18807 }
18808
18809 static int
18810 api_show_one_status (vat_main_t * vam)
18811 {
18812   vl_api_show_one_status_t *mp;
18813   int ret;
18814
18815   if (!vam->json_output)
18816     {
18817       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18818     }
18819
18820   M (SHOW_ONE_STATUS, mp);
18821   /* send it... */
18822   S (mp);
18823   /* Wait for a reply... */
18824   W (ret);
18825   return ret;
18826 }
18827
18828 #define api_show_lisp_status api_show_one_status
18829
18830 static int
18831 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18832 {
18833   vl_api_gpe_fwd_entry_path_dump_t *mp;
18834   vl_api_control_ping_t *mp_ping;
18835   unformat_input_t *i = vam->input;
18836   u32 fwd_entry_index = ~0;
18837   int ret;
18838
18839   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18840     {
18841       if (unformat (i, "index %d", &fwd_entry_index))
18842         ;
18843       else
18844         break;
18845     }
18846
18847   if (~0 == fwd_entry_index)
18848     {
18849       errmsg ("no index specified!");
18850       return -99;
18851     }
18852
18853   if (!vam->json_output)
18854     {
18855       print (vam->ofp, "first line");
18856     }
18857
18858   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18859
18860   /* send it... */
18861   S (mp);
18862   /* Use a control ping for synchronization */
18863   MPING (CONTROL_PING, mp_ping);
18864   S (mp_ping);
18865
18866   /* Wait for a reply... */
18867   W (ret);
18868   return ret;
18869 }
18870
18871 static int
18872 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18873 {
18874   vl_api_one_get_map_request_itr_rlocs_t *mp;
18875   int ret;
18876
18877   if (!vam->json_output)
18878     {
18879       print (vam->ofp, "%=20s", "itr-rlocs:");
18880     }
18881
18882   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18883   /* send it... */
18884   S (mp);
18885   /* Wait for a reply... */
18886   W (ret);
18887   return ret;
18888 }
18889
18890 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18891
18892 static int
18893 api_af_packet_create (vat_main_t * vam)
18894 {
18895   unformat_input_t *i = vam->input;
18896   vl_api_af_packet_create_t *mp;
18897   u8 *host_if_name = 0;
18898   u8 hw_addr[6];
18899   u8 random_hw_addr = 1;
18900   int ret;
18901
18902   memset (hw_addr, 0, sizeof (hw_addr));
18903
18904   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18905     {
18906       if (unformat (i, "name %s", &host_if_name))
18907         vec_add1 (host_if_name, 0);
18908       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18909         random_hw_addr = 0;
18910       else
18911         break;
18912     }
18913
18914   if (!vec_len (host_if_name))
18915     {
18916       errmsg ("host-interface name must be specified");
18917       return -99;
18918     }
18919
18920   if (vec_len (host_if_name) > 64)
18921     {
18922       errmsg ("host-interface name too long");
18923       return -99;
18924     }
18925
18926   M (AF_PACKET_CREATE, mp);
18927
18928   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18929   clib_memcpy (mp->hw_addr, hw_addr, 6);
18930   mp->use_random_hw_addr = random_hw_addr;
18931   vec_free (host_if_name);
18932
18933   S (mp);
18934
18935   /* *INDENT-OFF* */
18936   W2 (ret,
18937       ({
18938         if (ret == 0)
18939           fprintf (vam->ofp ? vam->ofp : stderr,
18940                    " new sw_if_index = %d\n", vam->sw_if_index);
18941       }));
18942   /* *INDENT-ON* */
18943   return ret;
18944 }
18945
18946 static int
18947 api_af_packet_delete (vat_main_t * vam)
18948 {
18949   unformat_input_t *i = vam->input;
18950   vl_api_af_packet_delete_t *mp;
18951   u8 *host_if_name = 0;
18952   int ret;
18953
18954   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18955     {
18956       if (unformat (i, "name %s", &host_if_name))
18957         vec_add1 (host_if_name, 0);
18958       else
18959         break;
18960     }
18961
18962   if (!vec_len (host_if_name))
18963     {
18964       errmsg ("host-interface name must be specified");
18965       return -99;
18966     }
18967
18968   if (vec_len (host_if_name) > 64)
18969     {
18970       errmsg ("host-interface name too long");
18971       return -99;
18972     }
18973
18974   M (AF_PACKET_DELETE, mp);
18975
18976   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18977   vec_free (host_if_name);
18978
18979   S (mp);
18980   W (ret);
18981   return ret;
18982 }
18983
18984 static int
18985 api_policer_add_del (vat_main_t * vam)
18986 {
18987   unformat_input_t *i = vam->input;
18988   vl_api_policer_add_del_t *mp;
18989   u8 is_add = 1;
18990   u8 *name = 0;
18991   u32 cir = 0;
18992   u32 eir = 0;
18993   u64 cb = 0;
18994   u64 eb = 0;
18995   u8 rate_type = 0;
18996   u8 round_type = 0;
18997   u8 type = 0;
18998   u8 color_aware = 0;
18999   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
19000   int ret;
19001
19002   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
19003   conform_action.dscp = 0;
19004   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
19005   exceed_action.dscp = 0;
19006   violate_action.action_type = SSE2_QOS_ACTION_DROP;
19007   violate_action.dscp = 0;
19008
19009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19010     {
19011       if (unformat (i, "del"))
19012         is_add = 0;
19013       else if (unformat (i, "name %s", &name))
19014         vec_add1 (name, 0);
19015       else if (unformat (i, "cir %u", &cir))
19016         ;
19017       else if (unformat (i, "eir %u", &eir))
19018         ;
19019       else if (unformat (i, "cb %u", &cb))
19020         ;
19021       else if (unformat (i, "eb %u", &eb))
19022         ;
19023       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
19024                          &rate_type))
19025         ;
19026       else if (unformat (i, "round_type %U", unformat_policer_round_type,
19027                          &round_type))
19028         ;
19029       else if (unformat (i, "type %U", unformat_policer_type, &type))
19030         ;
19031       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
19032                          &conform_action))
19033         ;
19034       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
19035                          &exceed_action))
19036         ;
19037       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
19038                          &violate_action))
19039         ;
19040       else if (unformat (i, "color-aware"))
19041         color_aware = 1;
19042       else
19043         break;
19044     }
19045
19046   if (!vec_len (name))
19047     {
19048       errmsg ("policer name must be specified");
19049       return -99;
19050     }
19051
19052   if (vec_len (name) > 64)
19053     {
19054       errmsg ("policer name too long");
19055       return -99;
19056     }
19057
19058   M (POLICER_ADD_DEL, mp);
19059
19060   clib_memcpy (mp->name, name, vec_len (name));
19061   vec_free (name);
19062   mp->is_add = is_add;
19063   mp->cir = ntohl (cir);
19064   mp->eir = ntohl (eir);
19065   mp->cb = clib_net_to_host_u64 (cb);
19066   mp->eb = clib_net_to_host_u64 (eb);
19067   mp->rate_type = rate_type;
19068   mp->round_type = round_type;
19069   mp->type = type;
19070   mp->conform_action_type = conform_action.action_type;
19071   mp->conform_dscp = conform_action.dscp;
19072   mp->exceed_action_type = exceed_action.action_type;
19073   mp->exceed_dscp = exceed_action.dscp;
19074   mp->violate_action_type = violate_action.action_type;
19075   mp->violate_dscp = violate_action.dscp;
19076   mp->color_aware = color_aware;
19077
19078   S (mp);
19079   W (ret);
19080   return ret;
19081 }
19082
19083 static int
19084 api_policer_dump (vat_main_t * vam)
19085 {
19086   unformat_input_t *i = vam->input;
19087   vl_api_policer_dump_t *mp;
19088   vl_api_control_ping_t *mp_ping;
19089   u8 *match_name = 0;
19090   u8 match_name_valid = 0;
19091   int ret;
19092
19093   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19094     {
19095       if (unformat (i, "name %s", &match_name))
19096         {
19097           vec_add1 (match_name, 0);
19098           match_name_valid = 1;
19099         }
19100       else
19101         break;
19102     }
19103
19104   M (POLICER_DUMP, mp);
19105   mp->match_name_valid = match_name_valid;
19106   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
19107   vec_free (match_name);
19108   /* send it... */
19109   S (mp);
19110
19111   /* Use a control ping for synchronization */
19112   MPING (CONTROL_PING, mp_ping);
19113   S (mp_ping);
19114
19115   /* Wait for a reply... */
19116   W (ret);
19117   return ret;
19118 }
19119
19120 static int
19121 api_policer_classify_set_interface (vat_main_t * vam)
19122 {
19123   unformat_input_t *i = vam->input;
19124   vl_api_policer_classify_set_interface_t *mp;
19125   u32 sw_if_index;
19126   int sw_if_index_set;
19127   u32 ip4_table_index = ~0;
19128   u32 ip6_table_index = ~0;
19129   u32 l2_table_index = ~0;
19130   u8 is_add = 1;
19131   int ret;
19132
19133   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19134     {
19135       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19136         sw_if_index_set = 1;
19137       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19138         sw_if_index_set = 1;
19139       else if (unformat (i, "del"))
19140         is_add = 0;
19141       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19142         ;
19143       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19144         ;
19145       else if (unformat (i, "l2-table %d", &l2_table_index))
19146         ;
19147       else
19148         {
19149           clib_warning ("parse error '%U'", format_unformat_error, i);
19150           return -99;
19151         }
19152     }
19153
19154   if (sw_if_index_set == 0)
19155     {
19156       errmsg ("missing interface name or sw_if_index");
19157       return -99;
19158     }
19159
19160   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
19161
19162   mp->sw_if_index = ntohl (sw_if_index);
19163   mp->ip4_table_index = ntohl (ip4_table_index);
19164   mp->ip6_table_index = ntohl (ip6_table_index);
19165   mp->l2_table_index = ntohl (l2_table_index);
19166   mp->is_add = is_add;
19167
19168   S (mp);
19169   W (ret);
19170   return ret;
19171 }
19172
19173 static int
19174 api_policer_classify_dump (vat_main_t * vam)
19175 {
19176   unformat_input_t *i = vam->input;
19177   vl_api_policer_classify_dump_t *mp;
19178   vl_api_control_ping_t *mp_ping;
19179   u8 type = POLICER_CLASSIFY_N_TABLES;
19180   int ret;
19181
19182   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
19183     ;
19184   else
19185     {
19186       errmsg ("classify table type must be specified");
19187       return -99;
19188     }
19189
19190   if (!vam->json_output)
19191     {
19192       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19193     }
19194
19195   M (POLICER_CLASSIFY_DUMP, mp);
19196   mp->type = type;
19197   /* send it... */
19198   S (mp);
19199
19200   /* Use a control ping for synchronization */
19201   MPING (CONTROL_PING, mp_ping);
19202   S (mp_ping);
19203
19204   /* Wait for a reply... */
19205   W (ret);
19206   return ret;
19207 }
19208
19209 static int
19210 api_netmap_create (vat_main_t * vam)
19211 {
19212   unformat_input_t *i = vam->input;
19213   vl_api_netmap_create_t *mp;
19214   u8 *if_name = 0;
19215   u8 hw_addr[6];
19216   u8 random_hw_addr = 1;
19217   u8 is_pipe = 0;
19218   u8 is_master = 0;
19219   int ret;
19220
19221   memset (hw_addr, 0, sizeof (hw_addr));
19222
19223   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19224     {
19225       if (unformat (i, "name %s", &if_name))
19226         vec_add1 (if_name, 0);
19227       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
19228         random_hw_addr = 0;
19229       else if (unformat (i, "pipe"))
19230         is_pipe = 1;
19231       else if (unformat (i, "master"))
19232         is_master = 1;
19233       else if (unformat (i, "slave"))
19234         is_master = 0;
19235       else
19236         break;
19237     }
19238
19239   if (!vec_len (if_name))
19240     {
19241       errmsg ("interface name must be specified");
19242       return -99;
19243     }
19244
19245   if (vec_len (if_name) > 64)
19246     {
19247       errmsg ("interface name too long");
19248       return -99;
19249     }
19250
19251   M (NETMAP_CREATE, mp);
19252
19253   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19254   clib_memcpy (mp->hw_addr, hw_addr, 6);
19255   mp->use_random_hw_addr = random_hw_addr;
19256   mp->is_pipe = is_pipe;
19257   mp->is_master = is_master;
19258   vec_free (if_name);
19259
19260   S (mp);
19261   W (ret);
19262   return ret;
19263 }
19264
19265 static int
19266 api_netmap_delete (vat_main_t * vam)
19267 {
19268   unformat_input_t *i = vam->input;
19269   vl_api_netmap_delete_t *mp;
19270   u8 *if_name = 0;
19271   int ret;
19272
19273   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19274     {
19275       if (unformat (i, "name %s", &if_name))
19276         vec_add1 (if_name, 0);
19277       else
19278         break;
19279     }
19280
19281   if (!vec_len (if_name))
19282     {
19283       errmsg ("interface name must be specified");
19284       return -99;
19285     }
19286
19287   if (vec_len (if_name) > 64)
19288     {
19289       errmsg ("interface name too long");
19290       return -99;
19291     }
19292
19293   M (NETMAP_DELETE, mp);
19294
19295   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
19296   vec_free (if_name);
19297
19298   S (mp);
19299   W (ret);
19300   return ret;
19301 }
19302
19303 static void
19304 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
19305 {
19306   if (fp->afi == IP46_TYPE_IP6)
19307     print (vam->ofp,
19308            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19309            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19310            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19311            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19312            format_ip6_address, fp->next_hop);
19313   else if (fp->afi == IP46_TYPE_IP4)
19314     print (vam->ofp,
19315            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19316            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19317            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19318            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19319            format_ip4_address, fp->next_hop);
19320 }
19321
19322 static void
19323 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
19324                                  vl_api_fib_path2_t * fp)
19325 {
19326   struct in_addr ip4;
19327   struct in6_addr ip6;
19328
19329   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19330   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19331   vat_json_object_add_uint (node, "is_local", fp->is_local);
19332   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19333   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19334   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19335   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19336   if (fp->afi == IP46_TYPE_IP4)
19337     {
19338       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19339       vat_json_object_add_ip4 (node, "next_hop", ip4);
19340     }
19341   else if (fp->afi == IP46_TYPE_IP6)
19342     {
19343       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19344       vat_json_object_add_ip6 (node, "next_hop", ip6);
19345     }
19346 }
19347
19348 static void
19349 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
19350 {
19351   vat_main_t *vam = &vat_main;
19352   int count = ntohl (mp->mt_count);
19353   vl_api_fib_path2_t *fp;
19354   i32 i;
19355
19356   print (vam->ofp, "[%d]: sw_if_index %d via:",
19357          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
19358   fp = mp->mt_paths;
19359   for (i = 0; i < count; i++)
19360     {
19361       vl_api_mpls_fib_path_print (vam, fp);
19362       fp++;
19363     }
19364
19365   print (vam->ofp, "");
19366 }
19367
19368 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
19369 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
19370
19371 static void
19372 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
19373 {
19374   vat_main_t *vam = &vat_main;
19375   vat_json_node_t *node = NULL;
19376   int count = ntohl (mp->mt_count);
19377   vl_api_fib_path2_t *fp;
19378   i32 i;
19379
19380   if (VAT_JSON_ARRAY != vam->json_tree.type)
19381     {
19382       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19383       vat_json_init_array (&vam->json_tree);
19384     }
19385   node = vat_json_array_add (&vam->json_tree);
19386
19387   vat_json_init_object (node);
19388   vat_json_object_add_uint (node, "tunnel_index",
19389                             ntohl (mp->mt_tunnel_index));
19390   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
19391
19392   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
19393
19394   fp = mp->mt_paths;
19395   for (i = 0; i < count; i++)
19396     {
19397       vl_api_mpls_fib_path_json_print (node, fp);
19398       fp++;
19399     }
19400 }
19401
19402 static int
19403 api_mpls_tunnel_dump (vat_main_t * vam)
19404 {
19405   vl_api_mpls_tunnel_dump_t *mp;
19406   vl_api_control_ping_t *mp_ping;
19407   i32 index = -1;
19408   int ret;
19409
19410   /* Parse args required to build the message */
19411   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
19412     {
19413       if (!unformat (vam->input, "tunnel_index %d", &index))
19414         {
19415           index = -1;
19416           break;
19417         }
19418     }
19419
19420   print (vam->ofp, "  tunnel_index %d", index);
19421
19422   M (MPLS_TUNNEL_DUMP, mp);
19423   mp->tunnel_index = htonl (index);
19424   S (mp);
19425
19426   /* Use a control ping for synchronization */
19427   MPING (CONTROL_PING, mp_ping);
19428   S (mp_ping);
19429
19430   W (ret);
19431   return ret;
19432 }
19433
19434 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
19435 #define vl_api_mpls_fib_details_t_print vl_noop_handler
19436
19437
19438 static void
19439 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
19440 {
19441   vat_main_t *vam = &vat_main;
19442   int count = ntohl (mp->count);
19443   vl_api_fib_path2_t *fp;
19444   int i;
19445
19446   print (vam->ofp,
19447          "table-id %d, label %u, ess_bit %u",
19448          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
19449   fp = mp->path;
19450   for (i = 0; i < count; i++)
19451     {
19452       vl_api_mpls_fib_path_print (vam, fp);
19453       fp++;
19454     }
19455 }
19456
19457 static void vl_api_mpls_fib_details_t_handler_json
19458   (vl_api_mpls_fib_details_t * mp)
19459 {
19460   vat_main_t *vam = &vat_main;
19461   int count = ntohl (mp->count);
19462   vat_json_node_t *node = NULL;
19463   vl_api_fib_path2_t *fp;
19464   int i;
19465
19466   if (VAT_JSON_ARRAY != vam->json_tree.type)
19467     {
19468       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19469       vat_json_init_array (&vam->json_tree);
19470     }
19471   node = vat_json_array_add (&vam->json_tree);
19472
19473   vat_json_init_object (node);
19474   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19475   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
19476   vat_json_object_add_uint (node, "label", ntohl (mp->label));
19477   vat_json_object_add_uint (node, "path_count", count);
19478   fp = mp->path;
19479   for (i = 0; i < count; i++)
19480     {
19481       vl_api_mpls_fib_path_json_print (node, fp);
19482       fp++;
19483     }
19484 }
19485
19486 static int
19487 api_mpls_fib_dump (vat_main_t * vam)
19488 {
19489   vl_api_mpls_fib_dump_t *mp;
19490   vl_api_control_ping_t *mp_ping;
19491   int ret;
19492
19493   M (MPLS_FIB_DUMP, mp);
19494   S (mp);
19495
19496   /* Use a control ping for synchronization */
19497   MPING (CONTROL_PING, mp_ping);
19498   S (mp_ping);
19499
19500   W (ret);
19501   return ret;
19502 }
19503
19504 #define vl_api_ip_fib_details_t_endian vl_noop_handler
19505 #define vl_api_ip_fib_details_t_print vl_noop_handler
19506
19507 static void
19508 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
19509 {
19510   vat_main_t *vam = &vat_main;
19511   int count = ntohl (mp->count);
19512   vl_api_fib_path_t *fp;
19513   int i;
19514
19515   print (vam->ofp,
19516          "table-id %d, prefix %U/%d",
19517          ntohl (mp->table_id), format_ip4_address, mp->address,
19518          mp->address_length);
19519   fp = mp->path;
19520   for (i = 0; i < count; i++)
19521     {
19522       if (fp->afi == IP46_TYPE_IP6)
19523         print (vam->ofp,
19524                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19525                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19526                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19527                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19528                format_ip6_address, fp->next_hop);
19529       else if (fp->afi == IP46_TYPE_IP4)
19530         print (vam->ofp,
19531                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19532                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19533                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19534                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19535                format_ip4_address, fp->next_hop);
19536       fp++;
19537     }
19538 }
19539
19540 static void vl_api_ip_fib_details_t_handler_json
19541   (vl_api_ip_fib_details_t * mp)
19542 {
19543   vat_main_t *vam = &vat_main;
19544   int count = ntohl (mp->count);
19545   vat_json_node_t *node = NULL;
19546   struct in_addr ip4;
19547   struct in6_addr ip6;
19548   vl_api_fib_path_t *fp;
19549   int i;
19550
19551   if (VAT_JSON_ARRAY != vam->json_tree.type)
19552     {
19553       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19554       vat_json_init_array (&vam->json_tree);
19555     }
19556   node = vat_json_array_add (&vam->json_tree);
19557
19558   vat_json_init_object (node);
19559   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19560   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
19561   vat_json_object_add_ip4 (node, "prefix", ip4);
19562   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19563   vat_json_object_add_uint (node, "path_count", count);
19564   fp = mp->path;
19565   for (i = 0; i < count; i++)
19566     {
19567       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19568       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19569       vat_json_object_add_uint (node, "is_local", fp->is_local);
19570       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19571       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19572       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19573       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19574       if (fp->afi == IP46_TYPE_IP4)
19575         {
19576           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19577           vat_json_object_add_ip4 (node, "next_hop", ip4);
19578         }
19579       else if (fp->afi == IP46_TYPE_IP6)
19580         {
19581           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19582           vat_json_object_add_ip6 (node, "next_hop", ip6);
19583         }
19584     }
19585 }
19586
19587 static int
19588 api_ip_fib_dump (vat_main_t * vam)
19589 {
19590   vl_api_ip_fib_dump_t *mp;
19591   vl_api_control_ping_t *mp_ping;
19592   int ret;
19593
19594   M (IP_FIB_DUMP, mp);
19595   S (mp);
19596
19597   /* Use a control ping for synchronization */
19598   MPING (CONTROL_PING, mp_ping);
19599   S (mp_ping);
19600
19601   W (ret);
19602   return ret;
19603 }
19604
19605 static int
19606 api_ip_mfib_dump (vat_main_t * vam)
19607 {
19608   vl_api_ip_mfib_dump_t *mp;
19609   vl_api_control_ping_t *mp_ping;
19610   int ret;
19611
19612   M (IP_MFIB_DUMP, mp);
19613   S (mp);
19614
19615   /* Use a control ping for synchronization */
19616   MPING (CONTROL_PING, mp_ping);
19617   S (mp_ping);
19618
19619   W (ret);
19620   return ret;
19621 }
19622
19623 static void vl_api_ip_neighbor_details_t_handler
19624   (vl_api_ip_neighbor_details_t * mp)
19625 {
19626   vat_main_t *vam = &vat_main;
19627
19628   print (vam->ofp, "%c %U %U",
19629          (mp->is_static) ? 'S' : 'D',
19630          format_ethernet_address, &mp->mac_address,
19631          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
19632          &mp->ip_address);
19633 }
19634
19635 static void vl_api_ip_neighbor_details_t_handler_json
19636   (vl_api_ip_neighbor_details_t * mp)
19637 {
19638
19639   vat_main_t *vam = &vat_main;
19640   vat_json_node_t *node;
19641   struct in_addr ip4;
19642   struct in6_addr ip6;
19643
19644   if (VAT_JSON_ARRAY != vam->json_tree.type)
19645     {
19646       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19647       vat_json_init_array (&vam->json_tree);
19648     }
19649   node = vat_json_array_add (&vam->json_tree);
19650
19651   vat_json_init_object (node);
19652   vat_json_object_add_string_copy (node, "flag",
19653                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
19654                                    "dynamic");
19655
19656   vat_json_object_add_string_copy (node, "link_layer",
19657                                    format (0, "%U", format_ethernet_address,
19658                                            &mp->mac_address));
19659
19660   if (mp->is_ipv6)
19661     {
19662       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
19663       vat_json_object_add_ip6 (node, "ip_address", ip6);
19664     }
19665   else
19666     {
19667       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
19668       vat_json_object_add_ip4 (node, "ip_address", ip4);
19669     }
19670 }
19671
19672 static int
19673 api_ip_neighbor_dump (vat_main_t * vam)
19674 {
19675   unformat_input_t *i = vam->input;
19676   vl_api_ip_neighbor_dump_t *mp;
19677   vl_api_control_ping_t *mp_ping;
19678   u8 is_ipv6 = 0;
19679   u32 sw_if_index = ~0;
19680   int ret;
19681
19682   /* Parse args required to build the message */
19683   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19684     {
19685       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19686         ;
19687       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19688         ;
19689       else if (unformat (i, "ip6"))
19690         is_ipv6 = 1;
19691       else
19692         break;
19693     }
19694
19695   if (sw_if_index == ~0)
19696     {
19697       errmsg ("missing interface name or sw_if_index");
19698       return -99;
19699     }
19700
19701   M (IP_NEIGHBOR_DUMP, mp);
19702   mp->is_ipv6 = (u8) is_ipv6;
19703   mp->sw_if_index = ntohl (sw_if_index);
19704   S (mp);
19705
19706   /* Use a control ping for synchronization */
19707   MPING (CONTROL_PING, mp_ping);
19708   S (mp_ping);
19709
19710   W (ret);
19711   return ret;
19712 }
19713
19714 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
19715 #define vl_api_ip6_fib_details_t_print vl_noop_handler
19716
19717 static void
19718 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
19719 {
19720   vat_main_t *vam = &vat_main;
19721   int count = ntohl (mp->count);
19722   vl_api_fib_path_t *fp;
19723   int i;
19724
19725   print (vam->ofp,
19726          "table-id %d, prefix %U/%d",
19727          ntohl (mp->table_id), format_ip6_address, mp->address,
19728          mp->address_length);
19729   fp = mp->path;
19730   for (i = 0; i < count; i++)
19731     {
19732       if (fp->afi == IP46_TYPE_IP6)
19733         print (vam->ofp,
19734                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19735                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19736                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19737                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19738                format_ip6_address, fp->next_hop);
19739       else if (fp->afi == IP46_TYPE_IP4)
19740         print (vam->ofp,
19741                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19742                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19743                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19744                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19745                format_ip4_address, fp->next_hop);
19746       fp++;
19747     }
19748 }
19749
19750 static void vl_api_ip6_fib_details_t_handler_json
19751   (vl_api_ip6_fib_details_t * mp)
19752 {
19753   vat_main_t *vam = &vat_main;
19754   int count = ntohl (mp->count);
19755   vat_json_node_t *node = NULL;
19756   struct in_addr ip4;
19757   struct in6_addr ip6;
19758   vl_api_fib_path_t *fp;
19759   int i;
19760
19761   if (VAT_JSON_ARRAY != vam->json_tree.type)
19762     {
19763       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19764       vat_json_init_array (&vam->json_tree);
19765     }
19766   node = vat_json_array_add (&vam->json_tree);
19767
19768   vat_json_init_object (node);
19769   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19770   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
19771   vat_json_object_add_ip6 (node, "prefix", ip6);
19772   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19773   vat_json_object_add_uint (node, "path_count", count);
19774   fp = mp->path;
19775   for (i = 0; i < count; i++)
19776     {
19777       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19778       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19779       vat_json_object_add_uint (node, "is_local", fp->is_local);
19780       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19781       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19782       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19783       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19784       if (fp->afi == IP46_TYPE_IP4)
19785         {
19786           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19787           vat_json_object_add_ip4 (node, "next_hop", ip4);
19788         }
19789       else if (fp->afi == IP46_TYPE_IP6)
19790         {
19791           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19792           vat_json_object_add_ip6 (node, "next_hop", ip6);
19793         }
19794     }
19795 }
19796
19797 static int
19798 api_ip6_fib_dump (vat_main_t * vam)
19799 {
19800   vl_api_ip6_fib_dump_t *mp;
19801   vl_api_control_ping_t *mp_ping;
19802   int ret;
19803
19804   M (IP6_FIB_DUMP, mp);
19805   S (mp);
19806
19807   /* Use a control ping for synchronization */
19808   MPING (CONTROL_PING, mp_ping);
19809   S (mp_ping);
19810
19811   W (ret);
19812   return ret;
19813 }
19814
19815 static int
19816 api_ip6_mfib_dump (vat_main_t * vam)
19817 {
19818   vl_api_ip6_mfib_dump_t *mp;
19819   vl_api_control_ping_t *mp_ping;
19820   int ret;
19821
19822   M (IP6_MFIB_DUMP, mp);
19823   S (mp);
19824
19825   /* Use a control ping for synchronization */
19826   MPING (CONTROL_PING, mp_ping);
19827   S (mp_ping);
19828
19829   W (ret);
19830   return ret;
19831 }
19832
19833 int
19834 api_classify_table_ids (vat_main_t * vam)
19835 {
19836   vl_api_classify_table_ids_t *mp;
19837   int ret;
19838
19839   /* Construct the API message */
19840   M (CLASSIFY_TABLE_IDS, mp);
19841   mp->context = 0;
19842
19843   S (mp);
19844   W (ret);
19845   return ret;
19846 }
19847
19848 int
19849 api_classify_table_by_interface (vat_main_t * vam)
19850 {
19851   unformat_input_t *input = vam->input;
19852   vl_api_classify_table_by_interface_t *mp;
19853
19854   u32 sw_if_index = ~0;
19855   int ret;
19856   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19857     {
19858       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19859         ;
19860       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19861         ;
19862       else
19863         break;
19864     }
19865   if (sw_if_index == ~0)
19866     {
19867       errmsg ("missing interface name or sw_if_index");
19868       return -99;
19869     }
19870
19871   /* Construct the API message */
19872   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19873   mp->context = 0;
19874   mp->sw_if_index = ntohl (sw_if_index);
19875
19876   S (mp);
19877   W (ret);
19878   return ret;
19879 }
19880
19881 int
19882 api_classify_table_info (vat_main_t * vam)
19883 {
19884   unformat_input_t *input = vam->input;
19885   vl_api_classify_table_info_t *mp;
19886
19887   u32 table_id = ~0;
19888   int ret;
19889   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19890     {
19891       if (unformat (input, "table_id %d", &table_id))
19892         ;
19893       else
19894         break;
19895     }
19896   if (table_id == ~0)
19897     {
19898       errmsg ("missing table id");
19899       return -99;
19900     }
19901
19902   /* Construct the API message */
19903   M (CLASSIFY_TABLE_INFO, mp);
19904   mp->context = 0;
19905   mp->table_id = ntohl (table_id);
19906
19907   S (mp);
19908   W (ret);
19909   return ret;
19910 }
19911
19912 int
19913 api_classify_session_dump (vat_main_t * vam)
19914 {
19915   unformat_input_t *input = vam->input;
19916   vl_api_classify_session_dump_t *mp;
19917   vl_api_control_ping_t *mp_ping;
19918
19919   u32 table_id = ~0;
19920   int ret;
19921   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19922     {
19923       if (unformat (input, "table_id %d", &table_id))
19924         ;
19925       else
19926         break;
19927     }
19928   if (table_id == ~0)
19929     {
19930       errmsg ("missing table id");
19931       return -99;
19932     }
19933
19934   /* Construct the API message */
19935   M (CLASSIFY_SESSION_DUMP, mp);
19936   mp->context = 0;
19937   mp->table_id = ntohl (table_id);
19938   S (mp);
19939
19940   /* Use a control ping for synchronization */
19941   MPING (CONTROL_PING, mp_ping);
19942   S (mp_ping);
19943
19944   W (ret);
19945   return ret;
19946 }
19947
19948 static void
19949 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19950 {
19951   vat_main_t *vam = &vat_main;
19952
19953   print (vam->ofp, "collector_address %U, collector_port %d, "
19954          "src_address %U, vrf_id %d, path_mtu %u, "
19955          "template_interval %u, udp_checksum %d",
19956          format_ip4_address, mp->collector_address,
19957          ntohs (mp->collector_port),
19958          format_ip4_address, mp->src_address,
19959          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19960          ntohl (mp->template_interval), mp->udp_checksum);
19961
19962   vam->retval = 0;
19963   vam->result_ready = 1;
19964 }
19965
19966 static void
19967   vl_api_ipfix_exporter_details_t_handler_json
19968   (vl_api_ipfix_exporter_details_t * mp)
19969 {
19970   vat_main_t *vam = &vat_main;
19971   vat_json_node_t node;
19972   struct in_addr collector_address;
19973   struct in_addr src_address;
19974
19975   vat_json_init_object (&node);
19976   clib_memcpy (&collector_address, &mp->collector_address,
19977                sizeof (collector_address));
19978   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19979   vat_json_object_add_uint (&node, "collector_port",
19980                             ntohs (mp->collector_port));
19981   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19982   vat_json_object_add_ip4 (&node, "src_address", src_address);
19983   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19984   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19985   vat_json_object_add_uint (&node, "template_interval",
19986                             ntohl (mp->template_interval));
19987   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19988
19989   vat_json_print (vam->ofp, &node);
19990   vat_json_free (&node);
19991   vam->retval = 0;
19992   vam->result_ready = 1;
19993 }
19994
19995 int
19996 api_ipfix_exporter_dump (vat_main_t * vam)
19997 {
19998   vl_api_ipfix_exporter_dump_t *mp;
19999   int ret;
20000
20001   /* Construct the API message */
20002   M (IPFIX_EXPORTER_DUMP, mp);
20003   mp->context = 0;
20004
20005   S (mp);
20006   W (ret);
20007   return ret;
20008 }
20009
20010 static int
20011 api_ipfix_classify_stream_dump (vat_main_t * vam)
20012 {
20013   vl_api_ipfix_classify_stream_dump_t *mp;
20014   int ret;
20015
20016   /* Construct the API message */
20017   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
20018   mp->context = 0;
20019
20020   S (mp);
20021   W (ret);
20022   return ret;
20023   /* NOTREACHED */
20024   return 0;
20025 }
20026
20027 static void
20028   vl_api_ipfix_classify_stream_details_t_handler
20029   (vl_api_ipfix_classify_stream_details_t * mp)
20030 {
20031   vat_main_t *vam = &vat_main;
20032   print (vam->ofp, "domain_id %d, src_port %d",
20033          ntohl (mp->domain_id), ntohs (mp->src_port));
20034   vam->retval = 0;
20035   vam->result_ready = 1;
20036 }
20037
20038 static void
20039   vl_api_ipfix_classify_stream_details_t_handler_json
20040   (vl_api_ipfix_classify_stream_details_t * mp)
20041 {
20042   vat_main_t *vam = &vat_main;
20043   vat_json_node_t node;
20044
20045   vat_json_init_object (&node);
20046   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
20047   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
20048
20049   vat_json_print (vam->ofp, &node);
20050   vat_json_free (&node);
20051   vam->retval = 0;
20052   vam->result_ready = 1;
20053 }
20054
20055 static int
20056 api_ipfix_classify_table_dump (vat_main_t * vam)
20057 {
20058   vl_api_ipfix_classify_table_dump_t *mp;
20059   vl_api_control_ping_t *mp_ping;
20060   int ret;
20061
20062   if (!vam->json_output)
20063     {
20064       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
20065              "transport_protocol");
20066     }
20067
20068   /* Construct the API message */
20069   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
20070
20071   /* send it... */
20072   S (mp);
20073
20074   /* Use a control ping for synchronization */
20075   MPING (CONTROL_PING, mp_ping);
20076   S (mp_ping);
20077
20078   W (ret);
20079   return ret;
20080 }
20081
20082 static void
20083   vl_api_ipfix_classify_table_details_t_handler
20084   (vl_api_ipfix_classify_table_details_t * mp)
20085 {
20086   vat_main_t *vam = &vat_main;
20087   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
20088          mp->transport_protocol);
20089 }
20090
20091 static void
20092   vl_api_ipfix_classify_table_details_t_handler_json
20093   (vl_api_ipfix_classify_table_details_t * mp)
20094 {
20095   vat_json_node_t *node = NULL;
20096   vat_main_t *vam = &vat_main;
20097
20098   if (VAT_JSON_ARRAY != vam->json_tree.type)
20099     {
20100       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20101       vat_json_init_array (&vam->json_tree);
20102     }
20103
20104   node = vat_json_array_add (&vam->json_tree);
20105   vat_json_init_object (node);
20106
20107   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
20108   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
20109   vat_json_object_add_uint (node, "transport_protocol",
20110                             mp->transport_protocol);
20111 }
20112
20113 static int
20114 api_sw_interface_span_enable_disable (vat_main_t * vam)
20115 {
20116   unformat_input_t *i = vam->input;
20117   vl_api_sw_interface_span_enable_disable_t *mp;
20118   u32 src_sw_if_index = ~0;
20119   u32 dst_sw_if_index = ~0;
20120   u8 state = 3;
20121   int ret;
20122   u8 is_l2 = 0;
20123
20124   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20125     {
20126       if (unformat
20127           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
20128         ;
20129       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
20130         ;
20131       else
20132         if (unformat
20133             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
20134         ;
20135       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
20136         ;
20137       else if (unformat (i, "disable"))
20138         state = 0;
20139       else if (unformat (i, "rx"))
20140         state = 1;
20141       else if (unformat (i, "tx"))
20142         state = 2;
20143       else if (unformat (i, "both"))
20144         state = 3;
20145       else if (unformat (i, "l2"))
20146         is_l2 = 1;
20147       else
20148         break;
20149     }
20150
20151   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
20152
20153   mp->sw_if_index_from = htonl (src_sw_if_index);
20154   mp->sw_if_index_to = htonl (dst_sw_if_index);
20155   mp->state = state;
20156   mp->is_l2 = is_l2;
20157
20158   S (mp);
20159   W (ret);
20160   return ret;
20161 }
20162
20163 static void
20164 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
20165                                             * mp)
20166 {
20167   vat_main_t *vam = &vat_main;
20168   u8 *sw_if_from_name = 0;
20169   u8 *sw_if_to_name = 0;
20170   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20171   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20172   char *states[] = { "none", "rx", "tx", "both" };
20173   hash_pair_t *p;
20174
20175   /* *INDENT-OFF* */
20176   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20177   ({
20178     if ((u32) p->value[0] == sw_if_index_from)
20179       {
20180         sw_if_from_name = (u8 *)(p->key);
20181         if (sw_if_to_name)
20182           break;
20183       }
20184     if ((u32) p->value[0] == sw_if_index_to)
20185       {
20186         sw_if_to_name = (u8 *)(p->key);
20187         if (sw_if_from_name)
20188           break;
20189       }
20190   }));
20191   /* *INDENT-ON* */
20192   print (vam->ofp, "%20s => %20s (%s)",
20193          sw_if_from_name, sw_if_to_name, states[mp->state]);
20194 }
20195
20196 static void
20197   vl_api_sw_interface_span_details_t_handler_json
20198   (vl_api_sw_interface_span_details_t * mp)
20199 {
20200   vat_main_t *vam = &vat_main;
20201   vat_json_node_t *node = NULL;
20202   u8 *sw_if_from_name = 0;
20203   u8 *sw_if_to_name = 0;
20204   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
20205   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
20206   hash_pair_t *p;
20207
20208   /* *INDENT-OFF* */
20209   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
20210   ({
20211     if ((u32) p->value[0] == sw_if_index_from)
20212       {
20213         sw_if_from_name = (u8 *)(p->key);
20214         if (sw_if_to_name)
20215           break;
20216       }
20217     if ((u32) p->value[0] == sw_if_index_to)
20218       {
20219         sw_if_to_name = (u8 *)(p->key);
20220         if (sw_if_from_name)
20221           break;
20222       }
20223   }));
20224   /* *INDENT-ON* */
20225
20226   if (VAT_JSON_ARRAY != vam->json_tree.type)
20227     {
20228       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20229       vat_json_init_array (&vam->json_tree);
20230     }
20231   node = vat_json_array_add (&vam->json_tree);
20232
20233   vat_json_init_object (node);
20234   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
20235   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
20236   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
20237   if (0 != sw_if_to_name)
20238     {
20239       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
20240     }
20241   vat_json_object_add_uint (node, "state", mp->state);
20242 }
20243
20244 static int
20245 api_sw_interface_span_dump (vat_main_t * vam)
20246 {
20247   unformat_input_t *input = vam->input;
20248   vl_api_sw_interface_span_dump_t *mp;
20249   vl_api_control_ping_t *mp_ping;
20250   u8 is_l2 = 0;
20251   int ret;
20252
20253   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20254     {
20255       if (unformat (input, "l2"))
20256         is_l2 = 1;
20257       else
20258         break;
20259     }
20260
20261   M (SW_INTERFACE_SPAN_DUMP, mp);
20262   mp->is_l2 = is_l2;
20263   S (mp);
20264
20265   /* Use a control ping for synchronization */
20266   MPING (CONTROL_PING, mp_ping);
20267   S (mp_ping);
20268
20269   W (ret);
20270   return ret;
20271 }
20272
20273 int
20274 api_pg_create_interface (vat_main_t * vam)
20275 {
20276   unformat_input_t *input = vam->input;
20277   vl_api_pg_create_interface_t *mp;
20278
20279   u32 if_id = ~0;
20280   int ret;
20281   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20282     {
20283       if (unformat (input, "if_id %d", &if_id))
20284         ;
20285       else
20286         break;
20287     }
20288   if (if_id == ~0)
20289     {
20290       errmsg ("missing pg interface index");
20291       return -99;
20292     }
20293
20294   /* Construct the API message */
20295   M (PG_CREATE_INTERFACE, mp);
20296   mp->context = 0;
20297   mp->interface_id = ntohl (if_id);
20298
20299   S (mp);
20300   W (ret);
20301   return ret;
20302 }
20303
20304 int
20305 api_pg_capture (vat_main_t * vam)
20306 {
20307   unformat_input_t *input = vam->input;
20308   vl_api_pg_capture_t *mp;
20309
20310   u32 if_id = ~0;
20311   u8 enable = 1;
20312   u32 count = 1;
20313   u8 pcap_file_set = 0;
20314   u8 *pcap_file = 0;
20315   int ret;
20316   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20317     {
20318       if (unformat (input, "if_id %d", &if_id))
20319         ;
20320       else if (unformat (input, "pcap %s", &pcap_file))
20321         pcap_file_set = 1;
20322       else if (unformat (input, "count %d", &count))
20323         ;
20324       else if (unformat (input, "disable"))
20325         enable = 0;
20326       else
20327         break;
20328     }
20329   if (if_id == ~0)
20330     {
20331       errmsg ("missing pg interface index");
20332       return -99;
20333     }
20334   if (pcap_file_set > 0)
20335     {
20336       if (vec_len (pcap_file) > 255)
20337         {
20338           errmsg ("pcap file name is too long");
20339           return -99;
20340         }
20341     }
20342
20343   u32 name_len = vec_len (pcap_file);
20344   /* Construct the API message */
20345   M (PG_CAPTURE, mp);
20346   mp->context = 0;
20347   mp->interface_id = ntohl (if_id);
20348   mp->is_enabled = enable;
20349   mp->count = ntohl (count);
20350   mp->pcap_name_length = ntohl (name_len);
20351   if (pcap_file_set != 0)
20352     {
20353       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
20354     }
20355   vec_free (pcap_file);
20356
20357   S (mp);
20358   W (ret);
20359   return ret;
20360 }
20361
20362 int
20363 api_pg_enable_disable (vat_main_t * vam)
20364 {
20365   unformat_input_t *input = vam->input;
20366   vl_api_pg_enable_disable_t *mp;
20367
20368   u8 enable = 1;
20369   u8 stream_name_set = 0;
20370   u8 *stream_name = 0;
20371   int ret;
20372   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20373     {
20374       if (unformat (input, "stream %s", &stream_name))
20375         stream_name_set = 1;
20376       else if (unformat (input, "disable"))
20377         enable = 0;
20378       else
20379         break;
20380     }
20381
20382   if (stream_name_set > 0)
20383     {
20384       if (vec_len (stream_name) > 255)
20385         {
20386           errmsg ("stream name too long");
20387           return -99;
20388         }
20389     }
20390
20391   u32 name_len = vec_len (stream_name);
20392   /* Construct the API message */
20393   M (PG_ENABLE_DISABLE, mp);
20394   mp->context = 0;
20395   mp->is_enabled = enable;
20396   if (stream_name_set != 0)
20397     {
20398       mp->stream_name_length = ntohl (name_len);
20399       clib_memcpy (mp->stream_name, stream_name, name_len);
20400     }
20401   vec_free (stream_name);
20402
20403   S (mp);
20404   W (ret);
20405   return ret;
20406 }
20407
20408 int
20409 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
20410 {
20411   unformat_input_t *input = vam->input;
20412   vl_api_ip_source_and_port_range_check_add_del_t *mp;
20413
20414   u16 *low_ports = 0;
20415   u16 *high_ports = 0;
20416   u16 this_low;
20417   u16 this_hi;
20418   ip4_address_t ip4_addr;
20419   ip6_address_t ip6_addr;
20420   u32 length;
20421   u32 tmp, tmp2;
20422   u8 prefix_set = 0;
20423   u32 vrf_id = ~0;
20424   u8 is_add = 1;
20425   u8 is_ipv6 = 0;
20426   int ret;
20427
20428   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20429     {
20430       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
20431         {
20432           prefix_set = 1;
20433         }
20434       else
20435         if (unformat
20436             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
20437         {
20438           prefix_set = 1;
20439           is_ipv6 = 1;
20440         }
20441       else if (unformat (input, "vrf %d", &vrf_id))
20442         ;
20443       else if (unformat (input, "del"))
20444         is_add = 0;
20445       else if (unformat (input, "port %d", &tmp))
20446         {
20447           if (tmp == 0 || tmp > 65535)
20448             {
20449               errmsg ("port %d out of range", tmp);
20450               return -99;
20451             }
20452           this_low = tmp;
20453           this_hi = this_low + 1;
20454           vec_add1 (low_ports, this_low);
20455           vec_add1 (high_ports, this_hi);
20456         }
20457       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
20458         {
20459           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
20460             {
20461               errmsg ("incorrect range parameters");
20462               return -99;
20463             }
20464           this_low = tmp;
20465           /* Note: in debug CLI +1 is added to high before
20466              passing to real fn that does "the work"
20467              (ip_source_and_port_range_check_add_del).
20468              This fn is a wrapper around the binary API fn a
20469              control plane will call, which expects this increment
20470              to have occurred. Hence letting the binary API control
20471              plane fn do the increment for consistency between VAT
20472              and other control planes.
20473            */
20474           this_hi = tmp2;
20475           vec_add1 (low_ports, this_low);
20476           vec_add1 (high_ports, this_hi);
20477         }
20478       else
20479         break;
20480     }
20481
20482   if (prefix_set == 0)
20483     {
20484       errmsg ("<address>/<mask> not specified");
20485       return -99;
20486     }
20487
20488   if (vrf_id == ~0)
20489     {
20490       errmsg ("VRF ID required, not specified");
20491       return -99;
20492     }
20493
20494   if (vrf_id == 0)
20495     {
20496       errmsg
20497         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20498       return -99;
20499     }
20500
20501   if (vec_len (low_ports) == 0)
20502     {
20503       errmsg ("At least one port or port range required");
20504       return -99;
20505     }
20506
20507   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
20508
20509   mp->is_add = is_add;
20510
20511   if (is_ipv6)
20512     {
20513       mp->is_ipv6 = 1;
20514       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
20515     }
20516   else
20517     {
20518       mp->is_ipv6 = 0;
20519       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
20520     }
20521
20522   mp->mask_length = length;
20523   mp->number_of_ranges = vec_len (low_ports);
20524
20525   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
20526   vec_free (low_ports);
20527
20528   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20529   vec_free (high_ports);
20530
20531   mp->vrf_id = ntohl (vrf_id);
20532
20533   S (mp);
20534   W (ret);
20535   return ret;
20536 }
20537
20538 int
20539 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20540 {
20541   unformat_input_t *input = vam->input;
20542   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20543   u32 sw_if_index = ~0;
20544   int vrf_set = 0;
20545   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20546   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20547   u8 is_add = 1;
20548   int ret;
20549
20550   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20551     {
20552       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20553         ;
20554       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20555         ;
20556       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20557         vrf_set = 1;
20558       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20559         vrf_set = 1;
20560       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20561         vrf_set = 1;
20562       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20563         vrf_set = 1;
20564       else if (unformat (input, "del"))
20565         is_add = 0;
20566       else
20567         break;
20568     }
20569
20570   if (sw_if_index == ~0)
20571     {
20572       errmsg ("Interface required but not specified");
20573       return -99;
20574     }
20575
20576   if (vrf_set == 0)
20577     {
20578       errmsg ("VRF ID required but not specified");
20579       return -99;
20580     }
20581
20582   if (tcp_out_vrf_id == 0
20583       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20584     {
20585       errmsg
20586         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20587       return -99;
20588     }
20589
20590   /* Construct the API message */
20591   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20592
20593   mp->sw_if_index = ntohl (sw_if_index);
20594   mp->is_add = is_add;
20595   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20596   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20597   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20598   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20599
20600   /* send it... */
20601   S (mp);
20602
20603   /* Wait for a reply... */
20604   W (ret);
20605   return ret;
20606 }
20607
20608 static int
20609 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
20610 {
20611   unformat_input_t *i = vam->input;
20612   vl_api_ipsec_gre_add_del_tunnel_t *mp;
20613   u32 local_sa_id = 0;
20614   u32 remote_sa_id = 0;
20615   ip4_address_t src_address;
20616   ip4_address_t dst_address;
20617   u8 is_add = 1;
20618   int ret;
20619
20620   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20621     {
20622       if (unformat (i, "local_sa %d", &local_sa_id))
20623         ;
20624       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20625         ;
20626       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
20627         ;
20628       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
20629         ;
20630       else if (unformat (i, "del"))
20631         is_add = 0;
20632       else
20633         {
20634           clib_warning ("parse error '%U'", format_unformat_error, i);
20635           return -99;
20636         }
20637     }
20638
20639   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
20640
20641   mp->local_sa_id = ntohl (local_sa_id);
20642   mp->remote_sa_id = ntohl (remote_sa_id);
20643   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
20644   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
20645   mp->is_add = is_add;
20646
20647   S (mp);
20648   W (ret);
20649   return ret;
20650 }
20651
20652 static int
20653 api_punt (vat_main_t * vam)
20654 {
20655   unformat_input_t *i = vam->input;
20656   vl_api_punt_t *mp;
20657   u32 ipv = ~0;
20658   u32 protocol = ~0;
20659   u32 port = ~0;
20660   int is_add = 1;
20661   int ret;
20662
20663   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20664     {
20665       if (unformat (i, "ip %d", &ipv))
20666         ;
20667       else if (unformat (i, "protocol %d", &protocol))
20668         ;
20669       else if (unformat (i, "port %d", &port))
20670         ;
20671       else if (unformat (i, "del"))
20672         is_add = 0;
20673       else
20674         {
20675           clib_warning ("parse error '%U'", format_unformat_error, i);
20676           return -99;
20677         }
20678     }
20679
20680   M (PUNT, mp);
20681
20682   mp->is_add = (u8) is_add;
20683   mp->ipv = (u8) ipv;
20684   mp->l4_protocol = (u8) protocol;
20685   mp->l4_port = htons ((u16) port);
20686
20687   S (mp);
20688   W (ret);
20689   return ret;
20690 }
20691
20692 static void vl_api_ipsec_gre_tunnel_details_t_handler
20693   (vl_api_ipsec_gre_tunnel_details_t * mp)
20694 {
20695   vat_main_t *vam = &vat_main;
20696
20697   print (vam->ofp, "%11d%15U%15U%14d%14d",
20698          ntohl (mp->sw_if_index),
20699          format_ip4_address, &mp->src_address,
20700          format_ip4_address, &mp->dst_address,
20701          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
20702 }
20703
20704 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
20705   (vl_api_ipsec_gre_tunnel_details_t * mp)
20706 {
20707   vat_main_t *vam = &vat_main;
20708   vat_json_node_t *node = NULL;
20709   struct in_addr ip4;
20710
20711   if (VAT_JSON_ARRAY != vam->json_tree.type)
20712     {
20713       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20714       vat_json_init_array (&vam->json_tree);
20715     }
20716   node = vat_json_array_add (&vam->json_tree);
20717
20718   vat_json_init_object (node);
20719   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
20720   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
20721   vat_json_object_add_ip4 (node, "src_address", ip4);
20722   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
20723   vat_json_object_add_ip4 (node, "dst_address", ip4);
20724   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
20725   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
20726 }
20727
20728 static int
20729 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
20730 {
20731   unformat_input_t *i = vam->input;
20732   vl_api_ipsec_gre_tunnel_dump_t *mp;
20733   vl_api_control_ping_t *mp_ping;
20734   u32 sw_if_index;
20735   u8 sw_if_index_set = 0;
20736   int ret;
20737
20738   /* Parse args required to build the message */
20739   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20740     {
20741       if (unformat (i, "sw_if_index %d", &sw_if_index))
20742         sw_if_index_set = 1;
20743       else
20744         break;
20745     }
20746
20747   if (sw_if_index_set == 0)
20748     {
20749       sw_if_index = ~0;
20750     }
20751
20752   if (!vam->json_output)
20753     {
20754       print (vam->ofp, "%11s%15s%15s%14s%14s",
20755              "sw_if_index", "src_address", "dst_address",
20756              "local_sa_id", "remote_sa_id");
20757     }
20758
20759   /* Get list of gre-tunnel interfaces */
20760   M (IPSEC_GRE_TUNNEL_DUMP, mp);
20761
20762   mp->sw_if_index = htonl (sw_if_index);
20763
20764   S (mp);
20765
20766   /* Use a control ping for synchronization */
20767   MPING (CONTROL_PING, mp_ping);
20768   S (mp_ping);
20769
20770   W (ret);
20771   return ret;
20772 }
20773
20774 static int
20775 api_delete_subif (vat_main_t * vam)
20776 {
20777   unformat_input_t *i = vam->input;
20778   vl_api_delete_subif_t *mp;
20779   u32 sw_if_index = ~0;
20780   int ret;
20781
20782   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20783     {
20784       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20785         ;
20786       if (unformat (i, "sw_if_index %d", &sw_if_index))
20787         ;
20788       else
20789         break;
20790     }
20791
20792   if (sw_if_index == ~0)
20793     {
20794       errmsg ("missing sw_if_index");
20795       return -99;
20796     }
20797
20798   /* Construct the API message */
20799   M (DELETE_SUBIF, mp);
20800   mp->sw_if_index = ntohl (sw_if_index);
20801
20802   S (mp);
20803   W (ret);
20804   return ret;
20805 }
20806
20807 #define foreach_pbb_vtr_op      \
20808 _("disable",  L2_VTR_DISABLED)  \
20809 _("pop",  L2_VTR_POP_2)         \
20810 _("push",  L2_VTR_PUSH_2)
20811
20812 static int
20813 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20814 {
20815   unformat_input_t *i = vam->input;
20816   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20817   u32 sw_if_index = ~0, vtr_op = ~0;
20818   u16 outer_tag = ~0;
20819   u8 dmac[6], smac[6];
20820   u8 dmac_set = 0, smac_set = 0;
20821   u16 vlanid = 0;
20822   u32 sid = ~0;
20823   u32 tmp;
20824   int ret;
20825
20826   /* Shut up coverity */
20827   memset (dmac, 0, sizeof (dmac));
20828   memset (smac, 0, sizeof (smac));
20829
20830   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20831     {
20832       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20833         ;
20834       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20835         ;
20836       else if (unformat (i, "vtr_op %d", &vtr_op))
20837         ;
20838 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20839       foreach_pbb_vtr_op
20840 #undef _
20841         else if (unformat (i, "translate_pbb_stag"))
20842         {
20843           if (unformat (i, "%d", &tmp))
20844             {
20845               vtr_op = L2_VTR_TRANSLATE_2_1;
20846               outer_tag = tmp;
20847             }
20848           else
20849             {
20850               errmsg
20851                 ("translate_pbb_stag operation requires outer tag definition");
20852               return -99;
20853             }
20854         }
20855       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20856         dmac_set++;
20857       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20858         smac_set++;
20859       else if (unformat (i, "sid %d", &sid))
20860         ;
20861       else if (unformat (i, "vlanid %d", &tmp))
20862         vlanid = tmp;
20863       else
20864         {
20865           clib_warning ("parse error '%U'", format_unformat_error, i);
20866           return -99;
20867         }
20868     }
20869
20870   if ((sw_if_index == ~0) || (vtr_op == ~0))
20871     {
20872       errmsg ("missing sw_if_index or vtr operation");
20873       return -99;
20874     }
20875   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20876       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20877     {
20878       errmsg
20879         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20880       return -99;
20881     }
20882
20883   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20884   mp->sw_if_index = ntohl (sw_if_index);
20885   mp->vtr_op = ntohl (vtr_op);
20886   mp->outer_tag = ntohs (outer_tag);
20887   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20888   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20889   mp->b_vlanid = ntohs (vlanid);
20890   mp->i_sid = ntohl (sid);
20891
20892   S (mp);
20893   W (ret);
20894   return ret;
20895 }
20896
20897 static int
20898 api_flow_classify_set_interface (vat_main_t * vam)
20899 {
20900   unformat_input_t *i = vam->input;
20901   vl_api_flow_classify_set_interface_t *mp;
20902   u32 sw_if_index;
20903   int sw_if_index_set;
20904   u32 ip4_table_index = ~0;
20905   u32 ip6_table_index = ~0;
20906   u8 is_add = 1;
20907   int ret;
20908
20909   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20910     {
20911       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20912         sw_if_index_set = 1;
20913       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20914         sw_if_index_set = 1;
20915       else if (unformat (i, "del"))
20916         is_add = 0;
20917       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20918         ;
20919       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20920         ;
20921       else
20922         {
20923           clib_warning ("parse error '%U'", format_unformat_error, i);
20924           return -99;
20925         }
20926     }
20927
20928   if (sw_if_index_set == 0)
20929     {
20930       errmsg ("missing interface name or sw_if_index");
20931       return -99;
20932     }
20933
20934   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20935
20936   mp->sw_if_index = ntohl (sw_if_index);
20937   mp->ip4_table_index = ntohl (ip4_table_index);
20938   mp->ip6_table_index = ntohl (ip6_table_index);
20939   mp->is_add = is_add;
20940
20941   S (mp);
20942   W (ret);
20943   return ret;
20944 }
20945
20946 static int
20947 api_flow_classify_dump (vat_main_t * vam)
20948 {
20949   unformat_input_t *i = vam->input;
20950   vl_api_flow_classify_dump_t *mp;
20951   vl_api_control_ping_t *mp_ping;
20952   u8 type = FLOW_CLASSIFY_N_TABLES;
20953   int ret;
20954
20955   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20956     ;
20957   else
20958     {
20959       errmsg ("classify table type must be specified");
20960       return -99;
20961     }
20962
20963   if (!vam->json_output)
20964     {
20965       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20966     }
20967
20968   M (FLOW_CLASSIFY_DUMP, mp);
20969   mp->type = type;
20970   /* send it... */
20971   S (mp);
20972
20973   /* Use a control ping for synchronization */
20974   MPING (CONTROL_PING, mp_ping);
20975   S (mp_ping);
20976
20977   /* Wait for a reply... */
20978   W (ret);
20979   return ret;
20980 }
20981
20982 static int
20983 api_feature_enable_disable (vat_main_t * vam)
20984 {
20985   unformat_input_t *i = vam->input;
20986   vl_api_feature_enable_disable_t *mp;
20987   u8 *arc_name = 0;
20988   u8 *feature_name = 0;
20989   u32 sw_if_index = ~0;
20990   u8 enable = 1;
20991   int ret;
20992
20993   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20994     {
20995       if (unformat (i, "arc_name %s", &arc_name))
20996         ;
20997       else if (unformat (i, "feature_name %s", &feature_name))
20998         ;
20999       else
21000         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21001         ;
21002       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21003         ;
21004       else if (unformat (i, "disable"))
21005         enable = 0;
21006       else
21007         break;
21008     }
21009
21010   if (arc_name == 0)
21011     {
21012       errmsg ("missing arc name");
21013       return -99;
21014     }
21015   if (vec_len (arc_name) > 63)
21016     {
21017       errmsg ("arc name too long");
21018     }
21019
21020   if (feature_name == 0)
21021     {
21022       errmsg ("missing feature name");
21023       return -99;
21024     }
21025   if (vec_len (feature_name) > 63)
21026     {
21027       errmsg ("feature name too long");
21028     }
21029
21030   if (sw_if_index == ~0)
21031     {
21032       errmsg ("missing interface name or sw_if_index");
21033       return -99;
21034     }
21035
21036   /* Construct the API message */
21037   M (FEATURE_ENABLE_DISABLE, mp);
21038   mp->sw_if_index = ntohl (sw_if_index);
21039   mp->enable = enable;
21040   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
21041   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
21042   vec_free (arc_name);
21043   vec_free (feature_name);
21044
21045   S (mp);
21046   W (ret);
21047   return ret;
21048 }
21049
21050 static int
21051 api_sw_interface_tag_add_del (vat_main_t * vam)
21052 {
21053   unformat_input_t *i = vam->input;
21054   vl_api_sw_interface_tag_add_del_t *mp;
21055   u32 sw_if_index = ~0;
21056   u8 *tag = 0;
21057   u8 enable = 1;
21058   int ret;
21059
21060   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21061     {
21062       if (unformat (i, "tag %s", &tag))
21063         ;
21064       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21065         ;
21066       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21067         ;
21068       else if (unformat (i, "del"))
21069         enable = 0;
21070       else
21071         break;
21072     }
21073
21074   if (sw_if_index == ~0)
21075     {
21076       errmsg ("missing interface name or sw_if_index");
21077       return -99;
21078     }
21079
21080   if (enable && (tag == 0))
21081     {
21082       errmsg ("no tag specified");
21083       return -99;
21084     }
21085
21086   /* Construct the API message */
21087   M (SW_INTERFACE_TAG_ADD_DEL, mp);
21088   mp->sw_if_index = ntohl (sw_if_index);
21089   mp->is_add = enable;
21090   if (enable)
21091     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
21092   vec_free (tag);
21093
21094   S (mp);
21095   W (ret);
21096   return ret;
21097 }
21098
21099 static void vl_api_l2_xconnect_details_t_handler
21100   (vl_api_l2_xconnect_details_t * mp)
21101 {
21102   vat_main_t *vam = &vat_main;
21103
21104   print (vam->ofp, "%15d%15d",
21105          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
21106 }
21107
21108 static void vl_api_l2_xconnect_details_t_handler_json
21109   (vl_api_l2_xconnect_details_t * mp)
21110 {
21111   vat_main_t *vam = &vat_main;
21112   vat_json_node_t *node = NULL;
21113
21114   if (VAT_JSON_ARRAY != vam->json_tree.type)
21115     {
21116       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21117       vat_json_init_array (&vam->json_tree);
21118     }
21119   node = vat_json_array_add (&vam->json_tree);
21120
21121   vat_json_init_object (node);
21122   vat_json_object_add_uint (node, "rx_sw_if_index",
21123                             ntohl (mp->rx_sw_if_index));
21124   vat_json_object_add_uint (node, "tx_sw_if_index",
21125                             ntohl (mp->tx_sw_if_index));
21126 }
21127
21128 static int
21129 api_l2_xconnect_dump (vat_main_t * vam)
21130 {
21131   vl_api_l2_xconnect_dump_t *mp;
21132   vl_api_control_ping_t *mp_ping;
21133   int ret;
21134
21135   if (!vam->json_output)
21136     {
21137       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
21138     }
21139
21140   M (L2_XCONNECT_DUMP, mp);
21141
21142   S (mp);
21143
21144   /* Use a control ping for synchronization */
21145   MPING (CONTROL_PING, mp_ping);
21146   S (mp_ping);
21147
21148   W (ret);
21149   return ret;
21150 }
21151
21152 static int
21153 api_sw_interface_set_mtu (vat_main_t * vam)
21154 {
21155   unformat_input_t *i = vam->input;
21156   vl_api_sw_interface_set_mtu_t *mp;
21157   u32 sw_if_index = ~0;
21158   u32 mtu = 0;
21159   int ret;
21160
21161   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21162     {
21163       if (unformat (i, "mtu %d", &mtu))
21164         ;
21165       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21166         ;
21167       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21168         ;
21169       else
21170         break;
21171     }
21172
21173   if (sw_if_index == ~0)
21174     {
21175       errmsg ("missing interface name or sw_if_index");
21176       return -99;
21177     }
21178
21179   if (mtu == 0)
21180     {
21181       errmsg ("no mtu specified");
21182       return -99;
21183     }
21184
21185   /* Construct the API message */
21186   M (SW_INTERFACE_SET_MTU, mp);
21187   mp->sw_if_index = ntohl (sw_if_index);
21188   mp->mtu = ntohs ((u16) mtu);
21189
21190   S (mp);
21191   W (ret);
21192   return ret;
21193 }
21194
21195 static int
21196 api_p2p_ethernet_add (vat_main_t * vam)
21197 {
21198   unformat_input_t *i = vam->input;
21199   vl_api_p2p_ethernet_add_t *mp;
21200   u32 parent_if_index = ~0;
21201   u32 sub_id = ~0;
21202   u8 remote_mac[6];
21203   u8 mac_set = 0;
21204   int ret;
21205
21206   memset (remote_mac, 0, sizeof (remote_mac));
21207   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21208     {
21209       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21210         ;
21211       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21212         ;
21213       else
21214         if (unformat
21215             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21216         mac_set++;
21217       else if (unformat (i, "sub_id %d", &sub_id))
21218         ;
21219       else
21220         {
21221           clib_warning ("parse error '%U'", format_unformat_error, i);
21222           return -99;
21223         }
21224     }
21225
21226   if (parent_if_index == ~0)
21227     {
21228       errmsg ("missing interface name or sw_if_index");
21229       return -99;
21230     }
21231   if (mac_set == 0)
21232     {
21233       errmsg ("missing remote mac address");
21234       return -99;
21235     }
21236   if (sub_id == ~0)
21237     {
21238       errmsg ("missing sub-interface id");
21239       return -99;
21240     }
21241
21242   M (P2P_ETHERNET_ADD, mp);
21243   mp->parent_if_index = ntohl (parent_if_index);
21244   mp->subif_id = ntohl (sub_id);
21245   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21246
21247   S (mp);
21248   W (ret);
21249   return ret;
21250 }
21251
21252 static int
21253 api_p2p_ethernet_del (vat_main_t * vam)
21254 {
21255   unformat_input_t *i = vam->input;
21256   vl_api_p2p_ethernet_del_t *mp;
21257   u32 parent_if_index = ~0;
21258   u8 remote_mac[6];
21259   u8 mac_set = 0;
21260   int ret;
21261
21262   memset (remote_mac, 0, sizeof (remote_mac));
21263   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21264     {
21265       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
21266         ;
21267       else if (unformat (i, "sw_if_index %d", &parent_if_index))
21268         ;
21269       else
21270         if (unformat
21271             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
21272         mac_set++;
21273       else
21274         {
21275           clib_warning ("parse error '%U'", format_unformat_error, i);
21276           return -99;
21277         }
21278     }
21279
21280   if (parent_if_index == ~0)
21281     {
21282       errmsg ("missing interface name or sw_if_index");
21283       return -99;
21284     }
21285   if (mac_set == 0)
21286     {
21287       errmsg ("missing remote mac address");
21288       return -99;
21289     }
21290
21291   M (P2P_ETHERNET_DEL, mp);
21292   mp->parent_if_index = ntohl (parent_if_index);
21293   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
21294
21295   S (mp);
21296   W (ret);
21297   return ret;
21298 }
21299
21300 static int
21301 api_lldp_config (vat_main_t * vam)
21302 {
21303   unformat_input_t *i = vam->input;
21304   vl_api_lldp_config_t *mp;
21305   int tx_hold = 0;
21306   int tx_interval = 0;
21307   u8 *sys_name = NULL;
21308   int ret;
21309
21310   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21311     {
21312       if (unformat (i, "system-name %s", &sys_name))
21313         ;
21314       else if (unformat (i, "tx-hold %d", &tx_hold))
21315         ;
21316       else if (unformat (i, "tx-interval %d", &tx_interval))
21317         ;
21318       else
21319         {
21320           clib_warning ("parse error '%U'", format_unformat_error, i);
21321           return -99;
21322         }
21323     }
21324
21325   vec_add1 (sys_name, 0);
21326
21327   M (LLDP_CONFIG, mp);
21328   mp->tx_hold = htonl (tx_hold);
21329   mp->tx_interval = htonl (tx_interval);
21330   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
21331   vec_free (sys_name);
21332
21333   S (mp);
21334   W (ret);
21335   return ret;
21336 }
21337
21338 static int
21339 api_sw_interface_set_lldp (vat_main_t * vam)
21340 {
21341   unformat_input_t *i = vam->input;
21342   vl_api_sw_interface_set_lldp_t *mp;
21343   u32 sw_if_index = ~0;
21344   u32 enable = 1;
21345   u8 *port_desc = NULL, *mgmt_oid = NULL;
21346   ip4_address_t ip4_addr;
21347   ip6_address_t ip6_addr;
21348   int ret;
21349
21350   memset (&ip4_addr, 0, sizeof (ip4_addr));
21351   memset (&ip6_addr, 0, sizeof (ip6_addr));
21352
21353   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21354     {
21355       if (unformat (i, "disable"))
21356         enable = 0;
21357       else
21358         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
21359         ;
21360       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21361         ;
21362       else if (unformat (i, "port-desc %s", &port_desc))
21363         ;
21364       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
21365         ;
21366       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
21367         ;
21368       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
21369         ;
21370       else
21371         break;
21372     }
21373
21374   if (sw_if_index == ~0)
21375     {
21376       errmsg ("missing interface name or sw_if_index");
21377       return -99;
21378     }
21379
21380   /* Construct the API message */
21381   vec_add1 (port_desc, 0);
21382   vec_add1 (mgmt_oid, 0);
21383   M (SW_INTERFACE_SET_LLDP, mp);
21384   mp->sw_if_index = ntohl (sw_if_index);
21385   mp->enable = enable;
21386   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
21387   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
21388   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
21389   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
21390   vec_free (port_desc);
21391   vec_free (mgmt_oid);
21392
21393   S (mp);
21394   W (ret);
21395   return ret;
21396 }
21397
21398 static int
21399 api_tcp_configure_src_addresses (vat_main_t * vam)
21400 {
21401   vl_api_tcp_configure_src_addresses_t *mp;
21402   unformat_input_t *i = vam->input;
21403   ip4_address_t v4first, v4last;
21404   ip6_address_t v6first, v6last;
21405   u8 range_set = 0;
21406   u32 vrf_id = 0;
21407   int ret;
21408
21409   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21410     {
21411       if (unformat (i, "%U - %U",
21412                     unformat_ip4_address, &v4first,
21413                     unformat_ip4_address, &v4last))
21414         {
21415           if (range_set)
21416             {
21417               errmsg ("one range per message (range already set)");
21418               return -99;
21419             }
21420           range_set = 1;
21421         }
21422       else if (unformat (i, "%U - %U",
21423                          unformat_ip6_address, &v6first,
21424                          unformat_ip6_address, &v6last))
21425         {
21426           if (range_set)
21427             {
21428               errmsg ("one range per message (range already set)");
21429               return -99;
21430             }
21431           range_set = 2;
21432         }
21433       else if (unformat (i, "vrf %d", &vrf_id))
21434         ;
21435       else
21436         break;
21437     }
21438
21439   if (range_set == 0)
21440     {
21441       errmsg ("address range not set");
21442       return -99;
21443     }
21444
21445   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
21446   mp->vrf_id = ntohl (vrf_id);
21447   /* ipv6? */
21448   if (range_set == 2)
21449     {
21450       mp->is_ipv6 = 1;
21451       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
21452       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
21453     }
21454   else
21455     {
21456       mp->is_ipv6 = 0;
21457       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
21458       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
21459     }
21460   S (mp);
21461   W (ret);
21462   return ret;
21463 }
21464
21465 static void vl_api_app_namespace_add_del_reply_t_handler
21466   (vl_api_app_namespace_add_del_reply_t * mp)
21467 {
21468   vat_main_t *vam = &vat_main;
21469   i32 retval = ntohl (mp->retval);
21470   if (vam->async_mode)
21471     {
21472       vam->async_errors += (retval < 0);
21473     }
21474   else
21475     {
21476       vam->retval = retval;
21477       if (retval == 0)
21478         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
21479       vam->result_ready = 1;
21480     }
21481 }
21482
21483 static void vl_api_app_namespace_add_del_reply_t_handler_json
21484   (vl_api_app_namespace_add_del_reply_t * mp)
21485 {
21486   vat_main_t *vam = &vat_main;
21487   vat_json_node_t node;
21488
21489   vat_json_init_object (&node);
21490   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
21491   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
21492
21493   vat_json_print (vam->ofp, &node);
21494   vat_json_free (&node);
21495
21496   vam->retval = ntohl (mp->retval);
21497   vam->result_ready = 1;
21498 }
21499
21500 static int
21501 api_app_namespace_add_del (vat_main_t * vam)
21502 {
21503   vl_api_app_namespace_add_del_t *mp;
21504   unformat_input_t *i = vam->input;
21505   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
21506   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
21507   u64 secret;
21508   int ret;
21509
21510   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21511     {
21512       if (unformat (i, "id %_%v%_", &ns_id))
21513         ;
21514       else if (unformat (i, "secret %lu", &secret))
21515         secret_set = 1;
21516       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21517         sw_if_index_set = 1;
21518       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
21519         ;
21520       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
21521         ;
21522       else
21523         break;
21524     }
21525   if (!ns_id || !secret_set || !sw_if_index_set)
21526     {
21527       errmsg ("namespace id, secret and sw_if_index must be set");
21528       return -99;
21529     }
21530   if (vec_len (ns_id) > 64)
21531     {
21532       errmsg ("namespace id too long");
21533       return -99;
21534     }
21535   M (APP_NAMESPACE_ADD_DEL, mp);
21536
21537   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
21538   mp->namespace_id_len = vec_len (ns_id);
21539   mp->secret = clib_host_to_net_u64 (secret);
21540   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21541   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
21542   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
21543   vec_free (ns_id);
21544   S (mp);
21545   W (ret);
21546   return ret;
21547 }
21548
21549 static int
21550 api_memfd_segment_create (vat_main_t * vam)
21551 {
21552 #if VPP_API_TEST_BUILTIN == 0
21553   unformat_input_t *i = vam->input;
21554   vl_api_memfd_segment_create_t *mp;
21555   u64 size = 64 << 20;
21556   int ret;
21557
21558   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21559     {
21560       if (unformat (i, "size %U", unformat_memory_size, &size))
21561         ;
21562       else
21563         break;
21564     }
21565
21566   M (MEMFD_SEGMENT_CREATE, mp);
21567   mp->requested_size = size;
21568   S (mp);
21569   W (ret);
21570   return ret;
21571
21572 #else
21573   errmsg ("memfd_segment_create (builtin) not supported");
21574   return -99;
21575 #endif
21576 }
21577
21578 static int
21579 api_dns_enable_disable (vat_main_t * vam)
21580 {
21581   unformat_input_t *line_input = vam->input;
21582   vl_api_dns_enable_disable_t *mp;
21583   u8 enable_disable = 1;
21584   int ret;
21585
21586   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21587     {
21588       if (unformat (line_input, "disable"))
21589         enable_disable = 0;
21590       if (unformat (line_input, "enable"))
21591         enable_disable = 1;
21592       else
21593         break;
21594     }
21595
21596   /* Construct the API message */
21597   M (DNS_ENABLE_DISABLE, mp);
21598   mp->enable = enable_disable;
21599
21600   /* send it... */
21601   S (mp);
21602   /* Wait for the reply */
21603   W (ret);
21604   return ret;
21605 }
21606
21607 static int
21608 api_dns_resolve_name (vat_main_t * vam)
21609 {
21610   unformat_input_t *line_input = vam->input;
21611   vl_api_dns_resolve_name_t *mp;
21612   u8 *name = 0;
21613   int ret;
21614
21615   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21616     {
21617       if (unformat (line_input, "%s", &name))
21618         ;
21619       else
21620         break;
21621     }
21622
21623   if (vec_len (name) > 127)
21624     {
21625       errmsg ("name too long");
21626       return -99;
21627     }
21628
21629   /* Construct the API message */
21630   M (DNS_RESOLVE_NAME, mp);
21631   memcpy (mp->name, name, vec_len (name));
21632   vec_free (name);
21633
21634   /* send it... */
21635   S (mp);
21636   /* Wait for the reply */
21637   W (ret);
21638   return ret;
21639 }
21640
21641 static int
21642 api_dns_resolve_ip (vat_main_t * vam)
21643 {
21644   unformat_input_t *line_input = vam->input;
21645   vl_api_dns_resolve_ip_t *mp;
21646   int is_ip6 = -1;
21647   ip4_address_t addr4;
21648   ip6_address_t addr6;
21649   int ret;
21650
21651   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21652     {
21653       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21654         is_ip6 = 1;
21655       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21656         is_ip6 = 0;
21657       else
21658         break;
21659     }
21660
21661   if (is_ip6 == -1)
21662     {
21663       errmsg ("missing address");
21664       return -99;
21665     }
21666
21667   /* Construct the API message */
21668   M (DNS_RESOLVE_IP, mp);
21669   mp->is_ip6 = is_ip6;
21670   if (is_ip6)
21671     memcpy (mp->address, &addr6, sizeof (addr6));
21672   else
21673     memcpy (mp->address, &addr4, sizeof (addr4));
21674
21675   /* send it... */
21676   S (mp);
21677   /* Wait for the reply */
21678   W (ret);
21679   return ret;
21680 }
21681
21682 static int
21683 api_dns_name_server_add_del (vat_main_t * vam)
21684 {
21685   unformat_input_t *i = vam->input;
21686   vl_api_dns_name_server_add_del_t *mp;
21687   u8 is_add = 1;
21688   ip6_address_t ip6_server;
21689   ip4_address_t ip4_server;
21690   int ip6_set = 0;
21691   int ip4_set = 0;
21692   int ret = 0;
21693
21694   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21695     {
21696       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21697         ip6_set = 1;
21698       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21699         ip4_set = 1;
21700       else if (unformat (i, "del"))
21701         is_add = 0;
21702       else
21703         {
21704           clib_warning ("parse error '%U'", format_unformat_error, i);
21705           return -99;
21706         }
21707     }
21708
21709   if (ip4_set && ip6_set)
21710     {
21711       errmsg ("Only one server address allowed per message");
21712       return -99;
21713     }
21714   if ((ip4_set + ip6_set) == 0)
21715     {
21716       errmsg ("Server address required");
21717       return -99;
21718     }
21719
21720   /* Construct the API message */
21721   M (DNS_NAME_SERVER_ADD_DEL, mp);
21722
21723   if (ip6_set)
21724     {
21725       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21726       mp->is_ip6 = 1;
21727     }
21728   else
21729     {
21730       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21731       mp->is_ip6 = 0;
21732     }
21733
21734   mp->is_add = is_add;
21735
21736   /* send it... */
21737   S (mp);
21738
21739   /* Wait for a reply, return good/bad news  */
21740   W (ret);
21741   return ret;
21742 }
21743
21744 static void
21745 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
21746 {
21747   vat_main_t *vam = &vat_main;
21748
21749   if (mp->is_ip4)
21750     {
21751       print (vam->ofp,
21752              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21753              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21754              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
21755              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
21756              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21757              clib_net_to_host_u32 (mp->action_index), mp->tag);
21758     }
21759   else
21760     {
21761       print (vam->ofp,
21762              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
21763              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
21764              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
21765              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
21766              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
21767              clib_net_to_host_u32 (mp->action_index), mp->tag);
21768     }
21769 }
21770
21771 static void
21772 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
21773                                              mp)
21774 {
21775   vat_main_t *vam = &vat_main;
21776   vat_json_node_t *node = NULL;
21777   struct in6_addr ip6;
21778   struct in_addr ip4;
21779
21780   if (VAT_JSON_ARRAY != vam->json_tree.type)
21781     {
21782       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
21783       vat_json_init_array (&vam->json_tree);
21784     }
21785   node = vat_json_array_add (&vam->json_tree);
21786   vat_json_init_object (node);
21787
21788   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
21789   vat_json_object_add_uint (node, "appns_index",
21790                             clib_net_to_host_u32 (mp->appns_index));
21791   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
21792   vat_json_object_add_uint (node, "scope", mp->scope);
21793   vat_json_object_add_uint (node, "action_index",
21794                             clib_net_to_host_u32 (mp->action_index));
21795   vat_json_object_add_uint (node, "lcl_port",
21796                             clib_net_to_host_u16 (mp->lcl_port));
21797   vat_json_object_add_uint (node, "rmt_port",
21798                             clib_net_to_host_u16 (mp->rmt_port));
21799   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
21800   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
21801   vat_json_object_add_string_copy (node, "tag", mp->tag);
21802   if (mp->is_ip4)
21803     {
21804       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
21805       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
21806       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
21807       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
21808     }
21809   else
21810     {
21811       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
21812       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
21813       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
21814       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
21815     }
21816 }
21817
21818 static int
21819 api_session_rule_add_del (vat_main_t * vam)
21820 {
21821   vl_api_session_rule_add_del_t *mp;
21822   unformat_input_t *i = vam->input;
21823   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
21824   u32 appns_index = 0, scope = 0;
21825   ip4_address_t lcl_ip4, rmt_ip4;
21826   ip6_address_t lcl_ip6, rmt_ip6;
21827   u8 is_ip4 = 1, conn_set = 0;
21828   u8 is_add = 1, *tag = 0;
21829   int ret;
21830
21831   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21832     {
21833       if (unformat (i, "del"))
21834         is_add = 0;
21835       else if (unformat (i, "add"))
21836         ;
21837       else if (unformat (i, "proto tcp"))
21838         proto = 0;
21839       else if (unformat (i, "proto udp"))
21840         proto = 1;
21841       else if (unformat (i, "appns %d", &appns_index))
21842         ;
21843       else if (unformat (i, "scope %d", &scope))
21844         ;
21845       else if (unformat (i, "tag %_%v%_", &tag))
21846         ;
21847       else
21848         if (unformat
21849             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
21850              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
21851              &rmt_port))
21852         {
21853           is_ip4 = 1;
21854           conn_set = 1;
21855         }
21856       else
21857         if (unformat
21858             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
21859              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
21860              &rmt_port))
21861         {
21862           is_ip4 = 0;
21863           conn_set = 1;
21864         }
21865       else if (unformat (i, "action %d", &action))
21866         ;
21867       else
21868         break;
21869     }
21870   if (proto == ~0 || !conn_set || action == ~0)
21871     {
21872       errmsg ("transport proto, connection and action must be set");
21873       return -99;
21874     }
21875
21876   if (scope > 3)
21877     {
21878       errmsg ("scope should be 0-3");
21879       return -99;
21880     }
21881
21882   M (SESSION_RULE_ADD_DEL, mp);
21883
21884   mp->is_ip4 = is_ip4;
21885   mp->transport_proto = proto;
21886   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
21887   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
21888   mp->lcl_plen = lcl_plen;
21889   mp->rmt_plen = rmt_plen;
21890   mp->action_index = clib_host_to_net_u32 (action);
21891   mp->appns_index = clib_host_to_net_u32 (appns_index);
21892   mp->scope = scope;
21893   mp->is_add = is_add;
21894   if (is_ip4)
21895     {
21896       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
21897       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
21898     }
21899   else
21900     {
21901       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
21902       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
21903     }
21904   if (tag)
21905     {
21906       clib_memcpy (mp->tag, tag, vec_len (tag));
21907       vec_free (tag);
21908     }
21909
21910   S (mp);
21911   W (ret);
21912   return ret;
21913 }
21914
21915 static int
21916 api_session_rules_dump (vat_main_t * vam)
21917 {
21918   vl_api_session_rules_dump_t *mp;
21919   vl_api_control_ping_t *mp_ping;
21920   int ret;
21921
21922   if (!vam->json_output)
21923     {
21924       print (vam->ofp, "%=20s", "Session Rules");
21925     }
21926
21927   M (SESSION_RULES_DUMP, mp);
21928   /* send it... */
21929   S (mp);
21930
21931   /* Use a control ping for synchronization */
21932   MPING (CONTROL_PING, mp_ping);
21933   S (mp_ping);
21934
21935   /* Wait for a reply... */
21936   W (ret);
21937   return ret;
21938 }
21939
21940 static int
21941 api_ip_container_proxy_add_del (vat_main_t * vam)
21942 {
21943   vl_api_ip_container_proxy_add_del_t *mp;
21944   unformat_input_t *i = vam->input;
21945   u32 plen = ~0, sw_if_index = ~0;
21946   ip4_address_t ip4;
21947   ip6_address_t ip6;
21948   u8 is_ip4 = 1;
21949   u8 is_add = 1;
21950   int ret;
21951
21952   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21953     {
21954       if (unformat (i, "del"))
21955         is_add = 0;
21956       else if (unformat (i, "add"))
21957         ;
21958       if (unformat (i, "%U", unformat_ip4_address, &ip4))
21959         {
21960           is_ip4 = 1;
21961           plen = 32;
21962         }
21963       else if (unformat (i, "%U", unformat_ip6_address, &ip6))
21964         {
21965           is_ip4 = 0;
21966           plen = 128;
21967         }
21968       else if (unformat (i, "sw_if_index %u", &sw_if_index))
21969         ;
21970       else
21971         break;
21972     }
21973   if (sw_if_index == ~0 || plen == ~0)
21974     {
21975       errmsg ("address and sw_if_index must be set");
21976       return -99;
21977     }
21978
21979   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
21980
21981   mp->is_ip4 = is_ip4;
21982   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21983   mp->plen = plen;
21984   mp->is_add = is_add;
21985   if (is_ip4)
21986     clib_memcpy (mp->ip, &ip4, sizeof (ip4));
21987   else
21988     clib_memcpy (mp->ip, &ip6, sizeof (ip6));
21989
21990   S (mp);
21991   W (ret);
21992   return ret;
21993 }
21994
21995 static int
21996 q_or_quit (vat_main_t * vam)
21997 {
21998 #if VPP_API_TEST_BUILTIN == 0
21999   longjmp (vam->jump_buf, 1);
22000 #endif
22001   return 0;                     /* not so much */
22002 }
22003
22004 static int
22005 q (vat_main_t * vam)
22006 {
22007   return q_or_quit (vam);
22008 }
22009
22010 static int
22011 quit (vat_main_t * vam)
22012 {
22013   return q_or_quit (vam);
22014 }
22015
22016 static int
22017 comment (vat_main_t * vam)
22018 {
22019   return 0;
22020 }
22021
22022 static int
22023 cmd_cmp (void *a1, void *a2)
22024 {
22025   u8 **c1 = a1;
22026   u8 **c2 = a2;
22027
22028   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
22029 }
22030
22031 static int
22032 help (vat_main_t * vam)
22033 {
22034   u8 **cmds = 0;
22035   u8 *name = 0;
22036   hash_pair_t *p;
22037   unformat_input_t *i = vam->input;
22038   int j;
22039
22040   if (unformat (i, "%s", &name))
22041     {
22042       uword *hs;
22043
22044       vec_add1 (name, 0);
22045
22046       hs = hash_get_mem (vam->help_by_name, name);
22047       if (hs)
22048         print (vam->ofp, "usage: %s %s", name, hs[0]);
22049       else
22050         print (vam->ofp, "No such msg / command '%s'", name);
22051       vec_free (name);
22052       return 0;
22053     }
22054
22055   print (vam->ofp, "Help is available for the following:");
22056
22057     /* *INDENT-OFF* */
22058     hash_foreach_pair (p, vam->function_by_name,
22059     ({
22060       vec_add1 (cmds, (u8 *)(p->key));
22061     }));
22062     /* *INDENT-ON* */
22063
22064   vec_sort_with_function (cmds, cmd_cmp);
22065
22066   for (j = 0; j < vec_len (cmds); j++)
22067     print (vam->ofp, "%s", cmds[j]);
22068
22069   vec_free (cmds);
22070   return 0;
22071 }
22072
22073 static int
22074 set (vat_main_t * vam)
22075 {
22076   u8 *name = 0, *value = 0;
22077   unformat_input_t *i = vam->input;
22078
22079   if (unformat (i, "%s", &name))
22080     {
22081       /* The input buffer is a vector, not a string. */
22082       value = vec_dup (i->buffer);
22083       vec_delete (value, i->index, 0);
22084       /* Almost certainly has a trailing newline */
22085       if (value[vec_len (value) - 1] == '\n')
22086         value[vec_len (value) - 1] = 0;
22087       /* Make sure it's a proper string, one way or the other */
22088       vec_add1 (value, 0);
22089       (void) clib_macro_set_value (&vam->macro_main,
22090                                    (char *) name, (char *) value);
22091     }
22092   else
22093     errmsg ("usage: set <name> <value>");
22094
22095   vec_free (name);
22096   vec_free (value);
22097   return 0;
22098 }
22099
22100 static int
22101 unset (vat_main_t * vam)
22102 {
22103   u8 *name = 0;
22104
22105   if (unformat (vam->input, "%s", &name))
22106     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
22107       errmsg ("unset: %s wasn't set", name);
22108   vec_free (name);
22109   return 0;
22110 }
22111
22112 typedef struct
22113 {
22114   u8 *name;
22115   u8 *value;
22116 } macro_sort_t;
22117
22118
22119 static int
22120 macro_sort_cmp (void *a1, void *a2)
22121 {
22122   macro_sort_t *s1 = a1;
22123   macro_sort_t *s2 = a2;
22124
22125   return strcmp ((char *) (s1->name), (char *) (s2->name));
22126 }
22127
22128 static int
22129 dump_macro_table (vat_main_t * vam)
22130 {
22131   macro_sort_t *sort_me = 0, *sm;
22132   int i;
22133   hash_pair_t *p;
22134
22135     /* *INDENT-OFF* */
22136     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
22137     ({
22138       vec_add2 (sort_me, sm, 1);
22139       sm->name = (u8 *)(p->key);
22140       sm->value = (u8 *) (p->value[0]);
22141     }));
22142     /* *INDENT-ON* */
22143
22144   vec_sort_with_function (sort_me, macro_sort_cmp);
22145
22146   if (vec_len (sort_me))
22147     print (vam->ofp, "%-15s%s", "Name", "Value");
22148   else
22149     print (vam->ofp, "The macro table is empty...");
22150
22151   for (i = 0; i < vec_len (sort_me); i++)
22152     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
22153   return 0;
22154 }
22155
22156 static int
22157 dump_node_table (vat_main_t * vam)
22158 {
22159   int i, j;
22160   vlib_node_t *node, *next_node;
22161
22162   if (vec_len (vam->graph_nodes) == 0)
22163     {
22164       print (vam->ofp, "Node table empty, issue get_node_graph...");
22165       return 0;
22166     }
22167
22168   for (i = 0; i < vec_len (vam->graph_nodes); i++)
22169     {
22170       node = vam->graph_nodes[i];
22171       print (vam->ofp, "[%d] %s", i, node->name);
22172       for (j = 0; j < vec_len (node->next_nodes); j++)
22173         {
22174           if (node->next_nodes[j] != ~0)
22175             {
22176               next_node = vam->graph_nodes[node->next_nodes[j]];
22177               print (vam->ofp, "  [%d] %s", j, next_node->name);
22178             }
22179         }
22180     }
22181   return 0;
22182 }
22183
22184 static int
22185 value_sort_cmp (void *a1, void *a2)
22186 {
22187   name_sort_t *n1 = a1;
22188   name_sort_t *n2 = a2;
22189
22190   if (n1->value < n2->value)
22191     return -1;
22192   if (n1->value > n2->value)
22193     return 1;
22194   return 0;
22195 }
22196
22197
22198 static int
22199 dump_msg_api_table (vat_main_t * vam)
22200 {
22201   api_main_t *am = &api_main;
22202   name_sort_t *nses = 0, *ns;
22203   hash_pair_t *hp;
22204   int i;
22205
22206   /* *INDENT-OFF* */
22207   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
22208   ({
22209     vec_add2 (nses, ns, 1);
22210     ns->name = (u8 *)(hp->key);
22211     ns->value = (u32) hp->value[0];
22212   }));
22213   /* *INDENT-ON* */
22214
22215   vec_sort_with_function (nses, value_sort_cmp);
22216
22217   for (i = 0; i < vec_len (nses); i++)
22218     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
22219   vec_free (nses);
22220   return 0;
22221 }
22222
22223 static int
22224 get_msg_id (vat_main_t * vam)
22225 {
22226   u8 *name_and_crc;
22227   u32 message_index;
22228
22229   if (unformat (vam->input, "%s", &name_and_crc))
22230     {
22231       message_index = vl_api_get_msg_index (name_and_crc);
22232       if (message_index == ~0)
22233         {
22234           print (vam->ofp, " '%s' not found", name_and_crc);
22235           return 0;
22236         }
22237       print (vam->ofp, " '%s' has message index %d",
22238              name_and_crc, message_index);
22239       return 0;
22240     }
22241   errmsg ("name_and_crc required...");
22242   return 0;
22243 }
22244
22245 static int
22246 search_node_table (vat_main_t * vam)
22247 {
22248   unformat_input_t *line_input = vam->input;
22249   u8 *node_to_find;
22250   int j;
22251   vlib_node_t *node, *next_node;
22252   uword *p;
22253
22254   if (vam->graph_node_index_by_name == 0)
22255     {
22256       print (vam->ofp, "Node table empty, issue get_node_graph...");
22257       return 0;
22258     }
22259
22260   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
22261     {
22262       if (unformat (line_input, "%s", &node_to_find))
22263         {
22264           vec_add1 (node_to_find, 0);
22265           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
22266           if (p == 0)
22267             {
22268               print (vam->ofp, "%s not found...", node_to_find);
22269               goto out;
22270             }
22271           node = vam->graph_nodes[p[0]];
22272           print (vam->ofp, "[%d] %s", p[0], node->name);
22273           for (j = 0; j < vec_len (node->next_nodes); j++)
22274             {
22275               if (node->next_nodes[j] != ~0)
22276                 {
22277                   next_node = vam->graph_nodes[node->next_nodes[j]];
22278                   print (vam->ofp, "  [%d] %s", j, next_node->name);
22279                 }
22280             }
22281         }
22282
22283       else
22284         {
22285           clib_warning ("parse error '%U'", format_unformat_error,
22286                         line_input);
22287           return -99;
22288         }
22289
22290     out:
22291       vec_free (node_to_find);
22292
22293     }
22294
22295   return 0;
22296 }
22297
22298
22299 static int
22300 script (vat_main_t * vam)
22301 {
22302 #if (VPP_API_TEST_BUILTIN==0)
22303   u8 *s = 0;
22304   char *save_current_file;
22305   unformat_input_t save_input;
22306   jmp_buf save_jump_buf;
22307   u32 save_line_number;
22308
22309   FILE *new_fp, *save_ifp;
22310
22311   if (unformat (vam->input, "%s", &s))
22312     {
22313       new_fp = fopen ((char *) s, "r");
22314       if (new_fp == 0)
22315         {
22316           errmsg ("Couldn't open script file %s", s);
22317           vec_free (s);
22318           return -99;
22319         }
22320     }
22321   else
22322     {
22323       errmsg ("Missing script name");
22324       return -99;
22325     }
22326
22327   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
22328   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
22329   save_ifp = vam->ifp;
22330   save_line_number = vam->input_line_number;
22331   save_current_file = (char *) vam->current_file;
22332
22333   vam->input_line_number = 0;
22334   vam->ifp = new_fp;
22335   vam->current_file = s;
22336   do_one_file (vam);
22337
22338   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
22339   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
22340   vam->ifp = save_ifp;
22341   vam->input_line_number = save_line_number;
22342   vam->current_file = (u8 *) save_current_file;
22343   vec_free (s);
22344
22345   return 0;
22346 #else
22347   clib_warning ("use the exec command...");
22348   return -99;
22349 #endif
22350 }
22351
22352 static int
22353 echo (vat_main_t * vam)
22354 {
22355   print (vam->ofp, "%v", vam->input->buffer);
22356   return 0;
22357 }
22358
22359 /* List of API message constructors, CLI names map to api_xxx */
22360 #define foreach_vpe_api_msg                                             \
22361 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
22362 _(sw_interface_dump,"")                                                 \
22363 _(sw_interface_set_flags,                                               \
22364   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
22365 _(sw_interface_add_del_address,                                         \
22366   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
22367 _(sw_interface_set_rx_mode,                                             \
22368   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
22369 _(sw_interface_set_table,                                               \
22370   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
22371 _(sw_interface_set_mpls_enable,                                         \
22372   "<intfc> | sw_if_index [disable | dis]")                              \
22373 _(sw_interface_set_vpath,                                               \
22374   "<intfc> | sw_if_index <id> enable | disable")                        \
22375 _(sw_interface_set_vxlan_bypass,                                        \
22376   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22377 _(sw_interface_set_geneve_bypass,                                       \
22378   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
22379 _(sw_interface_set_l2_xconnect,                                         \
22380   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22381   "enable | disable")                                                   \
22382 _(sw_interface_set_l2_bridge,                                           \
22383   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
22384   "[shg <split-horizon-group>] [bvi]\n"                                 \
22385   "enable | disable")                                                   \
22386 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
22387 _(bridge_domain_add_del,                                                \
22388   "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") \
22389 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
22390 _(l2fib_add_del,                                                        \
22391   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
22392 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
22393 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
22394 _(l2_flags,                                                             \
22395   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22396 _(bridge_flags,                                                         \
22397   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
22398 _(tap_connect,                                                          \
22399   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
22400 _(tap_modify,                                                           \
22401   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
22402 _(tap_delete,                                                           \
22403   "<vpp-if-name> | sw_if_index <id>")                                   \
22404 _(sw_interface_tap_dump, "")                                            \
22405 _(ip_table_add_del,                                                     \
22406   "table-id <n> [ipv6]\n")                                              \
22407 _(ip_add_del_route,                                                     \
22408   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
22409   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22410   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22411   "[multipath] [count <n>]")                                            \
22412 _(ip_mroute_add_del,                                                    \
22413   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
22414   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
22415 _(mpls_table_add_del,                                                   \
22416   "table-id <n>\n")                                                     \
22417 _(mpls_route_add_del,                                                   \
22418   "<label> <eos> via <addr> [table-id <n>]\n"                           \
22419   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
22420   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
22421   "[multipath] [count <n>]")                                            \
22422 _(mpls_ip_bind_unbind,                                                  \
22423   "<label> <addr/len>")                                                 \
22424 _(mpls_tunnel_add_del,                                                  \
22425   " via <addr> [table-id <n>]\n"                                        \
22426   "sw_if_index <id>] [l2]  [del]")                                      \
22427 _(bier_table_add_del,                                                   \
22428   "<label> <sub-domain> <set> <bsl> [del]")                             \
22429 _(bier_route_add_del,                                                   \
22430   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
22431   "[<intfc> | sw_if_index <id>]"                                        \
22432   "[weight <n>] [del] [multipath]")                                     \
22433 _(proxy_arp_add_del,                                                    \
22434   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
22435 _(proxy_arp_intfc_enable_disable,                                       \
22436   "<intfc> | sw_if_index <id> enable | disable")                        \
22437 _(sw_interface_set_unnumbered,                                          \
22438   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
22439 _(ip_neighbor_add_del,                                                  \
22440   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
22441   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
22442 _(reset_vrf, "vrf <id> [ipv6]")                                         \
22443 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
22444 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
22445   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
22446   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
22447   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
22448 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
22449 _(reset_fib, "vrf <n> [ipv6]")                                          \
22450 _(dhcp_proxy_config,                                                    \
22451   "svr <v46-address> src <v46-address>\n"                               \
22452    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
22453 _(dhcp_proxy_set_vss,                                                   \
22454   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
22455 _(dhcp_proxy_dump, "ip6")                                               \
22456 _(dhcp_client_config,                                                   \
22457   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
22458 _(set_ip_flow_hash,                                                     \
22459   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
22460 _(sw_interface_ip6_enable_disable,                                      \
22461   "<intfc> | sw_if_index <id> enable | disable")                        \
22462 _(sw_interface_ip6_set_link_local_address,                              \
22463   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
22464 _(ip6nd_proxy_add_del,                                                  \
22465   "<intfc> | sw_if_index <id> <ip6-address>")                           \
22466 _(ip6nd_proxy_dump, "")                                                 \
22467 _(sw_interface_ip6nd_ra_prefix,                                         \
22468   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
22469   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
22470   "[nolink] [isno]")                                                    \
22471 _(sw_interface_ip6nd_ra_config,                                         \
22472   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
22473   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
22474   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
22475 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
22476 _(l2_patch_add_del,                                                     \
22477   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
22478   "enable | disable")                                                   \
22479 _(sr_localsid_add_del,                                                  \
22480   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
22481   "fib-table <num> (end.psp) sw_if_index <num>")                        \
22482 _(classify_add_del_table,                                               \
22483   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
22484   " [del] [del-chain] mask <mask-value>\n"                              \
22485   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
22486   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
22487 _(classify_add_del_session,                                             \
22488   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
22489   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
22490   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
22491   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
22492 _(classify_set_interface_ip_table,                                      \
22493   "<intfc> | sw_if_index <nn> table <nn>")                              \
22494 _(classify_set_interface_l2_tables,                                     \
22495   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22496   "  [other-table <nn>]")                                               \
22497 _(get_node_index, "node <node-name")                                    \
22498 _(add_node_next, "node <node-name> next <next-node-name>")              \
22499 _(l2tpv3_create_tunnel,                                                 \
22500   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
22501   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
22502   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
22503 _(l2tpv3_set_tunnel_cookies,                                            \
22504   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
22505   "[new_remote_cookie <nn>]\n")                                         \
22506 _(l2tpv3_interface_enable_disable,                                      \
22507   "<intfc> | sw_if_index <nn> enable | disable")                        \
22508 _(l2tpv3_set_lookup_key,                                                \
22509   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
22510 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
22511 _(vxlan_add_del_tunnel,                                                 \
22512   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22513   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22514   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22515 _(geneve_add_del_tunnel,                                                \
22516   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
22517   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22518   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
22519 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
22520 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
22521 _(gre_add_del_tunnel,                                                   \
22522   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
22523 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
22524 _(l2_fib_clear_table, "")                                               \
22525 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
22526 _(l2_interface_vlan_tag_rewrite,                                        \
22527   "<intfc> | sw_if_index <nn> \n"                                       \
22528   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
22529   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
22530 _(create_vhost_user_if,                                                 \
22531         "socket <filename> [server] [renumber <dev_instance>] "         \
22532         "[mac <mac_address>]")                                          \
22533 _(modify_vhost_user_if,                                                 \
22534         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
22535         "[server] [renumber <dev_instance>]")                           \
22536 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
22537 _(sw_interface_vhost_user_dump, "")                                     \
22538 _(show_version, "")                                                     \
22539 _(vxlan_gpe_add_del_tunnel,                                             \
22540   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
22541   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
22542   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
22543   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
22544 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
22545 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
22546 _(interface_name_renumber,                                              \
22547   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
22548 _(input_acl_set_interface,                                              \
22549   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22550   "  [l2-table <nn>] [del]")                                            \
22551 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
22552 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
22553 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
22554 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
22555 _(ip_dump, "ipv4 | ipv6")                                               \
22556 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
22557 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
22558   "  spid_id <n> ")                                                     \
22559 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
22560   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
22561   "  integ_alg <alg> integ_key <hex>")                                  \
22562 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
22563   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
22564   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
22565   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
22566 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
22567 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
22568   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
22569   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
22570   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
22571 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
22572 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
22573   "  <alg> <hex>\n")                                                    \
22574 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
22575 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
22576 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
22577   "(auth_data 0x<data> | auth_data <data>)")                            \
22578 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
22579   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
22580 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
22581   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
22582   "(local|remote)")                                                     \
22583 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
22584 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
22585 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22586 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
22587 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
22588 _(ikev2_initiate_sa_init, "<profile_name>")                             \
22589 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
22590 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
22591 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
22592 _(delete_loopback,"sw_if_index <nn>")                                   \
22593 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
22594 _(map_add_domain,                                                       \
22595   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
22596   "ip6-src <ip6addr> "                                                  \
22597   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
22598 _(map_del_domain, "index <n>")                                          \
22599 _(map_add_del_rule,                                                     \
22600   "index <n> psid <n> dst <ip6addr> [del]")                             \
22601 _(map_domain_dump, "")                                                  \
22602 _(map_rule_dump, "index <map-domain>")                                  \
22603 _(want_interface_events,  "enable|disable")                             \
22604 _(want_stats,"enable|disable")                                          \
22605 _(get_first_msg_id, "client <name>")                                    \
22606 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
22607 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
22608   "fib-id <nn> [ip4][ip6][default]")                                    \
22609 _(get_node_graph, " ")                                                  \
22610 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
22611 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
22612 _(ioam_disable, "")                                                     \
22613 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
22614                             " sw_if_index <sw_if_index> p <priority> "  \
22615                             "w <weight>] [del]")                        \
22616 _(one_add_del_locator, "locator-set <locator_name> "                    \
22617                         "iface <intf> | sw_if_index <sw_if_index> "     \
22618                         "p <priority> w <weight> [del]")                \
22619 _(one_add_del_local_eid,"vni <vni> eid "                                \
22620                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22621                          "locator-set <locator_name> [del]"             \
22622                          "[key-id sha1|sha256 secret-key <secret-key>]")\
22623 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
22624 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
22625 _(one_enable_disable, "enable|disable")                                 \
22626 _(one_map_register_enable_disable, "enable|disable")                    \
22627 _(one_map_register_fallback_threshold, "<value>")                       \
22628 _(one_rloc_probe_enable_disable, "enable|disable")                      \
22629 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
22630                                "[seid <seid>] "                         \
22631                                "rloc <locator> p <prio> "               \
22632                                "w <weight> [rloc <loc> ... ] "          \
22633                                "action <action> [del-all]")             \
22634 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
22635                           "<local-eid>")                                \
22636 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
22637 _(one_use_petr, "ip-address> | disable")                                \
22638 _(one_map_request_mode, "src-dst|dst-only")                             \
22639 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
22640 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
22641 _(one_locator_set_dump, "[local | remote]")                             \
22642 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
22643 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
22644                        "[local] | [remote]")                            \
22645 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
22646 _(one_ndp_bd_get, "")                                                   \
22647 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
22648 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
22649 _(one_l2_arp_bd_get, "")                                                \
22650 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
22651 _(one_stats_enable_disable, "enable|disalbe")                           \
22652 _(show_one_stats_enable_disable, "")                                    \
22653 _(one_eid_table_vni_dump, "")                                           \
22654 _(one_eid_table_map_dump, "l2|l3")                                      \
22655 _(one_map_resolver_dump, "")                                            \
22656 _(one_map_server_dump, "")                                              \
22657 _(one_adjacencies_get, "vni <vni>")                                     \
22658 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22659 _(show_one_rloc_probe_state, "")                                        \
22660 _(show_one_map_register_state, "")                                      \
22661 _(show_one_status, "")                                                  \
22662 _(one_stats_dump, "")                                                   \
22663 _(one_stats_flush, "")                                                  \
22664 _(one_get_map_request_itr_rlocs, "")                                    \
22665 _(one_map_register_set_ttl, "<ttl>")                                    \
22666 _(one_set_transport_protocol, "udp|api")                                \
22667 _(one_get_transport_protocol, "")                                       \
22668 _(one_enable_disable_xtr_mode, "enable|disable")                        \
22669 _(one_show_xtr_mode, "")                                                \
22670 _(one_enable_disable_pitr_mode, "enable|disable")                       \
22671 _(one_show_pitr_mode, "")                                               \
22672 _(one_enable_disable_petr_mode, "enable|disable")                       \
22673 _(one_show_petr_mode, "")                                               \
22674 _(show_one_nsh_mapping, "")                                             \
22675 _(show_one_pitr, "")                                                    \
22676 _(show_one_use_petr, "")                                                \
22677 _(show_one_map_request_mode, "")                                        \
22678 _(show_one_map_register_ttl, "")                                        \
22679 _(show_one_map_register_fallback_threshold, "")                         \
22680 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22681                             " sw_if_index <sw_if_index> p <priority> "  \
22682                             "w <weight>] [del]")                        \
22683 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22684                         "iface <intf> | sw_if_index <sw_if_index> "     \
22685                         "p <priority> w <weight> [del]")                \
22686 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22687                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22688                          "locator-set <locator_name> [del]"             \
22689                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22690 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22691 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22692 _(lisp_enable_disable, "enable|disable")                                \
22693 _(lisp_map_register_enable_disable, "enable|disable")                   \
22694 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22695 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22696                                "[seid <seid>] "                         \
22697                                "rloc <locator> p <prio> "               \
22698                                "w <weight> [rloc <loc> ... ] "          \
22699                                "action <action> [del-all]")             \
22700 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22701                           "<local-eid>")                                \
22702 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22703 _(lisp_use_petr, "<ip-address> | disable")                              \
22704 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22705 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22706 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22707 _(lisp_locator_set_dump, "[local | remote]")                            \
22708 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22709 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22710                        "[local] | [remote]")                            \
22711 _(lisp_eid_table_vni_dump, "")                                          \
22712 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22713 _(lisp_map_resolver_dump, "")                                           \
22714 _(lisp_map_server_dump, "")                                             \
22715 _(lisp_adjacencies_get, "vni <vni>")                                    \
22716 _(gpe_fwd_entry_vnis_get, "")                                           \
22717 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22718 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22719                                 "[table <table-id>]")                   \
22720 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22721 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22722 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22723 _(gpe_get_encap_mode, "")                                               \
22724 _(lisp_gpe_add_del_iface, "up|down")                                    \
22725 _(lisp_gpe_enable_disable, "enable|disable")                            \
22726 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22727   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22728 _(show_lisp_rloc_probe_state, "")                                       \
22729 _(show_lisp_map_register_state, "")                                     \
22730 _(show_lisp_status, "")                                                 \
22731 _(lisp_get_map_request_itr_rlocs, "")                                   \
22732 _(show_lisp_pitr, "")                                                   \
22733 _(show_lisp_use_petr, "")                                               \
22734 _(show_lisp_map_request_mode, "")                                       \
22735 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22736 _(af_packet_delete, "name <host interface name>")                       \
22737 _(policer_add_del, "name <policer name> <params> [del]")                \
22738 _(policer_dump, "[name <policer name>]")                                \
22739 _(policer_classify_set_interface,                                       \
22740   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22741   "  [l2-table <nn>] [del]")                                            \
22742 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22743 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22744     "[master|slave]")                                                   \
22745 _(netmap_delete, "name <interface name>")                               \
22746 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22747 _(mpls_fib_dump, "")                                                    \
22748 _(classify_table_ids, "")                                               \
22749 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22750 _(classify_table_info, "table_id <nn>")                                 \
22751 _(classify_session_dump, "table_id <nn>")                               \
22752 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22753     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22754     "[template_interval <nn>] [udp_checksum]")                          \
22755 _(ipfix_exporter_dump, "")                                              \
22756 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22757 _(ipfix_classify_stream_dump, "")                                       \
22758 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22759 _(ipfix_classify_table_dump, "")                                        \
22760 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22761 _(sw_interface_span_dump, "[l2]")                                           \
22762 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22763 _(pg_create_interface, "if_id <nn>")                                    \
22764 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22765 _(pg_enable_disable, "[stream <id>] disable")                           \
22766 _(ip_source_and_port_range_check_add_del,                               \
22767   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22768 _(ip_source_and_port_range_check_interface_add_del,                     \
22769   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
22770   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
22771 _(ipsec_gre_add_del_tunnel,                                             \
22772   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
22773 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
22774 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
22775 _(l2_interface_pbb_tag_rewrite,                                         \
22776   "<intfc> | sw_if_index <nn> \n"                                       \
22777   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
22778   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
22779 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
22780 _(flow_classify_set_interface,                                          \
22781   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
22782 _(flow_classify_dump, "type [ip4|ip6]")                                 \
22783 _(ip_fib_dump, "")                                                      \
22784 _(ip_mfib_dump, "")                                                     \
22785 _(ip6_fib_dump, "")                                                     \
22786 _(ip6_mfib_dump, "")                                                    \
22787 _(feature_enable_disable, "arc_name <arc_name> "                        \
22788   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
22789 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
22790 "[disable]")                                                            \
22791 _(l2_xconnect_dump, "")                                                 \
22792 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
22793 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
22794 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
22795 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
22796 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
22797 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
22798 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
22799   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
22800 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
22801 _(memfd_segment_create,"size <nnn>")                                    \
22802 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
22803 _(dns_enable_disable, "[enable][disable]")                              \
22804 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22805 _(dns_resolve_name, "<hostname>")                                       \
22806 _(dns_resolve_ip, "<ip4|ip6>")                                          \
22807 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22808 _(dns_resolve_name, "<hostname>")                                       \
22809 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
22810   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
22811 _(session_rules_dump, "")                                               \
22812 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
22813
22814 /* List of command functions, CLI names map directly to functions */
22815 #define foreach_cli_function                                    \
22816 _(comment, "usage: comment <ignore-rest-of-line>")              \
22817 _(dump_interface_table, "usage: dump_interface_table")          \
22818 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
22819 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
22820 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
22821 _(dump_stats_table, "usage: dump_stats_table")                  \
22822 _(dump_macro_table, "usage: dump_macro_table ")                 \
22823 _(dump_node_table, "usage: dump_node_table")                    \
22824 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
22825 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
22826 _(echo, "usage: echo <message>")                                \
22827 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
22828 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
22829 _(help, "usage: help")                                          \
22830 _(q, "usage: quit")                                             \
22831 _(quit, "usage: quit")                                          \
22832 _(search_node_table, "usage: search_node_table <name>...")      \
22833 _(set, "usage: set <variable-name> <value>")                    \
22834 _(script, "usage: script <file-name>")                          \
22835 _(unset, "usage: unset <variable-name>")
22836 #define _(N,n)                                  \
22837     static void vl_api_##n##_t_handler_uni      \
22838     (vl_api_##n##_t * mp)                       \
22839     {                                           \
22840         vat_main_t * vam = &vat_main;           \
22841         if (vam->json_output) {                 \
22842             vl_api_##n##_t_handler_json(mp);    \
22843         } else {                                \
22844             vl_api_##n##_t_handler(mp);         \
22845         }                                       \
22846     }
22847 foreach_vpe_api_reply_msg;
22848 #if VPP_API_TEST_BUILTIN == 0
22849 foreach_standalone_reply_msg;
22850 #endif
22851 #undef _
22852
22853 void
22854 vat_api_hookup (vat_main_t * vam)
22855 {
22856 #define _(N,n)                                                  \
22857     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22858                            vl_api_##n##_t_handler_uni,          \
22859                            vl_noop_handler,                     \
22860                            vl_api_##n##_t_endian,               \
22861                            vl_api_##n##_t_print,                \
22862                            sizeof(vl_api_##n##_t), 1);
22863   foreach_vpe_api_reply_msg;
22864 #if VPP_API_TEST_BUILTIN == 0
22865   foreach_standalone_reply_msg;
22866 #endif
22867 #undef _
22868
22869 #if (VPP_API_TEST_BUILTIN==0)
22870   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22871
22872   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22873
22874   vam->function_by_name = hash_create_string (0, sizeof (uword));
22875
22876   vam->help_by_name = hash_create_string (0, sizeof (uword));
22877 #endif
22878
22879   /* API messages we can send */
22880 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22881   foreach_vpe_api_msg;
22882 #undef _
22883
22884   /* Help strings */
22885 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22886   foreach_vpe_api_msg;
22887 #undef _
22888
22889   /* CLI functions */
22890 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22891   foreach_cli_function;
22892 #undef _
22893
22894   /* Help strings */
22895 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22896   foreach_cli_function;
22897 #undef _
22898 }
22899
22900 #if VPP_API_TEST_BUILTIN
22901 static clib_error_t *
22902 vat_api_hookup_shim (vlib_main_t * vm)
22903 {
22904   vat_api_hookup (&vat_main);
22905   return 0;
22906 }
22907
22908 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22909 #endif
22910
22911 /*
22912  * fd.io coding-style-patch-verification: ON
22913  *
22914  * Local Variables:
22915  * eval: (c-set-style "gnu")
22916  * End:
22917  */