session: rules tables
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vppinfra/socket.h>
22 #include <svm/memfd.h>
23 #include <vlibapi/api.h>
24 #include <vlibmemory/api.h>
25 #include <vnet/ip/ip.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/geneve/geneve.h>
30 #include <vnet/gre/gre.h>
31 #include <vnet/vxlan-gpe/vxlan_gpe.h>
32 #include <vnet/lisp-gpe/lisp_gpe.h>
33
34 #include <vpp/api/vpe_msg_enum.h>
35 #include <vnet/l2/l2_classify.h>
36 #include <vnet/l2/l2_vtr.h>
37 #include <vnet/classify/input_acl.h>
38 #include <vnet/classify/policer_classify.h>
39 #include <vnet/classify/flow_classify.h>
40 #include <vnet/mpls/mpls.h>
41 #include <vnet/ipsec/ipsec.h>
42 #include <vnet/ipsec/ikev2.h>
43 #include <inttypes.h>
44 #include <vnet/map/map.h>
45 #include <vnet/cop/cop.h>
46 #include <vnet/ip/ip6_hop_by_hop.h>
47 #include <vnet/ip/ip_source_and_port_range_check.h>
48 #include <vnet/policer/xlate.h>
49 #include <vnet/span/span.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52 #include <vnet/mfib/mfib_types.h>
53
54 #include "vat/json_format.h"
55
56 #include <inttypes.h>
57 #include <sys/stat.h>
58
59 #define vl_typedefs             /* define message structures */
60 #include <vpp/api/vpe_all_api_h.h>
61 #undef vl_typedefs
62
63 /* declare message handlers for each api */
64
65 #define vl_endianfun            /* define message structures */
66 #include <vpp/api/vpe_all_api_h.h>
67 #undef vl_endianfun
68
69 /* instantiate all the print functions we know about */
70 #define vl_print(handle, ...)
71 #define vl_printfun
72 #include <vpp/api/vpe_all_api_h.h>
73 #undef vl_printfun
74
75 #define __plugin_msg_base 0
76 #include <vlibapi/vat_helper_macros.h>
77
78 #if VPP_API_TEST_BUILTIN == 0
79 #include <netdb.h>
80
81 u32
82 vl (void *p)
83 {
84   return vec_len (p);
85 }
86
87 int
88 vat_socket_connect (vat_main_t * vam)
89 {
90   return vl_socket_client_connect
91     (&vam->socket_client_main, (char *) vam->socket_name,
92      "vpp_api_test(s)", 0 /* default socket rx, tx buffer */ );
93 }
94 #else /* vpp built-in case, we don't do sockets... */
95 int
96 vat_socket_connect (vat_main_t * vam)
97 {
98   return 0;
99 }
100
101 void
102 vl_socket_client_read_reply (socket_client_main_t * scm)
103 {
104 };
105 #endif
106
107
108 f64
109 vat_time_now (vat_main_t * vam)
110 {
111 #if VPP_API_TEST_BUILTIN
112   return vlib_time_now (vam->vlib_main);
113 #else
114   return clib_time_now (&vam->clib_time);
115 #endif
116 }
117
118 void
119 errmsg (char *fmt, ...)
120 {
121   vat_main_t *vam = &vat_main;
122   va_list va;
123   u8 *s;
124
125   va_start (va, fmt);
126   s = va_format (0, fmt, &va);
127   va_end (va);
128
129   vec_add1 (s, 0);
130
131 #if VPP_API_TEST_BUILTIN
132   vlib_cli_output (vam->vlib_main, (char *) s);
133 #else
134   {
135     if (vam->ifp != stdin)
136       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
137                vam->input_line_number);
138     fformat (vam->ofp, (char *) s);
139     fflush (vam->ofp);
140   }
141 #endif
142
143   vec_free (s);
144 }
145
146 #if VPP_API_TEST_BUILTIN == 0
147 static uword
148 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
149 {
150   vat_main_t *vam = va_arg (*args, vat_main_t *);
151   u32 *result = va_arg (*args, u32 *);
152   u8 *if_name;
153   uword *p;
154
155   if (!unformat (input, "%s", &if_name))
156     return 0;
157
158   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
159   if (p == 0)
160     return 0;
161   *result = p[0];
162   return 1;
163 }
164
165 /* Parse an IP4 address %d.%d.%d.%d. */
166 uword
167 unformat_ip4_address (unformat_input_t * input, va_list * args)
168 {
169   u8 *result = va_arg (*args, u8 *);
170   unsigned a[4];
171
172   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
173     return 0;
174
175   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
176     return 0;
177
178   result[0] = a[0];
179   result[1] = a[1];
180   result[2] = a[2];
181   result[3] = a[3];
182
183   return 1;
184 }
185
186 uword
187 unformat_ethernet_address (unformat_input_t * input, va_list * args)
188 {
189   u8 *result = va_arg (*args, u8 *);
190   u32 i, a[6];
191
192   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
193                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
194     return 0;
195
196   /* Check range. */
197   for (i = 0; i < 6; i++)
198     if (a[i] >= (1 << 8))
199       return 0;
200
201   for (i = 0; i < 6; i++)
202     result[i] = a[i];
203
204   return 1;
205 }
206
207 /* Returns ethernet type as an int in host byte order. */
208 uword
209 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
210                                         va_list * args)
211 {
212   u16 *result = va_arg (*args, u16 *);
213   int type;
214
215   /* Numeric type. */
216   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
217     {
218       if (type >= (1 << 16))
219         return 0;
220       *result = type;
221       return 1;
222     }
223   return 0;
224 }
225
226 /* Parse an IP6 address. */
227 uword
228 unformat_ip6_address (unformat_input_t * input, va_list * args)
229 {
230   ip6_address_t *result = va_arg (*args, ip6_address_t *);
231   u16 hex_quads[8];
232   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
233   uword c, n_colon, double_colon_index;
234
235   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
236   double_colon_index = ARRAY_LEN (hex_quads);
237   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
238     {
239       hex_digit = 16;
240       if (c >= '0' && c <= '9')
241         hex_digit = c - '0';
242       else if (c >= 'a' && c <= 'f')
243         hex_digit = c + 10 - 'a';
244       else if (c >= 'A' && c <= 'F')
245         hex_digit = c + 10 - 'A';
246       else if (c == ':' && n_colon < 2)
247         n_colon++;
248       else
249         {
250           unformat_put_input (input);
251           break;
252         }
253
254       /* Too many hex quads. */
255       if (n_hex_quads >= ARRAY_LEN (hex_quads))
256         return 0;
257
258       if (hex_digit < 16)
259         {
260           hex_quad = (hex_quad << 4) | hex_digit;
261
262           /* Hex quad must fit in 16 bits. */
263           if (n_hex_digits >= 4)
264             return 0;
265
266           n_colon = 0;
267           n_hex_digits++;
268         }
269
270       /* Save position of :: */
271       if (n_colon == 2)
272         {
273           /* More than one :: ? */
274           if (double_colon_index < ARRAY_LEN (hex_quads))
275             return 0;
276           double_colon_index = n_hex_quads;
277         }
278
279       if (n_colon > 0 && n_hex_digits > 0)
280         {
281           hex_quads[n_hex_quads++] = hex_quad;
282           hex_quad = 0;
283           n_hex_digits = 0;
284         }
285     }
286
287   if (n_hex_digits > 0)
288     hex_quads[n_hex_quads++] = hex_quad;
289
290   {
291     word i;
292
293     /* Expand :: to appropriate number of zero hex quads. */
294     if (double_colon_index < ARRAY_LEN (hex_quads))
295       {
296         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
297
298         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
299           hex_quads[n_zero + i] = hex_quads[i];
300
301         for (i = 0; i < n_zero; i++)
302           hex_quads[double_colon_index + i] = 0;
303
304         n_hex_quads = ARRAY_LEN (hex_quads);
305       }
306
307     /* Too few hex quads given. */
308     if (n_hex_quads < ARRAY_LEN (hex_quads))
309       return 0;
310
311     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
312       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
313
314     return 1;
315   }
316 }
317
318 uword
319 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
320 {
321   u32 *r = va_arg (*args, u32 *);
322
323   if (0);
324 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
325   foreach_ipsec_policy_action
326 #undef _
327     else
328     return 0;
329   return 1;
330 }
331
332 uword
333 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
334 {
335   u32 *r = va_arg (*args, u32 *);
336
337   if (0);
338 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
339   foreach_ipsec_crypto_alg
340 #undef _
341     else
342     return 0;
343   return 1;
344 }
345
346 u8 *
347 format_ipsec_crypto_alg (u8 * s, va_list * args)
348 {
349   u32 i = va_arg (*args, u32);
350   u8 *t = 0;
351
352   switch (i)
353     {
354 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
355       foreach_ipsec_crypto_alg
356 #undef _
357     default:
358       return format (s, "unknown");
359     }
360   return format (s, "%s", t);
361 }
362
363 uword
364 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
365 {
366   u32 *r = va_arg (*args, u32 *);
367
368   if (0);
369 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
370   foreach_ipsec_integ_alg
371 #undef _
372     else
373     return 0;
374   return 1;
375 }
376
377 u8 *
378 format_ipsec_integ_alg (u8 * s, va_list * args)
379 {
380   u32 i = va_arg (*args, u32);
381   u8 *t = 0;
382
383   switch (i)
384     {
385 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
386       foreach_ipsec_integ_alg
387 #undef _
388     default:
389       return format (s, "unknown");
390     }
391   return format (s, "%s", t);
392 }
393
394 uword
395 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
396 {
397   u32 *r = va_arg (*args, u32 *);
398
399   if (0);
400 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
401   foreach_ikev2_auth_method
402 #undef _
403     else
404     return 0;
405   return 1;
406 }
407
408 uword
409 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
410 {
411   u32 *r = va_arg (*args, u32 *);
412
413   if (0);
414 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
415   foreach_ikev2_id_type
416 #undef _
417     else
418     return 0;
419   return 1;
420 }
421 #else /* VPP_API_TEST_BUILTIN == 1 */
422 static uword
423 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
424 {
425   vat_main_t *vam __attribute__ ((unused)) = va_arg (*args, vat_main_t *);
426   vnet_main_t *vnm = vnet_get_main ();
427   u32 *result = va_arg (*args, u32 *);
428   u32 sw_if_index;
429
430   if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
431     return 0;
432
433   *result = sw_if_index;
434   return 1;
435 }
436 #endif /* VPP_API_TEST_BUILTIN */
437
438 static uword
439 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
440 {
441   u8 *r = va_arg (*args, u8 *);
442
443   if (unformat (input, "kbps"))
444     *r = SSE2_QOS_RATE_KBPS;
445   else if (unformat (input, "pps"))
446     *r = SSE2_QOS_RATE_PPS;
447   else
448     return 0;
449   return 1;
450 }
451
452 static uword
453 unformat_policer_round_type (unformat_input_t * input, va_list * args)
454 {
455   u8 *r = va_arg (*args, u8 *);
456
457   if (unformat (input, "closest"))
458     *r = SSE2_QOS_ROUND_TO_CLOSEST;
459   else if (unformat (input, "up"))
460     *r = SSE2_QOS_ROUND_TO_UP;
461   else if (unformat (input, "down"))
462     *r = SSE2_QOS_ROUND_TO_DOWN;
463   else
464     return 0;
465   return 1;
466 }
467
468 static uword
469 unformat_policer_type (unformat_input_t * input, va_list * args)
470 {
471   u8 *r = va_arg (*args, u8 *);
472
473   if (unformat (input, "1r2c"))
474     *r = SSE2_QOS_POLICER_TYPE_1R2C;
475   else if (unformat (input, "1r3c"))
476     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
477   else if (unformat (input, "2r3c-2698"))
478     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
479   else if (unformat (input, "2r3c-4115"))
480     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
481   else if (unformat (input, "2r3c-mef5cf1"))
482     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
483   else
484     return 0;
485   return 1;
486 }
487
488 static uword
489 unformat_dscp (unformat_input_t * input, va_list * va)
490 {
491   u8 *r = va_arg (*va, u8 *);
492
493   if (0);
494 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
495   foreach_vnet_dscp
496 #undef _
497     else
498     return 0;
499   return 1;
500 }
501
502 static uword
503 unformat_policer_action_type (unformat_input_t * input, va_list * va)
504 {
505   sse2_qos_pol_action_params_st *a
506     = va_arg (*va, sse2_qos_pol_action_params_st *);
507
508   if (unformat (input, "drop"))
509     a->action_type = SSE2_QOS_ACTION_DROP;
510   else if (unformat (input, "transmit"))
511     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
512   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
513     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
514   else
515     return 0;
516   return 1;
517 }
518
519 static uword
520 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
521 {
522   u32 *r = va_arg (*va, u32 *);
523   u32 tid;
524
525   if (unformat (input, "ip4"))
526     tid = POLICER_CLASSIFY_TABLE_IP4;
527   else if (unformat (input, "ip6"))
528     tid = POLICER_CLASSIFY_TABLE_IP6;
529   else if (unformat (input, "l2"))
530     tid = POLICER_CLASSIFY_TABLE_L2;
531   else
532     return 0;
533
534   *r = tid;
535   return 1;
536 }
537
538 static uword
539 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
540 {
541   u32 *r = va_arg (*va, u32 *);
542   u32 tid;
543
544   if (unformat (input, "ip4"))
545     tid = FLOW_CLASSIFY_TABLE_IP4;
546   else if (unformat (input, "ip6"))
547     tid = FLOW_CLASSIFY_TABLE_IP6;
548   else
549     return 0;
550
551   *r = tid;
552   return 1;
553 }
554
555 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
556 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
557 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
558 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
559
560 #if (VPP_API_TEST_BUILTIN==0)
561 uword
562 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
563 {
564   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
565   mfib_itf_attribute_t attr;
566
567   old = *iflags;
568   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
569   {
570     if (unformat (input, mfib_itf_flag_long_names[attr]))
571       *iflags |= (1 << attr);
572   }
573   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
574   {
575     if (unformat (input, mfib_itf_flag_names[attr]))
576       *iflags |= (1 << attr);
577   }
578
579   return (old == *iflags ? 0 : 1);
580 }
581
582 uword
583 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
584 {
585   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
586   mfib_entry_attribute_t attr;
587
588   old = *eflags;
589   FOR_EACH_MFIB_ATTRIBUTE (attr)
590   {
591     if (unformat (input, mfib_flag_long_names[attr]))
592       *eflags |= (1 << attr);
593   }
594   FOR_EACH_MFIB_ATTRIBUTE (attr)
595   {
596     if (unformat (input, mfib_flag_names[attr]))
597       *eflags |= (1 << attr);
598   }
599
600   return (old == *eflags ? 0 : 1);
601 }
602
603 u8 *
604 format_ip4_address (u8 * s, va_list * args)
605 {
606   u8 *a = va_arg (*args, u8 *);
607   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
608 }
609
610 u8 *
611 format_ip6_address (u8 * s, va_list * args)
612 {
613   ip6_address_t *a = va_arg (*args, ip6_address_t *);
614   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
615
616   i_max_n_zero = ARRAY_LEN (a->as_u16);
617   max_n_zeros = 0;
618   i_first_zero = i_max_n_zero;
619   n_zeros = 0;
620   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
621     {
622       u32 is_zero = a->as_u16[i] == 0;
623       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
624         {
625           i_first_zero = i;
626           n_zeros = 0;
627         }
628       n_zeros += is_zero;
629       if ((!is_zero && n_zeros > max_n_zeros)
630           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
631         {
632           i_max_n_zero = i_first_zero;
633           max_n_zeros = n_zeros;
634           i_first_zero = ARRAY_LEN (a->as_u16);
635           n_zeros = 0;
636         }
637     }
638
639   last_double_colon = 0;
640   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
641     {
642       if (i == i_max_n_zero && max_n_zeros > 1)
643         {
644           s = format (s, "::");
645           i += max_n_zeros - 1;
646           last_double_colon = 1;
647         }
648       else
649         {
650           s = format (s, "%s%x",
651                       (last_double_colon || i == 0) ? "" : ":",
652                       clib_net_to_host_u16 (a->as_u16[i]));
653           last_double_colon = 0;
654         }
655     }
656
657   return s;
658 }
659
660 /* Format an IP46 address. */
661 u8 *
662 format_ip46_address (u8 * s, va_list * args)
663 {
664   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
665   ip46_type_t type = va_arg (*args, ip46_type_t);
666   int is_ip4 = 1;
667
668   switch (type)
669     {
670     case IP46_TYPE_ANY:
671       is_ip4 = ip46_address_is_ip4 (ip46);
672       break;
673     case IP46_TYPE_IP4:
674       is_ip4 = 1;
675       break;
676     case IP46_TYPE_IP6:
677       is_ip4 = 0;
678       break;
679     }
680
681   return is_ip4 ?
682     format (s, "%U", format_ip4_address, &ip46->ip4) :
683     format (s, "%U", format_ip6_address, &ip46->ip6);
684 }
685
686 u8 *
687 format_ethernet_address (u8 * s, va_list * args)
688 {
689   u8 *a = va_arg (*args, u8 *);
690
691   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
692                  a[0], a[1], a[2], a[3], a[4], a[5]);
693 }
694 #endif
695
696 static void
697 increment_v4_address (ip4_address_t * a)
698 {
699   u32 v;
700
701   v = ntohl (a->as_u32) + 1;
702   a->as_u32 = ntohl (v);
703 }
704
705 static void
706 increment_v6_address (ip6_address_t * a)
707 {
708   u64 v0, v1;
709
710   v0 = clib_net_to_host_u64 (a->as_u64[0]);
711   v1 = clib_net_to_host_u64 (a->as_u64[1]);
712
713   v1 += 1;
714   if (v1 == 0)
715     v0 += 1;
716   a->as_u64[0] = clib_net_to_host_u64 (v0);
717   a->as_u64[1] = clib_net_to_host_u64 (v1);
718 }
719
720 static void
721 increment_mac_address (u64 * mac)
722 {
723   u64 tmp = *mac;
724
725   tmp = clib_net_to_host_u64 (tmp);
726   tmp += 1 << 16;               /* skip unused (least significant) octets */
727   tmp = clib_host_to_net_u64 (tmp);
728   *mac = tmp;
729 }
730
731 static void vl_api_create_loopback_reply_t_handler
732   (vl_api_create_loopback_reply_t * mp)
733 {
734   vat_main_t *vam = &vat_main;
735   i32 retval = ntohl (mp->retval);
736
737   vam->retval = retval;
738   vam->regenerate_interface_table = 1;
739   vam->sw_if_index = ntohl (mp->sw_if_index);
740   vam->result_ready = 1;
741 }
742
743 static void vl_api_create_loopback_reply_t_handler_json
744   (vl_api_create_loopback_reply_t * mp)
745 {
746   vat_main_t *vam = &vat_main;
747   vat_json_node_t node;
748
749   vat_json_init_object (&node);
750   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
751   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
752
753   vat_json_print (vam->ofp, &node);
754   vat_json_free (&node);
755   vam->retval = ntohl (mp->retval);
756   vam->result_ready = 1;
757 }
758
759 static void vl_api_create_loopback_instance_reply_t_handler
760   (vl_api_create_loopback_instance_reply_t * mp)
761 {
762   vat_main_t *vam = &vat_main;
763   i32 retval = ntohl (mp->retval);
764
765   vam->retval = retval;
766   vam->regenerate_interface_table = 1;
767   vam->sw_if_index = ntohl (mp->sw_if_index);
768   vam->result_ready = 1;
769 }
770
771 static void vl_api_create_loopback_instance_reply_t_handler_json
772   (vl_api_create_loopback_instance_reply_t * mp)
773 {
774   vat_main_t *vam = &vat_main;
775   vat_json_node_t node;
776
777   vat_json_init_object (&node);
778   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
779   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
780
781   vat_json_print (vam->ofp, &node);
782   vat_json_free (&node);
783   vam->retval = ntohl (mp->retval);
784   vam->result_ready = 1;
785 }
786
787 static void vl_api_af_packet_create_reply_t_handler
788   (vl_api_af_packet_create_reply_t * mp)
789 {
790   vat_main_t *vam = &vat_main;
791   i32 retval = ntohl (mp->retval);
792
793   vam->retval = retval;
794   vam->regenerate_interface_table = 1;
795   vam->sw_if_index = ntohl (mp->sw_if_index);
796   vam->result_ready = 1;
797 }
798
799 static void vl_api_af_packet_create_reply_t_handler_json
800   (vl_api_af_packet_create_reply_t * mp)
801 {
802   vat_main_t *vam = &vat_main;
803   vat_json_node_t node;
804
805   vat_json_init_object (&node);
806   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
807   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
808
809   vat_json_print (vam->ofp, &node);
810   vat_json_free (&node);
811
812   vam->retval = ntohl (mp->retval);
813   vam->result_ready = 1;
814 }
815
816 static void vl_api_create_vlan_subif_reply_t_handler
817   (vl_api_create_vlan_subif_reply_t * mp)
818 {
819   vat_main_t *vam = &vat_main;
820   i32 retval = ntohl (mp->retval);
821
822   vam->retval = retval;
823   vam->regenerate_interface_table = 1;
824   vam->sw_if_index = ntohl (mp->sw_if_index);
825   vam->result_ready = 1;
826 }
827
828 static void vl_api_create_vlan_subif_reply_t_handler_json
829   (vl_api_create_vlan_subif_reply_t * mp)
830 {
831   vat_main_t *vam = &vat_main;
832   vat_json_node_t node;
833
834   vat_json_init_object (&node);
835   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
836   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
837
838   vat_json_print (vam->ofp, &node);
839   vat_json_free (&node);
840
841   vam->retval = ntohl (mp->retval);
842   vam->result_ready = 1;
843 }
844
845 static void vl_api_create_subif_reply_t_handler
846   (vl_api_create_subif_reply_t * mp)
847 {
848   vat_main_t *vam = &vat_main;
849   i32 retval = ntohl (mp->retval);
850
851   vam->retval = retval;
852   vam->regenerate_interface_table = 1;
853   vam->sw_if_index = ntohl (mp->sw_if_index);
854   vam->result_ready = 1;
855 }
856
857 static void vl_api_create_subif_reply_t_handler_json
858   (vl_api_create_subif_reply_t * mp)
859 {
860   vat_main_t *vam = &vat_main;
861   vat_json_node_t node;
862
863   vat_json_init_object (&node);
864   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
865   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
866
867   vat_json_print (vam->ofp, &node);
868   vat_json_free (&node);
869
870   vam->retval = ntohl (mp->retval);
871   vam->result_ready = 1;
872 }
873
874 static void vl_api_interface_name_renumber_reply_t_handler
875   (vl_api_interface_name_renumber_reply_t * mp)
876 {
877   vat_main_t *vam = &vat_main;
878   i32 retval = ntohl (mp->retval);
879
880   vam->retval = retval;
881   vam->regenerate_interface_table = 1;
882   vam->result_ready = 1;
883 }
884
885 static void vl_api_interface_name_renumber_reply_t_handler_json
886   (vl_api_interface_name_renumber_reply_t * mp)
887 {
888   vat_main_t *vam = &vat_main;
889   vat_json_node_t node;
890
891   vat_json_init_object (&node);
892   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
893
894   vat_json_print (vam->ofp, &node);
895   vat_json_free (&node);
896
897   vam->retval = ntohl (mp->retval);
898   vam->result_ready = 1;
899 }
900
901 /*
902  * Special-case: build the interface table, maintain
903  * the next loopback sw_if_index vbl.
904  */
905 static void vl_api_sw_interface_details_t_handler
906   (vl_api_sw_interface_details_t * mp)
907 {
908   vat_main_t *vam = &vat_main;
909   u8 *s = format (0, "%s%c", mp->interface_name, 0);
910
911   hash_set_mem (vam->sw_if_index_by_interface_name, s,
912                 ntohl (mp->sw_if_index));
913
914   /* In sub interface case, fill the sub interface table entry */
915   if (mp->sw_if_index != mp->sup_sw_if_index)
916     {
917       sw_interface_subif_t *sub = NULL;
918
919       vec_add2 (vam->sw_if_subif_table, sub, 1);
920
921       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
922       strncpy ((char *) sub->interface_name, (char *) s,
923                vec_len (sub->interface_name));
924       sub->sw_if_index = ntohl (mp->sw_if_index);
925       sub->sub_id = ntohl (mp->sub_id);
926
927       sub->sub_dot1ad = mp->sub_dot1ad;
928       sub->sub_number_of_tags = mp->sub_number_of_tags;
929       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
930       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
931       sub->sub_exact_match = mp->sub_exact_match;
932       sub->sub_default = mp->sub_default;
933       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
934       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
935
936       /* vlan tag rewrite */
937       sub->vtr_op = ntohl (mp->vtr_op);
938       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
939       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
940       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
941     }
942 }
943
944 static void vl_api_sw_interface_details_t_handler_json
945   (vl_api_sw_interface_details_t * mp)
946 {
947   vat_main_t *vam = &vat_main;
948   vat_json_node_t *node = NULL;
949
950   if (VAT_JSON_ARRAY != vam->json_tree.type)
951     {
952       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
953       vat_json_init_array (&vam->json_tree);
954     }
955   node = vat_json_array_add (&vam->json_tree);
956
957   vat_json_init_object (node);
958   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
959   vat_json_object_add_uint (node, "sup_sw_if_index",
960                             ntohl (mp->sup_sw_if_index));
961   vat_json_object_add_uint (node, "l2_address_length",
962                             ntohl (mp->l2_address_length));
963   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
964                              sizeof (mp->l2_address));
965   vat_json_object_add_string_copy (node, "interface_name",
966                                    mp->interface_name);
967   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
968   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
969   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
970   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
971   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
972   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
973   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
974   vat_json_object_add_uint (node, "sub_number_of_tags",
975                             mp->sub_number_of_tags);
976   vat_json_object_add_uint (node, "sub_outer_vlan_id",
977                             ntohs (mp->sub_outer_vlan_id));
978   vat_json_object_add_uint (node, "sub_inner_vlan_id",
979                             ntohs (mp->sub_inner_vlan_id));
980   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
981   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
982   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
983                             mp->sub_outer_vlan_id_any);
984   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
985                             mp->sub_inner_vlan_id_any);
986   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
987   vat_json_object_add_uint (node, "vtr_push_dot1q",
988                             ntohl (mp->vtr_push_dot1q));
989   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
990   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
991   if (mp->sub_dot1ah)
992     {
993       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
994                                        format (0, "%U",
995                                                format_ethernet_address,
996                                                &mp->b_dmac));
997       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
998                                        format (0, "%U",
999                                                format_ethernet_address,
1000                                                &mp->b_smac));
1001       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1002       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1003     }
1004 }
1005
1006 #if VPP_API_TEST_BUILTIN == 0
1007 static void vl_api_sw_interface_event_t_handler
1008   (vl_api_sw_interface_event_t * mp)
1009 {
1010   vat_main_t *vam = &vat_main;
1011   if (vam->interface_event_display)
1012     errmsg ("interface flags: sw_if_index %d %s %s",
1013             ntohl (mp->sw_if_index),
1014             mp->admin_up_down ? "admin-up" : "admin-down",
1015             mp->link_up_down ? "link-up" : "link-down");
1016 }
1017 #endif
1018
1019 static void vl_api_sw_interface_event_t_handler_json
1020   (vl_api_sw_interface_event_t * mp)
1021 {
1022   /* JSON output not supported */
1023 }
1024
1025 static void
1026 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1027 {
1028   vat_main_t *vam = &vat_main;
1029   i32 retval = ntohl (mp->retval);
1030
1031   vam->retval = retval;
1032   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1033   vam->result_ready = 1;
1034 }
1035
1036 static void
1037 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1038 {
1039   vat_main_t *vam = &vat_main;
1040   vat_json_node_t node;
1041   api_main_t *am = &api_main;
1042   void *oldheap;
1043   u8 *reply;
1044
1045   vat_json_init_object (&node);
1046   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1047   vat_json_object_add_uint (&node, "reply_in_shmem",
1048                             ntohl (mp->reply_in_shmem));
1049   /* Toss the shared-memory original... */
1050   pthread_mutex_lock (&am->vlib_rp->mutex);
1051   oldheap = svm_push_data_heap (am->vlib_rp);
1052
1053   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1054   vec_free (reply);
1055
1056   svm_pop_heap (oldheap);
1057   pthread_mutex_unlock (&am->vlib_rp->mutex);
1058
1059   vat_json_print (vam->ofp, &node);
1060   vat_json_free (&node);
1061
1062   vam->retval = ntohl (mp->retval);
1063   vam->result_ready = 1;
1064 }
1065
1066 static void
1067 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1068 {
1069   vat_main_t *vam = &vat_main;
1070   i32 retval = ntohl (mp->retval);
1071   u32 length = ntohl (mp->length);
1072
1073   vec_reset_length (vam->cmd_reply);
1074
1075   vam->retval = retval;
1076   if (retval == 0)
1077     {
1078       vec_validate (vam->cmd_reply, length);
1079       clib_memcpy ((char *) (vam->cmd_reply), mp->reply, length);
1080       vam->cmd_reply[length] = 0;
1081     }
1082   vam->result_ready = 1;
1083 }
1084
1085 static void
1086 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1087 {
1088   vat_main_t *vam = &vat_main;
1089   vat_json_node_t node;
1090
1091   vec_reset_length (vam->cmd_reply);
1092
1093   vat_json_init_object (&node);
1094   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1095   vat_json_object_add_string_copy (&node, "reply", mp->reply);
1096
1097   vat_json_print (vam->ofp, &node);
1098   vat_json_free (&node);
1099
1100   vam->retval = ntohl (mp->retval);
1101   vam->result_ready = 1;
1102 }
1103
1104 static void vl_api_classify_add_del_table_reply_t_handler
1105   (vl_api_classify_add_del_table_reply_t * mp)
1106 {
1107   vat_main_t *vam = &vat_main;
1108   i32 retval = ntohl (mp->retval);
1109   if (vam->async_mode)
1110     {
1111       vam->async_errors += (retval < 0);
1112     }
1113   else
1114     {
1115       vam->retval = retval;
1116       if (retval == 0 &&
1117           ((mp->new_table_index != 0xFFFFFFFF) ||
1118            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1119            (mp->match_n_vectors != 0xFFFFFFFF)))
1120         /*
1121          * Note: this is just barely thread-safe, depends on
1122          * the main thread spinning waiting for an answer...
1123          */
1124         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1125                 ntohl (mp->new_table_index),
1126                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1127       vam->result_ready = 1;
1128     }
1129 }
1130
1131 static void vl_api_classify_add_del_table_reply_t_handler_json
1132   (vl_api_classify_add_del_table_reply_t * mp)
1133 {
1134   vat_main_t *vam = &vat_main;
1135   vat_json_node_t node;
1136
1137   vat_json_init_object (&node);
1138   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1139   vat_json_object_add_uint (&node, "new_table_index",
1140                             ntohl (mp->new_table_index));
1141   vat_json_object_add_uint (&node, "skip_n_vectors",
1142                             ntohl (mp->skip_n_vectors));
1143   vat_json_object_add_uint (&node, "match_n_vectors",
1144                             ntohl (mp->match_n_vectors));
1145
1146   vat_json_print (vam->ofp, &node);
1147   vat_json_free (&node);
1148
1149   vam->retval = ntohl (mp->retval);
1150   vam->result_ready = 1;
1151 }
1152
1153 static void vl_api_get_node_index_reply_t_handler
1154   (vl_api_get_node_index_reply_t * mp)
1155 {
1156   vat_main_t *vam = &vat_main;
1157   i32 retval = ntohl (mp->retval);
1158   if (vam->async_mode)
1159     {
1160       vam->async_errors += (retval < 0);
1161     }
1162   else
1163     {
1164       vam->retval = retval;
1165       if (retval == 0)
1166         errmsg ("node index %d", ntohl (mp->node_index));
1167       vam->result_ready = 1;
1168     }
1169 }
1170
1171 static void vl_api_get_node_index_reply_t_handler_json
1172   (vl_api_get_node_index_reply_t * mp)
1173 {
1174   vat_main_t *vam = &vat_main;
1175   vat_json_node_t node;
1176
1177   vat_json_init_object (&node);
1178   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1179   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1180
1181   vat_json_print (vam->ofp, &node);
1182   vat_json_free (&node);
1183
1184   vam->retval = ntohl (mp->retval);
1185   vam->result_ready = 1;
1186 }
1187
1188 static void vl_api_get_next_index_reply_t_handler
1189   (vl_api_get_next_index_reply_t * mp)
1190 {
1191   vat_main_t *vam = &vat_main;
1192   i32 retval = ntohl (mp->retval);
1193   if (vam->async_mode)
1194     {
1195       vam->async_errors += (retval < 0);
1196     }
1197   else
1198     {
1199       vam->retval = retval;
1200       if (retval == 0)
1201         errmsg ("next node index %d", ntohl (mp->next_index));
1202       vam->result_ready = 1;
1203     }
1204 }
1205
1206 static void vl_api_get_next_index_reply_t_handler_json
1207   (vl_api_get_next_index_reply_t * mp)
1208 {
1209   vat_main_t *vam = &vat_main;
1210   vat_json_node_t node;
1211
1212   vat_json_init_object (&node);
1213   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1214   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1215
1216   vat_json_print (vam->ofp, &node);
1217   vat_json_free (&node);
1218
1219   vam->retval = ntohl (mp->retval);
1220   vam->result_ready = 1;
1221 }
1222
1223 static void vl_api_add_node_next_reply_t_handler
1224   (vl_api_add_node_next_reply_t * mp)
1225 {
1226   vat_main_t *vam = &vat_main;
1227   i32 retval = ntohl (mp->retval);
1228   if (vam->async_mode)
1229     {
1230       vam->async_errors += (retval < 0);
1231     }
1232   else
1233     {
1234       vam->retval = retval;
1235       if (retval == 0)
1236         errmsg ("next index %d", ntohl (mp->next_index));
1237       vam->result_ready = 1;
1238     }
1239 }
1240
1241 static void vl_api_add_node_next_reply_t_handler_json
1242   (vl_api_add_node_next_reply_t * mp)
1243 {
1244   vat_main_t *vam = &vat_main;
1245   vat_json_node_t node;
1246
1247   vat_json_init_object (&node);
1248   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1249   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1250
1251   vat_json_print (vam->ofp, &node);
1252   vat_json_free (&node);
1253
1254   vam->retval = ntohl (mp->retval);
1255   vam->result_ready = 1;
1256 }
1257
1258 static void vl_api_show_version_reply_t_handler
1259   (vl_api_show_version_reply_t * mp)
1260 {
1261   vat_main_t *vam = &vat_main;
1262   i32 retval = ntohl (mp->retval);
1263
1264   if (retval >= 0)
1265     {
1266       errmsg ("        program: %s", mp->program);
1267       errmsg ("        version: %s", mp->version);
1268       errmsg ("     build date: %s", mp->build_date);
1269       errmsg ("build directory: %s", mp->build_directory);
1270     }
1271   vam->retval = retval;
1272   vam->result_ready = 1;
1273 }
1274
1275 static void vl_api_show_version_reply_t_handler_json
1276   (vl_api_show_version_reply_t * mp)
1277 {
1278   vat_main_t *vam = &vat_main;
1279   vat_json_node_t node;
1280
1281   vat_json_init_object (&node);
1282   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1283   vat_json_object_add_string_copy (&node, "program", mp->program);
1284   vat_json_object_add_string_copy (&node, "version", mp->version);
1285   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1286   vat_json_object_add_string_copy (&node, "build_directory",
1287                                    mp->build_directory);
1288
1289   vat_json_print (vam->ofp, &node);
1290   vat_json_free (&node);
1291
1292   vam->retval = ntohl (mp->retval);
1293   vam->result_ready = 1;
1294 }
1295
1296 static void
1297 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1298 {
1299   u32 sw_if_index = ntohl (mp->sw_if_index);
1300   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1301           mp->mac_ip ? "mac/ip binding" : "address resolution",
1302           ntohl (mp->pid), format_ip4_address, &mp->address,
1303           format_ethernet_address, mp->new_mac, sw_if_index);
1304 }
1305
1306 static void
1307 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1308 {
1309   /* JSON output not supported */
1310 }
1311
1312 static void
1313 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1314 {
1315   u32 sw_if_index = ntohl (mp->sw_if_index);
1316   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1317           mp->mac_ip ? "mac/ip binding" : "address resolution",
1318           ntohl (mp->pid), format_ip6_address, mp->address,
1319           format_ethernet_address, mp->new_mac, sw_if_index);
1320 }
1321
1322 static void
1323 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1324 {
1325   /* JSON output not supported */
1326 }
1327
1328 static void
1329 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1330 {
1331   u32 n_macs = ntohl (mp->n_macs);
1332   errmsg ("L2MAC event recived with pid %d cl-idx %d for %d macs: \n",
1333           ntohl (mp->pid), mp->client_index, n_macs);
1334   int i;
1335   for (i = 0; i < n_macs; i++)
1336     {
1337       vl_api_mac_entry_t *mac = &mp->mac[i];
1338       errmsg (" [%d] sw_if_index %d  mac_addr %U  is_del %d \n",
1339               i + 1, ntohl (mac->sw_if_index),
1340               format_ethernet_address, mac->mac_addr, mac->is_del);
1341       if (i == 1000)
1342         break;
1343     }
1344 }
1345
1346 static void
1347 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1348 {
1349   /* JSON output not supported */
1350 }
1351
1352 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1353 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1354
1355 /*
1356  * Special-case: build the bridge domain table, maintain
1357  * the next bd id vbl.
1358  */
1359 static void vl_api_bridge_domain_details_t_handler
1360   (vl_api_bridge_domain_details_t * mp)
1361 {
1362   vat_main_t *vam = &vat_main;
1363   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1364   int i;
1365
1366   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1367          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1368
1369   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1370          ntohl (mp->bd_id), mp->learn, mp->forward,
1371          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1372
1373   if (n_sw_ifs)
1374     {
1375       vl_api_bridge_domain_sw_if_t *sw_ifs;
1376       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1377              "Interface Name");
1378
1379       sw_ifs = mp->sw_if_details;
1380       for (i = 0; i < n_sw_ifs; i++)
1381         {
1382           u8 *sw_if_name = 0;
1383           u32 sw_if_index;
1384           hash_pair_t *p;
1385
1386           sw_if_index = ntohl (sw_ifs->sw_if_index);
1387
1388           /* *INDENT-OFF* */
1389           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1390                              ({
1391                                if ((u32) p->value[0] == sw_if_index)
1392                                  {
1393                                    sw_if_name = (u8 *)(p->key);
1394                                    break;
1395                                  }
1396                              }));
1397           /* *INDENT-ON* */
1398           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1399                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1400                  "sw_if_index not found!");
1401
1402           sw_ifs++;
1403         }
1404     }
1405 }
1406
1407 static void vl_api_bridge_domain_details_t_handler_json
1408   (vl_api_bridge_domain_details_t * mp)
1409 {
1410   vat_main_t *vam = &vat_main;
1411   vat_json_node_t *node, *array = NULL;
1412   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1413
1414   if (VAT_JSON_ARRAY != vam->json_tree.type)
1415     {
1416       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1417       vat_json_init_array (&vam->json_tree);
1418     }
1419   node = vat_json_array_add (&vam->json_tree);
1420
1421   vat_json_init_object (node);
1422   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1423   vat_json_object_add_uint (node, "flood", mp->flood);
1424   vat_json_object_add_uint (node, "forward", mp->forward);
1425   vat_json_object_add_uint (node, "learn", mp->learn);
1426   vat_json_object_add_uint (node, "bvi_sw_if_index",
1427                             ntohl (mp->bvi_sw_if_index));
1428   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1429   array = vat_json_object_add (node, "sw_if");
1430   vat_json_init_array (array);
1431
1432
1433
1434   if (n_sw_ifs)
1435     {
1436       vl_api_bridge_domain_sw_if_t *sw_ifs;
1437       int i;
1438
1439       sw_ifs = mp->sw_if_details;
1440       for (i = 0; i < n_sw_ifs; i++)
1441         {
1442           node = vat_json_array_add (array);
1443           vat_json_init_object (node);
1444           vat_json_object_add_uint (node, "sw_if_index",
1445                                     ntohl (sw_ifs->sw_if_index));
1446           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1447           sw_ifs++;
1448         }
1449     }
1450 }
1451
1452 static void vl_api_control_ping_reply_t_handler
1453   (vl_api_control_ping_reply_t * mp)
1454 {
1455   vat_main_t *vam = &vat_main;
1456   i32 retval = ntohl (mp->retval);
1457   if (vam->async_mode)
1458     {
1459       vam->async_errors += (retval < 0);
1460     }
1461   else
1462     {
1463       vam->retval = retval;
1464       vam->result_ready = 1;
1465     }
1466   vam->socket_client_main.control_pings_outstanding--;
1467 }
1468
1469 static void vl_api_control_ping_reply_t_handler_json
1470   (vl_api_control_ping_reply_t * mp)
1471 {
1472   vat_main_t *vam = &vat_main;
1473   i32 retval = ntohl (mp->retval);
1474
1475   if (VAT_JSON_NONE != vam->json_tree.type)
1476     {
1477       vat_json_print (vam->ofp, &vam->json_tree);
1478       vat_json_free (&vam->json_tree);
1479       vam->json_tree.type = VAT_JSON_NONE;
1480     }
1481   else
1482     {
1483       /* just print [] */
1484       vat_json_init_array (&vam->json_tree);
1485       vat_json_print (vam->ofp, &vam->json_tree);
1486       vam->json_tree.type = VAT_JSON_NONE;
1487     }
1488
1489   vam->retval = retval;
1490   vam->result_ready = 1;
1491 }
1492
1493 static void
1494   vl_api_bridge_domain_set_mac_age_reply_t_handler
1495   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1496 {
1497   vat_main_t *vam = &vat_main;
1498   i32 retval = ntohl (mp->retval);
1499   if (vam->async_mode)
1500     {
1501       vam->async_errors += (retval < 0);
1502     }
1503   else
1504     {
1505       vam->retval = retval;
1506       vam->result_ready = 1;
1507     }
1508 }
1509
1510 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1511   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1512 {
1513   vat_main_t *vam = &vat_main;
1514   vat_json_node_t node;
1515
1516   vat_json_init_object (&node);
1517   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1518
1519   vat_json_print (vam->ofp, &node);
1520   vat_json_free (&node);
1521
1522   vam->retval = ntohl (mp->retval);
1523   vam->result_ready = 1;
1524 }
1525
1526 static void
1527 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1528 {
1529   vat_main_t *vam = &vat_main;
1530   i32 retval = ntohl (mp->retval);
1531   if (vam->async_mode)
1532     {
1533       vam->async_errors += (retval < 0);
1534     }
1535   else
1536     {
1537       vam->retval = retval;
1538       vam->result_ready = 1;
1539     }
1540 }
1541
1542 static void vl_api_l2_flags_reply_t_handler_json
1543   (vl_api_l2_flags_reply_t * mp)
1544 {
1545   vat_main_t *vam = &vat_main;
1546   vat_json_node_t node;
1547
1548   vat_json_init_object (&node);
1549   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1550   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1551                             ntohl (mp->resulting_feature_bitmap));
1552
1553   vat_json_print (vam->ofp, &node);
1554   vat_json_free (&node);
1555
1556   vam->retval = ntohl (mp->retval);
1557   vam->result_ready = 1;
1558 }
1559
1560 static void vl_api_bridge_flags_reply_t_handler
1561   (vl_api_bridge_flags_reply_t * mp)
1562 {
1563   vat_main_t *vam = &vat_main;
1564   i32 retval = ntohl (mp->retval);
1565   if (vam->async_mode)
1566     {
1567       vam->async_errors += (retval < 0);
1568     }
1569   else
1570     {
1571       vam->retval = retval;
1572       vam->result_ready = 1;
1573     }
1574 }
1575
1576 static void vl_api_bridge_flags_reply_t_handler_json
1577   (vl_api_bridge_flags_reply_t * mp)
1578 {
1579   vat_main_t *vam = &vat_main;
1580   vat_json_node_t node;
1581
1582   vat_json_init_object (&node);
1583   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1584   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1585                             ntohl (mp->resulting_feature_bitmap));
1586
1587   vat_json_print (vam->ofp, &node);
1588   vat_json_free (&node);
1589
1590   vam->retval = ntohl (mp->retval);
1591   vam->result_ready = 1;
1592 }
1593
1594 static void vl_api_tap_connect_reply_t_handler
1595   (vl_api_tap_connect_reply_t * mp)
1596 {
1597   vat_main_t *vam = &vat_main;
1598   i32 retval = ntohl (mp->retval);
1599   if (vam->async_mode)
1600     {
1601       vam->async_errors += (retval < 0);
1602     }
1603   else
1604     {
1605       vam->retval = retval;
1606       vam->sw_if_index = ntohl (mp->sw_if_index);
1607       vam->result_ready = 1;
1608     }
1609
1610 }
1611
1612 static void vl_api_tap_connect_reply_t_handler_json
1613   (vl_api_tap_connect_reply_t * mp)
1614 {
1615   vat_main_t *vam = &vat_main;
1616   vat_json_node_t node;
1617
1618   vat_json_init_object (&node);
1619   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1620   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1621
1622   vat_json_print (vam->ofp, &node);
1623   vat_json_free (&node);
1624
1625   vam->retval = ntohl (mp->retval);
1626   vam->result_ready = 1;
1627
1628 }
1629
1630 static void
1631 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1632 {
1633   vat_main_t *vam = &vat_main;
1634   i32 retval = ntohl (mp->retval);
1635   if (vam->async_mode)
1636     {
1637       vam->async_errors += (retval < 0);
1638     }
1639   else
1640     {
1641       vam->retval = retval;
1642       vam->sw_if_index = ntohl (mp->sw_if_index);
1643       vam->result_ready = 1;
1644     }
1645 }
1646
1647 static void vl_api_tap_modify_reply_t_handler_json
1648   (vl_api_tap_modify_reply_t * mp)
1649 {
1650   vat_main_t *vam = &vat_main;
1651   vat_json_node_t node;
1652
1653   vat_json_init_object (&node);
1654   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1655   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1656
1657   vat_json_print (vam->ofp, &node);
1658   vat_json_free (&node);
1659
1660   vam->retval = ntohl (mp->retval);
1661   vam->result_ready = 1;
1662 }
1663
1664 static void
1665 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1666 {
1667   vat_main_t *vam = &vat_main;
1668   i32 retval = ntohl (mp->retval);
1669   if (vam->async_mode)
1670     {
1671       vam->async_errors += (retval < 0);
1672     }
1673   else
1674     {
1675       vam->retval = retval;
1676       vam->result_ready = 1;
1677     }
1678 }
1679
1680 static void vl_api_tap_delete_reply_t_handler_json
1681   (vl_api_tap_delete_reply_t * mp)
1682 {
1683   vat_main_t *vam = &vat_main;
1684   vat_json_node_t node;
1685
1686   vat_json_init_object (&node);
1687   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1688
1689   vat_json_print (vam->ofp, &node);
1690   vat_json_free (&node);
1691
1692   vam->retval = ntohl (mp->retval);
1693   vam->result_ready = 1;
1694 }
1695
1696 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1697   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1698 {
1699   vat_main_t *vam = &vat_main;
1700   i32 retval = ntohl (mp->retval);
1701   if (vam->async_mode)
1702     {
1703       vam->async_errors += (retval < 0);
1704     }
1705   else
1706     {
1707       vam->retval = retval;
1708       vam->result_ready = 1;
1709     }
1710 }
1711
1712 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1713   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1714 {
1715   vat_main_t *vam = &vat_main;
1716   vat_json_node_t node;
1717
1718   vat_json_init_object (&node);
1719   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1720   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1721                             ntohl (mp->sw_if_index));
1722
1723   vat_json_print (vam->ofp, &node);
1724   vat_json_free (&node);
1725
1726   vam->retval = ntohl (mp->retval);
1727   vam->result_ready = 1;
1728 }
1729
1730 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1731   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1732 {
1733   vat_main_t *vam = &vat_main;
1734   i32 retval = ntohl (mp->retval);
1735   if (vam->async_mode)
1736     {
1737       vam->async_errors += (retval < 0);
1738     }
1739   else
1740     {
1741       vam->retval = retval;
1742       vam->sw_if_index = ntohl (mp->sw_if_index);
1743       vam->result_ready = 1;
1744     }
1745 }
1746
1747 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1748   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1749 {
1750   vat_main_t *vam = &vat_main;
1751   vat_json_node_t node;
1752
1753   vat_json_init_object (&node);
1754   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1755   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1756
1757   vat_json_print (vam->ofp, &node);
1758   vat_json_free (&node);
1759
1760   vam->retval = ntohl (mp->retval);
1761   vam->result_ready = 1;
1762 }
1763
1764 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
1765   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1766 {
1767   vat_main_t *vam = &vat_main;
1768   i32 retval = ntohl (mp->retval);
1769   if (vam->async_mode)
1770     {
1771       vam->async_errors += (retval < 0);
1772     }
1773   else
1774     {
1775       vam->retval = retval;
1776       vam->result_ready = 1;
1777     }
1778 }
1779
1780 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
1781   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
1782 {
1783   vat_main_t *vam = &vat_main;
1784   vat_json_node_t node;
1785
1786   vat_json_init_object (&node);
1787   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1788   vat_json_object_add_uint (&node, "fwd_entry_index",
1789                             clib_net_to_host_u32 (mp->fwd_entry_index));
1790
1791   vat_json_print (vam->ofp, &node);
1792   vat_json_free (&node);
1793
1794   vam->retval = ntohl (mp->retval);
1795   vam->result_ready = 1;
1796 }
1797
1798 u8 *
1799 format_lisp_transport_protocol (u8 * s, va_list * args)
1800 {
1801   u32 proto = va_arg (*args, u32);
1802
1803   switch (proto)
1804     {
1805     case 1:
1806       return format (s, "udp");
1807     case 2:
1808       return format (s, "api");
1809     default:
1810       return 0;
1811     }
1812   return 0;
1813 }
1814
1815 static void vl_api_one_get_transport_protocol_reply_t_handler
1816   (vl_api_one_get_transport_protocol_reply_t * mp)
1817 {
1818   vat_main_t *vam = &vat_main;
1819   i32 retval = ntohl (mp->retval);
1820   if (vam->async_mode)
1821     {
1822       vam->async_errors += (retval < 0);
1823     }
1824   else
1825     {
1826       u32 proto = mp->protocol;
1827       print (vam->ofp, "Transport protocol: %U",
1828              format_lisp_transport_protocol, proto);
1829       vam->retval = retval;
1830       vam->result_ready = 1;
1831     }
1832 }
1833
1834 static void vl_api_one_get_transport_protocol_reply_t_handler_json
1835   (vl_api_one_get_transport_protocol_reply_t * mp)
1836 {
1837   vat_main_t *vam = &vat_main;
1838   vat_json_node_t node;
1839   u8 *s;
1840
1841   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
1842   vec_add1 (s, 0);
1843
1844   vat_json_init_object (&node);
1845   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1846   vat_json_object_add_string_copy (&node, "transport-protocol", s);
1847
1848   vec_free (s);
1849   vat_json_print (vam->ofp, &node);
1850   vat_json_free (&node);
1851
1852   vam->retval = ntohl (mp->retval);
1853   vam->result_ready = 1;
1854 }
1855
1856 static void vl_api_one_add_del_locator_set_reply_t_handler
1857   (vl_api_one_add_del_locator_set_reply_t * mp)
1858 {
1859   vat_main_t *vam = &vat_main;
1860   i32 retval = ntohl (mp->retval);
1861   if (vam->async_mode)
1862     {
1863       vam->async_errors += (retval < 0);
1864     }
1865   else
1866     {
1867       vam->retval = retval;
1868       vam->result_ready = 1;
1869     }
1870 }
1871
1872 static void vl_api_one_add_del_locator_set_reply_t_handler_json
1873   (vl_api_one_add_del_locator_set_reply_t * mp)
1874 {
1875   vat_main_t *vam = &vat_main;
1876   vat_json_node_t node;
1877
1878   vat_json_init_object (&node);
1879   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1880   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1881
1882   vat_json_print (vam->ofp, &node);
1883   vat_json_free (&node);
1884
1885   vam->retval = ntohl (mp->retval);
1886   vam->result_ready = 1;
1887 }
1888
1889 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1890   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1891 {
1892   vat_main_t *vam = &vat_main;
1893   i32 retval = ntohl (mp->retval);
1894   if (vam->async_mode)
1895     {
1896       vam->async_errors += (retval < 0);
1897     }
1898   else
1899     {
1900       vam->retval = retval;
1901       vam->sw_if_index = ntohl (mp->sw_if_index);
1902       vam->result_ready = 1;
1903     }
1904 }
1905
1906 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1907   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1908 {
1909   vat_main_t *vam = &vat_main;
1910   vat_json_node_t node;
1911
1912   vat_json_init_object (&node);
1913   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1914   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1915
1916   vat_json_print (vam->ofp, &node);
1917   vat_json_free (&node);
1918
1919   vam->retval = ntohl (mp->retval);
1920   vam->result_ready = 1;
1921 }
1922
1923 static void vl_api_geneve_add_del_tunnel_reply_t_handler
1924   (vl_api_geneve_add_del_tunnel_reply_t * mp)
1925 {
1926   vat_main_t *vam = &vat_main;
1927   i32 retval = ntohl (mp->retval);
1928   if (vam->async_mode)
1929     {
1930       vam->async_errors += (retval < 0);
1931     }
1932   else
1933     {
1934       vam->retval = retval;
1935       vam->sw_if_index = ntohl (mp->sw_if_index);
1936       vam->result_ready = 1;
1937     }
1938 }
1939
1940 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
1941   (vl_api_geneve_add_del_tunnel_reply_t * mp)
1942 {
1943   vat_main_t *vam = &vat_main;
1944   vat_json_node_t node;
1945
1946   vat_json_init_object (&node);
1947   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1948   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1949
1950   vat_json_print (vam->ofp, &node);
1951   vat_json_free (&node);
1952
1953   vam->retval = ntohl (mp->retval);
1954   vam->result_ready = 1;
1955 }
1956
1957 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
1958   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
1959 {
1960   vat_main_t *vam = &vat_main;
1961   i32 retval = ntohl (mp->retval);
1962   if (vam->async_mode)
1963     {
1964       vam->async_errors += (retval < 0);
1965     }
1966   else
1967     {
1968       vam->retval = retval;
1969       vam->sw_if_index = ntohl (mp->sw_if_index);
1970       vam->result_ready = 1;
1971     }
1972 }
1973
1974 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
1975   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
1976 {
1977   vat_main_t *vam = &vat_main;
1978   vat_json_node_t node;
1979
1980   vat_json_init_object (&node);
1981   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1982   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1983
1984   vat_json_print (vam->ofp, &node);
1985   vat_json_free (&node);
1986
1987   vam->retval = ntohl (mp->retval);
1988   vam->result_ready = 1;
1989 }
1990
1991 static void vl_api_gre_add_del_tunnel_reply_t_handler
1992   (vl_api_gre_add_del_tunnel_reply_t * mp)
1993 {
1994   vat_main_t *vam = &vat_main;
1995   i32 retval = ntohl (mp->retval);
1996   if (vam->async_mode)
1997     {
1998       vam->async_errors += (retval < 0);
1999     }
2000   else
2001     {
2002       vam->retval = retval;
2003       vam->sw_if_index = ntohl (mp->sw_if_index);
2004       vam->result_ready = 1;
2005     }
2006 }
2007
2008 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
2009   (vl_api_gre_add_del_tunnel_reply_t * mp)
2010 {
2011   vat_main_t *vam = &vat_main;
2012   vat_json_node_t node;
2013
2014   vat_json_init_object (&node);
2015   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2016   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2017
2018   vat_json_print (vam->ofp, &node);
2019   vat_json_free (&node);
2020
2021   vam->retval = ntohl (mp->retval);
2022   vam->result_ready = 1;
2023 }
2024
2025 static void vl_api_create_vhost_user_if_reply_t_handler
2026   (vl_api_create_vhost_user_if_reply_t * mp)
2027 {
2028   vat_main_t *vam = &vat_main;
2029   i32 retval = ntohl (mp->retval);
2030   if (vam->async_mode)
2031     {
2032       vam->async_errors += (retval < 0);
2033     }
2034   else
2035     {
2036       vam->retval = retval;
2037       vam->sw_if_index = ntohl (mp->sw_if_index);
2038       vam->result_ready = 1;
2039     }
2040 }
2041
2042 static void vl_api_create_vhost_user_if_reply_t_handler_json
2043   (vl_api_create_vhost_user_if_reply_t * mp)
2044 {
2045   vat_main_t *vam = &vat_main;
2046   vat_json_node_t node;
2047
2048   vat_json_init_object (&node);
2049   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2050   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2051
2052   vat_json_print (vam->ofp, &node);
2053   vat_json_free (&node);
2054
2055   vam->retval = ntohl (mp->retval);
2056   vam->result_ready = 1;
2057 }
2058
2059 static clib_error_t *
2060 receive_fd_msg (int socket_fd, int *my_fd)
2061 {
2062   char msgbuf[16];
2063   char ctl[CMSG_SPACE (sizeof (int)) + CMSG_SPACE (sizeof (struct ucred))];
2064   struct msghdr mh = { 0 };
2065   struct iovec iov[1];
2066   ssize_t size;
2067   struct ucred *cr = 0;
2068   struct cmsghdr *cmsg;
2069   pid_t pid __attribute__ ((unused));
2070   uid_t uid __attribute__ ((unused));
2071   gid_t gid __attribute__ ((unused));
2072
2073   iov[0].iov_base = msgbuf;
2074   iov[0].iov_len = 5;
2075   mh.msg_iov = iov;
2076   mh.msg_iovlen = 1;
2077   mh.msg_control = ctl;
2078   mh.msg_controllen = sizeof (ctl);
2079
2080   memset (ctl, 0, sizeof (ctl));
2081
2082   /* receive the incoming message */
2083   size = recvmsg (socket_fd, &mh, 0);
2084   if (size != 5)
2085     {
2086       return (size == 0) ? clib_error_return (0, "disconnected") :
2087         clib_error_return_unix (0, "recvmsg: malformed message (fd %d)",
2088                                 socket_fd);
2089     }
2090
2091   cmsg = CMSG_FIRSTHDR (&mh);
2092   while (cmsg)
2093     {
2094       if (cmsg->cmsg_level == SOL_SOCKET)
2095         {
2096           if (cmsg->cmsg_type == SCM_CREDENTIALS)
2097             {
2098               cr = (struct ucred *) CMSG_DATA (cmsg);
2099               uid = cr->uid;
2100               gid = cr->gid;
2101               pid = cr->pid;
2102             }
2103           else if (cmsg->cmsg_type == SCM_RIGHTS)
2104             {
2105               clib_memcpy (my_fd, CMSG_DATA (cmsg), sizeof (int));
2106             }
2107         }
2108       cmsg = CMSG_NXTHDR (&mh, cmsg);
2109     }
2110   return 0;
2111 }
2112
2113 static void vl_api_memfd_segment_create_reply_t_handler
2114   (vl_api_memfd_segment_create_reply_t * mp)
2115 {
2116   /* Dont bother in the builtin version */
2117 #if VPP_API_TEST_BUILTIN == 0
2118   vat_main_t *vam = &vat_main;
2119   api_main_t *am = &api_main;
2120   socket_client_main_t *scm = &vam->socket_client_main;
2121   int my_fd = -1;
2122   clib_error_t *error;
2123   memfd_private_t memfd;
2124   i32 retval = ntohl (mp->retval);
2125
2126   if (retval == 0)
2127     {
2128       error = receive_fd_msg (scm->socket_fd, &my_fd);
2129       if (error)
2130         {
2131           retval = -99;
2132           goto out;
2133         }
2134
2135       memset (&memfd, 0, sizeof (memfd));
2136       memfd.fd = my_fd;
2137
2138       vam->client_index_invalid = 1;
2139
2140       /* 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_show_one_use_petr_reply_t_handler
4243   (vl_api_show_one_use_petr_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->status ? "enabled" : "disabled");
4251       if (mp->status)
4252         {
4253           print (vam->ofp, "Proxy-ETR address; %U",
4254                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4255                  mp->address);
4256         }
4257     }
4258
4259   vam->retval = retval;
4260   vam->result_ready = 1;
4261 }
4262
4263 static void
4264   vl_api_show_one_use_petr_reply_t_handler_json
4265   (vl_api_show_one_use_petr_reply_t * mp)
4266 {
4267   vat_main_t *vam = &vat_main;
4268   vat_json_node_t node;
4269   u8 *status = 0;
4270   struct in_addr ip4;
4271   struct in6_addr ip6;
4272
4273   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4274   vec_add1 (status, 0);
4275
4276   vat_json_init_object (&node);
4277   vat_json_object_add_string_copy (&node, "status", status);
4278   if (mp->status)
4279     {
4280       if (mp->is_ip4)
4281         {
4282           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4283           vat_json_object_add_ip6 (&node, "address", ip6);
4284         }
4285       else
4286         {
4287           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4288           vat_json_object_add_ip4 (&node, "address", ip4);
4289         }
4290     }
4291
4292   vec_free (status);
4293
4294   vat_json_print (vam->ofp, &node);
4295   vat_json_free (&node);
4296
4297   vam->retval = ntohl (mp->retval);
4298   vam->result_ready = 1;
4299 }
4300
4301 static void
4302   vl_api_show_one_nsh_mapping_reply_t_handler
4303   (vl_api_show_one_nsh_mapping_reply_t * mp)
4304 {
4305   vat_main_t *vam = &vat_main;
4306   i32 retval = ntohl (mp->retval);
4307
4308   if (0 <= retval)
4309     {
4310       print (vam->ofp, "%-20s%-16s",
4311              mp->is_set ? "set" : "not-set",
4312              mp->is_set ? (char *) mp->locator_set_name : "");
4313     }
4314
4315   vam->retval = retval;
4316   vam->result_ready = 1;
4317 }
4318
4319 static void
4320   vl_api_show_one_nsh_mapping_reply_t_handler_json
4321   (vl_api_show_one_nsh_mapping_reply_t * mp)
4322 {
4323   vat_main_t *vam = &vat_main;
4324   vat_json_node_t node;
4325   u8 *status = 0;
4326
4327   status = format (0, "%s", mp->is_set ? "yes" : "no");
4328   vec_add1 (status, 0);
4329
4330   vat_json_init_object (&node);
4331   vat_json_object_add_string_copy (&node, "is_set", status);
4332   if (mp->is_set)
4333     {
4334       vat_json_object_add_string_copy (&node, "locator_set",
4335                                        mp->locator_set_name);
4336     }
4337
4338   vec_free (status);
4339
4340   vat_json_print (vam->ofp, &node);
4341   vat_json_free (&node);
4342
4343   vam->retval = ntohl (mp->retval);
4344   vam->result_ready = 1;
4345 }
4346
4347 static void
4348   vl_api_show_one_map_register_ttl_reply_t_handler
4349   (vl_api_show_one_map_register_ttl_reply_t * mp)
4350 {
4351   vat_main_t *vam = &vat_main;
4352   i32 retval = ntohl (mp->retval);
4353
4354   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4355
4356   if (0 <= retval)
4357     {
4358       print (vam->ofp, "ttl: %u", mp->ttl);
4359     }
4360
4361   vam->retval = retval;
4362   vam->result_ready = 1;
4363 }
4364
4365 static void
4366   vl_api_show_one_map_register_ttl_reply_t_handler_json
4367   (vl_api_show_one_map_register_ttl_reply_t * mp)
4368 {
4369   vat_main_t *vam = &vat_main;
4370   vat_json_node_t node;
4371
4372   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4373   vat_json_init_object (&node);
4374   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4375
4376   vat_json_print (vam->ofp, &node);
4377   vat_json_free (&node);
4378
4379   vam->retval = ntohl (mp->retval);
4380   vam->result_ready = 1;
4381 }
4382
4383 static void
4384 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4385 {
4386   vat_main_t *vam = &vat_main;
4387   i32 retval = ntohl (mp->retval);
4388
4389   if (0 <= retval)
4390     {
4391       print (vam->ofp, "%-20s%-16s",
4392              mp->status ? "enabled" : "disabled",
4393              mp->status ? (char *) mp->locator_set_name : "");
4394     }
4395
4396   vam->retval = retval;
4397   vam->result_ready = 1;
4398 }
4399
4400 static void
4401 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4402 {
4403   vat_main_t *vam = &vat_main;
4404   vat_json_node_t node;
4405   u8 *status = 0;
4406
4407   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4408   vec_add1 (status, 0);
4409
4410   vat_json_init_object (&node);
4411   vat_json_object_add_string_copy (&node, "status", status);
4412   if (mp->status)
4413     {
4414       vat_json_object_add_string_copy (&node, "locator_set",
4415                                        mp->locator_set_name);
4416     }
4417
4418   vec_free (status);
4419
4420   vat_json_print (vam->ofp, &node);
4421   vat_json_free (&node);
4422
4423   vam->retval = ntohl (mp->retval);
4424   vam->result_ready = 1;
4425 }
4426
4427 static u8 *
4428 format_policer_type (u8 * s, va_list * va)
4429 {
4430   u32 i = va_arg (*va, u32);
4431
4432   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4433     s = format (s, "1r2c");
4434   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4435     s = format (s, "1r3c");
4436   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4437     s = format (s, "2r3c-2698");
4438   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4439     s = format (s, "2r3c-4115");
4440   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4441     s = format (s, "2r3c-mef5cf1");
4442   else
4443     s = format (s, "ILLEGAL");
4444   return s;
4445 }
4446
4447 static u8 *
4448 format_policer_rate_type (u8 * s, va_list * va)
4449 {
4450   u32 i = va_arg (*va, u32);
4451
4452   if (i == SSE2_QOS_RATE_KBPS)
4453     s = format (s, "kbps");
4454   else if (i == SSE2_QOS_RATE_PPS)
4455     s = format (s, "pps");
4456   else
4457     s = format (s, "ILLEGAL");
4458   return s;
4459 }
4460
4461 static u8 *
4462 format_policer_round_type (u8 * s, va_list * va)
4463 {
4464   u32 i = va_arg (*va, u32);
4465
4466   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4467     s = format (s, "closest");
4468   else if (i == SSE2_QOS_ROUND_TO_UP)
4469     s = format (s, "up");
4470   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4471     s = format (s, "down");
4472   else
4473     s = format (s, "ILLEGAL");
4474   return s;
4475 }
4476
4477 static u8 *
4478 format_policer_action_type (u8 * s, va_list * va)
4479 {
4480   u32 i = va_arg (*va, u32);
4481
4482   if (i == SSE2_QOS_ACTION_DROP)
4483     s = format (s, "drop");
4484   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4485     s = format (s, "transmit");
4486   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4487     s = format (s, "mark-and-transmit");
4488   else
4489     s = format (s, "ILLEGAL");
4490   return s;
4491 }
4492
4493 static u8 *
4494 format_dscp (u8 * s, va_list * va)
4495 {
4496   u32 i = va_arg (*va, u32);
4497   char *t = 0;
4498
4499   switch (i)
4500     {
4501 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4502       foreach_vnet_dscp
4503 #undef _
4504     default:
4505       return format (s, "ILLEGAL");
4506     }
4507   s = format (s, "%s", t);
4508   return s;
4509 }
4510
4511 static void
4512 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4513 {
4514   vat_main_t *vam = &vat_main;
4515   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4516
4517   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4518     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4519   else
4520     conform_dscp_str = format (0, "");
4521
4522   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4523     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4524   else
4525     exceed_dscp_str = format (0, "");
4526
4527   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4528     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4529   else
4530     violate_dscp_str = format (0, "");
4531
4532   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4533          "rate type %U, round type %U, %s rate, %s color-aware, "
4534          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4535          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4536          "conform action %U%s, exceed action %U%s, violate action %U%s",
4537          mp->name,
4538          format_policer_type, mp->type,
4539          ntohl (mp->cir),
4540          ntohl (mp->eir),
4541          clib_net_to_host_u64 (mp->cb),
4542          clib_net_to_host_u64 (mp->eb),
4543          format_policer_rate_type, mp->rate_type,
4544          format_policer_round_type, mp->round_type,
4545          mp->single_rate ? "single" : "dual",
4546          mp->color_aware ? "is" : "not",
4547          ntohl (mp->cir_tokens_per_period),
4548          ntohl (mp->pir_tokens_per_period),
4549          ntohl (mp->scale),
4550          ntohl (mp->current_limit),
4551          ntohl (mp->current_bucket),
4552          ntohl (mp->extended_limit),
4553          ntohl (mp->extended_bucket),
4554          clib_net_to_host_u64 (mp->last_update_time),
4555          format_policer_action_type, mp->conform_action_type,
4556          conform_dscp_str,
4557          format_policer_action_type, mp->exceed_action_type,
4558          exceed_dscp_str,
4559          format_policer_action_type, mp->violate_action_type,
4560          violate_dscp_str);
4561
4562   vec_free (conform_dscp_str);
4563   vec_free (exceed_dscp_str);
4564   vec_free (violate_dscp_str);
4565 }
4566
4567 static void vl_api_policer_details_t_handler_json
4568   (vl_api_policer_details_t * mp)
4569 {
4570   vat_main_t *vam = &vat_main;
4571   vat_json_node_t *node;
4572   u8 *rate_type_str, *round_type_str, *type_str;
4573   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4574
4575   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4576   round_type_str =
4577     format (0, "%U", format_policer_round_type, mp->round_type);
4578   type_str = format (0, "%U", format_policer_type, mp->type);
4579   conform_action_str = format (0, "%U", format_policer_action_type,
4580                                mp->conform_action_type);
4581   exceed_action_str = format (0, "%U", format_policer_action_type,
4582                               mp->exceed_action_type);
4583   violate_action_str = format (0, "%U", format_policer_action_type,
4584                                mp->violate_action_type);
4585
4586   if (VAT_JSON_ARRAY != vam->json_tree.type)
4587     {
4588       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4589       vat_json_init_array (&vam->json_tree);
4590     }
4591   node = vat_json_array_add (&vam->json_tree);
4592
4593   vat_json_init_object (node);
4594   vat_json_object_add_string_copy (node, "name", mp->name);
4595   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4596   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4597   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4598   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4599   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4600   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4601   vat_json_object_add_string_copy (node, "type", type_str);
4602   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4603   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4604   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4605   vat_json_object_add_uint (node, "cir_tokens_per_period",
4606                             ntohl (mp->cir_tokens_per_period));
4607   vat_json_object_add_uint (node, "eir_tokens_per_period",
4608                             ntohl (mp->pir_tokens_per_period));
4609   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4610   vat_json_object_add_uint (node, "current_bucket",
4611                             ntohl (mp->current_bucket));
4612   vat_json_object_add_uint (node, "extended_limit",
4613                             ntohl (mp->extended_limit));
4614   vat_json_object_add_uint (node, "extended_bucket",
4615                             ntohl (mp->extended_bucket));
4616   vat_json_object_add_uint (node, "last_update_time",
4617                             ntohl (mp->last_update_time));
4618   vat_json_object_add_string_copy (node, "conform_action",
4619                                    conform_action_str);
4620   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4621     {
4622       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4623       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4624       vec_free (dscp_str);
4625     }
4626   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4627   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4628     {
4629       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4630       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4631       vec_free (dscp_str);
4632     }
4633   vat_json_object_add_string_copy (node, "violate_action",
4634                                    violate_action_str);
4635   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4636     {
4637       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4638       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4639       vec_free (dscp_str);
4640     }
4641
4642   vec_free (rate_type_str);
4643   vec_free (round_type_str);
4644   vec_free (type_str);
4645   vec_free (conform_action_str);
4646   vec_free (exceed_action_str);
4647   vec_free (violate_action_str);
4648 }
4649
4650 static void
4651 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4652                                            mp)
4653 {
4654   vat_main_t *vam = &vat_main;
4655   int i, count = ntohl (mp->count);
4656
4657   if (count > 0)
4658     print (vam->ofp, "classify table ids (%d) : ", count);
4659   for (i = 0; i < count; i++)
4660     {
4661       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4662       print (vam->ofp, (i < count - 1) ? "," : "");
4663     }
4664   vam->retval = ntohl (mp->retval);
4665   vam->result_ready = 1;
4666 }
4667
4668 static void
4669   vl_api_classify_table_ids_reply_t_handler_json
4670   (vl_api_classify_table_ids_reply_t * mp)
4671 {
4672   vat_main_t *vam = &vat_main;
4673   int i, count = ntohl (mp->count);
4674
4675   if (count > 0)
4676     {
4677       vat_json_node_t node;
4678
4679       vat_json_init_object (&node);
4680       for (i = 0; i < count; i++)
4681         {
4682           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4683         }
4684       vat_json_print (vam->ofp, &node);
4685       vat_json_free (&node);
4686     }
4687   vam->retval = ntohl (mp->retval);
4688   vam->result_ready = 1;
4689 }
4690
4691 static void
4692   vl_api_classify_table_by_interface_reply_t_handler
4693   (vl_api_classify_table_by_interface_reply_t * mp)
4694 {
4695   vat_main_t *vam = &vat_main;
4696   u32 table_id;
4697
4698   table_id = ntohl (mp->l2_table_id);
4699   if (table_id != ~0)
4700     print (vam->ofp, "l2 table id : %d", table_id);
4701   else
4702     print (vam->ofp, "l2 table id : No input ACL tables configured");
4703   table_id = ntohl (mp->ip4_table_id);
4704   if (table_id != ~0)
4705     print (vam->ofp, "ip4 table id : %d", table_id);
4706   else
4707     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4708   table_id = ntohl (mp->ip6_table_id);
4709   if (table_id != ~0)
4710     print (vam->ofp, "ip6 table id : %d", table_id);
4711   else
4712     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4713   vam->retval = ntohl (mp->retval);
4714   vam->result_ready = 1;
4715 }
4716
4717 static void
4718   vl_api_classify_table_by_interface_reply_t_handler_json
4719   (vl_api_classify_table_by_interface_reply_t * mp)
4720 {
4721   vat_main_t *vam = &vat_main;
4722   vat_json_node_t node;
4723
4724   vat_json_init_object (&node);
4725
4726   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4727   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4728   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4729
4730   vat_json_print (vam->ofp, &node);
4731   vat_json_free (&node);
4732
4733   vam->retval = ntohl (mp->retval);
4734   vam->result_ready = 1;
4735 }
4736
4737 static void vl_api_policer_add_del_reply_t_handler
4738   (vl_api_policer_add_del_reply_t * mp)
4739 {
4740   vat_main_t *vam = &vat_main;
4741   i32 retval = ntohl (mp->retval);
4742   if (vam->async_mode)
4743     {
4744       vam->async_errors += (retval < 0);
4745     }
4746   else
4747     {
4748       vam->retval = retval;
4749       vam->result_ready = 1;
4750       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4751         /*
4752          * Note: this is just barely thread-safe, depends on
4753          * the main thread spinning waiting for an answer...
4754          */
4755         errmsg ("policer index %d", ntohl (mp->policer_index));
4756     }
4757 }
4758
4759 static void vl_api_policer_add_del_reply_t_handler_json
4760   (vl_api_policer_add_del_reply_t * mp)
4761 {
4762   vat_main_t *vam = &vat_main;
4763   vat_json_node_t node;
4764
4765   vat_json_init_object (&node);
4766   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4767   vat_json_object_add_uint (&node, "policer_index",
4768                             ntohl (mp->policer_index));
4769
4770   vat_json_print (vam->ofp, &node);
4771   vat_json_free (&node);
4772
4773   vam->retval = ntohl (mp->retval);
4774   vam->result_ready = 1;
4775 }
4776
4777 /* Format hex dump. */
4778 u8 *
4779 format_hex_bytes (u8 * s, va_list * va)
4780 {
4781   u8 *bytes = va_arg (*va, u8 *);
4782   int n_bytes = va_arg (*va, int);
4783   uword i;
4784
4785   /* Print short or long form depending on byte count. */
4786   uword short_form = n_bytes <= 32;
4787   u32 indent = format_get_indent (s);
4788
4789   if (n_bytes == 0)
4790     return s;
4791
4792   for (i = 0; i < n_bytes; i++)
4793     {
4794       if (!short_form && (i % 32) == 0)
4795         s = format (s, "%08x: ", i);
4796       s = format (s, "%02x", bytes[i]);
4797       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4798         s = format (s, "\n%U", format_white_space, indent);
4799     }
4800
4801   return s;
4802 }
4803
4804 static void
4805 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4806                                             * mp)
4807 {
4808   vat_main_t *vam = &vat_main;
4809   i32 retval = ntohl (mp->retval);
4810   if (retval == 0)
4811     {
4812       print (vam->ofp, "classify table info :");
4813       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4814              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4815              ntohl (mp->miss_next_index));
4816       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4817              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4818              ntohl (mp->match_n_vectors));
4819       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4820              ntohl (mp->mask_length));
4821     }
4822   vam->retval = retval;
4823   vam->result_ready = 1;
4824 }
4825
4826 static void
4827   vl_api_classify_table_info_reply_t_handler_json
4828   (vl_api_classify_table_info_reply_t * mp)
4829 {
4830   vat_main_t *vam = &vat_main;
4831   vat_json_node_t node;
4832
4833   i32 retval = ntohl (mp->retval);
4834   if (retval == 0)
4835     {
4836       vat_json_init_object (&node);
4837
4838       vat_json_object_add_int (&node, "sessions",
4839                                ntohl (mp->active_sessions));
4840       vat_json_object_add_int (&node, "nexttbl",
4841                                ntohl (mp->next_table_index));
4842       vat_json_object_add_int (&node, "nextnode",
4843                                ntohl (mp->miss_next_index));
4844       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4845       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4846       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4847       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4848                       ntohl (mp->mask_length), 0);
4849       vat_json_object_add_string_copy (&node, "mask", s);
4850
4851       vat_json_print (vam->ofp, &node);
4852       vat_json_free (&node);
4853     }
4854   vam->retval = ntohl (mp->retval);
4855   vam->result_ready = 1;
4856 }
4857
4858 static void
4859 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4860                                            mp)
4861 {
4862   vat_main_t *vam = &vat_main;
4863
4864   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4865          ntohl (mp->hit_next_index), ntohl (mp->advance),
4866          ntohl (mp->opaque_index));
4867   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4868          ntohl (mp->match_length));
4869 }
4870
4871 static void
4872   vl_api_classify_session_details_t_handler_json
4873   (vl_api_classify_session_details_t * mp)
4874 {
4875   vat_main_t *vam = &vat_main;
4876   vat_json_node_t *node = NULL;
4877
4878   if (VAT_JSON_ARRAY != vam->json_tree.type)
4879     {
4880       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4881       vat_json_init_array (&vam->json_tree);
4882     }
4883   node = vat_json_array_add (&vam->json_tree);
4884
4885   vat_json_init_object (node);
4886   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4887   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4888   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4889   u8 *s =
4890     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4891             0);
4892   vat_json_object_add_string_copy (node, "match", s);
4893 }
4894
4895 static void vl_api_pg_create_interface_reply_t_handler
4896   (vl_api_pg_create_interface_reply_t * mp)
4897 {
4898   vat_main_t *vam = &vat_main;
4899
4900   vam->retval = ntohl (mp->retval);
4901   vam->result_ready = 1;
4902 }
4903
4904 static void vl_api_pg_create_interface_reply_t_handler_json
4905   (vl_api_pg_create_interface_reply_t * mp)
4906 {
4907   vat_main_t *vam = &vat_main;
4908   vat_json_node_t node;
4909
4910   i32 retval = ntohl (mp->retval);
4911   if (retval == 0)
4912     {
4913       vat_json_init_object (&node);
4914
4915       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4916
4917       vat_json_print (vam->ofp, &node);
4918       vat_json_free (&node);
4919     }
4920   vam->retval = ntohl (mp->retval);
4921   vam->result_ready = 1;
4922 }
4923
4924 static void vl_api_policer_classify_details_t_handler
4925   (vl_api_policer_classify_details_t * mp)
4926 {
4927   vat_main_t *vam = &vat_main;
4928
4929   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4930          ntohl (mp->table_index));
4931 }
4932
4933 static void vl_api_policer_classify_details_t_handler_json
4934   (vl_api_policer_classify_details_t * mp)
4935 {
4936   vat_main_t *vam = &vat_main;
4937   vat_json_node_t *node;
4938
4939   if (VAT_JSON_ARRAY != vam->json_tree.type)
4940     {
4941       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4942       vat_json_init_array (&vam->json_tree);
4943     }
4944   node = vat_json_array_add (&vam->json_tree);
4945
4946   vat_json_init_object (node);
4947   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4948   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4949 }
4950
4951 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
4952   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4953 {
4954   vat_main_t *vam = &vat_main;
4955   i32 retval = ntohl (mp->retval);
4956   if (vam->async_mode)
4957     {
4958       vam->async_errors += (retval < 0);
4959     }
4960   else
4961     {
4962       vam->retval = retval;
4963       vam->sw_if_index = ntohl (mp->sw_if_index);
4964       vam->result_ready = 1;
4965     }
4966 }
4967
4968 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
4969   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4970 {
4971   vat_main_t *vam = &vat_main;
4972   vat_json_node_t node;
4973
4974   vat_json_init_object (&node);
4975   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4976   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
4977
4978   vat_json_print (vam->ofp, &node);
4979   vat_json_free (&node);
4980
4981   vam->retval = ntohl (mp->retval);
4982   vam->result_ready = 1;
4983 }
4984
4985 static void vl_api_flow_classify_details_t_handler
4986   (vl_api_flow_classify_details_t * mp)
4987 {
4988   vat_main_t *vam = &vat_main;
4989
4990   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4991          ntohl (mp->table_index));
4992 }
4993
4994 static void vl_api_flow_classify_details_t_handler_json
4995   (vl_api_flow_classify_details_t * mp)
4996 {
4997   vat_main_t *vam = &vat_main;
4998   vat_json_node_t *node;
4999
5000   if (VAT_JSON_ARRAY != vam->json_tree.type)
5001     {
5002       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5003       vat_json_init_array (&vam->json_tree);
5004     }
5005   node = vat_json_array_add (&vam->json_tree);
5006
5007   vat_json_init_object (node);
5008   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5009   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5010 }
5011
5012 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
5013 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
5014 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
5015 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
5016 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
5017 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
5018 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
5019 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
5020 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
5021 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
5022 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
5023 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
5024 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5025 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5026 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5027 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5028 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5029 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5030 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5031 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5032 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5033 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5034
5035 /*
5036  * Generate boilerplate reply handlers, which
5037  * dig the return value out of the xxx_reply_t API message,
5038  * stick it into vam->retval, and set vam->result_ready
5039  *
5040  * Could also do this by pointing N message decode slots at
5041  * a single function, but that could break in subtle ways.
5042  */
5043
5044 #define foreach_standard_reply_retval_handler           \
5045 _(sw_interface_set_flags_reply)                         \
5046 _(sw_interface_add_del_address_reply)                   \
5047 _(sw_interface_set_table_reply)                         \
5048 _(sw_interface_set_mpls_enable_reply)                   \
5049 _(sw_interface_set_vpath_reply)                         \
5050 _(sw_interface_set_vxlan_bypass_reply)                  \
5051 _(sw_interface_set_geneve_bypass_reply)                 \
5052 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5053 _(sw_interface_set_l2_bridge_reply)                     \
5054 _(bridge_domain_add_del_reply)                          \
5055 _(sw_interface_set_l2_xconnect_reply)                   \
5056 _(l2fib_add_del_reply)                                  \
5057 _(l2fib_flush_int_reply)                                \
5058 _(l2fib_flush_bd_reply)                                 \
5059 _(ip_add_del_route_reply)                               \
5060 _(ip_table_add_del_reply)                               \
5061 _(ip_mroute_add_del_reply)                              \
5062 _(mpls_route_add_del_reply)                             \
5063 _(mpls_table_add_del_reply)                             \
5064 _(mpls_ip_bind_unbind_reply)                            \
5065 _(proxy_arp_add_del_reply)                              \
5066 _(proxy_arp_intfc_enable_disable_reply)                 \
5067 _(sw_interface_set_unnumbered_reply)                    \
5068 _(ip_neighbor_add_del_reply)                            \
5069 _(reset_vrf_reply)                                      \
5070 _(oam_add_del_reply)                                    \
5071 _(reset_fib_reply)                                      \
5072 _(dhcp_proxy_config_reply)                              \
5073 _(dhcp_proxy_set_vss_reply)                             \
5074 _(dhcp_client_config_reply)                             \
5075 _(set_ip_flow_hash_reply)                               \
5076 _(sw_interface_ip6_enable_disable_reply)                \
5077 _(sw_interface_ip6_set_link_local_address_reply)        \
5078 _(ip6nd_proxy_add_del_reply)                            \
5079 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5080 _(sw_interface_ip6nd_ra_config_reply)                   \
5081 _(set_arp_neighbor_limit_reply)                         \
5082 _(l2_patch_add_del_reply)                               \
5083 _(sr_policy_add_reply)                                  \
5084 _(sr_policy_mod_reply)                                  \
5085 _(sr_policy_del_reply)                                  \
5086 _(sr_localsid_add_del_reply)                            \
5087 _(sr_steering_add_del_reply)                            \
5088 _(classify_add_del_session_reply)                       \
5089 _(classify_set_interface_ip_table_reply)                \
5090 _(classify_set_interface_l2_tables_reply)               \
5091 _(l2tpv3_set_tunnel_cookies_reply)                      \
5092 _(l2tpv3_interface_enable_disable_reply)                \
5093 _(l2tpv3_set_lookup_key_reply)                          \
5094 _(l2_fib_clear_table_reply)                             \
5095 _(l2_interface_efp_filter_reply)                        \
5096 _(l2_interface_vlan_tag_rewrite_reply)                  \
5097 _(modify_vhost_user_if_reply)                           \
5098 _(delete_vhost_user_if_reply)                           \
5099 _(want_ip4_arp_events_reply)                            \
5100 _(want_ip6_nd_events_reply)                             \
5101 _(want_l2_macs_events_reply)                            \
5102 _(input_acl_set_interface_reply)                        \
5103 _(ipsec_spd_add_del_reply)                              \
5104 _(ipsec_interface_add_del_spd_reply)                    \
5105 _(ipsec_spd_add_del_entry_reply)                        \
5106 _(ipsec_sad_add_del_entry_reply)                        \
5107 _(ipsec_sa_set_key_reply)                               \
5108 _(ipsec_tunnel_if_add_del_reply)                        \
5109 _(ipsec_tunnel_if_set_key_reply)                        \
5110 _(ipsec_tunnel_if_set_sa_reply)                         \
5111 _(ikev2_profile_add_del_reply)                          \
5112 _(ikev2_profile_set_auth_reply)                         \
5113 _(ikev2_profile_set_id_reply)                           \
5114 _(ikev2_profile_set_ts_reply)                           \
5115 _(ikev2_set_local_key_reply)                            \
5116 _(ikev2_set_responder_reply)                            \
5117 _(ikev2_set_ike_transforms_reply)                       \
5118 _(ikev2_set_esp_transforms_reply)                       \
5119 _(ikev2_set_sa_lifetime_reply)                          \
5120 _(ikev2_initiate_sa_init_reply)                         \
5121 _(ikev2_initiate_del_ike_sa_reply)                      \
5122 _(ikev2_initiate_del_child_sa_reply)                    \
5123 _(ikev2_initiate_rekey_child_sa_reply)                  \
5124 _(delete_loopback_reply)                                \
5125 _(bd_ip_mac_add_del_reply)                              \
5126 _(map_del_domain_reply)                                 \
5127 _(map_add_del_rule_reply)                               \
5128 _(want_interface_events_reply)                          \
5129 _(want_stats_reply)                                     \
5130 _(cop_interface_enable_disable_reply)                   \
5131 _(cop_whitelist_enable_disable_reply)                   \
5132 _(sw_interface_clear_stats_reply)                       \
5133 _(ioam_enable_reply)                                    \
5134 _(ioam_disable_reply)                                   \
5135 _(one_add_del_locator_reply)                            \
5136 _(one_add_del_local_eid_reply)                          \
5137 _(one_add_del_remote_mapping_reply)                     \
5138 _(one_add_del_adjacency_reply)                          \
5139 _(one_add_del_map_resolver_reply)                       \
5140 _(one_add_del_map_server_reply)                         \
5141 _(one_enable_disable_reply)                             \
5142 _(one_rloc_probe_enable_disable_reply)                  \
5143 _(one_map_register_enable_disable_reply)                \
5144 _(one_map_register_set_ttl_reply)                       \
5145 _(one_set_transport_protocol_reply)                     \
5146 _(one_map_register_fallback_threshold_reply)            \
5147 _(one_pitr_set_locator_set_reply)                       \
5148 _(one_map_request_mode_reply)                           \
5149 _(one_add_del_map_request_itr_rlocs_reply)              \
5150 _(one_eid_table_add_del_map_reply)                      \
5151 _(one_use_petr_reply)                                   \
5152 _(one_stats_enable_disable_reply)                       \
5153 _(one_add_del_l2_arp_entry_reply)                       \
5154 _(one_add_del_ndp_entry_reply)                          \
5155 _(one_stats_flush_reply)                                \
5156 _(gpe_enable_disable_reply)                             \
5157 _(gpe_set_encap_mode_reply)                             \
5158 _(gpe_add_del_iface_reply)                              \
5159 _(gpe_add_del_native_fwd_rpath_reply)                   \
5160 _(af_packet_delete_reply)                               \
5161 _(policer_classify_set_interface_reply)                 \
5162 _(netmap_create_reply)                                  \
5163 _(netmap_delete_reply)                                  \
5164 _(set_ipfix_exporter_reply)                             \
5165 _(set_ipfix_classify_stream_reply)                      \
5166 _(ipfix_classify_table_add_del_reply)                   \
5167 _(flow_classify_set_interface_reply)                    \
5168 _(sw_interface_span_enable_disable_reply)               \
5169 _(pg_capture_reply)                                     \
5170 _(pg_enable_disable_reply)                              \
5171 _(ip_source_and_port_range_check_add_del_reply)         \
5172 _(ip_source_and_port_range_check_interface_add_del_reply)\
5173 _(delete_subif_reply)                                   \
5174 _(l2_interface_pbb_tag_rewrite_reply)                   \
5175 _(punt_reply)                                           \
5176 _(feature_enable_disable_reply)                         \
5177 _(sw_interface_tag_add_del_reply)                       \
5178 _(sw_interface_set_mtu_reply)                           \
5179 _(p2p_ethernet_add_reply)                               \
5180 _(p2p_ethernet_del_reply)                               \
5181 _(lldp_config_reply)                                    \
5182 _(sw_interface_set_lldp_reply)                          \
5183 _(tcp_configure_src_addresses_reply)                    \
5184 _(app_namespace_add_del_reply)                          \
5185 _(dns_enable_disable_reply)                             \
5186 _(dns_name_server_add_del_reply)                        \
5187 _(session_rule_add_del_reply)
5188
5189 #define _(n)                                    \
5190     static void vl_api_##n##_t_handler          \
5191     (vl_api_##n##_t * mp)                       \
5192     {                                           \
5193         vat_main_t * vam = &vat_main;           \
5194         i32 retval = ntohl(mp->retval);         \
5195         if (vam->async_mode) {                  \
5196             vam->async_errors += (retval < 0);  \
5197         } else {                                \
5198             vam->retval = retval;               \
5199             vam->result_ready = 1;              \
5200         }                                       \
5201     }
5202 foreach_standard_reply_retval_handler;
5203 #undef _
5204
5205 #define _(n)                                    \
5206     static void vl_api_##n##_t_handler_json     \
5207     (vl_api_##n##_t * mp)                       \
5208     {                                           \
5209         vat_main_t * vam = &vat_main;           \
5210         vat_json_node_t node;                   \
5211         vat_json_init_object(&node);            \
5212         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5213         vat_json_print(vam->ofp, &node);        \
5214         vam->retval = ntohl(mp->retval);        \
5215         vam->result_ready = 1;                  \
5216     }
5217 foreach_standard_reply_retval_handler;
5218 #undef _
5219
5220 /*
5221  * Table of message reply handlers, must include boilerplate handlers
5222  * we just generated
5223  */
5224
5225 #define foreach_vpe_api_reply_msg                                       \
5226 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5227 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5228 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5229 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5230 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5231 _(CLI_REPLY, cli_reply)                                                 \
5232 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5233 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5234   sw_interface_add_del_address_reply)                                   \
5235 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5236 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5237 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5238 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5239 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5240 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5241 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5242   sw_interface_set_l2_xconnect_reply)                                   \
5243 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5244   sw_interface_set_l2_bridge_reply)                                     \
5245 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5246 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5247 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5248 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5249 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5250 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5251 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5252 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5253 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5254 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5255 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5256 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5257 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5258 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5259 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5260 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5261 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5262 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5263 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5264 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5265   proxy_arp_intfc_enable_disable_reply)                                 \
5266 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5267 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5268   sw_interface_set_unnumbered_reply)                                    \
5269 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5270 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
5271 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5272 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5273 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5274 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5275 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5276 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5277 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5278 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5279 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5280 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5281   sw_interface_ip6_enable_disable_reply)                                \
5282 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5283   sw_interface_ip6_set_link_local_address_reply)                        \
5284 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5285 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5286 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5287   sw_interface_ip6nd_ra_prefix_reply)                                   \
5288 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5289   sw_interface_ip6nd_ra_config_reply)                                   \
5290 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5291 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5292 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5293 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5294 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5295 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5296 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5297 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5298 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5299 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5300 classify_set_interface_ip_table_reply)                                  \
5301 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5302   classify_set_interface_l2_tables_reply)                               \
5303 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5304 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5305 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5306 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5307 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5308   l2tpv3_interface_enable_disable_reply)                                \
5309 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5310 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5311 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5312 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5313 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5314 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5315 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5316 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5317 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5318 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5319 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5320 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5321 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5322 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5323 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5324 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5325 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5326 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
5327 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5328 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5329 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5330 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5331 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5332 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5333 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5334 _(L2_MACS_EVENT, l2_macs_event)                                         \
5335 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5336 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5337 _(IP_DETAILS, ip_details)                                               \
5338 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5339 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5340 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5341 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5342 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5343 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5344 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5345 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5346 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5347 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5348 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5349 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5350 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5351 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5352 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5353 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5354 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5355 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5356 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5357 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5358 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5359 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5360 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5361 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5362 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5363 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5364 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5365 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5366 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5367 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5368 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5369 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5370 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5371 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5372 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5373 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5374 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5375 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5376 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5377 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5378 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5379 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5380 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5381 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5382 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5383 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5384 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5385 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5386   one_map_register_enable_disable_reply)                                \
5387 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5388 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5389 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5390 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5391   one_map_register_fallback_threshold_reply)                            \
5392 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5393   one_rloc_probe_enable_disable_reply)                                  \
5394 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5395 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5396 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5397 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5398 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5399 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5400 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5401 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5402 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5403 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5404 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5405 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5406 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5407 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5408 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5409 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5410   show_one_stats_enable_disable_reply)                                  \
5411 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5412 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5413 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5414 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5415 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5416 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5417 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5418 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5419 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5420 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5421 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5422 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5423 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5424 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5425 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5426   gpe_add_del_native_fwd_rpath_reply)                                   \
5427 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5428   gpe_fwd_entry_path_details)                                           \
5429 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5430 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5431   one_add_del_map_request_itr_rlocs_reply)                              \
5432 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5433   one_get_map_request_itr_rlocs_reply)                                  \
5434 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5435 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5436 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5437 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5438 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5439 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5440   show_one_map_register_state_reply)                                    \
5441 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5442 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5443   show_one_map_register_fallback_threshold_reply)                       \
5444 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5445 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5446 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5447 _(POLICER_DETAILS, policer_details)                                     \
5448 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5449 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5450 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5451 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5452 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5453 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5454 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5455 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5456 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5457 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5458 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5459 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5460 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5461 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5462 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5463 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5464 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5465 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5466 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5467 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5468 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5469 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5470 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5471 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5472 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5473  ip_source_and_port_range_check_add_del_reply)                          \
5474 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5475  ip_source_and_port_range_check_interface_add_del_reply)                \
5476 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5477 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5478 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5479 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5480 _(PUNT_REPLY, punt_reply)                                               \
5481 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5482 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5483 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5484 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5485 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5486 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5487 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5488 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5489 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5490 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5491 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5492 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5493 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5494 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5495 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5496 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5497 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5498 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5499 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)
5500
5501 #define foreach_standalone_reply_msg                                    \
5502 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5503 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5504 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5505 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5506 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5507 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5508 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
5509 _(MEMFD_SEGMENT_CREATE_REPLY, memfd_segment_create_reply)               \
5510
5511 typedef struct
5512 {
5513   u8 *name;
5514   u32 value;
5515 } name_sort_t;
5516
5517
5518 #define STR_VTR_OP_CASE(op)     \
5519     case L2_VTR_ ## op:         \
5520         return "" # op;
5521
5522 static const char *
5523 str_vtr_op (u32 vtr_op)
5524 {
5525   switch (vtr_op)
5526     {
5527       STR_VTR_OP_CASE (DISABLED);
5528       STR_VTR_OP_CASE (PUSH_1);
5529       STR_VTR_OP_CASE (PUSH_2);
5530       STR_VTR_OP_CASE (POP_1);
5531       STR_VTR_OP_CASE (POP_2);
5532       STR_VTR_OP_CASE (TRANSLATE_1_1);
5533       STR_VTR_OP_CASE (TRANSLATE_1_2);
5534       STR_VTR_OP_CASE (TRANSLATE_2_1);
5535       STR_VTR_OP_CASE (TRANSLATE_2_2);
5536     }
5537
5538   return "UNKNOWN";
5539 }
5540
5541 static int
5542 dump_sub_interface_table (vat_main_t * vam)
5543 {
5544   const sw_interface_subif_t *sub = NULL;
5545
5546   if (vam->json_output)
5547     {
5548       clib_warning
5549         ("JSON output supported only for VPE API calls and dump_stats_table");
5550       return -99;
5551     }
5552
5553   print (vam->ofp,
5554          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5555          "Interface", "sw_if_index",
5556          "sub id", "dot1ad", "tags", "outer id",
5557          "inner id", "exact", "default", "outer any", "inner any");
5558
5559   vec_foreach (sub, vam->sw_if_subif_table)
5560   {
5561     print (vam->ofp,
5562            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5563            sub->interface_name,
5564            sub->sw_if_index,
5565            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5566            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5567            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5568            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5569     if (sub->vtr_op != L2_VTR_DISABLED)
5570       {
5571         print (vam->ofp,
5572                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5573                "tag1: %d tag2: %d ]",
5574                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5575                sub->vtr_tag1, sub->vtr_tag2);
5576       }
5577   }
5578
5579   return 0;
5580 }
5581
5582 static int
5583 name_sort_cmp (void *a1, void *a2)
5584 {
5585   name_sort_t *n1 = a1;
5586   name_sort_t *n2 = a2;
5587
5588   return strcmp ((char *) n1->name, (char *) n2->name);
5589 }
5590
5591 static int
5592 dump_interface_table (vat_main_t * vam)
5593 {
5594   hash_pair_t *p;
5595   name_sort_t *nses = 0, *ns;
5596
5597   if (vam->json_output)
5598     {
5599       clib_warning
5600         ("JSON output supported only for VPE API calls and dump_stats_table");
5601       return -99;
5602     }
5603
5604   /* *INDENT-OFF* */
5605   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5606   ({
5607     vec_add2 (nses, ns, 1);
5608     ns->name = (u8 *)(p->key);
5609     ns->value = (u32) p->value[0];
5610   }));
5611   /* *INDENT-ON* */
5612
5613   vec_sort_with_function (nses, name_sort_cmp);
5614
5615   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5616   vec_foreach (ns, nses)
5617   {
5618     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5619   }
5620   vec_free (nses);
5621   return 0;
5622 }
5623
5624 static int
5625 dump_ip_table (vat_main_t * vam, int is_ipv6)
5626 {
5627   const ip_details_t *det = NULL;
5628   const ip_address_details_t *address = NULL;
5629   u32 i = ~0;
5630
5631   print (vam->ofp, "%-12s", "sw_if_index");
5632
5633   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5634   {
5635     i++;
5636     if (!det->present)
5637       {
5638         continue;
5639       }
5640     print (vam->ofp, "%-12d", i);
5641     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5642     if (!det->addr)
5643       {
5644         continue;
5645       }
5646     vec_foreach (address, det->addr)
5647     {
5648       print (vam->ofp,
5649              "            %-30U%-13d",
5650              is_ipv6 ? format_ip6_address : format_ip4_address,
5651              address->ip, address->prefix_length);
5652     }
5653   }
5654
5655   return 0;
5656 }
5657
5658 static int
5659 dump_ipv4_table (vat_main_t * vam)
5660 {
5661   if (vam->json_output)
5662     {
5663       clib_warning
5664         ("JSON output supported only for VPE API calls and dump_stats_table");
5665       return -99;
5666     }
5667
5668   return dump_ip_table (vam, 0);
5669 }
5670
5671 static int
5672 dump_ipv6_table (vat_main_t * vam)
5673 {
5674   if (vam->json_output)
5675     {
5676       clib_warning
5677         ("JSON output supported only for VPE API calls and dump_stats_table");
5678       return -99;
5679     }
5680
5681   return dump_ip_table (vam, 1);
5682 }
5683
5684 static char *
5685 counter_type_to_str (u8 counter_type, u8 is_combined)
5686 {
5687   if (!is_combined)
5688     {
5689       switch (counter_type)
5690         {
5691         case VNET_INTERFACE_COUNTER_DROP:
5692           return "drop";
5693         case VNET_INTERFACE_COUNTER_PUNT:
5694           return "punt";
5695         case VNET_INTERFACE_COUNTER_IP4:
5696           return "ip4";
5697         case VNET_INTERFACE_COUNTER_IP6:
5698           return "ip6";
5699         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5700           return "rx-no-buf";
5701         case VNET_INTERFACE_COUNTER_RX_MISS:
5702           return "rx-miss";
5703         case VNET_INTERFACE_COUNTER_RX_ERROR:
5704           return "rx-error";
5705         case VNET_INTERFACE_COUNTER_TX_ERROR:
5706           return "tx-error";
5707         default:
5708           return "INVALID-COUNTER-TYPE";
5709         }
5710     }
5711   else
5712     {
5713       switch (counter_type)
5714         {
5715         case VNET_INTERFACE_COUNTER_RX:
5716           return "rx";
5717         case VNET_INTERFACE_COUNTER_TX:
5718           return "tx";
5719         default:
5720           return "INVALID-COUNTER-TYPE";
5721         }
5722     }
5723 }
5724
5725 static int
5726 dump_stats_table (vat_main_t * vam)
5727 {
5728   vat_json_node_t node;
5729   vat_json_node_t *msg_array;
5730   vat_json_node_t *msg;
5731   vat_json_node_t *counter_array;
5732   vat_json_node_t *counter;
5733   interface_counter_t c;
5734   u64 packets;
5735   ip4_fib_counter_t *c4;
5736   ip6_fib_counter_t *c6;
5737   ip4_nbr_counter_t *n4;
5738   ip6_nbr_counter_t *n6;
5739   int i, j;
5740
5741   if (!vam->json_output)
5742     {
5743       clib_warning ("dump_stats_table supported only in JSON format");
5744       return -99;
5745     }
5746
5747   vat_json_init_object (&node);
5748
5749   /* interface counters */
5750   msg_array = vat_json_object_add (&node, "interface_counters");
5751   vat_json_init_array (msg_array);
5752   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5753     {
5754       msg = vat_json_array_add (msg_array);
5755       vat_json_init_object (msg);
5756       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5757                                        (u8 *) counter_type_to_str (i, 0));
5758       vat_json_object_add_int (msg, "is_combined", 0);
5759       counter_array = vat_json_object_add (msg, "data");
5760       vat_json_init_array (counter_array);
5761       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5762         {
5763           packets = vam->simple_interface_counters[i][j];
5764           vat_json_array_add_uint (counter_array, packets);
5765         }
5766     }
5767   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5768     {
5769       msg = vat_json_array_add (msg_array);
5770       vat_json_init_object (msg);
5771       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5772                                        (u8 *) counter_type_to_str (i, 1));
5773       vat_json_object_add_int (msg, "is_combined", 1);
5774       counter_array = vat_json_object_add (msg, "data");
5775       vat_json_init_array (counter_array);
5776       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5777         {
5778           c = vam->combined_interface_counters[i][j];
5779           counter = vat_json_array_add (counter_array);
5780           vat_json_init_object (counter);
5781           vat_json_object_add_uint (counter, "packets", c.packets);
5782           vat_json_object_add_uint (counter, "bytes", c.bytes);
5783         }
5784     }
5785
5786   /* ip4 fib counters */
5787   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
5788   vat_json_init_array (msg_array);
5789   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
5790     {
5791       msg = vat_json_array_add (msg_array);
5792       vat_json_init_object (msg);
5793       vat_json_object_add_uint (msg, "vrf_id",
5794                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
5795       counter_array = vat_json_object_add (msg, "c");
5796       vat_json_init_array (counter_array);
5797       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
5798         {
5799           counter = vat_json_array_add (counter_array);
5800           vat_json_init_object (counter);
5801           c4 = &vam->ip4_fib_counters[i][j];
5802           vat_json_object_add_ip4 (counter, "address", c4->address);
5803           vat_json_object_add_uint (counter, "address_length",
5804                                     c4->address_length);
5805           vat_json_object_add_uint (counter, "packets", c4->packets);
5806           vat_json_object_add_uint (counter, "bytes", c4->bytes);
5807         }
5808     }
5809
5810   /* ip6 fib counters */
5811   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
5812   vat_json_init_array (msg_array);
5813   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
5814     {
5815       msg = vat_json_array_add (msg_array);
5816       vat_json_init_object (msg);
5817       vat_json_object_add_uint (msg, "vrf_id",
5818                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
5819       counter_array = vat_json_object_add (msg, "c");
5820       vat_json_init_array (counter_array);
5821       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
5822         {
5823           counter = vat_json_array_add (counter_array);
5824           vat_json_init_object (counter);
5825           c6 = &vam->ip6_fib_counters[i][j];
5826           vat_json_object_add_ip6 (counter, "address", c6->address);
5827           vat_json_object_add_uint (counter, "address_length",
5828                                     c6->address_length);
5829           vat_json_object_add_uint (counter, "packets", c6->packets);
5830           vat_json_object_add_uint (counter, "bytes", c6->bytes);
5831         }
5832     }
5833
5834   /* ip4 nbr counters */
5835   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
5836   vat_json_init_array (msg_array);
5837   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
5838     {
5839       msg = vat_json_array_add (msg_array);
5840       vat_json_init_object (msg);
5841       vat_json_object_add_uint (msg, "sw_if_index", i);
5842       counter_array = vat_json_object_add (msg, "c");
5843       vat_json_init_array (counter_array);
5844       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
5845         {
5846           counter = vat_json_array_add (counter_array);
5847           vat_json_init_object (counter);
5848           n4 = &vam->ip4_nbr_counters[i][j];
5849           vat_json_object_add_ip4 (counter, "address", n4->address);
5850           vat_json_object_add_uint (counter, "link-type", n4->linkt);
5851           vat_json_object_add_uint (counter, "packets", n4->packets);
5852           vat_json_object_add_uint (counter, "bytes", n4->bytes);
5853         }
5854     }
5855
5856   /* ip6 nbr counters */
5857   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
5858   vat_json_init_array (msg_array);
5859   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
5860     {
5861       msg = vat_json_array_add (msg_array);
5862       vat_json_init_object (msg);
5863       vat_json_object_add_uint (msg, "sw_if_index", i);
5864       counter_array = vat_json_object_add (msg, "c");
5865       vat_json_init_array (counter_array);
5866       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
5867         {
5868           counter = vat_json_array_add (counter_array);
5869           vat_json_init_object (counter);
5870           n6 = &vam->ip6_nbr_counters[i][j];
5871           vat_json_object_add_ip6 (counter, "address", n6->address);
5872           vat_json_object_add_uint (counter, "packets", n6->packets);
5873           vat_json_object_add_uint (counter, "bytes", n6->bytes);
5874         }
5875     }
5876
5877   vat_json_print (vam->ofp, &node);
5878   vat_json_free (&node);
5879
5880   return 0;
5881 }
5882
5883 /*
5884  * Pass CLI buffers directly in the CLI_INBAND API message,
5885  * instead of an additional shared memory area.
5886  */
5887 static int
5888 exec_inband (vat_main_t * vam)
5889 {
5890   vl_api_cli_inband_t *mp;
5891   unformat_input_t *i = vam->input;
5892   int ret;
5893
5894   if (vec_len (i->buffer) == 0)
5895     return -1;
5896
5897   if (vam->exec_mode == 0 && unformat (i, "mode"))
5898     {
5899       vam->exec_mode = 1;
5900       return 0;
5901     }
5902   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5903     {
5904       vam->exec_mode = 0;
5905       return 0;
5906     }
5907
5908   /*
5909    * In order for the CLI command to work, it
5910    * must be a vector ending in \n, not a C-string ending
5911    * in \n\0.
5912    */
5913   u32 len = vec_len (vam->input->buffer);
5914   M2 (CLI_INBAND, mp, len);
5915   clib_memcpy (mp->cmd, vam->input->buffer, len);
5916   mp->length = htonl (len);
5917
5918   S (mp);
5919   W (ret);
5920   /* json responses may or may not include a useful reply... */
5921   if (vec_len (vam->cmd_reply))
5922     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5923   return ret;
5924 }
5925
5926 int
5927 exec (vat_main_t * vam)
5928 {
5929   return exec_inband (vam);
5930 }
5931
5932 static int
5933 api_create_loopback (vat_main_t * vam)
5934 {
5935   unformat_input_t *i = vam->input;
5936   vl_api_create_loopback_t *mp;
5937   vl_api_create_loopback_instance_t *mp_lbi;
5938   u8 mac_address[6];
5939   u8 mac_set = 0;
5940   u8 is_specified = 0;
5941   u32 user_instance = 0;
5942   int ret;
5943
5944   memset (mac_address, 0, sizeof (mac_address));
5945
5946   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5947     {
5948       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5949         mac_set = 1;
5950       if (unformat (i, "instance %d", &user_instance))
5951         is_specified = 1;
5952       else
5953         break;
5954     }
5955
5956   if (is_specified)
5957     {
5958       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5959       mp_lbi->is_specified = is_specified;
5960       if (is_specified)
5961         mp_lbi->user_instance = htonl (user_instance);
5962       if (mac_set)
5963         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5964       S (mp_lbi);
5965     }
5966   else
5967     {
5968       /* Construct the API message */
5969       M (CREATE_LOOPBACK, mp);
5970       if (mac_set)
5971         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5972       S (mp);
5973     }
5974
5975   W (ret);
5976   return ret;
5977 }
5978
5979 static int
5980 api_delete_loopback (vat_main_t * vam)
5981 {
5982   unformat_input_t *i = vam->input;
5983   vl_api_delete_loopback_t *mp;
5984   u32 sw_if_index = ~0;
5985   int ret;
5986
5987   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5988     {
5989       if (unformat (i, "sw_if_index %d", &sw_if_index))
5990         ;
5991       else
5992         break;
5993     }
5994
5995   if (sw_if_index == ~0)
5996     {
5997       errmsg ("missing sw_if_index");
5998       return -99;
5999     }
6000
6001   /* Construct the API message */
6002   M (DELETE_LOOPBACK, mp);
6003   mp->sw_if_index = ntohl (sw_if_index);
6004
6005   S (mp);
6006   W (ret);
6007   return ret;
6008 }
6009
6010 static int
6011 api_want_stats (vat_main_t * vam)
6012 {
6013   unformat_input_t *i = vam->input;
6014   vl_api_want_stats_t *mp;
6015   int enable = -1;
6016   int ret;
6017
6018   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6019     {
6020       if (unformat (i, "enable"))
6021         enable = 1;
6022       else if (unformat (i, "disable"))
6023         enable = 0;
6024       else
6025         break;
6026     }
6027
6028   if (enable == -1)
6029     {
6030       errmsg ("missing enable|disable");
6031       return -99;
6032     }
6033
6034   M (WANT_STATS, mp);
6035   mp->enable_disable = enable;
6036
6037   S (mp);
6038   W (ret);
6039   return ret;
6040 }
6041
6042 static int
6043 api_want_interface_events (vat_main_t * vam)
6044 {
6045   unformat_input_t *i = vam->input;
6046   vl_api_want_interface_events_t *mp;
6047   int enable = -1;
6048   int ret;
6049
6050   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6051     {
6052       if (unformat (i, "enable"))
6053         enable = 1;
6054       else if (unformat (i, "disable"))
6055         enable = 0;
6056       else
6057         break;
6058     }
6059
6060   if (enable == -1)
6061     {
6062       errmsg ("missing enable|disable");
6063       return -99;
6064     }
6065
6066   M (WANT_INTERFACE_EVENTS, mp);
6067   mp->enable_disable = enable;
6068
6069   vam->interface_event_display = enable;
6070
6071   S (mp);
6072   W (ret);
6073   return ret;
6074 }
6075
6076
6077 /* Note: non-static, called once to set up the initial intfc table */
6078 int
6079 api_sw_interface_dump (vat_main_t * vam)
6080 {
6081   vl_api_sw_interface_dump_t *mp;
6082   vl_api_control_ping_t *mp_ping;
6083   hash_pair_t *p;
6084   name_sort_t *nses = 0, *ns;
6085   sw_interface_subif_t *sub = NULL;
6086   int ret;
6087
6088   /* Toss the old name table */
6089   /* *INDENT-OFF* */
6090   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6091   ({
6092     vec_add2 (nses, ns, 1);
6093     ns->name = (u8 *)(p->key);
6094     ns->value = (u32) p->value[0];
6095   }));
6096   /* *INDENT-ON* */
6097
6098   hash_free (vam->sw_if_index_by_interface_name);
6099
6100   vec_foreach (ns, nses) vec_free (ns->name);
6101
6102   vec_free (nses);
6103
6104   vec_foreach (sub, vam->sw_if_subif_table)
6105   {
6106     vec_free (sub->interface_name);
6107   }
6108   vec_free (vam->sw_if_subif_table);
6109
6110   /* recreate the interface name hash table */
6111   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6112
6113   /* Get list of ethernets */
6114   M (SW_INTERFACE_DUMP, mp);
6115   mp->name_filter_valid = 1;
6116   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
6117   S (mp);
6118
6119   /* and local / loopback interfaces */
6120   M (SW_INTERFACE_DUMP, mp);
6121   mp->name_filter_valid = 1;
6122   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
6123   S (mp);
6124
6125   /* and packet-generator interfaces */
6126   M (SW_INTERFACE_DUMP, mp);
6127   mp->name_filter_valid = 1;
6128   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
6129   S (mp);
6130
6131   /* and vxlan-gpe tunnel interfaces */
6132   M (SW_INTERFACE_DUMP, mp);
6133   mp->name_filter_valid = 1;
6134   strncpy ((char *) mp->name_filter, "vxlan_gpe",
6135            sizeof (mp->name_filter) - 1);
6136   S (mp);
6137
6138   /* and vxlan tunnel interfaces */
6139   M (SW_INTERFACE_DUMP, mp);
6140   mp->name_filter_valid = 1;
6141   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
6142   S (mp);
6143
6144   /* and geneve tunnel interfaces */
6145   M (SW_INTERFACE_DUMP, mp);
6146   mp->name_filter_valid = 1;
6147   strncpy ((char *) mp->name_filter, "geneve", sizeof (mp->name_filter) - 1);
6148   S (mp);
6149
6150   /* and host (af_packet) interfaces */
6151   M (SW_INTERFACE_DUMP, mp);
6152   mp->name_filter_valid = 1;
6153   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
6154   S (mp);
6155
6156   /* and l2tpv3 tunnel interfaces */
6157   M (SW_INTERFACE_DUMP, mp);
6158   mp->name_filter_valid = 1;
6159   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
6160            sizeof (mp->name_filter) - 1);
6161   S (mp);
6162
6163   /* and GRE tunnel interfaces */
6164   M (SW_INTERFACE_DUMP, mp);
6165   mp->name_filter_valid = 1;
6166   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
6167   S (mp);
6168
6169   /* and LISP-GPE interfaces */
6170   M (SW_INTERFACE_DUMP, mp);
6171   mp->name_filter_valid = 1;
6172   strncpy ((char *) mp->name_filter, "lisp_gpe",
6173            sizeof (mp->name_filter) - 1);
6174   S (mp);
6175
6176   /* and IPSEC tunnel interfaces */
6177   M (SW_INTERFACE_DUMP, mp);
6178   mp->name_filter_valid = 1;
6179   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
6180   S (mp);
6181
6182   /* Use a control ping for synchronization */
6183   MPING (CONTROL_PING, mp_ping);
6184   S (mp_ping);
6185
6186   W (ret);
6187   return ret;
6188 }
6189
6190 static int
6191 api_sw_interface_set_flags (vat_main_t * vam)
6192 {
6193   unformat_input_t *i = vam->input;
6194   vl_api_sw_interface_set_flags_t *mp;
6195   u32 sw_if_index;
6196   u8 sw_if_index_set = 0;
6197   u8 admin_up = 0;
6198   int ret;
6199
6200   /* Parse args required to build the message */
6201   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6202     {
6203       if (unformat (i, "admin-up"))
6204         admin_up = 1;
6205       else if (unformat (i, "admin-down"))
6206         admin_up = 0;
6207       else
6208         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6209         sw_if_index_set = 1;
6210       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6211         sw_if_index_set = 1;
6212       else
6213         break;
6214     }
6215
6216   if (sw_if_index_set == 0)
6217     {
6218       errmsg ("missing interface name or sw_if_index");
6219       return -99;
6220     }
6221
6222   /* Construct the API message */
6223   M (SW_INTERFACE_SET_FLAGS, mp);
6224   mp->sw_if_index = ntohl (sw_if_index);
6225   mp->admin_up_down = admin_up;
6226
6227   /* send it... */
6228   S (mp);
6229
6230   /* Wait for a reply, return the good/bad news... */
6231   W (ret);
6232   return ret;
6233 }
6234
6235 static int
6236 api_sw_interface_clear_stats (vat_main_t * vam)
6237 {
6238   unformat_input_t *i = vam->input;
6239   vl_api_sw_interface_clear_stats_t *mp;
6240   u32 sw_if_index;
6241   u8 sw_if_index_set = 0;
6242   int ret;
6243
6244   /* Parse args required to build the message */
6245   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6246     {
6247       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6248         sw_if_index_set = 1;
6249       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6250         sw_if_index_set = 1;
6251       else
6252         break;
6253     }
6254
6255   /* Construct the API message */
6256   M (SW_INTERFACE_CLEAR_STATS, mp);
6257
6258   if (sw_if_index_set == 1)
6259     mp->sw_if_index = ntohl (sw_if_index);
6260   else
6261     mp->sw_if_index = ~0;
6262
6263   /* send it... */
6264   S (mp);
6265
6266   /* Wait for a reply, return the good/bad news... */
6267   W (ret);
6268   return ret;
6269 }
6270
6271 static int
6272 api_sw_interface_add_del_address (vat_main_t * vam)
6273 {
6274   unformat_input_t *i = vam->input;
6275   vl_api_sw_interface_add_del_address_t *mp;
6276   u32 sw_if_index;
6277   u8 sw_if_index_set = 0;
6278   u8 is_add = 1, del_all = 0;
6279   u32 address_length = 0;
6280   u8 v4_address_set = 0;
6281   u8 v6_address_set = 0;
6282   ip4_address_t v4address;
6283   ip6_address_t v6address;
6284   int ret;
6285
6286   /* Parse args required to build the message */
6287   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6288     {
6289       if (unformat (i, "del-all"))
6290         del_all = 1;
6291       else if (unformat (i, "del"))
6292         is_add = 0;
6293       else
6294         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6295         sw_if_index_set = 1;
6296       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6297         sw_if_index_set = 1;
6298       else if (unformat (i, "%U/%d",
6299                          unformat_ip4_address, &v4address, &address_length))
6300         v4_address_set = 1;
6301       else if (unformat (i, "%U/%d",
6302                          unformat_ip6_address, &v6address, &address_length))
6303         v6_address_set = 1;
6304       else
6305         break;
6306     }
6307
6308   if (sw_if_index_set == 0)
6309     {
6310       errmsg ("missing interface name or sw_if_index");
6311       return -99;
6312     }
6313   if (v4_address_set && v6_address_set)
6314     {
6315       errmsg ("both v4 and v6 addresses set");
6316       return -99;
6317     }
6318   if (!v4_address_set && !v6_address_set && !del_all)
6319     {
6320       errmsg ("no addresses set");
6321       return -99;
6322     }
6323
6324   /* Construct the API message */
6325   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6326
6327   mp->sw_if_index = ntohl (sw_if_index);
6328   mp->is_add = is_add;
6329   mp->del_all = del_all;
6330   if (v6_address_set)
6331     {
6332       mp->is_ipv6 = 1;
6333       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6334     }
6335   else
6336     {
6337       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6338     }
6339   mp->address_length = address_length;
6340
6341   /* send it... */
6342   S (mp);
6343
6344   /* Wait for a reply, return good/bad news  */
6345   W (ret);
6346   return ret;
6347 }
6348
6349 static int
6350 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6351 {
6352   unformat_input_t *i = vam->input;
6353   vl_api_sw_interface_set_mpls_enable_t *mp;
6354   u32 sw_if_index;
6355   u8 sw_if_index_set = 0;
6356   u8 enable = 1;
6357   int ret;
6358
6359   /* Parse args required to build the message */
6360   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6361     {
6362       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6363         sw_if_index_set = 1;
6364       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6365         sw_if_index_set = 1;
6366       else if (unformat (i, "disable"))
6367         enable = 0;
6368       else if (unformat (i, "dis"))
6369         enable = 0;
6370       else
6371         break;
6372     }
6373
6374   if (sw_if_index_set == 0)
6375     {
6376       errmsg ("missing interface name or sw_if_index");
6377       return -99;
6378     }
6379
6380   /* Construct the API message */
6381   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6382
6383   mp->sw_if_index = ntohl (sw_if_index);
6384   mp->enable = enable;
6385
6386   /* send it... */
6387   S (mp);
6388
6389   /* Wait for a reply... */
6390   W (ret);
6391   return ret;
6392 }
6393
6394 static int
6395 api_sw_interface_set_table (vat_main_t * vam)
6396 {
6397   unformat_input_t *i = vam->input;
6398   vl_api_sw_interface_set_table_t *mp;
6399   u32 sw_if_index, vrf_id = 0;
6400   u8 sw_if_index_set = 0;
6401   u8 is_ipv6 = 0;
6402   int ret;
6403
6404   /* Parse args required to build the message */
6405   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6406     {
6407       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6408         sw_if_index_set = 1;
6409       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6410         sw_if_index_set = 1;
6411       else if (unformat (i, "vrf %d", &vrf_id))
6412         ;
6413       else if (unformat (i, "ipv6"))
6414         is_ipv6 = 1;
6415       else
6416         break;
6417     }
6418
6419   if (sw_if_index_set == 0)
6420     {
6421       errmsg ("missing interface name or sw_if_index");
6422       return -99;
6423     }
6424
6425   /* Construct the API message */
6426   M (SW_INTERFACE_SET_TABLE, mp);
6427
6428   mp->sw_if_index = ntohl (sw_if_index);
6429   mp->is_ipv6 = is_ipv6;
6430   mp->vrf_id = ntohl (vrf_id);
6431
6432   /* send it... */
6433   S (mp);
6434
6435   /* Wait for a reply... */
6436   W (ret);
6437   return ret;
6438 }
6439
6440 static void vl_api_sw_interface_get_table_reply_t_handler
6441   (vl_api_sw_interface_get_table_reply_t * mp)
6442 {
6443   vat_main_t *vam = &vat_main;
6444
6445   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6446
6447   vam->retval = ntohl (mp->retval);
6448   vam->result_ready = 1;
6449
6450 }
6451
6452 static void vl_api_sw_interface_get_table_reply_t_handler_json
6453   (vl_api_sw_interface_get_table_reply_t * mp)
6454 {
6455   vat_main_t *vam = &vat_main;
6456   vat_json_node_t node;
6457
6458   vat_json_init_object (&node);
6459   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6460   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6461
6462   vat_json_print (vam->ofp, &node);
6463   vat_json_free (&node);
6464
6465   vam->retval = ntohl (mp->retval);
6466   vam->result_ready = 1;
6467 }
6468
6469 static int
6470 api_sw_interface_get_table (vat_main_t * vam)
6471 {
6472   unformat_input_t *i = vam->input;
6473   vl_api_sw_interface_get_table_t *mp;
6474   u32 sw_if_index;
6475   u8 sw_if_index_set = 0;
6476   u8 is_ipv6 = 0;
6477   int ret;
6478
6479   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6480     {
6481       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6482         sw_if_index_set = 1;
6483       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6484         sw_if_index_set = 1;
6485       else if (unformat (i, "ipv6"))
6486         is_ipv6 = 1;
6487       else
6488         break;
6489     }
6490
6491   if (sw_if_index_set == 0)
6492     {
6493       errmsg ("missing interface name or sw_if_index");
6494       return -99;
6495     }
6496
6497   M (SW_INTERFACE_GET_TABLE, mp);
6498   mp->sw_if_index = htonl (sw_if_index);
6499   mp->is_ipv6 = is_ipv6;
6500
6501   S (mp);
6502   W (ret);
6503   return ret;
6504 }
6505
6506 static int
6507 api_sw_interface_set_vpath (vat_main_t * vam)
6508 {
6509   unformat_input_t *i = vam->input;
6510   vl_api_sw_interface_set_vpath_t *mp;
6511   u32 sw_if_index = 0;
6512   u8 sw_if_index_set = 0;
6513   u8 is_enable = 0;
6514   int ret;
6515
6516   /* Parse args required to build the message */
6517   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6518     {
6519       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6520         sw_if_index_set = 1;
6521       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6522         sw_if_index_set = 1;
6523       else if (unformat (i, "enable"))
6524         is_enable = 1;
6525       else if (unformat (i, "disable"))
6526         is_enable = 0;
6527       else
6528         break;
6529     }
6530
6531   if (sw_if_index_set == 0)
6532     {
6533       errmsg ("missing interface name or sw_if_index");
6534       return -99;
6535     }
6536
6537   /* Construct the API message */
6538   M (SW_INTERFACE_SET_VPATH, mp);
6539
6540   mp->sw_if_index = ntohl (sw_if_index);
6541   mp->enable = is_enable;
6542
6543   /* send it... */
6544   S (mp);
6545
6546   /* Wait for a reply... */
6547   W (ret);
6548   return ret;
6549 }
6550
6551 static int
6552 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6553 {
6554   unformat_input_t *i = vam->input;
6555   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6556   u32 sw_if_index = 0;
6557   u8 sw_if_index_set = 0;
6558   u8 is_enable = 1;
6559   u8 is_ipv6 = 0;
6560   int ret;
6561
6562   /* Parse args required to build the message */
6563   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6564     {
6565       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6566         sw_if_index_set = 1;
6567       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6568         sw_if_index_set = 1;
6569       else if (unformat (i, "enable"))
6570         is_enable = 1;
6571       else if (unformat (i, "disable"))
6572         is_enable = 0;
6573       else if (unformat (i, "ip4"))
6574         is_ipv6 = 0;
6575       else if (unformat (i, "ip6"))
6576         is_ipv6 = 1;
6577       else
6578         break;
6579     }
6580
6581   if (sw_if_index_set == 0)
6582     {
6583       errmsg ("missing interface name or sw_if_index");
6584       return -99;
6585     }
6586
6587   /* Construct the API message */
6588   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6589
6590   mp->sw_if_index = ntohl (sw_if_index);
6591   mp->enable = is_enable;
6592   mp->is_ipv6 = is_ipv6;
6593
6594   /* send it... */
6595   S (mp);
6596
6597   /* Wait for a reply... */
6598   W (ret);
6599   return ret;
6600 }
6601
6602 static int
6603 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6604 {
6605   unformat_input_t *i = vam->input;
6606   vl_api_sw_interface_set_geneve_bypass_t *mp;
6607   u32 sw_if_index = 0;
6608   u8 sw_if_index_set = 0;
6609   u8 is_enable = 1;
6610   u8 is_ipv6 = 0;
6611   int ret;
6612
6613   /* Parse args required to build the message */
6614   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6615     {
6616       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6617         sw_if_index_set = 1;
6618       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6619         sw_if_index_set = 1;
6620       else if (unformat (i, "enable"))
6621         is_enable = 1;
6622       else if (unformat (i, "disable"))
6623         is_enable = 0;
6624       else if (unformat (i, "ip4"))
6625         is_ipv6 = 0;
6626       else if (unformat (i, "ip6"))
6627         is_ipv6 = 1;
6628       else
6629         break;
6630     }
6631
6632   if (sw_if_index_set == 0)
6633     {
6634       errmsg ("missing interface name or sw_if_index");
6635       return -99;
6636     }
6637
6638   /* Construct the API message */
6639   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6640
6641   mp->sw_if_index = ntohl (sw_if_index);
6642   mp->enable = is_enable;
6643   mp->is_ipv6 = is_ipv6;
6644
6645   /* send it... */
6646   S (mp);
6647
6648   /* Wait for a reply... */
6649   W (ret);
6650   return ret;
6651 }
6652
6653 static int
6654 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6655 {
6656   unformat_input_t *i = vam->input;
6657   vl_api_sw_interface_set_l2_xconnect_t *mp;
6658   u32 rx_sw_if_index;
6659   u8 rx_sw_if_index_set = 0;
6660   u32 tx_sw_if_index;
6661   u8 tx_sw_if_index_set = 0;
6662   u8 enable = 1;
6663   int ret;
6664
6665   /* Parse args required to build the message */
6666   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6667     {
6668       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6669         rx_sw_if_index_set = 1;
6670       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6671         tx_sw_if_index_set = 1;
6672       else if (unformat (i, "rx"))
6673         {
6674           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6675             {
6676               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6677                             &rx_sw_if_index))
6678                 rx_sw_if_index_set = 1;
6679             }
6680           else
6681             break;
6682         }
6683       else if (unformat (i, "tx"))
6684         {
6685           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6686             {
6687               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6688                             &tx_sw_if_index))
6689                 tx_sw_if_index_set = 1;
6690             }
6691           else
6692             break;
6693         }
6694       else if (unformat (i, "enable"))
6695         enable = 1;
6696       else if (unformat (i, "disable"))
6697         enable = 0;
6698       else
6699         break;
6700     }
6701
6702   if (rx_sw_if_index_set == 0)
6703     {
6704       errmsg ("missing rx interface name or rx_sw_if_index");
6705       return -99;
6706     }
6707
6708   if (enable && (tx_sw_if_index_set == 0))
6709     {
6710       errmsg ("missing tx interface name or tx_sw_if_index");
6711       return -99;
6712     }
6713
6714   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6715
6716   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6717   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6718   mp->enable = enable;
6719
6720   S (mp);
6721   W (ret);
6722   return ret;
6723 }
6724
6725 static int
6726 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6727 {
6728   unformat_input_t *i = vam->input;
6729   vl_api_sw_interface_set_l2_bridge_t *mp;
6730   u32 rx_sw_if_index;
6731   u8 rx_sw_if_index_set = 0;
6732   u32 bd_id;
6733   u8 bd_id_set = 0;
6734   u8 bvi = 0;
6735   u32 shg = 0;
6736   u8 enable = 1;
6737   int ret;
6738
6739   /* Parse args required to build the message */
6740   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6741     {
6742       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6743         rx_sw_if_index_set = 1;
6744       else if (unformat (i, "bd_id %d", &bd_id))
6745         bd_id_set = 1;
6746       else
6747         if (unformat
6748             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6749         rx_sw_if_index_set = 1;
6750       else if (unformat (i, "shg %d", &shg))
6751         ;
6752       else if (unformat (i, "bvi"))
6753         bvi = 1;
6754       else if (unformat (i, "enable"))
6755         enable = 1;
6756       else if (unformat (i, "disable"))
6757         enable = 0;
6758       else
6759         break;
6760     }
6761
6762   if (rx_sw_if_index_set == 0)
6763     {
6764       errmsg ("missing rx interface name or sw_if_index");
6765       return -99;
6766     }
6767
6768   if (enable && (bd_id_set == 0))
6769     {
6770       errmsg ("missing bridge domain");
6771       return -99;
6772     }
6773
6774   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6775
6776   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6777   mp->bd_id = ntohl (bd_id);
6778   mp->shg = (u8) shg;
6779   mp->bvi = bvi;
6780   mp->enable = enable;
6781
6782   S (mp);
6783   W (ret);
6784   return ret;
6785 }
6786
6787 static int
6788 api_bridge_domain_dump (vat_main_t * vam)
6789 {
6790   unformat_input_t *i = vam->input;
6791   vl_api_bridge_domain_dump_t *mp;
6792   vl_api_control_ping_t *mp_ping;
6793   u32 bd_id = ~0;
6794   int ret;
6795
6796   /* Parse args required to build the message */
6797   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6798     {
6799       if (unformat (i, "bd_id %d", &bd_id))
6800         ;
6801       else
6802         break;
6803     }
6804
6805   M (BRIDGE_DOMAIN_DUMP, mp);
6806   mp->bd_id = ntohl (bd_id);
6807   S (mp);
6808
6809   /* Use a control ping for synchronization */
6810   MPING (CONTROL_PING, mp_ping);
6811   S (mp_ping);
6812
6813   W (ret);
6814   return ret;
6815 }
6816
6817 static int
6818 api_bridge_domain_add_del (vat_main_t * vam)
6819 {
6820   unformat_input_t *i = vam->input;
6821   vl_api_bridge_domain_add_del_t *mp;
6822   u32 bd_id = ~0;
6823   u8 is_add = 1;
6824   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6825   u8 *bd_tag = NULL;
6826   u32 mac_age = 0;
6827   int ret;
6828
6829   /* Parse args required to build the message */
6830   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6831     {
6832       if (unformat (i, "bd_id %d", &bd_id))
6833         ;
6834       else if (unformat (i, "flood %d", &flood))
6835         ;
6836       else if (unformat (i, "uu-flood %d", &uu_flood))
6837         ;
6838       else if (unformat (i, "forward %d", &forward))
6839         ;
6840       else if (unformat (i, "learn %d", &learn))
6841         ;
6842       else if (unformat (i, "arp-term %d", &arp_term))
6843         ;
6844       else if (unformat (i, "mac-age %d", &mac_age))
6845         ;
6846       else if (unformat (i, "bd-tag %s", &bd_tag))
6847         ;
6848       else if (unformat (i, "del"))
6849         {
6850           is_add = 0;
6851           flood = uu_flood = forward = learn = 0;
6852         }
6853       else
6854         break;
6855     }
6856
6857   if (bd_id == ~0)
6858     {
6859       errmsg ("missing bridge domain");
6860       ret = -99;
6861       goto done;
6862     }
6863
6864   if (mac_age > 255)
6865     {
6866       errmsg ("mac age must be less than 256 ");
6867       ret = -99;
6868       goto done;
6869     }
6870
6871   if ((bd_tag) && (strlen ((char *) bd_tag) > 63))
6872     {
6873       errmsg ("bd-tag cannot be longer than 63");
6874       ret = -99;
6875       goto done;
6876     }
6877
6878   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6879
6880   mp->bd_id = ntohl (bd_id);
6881   mp->flood = flood;
6882   mp->uu_flood = uu_flood;
6883   mp->forward = forward;
6884   mp->learn = learn;
6885   mp->arp_term = arp_term;
6886   mp->is_add = is_add;
6887   mp->mac_age = (u8) mac_age;
6888   if (bd_tag)
6889     strcpy ((char *) mp->bd_tag, (char *) bd_tag);
6890
6891   S (mp);
6892   W (ret);
6893
6894 done:
6895   vec_free (bd_tag);
6896   return ret;
6897 }
6898
6899 static int
6900 api_l2fib_flush_bd (vat_main_t * vam)
6901 {
6902   unformat_input_t *i = vam->input;
6903   vl_api_l2fib_flush_bd_t *mp;
6904   u32 bd_id = ~0;
6905   int ret;
6906
6907   /* Parse args required to build the message */
6908   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6909     {
6910       if (unformat (i, "bd_id %d", &bd_id));
6911       else
6912         break;
6913     }
6914
6915   if (bd_id == ~0)
6916     {
6917       errmsg ("missing bridge domain");
6918       return -99;
6919     }
6920
6921   M (L2FIB_FLUSH_BD, mp);
6922
6923   mp->bd_id = htonl (bd_id);
6924
6925   S (mp);
6926   W (ret);
6927   return ret;
6928 }
6929
6930 static int
6931 api_l2fib_flush_int (vat_main_t * vam)
6932 {
6933   unformat_input_t *i = vam->input;
6934   vl_api_l2fib_flush_int_t *mp;
6935   u32 sw_if_index = ~0;
6936   int ret;
6937
6938   /* Parse args required to build the message */
6939   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6940     {
6941       if (unformat (i, "sw_if_index %d", &sw_if_index));
6942       else
6943         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6944       else
6945         break;
6946     }
6947
6948   if (sw_if_index == ~0)
6949     {
6950       errmsg ("missing interface name or sw_if_index");
6951       return -99;
6952     }
6953
6954   M (L2FIB_FLUSH_INT, mp);
6955
6956   mp->sw_if_index = ntohl (sw_if_index);
6957
6958   S (mp);
6959   W (ret);
6960   return ret;
6961 }
6962
6963 static int
6964 api_l2fib_add_del (vat_main_t * vam)
6965 {
6966   unformat_input_t *i = vam->input;
6967   vl_api_l2fib_add_del_t *mp;
6968   f64 timeout;
6969   u64 mac = 0;
6970   u8 mac_set = 0;
6971   u32 bd_id;
6972   u8 bd_id_set = 0;
6973   u32 sw_if_index = ~0;
6974   u8 sw_if_index_set = 0;
6975   u8 is_add = 1;
6976   u8 static_mac = 0;
6977   u8 filter_mac = 0;
6978   u8 bvi_mac = 0;
6979   int count = 1;
6980   f64 before = 0;
6981   int j;
6982
6983   /* Parse args required to build the message */
6984   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6985     {
6986       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
6987         mac_set = 1;
6988       else if (unformat (i, "bd_id %d", &bd_id))
6989         bd_id_set = 1;
6990       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6991         sw_if_index_set = 1;
6992       else if (unformat (i, "sw_if"))
6993         {
6994           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6995             {
6996               if (unformat
6997                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6998                 sw_if_index_set = 1;
6999             }
7000           else
7001             break;
7002         }
7003       else if (unformat (i, "static"))
7004         static_mac = 1;
7005       else if (unformat (i, "filter"))
7006         {
7007           filter_mac = 1;
7008           static_mac = 1;
7009         }
7010       else if (unformat (i, "bvi"))
7011         {
7012           bvi_mac = 1;
7013           static_mac = 1;
7014         }
7015       else if (unformat (i, "del"))
7016         is_add = 0;
7017       else if (unformat (i, "count %d", &count))
7018         ;
7019       else
7020         break;
7021     }
7022
7023   if (mac_set == 0)
7024     {
7025       errmsg ("missing mac address");
7026       return -99;
7027     }
7028
7029   if (bd_id_set == 0)
7030     {
7031       errmsg ("missing bridge domain");
7032       return -99;
7033     }
7034
7035   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7036     {
7037       errmsg ("missing interface name or sw_if_index");
7038       return -99;
7039     }
7040
7041   if (count > 1)
7042     {
7043       /* Turn on async mode */
7044       vam->async_mode = 1;
7045       vam->async_errors = 0;
7046       before = vat_time_now (vam);
7047     }
7048
7049   for (j = 0; j < count; j++)
7050     {
7051       M (L2FIB_ADD_DEL, mp);
7052
7053       mp->mac = mac;
7054       mp->bd_id = ntohl (bd_id);
7055       mp->is_add = is_add;
7056
7057       if (is_add)
7058         {
7059           mp->sw_if_index = ntohl (sw_if_index);
7060           mp->static_mac = static_mac;
7061           mp->filter_mac = filter_mac;
7062           mp->bvi_mac = bvi_mac;
7063         }
7064       increment_mac_address (&mac);
7065       /* send it... */
7066       S (mp);
7067     }
7068
7069   if (count > 1)
7070     {
7071       vl_api_control_ping_t *mp_ping;
7072       f64 after;
7073
7074       /* Shut off async mode */
7075       vam->async_mode = 0;
7076
7077       MPING (CONTROL_PING, mp_ping);
7078       S (mp_ping);
7079
7080       timeout = vat_time_now (vam) + 1.0;
7081       while (vat_time_now (vam) < timeout)
7082         if (vam->result_ready == 1)
7083           goto out;
7084       vam->retval = -99;
7085
7086     out:
7087       if (vam->retval == -99)
7088         errmsg ("timeout");
7089
7090       if (vam->async_errors > 0)
7091         {
7092           errmsg ("%d asynchronous errors", vam->async_errors);
7093           vam->retval = -98;
7094         }
7095       vam->async_errors = 0;
7096       after = vat_time_now (vam);
7097
7098       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7099              count, after - before, count / (after - before));
7100     }
7101   else
7102     {
7103       int ret;
7104
7105       /* Wait for a reply... */
7106       W (ret);
7107       return ret;
7108     }
7109   /* Return the good/bad news */
7110   return (vam->retval);
7111 }
7112
7113 static int
7114 api_bridge_domain_set_mac_age (vat_main_t * vam)
7115 {
7116   unformat_input_t *i = vam->input;
7117   vl_api_bridge_domain_set_mac_age_t *mp;
7118   u32 bd_id = ~0;
7119   u32 mac_age = 0;
7120   int ret;
7121
7122   /* Parse args required to build the message */
7123   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7124     {
7125       if (unformat (i, "bd_id %d", &bd_id));
7126       else if (unformat (i, "mac-age %d", &mac_age));
7127       else
7128         break;
7129     }
7130
7131   if (bd_id == ~0)
7132     {
7133       errmsg ("missing bridge domain");
7134       return -99;
7135     }
7136
7137   if (mac_age > 255)
7138     {
7139       errmsg ("mac age must be less than 256 ");
7140       return -99;
7141     }
7142
7143   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7144
7145   mp->bd_id = htonl (bd_id);
7146   mp->mac_age = (u8) mac_age;
7147
7148   S (mp);
7149   W (ret);
7150   return ret;
7151 }
7152
7153 static int
7154 api_l2_flags (vat_main_t * vam)
7155 {
7156   unformat_input_t *i = vam->input;
7157   vl_api_l2_flags_t *mp;
7158   u32 sw_if_index;
7159   u32 flags = 0;
7160   u8 sw_if_index_set = 0;
7161   u8 is_set = 0;
7162   int ret;
7163
7164   /* Parse args required to build the message */
7165   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7166     {
7167       if (unformat (i, "sw_if_index %d", &sw_if_index))
7168         sw_if_index_set = 1;
7169       else if (unformat (i, "sw_if"))
7170         {
7171           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7172             {
7173               if (unformat
7174                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7175                 sw_if_index_set = 1;
7176             }
7177           else
7178             break;
7179         }
7180       else if (unformat (i, "learn"))
7181         flags |= L2_LEARN;
7182       else if (unformat (i, "forward"))
7183         flags |= L2_FWD;
7184       else if (unformat (i, "flood"))
7185         flags |= L2_FLOOD;
7186       else if (unformat (i, "uu-flood"))
7187         flags |= L2_UU_FLOOD;
7188       else if (unformat (i, "arp-term"))
7189         flags |= L2_ARP_TERM;
7190       else if (unformat (i, "off"))
7191         is_set = 0;
7192       else if (unformat (i, "disable"))
7193         is_set = 0;
7194       else
7195         break;
7196     }
7197
7198   if (sw_if_index_set == 0)
7199     {
7200       errmsg ("missing interface name or sw_if_index");
7201       return -99;
7202     }
7203
7204   M (L2_FLAGS, mp);
7205
7206   mp->sw_if_index = ntohl (sw_if_index);
7207   mp->feature_bitmap = ntohl (flags);
7208   mp->is_set = is_set;
7209
7210   S (mp);
7211   W (ret);
7212   return ret;
7213 }
7214
7215 static int
7216 api_bridge_flags (vat_main_t * vam)
7217 {
7218   unformat_input_t *i = vam->input;
7219   vl_api_bridge_flags_t *mp;
7220   u32 bd_id;
7221   u8 bd_id_set = 0;
7222   u8 is_set = 1;
7223   u32 flags = 0;
7224   int ret;
7225
7226   /* Parse args required to build the message */
7227   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7228     {
7229       if (unformat (i, "bd_id %d", &bd_id))
7230         bd_id_set = 1;
7231       else if (unformat (i, "learn"))
7232         flags |= L2_LEARN;
7233       else if (unformat (i, "forward"))
7234         flags |= L2_FWD;
7235       else if (unformat (i, "flood"))
7236         flags |= L2_FLOOD;
7237       else if (unformat (i, "uu-flood"))
7238         flags |= L2_UU_FLOOD;
7239       else if (unformat (i, "arp-term"))
7240         flags |= L2_ARP_TERM;
7241       else if (unformat (i, "off"))
7242         is_set = 0;
7243       else if (unformat (i, "disable"))
7244         is_set = 0;
7245       else
7246         break;
7247     }
7248
7249   if (bd_id_set == 0)
7250     {
7251       errmsg ("missing bridge domain");
7252       return -99;
7253     }
7254
7255   M (BRIDGE_FLAGS, mp);
7256
7257   mp->bd_id = ntohl (bd_id);
7258   mp->feature_bitmap = ntohl (flags);
7259   mp->is_set = is_set;
7260
7261   S (mp);
7262   W (ret);
7263   return ret;
7264 }
7265
7266 static int
7267 api_bd_ip_mac_add_del (vat_main_t * vam)
7268 {
7269   unformat_input_t *i = vam->input;
7270   vl_api_bd_ip_mac_add_del_t *mp;
7271   u32 bd_id;
7272   u8 is_ipv6 = 0;
7273   u8 is_add = 1;
7274   u8 bd_id_set = 0;
7275   u8 ip_set = 0;
7276   u8 mac_set = 0;
7277   ip4_address_t v4addr;
7278   ip6_address_t v6addr;
7279   u8 macaddr[6];
7280   int ret;
7281
7282
7283   /* Parse args required to build the message */
7284   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7285     {
7286       if (unformat (i, "bd_id %d", &bd_id))
7287         {
7288           bd_id_set++;
7289         }
7290       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7291         {
7292           ip_set++;
7293         }
7294       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7295         {
7296           ip_set++;
7297           is_ipv6++;
7298         }
7299       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7300         {
7301           mac_set++;
7302         }
7303       else if (unformat (i, "del"))
7304         is_add = 0;
7305       else
7306         break;
7307     }
7308
7309   if (bd_id_set == 0)
7310     {
7311       errmsg ("missing bridge domain");
7312       return -99;
7313     }
7314   else if (ip_set == 0)
7315     {
7316       errmsg ("missing IP address");
7317       return -99;
7318     }
7319   else if (mac_set == 0)
7320     {
7321       errmsg ("missing MAC address");
7322       return -99;
7323     }
7324
7325   M (BD_IP_MAC_ADD_DEL, mp);
7326
7327   mp->bd_id = ntohl (bd_id);
7328   mp->is_ipv6 = is_ipv6;
7329   mp->is_add = is_add;
7330   if (is_ipv6)
7331     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7332   else
7333     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7334   clib_memcpy (mp->mac_address, macaddr, 6);
7335   S (mp);
7336   W (ret);
7337   return ret;
7338 }
7339
7340 static int
7341 api_tap_connect (vat_main_t * vam)
7342 {
7343   unformat_input_t *i = vam->input;
7344   vl_api_tap_connect_t *mp;
7345   u8 mac_address[6];
7346   u8 random_mac = 1;
7347   u8 name_set = 0;
7348   u8 *tap_name;
7349   u8 *tag = 0;
7350   ip4_address_t ip4_address;
7351   u32 ip4_mask_width;
7352   int ip4_address_set = 0;
7353   ip6_address_t ip6_address;
7354   u32 ip6_mask_width;
7355   int ip6_address_set = 0;
7356   int ret;
7357
7358   memset (mac_address, 0, sizeof (mac_address));
7359
7360   /* Parse args required to build the message */
7361   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7362     {
7363       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7364         {
7365           random_mac = 0;
7366         }
7367       else if (unformat (i, "random-mac"))
7368         random_mac = 1;
7369       else if (unformat (i, "tapname %s", &tap_name))
7370         name_set = 1;
7371       else if (unformat (i, "tag %s", &tag))
7372         ;
7373       else if (unformat (i, "address %U/%d",
7374                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7375         ip4_address_set = 1;
7376       else if (unformat (i, "address %U/%d",
7377                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7378         ip6_address_set = 1;
7379       else
7380         break;
7381     }
7382
7383   if (name_set == 0)
7384     {
7385       errmsg ("missing tap name");
7386       return -99;
7387     }
7388   if (vec_len (tap_name) > 63)
7389     {
7390       errmsg ("tap name too long");
7391       return -99;
7392     }
7393   vec_add1 (tap_name, 0);
7394
7395   if (vec_len (tag) > 63)
7396     {
7397       errmsg ("tag too long");
7398       return -99;
7399     }
7400
7401   /* Construct the API message */
7402   M (TAP_CONNECT, mp);
7403
7404   mp->use_random_mac = random_mac;
7405   clib_memcpy (mp->mac_address, mac_address, 6);
7406   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7407   if (tag)
7408     clib_memcpy (mp->tag, tag, vec_len (tag));
7409
7410   if (ip4_address_set)
7411     {
7412       mp->ip4_address_set = 1;
7413       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7414       mp->ip4_mask_width = ip4_mask_width;
7415     }
7416   if (ip6_address_set)
7417     {
7418       mp->ip6_address_set = 1;
7419       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7420       mp->ip6_mask_width = ip6_mask_width;
7421     }
7422
7423   vec_free (tap_name);
7424   vec_free (tag);
7425
7426   /* send it... */
7427   S (mp);
7428
7429   /* Wait for a reply... */
7430   W (ret);
7431   return ret;
7432 }
7433
7434 static int
7435 api_tap_modify (vat_main_t * vam)
7436 {
7437   unformat_input_t *i = vam->input;
7438   vl_api_tap_modify_t *mp;
7439   u8 mac_address[6];
7440   u8 random_mac = 1;
7441   u8 name_set = 0;
7442   u8 *tap_name;
7443   u32 sw_if_index = ~0;
7444   u8 sw_if_index_set = 0;
7445   int ret;
7446
7447   memset (mac_address, 0, sizeof (mac_address));
7448
7449   /* Parse args required to build the message */
7450   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7451     {
7452       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7453         sw_if_index_set = 1;
7454       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7455         sw_if_index_set = 1;
7456       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7457         {
7458           random_mac = 0;
7459         }
7460       else if (unformat (i, "random-mac"))
7461         random_mac = 1;
7462       else if (unformat (i, "tapname %s", &tap_name))
7463         name_set = 1;
7464       else
7465         break;
7466     }
7467
7468   if (sw_if_index_set == 0)
7469     {
7470       errmsg ("missing vpp interface name");
7471       return -99;
7472     }
7473   if (name_set == 0)
7474     {
7475       errmsg ("missing tap name");
7476       return -99;
7477     }
7478   if (vec_len (tap_name) > 63)
7479     {
7480       errmsg ("tap name too long");
7481     }
7482   vec_add1 (tap_name, 0);
7483
7484   /* Construct the API message */
7485   M (TAP_MODIFY, mp);
7486
7487   mp->use_random_mac = random_mac;
7488   mp->sw_if_index = ntohl (sw_if_index);
7489   clib_memcpy (mp->mac_address, mac_address, 6);
7490   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7491   vec_free (tap_name);
7492
7493   /* send it... */
7494   S (mp);
7495
7496   /* Wait for a reply... */
7497   W (ret);
7498   return ret;
7499 }
7500
7501 static int
7502 api_tap_delete (vat_main_t * vam)
7503 {
7504   unformat_input_t *i = vam->input;
7505   vl_api_tap_delete_t *mp;
7506   u32 sw_if_index = ~0;
7507   u8 sw_if_index_set = 0;
7508   int ret;
7509
7510   /* Parse args required to build the message */
7511   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7512     {
7513       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7514         sw_if_index_set = 1;
7515       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7516         sw_if_index_set = 1;
7517       else
7518         break;
7519     }
7520
7521   if (sw_if_index_set == 0)
7522     {
7523       errmsg ("missing vpp interface name");
7524       return -99;
7525     }
7526
7527   /* Construct the API message */
7528   M (TAP_DELETE, mp);
7529
7530   mp->sw_if_index = ntohl (sw_if_index);
7531
7532   /* send it... */
7533   S (mp);
7534
7535   /* Wait for a reply... */
7536   W (ret);
7537   return ret;
7538 }
7539
7540 static int
7541 api_ip_table_add_del (vat_main_t * vam)
7542 {
7543   unformat_input_t *i = vam->input;
7544   vl_api_ip_table_add_del_t *mp;
7545   u32 table_id = ~0;
7546   u8 is_ipv6 = 0;
7547   u8 is_add = 1;
7548   int ret = 0;
7549
7550   /* Parse args required to build the message */
7551   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7552     {
7553       if (unformat (i, "ipv6"))
7554         is_ipv6 = 1;
7555       else if (unformat (i, "del"))
7556         is_add = 0;
7557       else if (unformat (i, "add"))
7558         is_add = 1;
7559       else if (unformat (i, "table %d", &table_id))
7560         ;
7561       else
7562         {
7563           clib_warning ("parse error '%U'", format_unformat_error, i);
7564           return -99;
7565         }
7566     }
7567
7568   if (~0 == table_id)
7569     {
7570       errmsg ("missing table-ID");
7571       return -99;
7572     }
7573
7574   /* Construct the API message */
7575   M (IP_TABLE_ADD_DEL, mp);
7576
7577   mp->table_id = ntohl (table_id);
7578   mp->is_ipv6 = is_ipv6;
7579   mp->is_add = is_add;
7580
7581   /* send it... */
7582   S (mp);
7583
7584   /* Wait for a reply... */
7585   W (ret);
7586
7587   return ret;
7588 }
7589
7590 static int
7591 api_ip_add_del_route (vat_main_t * vam)
7592 {
7593   unformat_input_t *i = vam->input;
7594   vl_api_ip_add_del_route_t *mp;
7595   u32 sw_if_index = ~0, vrf_id = 0;
7596   u8 is_ipv6 = 0;
7597   u8 is_local = 0, is_drop = 0;
7598   u8 is_unreach = 0, is_prohibit = 0;
7599   u8 create_vrf_if_needed = 0;
7600   u8 is_add = 1;
7601   u32 next_hop_weight = 1;
7602   u8 is_multipath = 0;
7603   u8 address_set = 0;
7604   u8 address_length_set = 0;
7605   u32 next_hop_table_id = 0;
7606   u32 resolve_attempts = 0;
7607   u32 dst_address_length = 0;
7608   u8 next_hop_set = 0;
7609   ip4_address_t v4_dst_address, v4_next_hop_address;
7610   ip6_address_t v6_dst_address, v6_next_hop_address;
7611   int count = 1;
7612   int j;
7613   f64 before = 0;
7614   u32 random_add_del = 0;
7615   u32 *random_vector = 0;
7616   uword *random_hash;
7617   u32 random_seed = 0xdeaddabe;
7618   u32 classify_table_index = ~0;
7619   u8 is_classify = 0;
7620   u8 resolve_host = 0, resolve_attached = 0;
7621   mpls_label_t *next_hop_out_label_stack = NULL;
7622   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7623   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7624
7625   /* Parse args required to build the message */
7626   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7627     {
7628       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7629         ;
7630       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7631         ;
7632       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
7633         {
7634           address_set = 1;
7635           is_ipv6 = 0;
7636         }
7637       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
7638         {
7639           address_set = 1;
7640           is_ipv6 = 1;
7641         }
7642       else if (unformat (i, "/%d", &dst_address_length))
7643         {
7644           address_length_set = 1;
7645         }
7646
7647       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
7648                                          &v4_next_hop_address))
7649         {
7650           next_hop_set = 1;
7651         }
7652       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
7653                                          &v6_next_hop_address))
7654         {
7655           next_hop_set = 1;
7656         }
7657       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
7658         ;
7659       else if (unformat (i, "weight %d", &next_hop_weight))
7660         ;
7661       else if (unformat (i, "drop"))
7662         {
7663           is_drop = 1;
7664         }
7665       else if (unformat (i, "null-send-unreach"))
7666         {
7667           is_unreach = 1;
7668         }
7669       else if (unformat (i, "null-send-prohibit"))
7670         {
7671           is_prohibit = 1;
7672         }
7673       else if (unformat (i, "local"))
7674         {
7675           is_local = 1;
7676         }
7677       else if (unformat (i, "classify %d", &classify_table_index))
7678         {
7679           is_classify = 1;
7680         }
7681       else if (unformat (i, "del"))
7682         is_add = 0;
7683       else if (unformat (i, "add"))
7684         is_add = 1;
7685       else if (unformat (i, "resolve-via-host"))
7686         resolve_host = 1;
7687       else if (unformat (i, "resolve-via-attached"))
7688         resolve_attached = 1;
7689       else if (unformat (i, "multipath"))
7690         is_multipath = 1;
7691       else if (unformat (i, "vrf %d", &vrf_id))
7692         ;
7693       else if (unformat (i, "create-vrf"))
7694         create_vrf_if_needed = 1;
7695       else if (unformat (i, "count %d", &count))
7696         ;
7697       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
7698         ;
7699       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7700         ;
7701       else if (unformat (i, "out-label %d", &next_hop_out_label))
7702         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7703       else if (unformat (i, "via-label %d", &next_hop_via_label))
7704         ;
7705       else if (unformat (i, "random"))
7706         random_add_del = 1;
7707       else if (unformat (i, "seed %d", &random_seed))
7708         ;
7709       else
7710         {
7711           clib_warning ("parse error '%U'", format_unformat_error, i);
7712           return -99;
7713         }
7714     }
7715
7716   if (!next_hop_set && !is_drop && !is_local &&
7717       !is_classify && !is_unreach && !is_prohibit &&
7718       MPLS_LABEL_INVALID == next_hop_via_label)
7719     {
7720       errmsg
7721         ("next hop / local / drop / unreach / prohibit / classify not set");
7722       return -99;
7723     }
7724
7725   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
7726     {
7727       errmsg ("next hop and next-hop via label set");
7728       return -99;
7729     }
7730   if (address_set == 0)
7731     {
7732       errmsg ("missing addresses");
7733       return -99;
7734     }
7735
7736   if (address_length_set == 0)
7737     {
7738       errmsg ("missing address length");
7739       return -99;
7740     }
7741
7742   /* Generate a pile of unique, random routes */
7743   if (random_add_del)
7744     {
7745       u32 this_random_address;
7746       random_hash = hash_create (count, sizeof (uword));
7747
7748       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
7749       for (j = 0; j <= count; j++)
7750         {
7751           do
7752             {
7753               this_random_address = random_u32 (&random_seed);
7754               this_random_address =
7755                 clib_host_to_net_u32 (this_random_address);
7756             }
7757           while (hash_get (random_hash, this_random_address));
7758           vec_add1 (random_vector, this_random_address);
7759           hash_set (random_hash, this_random_address, 1);
7760         }
7761       hash_free (random_hash);
7762       v4_dst_address.as_u32 = random_vector[0];
7763     }
7764
7765   if (count > 1)
7766     {
7767       /* Turn on async mode */
7768       vam->async_mode = 1;
7769       vam->async_errors = 0;
7770       before = vat_time_now (vam);
7771     }
7772
7773   for (j = 0; j < count; j++)
7774     {
7775       /* Construct the API message */
7776       M2 (IP_ADD_DEL_ROUTE, mp,
7777           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7778
7779       mp->next_hop_sw_if_index = ntohl (sw_if_index);
7780       mp->table_id = ntohl (vrf_id);
7781       mp->create_vrf_if_needed = create_vrf_if_needed;
7782
7783       mp->is_add = is_add;
7784       mp->is_drop = is_drop;
7785       mp->is_unreach = is_unreach;
7786       mp->is_prohibit = is_prohibit;
7787       mp->is_ipv6 = is_ipv6;
7788       mp->is_local = is_local;
7789       mp->is_classify = is_classify;
7790       mp->is_multipath = is_multipath;
7791       mp->is_resolve_host = resolve_host;
7792       mp->is_resolve_attached = resolve_attached;
7793       mp->next_hop_weight = next_hop_weight;
7794       mp->dst_address_length = dst_address_length;
7795       mp->next_hop_table_id = ntohl (next_hop_table_id);
7796       mp->classify_table_index = ntohl (classify_table_index);
7797       mp->next_hop_via_label = ntohl (next_hop_via_label);
7798       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7799       if (0 != mp->next_hop_n_out_labels)
7800         {
7801           memcpy (mp->next_hop_out_label_stack,
7802                   next_hop_out_label_stack,
7803                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7804           vec_free (next_hop_out_label_stack);
7805         }
7806
7807       if (is_ipv6)
7808         {
7809           clib_memcpy (mp->dst_address, &v6_dst_address,
7810                        sizeof (v6_dst_address));
7811           if (next_hop_set)
7812             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
7813                          sizeof (v6_next_hop_address));
7814           increment_v6_address (&v6_dst_address);
7815         }
7816       else
7817         {
7818           clib_memcpy (mp->dst_address, &v4_dst_address,
7819                        sizeof (v4_dst_address));
7820           if (next_hop_set)
7821             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
7822                          sizeof (v4_next_hop_address));
7823           if (random_add_del)
7824             v4_dst_address.as_u32 = random_vector[j + 1];
7825           else
7826             increment_v4_address (&v4_dst_address);
7827         }
7828       /* send it... */
7829       S (mp);
7830       /* If we receive SIGTERM, stop now... */
7831       if (vam->do_exit)
7832         break;
7833     }
7834
7835   /* When testing multiple add/del ops, use a control-ping to sync */
7836   if (count > 1)
7837     {
7838       vl_api_control_ping_t *mp_ping;
7839       f64 after;
7840       f64 timeout;
7841
7842       /* Shut off async mode */
7843       vam->async_mode = 0;
7844
7845       MPING (CONTROL_PING, mp_ping);
7846       S (mp_ping);
7847
7848       timeout = vat_time_now (vam) + 1.0;
7849       while (vat_time_now (vam) < timeout)
7850         if (vam->result_ready == 1)
7851           goto out;
7852       vam->retval = -99;
7853
7854     out:
7855       if (vam->retval == -99)
7856         errmsg ("timeout");
7857
7858       if (vam->async_errors > 0)
7859         {
7860           errmsg ("%d asynchronous errors", vam->async_errors);
7861           vam->retval = -98;
7862         }
7863       vam->async_errors = 0;
7864       after = vat_time_now (vam);
7865
7866       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7867       if (j > 0)
7868         count = j;
7869
7870       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7871              count, after - before, count / (after - before));
7872     }
7873   else
7874     {
7875       int ret;
7876
7877       /* Wait for a reply... */
7878       W (ret);
7879       return ret;
7880     }
7881
7882   /* Return the good/bad news */
7883   return (vam->retval);
7884 }
7885
7886 static int
7887 api_ip_mroute_add_del (vat_main_t * vam)
7888 {
7889   unformat_input_t *i = vam->input;
7890   vl_api_ip_mroute_add_del_t *mp;
7891   u32 sw_if_index = ~0, vrf_id = 0;
7892   u8 is_ipv6 = 0;
7893   u8 is_local = 0;
7894   u8 create_vrf_if_needed = 0;
7895   u8 is_add = 1;
7896   u8 address_set = 0;
7897   u32 grp_address_length = 0;
7898   ip4_address_t v4_grp_address, v4_src_address;
7899   ip6_address_t v6_grp_address, v6_src_address;
7900   mfib_itf_flags_t iflags = 0;
7901   mfib_entry_flags_t eflags = 0;
7902   int ret;
7903
7904   /* Parse args required to build the message */
7905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7906     {
7907       if (unformat (i, "sw_if_index %d", &sw_if_index))
7908         ;
7909       else if (unformat (i, "%U %U",
7910                          unformat_ip4_address, &v4_src_address,
7911                          unformat_ip4_address, &v4_grp_address))
7912         {
7913           grp_address_length = 64;
7914           address_set = 1;
7915           is_ipv6 = 0;
7916         }
7917       else if (unformat (i, "%U %U",
7918                          unformat_ip6_address, &v6_src_address,
7919                          unformat_ip6_address, &v6_grp_address))
7920         {
7921           grp_address_length = 256;
7922           address_set = 1;
7923           is_ipv6 = 1;
7924         }
7925       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
7926         {
7927           memset (&v4_src_address, 0, sizeof (v4_src_address));
7928           grp_address_length = 32;
7929           address_set = 1;
7930           is_ipv6 = 0;
7931         }
7932       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
7933         {
7934           memset (&v6_src_address, 0, sizeof (v6_src_address));
7935           grp_address_length = 128;
7936           address_set = 1;
7937           is_ipv6 = 1;
7938         }
7939       else if (unformat (i, "/%d", &grp_address_length))
7940         ;
7941       else if (unformat (i, "local"))
7942         {
7943           is_local = 1;
7944         }
7945       else if (unformat (i, "del"))
7946         is_add = 0;
7947       else if (unformat (i, "add"))
7948         is_add = 1;
7949       else if (unformat (i, "vrf %d", &vrf_id))
7950         ;
7951       else if (unformat (i, "create-vrf"))
7952         create_vrf_if_needed = 1;
7953       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
7954         ;
7955       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
7956         ;
7957       else
7958         {
7959           clib_warning ("parse error '%U'", format_unformat_error, i);
7960           return -99;
7961         }
7962     }
7963
7964   if (address_set == 0)
7965     {
7966       errmsg ("missing addresses\n");
7967       return -99;
7968     }
7969
7970   /* Construct the API message */
7971   M (IP_MROUTE_ADD_DEL, mp);
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_ipv6 = is_ipv6;
7979   mp->is_local = is_local;
7980   mp->itf_flags = ntohl (iflags);
7981   mp->entry_flags = ntohl (eflags);
7982   mp->grp_address_length = grp_address_length;
7983   mp->grp_address_length = ntohs (mp->grp_address_length);
7984
7985   if (is_ipv6)
7986     {
7987       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
7988       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
7989     }
7990   else
7991     {
7992       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
7993       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
7994
7995     }
7996
7997   /* send it... */
7998   S (mp);
7999   /* Wait for a reply... */
8000   W (ret);
8001   return ret;
8002 }
8003
8004 static int
8005 api_mpls_table_add_del (vat_main_t * vam)
8006 {
8007   unformat_input_t *i = vam->input;
8008   vl_api_mpls_table_add_del_t *mp;
8009   u32 table_id = ~0;
8010   u8 is_add = 1;
8011   int ret = 0;
8012
8013   /* Parse args required to build the message */
8014   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8015     {
8016       if (unformat (i, "table %d", &table_id))
8017         ;
8018       else if (unformat (i, "del"))
8019         is_add = 0;
8020       else if (unformat (i, "add"))
8021         is_add = 1;
8022       else
8023         {
8024           clib_warning ("parse error '%U'", format_unformat_error, i);
8025           return -99;
8026         }
8027     }
8028
8029   if (~0 == table_id)
8030     {
8031       errmsg ("missing table-ID");
8032       return -99;
8033     }
8034
8035   /* Construct the API message */
8036   M (MPLS_TABLE_ADD_DEL, mp);
8037
8038   mp->mt_table_id = ntohl (table_id);
8039   mp->mt_is_add = is_add;
8040
8041   /* send it... */
8042   S (mp);
8043
8044   /* Wait for a reply... */
8045   W (ret);
8046
8047   return ret;
8048 }
8049
8050 static int
8051 api_mpls_route_add_del (vat_main_t * vam)
8052 {
8053   unformat_input_t *i = vam->input;
8054   vl_api_mpls_route_add_del_t *mp;
8055   u32 sw_if_index = ~0, table_id = 0;
8056   u8 create_table_if_needed = 0;
8057   u8 is_add = 1;
8058   u32 next_hop_weight = 1;
8059   u8 is_multipath = 0;
8060   u32 next_hop_table_id = 0;
8061   u8 next_hop_set = 0;
8062   ip4_address_t v4_next_hop_address = {
8063     .as_u32 = 0,
8064   };
8065   ip6_address_t v6_next_hop_address = { {0} };
8066   int count = 1;
8067   int j;
8068   f64 before = 0;
8069   u32 classify_table_index = ~0;
8070   u8 is_classify = 0;
8071   u8 resolve_host = 0, resolve_attached = 0;
8072   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8073   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8074   mpls_label_t *next_hop_out_label_stack = NULL;
8075   mpls_label_t local_label = MPLS_LABEL_INVALID;
8076   u8 is_eos = 0;
8077   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8078
8079   /* Parse args required to build the message */
8080   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8081     {
8082       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8083         ;
8084       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8085         ;
8086       else if (unformat (i, "%d", &local_label))
8087         ;
8088       else if (unformat (i, "eos"))
8089         is_eos = 1;
8090       else if (unformat (i, "non-eos"))
8091         is_eos = 0;
8092       else if (unformat (i, "via %U", unformat_ip4_address,
8093                          &v4_next_hop_address))
8094         {
8095           next_hop_set = 1;
8096           next_hop_proto = DPO_PROTO_IP4;
8097         }
8098       else if (unformat (i, "via %U", unformat_ip6_address,
8099                          &v6_next_hop_address))
8100         {
8101           next_hop_set = 1;
8102           next_hop_proto = DPO_PROTO_IP6;
8103         }
8104       else if (unformat (i, "weight %d", &next_hop_weight))
8105         ;
8106       else if (unformat (i, "create-table"))
8107         create_table_if_needed = 1;
8108       else if (unformat (i, "classify %d", &classify_table_index))
8109         {
8110           is_classify = 1;
8111         }
8112       else if (unformat (i, "del"))
8113         is_add = 0;
8114       else if (unformat (i, "add"))
8115         is_add = 1;
8116       else if (unformat (i, "resolve-via-host"))
8117         resolve_host = 1;
8118       else if (unformat (i, "resolve-via-attached"))
8119         resolve_attached = 1;
8120       else if (unformat (i, "multipath"))
8121         is_multipath = 1;
8122       else if (unformat (i, "count %d", &count))
8123         ;
8124       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8125         {
8126           next_hop_set = 1;
8127           next_hop_proto = DPO_PROTO_IP4;
8128         }
8129       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8130         {
8131           next_hop_set = 1;
8132           next_hop_proto = DPO_PROTO_IP6;
8133         }
8134       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8135         ;
8136       else if (unformat (i, "via-label %d", &next_hop_via_label))
8137         ;
8138       else if (unformat (i, "out-label %d", &next_hop_out_label))
8139         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8140       else
8141         {
8142           clib_warning ("parse error '%U'", format_unformat_error, i);
8143           return -99;
8144         }
8145     }
8146
8147   if (!next_hop_set && !is_classify)
8148     {
8149       errmsg ("next hop / classify not set");
8150       return -99;
8151     }
8152
8153   if (MPLS_LABEL_INVALID == local_label)
8154     {
8155       errmsg ("missing label");
8156       return -99;
8157     }
8158
8159   if (count > 1)
8160     {
8161       /* Turn on async mode */
8162       vam->async_mode = 1;
8163       vam->async_errors = 0;
8164       before = vat_time_now (vam);
8165     }
8166
8167   for (j = 0; j < count; j++)
8168     {
8169       /* Construct the API message */
8170       M2 (MPLS_ROUTE_ADD_DEL, mp,
8171           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8172
8173       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8174       mp->mr_table_id = ntohl (table_id);
8175       mp->mr_create_table_if_needed = create_table_if_needed;
8176
8177       mp->mr_is_add = is_add;
8178       mp->mr_next_hop_proto = next_hop_proto;
8179       mp->mr_is_classify = is_classify;
8180       mp->mr_is_multipath = is_multipath;
8181       mp->mr_is_resolve_host = resolve_host;
8182       mp->mr_is_resolve_attached = resolve_attached;
8183       mp->mr_next_hop_weight = next_hop_weight;
8184       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8185       mp->mr_classify_table_index = ntohl (classify_table_index);
8186       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8187       mp->mr_label = ntohl (local_label);
8188       mp->mr_eos = is_eos;
8189
8190       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8191       if (0 != mp->mr_next_hop_n_out_labels)
8192         {
8193           memcpy (mp->mr_next_hop_out_label_stack,
8194                   next_hop_out_label_stack,
8195                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8196           vec_free (next_hop_out_label_stack);
8197         }
8198
8199       if (next_hop_set)
8200         {
8201           if (DPO_PROTO_IP4 == next_hop_proto)
8202             {
8203               clib_memcpy (mp->mr_next_hop,
8204                            &v4_next_hop_address,
8205                            sizeof (v4_next_hop_address));
8206             }
8207           else if (DPO_PROTO_IP6 == next_hop_proto)
8208
8209             {
8210               clib_memcpy (mp->mr_next_hop,
8211                            &v6_next_hop_address,
8212                            sizeof (v6_next_hop_address));
8213             }
8214         }
8215       local_label++;
8216
8217       /* send it... */
8218       S (mp);
8219       /* If we receive SIGTERM, stop now... */
8220       if (vam->do_exit)
8221         break;
8222     }
8223
8224   /* When testing multiple add/del ops, use a control-ping to sync */
8225   if (count > 1)
8226     {
8227       vl_api_control_ping_t *mp_ping;
8228       f64 after;
8229       f64 timeout;
8230
8231       /* Shut off async mode */
8232       vam->async_mode = 0;
8233
8234       MPING (CONTROL_PING, mp_ping);
8235       S (mp_ping);
8236
8237       timeout = vat_time_now (vam) + 1.0;
8238       while (vat_time_now (vam) < timeout)
8239         if (vam->result_ready == 1)
8240           goto out;
8241       vam->retval = -99;
8242
8243     out:
8244       if (vam->retval == -99)
8245         errmsg ("timeout");
8246
8247       if (vam->async_errors > 0)
8248         {
8249           errmsg ("%d asynchronous errors", vam->async_errors);
8250           vam->retval = -98;
8251         }
8252       vam->async_errors = 0;
8253       after = vat_time_now (vam);
8254
8255       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8256       if (j > 0)
8257         count = j;
8258
8259       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8260              count, after - before, count / (after - before));
8261     }
8262   else
8263     {
8264       int ret;
8265
8266       /* Wait for a reply... */
8267       W (ret);
8268       return ret;
8269     }
8270
8271   /* Return the good/bad news */
8272   return (vam->retval);
8273 }
8274
8275 static int
8276 api_mpls_ip_bind_unbind (vat_main_t * vam)
8277 {
8278   unformat_input_t *i = vam->input;
8279   vl_api_mpls_ip_bind_unbind_t *mp;
8280   u32 ip_table_id = 0;
8281   u8 create_table_if_needed = 0;
8282   u8 is_bind = 1;
8283   u8 is_ip4 = 1;
8284   ip4_address_t v4_address;
8285   ip6_address_t v6_address;
8286   u32 address_length;
8287   u8 address_set = 0;
8288   mpls_label_t local_label = MPLS_LABEL_INVALID;
8289   int ret;
8290
8291   /* Parse args required to build the message */
8292   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8293     {
8294       if (unformat (i, "%U/%d", unformat_ip4_address,
8295                     &v4_address, &address_length))
8296         {
8297           is_ip4 = 1;
8298           address_set = 1;
8299         }
8300       else if (unformat (i, "%U/%d", unformat_ip6_address,
8301                          &v6_address, &address_length))
8302         {
8303           is_ip4 = 0;
8304           address_set = 1;
8305         }
8306       else if (unformat (i, "%d", &local_label))
8307         ;
8308       else if (unformat (i, "create-table"))
8309         create_table_if_needed = 1;
8310       else if (unformat (i, "table-id %d", &ip_table_id))
8311         ;
8312       else if (unformat (i, "unbind"))
8313         is_bind = 0;
8314       else if (unformat (i, "bind"))
8315         is_bind = 1;
8316       else
8317         {
8318           clib_warning ("parse error '%U'", format_unformat_error, i);
8319           return -99;
8320         }
8321     }
8322
8323   if (!address_set)
8324     {
8325       errmsg ("IP addres not set");
8326       return -99;
8327     }
8328
8329   if (MPLS_LABEL_INVALID == local_label)
8330     {
8331       errmsg ("missing label");
8332       return -99;
8333     }
8334
8335   /* Construct the API message */
8336   M (MPLS_IP_BIND_UNBIND, mp);
8337
8338   mp->mb_create_table_if_needed = create_table_if_needed;
8339   mp->mb_is_bind = is_bind;
8340   mp->mb_is_ip4 = is_ip4;
8341   mp->mb_ip_table_id = ntohl (ip_table_id);
8342   mp->mb_mpls_table_id = 0;
8343   mp->mb_label = ntohl (local_label);
8344   mp->mb_address_length = address_length;
8345
8346   if (is_ip4)
8347     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8348   else
8349     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8350
8351   /* send it... */
8352   S (mp);
8353
8354   /* Wait for a reply... */
8355   W (ret);
8356   return ret;
8357 }
8358
8359 static int
8360 api_proxy_arp_add_del (vat_main_t * vam)
8361 {
8362   unformat_input_t *i = vam->input;
8363   vl_api_proxy_arp_add_del_t *mp;
8364   u32 vrf_id = 0;
8365   u8 is_add = 1;
8366   ip4_address_t lo, hi;
8367   u8 range_set = 0;
8368   int ret;
8369
8370   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8371     {
8372       if (unformat (i, "vrf %d", &vrf_id))
8373         ;
8374       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
8375                          unformat_ip4_address, &hi))
8376         range_set = 1;
8377       else if (unformat (i, "del"))
8378         is_add = 0;
8379       else
8380         {
8381           clib_warning ("parse error '%U'", format_unformat_error, i);
8382           return -99;
8383         }
8384     }
8385
8386   if (range_set == 0)
8387     {
8388       errmsg ("address range not set");
8389       return -99;
8390     }
8391
8392   M (PROXY_ARP_ADD_DEL, mp);
8393
8394   mp->vrf_id = ntohl (vrf_id);
8395   mp->is_add = is_add;
8396   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
8397   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
8398
8399   S (mp);
8400   W (ret);
8401   return ret;
8402 }
8403
8404 static int
8405 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8406 {
8407   unformat_input_t *i = vam->input;
8408   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8409   u32 sw_if_index;
8410   u8 enable = 1;
8411   u8 sw_if_index_set = 0;
8412   int ret;
8413
8414   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8415     {
8416       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8417         sw_if_index_set = 1;
8418       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8419         sw_if_index_set = 1;
8420       else if (unformat (i, "enable"))
8421         enable = 1;
8422       else if (unformat (i, "disable"))
8423         enable = 0;
8424       else
8425         {
8426           clib_warning ("parse error '%U'", format_unformat_error, i);
8427           return -99;
8428         }
8429     }
8430
8431   if (sw_if_index_set == 0)
8432     {
8433       errmsg ("missing interface name or sw_if_index");
8434       return -99;
8435     }
8436
8437   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8438
8439   mp->sw_if_index = ntohl (sw_if_index);
8440   mp->enable_disable = enable;
8441
8442   S (mp);
8443   W (ret);
8444   return ret;
8445 }
8446
8447 static int
8448 api_mpls_tunnel_add_del (vat_main_t * vam)
8449 {
8450   unformat_input_t *i = vam->input;
8451   vl_api_mpls_tunnel_add_del_t *mp;
8452
8453   u8 is_add = 1;
8454   u8 l2_only = 0;
8455   u32 sw_if_index = ~0;
8456   u32 next_hop_sw_if_index = ~0;
8457   u32 next_hop_proto_is_ip4 = 1;
8458
8459   u32 next_hop_table_id = 0;
8460   ip4_address_t v4_next_hop_address = {
8461     .as_u32 = 0,
8462   };
8463   ip6_address_t v6_next_hop_address = { {0} };
8464   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
8465   int ret;
8466
8467   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8468     {
8469       if (unformat (i, "add"))
8470         is_add = 1;
8471       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8472         is_add = 0;
8473       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
8474         ;
8475       else if (unformat (i, "via %U",
8476                          unformat_ip4_address, &v4_next_hop_address))
8477         {
8478           next_hop_proto_is_ip4 = 1;
8479         }
8480       else if (unformat (i, "via %U",
8481                          unformat_ip6_address, &v6_next_hop_address))
8482         {
8483           next_hop_proto_is_ip4 = 0;
8484         }
8485       else if (unformat (i, "l2-only"))
8486         l2_only = 1;
8487       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8488         ;
8489       else if (unformat (i, "out-label %d", &next_hop_out_label))
8490         vec_add1 (labels, ntohl (next_hop_out_label));
8491       else
8492         {
8493           clib_warning ("parse error '%U'", format_unformat_error, i);
8494           return -99;
8495         }
8496     }
8497
8498   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
8499
8500   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
8501   mp->mt_sw_if_index = ntohl (sw_if_index);
8502   mp->mt_is_add = is_add;
8503   mp->mt_l2_only = l2_only;
8504   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
8505   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
8506
8507   mp->mt_next_hop_n_out_labels = vec_len (labels);
8508
8509   if (0 != mp->mt_next_hop_n_out_labels)
8510     {
8511       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
8512                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
8513       vec_free (labels);
8514     }
8515
8516   if (next_hop_proto_is_ip4)
8517     {
8518       clib_memcpy (mp->mt_next_hop,
8519                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8520     }
8521   else
8522     {
8523       clib_memcpy (mp->mt_next_hop,
8524                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8525     }
8526
8527   S (mp);
8528   W (ret);
8529   return ret;
8530 }
8531
8532 static int
8533 api_sw_interface_set_unnumbered (vat_main_t * vam)
8534 {
8535   unformat_input_t *i = vam->input;
8536   vl_api_sw_interface_set_unnumbered_t *mp;
8537   u32 sw_if_index;
8538   u32 unnum_sw_index = ~0;
8539   u8 is_add = 1;
8540   u8 sw_if_index_set = 0;
8541   int ret;
8542
8543   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8544     {
8545       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8546         sw_if_index_set = 1;
8547       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8548         sw_if_index_set = 1;
8549       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8550         ;
8551       else if (unformat (i, "del"))
8552         is_add = 0;
8553       else
8554         {
8555           clib_warning ("parse error '%U'", format_unformat_error, i);
8556           return -99;
8557         }
8558     }
8559
8560   if (sw_if_index_set == 0)
8561     {
8562       errmsg ("missing interface name or sw_if_index");
8563       return -99;
8564     }
8565
8566   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8567
8568   mp->sw_if_index = ntohl (sw_if_index);
8569   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8570   mp->is_add = is_add;
8571
8572   S (mp);
8573   W (ret);
8574   return ret;
8575 }
8576
8577 static int
8578 api_ip_neighbor_add_del (vat_main_t * vam)
8579 {
8580   unformat_input_t *i = vam->input;
8581   vl_api_ip_neighbor_add_del_t *mp;
8582   u32 sw_if_index;
8583   u8 sw_if_index_set = 0;
8584   u8 is_add = 1;
8585   u8 is_static = 0;
8586   u8 is_no_fib_entry = 0;
8587   u8 mac_address[6];
8588   u8 mac_set = 0;
8589   u8 v4_address_set = 0;
8590   u8 v6_address_set = 0;
8591   ip4_address_t v4address;
8592   ip6_address_t v6address;
8593   int ret;
8594
8595   memset (mac_address, 0, sizeof (mac_address));
8596
8597   /* Parse args required to build the message */
8598   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8599     {
8600       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8601         {
8602           mac_set = 1;
8603         }
8604       else if (unformat (i, "del"))
8605         is_add = 0;
8606       else
8607         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8608         sw_if_index_set = 1;
8609       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8610         sw_if_index_set = 1;
8611       else if (unformat (i, "is_static"))
8612         is_static = 1;
8613       else if (unformat (i, "no-fib-entry"))
8614         is_no_fib_entry = 1;
8615       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
8616         v4_address_set = 1;
8617       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
8618         v6_address_set = 1;
8619       else
8620         {
8621           clib_warning ("parse error '%U'", format_unformat_error, i);
8622           return -99;
8623         }
8624     }
8625
8626   if (sw_if_index_set == 0)
8627     {
8628       errmsg ("missing interface name or sw_if_index");
8629       return -99;
8630     }
8631   if (v4_address_set && v6_address_set)
8632     {
8633       errmsg ("both v4 and v6 addresses set");
8634       return -99;
8635     }
8636   if (!v4_address_set && !v6_address_set)
8637     {
8638       errmsg ("no address set");
8639       return -99;
8640     }
8641
8642   /* Construct the API message */
8643   M (IP_NEIGHBOR_ADD_DEL, mp);
8644
8645   mp->sw_if_index = ntohl (sw_if_index);
8646   mp->is_add = is_add;
8647   mp->is_static = is_static;
8648   mp->is_no_adj_fib = is_no_fib_entry;
8649   if (mac_set)
8650     clib_memcpy (mp->mac_address, mac_address, 6);
8651   if (v6_address_set)
8652     {
8653       mp->is_ipv6 = 1;
8654       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
8655     }
8656   else
8657     {
8658       /* mp->is_ipv6 = 0; via memset in M macro above */
8659       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
8660     }
8661
8662   /* send it... */
8663   S (mp);
8664
8665   /* Wait for a reply, return good/bad news  */
8666   W (ret);
8667   return ret;
8668 }
8669
8670 static int
8671 api_reset_vrf (vat_main_t * vam)
8672 {
8673   unformat_input_t *i = vam->input;
8674   vl_api_reset_vrf_t *mp;
8675   u32 vrf_id = 0;
8676   u8 is_ipv6 = 0;
8677   u8 vrf_id_set = 0;
8678   int ret;
8679
8680   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8681     {
8682       if (unformat (i, "vrf %d", &vrf_id))
8683         vrf_id_set = 1;
8684       else if (unformat (i, "ipv6"))
8685         is_ipv6 = 1;
8686       else
8687         {
8688           clib_warning ("parse error '%U'", format_unformat_error, i);
8689           return -99;
8690         }
8691     }
8692
8693   if (vrf_id_set == 0)
8694     {
8695       errmsg ("missing vrf id");
8696       return -99;
8697     }
8698
8699   M (RESET_VRF, mp);
8700
8701   mp->vrf_id = ntohl (vrf_id);
8702   mp->is_ipv6 = is_ipv6;
8703
8704   S (mp);
8705   W (ret);
8706   return ret;
8707 }
8708
8709 static int
8710 api_create_vlan_subif (vat_main_t * vam)
8711 {
8712   unformat_input_t *i = vam->input;
8713   vl_api_create_vlan_subif_t *mp;
8714   u32 sw_if_index;
8715   u8 sw_if_index_set = 0;
8716   u32 vlan_id;
8717   u8 vlan_id_set = 0;
8718   int ret;
8719
8720   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8721     {
8722       if (unformat (i, "sw_if_index %d", &sw_if_index))
8723         sw_if_index_set = 1;
8724       else
8725         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8726         sw_if_index_set = 1;
8727       else if (unformat (i, "vlan %d", &vlan_id))
8728         vlan_id_set = 1;
8729       else
8730         {
8731           clib_warning ("parse error '%U'", format_unformat_error, i);
8732           return -99;
8733         }
8734     }
8735
8736   if (sw_if_index_set == 0)
8737     {
8738       errmsg ("missing interface name or sw_if_index");
8739       return -99;
8740     }
8741
8742   if (vlan_id_set == 0)
8743     {
8744       errmsg ("missing vlan_id");
8745       return -99;
8746     }
8747   M (CREATE_VLAN_SUBIF, mp);
8748
8749   mp->sw_if_index = ntohl (sw_if_index);
8750   mp->vlan_id = ntohl (vlan_id);
8751
8752   S (mp);
8753   W (ret);
8754   return ret;
8755 }
8756
8757 #define foreach_create_subif_bit                \
8758 _(no_tags)                                      \
8759 _(one_tag)                                      \
8760 _(two_tags)                                     \
8761 _(dot1ad)                                       \
8762 _(exact_match)                                  \
8763 _(default_sub)                                  \
8764 _(outer_vlan_id_any)                            \
8765 _(inner_vlan_id_any)
8766
8767 static int
8768 api_create_subif (vat_main_t * vam)
8769 {
8770   unformat_input_t *i = vam->input;
8771   vl_api_create_subif_t *mp;
8772   u32 sw_if_index;
8773   u8 sw_if_index_set = 0;
8774   u32 sub_id;
8775   u8 sub_id_set = 0;
8776   u32 no_tags = 0;
8777   u32 one_tag = 0;
8778   u32 two_tags = 0;
8779   u32 dot1ad = 0;
8780   u32 exact_match = 0;
8781   u32 default_sub = 0;
8782   u32 outer_vlan_id_any = 0;
8783   u32 inner_vlan_id_any = 0;
8784   u32 tmp;
8785   u16 outer_vlan_id = 0;
8786   u16 inner_vlan_id = 0;
8787   int ret;
8788
8789   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8790     {
8791       if (unformat (i, "sw_if_index %d", &sw_if_index))
8792         sw_if_index_set = 1;
8793       else
8794         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8795         sw_if_index_set = 1;
8796       else if (unformat (i, "sub_id %d", &sub_id))
8797         sub_id_set = 1;
8798       else if (unformat (i, "outer_vlan_id %d", &tmp))
8799         outer_vlan_id = tmp;
8800       else if (unformat (i, "inner_vlan_id %d", &tmp))
8801         inner_vlan_id = tmp;
8802
8803 #define _(a) else if (unformat (i, #a)) a = 1 ;
8804       foreach_create_subif_bit
8805 #undef _
8806         else
8807         {
8808           clib_warning ("parse error '%U'", format_unformat_error, i);
8809           return -99;
8810         }
8811     }
8812
8813   if (sw_if_index_set == 0)
8814     {
8815       errmsg ("missing interface name or sw_if_index");
8816       return -99;
8817     }
8818
8819   if (sub_id_set == 0)
8820     {
8821       errmsg ("missing sub_id");
8822       return -99;
8823     }
8824   M (CREATE_SUBIF, mp);
8825
8826   mp->sw_if_index = ntohl (sw_if_index);
8827   mp->sub_id = ntohl (sub_id);
8828
8829 #define _(a) mp->a = a;
8830   foreach_create_subif_bit;
8831 #undef _
8832
8833   mp->outer_vlan_id = ntohs (outer_vlan_id);
8834   mp->inner_vlan_id = ntohs (inner_vlan_id);
8835
8836   S (mp);
8837   W (ret);
8838   return ret;
8839 }
8840
8841 static int
8842 api_oam_add_del (vat_main_t * vam)
8843 {
8844   unformat_input_t *i = vam->input;
8845   vl_api_oam_add_del_t *mp;
8846   u32 vrf_id = 0;
8847   u8 is_add = 1;
8848   ip4_address_t src, dst;
8849   u8 src_set = 0;
8850   u8 dst_set = 0;
8851   int ret;
8852
8853   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8854     {
8855       if (unformat (i, "vrf %d", &vrf_id))
8856         ;
8857       else if (unformat (i, "src %U", unformat_ip4_address, &src))
8858         src_set = 1;
8859       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
8860         dst_set = 1;
8861       else if (unformat (i, "del"))
8862         is_add = 0;
8863       else
8864         {
8865           clib_warning ("parse error '%U'", format_unformat_error, i);
8866           return -99;
8867         }
8868     }
8869
8870   if (src_set == 0)
8871     {
8872       errmsg ("missing src addr");
8873       return -99;
8874     }
8875
8876   if (dst_set == 0)
8877     {
8878       errmsg ("missing dst addr");
8879       return -99;
8880     }
8881
8882   M (OAM_ADD_DEL, mp);
8883
8884   mp->vrf_id = ntohl (vrf_id);
8885   mp->is_add = is_add;
8886   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
8887   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
8888
8889   S (mp);
8890   W (ret);
8891   return ret;
8892 }
8893
8894 static int
8895 api_reset_fib (vat_main_t * vam)
8896 {
8897   unformat_input_t *i = vam->input;
8898   vl_api_reset_fib_t *mp;
8899   u32 vrf_id = 0;
8900   u8 is_ipv6 = 0;
8901   u8 vrf_id_set = 0;
8902
8903   int ret;
8904   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8905     {
8906       if (unformat (i, "vrf %d", &vrf_id))
8907         vrf_id_set = 1;
8908       else if (unformat (i, "ipv6"))
8909         is_ipv6 = 1;
8910       else
8911         {
8912           clib_warning ("parse error '%U'", format_unformat_error, i);
8913           return -99;
8914         }
8915     }
8916
8917   if (vrf_id_set == 0)
8918     {
8919       errmsg ("missing vrf id");
8920       return -99;
8921     }
8922
8923   M (RESET_FIB, mp);
8924
8925   mp->vrf_id = ntohl (vrf_id);
8926   mp->is_ipv6 = is_ipv6;
8927
8928   S (mp);
8929   W (ret);
8930   return ret;
8931 }
8932
8933 static int
8934 api_dhcp_proxy_config (vat_main_t * vam)
8935 {
8936   unformat_input_t *i = vam->input;
8937   vl_api_dhcp_proxy_config_t *mp;
8938   u32 rx_vrf_id = 0;
8939   u32 server_vrf_id = 0;
8940   u8 is_add = 1;
8941   u8 v4_address_set = 0;
8942   u8 v6_address_set = 0;
8943   ip4_address_t v4address;
8944   ip6_address_t v6address;
8945   u8 v4_src_address_set = 0;
8946   u8 v6_src_address_set = 0;
8947   ip4_address_t v4srcaddress;
8948   ip6_address_t v6srcaddress;
8949   int ret;
8950
8951   /* Parse args required to build the message */
8952   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8953     {
8954       if (unformat (i, "del"))
8955         is_add = 0;
8956       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
8957         ;
8958       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
8959         ;
8960       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
8961         v4_address_set = 1;
8962       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
8963         v6_address_set = 1;
8964       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
8965         v4_src_address_set = 1;
8966       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
8967         v6_src_address_set = 1;
8968       else
8969         break;
8970     }
8971
8972   if (v4_address_set && v6_address_set)
8973     {
8974       errmsg ("both v4 and v6 server addresses set");
8975       return -99;
8976     }
8977   if (!v4_address_set && !v6_address_set)
8978     {
8979       errmsg ("no server addresses set");
8980       return -99;
8981     }
8982
8983   if (v4_src_address_set && v6_src_address_set)
8984     {
8985       errmsg ("both v4 and v6  src addresses set");
8986       return -99;
8987     }
8988   if (!v4_src_address_set && !v6_src_address_set)
8989     {
8990       errmsg ("no src addresses set");
8991       return -99;
8992     }
8993
8994   if (!(v4_src_address_set && v4_address_set) &&
8995       !(v6_src_address_set && v6_address_set))
8996     {
8997       errmsg ("no matching server and src addresses set");
8998       return -99;
8999     }
9000
9001   /* Construct the API message */
9002   M (DHCP_PROXY_CONFIG, mp);
9003
9004   mp->is_add = is_add;
9005   mp->rx_vrf_id = ntohl (rx_vrf_id);
9006   mp->server_vrf_id = ntohl (server_vrf_id);
9007   if (v6_address_set)
9008     {
9009       mp->is_ipv6 = 1;
9010       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9011       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9012     }
9013   else
9014     {
9015       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9016       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9017     }
9018
9019   /* send it... */
9020   S (mp);
9021
9022   /* Wait for a reply, return good/bad news  */
9023   W (ret);
9024   return ret;
9025 }
9026
9027 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9028 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9029
9030 static void
9031 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9032 {
9033   vat_main_t *vam = &vat_main;
9034   u32 i, count = mp->count;
9035   vl_api_dhcp_server_t *s;
9036
9037   if (mp->is_ipv6)
9038     print (vam->ofp,
9039            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
9040            ntohl (mp->rx_vrf_id),
9041            format_ip6_address, mp->dhcp_src_address,
9042            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9043   else
9044     print (vam->ofp,
9045            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
9046            ntohl (mp->rx_vrf_id),
9047            format_ip4_address, mp->dhcp_src_address,
9048            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9049
9050   for (i = 0; i < count; i++)
9051     {
9052       s = &mp->servers[i];
9053
9054       if (mp->is_ipv6)
9055         print (vam->ofp,
9056                " Server Table-ID %d, Server Address %U",
9057                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9058       else
9059         print (vam->ofp,
9060                " Server Table-ID %d, Server Address %U",
9061                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9062     }
9063 }
9064
9065 static void vl_api_dhcp_proxy_details_t_handler_json
9066   (vl_api_dhcp_proxy_details_t * mp)
9067 {
9068   vat_main_t *vam = &vat_main;
9069   vat_json_node_t *node = NULL;
9070   u32 i, count = mp->count;
9071   struct in_addr ip4;
9072   struct in6_addr ip6;
9073   vl_api_dhcp_server_t *s;
9074
9075   if (VAT_JSON_ARRAY != vam->json_tree.type)
9076     {
9077       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9078       vat_json_init_array (&vam->json_tree);
9079     }
9080   node = vat_json_array_add (&vam->json_tree);
9081
9082   vat_json_init_object (node);
9083   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9084   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9085   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9086
9087   if (mp->is_ipv6)
9088     {
9089       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9090       vat_json_object_add_ip6 (node, "src_address", ip6);
9091     }
9092   else
9093     {
9094       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9095       vat_json_object_add_ip4 (node, "src_address", ip4);
9096     }
9097
9098   for (i = 0; i < count; i++)
9099     {
9100       s = &mp->servers[i];
9101
9102       vat_json_object_add_uint (node, "server-table-id",
9103                                 ntohl (s->server_vrf_id));
9104
9105       if (mp->is_ipv6)
9106         {
9107           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9108           vat_json_object_add_ip4 (node, "src_address", ip4);
9109         }
9110       else
9111         {
9112           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9113           vat_json_object_add_ip6 (node, "server_address", ip6);
9114         }
9115     }
9116 }
9117
9118 static int
9119 api_dhcp_proxy_dump (vat_main_t * vam)
9120 {
9121   unformat_input_t *i = vam->input;
9122   vl_api_control_ping_t *mp_ping;
9123   vl_api_dhcp_proxy_dump_t *mp;
9124   u8 is_ipv6 = 0;
9125   int ret;
9126
9127   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9128     {
9129       if (unformat (i, "ipv6"))
9130         is_ipv6 = 1;
9131       else
9132         {
9133           clib_warning ("parse error '%U'", format_unformat_error, i);
9134           return -99;
9135         }
9136     }
9137
9138   M (DHCP_PROXY_DUMP, mp);
9139
9140   mp->is_ip6 = is_ipv6;
9141   S (mp);
9142
9143   /* Use a control ping for synchronization */
9144   MPING (CONTROL_PING, mp_ping);
9145   S (mp_ping);
9146
9147   W (ret);
9148   return ret;
9149 }
9150
9151 static int
9152 api_dhcp_proxy_set_vss (vat_main_t * vam)
9153 {
9154   unformat_input_t *i = vam->input;
9155   vl_api_dhcp_proxy_set_vss_t *mp;
9156   u8 is_ipv6 = 0;
9157   u8 is_add = 1;
9158   u32 tbl_id;
9159   u8 tbl_id_set = 0;
9160   u32 oui;
9161   u8 oui_set = 0;
9162   u32 fib_id;
9163   u8 fib_id_set = 0;
9164   int ret;
9165
9166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9167     {
9168       if (unformat (i, "tbl_id %d", &tbl_id))
9169         tbl_id_set = 1;
9170       if (unformat (i, "fib_id %d", &fib_id))
9171         fib_id_set = 1;
9172       if (unformat (i, "oui %d", &oui))
9173         oui_set = 1;
9174       else if (unformat (i, "ipv6"))
9175         is_ipv6 = 1;
9176       else if (unformat (i, "del"))
9177         is_add = 0;
9178       else
9179         {
9180           clib_warning ("parse error '%U'", format_unformat_error, i);
9181           return -99;
9182         }
9183     }
9184
9185   if (tbl_id_set == 0)
9186     {
9187       errmsg ("missing tbl id");
9188       return -99;
9189     }
9190
9191   if (fib_id_set == 0)
9192     {
9193       errmsg ("missing fib id");
9194       return -99;
9195     }
9196   if (oui_set == 0)
9197     {
9198       errmsg ("missing oui");
9199       return -99;
9200     }
9201
9202   M (DHCP_PROXY_SET_VSS, mp);
9203   mp->tbl_id = ntohl (tbl_id);
9204   mp->fib_id = ntohl (fib_id);
9205   mp->oui = ntohl (oui);
9206   mp->is_ipv6 = is_ipv6;
9207   mp->is_add = is_add;
9208
9209   S (mp);
9210   W (ret);
9211   return ret;
9212 }
9213
9214 static int
9215 api_dhcp_client_config (vat_main_t * vam)
9216 {
9217   unformat_input_t *i = vam->input;
9218   vl_api_dhcp_client_config_t *mp;
9219   u32 sw_if_index;
9220   u8 sw_if_index_set = 0;
9221   u8 is_add = 1;
9222   u8 *hostname = 0;
9223   u8 disable_event = 0;
9224   int ret;
9225
9226   /* Parse args required to build the message */
9227   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9228     {
9229       if (unformat (i, "del"))
9230         is_add = 0;
9231       else
9232         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9233         sw_if_index_set = 1;
9234       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9235         sw_if_index_set = 1;
9236       else if (unformat (i, "hostname %s", &hostname))
9237         ;
9238       else if (unformat (i, "disable_event"))
9239         disable_event = 1;
9240       else
9241         break;
9242     }
9243
9244   if (sw_if_index_set == 0)
9245     {
9246       errmsg ("missing interface name or sw_if_index");
9247       return -99;
9248     }
9249
9250   if (vec_len (hostname) > 63)
9251     {
9252       errmsg ("hostname too long");
9253     }
9254   vec_add1 (hostname, 0);
9255
9256   /* Construct the API message */
9257   M (DHCP_CLIENT_CONFIG, mp);
9258
9259   mp->sw_if_index = htonl (sw_if_index);
9260   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
9261   vec_free (hostname);
9262   mp->is_add = is_add;
9263   mp->want_dhcp_event = disable_event ? 0 : 1;
9264   mp->pid = htonl (getpid ());
9265
9266   /* send it... */
9267   S (mp);
9268
9269   /* Wait for a reply, return good/bad news  */
9270   W (ret);
9271   return ret;
9272 }
9273
9274 static int
9275 api_set_ip_flow_hash (vat_main_t * vam)
9276 {
9277   unformat_input_t *i = vam->input;
9278   vl_api_set_ip_flow_hash_t *mp;
9279   u32 vrf_id = 0;
9280   u8 is_ipv6 = 0;
9281   u8 vrf_id_set = 0;
9282   u8 src = 0;
9283   u8 dst = 0;
9284   u8 sport = 0;
9285   u8 dport = 0;
9286   u8 proto = 0;
9287   u8 reverse = 0;
9288   int ret;
9289
9290   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9291     {
9292       if (unformat (i, "vrf %d", &vrf_id))
9293         vrf_id_set = 1;
9294       else if (unformat (i, "ipv6"))
9295         is_ipv6 = 1;
9296       else if (unformat (i, "src"))
9297         src = 1;
9298       else if (unformat (i, "dst"))
9299         dst = 1;
9300       else if (unformat (i, "sport"))
9301         sport = 1;
9302       else if (unformat (i, "dport"))
9303         dport = 1;
9304       else if (unformat (i, "proto"))
9305         proto = 1;
9306       else if (unformat (i, "reverse"))
9307         reverse = 1;
9308
9309       else
9310         {
9311           clib_warning ("parse error '%U'", format_unformat_error, i);
9312           return -99;
9313         }
9314     }
9315
9316   if (vrf_id_set == 0)
9317     {
9318       errmsg ("missing vrf id");
9319       return -99;
9320     }
9321
9322   M (SET_IP_FLOW_HASH, mp);
9323   mp->src = src;
9324   mp->dst = dst;
9325   mp->sport = sport;
9326   mp->dport = dport;
9327   mp->proto = proto;
9328   mp->reverse = reverse;
9329   mp->vrf_id = ntohl (vrf_id);
9330   mp->is_ipv6 = is_ipv6;
9331
9332   S (mp);
9333   W (ret);
9334   return ret;
9335 }
9336
9337 static int
9338 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9339 {
9340   unformat_input_t *i = vam->input;
9341   vl_api_sw_interface_ip6_enable_disable_t *mp;
9342   u32 sw_if_index;
9343   u8 sw_if_index_set = 0;
9344   u8 enable = 0;
9345   int ret;
9346
9347   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9348     {
9349       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9350         sw_if_index_set = 1;
9351       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9352         sw_if_index_set = 1;
9353       else if (unformat (i, "enable"))
9354         enable = 1;
9355       else if (unformat (i, "disable"))
9356         enable = 0;
9357       else
9358         {
9359           clib_warning ("parse error '%U'", format_unformat_error, i);
9360           return -99;
9361         }
9362     }
9363
9364   if (sw_if_index_set == 0)
9365     {
9366       errmsg ("missing interface name or sw_if_index");
9367       return -99;
9368     }
9369
9370   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9371
9372   mp->sw_if_index = ntohl (sw_if_index);
9373   mp->enable = enable;
9374
9375   S (mp);
9376   W (ret);
9377   return ret;
9378 }
9379
9380 static int
9381 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
9382 {
9383   unformat_input_t *i = vam->input;
9384   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
9385   u32 sw_if_index;
9386   u8 sw_if_index_set = 0;
9387   u8 v6_address_set = 0;
9388   ip6_address_t v6address;
9389   int ret;
9390
9391   /* Parse args required to build the message */
9392   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9393     {
9394       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9395         sw_if_index_set = 1;
9396       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9397         sw_if_index_set = 1;
9398       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9399         v6_address_set = 1;
9400       else
9401         break;
9402     }
9403
9404   if (sw_if_index_set == 0)
9405     {
9406       errmsg ("missing interface name or sw_if_index");
9407       return -99;
9408     }
9409   if (!v6_address_set)
9410     {
9411       errmsg ("no address set");
9412       return -99;
9413     }
9414
9415   /* Construct the API message */
9416   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
9417
9418   mp->sw_if_index = ntohl (sw_if_index);
9419   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9420
9421   /* send it... */
9422   S (mp);
9423
9424   /* Wait for a reply, return good/bad news  */
9425   W (ret);
9426   return ret;
9427 }
9428
9429 static int
9430 api_ip6nd_proxy_add_del (vat_main_t * vam)
9431 {
9432   unformat_input_t *i = vam->input;
9433   vl_api_ip6nd_proxy_add_del_t *mp;
9434   u32 sw_if_index = ~0;
9435   u8 v6_address_set = 0;
9436   ip6_address_t v6address;
9437   u8 is_del = 0;
9438   int ret;
9439
9440   /* Parse args required to build the message */
9441   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9442     {
9443       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9444         ;
9445       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9446         ;
9447       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9448         v6_address_set = 1;
9449       if (unformat (i, "del"))
9450         is_del = 1;
9451       else
9452         {
9453           clib_warning ("parse error '%U'", format_unformat_error, i);
9454           return -99;
9455         }
9456     }
9457
9458   if (sw_if_index == ~0)
9459     {
9460       errmsg ("missing interface name or sw_if_index");
9461       return -99;
9462     }
9463   if (!v6_address_set)
9464     {
9465       errmsg ("no address set");
9466       return -99;
9467     }
9468
9469   /* Construct the API message */
9470   M (IP6ND_PROXY_ADD_DEL, mp);
9471
9472   mp->is_del = is_del;
9473   mp->sw_if_index = ntohl (sw_if_index);
9474   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9475
9476   /* send it... */
9477   S (mp);
9478
9479   /* Wait for a reply, return good/bad news  */
9480   W (ret);
9481   return ret;
9482 }
9483
9484 static int
9485 api_ip6nd_proxy_dump (vat_main_t * vam)
9486 {
9487   vl_api_ip6nd_proxy_dump_t *mp;
9488   vl_api_control_ping_t *mp_ping;
9489   int ret;
9490
9491   M (IP6ND_PROXY_DUMP, mp);
9492
9493   S (mp);
9494
9495   /* Use a control ping for synchronization */
9496   MPING (CONTROL_PING, mp_ping);
9497   S (mp_ping);
9498
9499   W (ret);
9500   return ret;
9501 }
9502
9503 static void vl_api_ip6nd_proxy_details_t_handler
9504   (vl_api_ip6nd_proxy_details_t * mp)
9505 {
9506   vat_main_t *vam = &vat_main;
9507
9508   print (vam->ofp, "host %U sw_if_index %d",
9509          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
9510 }
9511
9512 static void vl_api_ip6nd_proxy_details_t_handler_json
9513   (vl_api_ip6nd_proxy_details_t * mp)
9514 {
9515   vat_main_t *vam = &vat_main;
9516   struct in6_addr ip6;
9517   vat_json_node_t *node = NULL;
9518
9519   if (VAT_JSON_ARRAY != vam->json_tree.type)
9520     {
9521       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9522       vat_json_init_array (&vam->json_tree);
9523     }
9524   node = vat_json_array_add (&vam->json_tree);
9525
9526   vat_json_init_object (node);
9527   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9528
9529   clib_memcpy (&ip6, mp->address, sizeof (ip6));
9530   vat_json_object_add_ip6 (node, "host", ip6);
9531 }
9532
9533 static int
9534 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9535 {
9536   unformat_input_t *i = vam->input;
9537   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9538   u32 sw_if_index;
9539   u8 sw_if_index_set = 0;
9540   u32 address_length = 0;
9541   u8 v6_address_set = 0;
9542   ip6_address_t v6address;
9543   u8 use_default = 0;
9544   u8 no_advertise = 0;
9545   u8 off_link = 0;
9546   u8 no_autoconfig = 0;
9547   u8 no_onlink = 0;
9548   u8 is_no = 0;
9549   u32 val_lifetime = 0;
9550   u32 pref_lifetime = 0;
9551   int ret;
9552
9553   /* Parse args required to build the message */
9554   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9555     {
9556       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9557         sw_if_index_set = 1;
9558       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9559         sw_if_index_set = 1;
9560       else if (unformat (i, "%U/%d",
9561                          unformat_ip6_address, &v6address, &address_length))
9562         v6_address_set = 1;
9563       else if (unformat (i, "val_life %d", &val_lifetime))
9564         ;
9565       else if (unformat (i, "pref_life %d", &pref_lifetime))
9566         ;
9567       else if (unformat (i, "def"))
9568         use_default = 1;
9569       else if (unformat (i, "noadv"))
9570         no_advertise = 1;
9571       else if (unformat (i, "offl"))
9572         off_link = 1;
9573       else if (unformat (i, "noauto"))
9574         no_autoconfig = 1;
9575       else if (unformat (i, "nolink"))
9576         no_onlink = 1;
9577       else if (unformat (i, "isno"))
9578         is_no = 1;
9579       else
9580         {
9581           clib_warning ("parse error '%U'", format_unformat_error, i);
9582           return -99;
9583         }
9584     }
9585
9586   if (sw_if_index_set == 0)
9587     {
9588       errmsg ("missing interface name or sw_if_index");
9589       return -99;
9590     }
9591   if (!v6_address_set)
9592     {
9593       errmsg ("no address set");
9594       return -99;
9595     }
9596
9597   /* Construct the API message */
9598   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9599
9600   mp->sw_if_index = ntohl (sw_if_index);
9601   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9602   mp->address_length = address_length;
9603   mp->use_default = use_default;
9604   mp->no_advertise = no_advertise;
9605   mp->off_link = off_link;
9606   mp->no_autoconfig = no_autoconfig;
9607   mp->no_onlink = no_onlink;
9608   mp->is_no = is_no;
9609   mp->val_lifetime = ntohl (val_lifetime);
9610   mp->pref_lifetime = ntohl (pref_lifetime);
9611
9612   /* send it... */
9613   S (mp);
9614
9615   /* Wait for a reply, return good/bad news  */
9616   W (ret);
9617   return ret;
9618 }
9619
9620 static int
9621 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9622 {
9623   unformat_input_t *i = vam->input;
9624   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9625   u32 sw_if_index;
9626   u8 sw_if_index_set = 0;
9627   u8 suppress = 0;
9628   u8 managed = 0;
9629   u8 other = 0;
9630   u8 ll_option = 0;
9631   u8 send_unicast = 0;
9632   u8 cease = 0;
9633   u8 is_no = 0;
9634   u8 default_router = 0;
9635   u32 max_interval = 0;
9636   u32 min_interval = 0;
9637   u32 lifetime = 0;
9638   u32 initial_count = 0;
9639   u32 initial_interval = 0;
9640   int ret;
9641
9642
9643   /* Parse args required to build the message */
9644   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9645     {
9646       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9647         sw_if_index_set = 1;
9648       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9649         sw_if_index_set = 1;
9650       else if (unformat (i, "maxint %d", &max_interval))
9651         ;
9652       else if (unformat (i, "minint %d", &min_interval))
9653         ;
9654       else if (unformat (i, "life %d", &lifetime))
9655         ;
9656       else if (unformat (i, "count %d", &initial_count))
9657         ;
9658       else if (unformat (i, "interval %d", &initial_interval))
9659         ;
9660       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9661         suppress = 1;
9662       else if (unformat (i, "managed"))
9663         managed = 1;
9664       else if (unformat (i, "other"))
9665         other = 1;
9666       else if (unformat (i, "ll"))
9667         ll_option = 1;
9668       else if (unformat (i, "send"))
9669         send_unicast = 1;
9670       else if (unformat (i, "cease"))
9671         cease = 1;
9672       else if (unformat (i, "isno"))
9673         is_no = 1;
9674       else if (unformat (i, "def"))
9675         default_router = 1;
9676       else
9677         {
9678           clib_warning ("parse error '%U'", format_unformat_error, i);
9679           return -99;
9680         }
9681     }
9682
9683   if (sw_if_index_set == 0)
9684     {
9685       errmsg ("missing interface name or sw_if_index");
9686       return -99;
9687     }
9688
9689   /* Construct the API message */
9690   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9691
9692   mp->sw_if_index = ntohl (sw_if_index);
9693   mp->max_interval = ntohl (max_interval);
9694   mp->min_interval = ntohl (min_interval);
9695   mp->lifetime = ntohl (lifetime);
9696   mp->initial_count = ntohl (initial_count);
9697   mp->initial_interval = ntohl (initial_interval);
9698   mp->suppress = suppress;
9699   mp->managed = managed;
9700   mp->other = other;
9701   mp->ll_option = ll_option;
9702   mp->send_unicast = send_unicast;
9703   mp->cease = cease;
9704   mp->is_no = is_no;
9705   mp->default_router = default_router;
9706
9707   /* send it... */
9708   S (mp);
9709
9710   /* Wait for a reply, return good/bad news  */
9711   W (ret);
9712   return ret;
9713 }
9714
9715 static int
9716 api_set_arp_neighbor_limit (vat_main_t * vam)
9717 {
9718   unformat_input_t *i = vam->input;
9719   vl_api_set_arp_neighbor_limit_t *mp;
9720   u32 arp_nbr_limit;
9721   u8 limit_set = 0;
9722   u8 is_ipv6 = 0;
9723   int ret;
9724
9725   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9726     {
9727       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
9728         limit_set = 1;
9729       else if (unformat (i, "ipv6"))
9730         is_ipv6 = 1;
9731       else
9732         {
9733           clib_warning ("parse error '%U'", format_unformat_error, i);
9734           return -99;
9735         }
9736     }
9737
9738   if (limit_set == 0)
9739     {
9740       errmsg ("missing limit value");
9741       return -99;
9742     }
9743
9744   M (SET_ARP_NEIGHBOR_LIMIT, mp);
9745
9746   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
9747   mp->is_ipv6 = is_ipv6;
9748
9749   S (mp);
9750   W (ret);
9751   return ret;
9752 }
9753
9754 static int
9755 api_l2_patch_add_del (vat_main_t * vam)
9756 {
9757   unformat_input_t *i = vam->input;
9758   vl_api_l2_patch_add_del_t *mp;
9759   u32 rx_sw_if_index;
9760   u8 rx_sw_if_index_set = 0;
9761   u32 tx_sw_if_index;
9762   u8 tx_sw_if_index_set = 0;
9763   u8 is_add = 1;
9764   int ret;
9765
9766   /* Parse args required to build the message */
9767   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9768     {
9769       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9770         rx_sw_if_index_set = 1;
9771       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9772         tx_sw_if_index_set = 1;
9773       else if (unformat (i, "rx"))
9774         {
9775           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9776             {
9777               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9778                             &rx_sw_if_index))
9779                 rx_sw_if_index_set = 1;
9780             }
9781           else
9782             break;
9783         }
9784       else if (unformat (i, "tx"))
9785         {
9786           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9787             {
9788               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9789                             &tx_sw_if_index))
9790                 tx_sw_if_index_set = 1;
9791             }
9792           else
9793             break;
9794         }
9795       else if (unformat (i, "del"))
9796         is_add = 0;
9797       else
9798         break;
9799     }
9800
9801   if (rx_sw_if_index_set == 0)
9802     {
9803       errmsg ("missing rx interface name or rx_sw_if_index");
9804       return -99;
9805     }
9806
9807   if (tx_sw_if_index_set == 0)
9808     {
9809       errmsg ("missing tx interface name or tx_sw_if_index");
9810       return -99;
9811     }
9812
9813   M (L2_PATCH_ADD_DEL, mp);
9814
9815   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9816   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9817   mp->is_add = is_add;
9818
9819   S (mp);
9820   W (ret);
9821   return ret;
9822 }
9823
9824 u8 is_del;
9825 u8 localsid_addr[16];
9826 u8 end_psp;
9827 u8 behavior;
9828 u32 sw_if_index;
9829 u32 vlan_index;
9830 u32 fib_table;
9831 u8 nh_addr[16];
9832
9833 static int
9834 api_sr_localsid_add_del (vat_main_t * vam)
9835 {
9836   unformat_input_t *i = vam->input;
9837   vl_api_sr_localsid_add_del_t *mp;
9838
9839   u8 is_del;
9840   ip6_address_t localsid;
9841   u8 end_psp = 0;
9842   u8 behavior = ~0;
9843   u32 sw_if_index;
9844   u32 fib_table = ~(u32) 0;
9845   ip6_address_t next_hop;
9846
9847   bool nexthop_set = 0;
9848
9849   int ret;
9850
9851   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9852     {
9853       if (unformat (i, "del"))
9854         is_del = 1;
9855       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9856       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
9857         nexthop_set = 1;
9858       else if (unformat (i, "behavior %u", &behavior));
9859       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9860       else if (unformat (i, "fib-table %u", &fib_table));
9861       else if (unformat (i, "end.psp %u", &behavior));
9862       else
9863         break;
9864     }
9865
9866   M (SR_LOCALSID_ADD_DEL, mp);
9867
9868   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
9869   if (nexthop_set)
9870     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
9871   mp->behavior = behavior;
9872   mp->sw_if_index = ntohl (sw_if_index);
9873   mp->fib_table = ntohl (fib_table);
9874   mp->end_psp = end_psp;
9875   mp->is_del = is_del;
9876
9877   S (mp);
9878   W (ret);
9879   return ret;
9880 }
9881
9882 static int
9883 api_ioam_enable (vat_main_t * vam)
9884 {
9885   unformat_input_t *input = vam->input;
9886   vl_api_ioam_enable_t *mp;
9887   u32 id = 0;
9888   int has_trace_option = 0;
9889   int has_pot_option = 0;
9890   int has_seqno_option = 0;
9891   int has_analyse_option = 0;
9892   int ret;
9893
9894   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9895     {
9896       if (unformat (input, "trace"))
9897         has_trace_option = 1;
9898       else if (unformat (input, "pot"))
9899         has_pot_option = 1;
9900       else if (unformat (input, "seqno"))
9901         has_seqno_option = 1;
9902       else if (unformat (input, "analyse"))
9903         has_analyse_option = 1;
9904       else
9905         break;
9906     }
9907   M (IOAM_ENABLE, mp);
9908   mp->id = htons (id);
9909   mp->seqno = has_seqno_option;
9910   mp->analyse = has_analyse_option;
9911   mp->pot_enable = has_pot_option;
9912   mp->trace_enable = has_trace_option;
9913
9914   S (mp);
9915   W (ret);
9916   return ret;
9917 }
9918
9919
9920 static int
9921 api_ioam_disable (vat_main_t * vam)
9922 {
9923   vl_api_ioam_disable_t *mp;
9924   int ret;
9925
9926   M (IOAM_DISABLE, mp);
9927   S (mp);
9928   W (ret);
9929   return ret;
9930 }
9931
9932 #define foreach_tcp_proto_field                 \
9933 _(src_port)                                     \
9934 _(dst_port)
9935
9936 #define foreach_udp_proto_field                 \
9937 _(src_port)                                     \
9938 _(dst_port)
9939
9940 #define foreach_ip4_proto_field                 \
9941 _(src_address)                                  \
9942 _(dst_address)                                  \
9943 _(tos)                                          \
9944 _(length)                                       \
9945 _(fragment_id)                                  \
9946 _(ttl)                                          \
9947 _(protocol)                                     \
9948 _(checksum)
9949
9950 typedef struct
9951 {
9952   u16 src_port, dst_port;
9953 } tcpudp_header_t;
9954
9955 #if VPP_API_TEST_BUILTIN == 0
9956 uword
9957 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9958 {
9959   u8 **maskp = va_arg (*args, u8 **);
9960   u8 *mask = 0;
9961   u8 found_something = 0;
9962   tcp_header_t *tcp;
9963
9964 #define _(a) u8 a=0;
9965   foreach_tcp_proto_field;
9966 #undef _
9967
9968   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9969     {
9970       if (0);
9971 #define _(a) else if (unformat (input, #a)) a=1;
9972       foreach_tcp_proto_field
9973 #undef _
9974         else
9975         break;
9976     }
9977
9978 #define _(a) found_something += a;
9979   foreach_tcp_proto_field;
9980 #undef _
9981
9982   if (found_something == 0)
9983     return 0;
9984
9985   vec_validate (mask, sizeof (*tcp) - 1);
9986
9987   tcp = (tcp_header_t *) mask;
9988
9989 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
9990   foreach_tcp_proto_field;
9991 #undef _
9992
9993   *maskp = mask;
9994   return 1;
9995 }
9996
9997 uword
9998 unformat_udp_mask (unformat_input_t * input, va_list * args)
9999 {
10000   u8 **maskp = va_arg (*args, u8 **);
10001   u8 *mask = 0;
10002   u8 found_something = 0;
10003   udp_header_t *udp;
10004
10005 #define _(a) u8 a=0;
10006   foreach_udp_proto_field;
10007 #undef _
10008
10009   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10010     {
10011       if (0);
10012 #define _(a) else if (unformat (input, #a)) a=1;
10013       foreach_udp_proto_field
10014 #undef _
10015         else
10016         break;
10017     }
10018
10019 #define _(a) found_something += a;
10020   foreach_udp_proto_field;
10021 #undef _
10022
10023   if (found_something == 0)
10024     return 0;
10025
10026   vec_validate (mask, sizeof (*udp) - 1);
10027
10028   udp = (udp_header_t *) mask;
10029
10030 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
10031   foreach_udp_proto_field;
10032 #undef _
10033
10034   *maskp = mask;
10035   return 1;
10036 }
10037
10038 uword
10039 unformat_l4_mask (unformat_input_t * input, va_list * args)
10040 {
10041   u8 **maskp = va_arg (*args, u8 **);
10042   u16 src_port = 0, dst_port = 0;
10043   tcpudp_header_t *tcpudp;
10044
10045   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10046     {
10047       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10048         return 1;
10049       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10050         return 1;
10051       else if (unformat (input, "src_port"))
10052         src_port = 0xFFFF;
10053       else if (unformat (input, "dst_port"))
10054         dst_port = 0xFFFF;
10055       else
10056         return 0;
10057     }
10058
10059   if (!src_port && !dst_port)
10060     return 0;
10061
10062   u8 *mask = 0;
10063   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10064
10065   tcpudp = (tcpudp_header_t *) mask;
10066   tcpudp->src_port = src_port;
10067   tcpudp->dst_port = dst_port;
10068
10069   *maskp = mask;
10070
10071   return 1;
10072 }
10073
10074 uword
10075 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10076 {
10077   u8 **maskp = va_arg (*args, u8 **);
10078   u8 *mask = 0;
10079   u8 found_something = 0;
10080   ip4_header_t *ip;
10081
10082 #define _(a) u8 a=0;
10083   foreach_ip4_proto_field;
10084 #undef _
10085   u8 version = 0;
10086   u8 hdr_length = 0;
10087
10088
10089   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10090     {
10091       if (unformat (input, "version"))
10092         version = 1;
10093       else if (unformat (input, "hdr_length"))
10094         hdr_length = 1;
10095       else if (unformat (input, "src"))
10096         src_address = 1;
10097       else if (unformat (input, "dst"))
10098         dst_address = 1;
10099       else if (unformat (input, "proto"))
10100         protocol = 1;
10101
10102 #define _(a) else if (unformat (input, #a)) a=1;
10103       foreach_ip4_proto_field
10104 #undef _
10105         else
10106         break;
10107     }
10108
10109 #define _(a) found_something += a;
10110   foreach_ip4_proto_field;
10111 #undef _
10112
10113   if (found_something == 0)
10114     return 0;
10115
10116   vec_validate (mask, sizeof (*ip) - 1);
10117
10118   ip = (ip4_header_t *) mask;
10119
10120 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10121   foreach_ip4_proto_field;
10122 #undef _
10123
10124   ip->ip_version_and_header_length = 0;
10125
10126   if (version)
10127     ip->ip_version_and_header_length |= 0xF0;
10128
10129   if (hdr_length)
10130     ip->ip_version_and_header_length |= 0x0F;
10131
10132   *maskp = mask;
10133   return 1;
10134 }
10135
10136 #define foreach_ip6_proto_field                 \
10137 _(src_address)                                  \
10138 _(dst_address)                                  \
10139 _(payload_length)                               \
10140 _(hop_limit)                                    \
10141 _(protocol)
10142
10143 uword
10144 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10145 {
10146   u8 **maskp = va_arg (*args, u8 **);
10147   u8 *mask = 0;
10148   u8 found_something = 0;
10149   ip6_header_t *ip;
10150   u32 ip_version_traffic_class_and_flow_label;
10151
10152 #define _(a) u8 a=0;
10153   foreach_ip6_proto_field;
10154 #undef _
10155   u8 version = 0;
10156   u8 traffic_class = 0;
10157   u8 flow_label = 0;
10158
10159   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10160     {
10161       if (unformat (input, "version"))
10162         version = 1;
10163       else if (unformat (input, "traffic-class"))
10164         traffic_class = 1;
10165       else if (unformat (input, "flow-label"))
10166         flow_label = 1;
10167       else if (unformat (input, "src"))
10168         src_address = 1;
10169       else if (unformat (input, "dst"))
10170         dst_address = 1;
10171       else if (unformat (input, "proto"))
10172         protocol = 1;
10173
10174 #define _(a) else if (unformat (input, #a)) a=1;
10175       foreach_ip6_proto_field
10176 #undef _
10177         else
10178         break;
10179     }
10180
10181 #define _(a) found_something += a;
10182   foreach_ip6_proto_field;
10183 #undef _
10184
10185   if (found_something == 0)
10186     return 0;
10187
10188   vec_validate (mask, sizeof (*ip) - 1);
10189
10190   ip = (ip6_header_t *) mask;
10191
10192 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10193   foreach_ip6_proto_field;
10194 #undef _
10195
10196   ip_version_traffic_class_and_flow_label = 0;
10197
10198   if (version)
10199     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10200
10201   if (traffic_class)
10202     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10203
10204   if (flow_label)
10205     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10206
10207   ip->ip_version_traffic_class_and_flow_label =
10208     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10209
10210   *maskp = mask;
10211   return 1;
10212 }
10213
10214 uword
10215 unformat_l3_mask (unformat_input_t * input, va_list * args)
10216 {
10217   u8 **maskp = va_arg (*args, u8 **);
10218
10219   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10220     {
10221       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10222         return 1;
10223       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10224         return 1;
10225       else
10226         break;
10227     }
10228   return 0;
10229 }
10230
10231 uword
10232 unformat_l2_mask (unformat_input_t * input, va_list * args)
10233 {
10234   u8 **maskp = va_arg (*args, u8 **);
10235   u8 *mask = 0;
10236   u8 src = 0;
10237   u8 dst = 0;
10238   u8 proto = 0;
10239   u8 tag1 = 0;
10240   u8 tag2 = 0;
10241   u8 ignore_tag1 = 0;
10242   u8 ignore_tag2 = 0;
10243   u8 cos1 = 0;
10244   u8 cos2 = 0;
10245   u8 dot1q = 0;
10246   u8 dot1ad = 0;
10247   int len = 14;
10248
10249   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10250     {
10251       if (unformat (input, "src"))
10252         src = 1;
10253       else if (unformat (input, "dst"))
10254         dst = 1;
10255       else if (unformat (input, "proto"))
10256         proto = 1;
10257       else if (unformat (input, "tag1"))
10258         tag1 = 1;
10259       else if (unformat (input, "tag2"))
10260         tag2 = 1;
10261       else if (unformat (input, "ignore-tag1"))
10262         ignore_tag1 = 1;
10263       else if (unformat (input, "ignore-tag2"))
10264         ignore_tag2 = 1;
10265       else if (unformat (input, "cos1"))
10266         cos1 = 1;
10267       else if (unformat (input, "cos2"))
10268         cos2 = 1;
10269       else if (unformat (input, "dot1q"))
10270         dot1q = 1;
10271       else if (unformat (input, "dot1ad"))
10272         dot1ad = 1;
10273       else
10274         break;
10275     }
10276   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10277        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10278     return 0;
10279
10280   if (tag1 || ignore_tag1 || cos1 || dot1q)
10281     len = 18;
10282   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10283     len = 22;
10284
10285   vec_validate (mask, len - 1);
10286
10287   if (dst)
10288     memset (mask, 0xff, 6);
10289
10290   if (src)
10291     memset (mask + 6, 0xff, 6);
10292
10293   if (tag2 || dot1ad)
10294     {
10295       /* inner vlan tag */
10296       if (tag2)
10297         {
10298           mask[19] = 0xff;
10299           mask[18] = 0x0f;
10300         }
10301       if (cos2)
10302         mask[18] |= 0xe0;
10303       if (proto)
10304         mask[21] = mask[20] = 0xff;
10305       if (tag1)
10306         {
10307           mask[15] = 0xff;
10308           mask[14] = 0x0f;
10309         }
10310       if (cos1)
10311         mask[14] |= 0xe0;
10312       *maskp = mask;
10313       return 1;
10314     }
10315   if (tag1 | dot1q)
10316     {
10317       if (tag1)
10318         {
10319           mask[15] = 0xff;
10320           mask[14] = 0x0f;
10321         }
10322       if (cos1)
10323         mask[14] |= 0xe0;
10324       if (proto)
10325         mask[16] = mask[17] = 0xff;
10326
10327       *maskp = mask;
10328       return 1;
10329     }
10330   if (cos2)
10331     mask[18] |= 0xe0;
10332   if (cos1)
10333     mask[14] |= 0xe0;
10334   if (proto)
10335     mask[12] = mask[13] = 0xff;
10336
10337   *maskp = mask;
10338   return 1;
10339 }
10340
10341 uword
10342 unformat_classify_mask (unformat_input_t * input, va_list * args)
10343 {
10344   u8 **maskp = va_arg (*args, u8 **);
10345   u32 *skipp = va_arg (*args, u32 *);
10346   u32 *matchp = va_arg (*args, u32 *);
10347   u32 match;
10348   u8 *mask = 0;
10349   u8 *l2 = 0;
10350   u8 *l3 = 0;
10351   u8 *l4 = 0;
10352   int i;
10353
10354   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10355     {
10356       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10357         ;
10358       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10359         ;
10360       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10361         ;
10362       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10363         ;
10364       else
10365         break;
10366     }
10367
10368   if (l4 && !l3)
10369     {
10370       vec_free (mask);
10371       vec_free (l2);
10372       vec_free (l4);
10373       return 0;
10374     }
10375
10376   if (mask || l2 || l3 || l4)
10377     {
10378       if (l2 || l3 || l4)
10379         {
10380           /* "With a free Ethernet header in every package" */
10381           if (l2 == 0)
10382             vec_validate (l2, 13);
10383           mask = l2;
10384           if (vec_len (l3))
10385             {
10386               vec_append (mask, l3);
10387               vec_free (l3);
10388             }
10389           if (vec_len (l4))
10390             {
10391               vec_append (mask, l4);
10392               vec_free (l4);
10393             }
10394         }
10395
10396       /* Scan forward looking for the first significant mask octet */
10397       for (i = 0; i < vec_len (mask); i++)
10398         if (mask[i])
10399           break;
10400
10401       /* compute (skip, match) params */
10402       *skipp = i / sizeof (u32x4);
10403       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10404
10405       /* Pad mask to an even multiple of the vector size */
10406       while (vec_len (mask) % sizeof (u32x4))
10407         vec_add1 (mask, 0);
10408
10409       match = vec_len (mask) / sizeof (u32x4);
10410
10411       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10412         {
10413           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10414           if (*tmp || *(tmp + 1))
10415             break;
10416           match--;
10417         }
10418       if (match == 0)
10419         clib_warning ("BUG: match 0");
10420
10421       _vec_len (mask) = match * sizeof (u32x4);
10422
10423       *matchp = match;
10424       *maskp = mask;
10425
10426       return 1;
10427     }
10428
10429   return 0;
10430 }
10431 #endif /* VPP_API_TEST_BUILTIN */
10432
10433 #define foreach_l2_next                         \
10434 _(drop, DROP)                                   \
10435 _(ethernet, ETHERNET_INPUT)                     \
10436 _(ip4, IP4_INPUT)                               \
10437 _(ip6, IP6_INPUT)
10438
10439 uword
10440 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10441 {
10442   u32 *miss_next_indexp = va_arg (*args, u32 *);
10443   u32 next_index = 0;
10444   u32 tmp;
10445
10446 #define _(n,N) \
10447   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10448   foreach_l2_next;
10449 #undef _
10450
10451   if (unformat (input, "%d", &tmp))
10452     {
10453       next_index = tmp;
10454       goto out;
10455     }
10456
10457   return 0;
10458
10459 out:
10460   *miss_next_indexp = next_index;
10461   return 1;
10462 }
10463
10464 #define foreach_ip_next                         \
10465 _(drop, DROP)                                   \
10466 _(local, LOCAL)                                 \
10467 _(rewrite, REWRITE)
10468
10469 uword
10470 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10471 {
10472   u32 *miss_next_indexp = va_arg (*args, u32 *);
10473   u32 next_index = 0;
10474   u32 tmp;
10475
10476 #define _(n,N) \
10477   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10478   foreach_ip_next;
10479 #undef _
10480
10481   if (unformat (input, "%d", &tmp))
10482     {
10483       next_index = tmp;
10484       goto out;
10485     }
10486
10487   return 0;
10488
10489 out:
10490   *miss_next_indexp = next_index;
10491   return 1;
10492 }
10493
10494 #define foreach_acl_next                        \
10495 _(deny, DENY)
10496
10497 uword
10498 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10499 {
10500   u32 *miss_next_indexp = va_arg (*args, u32 *);
10501   u32 next_index = 0;
10502   u32 tmp;
10503
10504 #define _(n,N) \
10505   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10506   foreach_acl_next;
10507 #undef _
10508
10509   if (unformat (input, "permit"))
10510     {
10511       next_index = ~0;
10512       goto out;
10513     }
10514   else if (unformat (input, "%d", &tmp))
10515     {
10516       next_index = tmp;
10517       goto out;
10518     }
10519
10520   return 0;
10521
10522 out:
10523   *miss_next_indexp = next_index;
10524   return 1;
10525 }
10526
10527 uword
10528 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10529 {
10530   u32 *r = va_arg (*args, u32 *);
10531
10532   if (unformat (input, "conform-color"))
10533     *r = POLICE_CONFORM;
10534   else if (unformat (input, "exceed-color"))
10535     *r = POLICE_EXCEED;
10536   else
10537     return 0;
10538
10539   return 1;
10540 }
10541
10542 static int
10543 api_classify_add_del_table (vat_main_t * vam)
10544 {
10545   unformat_input_t *i = vam->input;
10546   vl_api_classify_add_del_table_t *mp;
10547
10548   u32 nbuckets = 2;
10549   u32 skip = ~0;
10550   u32 match = ~0;
10551   int is_add = 1;
10552   int del_chain = 0;
10553   u32 table_index = ~0;
10554   u32 next_table_index = ~0;
10555   u32 miss_next_index = ~0;
10556   u32 memory_size = 32 << 20;
10557   u8 *mask = 0;
10558   u32 current_data_flag = 0;
10559   int current_data_offset = 0;
10560   int ret;
10561
10562   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10563     {
10564       if (unformat (i, "del"))
10565         is_add = 0;
10566       else if (unformat (i, "del-chain"))
10567         {
10568           is_add = 0;
10569           del_chain = 1;
10570         }
10571       else if (unformat (i, "buckets %d", &nbuckets))
10572         ;
10573       else if (unformat (i, "memory_size %d", &memory_size))
10574         ;
10575       else if (unformat (i, "skip %d", &skip))
10576         ;
10577       else if (unformat (i, "match %d", &match))
10578         ;
10579       else if (unformat (i, "table %d", &table_index))
10580         ;
10581       else if (unformat (i, "mask %U", unformat_classify_mask,
10582                          &mask, &skip, &match))
10583         ;
10584       else if (unformat (i, "next-table %d", &next_table_index))
10585         ;
10586       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10587                          &miss_next_index))
10588         ;
10589       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10590                          &miss_next_index))
10591         ;
10592       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10593                          &miss_next_index))
10594         ;
10595       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10596         ;
10597       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10598         ;
10599       else
10600         break;
10601     }
10602
10603   if (is_add && mask == 0)
10604     {
10605       errmsg ("Mask required");
10606       return -99;
10607     }
10608
10609   if (is_add && skip == ~0)
10610     {
10611       errmsg ("skip count required");
10612       return -99;
10613     }
10614
10615   if (is_add && match == ~0)
10616     {
10617       errmsg ("match count required");
10618       return -99;
10619     }
10620
10621   if (!is_add && table_index == ~0)
10622     {
10623       errmsg ("table index required for delete");
10624       return -99;
10625     }
10626
10627   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10628
10629   mp->is_add = is_add;
10630   mp->del_chain = del_chain;
10631   mp->table_index = ntohl (table_index);
10632   mp->nbuckets = ntohl (nbuckets);
10633   mp->memory_size = ntohl (memory_size);
10634   mp->skip_n_vectors = ntohl (skip);
10635   mp->match_n_vectors = ntohl (match);
10636   mp->next_table_index = ntohl (next_table_index);
10637   mp->miss_next_index = ntohl (miss_next_index);
10638   mp->current_data_flag = ntohl (current_data_flag);
10639   mp->current_data_offset = ntohl (current_data_offset);
10640   clib_memcpy (mp->mask, mask, vec_len (mask));
10641
10642   vec_free (mask);
10643
10644   S (mp);
10645   W (ret);
10646   return ret;
10647 }
10648
10649 #if VPP_API_TEST_BUILTIN == 0
10650 uword
10651 unformat_l4_match (unformat_input_t * input, va_list * args)
10652 {
10653   u8 **matchp = va_arg (*args, u8 **);
10654
10655   u8 *proto_header = 0;
10656   int src_port = 0;
10657   int dst_port = 0;
10658
10659   tcpudp_header_t h;
10660
10661   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10662     {
10663       if (unformat (input, "src_port %d", &src_port))
10664         ;
10665       else if (unformat (input, "dst_port %d", &dst_port))
10666         ;
10667       else
10668         return 0;
10669     }
10670
10671   h.src_port = clib_host_to_net_u16 (src_port);
10672   h.dst_port = clib_host_to_net_u16 (dst_port);
10673   vec_validate (proto_header, sizeof (h) - 1);
10674   memcpy (proto_header, &h, sizeof (h));
10675
10676   *matchp = proto_header;
10677
10678   return 1;
10679 }
10680
10681 uword
10682 unformat_ip4_match (unformat_input_t * input, va_list * args)
10683 {
10684   u8 **matchp = va_arg (*args, u8 **);
10685   u8 *match = 0;
10686   ip4_header_t *ip;
10687   int version = 0;
10688   u32 version_val;
10689   int hdr_length = 0;
10690   u32 hdr_length_val;
10691   int src = 0, dst = 0;
10692   ip4_address_t src_val, dst_val;
10693   int proto = 0;
10694   u32 proto_val;
10695   int tos = 0;
10696   u32 tos_val;
10697   int length = 0;
10698   u32 length_val;
10699   int fragment_id = 0;
10700   u32 fragment_id_val;
10701   int ttl = 0;
10702   int ttl_val;
10703   int checksum = 0;
10704   u32 checksum_val;
10705
10706   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10707     {
10708       if (unformat (input, "version %d", &version_val))
10709         version = 1;
10710       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10711         hdr_length = 1;
10712       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10713         src = 1;
10714       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10715         dst = 1;
10716       else if (unformat (input, "proto %d", &proto_val))
10717         proto = 1;
10718       else if (unformat (input, "tos %d", &tos_val))
10719         tos = 1;
10720       else if (unformat (input, "length %d", &length_val))
10721         length = 1;
10722       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10723         fragment_id = 1;
10724       else if (unformat (input, "ttl %d", &ttl_val))
10725         ttl = 1;
10726       else if (unformat (input, "checksum %d", &checksum_val))
10727         checksum = 1;
10728       else
10729         break;
10730     }
10731
10732   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10733       + ttl + checksum == 0)
10734     return 0;
10735
10736   /*
10737    * Aligned because we use the real comparison functions
10738    */
10739   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10740
10741   ip = (ip4_header_t *) match;
10742
10743   /* These are realistically matched in practice */
10744   if (src)
10745     ip->src_address.as_u32 = src_val.as_u32;
10746
10747   if (dst)
10748     ip->dst_address.as_u32 = dst_val.as_u32;
10749
10750   if (proto)
10751     ip->protocol = proto_val;
10752
10753
10754   /* These are not, but they're included for completeness */
10755   if (version)
10756     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10757
10758   if (hdr_length)
10759     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10760
10761   if (tos)
10762     ip->tos = tos_val;
10763
10764   if (length)
10765     ip->length = clib_host_to_net_u16 (length_val);
10766
10767   if (ttl)
10768     ip->ttl = ttl_val;
10769
10770   if (checksum)
10771     ip->checksum = clib_host_to_net_u16 (checksum_val);
10772
10773   *matchp = match;
10774   return 1;
10775 }
10776
10777 uword
10778 unformat_ip6_match (unformat_input_t * input, va_list * args)
10779 {
10780   u8 **matchp = va_arg (*args, u8 **);
10781   u8 *match = 0;
10782   ip6_header_t *ip;
10783   int version = 0;
10784   u32 version_val;
10785   u8 traffic_class = 0;
10786   u32 traffic_class_val = 0;
10787   u8 flow_label = 0;
10788   u8 flow_label_val;
10789   int src = 0, dst = 0;
10790   ip6_address_t src_val, dst_val;
10791   int proto = 0;
10792   u32 proto_val;
10793   int payload_length = 0;
10794   u32 payload_length_val;
10795   int hop_limit = 0;
10796   int hop_limit_val;
10797   u32 ip_version_traffic_class_and_flow_label;
10798
10799   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10800     {
10801       if (unformat (input, "version %d", &version_val))
10802         version = 1;
10803       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10804         traffic_class = 1;
10805       else if (unformat (input, "flow_label %d", &flow_label_val))
10806         flow_label = 1;
10807       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10808         src = 1;
10809       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10810         dst = 1;
10811       else if (unformat (input, "proto %d", &proto_val))
10812         proto = 1;
10813       else if (unformat (input, "payload_length %d", &payload_length_val))
10814         payload_length = 1;
10815       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10816         hop_limit = 1;
10817       else
10818         break;
10819     }
10820
10821   if (version + traffic_class + flow_label + src + dst + proto +
10822       payload_length + hop_limit == 0)
10823     return 0;
10824
10825   /*
10826    * Aligned because we use the real comparison functions
10827    */
10828   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10829
10830   ip = (ip6_header_t *) match;
10831
10832   if (src)
10833     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10834
10835   if (dst)
10836     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10837
10838   if (proto)
10839     ip->protocol = proto_val;
10840
10841   ip_version_traffic_class_and_flow_label = 0;
10842
10843   if (version)
10844     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10845
10846   if (traffic_class)
10847     ip_version_traffic_class_and_flow_label |=
10848       (traffic_class_val & 0xFF) << 20;
10849
10850   if (flow_label)
10851     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10852
10853   ip->ip_version_traffic_class_and_flow_label =
10854     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10855
10856   if (payload_length)
10857     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10858
10859   if (hop_limit)
10860     ip->hop_limit = hop_limit_val;
10861
10862   *matchp = match;
10863   return 1;
10864 }
10865
10866 uword
10867 unformat_l3_match (unformat_input_t * input, va_list * args)
10868 {
10869   u8 **matchp = va_arg (*args, u8 **);
10870
10871   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10872     {
10873       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10874         return 1;
10875       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10876         return 1;
10877       else
10878         break;
10879     }
10880   return 0;
10881 }
10882
10883 uword
10884 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10885 {
10886   u8 *tagp = va_arg (*args, u8 *);
10887   u32 tag;
10888
10889   if (unformat (input, "%d", &tag))
10890     {
10891       tagp[0] = (tag >> 8) & 0x0F;
10892       tagp[1] = tag & 0xFF;
10893       return 1;
10894     }
10895
10896   return 0;
10897 }
10898
10899 uword
10900 unformat_l2_match (unformat_input_t * input, va_list * args)
10901 {
10902   u8 **matchp = va_arg (*args, u8 **);
10903   u8 *match = 0;
10904   u8 src = 0;
10905   u8 src_val[6];
10906   u8 dst = 0;
10907   u8 dst_val[6];
10908   u8 proto = 0;
10909   u16 proto_val;
10910   u8 tag1 = 0;
10911   u8 tag1_val[2];
10912   u8 tag2 = 0;
10913   u8 tag2_val[2];
10914   int len = 14;
10915   u8 ignore_tag1 = 0;
10916   u8 ignore_tag2 = 0;
10917   u8 cos1 = 0;
10918   u8 cos2 = 0;
10919   u32 cos1_val = 0;
10920   u32 cos2_val = 0;
10921
10922   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10923     {
10924       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10925         src = 1;
10926       else
10927         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10928         dst = 1;
10929       else if (unformat (input, "proto %U",
10930                          unformat_ethernet_type_host_byte_order, &proto_val))
10931         proto = 1;
10932       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10933         tag1 = 1;
10934       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10935         tag2 = 1;
10936       else if (unformat (input, "ignore-tag1"))
10937         ignore_tag1 = 1;
10938       else if (unformat (input, "ignore-tag2"))
10939         ignore_tag2 = 1;
10940       else if (unformat (input, "cos1 %d", &cos1_val))
10941         cos1 = 1;
10942       else if (unformat (input, "cos2 %d", &cos2_val))
10943         cos2 = 1;
10944       else
10945         break;
10946     }
10947   if ((src + dst + proto + tag1 + tag2 +
10948        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10949     return 0;
10950
10951   if (tag1 || ignore_tag1 || cos1)
10952     len = 18;
10953   if (tag2 || ignore_tag2 || cos2)
10954     len = 22;
10955
10956   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10957
10958   if (dst)
10959     clib_memcpy (match, dst_val, 6);
10960
10961   if (src)
10962     clib_memcpy (match + 6, src_val, 6);
10963
10964   if (tag2)
10965     {
10966       /* inner vlan tag */
10967       match[19] = tag2_val[1];
10968       match[18] = tag2_val[0];
10969       if (cos2)
10970         match[18] |= (cos2_val & 0x7) << 5;
10971       if (proto)
10972         {
10973           match[21] = proto_val & 0xff;
10974           match[20] = proto_val >> 8;
10975         }
10976       if (tag1)
10977         {
10978           match[15] = tag1_val[1];
10979           match[14] = tag1_val[0];
10980         }
10981       if (cos1)
10982         match[14] |= (cos1_val & 0x7) << 5;
10983       *matchp = match;
10984       return 1;
10985     }
10986   if (tag1)
10987     {
10988       match[15] = tag1_val[1];
10989       match[14] = tag1_val[0];
10990       if (proto)
10991         {
10992           match[17] = proto_val & 0xff;
10993           match[16] = proto_val >> 8;
10994         }
10995       if (cos1)
10996         match[14] |= (cos1_val & 0x7) << 5;
10997
10998       *matchp = match;
10999       return 1;
11000     }
11001   if (cos2)
11002     match[18] |= (cos2_val & 0x7) << 5;
11003   if (cos1)
11004     match[14] |= (cos1_val & 0x7) << 5;
11005   if (proto)
11006     {
11007       match[13] = proto_val & 0xff;
11008       match[12] = proto_val >> 8;
11009     }
11010
11011   *matchp = match;
11012   return 1;
11013 }
11014 #endif
11015
11016 uword
11017 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11018 {
11019   u8 **matchp = va_arg (*args, u8 **);
11020   u32 skip_n_vectors = va_arg (*args, u32);
11021   u32 match_n_vectors = va_arg (*args, u32);
11022
11023   u8 *match = 0;
11024   u8 *l2 = 0;
11025   u8 *l3 = 0;
11026   u8 *l4 = 0;
11027
11028   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11029     {
11030       if (unformat (input, "hex %U", unformat_hex_string, &match))
11031         ;
11032       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11033         ;
11034       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11035         ;
11036       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11037         ;
11038       else
11039         break;
11040     }
11041
11042   if (l4 && !l3)
11043     {
11044       vec_free (match);
11045       vec_free (l2);
11046       vec_free (l4);
11047       return 0;
11048     }
11049
11050   if (match || l2 || l3 || l4)
11051     {
11052       if (l2 || l3 || l4)
11053         {
11054           /* "Win a free Ethernet header in every packet" */
11055           if (l2 == 0)
11056             vec_validate_aligned (l2, 13, sizeof (u32x4));
11057           match = l2;
11058           if (vec_len (l3))
11059             {
11060               vec_append_aligned (match, l3, sizeof (u32x4));
11061               vec_free (l3);
11062             }
11063           if (vec_len (l4))
11064             {
11065               vec_append_aligned (match, l4, sizeof (u32x4));
11066               vec_free (l4);
11067             }
11068         }
11069
11070       /* Make sure the vector is big enough even if key is all 0's */
11071       vec_validate_aligned
11072         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11073          sizeof (u32x4));
11074
11075       /* Set size, include skipped vectors */
11076       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11077
11078       *matchp = match;
11079
11080       return 1;
11081     }
11082
11083   return 0;
11084 }
11085
11086 static int
11087 api_classify_add_del_session (vat_main_t * vam)
11088 {
11089   unformat_input_t *i = vam->input;
11090   vl_api_classify_add_del_session_t *mp;
11091   int is_add = 1;
11092   u32 table_index = ~0;
11093   u32 hit_next_index = ~0;
11094   u32 opaque_index = ~0;
11095   u8 *match = 0;
11096   i32 advance = 0;
11097   u32 skip_n_vectors = 0;
11098   u32 match_n_vectors = 0;
11099   u32 action = 0;
11100   u32 metadata = 0;
11101   int ret;
11102
11103   /*
11104    * Warning: you have to supply skip_n and match_n
11105    * because the API client cant simply look at the classify
11106    * table object.
11107    */
11108
11109   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11110     {
11111       if (unformat (i, "del"))
11112         is_add = 0;
11113       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11114                          &hit_next_index))
11115         ;
11116       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11117                          &hit_next_index))
11118         ;
11119       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11120                          &hit_next_index))
11121         ;
11122       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11123         ;
11124       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11125         ;
11126       else if (unformat (i, "opaque-index %d", &opaque_index))
11127         ;
11128       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11129         ;
11130       else if (unformat (i, "match_n %d", &match_n_vectors))
11131         ;
11132       else if (unformat (i, "match %U", api_unformat_classify_match,
11133                          &match, skip_n_vectors, match_n_vectors))
11134         ;
11135       else if (unformat (i, "advance %d", &advance))
11136         ;
11137       else if (unformat (i, "table-index %d", &table_index))
11138         ;
11139       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11140         action = 1;
11141       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11142         action = 2;
11143       else if (unformat (i, "action %d", &action))
11144         ;
11145       else if (unformat (i, "metadata %d", &metadata))
11146         ;
11147       else
11148         break;
11149     }
11150
11151   if (table_index == ~0)
11152     {
11153       errmsg ("Table index required");
11154       return -99;
11155     }
11156
11157   if (is_add && match == 0)
11158     {
11159       errmsg ("Match value required");
11160       return -99;
11161     }
11162
11163   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11164
11165   mp->is_add = is_add;
11166   mp->table_index = ntohl (table_index);
11167   mp->hit_next_index = ntohl (hit_next_index);
11168   mp->opaque_index = ntohl (opaque_index);
11169   mp->advance = ntohl (advance);
11170   mp->action = action;
11171   mp->metadata = ntohl (metadata);
11172   clib_memcpy (mp->match, match, vec_len (match));
11173   vec_free (match);
11174
11175   S (mp);
11176   W (ret);
11177   return ret;
11178 }
11179
11180 static int
11181 api_classify_set_interface_ip_table (vat_main_t * vam)
11182 {
11183   unformat_input_t *i = vam->input;
11184   vl_api_classify_set_interface_ip_table_t *mp;
11185   u32 sw_if_index;
11186   int sw_if_index_set;
11187   u32 table_index = ~0;
11188   u8 is_ipv6 = 0;
11189   int ret;
11190
11191   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11192     {
11193       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11194         sw_if_index_set = 1;
11195       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11196         sw_if_index_set = 1;
11197       else if (unformat (i, "table %d", &table_index))
11198         ;
11199       else
11200         {
11201           clib_warning ("parse error '%U'", format_unformat_error, i);
11202           return -99;
11203         }
11204     }
11205
11206   if (sw_if_index_set == 0)
11207     {
11208       errmsg ("missing interface name or sw_if_index");
11209       return -99;
11210     }
11211
11212
11213   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11214
11215   mp->sw_if_index = ntohl (sw_if_index);
11216   mp->table_index = ntohl (table_index);
11217   mp->is_ipv6 = is_ipv6;
11218
11219   S (mp);
11220   W (ret);
11221   return ret;
11222 }
11223
11224 static int
11225 api_classify_set_interface_l2_tables (vat_main_t * vam)
11226 {
11227   unformat_input_t *i = vam->input;
11228   vl_api_classify_set_interface_l2_tables_t *mp;
11229   u32 sw_if_index;
11230   int sw_if_index_set;
11231   u32 ip4_table_index = ~0;
11232   u32 ip6_table_index = ~0;
11233   u32 other_table_index = ~0;
11234   u32 is_input = 1;
11235   int ret;
11236
11237   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11238     {
11239       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11240         sw_if_index_set = 1;
11241       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11242         sw_if_index_set = 1;
11243       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11244         ;
11245       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11246         ;
11247       else if (unformat (i, "other-table %d", &other_table_index))
11248         ;
11249       else if (unformat (i, "is-input %d", &is_input))
11250         ;
11251       else
11252         {
11253           clib_warning ("parse error '%U'", format_unformat_error, i);
11254           return -99;
11255         }
11256     }
11257
11258   if (sw_if_index_set == 0)
11259     {
11260       errmsg ("missing interface name or sw_if_index");
11261       return -99;
11262     }
11263
11264
11265   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11266
11267   mp->sw_if_index = ntohl (sw_if_index);
11268   mp->ip4_table_index = ntohl (ip4_table_index);
11269   mp->ip6_table_index = ntohl (ip6_table_index);
11270   mp->other_table_index = ntohl (other_table_index);
11271   mp->is_input = (u8) is_input;
11272
11273   S (mp);
11274   W (ret);
11275   return ret;
11276 }
11277
11278 static int
11279 api_set_ipfix_exporter (vat_main_t * vam)
11280 {
11281   unformat_input_t *i = vam->input;
11282   vl_api_set_ipfix_exporter_t *mp;
11283   ip4_address_t collector_address;
11284   u8 collector_address_set = 0;
11285   u32 collector_port = ~0;
11286   ip4_address_t src_address;
11287   u8 src_address_set = 0;
11288   u32 vrf_id = ~0;
11289   u32 path_mtu = ~0;
11290   u32 template_interval = ~0;
11291   u8 udp_checksum = 0;
11292   int ret;
11293
11294   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11295     {
11296       if (unformat (i, "collector_address %U", unformat_ip4_address,
11297                     &collector_address))
11298         collector_address_set = 1;
11299       else if (unformat (i, "collector_port %d", &collector_port))
11300         ;
11301       else if (unformat (i, "src_address %U", unformat_ip4_address,
11302                          &src_address))
11303         src_address_set = 1;
11304       else if (unformat (i, "vrf_id %d", &vrf_id))
11305         ;
11306       else if (unformat (i, "path_mtu %d", &path_mtu))
11307         ;
11308       else if (unformat (i, "template_interval %d", &template_interval))
11309         ;
11310       else if (unformat (i, "udp_checksum"))
11311         udp_checksum = 1;
11312       else
11313         break;
11314     }
11315
11316   if (collector_address_set == 0)
11317     {
11318       errmsg ("collector_address required");
11319       return -99;
11320     }
11321
11322   if (src_address_set == 0)
11323     {
11324       errmsg ("src_address required");
11325       return -99;
11326     }
11327
11328   M (SET_IPFIX_EXPORTER, mp);
11329
11330   memcpy (mp->collector_address, collector_address.data,
11331           sizeof (collector_address.data));
11332   mp->collector_port = htons ((u16) collector_port);
11333   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11334   mp->vrf_id = htonl (vrf_id);
11335   mp->path_mtu = htonl (path_mtu);
11336   mp->template_interval = htonl (template_interval);
11337   mp->udp_checksum = udp_checksum;
11338
11339   S (mp);
11340   W (ret);
11341   return ret;
11342 }
11343
11344 static int
11345 api_set_ipfix_classify_stream (vat_main_t * vam)
11346 {
11347   unformat_input_t *i = vam->input;
11348   vl_api_set_ipfix_classify_stream_t *mp;
11349   u32 domain_id = 0;
11350   u32 src_port = UDP_DST_PORT_ipfix;
11351   int ret;
11352
11353   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11354     {
11355       if (unformat (i, "domain %d", &domain_id))
11356         ;
11357       else if (unformat (i, "src_port %d", &src_port))
11358         ;
11359       else
11360         {
11361           errmsg ("unknown input `%U'", format_unformat_error, i);
11362           return -99;
11363         }
11364     }
11365
11366   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11367
11368   mp->domain_id = htonl (domain_id);
11369   mp->src_port = htons ((u16) src_port);
11370
11371   S (mp);
11372   W (ret);
11373   return ret;
11374 }
11375
11376 static int
11377 api_ipfix_classify_table_add_del (vat_main_t * vam)
11378 {
11379   unformat_input_t *i = vam->input;
11380   vl_api_ipfix_classify_table_add_del_t *mp;
11381   int is_add = -1;
11382   u32 classify_table_index = ~0;
11383   u8 ip_version = 0;
11384   u8 transport_protocol = 255;
11385   int ret;
11386
11387   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11388     {
11389       if (unformat (i, "add"))
11390         is_add = 1;
11391       else if (unformat (i, "del"))
11392         is_add = 0;
11393       else if (unformat (i, "table %d", &classify_table_index))
11394         ;
11395       else if (unformat (i, "ip4"))
11396         ip_version = 4;
11397       else if (unformat (i, "ip6"))
11398         ip_version = 6;
11399       else if (unformat (i, "tcp"))
11400         transport_protocol = 6;
11401       else if (unformat (i, "udp"))
11402         transport_protocol = 17;
11403       else
11404         {
11405           errmsg ("unknown input `%U'", format_unformat_error, i);
11406           return -99;
11407         }
11408     }
11409
11410   if (is_add == -1)
11411     {
11412       errmsg ("expecting: add|del");
11413       return -99;
11414     }
11415   if (classify_table_index == ~0)
11416     {
11417       errmsg ("classifier table not specified");
11418       return -99;
11419     }
11420   if (ip_version == 0)
11421     {
11422       errmsg ("IP version not specified");
11423       return -99;
11424     }
11425
11426   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11427
11428   mp->is_add = is_add;
11429   mp->table_id = htonl (classify_table_index);
11430   mp->ip_version = ip_version;
11431   mp->transport_protocol = transport_protocol;
11432
11433   S (mp);
11434   W (ret);
11435   return ret;
11436 }
11437
11438 static int
11439 api_get_node_index (vat_main_t * vam)
11440 {
11441   unformat_input_t *i = vam->input;
11442   vl_api_get_node_index_t *mp;
11443   u8 *name = 0;
11444   int ret;
11445
11446   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11447     {
11448       if (unformat (i, "node %s", &name))
11449         ;
11450       else
11451         break;
11452     }
11453   if (name == 0)
11454     {
11455       errmsg ("node name required");
11456       return -99;
11457     }
11458   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11459     {
11460       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11461       return -99;
11462     }
11463
11464   M (GET_NODE_INDEX, mp);
11465   clib_memcpy (mp->node_name, name, vec_len (name));
11466   vec_free (name);
11467
11468   S (mp);
11469   W (ret);
11470   return ret;
11471 }
11472
11473 static int
11474 api_get_next_index (vat_main_t * vam)
11475 {
11476   unformat_input_t *i = vam->input;
11477   vl_api_get_next_index_t *mp;
11478   u8 *node_name = 0, *next_node_name = 0;
11479   int ret;
11480
11481   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11482     {
11483       if (unformat (i, "node-name %s", &node_name))
11484         ;
11485       else if (unformat (i, "next-node-name %s", &next_node_name))
11486         break;
11487     }
11488
11489   if (node_name == 0)
11490     {
11491       errmsg ("node name required");
11492       return -99;
11493     }
11494   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11495     {
11496       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11497       return -99;
11498     }
11499
11500   if (next_node_name == 0)
11501     {
11502       errmsg ("next node name required");
11503       return -99;
11504     }
11505   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11506     {
11507       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11508       return -99;
11509     }
11510
11511   M (GET_NEXT_INDEX, mp);
11512   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11513   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11514   vec_free (node_name);
11515   vec_free (next_node_name);
11516
11517   S (mp);
11518   W (ret);
11519   return ret;
11520 }
11521
11522 static int
11523 api_add_node_next (vat_main_t * vam)
11524 {
11525   unformat_input_t *i = vam->input;
11526   vl_api_add_node_next_t *mp;
11527   u8 *name = 0;
11528   u8 *next = 0;
11529   int ret;
11530
11531   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11532     {
11533       if (unformat (i, "node %s", &name))
11534         ;
11535       else if (unformat (i, "next %s", &next))
11536         ;
11537       else
11538         break;
11539     }
11540   if (name == 0)
11541     {
11542       errmsg ("node name required");
11543       return -99;
11544     }
11545   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11546     {
11547       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11548       return -99;
11549     }
11550   if (next == 0)
11551     {
11552       errmsg ("next node required");
11553       return -99;
11554     }
11555   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11556     {
11557       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11558       return -99;
11559     }
11560
11561   M (ADD_NODE_NEXT, mp);
11562   clib_memcpy (mp->node_name, name, vec_len (name));
11563   clib_memcpy (mp->next_name, next, vec_len (next));
11564   vec_free (name);
11565   vec_free (next);
11566
11567   S (mp);
11568   W (ret);
11569   return ret;
11570 }
11571
11572 static int
11573 api_l2tpv3_create_tunnel (vat_main_t * vam)
11574 {
11575   unformat_input_t *i = vam->input;
11576   ip6_address_t client_address, our_address;
11577   int client_address_set = 0;
11578   int our_address_set = 0;
11579   u32 local_session_id = 0;
11580   u32 remote_session_id = 0;
11581   u64 local_cookie = 0;
11582   u64 remote_cookie = 0;
11583   u8 l2_sublayer_present = 0;
11584   vl_api_l2tpv3_create_tunnel_t *mp;
11585   int ret;
11586
11587   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11588     {
11589       if (unformat (i, "client_address %U", unformat_ip6_address,
11590                     &client_address))
11591         client_address_set = 1;
11592       else if (unformat (i, "our_address %U", unformat_ip6_address,
11593                          &our_address))
11594         our_address_set = 1;
11595       else if (unformat (i, "local_session_id %d", &local_session_id))
11596         ;
11597       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11598         ;
11599       else if (unformat (i, "local_cookie %lld", &local_cookie))
11600         ;
11601       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11602         ;
11603       else if (unformat (i, "l2-sublayer-present"))
11604         l2_sublayer_present = 1;
11605       else
11606         break;
11607     }
11608
11609   if (client_address_set == 0)
11610     {
11611       errmsg ("client_address required");
11612       return -99;
11613     }
11614
11615   if (our_address_set == 0)
11616     {
11617       errmsg ("our_address required");
11618       return -99;
11619     }
11620
11621   M (L2TPV3_CREATE_TUNNEL, mp);
11622
11623   clib_memcpy (mp->client_address, client_address.as_u8,
11624                sizeof (mp->client_address));
11625
11626   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11627
11628   mp->local_session_id = ntohl (local_session_id);
11629   mp->remote_session_id = ntohl (remote_session_id);
11630   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11631   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11632   mp->l2_sublayer_present = l2_sublayer_present;
11633   mp->is_ipv6 = 1;
11634
11635   S (mp);
11636   W (ret);
11637   return ret;
11638 }
11639
11640 static int
11641 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11642 {
11643   unformat_input_t *i = vam->input;
11644   u32 sw_if_index;
11645   u8 sw_if_index_set = 0;
11646   u64 new_local_cookie = 0;
11647   u64 new_remote_cookie = 0;
11648   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11649   int ret;
11650
11651   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11652     {
11653       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11654         sw_if_index_set = 1;
11655       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11656         sw_if_index_set = 1;
11657       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11658         ;
11659       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11660         ;
11661       else
11662         break;
11663     }
11664
11665   if (sw_if_index_set == 0)
11666     {
11667       errmsg ("missing interface name or sw_if_index");
11668       return -99;
11669     }
11670
11671   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11672
11673   mp->sw_if_index = ntohl (sw_if_index);
11674   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11675   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11676
11677   S (mp);
11678   W (ret);
11679   return ret;
11680 }
11681
11682 static int
11683 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11684 {
11685   unformat_input_t *i = vam->input;
11686   vl_api_l2tpv3_interface_enable_disable_t *mp;
11687   u32 sw_if_index;
11688   u8 sw_if_index_set = 0;
11689   u8 enable_disable = 1;
11690   int ret;
11691
11692   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11693     {
11694       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11695         sw_if_index_set = 1;
11696       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11697         sw_if_index_set = 1;
11698       else if (unformat (i, "enable"))
11699         enable_disable = 1;
11700       else if (unformat (i, "disable"))
11701         enable_disable = 0;
11702       else
11703         break;
11704     }
11705
11706   if (sw_if_index_set == 0)
11707     {
11708       errmsg ("missing interface name or sw_if_index");
11709       return -99;
11710     }
11711
11712   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11713
11714   mp->sw_if_index = ntohl (sw_if_index);
11715   mp->enable_disable = enable_disable;
11716
11717   S (mp);
11718   W (ret);
11719   return ret;
11720 }
11721
11722 static int
11723 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11724 {
11725   unformat_input_t *i = vam->input;
11726   vl_api_l2tpv3_set_lookup_key_t *mp;
11727   u8 key = ~0;
11728   int ret;
11729
11730   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11731     {
11732       if (unformat (i, "lookup_v6_src"))
11733         key = L2T_LOOKUP_SRC_ADDRESS;
11734       else if (unformat (i, "lookup_v6_dst"))
11735         key = L2T_LOOKUP_DST_ADDRESS;
11736       else if (unformat (i, "lookup_session_id"))
11737         key = L2T_LOOKUP_SESSION_ID;
11738       else
11739         break;
11740     }
11741
11742   if (key == (u8) ~ 0)
11743     {
11744       errmsg ("l2tp session lookup key unset");
11745       return -99;
11746     }
11747
11748   M (L2TPV3_SET_LOOKUP_KEY, mp);
11749
11750   mp->key = key;
11751
11752   S (mp);
11753   W (ret);
11754   return ret;
11755 }
11756
11757 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11758   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11759 {
11760   vat_main_t *vam = &vat_main;
11761
11762   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11763          format_ip6_address, mp->our_address,
11764          format_ip6_address, mp->client_address,
11765          clib_net_to_host_u32 (mp->sw_if_index));
11766
11767   print (vam->ofp,
11768          "   local cookies %016llx %016llx remote cookie %016llx",
11769          clib_net_to_host_u64 (mp->local_cookie[0]),
11770          clib_net_to_host_u64 (mp->local_cookie[1]),
11771          clib_net_to_host_u64 (mp->remote_cookie));
11772
11773   print (vam->ofp, "   local session-id %d remote session-id %d",
11774          clib_net_to_host_u32 (mp->local_session_id),
11775          clib_net_to_host_u32 (mp->remote_session_id));
11776
11777   print (vam->ofp, "   l2 specific sublayer %s\n",
11778          mp->l2_sublayer_present ? "preset" : "absent");
11779
11780 }
11781
11782 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11783   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11784 {
11785   vat_main_t *vam = &vat_main;
11786   vat_json_node_t *node = NULL;
11787   struct in6_addr addr;
11788
11789   if (VAT_JSON_ARRAY != vam->json_tree.type)
11790     {
11791       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11792       vat_json_init_array (&vam->json_tree);
11793     }
11794   node = vat_json_array_add (&vam->json_tree);
11795
11796   vat_json_init_object (node);
11797
11798   clib_memcpy (&addr, mp->our_address, sizeof (addr));
11799   vat_json_object_add_ip6 (node, "our_address", addr);
11800   clib_memcpy (&addr, mp->client_address, sizeof (addr));
11801   vat_json_object_add_ip6 (node, "client_address", addr);
11802
11803   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11804   vat_json_init_array (lc);
11805   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11806   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11807   vat_json_object_add_uint (node, "remote_cookie",
11808                             clib_net_to_host_u64 (mp->remote_cookie));
11809
11810   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11811   vat_json_object_add_uint (node, "local_session_id",
11812                             clib_net_to_host_u32 (mp->local_session_id));
11813   vat_json_object_add_uint (node, "remote_session_id",
11814                             clib_net_to_host_u32 (mp->remote_session_id));
11815   vat_json_object_add_string_copy (node, "l2_sublayer",
11816                                    mp->l2_sublayer_present ? (u8 *) "present"
11817                                    : (u8 *) "absent");
11818 }
11819
11820 static int
11821 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11822 {
11823   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11824   vl_api_control_ping_t *mp_ping;
11825   int ret;
11826
11827   /* Get list of l2tpv3-tunnel interfaces */
11828   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11829   S (mp);
11830
11831   /* Use a control ping for synchronization */
11832   MPING (CONTROL_PING, mp_ping);
11833   S (mp_ping);
11834
11835   W (ret);
11836   return ret;
11837 }
11838
11839
11840 static void vl_api_sw_interface_tap_details_t_handler
11841   (vl_api_sw_interface_tap_details_t * mp)
11842 {
11843   vat_main_t *vam = &vat_main;
11844
11845   print (vam->ofp, "%-16s %d",
11846          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
11847 }
11848
11849 static void vl_api_sw_interface_tap_details_t_handler_json
11850   (vl_api_sw_interface_tap_details_t * mp)
11851 {
11852   vat_main_t *vam = &vat_main;
11853   vat_json_node_t *node = NULL;
11854
11855   if (VAT_JSON_ARRAY != vam->json_tree.type)
11856     {
11857       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11858       vat_json_init_array (&vam->json_tree);
11859     }
11860   node = vat_json_array_add (&vam->json_tree);
11861
11862   vat_json_init_object (node);
11863   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11864   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11865 }
11866
11867 static int
11868 api_sw_interface_tap_dump (vat_main_t * vam)
11869 {
11870   vl_api_sw_interface_tap_dump_t *mp;
11871   vl_api_control_ping_t *mp_ping;
11872   int ret;
11873
11874   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
11875   /* Get list of tap interfaces */
11876   M (SW_INTERFACE_TAP_DUMP, mp);
11877   S (mp);
11878
11879   /* Use a control ping for synchronization */
11880   MPING (CONTROL_PING, mp_ping);
11881   S (mp_ping);
11882
11883   W (ret);
11884   return ret;
11885 }
11886
11887 static uword unformat_vxlan_decap_next
11888   (unformat_input_t * input, va_list * args)
11889 {
11890   u32 *result = va_arg (*args, u32 *);
11891   u32 tmp;
11892
11893   if (unformat (input, "l2"))
11894     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11895   else if (unformat (input, "%d", &tmp))
11896     *result = tmp;
11897   else
11898     return 0;
11899   return 1;
11900 }
11901
11902 static int
11903 api_vxlan_add_del_tunnel (vat_main_t * vam)
11904 {
11905   unformat_input_t *line_input = vam->input;
11906   vl_api_vxlan_add_del_tunnel_t *mp;
11907   ip46_address_t src, dst;
11908   u8 is_add = 1;
11909   u8 ipv4_set = 0, ipv6_set = 0;
11910   u8 src_set = 0;
11911   u8 dst_set = 0;
11912   u8 grp_set = 0;
11913   u32 mcast_sw_if_index = ~0;
11914   u32 encap_vrf_id = 0;
11915   u32 decap_next_index = ~0;
11916   u32 vni = 0;
11917   int ret;
11918
11919   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11920   memset (&src, 0, sizeof src);
11921   memset (&dst, 0, sizeof dst);
11922
11923   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11924     {
11925       if (unformat (line_input, "del"))
11926         is_add = 0;
11927       else
11928         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11929         {
11930           ipv4_set = 1;
11931           src_set = 1;
11932         }
11933       else
11934         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11935         {
11936           ipv4_set = 1;
11937           dst_set = 1;
11938         }
11939       else
11940         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11941         {
11942           ipv6_set = 1;
11943           src_set = 1;
11944         }
11945       else
11946         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11947         {
11948           ipv6_set = 1;
11949           dst_set = 1;
11950         }
11951       else if (unformat (line_input, "group %U %U",
11952                          unformat_ip4_address, &dst.ip4,
11953                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11954         {
11955           grp_set = dst_set = 1;
11956           ipv4_set = 1;
11957         }
11958       else if (unformat (line_input, "group %U",
11959                          unformat_ip4_address, &dst.ip4))
11960         {
11961           grp_set = dst_set = 1;
11962           ipv4_set = 1;
11963         }
11964       else if (unformat (line_input, "group %U %U",
11965                          unformat_ip6_address, &dst.ip6,
11966                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11967         {
11968           grp_set = dst_set = 1;
11969           ipv6_set = 1;
11970         }
11971       else if (unformat (line_input, "group %U",
11972                          unformat_ip6_address, &dst.ip6))
11973         {
11974           grp_set = dst_set = 1;
11975           ipv6_set = 1;
11976         }
11977       else
11978         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11979         ;
11980       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11981         ;
11982       else if (unformat (line_input, "decap-next %U",
11983                          unformat_vxlan_decap_next, &decap_next_index))
11984         ;
11985       else if (unformat (line_input, "vni %d", &vni))
11986         ;
11987       else
11988         {
11989           errmsg ("parse error '%U'", format_unformat_error, line_input);
11990           return -99;
11991         }
11992     }
11993
11994   if (src_set == 0)
11995     {
11996       errmsg ("tunnel src address not specified");
11997       return -99;
11998     }
11999   if (dst_set == 0)
12000     {
12001       errmsg ("tunnel dst address not specified");
12002       return -99;
12003     }
12004
12005   if (grp_set && !ip46_address_is_multicast (&dst))
12006     {
12007       errmsg ("tunnel group address not multicast");
12008       return -99;
12009     }
12010   if (grp_set && mcast_sw_if_index == ~0)
12011     {
12012       errmsg ("tunnel nonexistent multicast device");
12013       return -99;
12014     }
12015   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12016     {
12017       errmsg ("tunnel dst address must be unicast");
12018       return -99;
12019     }
12020
12021
12022   if (ipv4_set && ipv6_set)
12023     {
12024       errmsg ("both IPv4 and IPv6 addresses specified");
12025       return -99;
12026     }
12027
12028   if ((vni == 0) || (vni >> 24))
12029     {
12030       errmsg ("vni not specified or out of range");
12031       return -99;
12032     }
12033
12034   M (VXLAN_ADD_DEL_TUNNEL, mp);
12035
12036   if (ipv6_set)
12037     {
12038       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12039       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12040     }
12041   else
12042     {
12043       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12044       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12045     }
12046   mp->encap_vrf_id = ntohl (encap_vrf_id);
12047   mp->decap_next_index = ntohl (decap_next_index);
12048   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12049   mp->vni = ntohl (vni);
12050   mp->is_add = is_add;
12051   mp->is_ipv6 = ipv6_set;
12052
12053   S (mp);
12054   W (ret);
12055   return ret;
12056 }
12057
12058 static void vl_api_vxlan_tunnel_details_t_handler
12059   (vl_api_vxlan_tunnel_details_t * mp)
12060 {
12061   vat_main_t *vam = &vat_main;
12062   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12063   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12064
12065   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12066          ntohl (mp->sw_if_index),
12067          format_ip46_address, &src, IP46_TYPE_ANY,
12068          format_ip46_address, &dst, IP46_TYPE_ANY,
12069          ntohl (mp->encap_vrf_id),
12070          ntohl (mp->decap_next_index), ntohl (mp->vni),
12071          ntohl (mp->mcast_sw_if_index));
12072 }
12073
12074 static void vl_api_vxlan_tunnel_details_t_handler_json
12075   (vl_api_vxlan_tunnel_details_t * mp)
12076 {
12077   vat_main_t *vam = &vat_main;
12078   vat_json_node_t *node = NULL;
12079
12080   if (VAT_JSON_ARRAY != vam->json_tree.type)
12081     {
12082       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12083       vat_json_init_array (&vam->json_tree);
12084     }
12085   node = vat_json_array_add (&vam->json_tree);
12086
12087   vat_json_init_object (node);
12088   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12089   if (mp->is_ipv6)
12090     {
12091       struct in6_addr ip6;
12092
12093       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12094       vat_json_object_add_ip6 (node, "src_address", ip6);
12095       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12096       vat_json_object_add_ip6 (node, "dst_address", ip6);
12097     }
12098   else
12099     {
12100       struct in_addr ip4;
12101
12102       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12103       vat_json_object_add_ip4 (node, "src_address", ip4);
12104       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12105       vat_json_object_add_ip4 (node, "dst_address", ip4);
12106     }
12107   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12108   vat_json_object_add_uint (node, "decap_next_index",
12109                             ntohl (mp->decap_next_index));
12110   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12111   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12112   vat_json_object_add_uint (node, "mcast_sw_if_index",
12113                             ntohl (mp->mcast_sw_if_index));
12114 }
12115
12116 static int
12117 api_vxlan_tunnel_dump (vat_main_t * vam)
12118 {
12119   unformat_input_t *i = vam->input;
12120   vl_api_vxlan_tunnel_dump_t *mp;
12121   vl_api_control_ping_t *mp_ping;
12122   u32 sw_if_index;
12123   u8 sw_if_index_set = 0;
12124   int ret;
12125
12126   /* Parse args required to build the message */
12127   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12128     {
12129       if (unformat (i, "sw_if_index %d", &sw_if_index))
12130         sw_if_index_set = 1;
12131       else
12132         break;
12133     }
12134
12135   if (sw_if_index_set == 0)
12136     {
12137       sw_if_index = ~0;
12138     }
12139
12140   if (!vam->json_output)
12141     {
12142       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12143              "sw_if_index", "src_address", "dst_address",
12144              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12145     }
12146
12147   /* Get list of vxlan-tunnel interfaces */
12148   M (VXLAN_TUNNEL_DUMP, mp);
12149
12150   mp->sw_if_index = htonl (sw_if_index);
12151
12152   S (mp);
12153
12154   /* Use a control ping for synchronization */
12155   MPING (CONTROL_PING, mp_ping);
12156   S (mp_ping);
12157
12158   W (ret);
12159   return ret;
12160 }
12161
12162 static uword unformat_geneve_decap_next
12163   (unformat_input_t * input, va_list * args)
12164 {
12165   u32 *result = va_arg (*args, u32 *);
12166   u32 tmp;
12167
12168   if (unformat (input, "l2"))
12169     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12170   else if (unformat (input, "%d", &tmp))
12171     *result = tmp;
12172   else
12173     return 0;
12174   return 1;
12175 }
12176
12177 static int
12178 api_geneve_add_del_tunnel (vat_main_t * vam)
12179 {
12180   unformat_input_t *line_input = vam->input;
12181   vl_api_geneve_add_del_tunnel_t *mp;
12182   ip46_address_t src, dst;
12183   u8 is_add = 1;
12184   u8 ipv4_set = 0, ipv6_set = 0;
12185   u8 src_set = 0;
12186   u8 dst_set = 0;
12187   u8 grp_set = 0;
12188   u32 mcast_sw_if_index = ~0;
12189   u32 encap_vrf_id = 0;
12190   u32 decap_next_index = ~0;
12191   u32 vni = 0;
12192   int ret;
12193
12194   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12195   memset (&src, 0, sizeof src);
12196   memset (&dst, 0, sizeof dst);
12197
12198   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12199     {
12200       if (unformat (line_input, "del"))
12201         is_add = 0;
12202       else
12203         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12204         {
12205           ipv4_set = 1;
12206           src_set = 1;
12207         }
12208       else
12209         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12210         {
12211           ipv4_set = 1;
12212           dst_set = 1;
12213         }
12214       else
12215         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12216         {
12217           ipv6_set = 1;
12218           src_set = 1;
12219         }
12220       else
12221         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12222         {
12223           ipv6_set = 1;
12224           dst_set = 1;
12225         }
12226       else if (unformat (line_input, "group %U %U",
12227                          unformat_ip4_address, &dst.ip4,
12228                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12229         {
12230           grp_set = dst_set = 1;
12231           ipv4_set = 1;
12232         }
12233       else if (unformat (line_input, "group %U",
12234                          unformat_ip4_address, &dst.ip4))
12235         {
12236           grp_set = dst_set = 1;
12237           ipv4_set = 1;
12238         }
12239       else if (unformat (line_input, "group %U %U",
12240                          unformat_ip6_address, &dst.ip6,
12241                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12242         {
12243           grp_set = dst_set = 1;
12244           ipv6_set = 1;
12245         }
12246       else if (unformat (line_input, "group %U",
12247                          unformat_ip6_address, &dst.ip6))
12248         {
12249           grp_set = dst_set = 1;
12250           ipv6_set = 1;
12251         }
12252       else
12253         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12254         ;
12255       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12256         ;
12257       else if (unformat (line_input, "decap-next %U",
12258                          unformat_geneve_decap_next, &decap_next_index))
12259         ;
12260       else if (unformat (line_input, "vni %d", &vni))
12261         ;
12262       else
12263         {
12264           errmsg ("parse error '%U'", format_unformat_error, line_input);
12265           return -99;
12266         }
12267     }
12268
12269   if (src_set == 0)
12270     {
12271       errmsg ("tunnel src address not specified");
12272       return -99;
12273     }
12274   if (dst_set == 0)
12275     {
12276       errmsg ("tunnel dst address not specified");
12277       return -99;
12278     }
12279
12280   if (grp_set && !ip46_address_is_multicast (&dst))
12281     {
12282       errmsg ("tunnel group address not multicast");
12283       return -99;
12284     }
12285   if (grp_set && mcast_sw_if_index == ~0)
12286     {
12287       errmsg ("tunnel nonexistent multicast device");
12288       return -99;
12289     }
12290   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12291     {
12292       errmsg ("tunnel dst address must be unicast");
12293       return -99;
12294     }
12295
12296
12297   if (ipv4_set && ipv6_set)
12298     {
12299       errmsg ("both IPv4 and IPv6 addresses specified");
12300       return -99;
12301     }
12302
12303   if ((vni == 0) || (vni >> 24))
12304     {
12305       errmsg ("vni not specified or out of range");
12306       return -99;
12307     }
12308
12309   M (GENEVE_ADD_DEL_TUNNEL, mp);
12310
12311   if (ipv6_set)
12312     {
12313       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12314       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12315     }
12316   else
12317     {
12318       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12319       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12320     }
12321   mp->encap_vrf_id = ntohl (encap_vrf_id);
12322   mp->decap_next_index = ntohl (decap_next_index);
12323   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12324   mp->vni = ntohl (vni);
12325   mp->is_add = is_add;
12326   mp->is_ipv6 = ipv6_set;
12327
12328   S (mp);
12329   W (ret);
12330   return ret;
12331 }
12332
12333 static void vl_api_geneve_tunnel_details_t_handler
12334   (vl_api_geneve_tunnel_details_t * mp)
12335 {
12336   vat_main_t *vam = &vat_main;
12337   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12338   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12339
12340   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12341          ntohl (mp->sw_if_index),
12342          format_ip46_address, &src, IP46_TYPE_ANY,
12343          format_ip46_address, &dst, IP46_TYPE_ANY,
12344          ntohl (mp->encap_vrf_id),
12345          ntohl (mp->decap_next_index), ntohl (mp->vni),
12346          ntohl (mp->mcast_sw_if_index));
12347 }
12348
12349 static void vl_api_geneve_tunnel_details_t_handler_json
12350   (vl_api_geneve_tunnel_details_t * mp)
12351 {
12352   vat_main_t *vam = &vat_main;
12353   vat_json_node_t *node = NULL;
12354
12355   if (VAT_JSON_ARRAY != vam->json_tree.type)
12356     {
12357       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12358       vat_json_init_array (&vam->json_tree);
12359     }
12360   node = vat_json_array_add (&vam->json_tree);
12361
12362   vat_json_init_object (node);
12363   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12364   if (mp->is_ipv6)
12365     {
12366       struct in6_addr ip6;
12367
12368       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12369       vat_json_object_add_ip6 (node, "src_address", ip6);
12370       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12371       vat_json_object_add_ip6 (node, "dst_address", ip6);
12372     }
12373   else
12374     {
12375       struct in_addr ip4;
12376
12377       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12378       vat_json_object_add_ip4 (node, "src_address", ip4);
12379       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12380       vat_json_object_add_ip4 (node, "dst_address", ip4);
12381     }
12382   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12383   vat_json_object_add_uint (node, "decap_next_index",
12384                             ntohl (mp->decap_next_index));
12385   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12386   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12387   vat_json_object_add_uint (node, "mcast_sw_if_index",
12388                             ntohl (mp->mcast_sw_if_index));
12389 }
12390
12391 static int
12392 api_geneve_tunnel_dump (vat_main_t * vam)
12393 {
12394   unformat_input_t *i = vam->input;
12395   vl_api_geneve_tunnel_dump_t *mp;
12396   vl_api_control_ping_t *mp_ping;
12397   u32 sw_if_index;
12398   u8 sw_if_index_set = 0;
12399   int ret;
12400
12401   /* Parse args required to build the message */
12402   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12403     {
12404       if (unformat (i, "sw_if_index %d", &sw_if_index))
12405         sw_if_index_set = 1;
12406       else
12407         break;
12408     }
12409
12410   if (sw_if_index_set == 0)
12411     {
12412       sw_if_index = ~0;
12413     }
12414
12415   if (!vam->json_output)
12416     {
12417       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12418              "sw_if_index", "local_address", "remote_address",
12419              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12420     }
12421
12422   /* Get list of geneve-tunnel interfaces */
12423   M (GENEVE_TUNNEL_DUMP, mp);
12424
12425   mp->sw_if_index = htonl (sw_if_index);
12426
12427   S (mp);
12428
12429   /* Use a control ping for synchronization */
12430   M (CONTROL_PING, mp_ping);
12431   S (mp_ping);
12432
12433   W (ret);
12434   return ret;
12435 }
12436
12437 static int
12438 api_gre_add_del_tunnel (vat_main_t * vam)
12439 {
12440   unformat_input_t *line_input = vam->input;
12441   vl_api_gre_add_del_tunnel_t *mp;
12442   ip4_address_t src4, dst4;
12443   ip6_address_t src6, dst6;
12444   u8 is_add = 1;
12445   u8 ipv4_set = 0;
12446   u8 ipv6_set = 0;
12447   u8 teb = 0;
12448   u8 src_set = 0;
12449   u8 dst_set = 0;
12450   u32 outer_fib_id = 0;
12451   int ret;
12452
12453   memset (&src4, 0, sizeof src4);
12454   memset (&dst4, 0, sizeof dst4);
12455   memset (&src6, 0, sizeof src6);
12456   memset (&dst6, 0, sizeof dst6);
12457
12458   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12459     {
12460       if (unformat (line_input, "del"))
12461         is_add = 0;
12462       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
12463         {
12464           src_set = 1;
12465           ipv4_set = 1;
12466         }
12467       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
12468         {
12469           dst_set = 1;
12470           ipv4_set = 1;
12471         }
12472       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
12473         {
12474           src_set = 1;
12475           ipv6_set = 1;
12476         }
12477       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
12478         {
12479           dst_set = 1;
12480           ipv6_set = 1;
12481         }
12482       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
12483         ;
12484       else if (unformat (line_input, "teb"))
12485         teb = 1;
12486       else
12487         {
12488           errmsg ("parse error '%U'", format_unformat_error, line_input);
12489           return -99;
12490         }
12491     }
12492
12493   if (src_set == 0)
12494     {
12495       errmsg ("tunnel src address not specified");
12496       return -99;
12497     }
12498   if (dst_set == 0)
12499     {
12500       errmsg ("tunnel dst address not specified");
12501       return -99;
12502     }
12503   if (ipv4_set && ipv6_set)
12504     {
12505       errmsg ("both IPv4 and IPv6 addresses specified");
12506       return -99;
12507     }
12508
12509
12510   M (GRE_ADD_DEL_TUNNEL, mp);
12511
12512   if (ipv4_set)
12513     {
12514       clib_memcpy (&mp->src_address, &src4, 4);
12515       clib_memcpy (&mp->dst_address, &dst4, 4);
12516     }
12517   else
12518     {
12519       clib_memcpy (&mp->src_address, &src6, 16);
12520       clib_memcpy (&mp->dst_address, &dst6, 16);
12521     }
12522   mp->outer_fib_id = ntohl (outer_fib_id);
12523   mp->is_add = is_add;
12524   mp->teb = teb;
12525   mp->is_ipv6 = ipv6_set;
12526
12527   S (mp);
12528   W (ret);
12529   return ret;
12530 }
12531
12532 static void vl_api_gre_tunnel_details_t_handler
12533   (vl_api_gre_tunnel_details_t * mp)
12534 {
12535   vat_main_t *vam = &vat_main;
12536   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
12537   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
12538
12539   print (vam->ofp, "%11d%24U%24U%6d%14d",
12540          ntohl (mp->sw_if_index),
12541          format_ip46_address, &src, IP46_TYPE_ANY,
12542          format_ip46_address, &dst, IP46_TYPE_ANY,
12543          mp->teb, ntohl (mp->outer_fib_id));
12544 }
12545
12546 static void vl_api_gre_tunnel_details_t_handler_json
12547   (vl_api_gre_tunnel_details_t * mp)
12548 {
12549   vat_main_t *vam = &vat_main;
12550   vat_json_node_t *node = NULL;
12551   struct in_addr ip4;
12552   struct in6_addr ip6;
12553
12554   if (VAT_JSON_ARRAY != vam->json_tree.type)
12555     {
12556       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12557       vat_json_init_array (&vam->json_tree);
12558     }
12559   node = vat_json_array_add (&vam->json_tree);
12560
12561   vat_json_init_object (node);
12562   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12563   if (!mp->is_ipv6)
12564     {
12565       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
12566       vat_json_object_add_ip4 (node, "src_address", ip4);
12567       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
12568       vat_json_object_add_ip4 (node, "dst_address", ip4);
12569     }
12570   else
12571     {
12572       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
12573       vat_json_object_add_ip6 (node, "src_address", ip6);
12574       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
12575       vat_json_object_add_ip6 (node, "dst_address", ip6);
12576     }
12577   vat_json_object_add_uint (node, "teb", mp->teb);
12578   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
12579   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
12580 }
12581
12582 static int
12583 api_gre_tunnel_dump (vat_main_t * vam)
12584 {
12585   unformat_input_t *i = vam->input;
12586   vl_api_gre_tunnel_dump_t *mp;
12587   vl_api_control_ping_t *mp_ping;
12588   u32 sw_if_index;
12589   u8 sw_if_index_set = 0;
12590   int ret;
12591
12592   /* Parse args required to build the message */
12593   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12594     {
12595       if (unformat (i, "sw_if_index %d", &sw_if_index))
12596         sw_if_index_set = 1;
12597       else
12598         break;
12599     }
12600
12601   if (sw_if_index_set == 0)
12602     {
12603       sw_if_index = ~0;
12604     }
12605
12606   if (!vam->json_output)
12607     {
12608       print (vam->ofp, "%11s%24s%24s%6s%14s",
12609              "sw_if_index", "src_address", "dst_address", "teb",
12610              "outer_fib_id");
12611     }
12612
12613   /* Get list of gre-tunnel interfaces */
12614   M (GRE_TUNNEL_DUMP, mp);
12615
12616   mp->sw_if_index = htonl (sw_if_index);
12617
12618   S (mp);
12619
12620   /* Use a control ping for synchronization */
12621   MPING (CONTROL_PING, mp_ping);
12622   S (mp_ping);
12623
12624   W (ret);
12625   return ret;
12626 }
12627
12628 static int
12629 api_l2_fib_clear_table (vat_main_t * vam)
12630 {
12631 //  unformat_input_t * i = vam->input;
12632   vl_api_l2_fib_clear_table_t *mp;
12633   int ret;
12634
12635   M (L2_FIB_CLEAR_TABLE, mp);
12636
12637   S (mp);
12638   W (ret);
12639   return ret;
12640 }
12641
12642 static int
12643 api_l2_interface_efp_filter (vat_main_t * vam)
12644 {
12645   unformat_input_t *i = vam->input;
12646   vl_api_l2_interface_efp_filter_t *mp;
12647   u32 sw_if_index;
12648   u8 enable = 1;
12649   u8 sw_if_index_set = 0;
12650   int ret;
12651
12652   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12653     {
12654       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12655         sw_if_index_set = 1;
12656       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12657         sw_if_index_set = 1;
12658       else if (unformat (i, "enable"))
12659         enable = 1;
12660       else if (unformat (i, "disable"))
12661         enable = 0;
12662       else
12663         {
12664           clib_warning ("parse error '%U'", format_unformat_error, i);
12665           return -99;
12666         }
12667     }
12668
12669   if (sw_if_index_set == 0)
12670     {
12671       errmsg ("missing sw_if_index");
12672       return -99;
12673     }
12674
12675   M (L2_INTERFACE_EFP_FILTER, mp);
12676
12677   mp->sw_if_index = ntohl (sw_if_index);
12678   mp->enable_disable = enable;
12679
12680   S (mp);
12681   W (ret);
12682   return ret;
12683 }
12684
12685 #define foreach_vtr_op                          \
12686 _("disable",  L2_VTR_DISABLED)                  \
12687 _("push-1",  L2_VTR_PUSH_1)                     \
12688 _("push-2",  L2_VTR_PUSH_2)                     \
12689 _("pop-1",  L2_VTR_POP_1)                       \
12690 _("pop-2",  L2_VTR_POP_2)                       \
12691 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12692 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12693 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12694 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12695
12696 static int
12697 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12698 {
12699   unformat_input_t *i = vam->input;
12700   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12701   u32 sw_if_index;
12702   u8 sw_if_index_set = 0;
12703   u8 vtr_op_set = 0;
12704   u32 vtr_op = 0;
12705   u32 push_dot1q = 1;
12706   u32 tag1 = ~0;
12707   u32 tag2 = ~0;
12708   int ret;
12709
12710   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12711     {
12712       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12713         sw_if_index_set = 1;
12714       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12715         sw_if_index_set = 1;
12716       else if (unformat (i, "vtr_op %d", &vtr_op))
12717         vtr_op_set = 1;
12718 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12719       foreach_vtr_op
12720 #undef _
12721         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12722         ;
12723       else if (unformat (i, "tag1 %d", &tag1))
12724         ;
12725       else if (unformat (i, "tag2 %d", &tag2))
12726         ;
12727       else
12728         {
12729           clib_warning ("parse error '%U'", format_unformat_error, i);
12730           return -99;
12731         }
12732     }
12733
12734   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12735     {
12736       errmsg ("missing vtr operation or sw_if_index");
12737       return -99;
12738     }
12739
12740   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12741   mp->sw_if_index = ntohl (sw_if_index);
12742   mp->vtr_op = ntohl (vtr_op);
12743   mp->push_dot1q = ntohl (push_dot1q);
12744   mp->tag1 = ntohl (tag1);
12745   mp->tag2 = ntohl (tag2);
12746
12747   S (mp);
12748   W (ret);
12749   return ret;
12750 }
12751
12752 static int
12753 api_create_vhost_user_if (vat_main_t * vam)
12754 {
12755   unformat_input_t *i = vam->input;
12756   vl_api_create_vhost_user_if_t *mp;
12757   u8 *file_name;
12758   u8 is_server = 0;
12759   u8 file_name_set = 0;
12760   u32 custom_dev_instance = ~0;
12761   u8 hwaddr[6];
12762   u8 use_custom_mac = 0;
12763   u8 *tag = 0;
12764   int ret;
12765
12766   /* Shut up coverity */
12767   memset (hwaddr, 0, sizeof (hwaddr));
12768
12769   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12770     {
12771       if (unformat (i, "socket %s", &file_name))
12772         {
12773           file_name_set = 1;
12774         }
12775       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12776         ;
12777       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12778         use_custom_mac = 1;
12779       else if (unformat (i, "server"))
12780         is_server = 1;
12781       else if (unformat (i, "tag %s", &tag))
12782         ;
12783       else
12784         break;
12785     }
12786
12787   if (file_name_set == 0)
12788     {
12789       errmsg ("missing socket file name");
12790       return -99;
12791     }
12792
12793   if (vec_len (file_name) > 255)
12794     {
12795       errmsg ("socket file name too long");
12796       return -99;
12797     }
12798   vec_add1 (file_name, 0);
12799
12800   M (CREATE_VHOST_USER_IF, mp);
12801
12802   mp->is_server = is_server;
12803   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12804   vec_free (file_name);
12805   if (custom_dev_instance != ~0)
12806     {
12807       mp->renumber = 1;
12808       mp->custom_dev_instance = ntohl (custom_dev_instance);
12809     }
12810   mp->use_custom_mac = use_custom_mac;
12811   clib_memcpy (mp->mac_address, hwaddr, 6);
12812   if (tag)
12813     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12814   vec_free (tag);
12815
12816   S (mp);
12817   W (ret);
12818   return ret;
12819 }
12820
12821 static int
12822 api_modify_vhost_user_if (vat_main_t * vam)
12823 {
12824   unformat_input_t *i = vam->input;
12825   vl_api_modify_vhost_user_if_t *mp;
12826   u8 *file_name;
12827   u8 is_server = 0;
12828   u8 file_name_set = 0;
12829   u32 custom_dev_instance = ~0;
12830   u8 sw_if_index_set = 0;
12831   u32 sw_if_index = (u32) ~ 0;
12832   int ret;
12833
12834   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12835     {
12836       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12837         sw_if_index_set = 1;
12838       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12839         sw_if_index_set = 1;
12840       else if (unformat (i, "socket %s", &file_name))
12841         {
12842           file_name_set = 1;
12843         }
12844       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12845         ;
12846       else if (unformat (i, "server"))
12847         is_server = 1;
12848       else
12849         break;
12850     }
12851
12852   if (sw_if_index_set == 0)
12853     {
12854       errmsg ("missing sw_if_index or interface name");
12855       return -99;
12856     }
12857
12858   if (file_name_set == 0)
12859     {
12860       errmsg ("missing socket file name");
12861       return -99;
12862     }
12863
12864   if (vec_len (file_name) > 255)
12865     {
12866       errmsg ("socket file name too long");
12867       return -99;
12868     }
12869   vec_add1 (file_name, 0);
12870
12871   M (MODIFY_VHOST_USER_IF, mp);
12872
12873   mp->sw_if_index = ntohl (sw_if_index);
12874   mp->is_server = is_server;
12875   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12876   vec_free (file_name);
12877   if (custom_dev_instance != ~0)
12878     {
12879       mp->renumber = 1;
12880       mp->custom_dev_instance = ntohl (custom_dev_instance);
12881     }
12882
12883   S (mp);
12884   W (ret);
12885   return ret;
12886 }
12887
12888 static int
12889 api_delete_vhost_user_if (vat_main_t * vam)
12890 {
12891   unformat_input_t *i = vam->input;
12892   vl_api_delete_vhost_user_if_t *mp;
12893   u32 sw_if_index = ~0;
12894   u8 sw_if_index_set = 0;
12895   int ret;
12896
12897   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12898     {
12899       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12900         sw_if_index_set = 1;
12901       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12902         sw_if_index_set = 1;
12903       else
12904         break;
12905     }
12906
12907   if (sw_if_index_set == 0)
12908     {
12909       errmsg ("missing sw_if_index or interface name");
12910       return -99;
12911     }
12912
12913
12914   M (DELETE_VHOST_USER_IF, mp);
12915
12916   mp->sw_if_index = ntohl (sw_if_index);
12917
12918   S (mp);
12919   W (ret);
12920   return ret;
12921 }
12922
12923 static void vl_api_sw_interface_vhost_user_details_t_handler
12924   (vl_api_sw_interface_vhost_user_details_t * mp)
12925 {
12926   vat_main_t *vam = &vat_main;
12927
12928   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12929          (char *) mp->interface_name,
12930          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12931          clib_net_to_host_u64 (mp->features), mp->is_server,
12932          ntohl (mp->num_regions), (char *) mp->sock_filename);
12933   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12934 }
12935
12936 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12937   (vl_api_sw_interface_vhost_user_details_t * mp)
12938 {
12939   vat_main_t *vam = &vat_main;
12940   vat_json_node_t *node = NULL;
12941
12942   if (VAT_JSON_ARRAY != vam->json_tree.type)
12943     {
12944       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12945       vat_json_init_array (&vam->json_tree);
12946     }
12947   node = vat_json_array_add (&vam->json_tree);
12948
12949   vat_json_init_object (node);
12950   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12951   vat_json_object_add_string_copy (node, "interface_name",
12952                                    mp->interface_name);
12953   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12954                             ntohl (mp->virtio_net_hdr_sz));
12955   vat_json_object_add_uint (node, "features",
12956                             clib_net_to_host_u64 (mp->features));
12957   vat_json_object_add_uint (node, "is_server", mp->is_server);
12958   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12959   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12960   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12961 }
12962
12963 static int
12964 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12965 {
12966   vl_api_sw_interface_vhost_user_dump_t *mp;
12967   vl_api_control_ping_t *mp_ping;
12968   int ret;
12969   print (vam->ofp,
12970          "Interface name            idx hdr_sz features server regions filename");
12971
12972   /* Get list of vhost-user interfaces */
12973   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12974   S (mp);
12975
12976   /* Use a control ping for synchronization */
12977   MPING (CONTROL_PING, mp_ping);
12978   S (mp_ping);
12979
12980   W (ret);
12981   return ret;
12982 }
12983
12984 static int
12985 api_show_version (vat_main_t * vam)
12986 {
12987   vl_api_show_version_t *mp;
12988   int ret;
12989
12990   M (SHOW_VERSION, mp);
12991
12992   S (mp);
12993   W (ret);
12994   return ret;
12995 }
12996
12997
12998 static int
12999 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13000 {
13001   unformat_input_t *line_input = vam->input;
13002   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13003   ip4_address_t local4, remote4;
13004   ip6_address_t local6, remote6;
13005   u8 is_add = 1;
13006   u8 ipv4_set = 0, ipv6_set = 0;
13007   u8 local_set = 0;
13008   u8 remote_set = 0;
13009   u8 grp_set = 0;
13010   u32 mcast_sw_if_index = ~0;
13011   u32 encap_vrf_id = 0;
13012   u32 decap_vrf_id = 0;
13013   u8 protocol = ~0;
13014   u32 vni;
13015   u8 vni_set = 0;
13016   int ret;
13017
13018   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13019   memset (&local4, 0, sizeof local4);
13020   memset (&remote4, 0, sizeof remote4);
13021   memset (&local6, 0, sizeof local6);
13022   memset (&remote6, 0, sizeof remote6);
13023
13024   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13025     {
13026       if (unformat (line_input, "del"))
13027         is_add = 0;
13028       else if (unformat (line_input, "local %U",
13029                          unformat_ip4_address, &local4))
13030         {
13031           local_set = 1;
13032           ipv4_set = 1;
13033         }
13034       else if (unformat (line_input, "remote %U",
13035                          unformat_ip4_address, &remote4))
13036         {
13037           remote_set = 1;
13038           ipv4_set = 1;
13039         }
13040       else if (unformat (line_input, "local %U",
13041                          unformat_ip6_address, &local6))
13042         {
13043           local_set = 1;
13044           ipv6_set = 1;
13045         }
13046       else if (unformat (line_input, "remote %U",
13047                          unformat_ip6_address, &remote6))
13048         {
13049           remote_set = 1;
13050           ipv6_set = 1;
13051         }
13052       else if (unformat (line_input, "group %U %U",
13053                          unformat_ip4_address, &remote4,
13054                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13055         {
13056           grp_set = remote_set = 1;
13057           ipv4_set = 1;
13058         }
13059       else if (unformat (line_input, "group %U",
13060                          unformat_ip4_address, &remote4))
13061         {
13062           grp_set = remote_set = 1;
13063           ipv4_set = 1;
13064         }
13065       else if (unformat (line_input, "group %U %U",
13066                          unformat_ip6_address, &remote6,
13067                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13068         {
13069           grp_set = remote_set = 1;
13070           ipv6_set = 1;
13071         }
13072       else if (unformat (line_input, "group %U",
13073                          unformat_ip6_address, &remote6))
13074         {
13075           grp_set = remote_set = 1;
13076           ipv6_set = 1;
13077         }
13078       else
13079         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13080         ;
13081       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13082         ;
13083       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13084         ;
13085       else if (unformat (line_input, "vni %d", &vni))
13086         vni_set = 1;
13087       else if (unformat (line_input, "next-ip4"))
13088         protocol = 1;
13089       else if (unformat (line_input, "next-ip6"))
13090         protocol = 2;
13091       else if (unformat (line_input, "next-ethernet"))
13092         protocol = 3;
13093       else if (unformat (line_input, "next-nsh"))
13094         protocol = 4;
13095       else
13096         {
13097           errmsg ("parse error '%U'", format_unformat_error, line_input);
13098           return -99;
13099         }
13100     }
13101
13102   if (local_set == 0)
13103     {
13104       errmsg ("tunnel local address not specified");
13105       return -99;
13106     }
13107   if (remote_set == 0)
13108     {
13109       errmsg ("tunnel remote address not specified");
13110       return -99;
13111     }
13112   if (grp_set && mcast_sw_if_index == ~0)
13113     {
13114       errmsg ("tunnel nonexistent multicast device");
13115       return -99;
13116     }
13117   if (ipv4_set && ipv6_set)
13118     {
13119       errmsg ("both IPv4 and IPv6 addresses specified");
13120       return -99;
13121     }
13122
13123   if (vni_set == 0)
13124     {
13125       errmsg ("vni not specified");
13126       return -99;
13127     }
13128
13129   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13130
13131
13132   if (ipv6_set)
13133     {
13134       clib_memcpy (&mp->local, &local6, sizeof (local6));
13135       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13136     }
13137   else
13138     {
13139       clib_memcpy (&mp->local, &local4, sizeof (local4));
13140       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13141     }
13142
13143   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13144   mp->encap_vrf_id = ntohl (encap_vrf_id);
13145   mp->decap_vrf_id = ntohl (decap_vrf_id);
13146   mp->protocol = protocol;
13147   mp->vni = ntohl (vni);
13148   mp->is_add = is_add;
13149   mp->is_ipv6 = ipv6_set;
13150
13151   S (mp);
13152   W (ret);
13153   return ret;
13154 }
13155
13156 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13157   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13158 {
13159   vat_main_t *vam = &vat_main;
13160   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13161   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13162
13163   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13164          ntohl (mp->sw_if_index),
13165          format_ip46_address, &local, IP46_TYPE_ANY,
13166          format_ip46_address, &remote, IP46_TYPE_ANY,
13167          ntohl (mp->vni), mp->protocol,
13168          ntohl (mp->mcast_sw_if_index),
13169          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13170 }
13171
13172
13173 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13174   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13175 {
13176   vat_main_t *vam = &vat_main;
13177   vat_json_node_t *node = NULL;
13178   struct in_addr ip4;
13179   struct in6_addr ip6;
13180
13181   if (VAT_JSON_ARRAY != vam->json_tree.type)
13182     {
13183       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13184       vat_json_init_array (&vam->json_tree);
13185     }
13186   node = vat_json_array_add (&vam->json_tree);
13187
13188   vat_json_init_object (node);
13189   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13190   if (mp->is_ipv6)
13191     {
13192       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13193       vat_json_object_add_ip6 (node, "local", ip6);
13194       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13195       vat_json_object_add_ip6 (node, "remote", ip6);
13196     }
13197   else
13198     {
13199       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13200       vat_json_object_add_ip4 (node, "local", ip4);
13201       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13202       vat_json_object_add_ip4 (node, "remote", ip4);
13203     }
13204   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13205   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13206   vat_json_object_add_uint (node, "mcast_sw_if_index",
13207                             ntohl (mp->mcast_sw_if_index));
13208   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13209   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13210   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13211 }
13212
13213 static int
13214 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13215 {
13216   unformat_input_t *i = vam->input;
13217   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13218   vl_api_control_ping_t *mp_ping;
13219   u32 sw_if_index;
13220   u8 sw_if_index_set = 0;
13221   int ret;
13222
13223   /* Parse args required to build the message */
13224   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13225     {
13226       if (unformat (i, "sw_if_index %d", &sw_if_index))
13227         sw_if_index_set = 1;
13228       else
13229         break;
13230     }
13231
13232   if (sw_if_index_set == 0)
13233     {
13234       sw_if_index = ~0;
13235     }
13236
13237   if (!vam->json_output)
13238     {
13239       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13240              "sw_if_index", "local", "remote", "vni",
13241              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13242     }
13243
13244   /* Get list of vxlan-tunnel interfaces */
13245   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13246
13247   mp->sw_if_index = htonl (sw_if_index);
13248
13249   S (mp);
13250
13251   /* Use a control ping for synchronization */
13252   MPING (CONTROL_PING, mp_ping);
13253   S (mp_ping);
13254
13255   W (ret);
13256   return ret;
13257 }
13258
13259
13260 u8 *
13261 format_l2_fib_mac_address (u8 * s, va_list * args)
13262 {
13263   u8 *a = va_arg (*args, u8 *);
13264
13265   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
13266                  a[2], a[3], a[4], a[5], a[6], a[7]);
13267 }
13268
13269 static void vl_api_l2_fib_table_details_t_handler
13270   (vl_api_l2_fib_table_details_t * mp)
13271 {
13272   vat_main_t *vam = &vat_main;
13273
13274   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13275          "       %d       %d     %d",
13276          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
13277          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13278          mp->bvi_mac);
13279 }
13280
13281 static void vl_api_l2_fib_table_details_t_handler_json
13282   (vl_api_l2_fib_table_details_t * mp)
13283 {
13284   vat_main_t *vam = &vat_main;
13285   vat_json_node_t *node = NULL;
13286
13287   if (VAT_JSON_ARRAY != vam->json_tree.type)
13288     {
13289       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13290       vat_json_init_array (&vam->json_tree);
13291     }
13292   node = vat_json_array_add (&vam->json_tree);
13293
13294   vat_json_init_object (node);
13295   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13296   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
13297   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13298   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13299   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13300   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13301 }
13302
13303 static int
13304 api_l2_fib_table_dump (vat_main_t * vam)
13305 {
13306   unformat_input_t *i = vam->input;
13307   vl_api_l2_fib_table_dump_t *mp;
13308   vl_api_control_ping_t *mp_ping;
13309   u32 bd_id;
13310   u8 bd_id_set = 0;
13311   int ret;
13312
13313   /* Parse args required to build the message */
13314   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13315     {
13316       if (unformat (i, "bd_id %d", &bd_id))
13317         bd_id_set = 1;
13318       else
13319         break;
13320     }
13321
13322   if (bd_id_set == 0)
13323     {
13324       errmsg ("missing bridge domain");
13325       return -99;
13326     }
13327
13328   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13329
13330   /* Get list of l2 fib entries */
13331   M (L2_FIB_TABLE_DUMP, mp);
13332
13333   mp->bd_id = ntohl (bd_id);
13334   S (mp);
13335
13336   /* Use a control ping for synchronization */
13337   MPING (CONTROL_PING, mp_ping);
13338   S (mp_ping);
13339
13340   W (ret);
13341   return ret;
13342 }
13343
13344
13345 static int
13346 api_interface_name_renumber (vat_main_t * vam)
13347 {
13348   unformat_input_t *line_input = vam->input;
13349   vl_api_interface_name_renumber_t *mp;
13350   u32 sw_if_index = ~0;
13351   u32 new_show_dev_instance = ~0;
13352   int ret;
13353
13354   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13355     {
13356       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13357                     &sw_if_index))
13358         ;
13359       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13360         ;
13361       else if (unformat (line_input, "new_show_dev_instance %d",
13362                          &new_show_dev_instance))
13363         ;
13364       else
13365         break;
13366     }
13367
13368   if (sw_if_index == ~0)
13369     {
13370       errmsg ("missing interface name or sw_if_index");
13371       return -99;
13372     }
13373
13374   if (new_show_dev_instance == ~0)
13375     {
13376       errmsg ("missing new_show_dev_instance");
13377       return -99;
13378     }
13379
13380   M (INTERFACE_NAME_RENUMBER, mp);
13381
13382   mp->sw_if_index = ntohl (sw_if_index);
13383   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13384
13385   S (mp);
13386   W (ret);
13387   return ret;
13388 }
13389
13390 static int
13391 api_want_ip4_arp_events (vat_main_t * vam)
13392 {
13393   unformat_input_t *line_input = vam->input;
13394   vl_api_want_ip4_arp_events_t *mp;
13395   ip4_address_t address;
13396   int address_set = 0;
13397   u32 enable_disable = 1;
13398   int ret;
13399
13400   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13401     {
13402       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
13403         address_set = 1;
13404       else if (unformat (line_input, "del"))
13405         enable_disable = 0;
13406       else
13407         break;
13408     }
13409
13410   if (address_set == 0)
13411     {
13412       errmsg ("missing addresses");
13413       return -99;
13414     }
13415
13416   M (WANT_IP4_ARP_EVENTS, mp);
13417   mp->enable_disable = enable_disable;
13418   mp->pid = htonl (getpid ());
13419   mp->address = address.as_u32;
13420
13421   S (mp);
13422   W (ret);
13423   return ret;
13424 }
13425
13426 static int
13427 api_want_ip6_nd_events (vat_main_t * vam)
13428 {
13429   unformat_input_t *line_input = vam->input;
13430   vl_api_want_ip6_nd_events_t *mp;
13431   ip6_address_t address;
13432   int address_set = 0;
13433   u32 enable_disable = 1;
13434   int ret;
13435
13436   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13437     {
13438       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
13439         address_set = 1;
13440       else if (unformat (line_input, "del"))
13441         enable_disable = 0;
13442       else
13443         break;
13444     }
13445
13446   if (address_set == 0)
13447     {
13448       errmsg ("missing addresses");
13449       return -99;
13450     }
13451
13452   M (WANT_IP6_ND_EVENTS, mp);
13453   mp->enable_disable = enable_disable;
13454   mp->pid = htonl (getpid ());
13455   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
13456
13457   S (mp);
13458   W (ret);
13459   return ret;
13460 }
13461
13462 static int
13463 api_want_l2_macs_events (vat_main_t * vam)
13464 {
13465   unformat_input_t *line_input = vam->input;
13466   vl_api_want_l2_macs_events_t *mp;
13467   u8 enable_disable = 1;
13468   u32 scan_delay = 0;
13469   u32 max_macs_in_event = 0;
13470   u32 learn_limit = 0;
13471   int ret;
13472
13473   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13474     {
13475       if (unformat (line_input, "learn-limit %d", &learn_limit))
13476         ;
13477       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13478         ;
13479       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13480         ;
13481       else if (unformat (line_input, "disable"))
13482         enable_disable = 0;
13483       else
13484         break;
13485     }
13486
13487   M (WANT_L2_MACS_EVENTS, mp);
13488   mp->enable_disable = enable_disable;
13489   mp->pid = htonl (getpid ());
13490   mp->learn_limit = htonl (learn_limit);
13491   mp->scan_delay = (u8) scan_delay;
13492   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13493   S (mp);
13494   W (ret);
13495   return ret;
13496 }
13497
13498 static int
13499 api_input_acl_set_interface (vat_main_t * vam)
13500 {
13501   unformat_input_t *i = vam->input;
13502   vl_api_input_acl_set_interface_t *mp;
13503   u32 sw_if_index;
13504   int sw_if_index_set;
13505   u32 ip4_table_index = ~0;
13506   u32 ip6_table_index = ~0;
13507   u32 l2_table_index = ~0;
13508   u8 is_add = 1;
13509   int ret;
13510
13511   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13512     {
13513       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13514         sw_if_index_set = 1;
13515       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13516         sw_if_index_set = 1;
13517       else if (unformat (i, "del"))
13518         is_add = 0;
13519       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13520         ;
13521       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13522         ;
13523       else if (unformat (i, "l2-table %d", &l2_table_index))
13524         ;
13525       else
13526         {
13527           clib_warning ("parse error '%U'", format_unformat_error, i);
13528           return -99;
13529         }
13530     }
13531
13532   if (sw_if_index_set == 0)
13533     {
13534       errmsg ("missing interface name or sw_if_index");
13535       return -99;
13536     }
13537
13538   M (INPUT_ACL_SET_INTERFACE, mp);
13539
13540   mp->sw_if_index = ntohl (sw_if_index);
13541   mp->ip4_table_index = ntohl (ip4_table_index);
13542   mp->ip6_table_index = ntohl (ip6_table_index);
13543   mp->l2_table_index = ntohl (l2_table_index);
13544   mp->is_add = is_add;
13545
13546   S (mp);
13547   W (ret);
13548   return ret;
13549 }
13550
13551 static int
13552 api_ip_address_dump (vat_main_t * vam)
13553 {
13554   unformat_input_t *i = vam->input;
13555   vl_api_ip_address_dump_t *mp;
13556   vl_api_control_ping_t *mp_ping;
13557   u32 sw_if_index = ~0;
13558   u8 sw_if_index_set = 0;
13559   u8 ipv4_set = 0;
13560   u8 ipv6_set = 0;
13561   int ret;
13562
13563   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13564     {
13565       if (unformat (i, "sw_if_index %d", &sw_if_index))
13566         sw_if_index_set = 1;
13567       else
13568         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13569         sw_if_index_set = 1;
13570       else if (unformat (i, "ipv4"))
13571         ipv4_set = 1;
13572       else if (unformat (i, "ipv6"))
13573         ipv6_set = 1;
13574       else
13575         break;
13576     }
13577
13578   if (ipv4_set && ipv6_set)
13579     {
13580       errmsg ("ipv4 and ipv6 flags cannot be both set");
13581       return -99;
13582     }
13583
13584   if ((!ipv4_set) && (!ipv6_set))
13585     {
13586       errmsg ("no ipv4 nor ipv6 flag set");
13587       return -99;
13588     }
13589
13590   if (sw_if_index_set == 0)
13591     {
13592       errmsg ("missing interface name or sw_if_index");
13593       return -99;
13594     }
13595
13596   vam->current_sw_if_index = sw_if_index;
13597   vam->is_ipv6 = ipv6_set;
13598
13599   M (IP_ADDRESS_DUMP, mp);
13600   mp->sw_if_index = ntohl (sw_if_index);
13601   mp->is_ipv6 = ipv6_set;
13602   S (mp);
13603
13604   /* Use a control ping for synchronization */
13605   MPING (CONTROL_PING, mp_ping);
13606   S (mp_ping);
13607
13608   W (ret);
13609   return ret;
13610 }
13611
13612 static int
13613 api_ip_dump (vat_main_t * vam)
13614 {
13615   vl_api_ip_dump_t *mp;
13616   vl_api_control_ping_t *mp_ping;
13617   unformat_input_t *in = vam->input;
13618   int ipv4_set = 0;
13619   int ipv6_set = 0;
13620   int is_ipv6;
13621   int i;
13622   int ret;
13623
13624   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13625     {
13626       if (unformat (in, "ipv4"))
13627         ipv4_set = 1;
13628       else if (unformat (in, "ipv6"))
13629         ipv6_set = 1;
13630       else
13631         break;
13632     }
13633
13634   if (ipv4_set && ipv6_set)
13635     {
13636       errmsg ("ipv4 and ipv6 flags cannot be both set");
13637       return -99;
13638     }
13639
13640   if ((!ipv4_set) && (!ipv6_set))
13641     {
13642       errmsg ("no ipv4 nor ipv6 flag set");
13643       return -99;
13644     }
13645
13646   is_ipv6 = ipv6_set;
13647   vam->is_ipv6 = is_ipv6;
13648
13649   /* free old data */
13650   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13651     {
13652       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13653     }
13654   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13655
13656   M (IP_DUMP, mp);
13657   mp->is_ipv6 = ipv6_set;
13658   S (mp);
13659
13660   /* Use a control ping for synchronization */
13661   MPING (CONTROL_PING, mp_ping);
13662   S (mp_ping);
13663
13664   W (ret);
13665   return ret;
13666 }
13667
13668 static int
13669 api_ipsec_spd_add_del (vat_main_t * vam)
13670 {
13671   unformat_input_t *i = vam->input;
13672   vl_api_ipsec_spd_add_del_t *mp;
13673   u32 spd_id = ~0;
13674   u8 is_add = 1;
13675   int ret;
13676
13677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13678     {
13679       if (unformat (i, "spd_id %d", &spd_id))
13680         ;
13681       else if (unformat (i, "del"))
13682         is_add = 0;
13683       else
13684         {
13685           clib_warning ("parse error '%U'", format_unformat_error, i);
13686           return -99;
13687         }
13688     }
13689   if (spd_id == ~0)
13690     {
13691       errmsg ("spd_id must be set");
13692       return -99;
13693     }
13694
13695   M (IPSEC_SPD_ADD_DEL, mp);
13696
13697   mp->spd_id = ntohl (spd_id);
13698   mp->is_add = is_add;
13699
13700   S (mp);
13701   W (ret);
13702   return ret;
13703 }
13704
13705 static int
13706 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13707 {
13708   unformat_input_t *i = vam->input;
13709   vl_api_ipsec_interface_add_del_spd_t *mp;
13710   u32 sw_if_index;
13711   u8 sw_if_index_set = 0;
13712   u32 spd_id = (u32) ~ 0;
13713   u8 is_add = 1;
13714   int ret;
13715
13716   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13717     {
13718       if (unformat (i, "del"))
13719         is_add = 0;
13720       else if (unformat (i, "spd_id %d", &spd_id))
13721         ;
13722       else
13723         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13724         sw_if_index_set = 1;
13725       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13726         sw_if_index_set = 1;
13727       else
13728         {
13729           clib_warning ("parse error '%U'", format_unformat_error, i);
13730           return -99;
13731         }
13732
13733     }
13734
13735   if (spd_id == (u32) ~ 0)
13736     {
13737       errmsg ("spd_id must be set");
13738       return -99;
13739     }
13740
13741   if (sw_if_index_set == 0)
13742     {
13743       errmsg ("missing interface name or sw_if_index");
13744       return -99;
13745     }
13746
13747   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13748
13749   mp->spd_id = ntohl (spd_id);
13750   mp->sw_if_index = ntohl (sw_if_index);
13751   mp->is_add = is_add;
13752
13753   S (mp);
13754   W (ret);
13755   return ret;
13756 }
13757
13758 static int
13759 api_ipsec_spd_add_del_entry (vat_main_t * vam)
13760 {
13761   unformat_input_t *i = vam->input;
13762   vl_api_ipsec_spd_add_del_entry_t *mp;
13763   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
13764   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13765   i32 priority = 0;
13766   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13767   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13768   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
13769   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
13770   int ret;
13771
13772   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
13773   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
13774   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
13775   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
13776   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
13777   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
13778
13779   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13780     {
13781       if (unformat (i, "del"))
13782         is_add = 0;
13783       if (unformat (i, "outbound"))
13784         is_outbound = 1;
13785       if (unformat (i, "inbound"))
13786         is_outbound = 0;
13787       else if (unformat (i, "spd_id %d", &spd_id))
13788         ;
13789       else if (unformat (i, "sa_id %d", &sa_id))
13790         ;
13791       else if (unformat (i, "priority %d", &priority))
13792         ;
13793       else if (unformat (i, "protocol %d", &protocol))
13794         ;
13795       else if (unformat (i, "lport_start %d", &lport_start))
13796         ;
13797       else if (unformat (i, "lport_stop %d", &lport_stop))
13798         ;
13799       else if (unformat (i, "rport_start %d", &rport_start))
13800         ;
13801       else if (unformat (i, "rport_stop %d", &rport_stop))
13802         ;
13803       else
13804         if (unformat
13805             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
13806         {
13807           is_ipv6 = 0;
13808           is_ip_any = 0;
13809         }
13810       else
13811         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
13812         {
13813           is_ipv6 = 0;
13814           is_ip_any = 0;
13815         }
13816       else
13817         if (unformat
13818             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
13819         {
13820           is_ipv6 = 0;
13821           is_ip_any = 0;
13822         }
13823       else
13824         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
13825         {
13826           is_ipv6 = 0;
13827           is_ip_any = 0;
13828         }
13829       else
13830         if (unformat
13831             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
13832         {
13833           is_ipv6 = 1;
13834           is_ip_any = 0;
13835         }
13836       else
13837         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
13838         {
13839           is_ipv6 = 1;
13840           is_ip_any = 0;
13841         }
13842       else
13843         if (unformat
13844             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
13845         {
13846           is_ipv6 = 1;
13847           is_ip_any = 0;
13848         }
13849       else
13850         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
13851         {
13852           is_ipv6 = 1;
13853           is_ip_any = 0;
13854         }
13855       else
13856         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13857         {
13858           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13859             {
13860               clib_warning ("unsupported action: 'resolve'");
13861               return -99;
13862             }
13863         }
13864       else
13865         {
13866           clib_warning ("parse error '%U'", format_unformat_error, i);
13867           return -99;
13868         }
13869
13870     }
13871
13872   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
13873
13874   mp->spd_id = ntohl (spd_id);
13875   mp->priority = ntohl (priority);
13876   mp->is_outbound = is_outbound;
13877
13878   mp->is_ipv6 = is_ipv6;
13879   if (is_ipv6 || is_ip_any)
13880     {
13881       clib_memcpy (mp->remote_address_start, &raddr6_start,
13882                    sizeof (ip6_address_t));
13883       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
13884                    sizeof (ip6_address_t));
13885       clib_memcpy (mp->local_address_start, &laddr6_start,
13886                    sizeof (ip6_address_t));
13887       clib_memcpy (mp->local_address_stop, &laddr6_stop,
13888                    sizeof (ip6_address_t));
13889     }
13890   else
13891     {
13892       clib_memcpy (mp->remote_address_start, &raddr4_start,
13893                    sizeof (ip4_address_t));
13894       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
13895                    sizeof (ip4_address_t));
13896       clib_memcpy (mp->local_address_start, &laddr4_start,
13897                    sizeof (ip4_address_t));
13898       clib_memcpy (mp->local_address_stop, &laddr4_stop,
13899                    sizeof (ip4_address_t));
13900     }
13901   mp->protocol = (u8) protocol;
13902   mp->local_port_start = ntohs ((u16) lport_start);
13903   mp->local_port_stop = ntohs ((u16) lport_stop);
13904   mp->remote_port_start = ntohs ((u16) rport_start);
13905   mp->remote_port_stop = ntohs ((u16) rport_stop);
13906   mp->policy = (u8) policy;
13907   mp->sa_id = ntohl (sa_id);
13908   mp->is_add = is_add;
13909   mp->is_ip_any = is_ip_any;
13910   S (mp);
13911   W (ret);
13912   return ret;
13913 }
13914
13915 static int
13916 api_ipsec_sad_add_del_entry (vat_main_t * vam)
13917 {
13918   unformat_input_t *i = vam->input;
13919   vl_api_ipsec_sad_add_del_entry_t *mp;
13920   u32 sad_id = 0, spi = 0;
13921   u8 *ck = 0, *ik = 0;
13922   u8 is_add = 1;
13923
13924   u8 protocol = IPSEC_PROTOCOL_AH;
13925   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
13926   u32 crypto_alg = 0, integ_alg = 0;
13927   ip4_address_t tun_src4;
13928   ip4_address_t tun_dst4;
13929   ip6_address_t tun_src6;
13930   ip6_address_t tun_dst6;
13931   int ret;
13932
13933   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13934     {
13935       if (unformat (i, "del"))
13936         is_add = 0;
13937       else if (unformat (i, "sad_id %d", &sad_id))
13938         ;
13939       else if (unformat (i, "spi %d", &spi))
13940         ;
13941       else if (unformat (i, "esp"))
13942         protocol = IPSEC_PROTOCOL_ESP;
13943       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
13944         {
13945           is_tunnel = 1;
13946           is_tunnel_ipv6 = 0;
13947         }
13948       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
13949         {
13950           is_tunnel = 1;
13951           is_tunnel_ipv6 = 0;
13952         }
13953       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
13954         {
13955           is_tunnel = 1;
13956           is_tunnel_ipv6 = 1;
13957         }
13958       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
13959         {
13960           is_tunnel = 1;
13961           is_tunnel_ipv6 = 1;
13962         }
13963       else
13964         if (unformat
13965             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
13966         {
13967           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
13968               crypto_alg >= IPSEC_CRYPTO_N_ALG)
13969             {
13970               clib_warning ("unsupported crypto-alg: '%U'",
13971                             format_ipsec_crypto_alg, crypto_alg);
13972               return -99;
13973             }
13974         }
13975       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13976         ;
13977       else
13978         if (unformat
13979             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
13980         {
13981           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
13982               integ_alg >= IPSEC_INTEG_N_ALG)
13983             {
13984               clib_warning ("unsupported integ-alg: '%U'",
13985                             format_ipsec_integ_alg, integ_alg);
13986               return -99;
13987             }
13988         }
13989       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13990         ;
13991       else
13992         {
13993           clib_warning ("parse error '%U'", format_unformat_error, i);
13994           return -99;
13995         }
13996
13997     }
13998
13999   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
14000
14001   mp->sad_id = ntohl (sad_id);
14002   mp->is_add = is_add;
14003   mp->protocol = protocol;
14004   mp->spi = ntohl (spi);
14005   mp->is_tunnel = is_tunnel;
14006   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
14007   mp->crypto_algorithm = crypto_alg;
14008   mp->integrity_algorithm = integ_alg;
14009   mp->crypto_key_length = vec_len (ck);
14010   mp->integrity_key_length = vec_len (ik);
14011
14012   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14013     mp->crypto_key_length = sizeof (mp->crypto_key);
14014
14015   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14016     mp->integrity_key_length = sizeof (mp->integrity_key);
14017
14018   if (ck)
14019     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14020   if (ik)
14021     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14022
14023   if (is_tunnel)
14024     {
14025       if (is_tunnel_ipv6)
14026         {
14027           clib_memcpy (mp->tunnel_src_address, &tun_src6,
14028                        sizeof (ip6_address_t));
14029           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
14030                        sizeof (ip6_address_t));
14031         }
14032       else
14033         {
14034           clib_memcpy (mp->tunnel_src_address, &tun_src4,
14035                        sizeof (ip4_address_t));
14036           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
14037                        sizeof (ip4_address_t));
14038         }
14039     }
14040
14041   S (mp);
14042   W (ret);
14043   return ret;
14044 }
14045
14046 static int
14047 api_ipsec_sa_set_key (vat_main_t * vam)
14048 {
14049   unformat_input_t *i = vam->input;
14050   vl_api_ipsec_sa_set_key_t *mp;
14051   u32 sa_id;
14052   u8 *ck = 0, *ik = 0;
14053   int ret;
14054
14055   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14056     {
14057       if (unformat (i, "sa_id %d", &sa_id))
14058         ;
14059       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14060         ;
14061       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14062         ;
14063       else
14064         {
14065           clib_warning ("parse error '%U'", format_unformat_error, i);
14066           return -99;
14067         }
14068     }
14069
14070   M (IPSEC_SA_SET_KEY, mp);
14071
14072   mp->sa_id = ntohl (sa_id);
14073   mp->crypto_key_length = vec_len (ck);
14074   mp->integrity_key_length = vec_len (ik);
14075
14076   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14077     mp->crypto_key_length = sizeof (mp->crypto_key);
14078
14079   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14080     mp->integrity_key_length = sizeof (mp->integrity_key);
14081
14082   if (ck)
14083     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14084   if (ik)
14085     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14086
14087   S (mp);
14088   W (ret);
14089   return ret;
14090 }
14091
14092 static int
14093 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14094 {
14095   unformat_input_t *i = vam->input;
14096   vl_api_ipsec_tunnel_if_add_del_t *mp;
14097   u32 local_spi = 0, remote_spi = 0;
14098   u32 crypto_alg = 0, integ_alg = 0;
14099   u8 *lck = NULL, *rck = NULL;
14100   u8 *lik = NULL, *rik = NULL;
14101   ip4_address_t local_ip = { {0} };
14102   ip4_address_t remote_ip = { {0} };
14103   u8 is_add = 1;
14104   u8 esn = 0;
14105   u8 anti_replay = 0;
14106   int ret;
14107
14108   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14109     {
14110       if (unformat (i, "del"))
14111         is_add = 0;
14112       else if (unformat (i, "esn"))
14113         esn = 1;
14114       else if (unformat (i, "anti_replay"))
14115         anti_replay = 1;
14116       else if (unformat (i, "local_spi %d", &local_spi))
14117         ;
14118       else if (unformat (i, "remote_spi %d", &remote_spi))
14119         ;
14120       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
14121         ;
14122       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
14123         ;
14124       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14125         ;
14126       else
14127         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14128         ;
14129       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14130         ;
14131       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14132         ;
14133       else
14134         if (unformat
14135             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14136         {
14137           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14138               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14139             {
14140               errmsg ("unsupported crypto-alg: '%U'\n",
14141                       format_ipsec_crypto_alg, crypto_alg);
14142               return -99;
14143             }
14144         }
14145       else
14146         if (unformat
14147             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14148         {
14149           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14150               integ_alg >= IPSEC_INTEG_N_ALG)
14151             {
14152               errmsg ("unsupported integ-alg: '%U'\n",
14153                       format_ipsec_integ_alg, integ_alg);
14154               return -99;
14155             }
14156         }
14157       else
14158         {
14159           errmsg ("parse error '%U'\n", format_unformat_error, i);
14160           return -99;
14161         }
14162     }
14163
14164   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14165
14166   mp->is_add = is_add;
14167   mp->esn = esn;
14168   mp->anti_replay = anti_replay;
14169
14170   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
14171   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
14172
14173   mp->local_spi = htonl (local_spi);
14174   mp->remote_spi = htonl (remote_spi);
14175   mp->crypto_alg = (u8) crypto_alg;
14176
14177   mp->local_crypto_key_len = 0;
14178   if (lck)
14179     {
14180       mp->local_crypto_key_len = vec_len (lck);
14181       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14182         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14183       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14184     }
14185
14186   mp->remote_crypto_key_len = 0;
14187   if (rck)
14188     {
14189       mp->remote_crypto_key_len = vec_len (rck);
14190       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14191         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14192       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14193     }
14194
14195   mp->integ_alg = (u8) integ_alg;
14196
14197   mp->local_integ_key_len = 0;
14198   if (lik)
14199     {
14200       mp->local_integ_key_len = vec_len (lik);
14201       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14202         mp->local_integ_key_len = sizeof (mp->local_integ_key);
14203       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14204     }
14205
14206   mp->remote_integ_key_len = 0;
14207   if (rik)
14208     {
14209       mp->remote_integ_key_len = vec_len (rik);
14210       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14211         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14212       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14213     }
14214
14215   S (mp);
14216   W (ret);
14217   return ret;
14218 }
14219
14220 static void
14221 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14222 {
14223   vat_main_t *vam = &vat_main;
14224
14225   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14226          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
14227          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
14228          "tunnel_src_addr %U tunnel_dst_addr %U "
14229          "salt %u seq_outbound %lu last_seq_inbound %lu "
14230          "replay_window %lu total_data_size %lu\n",
14231          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
14232          mp->protocol,
14233          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
14234          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
14235          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
14236          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14237          mp->tunnel_src_addr,
14238          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14239          mp->tunnel_dst_addr,
14240          ntohl (mp->salt),
14241          clib_net_to_host_u64 (mp->seq_outbound),
14242          clib_net_to_host_u64 (mp->last_seq_inbound),
14243          clib_net_to_host_u64 (mp->replay_window),
14244          clib_net_to_host_u64 (mp->total_data_size));
14245 }
14246
14247 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14248 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14249
14250 static void vl_api_ipsec_sa_details_t_handler_json
14251   (vl_api_ipsec_sa_details_t * mp)
14252 {
14253   vat_main_t *vam = &vat_main;
14254   vat_json_node_t *node = NULL;
14255   struct in_addr src_ip4, dst_ip4;
14256   struct in6_addr src_ip6, dst_ip6;
14257
14258   if (VAT_JSON_ARRAY != vam->json_tree.type)
14259     {
14260       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14261       vat_json_init_array (&vam->json_tree);
14262     }
14263   node = vat_json_array_add (&vam->json_tree);
14264
14265   vat_json_init_object (node);
14266   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
14267   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14268   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
14269   vat_json_object_add_uint (node, "proto", mp->protocol);
14270   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
14271   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
14272   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
14273   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
14274   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
14275   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
14276   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
14277                              mp->crypto_key_len);
14278   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
14279                              mp->integ_key_len);
14280   if (mp->is_tunnel_ip6)
14281     {
14282       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
14283       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
14284       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
14285       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
14286     }
14287   else
14288     {
14289       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
14290       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
14291       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
14292       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
14293     }
14294   vat_json_object_add_uint (node, "replay_window",
14295                             clib_net_to_host_u64 (mp->replay_window));
14296   vat_json_object_add_uint (node, "total_data_size",
14297                             clib_net_to_host_u64 (mp->total_data_size));
14298
14299 }
14300
14301 static int
14302 api_ipsec_sa_dump (vat_main_t * vam)
14303 {
14304   unformat_input_t *i = vam->input;
14305   vl_api_ipsec_sa_dump_t *mp;
14306   vl_api_control_ping_t *mp_ping;
14307   u32 sa_id = ~0;
14308   int ret;
14309
14310   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14311     {
14312       if (unformat (i, "sa_id %d", &sa_id))
14313         ;
14314       else
14315         {
14316           clib_warning ("parse error '%U'", format_unformat_error, i);
14317           return -99;
14318         }
14319     }
14320
14321   M (IPSEC_SA_DUMP, mp);
14322
14323   mp->sa_id = ntohl (sa_id);
14324
14325   S (mp);
14326
14327   /* Use a control ping for synchronization */
14328   M (CONTROL_PING, mp_ping);
14329   S (mp_ping);
14330
14331   W (ret);
14332   return ret;
14333 }
14334
14335 static int
14336 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
14337 {
14338   unformat_input_t *i = vam->input;
14339   vl_api_ipsec_tunnel_if_set_key_t *mp;
14340   u32 sw_if_index = ~0;
14341   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
14342   u8 *key = 0;
14343   u32 alg = ~0;
14344   int ret;
14345
14346   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14347     {
14348       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14349         ;
14350       else
14351         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
14352         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
14353       else
14354         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
14355         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
14356       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
14357         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
14358       else
14359         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
14360         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
14361       else if (unformat (i, "%U", unformat_hex_string, &key))
14362         ;
14363       else
14364         {
14365           clib_warning ("parse error '%U'", format_unformat_error, i);
14366           return -99;
14367         }
14368     }
14369
14370   if (sw_if_index == ~0)
14371     {
14372       errmsg ("interface must be specified");
14373       return -99;
14374     }
14375
14376   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
14377     {
14378       errmsg ("key type must be specified");
14379       return -99;
14380     }
14381
14382   if (alg == ~0)
14383     {
14384       errmsg ("algorithm must be specified");
14385       return -99;
14386     }
14387
14388   if (vec_len (key) == 0)
14389     {
14390       errmsg ("key must be specified");
14391       return -99;
14392     }
14393
14394   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
14395
14396   mp->sw_if_index = htonl (sw_if_index);
14397   mp->alg = alg;
14398   mp->key_type = key_type;
14399   mp->key_len = vec_len (key);
14400   clib_memcpy (mp->key, key, vec_len (key));
14401
14402   S (mp);
14403   W (ret);
14404
14405   return ret;
14406 }
14407
14408 static int
14409 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14410 {
14411   unformat_input_t *i = vam->input;
14412   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14413   u32 sw_if_index = ~0;
14414   u32 sa_id = ~0;
14415   u8 is_outbound = (u8) ~ 0;
14416   int ret;
14417
14418   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14419     {
14420       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14421         ;
14422       else if (unformat (i, "sa_id %d", &sa_id))
14423         ;
14424       else if (unformat (i, "outbound"))
14425         is_outbound = 1;
14426       else if (unformat (i, "inbound"))
14427         is_outbound = 0;
14428       else
14429         {
14430           clib_warning ("parse error '%U'", format_unformat_error, i);
14431           return -99;
14432         }
14433     }
14434
14435   if (sw_if_index == ~0)
14436     {
14437       errmsg ("interface must be specified");
14438       return -99;
14439     }
14440
14441   if (sa_id == ~0)
14442     {
14443       errmsg ("SA ID must be specified");
14444       return -99;
14445     }
14446
14447   M (IPSEC_TUNNEL_IF_SET_SA, mp);
14448
14449   mp->sw_if_index = htonl (sw_if_index);
14450   mp->sa_id = htonl (sa_id);
14451   mp->is_outbound = is_outbound;
14452
14453   S (mp);
14454   W (ret);
14455
14456   return ret;
14457 }
14458
14459 static int
14460 api_ikev2_profile_add_del (vat_main_t * vam)
14461 {
14462   unformat_input_t *i = vam->input;
14463   vl_api_ikev2_profile_add_del_t *mp;
14464   u8 is_add = 1;
14465   u8 *name = 0;
14466   int ret;
14467
14468   const char *valid_chars = "a-zA-Z0-9_";
14469
14470   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14471     {
14472       if (unformat (i, "del"))
14473         is_add = 0;
14474       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14475         vec_add1 (name, 0);
14476       else
14477         {
14478           errmsg ("parse error '%U'", format_unformat_error, i);
14479           return -99;
14480         }
14481     }
14482
14483   if (!vec_len (name))
14484     {
14485       errmsg ("profile name must be specified");
14486       return -99;
14487     }
14488
14489   if (vec_len (name) > 64)
14490     {
14491       errmsg ("profile name too long");
14492       return -99;
14493     }
14494
14495   M (IKEV2_PROFILE_ADD_DEL, mp);
14496
14497   clib_memcpy (mp->name, name, vec_len (name));
14498   mp->is_add = is_add;
14499   vec_free (name);
14500
14501   S (mp);
14502   W (ret);
14503   return ret;
14504 }
14505
14506 static int
14507 api_ikev2_profile_set_auth (vat_main_t * vam)
14508 {
14509   unformat_input_t *i = vam->input;
14510   vl_api_ikev2_profile_set_auth_t *mp;
14511   u8 *name = 0;
14512   u8 *data = 0;
14513   u32 auth_method = 0;
14514   u8 is_hex = 0;
14515   int ret;
14516
14517   const char *valid_chars = "a-zA-Z0-9_";
14518
14519   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14520     {
14521       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14522         vec_add1 (name, 0);
14523       else if (unformat (i, "auth_method %U",
14524                          unformat_ikev2_auth_method, &auth_method))
14525         ;
14526       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
14527         is_hex = 1;
14528       else if (unformat (i, "auth_data %v", &data))
14529         ;
14530       else
14531         {
14532           errmsg ("parse error '%U'", format_unformat_error, i);
14533           return -99;
14534         }
14535     }
14536
14537   if (!vec_len (name))
14538     {
14539       errmsg ("profile name must be specified");
14540       return -99;
14541     }
14542
14543   if (vec_len (name) > 64)
14544     {
14545       errmsg ("profile name too long");
14546       return -99;
14547     }
14548
14549   if (!vec_len (data))
14550     {
14551       errmsg ("auth_data must be specified");
14552       return -99;
14553     }
14554
14555   if (!auth_method)
14556     {
14557       errmsg ("auth_method must be specified");
14558       return -99;
14559     }
14560
14561   M (IKEV2_PROFILE_SET_AUTH, mp);
14562
14563   mp->is_hex = is_hex;
14564   mp->auth_method = (u8) auth_method;
14565   mp->data_len = vec_len (data);
14566   clib_memcpy (mp->name, name, vec_len (name));
14567   clib_memcpy (mp->data, data, vec_len (data));
14568   vec_free (name);
14569   vec_free (data);
14570
14571   S (mp);
14572   W (ret);
14573   return ret;
14574 }
14575
14576 static int
14577 api_ikev2_profile_set_id (vat_main_t * vam)
14578 {
14579   unformat_input_t *i = vam->input;
14580   vl_api_ikev2_profile_set_id_t *mp;
14581   u8 *name = 0;
14582   u8 *data = 0;
14583   u8 is_local = 0;
14584   u32 id_type = 0;
14585   ip4_address_t ip4;
14586   int ret;
14587
14588   const char *valid_chars = "a-zA-Z0-9_";
14589
14590   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14591     {
14592       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14593         vec_add1 (name, 0);
14594       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
14595         ;
14596       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
14597         {
14598           data = vec_new (u8, 4);
14599           clib_memcpy (data, ip4.as_u8, 4);
14600         }
14601       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
14602         ;
14603       else if (unformat (i, "id_data %v", &data))
14604         ;
14605       else if (unformat (i, "local"))
14606         is_local = 1;
14607       else if (unformat (i, "remote"))
14608         is_local = 0;
14609       else
14610         {
14611           errmsg ("parse error '%U'", format_unformat_error, i);
14612           return -99;
14613         }
14614     }
14615
14616   if (!vec_len (name))
14617     {
14618       errmsg ("profile name must be specified");
14619       return -99;
14620     }
14621
14622   if (vec_len (name) > 64)
14623     {
14624       errmsg ("profile name too long");
14625       return -99;
14626     }
14627
14628   if (!vec_len (data))
14629     {
14630       errmsg ("id_data must be specified");
14631       return -99;
14632     }
14633
14634   if (!id_type)
14635     {
14636       errmsg ("id_type must be specified");
14637       return -99;
14638     }
14639
14640   M (IKEV2_PROFILE_SET_ID, mp);
14641
14642   mp->is_local = is_local;
14643   mp->id_type = (u8) id_type;
14644   mp->data_len = vec_len (data);
14645   clib_memcpy (mp->name, name, vec_len (name));
14646   clib_memcpy (mp->data, data, vec_len (data));
14647   vec_free (name);
14648   vec_free (data);
14649
14650   S (mp);
14651   W (ret);
14652   return ret;
14653 }
14654
14655 static int
14656 api_ikev2_profile_set_ts (vat_main_t * vam)
14657 {
14658   unformat_input_t *i = vam->input;
14659   vl_api_ikev2_profile_set_ts_t *mp;
14660   u8 *name = 0;
14661   u8 is_local = 0;
14662   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
14663   ip4_address_t start_addr, end_addr;
14664
14665   const char *valid_chars = "a-zA-Z0-9_";
14666   int ret;
14667
14668   start_addr.as_u32 = 0;
14669   end_addr.as_u32 = (u32) ~ 0;
14670
14671   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14672     {
14673       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14674         vec_add1 (name, 0);
14675       else if (unformat (i, "protocol %d", &proto))
14676         ;
14677       else if (unformat (i, "start_port %d", &start_port))
14678         ;
14679       else if (unformat (i, "end_port %d", &end_port))
14680         ;
14681       else
14682         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
14683         ;
14684       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
14685         ;
14686       else if (unformat (i, "local"))
14687         is_local = 1;
14688       else if (unformat (i, "remote"))
14689         is_local = 0;
14690       else
14691         {
14692           errmsg ("parse error '%U'", format_unformat_error, i);
14693           return -99;
14694         }
14695     }
14696
14697   if (!vec_len (name))
14698     {
14699       errmsg ("profile name must be specified");
14700       return -99;
14701     }
14702
14703   if (vec_len (name) > 64)
14704     {
14705       errmsg ("profile name too long");
14706       return -99;
14707     }
14708
14709   M (IKEV2_PROFILE_SET_TS, mp);
14710
14711   mp->is_local = is_local;
14712   mp->proto = (u8) proto;
14713   mp->start_port = (u16) start_port;
14714   mp->end_port = (u16) end_port;
14715   mp->start_addr = start_addr.as_u32;
14716   mp->end_addr = end_addr.as_u32;
14717   clib_memcpy (mp->name, name, vec_len (name));
14718   vec_free (name);
14719
14720   S (mp);
14721   W (ret);
14722   return ret;
14723 }
14724
14725 static int
14726 api_ikev2_set_local_key (vat_main_t * vam)
14727 {
14728   unformat_input_t *i = vam->input;
14729   vl_api_ikev2_set_local_key_t *mp;
14730   u8 *file = 0;
14731   int ret;
14732
14733   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14734     {
14735       if (unformat (i, "file %v", &file))
14736         vec_add1 (file, 0);
14737       else
14738         {
14739           errmsg ("parse error '%U'", format_unformat_error, i);
14740           return -99;
14741         }
14742     }
14743
14744   if (!vec_len (file))
14745     {
14746       errmsg ("RSA key file must be specified");
14747       return -99;
14748     }
14749
14750   if (vec_len (file) > 256)
14751     {
14752       errmsg ("file name too long");
14753       return -99;
14754     }
14755
14756   M (IKEV2_SET_LOCAL_KEY, mp);
14757
14758   clib_memcpy (mp->key_file, file, vec_len (file));
14759   vec_free (file);
14760
14761   S (mp);
14762   W (ret);
14763   return ret;
14764 }
14765
14766 static int
14767 api_ikev2_set_responder (vat_main_t * vam)
14768 {
14769   unformat_input_t *i = vam->input;
14770   vl_api_ikev2_set_responder_t *mp;
14771   int ret;
14772   u8 *name = 0;
14773   u32 sw_if_index = ~0;
14774   ip4_address_t address;
14775
14776   const char *valid_chars = "a-zA-Z0-9_";
14777
14778   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14779     {
14780       if (unformat
14781           (i, "%U interface %d address %U", unformat_token, valid_chars,
14782            &name, &sw_if_index, unformat_ip4_address, &address))
14783         vec_add1 (name, 0);
14784       else
14785         {
14786           errmsg ("parse error '%U'", format_unformat_error, i);
14787           return -99;
14788         }
14789     }
14790
14791   if (!vec_len (name))
14792     {
14793       errmsg ("profile name must be specified");
14794       return -99;
14795     }
14796
14797   if (vec_len (name) > 64)
14798     {
14799       errmsg ("profile name too long");
14800       return -99;
14801     }
14802
14803   M (IKEV2_SET_RESPONDER, mp);
14804
14805   clib_memcpy (mp->name, name, vec_len (name));
14806   vec_free (name);
14807
14808   mp->sw_if_index = sw_if_index;
14809   clib_memcpy (mp->address, &address, sizeof (address));
14810
14811   S (mp);
14812   W (ret);
14813   return ret;
14814 }
14815
14816 static int
14817 api_ikev2_set_ike_transforms (vat_main_t * vam)
14818 {
14819   unformat_input_t *i = vam->input;
14820   vl_api_ikev2_set_ike_transforms_t *mp;
14821   int ret;
14822   u8 *name = 0;
14823   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
14824
14825   const char *valid_chars = "a-zA-Z0-9_";
14826
14827   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14828     {
14829       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
14830                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
14831         vec_add1 (name, 0);
14832       else
14833         {
14834           errmsg ("parse error '%U'", format_unformat_error, i);
14835           return -99;
14836         }
14837     }
14838
14839   if (!vec_len (name))
14840     {
14841       errmsg ("profile name must be specified");
14842       return -99;
14843     }
14844
14845   if (vec_len (name) > 64)
14846     {
14847       errmsg ("profile name too long");
14848       return -99;
14849     }
14850
14851   M (IKEV2_SET_IKE_TRANSFORMS, mp);
14852
14853   clib_memcpy (mp->name, name, vec_len (name));
14854   vec_free (name);
14855   mp->crypto_alg = crypto_alg;
14856   mp->crypto_key_size = crypto_key_size;
14857   mp->integ_alg = integ_alg;
14858   mp->dh_group = dh_group;
14859
14860   S (mp);
14861   W (ret);
14862   return ret;
14863 }
14864
14865
14866 static int
14867 api_ikev2_set_esp_transforms (vat_main_t * vam)
14868 {
14869   unformat_input_t *i = vam->input;
14870   vl_api_ikev2_set_esp_transforms_t *mp;
14871   int ret;
14872   u8 *name = 0;
14873   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
14874
14875   const char *valid_chars = "a-zA-Z0-9_";
14876
14877   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14878     {
14879       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
14880                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
14881         vec_add1 (name, 0);
14882       else
14883         {
14884           errmsg ("parse error '%U'", format_unformat_error, i);
14885           return -99;
14886         }
14887     }
14888
14889   if (!vec_len (name))
14890     {
14891       errmsg ("profile name must be specified");
14892       return -99;
14893     }
14894
14895   if (vec_len (name) > 64)
14896     {
14897       errmsg ("profile name too long");
14898       return -99;
14899     }
14900
14901   M (IKEV2_SET_ESP_TRANSFORMS, mp);
14902
14903   clib_memcpy (mp->name, name, vec_len (name));
14904   vec_free (name);
14905   mp->crypto_alg = crypto_alg;
14906   mp->crypto_key_size = crypto_key_size;
14907   mp->integ_alg = integ_alg;
14908   mp->dh_group = dh_group;
14909
14910   S (mp);
14911   W (ret);
14912   return ret;
14913 }
14914
14915 static int
14916 api_ikev2_set_sa_lifetime (vat_main_t * vam)
14917 {
14918   unformat_input_t *i = vam->input;
14919   vl_api_ikev2_set_sa_lifetime_t *mp;
14920   int ret;
14921   u8 *name = 0;
14922   u64 lifetime, lifetime_maxdata;
14923   u32 lifetime_jitter, handover;
14924
14925   const char *valid_chars = "a-zA-Z0-9_";
14926
14927   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14928     {
14929       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
14930                     &lifetime, &lifetime_jitter, &handover,
14931                     &lifetime_maxdata))
14932         vec_add1 (name, 0);
14933       else
14934         {
14935           errmsg ("parse error '%U'", format_unformat_error, i);
14936           return -99;
14937         }
14938     }
14939
14940   if (!vec_len (name))
14941     {
14942       errmsg ("profile name must be specified");
14943       return -99;
14944     }
14945
14946   if (vec_len (name) > 64)
14947     {
14948       errmsg ("profile name too long");
14949       return -99;
14950     }
14951
14952   M (IKEV2_SET_SA_LIFETIME, mp);
14953
14954   clib_memcpy (mp->name, name, vec_len (name));
14955   vec_free (name);
14956   mp->lifetime = lifetime;
14957   mp->lifetime_jitter = lifetime_jitter;
14958   mp->handover = handover;
14959   mp->lifetime_maxdata = lifetime_maxdata;
14960
14961   S (mp);
14962   W (ret);
14963   return ret;
14964 }
14965
14966 static int
14967 api_ikev2_initiate_sa_init (vat_main_t * vam)
14968 {
14969   unformat_input_t *i = vam->input;
14970   vl_api_ikev2_initiate_sa_init_t *mp;
14971   int ret;
14972   u8 *name = 0;
14973
14974   const char *valid_chars = "a-zA-Z0-9_";
14975
14976   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14977     {
14978       if (unformat (i, "%U", unformat_token, valid_chars, &name))
14979         vec_add1 (name, 0);
14980       else
14981         {
14982           errmsg ("parse error '%U'", format_unformat_error, i);
14983           return -99;
14984         }
14985     }
14986
14987   if (!vec_len (name))
14988     {
14989       errmsg ("profile name must be specified");
14990       return -99;
14991     }
14992
14993   if (vec_len (name) > 64)
14994     {
14995       errmsg ("profile name too long");
14996       return -99;
14997     }
14998
14999   M (IKEV2_INITIATE_SA_INIT, mp);
15000
15001   clib_memcpy (mp->name, name, vec_len (name));
15002   vec_free (name);
15003
15004   S (mp);
15005   W (ret);
15006   return ret;
15007 }
15008
15009 static int
15010 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
15011 {
15012   unformat_input_t *i = vam->input;
15013   vl_api_ikev2_initiate_del_ike_sa_t *mp;
15014   int ret;
15015   u64 ispi;
15016
15017
15018   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15019     {
15020       if (unformat (i, "%lx", &ispi))
15021         ;
15022       else
15023         {
15024           errmsg ("parse error '%U'", format_unformat_error, i);
15025           return -99;
15026         }
15027     }
15028
15029   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
15030
15031   mp->ispi = ispi;
15032
15033   S (mp);
15034   W (ret);
15035   return ret;
15036 }
15037
15038 static int
15039 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
15040 {
15041   unformat_input_t *i = vam->input;
15042   vl_api_ikev2_initiate_del_child_sa_t *mp;
15043   int ret;
15044   u32 ispi;
15045
15046
15047   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15048     {
15049       if (unformat (i, "%x", &ispi))
15050         ;
15051       else
15052         {
15053           errmsg ("parse error '%U'", format_unformat_error, i);
15054           return -99;
15055         }
15056     }
15057
15058   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
15059
15060   mp->ispi = ispi;
15061
15062   S (mp);
15063   W (ret);
15064   return ret;
15065 }
15066
15067 static int
15068 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
15069 {
15070   unformat_input_t *i = vam->input;
15071   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
15072   int ret;
15073   u32 ispi;
15074
15075
15076   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15077     {
15078       if (unformat (i, "%x", &ispi))
15079         ;
15080       else
15081         {
15082           errmsg ("parse error '%U'", format_unformat_error, i);
15083           return -99;
15084         }
15085     }
15086
15087   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
15088
15089   mp->ispi = ispi;
15090
15091   S (mp);
15092   W (ret);
15093   return ret;
15094 }
15095
15096 /*
15097  * MAP
15098  */
15099 static int
15100 api_map_add_domain (vat_main_t * vam)
15101 {
15102   unformat_input_t *i = vam->input;
15103   vl_api_map_add_domain_t *mp;
15104
15105   ip4_address_t ip4_prefix;
15106   ip6_address_t ip6_prefix;
15107   ip6_address_t ip6_src;
15108   u32 num_m_args = 0;
15109   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
15110     0, psid_length = 0;
15111   u8 is_translation = 0;
15112   u32 mtu = 0;
15113   u32 ip6_src_len = 128;
15114   int ret;
15115
15116   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15117     {
15118       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
15119                     &ip4_prefix, &ip4_prefix_len))
15120         num_m_args++;
15121       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
15122                          &ip6_prefix, &ip6_prefix_len))
15123         num_m_args++;
15124       else
15125         if (unformat
15126             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
15127              &ip6_src_len))
15128         num_m_args++;
15129       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
15130         num_m_args++;
15131       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
15132         num_m_args++;
15133       else if (unformat (i, "psid-offset %d", &psid_offset))
15134         num_m_args++;
15135       else if (unformat (i, "psid-len %d", &psid_length))
15136         num_m_args++;
15137       else if (unformat (i, "mtu %d", &mtu))
15138         num_m_args++;
15139       else if (unformat (i, "map-t"))
15140         is_translation = 1;
15141       else
15142         {
15143           clib_warning ("parse error '%U'", format_unformat_error, i);
15144           return -99;
15145         }
15146     }
15147
15148   if (num_m_args < 3)
15149     {
15150       errmsg ("mandatory argument(s) missing");
15151       return -99;
15152     }
15153
15154   /* Construct the API message */
15155   M (MAP_ADD_DOMAIN, mp);
15156
15157   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
15158   mp->ip4_prefix_len = ip4_prefix_len;
15159
15160   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
15161   mp->ip6_prefix_len = ip6_prefix_len;
15162
15163   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
15164   mp->ip6_src_prefix_len = ip6_src_len;
15165
15166   mp->ea_bits_len = ea_bits_len;
15167   mp->psid_offset = psid_offset;
15168   mp->psid_length = psid_length;
15169   mp->is_translation = is_translation;
15170   mp->mtu = htons (mtu);
15171
15172   /* send it... */
15173   S (mp);
15174
15175   /* Wait for a reply, return good/bad news  */
15176   W (ret);
15177   return ret;
15178 }
15179
15180 static int
15181 api_map_del_domain (vat_main_t * vam)
15182 {
15183   unformat_input_t *i = vam->input;
15184   vl_api_map_del_domain_t *mp;
15185
15186   u32 num_m_args = 0;
15187   u32 index;
15188   int ret;
15189
15190   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15191     {
15192       if (unformat (i, "index %d", &index))
15193         num_m_args++;
15194       else
15195         {
15196           clib_warning ("parse error '%U'", format_unformat_error, i);
15197           return -99;
15198         }
15199     }
15200
15201   if (num_m_args != 1)
15202     {
15203       errmsg ("mandatory argument(s) missing");
15204       return -99;
15205     }
15206
15207   /* Construct the API message */
15208   M (MAP_DEL_DOMAIN, mp);
15209
15210   mp->index = ntohl (index);
15211
15212   /* send it... */
15213   S (mp);
15214
15215   /* Wait for a reply, return good/bad news  */
15216   W (ret);
15217   return ret;
15218 }
15219
15220 static int
15221 api_map_add_del_rule (vat_main_t * vam)
15222 {
15223   unformat_input_t *i = vam->input;
15224   vl_api_map_add_del_rule_t *mp;
15225   u8 is_add = 1;
15226   ip6_address_t ip6_dst;
15227   u32 num_m_args = 0, index, psid = 0;
15228   int ret;
15229
15230   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15231     {
15232       if (unformat (i, "index %d", &index))
15233         num_m_args++;
15234       else if (unformat (i, "psid %d", &psid))
15235         num_m_args++;
15236       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
15237         num_m_args++;
15238       else if (unformat (i, "del"))
15239         {
15240           is_add = 0;
15241         }
15242       else
15243         {
15244           clib_warning ("parse error '%U'", format_unformat_error, i);
15245           return -99;
15246         }
15247     }
15248
15249   /* Construct the API message */
15250   M (MAP_ADD_DEL_RULE, mp);
15251
15252   mp->index = ntohl (index);
15253   mp->is_add = is_add;
15254   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
15255   mp->psid = ntohs (psid);
15256
15257   /* send it... */
15258   S (mp);
15259
15260   /* Wait for a reply, return good/bad news  */
15261   W (ret);
15262   return ret;
15263 }
15264
15265 static int
15266 api_map_domain_dump (vat_main_t * vam)
15267 {
15268   vl_api_map_domain_dump_t *mp;
15269   vl_api_control_ping_t *mp_ping;
15270   int ret;
15271
15272   /* Construct the API message */
15273   M (MAP_DOMAIN_DUMP, mp);
15274
15275   /* send it... */
15276   S (mp);
15277
15278   /* Use a control ping for synchronization */
15279   MPING (CONTROL_PING, mp_ping);
15280   S (mp_ping);
15281
15282   W (ret);
15283   return ret;
15284 }
15285
15286 static int
15287 api_map_rule_dump (vat_main_t * vam)
15288 {
15289   unformat_input_t *i = vam->input;
15290   vl_api_map_rule_dump_t *mp;
15291   vl_api_control_ping_t *mp_ping;
15292   u32 domain_index = ~0;
15293   int ret;
15294
15295   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15296     {
15297       if (unformat (i, "index %u", &domain_index))
15298         ;
15299       else
15300         break;
15301     }
15302
15303   if (domain_index == ~0)
15304     {
15305       clib_warning ("parse error: domain index expected");
15306       return -99;
15307     }
15308
15309   /* Construct the API message */
15310   M (MAP_RULE_DUMP, mp);
15311
15312   mp->domain_index = htonl (domain_index);
15313
15314   /* send it... */
15315   S (mp);
15316
15317   /* Use a control ping for synchronization */
15318   MPING (CONTROL_PING, mp_ping);
15319   S (mp_ping);
15320
15321   W (ret);
15322   return ret;
15323 }
15324
15325 static void vl_api_map_add_domain_reply_t_handler
15326   (vl_api_map_add_domain_reply_t * mp)
15327 {
15328   vat_main_t *vam = &vat_main;
15329   i32 retval = ntohl (mp->retval);
15330
15331   if (vam->async_mode)
15332     {
15333       vam->async_errors += (retval < 0);
15334     }
15335   else
15336     {
15337       vam->retval = retval;
15338       vam->result_ready = 1;
15339     }
15340 }
15341
15342 static void vl_api_map_add_domain_reply_t_handler_json
15343   (vl_api_map_add_domain_reply_t * mp)
15344 {
15345   vat_main_t *vam = &vat_main;
15346   vat_json_node_t node;
15347
15348   vat_json_init_object (&node);
15349   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
15350   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
15351
15352   vat_json_print (vam->ofp, &node);
15353   vat_json_free (&node);
15354
15355   vam->retval = ntohl (mp->retval);
15356   vam->result_ready = 1;
15357 }
15358
15359 static int
15360 api_get_first_msg_id (vat_main_t * vam)
15361 {
15362   vl_api_get_first_msg_id_t *mp;
15363   unformat_input_t *i = vam->input;
15364   u8 *name;
15365   u8 name_set = 0;
15366   int ret;
15367
15368   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15369     {
15370       if (unformat (i, "client %s", &name))
15371         name_set = 1;
15372       else
15373         break;
15374     }
15375
15376   if (name_set == 0)
15377     {
15378       errmsg ("missing client name");
15379       return -99;
15380     }
15381   vec_add1 (name, 0);
15382
15383   if (vec_len (name) > 63)
15384     {
15385       errmsg ("client name too long");
15386       return -99;
15387     }
15388
15389   M (GET_FIRST_MSG_ID, mp);
15390   clib_memcpy (mp->name, name, vec_len (name));
15391   S (mp);
15392   W (ret);
15393   return ret;
15394 }
15395
15396 static int
15397 api_cop_interface_enable_disable (vat_main_t * vam)
15398 {
15399   unformat_input_t *line_input = vam->input;
15400   vl_api_cop_interface_enable_disable_t *mp;
15401   u32 sw_if_index = ~0;
15402   u8 enable_disable = 1;
15403   int ret;
15404
15405   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15406     {
15407       if (unformat (line_input, "disable"))
15408         enable_disable = 0;
15409       if (unformat (line_input, "enable"))
15410         enable_disable = 1;
15411       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15412                          vam, &sw_if_index))
15413         ;
15414       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15415         ;
15416       else
15417         break;
15418     }
15419
15420   if (sw_if_index == ~0)
15421     {
15422       errmsg ("missing interface name or sw_if_index");
15423       return -99;
15424     }
15425
15426   /* Construct the API message */
15427   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15428   mp->sw_if_index = ntohl (sw_if_index);
15429   mp->enable_disable = enable_disable;
15430
15431   /* send it... */
15432   S (mp);
15433   /* Wait for the reply */
15434   W (ret);
15435   return ret;
15436 }
15437
15438 static int
15439 api_cop_whitelist_enable_disable (vat_main_t * vam)
15440 {
15441   unformat_input_t *line_input = vam->input;
15442   vl_api_cop_whitelist_enable_disable_t *mp;
15443   u32 sw_if_index = ~0;
15444   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15445   u32 fib_id = 0;
15446   int ret;
15447
15448   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15449     {
15450       if (unformat (line_input, "ip4"))
15451         ip4 = 1;
15452       else if (unformat (line_input, "ip6"))
15453         ip6 = 1;
15454       else if (unformat (line_input, "default"))
15455         default_cop = 1;
15456       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15457                          vam, &sw_if_index))
15458         ;
15459       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15460         ;
15461       else if (unformat (line_input, "fib-id %d", &fib_id))
15462         ;
15463       else
15464         break;
15465     }
15466
15467   if (sw_if_index == ~0)
15468     {
15469       errmsg ("missing interface name or sw_if_index");
15470       return -99;
15471     }
15472
15473   /* Construct the API message */
15474   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15475   mp->sw_if_index = ntohl (sw_if_index);
15476   mp->fib_id = ntohl (fib_id);
15477   mp->ip4 = ip4;
15478   mp->ip6 = ip6;
15479   mp->default_cop = default_cop;
15480
15481   /* send it... */
15482   S (mp);
15483   /* Wait for the reply */
15484   W (ret);
15485   return ret;
15486 }
15487
15488 static int
15489 api_get_node_graph (vat_main_t * vam)
15490 {
15491   vl_api_get_node_graph_t *mp;
15492   int ret;
15493
15494   M (GET_NODE_GRAPH, mp);
15495
15496   /* send it... */
15497   S (mp);
15498   /* Wait for the reply */
15499   W (ret);
15500   return ret;
15501 }
15502
15503 /* *INDENT-OFF* */
15504 /** Used for parsing LISP eids */
15505 typedef CLIB_PACKED(struct{
15506   u8 addr[16];   /**< eid address */
15507   u32 len;       /**< prefix length if IP */
15508   u8 type;      /**< type of eid */
15509 }) lisp_eid_vat_t;
15510 /* *INDENT-ON* */
15511
15512 static uword
15513 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15514 {
15515   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15516
15517   memset (a, 0, sizeof (a[0]));
15518
15519   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15520     {
15521       a->type = 0;              /* ipv4 type */
15522     }
15523   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15524     {
15525       a->type = 1;              /* ipv6 type */
15526     }
15527   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15528     {
15529       a->type = 2;              /* mac type */
15530     }
15531   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15532     {
15533       a->type = 3;              /* NSH type */
15534       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15535       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15536     }
15537   else
15538     {
15539       return 0;
15540     }
15541
15542   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15543     {
15544       return 0;
15545     }
15546
15547   return 1;
15548 }
15549
15550 static int
15551 lisp_eid_size_vat (u8 type)
15552 {
15553   switch (type)
15554     {
15555     case 0:
15556       return 4;
15557     case 1:
15558       return 16;
15559     case 2:
15560       return 6;
15561     case 3:
15562       return 5;
15563     }
15564   return 0;
15565 }
15566
15567 static void
15568 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15569 {
15570   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15571 }
15572
15573 static int
15574 api_one_add_del_locator_set (vat_main_t * vam)
15575 {
15576   unformat_input_t *input = vam->input;
15577   vl_api_one_add_del_locator_set_t *mp;
15578   u8 is_add = 1;
15579   u8 *locator_set_name = NULL;
15580   u8 locator_set_name_set = 0;
15581   vl_api_local_locator_t locator, *locators = 0;
15582   u32 sw_if_index, priority, weight;
15583   u32 data_len = 0;
15584
15585   int ret;
15586   /* Parse args required to build the message */
15587   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15588     {
15589       if (unformat (input, "del"))
15590         {
15591           is_add = 0;
15592         }
15593       else if (unformat (input, "locator-set %s", &locator_set_name))
15594         {
15595           locator_set_name_set = 1;
15596         }
15597       else if (unformat (input, "sw_if_index %u p %u w %u",
15598                          &sw_if_index, &priority, &weight))
15599         {
15600           locator.sw_if_index = htonl (sw_if_index);
15601           locator.priority = priority;
15602           locator.weight = weight;
15603           vec_add1 (locators, locator);
15604         }
15605       else
15606         if (unformat
15607             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15608              &sw_if_index, &priority, &weight))
15609         {
15610           locator.sw_if_index = htonl (sw_if_index);
15611           locator.priority = priority;
15612           locator.weight = weight;
15613           vec_add1 (locators, locator);
15614         }
15615       else
15616         break;
15617     }
15618
15619   if (locator_set_name_set == 0)
15620     {
15621       errmsg ("missing locator-set name");
15622       vec_free (locators);
15623       return -99;
15624     }
15625
15626   if (vec_len (locator_set_name) > 64)
15627     {
15628       errmsg ("locator-set name too long");
15629       vec_free (locator_set_name);
15630       vec_free (locators);
15631       return -99;
15632     }
15633   vec_add1 (locator_set_name, 0);
15634
15635   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15636
15637   /* Construct the API message */
15638   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15639
15640   mp->is_add = is_add;
15641   clib_memcpy (mp->locator_set_name, locator_set_name,
15642                vec_len (locator_set_name));
15643   vec_free (locator_set_name);
15644
15645   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15646   if (locators)
15647     clib_memcpy (mp->locators, locators, data_len);
15648   vec_free (locators);
15649
15650   /* send it... */
15651   S (mp);
15652
15653   /* Wait for a reply... */
15654   W (ret);
15655   return ret;
15656 }
15657
15658 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15659
15660 static int
15661 api_one_add_del_locator (vat_main_t * vam)
15662 {
15663   unformat_input_t *input = vam->input;
15664   vl_api_one_add_del_locator_t *mp;
15665   u32 tmp_if_index = ~0;
15666   u32 sw_if_index = ~0;
15667   u8 sw_if_index_set = 0;
15668   u8 sw_if_index_if_name_set = 0;
15669   u32 priority = ~0;
15670   u8 priority_set = 0;
15671   u32 weight = ~0;
15672   u8 weight_set = 0;
15673   u8 is_add = 1;
15674   u8 *locator_set_name = NULL;
15675   u8 locator_set_name_set = 0;
15676   int ret;
15677
15678   /* Parse args required to build the message */
15679   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15680     {
15681       if (unformat (input, "del"))
15682         {
15683           is_add = 0;
15684         }
15685       else if (unformat (input, "locator-set %s", &locator_set_name))
15686         {
15687           locator_set_name_set = 1;
15688         }
15689       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15690                          &tmp_if_index))
15691         {
15692           sw_if_index_if_name_set = 1;
15693           sw_if_index = tmp_if_index;
15694         }
15695       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15696         {
15697           sw_if_index_set = 1;
15698           sw_if_index = tmp_if_index;
15699         }
15700       else if (unformat (input, "p %d", &priority))
15701         {
15702           priority_set = 1;
15703         }
15704       else if (unformat (input, "w %d", &weight))
15705         {
15706           weight_set = 1;
15707         }
15708       else
15709         break;
15710     }
15711
15712   if (locator_set_name_set == 0)
15713     {
15714       errmsg ("missing locator-set name");
15715       return -99;
15716     }
15717
15718   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15719     {
15720       errmsg ("missing sw_if_index");
15721       vec_free (locator_set_name);
15722       return -99;
15723     }
15724
15725   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15726     {
15727       errmsg ("cannot use both params interface name and sw_if_index");
15728       vec_free (locator_set_name);
15729       return -99;
15730     }
15731
15732   if (priority_set == 0)
15733     {
15734       errmsg ("missing locator-set priority");
15735       vec_free (locator_set_name);
15736       return -99;
15737     }
15738
15739   if (weight_set == 0)
15740     {
15741       errmsg ("missing locator-set weight");
15742       vec_free (locator_set_name);
15743       return -99;
15744     }
15745
15746   if (vec_len (locator_set_name) > 64)
15747     {
15748       errmsg ("locator-set name too long");
15749       vec_free (locator_set_name);
15750       return -99;
15751     }
15752   vec_add1 (locator_set_name, 0);
15753
15754   /* Construct the API message */
15755   M (ONE_ADD_DEL_LOCATOR, mp);
15756
15757   mp->is_add = is_add;
15758   mp->sw_if_index = ntohl (sw_if_index);
15759   mp->priority = priority;
15760   mp->weight = weight;
15761   clib_memcpy (mp->locator_set_name, locator_set_name,
15762                vec_len (locator_set_name));
15763   vec_free (locator_set_name);
15764
15765   /* send it... */
15766   S (mp);
15767
15768   /* Wait for a reply... */
15769   W (ret);
15770   return ret;
15771 }
15772
15773 #define api_lisp_add_del_locator api_one_add_del_locator
15774
15775 uword
15776 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15777 {
15778   u32 *key_id = va_arg (*args, u32 *);
15779   u8 *s = 0;
15780
15781   if (unformat (input, "%s", &s))
15782     {
15783       if (!strcmp ((char *) s, "sha1"))
15784         key_id[0] = HMAC_SHA_1_96;
15785       else if (!strcmp ((char *) s, "sha256"))
15786         key_id[0] = HMAC_SHA_256_128;
15787       else
15788         {
15789           clib_warning ("invalid key_id: '%s'", s);
15790           key_id[0] = HMAC_NO_KEY;
15791         }
15792     }
15793   else
15794     return 0;
15795
15796   vec_free (s);
15797   return 1;
15798 }
15799
15800 static int
15801 api_one_add_del_local_eid (vat_main_t * vam)
15802 {
15803   unformat_input_t *input = vam->input;
15804   vl_api_one_add_del_local_eid_t *mp;
15805   u8 is_add = 1;
15806   u8 eid_set = 0;
15807   lisp_eid_vat_t _eid, *eid = &_eid;
15808   u8 *locator_set_name = 0;
15809   u8 locator_set_name_set = 0;
15810   u32 vni = 0;
15811   u16 key_id = 0;
15812   u8 *key = 0;
15813   int ret;
15814
15815   /* Parse args required to build the message */
15816   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15817     {
15818       if (unformat (input, "del"))
15819         {
15820           is_add = 0;
15821         }
15822       else if (unformat (input, "vni %d", &vni))
15823         {
15824           ;
15825         }
15826       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15827         {
15828           eid_set = 1;
15829         }
15830       else if (unformat (input, "locator-set %s", &locator_set_name))
15831         {
15832           locator_set_name_set = 1;
15833         }
15834       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15835         ;
15836       else if (unformat (input, "secret-key %_%v%_", &key))
15837         ;
15838       else
15839         break;
15840     }
15841
15842   if (locator_set_name_set == 0)
15843     {
15844       errmsg ("missing locator-set name");
15845       return -99;
15846     }
15847
15848   if (0 == eid_set)
15849     {
15850       errmsg ("EID address not set!");
15851       vec_free (locator_set_name);
15852       return -99;
15853     }
15854
15855   if (key && (0 == key_id))
15856     {
15857       errmsg ("invalid key_id!");
15858       return -99;
15859     }
15860
15861   if (vec_len (key) > 64)
15862     {
15863       errmsg ("key too long");
15864       vec_free (key);
15865       return -99;
15866     }
15867
15868   if (vec_len (locator_set_name) > 64)
15869     {
15870       errmsg ("locator-set name too long");
15871       vec_free (locator_set_name);
15872       return -99;
15873     }
15874   vec_add1 (locator_set_name, 0);
15875
15876   /* Construct the API message */
15877   M (ONE_ADD_DEL_LOCAL_EID, mp);
15878
15879   mp->is_add = is_add;
15880   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15881   mp->eid_type = eid->type;
15882   mp->prefix_len = eid->len;
15883   mp->vni = clib_host_to_net_u32 (vni);
15884   mp->key_id = clib_host_to_net_u16 (key_id);
15885   clib_memcpy (mp->locator_set_name, locator_set_name,
15886                vec_len (locator_set_name));
15887   clib_memcpy (mp->key, key, vec_len (key));
15888
15889   vec_free (locator_set_name);
15890   vec_free (key);
15891
15892   /* send it... */
15893   S (mp);
15894
15895   /* Wait for a reply... */
15896   W (ret);
15897   return ret;
15898 }
15899
15900 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15901
15902 static int
15903 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15904 {
15905   u32 dp_table = 0, vni = 0;;
15906   unformat_input_t *input = vam->input;
15907   vl_api_gpe_add_del_fwd_entry_t *mp;
15908   u8 is_add = 1;
15909   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15910   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15911   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15912   u32 action = ~0, w;
15913   ip4_address_t rmt_rloc4, lcl_rloc4;
15914   ip6_address_t rmt_rloc6, lcl_rloc6;
15915   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15916   int ret;
15917
15918   memset (&rloc, 0, sizeof (rloc));
15919
15920   /* Parse args required to build the message */
15921   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15922     {
15923       if (unformat (input, "del"))
15924         is_add = 0;
15925       else if (unformat (input, "add"))
15926         is_add = 1;
15927       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15928         {
15929           rmt_eid_set = 1;
15930         }
15931       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15932         {
15933           lcl_eid_set = 1;
15934         }
15935       else if (unformat (input, "vrf %d", &dp_table))
15936         ;
15937       else if (unformat (input, "bd %d", &dp_table))
15938         ;
15939       else if (unformat (input, "vni %d", &vni))
15940         ;
15941       else if (unformat (input, "w %d", &w))
15942         {
15943           if (!curr_rloc)
15944             {
15945               errmsg ("No RLOC configured for setting priority/weight!");
15946               return -99;
15947             }
15948           curr_rloc->weight = w;
15949         }
15950       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15951                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15952         {
15953           rloc.is_ip4 = 1;
15954
15955           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15956           rloc.weight = 0;
15957           vec_add1 (lcl_locs, rloc);
15958
15959           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15960           vec_add1 (rmt_locs, rloc);
15961           /* weight saved in rmt loc */
15962           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15963         }
15964       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15965                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15966         {
15967           rloc.is_ip4 = 0;
15968           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15969           rloc.weight = 0;
15970           vec_add1 (lcl_locs, rloc);
15971
15972           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15973           vec_add1 (rmt_locs, rloc);
15974           /* weight saved in rmt loc */
15975           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15976         }
15977       else if (unformat (input, "action %d", &action))
15978         {
15979           ;
15980         }
15981       else
15982         {
15983           clib_warning ("parse error '%U'", format_unformat_error, input);
15984           return -99;
15985         }
15986     }
15987
15988   if (!rmt_eid_set)
15989     {
15990       errmsg ("remote eid addresses not set");
15991       return -99;
15992     }
15993
15994   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15995     {
15996       errmsg ("eid types don't match");
15997       return -99;
15998     }
15999
16000   if (0 == rmt_locs && (u32) ~ 0 == action)
16001     {
16002       errmsg ("action not set for negative mapping");
16003       return -99;
16004     }
16005
16006   /* Construct the API message */
16007   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16008       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16009
16010   mp->is_add = is_add;
16011   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16012   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16013   mp->eid_type = rmt_eid->type;
16014   mp->dp_table = clib_host_to_net_u32 (dp_table);
16015   mp->vni = clib_host_to_net_u32 (vni);
16016   mp->rmt_len = rmt_eid->len;
16017   mp->lcl_len = lcl_eid->len;
16018   mp->action = action;
16019
16020   if (0 != rmt_locs && 0 != lcl_locs)
16021     {
16022       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16023       clib_memcpy (mp->locs, lcl_locs,
16024                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16025
16026       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16027       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16028                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16029     }
16030   vec_free (lcl_locs);
16031   vec_free (rmt_locs);
16032
16033   /* send it... */
16034   S (mp);
16035
16036   /* Wait for a reply... */
16037   W (ret);
16038   return ret;
16039 }
16040
16041 static int
16042 api_one_add_del_map_server (vat_main_t * vam)
16043 {
16044   unformat_input_t *input = vam->input;
16045   vl_api_one_add_del_map_server_t *mp;
16046   u8 is_add = 1;
16047   u8 ipv4_set = 0;
16048   u8 ipv6_set = 0;
16049   ip4_address_t ipv4;
16050   ip6_address_t ipv6;
16051   int ret;
16052
16053   /* Parse args required to build the message */
16054   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16055     {
16056       if (unformat (input, "del"))
16057         {
16058           is_add = 0;
16059         }
16060       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16061         {
16062           ipv4_set = 1;
16063         }
16064       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16065         {
16066           ipv6_set = 1;
16067         }
16068       else
16069         break;
16070     }
16071
16072   if (ipv4_set && ipv6_set)
16073     {
16074       errmsg ("both eid v4 and v6 addresses set");
16075       return -99;
16076     }
16077
16078   if (!ipv4_set && !ipv6_set)
16079     {
16080       errmsg ("eid addresses not set");
16081       return -99;
16082     }
16083
16084   /* Construct the API message */
16085   M (ONE_ADD_DEL_MAP_SERVER, mp);
16086
16087   mp->is_add = is_add;
16088   if (ipv6_set)
16089     {
16090       mp->is_ipv6 = 1;
16091       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16092     }
16093   else
16094     {
16095       mp->is_ipv6 = 0;
16096       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16097     }
16098
16099   /* send it... */
16100   S (mp);
16101
16102   /* Wait for a reply... */
16103   W (ret);
16104   return ret;
16105 }
16106
16107 #define api_lisp_add_del_map_server api_one_add_del_map_server
16108
16109 static int
16110 api_one_add_del_map_resolver (vat_main_t * vam)
16111 {
16112   unformat_input_t *input = vam->input;
16113   vl_api_one_add_del_map_resolver_t *mp;
16114   u8 is_add = 1;
16115   u8 ipv4_set = 0;
16116   u8 ipv6_set = 0;
16117   ip4_address_t ipv4;
16118   ip6_address_t ipv6;
16119   int ret;
16120
16121   /* Parse args required to build the message */
16122   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16123     {
16124       if (unformat (input, "del"))
16125         {
16126           is_add = 0;
16127         }
16128       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16129         {
16130           ipv4_set = 1;
16131         }
16132       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16133         {
16134           ipv6_set = 1;
16135         }
16136       else
16137         break;
16138     }
16139
16140   if (ipv4_set && ipv6_set)
16141     {
16142       errmsg ("both eid v4 and v6 addresses set");
16143       return -99;
16144     }
16145
16146   if (!ipv4_set && !ipv6_set)
16147     {
16148       errmsg ("eid addresses not set");
16149       return -99;
16150     }
16151
16152   /* Construct the API message */
16153   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16154
16155   mp->is_add = is_add;
16156   if (ipv6_set)
16157     {
16158       mp->is_ipv6 = 1;
16159       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16160     }
16161   else
16162     {
16163       mp->is_ipv6 = 0;
16164       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16165     }
16166
16167   /* send it... */
16168   S (mp);
16169
16170   /* Wait for a reply... */
16171   W (ret);
16172   return ret;
16173 }
16174
16175 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16176
16177 static int
16178 api_lisp_gpe_enable_disable (vat_main_t * vam)
16179 {
16180   unformat_input_t *input = vam->input;
16181   vl_api_gpe_enable_disable_t *mp;
16182   u8 is_set = 0;
16183   u8 is_en = 1;
16184   int ret;
16185
16186   /* Parse args required to build the message */
16187   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16188     {
16189       if (unformat (input, "enable"))
16190         {
16191           is_set = 1;
16192           is_en = 1;
16193         }
16194       else if (unformat (input, "disable"))
16195         {
16196           is_set = 1;
16197           is_en = 0;
16198         }
16199       else
16200         break;
16201     }
16202
16203   if (is_set == 0)
16204     {
16205       errmsg ("Value not set");
16206       return -99;
16207     }
16208
16209   /* Construct the API message */
16210   M (GPE_ENABLE_DISABLE, mp);
16211
16212   mp->is_en = is_en;
16213
16214   /* send it... */
16215   S (mp);
16216
16217   /* Wait for a reply... */
16218   W (ret);
16219   return ret;
16220 }
16221
16222 static int
16223 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16224 {
16225   unformat_input_t *input = vam->input;
16226   vl_api_one_rloc_probe_enable_disable_t *mp;
16227   u8 is_set = 0;
16228   u8 is_en = 0;
16229   int ret;
16230
16231   /* Parse args required to build the message */
16232   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16233     {
16234       if (unformat (input, "enable"))
16235         {
16236           is_set = 1;
16237           is_en = 1;
16238         }
16239       else if (unformat (input, "disable"))
16240         is_set = 1;
16241       else
16242         break;
16243     }
16244
16245   if (!is_set)
16246     {
16247       errmsg ("Value not set");
16248       return -99;
16249     }
16250
16251   /* Construct the API message */
16252   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16253
16254   mp->is_enabled = is_en;
16255
16256   /* send it... */
16257   S (mp);
16258
16259   /* Wait for a reply... */
16260   W (ret);
16261   return ret;
16262 }
16263
16264 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16265
16266 static int
16267 api_one_map_register_enable_disable (vat_main_t * vam)
16268 {
16269   unformat_input_t *input = vam->input;
16270   vl_api_one_map_register_enable_disable_t *mp;
16271   u8 is_set = 0;
16272   u8 is_en = 0;
16273   int ret;
16274
16275   /* Parse args required to build the message */
16276   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16277     {
16278       if (unformat (input, "enable"))
16279         {
16280           is_set = 1;
16281           is_en = 1;
16282         }
16283       else if (unformat (input, "disable"))
16284         is_set = 1;
16285       else
16286         break;
16287     }
16288
16289   if (!is_set)
16290     {
16291       errmsg ("Value not set");
16292       return -99;
16293     }
16294
16295   /* Construct the API message */
16296   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16297
16298   mp->is_enabled = is_en;
16299
16300   /* send it... */
16301   S (mp);
16302
16303   /* Wait for a reply... */
16304   W (ret);
16305   return ret;
16306 }
16307
16308 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16309
16310 static int
16311 api_one_enable_disable (vat_main_t * vam)
16312 {
16313   unformat_input_t *input = vam->input;
16314   vl_api_one_enable_disable_t *mp;
16315   u8 is_set = 0;
16316   u8 is_en = 0;
16317   int ret;
16318
16319   /* Parse args required to build the message */
16320   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16321     {
16322       if (unformat (input, "enable"))
16323         {
16324           is_set = 1;
16325           is_en = 1;
16326         }
16327       else if (unformat (input, "disable"))
16328         {
16329           is_set = 1;
16330         }
16331       else
16332         break;
16333     }
16334
16335   if (!is_set)
16336     {
16337       errmsg ("Value not set");
16338       return -99;
16339     }
16340
16341   /* Construct the API message */
16342   M (ONE_ENABLE_DISABLE, mp);
16343
16344   mp->is_en = is_en;
16345
16346   /* send it... */
16347   S (mp);
16348
16349   /* Wait for a reply... */
16350   W (ret);
16351   return ret;
16352 }
16353
16354 #define api_lisp_enable_disable api_one_enable_disable
16355
16356 static int
16357 api_show_one_map_register_state (vat_main_t * vam)
16358 {
16359   vl_api_show_one_map_register_state_t *mp;
16360   int ret;
16361
16362   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16363
16364   /* send */
16365   S (mp);
16366
16367   /* wait for reply */
16368   W (ret);
16369   return ret;
16370 }
16371
16372 #define api_show_lisp_map_register_state api_show_one_map_register_state
16373
16374 static int
16375 api_show_one_rloc_probe_state (vat_main_t * vam)
16376 {
16377   vl_api_show_one_rloc_probe_state_t *mp;
16378   int ret;
16379
16380   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16381
16382   /* send */
16383   S (mp);
16384
16385   /* wait for reply */
16386   W (ret);
16387   return ret;
16388 }
16389
16390 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16391
16392 static int
16393 api_one_add_del_ndp_entry (vat_main_t * vam)
16394 {
16395   vl_api_one_add_del_ndp_entry_t *mp;
16396   unformat_input_t *input = vam->input;
16397   u8 is_add = 1;
16398   u8 mac_set = 0;
16399   u8 bd_set = 0;
16400   u8 ip_set = 0;
16401   u8 mac[6] = { 0, };
16402   u8 ip6[16] = { 0, };
16403   u32 bd = ~0;
16404   int ret;
16405
16406   /* Parse args required to build the message */
16407   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16408     {
16409       if (unformat (input, "del"))
16410         is_add = 0;
16411       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16412         mac_set = 1;
16413       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16414         ip_set = 1;
16415       else if (unformat (input, "bd %d", &bd))
16416         bd_set = 1;
16417       else
16418         {
16419           errmsg ("parse error '%U'", format_unformat_error, input);
16420           return -99;
16421         }
16422     }
16423
16424   if (!bd_set || !ip_set || (!mac_set && is_add))
16425     {
16426       errmsg ("Missing BD, IP or MAC!");
16427       return -99;
16428     }
16429
16430   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16431   mp->is_add = is_add;
16432   clib_memcpy (mp->mac, mac, 6);
16433   mp->bd = clib_host_to_net_u32 (bd);
16434   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16435
16436   /* send */
16437   S (mp);
16438
16439   /* wait for reply */
16440   W (ret);
16441   return ret;
16442 }
16443
16444 static int
16445 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16446 {
16447   vl_api_one_add_del_l2_arp_entry_t *mp;
16448   unformat_input_t *input = vam->input;
16449   u8 is_add = 1;
16450   u8 mac_set = 0;
16451   u8 bd_set = 0;
16452   u8 ip_set = 0;
16453   u8 mac[6] = { 0, };
16454   u32 ip4 = 0, bd = ~0;
16455   int ret;
16456
16457   /* Parse args required to build the message */
16458   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16459     {
16460       if (unformat (input, "del"))
16461         is_add = 0;
16462       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16463         mac_set = 1;
16464       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16465         ip_set = 1;
16466       else if (unformat (input, "bd %d", &bd))
16467         bd_set = 1;
16468       else
16469         {
16470           errmsg ("parse error '%U'", format_unformat_error, input);
16471           return -99;
16472         }
16473     }
16474
16475   if (!bd_set || !ip_set || (!mac_set && is_add))
16476     {
16477       errmsg ("Missing BD, IP or MAC!");
16478       return -99;
16479     }
16480
16481   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16482   mp->is_add = is_add;
16483   clib_memcpy (mp->mac, mac, 6);
16484   mp->bd = clib_host_to_net_u32 (bd);
16485   mp->ip4 = ip4;
16486
16487   /* send */
16488   S (mp);
16489
16490   /* wait for reply */
16491   W (ret);
16492   return ret;
16493 }
16494
16495 static int
16496 api_one_ndp_bd_get (vat_main_t * vam)
16497 {
16498   vl_api_one_ndp_bd_get_t *mp;
16499   int ret;
16500
16501   M (ONE_NDP_BD_GET, mp);
16502
16503   /* send */
16504   S (mp);
16505
16506   /* wait for reply */
16507   W (ret);
16508   return ret;
16509 }
16510
16511 static int
16512 api_one_ndp_entries_get (vat_main_t * vam)
16513 {
16514   vl_api_one_ndp_entries_get_t *mp;
16515   unformat_input_t *input = vam->input;
16516   u8 bd_set = 0;
16517   u32 bd = ~0;
16518   int ret;
16519
16520   /* Parse args required to build the message */
16521   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16522     {
16523       if (unformat (input, "bd %d", &bd))
16524         bd_set = 1;
16525       else
16526         {
16527           errmsg ("parse error '%U'", format_unformat_error, input);
16528           return -99;
16529         }
16530     }
16531
16532   if (!bd_set)
16533     {
16534       errmsg ("Expected bridge domain!");
16535       return -99;
16536     }
16537
16538   M (ONE_NDP_ENTRIES_GET, mp);
16539   mp->bd = clib_host_to_net_u32 (bd);
16540
16541   /* send */
16542   S (mp);
16543
16544   /* wait for reply */
16545   W (ret);
16546   return ret;
16547 }
16548
16549 static int
16550 api_one_l2_arp_bd_get (vat_main_t * vam)
16551 {
16552   vl_api_one_l2_arp_bd_get_t *mp;
16553   int ret;
16554
16555   M (ONE_L2_ARP_BD_GET, mp);
16556
16557   /* send */
16558   S (mp);
16559
16560   /* wait for reply */
16561   W (ret);
16562   return ret;
16563 }
16564
16565 static int
16566 api_one_l2_arp_entries_get (vat_main_t * vam)
16567 {
16568   vl_api_one_l2_arp_entries_get_t *mp;
16569   unformat_input_t *input = vam->input;
16570   u8 bd_set = 0;
16571   u32 bd = ~0;
16572   int ret;
16573
16574   /* Parse args required to build the message */
16575   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16576     {
16577       if (unformat (input, "bd %d", &bd))
16578         bd_set = 1;
16579       else
16580         {
16581           errmsg ("parse error '%U'", format_unformat_error, input);
16582           return -99;
16583         }
16584     }
16585
16586   if (!bd_set)
16587     {
16588       errmsg ("Expected bridge domain!");
16589       return -99;
16590     }
16591
16592   M (ONE_L2_ARP_ENTRIES_GET, mp);
16593   mp->bd = clib_host_to_net_u32 (bd);
16594
16595   /* send */
16596   S (mp);
16597
16598   /* wait for reply */
16599   W (ret);
16600   return ret;
16601 }
16602
16603 static int
16604 api_one_stats_enable_disable (vat_main_t * vam)
16605 {
16606   vl_api_one_stats_enable_disable_t *mp;
16607   unformat_input_t *input = vam->input;
16608   u8 is_set = 0;
16609   u8 is_en = 0;
16610   int ret;
16611
16612   /* Parse args required to build the message */
16613   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16614     {
16615       if (unformat (input, "enable"))
16616         {
16617           is_set = 1;
16618           is_en = 1;
16619         }
16620       else if (unformat (input, "disable"))
16621         {
16622           is_set = 1;
16623         }
16624       else
16625         break;
16626     }
16627
16628   if (!is_set)
16629     {
16630       errmsg ("Value not set");
16631       return -99;
16632     }
16633
16634   M (ONE_STATS_ENABLE_DISABLE, mp);
16635   mp->is_en = is_en;
16636
16637   /* send */
16638   S (mp);
16639
16640   /* wait for reply */
16641   W (ret);
16642   return ret;
16643 }
16644
16645 static int
16646 api_show_one_stats_enable_disable (vat_main_t * vam)
16647 {
16648   vl_api_show_one_stats_enable_disable_t *mp;
16649   int ret;
16650
16651   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16652
16653   /* send */
16654   S (mp);
16655
16656   /* wait for reply */
16657   W (ret);
16658   return ret;
16659 }
16660
16661 static int
16662 api_show_one_map_request_mode (vat_main_t * vam)
16663 {
16664   vl_api_show_one_map_request_mode_t *mp;
16665   int ret;
16666
16667   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16668
16669   /* send */
16670   S (mp);
16671
16672   /* wait for reply */
16673   W (ret);
16674   return ret;
16675 }
16676
16677 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16678
16679 static int
16680 api_one_map_request_mode (vat_main_t * vam)
16681 {
16682   unformat_input_t *input = vam->input;
16683   vl_api_one_map_request_mode_t *mp;
16684   u8 mode = 0;
16685   int ret;
16686
16687   /* Parse args required to build the message */
16688   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16689     {
16690       if (unformat (input, "dst-only"))
16691         mode = 0;
16692       else if (unformat (input, "src-dst"))
16693         mode = 1;
16694       else
16695         {
16696           errmsg ("parse error '%U'", format_unformat_error, input);
16697           return -99;
16698         }
16699     }
16700
16701   M (ONE_MAP_REQUEST_MODE, mp);
16702
16703   mp->mode = mode;
16704
16705   /* send */
16706   S (mp);
16707
16708   /* wait for reply */
16709   W (ret);
16710   return ret;
16711 }
16712
16713 #define api_lisp_map_request_mode api_one_map_request_mode
16714
16715 /**
16716  * Enable/disable ONE proxy ITR.
16717  *
16718  * @param vam vpp API test context
16719  * @return return code
16720  */
16721 static int
16722 api_one_pitr_set_locator_set (vat_main_t * vam)
16723 {
16724   u8 ls_name_set = 0;
16725   unformat_input_t *input = vam->input;
16726   vl_api_one_pitr_set_locator_set_t *mp;
16727   u8 is_add = 1;
16728   u8 *ls_name = 0;
16729   int ret;
16730
16731   /* Parse args required to build the message */
16732   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16733     {
16734       if (unformat (input, "del"))
16735         is_add = 0;
16736       else if (unformat (input, "locator-set %s", &ls_name))
16737         ls_name_set = 1;
16738       else
16739         {
16740           errmsg ("parse error '%U'", format_unformat_error, input);
16741           return -99;
16742         }
16743     }
16744
16745   if (!ls_name_set)
16746     {
16747       errmsg ("locator-set name not set!");
16748       return -99;
16749     }
16750
16751   M (ONE_PITR_SET_LOCATOR_SET, mp);
16752
16753   mp->is_add = is_add;
16754   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16755   vec_free (ls_name);
16756
16757   /* send */
16758   S (mp);
16759
16760   /* wait for reply */
16761   W (ret);
16762   return ret;
16763 }
16764
16765 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16766
16767 static int
16768 api_one_nsh_set_locator_set (vat_main_t * vam)
16769 {
16770   u8 ls_name_set = 0;
16771   unformat_input_t *input = vam->input;
16772   vl_api_one_nsh_set_locator_set_t *mp;
16773   u8 is_add = 1;
16774   u8 *ls_name = 0;
16775   int ret;
16776
16777   /* Parse args required to build the message */
16778   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16779     {
16780       if (unformat (input, "del"))
16781         is_add = 0;
16782       else if (unformat (input, "ls %s", &ls_name))
16783         ls_name_set = 1;
16784       else
16785         {
16786           errmsg ("parse error '%U'", format_unformat_error, input);
16787           return -99;
16788         }
16789     }
16790
16791   if (!ls_name_set && is_add)
16792     {
16793       errmsg ("locator-set name not set!");
16794       return -99;
16795     }
16796
16797   M (ONE_NSH_SET_LOCATOR_SET, mp);
16798
16799   mp->is_add = is_add;
16800   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16801   vec_free (ls_name);
16802
16803   /* send */
16804   S (mp);
16805
16806   /* wait for reply */
16807   W (ret);
16808   return ret;
16809 }
16810
16811 static int
16812 api_show_one_pitr (vat_main_t * vam)
16813 {
16814   vl_api_show_one_pitr_t *mp;
16815   int ret;
16816
16817   if (!vam->json_output)
16818     {
16819       print (vam->ofp, "%=20s", "lisp status:");
16820     }
16821
16822   M (SHOW_ONE_PITR, mp);
16823   /* send it... */
16824   S (mp);
16825
16826   /* Wait for a reply... */
16827   W (ret);
16828   return ret;
16829 }
16830
16831 #define api_show_lisp_pitr api_show_one_pitr
16832
16833 static int
16834 api_one_use_petr (vat_main_t * vam)
16835 {
16836   unformat_input_t *input = vam->input;
16837   vl_api_one_use_petr_t *mp;
16838   u8 is_add = 0;
16839   ip_address_t ip;
16840   int ret;
16841
16842   memset (&ip, 0, sizeof (ip));
16843
16844   /* Parse args required to build the message */
16845   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16846     {
16847       if (unformat (input, "disable"))
16848         is_add = 0;
16849       else
16850         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16851         {
16852           is_add = 1;
16853           ip_addr_version (&ip) = IP4;
16854         }
16855       else
16856         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16857         {
16858           is_add = 1;
16859           ip_addr_version (&ip) = IP6;
16860         }
16861       else
16862         {
16863           errmsg ("parse error '%U'", format_unformat_error, input);
16864           return -99;
16865         }
16866     }
16867
16868   M (ONE_USE_PETR, mp);
16869
16870   mp->is_add = is_add;
16871   if (is_add)
16872     {
16873       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16874       if (mp->is_ip4)
16875         clib_memcpy (mp->address, &ip, 4);
16876       else
16877         clib_memcpy (mp->address, &ip, 16);
16878     }
16879
16880   /* send */
16881   S (mp);
16882
16883   /* wait for reply */
16884   W (ret);
16885   return ret;
16886 }
16887
16888 #define api_lisp_use_petr api_one_use_petr
16889
16890 static int
16891 api_show_one_nsh_mapping (vat_main_t * vam)
16892 {
16893   vl_api_show_one_use_petr_t *mp;
16894   int ret;
16895
16896   if (!vam->json_output)
16897     {
16898       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16899     }
16900
16901   M (SHOW_ONE_NSH_MAPPING, mp);
16902   /* send it... */
16903   S (mp);
16904
16905   /* Wait for a reply... */
16906   W (ret);
16907   return ret;
16908 }
16909
16910 static int
16911 api_show_one_use_petr (vat_main_t * vam)
16912 {
16913   vl_api_show_one_use_petr_t *mp;
16914   int ret;
16915
16916   if (!vam->json_output)
16917     {
16918       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16919     }
16920
16921   M (SHOW_ONE_USE_PETR, mp);
16922   /* send it... */
16923   S (mp);
16924
16925   /* Wait for a reply... */
16926   W (ret);
16927   return ret;
16928 }
16929
16930 #define api_show_lisp_use_petr api_show_one_use_petr
16931
16932 /**
16933  * Add/delete mapping between vni and vrf
16934  */
16935 static int
16936 api_one_eid_table_add_del_map (vat_main_t * vam)
16937 {
16938   unformat_input_t *input = vam->input;
16939   vl_api_one_eid_table_add_del_map_t *mp;
16940   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16941   u32 vni, vrf, bd_index;
16942   int ret;
16943
16944   /* Parse args required to build the message */
16945   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16946     {
16947       if (unformat (input, "del"))
16948         is_add = 0;
16949       else if (unformat (input, "vrf %d", &vrf))
16950         vrf_set = 1;
16951       else if (unformat (input, "bd_index %d", &bd_index))
16952         bd_index_set = 1;
16953       else if (unformat (input, "vni %d", &vni))
16954         vni_set = 1;
16955       else
16956         break;
16957     }
16958
16959   if (!vni_set || (!vrf_set && !bd_index_set))
16960     {
16961       errmsg ("missing arguments!");
16962       return -99;
16963     }
16964
16965   if (vrf_set && bd_index_set)
16966     {
16967       errmsg ("error: both vrf and bd entered!");
16968       return -99;
16969     }
16970
16971   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16972
16973   mp->is_add = is_add;
16974   mp->vni = htonl (vni);
16975   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16976   mp->is_l2 = bd_index_set;
16977
16978   /* send */
16979   S (mp);
16980
16981   /* wait for reply */
16982   W (ret);
16983   return ret;
16984 }
16985
16986 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16987
16988 uword
16989 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16990 {
16991   u32 *action = va_arg (*args, u32 *);
16992   u8 *s = 0;
16993
16994   if (unformat (input, "%s", &s))
16995     {
16996       if (!strcmp ((char *) s, "no-action"))
16997         action[0] = 0;
16998       else if (!strcmp ((char *) s, "natively-forward"))
16999         action[0] = 1;
17000       else if (!strcmp ((char *) s, "send-map-request"))
17001         action[0] = 2;
17002       else if (!strcmp ((char *) s, "drop"))
17003         action[0] = 3;
17004       else
17005         {
17006           clib_warning ("invalid action: '%s'", s);
17007           action[0] = 3;
17008         }
17009     }
17010   else
17011     return 0;
17012
17013   vec_free (s);
17014   return 1;
17015 }
17016
17017 /**
17018  * Add/del remote mapping to/from ONE control plane
17019  *
17020  * @param vam vpp API test context
17021  * @return return code
17022  */
17023 static int
17024 api_one_add_del_remote_mapping (vat_main_t * vam)
17025 {
17026   unformat_input_t *input = vam->input;
17027   vl_api_one_add_del_remote_mapping_t *mp;
17028   u32 vni = 0;
17029   lisp_eid_vat_t _eid, *eid = &_eid;
17030   lisp_eid_vat_t _seid, *seid = &_seid;
17031   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
17032   u32 action = ~0, p, w, data_len;
17033   ip4_address_t rloc4;
17034   ip6_address_t rloc6;
17035   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
17036   int ret;
17037
17038   memset (&rloc, 0, sizeof (rloc));
17039
17040   /* Parse args required to build the message */
17041   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17042     {
17043       if (unformat (input, "del-all"))
17044         {
17045           del_all = 1;
17046         }
17047       else if (unformat (input, "del"))
17048         {
17049           is_add = 0;
17050         }
17051       else if (unformat (input, "add"))
17052         {
17053           is_add = 1;
17054         }
17055       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17056         {
17057           eid_set = 1;
17058         }
17059       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
17060         {
17061           seid_set = 1;
17062         }
17063       else if (unformat (input, "vni %d", &vni))
17064         {
17065           ;
17066         }
17067       else if (unformat (input, "p %d w %d", &p, &w))
17068         {
17069           if (!curr_rloc)
17070             {
17071               errmsg ("No RLOC configured for setting priority/weight!");
17072               return -99;
17073             }
17074           curr_rloc->priority = p;
17075           curr_rloc->weight = w;
17076         }
17077       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
17078         {
17079           rloc.is_ip4 = 1;
17080           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17081           vec_add1 (rlocs, rloc);
17082           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17083         }
17084       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
17085         {
17086           rloc.is_ip4 = 0;
17087           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17088           vec_add1 (rlocs, rloc);
17089           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17090         }
17091       else if (unformat (input, "action %U",
17092                          unformat_negative_mapping_action, &action))
17093         {
17094           ;
17095         }
17096       else
17097         {
17098           clib_warning ("parse error '%U'", format_unformat_error, input);
17099           return -99;
17100         }
17101     }
17102
17103   if (0 == eid_set)
17104     {
17105       errmsg ("missing params!");
17106       return -99;
17107     }
17108
17109   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17110     {
17111       errmsg ("no action set for negative map-reply!");
17112       return -99;
17113     }
17114
17115   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17116
17117   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17118   mp->is_add = is_add;
17119   mp->vni = htonl (vni);
17120   mp->action = (u8) action;
17121   mp->is_src_dst = seid_set;
17122   mp->eid_len = eid->len;
17123   mp->seid_len = seid->len;
17124   mp->del_all = del_all;
17125   mp->eid_type = eid->type;
17126   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17127   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17128
17129   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17130   clib_memcpy (mp->rlocs, rlocs, data_len);
17131   vec_free (rlocs);
17132
17133   /* send it... */
17134   S (mp);
17135
17136   /* Wait for a reply... */
17137   W (ret);
17138   return ret;
17139 }
17140
17141 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17142
17143 /**
17144  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17145  * forwarding entries in data-plane accordingly.
17146  *
17147  * @param vam vpp API test context
17148  * @return return code
17149  */
17150 static int
17151 api_one_add_del_adjacency (vat_main_t * vam)
17152 {
17153   unformat_input_t *input = vam->input;
17154   vl_api_one_add_del_adjacency_t *mp;
17155   u32 vni = 0;
17156   ip4_address_t leid4, reid4;
17157   ip6_address_t leid6, reid6;
17158   u8 reid_mac[6] = { 0 };
17159   u8 leid_mac[6] = { 0 };
17160   u8 reid_type, leid_type;
17161   u32 leid_len = 0, reid_len = 0, len;
17162   u8 is_add = 1;
17163   int ret;
17164
17165   leid_type = reid_type = (u8) ~ 0;
17166
17167   /* Parse args required to build the message */
17168   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17169     {
17170       if (unformat (input, "del"))
17171         {
17172           is_add = 0;
17173         }
17174       else if (unformat (input, "add"))
17175         {
17176           is_add = 1;
17177         }
17178       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17179                          &reid4, &len))
17180         {
17181           reid_type = 0;        /* ipv4 */
17182           reid_len = len;
17183         }
17184       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17185                          &reid6, &len))
17186         {
17187           reid_type = 1;        /* ipv6 */
17188           reid_len = len;
17189         }
17190       else if (unformat (input, "reid %U", unformat_ethernet_address,
17191                          reid_mac))
17192         {
17193           reid_type = 2;        /* mac */
17194         }
17195       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17196                          &leid4, &len))
17197         {
17198           leid_type = 0;        /* ipv4 */
17199           leid_len = len;
17200         }
17201       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17202                          &leid6, &len))
17203         {
17204           leid_type = 1;        /* ipv6 */
17205           leid_len = len;
17206         }
17207       else if (unformat (input, "leid %U", unformat_ethernet_address,
17208                          leid_mac))
17209         {
17210           leid_type = 2;        /* mac */
17211         }
17212       else if (unformat (input, "vni %d", &vni))
17213         {
17214           ;
17215         }
17216       else
17217         {
17218           errmsg ("parse error '%U'", format_unformat_error, input);
17219           return -99;
17220         }
17221     }
17222
17223   if ((u8) ~ 0 == reid_type)
17224     {
17225       errmsg ("missing params!");
17226       return -99;
17227     }
17228
17229   if (leid_type != reid_type)
17230     {
17231       errmsg ("remote and local EIDs are of different types!");
17232       return -99;
17233     }
17234
17235   M (ONE_ADD_DEL_ADJACENCY, mp);
17236   mp->is_add = is_add;
17237   mp->vni = htonl (vni);
17238   mp->leid_len = leid_len;
17239   mp->reid_len = reid_len;
17240   mp->eid_type = reid_type;
17241
17242   switch (mp->eid_type)
17243     {
17244     case 0:
17245       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17246       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17247       break;
17248     case 1:
17249       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17250       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17251       break;
17252     case 2:
17253       clib_memcpy (mp->leid, leid_mac, 6);
17254       clib_memcpy (mp->reid, reid_mac, 6);
17255       break;
17256     default:
17257       errmsg ("unknown EID type %d!", mp->eid_type);
17258       return 0;
17259     }
17260
17261   /* send it... */
17262   S (mp);
17263
17264   /* Wait for a reply... */
17265   W (ret);
17266   return ret;
17267 }
17268
17269 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17270
17271 uword
17272 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17273 {
17274   u32 *mode = va_arg (*args, u32 *);
17275
17276   if (unformat (input, "lisp"))
17277     *mode = 0;
17278   else if (unformat (input, "vxlan"))
17279     *mode = 1;
17280   else
17281     return 0;
17282
17283   return 1;
17284 }
17285
17286 static int
17287 api_gpe_get_encap_mode (vat_main_t * vam)
17288 {
17289   vl_api_gpe_get_encap_mode_t *mp;
17290   int ret;
17291
17292   /* Construct the API message */
17293   M (GPE_GET_ENCAP_MODE, mp);
17294
17295   /* send it... */
17296   S (mp);
17297
17298   /* Wait for a reply... */
17299   W (ret);
17300   return ret;
17301 }
17302
17303 static int
17304 api_gpe_set_encap_mode (vat_main_t * vam)
17305 {
17306   unformat_input_t *input = vam->input;
17307   vl_api_gpe_set_encap_mode_t *mp;
17308   int ret;
17309   u32 mode = 0;
17310
17311   /* Parse args required to build the message */
17312   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17313     {
17314       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17315         ;
17316       else
17317         break;
17318     }
17319
17320   /* Construct the API message */
17321   M (GPE_SET_ENCAP_MODE, mp);
17322
17323   mp->mode = mode;
17324
17325   /* send it... */
17326   S (mp);
17327
17328   /* Wait for a reply... */
17329   W (ret);
17330   return ret;
17331 }
17332
17333 static int
17334 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17335 {
17336   unformat_input_t *input = vam->input;
17337   vl_api_gpe_add_del_iface_t *mp;
17338   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17339   u32 dp_table = 0, vni = 0;
17340   int ret;
17341
17342   /* Parse args required to build the message */
17343   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17344     {
17345       if (unformat (input, "up"))
17346         {
17347           action_set = 1;
17348           is_add = 1;
17349         }
17350       else if (unformat (input, "down"))
17351         {
17352           action_set = 1;
17353           is_add = 0;
17354         }
17355       else if (unformat (input, "table_id %d", &dp_table))
17356         {
17357           dp_table_set = 1;
17358         }
17359       else if (unformat (input, "bd_id %d", &dp_table))
17360         {
17361           dp_table_set = 1;
17362           is_l2 = 1;
17363         }
17364       else if (unformat (input, "vni %d", &vni))
17365         {
17366           vni_set = 1;
17367         }
17368       else
17369         break;
17370     }
17371
17372   if (action_set == 0)
17373     {
17374       errmsg ("Action not set");
17375       return -99;
17376     }
17377   if (dp_table_set == 0 || vni_set == 0)
17378     {
17379       errmsg ("vni and dp_table must be set");
17380       return -99;
17381     }
17382
17383   /* Construct the API message */
17384   M (GPE_ADD_DEL_IFACE, mp);
17385
17386   mp->is_add = is_add;
17387   mp->dp_table = clib_host_to_net_u32 (dp_table);
17388   mp->is_l2 = is_l2;
17389   mp->vni = clib_host_to_net_u32 (vni);
17390
17391   /* send it... */
17392   S (mp);
17393
17394   /* Wait for a reply... */
17395   W (ret);
17396   return ret;
17397 }
17398
17399 static int
17400 api_one_map_register_fallback_threshold (vat_main_t * vam)
17401 {
17402   unformat_input_t *input = vam->input;
17403   vl_api_one_map_register_fallback_threshold_t *mp;
17404   u32 value = 0;
17405   u8 is_set = 0;
17406   int ret;
17407
17408   /* Parse args required to build the message */
17409   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17410     {
17411       if (unformat (input, "%u", &value))
17412         is_set = 1;
17413       else
17414         {
17415           clib_warning ("parse error '%U'", format_unformat_error, input);
17416           return -99;
17417         }
17418     }
17419
17420   if (!is_set)
17421     {
17422       errmsg ("fallback threshold value is missing!");
17423       return -99;
17424     }
17425
17426   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17427   mp->value = clib_host_to_net_u32 (value);
17428
17429   /* send it... */
17430   S (mp);
17431
17432   /* Wait for a reply... */
17433   W (ret);
17434   return ret;
17435 }
17436
17437 static int
17438 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17439 {
17440   vl_api_show_one_map_register_fallback_threshold_t *mp;
17441   int ret;
17442
17443   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17444
17445   /* send it... */
17446   S (mp);
17447
17448   /* Wait for a reply... */
17449   W (ret);
17450   return ret;
17451 }
17452
17453 uword
17454 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17455 {
17456   u32 *proto = va_arg (*args, u32 *);
17457
17458   if (unformat (input, "udp"))
17459     *proto = 1;
17460   else if (unformat (input, "api"))
17461     *proto = 2;
17462   else
17463     return 0;
17464
17465   return 1;
17466 }
17467
17468 static int
17469 api_one_set_transport_protocol (vat_main_t * vam)
17470 {
17471   unformat_input_t *input = vam->input;
17472   vl_api_one_set_transport_protocol_t *mp;
17473   u8 is_set = 0;
17474   u32 protocol = 0;
17475   int ret;
17476
17477   /* Parse args required to build the message */
17478   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17479     {
17480       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17481         is_set = 1;
17482       else
17483         {
17484           clib_warning ("parse error '%U'", format_unformat_error, input);
17485           return -99;
17486         }
17487     }
17488
17489   if (!is_set)
17490     {
17491       errmsg ("Transport protocol missing!");
17492       return -99;
17493     }
17494
17495   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17496   mp->protocol = (u8) protocol;
17497
17498   /* send it... */
17499   S (mp);
17500
17501   /* Wait for a reply... */
17502   W (ret);
17503   return ret;
17504 }
17505
17506 static int
17507 api_one_get_transport_protocol (vat_main_t * vam)
17508 {
17509   vl_api_one_get_transport_protocol_t *mp;
17510   int ret;
17511
17512   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17513
17514   /* send it... */
17515   S (mp);
17516
17517   /* Wait for a reply... */
17518   W (ret);
17519   return ret;
17520 }
17521
17522 static int
17523 api_one_map_register_set_ttl (vat_main_t * vam)
17524 {
17525   unformat_input_t *input = vam->input;
17526   vl_api_one_map_register_set_ttl_t *mp;
17527   u32 ttl = 0;
17528   u8 is_set = 0;
17529   int ret;
17530
17531   /* Parse args required to build the message */
17532   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17533     {
17534       if (unformat (input, "%u", &ttl))
17535         is_set = 1;
17536       else
17537         {
17538           clib_warning ("parse error '%U'", format_unformat_error, input);
17539           return -99;
17540         }
17541     }
17542
17543   if (!is_set)
17544     {
17545       errmsg ("TTL value missing!");
17546       return -99;
17547     }
17548
17549   M (ONE_MAP_REGISTER_SET_TTL, mp);
17550   mp->ttl = clib_host_to_net_u32 (ttl);
17551
17552   /* send it... */
17553   S (mp);
17554
17555   /* Wait for a reply... */
17556   W (ret);
17557   return ret;
17558 }
17559
17560 static int
17561 api_show_one_map_register_ttl (vat_main_t * vam)
17562 {
17563   vl_api_show_one_map_register_ttl_t *mp;
17564   int ret;
17565
17566   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17567
17568   /* send it... */
17569   S (mp);
17570
17571   /* Wait for a reply... */
17572   W (ret);
17573   return ret;
17574 }
17575
17576 /**
17577  * Add/del map request itr rlocs from ONE control plane and updates
17578  *
17579  * @param vam vpp API test context
17580  * @return return code
17581  */
17582 static int
17583 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17584 {
17585   unformat_input_t *input = vam->input;
17586   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17587   u8 *locator_set_name = 0;
17588   u8 locator_set_name_set = 0;
17589   u8 is_add = 1;
17590   int ret;
17591
17592   /* Parse args required to build the message */
17593   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17594     {
17595       if (unformat (input, "del"))
17596         {
17597           is_add = 0;
17598         }
17599       else if (unformat (input, "%_%v%_", &locator_set_name))
17600         {
17601           locator_set_name_set = 1;
17602         }
17603       else
17604         {
17605           clib_warning ("parse error '%U'", format_unformat_error, input);
17606           return -99;
17607         }
17608     }
17609
17610   if (is_add && !locator_set_name_set)
17611     {
17612       errmsg ("itr-rloc is not set!");
17613       return -99;
17614     }
17615
17616   if (is_add && vec_len (locator_set_name) > 64)
17617     {
17618       errmsg ("itr-rloc locator-set name too long");
17619       vec_free (locator_set_name);
17620       return -99;
17621     }
17622
17623   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17624   mp->is_add = is_add;
17625   if (is_add)
17626     {
17627       clib_memcpy (mp->locator_set_name, locator_set_name,
17628                    vec_len (locator_set_name));
17629     }
17630   else
17631     {
17632       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17633     }
17634   vec_free (locator_set_name);
17635
17636   /* send it... */
17637   S (mp);
17638
17639   /* Wait for a reply... */
17640   W (ret);
17641   return ret;
17642 }
17643
17644 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17645
17646 static int
17647 api_one_locator_dump (vat_main_t * vam)
17648 {
17649   unformat_input_t *input = vam->input;
17650   vl_api_one_locator_dump_t *mp;
17651   vl_api_control_ping_t *mp_ping;
17652   u8 is_index_set = 0, is_name_set = 0;
17653   u8 *ls_name = 0;
17654   u32 ls_index = ~0;
17655   int ret;
17656
17657   /* Parse args required to build the message */
17658   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17659     {
17660       if (unformat (input, "ls_name %_%v%_", &ls_name))
17661         {
17662           is_name_set = 1;
17663         }
17664       else if (unformat (input, "ls_index %d", &ls_index))
17665         {
17666           is_index_set = 1;
17667         }
17668       else
17669         {
17670           errmsg ("parse error '%U'", format_unformat_error, input);
17671           return -99;
17672         }
17673     }
17674
17675   if (!is_index_set && !is_name_set)
17676     {
17677       errmsg ("error: expected one of index or name!");
17678       return -99;
17679     }
17680
17681   if (is_index_set && is_name_set)
17682     {
17683       errmsg ("error: only one param expected!");
17684       return -99;
17685     }
17686
17687   if (vec_len (ls_name) > 62)
17688     {
17689       errmsg ("error: locator set name too long!");
17690       return -99;
17691     }
17692
17693   if (!vam->json_output)
17694     {
17695       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17696     }
17697
17698   M (ONE_LOCATOR_DUMP, mp);
17699   mp->is_index_set = is_index_set;
17700
17701   if (is_index_set)
17702     mp->ls_index = clib_host_to_net_u32 (ls_index);
17703   else
17704     {
17705       vec_add1 (ls_name, 0);
17706       strncpy ((char *) mp->ls_name, (char *) ls_name,
17707                sizeof (mp->ls_name) - 1);
17708     }
17709
17710   /* send it... */
17711   S (mp);
17712
17713   /* Use a control ping for synchronization */
17714   MPING (CONTROL_PING, mp_ping);
17715   S (mp_ping);
17716
17717   /* Wait for a reply... */
17718   W (ret);
17719   return ret;
17720 }
17721
17722 #define api_lisp_locator_dump api_one_locator_dump
17723
17724 static int
17725 api_one_locator_set_dump (vat_main_t * vam)
17726 {
17727   vl_api_one_locator_set_dump_t *mp;
17728   vl_api_control_ping_t *mp_ping;
17729   unformat_input_t *input = vam->input;
17730   u8 filter = 0;
17731   int ret;
17732
17733   /* Parse args required to build the message */
17734   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17735     {
17736       if (unformat (input, "local"))
17737         {
17738           filter = 1;
17739         }
17740       else if (unformat (input, "remote"))
17741         {
17742           filter = 2;
17743         }
17744       else
17745         {
17746           errmsg ("parse error '%U'", format_unformat_error, input);
17747           return -99;
17748         }
17749     }
17750
17751   if (!vam->json_output)
17752     {
17753       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17754     }
17755
17756   M (ONE_LOCATOR_SET_DUMP, mp);
17757
17758   mp->filter = filter;
17759
17760   /* send it... */
17761   S (mp);
17762
17763   /* Use a control ping for synchronization */
17764   MPING (CONTROL_PING, mp_ping);
17765   S (mp_ping);
17766
17767   /* Wait for a reply... */
17768   W (ret);
17769   return ret;
17770 }
17771
17772 #define api_lisp_locator_set_dump api_one_locator_set_dump
17773
17774 static int
17775 api_one_eid_table_map_dump (vat_main_t * vam)
17776 {
17777   u8 is_l2 = 0;
17778   u8 mode_set = 0;
17779   unformat_input_t *input = vam->input;
17780   vl_api_one_eid_table_map_dump_t *mp;
17781   vl_api_control_ping_t *mp_ping;
17782   int ret;
17783
17784   /* Parse args required to build the message */
17785   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17786     {
17787       if (unformat (input, "l2"))
17788         {
17789           is_l2 = 1;
17790           mode_set = 1;
17791         }
17792       else if (unformat (input, "l3"))
17793         {
17794           is_l2 = 0;
17795           mode_set = 1;
17796         }
17797       else
17798         {
17799           errmsg ("parse error '%U'", format_unformat_error, input);
17800           return -99;
17801         }
17802     }
17803
17804   if (!mode_set)
17805     {
17806       errmsg ("expected one of 'l2' or 'l3' parameter!");
17807       return -99;
17808     }
17809
17810   if (!vam->json_output)
17811     {
17812       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17813     }
17814
17815   M (ONE_EID_TABLE_MAP_DUMP, mp);
17816   mp->is_l2 = is_l2;
17817
17818   /* send it... */
17819   S (mp);
17820
17821   /* Use a control ping for synchronization */
17822   MPING (CONTROL_PING, mp_ping);
17823   S (mp_ping);
17824
17825   /* Wait for a reply... */
17826   W (ret);
17827   return ret;
17828 }
17829
17830 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17831
17832 static int
17833 api_one_eid_table_vni_dump (vat_main_t * vam)
17834 {
17835   vl_api_one_eid_table_vni_dump_t *mp;
17836   vl_api_control_ping_t *mp_ping;
17837   int ret;
17838
17839   if (!vam->json_output)
17840     {
17841       print (vam->ofp, "VNI");
17842     }
17843
17844   M (ONE_EID_TABLE_VNI_DUMP, mp);
17845
17846   /* send it... */
17847   S (mp);
17848
17849   /* Use a control ping for synchronization */
17850   MPING (CONTROL_PING, mp_ping);
17851   S (mp_ping);
17852
17853   /* Wait for a reply... */
17854   W (ret);
17855   return ret;
17856 }
17857
17858 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17859
17860 static int
17861 api_one_eid_table_dump (vat_main_t * vam)
17862 {
17863   unformat_input_t *i = vam->input;
17864   vl_api_one_eid_table_dump_t *mp;
17865   vl_api_control_ping_t *mp_ping;
17866   struct in_addr ip4;
17867   struct in6_addr ip6;
17868   u8 mac[6];
17869   u8 eid_type = ~0, eid_set = 0;
17870   u32 prefix_length = ~0, t, vni = 0;
17871   u8 filter = 0;
17872   int ret;
17873   lisp_nsh_api_t nsh;
17874
17875   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17876     {
17877       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17878         {
17879           eid_set = 1;
17880           eid_type = 0;
17881           prefix_length = t;
17882         }
17883       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17884         {
17885           eid_set = 1;
17886           eid_type = 1;
17887           prefix_length = t;
17888         }
17889       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17890         {
17891           eid_set = 1;
17892           eid_type = 2;
17893         }
17894       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17895         {
17896           eid_set = 1;
17897           eid_type = 3;
17898         }
17899       else if (unformat (i, "vni %d", &t))
17900         {
17901           vni = t;
17902         }
17903       else if (unformat (i, "local"))
17904         {
17905           filter = 1;
17906         }
17907       else if (unformat (i, "remote"))
17908         {
17909           filter = 2;
17910         }
17911       else
17912         {
17913           errmsg ("parse error '%U'", format_unformat_error, i);
17914           return -99;
17915         }
17916     }
17917
17918   if (!vam->json_output)
17919     {
17920       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17921              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17922     }
17923
17924   M (ONE_EID_TABLE_DUMP, mp);
17925
17926   mp->filter = filter;
17927   if (eid_set)
17928     {
17929       mp->eid_set = 1;
17930       mp->vni = htonl (vni);
17931       mp->eid_type = eid_type;
17932       switch (eid_type)
17933         {
17934         case 0:
17935           mp->prefix_length = prefix_length;
17936           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17937           break;
17938         case 1:
17939           mp->prefix_length = prefix_length;
17940           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17941           break;
17942         case 2:
17943           clib_memcpy (mp->eid, mac, sizeof (mac));
17944           break;
17945         case 3:
17946           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17947           break;
17948         default:
17949           errmsg ("unknown EID type %d!", eid_type);
17950           return -99;
17951         }
17952     }
17953
17954   /* send it... */
17955   S (mp);
17956
17957   /* Use a control ping for synchronization */
17958   MPING (CONTROL_PING, mp_ping);
17959   S (mp_ping);
17960
17961   /* Wait for a reply... */
17962   W (ret);
17963   return ret;
17964 }
17965
17966 #define api_lisp_eid_table_dump api_one_eid_table_dump
17967
17968 static int
17969 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17970 {
17971   unformat_input_t *i = vam->input;
17972   vl_api_gpe_fwd_entries_get_t *mp;
17973   u8 vni_set = 0;
17974   u32 vni = ~0;
17975   int ret;
17976
17977   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17978     {
17979       if (unformat (i, "vni %d", &vni))
17980         {
17981           vni_set = 1;
17982         }
17983       else
17984         {
17985           errmsg ("parse error '%U'", format_unformat_error, i);
17986           return -99;
17987         }
17988     }
17989
17990   if (!vni_set)
17991     {
17992       errmsg ("vni not set!");
17993       return -99;
17994     }
17995
17996   if (!vam->json_output)
17997     {
17998       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17999              "leid", "reid");
18000     }
18001
18002   M (GPE_FWD_ENTRIES_GET, mp);
18003   mp->vni = clib_host_to_net_u32 (vni);
18004
18005   /* send it... */
18006   S (mp);
18007
18008   /* Wait for a reply... */
18009   W (ret);
18010   return ret;
18011 }
18012
18013 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
18014 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
18015 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
18016 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
18017 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
18018 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
18019 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
18020 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
18021
18022 static int
18023 api_one_adjacencies_get (vat_main_t * vam)
18024 {
18025   unformat_input_t *i = vam->input;
18026   vl_api_one_adjacencies_get_t *mp;
18027   u8 vni_set = 0;
18028   u32 vni = ~0;
18029   int ret;
18030
18031   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18032     {
18033       if (unformat (i, "vni %d", &vni))
18034         {
18035           vni_set = 1;
18036         }
18037       else
18038         {
18039           errmsg ("parse error '%U'", format_unformat_error, i);
18040           return -99;
18041         }
18042     }
18043
18044   if (!vni_set)
18045     {
18046       errmsg ("vni not set!");
18047       return -99;
18048     }
18049
18050   if (!vam->json_output)
18051     {
18052       print (vam->ofp, "%s %40s", "leid", "reid");
18053     }
18054
18055   M (ONE_ADJACENCIES_GET, mp);
18056   mp->vni = clib_host_to_net_u32 (vni);
18057
18058   /* send it... */
18059   S (mp);
18060
18061   /* Wait for a reply... */
18062   W (ret);
18063   return ret;
18064 }
18065
18066 #define api_lisp_adjacencies_get api_one_adjacencies_get
18067
18068 static int
18069 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
18070 {
18071   unformat_input_t *i = vam->input;
18072   vl_api_gpe_native_fwd_rpaths_get_t *mp;
18073   int ret;
18074   u8 ip_family_set = 0, is_ip4 = 1;
18075
18076   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18077     {
18078       if (unformat (i, "ip4"))
18079         {
18080           ip_family_set = 1;
18081           is_ip4 = 1;
18082         }
18083       else if (unformat (i, "ip6"))
18084         {
18085           ip_family_set = 1;
18086           is_ip4 = 0;
18087         }
18088       else
18089         {
18090           errmsg ("parse error '%U'", format_unformat_error, i);
18091           return -99;
18092         }
18093     }
18094
18095   if (!ip_family_set)
18096     {
18097       errmsg ("ip family not set!");
18098       return -99;
18099     }
18100
18101   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18102   mp->is_ip4 = is_ip4;
18103
18104   /* send it... */
18105   S (mp);
18106
18107   /* Wait for a reply... */
18108   W (ret);
18109   return ret;
18110 }
18111
18112 static int
18113 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18114 {
18115   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18116   int ret;
18117
18118   if (!vam->json_output)
18119     {
18120       print (vam->ofp, "VNIs");
18121     }
18122
18123   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18124
18125   /* send it... */
18126   S (mp);
18127
18128   /* Wait for a reply... */
18129   W (ret);
18130   return ret;
18131 }
18132
18133 static int
18134 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18135 {
18136   unformat_input_t *i = vam->input;
18137   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18138   int ret = 0;
18139   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18140   struct in_addr ip4;
18141   struct in6_addr ip6;
18142   u32 table_id = 0, nh_sw_if_index = ~0;
18143
18144   memset (&ip4, 0, sizeof (ip4));
18145   memset (&ip6, 0, sizeof (ip6));
18146
18147   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18148     {
18149       if (unformat (i, "del"))
18150         is_add = 0;
18151       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18152                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18153         {
18154           ip_set = 1;
18155           is_ip4 = 1;
18156         }
18157       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18158                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18159         {
18160           ip_set = 1;
18161           is_ip4 = 0;
18162         }
18163       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18164         {
18165           ip_set = 1;
18166           is_ip4 = 1;
18167           nh_sw_if_index = ~0;
18168         }
18169       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18170         {
18171           ip_set = 1;
18172           is_ip4 = 0;
18173           nh_sw_if_index = ~0;
18174         }
18175       else if (unformat (i, "table %d", &table_id))
18176         ;
18177       else
18178         {
18179           errmsg ("parse error '%U'", format_unformat_error, i);
18180           return -99;
18181         }
18182     }
18183
18184   if (!ip_set)
18185     {
18186       errmsg ("nh addr not set!");
18187       return -99;
18188     }
18189
18190   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18191   mp->is_add = is_add;
18192   mp->table_id = clib_host_to_net_u32 (table_id);
18193   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18194   mp->is_ip4 = is_ip4;
18195   if (is_ip4)
18196     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18197   else
18198     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18199
18200   /* send it... */
18201   S (mp);
18202
18203   /* Wait for a reply... */
18204   W (ret);
18205   return ret;
18206 }
18207
18208 static int
18209 api_one_map_server_dump (vat_main_t * vam)
18210 {
18211   vl_api_one_map_server_dump_t *mp;
18212   vl_api_control_ping_t *mp_ping;
18213   int ret;
18214
18215   if (!vam->json_output)
18216     {
18217       print (vam->ofp, "%=20s", "Map server");
18218     }
18219
18220   M (ONE_MAP_SERVER_DUMP, mp);
18221   /* send it... */
18222   S (mp);
18223
18224   /* Use a control ping for synchronization */
18225   MPING (CONTROL_PING, mp_ping);
18226   S (mp_ping);
18227
18228   /* Wait for a reply... */
18229   W (ret);
18230   return ret;
18231 }
18232
18233 #define api_lisp_map_server_dump api_one_map_server_dump
18234
18235 static int
18236 api_one_map_resolver_dump (vat_main_t * vam)
18237 {
18238   vl_api_one_map_resolver_dump_t *mp;
18239   vl_api_control_ping_t *mp_ping;
18240   int ret;
18241
18242   if (!vam->json_output)
18243     {
18244       print (vam->ofp, "%=20s", "Map resolver");
18245     }
18246
18247   M (ONE_MAP_RESOLVER_DUMP, mp);
18248   /* send it... */
18249   S (mp);
18250
18251   /* Use a control ping for synchronization */
18252   MPING (CONTROL_PING, mp_ping);
18253   S (mp_ping);
18254
18255   /* Wait for a reply... */
18256   W (ret);
18257   return ret;
18258 }
18259
18260 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18261
18262 static int
18263 api_one_stats_flush (vat_main_t * vam)
18264 {
18265   vl_api_one_stats_flush_t *mp;
18266   int ret = 0;
18267
18268   M (ONE_STATS_FLUSH, mp);
18269   S (mp);
18270   W (ret);
18271   return ret;
18272 }
18273
18274 static int
18275 api_one_stats_dump (vat_main_t * vam)
18276 {
18277   vl_api_one_stats_dump_t *mp;
18278   vl_api_control_ping_t *mp_ping;
18279   int ret;
18280
18281   M (ONE_STATS_DUMP, mp);
18282   /* send it... */
18283   S (mp);
18284
18285   /* Use a control ping for synchronization */
18286   MPING (CONTROL_PING, mp_ping);
18287   S (mp_ping);
18288
18289   /* Wait for a reply... */
18290   W (ret);
18291   return ret;
18292 }
18293
18294 static int
18295 api_show_one_status (vat_main_t * vam)
18296 {
18297   vl_api_show_one_status_t *mp;
18298   int ret;
18299
18300   if (!vam->json_output)
18301     {
18302       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18303     }
18304
18305   M (SHOW_ONE_STATUS, mp);
18306   /* send it... */
18307   S (mp);
18308   /* Wait for a reply... */
18309   W (ret);
18310   return ret;
18311 }
18312
18313 #define api_show_lisp_status api_show_one_status
18314
18315 static int
18316 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18317 {
18318   vl_api_gpe_fwd_entry_path_dump_t *mp;
18319   vl_api_control_ping_t *mp_ping;
18320   unformat_input_t *i = vam->input;
18321   u32 fwd_entry_index = ~0;
18322   int ret;
18323
18324   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18325     {
18326       if (unformat (i, "index %d", &fwd_entry_index))
18327         ;
18328       else
18329         break;
18330     }
18331
18332   if (~0 == fwd_entry_index)
18333     {
18334       errmsg ("no index specified!");
18335       return -99;
18336     }
18337
18338   if (!vam->json_output)
18339     {
18340       print (vam->ofp, "first line");
18341     }
18342
18343   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18344
18345   /* send it... */
18346   S (mp);
18347   /* Use a control ping for synchronization */
18348   MPING (CONTROL_PING, mp_ping);
18349   S (mp_ping);
18350
18351   /* Wait for a reply... */
18352   W (ret);
18353   return ret;
18354 }
18355
18356 static int
18357 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18358 {
18359   vl_api_one_get_map_request_itr_rlocs_t *mp;
18360   int ret;
18361
18362   if (!vam->json_output)
18363     {
18364       print (vam->ofp, "%=20s", "itr-rlocs:");
18365     }
18366
18367   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18368   /* send it... */
18369   S (mp);
18370   /* Wait for a reply... */
18371   W (ret);
18372   return ret;
18373 }
18374
18375 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18376
18377 static int
18378 api_af_packet_create (vat_main_t * vam)
18379 {
18380   unformat_input_t *i = vam->input;
18381   vl_api_af_packet_create_t *mp;
18382   u8 *host_if_name = 0;
18383   u8 hw_addr[6];
18384   u8 random_hw_addr = 1;
18385   int ret;
18386
18387   memset (hw_addr, 0, sizeof (hw_addr));
18388
18389   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18390     {
18391       if (unformat (i, "name %s", &host_if_name))
18392         vec_add1 (host_if_name, 0);
18393       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18394         random_hw_addr = 0;
18395       else
18396         break;
18397     }
18398
18399   if (!vec_len (host_if_name))
18400     {
18401       errmsg ("host-interface name must be specified");
18402       return -99;
18403     }
18404
18405   if (vec_len (host_if_name) > 64)
18406     {
18407       errmsg ("host-interface name too long");
18408       return -99;
18409     }
18410
18411   M (AF_PACKET_CREATE, mp);
18412
18413   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18414   clib_memcpy (mp->hw_addr, hw_addr, 6);
18415   mp->use_random_hw_addr = random_hw_addr;
18416   vec_free (host_if_name);
18417
18418   S (mp);
18419
18420   /* *INDENT-OFF* */
18421   W2 (ret,
18422       ({
18423         if (ret == 0)
18424           fprintf (vam->ofp ? vam->ofp : stderr,
18425                    " new sw_if_index = %d\n", vam->sw_if_index);
18426       }));
18427   /* *INDENT-ON* */
18428   return ret;
18429 }
18430
18431 static int
18432 api_af_packet_delete (vat_main_t * vam)
18433 {
18434   unformat_input_t *i = vam->input;
18435   vl_api_af_packet_delete_t *mp;
18436   u8 *host_if_name = 0;
18437   int ret;
18438
18439   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18440     {
18441       if (unformat (i, "name %s", &host_if_name))
18442         vec_add1 (host_if_name, 0);
18443       else
18444         break;
18445     }
18446
18447   if (!vec_len (host_if_name))
18448     {
18449       errmsg ("host-interface name must be specified");
18450       return -99;
18451     }
18452
18453   if (vec_len (host_if_name) > 64)
18454     {
18455       errmsg ("host-interface name too long");
18456       return -99;
18457     }
18458
18459   M (AF_PACKET_DELETE, mp);
18460
18461   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18462   vec_free (host_if_name);
18463
18464   S (mp);
18465   W (ret);
18466   return ret;
18467 }
18468
18469 static int
18470 api_policer_add_del (vat_main_t * vam)
18471 {
18472   unformat_input_t *i = vam->input;
18473   vl_api_policer_add_del_t *mp;
18474   u8 is_add = 1;
18475   u8 *name = 0;
18476   u32 cir = 0;
18477   u32 eir = 0;
18478   u64 cb = 0;
18479   u64 eb = 0;
18480   u8 rate_type = 0;
18481   u8 round_type = 0;
18482   u8 type = 0;
18483   u8 color_aware = 0;
18484   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18485   int ret;
18486
18487   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18488   conform_action.dscp = 0;
18489   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18490   exceed_action.dscp = 0;
18491   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18492   violate_action.dscp = 0;
18493
18494   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18495     {
18496       if (unformat (i, "del"))
18497         is_add = 0;
18498       else if (unformat (i, "name %s", &name))
18499         vec_add1 (name, 0);
18500       else if (unformat (i, "cir %u", &cir))
18501         ;
18502       else if (unformat (i, "eir %u", &eir))
18503         ;
18504       else if (unformat (i, "cb %u", &cb))
18505         ;
18506       else if (unformat (i, "eb %u", &eb))
18507         ;
18508       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18509                          &rate_type))
18510         ;
18511       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18512                          &round_type))
18513         ;
18514       else if (unformat (i, "type %U", unformat_policer_type, &type))
18515         ;
18516       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18517                          &conform_action))
18518         ;
18519       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18520                          &exceed_action))
18521         ;
18522       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18523                          &violate_action))
18524         ;
18525       else if (unformat (i, "color-aware"))
18526         color_aware = 1;
18527       else
18528         break;
18529     }
18530
18531   if (!vec_len (name))
18532     {
18533       errmsg ("policer name must be specified");
18534       return -99;
18535     }
18536
18537   if (vec_len (name) > 64)
18538     {
18539       errmsg ("policer name too long");
18540       return -99;
18541     }
18542
18543   M (POLICER_ADD_DEL, mp);
18544
18545   clib_memcpy (mp->name, name, vec_len (name));
18546   vec_free (name);
18547   mp->is_add = is_add;
18548   mp->cir = ntohl (cir);
18549   mp->eir = ntohl (eir);
18550   mp->cb = clib_net_to_host_u64 (cb);
18551   mp->eb = clib_net_to_host_u64 (eb);
18552   mp->rate_type = rate_type;
18553   mp->round_type = round_type;
18554   mp->type = type;
18555   mp->conform_action_type = conform_action.action_type;
18556   mp->conform_dscp = conform_action.dscp;
18557   mp->exceed_action_type = exceed_action.action_type;
18558   mp->exceed_dscp = exceed_action.dscp;
18559   mp->violate_action_type = violate_action.action_type;
18560   mp->violate_dscp = violate_action.dscp;
18561   mp->color_aware = color_aware;
18562
18563   S (mp);
18564   W (ret);
18565   return ret;
18566 }
18567
18568 static int
18569 api_policer_dump (vat_main_t * vam)
18570 {
18571   unformat_input_t *i = vam->input;
18572   vl_api_policer_dump_t *mp;
18573   vl_api_control_ping_t *mp_ping;
18574   u8 *match_name = 0;
18575   u8 match_name_valid = 0;
18576   int ret;
18577
18578   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18579     {
18580       if (unformat (i, "name %s", &match_name))
18581         {
18582           vec_add1 (match_name, 0);
18583           match_name_valid = 1;
18584         }
18585       else
18586         break;
18587     }
18588
18589   M (POLICER_DUMP, mp);
18590   mp->match_name_valid = match_name_valid;
18591   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18592   vec_free (match_name);
18593   /* send it... */
18594   S (mp);
18595
18596   /* Use a control ping for synchronization */
18597   MPING (CONTROL_PING, mp_ping);
18598   S (mp_ping);
18599
18600   /* Wait for a reply... */
18601   W (ret);
18602   return ret;
18603 }
18604
18605 static int
18606 api_policer_classify_set_interface (vat_main_t * vam)
18607 {
18608   unformat_input_t *i = vam->input;
18609   vl_api_policer_classify_set_interface_t *mp;
18610   u32 sw_if_index;
18611   int sw_if_index_set;
18612   u32 ip4_table_index = ~0;
18613   u32 ip6_table_index = ~0;
18614   u32 l2_table_index = ~0;
18615   u8 is_add = 1;
18616   int ret;
18617
18618   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18619     {
18620       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18621         sw_if_index_set = 1;
18622       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18623         sw_if_index_set = 1;
18624       else if (unformat (i, "del"))
18625         is_add = 0;
18626       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18627         ;
18628       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18629         ;
18630       else if (unformat (i, "l2-table %d", &l2_table_index))
18631         ;
18632       else
18633         {
18634           clib_warning ("parse error '%U'", format_unformat_error, i);
18635           return -99;
18636         }
18637     }
18638
18639   if (sw_if_index_set == 0)
18640     {
18641       errmsg ("missing interface name or sw_if_index");
18642       return -99;
18643     }
18644
18645   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18646
18647   mp->sw_if_index = ntohl (sw_if_index);
18648   mp->ip4_table_index = ntohl (ip4_table_index);
18649   mp->ip6_table_index = ntohl (ip6_table_index);
18650   mp->l2_table_index = ntohl (l2_table_index);
18651   mp->is_add = is_add;
18652
18653   S (mp);
18654   W (ret);
18655   return ret;
18656 }
18657
18658 static int
18659 api_policer_classify_dump (vat_main_t * vam)
18660 {
18661   unformat_input_t *i = vam->input;
18662   vl_api_policer_classify_dump_t *mp;
18663   vl_api_control_ping_t *mp_ping;
18664   u8 type = POLICER_CLASSIFY_N_TABLES;
18665   int ret;
18666
18667   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18668     ;
18669   else
18670     {
18671       errmsg ("classify table type must be specified");
18672       return -99;
18673     }
18674
18675   if (!vam->json_output)
18676     {
18677       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18678     }
18679
18680   M (POLICER_CLASSIFY_DUMP, mp);
18681   mp->type = type;
18682   /* send it... */
18683   S (mp);
18684
18685   /* Use a control ping for synchronization */
18686   MPING (CONTROL_PING, mp_ping);
18687   S (mp_ping);
18688
18689   /* Wait for a reply... */
18690   W (ret);
18691   return ret;
18692 }
18693
18694 static int
18695 api_netmap_create (vat_main_t * vam)
18696 {
18697   unformat_input_t *i = vam->input;
18698   vl_api_netmap_create_t *mp;
18699   u8 *if_name = 0;
18700   u8 hw_addr[6];
18701   u8 random_hw_addr = 1;
18702   u8 is_pipe = 0;
18703   u8 is_master = 0;
18704   int ret;
18705
18706   memset (hw_addr, 0, sizeof (hw_addr));
18707
18708   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18709     {
18710       if (unformat (i, "name %s", &if_name))
18711         vec_add1 (if_name, 0);
18712       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18713         random_hw_addr = 0;
18714       else if (unformat (i, "pipe"))
18715         is_pipe = 1;
18716       else if (unformat (i, "master"))
18717         is_master = 1;
18718       else if (unformat (i, "slave"))
18719         is_master = 0;
18720       else
18721         break;
18722     }
18723
18724   if (!vec_len (if_name))
18725     {
18726       errmsg ("interface name must be specified");
18727       return -99;
18728     }
18729
18730   if (vec_len (if_name) > 64)
18731     {
18732       errmsg ("interface name too long");
18733       return -99;
18734     }
18735
18736   M (NETMAP_CREATE, mp);
18737
18738   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18739   clib_memcpy (mp->hw_addr, hw_addr, 6);
18740   mp->use_random_hw_addr = random_hw_addr;
18741   mp->is_pipe = is_pipe;
18742   mp->is_master = is_master;
18743   vec_free (if_name);
18744
18745   S (mp);
18746   W (ret);
18747   return ret;
18748 }
18749
18750 static int
18751 api_netmap_delete (vat_main_t * vam)
18752 {
18753   unformat_input_t *i = vam->input;
18754   vl_api_netmap_delete_t *mp;
18755   u8 *if_name = 0;
18756   int ret;
18757
18758   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18759     {
18760       if (unformat (i, "name %s", &if_name))
18761         vec_add1 (if_name, 0);
18762       else
18763         break;
18764     }
18765
18766   if (!vec_len (if_name))
18767     {
18768       errmsg ("interface name must be specified");
18769       return -99;
18770     }
18771
18772   if (vec_len (if_name) > 64)
18773     {
18774       errmsg ("interface name too long");
18775       return -99;
18776     }
18777
18778   M (NETMAP_DELETE, mp);
18779
18780   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18781   vec_free (if_name);
18782
18783   S (mp);
18784   W (ret);
18785   return ret;
18786 }
18787
18788 static void
18789 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
18790 {
18791   if (fp->afi == IP46_TYPE_IP6)
18792     print (vam->ofp,
18793            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18794            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18795            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18796            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18797            format_ip6_address, fp->next_hop);
18798   else if (fp->afi == IP46_TYPE_IP4)
18799     print (vam->ofp,
18800            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18801            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18802            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18803            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18804            format_ip4_address, fp->next_hop);
18805 }
18806
18807 static void
18808 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18809                                  vl_api_fib_path2_t * fp)
18810 {
18811   struct in_addr ip4;
18812   struct in6_addr ip6;
18813
18814   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18815   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18816   vat_json_object_add_uint (node, "is_local", fp->is_local);
18817   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
18818   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
18819   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
18820   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
18821   if (fp->afi == IP46_TYPE_IP4)
18822     {
18823       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
18824       vat_json_object_add_ip4 (node, "next_hop", ip4);
18825     }
18826   else if (fp->afi == IP46_TYPE_IP6)
18827     {
18828       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
18829       vat_json_object_add_ip6 (node, "next_hop", ip6);
18830     }
18831 }
18832
18833 static void
18834 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18835 {
18836   vat_main_t *vam = &vat_main;
18837   int count = ntohl (mp->mt_count);
18838   vl_api_fib_path2_t *fp;
18839   i32 i;
18840
18841   print (vam->ofp, "[%d]: sw_if_index %d via:",
18842          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
18843   fp = mp->mt_paths;
18844   for (i = 0; i < count; i++)
18845     {
18846       vl_api_mpls_fib_path_print (vam, fp);
18847       fp++;
18848     }
18849
18850   print (vam->ofp, "");
18851 }
18852
18853 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18854 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18855
18856 static void
18857 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18858 {
18859   vat_main_t *vam = &vat_main;
18860   vat_json_node_t *node = NULL;
18861   int count = ntohl (mp->mt_count);
18862   vl_api_fib_path2_t *fp;
18863   i32 i;
18864
18865   if (VAT_JSON_ARRAY != vam->json_tree.type)
18866     {
18867       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18868       vat_json_init_array (&vam->json_tree);
18869     }
18870   node = vat_json_array_add (&vam->json_tree);
18871
18872   vat_json_init_object (node);
18873   vat_json_object_add_uint (node, "tunnel_index",
18874                             ntohl (mp->mt_tunnel_index));
18875   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
18876
18877   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
18878
18879   fp = mp->mt_paths;
18880   for (i = 0; i < count; i++)
18881     {
18882       vl_api_mpls_fib_path_json_print (node, fp);
18883       fp++;
18884     }
18885 }
18886
18887 static int
18888 api_mpls_tunnel_dump (vat_main_t * vam)
18889 {
18890   vl_api_mpls_tunnel_dump_t *mp;
18891   vl_api_control_ping_t *mp_ping;
18892   i32 index = -1;
18893   int ret;
18894
18895   /* Parse args required to build the message */
18896   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
18897     {
18898       if (!unformat (vam->input, "tunnel_index %d", &index))
18899         {
18900           index = -1;
18901           break;
18902         }
18903     }
18904
18905   print (vam->ofp, "  tunnel_index %d", index);
18906
18907   M (MPLS_TUNNEL_DUMP, mp);
18908   mp->tunnel_index = htonl (index);
18909   S (mp);
18910
18911   /* Use a control ping for synchronization */
18912   MPING (CONTROL_PING, mp_ping);
18913   S (mp_ping);
18914
18915   W (ret);
18916   return ret;
18917 }
18918
18919 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
18920 #define vl_api_mpls_fib_details_t_print vl_noop_handler
18921
18922
18923 static void
18924 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
18925 {
18926   vat_main_t *vam = &vat_main;
18927   int count = ntohl (mp->count);
18928   vl_api_fib_path2_t *fp;
18929   int i;
18930
18931   print (vam->ofp,
18932          "table-id %d, label %u, ess_bit %u",
18933          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
18934   fp = mp->path;
18935   for (i = 0; i < count; i++)
18936     {
18937       vl_api_mpls_fib_path_print (vam, fp);
18938       fp++;
18939     }
18940 }
18941
18942 static void vl_api_mpls_fib_details_t_handler_json
18943   (vl_api_mpls_fib_details_t * mp)
18944 {
18945   vat_main_t *vam = &vat_main;
18946   int count = ntohl (mp->count);
18947   vat_json_node_t *node = NULL;
18948   vl_api_fib_path2_t *fp;
18949   int i;
18950
18951   if (VAT_JSON_ARRAY != vam->json_tree.type)
18952     {
18953       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18954       vat_json_init_array (&vam->json_tree);
18955     }
18956   node = vat_json_array_add (&vam->json_tree);
18957
18958   vat_json_init_object (node);
18959   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
18960   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
18961   vat_json_object_add_uint (node, "label", ntohl (mp->label));
18962   vat_json_object_add_uint (node, "path_count", count);
18963   fp = mp->path;
18964   for (i = 0; i < count; i++)
18965     {
18966       vl_api_mpls_fib_path_json_print (node, fp);
18967       fp++;
18968     }
18969 }
18970
18971 static int
18972 api_mpls_fib_dump (vat_main_t * vam)
18973 {
18974   vl_api_mpls_fib_dump_t *mp;
18975   vl_api_control_ping_t *mp_ping;
18976   int ret;
18977
18978   M (MPLS_FIB_DUMP, mp);
18979   S (mp);
18980
18981   /* Use a control ping for synchronization */
18982   MPING (CONTROL_PING, mp_ping);
18983   S (mp_ping);
18984
18985   W (ret);
18986   return ret;
18987 }
18988
18989 #define vl_api_ip_fib_details_t_endian vl_noop_handler
18990 #define vl_api_ip_fib_details_t_print vl_noop_handler
18991
18992 static void
18993 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
18994 {
18995   vat_main_t *vam = &vat_main;
18996   int count = ntohl (mp->count);
18997   vl_api_fib_path_t *fp;
18998   int i;
18999
19000   print (vam->ofp,
19001          "table-id %d, prefix %U/%d",
19002          ntohl (mp->table_id), format_ip4_address, mp->address,
19003          mp->address_length);
19004   fp = mp->path;
19005   for (i = 0; i < count; i++)
19006     {
19007       if (fp->afi == IP46_TYPE_IP6)
19008         print (vam->ofp,
19009                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19010                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19011                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19012                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19013                format_ip6_address, fp->next_hop);
19014       else if (fp->afi == IP46_TYPE_IP4)
19015         print (vam->ofp,
19016                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19017                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19018                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19019                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19020                format_ip4_address, fp->next_hop);
19021       fp++;
19022     }
19023 }
19024
19025 static void vl_api_ip_fib_details_t_handler_json
19026   (vl_api_ip_fib_details_t * mp)
19027 {
19028   vat_main_t *vam = &vat_main;
19029   int count = ntohl (mp->count);
19030   vat_json_node_t *node = NULL;
19031   struct in_addr ip4;
19032   struct in6_addr ip6;
19033   vl_api_fib_path_t *fp;
19034   int i;
19035
19036   if (VAT_JSON_ARRAY != vam->json_tree.type)
19037     {
19038       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19039       vat_json_init_array (&vam->json_tree);
19040     }
19041   node = vat_json_array_add (&vam->json_tree);
19042
19043   vat_json_init_object (node);
19044   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19045   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
19046   vat_json_object_add_ip4 (node, "prefix", ip4);
19047   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19048   vat_json_object_add_uint (node, "path_count", count);
19049   fp = mp->path;
19050   for (i = 0; i < count; i++)
19051     {
19052       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19053       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19054       vat_json_object_add_uint (node, "is_local", fp->is_local);
19055       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19056       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19057       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19058       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19059       if (fp->afi == IP46_TYPE_IP4)
19060         {
19061           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19062           vat_json_object_add_ip4 (node, "next_hop", ip4);
19063         }
19064       else if (fp->afi == IP46_TYPE_IP6)
19065         {
19066           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19067           vat_json_object_add_ip6 (node, "next_hop", ip6);
19068         }
19069     }
19070 }
19071
19072 static int
19073 api_ip_fib_dump (vat_main_t * vam)
19074 {
19075   vl_api_ip_fib_dump_t *mp;
19076   vl_api_control_ping_t *mp_ping;
19077   int ret;
19078
19079   M (IP_FIB_DUMP, mp);
19080   S (mp);
19081
19082   /* Use a control ping for synchronization */
19083   MPING (CONTROL_PING, mp_ping);
19084   S (mp_ping);
19085
19086   W (ret);
19087   return ret;
19088 }
19089
19090 static int
19091 api_ip_mfib_dump (vat_main_t * vam)
19092 {
19093   vl_api_ip_mfib_dump_t *mp;
19094   vl_api_control_ping_t *mp_ping;
19095   int ret;
19096
19097   M (IP_MFIB_DUMP, mp);
19098   S (mp);
19099
19100   /* Use a control ping for synchronization */
19101   MPING (CONTROL_PING, mp_ping);
19102   S (mp_ping);
19103
19104   W (ret);
19105   return ret;
19106 }
19107
19108 static void vl_api_ip_neighbor_details_t_handler
19109   (vl_api_ip_neighbor_details_t * mp)
19110 {
19111   vat_main_t *vam = &vat_main;
19112
19113   print (vam->ofp, "%c %U %U",
19114          (mp->is_static) ? 'S' : 'D',
19115          format_ethernet_address, &mp->mac_address,
19116          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
19117          &mp->ip_address);
19118 }
19119
19120 static void vl_api_ip_neighbor_details_t_handler_json
19121   (vl_api_ip_neighbor_details_t * mp)
19122 {
19123
19124   vat_main_t *vam = &vat_main;
19125   vat_json_node_t *node;
19126   struct in_addr ip4;
19127   struct in6_addr ip6;
19128
19129   if (VAT_JSON_ARRAY != vam->json_tree.type)
19130     {
19131       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19132       vat_json_init_array (&vam->json_tree);
19133     }
19134   node = vat_json_array_add (&vam->json_tree);
19135
19136   vat_json_init_object (node);
19137   vat_json_object_add_string_copy (node, "flag",
19138                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
19139                                    "dynamic");
19140
19141   vat_json_object_add_string_copy (node, "link_layer",
19142                                    format (0, "%U", format_ethernet_address,
19143                                            &mp->mac_address));
19144
19145   if (mp->is_ipv6)
19146     {
19147       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
19148       vat_json_object_add_ip6 (node, "ip_address", ip6);
19149     }
19150   else
19151     {
19152       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
19153       vat_json_object_add_ip4 (node, "ip_address", ip4);
19154     }
19155 }
19156
19157 static int
19158 api_ip_neighbor_dump (vat_main_t * vam)
19159 {
19160   unformat_input_t *i = vam->input;
19161   vl_api_ip_neighbor_dump_t *mp;
19162   vl_api_control_ping_t *mp_ping;
19163   u8 is_ipv6 = 0;
19164   u32 sw_if_index = ~0;
19165   int ret;
19166
19167   /* Parse args required to build the message */
19168   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19169     {
19170       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19171         ;
19172       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19173         ;
19174       else if (unformat (i, "ip6"))
19175         is_ipv6 = 1;
19176       else
19177         break;
19178     }
19179
19180   if (sw_if_index == ~0)
19181     {
19182       errmsg ("missing interface name or sw_if_index");
19183       return -99;
19184     }
19185
19186   M (IP_NEIGHBOR_DUMP, mp);
19187   mp->is_ipv6 = (u8) is_ipv6;
19188   mp->sw_if_index = ntohl (sw_if_index);
19189   S (mp);
19190
19191   /* Use a control ping for synchronization */
19192   MPING (CONTROL_PING, mp_ping);
19193   S (mp_ping);
19194
19195   W (ret);
19196   return ret;
19197 }
19198
19199 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
19200 #define vl_api_ip6_fib_details_t_print vl_noop_handler
19201
19202 static void
19203 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
19204 {
19205   vat_main_t *vam = &vat_main;
19206   int count = ntohl (mp->count);
19207   vl_api_fib_path_t *fp;
19208   int i;
19209
19210   print (vam->ofp,
19211          "table-id %d, prefix %U/%d",
19212          ntohl (mp->table_id), format_ip6_address, mp->address,
19213          mp->address_length);
19214   fp = mp->path;
19215   for (i = 0; i < count; i++)
19216     {
19217       if (fp->afi == IP46_TYPE_IP6)
19218         print (vam->ofp,
19219                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19220                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19221                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19222                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19223                format_ip6_address, fp->next_hop);
19224       else if (fp->afi == IP46_TYPE_IP4)
19225         print (vam->ofp,
19226                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19227                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19228                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19229                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19230                format_ip4_address, fp->next_hop);
19231       fp++;
19232     }
19233 }
19234
19235 static void vl_api_ip6_fib_details_t_handler_json
19236   (vl_api_ip6_fib_details_t * mp)
19237 {
19238   vat_main_t *vam = &vat_main;
19239   int count = ntohl (mp->count);
19240   vat_json_node_t *node = NULL;
19241   struct in_addr ip4;
19242   struct in6_addr ip6;
19243   vl_api_fib_path_t *fp;
19244   int i;
19245
19246   if (VAT_JSON_ARRAY != vam->json_tree.type)
19247     {
19248       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19249       vat_json_init_array (&vam->json_tree);
19250     }
19251   node = vat_json_array_add (&vam->json_tree);
19252
19253   vat_json_init_object (node);
19254   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19255   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
19256   vat_json_object_add_ip6 (node, "prefix", ip6);
19257   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19258   vat_json_object_add_uint (node, "path_count", count);
19259   fp = mp->path;
19260   for (i = 0; i < count; i++)
19261     {
19262       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19263       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19264       vat_json_object_add_uint (node, "is_local", fp->is_local);
19265       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19266       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19267       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19268       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19269       if (fp->afi == IP46_TYPE_IP4)
19270         {
19271           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19272           vat_json_object_add_ip4 (node, "next_hop", ip4);
19273         }
19274       else if (fp->afi == IP46_TYPE_IP6)
19275         {
19276           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19277           vat_json_object_add_ip6 (node, "next_hop", ip6);
19278         }
19279     }
19280 }
19281
19282 static int
19283 api_ip6_fib_dump (vat_main_t * vam)
19284 {
19285   vl_api_ip6_fib_dump_t *mp;
19286   vl_api_control_ping_t *mp_ping;
19287   int ret;
19288
19289   M (IP6_FIB_DUMP, mp);
19290   S (mp);
19291
19292   /* Use a control ping for synchronization */
19293   MPING (CONTROL_PING, mp_ping);
19294   S (mp_ping);
19295
19296   W (ret);
19297   return ret;
19298 }
19299
19300 static int
19301 api_ip6_mfib_dump (vat_main_t * vam)
19302 {
19303   vl_api_ip6_mfib_dump_t *mp;
19304   vl_api_control_ping_t *mp_ping;
19305   int ret;
19306
19307   M (IP6_MFIB_DUMP, mp);
19308   S (mp);
19309
19310   /* Use a control ping for synchronization */
19311   MPING (CONTROL_PING, mp_ping);
19312   S (mp_ping);
19313
19314   W (ret);
19315   return ret;
19316 }
19317
19318 int
19319 api_classify_table_ids (vat_main_t * vam)
19320 {
19321   vl_api_classify_table_ids_t *mp;
19322   int ret;
19323
19324   /* Construct the API message */
19325   M (CLASSIFY_TABLE_IDS, mp);
19326   mp->context = 0;
19327
19328   S (mp);
19329   W (ret);
19330   return ret;
19331 }
19332
19333 int
19334 api_classify_table_by_interface (vat_main_t * vam)
19335 {
19336   unformat_input_t *input = vam->input;
19337   vl_api_classify_table_by_interface_t *mp;
19338
19339   u32 sw_if_index = ~0;
19340   int ret;
19341   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19342     {
19343       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19344         ;
19345       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19346         ;
19347       else
19348         break;
19349     }
19350   if (sw_if_index == ~0)
19351     {
19352       errmsg ("missing interface name or sw_if_index");
19353       return -99;
19354     }
19355
19356   /* Construct the API message */
19357   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19358   mp->context = 0;
19359   mp->sw_if_index = ntohl (sw_if_index);
19360
19361   S (mp);
19362   W (ret);
19363   return ret;
19364 }
19365
19366 int
19367 api_classify_table_info (vat_main_t * vam)
19368 {
19369   unformat_input_t *input = vam->input;
19370   vl_api_classify_table_info_t *mp;
19371
19372   u32 table_id = ~0;
19373   int ret;
19374   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19375     {
19376       if (unformat (input, "table_id %d", &table_id))
19377         ;
19378       else
19379         break;
19380     }
19381   if (table_id == ~0)
19382     {
19383       errmsg ("missing table id");
19384       return -99;
19385     }
19386
19387   /* Construct the API message */
19388   M (CLASSIFY_TABLE_INFO, mp);
19389   mp->context = 0;
19390   mp->table_id = ntohl (table_id);
19391
19392   S (mp);
19393   W (ret);
19394   return ret;
19395 }
19396
19397 int
19398 api_classify_session_dump (vat_main_t * vam)
19399 {
19400   unformat_input_t *input = vam->input;
19401   vl_api_classify_session_dump_t *mp;
19402   vl_api_control_ping_t *mp_ping;
19403
19404   u32 table_id = ~0;
19405   int ret;
19406   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19407     {
19408       if (unformat (input, "table_id %d", &table_id))
19409         ;
19410       else
19411         break;
19412     }
19413   if (table_id == ~0)
19414     {
19415       errmsg ("missing table id");
19416       return -99;
19417     }
19418
19419   /* Construct the API message */
19420   M (CLASSIFY_SESSION_DUMP, mp);
19421   mp->context = 0;
19422   mp->table_id = ntohl (table_id);
19423   S (mp);
19424
19425   /* Use a control ping for synchronization */
19426   MPING (CONTROL_PING, mp_ping);
19427   S (mp_ping);
19428
19429   W (ret);
19430   return ret;
19431 }
19432
19433 static void
19434 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19435 {
19436   vat_main_t *vam = &vat_main;
19437
19438   print (vam->ofp, "collector_address %U, collector_port %d, "
19439          "src_address %U, vrf_id %d, path_mtu %u, "
19440          "template_interval %u, udp_checksum %d",
19441          format_ip4_address, mp->collector_address,
19442          ntohs (mp->collector_port),
19443          format_ip4_address, mp->src_address,
19444          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19445          ntohl (mp->template_interval), mp->udp_checksum);
19446
19447   vam->retval = 0;
19448   vam->result_ready = 1;
19449 }
19450
19451 static void
19452   vl_api_ipfix_exporter_details_t_handler_json
19453   (vl_api_ipfix_exporter_details_t * mp)
19454 {
19455   vat_main_t *vam = &vat_main;
19456   vat_json_node_t node;
19457   struct in_addr collector_address;
19458   struct in_addr src_address;
19459
19460   vat_json_init_object (&node);
19461   clib_memcpy (&collector_address, &mp->collector_address,
19462                sizeof (collector_address));
19463   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19464   vat_json_object_add_uint (&node, "collector_port",
19465                             ntohs (mp->collector_port));
19466   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19467   vat_json_object_add_ip4 (&node, "src_address", src_address);
19468   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19469   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19470   vat_json_object_add_uint (&node, "template_interval",
19471                             ntohl (mp->template_interval));
19472   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19473
19474   vat_json_print (vam->ofp, &node);
19475   vat_json_free (&node);
19476   vam->retval = 0;
19477   vam->result_ready = 1;
19478 }
19479
19480 int
19481 api_ipfix_exporter_dump (vat_main_t * vam)
19482 {
19483   vl_api_ipfix_exporter_dump_t *mp;
19484   int ret;
19485
19486   /* Construct the API message */
19487   M (IPFIX_EXPORTER_DUMP, mp);
19488   mp->context = 0;
19489
19490   S (mp);
19491   W (ret);
19492   return ret;
19493 }
19494
19495 static int
19496 api_ipfix_classify_stream_dump (vat_main_t * vam)
19497 {
19498   vl_api_ipfix_classify_stream_dump_t *mp;
19499   int ret;
19500
19501   /* Construct the API message */
19502   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19503   mp->context = 0;
19504
19505   S (mp);
19506   W (ret);
19507   return ret;
19508   /* NOTREACHED */
19509   return 0;
19510 }
19511
19512 static void
19513   vl_api_ipfix_classify_stream_details_t_handler
19514   (vl_api_ipfix_classify_stream_details_t * mp)
19515 {
19516   vat_main_t *vam = &vat_main;
19517   print (vam->ofp, "domain_id %d, src_port %d",
19518          ntohl (mp->domain_id), ntohs (mp->src_port));
19519   vam->retval = 0;
19520   vam->result_ready = 1;
19521 }
19522
19523 static void
19524   vl_api_ipfix_classify_stream_details_t_handler_json
19525   (vl_api_ipfix_classify_stream_details_t * mp)
19526 {
19527   vat_main_t *vam = &vat_main;
19528   vat_json_node_t node;
19529
19530   vat_json_init_object (&node);
19531   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19532   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19533
19534   vat_json_print (vam->ofp, &node);
19535   vat_json_free (&node);
19536   vam->retval = 0;
19537   vam->result_ready = 1;
19538 }
19539
19540 static int
19541 api_ipfix_classify_table_dump (vat_main_t * vam)
19542 {
19543   vl_api_ipfix_classify_table_dump_t *mp;
19544   vl_api_control_ping_t *mp_ping;
19545   int ret;
19546
19547   if (!vam->json_output)
19548     {
19549       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19550              "transport_protocol");
19551     }
19552
19553   /* Construct the API message */
19554   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19555
19556   /* send it... */
19557   S (mp);
19558
19559   /* Use a control ping for synchronization */
19560   MPING (CONTROL_PING, mp_ping);
19561   S (mp_ping);
19562
19563   W (ret);
19564   return ret;
19565 }
19566
19567 static void
19568   vl_api_ipfix_classify_table_details_t_handler
19569   (vl_api_ipfix_classify_table_details_t * mp)
19570 {
19571   vat_main_t *vam = &vat_main;
19572   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19573          mp->transport_protocol);
19574 }
19575
19576 static void
19577   vl_api_ipfix_classify_table_details_t_handler_json
19578   (vl_api_ipfix_classify_table_details_t * mp)
19579 {
19580   vat_json_node_t *node = NULL;
19581   vat_main_t *vam = &vat_main;
19582
19583   if (VAT_JSON_ARRAY != vam->json_tree.type)
19584     {
19585       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19586       vat_json_init_array (&vam->json_tree);
19587     }
19588
19589   node = vat_json_array_add (&vam->json_tree);
19590   vat_json_init_object (node);
19591
19592   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19593   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19594   vat_json_object_add_uint (node, "transport_protocol",
19595                             mp->transport_protocol);
19596 }
19597
19598 static int
19599 api_sw_interface_span_enable_disable (vat_main_t * vam)
19600 {
19601   unformat_input_t *i = vam->input;
19602   vl_api_sw_interface_span_enable_disable_t *mp;
19603   u32 src_sw_if_index = ~0;
19604   u32 dst_sw_if_index = ~0;
19605   u8 state = 3;
19606   int ret;
19607   u8 is_l2 = 0;
19608
19609   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19610     {
19611       if (unformat
19612           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19613         ;
19614       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19615         ;
19616       else
19617         if (unformat
19618             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19619         ;
19620       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19621         ;
19622       else if (unformat (i, "disable"))
19623         state = 0;
19624       else if (unformat (i, "rx"))
19625         state = 1;
19626       else if (unformat (i, "tx"))
19627         state = 2;
19628       else if (unformat (i, "both"))
19629         state = 3;
19630       else if (unformat (i, "l2"))
19631         is_l2 = 1;
19632       else
19633         break;
19634     }
19635
19636   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19637
19638   mp->sw_if_index_from = htonl (src_sw_if_index);
19639   mp->sw_if_index_to = htonl (dst_sw_if_index);
19640   mp->state = state;
19641   mp->is_l2 = is_l2;
19642
19643   S (mp);
19644   W (ret);
19645   return ret;
19646 }
19647
19648 static void
19649 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19650                                             * mp)
19651 {
19652   vat_main_t *vam = &vat_main;
19653   u8 *sw_if_from_name = 0;
19654   u8 *sw_if_to_name = 0;
19655   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19656   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19657   char *states[] = { "none", "rx", "tx", "both" };
19658   hash_pair_t *p;
19659
19660   /* *INDENT-OFF* */
19661   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19662   ({
19663     if ((u32) p->value[0] == sw_if_index_from)
19664       {
19665         sw_if_from_name = (u8 *)(p->key);
19666         if (sw_if_to_name)
19667           break;
19668       }
19669     if ((u32) p->value[0] == sw_if_index_to)
19670       {
19671         sw_if_to_name = (u8 *)(p->key);
19672         if (sw_if_from_name)
19673           break;
19674       }
19675   }));
19676   /* *INDENT-ON* */
19677   print (vam->ofp, "%20s => %20s (%s)",
19678          sw_if_from_name, sw_if_to_name, states[mp->state]);
19679 }
19680
19681 static void
19682   vl_api_sw_interface_span_details_t_handler_json
19683   (vl_api_sw_interface_span_details_t * mp)
19684 {
19685   vat_main_t *vam = &vat_main;
19686   vat_json_node_t *node = NULL;
19687   u8 *sw_if_from_name = 0;
19688   u8 *sw_if_to_name = 0;
19689   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19690   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19691   hash_pair_t *p;
19692
19693   /* *INDENT-OFF* */
19694   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19695   ({
19696     if ((u32) p->value[0] == sw_if_index_from)
19697       {
19698         sw_if_from_name = (u8 *)(p->key);
19699         if (sw_if_to_name)
19700           break;
19701       }
19702     if ((u32) p->value[0] == sw_if_index_to)
19703       {
19704         sw_if_to_name = (u8 *)(p->key);
19705         if (sw_if_from_name)
19706           break;
19707       }
19708   }));
19709   /* *INDENT-ON* */
19710
19711   if (VAT_JSON_ARRAY != vam->json_tree.type)
19712     {
19713       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19714       vat_json_init_array (&vam->json_tree);
19715     }
19716   node = vat_json_array_add (&vam->json_tree);
19717
19718   vat_json_init_object (node);
19719   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19720   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19721   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19722   if (0 != sw_if_to_name)
19723     {
19724       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19725     }
19726   vat_json_object_add_uint (node, "state", mp->state);
19727 }
19728
19729 static int
19730 api_sw_interface_span_dump (vat_main_t * vam)
19731 {
19732   unformat_input_t *input = vam->input;
19733   vl_api_sw_interface_span_dump_t *mp;
19734   vl_api_control_ping_t *mp_ping;
19735   u8 is_l2 = 0;
19736   int ret;
19737
19738   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19739     {
19740       if (unformat (input, "l2"))
19741         is_l2 = 1;
19742       else
19743         break;
19744     }
19745
19746   M (SW_INTERFACE_SPAN_DUMP, mp);
19747   mp->is_l2 = is_l2;
19748   S (mp);
19749
19750   /* Use a control ping for synchronization */
19751   MPING (CONTROL_PING, mp_ping);
19752   S (mp_ping);
19753
19754   W (ret);
19755   return ret;
19756 }
19757
19758 int
19759 api_pg_create_interface (vat_main_t * vam)
19760 {
19761   unformat_input_t *input = vam->input;
19762   vl_api_pg_create_interface_t *mp;
19763
19764   u32 if_id = ~0;
19765   int ret;
19766   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19767     {
19768       if (unformat (input, "if_id %d", &if_id))
19769         ;
19770       else
19771         break;
19772     }
19773   if (if_id == ~0)
19774     {
19775       errmsg ("missing pg interface index");
19776       return -99;
19777     }
19778
19779   /* Construct the API message */
19780   M (PG_CREATE_INTERFACE, mp);
19781   mp->context = 0;
19782   mp->interface_id = ntohl (if_id);
19783
19784   S (mp);
19785   W (ret);
19786   return ret;
19787 }
19788
19789 int
19790 api_pg_capture (vat_main_t * vam)
19791 {
19792   unformat_input_t *input = vam->input;
19793   vl_api_pg_capture_t *mp;
19794
19795   u32 if_id = ~0;
19796   u8 enable = 1;
19797   u32 count = 1;
19798   u8 pcap_file_set = 0;
19799   u8 *pcap_file = 0;
19800   int ret;
19801   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19802     {
19803       if (unformat (input, "if_id %d", &if_id))
19804         ;
19805       else if (unformat (input, "pcap %s", &pcap_file))
19806         pcap_file_set = 1;
19807       else if (unformat (input, "count %d", &count))
19808         ;
19809       else if (unformat (input, "disable"))
19810         enable = 0;
19811       else
19812         break;
19813     }
19814   if (if_id == ~0)
19815     {
19816       errmsg ("missing pg interface index");
19817       return -99;
19818     }
19819   if (pcap_file_set > 0)
19820     {
19821       if (vec_len (pcap_file) > 255)
19822         {
19823           errmsg ("pcap file name is too long");
19824           return -99;
19825         }
19826     }
19827
19828   u32 name_len = vec_len (pcap_file);
19829   /* Construct the API message */
19830   M (PG_CAPTURE, mp);
19831   mp->context = 0;
19832   mp->interface_id = ntohl (if_id);
19833   mp->is_enabled = enable;
19834   mp->count = ntohl (count);
19835   mp->pcap_name_length = ntohl (name_len);
19836   if (pcap_file_set != 0)
19837     {
19838       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19839     }
19840   vec_free (pcap_file);
19841
19842   S (mp);
19843   W (ret);
19844   return ret;
19845 }
19846
19847 int
19848 api_pg_enable_disable (vat_main_t * vam)
19849 {
19850   unformat_input_t *input = vam->input;
19851   vl_api_pg_enable_disable_t *mp;
19852
19853   u8 enable = 1;
19854   u8 stream_name_set = 0;
19855   u8 *stream_name = 0;
19856   int ret;
19857   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19858     {
19859       if (unformat (input, "stream %s", &stream_name))
19860         stream_name_set = 1;
19861       else if (unformat (input, "disable"))
19862         enable = 0;
19863       else
19864         break;
19865     }
19866
19867   if (stream_name_set > 0)
19868     {
19869       if (vec_len (stream_name) > 255)
19870         {
19871           errmsg ("stream name too long");
19872           return -99;
19873         }
19874     }
19875
19876   u32 name_len = vec_len (stream_name);
19877   /* Construct the API message */
19878   M (PG_ENABLE_DISABLE, mp);
19879   mp->context = 0;
19880   mp->is_enabled = enable;
19881   if (stream_name_set != 0)
19882     {
19883       mp->stream_name_length = ntohl (name_len);
19884       clib_memcpy (mp->stream_name, stream_name, name_len);
19885     }
19886   vec_free (stream_name);
19887
19888   S (mp);
19889   W (ret);
19890   return ret;
19891 }
19892
19893 int
19894 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19895 {
19896   unformat_input_t *input = vam->input;
19897   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19898
19899   u16 *low_ports = 0;
19900   u16 *high_ports = 0;
19901   u16 this_low;
19902   u16 this_hi;
19903   ip4_address_t ip4_addr;
19904   ip6_address_t ip6_addr;
19905   u32 length;
19906   u32 tmp, tmp2;
19907   u8 prefix_set = 0;
19908   u32 vrf_id = ~0;
19909   u8 is_add = 1;
19910   u8 is_ipv6 = 0;
19911   int ret;
19912
19913   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19914     {
19915       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
19916         {
19917           prefix_set = 1;
19918         }
19919       else
19920         if (unformat
19921             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
19922         {
19923           prefix_set = 1;
19924           is_ipv6 = 1;
19925         }
19926       else if (unformat (input, "vrf %d", &vrf_id))
19927         ;
19928       else if (unformat (input, "del"))
19929         is_add = 0;
19930       else if (unformat (input, "port %d", &tmp))
19931         {
19932           if (tmp == 0 || tmp > 65535)
19933             {
19934               errmsg ("port %d out of range", tmp);
19935               return -99;
19936             }
19937           this_low = tmp;
19938           this_hi = this_low + 1;
19939           vec_add1 (low_ports, this_low);
19940           vec_add1 (high_ports, this_hi);
19941         }
19942       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19943         {
19944           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19945             {
19946               errmsg ("incorrect range parameters");
19947               return -99;
19948             }
19949           this_low = tmp;
19950           /* Note: in debug CLI +1 is added to high before
19951              passing to real fn that does "the work"
19952              (ip_source_and_port_range_check_add_del).
19953              This fn is a wrapper around the binary API fn a
19954              control plane will call, which expects this increment
19955              to have occurred. Hence letting the binary API control
19956              plane fn do the increment for consistency between VAT
19957              and other control planes.
19958            */
19959           this_hi = tmp2;
19960           vec_add1 (low_ports, this_low);
19961           vec_add1 (high_ports, this_hi);
19962         }
19963       else
19964         break;
19965     }
19966
19967   if (prefix_set == 0)
19968     {
19969       errmsg ("<address>/<mask> not specified");
19970       return -99;
19971     }
19972
19973   if (vrf_id == ~0)
19974     {
19975       errmsg ("VRF ID required, not specified");
19976       return -99;
19977     }
19978
19979   if (vrf_id == 0)
19980     {
19981       errmsg
19982         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19983       return -99;
19984     }
19985
19986   if (vec_len (low_ports) == 0)
19987     {
19988       errmsg ("At least one port or port range required");
19989       return -99;
19990     }
19991
19992   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19993
19994   mp->is_add = is_add;
19995
19996   if (is_ipv6)
19997     {
19998       mp->is_ipv6 = 1;
19999       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
20000     }
20001   else
20002     {
20003       mp->is_ipv6 = 0;
20004       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
20005     }
20006
20007   mp->mask_length = length;
20008   mp->number_of_ranges = vec_len (low_ports);
20009
20010   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
20011   vec_free (low_ports);
20012
20013   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20014   vec_free (high_ports);
20015
20016   mp->vrf_id = ntohl (vrf_id);
20017
20018   S (mp);
20019   W (ret);
20020   return ret;
20021 }
20022
20023 int
20024 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20025 {
20026   unformat_input_t *input = vam->input;
20027   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20028   u32 sw_if_index = ~0;
20029   int vrf_set = 0;
20030   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20031   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20032   u8 is_add = 1;
20033   int ret;
20034
20035   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20036     {
20037       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20038         ;
20039       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20040         ;
20041       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20042         vrf_set = 1;
20043       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20044         vrf_set = 1;
20045       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20046         vrf_set = 1;
20047       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20048         vrf_set = 1;
20049       else if (unformat (input, "del"))
20050         is_add = 0;
20051       else
20052         break;
20053     }
20054
20055   if (sw_if_index == ~0)
20056     {
20057       errmsg ("Interface required but not specified");
20058       return -99;
20059     }
20060
20061   if (vrf_set == 0)
20062     {
20063       errmsg ("VRF ID required but not specified");
20064       return -99;
20065     }
20066
20067   if (tcp_out_vrf_id == 0
20068       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20069     {
20070       errmsg
20071         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20072       return -99;
20073     }
20074
20075   /* Construct the API message */
20076   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20077
20078   mp->sw_if_index = ntohl (sw_if_index);
20079   mp->is_add = is_add;
20080   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20081   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20082   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20083   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20084
20085   /* send it... */
20086   S (mp);
20087
20088   /* Wait for a reply... */
20089   W (ret);
20090   return ret;
20091 }
20092
20093 static int
20094 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
20095 {
20096   unformat_input_t *i = vam->input;
20097   vl_api_ipsec_gre_add_del_tunnel_t *mp;
20098   u32 local_sa_id = 0;
20099   u32 remote_sa_id = 0;
20100   ip4_address_t src_address;
20101   ip4_address_t dst_address;
20102   u8 is_add = 1;
20103   int ret;
20104
20105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20106     {
20107       if (unformat (i, "local_sa %d", &local_sa_id))
20108         ;
20109       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20110         ;
20111       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
20112         ;
20113       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
20114         ;
20115       else if (unformat (i, "del"))
20116         is_add = 0;
20117       else
20118         {
20119           clib_warning ("parse error '%U'", format_unformat_error, i);
20120           return -99;
20121         }
20122     }
20123
20124   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
20125
20126   mp->local_sa_id = ntohl (local_sa_id);
20127   mp->remote_sa_id = ntohl (remote_sa_id);
20128   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
20129   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
20130   mp->is_add = is_add;
20131
20132   S (mp);
20133   W (ret);
20134   return ret;
20135 }
20136
20137 static int
20138 api_punt (vat_main_t * vam)
20139 {
20140   unformat_input_t *i = vam->input;
20141   vl_api_punt_t *mp;
20142   u32 ipv = ~0;
20143   u32 protocol = ~0;
20144   u32 port = ~0;
20145   int is_add = 1;
20146   int ret;
20147
20148   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20149     {
20150       if (unformat (i, "ip %d", &ipv))
20151         ;
20152       else if (unformat (i, "protocol %d", &protocol))
20153         ;
20154       else if (unformat (i, "port %d", &port))
20155         ;
20156       else if (unformat (i, "del"))
20157         is_add = 0;
20158       else
20159         {
20160           clib_warning ("parse error '%U'", format_unformat_error, i);
20161           return -99;
20162         }
20163     }
20164
20165   M (PUNT, mp);
20166
20167   mp->is_add = (u8) is_add;
20168   mp->ipv = (u8) ipv;
20169   mp->l4_protocol = (u8) protocol;
20170   mp->l4_port = htons ((u16) port);
20171
20172   S (mp);
20173   W (ret);
20174   return ret;
20175 }
20176
20177 static void vl_api_ipsec_gre_tunnel_details_t_handler
20178   (vl_api_ipsec_gre_tunnel_details_t * mp)
20179 {
20180   vat_main_t *vam = &vat_main;
20181
20182   print (vam->ofp, "%11d%15U%15U%14d%14d",
20183          ntohl (mp->sw_if_index),
20184          format_ip4_address, &mp->src_address,
20185          format_ip4_address, &mp->dst_address,
20186          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
20187 }
20188
20189 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
20190   (vl_api_ipsec_gre_tunnel_details_t * mp)
20191 {
20192   vat_main_t *vam = &vat_main;
20193   vat_json_node_t *node = NULL;
20194   struct in_addr ip4;
20195
20196   if (VAT_JSON_ARRAY != vam->json_tree.type)
20197     {
20198       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20199       vat_json_init_array (&vam->json_tree);
20200     }
20201   node = vat_json_array_add (&vam->json_tree);
20202
20203   vat_json_init_object (node);
20204   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
20205   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
20206   vat_json_object_add_ip4 (node, "src_address", ip4);
20207   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
20208   vat_json_object_add_ip4 (node, "dst_address", ip4);
20209   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
20210   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
20211 }
20212
20213 static int
20214 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
20215 {
20216   unformat_input_t *i = vam->input;
20217   vl_api_ipsec_gre_tunnel_dump_t *mp;
20218   vl_api_control_ping_t *mp_ping;
20219   u32 sw_if_index;
20220   u8 sw_if_index_set = 0;
20221   int ret;
20222
20223   /* Parse args required to build the message */
20224   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20225     {
20226       if (unformat (i, "sw_if_index %d", &sw_if_index))
20227         sw_if_index_set = 1;
20228       else
20229         break;
20230     }
20231
20232   if (sw_if_index_set == 0)
20233     {
20234       sw_if_index = ~0;
20235     }
20236
20237   if (!vam->json_output)
20238     {
20239       print (vam->ofp, "%11s%15s%15s%14s%14s",
20240              "sw_if_index", "src_address", "dst_address",
20241              "local_sa_id", "remote_sa_id");
20242     }
20243
20244   /* Get list of gre-tunnel interfaces */
20245   M (IPSEC_GRE_TUNNEL_DUMP, mp);
20246
20247   mp->sw_if_index = htonl (sw_if_index);
20248
20249   S (mp);
20250
20251   /* Use a control ping for synchronization */
20252   MPING (CONTROL_PING, mp_ping);
20253   S (mp_ping);
20254
20255   W (ret);
20256   return ret;
20257 }
20258
20259 static int
20260 api_delete_subif (vat_main_t * vam)
20261 {
20262   unformat_input_t *i = vam->input;
20263   vl_api_delete_subif_t *mp;
20264   u32 sw_if_index = ~0;
20265   int ret;
20266
20267   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20268     {
20269       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20270         ;
20271       if (unformat (i, "sw_if_index %d", &sw_if_index))
20272         ;
20273       else
20274         break;
20275     }
20276
20277   if (sw_if_index == ~0)
20278     {
20279       errmsg ("missing sw_if_index");
20280       return -99;
20281     }
20282
20283   /* Construct the API message */
20284   M (DELETE_SUBIF, mp);
20285   mp->sw_if_index = ntohl (sw_if_index);
20286
20287   S (mp);
20288   W (ret);
20289   return ret;
20290 }
20291
20292 #define foreach_pbb_vtr_op      \
20293 _("disable",  L2_VTR_DISABLED)  \
20294 _("pop",  L2_VTR_POP_2)         \
20295 _("push",  L2_VTR_PUSH_2)
20296
20297 static int
20298 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20299 {
20300   unformat_input_t *i = vam->input;
20301   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20302   u32 sw_if_index = ~0, vtr_op = ~0;
20303   u16 outer_tag = ~0;
20304   u8 dmac[6], smac[6];
20305   u8 dmac_set = 0, smac_set = 0;
20306   u16 vlanid = 0;
20307   u32 sid = ~0;
20308   u32 tmp;
20309   int ret;
20310
20311   /* Shut up coverity */
20312   memset (dmac, 0, sizeof (dmac));
20313   memset (smac, 0, sizeof (smac));
20314
20315   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20316     {
20317       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20318         ;
20319       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20320         ;
20321       else if (unformat (i, "vtr_op %d", &vtr_op))
20322         ;
20323 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20324       foreach_pbb_vtr_op
20325 #undef _
20326         else if (unformat (i, "translate_pbb_stag"))
20327         {
20328           if (unformat (i, "%d", &tmp))
20329             {
20330               vtr_op = L2_VTR_TRANSLATE_2_1;
20331               outer_tag = tmp;
20332             }
20333           else
20334             {
20335               errmsg
20336                 ("translate_pbb_stag operation requires outer tag definition");
20337               return -99;
20338             }
20339         }
20340       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20341         dmac_set++;
20342       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20343         smac_set++;
20344       else if (unformat (i, "sid %d", &sid))
20345         ;
20346       else if (unformat (i, "vlanid %d", &tmp))
20347         vlanid = tmp;
20348       else
20349         {
20350           clib_warning ("parse error '%U'", format_unformat_error, i);
20351           return -99;
20352         }
20353     }
20354
20355   if ((sw_if_index == ~0) || (vtr_op == ~0))
20356     {
20357       errmsg ("missing sw_if_index or vtr operation");
20358       return -99;
20359     }
20360   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20361       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20362     {
20363       errmsg
20364         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20365       return -99;
20366     }
20367
20368   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20369   mp->sw_if_index = ntohl (sw_if_index);
20370   mp->vtr_op = ntohl (vtr_op);
20371   mp->outer_tag = ntohs (outer_tag);
20372   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20373   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20374   mp->b_vlanid = ntohs (vlanid);
20375   mp->i_sid = ntohl (sid);
20376
20377   S (mp);
20378   W (ret);
20379   return ret;
20380 }
20381
20382 static int
20383 api_flow_classify_set_interface (vat_main_t * vam)
20384 {
20385   unformat_input_t *i = vam->input;
20386   vl_api_flow_classify_set_interface_t *mp;
20387   u32 sw_if_index;
20388   int sw_if_index_set;
20389   u32 ip4_table_index = ~0;
20390   u32 ip6_table_index = ~0;
20391   u8 is_add = 1;
20392   int ret;
20393
20394   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20395     {
20396       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20397         sw_if_index_set = 1;
20398       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20399         sw_if_index_set = 1;
20400       else if (unformat (i, "del"))
20401         is_add = 0;
20402       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20403         ;
20404       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20405         ;
20406       else
20407         {
20408           clib_warning ("parse error '%U'", format_unformat_error, i);
20409           return -99;
20410         }
20411     }
20412
20413   if (sw_if_index_set == 0)
20414     {
20415       errmsg ("missing interface name or sw_if_index");
20416       return -99;
20417     }
20418
20419   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20420
20421   mp->sw_if_index = ntohl (sw_if_index);
20422   mp->ip4_table_index = ntohl (ip4_table_index);
20423   mp->ip6_table_index = ntohl (ip6_table_index);
20424   mp->is_add = is_add;
20425
20426   S (mp);
20427   W (ret);
20428   return ret;
20429 }
20430
20431 static int
20432 api_flow_classify_dump (vat_main_t * vam)
20433 {
20434   unformat_input_t *i = vam->input;
20435   vl_api_flow_classify_dump_t *mp;
20436   vl_api_control_ping_t *mp_ping;
20437   u8 type = FLOW_CLASSIFY_N_TABLES;
20438   int ret;
20439
20440   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20441     ;
20442   else
20443     {
20444       errmsg ("classify table type must be specified");
20445       return -99;
20446     }
20447
20448   if (!vam->json_output)
20449     {
20450       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20451     }
20452
20453   M (FLOW_CLASSIFY_DUMP, mp);
20454   mp->type = type;
20455   /* send it... */
20456   S (mp);
20457
20458   /* Use a control ping for synchronization */
20459   MPING (CONTROL_PING, mp_ping);
20460   S (mp_ping);
20461
20462   /* Wait for a reply... */
20463   W (ret);
20464   return ret;
20465 }
20466
20467 static int
20468 api_feature_enable_disable (vat_main_t * vam)
20469 {
20470   unformat_input_t *i = vam->input;
20471   vl_api_feature_enable_disable_t *mp;
20472   u8 *arc_name = 0;
20473   u8 *feature_name = 0;
20474   u32 sw_if_index = ~0;
20475   u8 enable = 1;
20476   int ret;
20477
20478   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20479     {
20480       if (unformat (i, "arc_name %s", &arc_name))
20481         ;
20482       else if (unformat (i, "feature_name %s", &feature_name))
20483         ;
20484       else
20485         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20486         ;
20487       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20488         ;
20489       else if (unformat (i, "disable"))
20490         enable = 0;
20491       else
20492         break;
20493     }
20494
20495   if (arc_name == 0)
20496     {
20497       errmsg ("missing arc name");
20498       return -99;
20499     }
20500   if (vec_len (arc_name) > 63)
20501     {
20502       errmsg ("arc name too long");
20503     }
20504
20505   if (feature_name == 0)
20506     {
20507       errmsg ("missing feature name");
20508       return -99;
20509     }
20510   if (vec_len (feature_name) > 63)
20511     {
20512       errmsg ("feature name too long");
20513     }
20514
20515   if (sw_if_index == ~0)
20516     {
20517       errmsg ("missing interface name or sw_if_index");
20518       return -99;
20519     }
20520
20521   /* Construct the API message */
20522   M (FEATURE_ENABLE_DISABLE, mp);
20523   mp->sw_if_index = ntohl (sw_if_index);
20524   mp->enable = enable;
20525   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20526   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20527   vec_free (arc_name);
20528   vec_free (feature_name);
20529
20530   S (mp);
20531   W (ret);
20532   return ret;
20533 }
20534
20535 static int
20536 api_sw_interface_tag_add_del (vat_main_t * vam)
20537 {
20538   unformat_input_t *i = vam->input;
20539   vl_api_sw_interface_tag_add_del_t *mp;
20540   u32 sw_if_index = ~0;
20541   u8 *tag = 0;
20542   u8 enable = 1;
20543   int ret;
20544
20545   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20546     {
20547       if (unformat (i, "tag %s", &tag))
20548         ;
20549       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20550         ;
20551       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20552         ;
20553       else if (unformat (i, "del"))
20554         enable = 0;
20555       else
20556         break;
20557     }
20558
20559   if (sw_if_index == ~0)
20560     {
20561       errmsg ("missing interface name or sw_if_index");
20562       return -99;
20563     }
20564
20565   if (enable && (tag == 0))
20566     {
20567       errmsg ("no tag specified");
20568       return -99;
20569     }
20570
20571   /* Construct the API message */
20572   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20573   mp->sw_if_index = ntohl (sw_if_index);
20574   mp->is_add = enable;
20575   if (enable)
20576     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20577   vec_free (tag);
20578
20579   S (mp);
20580   W (ret);
20581   return ret;
20582 }
20583
20584 static void vl_api_l2_xconnect_details_t_handler
20585   (vl_api_l2_xconnect_details_t * mp)
20586 {
20587   vat_main_t *vam = &vat_main;
20588
20589   print (vam->ofp, "%15d%15d",
20590          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20591 }
20592
20593 static void vl_api_l2_xconnect_details_t_handler_json
20594   (vl_api_l2_xconnect_details_t * mp)
20595 {
20596   vat_main_t *vam = &vat_main;
20597   vat_json_node_t *node = NULL;
20598
20599   if (VAT_JSON_ARRAY != vam->json_tree.type)
20600     {
20601       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20602       vat_json_init_array (&vam->json_tree);
20603     }
20604   node = vat_json_array_add (&vam->json_tree);
20605
20606   vat_json_init_object (node);
20607   vat_json_object_add_uint (node, "rx_sw_if_index",
20608                             ntohl (mp->rx_sw_if_index));
20609   vat_json_object_add_uint (node, "tx_sw_if_index",
20610                             ntohl (mp->tx_sw_if_index));
20611 }
20612
20613 static int
20614 api_l2_xconnect_dump (vat_main_t * vam)
20615 {
20616   vl_api_l2_xconnect_dump_t *mp;
20617   vl_api_control_ping_t *mp_ping;
20618   int ret;
20619
20620   if (!vam->json_output)
20621     {
20622       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20623     }
20624
20625   M (L2_XCONNECT_DUMP, mp);
20626
20627   S (mp);
20628
20629   /* Use a control ping for synchronization */
20630   MPING (CONTROL_PING, mp_ping);
20631   S (mp_ping);
20632
20633   W (ret);
20634   return ret;
20635 }
20636
20637 static int
20638 api_sw_interface_set_mtu (vat_main_t * vam)
20639 {
20640   unformat_input_t *i = vam->input;
20641   vl_api_sw_interface_set_mtu_t *mp;
20642   u32 sw_if_index = ~0;
20643   u32 mtu = 0;
20644   int ret;
20645
20646   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20647     {
20648       if (unformat (i, "mtu %d", &mtu))
20649         ;
20650       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20651         ;
20652       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20653         ;
20654       else
20655         break;
20656     }
20657
20658   if (sw_if_index == ~0)
20659     {
20660       errmsg ("missing interface name or sw_if_index");
20661       return -99;
20662     }
20663
20664   if (mtu == 0)
20665     {
20666       errmsg ("no mtu specified");
20667       return -99;
20668     }
20669
20670   /* Construct the API message */
20671   M (SW_INTERFACE_SET_MTU, mp);
20672   mp->sw_if_index = ntohl (sw_if_index);
20673   mp->mtu = ntohs ((u16) mtu);
20674
20675   S (mp);
20676   W (ret);
20677   return ret;
20678 }
20679
20680 static int
20681 api_p2p_ethernet_add (vat_main_t * vam)
20682 {
20683   unformat_input_t *i = vam->input;
20684   vl_api_p2p_ethernet_add_t *mp;
20685   u32 parent_if_index = ~0;
20686   u32 sub_id = ~0;
20687   u8 remote_mac[6];
20688   u8 mac_set = 0;
20689   int ret;
20690
20691   memset (remote_mac, 0, sizeof (remote_mac));
20692   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20693     {
20694       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20695         ;
20696       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20697         ;
20698       else
20699         if (unformat
20700             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20701         mac_set++;
20702       else if (unformat (i, "sub_id %d", &sub_id))
20703         ;
20704       else
20705         {
20706           clib_warning ("parse error '%U'", format_unformat_error, i);
20707           return -99;
20708         }
20709     }
20710
20711   if (parent_if_index == ~0)
20712     {
20713       errmsg ("missing interface name or sw_if_index");
20714       return -99;
20715     }
20716   if (mac_set == 0)
20717     {
20718       errmsg ("missing remote mac address");
20719       return -99;
20720     }
20721   if (sub_id == ~0)
20722     {
20723       errmsg ("missing sub-interface id");
20724       return -99;
20725     }
20726
20727   M (P2P_ETHERNET_ADD, mp);
20728   mp->parent_if_index = ntohl (parent_if_index);
20729   mp->subif_id = ntohl (sub_id);
20730   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20731
20732   S (mp);
20733   W (ret);
20734   return ret;
20735 }
20736
20737 static int
20738 api_p2p_ethernet_del (vat_main_t * vam)
20739 {
20740   unformat_input_t *i = vam->input;
20741   vl_api_p2p_ethernet_del_t *mp;
20742   u32 parent_if_index = ~0;
20743   u8 remote_mac[6];
20744   u8 mac_set = 0;
20745   int ret;
20746
20747   memset (remote_mac, 0, sizeof (remote_mac));
20748   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20749     {
20750       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20751         ;
20752       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20753         ;
20754       else
20755         if (unformat
20756             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20757         mac_set++;
20758       else
20759         {
20760           clib_warning ("parse error '%U'", format_unformat_error, i);
20761           return -99;
20762         }
20763     }
20764
20765   if (parent_if_index == ~0)
20766     {
20767       errmsg ("missing interface name or sw_if_index");
20768       return -99;
20769     }
20770   if (mac_set == 0)
20771     {
20772       errmsg ("missing remote mac address");
20773       return -99;
20774     }
20775
20776   M (P2P_ETHERNET_DEL, mp);
20777   mp->parent_if_index = ntohl (parent_if_index);
20778   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20779
20780   S (mp);
20781   W (ret);
20782   return ret;
20783 }
20784
20785 static int
20786 api_lldp_config (vat_main_t * vam)
20787 {
20788   unformat_input_t *i = vam->input;
20789   vl_api_lldp_config_t *mp;
20790   int tx_hold = 0;
20791   int tx_interval = 0;
20792   u8 *sys_name = NULL;
20793   int ret;
20794
20795   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20796     {
20797       if (unformat (i, "system-name %s", &sys_name))
20798         ;
20799       else if (unformat (i, "tx-hold %d", &tx_hold))
20800         ;
20801       else if (unformat (i, "tx-interval %d", &tx_interval))
20802         ;
20803       else
20804         {
20805           clib_warning ("parse error '%U'", format_unformat_error, i);
20806           return -99;
20807         }
20808     }
20809
20810   vec_add1 (sys_name, 0);
20811
20812   M (LLDP_CONFIG, mp);
20813   mp->tx_hold = htonl (tx_hold);
20814   mp->tx_interval = htonl (tx_interval);
20815   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20816   vec_free (sys_name);
20817
20818   S (mp);
20819   W (ret);
20820   return ret;
20821 }
20822
20823 static int
20824 api_sw_interface_set_lldp (vat_main_t * vam)
20825 {
20826   unformat_input_t *i = vam->input;
20827   vl_api_sw_interface_set_lldp_t *mp;
20828   u32 sw_if_index = ~0;
20829   u32 enable = 1;
20830   u8 *port_desc = NULL, *mgmt_oid = NULL;
20831   ip4_address_t ip4_addr;
20832   ip6_address_t ip6_addr;
20833   int ret;
20834
20835   memset (&ip4_addr, 0, sizeof (ip4_addr));
20836   memset (&ip6_addr, 0, sizeof (ip6_addr));
20837
20838   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20839     {
20840       if (unformat (i, "disable"))
20841         enable = 0;
20842       else
20843         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20844         ;
20845       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20846         ;
20847       else if (unformat (i, "port-desc %s", &port_desc))
20848         ;
20849       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20850         ;
20851       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20852         ;
20853       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20854         ;
20855       else
20856         break;
20857     }
20858
20859   if (sw_if_index == ~0)
20860     {
20861       errmsg ("missing interface name or sw_if_index");
20862       return -99;
20863     }
20864
20865   /* Construct the API message */
20866   vec_add1 (port_desc, 0);
20867   vec_add1 (mgmt_oid, 0);
20868   M (SW_INTERFACE_SET_LLDP, mp);
20869   mp->sw_if_index = ntohl (sw_if_index);
20870   mp->enable = enable;
20871   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20872   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20873   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20874   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20875   vec_free (port_desc);
20876   vec_free (mgmt_oid);
20877
20878   S (mp);
20879   W (ret);
20880   return ret;
20881 }
20882
20883 static int
20884 api_tcp_configure_src_addresses (vat_main_t * vam)
20885 {
20886   vl_api_tcp_configure_src_addresses_t *mp;
20887   unformat_input_t *i = vam->input;
20888   ip4_address_t v4first, v4last;
20889   ip6_address_t v6first, v6last;
20890   u8 range_set = 0;
20891   u32 vrf_id = 0;
20892   int ret;
20893
20894   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20895     {
20896       if (unformat (i, "%U - %U",
20897                     unformat_ip4_address, &v4first,
20898                     unformat_ip4_address, &v4last))
20899         {
20900           if (range_set)
20901             {
20902               errmsg ("one range per message (range already set)");
20903               return -99;
20904             }
20905           range_set = 1;
20906         }
20907       else if (unformat (i, "%U - %U",
20908                          unformat_ip6_address, &v6first,
20909                          unformat_ip6_address, &v6last))
20910         {
20911           if (range_set)
20912             {
20913               errmsg ("one range per message (range already set)");
20914               return -99;
20915             }
20916           range_set = 2;
20917         }
20918       else if (unformat (i, "vrf %d", &vrf_id))
20919         ;
20920       else
20921         break;
20922     }
20923
20924   if (range_set == 0)
20925     {
20926       errmsg ("address range not set");
20927       return -99;
20928     }
20929
20930   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20931   mp->vrf_id = ntohl (vrf_id);
20932   /* ipv6? */
20933   if (range_set == 2)
20934     {
20935       mp->is_ipv6 = 1;
20936       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20937       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20938     }
20939   else
20940     {
20941       mp->is_ipv6 = 0;
20942       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20943       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20944     }
20945   S (mp);
20946   W (ret);
20947   return ret;
20948 }
20949
20950 static int
20951 api_app_namespace_add_del (vat_main_t * vam)
20952 {
20953   vl_api_app_namespace_add_del_t *mp;
20954   unformat_input_t *i = vam->input;
20955   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
20956   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
20957   u64 secret;
20958   int ret;
20959
20960   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20961     {
20962       if (unformat (i, "id %_%v%_", &ns_id))
20963         ;
20964       else if (unformat (i, "secret %lu", &secret))
20965         secret_set = 1;
20966       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20967         sw_if_index_set = 1;
20968       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
20969         ;
20970       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
20971         ;
20972       else
20973         break;
20974     }
20975   if (!ns_id || !secret_set || !sw_if_index_set)
20976     {
20977       errmsg ("namespace id, secret and sw_if_index must be set");
20978       return -99;
20979     }
20980   if (vec_len (ns_id) > 64)
20981     {
20982       errmsg ("namespace id too long");
20983       return -99;
20984     }
20985   M (APP_NAMESPACE_ADD_DEL, mp);
20986
20987   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
20988   mp->namespace_id_len = vec_len (ns_id);
20989   mp->secret = clib_host_to_net_u64 (secret);
20990   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20991   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
20992   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
20993   vec_free (ns_id);
20994   S (mp);
20995   W (ret);
20996   return ret;
20997 }
20998
20999 static int
21000 api_memfd_segment_create (vat_main_t * vam)
21001 {
21002 #if VPP_API_TEST_BUILTIN == 0
21003   unformat_input_t *i = vam->input;
21004   vl_api_memfd_segment_create_t *mp;
21005   u64 size = 64 << 20;
21006   int ret;
21007
21008   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21009     {
21010       if (unformat (i, "size %U", unformat_memory_size, &size))
21011         ;
21012       else
21013         break;
21014     }
21015
21016   M (MEMFD_SEGMENT_CREATE, mp);
21017   mp->requested_size = size;
21018   S (mp);
21019   W (ret);
21020   return ret;
21021
21022 #else
21023   errmsg ("memfd_segment_create (builtin) not supported");
21024   return -99;
21025 #endif
21026 }
21027
21028 static int
21029 api_dns_enable_disable (vat_main_t * vam)
21030 {
21031   unformat_input_t *line_input = vam->input;
21032   vl_api_dns_enable_disable_t *mp;
21033   u8 enable_disable = 1;
21034   int ret;
21035
21036   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21037     {
21038       if (unformat (line_input, "disable"))
21039         enable_disable = 0;
21040       if (unformat (line_input, "enable"))
21041         enable_disable = 1;
21042       else
21043         break;
21044     }
21045
21046   /* Construct the API message */
21047   M (DNS_ENABLE_DISABLE, mp);
21048   mp->enable = enable_disable;
21049
21050   /* send it... */
21051   S (mp);
21052   /* Wait for the reply */
21053   W (ret);
21054   return ret;
21055 }
21056
21057 static int
21058 api_dns_resolve_name (vat_main_t * vam)
21059 {
21060   unformat_input_t *line_input = vam->input;
21061   vl_api_dns_resolve_name_t *mp;
21062   u8 *name = 0;
21063   int ret;
21064
21065   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21066     {
21067       if (unformat (line_input, "%s", &name))
21068         ;
21069       else
21070         break;
21071     }
21072
21073   if (vec_len (name) > 127)
21074     {
21075       errmsg ("name too long");
21076       return -99;
21077     }
21078
21079   /* Construct the API message */
21080   M (DNS_RESOLVE_NAME, mp);
21081   memcpy (mp->name, name, vec_len (name));
21082   vec_free (name);
21083
21084   /* send it... */
21085   S (mp);
21086   /* Wait for the reply */
21087   W (ret);
21088   return ret;
21089 }
21090
21091 static int
21092 api_dns_resolve_ip (vat_main_t * vam)
21093 {
21094   unformat_input_t *line_input = vam->input;
21095   vl_api_dns_resolve_ip_t *mp;
21096   int is_ip6 = -1;
21097   ip4_address_t addr4;
21098   ip6_address_t addr6;
21099   int ret;
21100
21101   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21102     {
21103       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21104         is_ip6 = 1;
21105       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21106         is_ip6 = 0;
21107       else
21108         break;
21109     }
21110
21111   if (is_ip6 == -1)
21112     {
21113       errmsg ("missing address");
21114       return -99;
21115     }
21116
21117   /* Construct the API message */
21118   M (DNS_RESOLVE_IP, mp);
21119   mp->is_ip6 = is_ip6;
21120   if (is_ip6)
21121     memcpy (mp->address, &addr6, sizeof (addr6));
21122   else
21123     memcpy (mp->address, &addr4, sizeof (addr4));
21124
21125   /* send it... */
21126   S (mp);
21127   /* Wait for the reply */
21128   W (ret);
21129   return ret;
21130 }
21131
21132 static int
21133 api_dns_name_server_add_del (vat_main_t * vam)
21134 {
21135   unformat_input_t *i = vam->input;
21136   vl_api_dns_name_server_add_del_t *mp;
21137   u8 is_add = 1;
21138   ip6_address_t ip6_server;
21139   ip4_address_t ip4_server;
21140   int ip6_set = 0;
21141   int ip4_set = 0;
21142   int ret = 0;
21143
21144   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21145     {
21146       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21147         ip6_set = 1;
21148       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21149         ip4_set = 1;
21150       else if (unformat (i, "del"))
21151         is_add = 0;
21152       else
21153         {
21154           clib_warning ("parse error '%U'", format_unformat_error, i);
21155           return -99;
21156         }
21157     }
21158
21159   if (ip4_set && ip6_set)
21160     {
21161       errmsg ("Only one server address allowed per message");
21162       return -99;
21163     }
21164   if ((ip4_set + ip6_set) == 0)
21165     {
21166       errmsg ("Server address required");
21167       return -99;
21168     }
21169
21170   /* Construct the API message */
21171   M (DNS_NAME_SERVER_ADD_DEL, mp);
21172
21173   if (ip6_set)
21174     {
21175       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21176       mp->is_ip6 = 1;
21177     }
21178   else
21179     {
21180       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21181       mp->is_ip6 = 0;
21182     }
21183
21184   mp->is_add = is_add;
21185
21186   /* send it... */
21187   S (mp);
21188
21189   /* Wait for a reply, return good/bad news  */
21190   W (ret);
21191   return ret;
21192 }
21193
21194 static int
21195 api_session_rule_add_del (vat_main_t * vam)
21196 {
21197   vl_api_session_rule_add_del_t *mp;
21198   unformat_input_t *i = vam->input;
21199   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
21200   u32 appns_index = 0, scope = 0;
21201   ip4_address_t lcl_ip4, rmt_ip4;
21202   ip6_address_t lcl_ip6, rmt_ip6;
21203   u8 is_ip4 = 1, conn_set = 0;
21204   u8 is_add = 1;
21205   int ret;
21206
21207   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21208     {
21209       if (unformat (i, "del"))
21210         is_add = 0;
21211       else if (unformat (i, "add"))
21212         ;
21213       else if (unformat (i, "proto tcp"))
21214         proto = 0;
21215       else if (unformat (i, "proto udp"))
21216         proto = 1;
21217       else if (unformat (i, "appns %d", &appns_index))
21218         ;
21219       else if (unformat (i, "scope %d", &scope))
21220         ;
21221       else
21222         if (unformat
21223             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
21224              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
21225              &rmt_port))
21226         {
21227           is_ip4 = 1;
21228           conn_set = 1;
21229         }
21230       else
21231         if (unformat
21232             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
21233              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
21234              &rmt_port))
21235         {
21236           is_ip4 = 0;
21237           conn_set = 1;
21238         }
21239       else if (unformat (i, "action %d", &action))
21240         ;
21241       else
21242         break;
21243     }
21244   if (proto == ~0 || !conn_set || action == ~0)
21245     {
21246       errmsg ("transport proto, connection and action must be set");
21247       return -99;
21248     }
21249
21250   if (scope > 3)
21251     {
21252       errmsg ("scope should be 0-3");
21253       return -99;
21254     }
21255
21256   M (SESSION_RULE_ADD_DEL, mp);
21257
21258   mp->is_ip4 = is_ip4;
21259   mp->transport_proto = proto;
21260   mp->lcl_plen = clib_host_to_net_u16 (lcl_plen);
21261   mp->rmt_plen = clib_host_to_net_u16 (rmt_plen);
21262   mp->action_index = clib_host_to_net_u32 (action);
21263   mp->appns_index = clib_host_to_net_u32 (appns_index);
21264   mp->scope = scope;
21265   mp->is_add = is_add;
21266   if (is_ip4)
21267     {
21268       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
21269       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
21270     }
21271   else
21272     {
21273       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
21274       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
21275     }
21276
21277   S (mp);
21278   W (ret);
21279   return ret;
21280 }
21281
21282 static int
21283 q_or_quit (vat_main_t * vam)
21284 {
21285 #if VPP_API_TEST_BUILTIN == 0
21286   longjmp (vam->jump_buf, 1);
21287 #endif
21288   return 0;                     /* not so much */
21289 }
21290
21291 static int
21292 q (vat_main_t * vam)
21293 {
21294   return q_or_quit (vam);
21295 }
21296
21297 static int
21298 quit (vat_main_t * vam)
21299 {
21300   return q_or_quit (vam);
21301 }
21302
21303 static int
21304 comment (vat_main_t * vam)
21305 {
21306   return 0;
21307 }
21308
21309 static int
21310 cmd_cmp (void *a1, void *a2)
21311 {
21312   u8 **c1 = a1;
21313   u8 **c2 = a2;
21314
21315   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21316 }
21317
21318 static int
21319 help (vat_main_t * vam)
21320 {
21321   u8 **cmds = 0;
21322   u8 *name = 0;
21323   hash_pair_t *p;
21324   unformat_input_t *i = vam->input;
21325   int j;
21326
21327   if (unformat (i, "%s", &name))
21328     {
21329       uword *hs;
21330
21331       vec_add1 (name, 0);
21332
21333       hs = hash_get_mem (vam->help_by_name, name);
21334       if (hs)
21335         print (vam->ofp, "usage: %s %s", name, hs[0]);
21336       else
21337         print (vam->ofp, "No such msg / command '%s'", name);
21338       vec_free (name);
21339       return 0;
21340     }
21341
21342   print (vam->ofp, "Help is available for the following:");
21343
21344     /* *INDENT-OFF* */
21345     hash_foreach_pair (p, vam->function_by_name,
21346     ({
21347       vec_add1 (cmds, (u8 *)(p->key));
21348     }));
21349     /* *INDENT-ON* */
21350
21351   vec_sort_with_function (cmds, cmd_cmp);
21352
21353   for (j = 0; j < vec_len (cmds); j++)
21354     print (vam->ofp, "%s", cmds[j]);
21355
21356   vec_free (cmds);
21357   return 0;
21358 }
21359
21360 static int
21361 set (vat_main_t * vam)
21362 {
21363   u8 *name = 0, *value = 0;
21364   unformat_input_t *i = vam->input;
21365
21366   if (unformat (i, "%s", &name))
21367     {
21368       /* The input buffer is a vector, not a string. */
21369       value = vec_dup (i->buffer);
21370       vec_delete (value, i->index, 0);
21371       /* Almost certainly has a trailing newline */
21372       if (value[vec_len (value) - 1] == '\n')
21373         value[vec_len (value) - 1] = 0;
21374       /* Make sure it's a proper string, one way or the other */
21375       vec_add1 (value, 0);
21376       (void) clib_macro_set_value (&vam->macro_main,
21377                                    (char *) name, (char *) value);
21378     }
21379   else
21380     errmsg ("usage: set <name> <value>");
21381
21382   vec_free (name);
21383   vec_free (value);
21384   return 0;
21385 }
21386
21387 static int
21388 unset (vat_main_t * vam)
21389 {
21390   u8 *name = 0;
21391
21392   if (unformat (vam->input, "%s", &name))
21393     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21394       errmsg ("unset: %s wasn't set", name);
21395   vec_free (name);
21396   return 0;
21397 }
21398
21399 typedef struct
21400 {
21401   u8 *name;
21402   u8 *value;
21403 } macro_sort_t;
21404
21405
21406 static int
21407 macro_sort_cmp (void *a1, void *a2)
21408 {
21409   macro_sort_t *s1 = a1;
21410   macro_sort_t *s2 = a2;
21411
21412   return strcmp ((char *) (s1->name), (char *) (s2->name));
21413 }
21414
21415 static int
21416 dump_macro_table (vat_main_t * vam)
21417 {
21418   macro_sort_t *sort_me = 0, *sm;
21419   int i;
21420   hash_pair_t *p;
21421
21422     /* *INDENT-OFF* */
21423     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21424     ({
21425       vec_add2 (sort_me, sm, 1);
21426       sm->name = (u8 *)(p->key);
21427       sm->value = (u8 *) (p->value[0]);
21428     }));
21429     /* *INDENT-ON* */
21430
21431   vec_sort_with_function (sort_me, macro_sort_cmp);
21432
21433   if (vec_len (sort_me))
21434     print (vam->ofp, "%-15s%s", "Name", "Value");
21435   else
21436     print (vam->ofp, "The macro table is empty...");
21437
21438   for (i = 0; i < vec_len (sort_me); i++)
21439     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21440   return 0;
21441 }
21442
21443 static int
21444 dump_node_table (vat_main_t * vam)
21445 {
21446   int i, j;
21447   vlib_node_t *node, *next_node;
21448
21449   if (vec_len (vam->graph_nodes) == 0)
21450     {
21451       print (vam->ofp, "Node table empty, issue get_node_graph...");
21452       return 0;
21453     }
21454
21455   for (i = 0; i < vec_len (vam->graph_nodes); i++)
21456     {
21457       node = vam->graph_nodes[i];
21458       print (vam->ofp, "[%d] %s", i, node->name);
21459       for (j = 0; j < vec_len (node->next_nodes); j++)
21460         {
21461           if (node->next_nodes[j] != ~0)
21462             {
21463               next_node = vam->graph_nodes[node->next_nodes[j]];
21464               print (vam->ofp, "  [%d] %s", j, next_node->name);
21465             }
21466         }
21467     }
21468   return 0;
21469 }
21470
21471 static int
21472 value_sort_cmp (void *a1, void *a2)
21473 {
21474   name_sort_t *n1 = a1;
21475   name_sort_t *n2 = a2;
21476
21477   if (n1->value < n2->value)
21478     return -1;
21479   if (n1->value > n2->value)
21480     return 1;
21481   return 0;
21482 }
21483
21484
21485 static int
21486 dump_msg_api_table (vat_main_t * vam)
21487 {
21488   api_main_t *am = &api_main;
21489   name_sort_t *nses = 0, *ns;
21490   hash_pair_t *hp;
21491   int i;
21492
21493   /* *INDENT-OFF* */
21494   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21495   ({
21496     vec_add2 (nses, ns, 1);
21497     ns->name = (u8 *)(hp->key);
21498     ns->value = (u32) hp->value[0];
21499   }));
21500   /* *INDENT-ON* */
21501
21502   vec_sort_with_function (nses, value_sort_cmp);
21503
21504   for (i = 0; i < vec_len (nses); i++)
21505     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21506   vec_free (nses);
21507   return 0;
21508 }
21509
21510 static int
21511 get_msg_id (vat_main_t * vam)
21512 {
21513   u8 *name_and_crc;
21514   u32 message_index;
21515
21516   if (unformat (vam->input, "%s", &name_and_crc))
21517     {
21518       message_index = vl_api_get_msg_index (name_and_crc);
21519       if (message_index == ~0)
21520         {
21521           print (vam->ofp, " '%s' not found", name_and_crc);
21522           return 0;
21523         }
21524       print (vam->ofp, " '%s' has message index %d",
21525              name_and_crc, message_index);
21526       return 0;
21527     }
21528   errmsg ("name_and_crc required...");
21529   return 0;
21530 }
21531
21532 static int
21533 search_node_table (vat_main_t * vam)
21534 {
21535   unformat_input_t *line_input = vam->input;
21536   u8 *node_to_find;
21537   int j;
21538   vlib_node_t *node, *next_node;
21539   uword *p;
21540
21541   if (vam->graph_node_index_by_name == 0)
21542     {
21543       print (vam->ofp, "Node table empty, issue get_node_graph...");
21544       return 0;
21545     }
21546
21547   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21548     {
21549       if (unformat (line_input, "%s", &node_to_find))
21550         {
21551           vec_add1 (node_to_find, 0);
21552           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21553           if (p == 0)
21554             {
21555               print (vam->ofp, "%s not found...", node_to_find);
21556               goto out;
21557             }
21558           node = vam->graph_nodes[p[0]];
21559           print (vam->ofp, "[%d] %s", p[0], node->name);
21560           for (j = 0; j < vec_len (node->next_nodes); j++)
21561             {
21562               if (node->next_nodes[j] != ~0)
21563                 {
21564                   next_node = vam->graph_nodes[node->next_nodes[j]];
21565                   print (vam->ofp, "  [%d] %s", j, next_node->name);
21566                 }
21567             }
21568         }
21569
21570       else
21571         {
21572           clib_warning ("parse error '%U'", format_unformat_error,
21573                         line_input);
21574           return -99;
21575         }
21576
21577     out:
21578       vec_free (node_to_find);
21579
21580     }
21581
21582   return 0;
21583 }
21584
21585
21586 static int
21587 script (vat_main_t * vam)
21588 {
21589 #if (VPP_API_TEST_BUILTIN==0)
21590   u8 *s = 0;
21591   char *save_current_file;
21592   unformat_input_t save_input;
21593   jmp_buf save_jump_buf;
21594   u32 save_line_number;
21595
21596   FILE *new_fp, *save_ifp;
21597
21598   if (unformat (vam->input, "%s", &s))
21599     {
21600       new_fp = fopen ((char *) s, "r");
21601       if (new_fp == 0)
21602         {
21603           errmsg ("Couldn't open script file %s", s);
21604           vec_free (s);
21605           return -99;
21606         }
21607     }
21608   else
21609     {
21610       errmsg ("Missing script name");
21611       return -99;
21612     }
21613
21614   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
21615   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
21616   save_ifp = vam->ifp;
21617   save_line_number = vam->input_line_number;
21618   save_current_file = (char *) vam->current_file;
21619
21620   vam->input_line_number = 0;
21621   vam->ifp = new_fp;
21622   vam->current_file = s;
21623   do_one_file (vam);
21624
21625   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
21626   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
21627   vam->ifp = save_ifp;
21628   vam->input_line_number = save_line_number;
21629   vam->current_file = (u8 *) save_current_file;
21630   vec_free (s);
21631
21632   return 0;
21633 #else
21634   clib_warning ("use the exec command...");
21635   return -99;
21636 #endif
21637 }
21638
21639 static int
21640 echo (vat_main_t * vam)
21641 {
21642   print (vam->ofp, "%v", vam->input->buffer);
21643   return 0;
21644 }
21645
21646 /* List of API message constructors, CLI names map to api_xxx */
21647 #define foreach_vpe_api_msg                                             \
21648 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
21649 _(sw_interface_dump,"")                                                 \
21650 _(sw_interface_set_flags,                                               \
21651   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
21652 _(sw_interface_add_del_address,                                         \
21653   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
21654 _(sw_interface_set_table,                                               \
21655   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
21656 _(sw_interface_set_mpls_enable,                                         \
21657   "<intfc> | sw_if_index [disable | dis]")                              \
21658 _(sw_interface_set_vpath,                                               \
21659   "<intfc> | sw_if_index <id> enable | disable")                        \
21660 _(sw_interface_set_vxlan_bypass,                                        \
21661   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21662 _(sw_interface_set_geneve_bypass,                                       \
21663   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21664 _(sw_interface_set_l2_xconnect,                                         \
21665   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21666   "enable | disable")                                                   \
21667 _(sw_interface_set_l2_bridge,                                           \
21668   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
21669   "[shg <split-horizon-group>] [bvi]\n"                                 \
21670   "enable | disable")                                                   \
21671 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
21672 _(bridge_domain_add_del,                                                \
21673   "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") \
21674 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
21675 _(l2fib_add_del,                                                        \
21676   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
21677 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
21678 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
21679 _(l2_flags,                                                             \
21680   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21681 _(bridge_flags,                                                         \
21682   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21683 _(tap_connect,                                                          \
21684   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
21685 _(tap_modify,                                                           \
21686   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
21687 _(tap_delete,                                                           \
21688   "<vpp-if-name> | sw_if_index <id>")                                   \
21689 _(sw_interface_tap_dump, "")                                            \
21690 _(ip_table_add_del,                                                     \
21691   "table-id <n> [ipv6]\n")                                              \
21692 _(ip_add_del_route,                                                     \
21693   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
21694   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
21695   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
21696   "[multipath] [count <n>]")                                            \
21697 _(ip_mroute_add_del,                                                    \
21698   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
21699   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
21700 _(mpls_table_add_del,                                                   \
21701   "table-id <n>\n")                                                     \
21702 _(mpls_route_add_del,                                                   \
21703   "<label> <eos> via <addr> [table-id <n>]\n"                           \
21704   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
21705   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
21706   "[multipath] [count <n>]")                                            \
21707 _(mpls_ip_bind_unbind,                                                  \
21708   "<label> <addr/len>")                                                 \
21709 _(mpls_tunnel_add_del,                                                  \
21710   " via <addr> [table-id <n>]\n"                                        \
21711   "sw_if_index <id>] [l2]  [del]")                                      \
21712 _(proxy_arp_add_del,                                                    \
21713   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
21714 _(proxy_arp_intfc_enable_disable,                                       \
21715   "<intfc> | sw_if_index <id> enable | disable")                        \
21716 _(sw_interface_set_unnumbered,                                          \
21717   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
21718 _(ip_neighbor_add_del,                                                  \
21719   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
21720   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
21721 _(reset_vrf, "vrf <id> [ipv6]")                                         \
21722 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
21723 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
21724   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
21725   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
21726   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
21727 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
21728 _(reset_fib, "vrf <n> [ipv6]")                                          \
21729 _(dhcp_proxy_config,                                                    \
21730   "svr <v46-address> src <v46-address>\n"                               \
21731    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
21732 _(dhcp_proxy_set_vss,                                                   \
21733   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
21734 _(dhcp_proxy_dump, "ip6")                                               \
21735 _(dhcp_client_config,                                                   \
21736   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
21737 _(set_ip_flow_hash,                                                     \
21738   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
21739 _(sw_interface_ip6_enable_disable,                                      \
21740   "<intfc> | sw_if_index <id> enable | disable")                        \
21741 _(sw_interface_ip6_set_link_local_address,                              \
21742   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
21743 _(ip6nd_proxy_add_del,                                                  \
21744   "<intfc> | sw_if_index <id> <ip6-address>")                           \
21745 _(ip6nd_proxy_dump, "")                                                 \
21746 _(sw_interface_ip6nd_ra_prefix,                                         \
21747   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
21748   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
21749   "[nolink] [isno]")                                                    \
21750 _(sw_interface_ip6nd_ra_config,                                         \
21751   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
21752   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
21753   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
21754 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
21755 _(l2_patch_add_del,                                                     \
21756   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21757   "enable | disable")                                                   \
21758 _(sr_localsid_add_del,                                                  \
21759   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
21760   "fib-table <num> (end.psp) sw_if_index <num>")                        \
21761 _(classify_add_del_table,                                               \
21762   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
21763   " [del] [del-chain] mask <mask-value>\n"                              \
21764   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
21765   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
21766 _(classify_add_del_session,                                             \
21767   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
21768   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
21769   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
21770   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
21771 _(classify_set_interface_ip_table,                                      \
21772   "<intfc> | sw_if_index <nn> table <nn>")                              \
21773 _(classify_set_interface_l2_tables,                                     \
21774   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21775   "  [other-table <nn>]")                                               \
21776 _(get_node_index, "node <node-name")                                    \
21777 _(add_node_next, "node <node-name> next <next-node-name>")              \
21778 _(l2tpv3_create_tunnel,                                                 \
21779   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
21780   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
21781   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
21782 _(l2tpv3_set_tunnel_cookies,                                            \
21783   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
21784   "[new_remote_cookie <nn>]\n")                                         \
21785 _(l2tpv3_interface_enable_disable,                                      \
21786   "<intfc> | sw_if_index <nn> enable | disable")                        \
21787 _(l2tpv3_set_lookup_key,                                                \
21788   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
21789 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
21790 _(vxlan_add_del_tunnel,                                                 \
21791   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21792   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21793   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21794 _(geneve_add_del_tunnel,                                                \
21795   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21796   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21797   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21798 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
21799 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
21800 _(gre_add_del_tunnel,                                                   \
21801   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
21802 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
21803 _(l2_fib_clear_table, "")                                               \
21804 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
21805 _(l2_interface_vlan_tag_rewrite,                                        \
21806   "<intfc> | sw_if_index <nn> \n"                                       \
21807   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
21808   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
21809 _(create_vhost_user_if,                                                 \
21810         "socket <filename> [server] [renumber <dev_instance>] "         \
21811         "[mac <mac_address>]")                                          \
21812 _(modify_vhost_user_if,                                                 \
21813         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
21814         "[server] [renumber <dev_instance>]")                           \
21815 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
21816 _(sw_interface_vhost_user_dump, "")                                     \
21817 _(show_version, "")                                                     \
21818 _(vxlan_gpe_add_del_tunnel,                                             \
21819   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
21820   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21821   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
21822   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
21823 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
21824 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
21825 _(interface_name_renumber,                                              \
21826   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
21827 _(input_acl_set_interface,                                              \
21828   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21829   "  [l2-table <nn>] [del]")                                            \
21830 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
21831 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
21832 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
21833 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
21834 _(ip_dump, "ipv4 | ipv6")                                               \
21835 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
21836 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
21837   "  spid_id <n> ")                                                     \
21838 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
21839   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
21840   "  integ_alg <alg> integ_key <hex>")                                  \
21841 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
21842   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
21843   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
21844   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
21845 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
21846 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
21847   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
21848   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
21849   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
21850 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
21851 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
21852   "  <alg> <hex>\n")                                                    \
21853 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
21854 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
21855 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
21856   "(auth_data 0x<data> | auth_data <data>)")                            \
21857 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
21858   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
21859 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
21860   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
21861   "(local|remote)")                                                     \
21862 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
21863 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
21864 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
21865 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
21866 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
21867 _(ikev2_initiate_sa_init, "<profile_name>")                             \
21868 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
21869 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
21870 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
21871 _(delete_loopback,"sw_if_index <nn>")                                   \
21872 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
21873 _(map_add_domain,                                                       \
21874   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
21875   "ip6-src <ip6addr> "                                                  \
21876   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
21877 _(map_del_domain, "index <n>")                                          \
21878 _(map_add_del_rule,                                                     \
21879   "index <n> psid <n> dst <ip6addr> [del]")                             \
21880 _(map_domain_dump, "")                                                  \
21881 _(map_rule_dump, "index <map-domain>")                                  \
21882 _(want_interface_events,  "enable|disable")                             \
21883 _(want_stats,"enable|disable")                                          \
21884 _(get_first_msg_id, "client <name>")                                    \
21885 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
21886 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
21887   "fib-id <nn> [ip4][ip6][default]")                                    \
21888 _(get_node_graph, " ")                                                  \
21889 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
21890 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
21891 _(ioam_disable, "")                                                     \
21892 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
21893                             " sw_if_index <sw_if_index> p <priority> "  \
21894                             "w <weight>] [del]")                        \
21895 _(one_add_del_locator, "locator-set <locator_name> "                    \
21896                         "iface <intf> | sw_if_index <sw_if_index> "     \
21897                         "p <priority> w <weight> [del]")                \
21898 _(one_add_del_local_eid,"vni <vni> eid "                                \
21899                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21900                          "locator-set <locator_name> [del]"             \
21901                          "[key-id sha1|sha256 secret-key <secret-key>]")\
21902 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
21903 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
21904 _(one_enable_disable, "enable|disable")                                 \
21905 _(one_map_register_enable_disable, "enable|disable")                    \
21906 _(one_map_register_fallback_threshold, "<value>")                       \
21907 _(one_rloc_probe_enable_disable, "enable|disable")                      \
21908 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
21909                                "[seid <seid>] "                         \
21910                                "rloc <locator> p <prio> "               \
21911                                "w <weight> [rloc <loc> ... ] "          \
21912                                "action <action> [del-all]")             \
21913 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
21914                           "<local-eid>")                                \
21915 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
21916 _(one_use_petr, "ip-address> | disable")                                \
21917 _(one_map_request_mode, "src-dst|dst-only")                             \
21918 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
21919 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
21920 _(one_locator_set_dump, "[local | remote]")                             \
21921 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
21922 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
21923                        "[local] | [remote]")                            \
21924 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
21925 _(one_ndp_bd_get, "")                                                   \
21926 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
21927 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
21928 _(one_l2_arp_bd_get, "")                                                \
21929 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
21930 _(one_stats_enable_disable, "enable|disalbe")                           \
21931 _(show_one_stats_enable_disable, "")                                    \
21932 _(one_eid_table_vni_dump, "")                                           \
21933 _(one_eid_table_map_dump, "l2|l3")                                      \
21934 _(one_map_resolver_dump, "")                                            \
21935 _(one_map_server_dump, "")                                              \
21936 _(one_adjacencies_get, "vni <vni>")                                     \
21937 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
21938 _(show_one_rloc_probe_state, "")                                        \
21939 _(show_one_map_register_state, "")                                      \
21940 _(show_one_status, "")                                                  \
21941 _(one_stats_dump, "")                                                   \
21942 _(one_stats_flush, "")                                                  \
21943 _(one_get_map_request_itr_rlocs, "")                                    \
21944 _(one_map_register_set_ttl, "<ttl>")                                    \
21945 _(one_set_transport_protocol, "udp|api")                                \
21946 _(one_get_transport_protocol, "")                                       \
21947 _(show_one_nsh_mapping, "")                                             \
21948 _(show_one_pitr, "")                                                    \
21949 _(show_one_use_petr, "")                                                \
21950 _(show_one_map_request_mode, "")                                        \
21951 _(show_one_map_register_ttl, "")                                        \
21952 _(show_one_map_register_fallback_threshold, "")                         \
21953 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
21954                             " sw_if_index <sw_if_index> p <priority> "  \
21955                             "w <weight>] [del]")                        \
21956 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
21957                         "iface <intf> | sw_if_index <sw_if_index> "     \
21958                         "p <priority> w <weight> [del]")                \
21959 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
21960                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21961                          "locator-set <locator_name> [del]"             \
21962                          "[key-id sha1|sha256 secret-key <secret-key>]") \
21963 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
21964 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
21965 _(lisp_enable_disable, "enable|disable")                                \
21966 _(lisp_map_register_enable_disable, "enable|disable")                   \
21967 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
21968 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
21969                                "[seid <seid>] "                         \
21970                                "rloc <locator> p <prio> "               \
21971                                "w <weight> [rloc <loc> ... ] "          \
21972                                "action <action> [del-all]")             \
21973 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
21974                           "<local-eid>")                                \
21975 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
21976 _(lisp_use_petr, "<ip-address> | disable")                              \
21977 _(lisp_map_request_mode, "src-dst|dst-only")                            \
21978 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
21979 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
21980 _(lisp_locator_set_dump, "[local | remote]")                            \
21981 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
21982 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
21983                        "[local] | [remote]")                            \
21984 _(lisp_eid_table_vni_dump, "")                                          \
21985 _(lisp_eid_table_map_dump, "l2|l3")                                     \
21986 _(lisp_map_resolver_dump, "")                                           \
21987 _(lisp_map_server_dump, "")                                             \
21988 _(lisp_adjacencies_get, "vni <vni>")                                    \
21989 _(gpe_fwd_entry_vnis_get, "")                                           \
21990 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
21991 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
21992                                 "[table <table-id>]")                   \
21993 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
21994 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
21995 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
21996 _(gpe_get_encap_mode, "")                                               \
21997 _(lisp_gpe_add_del_iface, "up|down")                                    \
21998 _(lisp_gpe_enable_disable, "enable|disable")                            \
21999 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22000   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22001 _(show_lisp_rloc_probe_state, "")                                       \
22002 _(show_lisp_map_register_state, "")                                     \
22003 _(show_lisp_status, "")                                                 \
22004 _(lisp_get_map_request_itr_rlocs, "")                                   \
22005 _(show_lisp_pitr, "")                                                   \
22006 _(show_lisp_use_petr, "")                                               \
22007 _(show_lisp_map_request_mode, "")                                       \
22008 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22009 _(af_packet_delete, "name <host interface name>")                       \
22010 _(policer_add_del, "name <policer name> <params> [del]")                \
22011 _(policer_dump, "[name <policer name>]")                                \
22012 _(policer_classify_set_interface,                                       \
22013   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22014   "  [l2-table <nn>] [del]")                                            \
22015 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22016 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22017     "[master|slave]")                                                   \
22018 _(netmap_delete, "name <interface name>")                               \
22019 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22020 _(mpls_fib_dump, "")                                                    \
22021 _(classify_table_ids, "")                                               \
22022 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22023 _(classify_table_info, "table_id <nn>")                                 \
22024 _(classify_session_dump, "table_id <nn>")                               \
22025 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22026     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22027     "[template_interval <nn>] [udp_checksum]")                          \
22028 _(ipfix_exporter_dump, "")                                              \
22029 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22030 _(ipfix_classify_stream_dump, "")                                       \
22031 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22032 _(ipfix_classify_table_dump, "")                                        \
22033 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22034 _(sw_interface_span_dump, "[l2]")                                           \
22035 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22036 _(pg_create_interface, "if_id <nn>")                                    \
22037 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22038 _(pg_enable_disable, "[stream <id>] disable")                           \
22039 _(ip_source_and_port_range_check_add_del,                               \
22040   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22041 _(ip_source_and_port_range_check_interface_add_del,                     \
22042   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
22043   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
22044 _(ipsec_gre_add_del_tunnel,                                             \
22045   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
22046 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
22047 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
22048 _(l2_interface_pbb_tag_rewrite,                                         \
22049   "<intfc> | sw_if_index <nn> \n"                                       \
22050   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
22051   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
22052 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
22053 _(flow_classify_set_interface,                                          \
22054   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
22055 _(flow_classify_dump, "type [ip4|ip6]")                                 \
22056 _(ip_fib_dump, "")                                                      \
22057 _(ip_mfib_dump, "")                                                     \
22058 _(ip6_fib_dump, "")                                                     \
22059 _(ip6_mfib_dump, "")                                                    \
22060 _(feature_enable_disable, "arc_name <arc_name> "                        \
22061   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
22062 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
22063 "[disable]")                                                            \
22064 _(l2_xconnect_dump, "")                                                 \
22065 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
22066 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
22067 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
22068 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
22069 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
22070 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
22071 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
22072   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
22073 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
22074 _(memfd_segment_create,"size <nnn>")                                    \
22075 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
22076 _(dns_enable_disable, "[enable][disable]")                              \
22077 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22078 _(dns_resolve_name, "<hostname>")                                       \
22079 _(dns_resolve_ip, "<ip4|ip6>")                                          \
22080 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22081 _(dns_resolve_name, "<hostname>")                                       \
22082 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
22083   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
22084
22085 /* List of command functions, CLI names map directly to functions */
22086 #define foreach_cli_function                                    \
22087 _(comment, "usage: comment <ignore-rest-of-line>")              \
22088 _(dump_interface_table, "usage: dump_interface_table")          \
22089 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
22090 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
22091 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
22092 _(dump_stats_table, "usage: dump_stats_table")                  \
22093 _(dump_macro_table, "usage: dump_macro_table ")                 \
22094 _(dump_node_table, "usage: dump_node_table")                    \
22095 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
22096 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
22097 _(echo, "usage: echo <message>")                                \
22098 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
22099 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
22100 _(help, "usage: help")                                          \
22101 _(q, "usage: quit")                                             \
22102 _(quit, "usage: quit")                                          \
22103 _(search_node_table, "usage: search_node_table <name>...")      \
22104 _(set, "usage: set <variable-name> <value>")                    \
22105 _(script, "usage: script <file-name>")                          \
22106 _(unset, "usage: unset <variable-name>")
22107 #define _(N,n)                                  \
22108     static void vl_api_##n##_t_handler_uni      \
22109     (vl_api_##n##_t * mp)                       \
22110     {                                           \
22111         vat_main_t * vam = &vat_main;           \
22112         if (vam->json_output) {                 \
22113             vl_api_##n##_t_handler_json(mp);    \
22114         } else {                                \
22115             vl_api_##n##_t_handler(mp);         \
22116         }                                       \
22117     }
22118 foreach_vpe_api_reply_msg;
22119 #if VPP_API_TEST_BUILTIN == 0
22120 foreach_standalone_reply_msg;
22121 #endif
22122 #undef _
22123
22124 void
22125 vat_api_hookup (vat_main_t * vam)
22126 {
22127 #define _(N,n)                                                  \
22128     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22129                            vl_api_##n##_t_handler_uni,          \
22130                            vl_noop_handler,                     \
22131                            vl_api_##n##_t_endian,               \
22132                            vl_api_##n##_t_print,                \
22133                            sizeof(vl_api_##n##_t), 1);
22134   foreach_vpe_api_reply_msg;
22135 #if VPP_API_TEST_BUILTIN == 0
22136   foreach_standalone_reply_msg;
22137 #endif
22138 #undef _
22139
22140 #if (VPP_API_TEST_BUILTIN==0)
22141   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22142
22143   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22144
22145   vam->function_by_name = hash_create_string (0, sizeof (uword));
22146
22147   vam->help_by_name = hash_create_string (0, sizeof (uword));
22148 #endif
22149
22150   /* API messages we can send */
22151 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22152   foreach_vpe_api_msg;
22153 #undef _
22154
22155   /* Help strings */
22156 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22157   foreach_vpe_api_msg;
22158 #undef _
22159
22160   /* CLI functions */
22161 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22162   foreach_cli_function;
22163 #undef _
22164
22165   /* Help strings */
22166 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22167   foreach_cli_function;
22168 #undef _
22169 }
22170
22171 #if VPP_API_TEST_BUILTIN
22172 static clib_error_t *
22173 vat_api_hookup_shim (vlib_main_t * vm)
22174 {
22175   vat_api_hookup (&vat_main);
22176   return 0;
22177 }
22178
22179 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22180 #endif
22181
22182 /*
22183  * fd.io coding-style-patch-verification: ON
22184  *
22185  * Local Variables:
22186  * eval: (c-set-style "gnu")
22187  * End:
22188  */