devices: Add binary API for set interface <interface> rx-mode
[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_rx_mode_reply)                       \
5048 _(sw_interface_set_table_reply)                         \
5049 _(sw_interface_set_mpls_enable_reply)                   \
5050 _(sw_interface_set_vpath_reply)                         \
5051 _(sw_interface_set_vxlan_bypass_reply)                  \
5052 _(sw_interface_set_geneve_bypass_reply)                 \
5053 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5054 _(sw_interface_set_l2_bridge_reply)                     \
5055 _(bridge_domain_add_del_reply)                          \
5056 _(sw_interface_set_l2_xconnect_reply)                   \
5057 _(l2fib_add_del_reply)                                  \
5058 _(l2fib_flush_int_reply)                                \
5059 _(l2fib_flush_bd_reply)                                 \
5060 _(ip_add_del_route_reply)                               \
5061 _(ip_table_add_del_reply)                               \
5062 _(ip_mroute_add_del_reply)                              \
5063 _(mpls_route_add_del_reply)                             \
5064 _(mpls_table_add_del_reply)                             \
5065 _(mpls_ip_bind_unbind_reply)                            \
5066 _(proxy_arp_add_del_reply)                              \
5067 _(proxy_arp_intfc_enable_disable_reply)                 \
5068 _(sw_interface_set_unnumbered_reply)                    \
5069 _(ip_neighbor_add_del_reply)                            \
5070 _(reset_vrf_reply)                                      \
5071 _(oam_add_del_reply)                                    \
5072 _(reset_fib_reply)                                      \
5073 _(dhcp_proxy_config_reply)                              \
5074 _(dhcp_proxy_set_vss_reply)                             \
5075 _(dhcp_client_config_reply)                             \
5076 _(set_ip_flow_hash_reply)                               \
5077 _(sw_interface_ip6_enable_disable_reply)                \
5078 _(sw_interface_ip6_set_link_local_address_reply)        \
5079 _(ip6nd_proxy_add_del_reply)                            \
5080 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5081 _(sw_interface_ip6nd_ra_config_reply)                   \
5082 _(set_arp_neighbor_limit_reply)                         \
5083 _(l2_patch_add_del_reply)                               \
5084 _(sr_policy_add_reply)                                  \
5085 _(sr_policy_mod_reply)                                  \
5086 _(sr_policy_del_reply)                                  \
5087 _(sr_localsid_add_del_reply)                            \
5088 _(sr_steering_add_del_reply)                            \
5089 _(classify_add_del_session_reply)                       \
5090 _(classify_set_interface_ip_table_reply)                \
5091 _(classify_set_interface_l2_tables_reply)               \
5092 _(l2tpv3_set_tunnel_cookies_reply)                      \
5093 _(l2tpv3_interface_enable_disable_reply)                \
5094 _(l2tpv3_set_lookup_key_reply)                          \
5095 _(l2_fib_clear_table_reply)                             \
5096 _(l2_interface_efp_filter_reply)                        \
5097 _(l2_interface_vlan_tag_rewrite_reply)                  \
5098 _(modify_vhost_user_if_reply)                           \
5099 _(delete_vhost_user_if_reply)                           \
5100 _(want_ip4_arp_events_reply)                            \
5101 _(want_ip6_nd_events_reply)                             \
5102 _(want_l2_macs_events_reply)                            \
5103 _(input_acl_set_interface_reply)                        \
5104 _(ipsec_spd_add_del_reply)                              \
5105 _(ipsec_interface_add_del_spd_reply)                    \
5106 _(ipsec_spd_add_del_entry_reply)                        \
5107 _(ipsec_sad_add_del_entry_reply)                        \
5108 _(ipsec_sa_set_key_reply)                               \
5109 _(ipsec_tunnel_if_add_del_reply)                        \
5110 _(ipsec_tunnel_if_set_key_reply)                        \
5111 _(ipsec_tunnel_if_set_sa_reply)                         \
5112 _(ikev2_profile_add_del_reply)                          \
5113 _(ikev2_profile_set_auth_reply)                         \
5114 _(ikev2_profile_set_id_reply)                           \
5115 _(ikev2_profile_set_ts_reply)                           \
5116 _(ikev2_set_local_key_reply)                            \
5117 _(ikev2_set_responder_reply)                            \
5118 _(ikev2_set_ike_transforms_reply)                       \
5119 _(ikev2_set_esp_transforms_reply)                       \
5120 _(ikev2_set_sa_lifetime_reply)                          \
5121 _(ikev2_initiate_sa_init_reply)                         \
5122 _(ikev2_initiate_del_ike_sa_reply)                      \
5123 _(ikev2_initiate_del_child_sa_reply)                    \
5124 _(ikev2_initiate_rekey_child_sa_reply)                  \
5125 _(delete_loopback_reply)                                \
5126 _(bd_ip_mac_add_del_reply)                              \
5127 _(map_del_domain_reply)                                 \
5128 _(map_add_del_rule_reply)                               \
5129 _(want_interface_events_reply)                          \
5130 _(want_stats_reply)                                     \
5131 _(cop_interface_enable_disable_reply)                   \
5132 _(cop_whitelist_enable_disable_reply)                   \
5133 _(sw_interface_clear_stats_reply)                       \
5134 _(ioam_enable_reply)                                    \
5135 _(ioam_disable_reply)                                   \
5136 _(one_add_del_locator_reply)                            \
5137 _(one_add_del_local_eid_reply)                          \
5138 _(one_add_del_remote_mapping_reply)                     \
5139 _(one_add_del_adjacency_reply)                          \
5140 _(one_add_del_map_resolver_reply)                       \
5141 _(one_add_del_map_server_reply)                         \
5142 _(one_enable_disable_reply)                             \
5143 _(one_rloc_probe_enable_disable_reply)                  \
5144 _(one_map_register_enable_disable_reply)                \
5145 _(one_map_register_set_ttl_reply)                       \
5146 _(one_set_transport_protocol_reply)                     \
5147 _(one_map_register_fallback_threshold_reply)            \
5148 _(one_pitr_set_locator_set_reply)                       \
5149 _(one_map_request_mode_reply)                           \
5150 _(one_add_del_map_request_itr_rlocs_reply)              \
5151 _(one_eid_table_add_del_map_reply)                      \
5152 _(one_use_petr_reply)                                   \
5153 _(one_stats_enable_disable_reply)                       \
5154 _(one_add_del_l2_arp_entry_reply)                       \
5155 _(one_add_del_ndp_entry_reply)                          \
5156 _(one_stats_flush_reply)                                \
5157 _(gpe_enable_disable_reply)                             \
5158 _(gpe_set_encap_mode_reply)                             \
5159 _(gpe_add_del_iface_reply)                              \
5160 _(gpe_add_del_native_fwd_rpath_reply)                   \
5161 _(af_packet_delete_reply)                               \
5162 _(policer_classify_set_interface_reply)                 \
5163 _(netmap_create_reply)                                  \
5164 _(netmap_delete_reply)                                  \
5165 _(set_ipfix_exporter_reply)                             \
5166 _(set_ipfix_classify_stream_reply)                      \
5167 _(ipfix_classify_table_add_del_reply)                   \
5168 _(flow_classify_set_interface_reply)                    \
5169 _(sw_interface_span_enable_disable_reply)               \
5170 _(pg_capture_reply)                                     \
5171 _(pg_enable_disable_reply)                              \
5172 _(ip_source_and_port_range_check_add_del_reply)         \
5173 _(ip_source_and_port_range_check_interface_add_del_reply)\
5174 _(delete_subif_reply)                                   \
5175 _(l2_interface_pbb_tag_rewrite_reply)                   \
5176 _(punt_reply)                                           \
5177 _(feature_enable_disable_reply)                         \
5178 _(sw_interface_tag_add_del_reply)                       \
5179 _(sw_interface_set_mtu_reply)                           \
5180 _(p2p_ethernet_add_reply)                               \
5181 _(p2p_ethernet_del_reply)                               \
5182 _(lldp_config_reply)                                    \
5183 _(sw_interface_set_lldp_reply)                          \
5184 _(tcp_configure_src_addresses_reply)                    \
5185 _(app_namespace_add_del_reply)                          \
5186 _(dns_enable_disable_reply)                             \
5187 _(dns_name_server_add_del_reply)                        \
5188 _(session_rule_add_del_reply)
5189
5190 #define _(n)                                    \
5191     static void vl_api_##n##_t_handler          \
5192     (vl_api_##n##_t * mp)                       \
5193     {                                           \
5194         vat_main_t * vam = &vat_main;           \
5195         i32 retval = ntohl(mp->retval);         \
5196         if (vam->async_mode) {                  \
5197             vam->async_errors += (retval < 0);  \
5198         } else {                                \
5199             vam->retval = retval;               \
5200             vam->result_ready = 1;              \
5201         }                                       \
5202     }
5203 foreach_standard_reply_retval_handler;
5204 #undef _
5205
5206 #define _(n)                                    \
5207     static void vl_api_##n##_t_handler_json     \
5208     (vl_api_##n##_t * mp)                       \
5209     {                                           \
5210         vat_main_t * vam = &vat_main;           \
5211         vat_json_node_t node;                   \
5212         vat_json_init_object(&node);            \
5213         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5214         vat_json_print(vam->ofp, &node);        \
5215         vam->retval = ntohl(mp->retval);        \
5216         vam->result_ready = 1;                  \
5217     }
5218 foreach_standard_reply_retval_handler;
5219 #undef _
5220
5221 /*
5222  * Table of message reply handlers, must include boilerplate handlers
5223  * we just generated
5224  */
5225
5226 #define foreach_vpe_api_reply_msg                                       \
5227 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5228 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5229 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5230 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5231 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5232 _(CLI_REPLY, cli_reply)                                                 \
5233 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5234 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5235   sw_interface_add_del_address_reply)                                   \
5236 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5237 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5238 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5239 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5240 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5241 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5242 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5243 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5244   sw_interface_set_l2_xconnect_reply)                                   \
5245 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5246   sw_interface_set_l2_bridge_reply)                                     \
5247 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5248 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5249 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5250 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5251 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5252 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5253 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5254 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5255 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5256 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5257 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5258 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5259 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5260 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5261 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5262 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5263 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5264 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5265 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5266 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5267   proxy_arp_intfc_enable_disable_reply)                                 \
5268 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5269 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5270   sw_interface_set_unnumbered_reply)                                    \
5271 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5272 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
5273 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5274 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5275 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5276 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5277 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5278 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5279 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5280 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5281 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5282 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5283   sw_interface_ip6_enable_disable_reply)                                \
5284 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5285   sw_interface_ip6_set_link_local_address_reply)                        \
5286 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5287 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5288 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5289   sw_interface_ip6nd_ra_prefix_reply)                                   \
5290 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5291   sw_interface_ip6nd_ra_config_reply)                                   \
5292 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5293 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5294 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5295 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5296 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5297 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5298 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5299 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5300 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5301 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5302 classify_set_interface_ip_table_reply)                                  \
5303 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5304   classify_set_interface_l2_tables_reply)                               \
5305 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5306 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5307 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5308 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5309 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5310   l2tpv3_interface_enable_disable_reply)                                \
5311 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5312 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5313 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5314 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5315 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5316 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5317 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5318 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5319 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5320 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5321 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5322 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5323 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5324 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5325 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5326 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5327 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5328 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
5329 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5330 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5331 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5332 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5333 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5334 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5335 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5336 _(L2_MACS_EVENT, l2_macs_event)                                         \
5337 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5338 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5339 _(IP_DETAILS, ip_details)                                               \
5340 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5341 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5342 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5343 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5344 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5345 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5346 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5347 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5348 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5349 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5350 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5351 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5352 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5353 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5354 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5355 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5356 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5357 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5358 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5359 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5360 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5361 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5362 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5363 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5364 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5365 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5366 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5367 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5368 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5369 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5370 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5371 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5372 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5373 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5374 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5375 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5376 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5377 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5378 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5379 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5380 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5381 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5382 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5383 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5384 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5385 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5386 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5387 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5388   one_map_register_enable_disable_reply)                                \
5389 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5390 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5391 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5392 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5393   one_map_register_fallback_threshold_reply)                            \
5394 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5395   one_rloc_probe_enable_disable_reply)                                  \
5396 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5397 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5398 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5399 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5400 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5401 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5402 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5403 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5404 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5405 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5406 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5407 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5408 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5409 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5410 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5411 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5412   show_one_stats_enable_disable_reply)                                  \
5413 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5414 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5415 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5416 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5417 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5418 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5419 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5420 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5421 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5422 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5423 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5424 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5425 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5426 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5427 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5428   gpe_add_del_native_fwd_rpath_reply)                                   \
5429 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5430   gpe_fwd_entry_path_details)                                           \
5431 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5432 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5433   one_add_del_map_request_itr_rlocs_reply)                              \
5434 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5435   one_get_map_request_itr_rlocs_reply)                                  \
5436 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5437 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5438 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5439 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5440 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5441 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5442   show_one_map_register_state_reply)                                    \
5443 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5444 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5445   show_one_map_register_fallback_threshold_reply)                       \
5446 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5447 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5448 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5449 _(POLICER_DETAILS, policer_details)                                     \
5450 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5451 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5452 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5453 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5454 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5455 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5456 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5457 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5458 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5459 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5460 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5461 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5462 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5463 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5464 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5465 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5466 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5467 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5468 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5469 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5470 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5471 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5472 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5473 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5474 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5475  ip_source_and_port_range_check_add_del_reply)                          \
5476 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5477  ip_source_and_port_range_check_interface_add_del_reply)                \
5478 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5479 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5480 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5481 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5482 _(PUNT_REPLY, punt_reply)                                               \
5483 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5484 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5485 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5486 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5487 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5488 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5489 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5490 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5491 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5492 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5493 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5494 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5495 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5496 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5497 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5498 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5499 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)                       \
5500 _(DNS_RESOLVE_IP_REPLY, dns_resolve_ip_reply)                           \
5501 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)
5502
5503 #define foreach_standalone_reply_msg                                    \
5504 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5505 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5506 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5507 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5508 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5509 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5510 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
5511 _(MEMFD_SEGMENT_CREATE_REPLY, memfd_segment_create_reply)               \
5512
5513 typedef struct
5514 {
5515   u8 *name;
5516   u32 value;
5517 } name_sort_t;
5518
5519
5520 #define STR_VTR_OP_CASE(op)     \
5521     case L2_VTR_ ## op:         \
5522         return "" # op;
5523
5524 static const char *
5525 str_vtr_op (u32 vtr_op)
5526 {
5527   switch (vtr_op)
5528     {
5529       STR_VTR_OP_CASE (DISABLED);
5530       STR_VTR_OP_CASE (PUSH_1);
5531       STR_VTR_OP_CASE (PUSH_2);
5532       STR_VTR_OP_CASE (POP_1);
5533       STR_VTR_OP_CASE (POP_2);
5534       STR_VTR_OP_CASE (TRANSLATE_1_1);
5535       STR_VTR_OP_CASE (TRANSLATE_1_2);
5536       STR_VTR_OP_CASE (TRANSLATE_2_1);
5537       STR_VTR_OP_CASE (TRANSLATE_2_2);
5538     }
5539
5540   return "UNKNOWN";
5541 }
5542
5543 static int
5544 dump_sub_interface_table (vat_main_t * vam)
5545 {
5546   const sw_interface_subif_t *sub = NULL;
5547
5548   if (vam->json_output)
5549     {
5550       clib_warning
5551         ("JSON output supported only for VPE API calls and dump_stats_table");
5552       return -99;
5553     }
5554
5555   print (vam->ofp,
5556          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5557          "Interface", "sw_if_index",
5558          "sub id", "dot1ad", "tags", "outer id",
5559          "inner id", "exact", "default", "outer any", "inner any");
5560
5561   vec_foreach (sub, vam->sw_if_subif_table)
5562   {
5563     print (vam->ofp,
5564            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5565            sub->interface_name,
5566            sub->sw_if_index,
5567            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5568            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5569            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5570            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5571     if (sub->vtr_op != L2_VTR_DISABLED)
5572       {
5573         print (vam->ofp,
5574                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5575                "tag1: %d tag2: %d ]",
5576                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5577                sub->vtr_tag1, sub->vtr_tag2);
5578       }
5579   }
5580
5581   return 0;
5582 }
5583
5584 static int
5585 name_sort_cmp (void *a1, void *a2)
5586 {
5587   name_sort_t *n1 = a1;
5588   name_sort_t *n2 = a2;
5589
5590   return strcmp ((char *) n1->name, (char *) n2->name);
5591 }
5592
5593 static int
5594 dump_interface_table (vat_main_t * vam)
5595 {
5596   hash_pair_t *p;
5597   name_sort_t *nses = 0, *ns;
5598
5599   if (vam->json_output)
5600     {
5601       clib_warning
5602         ("JSON output supported only for VPE API calls and dump_stats_table");
5603       return -99;
5604     }
5605
5606   /* *INDENT-OFF* */
5607   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5608   ({
5609     vec_add2 (nses, ns, 1);
5610     ns->name = (u8 *)(p->key);
5611     ns->value = (u32) p->value[0];
5612   }));
5613   /* *INDENT-ON* */
5614
5615   vec_sort_with_function (nses, name_sort_cmp);
5616
5617   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5618   vec_foreach (ns, nses)
5619   {
5620     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5621   }
5622   vec_free (nses);
5623   return 0;
5624 }
5625
5626 static int
5627 dump_ip_table (vat_main_t * vam, int is_ipv6)
5628 {
5629   const ip_details_t *det = NULL;
5630   const ip_address_details_t *address = NULL;
5631   u32 i = ~0;
5632
5633   print (vam->ofp, "%-12s", "sw_if_index");
5634
5635   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5636   {
5637     i++;
5638     if (!det->present)
5639       {
5640         continue;
5641       }
5642     print (vam->ofp, "%-12d", i);
5643     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5644     if (!det->addr)
5645       {
5646         continue;
5647       }
5648     vec_foreach (address, det->addr)
5649     {
5650       print (vam->ofp,
5651              "            %-30U%-13d",
5652              is_ipv6 ? format_ip6_address : format_ip4_address,
5653              address->ip, address->prefix_length);
5654     }
5655   }
5656
5657   return 0;
5658 }
5659
5660 static int
5661 dump_ipv4_table (vat_main_t * vam)
5662 {
5663   if (vam->json_output)
5664     {
5665       clib_warning
5666         ("JSON output supported only for VPE API calls and dump_stats_table");
5667       return -99;
5668     }
5669
5670   return dump_ip_table (vam, 0);
5671 }
5672
5673 static int
5674 dump_ipv6_table (vat_main_t * vam)
5675 {
5676   if (vam->json_output)
5677     {
5678       clib_warning
5679         ("JSON output supported only for VPE API calls and dump_stats_table");
5680       return -99;
5681     }
5682
5683   return dump_ip_table (vam, 1);
5684 }
5685
5686 static char *
5687 counter_type_to_str (u8 counter_type, u8 is_combined)
5688 {
5689   if (!is_combined)
5690     {
5691       switch (counter_type)
5692         {
5693         case VNET_INTERFACE_COUNTER_DROP:
5694           return "drop";
5695         case VNET_INTERFACE_COUNTER_PUNT:
5696           return "punt";
5697         case VNET_INTERFACE_COUNTER_IP4:
5698           return "ip4";
5699         case VNET_INTERFACE_COUNTER_IP6:
5700           return "ip6";
5701         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5702           return "rx-no-buf";
5703         case VNET_INTERFACE_COUNTER_RX_MISS:
5704           return "rx-miss";
5705         case VNET_INTERFACE_COUNTER_RX_ERROR:
5706           return "rx-error";
5707         case VNET_INTERFACE_COUNTER_TX_ERROR:
5708           return "tx-error";
5709         default:
5710           return "INVALID-COUNTER-TYPE";
5711         }
5712     }
5713   else
5714     {
5715       switch (counter_type)
5716         {
5717         case VNET_INTERFACE_COUNTER_RX:
5718           return "rx";
5719         case VNET_INTERFACE_COUNTER_TX:
5720           return "tx";
5721         default:
5722           return "INVALID-COUNTER-TYPE";
5723         }
5724     }
5725 }
5726
5727 static int
5728 dump_stats_table (vat_main_t * vam)
5729 {
5730   vat_json_node_t node;
5731   vat_json_node_t *msg_array;
5732   vat_json_node_t *msg;
5733   vat_json_node_t *counter_array;
5734   vat_json_node_t *counter;
5735   interface_counter_t c;
5736   u64 packets;
5737   ip4_fib_counter_t *c4;
5738   ip6_fib_counter_t *c6;
5739   ip4_nbr_counter_t *n4;
5740   ip6_nbr_counter_t *n6;
5741   int i, j;
5742
5743   if (!vam->json_output)
5744     {
5745       clib_warning ("dump_stats_table supported only in JSON format");
5746       return -99;
5747     }
5748
5749   vat_json_init_object (&node);
5750
5751   /* interface counters */
5752   msg_array = vat_json_object_add (&node, "interface_counters");
5753   vat_json_init_array (msg_array);
5754   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5755     {
5756       msg = vat_json_array_add (msg_array);
5757       vat_json_init_object (msg);
5758       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5759                                        (u8 *) counter_type_to_str (i, 0));
5760       vat_json_object_add_int (msg, "is_combined", 0);
5761       counter_array = vat_json_object_add (msg, "data");
5762       vat_json_init_array (counter_array);
5763       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5764         {
5765           packets = vam->simple_interface_counters[i][j];
5766           vat_json_array_add_uint (counter_array, packets);
5767         }
5768     }
5769   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5770     {
5771       msg = vat_json_array_add (msg_array);
5772       vat_json_init_object (msg);
5773       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5774                                        (u8 *) counter_type_to_str (i, 1));
5775       vat_json_object_add_int (msg, "is_combined", 1);
5776       counter_array = vat_json_object_add (msg, "data");
5777       vat_json_init_array (counter_array);
5778       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5779         {
5780           c = vam->combined_interface_counters[i][j];
5781           counter = vat_json_array_add (counter_array);
5782           vat_json_init_object (counter);
5783           vat_json_object_add_uint (counter, "packets", c.packets);
5784           vat_json_object_add_uint (counter, "bytes", c.bytes);
5785         }
5786     }
5787
5788   /* ip4 fib counters */
5789   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
5790   vat_json_init_array (msg_array);
5791   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
5792     {
5793       msg = vat_json_array_add (msg_array);
5794       vat_json_init_object (msg);
5795       vat_json_object_add_uint (msg, "vrf_id",
5796                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
5797       counter_array = vat_json_object_add (msg, "c");
5798       vat_json_init_array (counter_array);
5799       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
5800         {
5801           counter = vat_json_array_add (counter_array);
5802           vat_json_init_object (counter);
5803           c4 = &vam->ip4_fib_counters[i][j];
5804           vat_json_object_add_ip4 (counter, "address", c4->address);
5805           vat_json_object_add_uint (counter, "address_length",
5806                                     c4->address_length);
5807           vat_json_object_add_uint (counter, "packets", c4->packets);
5808           vat_json_object_add_uint (counter, "bytes", c4->bytes);
5809         }
5810     }
5811
5812   /* ip6 fib counters */
5813   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
5814   vat_json_init_array (msg_array);
5815   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
5816     {
5817       msg = vat_json_array_add (msg_array);
5818       vat_json_init_object (msg);
5819       vat_json_object_add_uint (msg, "vrf_id",
5820                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
5821       counter_array = vat_json_object_add (msg, "c");
5822       vat_json_init_array (counter_array);
5823       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
5824         {
5825           counter = vat_json_array_add (counter_array);
5826           vat_json_init_object (counter);
5827           c6 = &vam->ip6_fib_counters[i][j];
5828           vat_json_object_add_ip6 (counter, "address", c6->address);
5829           vat_json_object_add_uint (counter, "address_length",
5830                                     c6->address_length);
5831           vat_json_object_add_uint (counter, "packets", c6->packets);
5832           vat_json_object_add_uint (counter, "bytes", c6->bytes);
5833         }
5834     }
5835
5836   /* ip4 nbr counters */
5837   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
5838   vat_json_init_array (msg_array);
5839   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
5840     {
5841       msg = vat_json_array_add (msg_array);
5842       vat_json_init_object (msg);
5843       vat_json_object_add_uint (msg, "sw_if_index", i);
5844       counter_array = vat_json_object_add (msg, "c");
5845       vat_json_init_array (counter_array);
5846       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
5847         {
5848           counter = vat_json_array_add (counter_array);
5849           vat_json_init_object (counter);
5850           n4 = &vam->ip4_nbr_counters[i][j];
5851           vat_json_object_add_ip4 (counter, "address", n4->address);
5852           vat_json_object_add_uint (counter, "link-type", n4->linkt);
5853           vat_json_object_add_uint (counter, "packets", n4->packets);
5854           vat_json_object_add_uint (counter, "bytes", n4->bytes);
5855         }
5856     }
5857
5858   /* ip6 nbr counters */
5859   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
5860   vat_json_init_array (msg_array);
5861   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
5862     {
5863       msg = vat_json_array_add (msg_array);
5864       vat_json_init_object (msg);
5865       vat_json_object_add_uint (msg, "sw_if_index", i);
5866       counter_array = vat_json_object_add (msg, "c");
5867       vat_json_init_array (counter_array);
5868       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
5869         {
5870           counter = vat_json_array_add (counter_array);
5871           vat_json_init_object (counter);
5872           n6 = &vam->ip6_nbr_counters[i][j];
5873           vat_json_object_add_ip6 (counter, "address", n6->address);
5874           vat_json_object_add_uint (counter, "packets", n6->packets);
5875           vat_json_object_add_uint (counter, "bytes", n6->bytes);
5876         }
5877     }
5878
5879   vat_json_print (vam->ofp, &node);
5880   vat_json_free (&node);
5881
5882   return 0;
5883 }
5884
5885 /*
5886  * Pass CLI buffers directly in the CLI_INBAND API message,
5887  * instead of an additional shared memory area.
5888  */
5889 static int
5890 exec_inband (vat_main_t * vam)
5891 {
5892   vl_api_cli_inband_t *mp;
5893   unformat_input_t *i = vam->input;
5894   int ret;
5895
5896   if (vec_len (i->buffer) == 0)
5897     return -1;
5898
5899   if (vam->exec_mode == 0 && unformat (i, "mode"))
5900     {
5901       vam->exec_mode = 1;
5902       return 0;
5903     }
5904   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5905     {
5906       vam->exec_mode = 0;
5907       return 0;
5908     }
5909
5910   /*
5911    * In order for the CLI command to work, it
5912    * must be a vector ending in \n, not a C-string ending
5913    * in \n\0.
5914    */
5915   u32 len = vec_len (vam->input->buffer);
5916   M2 (CLI_INBAND, mp, len);
5917   clib_memcpy (mp->cmd, vam->input->buffer, len);
5918   mp->length = htonl (len);
5919
5920   S (mp);
5921   W (ret);
5922   /* json responses may or may not include a useful reply... */
5923   if (vec_len (vam->cmd_reply))
5924     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5925   return ret;
5926 }
5927
5928 int
5929 exec (vat_main_t * vam)
5930 {
5931   return exec_inband (vam);
5932 }
5933
5934 static int
5935 api_create_loopback (vat_main_t * vam)
5936 {
5937   unformat_input_t *i = vam->input;
5938   vl_api_create_loopback_t *mp;
5939   vl_api_create_loopback_instance_t *mp_lbi;
5940   u8 mac_address[6];
5941   u8 mac_set = 0;
5942   u8 is_specified = 0;
5943   u32 user_instance = 0;
5944   int ret;
5945
5946   memset (mac_address, 0, sizeof (mac_address));
5947
5948   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5949     {
5950       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5951         mac_set = 1;
5952       if (unformat (i, "instance %d", &user_instance))
5953         is_specified = 1;
5954       else
5955         break;
5956     }
5957
5958   if (is_specified)
5959     {
5960       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5961       mp_lbi->is_specified = is_specified;
5962       if (is_specified)
5963         mp_lbi->user_instance = htonl (user_instance);
5964       if (mac_set)
5965         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5966       S (mp_lbi);
5967     }
5968   else
5969     {
5970       /* Construct the API message */
5971       M (CREATE_LOOPBACK, mp);
5972       if (mac_set)
5973         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5974       S (mp);
5975     }
5976
5977   W (ret);
5978   return ret;
5979 }
5980
5981 static int
5982 api_delete_loopback (vat_main_t * vam)
5983 {
5984   unformat_input_t *i = vam->input;
5985   vl_api_delete_loopback_t *mp;
5986   u32 sw_if_index = ~0;
5987   int ret;
5988
5989   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5990     {
5991       if (unformat (i, "sw_if_index %d", &sw_if_index))
5992         ;
5993       else
5994         break;
5995     }
5996
5997   if (sw_if_index == ~0)
5998     {
5999       errmsg ("missing sw_if_index");
6000       return -99;
6001     }
6002
6003   /* Construct the API message */
6004   M (DELETE_LOOPBACK, mp);
6005   mp->sw_if_index = ntohl (sw_if_index);
6006
6007   S (mp);
6008   W (ret);
6009   return ret;
6010 }
6011
6012 static int
6013 api_want_stats (vat_main_t * vam)
6014 {
6015   unformat_input_t *i = vam->input;
6016   vl_api_want_stats_t *mp;
6017   int enable = -1;
6018   int ret;
6019
6020   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6021     {
6022       if (unformat (i, "enable"))
6023         enable = 1;
6024       else if (unformat (i, "disable"))
6025         enable = 0;
6026       else
6027         break;
6028     }
6029
6030   if (enable == -1)
6031     {
6032       errmsg ("missing enable|disable");
6033       return -99;
6034     }
6035
6036   M (WANT_STATS, mp);
6037   mp->enable_disable = enable;
6038
6039   S (mp);
6040   W (ret);
6041   return ret;
6042 }
6043
6044 static int
6045 api_want_interface_events (vat_main_t * vam)
6046 {
6047   unformat_input_t *i = vam->input;
6048   vl_api_want_interface_events_t *mp;
6049   int enable = -1;
6050   int ret;
6051
6052   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6053     {
6054       if (unformat (i, "enable"))
6055         enable = 1;
6056       else if (unformat (i, "disable"))
6057         enable = 0;
6058       else
6059         break;
6060     }
6061
6062   if (enable == -1)
6063     {
6064       errmsg ("missing enable|disable");
6065       return -99;
6066     }
6067
6068   M (WANT_INTERFACE_EVENTS, mp);
6069   mp->enable_disable = enable;
6070
6071   vam->interface_event_display = enable;
6072
6073   S (mp);
6074   W (ret);
6075   return ret;
6076 }
6077
6078
6079 /* Note: non-static, called once to set up the initial intfc table */
6080 int
6081 api_sw_interface_dump (vat_main_t * vam)
6082 {
6083   vl_api_sw_interface_dump_t *mp;
6084   vl_api_control_ping_t *mp_ping;
6085   hash_pair_t *p;
6086   name_sort_t *nses = 0, *ns;
6087   sw_interface_subif_t *sub = NULL;
6088   int ret;
6089
6090   /* Toss the old name table */
6091   /* *INDENT-OFF* */
6092   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6093   ({
6094     vec_add2 (nses, ns, 1);
6095     ns->name = (u8 *)(p->key);
6096     ns->value = (u32) p->value[0];
6097   }));
6098   /* *INDENT-ON* */
6099
6100   hash_free (vam->sw_if_index_by_interface_name);
6101
6102   vec_foreach (ns, nses) vec_free (ns->name);
6103
6104   vec_free (nses);
6105
6106   vec_foreach (sub, vam->sw_if_subif_table)
6107   {
6108     vec_free (sub->interface_name);
6109   }
6110   vec_free (vam->sw_if_subif_table);
6111
6112   /* recreate the interface name hash table */
6113   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6114
6115   /* Get list of ethernets */
6116   M (SW_INTERFACE_DUMP, mp);
6117   mp->name_filter_valid = 1;
6118   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
6119   S (mp);
6120
6121   /* and local / loopback interfaces */
6122   M (SW_INTERFACE_DUMP, mp);
6123   mp->name_filter_valid = 1;
6124   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
6125   S (mp);
6126
6127   /* and packet-generator interfaces */
6128   M (SW_INTERFACE_DUMP, mp);
6129   mp->name_filter_valid = 1;
6130   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
6131   S (mp);
6132
6133   /* and vxlan-gpe tunnel interfaces */
6134   M (SW_INTERFACE_DUMP, mp);
6135   mp->name_filter_valid = 1;
6136   strncpy ((char *) mp->name_filter, "vxlan_gpe",
6137            sizeof (mp->name_filter) - 1);
6138   S (mp);
6139
6140   /* and vxlan tunnel interfaces */
6141   M (SW_INTERFACE_DUMP, mp);
6142   mp->name_filter_valid = 1;
6143   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
6144   S (mp);
6145
6146   /* and geneve tunnel interfaces */
6147   M (SW_INTERFACE_DUMP, mp);
6148   mp->name_filter_valid = 1;
6149   strncpy ((char *) mp->name_filter, "geneve", sizeof (mp->name_filter) - 1);
6150   S (mp);
6151
6152   /* and host (af_packet) interfaces */
6153   M (SW_INTERFACE_DUMP, mp);
6154   mp->name_filter_valid = 1;
6155   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
6156   S (mp);
6157
6158   /* and l2tpv3 tunnel interfaces */
6159   M (SW_INTERFACE_DUMP, mp);
6160   mp->name_filter_valid = 1;
6161   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
6162            sizeof (mp->name_filter) - 1);
6163   S (mp);
6164
6165   /* and GRE tunnel interfaces */
6166   M (SW_INTERFACE_DUMP, mp);
6167   mp->name_filter_valid = 1;
6168   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
6169   S (mp);
6170
6171   /* and LISP-GPE interfaces */
6172   M (SW_INTERFACE_DUMP, mp);
6173   mp->name_filter_valid = 1;
6174   strncpy ((char *) mp->name_filter, "lisp_gpe",
6175            sizeof (mp->name_filter) - 1);
6176   S (mp);
6177
6178   /* and IPSEC tunnel interfaces */
6179   M (SW_INTERFACE_DUMP, mp);
6180   mp->name_filter_valid = 1;
6181   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
6182   S (mp);
6183
6184   /* Use a control ping for synchronization */
6185   MPING (CONTROL_PING, mp_ping);
6186   S (mp_ping);
6187
6188   W (ret);
6189   return ret;
6190 }
6191
6192 static int
6193 api_sw_interface_set_flags (vat_main_t * vam)
6194 {
6195   unformat_input_t *i = vam->input;
6196   vl_api_sw_interface_set_flags_t *mp;
6197   u32 sw_if_index;
6198   u8 sw_if_index_set = 0;
6199   u8 admin_up = 0;
6200   int ret;
6201
6202   /* Parse args required to build the message */
6203   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6204     {
6205       if (unformat (i, "admin-up"))
6206         admin_up = 1;
6207       else if (unformat (i, "admin-down"))
6208         admin_up = 0;
6209       else
6210         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6211         sw_if_index_set = 1;
6212       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6213         sw_if_index_set = 1;
6214       else
6215         break;
6216     }
6217
6218   if (sw_if_index_set == 0)
6219     {
6220       errmsg ("missing interface name or sw_if_index");
6221       return -99;
6222     }
6223
6224   /* Construct the API message */
6225   M (SW_INTERFACE_SET_FLAGS, mp);
6226   mp->sw_if_index = ntohl (sw_if_index);
6227   mp->admin_up_down = admin_up;
6228
6229   /* send it... */
6230   S (mp);
6231
6232   /* Wait for a reply, return the good/bad news... */
6233   W (ret);
6234   return ret;
6235 }
6236
6237 static int
6238 api_sw_interface_set_rx_mode (vat_main_t * vam)
6239 {
6240   unformat_input_t *i = vam->input;
6241   vl_api_sw_interface_set_rx_mode_t *mp;
6242   u32 sw_if_index;
6243   u8 sw_if_index_set = 0;
6244   int ret;
6245   u8 queue_id_valid = 0;
6246   u32 queue_id;
6247   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
6248
6249   /* Parse args required to build the message */
6250   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6251     {
6252       if (unformat (i, "queue %d", &queue_id))
6253         queue_id_valid = 1;
6254       else if (unformat (i, "polling"))
6255         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
6256       else if (unformat (i, "interrupt"))
6257         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
6258       else if (unformat (i, "adaptive"))
6259         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
6260       else
6261         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6262         sw_if_index_set = 1;
6263       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6264         sw_if_index_set = 1;
6265       else
6266         break;
6267     }
6268
6269   if (sw_if_index_set == 0)
6270     {
6271       errmsg ("missing interface name or sw_if_index");
6272       return -99;
6273     }
6274   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
6275     {
6276       errmsg ("missing rx-mode");
6277       return -99;
6278     }
6279
6280   /* Construct the API message */
6281   M (SW_INTERFACE_SET_RX_MODE, mp);
6282   mp->sw_if_index = ntohl (sw_if_index);
6283   mp->mode = mode;
6284   mp->queue_id_valid = queue_id_valid;
6285   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
6286
6287   /* send it... */
6288   S (mp);
6289
6290   /* Wait for a reply, return the good/bad news... */
6291   W (ret);
6292   return ret;
6293 }
6294
6295 static int
6296 api_sw_interface_clear_stats (vat_main_t * vam)
6297 {
6298   unformat_input_t *i = vam->input;
6299   vl_api_sw_interface_clear_stats_t *mp;
6300   u32 sw_if_index;
6301   u8 sw_if_index_set = 0;
6302   int ret;
6303
6304   /* Parse args required to build the message */
6305   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6306     {
6307       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6308         sw_if_index_set = 1;
6309       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6310         sw_if_index_set = 1;
6311       else
6312         break;
6313     }
6314
6315   /* Construct the API message */
6316   M (SW_INTERFACE_CLEAR_STATS, mp);
6317
6318   if (sw_if_index_set == 1)
6319     mp->sw_if_index = ntohl (sw_if_index);
6320   else
6321     mp->sw_if_index = ~0;
6322
6323   /* send it... */
6324   S (mp);
6325
6326   /* Wait for a reply, return the good/bad news... */
6327   W (ret);
6328   return ret;
6329 }
6330
6331 static int
6332 api_sw_interface_add_del_address (vat_main_t * vam)
6333 {
6334   unformat_input_t *i = vam->input;
6335   vl_api_sw_interface_add_del_address_t *mp;
6336   u32 sw_if_index;
6337   u8 sw_if_index_set = 0;
6338   u8 is_add = 1, del_all = 0;
6339   u32 address_length = 0;
6340   u8 v4_address_set = 0;
6341   u8 v6_address_set = 0;
6342   ip4_address_t v4address;
6343   ip6_address_t v6address;
6344   int ret;
6345
6346   /* Parse args required to build the message */
6347   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6348     {
6349       if (unformat (i, "del-all"))
6350         del_all = 1;
6351       else if (unformat (i, "del"))
6352         is_add = 0;
6353       else
6354         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6355         sw_if_index_set = 1;
6356       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6357         sw_if_index_set = 1;
6358       else if (unformat (i, "%U/%d",
6359                          unformat_ip4_address, &v4address, &address_length))
6360         v4_address_set = 1;
6361       else if (unformat (i, "%U/%d",
6362                          unformat_ip6_address, &v6address, &address_length))
6363         v6_address_set = 1;
6364       else
6365         break;
6366     }
6367
6368   if (sw_if_index_set == 0)
6369     {
6370       errmsg ("missing interface name or sw_if_index");
6371       return -99;
6372     }
6373   if (v4_address_set && v6_address_set)
6374     {
6375       errmsg ("both v4 and v6 addresses set");
6376       return -99;
6377     }
6378   if (!v4_address_set && !v6_address_set && !del_all)
6379     {
6380       errmsg ("no addresses set");
6381       return -99;
6382     }
6383
6384   /* Construct the API message */
6385   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6386
6387   mp->sw_if_index = ntohl (sw_if_index);
6388   mp->is_add = is_add;
6389   mp->del_all = del_all;
6390   if (v6_address_set)
6391     {
6392       mp->is_ipv6 = 1;
6393       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6394     }
6395   else
6396     {
6397       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6398     }
6399   mp->address_length = address_length;
6400
6401   /* send it... */
6402   S (mp);
6403
6404   /* Wait for a reply, return good/bad news  */
6405   W (ret);
6406   return ret;
6407 }
6408
6409 static int
6410 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6411 {
6412   unformat_input_t *i = vam->input;
6413   vl_api_sw_interface_set_mpls_enable_t *mp;
6414   u32 sw_if_index;
6415   u8 sw_if_index_set = 0;
6416   u8 enable = 1;
6417   int ret;
6418
6419   /* Parse args required to build the message */
6420   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6421     {
6422       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6423         sw_if_index_set = 1;
6424       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6425         sw_if_index_set = 1;
6426       else if (unformat (i, "disable"))
6427         enable = 0;
6428       else if (unformat (i, "dis"))
6429         enable = 0;
6430       else
6431         break;
6432     }
6433
6434   if (sw_if_index_set == 0)
6435     {
6436       errmsg ("missing interface name or sw_if_index");
6437       return -99;
6438     }
6439
6440   /* Construct the API message */
6441   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6442
6443   mp->sw_if_index = ntohl (sw_if_index);
6444   mp->enable = enable;
6445
6446   /* send it... */
6447   S (mp);
6448
6449   /* Wait for a reply... */
6450   W (ret);
6451   return ret;
6452 }
6453
6454 static int
6455 api_sw_interface_set_table (vat_main_t * vam)
6456 {
6457   unformat_input_t *i = vam->input;
6458   vl_api_sw_interface_set_table_t *mp;
6459   u32 sw_if_index, vrf_id = 0;
6460   u8 sw_if_index_set = 0;
6461   u8 is_ipv6 = 0;
6462   int ret;
6463
6464   /* Parse args required to build the message */
6465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6466     {
6467       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6468         sw_if_index_set = 1;
6469       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6470         sw_if_index_set = 1;
6471       else if (unformat (i, "vrf %d", &vrf_id))
6472         ;
6473       else if (unformat (i, "ipv6"))
6474         is_ipv6 = 1;
6475       else
6476         break;
6477     }
6478
6479   if (sw_if_index_set == 0)
6480     {
6481       errmsg ("missing interface name or sw_if_index");
6482       return -99;
6483     }
6484
6485   /* Construct the API message */
6486   M (SW_INTERFACE_SET_TABLE, mp);
6487
6488   mp->sw_if_index = ntohl (sw_if_index);
6489   mp->is_ipv6 = is_ipv6;
6490   mp->vrf_id = ntohl (vrf_id);
6491
6492   /* send it... */
6493   S (mp);
6494
6495   /* Wait for a reply... */
6496   W (ret);
6497   return ret;
6498 }
6499
6500 static void vl_api_sw_interface_get_table_reply_t_handler
6501   (vl_api_sw_interface_get_table_reply_t * mp)
6502 {
6503   vat_main_t *vam = &vat_main;
6504
6505   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6506
6507   vam->retval = ntohl (mp->retval);
6508   vam->result_ready = 1;
6509
6510 }
6511
6512 static void vl_api_sw_interface_get_table_reply_t_handler_json
6513   (vl_api_sw_interface_get_table_reply_t * mp)
6514 {
6515   vat_main_t *vam = &vat_main;
6516   vat_json_node_t node;
6517
6518   vat_json_init_object (&node);
6519   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6520   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6521
6522   vat_json_print (vam->ofp, &node);
6523   vat_json_free (&node);
6524
6525   vam->retval = ntohl (mp->retval);
6526   vam->result_ready = 1;
6527 }
6528
6529 static int
6530 api_sw_interface_get_table (vat_main_t * vam)
6531 {
6532   unformat_input_t *i = vam->input;
6533   vl_api_sw_interface_get_table_t *mp;
6534   u32 sw_if_index;
6535   u8 sw_if_index_set = 0;
6536   u8 is_ipv6 = 0;
6537   int ret;
6538
6539   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6540     {
6541       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6542         sw_if_index_set = 1;
6543       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6544         sw_if_index_set = 1;
6545       else if (unformat (i, "ipv6"))
6546         is_ipv6 = 1;
6547       else
6548         break;
6549     }
6550
6551   if (sw_if_index_set == 0)
6552     {
6553       errmsg ("missing interface name or sw_if_index");
6554       return -99;
6555     }
6556
6557   M (SW_INTERFACE_GET_TABLE, mp);
6558   mp->sw_if_index = htonl (sw_if_index);
6559   mp->is_ipv6 = is_ipv6;
6560
6561   S (mp);
6562   W (ret);
6563   return ret;
6564 }
6565
6566 static int
6567 api_sw_interface_set_vpath (vat_main_t * vam)
6568 {
6569   unformat_input_t *i = vam->input;
6570   vl_api_sw_interface_set_vpath_t *mp;
6571   u32 sw_if_index = 0;
6572   u8 sw_if_index_set = 0;
6573   u8 is_enable = 0;
6574   int ret;
6575
6576   /* Parse args required to build the message */
6577   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6578     {
6579       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6580         sw_if_index_set = 1;
6581       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6582         sw_if_index_set = 1;
6583       else if (unformat (i, "enable"))
6584         is_enable = 1;
6585       else if (unformat (i, "disable"))
6586         is_enable = 0;
6587       else
6588         break;
6589     }
6590
6591   if (sw_if_index_set == 0)
6592     {
6593       errmsg ("missing interface name or sw_if_index");
6594       return -99;
6595     }
6596
6597   /* Construct the API message */
6598   M (SW_INTERFACE_SET_VPATH, mp);
6599
6600   mp->sw_if_index = ntohl (sw_if_index);
6601   mp->enable = is_enable;
6602
6603   /* send it... */
6604   S (mp);
6605
6606   /* Wait for a reply... */
6607   W (ret);
6608   return ret;
6609 }
6610
6611 static int
6612 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6613 {
6614   unformat_input_t *i = vam->input;
6615   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6616   u32 sw_if_index = 0;
6617   u8 sw_if_index_set = 0;
6618   u8 is_enable = 1;
6619   u8 is_ipv6 = 0;
6620   int ret;
6621
6622   /* Parse args required to build the message */
6623   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6624     {
6625       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6626         sw_if_index_set = 1;
6627       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6628         sw_if_index_set = 1;
6629       else if (unformat (i, "enable"))
6630         is_enable = 1;
6631       else if (unformat (i, "disable"))
6632         is_enable = 0;
6633       else if (unformat (i, "ip4"))
6634         is_ipv6 = 0;
6635       else if (unformat (i, "ip6"))
6636         is_ipv6 = 1;
6637       else
6638         break;
6639     }
6640
6641   if (sw_if_index_set == 0)
6642     {
6643       errmsg ("missing interface name or sw_if_index");
6644       return -99;
6645     }
6646
6647   /* Construct the API message */
6648   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6649
6650   mp->sw_if_index = ntohl (sw_if_index);
6651   mp->enable = is_enable;
6652   mp->is_ipv6 = is_ipv6;
6653
6654   /* send it... */
6655   S (mp);
6656
6657   /* Wait for a reply... */
6658   W (ret);
6659   return ret;
6660 }
6661
6662 static int
6663 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6664 {
6665   unformat_input_t *i = vam->input;
6666   vl_api_sw_interface_set_geneve_bypass_t *mp;
6667   u32 sw_if_index = 0;
6668   u8 sw_if_index_set = 0;
6669   u8 is_enable = 1;
6670   u8 is_ipv6 = 0;
6671   int ret;
6672
6673   /* Parse args required to build the message */
6674   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6675     {
6676       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6677         sw_if_index_set = 1;
6678       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6679         sw_if_index_set = 1;
6680       else if (unformat (i, "enable"))
6681         is_enable = 1;
6682       else if (unformat (i, "disable"))
6683         is_enable = 0;
6684       else if (unformat (i, "ip4"))
6685         is_ipv6 = 0;
6686       else if (unformat (i, "ip6"))
6687         is_ipv6 = 1;
6688       else
6689         break;
6690     }
6691
6692   if (sw_if_index_set == 0)
6693     {
6694       errmsg ("missing interface name or sw_if_index");
6695       return -99;
6696     }
6697
6698   /* Construct the API message */
6699   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6700
6701   mp->sw_if_index = ntohl (sw_if_index);
6702   mp->enable = is_enable;
6703   mp->is_ipv6 = is_ipv6;
6704
6705   /* send it... */
6706   S (mp);
6707
6708   /* Wait for a reply... */
6709   W (ret);
6710   return ret;
6711 }
6712
6713 static int
6714 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6715 {
6716   unformat_input_t *i = vam->input;
6717   vl_api_sw_interface_set_l2_xconnect_t *mp;
6718   u32 rx_sw_if_index;
6719   u8 rx_sw_if_index_set = 0;
6720   u32 tx_sw_if_index;
6721   u8 tx_sw_if_index_set = 0;
6722   u8 enable = 1;
6723   int ret;
6724
6725   /* Parse args required to build the message */
6726   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6727     {
6728       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6729         rx_sw_if_index_set = 1;
6730       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6731         tx_sw_if_index_set = 1;
6732       else if (unformat (i, "rx"))
6733         {
6734           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6735             {
6736               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6737                             &rx_sw_if_index))
6738                 rx_sw_if_index_set = 1;
6739             }
6740           else
6741             break;
6742         }
6743       else if (unformat (i, "tx"))
6744         {
6745           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6746             {
6747               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6748                             &tx_sw_if_index))
6749                 tx_sw_if_index_set = 1;
6750             }
6751           else
6752             break;
6753         }
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 rx_sw_if_index");
6765       return -99;
6766     }
6767
6768   if (enable && (tx_sw_if_index_set == 0))
6769     {
6770       errmsg ("missing tx interface name or tx_sw_if_index");
6771       return -99;
6772     }
6773
6774   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6775
6776   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6777   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6778   mp->enable = enable;
6779
6780   S (mp);
6781   W (ret);
6782   return ret;
6783 }
6784
6785 static int
6786 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6787 {
6788   unformat_input_t *i = vam->input;
6789   vl_api_sw_interface_set_l2_bridge_t *mp;
6790   u32 rx_sw_if_index;
6791   u8 rx_sw_if_index_set = 0;
6792   u32 bd_id;
6793   u8 bd_id_set = 0;
6794   u8 bvi = 0;
6795   u32 shg = 0;
6796   u8 enable = 1;
6797   int ret;
6798
6799   /* Parse args required to build the message */
6800   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6801     {
6802       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6803         rx_sw_if_index_set = 1;
6804       else if (unformat (i, "bd_id %d", &bd_id))
6805         bd_id_set = 1;
6806       else
6807         if (unformat
6808             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6809         rx_sw_if_index_set = 1;
6810       else if (unformat (i, "shg %d", &shg))
6811         ;
6812       else if (unformat (i, "bvi"))
6813         bvi = 1;
6814       else if (unformat (i, "enable"))
6815         enable = 1;
6816       else if (unformat (i, "disable"))
6817         enable = 0;
6818       else
6819         break;
6820     }
6821
6822   if (rx_sw_if_index_set == 0)
6823     {
6824       errmsg ("missing rx interface name or sw_if_index");
6825       return -99;
6826     }
6827
6828   if (enable && (bd_id_set == 0))
6829     {
6830       errmsg ("missing bridge domain");
6831       return -99;
6832     }
6833
6834   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6835
6836   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6837   mp->bd_id = ntohl (bd_id);
6838   mp->shg = (u8) shg;
6839   mp->bvi = bvi;
6840   mp->enable = enable;
6841
6842   S (mp);
6843   W (ret);
6844   return ret;
6845 }
6846
6847 static int
6848 api_bridge_domain_dump (vat_main_t * vam)
6849 {
6850   unformat_input_t *i = vam->input;
6851   vl_api_bridge_domain_dump_t *mp;
6852   vl_api_control_ping_t *mp_ping;
6853   u32 bd_id = ~0;
6854   int ret;
6855
6856   /* Parse args required to build the message */
6857   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6858     {
6859       if (unformat (i, "bd_id %d", &bd_id))
6860         ;
6861       else
6862         break;
6863     }
6864
6865   M (BRIDGE_DOMAIN_DUMP, mp);
6866   mp->bd_id = ntohl (bd_id);
6867   S (mp);
6868
6869   /* Use a control ping for synchronization */
6870   MPING (CONTROL_PING, mp_ping);
6871   S (mp_ping);
6872
6873   W (ret);
6874   return ret;
6875 }
6876
6877 static int
6878 api_bridge_domain_add_del (vat_main_t * vam)
6879 {
6880   unformat_input_t *i = vam->input;
6881   vl_api_bridge_domain_add_del_t *mp;
6882   u32 bd_id = ~0;
6883   u8 is_add = 1;
6884   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6885   u8 *bd_tag = NULL;
6886   u32 mac_age = 0;
6887   int ret;
6888
6889   /* Parse args required to build the message */
6890   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6891     {
6892       if (unformat (i, "bd_id %d", &bd_id))
6893         ;
6894       else if (unformat (i, "flood %d", &flood))
6895         ;
6896       else if (unformat (i, "uu-flood %d", &uu_flood))
6897         ;
6898       else if (unformat (i, "forward %d", &forward))
6899         ;
6900       else if (unformat (i, "learn %d", &learn))
6901         ;
6902       else if (unformat (i, "arp-term %d", &arp_term))
6903         ;
6904       else if (unformat (i, "mac-age %d", &mac_age))
6905         ;
6906       else if (unformat (i, "bd-tag %s", &bd_tag))
6907         ;
6908       else if (unformat (i, "del"))
6909         {
6910           is_add = 0;
6911           flood = uu_flood = forward = learn = 0;
6912         }
6913       else
6914         break;
6915     }
6916
6917   if (bd_id == ~0)
6918     {
6919       errmsg ("missing bridge domain");
6920       ret = -99;
6921       goto done;
6922     }
6923
6924   if (mac_age > 255)
6925     {
6926       errmsg ("mac age must be less than 256 ");
6927       ret = -99;
6928       goto done;
6929     }
6930
6931   if ((bd_tag) && (strlen ((char *) bd_tag) > 63))
6932     {
6933       errmsg ("bd-tag cannot be longer than 63");
6934       ret = -99;
6935       goto done;
6936     }
6937
6938   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6939
6940   mp->bd_id = ntohl (bd_id);
6941   mp->flood = flood;
6942   mp->uu_flood = uu_flood;
6943   mp->forward = forward;
6944   mp->learn = learn;
6945   mp->arp_term = arp_term;
6946   mp->is_add = is_add;
6947   mp->mac_age = (u8) mac_age;
6948   if (bd_tag)
6949     strcpy ((char *) mp->bd_tag, (char *) bd_tag);
6950
6951   S (mp);
6952   W (ret);
6953
6954 done:
6955   vec_free (bd_tag);
6956   return ret;
6957 }
6958
6959 static int
6960 api_l2fib_flush_bd (vat_main_t * vam)
6961 {
6962   unformat_input_t *i = vam->input;
6963   vl_api_l2fib_flush_bd_t *mp;
6964   u32 bd_id = ~0;
6965   int ret;
6966
6967   /* Parse args required to build the message */
6968   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6969     {
6970       if (unformat (i, "bd_id %d", &bd_id));
6971       else
6972         break;
6973     }
6974
6975   if (bd_id == ~0)
6976     {
6977       errmsg ("missing bridge domain");
6978       return -99;
6979     }
6980
6981   M (L2FIB_FLUSH_BD, mp);
6982
6983   mp->bd_id = htonl (bd_id);
6984
6985   S (mp);
6986   W (ret);
6987   return ret;
6988 }
6989
6990 static int
6991 api_l2fib_flush_int (vat_main_t * vam)
6992 {
6993   unformat_input_t *i = vam->input;
6994   vl_api_l2fib_flush_int_t *mp;
6995   u32 sw_if_index = ~0;
6996   int ret;
6997
6998   /* Parse args required to build the message */
6999   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7000     {
7001       if (unformat (i, "sw_if_index %d", &sw_if_index));
7002       else
7003         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
7004       else
7005         break;
7006     }
7007
7008   if (sw_if_index == ~0)
7009     {
7010       errmsg ("missing interface name or sw_if_index");
7011       return -99;
7012     }
7013
7014   M (L2FIB_FLUSH_INT, mp);
7015
7016   mp->sw_if_index = ntohl (sw_if_index);
7017
7018   S (mp);
7019   W (ret);
7020   return ret;
7021 }
7022
7023 static int
7024 api_l2fib_add_del (vat_main_t * vam)
7025 {
7026   unformat_input_t *i = vam->input;
7027   vl_api_l2fib_add_del_t *mp;
7028   f64 timeout;
7029   u64 mac = 0;
7030   u8 mac_set = 0;
7031   u32 bd_id;
7032   u8 bd_id_set = 0;
7033   u32 sw_if_index = ~0;
7034   u8 sw_if_index_set = 0;
7035   u8 is_add = 1;
7036   u8 static_mac = 0;
7037   u8 filter_mac = 0;
7038   u8 bvi_mac = 0;
7039   int count = 1;
7040   f64 before = 0;
7041   int j;
7042
7043   /* Parse args required to build the message */
7044   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7045     {
7046       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
7047         mac_set = 1;
7048       else if (unformat (i, "bd_id %d", &bd_id))
7049         bd_id_set = 1;
7050       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7051         sw_if_index_set = 1;
7052       else if (unformat (i, "sw_if"))
7053         {
7054           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7055             {
7056               if (unformat
7057                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7058                 sw_if_index_set = 1;
7059             }
7060           else
7061             break;
7062         }
7063       else if (unformat (i, "static"))
7064         static_mac = 1;
7065       else if (unformat (i, "filter"))
7066         {
7067           filter_mac = 1;
7068           static_mac = 1;
7069         }
7070       else if (unformat (i, "bvi"))
7071         {
7072           bvi_mac = 1;
7073           static_mac = 1;
7074         }
7075       else if (unformat (i, "del"))
7076         is_add = 0;
7077       else if (unformat (i, "count %d", &count))
7078         ;
7079       else
7080         break;
7081     }
7082
7083   if (mac_set == 0)
7084     {
7085       errmsg ("missing mac address");
7086       return -99;
7087     }
7088
7089   if (bd_id_set == 0)
7090     {
7091       errmsg ("missing bridge domain");
7092       return -99;
7093     }
7094
7095   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7096     {
7097       errmsg ("missing interface name or sw_if_index");
7098       return -99;
7099     }
7100
7101   if (count > 1)
7102     {
7103       /* Turn on async mode */
7104       vam->async_mode = 1;
7105       vam->async_errors = 0;
7106       before = vat_time_now (vam);
7107     }
7108
7109   for (j = 0; j < count; j++)
7110     {
7111       M (L2FIB_ADD_DEL, mp);
7112
7113       mp->mac = mac;
7114       mp->bd_id = ntohl (bd_id);
7115       mp->is_add = is_add;
7116
7117       if (is_add)
7118         {
7119           mp->sw_if_index = ntohl (sw_if_index);
7120           mp->static_mac = static_mac;
7121           mp->filter_mac = filter_mac;
7122           mp->bvi_mac = bvi_mac;
7123         }
7124       increment_mac_address (&mac);
7125       /* send it... */
7126       S (mp);
7127     }
7128
7129   if (count > 1)
7130     {
7131       vl_api_control_ping_t *mp_ping;
7132       f64 after;
7133
7134       /* Shut off async mode */
7135       vam->async_mode = 0;
7136
7137       MPING (CONTROL_PING, mp_ping);
7138       S (mp_ping);
7139
7140       timeout = vat_time_now (vam) + 1.0;
7141       while (vat_time_now (vam) < timeout)
7142         if (vam->result_ready == 1)
7143           goto out;
7144       vam->retval = -99;
7145
7146     out:
7147       if (vam->retval == -99)
7148         errmsg ("timeout");
7149
7150       if (vam->async_errors > 0)
7151         {
7152           errmsg ("%d asynchronous errors", vam->async_errors);
7153           vam->retval = -98;
7154         }
7155       vam->async_errors = 0;
7156       after = vat_time_now (vam);
7157
7158       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7159              count, after - before, count / (after - before));
7160     }
7161   else
7162     {
7163       int ret;
7164
7165       /* Wait for a reply... */
7166       W (ret);
7167       return ret;
7168     }
7169   /* Return the good/bad news */
7170   return (vam->retval);
7171 }
7172
7173 static int
7174 api_bridge_domain_set_mac_age (vat_main_t * vam)
7175 {
7176   unformat_input_t *i = vam->input;
7177   vl_api_bridge_domain_set_mac_age_t *mp;
7178   u32 bd_id = ~0;
7179   u32 mac_age = 0;
7180   int ret;
7181
7182   /* Parse args required to build the message */
7183   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7184     {
7185       if (unformat (i, "bd_id %d", &bd_id));
7186       else if (unformat (i, "mac-age %d", &mac_age));
7187       else
7188         break;
7189     }
7190
7191   if (bd_id == ~0)
7192     {
7193       errmsg ("missing bridge domain");
7194       return -99;
7195     }
7196
7197   if (mac_age > 255)
7198     {
7199       errmsg ("mac age must be less than 256 ");
7200       return -99;
7201     }
7202
7203   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7204
7205   mp->bd_id = htonl (bd_id);
7206   mp->mac_age = (u8) mac_age;
7207
7208   S (mp);
7209   W (ret);
7210   return ret;
7211 }
7212
7213 static int
7214 api_l2_flags (vat_main_t * vam)
7215 {
7216   unformat_input_t *i = vam->input;
7217   vl_api_l2_flags_t *mp;
7218   u32 sw_if_index;
7219   u32 flags = 0;
7220   u8 sw_if_index_set = 0;
7221   u8 is_set = 0;
7222   int ret;
7223
7224   /* Parse args required to build the message */
7225   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7226     {
7227       if (unformat (i, "sw_if_index %d", &sw_if_index))
7228         sw_if_index_set = 1;
7229       else if (unformat (i, "sw_if"))
7230         {
7231           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7232             {
7233               if (unformat
7234                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7235                 sw_if_index_set = 1;
7236             }
7237           else
7238             break;
7239         }
7240       else if (unformat (i, "learn"))
7241         flags |= L2_LEARN;
7242       else if (unformat (i, "forward"))
7243         flags |= L2_FWD;
7244       else if (unformat (i, "flood"))
7245         flags |= L2_FLOOD;
7246       else if (unformat (i, "uu-flood"))
7247         flags |= L2_UU_FLOOD;
7248       else if (unformat (i, "arp-term"))
7249         flags |= L2_ARP_TERM;
7250       else if (unformat (i, "off"))
7251         is_set = 0;
7252       else if (unformat (i, "disable"))
7253         is_set = 0;
7254       else
7255         break;
7256     }
7257
7258   if (sw_if_index_set == 0)
7259     {
7260       errmsg ("missing interface name or sw_if_index");
7261       return -99;
7262     }
7263
7264   M (L2_FLAGS, mp);
7265
7266   mp->sw_if_index = ntohl (sw_if_index);
7267   mp->feature_bitmap = ntohl (flags);
7268   mp->is_set = is_set;
7269
7270   S (mp);
7271   W (ret);
7272   return ret;
7273 }
7274
7275 static int
7276 api_bridge_flags (vat_main_t * vam)
7277 {
7278   unformat_input_t *i = vam->input;
7279   vl_api_bridge_flags_t *mp;
7280   u32 bd_id;
7281   u8 bd_id_set = 0;
7282   u8 is_set = 1;
7283   u32 flags = 0;
7284   int ret;
7285
7286   /* Parse args required to build the message */
7287   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7288     {
7289       if (unformat (i, "bd_id %d", &bd_id))
7290         bd_id_set = 1;
7291       else if (unformat (i, "learn"))
7292         flags |= L2_LEARN;
7293       else if (unformat (i, "forward"))
7294         flags |= L2_FWD;
7295       else if (unformat (i, "flood"))
7296         flags |= L2_FLOOD;
7297       else if (unformat (i, "uu-flood"))
7298         flags |= L2_UU_FLOOD;
7299       else if (unformat (i, "arp-term"))
7300         flags |= L2_ARP_TERM;
7301       else if (unformat (i, "off"))
7302         is_set = 0;
7303       else if (unformat (i, "disable"))
7304         is_set = 0;
7305       else
7306         break;
7307     }
7308
7309   if (bd_id_set == 0)
7310     {
7311       errmsg ("missing bridge domain");
7312       return -99;
7313     }
7314
7315   M (BRIDGE_FLAGS, mp);
7316
7317   mp->bd_id = ntohl (bd_id);
7318   mp->feature_bitmap = ntohl (flags);
7319   mp->is_set = is_set;
7320
7321   S (mp);
7322   W (ret);
7323   return ret;
7324 }
7325
7326 static int
7327 api_bd_ip_mac_add_del (vat_main_t * vam)
7328 {
7329   unformat_input_t *i = vam->input;
7330   vl_api_bd_ip_mac_add_del_t *mp;
7331   u32 bd_id;
7332   u8 is_ipv6 = 0;
7333   u8 is_add = 1;
7334   u8 bd_id_set = 0;
7335   u8 ip_set = 0;
7336   u8 mac_set = 0;
7337   ip4_address_t v4addr;
7338   ip6_address_t v6addr;
7339   u8 macaddr[6];
7340   int ret;
7341
7342
7343   /* Parse args required to build the message */
7344   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7345     {
7346       if (unformat (i, "bd_id %d", &bd_id))
7347         {
7348           bd_id_set++;
7349         }
7350       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7351         {
7352           ip_set++;
7353         }
7354       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7355         {
7356           ip_set++;
7357           is_ipv6++;
7358         }
7359       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7360         {
7361           mac_set++;
7362         }
7363       else if (unformat (i, "del"))
7364         is_add = 0;
7365       else
7366         break;
7367     }
7368
7369   if (bd_id_set == 0)
7370     {
7371       errmsg ("missing bridge domain");
7372       return -99;
7373     }
7374   else if (ip_set == 0)
7375     {
7376       errmsg ("missing IP address");
7377       return -99;
7378     }
7379   else if (mac_set == 0)
7380     {
7381       errmsg ("missing MAC address");
7382       return -99;
7383     }
7384
7385   M (BD_IP_MAC_ADD_DEL, mp);
7386
7387   mp->bd_id = ntohl (bd_id);
7388   mp->is_ipv6 = is_ipv6;
7389   mp->is_add = is_add;
7390   if (is_ipv6)
7391     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7392   else
7393     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7394   clib_memcpy (mp->mac_address, macaddr, 6);
7395   S (mp);
7396   W (ret);
7397   return ret;
7398 }
7399
7400 static int
7401 api_tap_connect (vat_main_t * vam)
7402 {
7403   unformat_input_t *i = vam->input;
7404   vl_api_tap_connect_t *mp;
7405   u8 mac_address[6];
7406   u8 random_mac = 1;
7407   u8 name_set = 0;
7408   u8 *tap_name;
7409   u8 *tag = 0;
7410   ip4_address_t ip4_address;
7411   u32 ip4_mask_width;
7412   int ip4_address_set = 0;
7413   ip6_address_t ip6_address;
7414   u32 ip6_mask_width;
7415   int ip6_address_set = 0;
7416   int ret;
7417
7418   memset (mac_address, 0, sizeof (mac_address));
7419
7420   /* Parse args required to build the message */
7421   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7422     {
7423       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7424         {
7425           random_mac = 0;
7426         }
7427       else if (unformat (i, "random-mac"))
7428         random_mac = 1;
7429       else if (unformat (i, "tapname %s", &tap_name))
7430         name_set = 1;
7431       else if (unformat (i, "tag %s", &tag))
7432         ;
7433       else if (unformat (i, "address %U/%d",
7434                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7435         ip4_address_set = 1;
7436       else if (unformat (i, "address %U/%d",
7437                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7438         ip6_address_set = 1;
7439       else
7440         break;
7441     }
7442
7443   if (name_set == 0)
7444     {
7445       errmsg ("missing tap name");
7446       return -99;
7447     }
7448   if (vec_len (tap_name) > 63)
7449     {
7450       errmsg ("tap name too long");
7451       return -99;
7452     }
7453   vec_add1 (tap_name, 0);
7454
7455   if (vec_len (tag) > 63)
7456     {
7457       errmsg ("tag too long");
7458       return -99;
7459     }
7460
7461   /* Construct the API message */
7462   M (TAP_CONNECT, mp);
7463
7464   mp->use_random_mac = random_mac;
7465   clib_memcpy (mp->mac_address, mac_address, 6);
7466   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7467   if (tag)
7468     clib_memcpy (mp->tag, tag, vec_len (tag));
7469
7470   if (ip4_address_set)
7471     {
7472       mp->ip4_address_set = 1;
7473       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7474       mp->ip4_mask_width = ip4_mask_width;
7475     }
7476   if (ip6_address_set)
7477     {
7478       mp->ip6_address_set = 1;
7479       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7480       mp->ip6_mask_width = ip6_mask_width;
7481     }
7482
7483   vec_free (tap_name);
7484   vec_free (tag);
7485
7486   /* send it... */
7487   S (mp);
7488
7489   /* Wait for a reply... */
7490   W (ret);
7491   return ret;
7492 }
7493
7494 static int
7495 api_tap_modify (vat_main_t * vam)
7496 {
7497   unformat_input_t *i = vam->input;
7498   vl_api_tap_modify_t *mp;
7499   u8 mac_address[6];
7500   u8 random_mac = 1;
7501   u8 name_set = 0;
7502   u8 *tap_name;
7503   u32 sw_if_index = ~0;
7504   u8 sw_if_index_set = 0;
7505   int ret;
7506
7507   memset (mac_address, 0, sizeof (mac_address));
7508
7509   /* Parse args required to build the message */
7510   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7511     {
7512       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7513         sw_if_index_set = 1;
7514       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7515         sw_if_index_set = 1;
7516       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7517         {
7518           random_mac = 0;
7519         }
7520       else if (unformat (i, "random-mac"))
7521         random_mac = 1;
7522       else if (unformat (i, "tapname %s", &tap_name))
7523         name_set = 1;
7524       else
7525         break;
7526     }
7527
7528   if (sw_if_index_set == 0)
7529     {
7530       errmsg ("missing vpp interface name");
7531       return -99;
7532     }
7533   if (name_set == 0)
7534     {
7535       errmsg ("missing tap name");
7536       return -99;
7537     }
7538   if (vec_len (tap_name) > 63)
7539     {
7540       errmsg ("tap name too long");
7541     }
7542   vec_add1 (tap_name, 0);
7543
7544   /* Construct the API message */
7545   M (TAP_MODIFY, mp);
7546
7547   mp->use_random_mac = random_mac;
7548   mp->sw_if_index = ntohl (sw_if_index);
7549   clib_memcpy (mp->mac_address, mac_address, 6);
7550   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7551   vec_free (tap_name);
7552
7553   /* send it... */
7554   S (mp);
7555
7556   /* Wait for a reply... */
7557   W (ret);
7558   return ret;
7559 }
7560
7561 static int
7562 api_tap_delete (vat_main_t * vam)
7563 {
7564   unformat_input_t *i = vam->input;
7565   vl_api_tap_delete_t *mp;
7566   u32 sw_if_index = ~0;
7567   u8 sw_if_index_set = 0;
7568   int ret;
7569
7570   /* Parse args required to build the message */
7571   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7572     {
7573       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7574         sw_if_index_set = 1;
7575       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7576         sw_if_index_set = 1;
7577       else
7578         break;
7579     }
7580
7581   if (sw_if_index_set == 0)
7582     {
7583       errmsg ("missing vpp interface name");
7584       return -99;
7585     }
7586
7587   /* Construct the API message */
7588   M (TAP_DELETE, mp);
7589
7590   mp->sw_if_index = ntohl (sw_if_index);
7591
7592   /* send it... */
7593   S (mp);
7594
7595   /* Wait for a reply... */
7596   W (ret);
7597   return ret;
7598 }
7599
7600 static int
7601 api_ip_table_add_del (vat_main_t * vam)
7602 {
7603   unformat_input_t *i = vam->input;
7604   vl_api_ip_table_add_del_t *mp;
7605   u32 table_id = ~0;
7606   u8 is_ipv6 = 0;
7607   u8 is_add = 1;
7608   int ret = 0;
7609
7610   /* Parse args required to build the message */
7611   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7612     {
7613       if (unformat (i, "ipv6"))
7614         is_ipv6 = 1;
7615       else if (unformat (i, "del"))
7616         is_add = 0;
7617       else if (unformat (i, "add"))
7618         is_add = 1;
7619       else if (unformat (i, "table %d", &table_id))
7620         ;
7621       else
7622         {
7623           clib_warning ("parse error '%U'", format_unformat_error, i);
7624           return -99;
7625         }
7626     }
7627
7628   if (~0 == table_id)
7629     {
7630       errmsg ("missing table-ID");
7631       return -99;
7632     }
7633
7634   /* Construct the API message */
7635   M (IP_TABLE_ADD_DEL, mp);
7636
7637   mp->table_id = ntohl (table_id);
7638   mp->is_ipv6 = is_ipv6;
7639   mp->is_add = is_add;
7640
7641   /* send it... */
7642   S (mp);
7643
7644   /* Wait for a reply... */
7645   W (ret);
7646
7647   return ret;
7648 }
7649
7650 static int
7651 api_ip_add_del_route (vat_main_t * vam)
7652 {
7653   unformat_input_t *i = vam->input;
7654   vl_api_ip_add_del_route_t *mp;
7655   u32 sw_if_index = ~0, vrf_id = 0;
7656   u8 is_ipv6 = 0;
7657   u8 is_local = 0, is_drop = 0;
7658   u8 is_unreach = 0, is_prohibit = 0;
7659   u8 create_vrf_if_needed = 0;
7660   u8 is_add = 1;
7661   u32 next_hop_weight = 1;
7662   u8 is_multipath = 0;
7663   u8 address_set = 0;
7664   u8 address_length_set = 0;
7665   u32 next_hop_table_id = 0;
7666   u32 resolve_attempts = 0;
7667   u32 dst_address_length = 0;
7668   u8 next_hop_set = 0;
7669   ip4_address_t v4_dst_address, v4_next_hop_address;
7670   ip6_address_t v6_dst_address, v6_next_hop_address;
7671   int count = 1;
7672   int j;
7673   f64 before = 0;
7674   u32 random_add_del = 0;
7675   u32 *random_vector = 0;
7676   uword *random_hash;
7677   u32 random_seed = 0xdeaddabe;
7678   u32 classify_table_index = ~0;
7679   u8 is_classify = 0;
7680   u8 resolve_host = 0, resolve_attached = 0;
7681   mpls_label_t *next_hop_out_label_stack = NULL;
7682   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7683   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7684
7685   /* Parse args required to build the message */
7686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7687     {
7688       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7689         ;
7690       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7691         ;
7692       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
7693         {
7694           address_set = 1;
7695           is_ipv6 = 0;
7696         }
7697       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
7698         {
7699           address_set = 1;
7700           is_ipv6 = 1;
7701         }
7702       else if (unformat (i, "/%d", &dst_address_length))
7703         {
7704           address_length_set = 1;
7705         }
7706
7707       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
7708                                          &v4_next_hop_address))
7709         {
7710           next_hop_set = 1;
7711         }
7712       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
7713                                          &v6_next_hop_address))
7714         {
7715           next_hop_set = 1;
7716         }
7717       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
7718         ;
7719       else if (unformat (i, "weight %d", &next_hop_weight))
7720         ;
7721       else if (unformat (i, "drop"))
7722         {
7723           is_drop = 1;
7724         }
7725       else if (unformat (i, "null-send-unreach"))
7726         {
7727           is_unreach = 1;
7728         }
7729       else if (unformat (i, "null-send-prohibit"))
7730         {
7731           is_prohibit = 1;
7732         }
7733       else if (unformat (i, "local"))
7734         {
7735           is_local = 1;
7736         }
7737       else if (unformat (i, "classify %d", &classify_table_index))
7738         {
7739           is_classify = 1;
7740         }
7741       else if (unformat (i, "del"))
7742         is_add = 0;
7743       else if (unformat (i, "add"))
7744         is_add = 1;
7745       else if (unformat (i, "resolve-via-host"))
7746         resolve_host = 1;
7747       else if (unformat (i, "resolve-via-attached"))
7748         resolve_attached = 1;
7749       else if (unformat (i, "multipath"))
7750         is_multipath = 1;
7751       else if (unformat (i, "vrf %d", &vrf_id))
7752         ;
7753       else if (unformat (i, "create-vrf"))
7754         create_vrf_if_needed = 1;
7755       else if (unformat (i, "count %d", &count))
7756         ;
7757       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
7758         ;
7759       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7760         ;
7761       else if (unformat (i, "out-label %d", &next_hop_out_label))
7762         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7763       else if (unformat (i, "via-label %d", &next_hop_via_label))
7764         ;
7765       else if (unformat (i, "random"))
7766         random_add_del = 1;
7767       else if (unformat (i, "seed %d", &random_seed))
7768         ;
7769       else
7770         {
7771           clib_warning ("parse error '%U'", format_unformat_error, i);
7772           return -99;
7773         }
7774     }
7775
7776   if (!next_hop_set && !is_drop && !is_local &&
7777       !is_classify && !is_unreach && !is_prohibit &&
7778       MPLS_LABEL_INVALID == next_hop_via_label)
7779     {
7780       errmsg
7781         ("next hop / local / drop / unreach / prohibit / classify not set");
7782       return -99;
7783     }
7784
7785   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
7786     {
7787       errmsg ("next hop and next-hop via label set");
7788       return -99;
7789     }
7790   if (address_set == 0)
7791     {
7792       errmsg ("missing addresses");
7793       return -99;
7794     }
7795
7796   if (address_length_set == 0)
7797     {
7798       errmsg ("missing address length");
7799       return -99;
7800     }
7801
7802   /* Generate a pile of unique, random routes */
7803   if (random_add_del)
7804     {
7805       u32 this_random_address;
7806       random_hash = hash_create (count, sizeof (uword));
7807
7808       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
7809       for (j = 0; j <= count; j++)
7810         {
7811           do
7812             {
7813               this_random_address = random_u32 (&random_seed);
7814               this_random_address =
7815                 clib_host_to_net_u32 (this_random_address);
7816             }
7817           while (hash_get (random_hash, this_random_address));
7818           vec_add1 (random_vector, this_random_address);
7819           hash_set (random_hash, this_random_address, 1);
7820         }
7821       hash_free (random_hash);
7822       v4_dst_address.as_u32 = random_vector[0];
7823     }
7824
7825   if (count > 1)
7826     {
7827       /* Turn on async mode */
7828       vam->async_mode = 1;
7829       vam->async_errors = 0;
7830       before = vat_time_now (vam);
7831     }
7832
7833   for (j = 0; j < count; j++)
7834     {
7835       /* Construct the API message */
7836       M2 (IP_ADD_DEL_ROUTE, mp,
7837           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7838
7839       mp->next_hop_sw_if_index = ntohl (sw_if_index);
7840       mp->table_id = ntohl (vrf_id);
7841       mp->create_vrf_if_needed = create_vrf_if_needed;
7842
7843       mp->is_add = is_add;
7844       mp->is_drop = is_drop;
7845       mp->is_unreach = is_unreach;
7846       mp->is_prohibit = is_prohibit;
7847       mp->is_ipv6 = is_ipv6;
7848       mp->is_local = is_local;
7849       mp->is_classify = is_classify;
7850       mp->is_multipath = is_multipath;
7851       mp->is_resolve_host = resolve_host;
7852       mp->is_resolve_attached = resolve_attached;
7853       mp->next_hop_weight = next_hop_weight;
7854       mp->dst_address_length = dst_address_length;
7855       mp->next_hop_table_id = ntohl (next_hop_table_id);
7856       mp->classify_table_index = ntohl (classify_table_index);
7857       mp->next_hop_via_label = ntohl (next_hop_via_label);
7858       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7859       if (0 != mp->next_hop_n_out_labels)
7860         {
7861           memcpy (mp->next_hop_out_label_stack,
7862                   next_hop_out_label_stack,
7863                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7864           vec_free (next_hop_out_label_stack);
7865         }
7866
7867       if (is_ipv6)
7868         {
7869           clib_memcpy (mp->dst_address, &v6_dst_address,
7870                        sizeof (v6_dst_address));
7871           if (next_hop_set)
7872             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
7873                          sizeof (v6_next_hop_address));
7874           increment_v6_address (&v6_dst_address);
7875         }
7876       else
7877         {
7878           clib_memcpy (mp->dst_address, &v4_dst_address,
7879                        sizeof (v4_dst_address));
7880           if (next_hop_set)
7881             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
7882                          sizeof (v4_next_hop_address));
7883           if (random_add_del)
7884             v4_dst_address.as_u32 = random_vector[j + 1];
7885           else
7886             increment_v4_address (&v4_dst_address);
7887         }
7888       /* send it... */
7889       S (mp);
7890       /* If we receive SIGTERM, stop now... */
7891       if (vam->do_exit)
7892         break;
7893     }
7894
7895   /* When testing multiple add/del ops, use a control-ping to sync */
7896   if (count > 1)
7897     {
7898       vl_api_control_ping_t *mp_ping;
7899       f64 after;
7900       f64 timeout;
7901
7902       /* Shut off async mode */
7903       vam->async_mode = 0;
7904
7905       MPING (CONTROL_PING, mp_ping);
7906       S (mp_ping);
7907
7908       timeout = vat_time_now (vam) + 1.0;
7909       while (vat_time_now (vam) < timeout)
7910         if (vam->result_ready == 1)
7911           goto out;
7912       vam->retval = -99;
7913
7914     out:
7915       if (vam->retval == -99)
7916         errmsg ("timeout");
7917
7918       if (vam->async_errors > 0)
7919         {
7920           errmsg ("%d asynchronous errors", vam->async_errors);
7921           vam->retval = -98;
7922         }
7923       vam->async_errors = 0;
7924       after = vat_time_now (vam);
7925
7926       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7927       if (j > 0)
7928         count = j;
7929
7930       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7931              count, after - before, count / (after - before));
7932     }
7933   else
7934     {
7935       int ret;
7936
7937       /* Wait for a reply... */
7938       W (ret);
7939       return ret;
7940     }
7941
7942   /* Return the good/bad news */
7943   return (vam->retval);
7944 }
7945
7946 static int
7947 api_ip_mroute_add_del (vat_main_t * vam)
7948 {
7949   unformat_input_t *i = vam->input;
7950   vl_api_ip_mroute_add_del_t *mp;
7951   u32 sw_if_index = ~0, vrf_id = 0;
7952   u8 is_ipv6 = 0;
7953   u8 is_local = 0;
7954   u8 create_vrf_if_needed = 0;
7955   u8 is_add = 1;
7956   u8 address_set = 0;
7957   u32 grp_address_length = 0;
7958   ip4_address_t v4_grp_address, v4_src_address;
7959   ip6_address_t v6_grp_address, v6_src_address;
7960   mfib_itf_flags_t iflags = 0;
7961   mfib_entry_flags_t eflags = 0;
7962   int ret;
7963
7964   /* Parse args required to build the message */
7965   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7966     {
7967       if (unformat (i, "sw_if_index %d", &sw_if_index))
7968         ;
7969       else if (unformat (i, "%U %U",
7970                          unformat_ip4_address, &v4_src_address,
7971                          unformat_ip4_address, &v4_grp_address))
7972         {
7973           grp_address_length = 64;
7974           address_set = 1;
7975           is_ipv6 = 0;
7976         }
7977       else if (unformat (i, "%U %U",
7978                          unformat_ip6_address, &v6_src_address,
7979                          unformat_ip6_address, &v6_grp_address))
7980         {
7981           grp_address_length = 256;
7982           address_set = 1;
7983           is_ipv6 = 1;
7984         }
7985       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
7986         {
7987           memset (&v4_src_address, 0, sizeof (v4_src_address));
7988           grp_address_length = 32;
7989           address_set = 1;
7990           is_ipv6 = 0;
7991         }
7992       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
7993         {
7994           memset (&v6_src_address, 0, sizeof (v6_src_address));
7995           grp_address_length = 128;
7996           address_set = 1;
7997           is_ipv6 = 1;
7998         }
7999       else if (unformat (i, "/%d", &grp_address_length))
8000         ;
8001       else if (unformat (i, "local"))
8002         {
8003           is_local = 1;
8004         }
8005       else if (unformat (i, "del"))
8006         is_add = 0;
8007       else if (unformat (i, "add"))
8008         is_add = 1;
8009       else if (unformat (i, "vrf %d", &vrf_id))
8010         ;
8011       else if (unformat (i, "create-vrf"))
8012         create_vrf_if_needed = 1;
8013       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
8014         ;
8015       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8016         ;
8017       else
8018         {
8019           clib_warning ("parse error '%U'", format_unformat_error, i);
8020           return -99;
8021         }
8022     }
8023
8024   if (address_set == 0)
8025     {
8026       errmsg ("missing addresses\n");
8027       return -99;
8028     }
8029
8030   /* Construct the API message */
8031   M (IP_MROUTE_ADD_DEL, mp);
8032
8033   mp->next_hop_sw_if_index = ntohl (sw_if_index);
8034   mp->table_id = ntohl (vrf_id);
8035   mp->create_vrf_if_needed = create_vrf_if_needed;
8036
8037   mp->is_add = is_add;
8038   mp->is_ipv6 = is_ipv6;
8039   mp->is_local = is_local;
8040   mp->itf_flags = ntohl (iflags);
8041   mp->entry_flags = ntohl (eflags);
8042   mp->grp_address_length = grp_address_length;
8043   mp->grp_address_length = ntohs (mp->grp_address_length);
8044
8045   if (is_ipv6)
8046     {
8047       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
8048       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
8049     }
8050   else
8051     {
8052       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
8053       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
8054
8055     }
8056
8057   /* send it... */
8058   S (mp);
8059   /* Wait for a reply... */
8060   W (ret);
8061   return ret;
8062 }
8063
8064 static int
8065 api_mpls_table_add_del (vat_main_t * vam)
8066 {
8067   unformat_input_t *i = vam->input;
8068   vl_api_mpls_table_add_del_t *mp;
8069   u32 table_id = ~0;
8070   u8 is_add = 1;
8071   int ret = 0;
8072
8073   /* Parse args required to build the message */
8074   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8075     {
8076       if (unformat (i, "table %d", &table_id))
8077         ;
8078       else if (unformat (i, "del"))
8079         is_add = 0;
8080       else if (unformat (i, "add"))
8081         is_add = 1;
8082       else
8083         {
8084           clib_warning ("parse error '%U'", format_unformat_error, i);
8085           return -99;
8086         }
8087     }
8088
8089   if (~0 == table_id)
8090     {
8091       errmsg ("missing table-ID");
8092       return -99;
8093     }
8094
8095   /* Construct the API message */
8096   M (MPLS_TABLE_ADD_DEL, mp);
8097
8098   mp->mt_table_id = ntohl (table_id);
8099   mp->mt_is_add = is_add;
8100
8101   /* send it... */
8102   S (mp);
8103
8104   /* Wait for a reply... */
8105   W (ret);
8106
8107   return ret;
8108 }
8109
8110 static int
8111 api_mpls_route_add_del (vat_main_t * vam)
8112 {
8113   unformat_input_t *i = vam->input;
8114   vl_api_mpls_route_add_del_t *mp;
8115   u32 sw_if_index = ~0, table_id = 0;
8116   u8 create_table_if_needed = 0;
8117   u8 is_add = 1;
8118   u32 next_hop_weight = 1;
8119   u8 is_multipath = 0;
8120   u32 next_hop_table_id = 0;
8121   u8 next_hop_set = 0;
8122   ip4_address_t v4_next_hop_address = {
8123     .as_u32 = 0,
8124   };
8125   ip6_address_t v6_next_hop_address = { {0} };
8126   int count = 1;
8127   int j;
8128   f64 before = 0;
8129   u32 classify_table_index = ~0;
8130   u8 is_classify = 0;
8131   u8 resolve_host = 0, resolve_attached = 0;
8132   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8133   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8134   mpls_label_t *next_hop_out_label_stack = NULL;
8135   mpls_label_t local_label = MPLS_LABEL_INVALID;
8136   u8 is_eos = 0;
8137   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8138
8139   /* Parse args required to build the message */
8140   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8141     {
8142       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8143         ;
8144       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8145         ;
8146       else if (unformat (i, "%d", &local_label))
8147         ;
8148       else if (unformat (i, "eos"))
8149         is_eos = 1;
8150       else if (unformat (i, "non-eos"))
8151         is_eos = 0;
8152       else if (unformat (i, "via %U", unformat_ip4_address,
8153                          &v4_next_hop_address))
8154         {
8155           next_hop_set = 1;
8156           next_hop_proto = DPO_PROTO_IP4;
8157         }
8158       else if (unformat (i, "via %U", unformat_ip6_address,
8159                          &v6_next_hop_address))
8160         {
8161           next_hop_set = 1;
8162           next_hop_proto = DPO_PROTO_IP6;
8163         }
8164       else if (unformat (i, "weight %d", &next_hop_weight))
8165         ;
8166       else if (unformat (i, "create-table"))
8167         create_table_if_needed = 1;
8168       else if (unformat (i, "classify %d", &classify_table_index))
8169         {
8170           is_classify = 1;
8171         }
8172       else if (unformat (i, "del"))
8173         is_add = 0;
8174       else if (unformat (i, "add"))
8175         is_add = 1;
8176       else if (unformat (i, "resolve-via-host"))
8177         resolve_host = 1;
8178       else if (unformat (i, "resolve-via-attached"))
8179         resolve_attached = 1;
8180       else if (unformat (i, "multipath"))
8181         is_multipath = 1;
8182       else if (unformat (i, "count %d", &count))
8183         ;
8184       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8185         {
8186           next_hop_set = 1;
8187           next_hop_proto = DPO_PROTO_IP4;
8188         }
8189       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8190         {
8191           next_hop_set = 1;
8192           next_hop_proto = DPO_PROTO_IP6;
8193         }
8194       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8195         ;
8196       else if (unformat (i, "via-label %d", &next_hop_via_label))
8197         ;
8198       else if (unformat (i, "out-label %d", &next_hop_out_label))
8199         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8200       else
8201         {
8202           clib_warning ("parse error '%U'", format_unformat_error, i);
8203           return -99;
8204         }
8205     }
8206
8207   if (!next_hop_set && !is_classify)
8208     {
8209       errmsg ("next hop / classify not set");
8210       return -99;
8211     }
8212
8213   if (MPLS_LABEL_INVALID == local_label)
8214     {
8215       errmsg ("missing label");
8216       return -99;
8217     }
8218
8219   if (count > 1)
8220     {
8221       /* Turn on async mode */
8222       vam->async_mode = 1;
8223       vam->async_errors = 0;
8224       before = vat_time_now (vam);
8225     }
8226
8227   for (j = 0; j < count; j++)
8228     {
8229       /* Construct the API message */
8230       M2 (MPLS_ROUTE_ADD_DEL, mp,
8231           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8232
8233       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8234       mp->mr_table_id = ntohl (table_id);
8235       mp->mr_create_table_if_needed = create_table_if_needed;
8236
8237       mp->mr_is_add = is_add;
8238       mp->mr_next_hop_proto = next_hop_proto;
8239       mp->mr_is_classify = is_classify;
8240       mp->mr_is_multipath = is_multipath;
8241       mp->mr_is_resolve_host = resolve_host;
8242       mp->mr_is_resolve_attached = resolve_attached;
8243       mp->mr_next_hop_weight = next_hop_weight;
8244       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8245       mp->mr_classify_table_index = ntohl (classify_table_index);
8246       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8247       mp->mr_label = ntohl (local_label);
8248       mp->mr_eos = is_eos;
8249
8250       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8251       if (0 != mp->mr_next_hop_n_out_labels)
8252         {
8253           memcpy (mp->mr_next_hop_out_label_stack,
8254                   next_hop_out_label_stack,
8255                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8256           vec_free (next_hop_out_label_stack);
8257         }
8258
8259       if (next_hop_set)
8260         {
8261           if (DPO_PROTO_IP4 == next_hop_proto)
8262             {
8263               clib_memcpy (mp->mr_next_hop,
8264                            &v4_next_hop_address,
8265                            sizeof (v4_next_hop_address));
8266             }
8267           else if (DPO_PROTO_IP6 == next_hop_proto)
8268
8269             {
8270               clib_memcpy (mp->mr_next_hop,
8271                            &v6_next_hop_address,
8272                            sizeof (v6_next_hop_address));
8273             }
8274         }
8275       local_label++;
8276
8277       /* send it... */
8278       S (mp);
8279       /* If we receive SIGTERM, stop now... */
8280       if (vam->do_exit)
8281         break;
8282     }
8283
8284   /* When testing multiple add/del ops, use a control-ping to sync */
8285   if (count > 1)
8286     {
8287       vl_api_control_ping_t *mp_ping;
8288       f64 after;
8289       f64 timeout;
8290
8291       /* Shut off async mode */
8292       vam->async_mode = 0;
8293
8294       MPING (CONTROL_PING, mp_ping);
8295       S (mp_ping);
8296
8297       timeout = vat_time_now (vam) + 1.0;
8298       while (vat_time_now (vam) < timeout)
8299         if (vam->result_ready == 1)
8300           goto out;
8301       vam->retval = -99;
8302
8303     out:
8304       if (vam->retval == -99)
8305         errmsg ("timeout");
8306
8307       if (vam->async_errors > 0)
8308         {
8309           errmsg ("%d asynchronous errors", vam->async_errors);
8310           vam->retval = -98;
8311         }
8312       vam->async_errors = 0;
8313       after = vat_time_now (vam);
8314
8315       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8316       if (j > 0)
8317         count = j;
8318
8319       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8320              count, after - before, count / (after - before));
8321     }
8322   else
8323     {
8324       int ret;
8325
8326       /* Wait for a reply... */
8327       W (ret);
8328       return ret;
8329     }
8330
8331   /* Return the good/bad news */
8332   return (vam->retval);
8333 }
8334
8335 static int
8336 api_mpls_ip_bind_unbind (vat_main_t * vam)
8337 {
8338   unformat_input_t *i = vam->input;
8339   vl_api_mpls_ip_bind_unbind_t *mp;
8340   u32 ip_table_id = 0;
8341   u8 create_table_if_needed = 0;
8342   u8 is_bind = 1;
8343   u8 is_ip4 = 1;
8344   ip4_address_t v4_address;
8345   ip6_address_t v6_address;
8346   u32 address_length;
8347   u8 address_set = 0;
8348   mpls_label_t local_label = MPLS_LABEL_INVALID;
8349   int ret;
8350
8351   /* Parse args required to build the message */
8352   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8353     {
8354       if (unformat (i, "%U/%d", unformat_ip4_address,
8355                     &v4_address, &address_length))
8356         {
8357           is_ip4 = 1;
8358           address_set = 1;
8359         }
8360       else if (unformat (i, "%U/%d", unformat_ip6_address,
8361                          &v6_address, &address_length))
8362         {
8363           is_ip4 = 0;
8364           address_set = 1;
8365         }
8366       else if (unformat (i, "%d", &local_label))
8367         ;
8368       else if (unformat (i, "create-table"))
8369         create_table_if_needed = 1;
8370       else if (unformat (i, "table-id %d", &ip_table_id))
8371         ;
8372       else if (unformat (i, "unbind"))
8373         is_bind = 0;
8374       else if (unformat (i, "bind"))
8375         is_bind = 1;
8376       else
8377         {
8378           clib_warning ("parse error '%U'", format_unformat_error, i);
8379           return -99;
8380         }
8381     }
8382
8383   if (!address_set)
8384     {
8385       errmsg ("IP addres not set");
8386       return -99;
8387     }
8388
8389   if (MPLS_LABEL_INVALID == local_label)
8390     {
8391       errmsg ("missing label");
8392       return -99;
8393     }
8394
8395   /* Construct the API message */
8396   M (MPLS_IP_BIND_UNBIND, mp);
8397
8398   mp->mb_create_table_if_needed = create_table_if_needed;
8399   mp->mb_is_bind = is_bind;
8400   mp->mb_is_ip4 = is_ip4;
8401   mp->mb_ip_table_id = ntohl (ip_table_id);
8402   mp->mb_mpls_table_id = 0;
8403   mp->mb_label = ntohl (local_label);
8404   mp->mb_address_length = address_length;
8405
8406   if (is_ip4)
8407     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8408   else
8409     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8410
8411   /* send it... */
8412   S (mp);
8413
8414   /* Wait for a reply... */
8415   W (ret);
8416   return ret;
8417 }
8418
8419 static int
8420 api_proxy_arp_add_del (vat_main_t * vam)
8421 {
8422   unformat_input_t *i = vam->input;
8423   vl_api_proxy_arp_add_del_t *mp;
8424   u32 vrf_id = 0;
8425   u8 is_add = 1;
8426   ip4_address_t lo, hi;
8427   u8 range_set = 0;
8428   int ret;
8429
8430   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8431     {
8432       if (unformat (i, "vrf %d", &vrf_id))
8433         ;
8434       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
8435                          unformat_ip4_address, &hi))
8436         range_set = 1;
8437       else if (unformat (i, "del"))
8438         is_add = 0;
8439       else
8440         {
8441           clib_warning ("parse error '%U'", format_unformat_error, i);
8442           return -99;
8443         }
8444     }
8445
8446   if (range_set == 0)
8447     {
8448       errmsg ("address range not set");
8449       return -99;
8450     }
8451
8452   M (PROXY_ARP_ADD_DEL, mp);
8453
8454   mp->vrf_id = ntohl (vrf_id);
8455   mp->is_add = is_add;
8456   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
8457   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
8458
8459   S (mp);
8460   W (ret);
8461   return ret;
8462 }
8463
8464 static int
8465 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8466 {
8467   unformat_input_t *i = vam->input;
8468   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8469   u32 sw_if_index;
8470   u8 enable = 1;
8471   u8 sw_if_index_set = 0;
8472   int ret;
8473
8474   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8475     {
8476       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8477         sw_if_index_set = 1;
8478       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8479         sw_if_index_set = 1;
8480       else if (unformat (i, "enable"))
8481         enable = 1;
8482       else if (unformat (i, "disable"))
8483         enable = 0;
8484       else
8485         {
8486           clib_warning ("parse error '%U'", format_unformat_error, i);
8487           return -99;
8488         }
8489     }
8490
8491   if (sw_if_index_set == 0)
8492     {
8493       errmsg ("missing interface name or sw_if_index");
8494       return -99;
8495     }
8496
8497   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8498
8499   mp->sw_if_index = ntohl (sw_if_index);
8500   mp->enable_disable = enable;
8501
8502   S (mp);
8503   W (ret);
8504   return ret;
8505 }
8506
8507 static int
8508 api_mpls_tunnel_add_del (vat_main_t * vam)
8509 {
8510   unformat_input_t *i = vam->input;
8511   vl_api_mpls_tunnel_add_del_t *mp;
8512
8513   u8 is_add = 1;
8514   u8 l2_only = 0;
8515   u32 sw_if_index = ~0;
8516   u32 next_hop_sw_if_index = ~0;
8517   u32 next_hop_proto_is_ip4 = 1;
8518
8519   u32 next_hop_table_id = 0;
8520   ip4_address_t v4_next_hop_address = {
8521     .as_u32 = 0,
8522   };
8523   ip6_address_t v6_next_hop_address = { {0} };
8524   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
8525   int ret;
8526
8527   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8528     {
8529       if (unformat (i, "add"))
8530         is_add = 1;
8531       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8532         is_add = 0;
8533       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
8534         ;
8535       else if (unformat (i, "via %U",
8536                          unformat_ip4_address, &v4_next_hop_address))
8537         {
8538           next_hop_proto_is_ip4 = 1;
8539         }
8540       else if (unformat (i, "via %U",
8541                          unformat_ip6_address, &v6_next_hop_address))
8542         {
8543           next_hop_proto_is_ip4 = 0;
8544         }
8545       else if (unformat (i, "l2-only"))
8546         l2_only = 1;
8547       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8548         ;
8549       else if (unformat (i, "out-label %d", &next_hop_out_label))
8550         vec_add1 (labels, ntohl (next_hop_out_label));
8551       else
8552         {
8553           clib_warning ("parse error '%U'", format_unformat_error, i);
8554           return -99;
8555         }
8556     }
8557
8558   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
8559
8560   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
8561   mp->mt_sw_if_index = ntohl (sw_if_index);
8562   mp->mt_is_add = is_add;
8563   mp->mt_l2_only = l2_only;
8564   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
8565   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
8566
8567   mp->mt_next_hop_n_out_labels = vec_len (labels);
8568
8569   if (0 != mp->mt_next_hop_n_out_labels)
8570     {
8571       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
8572                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
8573       vec_free (labels);
8574     }
8575
8576   if (next_hop_proto_is_ip4)
8577     {
8578       clib_memcpy (mp->mt_next_hop,
8579                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8580     }
8581   else
8582     {
8583       clib_memcpy (mp->mt_next_hop,
8584                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8585     }
8586
8587   S (mp);
8588   W (ret);
8589   return ret;
8590 }
8591
8592 static int
8593 api_sw_interface_set_unnumbered (vat_main_t * vam)
8594 {
8595   unformat_input_t *i = vam->input;
8596   vl_api_sw_interface_set_unnumbered_t *mp;
8597   u32 sw_if_index;
8598   u32 unnum_sw_index = ~0;
8599   u8 is_add = 1;
8600   u8 sw_if_index_set = 0;
8601   int ret;
8602
8603   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8604     {
8605       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8606         sw_if_index_set = 1;
8607       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8608         sw_if_index_set = 1;
8609       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8610         ;
8611       else if (unformat (i, "del"))
8612         is_add = 0;
8613       else
8614         {
8615           clib_warning ("parse error '%U'", format_unformat_error, i);
8616           return -99;
8617         }
8618     }
8619
8620   if (sw_if_index_set == 0)
8621     {
8622       errmsg ("missing interface name or sw_if_index");
8623       return -99;
8624     }
8625
8626   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8627
8628   mp->sw_if_index = ntohl (sw_if_index);
8629   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8630   mp->is_add = is_add;
8631
8632   S (mp);
8633   W (ret);
8634   return ret;
8635 }
8636
8637 static int
8638 api_ip_neighbor_add_del (vat_main_t * vam)
8639 {
8640   unformat_input_t *i = vam->input;
8641   vl_api_ip_neighbor_add_del_t *mp;
8642   u32 sw_if_index;
8643   u8 sw_if_index_set = 0;
8644   u8 is_add = 1;
8645   u8 is_static = 0;
8646   u8 is_no_fib_entry = 0;
8647   u8 mac_address[6];
8648   u8 mac_set = 0;
8649   u8 v4_address_set = 0;
8650   u8 v6_address_set = 0;
8651   ip4_address_t v4address;
8652   ip6_address_t v6address;
8653   int ret;
8654
8655   memset (mac_address, 0, sizeof (mac_address));
8656
8657   /* Parse args required to build the message */
8658   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8659     {
8660       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8661         {
8662           mac_set = 1;
8663         }
8664       else if (unformat (i, "del"))
8665         is_add = 0;
8666       else
8667         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8668         sw_if_index_set = 1;
8669       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8670         sw_if_index_set = 1;
8671       else if (unformat (i, "is_static"))
8672         is_static = 1;
8673       else if (unformat (i, "no-fib-entry"))
8674         is_no_fib_entry = 1;
8675       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
8676         v4_address_set = 1;
8677       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
8678         v6_address_set = 1;
8679       else
8680         {
8681           clib_warning ("parse error '%U'", format_unformat_error, i);
8682           return -99;
8683         }
8684     }
8685
8686   if (sw_if_index_set == 0)
8687     {
8688       errmsg ("missing interface name or sw_if_index");
8689       return -99;
8690     }
8691   if (v4_address_set && v6_address_set)
8692     {
8693       errmsg ("both v4 and v6 addresses set");
8694       return -99;
8695     }
8696   if (!v4_address_set && !v6_address_set)
8697     {
8698       errmsg ("no address set");
8699       return -99;
8700     }
8701
8702   /* Construct the API message */
8703   M (IP_NEIGHBOR_ADD_DEL, mp);
8704
8705   mp->sw_if_index = ntohl (sw_if_index);
8706   mp->is_add = is_add;
8707   mp->is_static = is_static;
8708   mp->is_no_adj_fib = is_no_fib_entry;
8709   if (mac_set)
8710     clib_memcpy (mp->mac_address, mac_address, 6);
8711   if (v6_address_set)
8712     {
8713       mp->is_ipv6 = 1;
8714       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
8715     }
8716   else
8717     {
8718       /* mp->is_ipv6 = 0; via memset in M macro above */
8719       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
8720     }
8721
8722   /* send it... */
8723   S (mp);
8724
8725   /* Wait for a reply, return good/bad news  */
8726   W (ret);
8727   return ret;
8728 }
8729
8730 static int
8731 api_reset_vrf (vat_main_t * vam)
8732 {
8733   unformat_input_t *i = vam->input;
8734   vl_api_reset_vrf_t *mp;
8735   u32 vrf_id = 0;
8736   u8 is_ipv6 = 0;
8737   u8 vrf_id_set = 0;
8738   int ret;
8739
8740   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8741     {
8742       if (unformat (i, "vrf %d", &vrf_id))
8743         vrf_id_set = 1;
8744       else if (unformat (i, "ipv6"))
8745         is_ipv6 = 1;
8746       else
8747         {
8748           clib_warning ("parse error '%U'", format_unformat_error, i);
8749           return -99;
8750         }
8751     }
8752
8753   if (vrf_id_set == 0)
8754     {
8755       errmsg ("missing vrf id");
8756       return -99;
8757     }
8758
8759   M (RESET_VRF, mp);
8760
8761   mp->vrf_id = ntohl (vrf_id);
8762   mp->is_ipv6 = is_ipv6;
8763
8764   S (mp);
8765   W (ret);
8766   return ret;
8767 }
8768
8769 static int
8770 api_create_vlan_subif (vat_main_t * vam)
8771 {
8772   unformat_input_t *i = vam->input;
8773   vl_api_create_vlan_subif_t *mp;
8774   u32 sw_if_index;
8775   u8 sw_if_index_set = 0;
8776   u32 vlan_id;
8777   u8 vlan_id_set = 0;
8778   int ret;
8779
8780   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8781     {
8782       if (unformat (i, "sw_if_index %d", &sw_if_index))
8783         sw_if_index_set = 1;
8784       else
8785         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8786         sw_if_index_set = 1;
8787       else if (unformat (i, "vlan %d", &vlan_id))
8788         vlan_id_set = 1;
8789       else
8790         {
8791           clib_warning ("parse error '%U'", format_unformat_error, i);
8792           return -99;
8793         }
8794     }
8795
8796   if (sw_if_index_set == 0)
8797     {
8798       errmsg ("missing interface name or sw_if_index");
8799       return -99;
8800     }
8801
8802   if (vlan_id_set == 0)
8803     {
8804       errmsg ("missing vlan_id");
8805       return -99;
8806     }
8807   M (CREATE_VLAN_SUBIF, mp);
8808
8809   mp->sw_if_index = ntohl (sw_if_index);
8810   mp->vlan_id = ntohl (vlan_id);
8811
8812   S (mp);
8813   W (ret);
8814   return ret;
8815 }
8816
8817 #define foreach_create_subif_bit                \
8818 _(no_tags)                                      \
8819 _(one_tag)                                      \
8820 _(two_tags)                                     \
8821 _(dot1ad)                                       \
8822 _(exact_match)                                  \
8823 _(default_sub)                                  \
8824 _(outer_vlan_id_any)                            \
8825 _(inner_vlan_id_any)
8826
8827 static int
8828 api_create_subif (vat_main_t * vam)
8829 {
8830   unformat_input_t *i = vam->input;
8831   vl_api_create_subif_t *mp;
8832   u32 sw_if_index;
8833   u8 sw_if_index_set = 0;
8834   u32 sub_id;
8835   u8 sub_id_set = 0;
8836   u32 no_tags = 0;
8837   u32 one_tag = 0;
8838   u32 two_tags = 0;
8839   u32 dot1ad = 0;
8840   u32 exact_match = 0;
8841   u32 default_sub = 0;
8842   u32 outer_vlan_id_any = 0;
8843   u32 inner_vlan_id_any = 0;
8844   u32 tmp;
8845   u16 outer_vlan_id = 0;
8846   u16 inner_vlan_id = 0;
8847   int ret;
8848
8849   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8850     {
8851       if (unformat (i, "sw_if_index %d", &sw_if_index))
8852         sw_if_index_set = 1;
8853       else
8854         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8855         sw_if_index_set = 1;
8856       else if (unformat (i, "sub_id %d", &sub_id))
8857         sub_id_set = 1;
8858       else if (unformat (i, "outer_vlan_id %d", &tmp))
8859         outer_vlan_id = tmp;
8860       else if (unformat (i, "inner_vlan_id %d", &tmp))
8861         inner_vlan_id = tmp;
8862
8863 #define _(a) else if (unformat (i, #a)) a = 1 ;
8864       foreach_create_subif_bit
8865 #undef _
8866         else
8867         {
8868           clib_warning ("parse error '%U'", format_unformat_error, i);
8869           return -99;
8870         }
8871     }
8872
8873   if (sw_if_index_set == 0)
8874     {
8875       errmsg ("missing interface name or sw_if_index");
8876       return -99;
8877     }
8878
8879   if (sub_id_set == 0)
8880     {
8881       errmsg ("missing sub_id");
8882       return -99;
8883     }
8884   M (CREATE_SUBIF, mp);
8885
8886   mp->sw_if_index = ntohl (sw_if_index);
8887   mp->sub_id = ntohl (sub_id);
8888
8889 #define _(a) mp->a = a;
8890   foreach_create_subif_bit;
8891 #undef _
8892
8893   mp->outer_vlan_id = ntohs (outer_vlan_id);
8894   mp->inner_vlan_id = ntohs (inner_vlan_id);
8895
8896   S (mp);
8897   W (ret);
8898   return ret;
8899 }
8900
8901 static int
8902 api_oam_add_del (vat_main_t * vam)
8903 {
8904   unformat_input_t *i = vam->input;
8905   vl_api_oam_add_del_t *mp;
8906   u32 vrf_id = 0;
8907   u8 is_add = 1;
8908   ip4_address_t src, dst;
8909   u8 src_set = 0;
8910   u8 dst_set = 0;
8911   int ret;
8912
8913   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8914     {
8915       if (unformat (i, "vrf %d", &vrf_id))
8916         ;
8917       else if (unformat (i, "src %U", unformat_ip4_address, &src))
8918         src_set = 1;
8919       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
8920         dst_set = 1;
8921       else if (unformat (i, "del"))
8922         is_add = 0;
8923       else
8924         {
8925           clib_warning ("parse error '%U'", format_unformat_error, i);
8926           return -99;
8927         }
8928     }
8929
8930   if (src_set == 0)
8931     {
8932       errmsg ("missing src addr");
8933       return -99;
8934     }
8935
8936   if (dst_set == 0)
8937     {
8938       errmsg ("missing dst addr");
8939       return -99;
8940     }
8941
8942   M (OAM_ADD_DEL, mp);
8943
8944   mp->vrf_id = ntohl (vrf_id);
8945   mp->is_add = is_add;
8946   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
8947   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
8948
8949   S (mp);
8950   W (ret);
8951   return ret;
8952 }
8953
8954 static int
8955 api_reset_fib (vat_main_t * vam)
8956 {
8957   unformat_input_t *i = vam->input;
8958   vl_api_reset_fib_t *mp;
8959   u32 vrf_id = 0;
8960   u8 is_ipv6 = 0;
8961   u8 vrf_id_set = 0;
8962
8963   int ret;
8964   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8965     {
8966       if (unformat (i, "vrf %d", &vrf_id))
8967         vrf_id_set = 1;
8968       else if (unformat (i, "ipv6"))
8969         is_ipv6 = 1;
8970       else
8971         {
8972           clib_warning ("parse error '%U'", format_unformat_error, i);
8973           return -99;
8974         }
8975     }
8976
8977   if (vrf_id_set == 0)
8978     {
8979       errmsg ("missing vrf id");
8980       return -99;
8981     }
8982
8983   M (RESET_FIB, mp);
8984
8985   mp->vrf_id = ntohl (vrf_id);
8986   mp->is_ipv6 = is_ipv6;
8987
8988   S (mp);
8989   W (ret);
8990   return ret;
8991 }
8992
8993 static int
8994 api_dhcp_proxy_config (vat_main_t * vam)
8995 {
8996   unformat_input_t *i = vam->input;
8997   vl_api_dhcp_proxy_config_t *mp;
8998   u32 rx_vrf_id = 0;
8999   u32 server_vrf_id = 0;
9000   u8 is_add = 1;
9001   u8 v4_address_set = 0;
9002   u8 v6_address_set = 0;
9003   ip4_address_t v4address;
9004   ip6_address_t v6address;
9005   u8 v4_src_address_set = 0;
9006   u8 v6_src_address_set = 0;
9007   ip4_address_t v4srcaddress;
9008   ip6_address_t v6srcaddress;
9009   int ret;
9010
9011   /* Parse args required to build the message */
9012   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9013     {
9014       if (unformat (i, "del"))
9015         is_add = 0;
9016       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
9017         ;
9018       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
9019         ;
9020       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
9021         v4_address_set = 1;
9022       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
9023         v6_address_set = 1;
9024       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
9025         v4_src_address_set = 1;
9026       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
9027         v6_src_address_set = 1;
9028       else
9029         break;
9030     }
9031
9032   if (v4_address_set && v6_address_set)
9033     {
9034       errmsg ("both v4 and v6 server addresses set");
9035       return -99;
9036     }
9037   if (!v4_address_set && !v6_address_set)
9038     {
9039       errmsg ("no server addresses set");
9040       return -99;
9041     }
9042
9043   if (v4_src_address_set && v6_src_address_set)
9044     {
9045       errmsg ("both v4 and v6  src addresses set");
9046       return -99;
9047     }
9048   if (!v4_src_address_set && !v6_src_address_set)
9049     {
9050       errmsg ("no src addresses set");
9051       return -99;
9052     }
9053
9054   if (!(v4_src_address_set && v4_address_set) &&
9055       !(v6_src_address_set && v6_address_set))
9056     {
9057       errmsg ("no matching server and src addresses set");
9058       return -99;
9059     }
9060
9061   /* Construct the API message */
9062   M (DHCP_PROXY_CONFIG, mp);
9063
9064   mp->is_add = is_add;
9065   mp->rx_vrf_id = ntohl (rx_vrf_id);
9066   mp->server_vrf_id = ntohl (server_vrf_id);
9067   if (v6_address_set)
9068     {
9069       mp->is_ipv6 = 1;
9070       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
9071       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
9072     }
9073   else
9074     {
9075       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
9076       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
9077     }
9078
9079   /* send it... */
9080   S (mp);
9081
9082   /* Wait for a reply, return good/bad news  */
9083   W (ret);
9084   return ret;
9085 }
9086
9087 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
9088 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
9089
9090 static void
9091 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9092 {
9093   vat_main_t *vam = &vat_main;
9094   u32 i, count = mp->count;
9095   vl_api_dhcp_server_t *s;
9096
9097   if (mp->is_ipv6)
9098     print (vam->ofp,
9099            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
9100            ntohl (mp->rx_vrf_id),
9101            format_ip6_address, mp->dhcp_src_address,
9102            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9103   else
9104     print (vam->ofp,
9105            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
9106            ntohl (mp->rx_vrf_id),
9107            format_ip4_address, mp->dhcp_src_address,
9108            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9109
9110   for (i = 0; i < count; i++)
9111     {
9112       s = &mp->servers[i];
9113
9114       if (mp->is_ipv6)
9115         print (vam->ofp,
9116                " Server Table-ID %d, Server Address %U",
9117                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9118       else
9119         print (vam->ofp,
9120                " Server Table-ID %d, Server Address %U",
9121                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9122     }
9123 }
9124
9125 static void vl_api_dhcp_proxy_details_t_handler_json
9126   (vl_api_dhcp_proxy_details_t * mp)
9127 {
9128   vat_main_t *vam = &vat_main;
9129   vat_json_node_t *node = NULL;
9130   u32 i, count = mp->count;
9131   struct in_addr ip4;
9132   struct in6_addr ip6;
9133   vl_api_dhcp_server_t *s;
9134
9135   if (VAT_JSON_ARRAY != vam->json_tree.type)
9136     {
9137       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9138       vat_json_init_array (&vam->json_tree);
9139     }
9140   node = vat_json_array_add (&vam->json_tree);
9141
9142   vat_json_init_object (node);
9143   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9144   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9145   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9146
9147   if (mp->is_ipv6)
9148     {
9149       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9150       vat_json_object_add_ip6 (node, "src_address", ip6);
9151     }
9152   else
9153     {
9154       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9155       vat_json_object_add_ip4 (node, "src_address", ip4);
9156     }
9157
9158   for (i = 0; i < count; i++)
9159     {
9160       s = &mp->servers[i];
9161
9162       vat_json_object_add_uint (node, "server-table-id",
9163                                 ntohl (s->server_vrf_id));
9164
9165       if (mp->is_ipv6)
9166         {
9167           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9168           vat_json_object_add_ip4 (node, "src_address", ip4);
9169         }
9170       else
9171         {
9172           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9173           vat_json_object_add_ip6 (node, "server_address", ip6);
9174         }
9175     }
9176 }
9177
9178 static int
9179 api_dhcp_proxy_dump (vat_main_t * vam)
9180 {
9181   unformat_input_t *i = vam->input;
9182   vl_api_control_ping_t *mp_ping;
9183   vl_api_dhcp_proxy_dump_t *mp;
9184   u8 is_ipv6 = 0;
9185   int ret;
9186
9187   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9188     {
9189       if (unformat (i, "ipv6"))
9190         is_ipv6 = 1;
9191       else
9192         {
9193           clib_warning ("parse error '%U'", format_unformat_error, i);
9194           return -99;
9195         }
9196     }
9197
9198   M (DHCP_PROXY_DUMP, mp);
9199
9200   mp->is_ip6 = is_ipv6;
9201   S (mp);
9202
9203   /* Use a control ping for synchronization */
9204   MPING (CONTROL_PING, mp_ping);
9205   S (mp_ping);
9206
9207   W (ret);
9208   return ret;
9209 }
9210
9211 static int
9212 api_dhcp_proxy_set_vss (vat_main_t * vam)
9213 {
9214   unformat_input_t *i = vam->input;
9215   vl_api_dhcp_proxy_set_vss_t *mp;
9216   u8 is_ipv6 = 0;
9217   u8 is_add = 1;
9218   u32 tbl_id;
9219   u8 tbl_id_set = 0;
9220   u32 oui;
9221   u8 oui_set = 0;
9222   u32 fib_id;
9223   u8 fib_id_set = 0;
9224   int ret;
9225
9226   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9227     {
9228       if (unformat (i, "tbl_id %d", &tbl_id))
9229         tbl_id_set = 1;
9230       if (unformat (i, "fib_id %d", &fib_id))
9231         fib_id_set = 1;
9232       if (unformat (i, "oui %d", &oui))
9233         oui_set = 1;
9234       else if (unformat (i, "ipv6"))
9235         is_ipv6 = 1;
9236       else if (unformat (i, "del"))
9237         is_add = 0;
9238       else
9239         {
9240           clib_warning ("parse error '%U'", format_unformat_error, i);
9241           return -99;
9242         }
9243     }
9244
9245   if (tbl_id_set == 0)
9246     {
9247       errmsg ("missing tbl id");
9248       return -99;
9249     }
9250
9251   if (fib_id_set == 0)
9252     {
9253       errmsg ("missing fib id");
9254       return -99;
9255     }
9256   if (oui_set == 0)
9257     {
9258       errmsg ("missing oui");
9259       return -99;
9260     }
9261
9262   M (DHCP_PROXY_SET_VSS, mp);
9263   mp->tbl_id = ntohl (tbl_id);
9264   mp->fib_id = ntohl (fib_id);
9265   mp->oui = ntohl (oui);
9266   mp->is_ipv6 = is_ipv6;
9267   mp->is_add = is_add;
9268
9269   S (mp);
9270   W (ret);
9271   return ret;
9272 }
9273
9274 static int
9275 api_dhcp_client_config (vat_main_t * vam)
9276 {
9277   unformat_input_t *i = vam->input;
9278   vl_api_dhcp_client_config_t *mp;
9279   u32 sw_if_index;
9280   u8 sw_if_index_set = 0;
9281   u8 is_add = 1;
9282   u8 *hostname = 0;
9283   u8 disable_event = 0;
9284   int ret;
9285
9286   /* Parse args required to build the message */
9287   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9288     {
9289       if (unformat (i, "del"))
9290         is_add = 0;
9291       else
9292         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9293         sw_if_index_set = 1;
9294       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9295         sw_if_index_set = 1;
9296       else if (unformat (i, "hostname %s", &hostname))
9297         ;
9298       else if (unformat (i, "disable_event"))
9299         disable_event = 1;
9300       else
9301         break;
9302     }
9303
9304   if (sw_if_index_set == 0)
9305     {
9306       errmsg ("missing interface name or sw_if_index");
9307       return -99;
9308     }
9309
9310   if (vec_len (hostname) > 63)
9311     {
9312       errmsg ("hostname too long");
9313     }
9314   vec_add1 (hostname, 0);
9315
9316   /* Construct the API message */
9317   M (DHCP_CLIENT_CONFIG, mp);
9318
9319   mp->sw_if_index = htonl (sw_if_index);
9320   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
9321   vec_free (hostname);
9322   mp->is_add = is_add;
9323   mp->want_dhcp_event = disable_event ? 0 : 1;
9324   mp->pid = htonl (getpid ());
9325
9326   /* send it... */
9327   S (mp);
9328
9329   /* Wait for a reply, return good/bad news  */
9330   W (ret);
9331   return ret;
9332 }
9333
9334 static int
9335 api_set_ip_flow_hash (vat_main_t * vam)
9336 {
9337   unformat_input_t *i = vam->input;
9338   vl_api_set_ip_flow_hash_t *mp;
9339   u32 vrf_id = 0;
9340   u8 is_ipv6 = 0;
9341   u8 vrf_id_set = 0;
9342   u8 src = 0;
9343   u8 dst = 0;
9344   u8 sport = 0;
9345   u8 dport = 0;
9346   u8 proto = 0;
9347   u8 reverse = 0;
9348   int ret;
9349
9350   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9351     {
9352       if (unformat (i, "vrf %d", &vrf_id))
9353         vrf_id_set = 1;
9354       else if (unformat (i, "ipv6"))
9355         is_ipv6 = 1;
9356       else if (unformat (i, "src"))
9357         src = 1;
9358       else if (unformat (i, "dst"))
9359         dst = 1;
9360       else if (unformat (i, "sport"))
9361         sport = 1;
9362       else if (unformat (i, "dport"))
9363         dport = 1;
9364       else if (unformat (i, "proto"))
9365         proto = 1;
9366       else if (unformat (i, "reverse"))
9367         reverse = 1;
9368
9369       else
9370         {
9371           clib_warning ("parse error '%U'", format_unformat_error, i);
9372           return -99;
9373         }
9374     }
9375
9376   if (vrf_id_set == 0)
9377     {
9378       errmsg ("missing vrf id");
9379       return -99;
9380     }
9381
9382   M (SET_IP_FLOW_HASH, mp);
9383   mp->src = src;
9384   mp->dst = dst;
9385   mp->sport = sport;
9386   mp->dport = dport;
9387   mp->proto = proto;
9388   mp->reverse = reverse;
9389   mp->vrf_id = ntohl (vrf_id);
9390   mp->is_ipv6 = is_ipv6;
9391
9392   S (mp);
9393   W (ret);
9394   return ret;
9395 }
9396
9397 static int
9398 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9399 {
9400   unformat_input_t *i = vam->input;
9401   vl_api_sw_interface_ip6_enable_disable_t *mp;
9402   u32 sw_if_index;
9403   u8 sw_if_index_set = 0;
9404   u8 enable = 0;
9405   int ret;
9406
9407   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9408     {
9409       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9410         sw_if_index_set = 1;
9411       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9412         sw_if_index_set = 1;
9413       else if (unformat (i, "enable"))
9414         enable = 1;
9415       else if (unformat (i, "disable"))
9416         enable = 0;
9417       else
9418         {
9419           clib_warning ("parse error '%U'", format_unformat_error, i);
9420           return -99;
9421         }
9422     }
9423
9424   if (sw_if_index_set == 0)
9425     {
9426       errmsg ("missing interface name or sw_if_index");
9427       return -99;
9428     }
9429
9430   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9431
9432   mp->sw_if_index = ntohl (sw_if_index);
9433   mp->enable = enable;
9434
9435   S (mp);
9436   W (ret);
9437   return ret;
9438 }
9439
9440 static int
9441 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
9442 {
9443   unformat_input_t *i = vam->input;
9444   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
9445   u32 sw_if_index;
9446   u8 sw_if_index_set = 0;
9447   u8 v6_address_set = 0;
9448   ip6_address_t v6address;
9449   int ret;
9450
9451   /* Parse args required to build the message */
9452   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9453     {
9454       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9455         sw_if_index_set = 1;
9456       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9457         sw_if_index_set = 1;
9458       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9459         v6_address_set = 1;
9460       else
9461         break;
9462     }
9463
9464   if (sw_if_index_set == 0)
9465     {
9466       errmsg ("missing interface name or sw_if_index");
9467       return -99;
9468     }
9469   if (!v6_address_set)
9470     {
9471       errmsg ("no address set");
9472       return -99;
9473     }
9474
9475   /* Construct the API message */
9476   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
9477
9478   mp->sw_if_index = ntohl (sw_if_index);
9479   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9480
9481   /* send it... */
9482   S (mp);
9483
9484   /* Wait for a reply, return good/bad news  */
9485   W (ret);
9486   return ret;
9487 }
9488
9489 static int
9490 api_ip6nd_proxy_add_del (vat_main_t * vam)
9491 {
9492   unformat_input_t *i = vam->input;
9493   vl_api_ip6nd_proxy_add_del_t *mp;
9494   u32 sw_if_index = ~0;
9495   u8 v6_address_set = 0;
9496   ip6_address_t v6address;
9497   u8 is_del = 0;
9498   int ret;
9499
9500   /* Parse args required to build the message */
9501   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9502     {
9503       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9504         ;
9505       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9506         ;
9507       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9508         v6_address_set = 1;
9509       if (unformat (i, "del"))
9510         is_del = 1;
9511       else
9512         {
9513           clib_warning ("parse error '%U'", format_unformat_error, i);
9514           return -99;
9515         }
9516     }
9517
9518   if (sw_if_index == ~0)
9519     {
9520       errmsg ("missing interface name or sw_if_index");
9521       return -99;
9522     }
9523   if (!v6_address_set)
9524     {
9525       errmsg ("no address set");
9526       return -99;
9527     }
9528
9529   /* Construct the API message */
9530   M (IP6ND_PROXY_ADD_DEL, mp);
9531
9532   mp->is_del = is_del;
9533   mp->sw_if_index = ntohl (sw_if_index);
9534   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9535
9536   /* send it... */
9537   S (mp);
9538
9539   /* Wait for a reply, return good/bad news  */
9540   W (ret);
9541   return ret;
9542 }
9543
9544 static int
9545 api_ip6nd_proxy_dump (vat_main_t * vam)
9546 {
9547   vl_api_ip6nd_proxy_dump_t *mp;
9548   vl_api_control_ping_t *mp_ping;
9549   int ret;
9550
9551   M (IP6ND_PROXY_DUMP, mp);
9552
9553   S (mp);
9554
9555   /* Use a control ping for synchronization */
9556   MPING (CONTROL_PING, mp_ping);
9557   S (mp_ping);
9558
9559   W (ret);
9560   return ret;
9561 }
9562
9563 static void vl_api_ip6nd_proxy_details_t_handler
9564   (vl_api_ip6nd_proxy_details_t * mp)
9565 {
9566   vat_main_t *vam = &vat_main;
9567
9568   print (vam->ofp, "host %U sw_if_index %d",
9569          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
9570 }
9571
9572 static void vl_api_ip6nd_proxy_details_t_handler_json
9573   (vl_api_ip6nd_proxy_details_t * mp)
9574 {
9575   vat_main_t *vam = &vat_main;
9576   struct in6_addr ip6;
9577   vat_json_node_t *node = NULL;
9578
9579   if (VAT_JSON_ARRAY != vam->json_tree.type)
9580     {
9581       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9582       vat_json_init_array (&vam->json_tree);
9583     }
9584   node = vat_json_array_add (&vam->json_tree);
9585
9586   vat_json_init_object (node);
9587   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9588
9589   clib_memcpy (&ip6, mp->address, sizeof (ip6));
9590   vat_json_object_add_ip6 (node, "host", ip6);
9591 }
9592
9593 static int
9594 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9595 {
9596   unformat_input_t *i = vam->input;
9597   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9598   u32 sw_if_index;
9599   u8 sw_if_index_set = 0;
9600   u32 address_length = 0;
9601   u8 v6_address_set = 0;
9602   ip6_address_t v6address;
9603   u8 use_default = 0;
9604   u8 no_advertise = 0;
9605   u8 off_link = 0;
9606   u8 no_autoconfig = 0;
9607   u8 no_onlink = 0;
9608   u8 is_no = 0;
9609   u32 val_lifetime = 0;
9610   u32 pref_lifetime = 0;
9611   int ret;
9612
9613   /* Parse args required to build the message */
9614   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9615     {
9616       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9617         sw_if_index_set = 1;
9618       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9619         sw_if_index_set = 1;
9620       else if (unformat (i, "%U/%d",
9621                          unformat_ip6_address, &v6address, &address_length))
9622         v6_address_set = 1;
9623       else if (unformat (i, "val_life %d", &val_lifetime))
9624         ;
9625       else if (unformat (i, "pref_life %d", &pref_lifetime))
9626         ;
9627       else if (unformat (i, "def"))
9628         use_default = 1;
9629       else if (unformat (i, "noadv"))
9630         no_advertise = 1;
9631       else if (unformat (i, "offl"))
9632         off_link = 1;
9633       else if (unformat (i, "noauto"))
9634         no_autoconfig = 1;
9635       else if (unformat (i, "nolink"))
9636         no_onlink = 1;
9637       else if (unformat (i, "isno"))
9638         is_no = 1;
9639       else
9640         {
9641           clib_warning ("parse error '%U'", format_unformat_error, i);
9642           return -99;
9643         }
9644     }
9645
9646   if (sw_if_index_set == 0)
9647     {
9648       errmsg ("missing interface name or sw_if_index");
9649       return -99;
9650     }
9651   if (!v6_address_set)
9652     {
9653       errmsg ("no address set");
9654       return -99;
9655     }
9656
9657   /* Construct the API message */
9658   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9659
9660   mp->sw_if_index = ntohl (sw_if_index);
9661   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9662   mp->address_length = address_length;
9663   mp->use_default = use_default;
9664   mp->no_advertise = no_advertise;
9665   mp->off_link = off_link;
9666   mp->no_autoconfig = no_autoconfig;
9667   mp->no_onlink = no_onlink;
9668   mp->is_no = is_no;
9669   mp->val_lifetime = ntohl (val_lifetime);
9670   mp->pref_lifetime = ntohl (pref_lifetime);
9671
9672   /* send it... */
9673   S (mp);
9674
9675   /* Wait for a reply, return good/bad news  */
9676   W (ret);
9677   return ret;
9678 }
9679
9680 static int
9681 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9682 {
9683   unformat_input_t *i = vam->input;
9684   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9685   u32 sw_if_index;
9686   u8 sw_if_index_set = 0;
9687   u8 suppress = 0;
9688   u8 managed = 0;
9689   u8 other = 0;
9690   u8 ll_option = 0;
9691   u8 send_unicast = 0;
9692   u8 cease = 0;
9693   u8 is_no = 0;
9694   u8 default_router = 0;
9695   u32 max_interval = 0;
9696   u32 min_interval = 0;
9697   u32 lifetime = 0;
9698   u32 initial_count = 0;
9699   u32 initial_interval = 0;
9700   int ret;
9701
9702
9703   /* Parse args required to build the message */
9704   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9705     {
9706       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9707         sw_if_index_set = 1;
9708       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9709         sw_if_index_set = 1;
9710       else if (unformat (i, "maxint %d", &max_interval))
9711         ;
9712       else if (unformat (i, "minint %d", &min_interval))
9713         ;
9714       else if (unformat (i, "life %d", &lifetime))
9715         ;
9716       else if (unformat (i, "count %d", &initial_count))
9717         ;
9718       else if (unformat (i, "interval %d", &initial_interval))
9719         ;
9720       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9721         suppress = 1;
9722       else if (unformat (i, "managed"))
9723         managed = 1;
9724       else if (unformat (i, "other"))
9725         other = 1;
9726       else if (unformat (i, "ll"))
9727         ll_option = 1;
9728       else if (unformat (i, "send"))
9729         send_unicast = 1;
9730       else if (unformat (i, "cease"))
9731         cease = 1;
9732       else if (unformat (i, "isno"))
9733         is_no = 1;
9734       else if (unformat (i, "def"))
9735         default_router = 1;
9736       else
9737         {
9738           clib_warning ("parse error '%U'", format_unformat_error, i);
9739           return -99;
9740         }
9741     }
9742
9743   if (sw_if_index_set == 0)
9744     {
9745       errmsg ("missing interface name or sw_if_index");
9746       return -99;
9747     }
9748
9749   /* Construct the API message */
9750   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9751
9752   mp->sw_if_index = ntohl (sw_if_index);
9753   mp->max_interval = ntohl (max_interval);
9754   mp->min_interval = ntohl (min_interval);
9755   mp->lifetime = ntohl (lifetime);
9756   mp->initial_count = ntohl (initial_count);
9757   mp->initial_interval = ntohl (initial_interval);
9758   mp->suppress = suppress;
9759   mp->managed = managed;
9760   mp->other = other;
9761   mp->ll_option = ll_option;
9762   mp->send_unicast = send_unicast;
9763   mp->cease = cease;
9764   mp->is_no = is_no;
9765   mp->default_router = default_router;
9766
9767   /* send it... */
9768   S (mp);
9769
9770   /* Wait for a reply, return good/bad news  */
9771   W (ret);
9772   return ret;
9773 }
9774
9775 static int
9776 api_set_arp_neighbor_limit (vat_main_t * vam)
9777 {
9778   unformat_input_t *i = vam->input;
9779   vl_api_set_arp_neighbor_limit_t *mp;
9780   u32 arp_nbr_limit;
9781   u8 limit_set = 0;
9782   u8 is_ipv6 = 0;
9783   int ret;
9784
9785   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9786     {
9787       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
9788         limit_set = 1;
9789       else if (unformat (i, "ipv6"))
9790         is_ipv6 = 1;
9791       else
9792         {
9793           clib_warning ("parse error '%U'", format_unformat_error, i);
9794           return -99;
9795         }
9796     }
9797
9798   if (limit_set == 0)
9799     {
9800       errmsg ("missing limit value");
9801       return -99;
9802     }
9803
9804   M (SET_ARP_NEIGHBOR_LIMIT, mp);
9805
9806   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
9807   mp->is_ipv6 = is_ipv6;
9808
9809   S (mp);
9810   W (ret);
9811   return ret;
9812 }
9813
9814 static int
9815 api_l2_patch_add_del (vat_main_t * vam)
9816 {
9817   unformat_input_t *i = vam->input;
9818   vl_api_l2_patch_add_del_t *mp;
9819   u32 rx_sw_if_index;
9820   u8 rx_sw_if_index_set = 0;
9821   u32 tx_sw_if_index;
9822   u8 tx_sw_if_index_set = 0;
9823   u8 is_add = 1;
9824   int ret;
9825
9826   /* Parse args required to build the message */
9827   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9828     {
9829       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9830         rx_sw_if_index_set = 1;
9831       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9832         tx_sw_if_index_set = 1;
9833       else if (unformat (i, "rx"))
9834         {
9835           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9836             {
9837               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9838                             &rx_sw_if_index))
9839                 rx_sw_if_index_set = 1;
9840             }
9841           else
9842             break;
9843         }
9844       else if (unformat (i, "tx"))
9845         {
9846           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9847             {
9848               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9849                             &tx_sw_if_index))
9850                 tx_sw_if_index_set = 1;
9851             }
9852           else
9853             break;
9854         }
9855       else if (unformat (i, "del"))
9856         is_add = 0;
9857       else
9858         break;
9859     }
9860
9861   if (rx_sw_if_index_set == 0)
9862     {
9863       errmsg ("missing rx interface name or rx_sw_if_index");
9864       return -99;
9865     }
9866
9867   if (tx_sw_if_index_set == 0)
9868     {
9869       errmsg ("missing tx interface name or tx_sw_if_index");
9870       return -99;
9871     }
9872
9873   M (L2_PATCH_ADD_DEL, mp);
9874
9875   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9876   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9877   mp->is_add = is_add;
9878
9879   S (mp);
9880   W (ret);
9881   return ret;
9882 }
9883
9884 u8 is_del;
9885 u8 localsid_addr[16];
9886 u8 end_psp;
9887 u8 behavior;
9888 u32 sw_if_index;
9889 u32 vlan_index;
9890 u32 fib_table;
9891 u8 nh_addr[16];
9892
9893 static int
9894 api_sr_localsid_add_del (vat_main_t * vam)
9895 {
9896   unformat_input_t *i = vam->input;
9897   vl_api_sr_localsid_add_del_t *mp;
9898
9899   u8 is_del;
9900   ip6_address_t localsid;
9901   u8 end_psp = 0;
9902   u8 behavior = ~0;
9903   u32 sw_if_index;
9904   u32 fib_table = ~(u32) 0;
9905   ip6_address_t next_hop;
9906
9907   bool nexthop_set = 0;
9908
9909   int ret;
9910
9911   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9912     {
9913       if (unformat (i, "del"))
9914         is_del = 1;
9915       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9916       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
9917         nexthop_set = 1;
9918       else if (unformat (i, "behavior %u", &behavior));
9919       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9920       else if (unformat (i, "fib-table %u", &fib_table));
9921       else if (unformat (i, "end.psp %u", &behavior));
9922       else
9923         break;
9924     }
9925
9926   M (SR_LOCALSID_ADD_DEL, mp);
9927
9928   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
9929   if (nexthop_set)
9930     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
9931   mp->behavior = behavior;
9932   mp->sw_if_index = ntohl (sw_if_index);
9933   mp->fib_table = ntohl (fib_table);
9934   mp->end_psp = end_psp;
9935   mp->is_del = is_del;
9936
9937   S (mp);
9938   W (ret);
9939   return ret;
9940 }
9941
9942 static int
9943 api_ioam_enable (vat_main_t * vam)
9944 {
9945   unformat_input_t *input = vam->input;
9946   vl_api_ioam_enable_t *mp;
9947   u32 id = 0;
9948   int has_trace_option = 0;
9949   int has_pot_option = 0;
9950   int has_seqno_option = 0;
9951   int has_analyse_option = 0;
9952   int ret;
9953
9954   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9955     {
9956       if (unformat (input, "trace"))
9957         has_trace_option = 1;
9958       else if (unformat (input, "pot"))
9959         has_pot_option = 1;
9960       else if (unformat (input, "seqno"))
9961         has_seqno_option = 1;
9962       else if (unformat (input, "analyse"))
9963         has_analyse_option = 1;
9964       else
9965         break;
9966     }
9967   M (IOAM_ENABLE, mp);
9968   mp->id = htons (id);
9969   mp->seqno = has_seqno_option;
9970   mp->analyse = has_analyse_option;
9971   mp->pot_enable = has_pot_option;
9972   mp->trace_enable = has_trace_option;
9973
9974   S (mp);
9975   W (ret);
9976   return ret;
9977 }
9978
9979
9980 static int
9981 api_ioam_disable (vat_main_t * vam)
9982 {
9983   vl_api_ioam_disable_t *mp;
9984   int ret;
9985
9986   M (IOAM_DISABLE, mp);
9987   S (mp);
9988   W (ret);
9989   return ret;
9990 }
9991
9992 #define foreach_tcp_proto_field                 \
9993 _(src_port)                                     \
9994 _(dst_port)
9995
9996 #define foreach_udp_proto_field                 \
9997 _(src_port)                                     \
9998 _(dst_port)
9999
10000 #define foreach_ip4_proto_field                 \
10001 _(src_address)                                  \
10002 _(dst_address)                                  \
10003 _(tos)                                          \
10004 _(length)                                       \
10005 _(fragment_id)                                  \
10006 _(ttl)                                          \
10007 _(protocol)                                     \
10008 _(checksum)
10009
10010 typedef struct
10011 {
10012   u16 src_port, dst_port;
10013 } tcpudp_header_t;
10014
10015 #if VPP_API_TEST_BUILTIN == 0
10016 uword
10017 unformat_tcp_mask (unformat_input_t * input, va_list * args)
10018 {
10019   u8 **maskp = va_arg (*args, u8 **);
10020   u8 *mask = 0;
10021   u8 found_something = 0;
10022   tcp_header_t *tcp;
10023
10024 #define _(a) u8 a=0;
10025   foreach_tcp_proto_field;
10026 #undef _
10027
10028   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10029     {
10030       if (0);
10031 #define _(a) else if (unformat (input, #a)) a=1;
10032       foreach_tcp_proto_field
10033 #undef _
10034         else
10035         break;
10036     }
10037
10038 #define _(a) found_something += a;
10039   foreach_tcp_proto_field;
10040 #undef _
10041
10042   if (found_something == 0)
10043     return 0;
10044
10045   vec_validate (mask, sizeof (*tcp) - 1);
10046
10047   tcp = (tcp_header_t *) mask;
10048
10049 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
10050   foreach_tcp_proto_field;
10051 #undef _
10052
10053   *maskp = mask;
10054   return 1;
10055 }
10056
10057 uword
10058 unformat_udp_mask (unformat_input_t * input, va_list * args)
10059 {
10060   u8 **maskp = va_arg (*args, u8 **);
10061   u8 *mask = 0;
10062   u8 found_something = 0;
10063   udp_header_t *udp;
10064
10065 #define _(a) u8 a=0;
10066   foreach_udp_proto_field;
10067 #undef _
10068
10069   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10070     {
10071       if (0);
10072 #define _(a) else if (unformat (input, #a)) a=1;
10073       foreach_udp_proto_field
10074 #undef _
10075         else
10076         break;
10077     }
10078
10079 #define _(a) found_something += a;
10080   foreach_udp_proto_field;
10081 #undef _
10082
10083   if (found_something == 0)
10084     return 0;
10085
10086   vec_validate (mask, sizeof (*udp) - 1);
10087
10088   udp = (udp_header_t *) mask;
10089
10090 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
10091   foreach_udp_proto_field;
10092 #undef _
10093
10094   *maskp = mask;
10095   return 1;
10096 }
10097
10098 uword
10099 unformat_l4_mask (unformat_input_t * input, va_list * args)
10100 {
10101   u8 **maskp = va_arg (*args, u8 **);
10102   u16 src_port = 0, dst_port = 0;
10103   tcpudp_header_t *tcpudp;
10104
10105   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10106     {
10107       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10108         return 1;
10109       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10110         return 1;
10111       else if (unformat (input, "src_port"))
10112         src_port = 0xFFFF;
10113       else if (unformat (input, "dst_port"))
10114         dst_port = 0xFFFF;
10115       else
10116         return 0;
10117     }
10118
10119   if (!src_port && !dst_port)
10120     return 0;
10121
10122   u8 *mask = 0;
10123   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10124
10125   tcpudp = (tcpudp_header_t *) mask;
10126   tcpudp->src_port = src_port;
10127   tcpudp->dst_port = dst_port;
10128
10129   *maskp = mask;
10130
10131   return 1;
10132 }
10133
10134 uword
10135 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10136 {
10137   u8 **maskp = va_arg (*args, u8 **);
10138   u8 *mask = 0;
10139   u8 found_something = 0;
10140   ip4_header_t *ip;
10141
10142 #define _(a) u8 a=0;
10143   foreach_ip4_proto_field;
10144 #undef _
10145   u8 version = 0;
10146   u8 hdr_length = 0;
10147
10148
10149   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10150     {
10151       if (unformat (input, "version"))
10152         version = 1;
10153       else if (unformat (input, "hdr_length"))
10154         hdr_length = 1;
10155       else if (unformat (input, "src"))
10156         src_address = 1;
10157       else if (unformat (input, "dst"))
10158         dst_address = 1;
10159       else if (unformat (input, "proto"))
10160         protocol = 1;
10161
10162 #define _(a) else if (unformat (input, #a)) a=1;
10163       foreach_ip4_proto_field
10164 #undef _
10165         else
10166         break;
10167     }
10168
10169 #define _(a) found_something += a;
10170   foreach_ip4_proto_field;
10171 #undef _
10172
10173   if (found_something == 0)
10174     return 0;
10175
10176   vec_validate (mask, sizeof (*ip) - 1);
10177
10178   ip = (ip4_header_t *) mask;
10179
10180 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10181   foreach_ip4_proto_field;
10182 #undef _
10183
10184   ip->ip_version_and_header_length = 0;
10185
10186   if (version)
10187     ip->ip_version_and_header_length |= 0xF0;
10188
10189   if (hdr_length)
10190     ip->ip_version_and_header_length |= 0x0F;
10191
10192   *maskp = mask;
10193   return 1;
10194 }
10195
10196 #define foreach_ip6_proto_field                 \
10197 _(src_address)                                  \
10198 _(dst_address)                                  \
10199 _(payload_length)                               \
10200 _(hop_limit)                                    \
10201 _(protocol)
10202
10203 uword
10204 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10205 {
10206   u8 **maskp = va_arg (*args, u8 **);
10207   u8 *mask = 0;
10208   u8 found_something = 0;
10209   ip6_header_t *ip;
10210   u32 ip_version_traffic_class_and_flow_label;
10211
10212 #define _(a) u8 a=0;
10213   foreach_ip6_proto_field;
10214 #undef _
10215   u8 version = 0;
10216   u8 traffic_class = 0;
10217   u8 flow_label = 0;
10218
10219   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10220     {
10221       if (unformat (input, "version"))
10222         version = 1;
10223       else if (unformat (input, "traffic-class"))
10224         traffic_class = 1;
10225       else if (unformat (input, "flow-label"))
10226         flow_label = 1;
10227       else if (unformat (input, "src"))
10228         src_address = 1;
10229       else if (unformat (input, "dst"))
10230         dst_address = 1;
10231       else if (unformat (input, "proto"))
10232         protocol = 1;
10233
10234 #define _(a) else if (unformat (input, #a)) a=1;
10235       foreach_ip6_proto_field
10236 #undef _
10237         else
10238         break;
10239     }
10240
10241 #define _(a) found_something += a;
10242   foreach_ip6_proto_field;
10243 #undef _
10244
10245   if (found_something == 0)
10246     return 0;
10247
10248   vec_validate (mask, sizeof (*ip) - 1);
10249
10250   ip = (ip6_header_t *) mask;
10251
10252 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10253   foreach_ip6_proto_field;
10254 #undef _
10255
10256   ip_version_traffic_class_and_flow_label = 0;
10257
10258   if (version)
10259     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10260
10261   if (traffic_class)
10262     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10263
10264   if (flow_label)
10265     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10266
10267   ip->ip_version_traffic_class_and_flow_label =
10268     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10269
10270   *maskp = mask;
10271   return 1;
10272 }
10273
10274 uword
10275 unformat_l3_mask (unformat_input_t * input, va_list * args)
10276 {
10277   u8 **maskp = va_arg (*args, u8 **);
10278
10279   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10280     {
10281       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10282         return 1;
10283       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10284         return 1;
10285       else
10286         break;
10287     }
10288   return 0;
10289 }
10290
10291 uword
10292 unformat_l2_mask (unformat_input_t * input, va_list * args)
10293 {
10294   u8 **maskp = va_arg (*args, u8 **);
10295   u8 *mask = 0;
10296   u8 src = 0;
10297   u8 dst = 0;
10298   u8 proto = 0;
10299   u8 tag1 = 0;
10300   u8 tag2 = 0;
10301   u8 ignore_tag1 = 0;
10302   u8 ignore_tag2 = 0;
10303   u8 cos1 = 0;
10304   u8 cos2 = 0;
10305   u8 dot1q = 0;
10306   u8 dot1ad = 0;
10307   int len = 14;
10308
10309   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10310     {
10311       if (unformat (input, "src"))
10312         src = 1;
10313       else if (unformat (input, "dst"))
10314         dst = 1;
10315       else if (unformat (input, "proto"))
10316         proto = 1;
10317       else if (unformat (input, "tag1"))
10318         tag1 = 1;
10319       else if (unformat (input, "tag2"))
10320         tag2 = 1;
10321       else if (unformat (input, "ignore-tag1"))
10322         ignore_tag1 = 1;
10323       else if (unformat (input, "ignore-tag2"))
10324         ignore_tag2 = 1;
10325       else if (unformat (input, "cos1"))
10326         cos1 = 1;
10327       else if (unformat (input, "cos2"))
10328         cos2 = 1;
10329       else if (unformat (input, "dot1q"))
10330         dot1q = 1;
10331       else if (unformat (input, "dot1ad"))
10332         dot1ad = 1;
10333       else
10334         break;
10335     }
10336   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10337        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10338     return 0;
10339
10340   if (tag1 || ignore_tag1 || cos1 || dot1q)
10341     len = 18;
10342   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10343     len = 22;
10344
10345   vec_validate (mask, len - 1);
10346
10347   if (dst)
10348     memset (mask, 0xff, 6);
10349
10350   if (src)
10351     memset (mask + 6, 0xff, 6);
10352
10353   if (tag2 || dot1ad)
10354     {
10355       /* inner vlan tag */
10356       if (tag2)
10357         {
10358           mask[19] = 0xff;
10359           mask[18] = 0x0f;
10360         }
10361       if (cos2)
10362         mask[18] |= 0xe0;
10363       if (proto)
10364         mask[21] = mask[20] = 0xff;
10365       if (tag1)
10366         {
10367           mask[15] = 0xff;
10368           mask[14] = 0x0f;
10369         }
10370       if (cos1)
10371         mask[14] |= 0xe0;
10372       *maskp = mask;
10373       return 1;
10374     }
10375   if (tag1 | dot1q)
10376     {
10377       if (tag1)
10378         {
10379           mask[15] = 0xff;
10380           mask[14] = 0x0f;
10381         }
10382       if (cos1)
10383         mask[14] |= 0xe0;
10384       if (proto)
10385         mask[16] = mask[17] = 0xff;
10386
10387       *maskp = mask;
10388       return 1;
10389     }
10390   if (cos2)
10391     mask[18] |= 0xe0;
10392   if (cos1)
10393     mask[14] |= 0xe0;
10394   if (proto)
10395     mask[12] = mask[13] = 0xff;
10396
10397   *maskp = mask;
10398   return 1;
10399 }
10400
10401 uword
10402 unformat_classify_mask (unformat_input_t * input, va_list * args)
10403 {
10404   u8 **maskp = va_arg (*args, u8 **);
10405   u32 *skipp = va_arg (*args, u32 *);
10406   u32 *matchp = va_arg (*args, u32 *);
10407   u32 match;
10408   u8 *mask = 0;
10409   u8 *l2 = 0;
10410   u8 *l3 = 0;
10411   u8 *l4 = 0;
10412   int i;
10413
10414   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10415     {
10416       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10417         ;
10418       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10419         ;
10420       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10421         ;
10422       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10423         ;
10424       else
10425         break;
10426     }
10427
10428   if (l4 && !l3)
10429     {
10430       vec_free (mask);
10431       vec_free (l2);
10432       vec_free (l4);
10433       return 0;
10434     }
10435
10436   if (mask || l2 || l3 || l4)
10437     {
10438       if (l2 || l3 || l4)
10439         {
10440           /* "With a free Ethernet header in every package" */
10441           if (l2 == 0)
10442             vec_validate (l2, 13);
10443           mask = l2;
10444           if (vec_len (l3))
10445             {
10446               vec_append (mask, l3);
10447               vec_free (l3);
10448             }
10449           if (vec_len (l4))
10450             {
10451               vec_append (mask, l4);
10452               vec_free (l4);
10453             }
10454         }
10455
10456       /* Scan forward looking for the first significant mask octet */
10457       for (i = 0; i < vec_len (mask); i++)
10458         if (mask[i])
10459           break;
10460
10461       /* compute (skip, match) params */
10462       *skipp = i / sizeof (u32x4);
10463       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10464
10465       /* Pad mask to an even multiple of the vector size */
10466       while (vec_len (mask) % sizeof (u32x4))
10467         vec_add1 (mask, 0);
10468
10469       match = vec_len (mask) / sizeof (u32x4);
10470
10471       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10472         {
10473           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10474           if (*tmp || *(tmp + 1))
10475             break;
10476           match--;
10477         }
10478       if (match == 0)
10479         clib_warning ("BUG: match 0");
10480
10481       _vec_len (mask) = match * sizeof (u32x4);
10482
10483       *matchp = match;
10484       *maskp = mask;
10485
10486       return 1;
10487     }
10488
10489   return 0;
10490 }
10491 #endif /* VPP_API_TEST_BUILTIN */
10492
10493 #define foreach_l2_next                         \
10494 _(drop, DROP)                                   \
10495 _(ethernet, ETHERNET_INPUT)                     \
10496 _(ip4, IP4_INPUT)                               \
10497 _(ip6, IP6_INPUT)
10498
10499 uword
10500 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10501 {
10502   u32 *miss_next_indexp = va_arg (*args, u32 *);
10503   u32 next_index = 0;
10504   u32 tmp;
10505
10506 #define _(n,N) \
10507   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10508   foreach_l2_next;
10509 #undef _
10510
10511   if (unformat (input, "%d", &tmp))
10512     {
10513       next_index = tmp;
10514       goto out;
10515     }
10516
10517   return 0;
10518
10519 out:
10520   *miss_next_indexp = next_index;
10521   return 1;
10522 }
10523
10524 #define foreach_ip_next                         \
10525 _(drop, DROP)                                   \
10526 _(local, LOCAL)                                 \
10527 _(rewrite, REWRITE)
10528
10529 uword
10530 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10531 {
10532   u32 *miss_next_indexp = va_arg (*args, u32 *);
10533   u32 next_index = 0;
10534   u32 tmp;
10535
10536 #define _(n,N) \
10537   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10538   foreach_ip_next;
10539 #undef _
10540
10541   if (unformat (input, "%d", &tmp))
10542     {
10543       next_index = tmp;
10544       goto out;
10545     }
10546
10547   return 0;
10548
10549 out:
10550   *miss_next_indexp = next_index;
10551   return 1;
10552 }
10553
10554 #define foreach_acl_next                        \
10555 _(deny, DENY)
10556
10557 uword
10558 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10559 {
10560   u32 *miss_next_indexp = va_arg (*args, u32 *);
10561   u32 next_index = 0;
10562   u32 tmp;
10563
10564 #define _(n,N) \
10565   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10566   foreach_acl_next;
10567 #undef _
10568
10569   if (unformat (input, "permit"))
10570     {
10571       next_index = ~0;
10572       goto out;
10573     }
10574   else if (unformat (input, "%d", &tmp))
10575     {
10576       next_index = tmp;
10577       goto out;
10578     }
10579
10580   return 0;
10581
10582 out:
10583   *miss_next_indexp = next_index;
10584   return 1;
10585 }
10586
10587 uword
10588 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10589 {
10590   u32 *r = va_arg (*args, u32 *);
10591
10592   if (unformat (input, "conform-color"))
10593     *r = POLICE_CONFORM;
10594   else if (unformat (input, "exceed-color"))
10595     *r = POLICE_EXCEED;
10596   else
10597     return 0;
10598
10599   return 1;
10600 }
10601
10602 static int
10603 api_classify_add_del_table (vat_main_t * vam)
10604 {
10605   unformat_input_t *i = vam->input;
10606   vl_api_classify_add_del_table_t *mp;
10607
10608   u32 nbuckets = 2;
10609   u32 skip = ~0;
10610   u32 match = ~0;
10611   int is_add = 1;
10612   int del_chain = 0;
10613   u32 table_index = ~0;
10614   u32 next_table_index = ~0;
10615   u32 miss_next_index = ~0;
10616   u32 memory_size = 32 << 20;
10617   u8 *mask = 0;
10618   u32 current_data_flag = 0;
10619   int current_data_offset = 0;
10620   int ret;
10621
10622   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10623     {
10624       if (unformat (i, "del"))
10625         is_add = 0;
10626       else if (unformat (i, "del-chain"))
10627         {
10628           is_add = 0;
10629           del_chain = 1;
10630         }
10631       else if (unformat (i, "buckets %d", &nbuckets))
10632         ;
10633       else if (unformat (i, "memory_size %d", &memory_size))
10634         ;
10635       else if (unformat (i, "skip %d", &skip))
10636         ;
10637       else if (unformat (i, "match %d", &match))
10638         ;
10639       else if (unformat (i, "table %d", &table_index))
10640         ;
10641       else if (unformat (i, "mask %U", unformat_classify_mask,
10642                          &mask, &skip, &match))
10643         ;
10644       else if (unformat (i, "next-table %d", &next_table_index))
10645         ;
10646       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10647                          &miss_next_index))
10648         ;
10649       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10650                          &miss_next_index))
10651         ;
10652       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10653                          &miss_next_index))
10654         ;
10655       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10656         ;
10657       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10658         ;
10659       else
10660         break;
10661     }
10662
10663   if (is_add && mask == 0)
10664     {
10665       errmsg ("Mask required");
10666       return -99;
10667     }
10668
10669   if (is_add && skip == ~0)
10670     {
10671       errmsg ("skip count required");
10672       return -99;
10673     }
10674
10675   if (is_add && match == ~0)
10676     {
10677       errmsg ("match count required");
10678       return -99;
10679     }
10680
10681   if (!is_add && table_index == ~0)
10682     {
10683       errmsg ("table index required for delete");
10684       return -99;
10685     }
10686
10687   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10688
10689   mp->is_add = is_add;
10690   mp->del_chain = del_chain;
10691   mp->table_index = ntohl (table_index);
10692   mp->nbuckets = ntohl (nbuckets);
10693   mp->memory_size = ntohl (memory_size);
10694   mp->skip_n_vectors = ntohl (skip);
10695   mp->match_n_vectors = ntohl (match);
10696   mp->next_table_index = ntohl (next_table_index);
10697   mp->miss_next_index = ntohl (miss_next_index);
10698   mp->current_data_flag = ntohl (current_data_flag);
10699   mp->current_data_offset = ntohl (current_data_offset);
10700   clib_memcpy (mp->mask, mask, vec_len (mask));
10701
10702   vec_free (mask);
10703
10704   S (mp);
10705   W (ret);
10706   return ret;
10707 }
10708
10709 #if VPP_API_TEST_BUILTIN == 0
10710 uword
10711 unformat_l4_match (unformat_input_t * input, va_list * args)
10712 {
10713   u8 **matchp = va_arg (*args, u8 **);
10714
10715   u8 *proto_header = 0;
10716   int src_port = 0;
10717   int dst_port = 0;
10718
10719   tcpudp_header_t h;
10720
10721   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10722     {
10723       if (unformat (input, "src_port %d", &src_port))
10724         ;
10725       else if (unformat (input, "dst_port %d", &dst_port))
10726         ;
10727       else
10728         return 0;
10729     }
10730
10731   h.src_port = clib_host_to_net_u16 (src_port);
10732   h.dst_port = clib_host_to_net_u16 (dst_port);
10733   vec_validate (proto_header, sizeof (h) - 1);
10734   memcpy (proto_header, &h, sizeof (h));
10735
10736   *matchp = proto_header;
10737
10738   return 1;
10739 }
10740
10741 uword
10742 unformat_ip4_match (unformat_input_t * input, va_list * args)
10743 {
10744   u8 **matchp = va_arg (*args, u8 **);
10745   u8 *match = 0;
10746   ip4_header_t *ip;
10747   int version = 0;
10748   u32 version_val;
10749   int hdr_length = 0;
10750   u32 hdr_length_val;
10751   int src = 0, dst = 0;
10752   ip4_address_t src_val, dst_val;
10753   int proto = 0;
10754   u32 proto_val;
10755   int tos = 0;
10756   u32 tos_val;
10757   int length = 0;
10758   u32 length_val;
10759   int fragment_id = 0;
10760   u32 fragment_id_val;
10761   int ttl = 0;
10762   int ttl_val;
10763   int checksum = 0;
10764   u32 checksum_val;
10765
10766   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10767     {
10768       if (unformat (input, "version %d", &version_val))
10769         version = 1;
10770       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10771         hdr_length = 1;
10772       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10773         src = 1;
10774       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10775         dst = 1;
10776       else if (unformat (input, "proto %d", &proto_val))
10777         proto = 1;
10778       else if (unformat (input, "tos %d", &tos_val))
10779         tos = 1;
10780       else if (unformat (input, "length %d", &length_val))
10781         length = 1;
10782       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10783         fragment_id = 1;
10784       else if (unformat (input, "ttl %d", &ttl_val))
10785         ttl = 1;
10786       else if (unformat (input, "checksum %d", &checksum_val))
10787         checksum = 1;
10788       else
10789         break;
10790     }
10791
10792   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10793       + ttl + checksum == 0)
10794     return 0;
10795
10796   /*
10797    * Aligned because we use the real comparison functions
10798    */
10799   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10800
10801   ip = (ip4_header_t *) match;
10802
10803   /* These are realistically matched in practice */
10804   if (src)
10805     ip->src_address.as_u32 = src_val.as_u32;
10806
10807   if (dst)
10808     ip->dst_address.as_u32 = dst_val.as_u32;
10809
10810   if (proto)
10811     ip->protocol = proto_val;
10812
10813
10814   /* These are not, but they're included for completeness */
10815   if (version)
10816     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10817
10818   if (hdr_length)
10819     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10820
10821   if (tos)
10822     ip->tos = tos_val;
10823
10824   if (length)
10825     ip->length = clib_host_to_net_u16 (length_val);
10826
10827   if (ttl)
10828     ip->ttl = ttl_val;
10829
10830   if (checksum)
10831     ip->checksum = clib_host_to_net_u16 (checksum_val);
10832
10833   *matchp = match;
10834   return 1;
10835 }
10836
10837 uword
10838 unformat_ip6_match (unformat_input_t * input, va_list * args)
10839 {
10840   u8 **matchp = va_arg (*args, u8 **);
10841   u8 *match = 0;
10842   ip6_header_t *ip;
10843   int version = 0;
10844   u32 version_val;
10845   u8 traffic_class = 0;
10846   u32 traffic_class_val = 0;
10847   u8 flow_label = 0;
10848   u8 flow_label_val;
10849   int src = 0, dst = 0;
10850   ip6_address_t src_val, dst_val;
10851   int proto = 0;
10852   u32 proto_val;
10853   int payload_length = 0;
10854   u32 payload_length_val;
10855   int hop_limit = 0;
10856   int hop_limit_val;
10857   u32 ip_version_traffic_class_and_flow_label;
10858
10859   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10860     {
10861       if (unformat (input, "version %d", &version_val))
10862         version = 1;
10863       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10864         traffic_class = 1;
10865       else if (unformat (input, "flow_label %d", &flow_label_val))
10866         flow_label = 1;
10867       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10868         src = 1;
10869       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10870         dst = 1;
10871       else if (unformat (input, "proto %d", &proto_val))
10872         proto = 1;
10873       else if (unformat (input, "payload_length %d", &payload_length_val))
10874         payload_length = 1;
10875       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10876         hop_limit = 1;
10877       else
10878         break;
10879     }
10880
10881   if (version + traffic_class + flow_label + src + dst + proto +
10882       payload_length + hop_limit == 0)
10883     return 0;
10884
10885   /*
10886    * Aligned because we use the real comparison functions
10887    */
10888   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10889
10890   ip = (ip6_header_t *) match;
10891
10892   if (src)
10893     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10894
10895   if (dst)
10896     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10897
10898   if (proto)
10899     ip->protocol = proto_val;
10900
10901   ip_version_traffic_class_and_flow_label = 0;
10902
10903   if (version)
10904     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10905
10906   if (traffic_class)
10907     ip_version_traffic_class_and_flow_label |=
10908       (traffic_class_val & 0xFF) << 20;
10909
10910   if (flow_label)
10911     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10912
10913   ip->ip_version_traffic_class_and_flow_label =
10914     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10915
10916   if (payload_length)
10917     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10918
10919   if (hop_limit)
10920     ip->hop_limit = hop_limit_val;
10921
10922   *matchp = match;
10923   return 1;
10924 }
10925
10926 uword
10927 unformat_l3_match (unformat_input_t * input, va_list * args)
10928 {
10929   u8 **matchp = va_arg (*args, u8 **);
10930
10931   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10932     {
10933       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10934         return 1;
10935       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10936         return 1;
10937       else
10938         break;
10939     }
10940   return 0;
10941 }
10942
10943 uword
10944 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10945 {
10946   u8 *tagp = va_arg (*args, u8 *);
10947   u32 tag;
10948
10949   if (unformat (input, "%d", &tag))
10950     {
10951       tagp[0] = (tag >> 8) & 0x0F;
10952       tagp[1] = tag & 0xFF;
10953       return 1;
10954     }
10955
10956   return 0;
10957 }
10958
10959 uword
10960 unformat_l2_match (unformat_input_t * input, va_list * args)
10961 {
10962   u8 **matchp = va_arg (*args, u8 **);
10963   u8 *match = 0;
10964   u8 src = 0;
10965   u8 src_val[6];
10966   u8 dst = 0;
10967   u8 dst_val[6];
10968   u8 proto = 0;
10969   u16 proto_val;
10970   u8 tag1 = 0;
10971   u8 tag1_val[2];
10972   u8 tag2 = 0;
10973   u8 tag2_val[2];
10974   int len = 14;
10975   u8 ignore_tag1 = 0;
10976   u8 ignore_tag2 = 0;
10977   u8 cos1 = 0;
10978   u8 cos2 = 0;
10979   u32 cos1_val = 0;
10980   u32 cos2_val = 0;
10981
10982   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10983     {
10984       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10985         src = 1;
10986       else
10987         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10988         dst = 1;
10989       else if (unformat (input, "proto %U",
10990                          unformat_ethernet_type_host_byte_order, &proto_val))
10991         proto = 1;
10992       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10993         tag1 = 1;
10994       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10995         tag2 = 1;
10996       else if (unformat (input, "ignore-tag1"))
10997         ignore_tag1 = 1;
10998       else if (unformat (input, "ignore-tag2"))
10999         ignore_tag2 = 1;
11000       else if (unformat (input, "cos1 %d", &cos1_val))
11001         cos1 = 1;
11002       else if (unformat (input, "cos2 %d", &cos2_val))
11003         cos2 = 1;
11004       else
11005         break;
11006     }
11007   if ((src + dst + proto + tag1 + tag2 +
11008        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
11009     return 0;
11010
11011   if (tag1 || ignore_tag1 || cos1)
11012     len = 18;
11013   if (tag2 || ignore_tag2 || cos2)
11014     len = 22;
11015
11016   vec_validate_aligned (match, len - 1, sizeof (u32x4));
11017
11018   if (dst)
11019     clib_memcpy (match, dst_val, 6);
11020
11021   if (src)
11022     clib_memcpy (match + 6, src_val, 6);
11023
11024   if (tag2)
11025     {
11026       /* inner vlan tag */
11027       match[19] = tag2_val[1];
11028       match[18] = tag2_val[0];
11029       if (cos2)
11030         match[18] |= (cos2_val & 0x7) << 5;
11031       if (proto)
11032         {
11033           match[21] = proto_val & 0xff;
11034           match[20] = proto_val >> 8;
11035         }
11036       if (tag1)
11037         {
11038           match[15] = tag1_val[1];
11039           match[14] = tag1_val[0];
11040         }
11041       if (cos1)
11042         match[14] |= (cos1_val & 0x7) << 5;
11043       *matchp = match;
11044       return 1;
11045     }
11046   if (tag1)
11047     {
11048       match[15] = tag1_val[1];
11049       match[14] = tag1_val[0];
11050       if (proto)
11051         {
11052           match[17] = proto_val & 0xff;
11053           match[16] = proto_val >> 8;
11054         }
11055       if (cos1)
11056         match[14] |= (cos1_val & 0x7) << 5;
11057
11058       *matchp = match;
11059       return 1;
11060     }
11061   if (cos2)
11062     match[18] |= (cos2_val & 0x7) << 5;
11063   if (cos1)
11064     match[14] |= (cos1_val & 0x7) << 5;
11065   if (proto)
11066     {
11067       match[13] = proto_val & 0xff;
11068       match[12] = proto_val >> 8;
11069     }
11070
11071   *matchp = match;
11072   return 1;
11073 }
11074 #endif
11075
11076 uword
11077 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11078 {
11079   u8 **matchp = va_arg (*args, u8 **);
11080   u32 skip_n_vectors = va_arg (*args, u32);
11081   u32 match_n_vectors = va_arg (*args, u32);
11082
11083   u8 *match = 0;
11084   u8 *l2 = 0;
11085   u8 *l3 = 0;
11086   u8 *l4 = 0;
11087
11088   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11089     {
11090       if (unformat (input, "hex %U", unformat_hex_string, &match))
11091         ;
11092       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11093         ;
11094       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11095         ;
11096       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11097         ;
11098       else
11099         break;
11100     }
11101
11102   if (l4 && !l3)
11103     {
11104       vec_free (match);
11105       vec_free (l2);
11106       vec_free (l4);
11107       return 0;
11108     }
11109
11110   if (match || l2 || l3 || l4)
11111     {
11112       if (l2 || l3 || l4)
11113         {
11114           /* "Win a free Ethernet header in every packet" */
11115           if (l2 == 0)
11116             vec_validate_aligned (l2, 13, sizeof (u32x4));
11117           match = l2;
11118           if (vec_len (l3))
11119             {
11120               vec_append_aligned (match, l3, sizeof (u32x4));
11121               vec_free (l3);
11122             }
11123           if (vec_len (l4))
11124             {
11125               vec_append_aligned (match, l4, sizeof (u32x4));
11126               vec_free (l4);
11127             }
11128         }
11129
11130       /* Make sure the vector is big enough even if key is all 0's */
11131       vec_validate_aligned
11132         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11133          sizeof (u32x4));
11134
11135       /* Set size, include skipped vectors */
11136       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11137
11138       *matchp = match;
11139
11140       return 1;
11141     }
11142
11143   return 0;
11144 }
11145
11146 static int
11147 api_classify_add_del_session (vat_main_t * vam)
11148 {
11149   unformat_input_t *i = vam->input;
11150   vl_api_classify_add_del_session_t *mp;
11151   int is_add = 1;
11152   u32 table_index = ~0;
11153   u32 hit_next_index = ~0;
11154   u32 opaque_index = ~0;
11155   u8 *match = 0;
11156   i32 advance = 0;
11157   u32 skip_n_vectors = 0;
11158   u32 match_n_vectors = 0;
11159   u32 action = 0;
11160   u32 metadata = 0;
11161   int ret;
11162
11163   /*
11164    * Warning: you have to supply skip_n and match_n
11165    * because the API client cant simply look at the classify
11166    * table object.
11167    */
11168
11169   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11170     {
11171       if (unformat (i, "del"))
11172         is_add = 0;
11173       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11174                          &hit_next_index))
11175         ;
11176       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11177                          &hit_next_index))
11178         ;
11179       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11180                          &hit_next_index))
11181         ;
11182       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11183         ;
11184       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11185         ;
11186       else if (unformat (i, "opaque-index %d", &opaque_index))
11187         ;
11188       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11189         ;
11190       else if (unformat (i, "match_n %d", &match_n_vectors))
11191         ;
11192       else if (unformat (i, "match %U", api_unformat_classify_match,
11193                          &match, skip_n_vectors, match_n_vectors))
11194         ;
11195       else if (unformat (i, "advance %d", &advance))
11196         ;
11197       else if (unformat (i, "table-index %d", &table_index))
11198         ;
11199       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11200         action = 1;
11201       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11202         action = 2;
11203       else if (unformat (i, "action %d", &action))
11204         ;
11205       else if (unformat (i, "metadata %d", &metadata))
11206         ;
11207       else
11208         break;
11209     }
11210
11211   if (table_index == ~0)
11212     {
11213       errmsg ("Table index required");
11214       return -99;
11215     }
11216
11217   if (is_add && match == 0)
11218     {
11219       errmsg ("Match value required");
11220       return -99;
11221     }
11222
11223   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11224
11225   mp->is_add = is_add;
11226   mp->table_index = ntohl (table_index);
11227   mp->hit_next_index = ntohl (hit_next_index);
11228   mp->opaque_index = ntohl (opaque_index);
11229   mp->advance = ntohl (advance);
11230   mp->action = action;
11231   mp->metadata = ntohl (metadata);
11232   clib_memcpy (mp->match, match, vec_len (match));
11233   vec_free (match);
11234
11235   S (mp);
11236   W (ret);
11237   return ret;
11238 }
11239
11240 static int
11241 api_classify_set_interface_ip_table (vat_main_t * vam)
11242 {
11243   unformat_input_t *i = vam->input;
11244   vl_api_classify_set_interface_ip_table_t *mp;
11245   u32 sw_if_index;
11246   int sw_if_index_set;
11247   u32 table_index = ~0;
11248   u8 is_ipv6 = 0;
11249   int ret;
11250
11251   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11252     {
11253       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11254         sw_if_index_set = 1;
11255       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11256         sw_if_index_set = 1;
11257       else if (unformat (i, "table %d", &table_index))
11258         ;
11259       else
11260         {
11261           clib_warning ("parse error '%U'", format_unformat_error, i);
11262           return -99;
11263         }
11264     }
11265
11266   if (sw_if_index_set == 0)
11267     {
11268       errmsg ("missing interface name or sw_if_index");
11269       return -99;
11270     }
11271
11272
11273   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11274
11275   mp->sw_if_index = ntohl (sw_if_index);
11276   mp->table_index = ntohl (table_index);
11277   mp->is_ipv6 = is_ipv6;
11278
11279   S (mp);
11280   W (ret);
11281   return ret;
11282 }
11283
11284 static int
11285 api_classify_set_interface_l2_tables (vat_main_t * vam)
11286 {
11287   unformat_input_t *i = vam->input;
11288   vl_api_classify_set_interface_l2_tables_t *mp;
11289   u32 sw_if_index;
11290   int sw_if_index_set;
11291   u32 ip4_table_index = ~0;
11292   u32 ip6_table_index = ~0;
11293   u32 other_table_index = ~0;
11294   u32 is_input = 1;
11295   int ret;
11296
11297   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11298     {
11299       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11300         sw_if_index_set = 1;
11301       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11302         sw_if_index_set = 1;
11303       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11304         ;
11305       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11306         ;
11307       else if (unformat (i, "other-table %d", &other_table_index))
11308         ;
11309       else if (unformat (i, "is-input %d", &is_input))
11310         ;
11311       else
11312         {
11313           clib_warning ("parse error '%U'", format_unformat_error, i);
11314           return -99;
11315         }
11316     }
11317
11318   if (sw_if_index_set == 0)
11319     {
11320       errmsg ("missing interface name or sw_if_index");
11321       return -99;
11322     }
11323
11324
11325   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11326
11327   mp->sw_if_index = ntohl (sw_if_index);
11328   mp->ip4_table_index = ntohl (ip4_table_index);
11329   mp->ip6_table_index = ntohl (ip6_table_index);
11330   mp->other_table_index = ntohl (other_table_index);
11331   mp->is_input = (u8) is_input;
11332
11333   S (mp);
11334   W (ret);
11335   return ret;
11336 }
11337
11338 static int
11339 api_set_ipfix_exporter (vat_main_t * vam)
11340 {
11341   unformat_input_t *i = vam->input;
11342   vl_api_set_ipfix_exporter_t *mp;
11343   ip4_address_t collector_address;
11344   u8 collector_address_set = 0;
11345   u32 collector_port = ~0;
11346   ip4_address_t src_address;
11347   u8 src_address_set = 0;
11348   u32 vrf_id = ~0;
11349   u32 path_mtu = ~0;
11350   u32 template_interval = ~0;
11351   u8 udp_checksum = 0;
11352   int ret;
11353
11354   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11355     {
11356       if (unformat (i, "collector_address %U", unformat_ip4_address,
11357                     &collector_address))
11358         collector_address_set = 1;
11359       else if (unformat (i, "collector_port %d", &collector_port))
11360         ;
11361       else if (unformat (i, "src_address %U", unformat_ip4_address,
11362                          &src_address))
11363         src_address_set = 1;
11364       else if (unformat (i, "vrf_id %d", &vrf_id))
11365         ;
11366       else if (unformat (i, "path_mtu %d", &path_mtu))
11367         ;
11368       else if (unformat (i, "template_interval %d", &template_interval))
11369         ;
11370       else if (unformat (i, "udp_checksum"))
11371         udp_checksum = 1;
11372       else
11373         break;
11374     }
11375
11376   if (collector_address_set == 0)
11377     {
11378       errmsg ("collector_address required");
11379       return -99;
11380     }
11381
11382   if (src_address_set == 0)
11383     {
11384       errmsg ("src_address required");
11385       return -99;
11386     }
11387
11388   M (SET_IPFIX_EXPORTER, mp);
11389
11390   memcpy (mp->collector_address, collector_address.data,
11391           sizeof (collector_address.data));
11392   mp->collector_port = htons ((u16) collector_port);
11393   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11394   mp->vrf_id = htonl (vrf_id);
11395   mp->path_mtu = htonl (path_mtu);
11396   mp->template_interval = htonl (template_interval);
11397   mp->udp_checksum = udp_checksum;
11398
11399   S (mp);
11400   W (ret);
11401   return ret;
11402 }
11403
11404 static int
11405 api_set_ipfix_classify_stream (vat_main_t * vam)
11406 {
11407   unformat_input_t *i = vam->input;
11408   vl_api_set_ipfix_classify_stream_t *mp;
11409   u32 domain_id = 0;
11410   u32 src_port = UDP_DST_PORT_ipfix;
11411   int ret;
11412
11413   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11414     {
11415       if (unformat (i, "domain %d", &domain_id))
11416         ;
11417       else if (unformat (i, "src_port %d", &src_port))
11418         ;
11419       else
11420         {
11421           errmsg ("unknown input `%U'", format_unformat_error, i);
11422           return -99;
11423         }
11424     }
11425
11426   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11427
11428   mp->domain_id = htonl (domain_id);
11429   mp->src_port = htons ((u16) src_port);
11430
11431   S (mp);
11432   W (ret);
11433   return ret;
11434 }
11435
11436 static int
11437 api_ipfix_classify_table_add_del (vat_main_t * vam)
11438 {
11439   unformat_input_t *i = vam->input;
11440   vl_api_ipfix_classify_table_add_del_t *mp;
11441   int is_add = -1;
11442   u32 classify_table_index = ~0;
11443   u8 ip_version = 0;
11444   u8 transport_protocol = 255;
11445   int ret;
11446
11447   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11448     {
11449       if (unformat (i, "add"))
11450         is_add = 1;
11451       else if (unformat (i, "del"))
11452         is_add = 0;
11453       else if (unformat (i, "table %d", &classify_table_index))
11454         ;
11455       else if (unformat (i, "ip4"))
11456         ip_version = 4;
11457       else if (unformat (i, "ip6"))
11458         ip_version = 6;
11459       else if (unformat (i, "tcp"))
11460         transport_protocol = 6;
11461       else if (unformat (i, "udp"))
11462         transport_protocol = 17;
11463       else
11464         {
11465           errmsg ("unknown input `%U'", format_unformat_error, i);
11466           return -99;
11467         }
11468     }
11469
11470   if (is_add == -1)
11471     {
11472       errmsg ("expecting: add|del");
11473       return -99;
11474     }
11475   if (classify_table_index == ~0)
11476     {
11477       errmsg ("classifier table not specified");
11478       return -99;
11479     }
11480   if (ip_version == 0)
11481     {
11482       errmsg ("IP version not specified");
11483       return -99;
11484     }
11485
11486   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11487
11488   mp->is_add = is_add;
11489   mp->table_id = htonl (classify_table_index);
11490   mp->ip_version = ip_version;
11491   mp->transport_protocol = transport_protocol;
11492
11493   S (mp);
11494   W (ret);
11495   return ret;
11496 }
11497
11498 static int
11499 api_get_node_index (vat_main_t * vam)
11500 {
11501   unformat_input_t *i = vam->input;
11502   vl_api_get_node_index_t *mp;
11503   u8 *name = 0;
11504   int ret;
11505
11506   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11507     {
11508       if (unformat (i, "node %s", &name))
11509         ;
11510       else
11511         break;
11512     }
11513   if (name == 0)
11514     {
11515       errmsg ("node name required");
11516       return -99;
11517     }
11518   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11519     {
11520       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11521       return -99;
11522     }
11523
11524   M (GET_NODE_INDEX, mp);
11525   clib_memcpy (mp->node_name, name, vec_len (name));
11526   vec_free (name);
11527
11528   S (mp);
11529   W (ret);
11530   return ret;
11531 }
11532
11533 static int
11534 api_get_next_index (vat_main_t * vam)
11535 {
11536   unformat_input_t *i = vam->input;
11537   vl_api_get_next_index_t *mp;
11538   u8 *node_name = 0, *next_node_name = 0;
11539   int ret;
11540
11541   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11542     {
11543       if (unformat (i, "node-name %s", &node_name))
11544         ;
11545       else if (unformat (i, "next-node-name %s", &next_node_name))
11546         break;
11547     }
11548
11549   if (node_name == 0)
11550     {
11551       errmsg ("node name required");
11552       return -99;
11553     }
11554   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11555     {
11556       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11557       return -99;
11558     }
11559
11560   if (next_node_name == 0)
11561     {
11562       errmsg ("next node name required");
11563       return -99;
11564     }
11565   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11566     {
11567       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11568       return -99;
11569     }
11570
11571   M (GET_NEXT_INDEX, mp);
11572   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11573   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11574   vec_free (node_name);
11575   vec_free (next_node_name);
11576
11577   S (mp);
11578   W (ret);
11579   return ret;
11580 }
11581
11582 static int
11583 api_add_node_next (vat_main_t * vam)
11584 {
11585   unformat_input_t *i = vam->input;
11586   vl_api_add_node_next_t *mp;
11587   u8 *name = 0;
11588   u8 *next = 0;
11589   int ret;
11590
11591   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11592     {
11593       if (unformat (i, "node %s", &name))
11594         ;
11595       else if (unformat (i, "next %s", &next))
11596         ;
11597       else
11598         break;
11599     }
11600   if (name == 0)
11601     {
11602       errmsg ("node name required");
11603       return -99;
11604     }
11605   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11606     {
11607       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11608       return -99;
11609     }
11610   if (next == 0)
11611     {
11612       errmsg ("next node required");
11613       return -99;
11614     }
11615   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11616     {
11617       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11618       return -99;
11619     }
11620
11621   M (ADD_NODE_NEXT, mp);
11622   clib_memcpy (mp->node_name, name, vec_len (name));
11623   clib_memcpy (mp->next_name, next, vec_len (next));
11624   vec_free (name);
11625   vec_free (next);
11626
11627   S (mp);
11628   W (ret);
11629   return ret;
11630 }
11631
11632 static int
11633 api_l2tpv3_create_tunnel (vat_main_t * vam)
11634 {
11635   unformat_input_t *i = vam->input;
11636   ip6_address_t client_address, our_address;
11637   int client_address_set = 0;
11638   int our_address_set = 0;
11639   u32 local_session_id = 0;
11640   u32 remote_session_id = 0;
11641   u64 local_cookie = 0;
11642   u64 remote_cookie = 0;
11643   u8 l2_sublayer_present = 0;
11644   vl_api_l2tpv3_create_tunnel_t *mp;
11645   int ret;
11646
11647   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11648     {
11649       if (unformat (i, "client_address %U", unformat_ip6_address,
11650                     &client_address))
11651         client_address_set = 1;
11652       else if (unformat (i, "our_address %U", unformat_ip6_address,
11653                          &our_address))
11654         our_address_set = 1;
11655       else if (unformat (i, "local_session_id %d", &local_session_id))
11656         ;
11657       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11658         ;
11659       else if (unformat (i, "local_cookie %lld", &local_cookie))
11660         ;
11661       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11662         ;
11663       else if (unformat (i, "l2-sublayer-present"))
11664         l2_sublayer_present = 1;
11665       else
11666         break;
11667     }
11668
11669   if (client_address_set == 0)
11670     {
11671       errmsg ("client_address required");
11672       return -99;
11673     }
11674
11675   if (our_address_set == 0)
11676     {
11677       errmsg ("our_address required");
11678       return -99;
11679     }
11680
11681   M (L2TPV3_CREATE_TUNNEL, mp);
11682
11683   clib_memcpy (mp->client_address, client_address.as_u8,
11684                sizeof (mp->client_address));
11685
11686   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11687
11688   mp->local_session_id = ntohl (local_session_id);
11689   mp->remote_session_id = ntohl (remote_session_id);
11690   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11691   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11692   mp->l2_sublayer_present = l2_sublayer_present;
11693   mp->is_ipv6 = 1;
11694
11695   S (mp);
11696   W (ret);
11697   return ret;
11698 }
11699
11700 static int
11701 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11702 {
11703   unformat_input_t *i = vam->input;
11704   u32 sw_if_index;
11705   u8 sw_if_index_set = 0;
11706   u64 new_local_cookie = 0;
11707   u64 new_remote_cookie = 0;
11708   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11709   int ret;
11710
11711   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11712     {
11713       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11714         sw_if_index_set = 1;
11715       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11716         sw_if_index_set = 1;
11717       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11718         ;
11719       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11720         ;
11721       else
11722         break;
11723     }
11724
11725   if (sw_if_index_set == 0)
11726     {
11727       errmsg ("missing interface name or sw_if_index");
11728       return -99;
11729     }
11730
11731   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11732
11733   mp->sw_if_index = ntohl (sw_if_index);
11734   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11735   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11736
11737   S (mp);
11738   W (ret);
11739   return ret;
11740 }
11741
11742 static int
11743 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11744 {
11745   unformat_input_t *i = vam->input;
11746   vl_api_l2tpv3_interface_enable_disable_t *mp;
11747   u32 sw_if_index;
11748   u8 sw_if_index_set = 0;
11749   u8 enable_disable = 1;
11750   int ret;
11751
11752   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11753     {
11754       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11755         sw_if_index_set = 1;
11756       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11757         sw_if_index_set = 1;
11758       else if (unformat (i, "enable"))
11759         enable_disable = 1;
11760       else if (unformat (i, "disable"))
11761         enable_disable = 0;
11762       else
11763         break;
11764     }
11765
11766   if (sw_if_index_set == 0)
11767     {
11768       errmsg ("missing interface name or sw_if_index");
11769       return -99;
11770     }
11771
11772   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11773
11774   mp->sw_if_index = ntohl (sw_if_index);
11775   mp->enable_disable = enable_disable;
11776
11777   S (mp);
11778   W (ret);
11779   return ret;
11780 }
11781
11782 static int
11783 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11784 {
11785   unformat_input_t *i = vam->input;
11786   vl_api_l2tpv3_set_lookup_key_t *mp;
11787   u8 key = ~0;
11788   int ret;
11789
11790   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11791     {
11792       if (unformat (i, "lookup_v6_src"))
11793         key = L2T_LOOKUP_SRC_ADDRESS;
11794       else if (unformat (i, "lookup_v6_dst"))
11795         key = L2T_LOOKUP_DST_ADDRESS;
11796       else if (unformat (i, "lookup_session_id"))
11797         key = L2T_LOOKUP_SESSION_ID;
11798       else
11799         break;
11800     }
11801
11802   if (key == (u8) ~ 0)
11803     {
11804       errmsg ("l2tp session lookup key unset");
11805       return -99;
11806     }
11807
11808   M (L2TPV3_SET_LOOKUP_KEY, mp);
11809
11810   mp->key = key;
11811
11812   S (mp);
11813   W (ret);
11814   return ret;
11815 }
11816
11817 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11818   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11819 {
11820   vat_main_t *vam = &vat_main;
11821
11822   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11823          format_ip6_address, mp->our_address,
11824          format_ip6_address, mp->client_address,
11825          clib_net_to_host_u32 (mp->sw_if_index));
11826
11827   print (vam->ofp,
11828          "   local cookies %016llx %016llx remote cookie %016llx",
11829          clib_net_to_host_u64 (mp->local_cookie[0]),
11830          clib_net_to_host_u64 (mp->local_cookie[1]),
11831          clib_net_to_host_u64 (mp->remote_cookie));
11832
11833   print (vam->ofp, "   local session-id %d remote session-id %d",
11834          clib_net_to_host_u32 (mp->local_session_id),
11835          clib_net_to_host_u32 (mp->remote_session_id));
11836
11837   print (vam->ofp, "   l2 specific sublayer %s\n",
11838          mp->l2_sublayer_present ? "preset" : "absent");
11839
11840 }
11841
11842 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11843   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11844 {
11845   vat_main_t *vam = &vat_main;
11846   vat_json_node_t *node = NULL;
11847   struct in6_addr addr;
11848
11849   if (VAT_JSON_ARRAY != vam->json_tree.type)
11850     {
11851       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11852       vat_json_init_array (&vam->json_tree);
11853     }
11854   node = vat_json_array_add (&vam->json_tree);
11855
11856   vat_json_init_object (node);
11857
11858   clib_memcpy (&addr, mp->our_address, sizeof (addr));
11859   vat_json_object_add_ip6 (node, "our_address", addr);
11860   clib_memcpy (&addr, mp->client_address, sizeof (addr));
11861   vat_json_object_add_ip6 (node, "client_address", addr);
11862
11863   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11864   vat_json_init_array (lc);
11865   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11866   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11867   vat_json_object_add_uint (node, "remote_cookie",
11868                             clib_net_to_host_u64 (mp->remote_cookie));
11869
11870   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11871   vat_json_object_add_uint (node, "local_session_id",
11872                             clib_net_to_host_u32 (mp->local_session_id));
11873   vat_json_object_add_uint (node, "remote_session_id",
11874                             clib_net_to_host_u32 (mp->remote_session_id));
11875   vat_json_object_add_string_copy (node, "l2_sublayer",
11876                                    mp->l2_sublayer_present ? (u8 *) "present"
11877                                    : (u8 *) "absent");
11878 }
11879
11880 static int
11881 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11882 {
11883   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11884   vl_api_control_ping_t *mp_ping;
11885   int ret;
11886
11887   /* Get list of l2tpv3-tunnel interfaces */
11888   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11889   S (mp);
11890
11891   /* Use a control ping for synchronization */
11892   MPING (CONTROL_PING, mp_ping);
11893   S (mp_ping);
11894
11895   W (ret);
11896   return ret;
11897 }
11898
11899
11900 static void vl_api_sw_interface_tap_details_t_handler
11901   (vl_api_sw_interface_tap_details_t * mp)
11902 {
11903   vat_main_t *vam = &vat_main;
11904
11905   print (vam->ofp, "%-16s %d",
11906          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
11907 }
11908
11909 static void vl_api_sw_interface_tap_details_t_handler_json
11910   (vl_api_sw_interface_tap_details_t * mp)
11911 {
11912   vat_main_t *vam = &vat_main;
11913   vat_json_node_t *node = NULL;
11914
11915   if (VAT_JSON_ARRAY != vam->json_tree.type)
11916     {
11917       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11918       vat_json_init_array (&vam->json_tree);
11919     }
11920   node = vat_json_array_add (&vam->json_tree);
11921
11922   vat_json_init_object (node);
11923   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11924   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11925 }
11926
11927 static int
11928 api_sw_interface_tap_dump (vat_main_t * vam)
11929 {
11930   vl_api_sw_interface_tap_dump_t *mp;
11931   vl_api_control_ping_t *mp_ping;
11932   int ret;
11933
11934   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
11935   /* Get list of tap interfaces */
11936   M (SW_INTERFACE_TAP_DUMP, mp);
11937   S (mp);
11938
11939   /* Use a control ping for synchronization */
11940   MPING (CONTROL_PING, mp_ping);
11941   S (mp_ping);
11942
11943   W (ret);
11944   return ret;
11945 }
11946
11947 static uword unformat_vxlan_decap_next
11948   (unformat_input_t * input, va_list * args)
11949 {
11950   u32 *result = va_arg (*args, u32 *);
11951   u32 tmp;
11952
11953   if (unformat (input, "l2"))
11954     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11955   else if (unformat (input, "%d", &tmp))
11956     *result = tmp;
11957   else
11958     return 0;
11959   return 1;
11960 }
11961
11962 static int
11963 api_vxlan_add_del_tunnel (vat_main_t * vam)
11964 {
11965   unformat_input_t *line_input = vam->input;
11966   vl_api_vxlan_add_del_tunnel_t *mp;
11967   ip46_address_t src, dst;
11968   u8 is_add = 1;
11969   u8 ipv4_set = 0, ipv6_set = 0;
11970   u8 src_set = 0;
11971   u8 dst_set = 0;
11972   u8 grp_set = 0;
11973   u32 mcast_sw_if_index = ~0;
11974   u32 encap_vrf_id = 0;
11975   u32 decap_next_index = ~0;
11976   u32 vni = 0;
11977   int ret;
11978
11979   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11980   memset (&src, 0, sizeof src);
11981   memset (&dst, 0, sizeof dst);
11982
11983   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11984     {
11985       if (unformat (line_input, "del"))
11986         is_add = 0;
11987       else
11988         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11989         {
11990           ipv4_set = 1;
11991           src_set = 1;
11992         }
11993       else
11994         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11995         {
11996           ipv4_set = 1;
11997           dst_set = 1;
11998         }
11999       else
12000         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12001         {
12002           ipv6_set = 1;
12003           src_set = 1;
12004         }
12005       else
12006         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12007         {
12008           ipv6_set = 1;
12009           dst_set = 1;
12010         }
12011       else if (unformat (line_input, "group %U %U",
12012                          unformat_ip4_address, &dst.ip4,
12013                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12014         {
12015           grp_set = dst_set = 1;
12016           ipv4_set = 1;
12017         }
12018       else if (unformat (line_input, "group %U",
12019                          unformat_ip4_address, &dst.ip4))
12020         {
12021           grp_set = dst_set = 1;
12022           ipv4_set = 1;
12023         }
12024       else if (unformat (line_input, "group %U %U",
12025                          unformat_ip6_address, &dst.ip6,
12026                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12027         {
12028           grp_set = dst_set = 1;
12029           ipv6_set = 1;
12030         }
12031       else if (unformat (line_input, "group %U",
12032                          unformat_ip6_address, &dst.ip6))
12033         {
12034           grp_set = dst_set = 1;
12035           ipv6_set = 1;
12036         }
12037       else
12038         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12039         ;
12040       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12041         ;
12042       else if (unformat (line_input, "decap-next %U",
12043                          unformat_vxlan_decap_next, &decap_next_index))
12044         ;
12045       else if (unformat (line_input, "vni %d", &vni))
12046         ;
12047       else
12048         {
12049           errmsg ("parse error '%U'", format_unformat_error, line_input);
12050           return -99;
12051         }
12052     }
12053
12054   if (src_set == 0)
12055     {
12056       errmsg ("tunnel src address not specified");
12057       return -99;
12058     }
12059   if (dst_set == 0)
12060     {
12061       errmsg ("tunnel dst address not specified");
12062       return -99;
12063     }
12064
12065   if (grp_set && !ip46_address_is_multicast (&dst))
12066     {
12067       errmsg ("tunnel group address not multicast");
12068       return -99;
12069     }
12070   if (grp_set && mcast_sw_if_index == ~0)
12071     {
12072       errmsg ("tunnel nonexistent multicast device");
12073       return -99;
12074     }
12075   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12076     {
12077       errmsg ("tunnel dst address must be unicast");
12078       return -99;
12079     }
12080
12081
12082   if (ipv4_set && ipv6_set)
12083     {
12084       errmsg ("both IPv4 and IPv6 addresses specified");
12085       return -99;
12086     }
12087
12088   if ((vni == 0) || (vni >> 24))
12089     {
12090       errmsg ("vni not specified or out of range");
12091       return -99;
12092     }
12093
12094   M (VXLAN_ADD_DEL_TUNNEL, mp);
12095
12096   if (ipv6_set)
12097     {
12098       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12099       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12100     }
12101   else
12102     {
12103       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12104       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12105     }
12106   mp->encap_vrf_id = ntohl (encap_vrf_id);
12107   mp->decap_next_index = ntohl (decap_next_index);
12108   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12109   mp->vni = ntohl (vni);
12110   mp->is_add = is_add;
12111   mp->is_ipv6 = ipv6_set;
12112
12113   S (mp);
12114   W (ret);
12115   return ret;
12116 }
12117
12118 static void vl_api_vxlan_tunnel_details_t_handler
12119   (vl_api_vxlan_tunnel_details_t * mp)
12120 {
12121   vat_main_t *vam = &vat_main;
12122   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12123   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12124
12125   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12126          ntohl (mp->sw_if_index),
12127          format_ip46_address, &src, IP46_TYPE_ANY,
12128          format_ip46_address, &dst, IP46_TYPE_ANY,
12129          ntohl (mp->encap_vrf_id),
12130          ntohl (mp->decap_next_index), ntohl (mp->vni),
12131          ntohl (mp->mcast_sw_if_index));
12132 }
12133
12134 static void vl_api_vxlan_tunnel_details_t_handler_json
12135   (vl_api_vxlan_tunnel_details_t * mp)
12136 {
12137   vat_main_t *vam = &vat_main;
12138   vat_json_node_t *node = NULL;
12139
12140   if (VAT_JSON_ARRAY != vam->json_tree.type)
12141     {
12142       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12143       vat_json_init_array (&vam->json_tree);
12144     }
12145   node = vat_json_array_add (&vam->json_tree);
12146
12147   vat_json_init_object (node);
12148   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12149   if (mp->is_ipv6)
12150     {
12151       struct in6_addr ip6;
12152
12153       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12154       vat_json_object_add_ip6 (node, "src_address", ip6);
12155       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12156       vat_json_object_add_ip6 (node, "dst_address", ip6);
12157     }
12158   else
12159     {
12160       struct in_addr ip4;
12161
12162       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12163       vat_json_object_add_ip4 (node, "src_address", ip4);
12164       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12165       vat_json_object_add_ip4 (node, "dst_address", ip4);
12166     }
12167   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12168   vat_json_object_add_uint (node, "decap_next_index",
12169                             ntohl (mp->decap_next_index));
12170   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12171   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12172   vat_json_object_add_uint (node, "mcast_sw_if_index",
12173                             ntohl (mp->mcast_sw_if_index));
12174 }
12175
12176 static int
12177 api_vxlan_tunnel_dump (vat_main_t * vam)
12178 {
12179   unformat_input_t *i = vam->input;
12180   vl_api_vxlan_tunnel_dump_t *mp;
12181   vl_api_control_ping_t *mp_ping;
12182   u32 sw_if_index;
12183   u8 sw_if_index_set = 0;
12184   int ret;
12185
12186   /* Parse args required to build the message */
12187   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12188     {
12189       if (unformat (i, "sw_if_index %d", &sw_if_index))
12190         sw_if_index_set = 1;
12191       else
12192         break;
12193     }
12194
12195   if (sw_if_index_set == 0)
12196     {
12197       sw_if_index = ~0;
12198     }
12199
12200   if (!vam->json_output)
12201     {
12202       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12203              "sw_if_index", "src_address", "dst_address",
12204              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12205     }
12206
12207   /* Get list of vxlan-tunnel interfaces */
12208   M (VXLAN_TUNNEL_DUMP, mp);
12209
12210   mp->sw_if_index = htonl (sw_if_index);
12211
12212   S (mp);
12213
12214   /* Use a control ping for synchronization */
12215   MPING (CONTROL_PING, mp_ping);
12216   S (mp_ping);
12217
12218   W (ret);
12219   return ret;
12220 }
12221
12222 static uword unformat_geneve_decap_next
12223   (unformat_input_t * input, va_list * args)
12224 {
12225   u32 *result = va_arg (*args, u32 *);
12226   u32 tmp;
12227
12228   if (unformat (input, "l2"))
12229     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12230   else if (unformat (input, "%d", &tmp))
12231     *result = tmp;
12232   else
12233     return 0;
12234   return 1;
12235 }
12236
12237 static int
12238 api_geneve_add_del_tunnel (vat_main_t * vam)
12239 {
12240   unformat_input_t *line_input = vam->input;
12241   vl_api_geneve_add_del_tunnel_t *mp;
12242   ip46_address_t src, dst;
12243   u8 is_add = 1;
12244   u8 ipv4_set = 0, ipv6_set = 0;
12245   u8 src_set = 0;
12246   u8 dst_set = 0;
12247   u8 grp_set = 0;
12248   u32 mcast_sw_if_index = ~0;
12249   u32 encap_vrf_id = 0;
12250   u32 decap_next_index = ~0;
12251   u32 vni = 0;
12252   int ret;
12253
12254   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12255   memset (&src, 0, sizeof src);
12256   memset (&dst, 0, sizeof dst);
12257
12258   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12259     {
12260       if (unformat (line_input, "del"))
12261         is_add = 0;
12262       else
12263         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12264         {
12265           ipv4_set = 1;
12266           src_set = 1;
12267         }
12268       else
12269         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12270         {
12271           ipv4_set = 1;
12272           dst_set = 1;
12273         }
12274       else
12275         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12276         {
12277           ipv6_set = 1;
12278           src_set = 1;
12279         }
12280       else
12281         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12282         {
12283           ipv6_set = 1;
12284           dst_set = 1;
12285         }
12286       else if (unformat (line_input, "group %U %U",
12287                          unformat_ip4_address, &dst.ip4,
12288                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12289         {
12290           grp_set = dst_set = 1;
12291           ipv4_set = 1;
12292         }
12293       else if (unformat (line_input, "group %U",
12294                          unformat_ip4_address, &dst.ip4))
12295         {
12296           grp_set = dst_set = 1;
12297           ipv4_set = 1;
12298         }
12299       else if (unformat (line_input, "group %U %U",
12300                          unformat_ip6_address, &dst.ip6,
12301                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12302         {
12303           grp_set = dst_set = 1;
12304           ipv6_set = 1;
12305         }
12306       else if (unformat (line_input, "group %U",
12307                          unformat_ip6_address, &dst.ip6))
12308         {
12309           grp_set = dst_set = 1;
12310           ipv6_set = 1;
12311         }
12312       else
12313         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12314         ;
12315       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12316         ;
12317       else if (unformat (line_input, "decap-next %U",
12318                          unformat_geneve_decap_next, &decap_next_index))
12319         ;
12320       else if (unformat (line_input, "vni %d", &vni))
12321         ;
12322       else
12323         {
12324           errmsg ("parse error '%U'", format_unformat_error, line_input);
12325           return -99;
12326         }
12327     }
12328
12329   if (src_set == 0)
12330     {
12331       errmsg ("tunnel src address not specified");
12332       return -99;
12333     }
12334   if (dst_set == 0)
12335     {
12336       errmsg ("tunnel dst address not specified");
12337       return -99;
12338     }
12339
12340   if (grp_set && !ip46_address_is_multicast (&dst))
12341     {
12342       errmsg ("tunnel group address not multicast");
12343       return -99;
12344     }
12345   if (grp_set && mcast_sw_if_index == ~0)
12346     {
12347       errmsg ("tunnel nonexistent multicast device");
12348       return -99;
12349     }
12350   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12351     {
12352       errmsg ("tunnel dst address must be unicast");
12353       return -99;
12354     }
12355
12356
12357   if (ipv4_set && ipv6_set)
12358     {
12359       errmsg ("both IPv4 and IPv6 addresses specified");
12360       return -99;
12361     }
12362
12363   if ((vni == 0) || (vni >> 24))
12364     {
12365       errmsg ("vni not specified or out of range");
12366       return -99;
12367     }
12368
12369   M (GENEVE_ADD_DEL_TUNNEL, mp);
12370
12371   if (ipv6_set)
12372     {
12373       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12374       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12375     }
12376   else
12377     {
12378       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12379       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12380     }
12381   mp->encap_vrf_id = ntohl (encap_vrf_id);
12382   mp->decap_next_index = ntohl (decap_next_index);
12383   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12384   mp->vni = ntohl (vni);
12385   mp->is_add = is_add;
12386   mp->is_ipv6 = ipv6_set;
12387
12388   S (mp);
12389   W (ret);
12390   return ret;
12391 }
12392
12393 static void vl_api_geneve_tunnel_details_t_handler
12394   (vl_api_geneve_tunnel_details_t * mp)
12395 {
12396   vat_main_t *vam = &vat_main;
12397   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12398   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12399
12400   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12401          ntohl (mp->sw_if_index),
12402          format_ip46_address, &src, IP46_TYPE_ANY,
12403          format_ip46_address, &dst, IP46_TYPE_ANY,
12404          ntohl (mp->encap_vrf_id),
12405          ntohl (mp->decap_next_index), ntohl (mp->vni),
12406          ntohl (mp->mcast_sw_if_index));
12407 }
12408
12409 static void vl_api_geneve_tunnel_details_t_handler_json
12410   (vl_api_geneve_tunnel_details_t * mp)
12411 {
12412   vat_main_t *vam = &vat_main;
12413   vat_json_node_t *node = NULL;
12414
12415   if (VAT_JSON_ARRAY != vam->json_tree.type)
12416     {
12417       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12418       vat_json_init_array (&vam->json_tree);
12419     }
12420   node = vat_json_array_add (&vam->json_tree);
12421
12422   vat_json_init_object (node);
12423   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12424   if (mp->is_ipv6)
12425     {
12426       struct in6_addr ip6;
12427
12428       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12429       vat_json_object_add_ip6 (node, "src_address", ip6);
12430       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12431       vat_json_object_add_ip6 (node, "dst_address", ip6);
12432     }
12433   else
12434     {
12435       struct in_addr ip4;
12436
12437       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12438       vat_json_object_add_ip4 (node, "src_address", ip4);
12439       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12440       vat_json_object_add_ip4 (node, "dst_address", ip4);
12441     }
12442   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12443   vat_json_object_add_uint (node, "decap_next_index",
12444                             ntohl (mp->decap_next_index));
12445   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12446   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12447   vat_json_object_add_uint (node, "mcast_sw_if_index",
12448                             ntohl (mp->mcast_sw_if_index));
12449 }
12450
12451 static int
12452 api_geneve_tunnel_dump (vat_main_t * vam)
12453 {
12454   unformat_input_t *i = vam->input;
12455   vl_api_geneve_tunnel_dump_t *mp;
12456   vl_api_control_ping_t *mp_ping;
12457   u32 sw_if_index;
12458   u8 sw_if_index_set = 0;
12459   int ret;
12460
12461   /* Parse args required to build the message */
12462   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12463     {
12464       if (unformat (i, "sw_if_index %d", &sw_if_index))
12465         sw_if_index_set = 1;
12466       else
12467         break;
12468     }
12469
12470   if (sw_if_index_set == 0)
12471     {
12472       sw_if_index = ~0;
12473     }
12474
12475   if (!vam->json_output)
12476     {
12477       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12478              "sw_if_index", "local_address", "remote_address",
12479              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12480     }
12481
12482   /* Get list of geneve-tunnel interfaces */
12483   M (GENEVE_TUNNEL_DUMP, mp);
12484
12485   mp->sw_if_index = htonl (sw_if_index);
12486
12487   S (mp);
12488
12489   /* Use a control ping for synchronization */
12490   M (CONTROL_PING, mp_ping);
12491   S (mp_ping);
12492
12493   W (ret);
12494   return ret;
12495 }
12496
12497 static int
12498 api_gre_add_del_tunnel (vat_main_t * vam)
12499 {
12500   unformat_input_t *line_input = vam->input;
12501   vl_api_gre_add_del_tunnel_t *mp;
12502   ip4_address_t src4, dst4;
12503   ip6_address_t src6, dst6;
12504   u8 is_add = 1;
12505   u8 ipv4_set = 0;
12506   u8 ipv6_set = 0;
12507   u8 teb = 0;
12508   u8 src_set = 0;
12509   u8 dst_set = 0;
12510   u32 outer_fib_id = 0;
12511   int ret;
12512
12513   memset (&src4, 0, sizeof src4);
12514   memset (&dst4, 0, sizeof dst4);
12515   memset (&src6, 0, sizeof src6);
12516   memset (&dst6, 0, sizeof dst6);
12517
12518   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12519     {
12520       if (unformat (line_input, "del"))
12521         is_add = 0;
12522       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
12523         {
12524           src_set = 1;
12525           ipv4_set = 1;
12526         }
12527       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
12528         {
12529           dst_set = 1;
12530           ipv4_set = 1;
12531         }
12532       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
12533         {
12534           src_set = 1;
12535           ipv6_set = 1;
12536         }
12537       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
12538         {
12539           dst_set = 1;
12540           ipv6_set = 1;
12541         }
12542       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
12543         ;
12544       else if (unformat (line_input, "teb"))
12545         teb = 1;
12546       else
12547         {
12548           errmsg ("parse error '%U'", format_unformat_error, line_input);
12549           return -99;
12550         }
12551     }
12552
12553   if (src_set == 0)
12554     {
12555       errmsg ("tunnel src address not specified");
12556       return -99;
12557     }
12558   if (dst_set == 0)
12559     {
12560       errmsg ("tunnel dst address not specified");
12561       return -99;
12562     }
12563   if (ipv4_set && ipv6_set)
12564     {
12565       errmsg ("both IPv4 and IPv6 addresses specified");
12566       return -99;
12567     }
12568
12569
12570   M (GRE_ADD_DEL_TUNNEL, mp);
12571
12572   if (ipv4_set)
12573     {
12574       clib_memcpy (&mp->src_address, &src4, 4);
12575       clib_memcpy (&mp->dst_address, &dst4, 4);
12576     }
12577   else
12578     {
12579       clib_memcpy (&mp->src_address, &src6, 16);
12580       clib_memcpy (&mp->dst_address, &dst6, 16);
12581     }
12582   mp->outer_fib_id = ntohl (outer_fib_id);
12583   mp->is_add = is_add;
12584   mp->teb = teb;
12585   mp->is_ipv6 = ipv6_set;
12586
12587   S (mp);
12588   W (ret);
12589   return ret;
12590 }
12591
12592 static void vl_api_gre_tunnel_details_t_handler
12593   (vl_api_gre_tunnel_details_t * mp)
12594 {
12595   vat_main_t *vam = &vat_main;
12596   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
12597   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
12598
12599   print (vam->ofp, "%11d%24U%24U%6d%14d",
12600          ntohl (mp->sw_if_index),
12601          format_ip46_address, &src, IP46_TYPE_ANY,
12602          format_ip46_address, &dst, IP46_TYPE_ANY,
12603          mp->teb, ntohl (mp->outer_fib_id));
12604 }
12605
12606 static void vl_api_gre_tunnel_details_t_handler_json
12607   (vl_api_gre_tunnel_details_t * mp)
12608 {
12609   vat_main_t *vam = &vat_main;
12610   vat_json_node_t *node = NULL;
12611   struct in_addr ip4;
12612   struct in6_addr ip6;
12613
12614   if (VAT_JSON_ARRAY != vam->json_tree.type)
12615     {
12616       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12617       vat_json_init_array (&vam->json_tree);
12618     }
12619   node = vat_json_array_add (&vam->json_tree);
12620
12621   vat_json_init_object (node);
12622   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12623   if (!mp->is_ipv6)
12624     {
12625       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
12626       vat_json_object_add_ip4 (node, "src_address", ip4);
12627       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
12628       vat_json_object_add_ip4 (node, "dst_address", ip4);
12629     }
12630   else
12631     {
12632       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
12633       vat_json_object_add_ip6 (node, "src_address", ip6);
12634       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
12635       vat_json_object_add_ip6 (node, "dst_address", ip6);
12636     }
12637   vat_json_object_add_uint (node, "teb", mp->teb);
12638   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
12639   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
12640 }
12641
12642 static int
12643 api_gre_tunnel_dump (vat_main_t * vam)
12644 {
12645   unformat_input_t *i = vam->input;
12646   vl_api_gre_tunnel_dump_t *mp;
12647   vl_api_control_ping_t *mp_ping;
12648   u32 sw_if_index;
12649   u8 sw_if_index_set = 0;
12650   int ret;
12651
12652   /* Parse args required to build the message */
12653   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12654     {
12655       if (unformat (i, "sw_if_index %d", &sw_if_index))
12656         sw_if_index_set = 1;
12657       else
12658         break;
12659     }
12660
12661   if (sw_if_index_set == 0)
12662     {
12663       sw_if_index = ~0;
12664     }
12665
12666   if (!vam->json_output)
12667     {
12668       print (vam->ofp, "%11s%24s%24s%6s%14s",
12669              "sw_if_index", "src_address", "dst_address", "teb",
12670              "outer_fib_id");
12671     }
12672
12673   /* Get list of gre-tunnel interfaces */
12674   M (GRE_TUNNEL_DUMP, mp);
12675
12676   mp->sw_if_index = htonl (sw_if_index);
12677
12678   S (mp);
12679
12680   /* Use a control ping for synchronization */
12681   MPING (CONTROL_PING, mp_ping);
12682   S (mp_ping);
12683
12684   W (ret);
12685   return ret;
12686 }
12687
12688 static int
12689 api_l2_fib_clear_table (vat_main_t * vam)
12690 {
12691 //  unformat_input_t * i = vam->input;
12692   vl_api_l2_fib_clear_table_t *mp;
12693   int ret;
12694
12695   M (L2_FIB_CLEAR_TABLE, mp);
12696
12697   S (mp);
12698   W (ret);
12699   return ret;
12700 }
12701
12702 static int
12703 api_l2_interface_efp_filter (vat_main_t * vam)
12704 {
12705   unformat_input_t *i = vam->input;
12706   vl_api_l2_interface_efp_filter_t *mp;
12707   u32 sw_if_index;
12708   u8 enable = 1;
12709   u8 sw_if_index_set = 0;
12710   int ret;
12711
12712   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12713     {
12714       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12715         sw_if_index_set = 1;
12716       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12717         sw_if_index_set = 1;
12718       else if (unformat (i, "enable"))
12719         enable = 1;
12720       else if (unformat (i, "disable"))
12721         enable = 0;
12722       else
12723         {
12724           clib_warning ("parse error '%U'", format_unformat_error, i);
12725           return -99;
12726         }
12727     }
12728
12729   if (sw_if_index_set == 0)
12730     {
12731       errmsg ("missing sw_if_index");
12732       return -99;
12733     }
12734
12735   M (L2_INTERFACE_EFP_FILTER, mp);
12736
12737   mp->sw_if_index = ntohl (sw_if_index);
12738   mp->enable_disable = enable;
12739
12740   S (mp);
12741   W (ret);
12742   return ret;
12743 }
12744
12745 #define foreach_vtr_op                          \
12746 _("disable",  L2_VTR_DISABLED)                  \
12747 _("push-1",  L2_VTR_PUSH_1)                     \
12748 _("push-2",  L2_VTR_PUSH_2)                     \
12749 _("pop-1",  L2_VTR_POP_1)                       \
12750 _("pop-2",  L2_VTR_POP_2)                       \
12751 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12752 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12753 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12754 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12755
12756 static int
12757 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12758 {
12759   unformat_input_t *i = vam->input;
12760   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12761   u32 sw_if_index;
12762   u8 sw_if_index_set = 0;
12763   u8 vtr_op_set = 0;
12764   u32 vtr_op = 0;
12765   u32 push_dot1q = 1;
12766   u32 tag1 = ~0;
12767   u32 tag2 = ~0;
12768   int ret;
12769
12770   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12771     {
12772       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12773         sw_if_index_set = 1;
12774       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12775         sw_if_index_set = 1;
12776       else if (unformat (i, "vtr_op %d", &vtr_op))
12777         vtr_op_set = 1;
12778 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12779       foreach_vtr_op
12780 #undef _
12781         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12782         ;
12783       else if (unformat (i, "tag1 %d", &tag1))
12784         ;
12785       else if (unformat (i, "tag2 %d", &tag2))
12786         ;
12787       else
12788         {
12789           clib_warning ("parse error '%U'", format_unformat_error, i);
12790           return -99;
12791         }
12792     }
12793
12794   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12795     {
12796       errmsg ("missing vtr operation or sw_if_index");
12797       return -99;
12798     }
12799
12800   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12801   mp->sw_if_index = ntohl (sw_if_index);
12802   mp->vtr_op = ntohl (vtr_op);
12803   mp->push_dot1q = ntohl (push_dot1q);
12804   mp->tag1 = ntohl (tag1);
12805   mp->tag2 = ntohl (tag2);
12806
12807   S (mp);
12808   W (ret);
12809   return ret;
12810 }
12811
12812 static int
12813 api_create_vhost_user_if (vat_main_t * vam)
12814 {
12815   unformat_input_t *i = vam->input;
12816   vl_api_create_vhost_user_if_t *mp;
12817   u8 *file_name;
12818   u8 is_server = 0;
12819   u8 file_name_set = 0;
12820   u32 custom_dev_instance = ~0;
12821   u8 hwaddr[6];
12822   u8 use_custom_mac = 0;
12823   u8 *tag = 0;
12824   int ret;
12825
12826   /* Shut up coverity */
12827   memset (hwaddr, 0, sizeof (hwaddr));
12828
12829   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12830     {
12831       if (unformat (i, "socket %s", &file_name))
12832         {
12833           file_name_set = 1;
12834         }
12835       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12836         ;
12837       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12838         use_custom_mac = 1;
12839       else if (unformat (i, "server"))
12840         is_server = 1;
12841       else if (unformat (i, "tag %s", &tag))
12842         ;
12843       else
12844         break;
12845     }
12846
12847   if (file_name_set == 0)
12848     {
12849       errmsg ("missing socket file name");
12850       return -99;
12851     }
12852
12853   if (vec_len (file_name) > 255)
12854     {
12855       errmsg ("socket file name too long");
12856       return -99;
12857     }
12858   vec_add1 (file_name, 0);
12859
12860   M (CREATE_VHOST_USER_IF, mp);
12861
12862   mp->is_server = is_server;
12863   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12864   vec_free (file_name);
12865   if (custom_dev_instance != ~0)
12866     {
12867       mp->renumber = 1;
12868       mp->custom_dev_instance = ntohl (custom_dev_instance);
12869     }
12870   mp->use_custom_mac = use_custom_mac;
12871   clib_memcpy (mp->mac_address, hwaddr, 6);
12872   if (tag)
12873     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12874   vec_free (tag);
12875
12876   S (mp);
12877   W (ret);
12878   return ret;
12879 }
12880
12881 static int
12882 api_modify_vhost_user_if (vat_main_t * vam)
12883 {
12884   unformat_input_t *i = vam->input;
12885   vl_api_modify_vhost_user_if_t *mp;
12886   u8 *file_name;
12887   u8 is_server = 0;
12888   u8 file_name_set = 0;
12889   u32 custom_dev_instance = ~0;
12890   u8 sw_if_index_set = 0;
12891   u32 sw_if_index = (u32) ~ 0;
12892   int ret;
12893
12894   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12895     {
12896       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12897         sw_if_index_set = 1;
12898       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12899         sw_if_index_set = 1;
12900       else if (unformat (i, "socket %s", &file_name))
12901         {
12902           file_name_set = 1;
12903         }
12904       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12905         ;
12906       else if (unformat (i, "server"))
12907         is_server = 1;
12908       else
12909         break;
12910     }
12911
12912   if (sw_if_index_set == 0)
12913     {
12914       errmsg ("missing sw_if_index or interface name");
12915       return -99;
12916     }
12917
12918   if (file_name_set == 0)
12919     {
12920       errmsg ("missing socket file name");
12921       return -99;
12922     }
12923
12924   if (vec_len (file_name) > 255)
12925     {
12926       errmsg ("socket file name too long");
12927       return -99;
12928     }
12929   vec_add1 (file_name, 0);
12930
12931   M (MODIFY_VHOST_USER_IF, mp);
12932
12933   mp->sw_if_index = ntohl (sw_if_index);
12934   mp->is_server = is_server;
12935   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12936   vec_free (file_name);
12937   if (custom_dev_instance != ~0)
12938     {
12939       mp->renumber = 1;
12940       mp->custom_dev_instance = ntohl (custom_dev_instance);
12941     }
12942
12943   S (mp);
12944   W (ret);
12945   return ret;
12946 }
12947
12948 static int
12949 api_delete_vhost_user_if (vat_main_t * vam)
12950 {
12951   unformat_input_t *i = vam->input;
12952   vl_api_delete_vhost_user_if_t *mp;
12953   u32 sw_if_index = ~0;
12954   u8 sw_if_index_set = 0;
12955   int ret;
12956
12957   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12958     {
12959       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12960         sw_if_index_set = 1;
12961       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12962         sw_if_index_set = 1;
12963       else
12964         break;
12965     }
12966
12967   if (sw_if_index_set == 0)
12968     {
12969       errmsg ("missing sw_if_index or interface name");
12970       return -99;
12971     }
12972
12973
12974   M (DELETE_VHOST_USER_IF, mp);
12975
12976   mp->sw_if_index = ntohl (sw_if_index);
12977
12978   S (mp);
12979   W (ret);
12980   return ret;
12981 }
12982
12983 static void vl_api_sw_interface_vhost_user_details_t_handler
12984   (vl_api_sw_interface_vhost_user_details_t * mp)
12985 {
12986   vat_main_t *vam = &vat_main;
12987
12988   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12989          (char *) mp->interface_name,
12990          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12991          clib_net_to_host_u64 (mp->features), mp->is_server,
12992          ntohl (mp->num_regions), (char *) mp->sock_filename);
12993   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12994 }
12995
12996 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12997   (vl_api_sw_interface_vhost_user_details_t * mp)
12998 {
12999   vat_main_t *vam = &vat_main;
13000   vat_json_node_t *node = NULL;
13001
13002   if (VAT_JSON_ARRAY != vam->json_tree.type)
13003     {
13004       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13005       vat_json_init_array (&vam->json_tree);
13006     }
13007   node = vat_json_array_add (&vam->json_tree);
13008
13009   vat_json_init_object (node);
13010   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13011   vat_json_object_add_string_copy (node, "interface_name",
13012                                    mp->interface_name);
13013   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13014                             ntohl (mp->virtio_net_hdr_sz));
13015   vat_json_object_add_uint (node, "features",
13016                             clib_net_to_host_u64 (mp->features));
13017   vat_json_object_add_uint (node, "is_server", mp->is_server);
13018   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13019   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13020   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13021 }
13022
13023 static int
13024 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13025 {
13026   vl_api_sw_interface_vhost_user_dump_t *mp;
13027   vl_api_control_ping_t *mp_ping;
13028   int ret;
13029   print (vam->ofp,
13030          "Interface name            idx hdr_sz features server regions filename");
13031
13032   /* Get list of vhost-user interfaces */
13033   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13034   S (mp);
13035
13036   /* Use a control ping for synchronization */
13037   MPING (CONTROL_PING, mp_ping);
13038   S (mp_ping);
13039
13040   W (ret);
13041   return ret;
13042 }
13043
13044 static int
13045 api_show_version (vat_main_t * vam)
13046 {
13047   vl_api_show_version_t *mp;
13048   int ret;
13049
13050   M (SHOW_VERSION, mp);
13051
13052   S (mp);
13053   W (ret);
13054   return ret;
13055 }
13056
13057
13058 static int
13059 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13060 {
13061   unformat_input_t *line_input = vam->input;
13062   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13063   ip4_address_t local4, remote4;
13064   ip6_address_t local6, remote6;
13065   u8 is_add = 1;
13066   u8 ipv4_set = 0, ipv6_set = 0;
13067   u8 local_set = 0;
13068   u8 remote_set = 0;
13069   u8 grp_set = 0;
13070   u32 mcast_sw_if_index = ~0;
13071   u32 encap_vrf_id = 0;
13072   u32 decap_vrf_id = 0;
13073   u8 protocol = ~0;
13074   u32 vni;
13075   u8 vni_set = 0;
13076   int ret;
13077
13078   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13079   memset (&local4, 0, sizeof local4);
13080   memset (&remote4, 0, sizeof remote4);
13081   memset (&local6, 0, sizeof local6);
13082   memset (&remote6, 0, sizeof remote6);
13083
13084   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13085     {
13086       if (unformat (line_input, "del"))
13087         is_add = 0;
13088       else if (unformat (line_input, "local %U",
13089                          unformat_ip4_address, &local4))
13090         {
13091           local_set = 1;
13092           ipv4_set = 1;
13093         }
13094       else if (unformat (line_input, "remote %U",
13095                          unformat_ip4_address, &remote4))
13096         {
13097           remote_set = 1;
13098           ipv4_set = 1;
13099         }
13100       else if (unformat (line_input, "local %U",
13101                          unformat_ip6_address, &local6))
13102         {
13103           local_set = 1;
13104           ipv6_set = 1;
13105         }
13106       else if (unformat (line_input, "remote %U",
13107                          unformat_ip6_address, &remote6))
13108         {
13109           remote_set = 1;
13110           ipv6_set = 1;
13111         }
13112       else if (unformat (line_input, "group %U %U",
13113                          unformat_ip4_address, &remote4,
13114                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13115         {
13116           grp_set = remote_set = 1;
13117           ipv4_set = 1;
13118         }
13119       else if (unformat (line_input, "group %U",
13120                          unformat_ip4_address, &remote4))
13121         {
13122           grp_set = remote_set = 1;
13123           ipv4_set = 1;
13124         }
13125       else if (unformat (line_input, "group %U %U",
13126                          unformat_ip6_address, &remote6,
13127                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13128         {
13129           grp_set = remote_set = 1;
13130           ipv6_set = 1;
13131         }
13132       else if (unformat (line_input, "group %U",
13133                          unformat_ip6_address, &remote6))
13134         {
13135           grp_set = remote_set = 1;
13136           ipv6_set = 1;
13137         }
13138       else
13139         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13140         ;
13141       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13142         ;
13143       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13144         ;
13145       else if (unformat (line_input, "vni %d", &vni))
13146         vni_set = 1;
13147       else if (unformat (line_input, "next-ip4"))
13148         protocol = 1;
13149       else if (unformat (line_input, "next-ip6"))
13150         protocol = 2;
13151       else if (unformat (line_input, "next-ethernet"))
13152         protocol = 3;
13153       else if (unformat (line_input, "next-nsh"))
13154         protocol = 4;
13155       else
13156         {
13157           errmsg ("parse error '%U'", format_unformat_error, line_input);
13158           return -99;
13159         }
13160     }
13161
13162   if (local_set == 0)
13163     {
13164       errmsg ("tunnel local address not specified");
13165       return -99;
13166     }
13167   if (remote_set == 0)
13168     {
13169       errmsg ("tunnel remote address not specified");
13170       return -99;
13171     }
13172   if (grp_set && mcast_sw_if_index == ~0)
13173     {
13174       errmsg ("tunnel nonexistent multicast device");
13175       return -99;
13176     }
13177   if (ipv4_set && ipv6_set)
13178     {
13179       errmsg ("both IPv4 and IPv6 addresses specified");
13180       return -99;
13181     }
13182
13183   if (vni_set == 0)
13184     {
13185       errmsg ("vni not specified");
13186       return -99;
13187     }
13188
13189   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13190
13191
13192   if (ipv6_set)
13193     {
13194       clib_memcpy (&mp->local, &local6, sizeof (local6));
13195       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13196     }
13197   else
13198     {
13199       clib_memcpy (&mp->local, &local4, sizeof (local4));
13200       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13201     }
13202
13203   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13204   mp->encap_vrf_id = ntohl (encap_vrf_id);
13205   mp->decap_vrf_id = ntohl (decap_vrf_id);
13206   mp->protocol = protocol;
13207   mp->vni = ntohl (vni);
13208   mp->is_add = is_add;
13209   mp->is_ipv6 = ipv6_set;
13210
13211   S (mp);
13212   W (ret);
13213   return ret;
13214 }
13215
13216 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13217   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13218 {
13219   vat_main_t *vam = &vat_main;
13220   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13221   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13222
13223   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13224          ntohl (mp->sw_if_index),
13225          format_ip46_address, &local, IP46_TYPE_ANY,
13226          format_ip46_address, &remote, IP46_TYPE_ANY,
13227          ntohl (mp->vni), mp->protocol,
13228          ntohl (mp->mcast_sw_if_index),
13229          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13230 }
13231
13232
13233 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13234   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13235 {
13236   vat_main_t *vam = &vat_main;
13237   vat_json_node_t *node = NULL;
13238   struct in_addr ip4;
13239   struct in6_addr ip6;
13240
13241   if (VAT_JSON_ARRAY != vam->json_tree.type)
13242     {
13243       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13244       vat_json_init_array (&vam->json_tree);
13245     }
13246   node = vat_json_array_add (&vam->json_tree);
13247
13248   vat_json_init_object (node);
13249   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13250   if (mp->is_ipv6)
13251     {
13252       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13253       vat_json_object_add_ip6 (node, "local", ip6);
13254       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13255       vat_json_object_add_ip6 (node, "remote", ip6);
13256     }
13257   else
13258     {
13259       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13260       vat_json_object_add_ip4 (node, "local", ip4);
13261       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13262       vat_json_object_add_ip4 (node, "remote", ip4);
13263     }
13264   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13265   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13266   vat_json_object_add_uint (node, "mcast_sw_if_index",
13267                             ntohl (mp->mcast_sw_if_index));
13268   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13269   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13270   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13271 }
13272
13273 static int
13274 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13275 {
13276   unformat_input_t *i = vam->input;
13277   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13278   vl_api_control_ping_t *mp_ping;
13279   u32 sw_if_index;
13280   u8 sw_if_index_set = 0;
13281   int ret;
13282
13283   /* Parse args required to build the message */
13284   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13285     {
13286       if (unformat (i, "sw_if_index %d", &sw_if_index))
13287         sw_if_index_set = 1;
13288       else
13289         break;
13290     }
13291
13292   if (sw_if_index_set == 0)
13293     {
13294       sw_if_index = ~0;
13295     }
13296
13297   if (!vam->json_output)
13298     {
13299       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13300              "sw_if_index", "local", "remote", "vni",
13301              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13302     }
13303
13304   /* Get list of vxlan-tunnel interfaces */
13305   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13306
13307   mp->sw_if_index = htonl (sw_if_index);
13308
13309   S (mp);
13310
13311   /* Use a control ping for synchronization */
13312   MPING (CONTROL_PING, mp_ping);
13313   S (mp_ping);
13314
13315   W (ret);
13316   return ret;
13317 }
13318
13319
13320 u8 *
13321 format_l2_fib_mac_address (u8 * s, va_list * args)
13322 {
13323   u8 *a = va_arg (*args, u8 *);
13324
13325   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
13326                  a[2], a[3], a[4], a[5], a[6], a[7]);
13327 }
13328
13329 static void vl_api_l2_fib_table_details_t_handler
13330   (vl_api_l2_fib_table_details_t * mp)
13331 {
13332   vat_main_t *vam = &vat_main;
13333
13334   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13335          "       %d       %d     %d",
13336          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
13337          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13338          mp->bvi_mac);
13339 }
13340
13341 static void vl_api_l2_fib_table_details_t_handler_json
13342   (vl_api_l2_fib_table_details_t * mp)
13343 {
13344   vat_main_t *vam = &vat_main;
13345   vat_json_node_t *node = NULL;
13346
13347   if (VAT_JSON_ARRAY != vam->json_tree.type)
13348     {
13349       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13350       vat_json_init_array (&vam->json_tree);
13351     }
13352   node = vat_json_array_add (&vam->json_tree);
13353
13354   vat_json_init_object (node);
13355   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13356   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
13357   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13358   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13359   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13360   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13361 }
13362
13363 static int
13364 api_l2_fib_table_dump (vat_main_t * vam)
13365 {
13366   unformat_input_t *i = vam->input;
13367   vl_api_l2_fib_table_dump_t *mp;
13368   vl_api_control_ping_t *mp_ping;
13369   u32 bd_id;
13370   u8 bd_id_set = 0;
13371   int ret;
13372
13373   /* Parse args required to build the message */
13374   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13375     {
13376       if (unformat (i, "bd_id %d", &bd_id))
13377         bd_id_set = 1;
13378       else
13379         break;
13380     }
13381
13382   if (bd_id_set == 0)
13383     {
13384       errmsg ("missing bridge domain");
13385       return -99;
13386     }
13387
13388   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13389
13390   /* Get list of l2 fib entries */
13391   M (L2_FIB_TABLE_DUMP, mp);
13392
13393   mp->bd_id = ntohl (bd_id);
13394   S (mp);
13395
13396   /* Use a control ping for synchronization */
13397   MPING (CONTROL_PING, mp_ping);
13398   S (mp_ping);
13399
13400   W (ret);
13401   return ret;
13402 }
13403
13404
13405 static int
13406 api_interface_name_renumber (vat_main_t * vam)
13407 {
13408   unformat_input_t *line_input = vam->input;
13409   vl_api_interface_name_renumber_t *mp;
13410   u32 sw_if_index = ~0;
13411   u32 new_show_dev_instance = ~0;
13412   int ret;
13413
13414   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13415     {
13416       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13417                     &sw_if_index))
13418         ;
13419       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13420         ;
13421       else if (unformat (line_input, "new_show_dev_instance %d",
13422                          &new_show_dev_instance))
13423         ;
13424       else
13425         break;
13426     }
13427
13428   if (sw_if_index == ~0)
13429     {
13430       errmsg ("missing interface name or sw_if_index");
13431       return -99;
13432     }
13433
13434   if (new_show_dev_instance == ~0)
13435     {
13436       errmsg ("missing new_show_dev_instance");
13437       return -99;
13438     }
13439
13440   M (INTERFACE_NAME_RENUMBER, mp);
13441
13442   mp->sw_if_index = ntohl (sw_if_index);
13443   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13444
13445   S (mp);
13446   W (ret);
13447   return ret;
13448 }
13449
13450 static int
13451 api_want_ip4_arp_events (vat_main_t * vam)
13452 {
13453   unformat_input_t *line_input = vam->input;
13454   vl_api_want_ip4_arp_events_t *mp;
13455   ip4_address_t address;
13456   int address_set = 0;
13457   u32 enable_disable = 1;
13458   int ret;
13459
13460   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13461     {
13462       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
13463         address_set = 1;
13464       else if (unformat (line_input, "del"))
13465         enable_disable = 0;
13466       else
13467         break;
13468     }
13469
13470   if (address_set == 0)
13471     {
13472       errmsg ("missing addresses");
13473       return -99;
13474     }
13475
13476   M (WANT_IP4_ARP_EVENTS, mp);
13477   mp->enable_disable = enable_disable;
13478   mp->pid = htonl (getpid ());
13479   mp->address = address.as_u32;
13480
13481   S (mp);
13482   W (ret);
13483   return ret;
13484 }
13485
13486 static int
13487 api_want_ip6_nd_events (vat_main_t * vam)
13488 {
13489   unformat_input_t *line_input = vam->input;
13490   vl_api_want_ip6_nd_events_t *mp;
13491   ip6_address_t address;
13492   int address_set = 0;
13493   u32 enable_disable = 1;
13494   int ret;
13495
13496   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13497     {
13498       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
13499         address_set = 1;
13500       else if (unformat (line_input, "del"))
13501         enable_disable = 0;
13502       else
13503         break;
13504     }
13505
13506   if (address_set == 0)
13507     {
13508       errmsg ("missing addresses");
13509       return -99;
13510     }
13511
13512   M (WANT_IP6_ND_EVENTS, mp);
13513   mp->enable_disable = enable_disable;
13514   mp->pid = htonl (getpid ());
13515   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
13516
13517   S (mp);
13518   W (ret);
13519   return ret;
13520 }
13521
13522 static int
13523 api_want_l2_macs_events (vat_main_t * vam)
13524 {
13525   unformat_input_t *line_input = vam->input;
13526   vl_api_want_l2_macs_events_t *mp;
13527   u8 enable_disable = 1;
13528   u32 scan_delay = 0;
13529   u32 max_macs_in_event = 0;
13530   u32 learn_limit = 0;
13531   int ret;
13532
13533   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13534     {
13535       if (unformat (line_input, "learn-limit %d", &learn_limit))
13536         ;
13537       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13538         ;
13539       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13540         ;
13541       else if (unformat (line_input, "disable"))
13542         enable_disable = 0;
13543       else
13544         break;
13545     }
13546
13547   M (WANT_L2_MACS_EVENTS, mp);
13548   mp->enable_disable = enable_disable;
13549   mp->pid = htonl (getpid ());
13550   mp->learn_limit = htonl (learn_limit);
13551   mp->scan_delay = (u8) scan_delay;
13552   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13553   S (mp);
13554   W (ret);
13555   return ret;
13556 }
13557
13558 static int
13559 api_input_acl_set_interface (vat_main_t * vam)
13560 {
13561   unformat_input_t *i = vam->input;
13562   vl_api_input_acl_set_interface_t *mp;
13563   u32 sw_if_index;
13564   int sw_if_index_set;
13565   u32 ip4_table_index = ~0;
13566   u32 ip6_table_index = ~0;
13567   u32 l2_table_index = ~0;
13568   u8 is_add = 1;
13569   int ret;
13570
13571   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13572     {
13573       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13574         sw_if_index_set = 1;
13575       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13576         sw_if_index_set = 1;
13577       else if (unformat (i, "del"))
13578         is_add = 0;
13579       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13580         ;
13581       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13582         ;
13583       else if (unformat (i, "l2-table %d", &l2_table_index))
13584         ;
13585       else
13586         {
13587           clib_warning ("parse error '%U'", format_unformat_error, i);
13588           return -99;
13589         }
13590     }
13591
13592   if (sw_if_index_set == 0)
13593     {
13594       errmsg ("missing interface name or sw_if_index");
13595       return -99;
13596     }
13597
13598   M (INPUT_ACL_SET_INTERFACE, mp);
13599
13600   mp->sw_if_index = ntohl (sw_if_index);
13601   mp->ip4_table_index = ntohl (ip4_table_index);
13602   mp->ip6_table_index = ntohl (ip6_table_index);
13603   mp->l2_table_index = ntohl (l2_table_index);
13604   mp->is_add = is_add;
13605
13606   S (mp);
13607   W (ret);
13608   return ret;
13609 }
13610
13611 static int
13612 api_ip_address_dump (vat_main_t * vam)
13613 {
13614   unformat_input_t *i = vam->input;
13615   vl_api_ip_address_dump_t *mp;
13616   vl_api_control_ping_t *mp_ping;
13617   u32 sw_if_index = ~0;
13618   u8 sw_if_index_set = 0;
13619   u8 ipv4_set = 0;
13620   u8 ipv6_set = 0;
13621   int ret;
13622
13623   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13624     {
13625       if (unformat (i, "sw_if_index %d", &sw_if_index))
13626         sw_if_index_set = 1;
13627       else
13628         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13629         sw_if_index_set = 1;
13630       else if (unformat (i, "ipv4"))
13631         ipv4_set = 1;
13632       else if (unformat (i, "ipv6"))
13633         ipv6_set = 1;
13634       else
13635         break;
13636     }
13637
13638   if (ipv4_set && ipv6_set)
13639     {
13640       errmsg ("ipv4 and ipv6 flags cannot be both set");
13641       return -99;
13642     }
13643
13644   if ((!ipv4_set) && (!ipv6_set))
13645     {
13646       errmsg ("no ipv4 nor ipv6 flag set");
13647       return -99;
13648     }
13649
13650   if (sw_if_index_set == 0)
13651     {
13652       errmsg ("missing interface name or sw_if_index");
13653       return -99;
13654     }
13655
13656   vam->current_sw_if_index = sw_if_index;
13657   vam->is_ipv6 = ipv6_set;
13658
13659   M (IP_ADDRESS_DUMP, mp);
13660   mp->sw_if_index = ntohl (sw_if_index);
13661   mp->is_ipv6 = ipv6_set;
13662   S (mp);
13663
13664   /* Use a control ping for synchronization */
13665   MPING (CONTROL_PING, mp_ping);
13666   S (mp_ping);
13667
13668   W (ret);
13669   return ret;
13670 }
13671
13672 static int
13673 api_ip_dump (vat_main_t * vam)
13674 {
13675   vl_api_ip_dump_t *mp;
13676   vl_api_control_ping_t *mp_ping;
13677   unformat_input_t *in = vam->input;
13678   int ipv4_set = 0;
13679   int ipv6_set = 0;
13680   int is_ipv6;
13681   int i;
13682   int ret;
13683
13684   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13685     {
13686       if (unformat (in, "ipv4"))
13687         ipv4_set = 1;
13688       else if (unformat (in, "ipv6"))
13689         ipv6_set = 1;
13690       else
13691         break;
13692     }
13693
13694   if (ipv4_set && ipv6_set)
13695     {
13696       errmsg ("ipv4 and ipv6 flags cannot be both set");
13697       return -99;
13698     }
13699
13700   if ((!ipv4_set) && (!ipv6_set))
13701     {
13702       errmsg ("no ipv4 nor ipv6 flag set");
13703       return -99;
13704     }
13705
13706   is_ipv6 = ipv6_set;
13707   vam->is_ipv6 = is_ipv6;
13708
13709   /* free old data */
13710   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13711     {
13712       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13713     }
13714   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13715
13716   M (IP_DUMP, mp);
13717   mp->is_ipv6 = ipv6_set;
13718   S (mp);
13719
13720   /* Use a control ping for synchronization */
13721   MPING (CONTROL_PING, mp_ping);
13722   S (mp_ping);
13723
13724   W (ret);
13725   return ret;
13726 }
13727
13728 static int
13729 api_ipsec_spd_add_del (vat_main_t * vam)
13730 {
13731   unformat_input_t *i = vam->input;
13732   vl_api_ipsec_spd_add_del_t *mp;
13733   u32 spd_id = ~0;
13734   u8 is_add = 1;
13735   int ret;
13736
13737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13738     {
13739       if (unformat (i, "spd_id %d", &spd_id))
13740         ;
13741       else if (unformat (i, "del"))
13742         is_add = 0;
13743       else
13744         {
13745           clib_warning ("parse error '%U'", format_unformat_error, i);
13746           return -99;
13747         }
13748     }
13749   if (spd_id == ~0)
13750     {
13751       errmsg ("spd_id must be set");
13752       return -99;
13753     }
13754
13755   M (IPSEC_SPD_ADD_DEL, mp);
13756
13757   mp->spd_id = ntohl (spd_id);
13758   mp->is_add = is_add;
13759
13760   S (mp);
13761   W (ret);
13762   return ret;
13763 }
13764
13765 static int
13766 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13767 {
13768   unformat_input_t *i = vam->input;
13769   vl_api_ipsec_interface_add_del_spd_t *mp;
13770   u32 sw_if_index;
13771   u8 sw_if_index_set = 0;
13772   u32 spd_id = (u32) ~ 0;
13773   u8 is_add = 1;
13774   int ret;
13775
13776   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13777     {
13778       if (unformat (i, "del"))
13779         is_add = 0;
13780       else if (unformat (i, "spd_id %d", &spd_id))
13781         ;
13782       else
13783         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13784         sw_if_index_set = 1;
13785       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13786         sw_if_index_set = 1;
13787       else
13788         {
13789           clib_warning ("parse error '%U'", format_unformat_error, i);
13790           return -99;
13791         }
13792
13793     }
13794
13795   if (spd_id == (u32) ~ 0)
13796     {
13797       errmsg ("spd_id must be set");
13798       return -99;
13799     }
13800
13801   if (sw_if_index_set == 0)
13802     {
13803       errmsg ("missing interface name or sw_if_index");
13804       return -99;
13805     }
13806
13807   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13808
13809   mp->spd_id = ntohl (spd_id);
13810   mp->sw_if_index = ntohl (sw_if_index);
13811   mp->is_add = is_add;
13812
13813   S (mp);
13814   W (ret);
13815   return ret;
13816 }
13817
13818 static int
13819 api_ipsec_spd_add_del_entry (vat_main_t * vam)
13820 {
13821   unformat_input_t *i = vam->input;
13822   vl_api_ipsec_spd_add_del_entry_t *mp;
13823   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
13824   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13825   i32 priority = 0;
13826   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13827   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13828   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
13829   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
13830   int ret;
13831
13832   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
13833   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
13834   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
13835   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
13836   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
13837   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
13838
13839   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13840     {
13841       if (unformat (i, "del"))
13842         is_add = 0;
13843       if (unformat (i, "outbound"))
13844         is_outbound = 1;
13845       if (unformat (i, "inbound"))
13846         is_outbound = 0;
13847       else if (unformat (i, "spd_id %d", &spd_id))
13848         ;
13849       else if (unformat (i, "sa_id %d", &sa_id))
13850         ;
13851       else if (unformat (i, "priority %d", &priority))
13852         ;
13853       else if (unformat (i, "protocol %d", &protocol))
13854         ;
13855       else if (unformat (i, "lport_start %d", &lport_start))
13856         ;
13857       else if (unformat (i, "lport_stop %d", &lport_stop))
13858         ;
13859       else if (unformat (i, "rport_start %d", &rport_start))
13860         ;
13861       else if (unformat (i, "rport_stop %d", &rport_stop))
13862         ;
13863       else
13864         if (unformat
13865             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
13866         {
13867           is_ipv6 = 0;
13868           is_ip_any = 0;
13869         }
13870       else
13871         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
13872         {
13873           is_ipv6 = 0;
13874           is_ip_any = 0;
13875         }
13876       else
13877         if (unformat
13878             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
13879         {
13880           is_ipv6 = 0;
13881           is_ip_any = 0;
13882         }
13883       else
13884         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
13885         {
13886           is_ipv6 = 0;
13887           is_ip_any = 0;
13888         }
13889       else
13890         if (unformat
13891             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
13892         {
13893           is_ipv6 = 1;
13894           is_ip_any = 0;
13895         }
13896       else
13897         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
13898         {
13899           is_ipv6 = 1;
13900           is_ip_any = 0;
13901         }
13902       else
13903         if (unformat
13904             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
13905         {
13906           is_ipv6 = 1;
13907           is_ip_any = 0;
13908         }
13909       else
13910         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
13911         {
13912           is_ipv6 = 1;
13913           is_ip_any = 0;
13914         }
13915       else
13916         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13917         {
13918           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13919             {
13920               clib_warning ("unsupported action: 'resolve'");
13921               return -99;
13922             }
13923         }
13924       else
13925         {
13926           clib_warning ("parse error '%U'", format_unformat_error, i);
13927           return -99;
13928         }
13929
13930     }
13931
13932   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
13933
13934   mp->spd_id = ntohl (spd_id);
13935   mp->priority = ntohl (priority);
13936   mp->is_outbound = is_outbound;
13937
13938   mp->is_ipv6 = is_ipv6;
13939   if (is_ipv6 || is_ip_any)
13940     {
13941       clib_memcpy (mp->remote_address_start, &raddr6_start,
13942                    sizeof (ip6_address_t));
13943       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
13944                    sizeof (ip6_address_t));
13945       clib_memcpy (mp->local_address_start, &laddr6_start,
13946                    sizeof (ip6_address_t));
13947       clib_memcpy (mp->local_address_stop, &laddr6_stop,
13948                    sizeof (ip6_address_t));
13949     }
13950   else
13951     {
13952       clib_memcpy (mp->remote_address_start, &raddr4_start,
13953                    sizeof (ip4_address_t));
13954       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
13955                    sizeof (ip4_address_t));
13956       clib_memcpy (mp->local_address_start, &laddr4_start,
13957                    sizeof (ip4_address_t));
13958       clib_memcpy (mp->local_address_stop, &laddr4_stop,
13959                    sizeof (ip4_address_t));
13960     }
13961   mp->protocol = (u8) protocol;
13962   mp->local_port_start = ntohs ((u16) lport_start);
13963   mp->local_port_stop = ntohs ((u16) lport_stop);
13964   mp->remote_port_start = ntohs ((u16) rport_start);
13965   mp->remote_port_stop = ntohs ((u16) rport_stop);
13966   mp->policy = (u8) policy;
13967   mp->sa_id = ntohl (sa_id);
13968   mp->is_add = is_add;
13969   mp->is_ip_any = is_ip_any;
13970   S (mp);
13971   W (ret);
13972   return ret;
13973 }
13974
13975 static int
13976 api_ipsec_sad_add_del_entry (vat_main_t * vam)
13977 {
13978   unformat_input_t *i = vam->input;
13979   vl_api_ipsec_sad_add_del_entry_t *mp;
13980   u32 sad_id = 0, spi = 0;
13981   u8 *ck = 0, *ik = 0;
13982   u8 is_add = 1;
13983
13984   u8 protocol = IPSEC_PROTOCOL_AH;
13985   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
13986   u32 crypto_alg = 0, integ_alg = 0;
13987   ip4_address_t tun_src4;
13988   ip4_address_t tun_dst4;
13989   ip6_address_t tun_src6;
13990   ip6_address_t tun_dst6;
13991   int ret;
13992
13993   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13994     {
13995       if (unformat (i, "del"))
13996         is_add = 0;
13997       else if (unformat (i, "sad_id %d", &sad_id))
13998         ;
13999       else if (unformat (i, "spi %d", &spi))
14000         ;
14001       else if (unformat (i, "esp"))
14002         protocol = IPSEC_PROTOCOL_ESP;
14003       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
14004         {
14005           is_tunnel = 1;
14006           is_tunnel_ipv6 = 0;
14007         }
14008       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
14009         {
14010           is_tunnel = 1;
14011           is_tunnel_ipv6 = 0;
14012         }
14013       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
14014         {
14015           is_tunnel = 1;
14016           is_tunnel_ipv6 = 1;
14017         }
14018       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
14019         {
14020           is_tunnel = 1;
14021           is_tunnel_ipv6 = 1;
14022         }
14023       else
14024         if (unformat
14025             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14026         {
14027           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14028               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14029             {
14030               clib_warning ("unsupported crypto-alg: '%U'",
14031                             format_ipsec_crypto_alg, crypto_alg);
14032               return -99;
14033             }
14034         }
14035       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14036         ;
14037       else
14038         if (unformat
14039             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14040         {
14041           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14042               integ_alg >= IPSEC_INTEG_N_ALG)
14043             {
14044               clib_warning ("unsupported integ-alg: '%U'",
14045                             format_ipsec_integ_alg, integ_alg);
14046               return -99;
14047             }
14048         }
14049       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14050         ;
14051       else
14052         {
14053           clib_warning ("parse error '%U'", format_unformat_error, i);
14054           return -99;
14055         }
14056
14057     }
14058
14059   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
14060
14061   mp->sad_id = ntohl (sad_id);
14062   mp->is_add = is_add;
14063   mp->protocol = protocol;
14064   mp->spi = ntohl (spi);
14065   mp->is_tunnel = is_tunnel;
14066   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
14067   mp->crypto_algorithm = crypto_alg;
14068   mp->integrity_algorithm = integ_alg;
14069   mp->crypto_key_length = vec_len (ck);
14070   mp->integrity_key_length = vec_len (ik);
14071
14072   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14073     mp->crypto_key_length = sizeof (mp->crypto_key);
14074
14075   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14076     mp->integrity_key_length = sizeof (mp->integrity_key);
14077
14078   if (ck)
14079     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14080   if (ik)
14081     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14082
14083   if (is_tunnel)
14084     {
14085       if (is_tunnel_ipv6)
14086         {
14087           clib_memcpy (mp->tunnel_src_address, &tun_src6,
14088                        sizeof (ip6_address_t));
14089           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
14090                        sizeof (ip6_address_t));
14091         }
14092       else
14093         {
14094           clib_memcpy (mp->tunnel_src_address, &tun_src4,
14095                        sizeof (ip4_address_t));
14096           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
14097                        sizeof (ip4_address_t));
14098         }
14099     }
14100
14101   S (mp);
14102   W (ret);
14103   return ret;
14104 }
14105
14106 static int
14107 api_ipsec_sa_set_key (vat_main_t * vam)
14108 {
14109   unformat_input_t *i = vam->input;
14110   vl_api_ipsec_sa_set_key_t *mp;
14111   u32 sa_id;
14112   u8 *ck = 0, *ik = 0;
14113   int ret;
14114
14115   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14116     {
14117       if (unformat (i, "sa_id %d", &sa_id))
14118         ;
14119       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14120         ;
14121       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14122         ;
14123       else
14124         {
14125           clib_warning ("parse error '%U'", format_unformat_error, i);
14126           return -99;
14127         }
14128     }
14129
14130   M (IPSEC_SA_SET_KEY, mp);
14131
14132   mp->sa_id = ntohl (sa_id);
14133   mp->crypto_key_length = vec_len (ck);
14134   mp->integrity_key_length = vec_len (ik);
14135
14136   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14137     mp->crypto_key_length = sizeof (mp->crypto_key);
14138
14139   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14140     mp->integrity_key_length = sizeof (mp->integrity_key);
14141
14142   if (ck)
14143     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14144   if (ik)
14145     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14146
14147   S (mp);
14148   W (ret);
14149   return ret;
14150 }
14151
14152 static int
14153 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14154 {
14155   unformat_input_t *i = vam->input;
14156   vl_api_ipsec_tunnel_if_add_del_t *mp;
14157   u32 local_spi = 0, remote_spi = 0;
14158   u32 crypto_alg = 0, integ_alg = 0;
14159   u8 *lck = NULL, *rck = NULL;
14160   u8 *lik = NULL, *rik = NULL;
14161   ip4_address_t local_ip = { {0} };
14162   ip4_address_t remote_ip = { {0} };
14163   u8 is_add = 1;
14164   u8 esn = 0;
14165   u8 anti_replay = 0;
14166   int ret;
14167
14168   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14169     {
14170       if (unformat (i, "del"))
14171         is_add = 0;
14172       else if (unformat (i, "esn"))
14173         esn = 1;
14174       else if (unformat (i, "anti_replay"))
14175         anti_replay = 1;
14176       else if (unformat (i, "local_spi %d", &local_spi))
14177         ;
14178       else if (unformat (i, "remote_spi %d", &remote_spi))
14179         ;
14180       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
14181         ;
14182       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
14183         ;
14184       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14185         ;
14186       else
14187         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14188         ;
14189       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14190         ;
14191       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14192         ;
14193       else
14194         if (unformat
14195             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14196         {
14197           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14198               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14199             {
14200               errmsg ("unsupported crypto-alg: '%U'\n",
14201                       format_ipsec_crypto_alg, crypto_alg);
14202               return -99;
14203             }
14204         }
14205       else
14206         if (unformat
14207             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14208         {
14209           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14210               integ_alg >= IPSEC_INTEG_N_ALG)
14211             {
14212               errmsg ("unsupported integ-alg: '%U'\n",
14213                       format_ipsec_integ_alg, integ_alg);
14214               return -99;
14215             }
14216         }
14217       else
14218         {
14219           errmsg ("parse error '%U'\n", format_unformat_error, i);
14220           return -99;
14221         }
14222     }
14223
14224   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14225
14226   mp->is_add = is_add;
14227   mp->esn = esn;
14228   mp->anti_replay = anti_replay;
14229
14230   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
14231   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
14232
14233   mp->local_spi = htonl (local_spi);
14234   mp->remote_spi = htonl (remote_spi);
14235   mp->crypto_alg = (u8) crypto_alg;
14236
14237   mp->local_crypto_key_len = 0;
14238   if (lck)
14239     {
14240       mp->local_crypto_key_len = vec_len (lck);
14241       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14242         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14243       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14244     }
14245
14246   mp->remote_crypto_key_len = 0;
14247   if (rck)
14248     {
14249       mp->remote_crypto_key_len = vec_len (rck);
14250       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14251         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14252       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14253     }
14254
14255   mp->integ_alg = (u8) integ_alg;
14256
14257   mp->local_integ_key_len = 0;
14258   if (lik)
14259     {
14260       mp->local_integ_key_len = vec_len (lik);
14261       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14262         mp->local_integ_key_len = sizeof (mp->local_integ_key);
14263       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14264     }
14265
14266   mp->remote_integ_key_len = 0;
14267   if (rik)
14268     {
14269       mp->remote_integ_key_len = vec_len (rik);
14270       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14271         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14272       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14273     }
14274
14275   S (mp);
14276   W (ret);
14277   return ret;
14278 }
14279
14280 static void
14281 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14282 {
14283   vat_main_t *vam = &vat_main;
14284
14285   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14286          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
14287          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
14288          "tunnel_src_addr %U tunnel_dst_addr %U "
14289          "salt %u seq_outbound %lu last_seq_inbound %lu "
14290          "replay_window %lu total_data_size %lu\n",
14291          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
14292          mp->protocol,
14293          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
14294          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
14295          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
14296          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14297          mp->tunnel_src_addr,
14298          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14299          mp->tunnel_dst_addr,
14300          ntohl (mp->salt),
14301          clib_net_to_host_u64 (mp->seq_outbound),
14302          clib_net_to_host_u64 (mp->last_seq_inbound),
14303          clib_net_to_host_u64 (mp->replay_window),
14304          clib_net_to_host_u64 (mp->total_data_size));
14305 }
14306
14307 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14308 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14309
14310 static void vl_api_ipsec_sa_details_t_handler_json
14311   (vl_api_ipsec_sa_details_t * mp)
14312 {
14313   vat_main_t *vam = &vat_main;
14314   vat_json_node_t *node = NULL;
14315   struct in_addr src_ip4, dst_ip4;
14316   struct in6_addr src_ip6, dst_ip6;
14317
14318   if (VAT_JSON_ARRAY != vam->json_tree.type)
14319     {
14320       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14321       vat_json_init_array (&vam->json_tree);
14322     }
14323   node = vat_json_array_add (&vam->json_tree);
14324
14325   vat_json_init_object (node);
14326   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
14327   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14328   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
14329   vat_json_object_add_uint (node, "proto", mp->protocol);
14330   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
14331   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
14332   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
14333   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
14334   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
14335   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
14336   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
14337                              mp->crypto_key_len);
14338   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
14339                              mp->integ_key_len);
14340   if (mp->is_tunnel_ip6)
14341     {
14342       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
14343       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
14344       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
14345       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
14346     }
14347   else
14348     {
14349       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
14350       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
14351       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
14352       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
14353     }
14354   vat_json_object_add_uint (node, "replay_window",
14355                             clib_net_to_host_u64 (mp->replay_window));
14356   vat_json_object_add_uint (node, "total_data_size",
14357                             clib_net_to_host_u64 (mp->total_data_size));
14358
14359 }
14360
14361 static int
14362 api_ipsec_sa_dump (vat_main_t * vam)
14363 {
14364   unformat_input_t *i = vam->input;
14365   vl_api_ipsec_sa_dump_t *mp;
14366   vl_api_control_ping_t *mp_ping;
14367   u32 sa_id = ~0;
14368   int ret;
14369
14370   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14371     {
14372       if (unformat (i, "sa_id %d", &sa_id))
14373         ;
14374       else
14375         {
14376           clib_warning ("parse error '%U'", format_unformat_error, i);
14377           return -99;
14378         }
14379     }
14380
14381   M (IPSEC_SA_DUMP, mp);
14382
14383   mp->sa_id = ntohl (sa_id);
14384
14385   S (mp);
14386
14387   /* Use a control ping for synchronization */
14388   M (CONTROL_PING, mp_ping);
14389   S (mp_ping);
14390
14391   W (ret);
14392   return ret;
14393 }
14394
14395 static int
14396 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
14397 {
14398   unformat_input_t *i = vam->input;
14399   vl_api_ipsec_tunnel_if_set_key_t *mp;
14400   u32 sw_if_index = ~0;
14401   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
14402   u8 *key = 0;
14403   u32 alg = ~0;
14404   int ret;
14405
14406   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14407     {
14408       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14409         ;
14410       else
14411         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
14412         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
14413       else
14414         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
14415         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
14416       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
14417         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
14418       else
14419         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
14420         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
14421       else if (unformat (i, "%U", unformat_hex_string, &key))
14422         ;
14423       else
14424         {
14425           clib_warning ("parse error '%U'", format_unformat_error, i);
14426           return -99;
14427         }
14428     }
14429
14430   if (sw_if_index == ~0)
14431     {
14432       errmsg ("interface must be specified");
14433       return -99;
14434     }
14435
14436   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
14437     {
14438       errmsg ("key type must be specified");
14439       return -99;
14440     }
14441
14442   if (alg == ~0)
14443     {
14444       errmsg ("algorithm must be specified");
14445       return -99;
14446     }
14447
14448   if (vec_len (key) == 0)
14449     {
14450       errmsg ("key must be specified");
14451       return -99;
14452     }
14453
14454   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
14455
14456   mp->sw_if_index = htonl (sw_if_index);
14457   mp->alg = alg;
14458   mp->key_type = key_type;
14459   mp->key_len = vec_len (key);
14460   clib_memcpy (mp->key, key, vec_len (key));
14461
14462   S (mp);
14463   W (ret);
14464
14465   return ret;
14466 }
14467
14468 static int
14469 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14470 {
14471   unformat_input_t *i = vam->input;
14472   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14473   u32 sw_if_index = ~0;
14474   u32 sa_id = ~0;
14475   u8 is_outbound = (u8) ~ 0;
14476   int ret;
14477
14478   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14479     {
14480       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14481         ;
14482       else if (unformat (i, "sa_id %d", &sa_id))
14483         ;
14484       else if (unformat (i, "outbound"))
14485         is_outbound = 1;
14486       else if (unformat (i, "inbound"))
14487         is_outbound = 0;
14488       else
14489         {
14490           clib_warning ("parse error '%U'", format_unformat_error, i);
14491           return -99;
14492         }
14493     }
14494
14495   if (sw_if_index == ~0)
14496     {
14497       errmsg ("interface must be specified");
14498       return -99;
14499     }
14500
14501   if (sa_id == ~0)
14502     {
14503       errmsg ("SA ID must be specified");
14504       return -99;
14505     }
14506
14507   M (IPSEC_TUNNEL_IF_SET_SA, mp);
14508
14509   mp->sw_if_index = htonl (sw_if_index);
14510   mp->sa_id = htonl (sa_id);
14511   mp->is_outbound = is_outbound;
14512
14513   S (mp);
14514   W (ret);
14515
14516   return ret;
14517 }
14518
14519 static int
14520 api_ikev2_profile_add_del (vat_main_t * vam)
14521 {
14522   unformat_input_t *i = vam->input;
14523   vl_api_ikev2_profile_add_del_t *mp;
14524   u8 is_add = 1;
14525   u8 *name = 0;
14526   int ret;
14527
14528   const char *valid_chars = "a-zA-Z0-9_";
14529
14530   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14531     {
14532       if (unformat (i, "del"))
14533         is_add = 0;
14534       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14535         vec_add1 (name, 0);
14536       else
14537         {
14538           errmsg ("parse error '%U'", format_unformat_error, i);
14539           return -99;
14540         }
14541     }
14542
14543   if (!vec_len (name))
14544     {
14545       errmsg ("profile name must be specified");
14546       return -99;
14547     }
14548
14549   if (vec_len (name) > 64)
14550     {
14551       errmsg ("profile name too long");
14552       return -99;
14553     }
14554
14555   M (IKEV2_PROFILE_ADD_DEL, mp);
14556
14557   clib_memcpy (mp->name, name, vec_len (name));
14558   mp->is_add = is_add;
14559   vec_free (name);
14560
14561   S (mp);
14562   W (ret);
14563   return ret;
14564 }
14565
14566 static int
14567 api_ikev2_profile_set_auth (vat_main_t * vam)
14568 {
14569   unformat_input_t *i = vam->input;
14570   vl_api_ikev2_profile_set_auth_t *mp;
14571   u8 *name = 0;
14572   u8 *data = 0;
14573   u32 auth_method = 0;
14574   u8 is_hex = 0;
14575   int ret;
14576
14577   const char *valid_chars = "a-zA-Z0-9_";
14578
14579   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14580     {
14581       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14582         vec_add1 (name, 0);
14583       else if (unformat (i, "auth_method %U",
14584                          unformat_ikev2_auth_method, &auth_method))
14585         ;
14586       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
14587         is_hex = 1;
14588       else if (unformat (i, "auth_data %v", &data))
14589         ;
14590       else
14591         {
14592           errmsg ("parse error '%U'", format_unformat_error, i);
14593           return -99;
14594         }
14595     }
14596
14597   if (!vec_len (name))
14598     {
14599       errmsg ("profile name must be specified");
14600       return -99;
14601     }
14602
14603   if (vec_len (name) > 64)
14604     {
14605       errmsg ("profile name too long");
14606       return -99;
14607     }
14608
14609   if (!vec_len (data))
14610     {
14611       errmsg ("auth_data must be specified");
14612       return -99;
14613     }
14614
14615   if (!auth_method)
14616     {
14617       errmsg ("auth_method must be specified");
14618       return -99;
14619     }
14620
14621   M (IKEV2_PROFILE_SET_AUTH, mp);
14622
14623   mp->is_hex = is_hex;
14624   mp->auth_method = (u8) auth_method;
14625   mp->data_len = vec_len (data);
14626   clib_memcpy (mp->name, name, vec_len (name));
14627   clib_memcpy (mp->data, data, vec_len (data));
14628   vec_free (name);
14629   vec_free (data);
14630
14631   S (mp);
14632   W (ret);
14633   return ret;
14634 }
14635
14636 static int
14637 api_ikev2_profile_set_id (vat_main_t * vam)
14638 {
14639   unformat_input_t *i = vam->input;
14640   vl_api_ikev2_profile_set_id_t *mp;
14641   u8 *name = 0;
14642   u8 *data = 0;
14643   u8 is_local = 0;
14644   u32 id_type = 0;
14645   ip4_address_t ip4;
14646   int ret;
14647
14648   const char *valid_chars = "a-zA-Z0-9_";
14649
14650   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14651     {
14652       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14653         vec_add1 (name, 0);
14654       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
14655         ;
14656       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
14657         {
14658           data = vec_new (u8, 4);
14659           clib_memcpy (data, ip4.as_u8, 4);
14660         }
14661       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
14662         ;
14663       else if (unformat (i, "id_data %v", &data))
14664         ;
14665       else if (unformat (i, "local"))
14666         is_local = 1;
14667       else if (unformat (i, "remote"))
14668         is_local = 0;
14669       else
14670         {
14671           errmsg ("parse error '%U'", format_unformat_error, i);
14672           return -99;
14673         }
14674     }
14675
14676   if (!vec_len (name))
14677     {
14678       errmsg ("profile name must be specified");
14679       return -99;
14680     }
14681
14682   if (vec_len (name) > 64)
14683     {
14684       errmsg ("profile name too long");
14685       return -99;
14686     }
14687
14688   if (!vec_len (data))
14689     {
14690       errmsg ("id_data must be specified");
14691       return -99;
14692     }
14693
14694   if (!id_type)
14695     {
14696       errmsg ("id_type must be specified");
14697       return -99;
14698     }
14699
14700   M (IKEV2_PROFILE_SET_ID, mp);
14701
14702   mp->is_local = is_local;
14703   mp->id_type = (u8) id_type;
14704   mp->data_len = vec_len (data);
14705   clib_memcpy (mp->name, name, vec_len (name));
14706   clib_memcpy (mp->data, data, vec_len (data));
14707   vec_free (name);
14708   vec_free (data);
14709
14710   S (mp);
14711   W (ret);
14712   return ret;
14713 }
14714
14715 static int
14716 api_ikev2_profile_set_ts (vat_main_t * vam)
14717 {
14718   unformat_input_t *i = vam->input;
14719   vl_api_ikev2_profile_set_ts_t *mp;
14720   u8 *name = 0;
14721   u8 is_local = 0;
14722   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
14723   ip4_address_t start_addr, end_addr;
14724
14725   const char *valid_chars = "a-zA-Z0-9_";
14726   int ret;
14727
14728   start_addr.as_u32 = 0;
14729   end_addr.as_u32 = (u32) ~ 0;
14730
14731   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14732     {
14733       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14734         vec_add1 (name, 0);
14735       else if (unformat (i, "protocol %d", &proto))
14736         ;
14737       else if (unformat (i, "start_port %d", &start_port))
14738         ;
14739       else if (unformat (i, "end_port %d", &end_port))
14740         ;
14741       else
14742         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
14743         ;
14744       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
14745         ;
14746       else if (unformat (i, "local"))
14747         is_local = 1;
14748       else if (unformat (i, "remote"))
14749         is_local = 0;
14750       else
14751         {
14752           errmsg ("parse error '%U'", format_unformat_error, i);
14753           return -99;
14754         }
14755     }
14756
14757   if (!vec_len (name))
14758     {
14759       errmsg ("profile name must be specified");
14760       return -99;
14761     }
14762
14763   if (vec_len (name) > 64)
14764     {
14765       errmsg ("profile name too long");
14766       return -99;
14767     }
14768
14769   M (IKEV2_PROFILE_SET_TS, mp);
14770
14771   mp->is_local = is_local;
14772   mp->proto = (u8) proto;
14773   mp->start_port = (u16) start_port;
14774   mp->end_port = (u16) end_port;
14775   mp->start_addr = start_addr.as_u32;
14776   mp->end_addr = end_addr.as_u32;
14777   clib_memcpy (mp->name, name, vec_len (name));
14778   vec_free (name);
14779
14780   S (mp);
14781   W (ret);
14782   return ret;
14783 }
14784
14785 static int
14786 api_ikev2_set_local_key (vat_main_t * vam)
14787 {
14788   unformat_input_t *i = vam->input;
14789   vl_api_ikev2_set_local_key_t *mp;
14790   u8 *file = 0;
14791   int ret;
14792
14793   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14794     {
14795       if (unformat (i, "file %v", &file))
14796         vec_add1 (file, 0);
14797       else
14798         {
14799           errmsg ("parse error '%U'", format_unformat_error, i);
14800           return -99;
14801         }
14802     }
14803
14804   if (!vec_len (file))
14805     {
14806       errmsg ("RSA key file must be specified");
14807       return -99;
14808     }
14809
14810   if (vec_len (file) > 256)
14811     {
14812       errmsg ("file name too long");
14813       return -99;
14814     }
14815
14816   M (IKEV2_SET_LOCAL_KEY, mp);
14817
14818   clib_memcpy (mp->key_file, file, vec_len (file));
14819   vec_free (file);
14820
14821   S (mp);
14822   W (ret);
14823   return ret;
14824 }
14825
14826 static int
14827 api_ikev2_set_responder (vat_main_t * vam)
14828 {
14829   unformat_input_t *i = vam->input;
14830   vl_api_ikev2_set_responder_t *mp;
14831   int ret;
14832   u8 *name = 0;
14833   u32 sw_if_index = ~0;
14834   ip4_address_t address;
14835
14836   const char *valid_chars = "a-zA-Z0-9_";
14837
14838   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14839     {
14840       if (unformat
14841           (i, "%U interface %d address %U", unformat_token, valid_chars,
14842            &name, &sw_if_index, unformat_ip4_address, &address))
14843         vec_add1 (name, 0);
14844       else
14845         {
14846           errmsg ("parse error '%U'", format_unformat_error, i);
14847           return -99;
14848         }
14849     }
14850
14851   if (!vec_len (name))
14852     {
14853       errmsg ("profile name must be specified");
14854       return -99;
14855     }
14856
14857   if (vec_len (name) > 64)
14858     {
14859       errmsg ("profile name too long");
14860       return -99;
14861     }
14862
14863   M (IKEV2_SET_RESPONDER, mp);
14864
14865   clib_memcpy (mp->name, name, vec_len (name));
14866   vec_free (name);
14867
14868   mp->sw_if_index = sw_if_index;
14869   clib_memcpy (mp->address, &address, sizeof (address));
14870
14871   S (mp);
14872   W (ret);
14873   return ret;
14874 }
14875
14876 static int
14877 api_ikev2_set_ike_transforms (vat_main_t * vam)
14878 {
14879   unformat_input_t *i = vam->input;
14880   vl_api_ikev2_set_ike_transforms_t *mp;
14881   int ret;
14882   u8 *name = 0;
14883   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
14884
14885   const char *valid_chars = "a-zA-Z0-9_";
14886
14887   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14888     {
14889       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
14890                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
14891         vec_add1 (name, 0);
14892       else
14893         {
14894           errmsg ("parse error '%U'", format_unformat_error, i);
14895           return -99;
14896         }
14897     }
14898
14899   if (!vec_len (name))
14900     {
14901       errmsg ("profile name must be specified");
14902       return -99;
14903     }
14904
14905   if (vec_len (name) > 64)
14906     {
14907       errmsg ("profile name too long");
14908       return -99;
14909     }
14910
14911   M (IKEV2_SET_IKE_TRANSFORMS, mp);
14912
14913   clib_memcpy (mp->name, name, vec_len (name));
14914   vec_free (name);
14915   mp->crypto_alg = crypto_alg;
14916   mp->crypto_key_size = crypto_key_size;
14917   mp->integ_alg = integ_alg;
14918   mp->dh_group = dh_group;
14919
14920   S (mp);
14921   W (ret);
14922   return ret;
14923 }
14924
14925
14926 static int
14927 api_ikev2_set_esp_transforms (vat_main_t * vam)
14928 {
14929   unformat_input_t *i = vam->input;
14930   vl_api_ikev2_set_esp_transforms_t *mp;
14931   int ret;
14932   u8 *name = 0;
14933   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
14934
14935   const char *valid_chars = "a-zA-Z0-9_";
14936
14937   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14938     {
14939       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
14940                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
14941         vec_add1 (name, 0);
14942       else
14943         {
14944           errmsg ("parse error '%U'", format_unformat_error, i);
14945           return -99;
14946         }
14947     }
14948
14949   if (!vec_len (name))
14950     {
14951       errmsg ("profile name must be specified");
14952       return -99;
14953     }
14954
14955   if (vec_len (name) > 64)
14956     {
14957       errmsg ("profile name too long");
14958       return -99;
14959     }
14960
14961   M (IKEV2_SET_ESP_TRANSFORMS, mp);
14962
14963   clib_memcpy (mp->name, name, vec_len (name));
14964   vec_free (name);
14965   mp->crypto_alg = crypto_alg;
14966   mp->crypto_key_size = crypto_key_size;
14967   mp->integ_alg = integ_alg;
14968   mp->dh_group = dh_group;
14969
14970   S (mp);
14971   W (ret);
14972   return ret;
14973 }
14974
14975 static int
14976 api_ikev2_set_sa_lifetime (vat_main_t * vam)
14977 {
14978   unformat_input_t *i = vam->input;
14979   vl_api_ikev2_set_sa_lifetime_t *mp;
14980   int ret;
14981   u8 *name = 0;
14982   u64 lifetime, lifetime_maxdata;
14983   u32 lifetime_jitter, handover;
14984
14985   const char *valid_chars = "a-zA-Z0-9_";
14986
14987   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14988     {
14989       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
14990                     &lifetime, &lifetime_jitter, &handover,
14991                     &lifetime_maxdata))
14992         vec_add1 (name, 0);
14993       else
14994         {
14995           errmsg ("parse error '%U'", format_unformat_error, i);
14996           return -99;
14997         }
14998     }
14999
15000   if (!vec_len (name))
15001     {
15002       errmsg ("profile name must be specified");
15003       return -99;
15004     }
15005
15006   if (vec_len (name) > 64)
15007     {
15008       errmsg ("profile name too long");
15009       return -99;
15010     }
15011
15012   M (IKEV2_SET_SA_LIFETIME, mp);
15013
15014   clib_memcpy (mp->name, name, vec_len (name));
15015   vec_free (name);
15016   mp->lifetime = lifetime;
15017   mp->lifetime_jitter = lifetime_jitter;
15018   mp->handover = handover;
15019   mp->lifetime_maxdata = lifetime_maxdata;
15020
15021   S (mp);
15022   W (ret);
15023   return ret;
15024 }
15025
15026 static int
15027 api_ikev2_initiate_sa_init (vat_main_t * vam)
15028 {
15029   unformat_input_t *i = vam->input;
15030   vl_api_ikev2_initiate_sa_init_t *mp;
15031   int ret;
15032   u8 *name = 0;
15033
15034   const char *valid_chars = "a-zA-Z0-9_";
15035
15036   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15037     {
15038       if (unformat (i, "%U", unformat_token, valid_chars, &name))
15039         vec_add1 (name, 0);
15040       else
15041         {
15042           errmsg ("parse error '%U'", format_unformat_error, i);
15043           return -99;
15044         }
15045     }
15046
15047   if (!vec_len (name))
15048     {
15049       errmsg ("profile name must be specified");
15050       return -99;
15051     }
15052
15053   if (vec_len (name) > 64)
15054     {
15055       errmsg ("profile name too long");
15056       return -99;
15057     }
15058
15059   M (IKEV2_INITIATE_SA_INIT, mp);
15060
15061   clib_memcpy (mp->name, name, vec_len (name));
15062   vec_free (name);
15063
15064   S (mp);
15065   W (ret);
15066   return ret;
15067 }
15068
15069 static int
15070 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
15071 {
15072   unformat_input_t *i = vam->input;
15073   vl_api_ikev2_initiate_del_ike_sa_t *mp;
15074   int ret;
15075   u64 ispi;
15076
15077
15078   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15079     {
15080       if (unformat (i, "%lx", &ispi))
15081         ;
15082       else
15083         {
15084           errmsg ("parse error '%U'", format_unformat_error, i);
15085           return -99;
15086         }
15087     }
15088
15089   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
15090
15091   mp->ispi = ispi;
15092
15093   S (mp);
15094   W (ret);
15095   return ret;
15096 }
15097
15098 static int
15099 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
15100 {
15101   unformat_input_t *i = vam->input;
15102   vl_api_ikev2_initiate_del_child_sa_t *mp;
15103   int ret;
15104   u32 ispi;
15105
15106
15107   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15108     {
15109       if (unformat (i, "%x", &ispi))
15110         ;
15111       else
15112         {
15113           errmsg ("parse error '%U'", format_unformat_error, i);
15114           return -99;
15115         }
15116     }
15117
15118   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
15119
15120   mp->ispi = ispi;
15121
15122   S (mp);
15123   W (ret);
15124   return ret;
15125 }
15126
15127 static int
15128 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
15129 {
15130   unformat_input_t *i = vam->input;
15131   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
15132   int ret;
15133   u32 ispi;
15134
15135
15136   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15137     {
15138       if (unformat (i, "%x", &ispi))
15139         ;
15140       else
15141         {
15142           errmsg ("parse error '%U'", format_unformat_error, i);
15143           return -99;
15144         }
15145     }
15146
15147   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
15148
15149   mp->ispi = ispi;
15150
15151   S (mp);
15152   W (ret);
15153   return ret;
15154 }
15155
15156 /*
15157  * MAP
15158  */
15159 static int
15160 api_map_add_domain (vat_main_t * vam)
15161 {
15162   unformat_input_t *i = vam->input;
15163   vl_api_map_add_domain_t *mp;
15164
15165   ip4_address_t ip4_prefix;
15166   ip6_address_t ip6_prefix;
15167   ip6_address_t ip6_src;
15168   u32 num_m_args = 0;
15169   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
15170     0, psid_length = 0;
15171   u8 is_translation = 0;
15172   u32 mtu = 0;
15173   u32 ip6_src_len = 128;
15174   int ret;
15175
15176   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15177     {
15178       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
15179                     &ip4_prefix, &ip4_prefix_len))
15180         num_m_args++;
15181       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
15182                          &ip6_prefix, &ip6_prefix_len))
15183         num_m_args++;
15184       else
15185         if (unformat
15186             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
15187              &ip6_src_len))
15188         num_m_args++;
15189       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
15190         num_m_args++;
15191       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
15192         num_m_args++;
15193       else if (unformat (i, "psid-offset %d", &psid_offset))
15194         num_m_args++;
15195       else if (unformat (i, "psid-len %d", &psid_length))
15196         num_m_args++;
15197       else if (unformat (i, "mtu %d", &mtu))
15198         num_m_args++;
15199       else if (unformat (i, "map-t"))
15200         is_translation = 1;
15201       else
15202         {
15203           clib_warning ("parse error '%U'", format_unformat_error, i);
15204           return -99;
15205         }
15206     }
15207
15208   if (num_m_args < 3)
15209     {
15210       errmsg ("mandatory argument(s) missing");
15211       return -99;
15212     }
15213
15214   /* Construct the API message */
15215   M (MAP_ADD_DOMAIN, mp);
15216
15217   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
15218   mp->ip4_prefix_len = ip4_prefix_len;
15219
15220   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
15221   mp->ip6_prefix_len = ip6_prefix_len;
15222
15223   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
15224   mp->ip6_src_prefix_len = ip6_src_len;
15225
15226   mp->ea_bits_len = ea_bits_len;
15227   mp->psid_offset = psid_offset;
15228   mp->psid_length = psid_length;
15229   mp->is_translation = is_translation;
15230   mp->mtu = htons (mtu);
15231
15232   /* send it... */
15233   S (mp);
15234
15235   /* Wait for a reply, return good/bad news  */
15236   W (ret);
15237   return ret;
15238 }
15239
15240 static int
15241 api_map_del_domain (vat_main_t * vam)
15242 {
15243   unformat_input_t *i = vam->input;
15244   vl_api_map_del_domain_t *mp;
15245
15246   u32 num_m_args = 0;
15247   u32 index;
15248   int ret;
15249
15250   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15251     {
15252       if (unformat (i, "index %d", &index))
15253         num_m_args++;
15254       else
15255         {
15256           clib_warning ("parse error '%U'", format_unformat_error, i);
15257           return -99;
15258         }
15259     }
15260
15261   if (num_m_args != 1)
15262     {
15263       errmsg ("mandatory argument(s) missing");
15264       return -99;
15265     }
15266
15267   /* Construct the API message */
15268   M (MAP_DEL_DOMAIN, mp);
15269
15270   mp->index = ntohl (index);
15271
15272   /* send it... */
15273   S (mp);
15274
15275   /* Wait for a reply, return good/bad news  */
15276   W (ret);
15277   return ret;
15278 }
15279
15280 static int
15281 api_map_add_del_rule (vat_main_t * vam)
15282 {
15283   unformat_input_t *i = vam->input;
15284   vl_api_map_add_del_rule_t *mp;
15285   u8 is_add = 1;
15286   ip6_address_t ip6_dst;
15287   u32 num_m_args = 0, index, psid = 0;
15288   int ret;
15289
15290   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15291     {
15292       if (unformat (i, "index %d", &index))
15293         num_m_args++;
15294       else if (unformat (i, "psid %d", &psid))
15295         num_m_args++;
15296       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
15297         num_m_args++;
15298       else if (unformat (i, "del"))
15299         {
15300           is_add = 0;
15301         }
15302       else
15303         {
15304           clib_warning ("parse error '%U'", format_unformat_error, i);
15305           return -99;
15306         }
15307     }
15308
15309   /* Construct the API message */
15310   M (MAP_ADD_DEL_RULE, mp);
15311
15312   mp->index = ntohl (index);
15313   mp->is_add = is_add;
15314   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
15315   mp->psid = ntohs (psid);
15316
15317   /* send it... */
15318   S (mp);
15319
15320   /* Wait for a reply, return good/bad news  */
15321   W (ret);
15322   return ret;
15323 }
15324
15325 static int
15326 api_map_domain_dump (vat_main_t * vam)
15327 {
15328   vl_api_map_domain_dump_t *mp;
15329   vl_api_control_ping_t *mp_ping;
15330   int ret;
15331
15332   /* Construct the API message */
15333   M (MAP_DOMAIN_DUMP, mp);
15334
15335   /* send it... */
15336   S (mp);
15337
15338   /* Use a control ping for synchronization */
15339   MPING (CONTROL_PING, mp_ping);
15340   S (mp_ping);
15341
15342   W (ret);
15343   return ret;
15344 }
15345
15346 static int
15347 api_map_rule_dump (vat_main_t * vam)
15348 {
15349   unformat_input_t *i = vam->input;
15350   vl_api_map_rule_dump_t *mp;
15351   vl_api_control_ping_t *mp_ping;
15352   u32 domain_index = ~0;
15353   int ret;
15354
15355   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15356     {
15357       if (unformat (i, "index %u", &domain_index))
15358         ;
15359       else
15360         break;
15361     }
15362
15363   if (domain_index == ~0)
15364     {
15365       clib_warning ("parse error: domain index expected");
15366       return -99;
15367     }
15368
15369   /* Construct the API message */
15370   M (MAP_RULE_DUMP, mp);
15371
15372   mp->domain_index = htonl (domain_index);
15373
15374   /* send it... */
15375   S (mp);
15376
15377   /* Use a control ping for synchronization */
15378   MPING (CONTROL_PING, mp_ping);
15379   S (mp_ping);
15380
15381   W (ret);
15382   return ret;
15383 }
15384
15385 static void vl_api_map_add_domain_reply_t_handler
15386   (vl_api_map_add_domain_reply_t * mp)
15387 {
15388   vat_main_t *vam = &vat_main;
15389   i32 retval = ntohl (mp->retval);
15390
15391   if (vam->async_mode)
15392     {
15393       vam->async_errors += (retval < 0);
15394     }
15395   else
15396     {
15397       vam->retval = retval;
15398       vam->result_ready = 1;
15399     }
15400 }
15401
15402 static void vl_api_map_add_domain_reply_t_handler_json
15403   (vl_api_map_add_domain_reply_t * mp)
15404 {
15405   vat_main_t *vam = &vat_main;
15406   vat_json_node_t node;
15407
15408   vat_json_init_object (&node);
15409   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
15410   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
15411
15412   vat_json_print (vam->ofp, &node);
15413   vat_json_free (&node);
15414
15415   vam->retval = ntohl (mp->retval);
15416   vam->result_ready = 1;
15417 }
15418
15419 static int
15420 api_get_first_msg_id (vat_main_t * vam)
15421 {
15422   vl_api_get_first_msg_id_t *mp;
15423   unformat_input_t *i = vam->input;
15424   u8 *name;
15425   u8 name_set = 0;
15426   int ret;
15427
15428   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15429     {
15430       if (unformat (i, "client %s", &name))
15431         name_set = 1;
15432       else
15433         break;
15434     }
15435
15436   if (name_set == 0)
15437     {
15438       errmsg ("missing client name");
15439       return -99;
15440     }
15441   vec_add1 (name, 0);
15442
15443   if (vec_len (name) > 63)
15444     {
15445       errmsg ("client name too long");
15446       return -99;
15447     }
15448
15449   M (GET_FIRST_MSG_ID, mp);
15450   clib_memcpy (mp->name, name, vec_len (name));
15451   S (mp);
15452   W (ret);
15453   return ret;
15454 }
15455
15456 static int
15457 api_cop_interface_enable_disable (vat_main_t * vam)
15458 {
15459   unformat_input_t *line_input = vam->input;
15460   vl_api_cop_interface_enable_disable_t *mp;
15461   u32 sw_if_index = ~0;
15462   u8 enable_disable = 1;
15463   int ret;
15464
15465   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15466     {
15467       if (unformat (line_input, "disable"))
15468         enable_disable = 0;
15469       if (unformat (line_input, "enable"))
15470         enable_disable = 1;
15471       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15472                          vam, &sw_if_index))
15473         ;
15474       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15475         ;
15476       else
15477         break;
15478     }
15479
15480   if (sw_if_index == ~0)
15481     {
15482       errmsg ("missing interface name or sw_if_index");
15483       return -99;
15484     }
15485
15486   /* Construct the API message */
15487   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15488   mp->sw_if_index = ntohl (sw_if_index);
15489   mp->enable_disable = enable_disable;
15490
15491   /* send it... */
15492   S (mp);
15493   /* Wait for the reply */
15494   W (ret);
15495   return ret;
15496 }
15497
15498 static int
15499 api_cop_whitelist_enable_disable (vat_main_t * vam)
15500 {
15501   unformat_input_t *line_input = vam->input;
15502   vl_api_cop_whitelist_enable_disable_t *mp;
15503   u32 sw_if_index = ~0;
15504   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15505   u32 fib_id = 0;
15506   int ret;
15507
15508   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15509     {
15510       if (unformat (line_input, "ip4"))
15511         ip4 = 1;
15512       else if (unformat (line_input, "ip6"))
15513         ip6 = 1;
15514       else if (unformat (line_input, "default"))
15515         default_cop = 1;
15516       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15517                          vam, &sw_if_index))
15518         ;
15519       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15520         ;
15521       else if (unformat (line_input, "fib-id %d", &fib_id))
15522         ;
15523       else
15524         break;
15525     }
15526
15527   if (sw_if_index == ~0)
15528     {
15529       errmsg ("missing interface name or sw_if_index");
15530       return -99;
15531     }
15532
15533   /* Construct the API message */
15534   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15535   mp->sw_if_index = ntohl (sw_if_index);
15536   mp->fib_id = ntohl (fib_id);
15537   mp->ip4 = ip4;
15538   mp->ip6 = ip6;
15539   mp->default_cop = default_cop;
15540
15541   /* send it... */
15542   S (mp);
15543   /* Wait for the reply */
15544   W (ret);
15545   return ret;
15546 }
15547
15548 static int
15549 api_get_node_graph (vat_main_t * vam)
15550 {
15551   vl_api_get_node_graph_t *mp;
15552   int ret;
15553
15554   M (GET_NODE_GRAPH, mp);
15555
15556   /* send it... */
15557   S (mp);
15558   /* Wait for the reply */
15559   W (ret);
15560   return ret;
15561 }
15562
15563 /* *INDENT-OFF* */
15564 /** Used for parsing LISP eids */
15565 typedef CLIB_PACKED(struct{
15566   u8 addr[16];   /**< eid address */
15567   u32 len;       /**< prefix length if IP */
15568   u8 type;      /**< type of eid */
15569 }) lisp_eid_vat_t;
15570 /* *INDENT-ON* */
15571
15572 static uword
15573 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15574 {
15575   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15576
15577   memset (a, 0, sizeof (a[0]));
15578
15579   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15580     {
15581       a->type = 0;              /* ipv4 type */
15582     }
15583   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15584     {
15585       a->type = 1;              /* ipv6 type */
15586     }
15587   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15588     {
15589       a->type = 2;              /* mac type */
15590     }
15591   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15592     {
15593       a->type = 3;              /* NSH type */
15594       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15595       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15596     }
15597   else
15598     {
15599       return 0;
15600     }
15601
15602   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15603     {
15604       return 0;
15605     }
15606
15607   return 1;
15608 }
15609
15610 static int
15611 lisp_eid_size_vat (u8 type)
15612 {
15613   switch (type)
15614     {
15615     case 0:
15616       return 4;
15617     case 1:
15618       return 16;
15619     case 2:
15620       return 6;
15621     case 3:
15622       return 5;
15623     }
15624   return 0;
15625 }
15626
15627 static void
15628 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15629 {
15630   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15631 }
15632
15633 static int
15634 api_one_add_del_locator_set (vat_main_t * vam)
15635 {
15636   unformat_input_t *input = vam->input;
15637   vl_api_one_add_del_locator_set_t *mp;
15638   u8 is_add = 1;
15639   u8 *locator_set_name = NULL;
15640   u8 locator_set_name_set = 0;
15641   vl_api_local_locator_t locator, *locators = 0;
15642   u32 sw_if_index, priority, weight;
15643   u32 data_len = 0;
15644
15645   int ret;
15646   /* Parse args required to build the message */
15647   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15648     {
15649       if (unformat (input, "del"))
15650         {
15651           is_add = 0;
15652         }
15653       else if (unformat (input, "locator-set %s", &locator_set_name))
15654         {
15655           locator_set_name_set = 1;
15656         }
15657       else if (unformat (input, "sw_if_index %u p %u w %u",
15658                          &sw_if_index, &priority, &weight))
15659         {
15660           locator.sw_if_index = htonl (sw_if_index);
15661           locator.priority = priority;
15662           locator.weight = weight;
15663           vec_add1 (locators, locator);
15664         }
15665       else
15666         if (unformat
15667             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15668              &sw_if_index, &priority, &weight))
15669         {
15670           locator.sw_if_index = htonl (sw_if_index);
15671           locator.priority = priority;
15672           locator.weight = weight;
15673           vec_add1 (locators, locator);
15674         }
15675       else
15676         break;
15677     }
15678
15679   if (locator_set_name_set == 0)
15680     {
15681       errmsg ("missing locator-set name");
15682       vec_free (locators);
15683       return -99;
15684     }
15685
15686   if (vec_len (locator_set_name) > 64)
15687     {
15688       errmsg ("locator-set name too long");
15689       vec_free (locator_set_name);
15690       vec_free (locators);
15691       return -99;
15692     }
15693   vec_add1 (locator_set_name, 0);
15694
15695   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15696
15697   /* Construct the API message */
15698   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15699
15700   mp->is_add = is_add;
15701   clib_memcpy (mp->locator_set_name, locator_set_name,
15702                vec_len (locator_set_name));
15703   vec_free (locator_set_name);
15704
15705   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15706   if (locators)
15707     clib_memcpy (mp->locators, locators, data_len);
15708   vec_free (locators);
15709
15710   /* send it... */
15711   S (mp);
15712
15713   /* Wait for a reply... */
15714   W (ret);
15715   return ret;
15716 }
15717
15718 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15719
15720 static int
15721 api_one_add_del_locator (vat_main_t * vam)
15722 {
15723   unformat_input_t *input = vam->input;
15724   vl_api_one_add_del_locator_t *mp;
15725   u32 tmp_if_index = ~0;
15726   u32 sw_if_index = ~0;
15727   u8 sw_if_index_set = 0;
15728   u8 sw_if_index_if_name_set = 0;
15729   u32 priority = ~0;
15730   u8 priority_set = 0;
15731   u32 weight = ~0;
15732   u8 weight_set = 0;
15733   u8 is_add = 1;
15734   u8 *locator_set_name = NULL;
15735   u8 locator_set_name_set = 0;
15736   int ret;
15737
15738   /* Parse args required to build the message */
15739   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15740     {
15741       if (unformat (input, "del"))
15742         {
15743           is_add = 0;
15744         }
15745       else if (unformat (input, "locator-set %s", &locator_set_name))
15746         {
15747           locator_set_name_set = 1;
15748         }
15749       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15750                          &tmp_if_index))
15751         {
15752           sw_if_index_if_name_set = 1;
15753           sw_if_index = tmp_if_index;
15754         }
15755       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15756         {
15757           sw_if_index_set = 1;
15758           sw_if_index = tmp_if_index;
15759         }
15760       else if (unformat (input, "p %d", &priority))
15761         {
15762           priority_set = 1;
15763         }
15764       else if (unformat (input, "w %d", &weight))
15765         {
15766           weight_set = 1;
15767         }
15768       else
15769         break;
15770     }
15771
15772   if (locator_set_name_set == 0)
15773     {
15774       errmsg ("missing locator-set name");
15775       return -99;
15776     }
15777
15778   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15779     {
15780       errmsg ("missing sw_if_index");
15781       vec_free (locator_set_name);
15782       return -99;
15783     }
15784
15785   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15786     {
15787       errmsg ("cannot use both params interface name and sw_if_index");
15788       vec_free (locator_set_name);
15789       return -99;
15790     }
15791
15792   if (priority_set == 0)
15793     {
15794       errmsg ("missing locator-set priority");
15795       vec_free (locator_set_name);
15796       return -99;
15797     }
15798
15799   if (weight_set == 0)
15800     {
15801       errmsg ("missing locator-set weight");
15802       vec_free (locator_set_name);
15803       return -99;
15804     }
15805
15806   if (vec_len (locator_set_name) > 64)
15807     {
15808       errmsg ("locator-set name too long");
15809       vec_free (locator_set_name);
15810       return -99;
15811     }
15812   vec_add1 (locator_set_name, 0);
15813
15814   /* Construct the API message */
15815   M (ONE_ADD_DEL_LOCATOR, mp);
15816
15817   mp->is_add = is_add;
15818   mp->sw_if_index = ntohl (sw_if_index);
15819   mp->priority = priority;
15820   mp->weight = weight;
15821   clib_memcpy (mp->locator_set_name, locator_set_name,
15822                vec_len (locator_set_name));
15823   vec_free (locator_set_name);
15824
15825   /* send it... */
15826   S (mp);
15827
15828   /* Wait for a reply... */
15829   W (ret);
15830   return ret;
15831 }
15832
15833 #define api_lisp_add_del_locator api_one_add_del_locator
15834
15835 uword
15836 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15837 {
15838   u32 *key_id = va_arg (*args, u32 *);
15839   u8 *s = 0;
15840
15841   if (unformat (input, "%s", &s))
15842     {
15843       if (!strcmp ((char *) s, "sha1"))
15844         key_id[0] = HMAC_SHA_1_96;
15845       else if (!strcmp ((char *) s, "sha256"))
15846         key_id[0] = HMAC_SHA_256_128;
15847       else
15848         {
15849           clib_warning ("invalid key_id: '%s'", s);
15850           key_id[0] = HMAC_NO_KEY;
15851         }
15852     }
15853   else
15854     return 0;
15855
15856   vec_free (s);
15857   return 1;
15858 }
15859
15860 static int
15861 api_one_add_del_local_eid (vat_main_t * vam)
15862 {
15863   unformat_input_t *input = vam->input;
15864   vl_api_one_add_del_local_eid_t *mp;
15865   u8 is_add = 1;
15866   u8 eid_set = 0;
15867   lisp_eid_vat_t _eid, *eid = &_eid;
15868   u8 *locator_set_name = 0;
15869   u8 locator_set_name_set = 0;
15870   u32 vni = 0;
15871   u16 key_id = 0;
15872   u8 *key = 0;
15873   int ret;
15874
15875   /* Parse args required to build the message */
15876   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15877     {
15878       if (unformat (input, "del"))
15879         {
15880           is_add = 0;
15881         }
15882       else if (unformat (input, "vni %d", &vni))
15883         {
15884           ;
15885         }
15886       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15887         {
15888           eid_set = 1;
15889         }
15890       else if (unformat (input, "locator-set %s", &locator_set_name))
15891         {
15892           locator_set_name_set = 1;
15893         }
15894       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15895         ;
15896       else if (unformat (input, "secret-key %_%v%_", &key))
15897         ;
15898       else
15899         break;
15900     }
15901
15902   if (locator_set_name_set == 0)
15903     {
15904       errmsg ("missing locator-set name");
15905       return -99;
15906     }
15907
15908   if (0 == eid_set)
15909     {
15910       errmsg ("EID address not set!");
15911       vec_free (locator_set_name);
15912       return -99;
15913     }
15914
15915   if (key && (0 == key_id))
15916     {
15917       errmsg ("invalid key_id!");
15918       return -99;
15919     }
15920
15921   if (vec_len (key) > 64)
15922     {
15923       errmsg ("key too long");
15924       vec_free (key);
15925       return -99;
15926     }
15927
15928   if (vec_len (locator_set_name) > 64)
15929     {
15930       errmsg ("locator-set name too long");
15931       vec_free (locator_set_name);
15932       return -99;
15933     }
15934   vec_add1 (locator_set_name, 0);
15935
15936   /* Construct the API message */
15937   M (ONE_ADD_DEL_LOCAL_EID, mp);
15938
15939   mp->is_add = is_add;
15940   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15941   mp->eid_type = eid->type;
15942   mp->prefix_len = eid->len;
15943   mp->vni = clib_host_to_net_u32 (vni);
15944   mp->key_id = clib_host_to_net_u16 (key_id);
15945   clib_memcpy (mp->locator_set_name, locator_set_name,
15946                vec_len (locator_set_name));
15947   clib_memcpy (mp->key, key, vec_len (key));
15948
15949   vec_free (locator_set_name);
15950   vec_free (key);
15951
15952   /* send it... */
15953   S (mp);
15954
15955   /* Wait for a reply... */
15956   W (ret);
15957   return ret;
15958 }
15959
15960 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15961
15962 static int
15963 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15964 {
15965   u32 dp_table = 0, vni = 0;;
15966   unformat_input_t *input = vam->input;
15967   vl_api_gpe_add_del_fwd_entry_t *mp;
15968   u8 is_add = 1;
15969   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15970   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15971   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15972   u32 action = ~0, w;
15973   ip4_address_t rmt_rloc4, lcl_rloc4;
15974   ip6_address_t rmt_rloc6, lcl_rloc6;
15975   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15976   int ret;
15977
15978   memset (&rloc, 0, sizeof (rloc));
15979
15980   /* Parse args required to build the message */
15981   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15982     {
15983       if (unformat (input, "del"))
15984         is_add = 0;
15985       else if (unformat (input, "add"))
15986         is_add = 1;
15987       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15988         {
15989           rmt_eid_set = 1;
15990         }
15991       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15992         {
15993           lcl_eid_set = 1;
15994         }
15995       else if (unformat (input, "vrf %d", &dp_table))
15996         ;
15997       else if (unformat (input, "bd %d", &dp_table))
15998         ;
15999       else if (unformat (input, "vni %d", &vni))
16000         ;
16001       else if (unformat (input, "w %d", &w))
16002         {
16003           if (!curr_rloc)
16004             {
16005               errmsg ("No RLOC configured for setting priority/weight!");
16006               return -99;
16007             }
16008           curr_rloc->weight = w;
16009         }
16010       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
16011                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
16012         {
16013           rloc.is_ip4 = 1;
16014
16015           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
16016           rloc.weight = 0;
16017           vec_add1 (lcl_locs, rloc);
16018
16019           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
16020           vec_add1 (rmt_locs, rloc);
16021           /* weight saved in rmt loc */
16022           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16023         }
16024       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
16025                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
16026         {
16027           rloc.is_ip4 = 0;
16028           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
16029           rloc.weight = 0;
16030           vec_add1 (lcl_locs, rloc);
16031
16032           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
16033           vec_add1 (rmt_locs, rloc);
16034           /* weight saved in rmt loc */
16035           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
16036         }
16037       else if (unformat (input, "action %d", &action))
16038         {
16039           ;
16040         }
16041       else
16042         {
16043           clib_warning ("parse error '%U'", format_unformat_error, input);
16044           return -99;
16045         }
16046     }
16047
16048   if (!rmt_eid_set)
16049     {
16050       errmsg ("remote eid addresses not set");
16051       return -99;
16052     }
16053
16054   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
16055     {
16056       errmsg ("eid types don't match");
16057       return -99;
16058     }
16059
16060   if (0 == rmt_locs && (u32) ~ 0 == action)
16061     {
16062       errmsg ("action not set for negative mapping");
16063       return -99;
16064     }
16065
16066   /* Construct the API message */
16067   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
16068       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
16069
16070   mp->is_add = is_add;
16071   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
16072   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
16073   mp->eid_type = rmt_eid->type;
16074   mp->dp_table = clib_host_to_net_u32 (dp_table);
16075   mp->vni = clib_host_to_net_u32 (vni);
16076   mp->rmt_len = rmt_eid->len;
16077   mp->lcl_len = lcl_eid->len;
16078   mp->action = action;
16079
16080   if (0 != rmt_locs && 0 != lcl_locs)
16081     {
16082       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
16083       clib_memcpy (mp->locs, lcl_locs,
16084                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
16085
16086       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
16087       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
16088                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
16089     }
16090   vec_free (lcl_locs);
16091   vec_free (rmt_locs);
16092
16093   /* send it... */
16094   S (mp);
16095
16096   /* Wait for a reply... */
16097   W (ret);
16098   return ret;
16099 }
16100
16101 static int
16102 api_one_add_del_map_server (vat_main_t * vam)
16103 {
16104   unformat_input_t *input = vam->input;
16105   vl_api_one_add_del_map_server_t *mp;
16106   u8 is_add = 1;
16107   u8 ipv4_set = 0;
16108   u8 ipv6_set = 0;
16109   ip4_address_t ipv4;
16110   ip6_address_t ipv6;
16111   int ret;
16112
16113   /* Parse args required to build the message */
16114   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16115     {
16116       if (unformat (input, "del"))
16117         {
16118           is_add = 0;
16119         }
16120       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16121         {
16122           ipv4_set = 1;
16123         }
16124       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16125         {
16126           ipv6_set = 1;
16127         }
16128       else
16129         break;
16130     }
16131
16132   if (ipv4_set && ipv6_set)
16133     {
16134       errmsg ("both eid v4 and v6 addresses set");
16135       return -99;
16136     }
16137
16138   if (!ipv4_set && !ipv6_set)
16139     {
16140       errmsg ("eid addresses not set");
16141       return -99;
16142     }
16143
16144   /* Construct the API message */
16145   M (ONE_ADD_DEL_MAP_SERVER, mp);
16146
16147   mp->is_add = is_add;
16148   if (ipv6_set)
16149     {
16150       mp->is_ipv6 = 1;
16151       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16152     }
16153   else
16154     {
16155       mp->is_ipv6 = 0;
16156       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16157     }
16158
16159   /* send it... */
16160   S (mp);
16161
16162   /* Wait for a reply... */
16163   W (ret);
16164   return ret;
16165 }
16166
16167 #define api_lisp_add_del_map_server api_one_add_del_map_server
16168
16169 static int
16170 api_one_add_del_map_resolver (vat_main_t * vam)
16171 {
16172   unformat_input_t *input = vam->input;
16173   vl_api_one_add_del_map_resolver_t *mp;
16174   u8 is_add = 1;
16175   u8 ipv4_set = 0;
16176   u8 ipv6_set = 0;
16177   ip4_address_t ipv4;
16178   ip6_address_t ipv6;
16179   int ret;
16180
16181   /* Parse args required to build the message */
16182   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16183     {
16184       if (unformat (input, "del"))
16185         {
16186           is_add = 0;
16187         }
16188       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16189         {
16190           ipv4_set = 1;
16191         }
16192       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16193         {
16194           ipv6_set = 1;
16195         }
16196       else
16197         break;
16198     }
16199
16200   if (ipv4_set && ipv6_set)
16201     {
16202       errmsg ("both eid v4 and v6 addresses set");
16203       return -99;
16204     }
16205
16206   if (!ipv4_set && !ipv6_set)
16207     {
16208       errmsg ("eid addresses not set");
16209       return -99;
16210     }
16211
16212   /* Construct the API message */
16213   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16214
16215   mp->is_add = is_add;
16216   if (ipv6_set)
16217     {
16218       mp->is_ipv6 = 1;
16219       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16220     }
16221   else
16222     {
16223       mp->is_ipv6 = 0;
16224       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16225     }
16226
16227   /* send it... */
16228   S (mp);
16229
16230   /* Wait for a reply... */
16231   W (ret);
16232   return ret;
16233 }
16234
16235 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16236
16237 static int
16238 api_lisp_gpe_enable_disable (vat_main_t * vam)
16239 {
16240   unformat_input_t *input = vam->input;
16241   vl_api_gpe_enable_disable_t *mp;
16242   u8 is_set = 0;
16243   u8 is_en = 1;
16244   int ret;
16245
16246   /* Parse args required to build the message */
16247   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16248     {
16249       if (unformat (input, "enable"))
16250         {
16251           is_set = 1;
16252           is_en = 1;
16253         }
16254       else if (unformat (input, "disable"))
16255         {
16256           is_set = 1;
16257           is_en = 0;
16258         }
16259       else
16260         break;
16261     }
16262
16263   if (is_set == 0)
16264     {
16265       errmsg ("Value not set");
16266       return -99;
16267     }
16268
16269   /* Construct the API message */
16270   M (GPE_ENABLE_DISABLE, mp);
16271
16272   mp->is_en = is_en;
16273
16274   /* send it... */
16275   S (mp);
16276
16277   /* Wait for a reply... */
16278   W (ret);
16279   return ret;
16280 }
16281
16282 static int
16283 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16284 {
16285   unformat_input_t *input = vam->input;
16286   vl_api_one_rloc_probe_enable_disable_t *mp;
16287   u8 is_set = 0;
16288   u8 is_en = 0;
16289   int ret;
16290
16291   /* Parse args required to build the message */
16292   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16293     {
16294       if (unformat (input, "enable"))
16295         {
16296           is_set = 1;
16297           is_en = 1;
16298         }
16299       else if (unformat (input, "disable"))
16300         is_set = 1;
16301       else
16302         break;
16303     }
16304
16305   if (!is_set)
16306     {
16307       errmsg ("Value not set");
16308       return -99;
16309     }
16310
16311   /* Construct the API message */
16312   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16313
16314   mp->is_enabled = is_en;
16315
16316   /* send it... */
16317   S (mp);
16318
16319   /* Wait for a reply... */
16320   W (ret);
16321   return ret;
16322 }
16323
16324 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16325
16326 static int
16327 api_one_map_register_enable_disable (vat_main_t * vam)
16328 {
16329   unformat_input_t *input = vam->input;
16330   vl_api_one_map_register_enable_disable_t *mp;
16331   u8 is_set = 0;
16332   u8 is_en = 0;
16333   int ret;
16334
16335   /* Parse args required to build the message */
16336   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16337     {
16338       if (unformat (input, "enable"))
16339         {
16340           is_set = 1;
16341           is_en = 1;
16342         }
16343       else if (unformat (input, "disable"))
16344         is_set = 1;
16345       else
16346         break;
16347     }
16348
16349   if (!is_set)
16350     {
16351       errmsg ("Value not set");
16352       return -99;
16353     }
16354
16355   /* Construct the API message */
16356   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16357
16358   mp->is_enabled = is_en;
16359
16360   /* send it... */
16361   S (mp);
16362
16363   /* Wait for a reply... */
16364   W (ret);
16365   return ret;
16366 }
16367
16368 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16369
16370 static int
16371 api_one_enable_disable (vat_main_t * vam)
16372 {
16373   unformat_input_t *input = vam->input;
16374   vl_api_one_enable_disable_t *mp;
16375   u8 is_set = 0;
16376   u8 is_en = 0;
16377   int ret;
16378
16379   /* Parse args required to build the message */
16380   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16381     {
16382       if (unformat (input, "enable"))
16383         {
16384           is_set = 1;
16385           is_en = 1;
16386         }
16387       else if (unformat (input, "disable"))
16388         {
16389           is_set = 1;
16390         }
16391       else
16392         break;
16393     }
16394
16395   if (!is_set)
16396     {
16397       errmsg ("Value not set");
16398       return -99;
16399     }
16400
16401   /* Construct the API message */
16402   M (ONE_ENABLE_DISABLE, mp);
16403
16404   mp->is_en = is_en;
16405
16406   /* send it... */
16407   S (mp);
16408
16409   /* Wait for a reply... */
16410   W (ret);
16411   return ret;
16412 }
16413
16414 #define api_lisp_enable_disable api_one_enable_disable
16415
16416 static int
16417 api_show_one_map_register_state (vat_main_t * vam)
16418 {
16419   vl_api_show_one_map_register_state_t *mp;
16420   int ret;
16421
16422   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16423
16424   /* send */
16425   S (mp);
16426
16427   /* wait for reply */
16428   W (ret);
16429   return ret;
16430 }
16431
16432 #define api_show_lisp_map_register_state api_show_one_map_register_state
16433
16434 static int
16435 api_show_one_rloc_probe_state (vat_main_t * vam)
16436 {
16437   vl_api_show_one_rloc_probe_state_t *mp;
16438   int ret;
16439
16440   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16441
16442   /* send */
16443   S (mp);
16444
16445   /* wait for reply */
16446   W (ret);
16447   return ret;
16448 }
16449
16450 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16451
16452 static int
16453 api_one_add_del_ndp_entry (vat_main_t * vam)
16454 {
16455   vl_api_one_add_del_ndp_entry_t *mp;
16456   unformat_input_t *input = vam->input;
16457   u8 is_add = 1;
16458   u8 mac_set = 0;
16459   u8 bd_set = 0;
16460   u8 ip_set = 0;
16461   u8 mac[6] = { 0, };
16462   u8 ip6[16] = { 0, };
16463   u32 bd = ~0;
16464   int ret;
16465
16466   /* Parse args required to build the message */
16467   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16468     {
16469       if (unformat (input, "del"))
16470         is_add = 0;
16471       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16472         mac_set = 1;
16473       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16474         ip_set = 1;
16475       else if (unformat (input, "bd %d", &bd))
16476         bd_set = 1;
16477       else
16478         {
16479           errmsg ("parse error '%U'", format_unformat_error, input);
16480           return -99;
16481         }
16482     }
16483
16484   if (!bd_set || !ip_set || (!mac_set && is_add))
16485     {
16486       errmsg ("Missing BD, IP or MAC!");
16487       return -99;
16488     }
16489
16490   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16491   mp->is_add = is_add;
16492   clib_memcpy (mp->mac, mac, 6);
16493   mp->bd = clib_host_to_net_u32 (bd);
16494   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16495
16496   /* send */
16497   S (mp);
16498
16499   /* wait for reply */
16500   W (ret);
16501   return ret;
16502 }
16503
16504 static int
16505 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16506 {
16507   vl_api_one_add_del_l2_arp_entry_t *mp;
16508   unformat_input_t *input = vam->input;
16509   u8 is_add = 1;
16510   u8 mac_set = 0;
16511   u8 bd_set = 0;
16512   u8 ip_set = 0;
16513   u8 mac[6] = { 0, };
16514   u32 ip4 = 0, bd = ~0;
16515   int ret;
16516
16517   /* Parse args required to build the message */
16518   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16519     {
16520       if (unformat (input, "del"))
16521         is_add = 0;
16522       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16523         mac_set = 1;
16524       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16525         ip_set = 1;
16526       else if (unformat (input, "bd %d", &bd))
16527         bd_set = 1;
16528       else
16529         {
16530           errmsg ("parse error '%U'", format_unformat_error, input);
16531           return -99;
16532         }
16533     }
16534
16535   if (!bd_set || !ip_set || (!mac_set && is_add))
16536     {
16537       errmsg ("Missing BD, IP or MAC!");
16538       return -99;
16539     }
16540
16541   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16542   mp->is_add = is_add;
16543   clib_memcpy (mp->mac, mac, 6);
16544   mp->bd = clib_host_to_net_u32 (bd);
16545   mp->ip4 = ip4;
16546
16547   /* send */
16548   S (mp);
16549
16550   /* wait for reply */
16551   W (ret);
16552   return ret;
16553 }
16554
16555 static int
16556 api_one_ndp_bd_get (vat_main_t * vam)
16557 {
16558   vl_api_one_ndp_bd_get_t *mp;
16559   int ret;
16560
16561   M (ONE_NDP_BD_GET, mp);
16562
16563   /* send */
16564   S (mp);
16565
16566   /* wait for reply */
16567   W (ret);
16568   return ret;
16569 }
16570
16571 static int
16572 api_one_ndp_entries_get (vat_main_t * vam)
16573 {
16574   vl_api_one_ndp_entries_get_t *mp;
16575   unformat_input_t *input = vam->input;
16576   u8 bd_set = 0;
16577   u32 bd = ~0;
16578   int ret;
16579
16580   /* Parse args required to build the message */
16581   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16582     {
16583       if (unformat (input, "bd %d", &bd))
16584         bd_set = 1;
16585       else
16586         {
16587           errmsg ("parse error '%U'", format_unformat_error, input);
16588           return -99;
16589         }
16590     }
16591
16592   if (!bd_set)
16593     {
16594       errmsg ("Expected bridge domain!");
16595       return -99;
16596     }
16597
16598   M (ONE_NDP_ENTRIES_GET, mp);
16599   mp->bd = clib_host_to_net_u32 (bd);
16600
16601   /* send */
16602   S (mp);
16603
16604   /* wait for reply */
16605   W (ret);
16606   return ret;
16607 }
16608
16609 static int
16610 api_one_l2_arp_bd_get (vat_main_t * vam)
16611 {
16612   vl_api_one_l2_arp_bd_get_t *mp;
16613   int ret;
16614
16615   M (ONE_L2_ARP_BD_GET, mp);
16616
16617   /* send */
16618   S (mp);
16619
16620   /* wait for reply */
16621   W (ret);
16622   return ret;
16623 }
16624
16625 static int
16626 api_one_l2_arp_entries_get (vat_main_t * vam)
16627 {
16628   vl_api_one_l2_arp_entries_get_t *mp;
16629   unformat_input_t *input = vam->input;
16630   u8 bd_set = 0;
16631   u32 bd = ~0;
16632   int ret;
16633
16634   /* Parse args required to build the message */
16635   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16636     {
16637       if (unformat (input, "bd %d", &bd))
16638         bd_set = 1;
16639       else
16640         {
16641           errmsg ("parse error '%U'", format_unformat_error, input);
16642           return -99;
16643         }
16644     }
16645
16646   if (!bd_set)
16647     {
16648       errmsg ("Expected bridge domain!");
16649       return -99;
16650     }
16651
16652   M (ONE_L2_ARP_ENTRIES_GET, mp);
16653   mp->bd = clib_host_to_net_u32 (bd);
16654
16655   /* send */
16656   S (mp);
16657
16658   /* wait for reply */
16659   W (ret);
16660   return ret;
16661 }
16662
16663 static int
16664 api_one_stats_enable_disable (vat_main_t * vam)
16665 {
16666   vl_api_one_stats_enable_disable_t *mp;
16667   unformat_input_t *input = vam->input;
16668   u8 is_set = 0;
16669   u8 is_en = 0;
16670   int ret;
16671
16672   /* Parse args required to build the message */
16673   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16674     {
16675       if (unformat (input, "enable"))
16676         {
16677           is_set = 1;
16678           is_en = 1;
16679         }
16680       else if (unformat (input, "disable"))
16681         {
16682           is_set = 1;
16683         }
16684       else
16685         break;
16686     }
16687
16688   if (!is_set)
16689     {
16690       errmsg ("Value not set");
16691       return -99;
16692     }
16693
16694   M (ONE_STATS_ENABLE_DISABLE, mp);
16695   mp->is_en = is_en;
16696
16697   /* send */
16698   S (mp);
16699
16700   /* wait for reply */
16701   W (ret);
16702   return ret;
16703 }
16704
16705 static int
16706 api_show_one_stats_enable_disable (vat_main_t * vam)
16707 {
16708   vl_api_show_one_stats_enable_disable_t *mp;
16709   int ret;
16710
16711   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16712
16713   /* send */
16714   S (mp);
16715
16716   /* wait for reply */
16717   W (ret);
16718   return ret;
16719 }
16720
16721 static int
16722 api_show_one_map_request_mode (vat_main_t * vam)
16723 {
16724   vl_api_show_one_map_request_mode_t *mp;
16725   int ret;
16726
16727   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16728
16729   /* send */
16730   S (mp);
16731
16732   /* wait for reply */
16733   W (ret);
16734   return ret;
16735 }
16736
16737 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16738
16739 static int
16740 api_one_map_request_mode (vat_main_t * vam)
16741 {
16742   unformat_input_t *input = vam->input;
16743   vl_api_one_map_request_mode_t *mp;
16744   u8 mode = 0;
16745   int ret;
16746
16747   /* Parse args required to build the message */
16748   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16749     {
16750       if (unformat (input, "dst-only"))
16751         mode = 0;
16752       else if (unformat (input, "src-dst"))
16753         mode = 1;
16754       else
16755         {
16756           errmsg ("parse error '%U'", format_unformat_error, input);
16757           return -99;
16758         }
16759     }
16760
16761   M (ONE_MAP_REQUEST_MODE, mp);
16762
16763   mp->mode = mode;
16764
16765   /* send */
16766   S (mp);
16767
16768   /* wait for reply */
16769   W (ret);
16770   return ret;
16771 }
16772
16773 #define api_lisp_map_request_mode api_one_map_request_mode
16774
16775 /**
16776  * Enable/disable ONE proxy ITR.
16777  *
16778  * @param vam vpp API test context
16779  * @return return code
16780  */
16781 static int
16782 api_one_pitr_set_locator_set (vat_main_t * vam)
16783 {
16784   u8 ls_name_set = 0;
16785   unformat_input_t *input = vam->input;
16786   vl_api_one_pitr_set_locator_set_t *mp;
16787   u8 is_add = 1;
16788   u8 *ls_name = 0;
16789   int ret;
16790
16791   /* Parse args required to build the message */
16792   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16793     {
16794       if (unformat (input, "del"))
16795         is_add = 0;
16796       else if (unformat (input, "locator-set %s", &ls_name))
16797         ls_name_set = 1;
16798       else
16799         {
16800           errmsg ("parse error '%U'", format_unformat_error, input);
16801           return -99;
16802         }
16803     }
16804
16805   if (!ls_name_set)
16806     {
16807       errmsg ("locator-set name not set!");
16808       return -99;
16809     }
16810
16811   M (ONE_PITR_SET_LOCATOR_SET, mp);
16812
16813   mp->is_add = is_add;
16814   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16815   vec_free (ls_name);
16816
16817   /* send */
16818   S (mp);
16819
16820   /* wait for reply */
16821   W (ret);
16822   return ret;
16823 }
16824
16825 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16826
16827 static int
16828 api_one_nsh_set_locator_set (vat_main_t * vam)
16829 {
16830   u8 ls_name_set = 0;
16831   unformat_input_t *input = vam->input;
16832   vl_api_one_nsh_set_locator_set_t *mp;
16833   u8 is_add = 1;
16834   u8 *ls_name = 0;
16835   int ret;
16836
16837   /* Parse args required to build the message */
16838   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16839     {
16840       if (unformat (input, "del"))
16841         is_add = 0;
16842       else if (unformat (input, "ls %s", &ls_name))
16843         ls_name_set = 1;
16844       else
16845         {
16846           errmsg ("parse error '%U'", format_unformat_error, input);
16847           return -99;
16848         }
16849     }
16850
16851   if (!ls_name_set && is_add)
16852     {
16853       errmsg ("locator-set name not set!");
16854       return -99;
16855     }
16856
16857   M (ONE_NSH_SET_LOCATOR_SET, mp);
16858
16859   mp->is_add = is_add;
16860   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16861   vec_free (ls_name);
16862
16863   /* send */
16864   S (mp);
16865
16866   /* wait for reply */
16867   W (ret);
16868   return ret;
16869 }
16870
16871 static int
16872 api_show_one_pitr (vat_main_t * vam)
16873 {
16874   vl_api_show_one_pitr_t *mp;
16875   int ret;
16876
16877   if (!vam->json_output)
16878     {
16879       print (vam->ofp, "%=20s", "lisp status:");
16880     }
16881
16882   M (SHOW_ONE_PITR, mp);
16883   /* send it... */
16884   S (mp);
16885
16886   /* Wait for a reply... */
16887   W (ret);
16888   return ret;
16889 }
16890
16891 #define api_show_lisp_pitr api_show_one_pitr
16892
16893 static int
16894 api_one_use_petr (vat_main_t * vam)
16895 {
16896   unformat_input_t *input = vam->input;
16897   vl_api_one_use_petr_t *mp;
16898   u8 is_add = 0;
16899   ip_address_t ip;
16900   int ret;
16901
16902   memset (&ip, 0, sizeof (ip));
16903
16904   /* Parse args required to build the message */
16905   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16906     {
16907       if (unformat (input, "disable"))
16908         is_add = 0;
16909       else
16910         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16911         {
16912           is_add = 1;
16913           ip_addr_version (&ip) = IP4;
16914         }
16915       else
16916         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16917         {
16918           is_add = 1;
16919           ip_addr_version (&ip) = IP6;
16920         }
16921       else
16922         {
16923           errmsg ("parse error '%U'", format_unformat_error, input);
16924           return -99;
16925         }
16926     }
16927
16928   M (ONE_USE_PETR, mp);
16929
16930   mp->is_add = is_add;
16931   if (is_add)
16932     {
16933       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16934       if (mp->is_ip4)
16935         clib_memcpy (mp->address, &ip, 4);
16936       else
16937         clib_memcpy (mp->address, &ip, 16);
16938     }
16939
16940   /* send */
16941   S (mp);
16942
16943   /* wait for reply */
16944   W (ret);
16945   return ret;
16946 }
16947
16948 #define api_lisp_use_petr api_one_use_petr
16949
16950 static int
16951 api_show_one_nsh_mapping (vat_main_t * vam)
16952 {
16953   vl_api_show_one_use_petr_t *mp;
16954   int ret;
16955
16956   if (!vam->json_output)
16957     {
16958       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16959     }
16960
16961   M (SHOW_ONE_NSH_MAPPING, mp);
16962   /* send it... */
16963   S (mp);
16964
16965   /* Wait for a reply... */
16966   W (ret);
16967   return ret;
16968 }
16969
16970 static int
16971 api_show_one_use_petr (vat_main_t * vam)
16972 {
16973   vl_api_show_one_use_petr_t *mp;
16974   int ret;
16975
16976   if (!vam->json_output)
16977     {
16978       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16979     }
16980
16981   M (SHOW_ONE_USE_PETR, mp);
16982   /* send it... */
16983   S (mp);
16984
16985   /* Wait for a reply... */
16986   W (ret);
16987   return ret;
16988 }
16989
16990 #define api_show_lisp_use_petr api_show_one_use_petr
16991
16992 /**
16993  * Add/delete mapping between vni and vrf
16994  */
16995 static int
16996 api_one_eid_table_add_del_map (vat_main_t * vam)
16997 {
16998   unformat_input_t *input = vam->input;
16999   vl_api_one_eid_table_add_del_map_t *mp;
17000   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
17001   u32 vni, vrf, bd_index;
17002   int ret;
17003
17004   /* Parse args required to build the message */
17005   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17006     {
17007       if (unformat (input, "del"))
17008         is_add = 0;
17009       else if (unformat (input, "vrf %d", &vrf))
17010         vrf_set = 1;
17011       else if (unformat (input, "bd_index %d", &bd_index))
17012         bd_index_set = 1;
17013       else if (unformat (input, "vni %d", &vni))
17014         vni_set = 1;
17015       else
17016         break;
17017     }
17018
17019   if (!vni_set || (!vrf_set && !bd_index_set))
17020     {
17021       errmsg ("missing arguments!");
17022       return -99;
17023     }
17024
17025   if (vrf_set && bd_index_set)
17026     {
17027       errmsg ("error: both vrf and bd entered!");
17028       return -99;
17029     }
17030
17031   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
17032
17033   mp->is_add = is_add;
17034   mp->vni = htonl (vni);
17035   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
17036   mp->is_l2 = bd_index_set;
17037
17038   /* send */
17039   S (mp);
17040
17041   /* wait for reply */
17042   W (ret);
17043   return ret;
17044 }
17045
17046 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
17047
17048 uword
17049 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
17050 {
17051   u32 *action = va_arg (*args, u32 *);
17052   u8 *s = 0;
17053
17054   if (unformat (input, "%s", &s))
17055     {
17056       if (!strcmp ((char *) s, "no-action"))
17057         action[0] = 0;
17058       else if (!strcmp ((char *) s, "natively-forward"))
17059         action[0] = 1;
17060       else if (!strcmp ((char *) s, "send-map-request"))
17061         action[0] = 2;
17062       else if (!strcmp ((char *) s, "drop"))
17063         action[0] = 3;
17064       else
17065         {
17066           clib_warning ("invalid action: '%s'", s);
17067           action[0] = 3;
17068         }
17069     }
17070   else
17071     return 0;
17072
17073   vec_free (s);
17074   return 1;
17075 }
17076
17077 /**
17078  * Add/del remote mapping to/from ONE control plane
17079  *
17080  * @param vam vpp API test context
17081  * @return return code
17082  */
17083 static int
17084 api_one_add_del_remote_mapping (vat_main_t * vam)
17085 {
17086   unformat_input_t *input = vam->input;
17087   vl_api_one_add_del_remote_mapping_t *mp;
17088   u32 vni = 0;
17089   lisp_eid_vat_t _eid, *eid = &_eid;
17090   lisp_eid_vat_t _seid, *seid = &_seid;
17091   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
17092   u32 action = ~0, p, w, data_len;
17093   ip4_address_t rloc4;
17094   ip6_address_t rloc6;
17095   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
17096   int ret;
17097
17098   memset (&rloc, 0, sizeof (rloc));
17099
17100   /* Parse args required to build the message */
17101   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17102     {
17103       if (unformat (input, "del-all"))
17104         {
17105           del_all = 1;
17106         }
17107       else if (unformat (input, "del"))
17108         {
17109           is_add = 0;
17110         }
17111       else if (unformat (input, "add"))
17112         {
17113           is_add = 1;
17114         }
17115       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
17116         {
17117           eid_set = 1;
17118         }
17119       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
17120         {
17121           seid_set = 1;
17122         }
17123       else if (unformat (input, "vni %d", &vni))
17124         {
17125           ;
17126         }
17127       else if (unformat (input, "p %d w %d", &p, &w))
17128         {
17129           if (!curr_rloc)
17130             {
17131               errmsg ("No RLOC configured for setting priority/weight!");
17132               return -99;
17133             }
17134           curr_rloc->priority = p;
17135           curr_rloc->weight = w;
17136         }
17137       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
17138         {
17139           rloc.is_ip4 = 1;
17140           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17141           vec_add1 (rlocs, rloc);
17142           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17143         }
17144       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
17145         {
17146           rloc.is_ip4 = 0;
17147           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17148           vec_add1 (rlocs, rloc);
17149           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17150         }
17151       else if (unformat (input, "action %U",
17152                          unformat_negative_mapping_action, &action))
17153         {
17154           ;
17155         }
17156       else
17157         {
17158           clib_warning ("parse error '%U'", format_unformat_error, input);
17159           return -99;
17160         }
17161     }
17162
17163   if (0 == eid_set)
17164     {
17165       errmsg ("missing params!");
17166       return -99;
17167     }
17168
17169   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17170     {
17171       errmsg ("no action set for negative map-reply!");
17172       return -99;
17173     }
17174
17175   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17176
17177   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17178   mp->is_add = is_add;
17179   mp->vni = htonl (vni);
17180   mp->action = (u8) action;
17181   mp->is_src_dst = seid_set;
17182   mp->eid_len = eid->len;
17183   mp->seid_len = seid->len;
17184   mp->del_all = del_all;
17185   mp->eid_type = eid->type;
17186   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17187   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17188
17189   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17190   clib_memcpy (mp->rlocs, rlocs, data_len);
17191   vec_free (rlocs);
17192
17193   /* send it... */
17194   S (mp);
17195
17196   /* Wait for a reply... */
17197   W (ret);
17198   return ret;
17199 }
17200
17201 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17202
17203 /**
17204  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17205  * forwarding entries in data-plane accordingly.
17206  *
17207  * @param vam vpp API test context
17208  * @return return code
17209  */
17210 static int
17211 api_one_add_del_adjacency (vat_main_t * vam)
17212 {
17213   unformat_input_t *input = vam->input;
17214   vl_api_one_add_del_adjacency_t *mp;
17215   u32 vni = 0;
17216   ip4_address_t leid4, reid4;
17217   ip6_address_t leid6, reid6;
17218   u8 reid_mac[6] = { 0 };
17219   u8 leid_mac[6] = { 0 };
17220   u8 reid_type, leid_type;
17221   u32 leid_len = 0, reid_len = 0, len;
17222   u8 is_add = 1;
17223   int ret;
17224
17225   leid_type = reid_type = (u8) ~ 0;
17226
17227   /* Parse args required to build the message */
17228   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17229     {
17230       if (unformat (input, "del"))
17231         {
17232           is_add = 0;
17233         }
17234       else if (unformat (input, "add"))
17235         {
17236           is_add = 1;
17237         }
17238       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17239                          &reid4, &len))
17240         {
17241           reid_type = 0;        /* ipv4 */
17242           reid_len = len;
17243         }
17244       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17245                          &reid6, &len))
17246         {
17247           reid_type = 1;        /* ipv6 */
17248           reid_len = len;
17249         }
17250       else if (unformat (input, "reid %U", unformat_ethernet_address,
17251                          reid_mac))
17252         {
17253           reid_type = 2;        /* mac */
17254         }
17255       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17256                          &leid4, &len))
17257         {
17258           leid_type = 0;        /* ipv4 */
17259           leid_len = len;
17260         }
17261       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17262                          &leid6, &len))
17263         {
17264           leid_type = 1;        /* ipv6 */
17265           leid_len = len;
17266         }
17267       else if (unformat (input, "leid %U", unformat_ethernet_address,
17268                          leid_mac))
17269         {
17270           leid_type = 2;        /* mac */
17271         }
17272       else if (unformat (input, "vni %d", &vni))
17273         {
17274           ;
17275         }
17276       else
17277         {
17278           errmsg ("parse error '%U'", format_unformat_error, input);
17279           return -99;
17280         }
17281     }
17282
17283   if ((u8) ~ 0 == reid_type)
17284     {
17285       errmsg ("missing params!");
17286       return -99;
17287     }
17288
17289   if (leid_type != reid_type)
17290     {
17291       errmsg ("remote and local EIDs are of different types!");
17292       return -99;
17293     }
17294
17295   M (ONE_ADD_DEL_ADJACENCY, mp);
17296   mp->is_add = is_add;
17297   mp->vni = htonl (vni);
17298   mp->leid_len = leid_len;
17299   mp->reid_len = reid_len;
17300   mp->eid_type = reid_type;
17301
17302   switch (mp->eid_type)
17303     {
17304     case 0:
17305       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17306       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17307       break;
17308     case 1:
17309       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17310       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17311       break;
17312     case 2:
17313       clib_memcpy (mp->leid, leid_mac, 6);
17314       clib_memcpy (mp->reid, reid_mac, 6);
17315       break;
17316     default:
17317       errmsg ("unknown EID type %d!", mp->eid_type);
17318       return 0;
17319     }
17320
17321   /* send it... */
17322   S (mp);
17323
17324   /* Wait for a reply... */
17325   W (ret);
17326   return ret;
17327 }
17328
17329 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17330
17331 uword
17332 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17333 {
17334   u32 *mode = va_arg (*args, u32 *);
17335
17336   if (unformat (input, "lisp"))
17337     *mode = 0;
17338   else if (unformat (input, "vxlan"))
17339     *mode = 1;
17340   else
17341     return 0;
17342
17343   return 1;
17344 }
17345
17346 static int
17347 api_gpe_get_encap_mode (vat_main_t * vam)
17348 {
17349   vl_api_gpe_get_encap_mode_t *mp;
17350   int ret;
17351
17352   /* Construct the API message */
17353   M (GPE_GET_ENCAP_MODE, mp);
17354
17355   /* send it... */
17356   S (mp);
17357
17358   /* Wait for a reply... */
17359   W (ret);
17360   return ret;
17361 }
17362
17363 static int
17364 api_gpe_set_encap_mode (vat_main_t * vam)
17365 {
17366   unformat_input_t *input = vam->input;
17367   vl_api_gpe_set_encap_mode_t *mp;
17368   int ret;
17369   u32 mode = 0;
17370
17371   /* Parse args required to build the message */
17372   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17373     {
17374       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17375         ;
17376       else
17377         break;
17378     }
17379
17380   /* Construct the API message */
17381   M (GPE_SET_ENCAP_MODE, mp);
17382
17383   mp->mode = mode;
17384
17385   /* send it... */
17386   S (mp);
17387
17388   /* Wait for a reply... */
17389   W (ret);
17390   return ret;
17391 }
17392
17393 static int
17394 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17395 {
17396   unformat_input_t *input = vam->input;
17397   vl_api_gpe_add_del_iface_t *mp;
17398   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17399   u32 dp_table = 0, vni = 0;
17400   int ret;
17401
17402   /* Parse args required to build the message */
17403   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17404     {
17405       if (unformat (input, "up"))
17406         {
17407           action_set = 1;
17408           is_add = 1;
17409         }
17410       else if (unformat (input, "down"))
17411         {
17412           action_set = 1;
17413           is_add = 0;
17414         }
17415       else if (unformat (input, "table_id %d", &dp_table))
17416         {
17417           dp_table_set = 1;
17418         }
17419       else if (unformat (input, "bd_id %d", &dp_table))
17420         {
17421           dp_table_set = 1;
17422           is_l2 = 1;
17423         }
17424       else if (unformat (input, "vni %d", &vni))
17425         {
17426           vni_set = 1;
17427         }
17428       else
17429         break;
17430     }
17431
17432   if (action_set == 0)
17433     {
17434       errmsg ("Action not set");
17435       return -99;
17436     }
17437   if (dp_table_set == 0 || vni_set == 0)
17438     {
17439       errmsg ("vni and dp_table must be set");
17440       return -99;
17441     }
17442
17443   /* Construct the API message */
17444   M (GPE_ADD_DEL_IFACE, mp);
17445
17446   mp->is_add = is_add;
17447   mp->dp_table = clib_host_to_net_u32 (dp_table);
17448   mp->is_l2 = is_l2;
17449   mp->vni = clib_host_to_net_u32 (vni);
17450
17451   /* send it... */
17452   S (mp);
17453
17454   /* Wait for a reply... */
17455   W (ret);
17456   return ret;
17457 }
17458
17459 static int
17460 api_one_map_register_fallback_threshold (vat_main_t * vam)
17461 {
17462   unformat_input_t *input = vam->input;
17463   vl_api_one_map_register_fallback_threshold_t *mp;
17464   u32 value = 0;
17465   u8 is_set = 0;
17466   int ret;
17467
17468   /* Parse args required to build the message */
17469   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17470     {
17471       if (unformat (input, "%u", &value))
17472         is_set = 1;
17473       else
17474         {
17475           clib_warning ("parse error '%U'", format_unformat_error, input);
17476           return -99;
17477         }
17478     }
17479
17480   if (!is_set)
17481     {
17482       errmsg ("fallback threshold value is missing!");
17483       return -99;
17484     }
17485
17486   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17487   mp->value = clib_host_to_net_u32 (value);
17488
17489   /* send it... */
17490   S (mp);
17491
17492   /* Wait for a reply... */
17493   W (ret);
17494   return ret;
17495 }
17496
17497 static int
17498 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17499 {
17500   vl_api_show_one_map_register_fallback_threshold_t *mp;
17501   int ret;
17502
17503   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17504
17505   /* send it... */
17506   S (mp);
17507
17508   /* Wait for a reply... */
17509   W (ret);
17510   return ret;
17511 }
17512
17513 uword
17514 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17515 {
17516   u32 *proto = va_arg (*args, u32 *);
17517
17518   if (unformat (input, "udp"))
17519     *proto = 1;
17520   else if (unformat (input, "api"))
17521     *proto = 2;
17522   else
17523     return 0;
17524
17525   return 1;
17526 }
17527
17528 static int
17529 api_one_set_transport_protocol (vat_main_t * vam)
17530 {
17531   unformat_input_t *input = vam->input;
17532   vl_api_one_set_transport_protocol_t *mp;
17533   u8 is_set = 0;
17534   u32 protocol = 0;
17535   int ret;
17536
17537   /* Parse args required to build the message */
17538   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17539     {
17540       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17541         is_set = 1;
17542       else
17543         {
17544           clib_warning ("parse error '%U'", format_unformat_error, input);
17545           return -99;
17546         }
17547     }
17548
17549   if (!is_set)
17550     {
17551       errmsg ("Transport protocol missing!");
17552       return -99;
17553     }
17554
17555   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17556   mp->protocol = (u8) protocol;
17557
17558   /* send it... */
17559   S (mp);
17560
17561   /* Wait for a reply... */
17562   W (ret);
17563   return ret;
17564 }
17565
17566 static int
17567 api_one_get_transport_protocol (vat_main_t * vam)
17568 {
17569   vl_api_one_get_transport_protocol_t *mp;
17570   int ret;
17571
17572   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17573
17574   /* send it... */
17575   S (mp);
17576
17577   /* Wait for a reply... */
17578   W (ret);
17579   return ret;
17580 }
17581
17582 static int
17583 api_one_map_register_set_ttl (vat_main_t * vam)
17584 {
17585   unformat_input_t *input = vam->input;
17586   vl_api_one_map_register_set_ttl_t *mp;
17587   u32 ttl = 0;
17588   u8 is_set = 0;
17589   int ret;
17590
17591   /* Parse args required to build the message */
17592   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17593     {
17594       if (unformat (input, "%u", &ttl))
17595         is_set = 1;
17596       else
17597         {
17598           clib_warning ("parse error '%U'", format_unformat_error, input);
17599           return -99;
17600         }
17601     }
17602
17603   if (!is_set)
17604     {
17605       errmsg ("TTL value missing!");
17606       return -99;
17607     }
17608
17609   M (ONE_MAP_REGISTER_SET_TTL, mp);
17610   mp->ttl = clib_host_to_net_u32 (ttl);
17611
17612   /* send it... */
17613   S (mp);
17614
17615   /* Wait for a reply... */
17616   W (ret);
17617   return ret;
17618 }
17619
17620 static int
17621 api_show_one_map_register_ttl (vat_main_t * vam)
17622 {
17623   vl_api_show_one_map_register_ttl_t *mp;
17624   int ret;
17625
17626   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17627
17628   /* send it... */
17629   S (mp);
17630
17631   /* Wait for a reply... */
17632   W (ret);
17633   return ret;
17634 }
17635
17636 /**
17637  * Add/del map request itr rlocs from ONE control plane and updates
17638  *
17639  * @param vam vpp API test context
17640  * @return return code
17641  */
17642 static int
17643 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17644 {
17645   unformat_input_t *input = vam->input;
17646   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17647   u8 *locator_set_name = 0;
17648   u8 locator_set_name_set = 0;
17649   u8 is_add = 1;
17650   int ret;
17651
17652   /* Parse args required to build the message */
17653   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17654     {
17655       if (unformat (input, "del"))
17656         {
17657           is_add = 0;
17658         }
17659       else if (unformat (input, "%_%v%_", &locator_set_name))
17660         {
17661           locator_set_name_set = 1;
17662         }
17663       else
17664         {
17665           clib_warning ("parse error '%U'", format_unformat_error, input);
17666           return -99;
17667         }
17668     }
17669
17670   if (is_add && !locator_set_name_set)
17671     {
17672       errmsg ("itr-rloc is not set!");
17673       return -99;
17674     }
17675
17676   if (is_add && vec_len (locator_set_name) > 64)
17677     {
17678       errmsg ("itr-rloc locator-set name too long");
17679       vec_free (locator_set_name);
17680       return -99;
17681     }
17682
17683   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17684   mp->is_add = is_add;
17685   if (is_add)
17686     {
17687       clib_memcpy (mp->locator_set_name, locator_set_name,
17688                    vec_len (locator_set_name));
17689     }
17690   else
17691     {
17692       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17693     }
17694   vec_free (locator_set_name);
17695
17696   /* send it... */
17697   S (mp);
17698
17699   /* Wait for a reply... */
17700   W (ret);
17701   return ret;
17702 }
17703
17704 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17705
17706 static int
17707 api_one_locator_dump (vat_main_t * vam)
17708 {
17709   unformat_input_t *input = vam->input;
17710   vl_api_one_locator_dump_t *mp;
17711   vl_api_control_ping_t *mp_ping;
17712   u8 is_index_set = 0, is_name_set = 0;
17713   u8 *ls_name = 0;
17714   u32 ls_index = ~0;
17715   int ret;
17716
17717   /* Parse args required to build the message */
17718   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17719     {
17720       if (unformat (input, "ls_name %_%v%_", &ls_name))
17721         {
17722           is_name_set = 1;
17723         }
17724       else if (unformat (input, "ls_index %d", &ls_index))
17725         {
17726           is_index_set = 1;
17727         }
17728       else
17729         {
17730           errmsg ("parse error '%U'", format_unformat_error, input);
17731           return -99;
17732         }
17733     }
17734
17735   if (!is_index_set && !is_name_set)
17736     {
17737       errmsg ("error: expected one of index or name!");
17738       return -99;
17739     }
17740
17741   if (is_index_set && is_name_set)
17742     {
17743       errmsg ("error: only one param expected!");
17744       return -99;
17745     }
17746
17747   if (vec_len (ls_name) > 62)
17748     {
17749       errmsg ("error: locator set name too long!");
17750       return -99;
17751     }
17752
17753   if (!vam->json_output)
17754     {
17755       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17756     }
17757
17758   M (ONE_LOCATOR_DUMP, mp);
17759   mp->is_index_set = is_index_set;
17760
17761   if (is_index_set)
17762     mp->ls_index = clib_host_to_net_u32 (ls_index);
17763   else
17764     {
17765       vec_add1 (ls_name, 0);
17766       strncpy ((char *) mp->ls_name, (char *) ls_name,
17767                sizeof (mp->ls_name) - 1);
17768     }
17769
17770   /* send it... */
17771   S (mp);
17772
17773   /* Use a control ping for synchronization */
17774   MPING (CONTROL_PING, mp_ping);
17775   S (mp_ping);
17776
17777   /* Wait for a reply... */
17778   W (ret);
17779   return ret;
17780 }
17781
17782 #define api_lisp_locator_dump api_one_locator_dump
17783
17784 static int
17785 api_one_locator_set_dump (vat_main_t * vam)
17786 {
17787   vl_api_one_locator_set_dump_t *mp;
17788   vl_api_control_ping_t *mp_ping;
17789   unformat_input_t *input = vam->input;
17790   u8 filter = 0;
17791   int ret;
17792
17793   /* Parse args required to build the message */
17794   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17795     {
17796       if (unformat (input, "local"))
17797         {
17798           filter = 1;
17799         }
17800       else if (unformat (input, "remote"))
17801         {
17802           filter = 2;
17803         }
17804       else
17805         {
17806           errmsg ("parse error '%U'", format_unformat_error, input);
17807           return -99;
17808         }
17809     }
17810
17811   if (!vam->json_output)
17812     {
17813       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17814     }
17815
17816   M (ONE_LOCATOR_SET_DUMP, mp);
17817
17818   mp->filter = filter;
17819
17820   /* send it... */
17821   S (mp);
17822
17823   /* Use a control ping for synchronization */
17824   MPING (CONTROL_PING, mp_ping);
17825   S (mp_ping);
17826
17827   /* Wait for a reply... */
17828   W (ret);
17829   return ret;
17830 }
17831
17832 #define api_lisp_locator_set_dump api_one_locator_set_dump
17833
17834 static int
17835 api_one_eid_table_map_dump (vat_main_t * vam)
17836 {
17837   u8 is_l2 = 0;
17838   u8 mode_set = 0;
17839   unformat_input_t *input = vam->input;
17840   vl_api_one_eid_table_map_dump_t *mp;
17841   vl_api_control_ping_t *mp_ping;
17842   int ret;
17843
17844   /* Parse args required to build the message */
17845   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17846     {
17847       if (unformat (input, "l2"))
17848         {
17849           is_l2 = 1;
17850           mode_set = 1;
17851         }
17852       else if (unformat (input, "l3"))
17853         {
17854           is_l2 = 0;
17855           mode_set = 1;
17856         }
17857       else
17858         {
17859           errmsg ("parse error '%U'", format_unformat_error, input);
17860           return -99;
17861         }
17862     }
17863
17864   if (!mode_set)
17865     {
17866       errmsg ("expected one of 'l2' or 'l3' parameter!");
17867       return -99;
17868     }
17869
17870   if (!vam->json_output)
17871     {
17872       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17873     }
17874
17875   M (ONE_EID_TABLE_MAP_DUMP, mp);
17876   mp->is_l2 = is_l2;
17877
17878   /* send it... */
17879   S (mp);
17880
17881   /* Use a control ping for synchronization */
17882   MPING (CONTROL_PING, mp_ping);
17883   S (mp_ping);
17884
17885   /* Wait for a reply... */
17886   W (ret);
17887   return ret;
17888 }
17889
17890 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17891
17892 static int
17893 api_one_eid_table_vni_dump (vat_main_t * vam)
17894 {
17895   vl_api_one_eid_table_vni_dump_t *mp;
17896   vl_api_control_ping_t *mp_ping;
17897   int ret;
17898
17899   if (!vam->json_output)
17900     {
17901       print (vam->ofp, "VNI");
17902     }
17903
17904   M (ONE_EID_TABLE_VNI_DUMP, mp);
17905
17906   /* send it... */
17907   S (mp);
17908
17909   /* Use a control ping for synchronization */
17910   MPING (CONTROL_PING, mp_ping);
17911   S (mp_ping);
17912
17913   /* Wait for a reply... */
17914   W (ret);
17915   return ret;
17916 }
17917
17918 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17919
17920 static int
17921 api_one_eid_table_dump (vat_main_t * vam)
17922 {
17923   unformat_input_t *i = vam->input;
17924   vl_api_one_eid_table_dump_t *mp;
17925   vl_api_control_ping_t *mp_ping;
17926   struct in_addr ip4;
17927   struct in6_addr ip6;
17928   u8 mac[6];
17929   u8 eid_type = ~0, eid_set = 0;
17930   u32 prefix_length = ~0, t, vni = 0;
17931   u8 filter = 0;
17932   int ret;
17933   lisp_nsh_api_t nsh;
17934
17935   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17936     {
17937       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17938         {
17939           eid_set = 1;
17940           eid_type = 0;
17941           prefix_length = t;
17942         }
17943       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17944         {
17945           eid_set = 1;
17946           eid_type = 1;
17947           prefix_length = t;
17948         }
17949       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17950         {
17951           eid_set = 1;
17952           eid_type = 2;
17953         }
17954       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17955         {
17956           eid_set = 1;
17957           eid_type = 3;
17958         }
17959       else if (unformat (i, "vni %d", &t))
17960         {
17961           vni = t;
17962         }
17963       else if (unformat (i, "local"))
17964         {
17965           filter = 1;
17966         }
17967       else if (unformat (i, "remote"))
17968         {
17969           filter = 2;
17970         }
17971       else
17972         {
17973           errmsg ("parse error '%U'", format_unformat_error, i);
17974           return -99;
17975         }
17976     }
17977
17978   if (!vam->json_output)
17979     {
17980       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17981              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17982     }
17983
17984   M (ONE_EID_TABLE_DUMP, mp);
17985
17986   mp->filter = filter;
17987   if (eid_set)
17988     {
17989       mp->eid_set = 1;
17990       mp->vni = htonl (vni);
17991       mp->eid_type = eid_type;
17992       switch (eid_type)
17993         {
17994         case 0:
17995           mp->prefix_length = prefix_length;
17996           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17997           break;
17998         case 1:
17999           mp->prefix_length = prefix_length;
18000           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
18001           break;
18002         case 2:
18003           clib_memcpy (mp->eid, mac, sizeof (mac));
18004           break;
18005         case 3:
18006           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
18007           break;
18008         default:
18009           errmsg ("unknown EID type %d!", eid_type);
18010           return -99;
18011         }
18012     }
18013
18014   /* send it... */
18015   S (mp);
18016
18017   /* Use a control ping for synchronization */
18018   MPING (CONTROL_PING, mp_ping);
18019   S (mp_ping);
18020
18021   /* Wait for a reply... */
18022   W (ret);
18023   return ret;
18024 }
18025
18026 #define api_lisp_eid_table_dump api_one_eid_table_dump
18027
18028 static int
18029 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
18030 {
18031   unformat_input_t *i = vam->input;
18032   vl_api_gpe_fwd_entries_get_t *mp;
18033   u8 vni_set = 0;
18034   u32 vni = ~0;
18035   int ret;
18036
18037   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18038     {
18039       if (unformat (i, "vni %d", &vni))
18040         {
18041           vni_set = 1;
18042         }
18043       else
18044         {
18045           errmsg ("parse error '%U'", format_unformat_error, i);
18046           return -99;
18047         }
18048     }
18049
18050   if (!vni_set)
18051     {
18052       errmsg ("vni not set!");
18053       return -99;
18054     }
18055
18056   if (!vam->json_output)
18057     {
18058       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
18059              "leid", "reid");
18060     }
18061
18062   M (GPE_FWD_ENTRIES_GET, mp);
18063   mp->vni = clib_host_to_net_u32 (vni);
18064
18065   /* send it... */
18066   S (mp);
18067
18068   /* Wait for a reply... */
18069   W (ret);
18070   return ret;
18071 }
18072
18073 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
18074 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
18075 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
18076 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
18077 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
18078 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
18079 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
18080 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
18081
18082 static int
18083 api_one_adjacencies_get (vat_main_t * vam)
18084 {
18085   unformat_input_t *i = vam->input;
18086   vl_api_one_adjacencies_get_t *mp;
18087   u8 vni_set = 0;
18088   u32 vni = ~0;
18089   int ret;
18090
18091   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18092     {
18093       if (unformat (i, "vni %d", &vni))
18094         {
18095           vni_set = 1;
18096         }
18097       else
18098         {
18099           errmsg ("parse error '%U'", format_unformat_error, i);
18100           return -99;
18101         }
18102     }
18103
18104   if (!vni_set)
18105     {
18106       errmsg ("vni not set!");
18107       return -99;
18108     }
18109
18110   if (!vam->json_output)
18111     {
18112       print (vam->ofp, "%s %40s", "leid", "reid");
18113     }
18114
18115   M (ONE_ADJACENCIES_GET, mp);
18116   mp->vni = clib_host_to_net_u32 (vni);
18117
18118   /* send it... */
18119   S (mp);
18120
18121   /* Wait for a reply... */
18122   W (ret);
18123   return ret;
18124 }
18125
18126 #define api_lisp_adjacencies_get api_one_adjacencies_get
18127
18128 static int
18129 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
18130 {
18131   unformat_input_t *i = vam->input;
18132   vl_api_gpe_native_fwd_rpaths_get_t *mp;
18133   int ret;
18134   u8 ip_family_set = 0, is_ip4 = 1;
18135
18136   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18137     {
18138       if (unformat (i, "ip4"))
18139         {
18140           ip_family_set = 1;
18141           is_ip4 = 1;
18142         }
18143       else if (unformat (i, "ip6"))
18144         {
18145           ip_family_set = 1;
18146           is_ip4 = 0;
18147         }
18148       else
18149         {
18150           errmsg ("parse error '%U'", format_unformat_error, i);
18151           return -99;
18152         }
18153     }
18154
18155   if (!ip_family_set)
18156     {
18157       errmsg ("ip family not set!");
18158       return -99;
18159     }
18160
18161   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18162   mp->is_ip4 = is_ip4;
18163
18164   /* send it... */
18165   S (mp);
18166
18167   /* Wait for a reply... */
18168   W (ret);
18169   return ret;
18170 }
18171
18172 static int
18173 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18174 {
18175   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18176   int ret;
18177
18178   if (!vam->json_output)
18179     {
18180       print (vam->ofp, "VNIs");
18181     }
18182
18183   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18184
18185   /* send it... */
18186   S (mp);
18187
18188   /* Wait for a reply... */
18189   W (ret);
18190   return ret;
18191 }
18192
18193 static int
18194 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18195 {
18196   unformat_input_t *i = vam->input;
18197   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18198   int ret = 0;
18199   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18200   struct in_addr ip4;
18201   struct in6_addr ip6;
18202   u32 table_id = 0, nh_sw_if_index = ~0;
18203
18204   memset (&ip4, 0, sizeof (ip4));
18205   memset (&ip6, 0, sizeof (ip6));
18206
18207   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18208     {
18209       if (unformat (i, "del"))
18210         is_add = 0;
18211       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18212                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18213         {
18214           ip_set = 1;
18215           is_ip4 = 1;
18216         }
18217       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18218                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18219         {
18220           ip_set = 1;
18221           is_ip4 = 0;
18222         }
18223       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18224         {
18225           ip_set = 1;
18226           is_ip4 = 1;
18227           nh_sw_if_index = ~0;
18228         }
18229       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18230         {
18231           ip_set = 1;
18232           is_ip4 = 0;
18233           nh_sw_if_index = ~0;
18234         }
18235       else if (unformat (i, "table %d", &table_id))
18236         ;
18237       else
18238         {
18239           errmsg ("parse error '%U'", format_unformat_error, i);
18240           return -99;
18241         }
18242     }
18243
18244   if (!ip_set)
18245     {
18246       errmsg ("nh addr not set!");
18247       return -99;
18248     }
18249
18250   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18251   mp->is_add = is_add;
18252   mp->table_id = clib_host_to_net_u32 (table_id);
18253   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18254   mp->is_ip4 = is_ip4;
18255   if (is_ip4)
18256     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18257   else
18258     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18259
18260   /* send it... */
18261   S (mp);
18262
18263   /* Wait for a reply... */
18264   W (ret);
18265   return ret;
18266 }
18267
18268 static int
18269 api_one_map_server_dump (vat_main_t * vam)
18270 {
18271   vl_api_one_map_server_dump_t *mp;
18272   vl_api_control_ping_t *mp_ping;
18273   int ret;
18274
18275   if (!vam->json_output)
18276     {
18277       print (vam->ofp, "%=20s", "Map server");
18278     }
18279
18280   M (ONE_MAP_SERVER_DUMP, mp);
18281   /* send it... */
18282   S (mp);
18283
18284   /* Use a control ping for synchronization */
18285   MPING (CONTROL_PING, mp_ping);
18286   S (mp_ping);
18287
18288   /* Wait for a reply... */
18289   W (ret);
18290   return ret;
18291 }
18292
18293 #define api_lisp_map_server_dump api_one_map_server_dump
18294
18295 static int
18296 api_one_map_resolver_dump (vat_main_t * vam)
18297 {
18298   vl_api_one_map_resolver_dump_t *mp;
18299   vl_api_control_ping_t *mp_ping;
18300   int ret;
18301
18302   if (!vam->json_output)
18303     {
18304       print (vam->ofp, "%=20s", "Map resolver");
18305     }
18306
18307   M (ONE_MAP_RESOLVER_DUMP, mp);
18308   /* send it... */
18309   S (mp);
18310
18311   /* Use a control ping for synchronization */
18312   MPING (CONTROL_PING, mp_ping);
18313   S (mp_ping);
18314
18315   /* Wait for a reply... */
18316   W (ret);
18317   return ret;
18318 }
18319
18320 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18321
18322 static int
18323 api_one_stats_flush (vat_main_t * vam)
18324 {
18325   vl_api_one_stats_flush_t *mp;
18326   int ret = 0;
18327
18328   M (ONE_STATS_FLUSH, mp);
18329   S (mp);
18330   W (ret);
18331   return ret;
18332 }
18333
18334 static int
18335 api_one_stats_dump (vat_main_t * vam)
18336 {
18337   vl_api_one_stats_dump_t *mp;
18338   vl_api_control_ping_t *mp_ping;
18339   int ret;
18340
18341   M (ONE_STATS_DUMP, mp);
18342   /* send it... */
18343   S (mp);
18344
18345   /* Use a control ping for synchronization */
18346   MPING (CONTROL_PING, mp_ping);
18347   S (mp_ping);
18348
18349   /* Wait for a reply... */
18350   W (ret);
18351   return ret;
18352 }
18353
18354 static int
18355 api_show_one_status (vat_main_t * vam)
18356 {
18357   vl_api_show_one_status_t *mp;
18358   int ret;
18359
18360   if (!vam->json_output)
18361     {
18362       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18363     }
18364
18365   M (SHOW_ONE_STATUS, mp);
18366   /* send it... */
18367   S (mp);
18368   /* Wait for a reply... */
18369   W (ret);
18370   return ret;
18371 }
18372
18373 #define api_show_lisp_status api_show_one_status
18374
18375 static int
18376 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18377 {
18378   vl_api_gpe_fwd_entry_path_dump_t *mp;
18379   vl_api_control_ping_t *mp_ping;
18380   unformat_input_t *i = vam->input;
18381   u32 fwd_entry_index = ~0;
18382   int ret;
18383
18384   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18385     {
18386       if (unformat (i, "index %d", &fwd_entry_index))
18387         ;
18388       else
18389         break;
18390     }
18391
18392   if (~0 == fwd_entry_index)
18393     {
18394       errmsg ("no index specified!");
18395       return -99;
18396     }
18397
18398   if (!vam->json_output)
18399     {
18400       print (vam->ofp, "first line");
18401     }
18402
18403   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18404
18405   /* send it... */
18406   S (mp);
18407   /* Use a control ping for synchronization */
18408   MPING (CONTROL_PING, mp_ping);
18409   S (mp_ping);
18410
18411   /* Wait for a reply... */
18412   W (ret);
18413   return ret;
18414 }
18415
18416 static int
18417 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18418 {
18419   vl_api_one_get_map_request_itr_rlocs_t *mp;
18420   int ret;
18421
18422   if (!vam->json_output)
18423     {
18424       print (vam->ofp, "%=20s", "itr-rlocs:");
18425     }
18426
18427   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18428   /* send it... */
18429   S (mp);
18430   /* Wait for a reply... */
18431   W (ret);
18432   return ret;
18433 }
18434
18435 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18436
18437 static int
18438 api_af_packet_create (vat_main_t * vam)
18439 {
18440   unformat_input_t *i = vam->input;
18441   vl_api_af_packet_create_t *mp;
18442   u8 *host_if_name = 0;
18443   u8 hw_addr[6];
18444   u8 random_hw_addr = 1;
18445   int ret;
18446
18447   memset (hw_addr, 0, sizeof (hw_addr));
18448
18449   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18450     {
18451       if (unformat (i, "name %s", &host_if_name))
18452         vec_add1 (host_if_name, 0);
18453       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18454         random_hw_addr = 0;
18455       else
18456         break;
18457     }
18458
18459   if (!vec_len (host_if_name))
18460     {
18461       errmsg ("host-interface name must be specified");
18462       return -99;
18463     }
18464
18465   if (vec_len (host_if_name) > 64)
18466     {
18467       errmsg ("host-interface name too long");
18468       return -99;
18469     }
18470
18471   M (AF_PACKET_CREATE, mp);
18472
18473   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18474   clib_memcpy (mp->hw_addr, hw_addr, 6);
18475   mp->use_random_hw_addr = random_hw_addr;
18476   vec_free (host_if_name);
18477
18478   S (mp);
18479
18480   /* *INDENT-OFF* */
18481   W2 (ret,
18482       ({
18483         if (ret == 0)
18484           fprintf (vam->ofp ? vam->ofp : stderr,
18485                    " new sw_if_index = %d\n", vam->sw_if_index);
18486       }));
18487   /* *INDENT-ON* */
18488   return ret;
18489 }
18490
18491 static int
18492 api_af_packet_delete (vat_main_t * vam)
18493 {
18494   unformat_input_t *i = vam->input;
18495   vl_api_af_packet_delete_t *mp;
18496   u8 *host_if_name = 0;
18497   int ret;
18498
18499   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18500     {
18501       if (unformat (i, "name %s", &host_if_name))
18502         vec_add1 (host_if_name, 0);
18503       else
18504         break;
18505     }
18506
18507   if (!vec_len (host_if_name))
18508     {
18509       errmsg ("host-interface name must be specified");
18510       return -99;
18511     }
18512
18513   if (vec_len (host_if_name) > 64)
18514     {
18515       errmsg ("host-interface name too long");
18516       return -99;
18517     }
18518
18519   M (AF_PACKET_DELETE, mp);
18520
18521   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18522   vec_free (host_if_name);
18523
18524   S (mp);
18525   W (ret);
18526   return ret;
18527 }
18528
18529 static int
18530 api_policer_add_del (vat_main_t * vam)
18531 {
18532   unformat_input_t *i = vam->input;
18533   vl_api_policer_add_del_t *mp;
18534   u8 is_add = 1;
18535   u8 *name = 0;
18536   u32 cir = 0;
18537   u32 eir = 0;
18538   u64 cb = 0;
18539   u64 eb = 0;
18540   u8 rate_type = 0;
18541   u8 round_type = 0;
18542   u8 type = 0;
18543   u8 color_aware = 0;
18544   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18545   int ret;
18546
18547   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18548   conform_action.dscp = 0;
18549   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18550   exceed_action.dscp = 0;
18551   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18552   violate_action.dscp = 0;
18553
18554   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18555     {
18556       if (unformat (i, "del"))
18557         is_add = 0;
18558       else if (unformat (i, "name %s", &name))
18559         vec_add1 (name, 0);
18560       else if (unformat (i, "cir %u", &cir))
18561         ;
18562       else if (unformat (i, "eir %u", &eir))
18563         ;
18564       else if (unformat (i, "cb %u", &cb))
18565         ;
18566       else if (unformat (i, "eb %u", &eb))
18567         ;
18568       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18569                          &rate_type))
18570         ;
18571       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18572                          &round_type))
18573         ;
18574       else if (unformat (i, "type %U", unformat_policer_type, &type))
18575         ;
18576       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18577                          &conform_action))
18578         ;
18579       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18580                          &exceed_action))
18581         ;
18582       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18583                          &violate_action))
18584         ;
18585       else if (unformat (i, "color-aware"))
18586         color_aware = 1;
18587       else
18588         break;
18589     }
18590
18591   if (!vec_len (name))
18592     {
18593       errmsg ("policer name must be specified");
18594       return -99;
18595     }
18596
18597   if (vec_len (name) > 64)
18598     {
18599       errmsg ("policer name too long");
18600       return -99;
18601     }
18602
18603   M (POLICER_ADD_DEL, mp);
18604
18605   clib_memcpy (mp->name, name, vec_len (name));
18606   vec_free (name);
18607   mp->is_add = is_add;
18608   mp->cir = ntohl (cir);
18609   mp->eir = ntohl (eir);
18610   mp->cb = clib_net_to_host_u64 (cb);
18611   mp->eb = clib_net_to_host_u64 (eb);
18612   mp->rate_type = rate_type;
18613   mp->round_type = round_type;
18614   mp->type = type;
18615   mp->conform_action_type = conform_action.action_type;
18616   mp->conform_dscp = conform_action.dscp;
18617   mp->exceed_action_type = exceed_action.action_type;
18618   mp->exceed_dscp = exceed_action.dscp;
18619   mp->violate_action_type = violate_action.action_type;
18620   mp->violate_dscp = violate_action.dscp;
18621   mp->color_aware = color_aware;
18622
18623   S (mp);
18624   W (ret);
18625   return ret;
18626 }
18627
18628 static int
18629 api_policer_dump (vat_main_t * vam)
18630 {
18631   unformat_input_t *i = vam->input;
18632   vl_api_policer_dump_t *mp;
18633   vl_api_control_ping_t *mp_ping;
18634   u8 *match_name = 0;
18635   u8 match_name_valid = 0;
18636   int ret;
18637
18638   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18639     {
18640       if (unformat (i, "name %s", &match_name))
18641         {
18642           vec_add1 (match_name, 0);
18643           match_name_valid = 1;
18644         }
18645       else
18646         break;
18647     }
18648
18649   M (POLICER_DUMP, mp);
18650   mp->match_name_valid = match_name_valid;
18651   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18652   vec_free (match_name);
18653   /* send it... */
18654   S (mp);
18655
18656   /* Use a control ping for synchronization */
18657   MPING (CONTROL_PING, mp_ping);
18658   S (mp_ping);
18659
18660   /* Wait for a reply... */
18661   W (ret);
18662   return ret;
18663 }
18664
18665 static int
18666 api_policer_classify_set_interface (vat_main_t * vam)
18667 {
18668   unformat_input_t *i = vam->input;
18669   vl_api_policer_classify_set_interface_t *mp;
18670   u32 sw_if_index;
18671   int sw_if_index_set;
18672   u32 ip4_table_index = ~0;
18673   u32 ip6_table_index = ~0;
18674   u32 l2_table_index = ~0;
18675   u8 is_add = 1;
18676   int ret;
18677
18678   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18679     {
18680       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18681         sw_if_index_set = 1;
18682       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18683         sw_if_index_set = 1;
18684       else if (unformat (i, "del"))
18685         is_add = 0;
18686       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18687         ;
18688       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18689         ;
18690       else if (unformat (i, "l2-table %d", &l2_table_index))
18691         ;
18692       else
18693         {
18694           clib_warning ("parse error '%U'", format_unformat_error, i);
18695           return -99;
18696         }
18697     }
18698
18699   if (sw_if_index_set == 0)
18700     {
18701       errmsg ("missing interface name or sw_if_index");
18702       return -99;
18703     }
18704
18705   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18706
18707   mp->sw_if_index = ntohl (sw_if_index);
18708   mp->ip4_table_index = ntohl (ip4_table_index);
18709   mp->ip6_table_index = ntohl (ip6_table_index);
18710   mp->l2_table_index = ntohl (l2_table_index);
18711   mp->is_add = is_add;
18712
18713   S (mp);
18714   W (ret);
18715   return ret;
18716 }
18717
18718 static int
18719 api_policer_classify_dump (vat_main_t * vam)
18720 {
18721   unformat_input_t *i = vam->input;
18722   vl_api_policer_classify_dump_t *mp;
18723   vl_api_control_ping_t *mp_ping;
18724   u8 type = POLICER_CLASSIFY_N_TABLES;
18725   int ret;
18726
18727   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18728     ;
18729   else
18730     {
18731       errmsg ("classify table type must be specified");
18732       return -99;
18733     }
18734
18735   if (!vam->json_output)
18736     {
18737       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18738     }
18739
18740   M (POLICER_CLASSIFY_DUMP, mp);
18741   mp->type = type;
18742   /* send it... */
18743   S (mp);
18744
18745   /* Use a control ping for synchronization */
18746   MPING (CONTROL_PING, mp_ping);
18747   S (mp_ping);
18748
18749   /* Wait for a reply... */
18750   W (ret);
18751   return ret;
18752 }
18753
18754 static int
18755 api_netmap_create (vat_main_t * vam)
18756 {
18757   unformat_input_t *i = vam->input;
18758   vl_api_netmap_create_t *mp;
18759   u8 *if_name = 0;
18760   u8 hw_addr[6];
18761   u8 random_hw_addr = 1;
18762   u8 is_pipe = 0;
18763   u8 is_master = 0;
18764   int ret;
18765
18766   memset (hw_addr, 0, sizeof (hw_addr));
18767
18768   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18769     {
18770       if (unformat (i, "name %s", &if_name))
18771         vec_add1 (if_name, 0);
18772       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18773         random_hw_addr = 0;
18774       else if (unformat (i, "pipe"))
18775         is_pipe = 1;
18776       else if (unformat (i, "master"))
18777         is_master = 1;
18778       else if (unformat (i, "slave"))
18779         is_master = 0;
18780       else
18781         break;
18782     }
18783
18784   if (!vec_len (if_name))
18785     {
18786       errmsg ("interface name must be specified");
18787       return -99;
18788     }
18789
18790   if (vec_len (if_name) > 64)
18791     {
18792       errmsg ("interface name too long");
18793       return -99;
18794     }
18795
18796   M (NETMAP_CREATE, mp);
18797
18798   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18799   clib_memcpy (mp->hw_addr, hw_addr, 6);
18800   mp->use_random_hw_addr = random_hw_addr;
18801   mp->is_pipe = is_pipe;
18802   mp->is_master = is_master;
18803   vec_free (if_name);
18804
18805   S (mp);
18806   W (ret);
18807   return ret;
18808 }
18809
18810 static int
18811 api_netmap_delete (vat_main_t * vam)
18812 {
18813   unformat_input_t *i = vam->input;
18814   vl_api_netmap_delete_t *mp;
18815   u8 *if_name = 0;
18816   int ret;
18817
18818   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18819     {
18820       if (unformat (i, "name %s", &if_name))
18821         vec_add1 (if_name, 0);
18822       else
18823         break;
18824     }
18825
18826   if (!vec_len (if_name))
18827     {
18828       errmsg ("interface name must be specified");
18829       return -99;
18830     }
18831
18832   if (vec_len (if_name) > 64)
18833     {
18834       errmsg ("interface name too long");
18835       return -99;
18836     }
18837
18838   M (NETMAP_DELETE, mp);
18839
18840   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18841   vec_free (if_name);
18842
18843   S (mp);
18844   W (ret);
18845   return ret;
18846 }
18847
18848 static void
18849 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
18850 {
18851   if (fp->afi == IP46_TYPE_IP6)
18852     print (vam->ofp,
18853            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18854            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18855            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18856            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18857            format_ip6_address, fp->next_hop);
18858   else if (fp->afi == IP46_TYPE_IP4)
18859     print (vam->ofp,
18860            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18861            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18862            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18863            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18864            format_ip4_address, fp->next_hop);
18865 }
18866
18867 static void
18868 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18869                                  vl_api_fib_path2_t * fp)
18870 {
18871   struct in_addr ip4;
18872   struct in6_addr ip6;
18873
18874   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18875   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18876   vat_json_object_add_uint (node, "is_local", fp->is_local);
18877   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
18878   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
18879   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
18880   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
18881   if (fp->afi == IP46_TYPE_IP4)
18882     {
18883       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
18884       vat_json_object_add_ip4 (node, "next_hop", ip4);
18885     }
18886   else if (fp->afi == IP46_TYPE_IP6)
18887     {
18888       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
18889       vat_json_object_add_ip6 (node, "next_hop", ip6);
18890     }
18891 }
18892
18893 static void
18894 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18895 {
18896   vat_main_t *vam = &vat_main;
18897   int count = ntohl (mp->mt_count);
18898   vl_api_fib_path2_t *fp;
18899   i32 i;
18900
18901   print (vam->ofp, "[%d]: sw_if_index %d via:",
18902          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
18903   fp = mp->mt_paths;
18904   for (i = 0; i < count; i++)
18905     {
18906       vl_api_mpls_fib_path_print (vam, fp);
18907       fp++;
18908     }
18909
18910   print (vam->ofp, "");
18911 }
18912
18913 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18914 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18915
18916 static void
18917 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18918 {
18919   vat_main_t *vam = &vat_main;
18920   vat_json_node_t *node = NULL;
18921   int count = ntohl (mp->mt_count);
18922   vl_api_fib_path2_t *fp;
18923   i32 i;
18924
18925   if (VAT_JSON_ARRAY != vam->json_tree.type)
18926     {
18927       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18928       vat_json_init_array (&vam->json_tree);
18929     }
18930   node = vat_json_array_add (&vam->json_tree);
18931
18932   vat_json_init_object (node);
18933   vat_json_object_add_uint (node, "tunnel_index",
18934                             ntohl (mp->mt_tunnel_index));
18935   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
18936
18937   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
18938
18939   fp = mp->mt_paths;
18940   for (i = 0; i < count; i++)
18941     {
18942       vl_api_mpls_fib_path_json_print (node, fp);
18943       fp++;
18944     }
18945 }
18946
18947 static int
18948 api_mpls_tunnel_dump (vat_main_t * vam)
18949 {
18950   vl_api_mpls_tunnel_dump_t *mp;
18951   vl_api_control_ping_t *mp_ping;
18952   i32 index = -1;
18953   int ret;
18954
18955   /* Parse args required to build the message */
18956   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
18957     {
18958       if (!unformat (vam->input, "tunnel_index %d", &index))
18959         {
18960           index = -1;
18961           break;
18962         }
18963     }
18964
18965   print (vam->ofp, "  tunnel_index %d", index);
18966
18967   M (MPLS_TUNNEL_DUMP, mp);
18968   mp->tunnel_index = htonl (index);
18969   S (mp);
18970
18971   /* Use a control ping for synchronization */
18972   MPING (CONTROL_PING, mp_ping);
18973   S (mp_ping);
18974
18975   W (ret);
18976   return ret;
18977 }
18978
18979 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
18980 #define vl_api_mpls_fib_details_t_print vl_noop_handler
18981
18982
18983 static void
18984 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
18985 {
18986   vat_main_t *vam = &vat_main;
18987   int count = ntohl (mp->count);
18988   vl_api_fib_path2_t *fp;
18989   int i;
18990
18991   print (vam->ofp,
18992          "table-id %d, label %u, ess_bit %u",
18993          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
18994   fp = mp->path;
18995   for (i = 0; i < count; i++)
18996     {
18997       vl_api_mpls_fib_path_print (vam, fp);
18998       fp++;
18999     }
19000 }
19001
19002 static void vl_api_mpls_fib_details_t_handler_json
19003   (vl_api_mpls_fib_details_t * mp)
19004 {
19005   vat_main_t *vam = &vat_main;
19006   int count = ntohl (mp->count);
19007   vat_json_node_t *node = NULL;
19008   vl_api_fib_path2_t *fp;
19009   int i;
19010
19011   if (VAT_JSON_ARRAY != vam->json_tree.type)
19012     {
19013       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19014       vat_json_init_array (&vam->json_tree);
19015     }
19016   node = vat_json_array_add (&vam->json_tree);
19017
19018   vat_json_init_object (node);
19019   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19020   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
19021   vat_json_object_add_uint (node, "label", ntohl (mp->label));
19022   vat_json_object_add_uint (node, "path_count", count);
19023   fp = mp->path;
19024   for (i = 0; i < count; i++)
19025     {
19026       vl_api_mpls_fib_path_json_print (node, fp);
19027       fp++;
19028     }
19029 }
19030
19031 static int
19032 api_mpls_fib_dump (vat_main_t * vam)
19033 {
19034   vl_api_mpls_fib_dump_t *mp;
19035   vl_api_control_ping_t *mp_ping;
19036   int ret;
19037
19038   M (MPLS_FIB_DUMP, mp);
19039   S (mp);
19040
19041   /* Use a control ping for synchronization */
19042   MPING (CONTROL_PING, mp_ping);
19043   S (mp_ping);
19044
19045   W (ret);
19046   return ret;
19047 }
19048
19049 #define vl_api_ip_fib_details_t_endian vl_noop_handler
19050 #define vl_api_ip_fib_details_t_print vl_noop_handler
19051
19052 static void
19053 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
19054 {
19055   vat_main_t *vam = &vat_main;
19056   int count = ntohl (mp->count);
19057   vl_api_fib_path_t *fp;
19058   int i;
19059
19060   print (vam->ofp,
19061          "table-id %d, prefix %U/%d",
19062          ntohl (mp->table_id), format_ip4_address, mp->address,
19063          mp->address_length);
19064   fp = mp->path;
19065   for (i = 0; i < count; i++)
19066     {
19067       if (fp->afi == IP46_TYPE_IP6)
19068         print (vam->ofp,
19069                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19070                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19071                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19072                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19073                format_ip6_address, fp->next_hop);
19074       else if (fp->afi == IP46_TYPE_IP4)
19075         print (vam->ofp,
19076                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19077                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19078                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19079                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19080                format_ip4_address, fp->next_hop);
19081       fp++;
19082     }
19083 }
19084
19085 static void vl_api_ip_fib_details_t_handler_json
19086   (vl_api_ip_fib_details_t * mp)
19087 {
19088   vat_main_t *vam = &vat_main;
19089   int count = ntohl (mp->count);
19090   vat_json_node_t *node = NULL;
19091   struct in_addr ip4;
19092   struct in6_addr ip6;
19093   vl_api_fib_path_t *fp;
19094   int i;
19095
19096   if (VAT_JSON_ARRAY != vam->json_tree.type)
19097     {
19098       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19099       vat_json_init_array (&vam->json_tree);
19100     }
19101   node = vat_json_array_add (&vam->json_tree);
19102
19103   vat_json_init_object (node);
19104   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19105   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
19106   vat_json_object_add_ip4 (node, "prefix", ip4);
19107   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19108   vat_json_object_add_uint (node, "path_count", count);
19109   fp = mp->path;
19110   for (i = 0; i < count; i++)
19111     {
19112       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19113       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19114       vat_json_object_add_uint (node, "is_local", fp->is_local);
19115       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19116       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19117       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19118       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19119       if (fp->afi == IP46_TYPE_IP4)
19120         {
19121           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19122           vat_json_object_add_ip4 (node, "next_hop", ip4);
19123         }
19124       else if (fp->afi == IP46_TYPE_IP6)
19125         {
19126           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19127           vat_json_object_add_ip6 (node, "next_hop", ip6);
19128         }
19129     }
19130 }
19131
19132 static int
19133 api_ip_fib_dump (vat_main_t * vam)
19134 {
19135   vl_api_ip_fib_dump_t *mp;
19136   vl_api_control_ping_t *mp_ping;
19137   int ret;
19138
19139   M (IP_FIB_DUMP, mp);
19140   S (mp);
19141
19142   /* Use a control ping for synchronization */
19143   MPING (CONTROL_PING, mp_ping);
19144   S (mp_ping);
19145
19146   W (ret);
19147   return ret;
19148 }
19149
19150 static int
19151 api_ip_mfib_dump (vat_main_t * vam)
19152 {
19153   vl_api_ip_mfib_dump_t *mp;
19154   vl_api_control_ping_t *mp_ping;
19155   int ret;
19156
19157   M (IP_MFIB_DUMP, mp);
19158   S (mp);
19159
19160   /* Use a control ping for synchronization */
19161   MPING (CONTROL_PING, mp_ping);
19162   S (mp_ping);
19163
19164   W (ret);
19165   return ret;
19166 }
19167
19168 static void vl_api_ip_neighbor_details_t_handler
19169   (vl_api_ip_neighbor_details_t * mp)
19170 {
19171   vat_main_t *vam = &vat_main;
19172
19173   print (vam->ofp, "%c %U %U",
19174          (mp->is_static) ? 'S' : 'D',
19175          format_ethernet_address, &mp->mac_address,
19176          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
19177          &mp->ip_address);
19178 }
19179
19180 static void vl_api_ip_neighbor_details_t_handler_json
19181   (vl_api_ip_neighbor_details_t * mp)
19182 {
19183
19184   vat_main_t *vam = &vat_main;
19185   vat_json_node_t *node;
19186   struct in_addr ip4;
19187   struct in6_addr ip6;
19188
19189   if (VAT_JSON_ARRAY != vam->json_tree.type)
19190     {
19191       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19192       vat_json_init_array (&vam->json_tree);
19193     }
19194   node = vat_json_array_add (&vam->json_tree);
19195
19196   vat_json_init_object (node);
19197   vat_json_object_add_string_copy (node, "flag",
19198                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
19199                                    "dynamic");
19200
19201   vat_json_object_add_string_copy (node, "link_layer",
19202                                    format (0, "%U", format_ethernet_address,
19203                                            &mp->mac_address));
19204
19205   if (mp->is_ipv6)
19206     {
19207       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
19208       vat_json_object_add_ip6 (node, "ip_address", ip6);
19209     }
19210   else
19211     {
19212       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
19213       vat_json_object_add_ip4 (node, "ip_address", ip4);
19214     }
19215 }
19216
19217 static int
19218 api_ip_neighbor_dump (vat_main_t * vam)
19219 {
19220   unformat_input_t *i = vam->input;
19221   vl_api_ip_neighbor_dump_t *mp;
19222   vl_api_control_ping_t *mp_ping;
19223   u8 is_ipv6 = 0;
19224   u32 sw_if_index = ~0;
19225   int ret;
19226
19227   /* Parse args required to build the message */
19228   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19229     {
19230       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19231         ;
19232       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19233         ;
19234       else if (unformat (i, "ip6"))
19235         is_ipv6 = 1;
19236       else
19237         break;
19238     }
19239
19240   if (sw_if_index == ~0)
19241     {
19242       errmsg ("missing interface name or sw_if_index");
19243       return -99;
19244     }
19245
19246   M (IP_NEIGHBOR_DUMP, mp);
19247   mp->is_ipv6 = (u8) is_ipv6;
19248   mp->sw_if_index = ntohl (sw_if_index);
19249   S (mp);
19250
19251   /* Use a control ping for synchronization */
19252   MPING (CONTROL_PING, mp_ping);
19253   S (mp_ping);
19254
19255   W (ret);
19256   return ret;
19257 }
19258
19259 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
19260 #define vl_api_ip6_fib_details_t_print vl_noop_handler
19261
19262 static void
19263 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
19264 {
19265   vat_main_t *vam = &vat_main;
19266   int count = ntohl (mp->count);
19267   vl_api_fib_path_t *fp;
19268   int i;
19269
19270   print (vam->ofp,
19271          "table-id %d, prefix %U/%d",
19272          ntohl (mp->table_id), format_ip6_address, mp->address,
19273          mp->address_length);
19274   fp = mp->path;
19275   for (i = 0; i < count; i++)
19276     {
19277       if (fp->afi == IP46_TYPE_IP6)
19278         print (vam->ofp,
19279                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19280                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19281                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19282                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19283                format_ip6_address, fp->next_hop);
19284       else if (fp->afi == IP46_TYPE_IP4)
19285         print (vam->ofp,
19286                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19287                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19288                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19289                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19290                format_ip4_address, fp->next_hop);
19291       fp++;
19292     }
19293 }
19294
19295 static void vl_api_ip6_fib_details_t_handler_json
19296   (vl_api_ip6_fib_details_t * mp)
19297 {
19298   vat_main_t *vam = &vat_main;
19299   int count = ntohl (mp->count);
19300   vat_json_node_t *node = NULL;
19301   struct in_addr ip4;
19302   struct in6_addr ip6;
19303   vl_api_fib_path_t *fp;
19304   int i;
19305
19306   if (VAT_JSON_ARRAY != vam->json_tree.type)
19307     {
19308       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19309       vat_json_init_array (&vam->json_tree);
19310     }
19311   node = vat_json_array_add (&vam->json_tree);
19312
19313   vat_json_init_object (node);
19314   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19315   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
19316   vat_json_object_add_ip6 (node, "prefix", ip6);
19317   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19318   vat_json_object_add_uint (node, "path_count", count);
19319   fp = mp->path;
19320   for (i = 0; i < count; i++)
19321     {
19322       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19323       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19324       vat_json_object_add_uint (node, "is_local", fp->is_local);
19325       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19326       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19327       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19328       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19329       if (fp->afi == IP46_TYPE_IP4)
19330         {
19331           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19332           vat_json_object_add_ip4 (node, "next_hop", ip4);
19333         }
19334       else if (fp->afi == IP46_TYPE_IP6)
19335         {
19336           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19337           vat_json_object_add_ip6 (node, "next_hop", ip6);
19338         }
19339     }
19340 }
19341
19342 static int
19343 api_ip6_fib_dump (vat_main_t * vam)
19344 {
19345   vl_api_ip6_fib_dump_t *mp;
19346   vl_api_control_ping_t *mp_ping;
19347   int ret;
19348
19349   M (IP6_FIB_DUMP, mp);
19350   S (mp);
19351
19352   /* Use a control ping for synchronization */
19353   MPING (CONTROL_PING, mp_ping);
19354   S (mp_ping);
19355
19356   W (ret);
19357   return ret;
19358 }
19359
19360 static int
19361 api_ip6_mfib_dump (vat_main_t * vam)
19362 {
19363   vl_api_ip6_mfib_dump_t *mp;
19364   vl_api_control_ping_t *mp_ping;
19365   int ret;
19366
19367   M (IP6_MFIB_DUMP, mp);
19368   S (mp);
19369
19370   /* Use a control ping for synchronization */
19371   MPING (CONTROL_PING, mp_ping);
19372   S (mp_ping);
19373
19374   W (ret);
19375   return ret;
19376 }
19377
19378 int
19379 api_classify_table_ids (vat_main_t * vam)
19380 {
19381   vl_api_classify_table_ids_t *mp;
19382   int ret;
19383
19384   /* Construct the API message */
19385   M (CLASSIFY_TABLE_IDS, mp);
19386   mp->context = 0;
19387
19388   S (mp);
19389   W (ret);
19390   return ret;
19391 }
19392
19393 int
19394 api_classify_table_by_interface (vat_main_t * vam)
19395 {
19396   unformat_input_t *input = vam->input;
19397   vl_api_classify_table_by_interface_t *mp;
19398
19399   u32 sw_if_index = ~0;
19400   int ret;
19401   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19402     {
19403       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19404         ;
19405       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19406         ;
19407       else
19408         break;
19409     }
19410   if (sw_if_index == ~0)
19411     {
19412       errmsg ("missing interface name or sw_if_index");
19413       return -99;
19414     }
19415
19416   /* Construct the API message */
19417   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19418   mp->context = 0;
19419   mp->sw_if_index = ntohl (sw_if_index);
19420
19421   S (mp);
19422   W (ret);
19423   return ret;
19424 }
19425
19426 int
19427 api_classify_table_info (vat_main_t * vam)
19428 {
19429   unformat_input_t *input = vam->input;
19430   vl_api_classify_table_info_t *mp;
19431
19432   u32 table_id = ~0;
19433   int ret;
19434   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19435     {
19436       if (unformat (input, "table_id %d", &table_id))
19437         ;
19438       else
19439         break;
19440     }
19441   if (table_id == ~0)
19442     {
19443       errmsg ("missing table id");
19444       return -99;
19445     }
19446
19447   /* Construct the API message */
19448   M (CLASSIFY_TABLE_INFO, mp);
19449   mp->context = 0;
19450   mp->table_id = ntohl (table_id);
19451
19452   S (mp);
19453   W (ret);
19454   return ret;
19455 }
19456
19457 int
19458 api_classify_session_dump (vat_main_t * vam)
19459 {
19460   unformat_input_t *input = vam->input;
19461   vl_api_classify_session_dump_t *mp;
19462   vl_api_control_ping_t *mp_ping;
19463
19464   u32 table_id = ~0;
19465   int ret;
19466   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19467     {
19468       if (unformat (input, "table_id %d", &table_id))
19469         ;
19470       else
19471         break;
19472     }
19473   if (table_id == ~0)
19474     {
19475       errmsg ("missing table id");
19476       return -99;
19477     }
19478
19479   /* Construct the API message */
19480   M (CLASSIFY_SESSION_DUMP, mp);
19481   mp->context = 0;
19482   mp->table_id = ntohl (table_id);
19483   S (mp);
19484
19485   /* Use a control ping for synchronization */
19486   MPING (CONTROL_PING, mp_ping);
19487   S (mp_ping);
19488
19489   W (ret);
19490   return ret;
19491 }
19492
19493 static void
19494 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19495 {
19496   vat_main_t *vam = &vat_main;
19497
19498   print (vam->ofp, "collector_address %U, collector_port %d, "
19499          "src_address %U, vrf_id %d, path_mtu %u, "
19500          "template_interval %u, udp_checksum %d",
19501          format_ip4_address, mp->collector_address,
19502          ntohs (mp->collector_port),
19503          format_ip4_address, mp->src_address,
19504          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19505          ntohl (mp->template_interval), mp->udp_checksum);
19506
19507   vam->retval = 0;
19508   vam->result_ready = 1;
19509 }
19510
19511 static void
19512   vl_api_ipfix_exporter_details_t_handler_json
19513   (vl_api_ipfix_exporter_details_t * mp)
19514 {
19515   vat_main_t *vam = &vat_main;
19516   vat_json_node_t node;
19517   struct in_addr collector_address;
19518   struct in_addr src_address;
19519
19520   vat_json_init_object (&node);
19521   clib_memcpy (&collector_address, &mp->collector_address,
19522                sizeof (collector_address));
19523   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19524   vat_json_object_add_uint (&node, "collector_port",
19525                             ntohs (mp->collector_port));
19526   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19527   vat_json_object_add_ip4 (&node, "src_address", src_address);
19528   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19529   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19530   vat_json_object_add_uint (&node, "template_interval",
19531                             ntohl (mp->template_interval));
19532   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
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 int
19541 api_ipfix_exporter_dump (vat_main_t * vam)
19542 {
19543   vl_api_ipfix_exporter_dump_t *mp;
19544   int ret;
19545
19546   /* Construct the API message */
19547   M (IPFIX_EXPORTER_DUMP, mp);
19548   mp->context = 0;
19549
19550   S (mp);
19551   W (ret);
19552   return ret;
19553 }
19554
19555 static int
19556 api_ipfix_classify_stream_dump (vat_main_t * vam)
19557 {
19558   vl_api_ipfix_classify_stream_dump_t *mp;
19559   int ret;
19560
19561   /* Construct the API message */
19562   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19563   mp->context = 0;
19564
19565   S (mp);
19566   W (ret);
19567   return ret;
19568   /* NOTREACHED */
19569   return 0;
19570 }
19571
19572 static void
19573   vl_api_ipfix_classify_stream_details_t_handler
19574   (vl_api_ipfix_classify_stream_details_t * mp)
19575 {
19576   vat_main_t *vam = &vat_main;
19577   print (vam->ofp, "domain_id %d, src_port %d",
19578          ntohl (mp->domain_id), ntohs (mp->src_port));
19579   vam->retval = 0;
19580   vam->result_ready = 1;
19581 }
19582
19583 static void
19584   vl_api_ipfix_classify_stream_details_t_handler_json
19585   (vl_api_ipfix_classify_stream_details_t * mp)
19586 {
19587   vat_main_t *vam = &vat_main;
19588   vat_json_node_t node;
19589
19590   vat_json_init_object (&node);
19591   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19592   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19593
19594   vat_json_print (vam->ofp, &node);
19595   vat_json_free (&node);
19596   vam->retval = 0;
19597   vam->result_ready = 1;
19598 }
19599
19600 static int
19601 api_ipfix_classify_table_dump (vat_main_t * vam)
19602 {
19603   vl_api_ipfix_classify_table_dump_t *mp;
19604   vl_api_control_ping_t *mp_ping;
19605   int ret;
19606
19607   if (!vam->json_output)
19608     {
19609       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19610              "transport_protocol");
19611     }
19612
19613   /* Construct the API message */
19614   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19615
19616   /* send it... */
19617   S (mp);
19618
19619   /* Use a control ping for synchronization */
19620   MPING (CONTROL_PING, mp_ping);
19621   S (mp_ping);
19622
19623   W (ret);
19624   return ret;
19625 }
19626
19627 static void
19628   vl_api_ipfix_classify_table_details_t_handler
19629   (vl_api_ipfix_classify_table_details_t * mp)
19630 {
19631   vat_main_t *vam = &vat_main;
19632   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19633          mp->transport_protocol);
19634 }
19635
19636 static void
19637   vl_api_ipfix_classify_table_details_t_handler_json
19638   (vl_api_ipfix_classify_table_details_t * mp)
19639 {
19640   vat_json_node_t *node = NULL;
19641   vat_main_t *vam = &vat_main;
19642
19643   if (VAT_JSON_ARRAY != vam->json_tree.type)
19644     {
19645       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19646       vat_json_init_array (&vam->json_tree);
19647     }
19648
19649   node = vat_json_array_add (&vam->json_tree);
19650   vat_json_init_object (node);
19651
19652   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19653   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19654   vat_json_object_add_uint (node, "transport_protocol",
19655                             mp->transport_protocol);
19656 }
19657
19658 static int
19659 api_sw_interface_span_enable_disable (vat_main_t * vam)
19660 {
19661   unformat_input_t *i = vam->input;
19662   vl_api_sw_interface_span_enable_disable_t *mp;
19663   u32 src_sw_if_index = ~0;
19664   u32 dst_sw_if_index = ~0;
19665   u8 state = 3;
19666   int ret;
19667   u8 is_l2 = 0;
19668
19669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19670     {
19671       if (unformat
19672           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19673         ;
19674       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19675         ;
19676       else
19677         if (unformat
19678             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19679         ;
19680       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19681         ;
19682       else if (unformat (i, "disable"))
19683         state = 0;
19684       else if (unformat (i, "rx"))
19685         state = 1;
19686       else if (unformat (i, "tx"))
19687         state = 2;
19688       else if (unformat (i, "both"))
19689         state = 3;
19690       else if (unformat (i, "l2"))
19691         is_l2 = 1;
19692       else
19693         break;
19694     }
19695
19696   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19697
19698   mp->sw_if_index_from = htonl (src_sw_if_index);
19699   mp->sw_if_index_to = htonl (dst_sw_if_index);
19700   mp->state = state;
19701   mp->is_l2 = is_l2;
19702
19703   S (mp);
19704   W (ret);
19705   return ret;
19706 }
19707
19708 static void
19709 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19710                                             * mp)
19711 {
19712   vat_main_t *vam = &vat_main;
19713   u8 *sw_if_from_name = 0;
19714   u8 *sw_if_to_name = 0;
19715   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19716   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19717   char *states[] = { "none", "rx", "tx", "both" };
19718   hash_pair_t *p;
19719
19720   /* *INDENT-OFF* */
19721   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19722   ({
19723     if ((u32) p->value[0] == sw_if_index_from)
19724       {
19725         sw_if_from_name = (u8 *)(p->key);
19726         if (sw_if_to_name)
19727           break;
19728       }
19729     if ((u32) p->value[0] == sw_if_index_to)
19730       {
19731         sw_if_to_name = (u8 *)(p->key);
19732         if (sw_if_from_name)
19733           break;
19734       }
19735   }));
19736   /* *INDENT-ON* */
19737   print (vam->ofp, "%20s => %20s (%s)",
19738          sw_if_from_name, sw_if_to_name, states[mp->state]);
19739 }
19740
19741 static void
19742   vl_api_sw_interface_span_details_t_handler_json
19743   (vl_api_sw_interface_span_details_t * mp)
19744 {
19745   vat_main_t *vam = &vat_main;
19746   vat_json_node_t *node = NULL;
19747   u8 *sw_if_from_name = 0;
19748   u8 *sw_if_to_name = 0;
19749   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19750   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19751   hash_pair_t *p;
19752
19753   /* *INDENT-OFF* */
19754   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19755   ({
19756     if ((u32) p->value[0] == sw_if_index_from)
19757       {
19758         sw_if_from_name = (u8 *)(p->key);
19759         if (sw_if_to_name)
19760           break;
19761       }
19762     if ((u32) p->value[0] == sw_if_index_to)
19763       {
19764         sw_if_to_name = (u8 *)(p->key);
19765         if (sw_if_from_name)
19766           break;
19767       }
19768   }));
19769   /* *INDENT-ON* */
19770
19771   if (VAT_JSON_ARRAY != vam->json_tree.type)
19772     {
19773       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19774       vat_json_init_array (&vam->json_tree);
19775     }
19776   node = vat_json_array_add (&vam->json_tree);
19777
19778   vat_json_init_object (node);
19779   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19780   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19781   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19782   if (0 != sw_if_to_name)
19783     {
19784       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19785     }
19786   vat_json_object_add_uint (node, "state", mp->state);
19787 }
19788
19789 static int
19790 api_sw_interface_span_dump (vat_main_t * vam)
19791 {
19792   unformat_input_t *input = vam->input;
19793   vl_api_sw_interface_span_dump_t *mp;
19794   vl_api_control_ping_t *mp_ping;
19795   u8 is_l2 = 0;
19796   int ret;
19797
19798   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19799     {
19800       if (unformat (input, "l2"))
19801         is_l2 = 1;
19802       else
19803         break;
19804     }
19805
19806   M (SW_INTERFACE_SPAN_DUMP, mp);
19807   mp->is_l2 = is_l2;
19808   S (mp);
19809
19810   /* Use a control ping for synchronization */
19811   MPING (CONTROL_PING, mp_ping);
19812   S (mp_ping);
19813
19814   W (ret);
19815   return ret;
19816 }
19817
19818 int
19819 api_pg_create_interface (vat_main_t * vam)
19820 {
19821   unformat_input_t *input = vam->input;
19822   vl_api_pg_create_interface_t *mp;
19823
19824   u32 if_id = ~0;
19825   int ret;
19826   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19827     {
19828       if (unformat (input, "if_id %d", &if_id))
19829         ;
19830       else
19831         break;
19832     }
19833   if (if_id == ~0)
19834     {
19835       errmsg ("missing pg interface index");
19836       return -99;
19837     }
19838
19839   /* Construct the API message */
19840   M (PG_CREATE_INTERFACE, mp);
19841   mp->context = 0;
19842   mp->interface_id = ntohl (if_id);
19843
19844   S (mp);
19845   W (ret);
19846   return ret;
19847 }
19848
19849 int
19850 api_pg_capture (vat_main_t * vam)
19851 {
19852   unformat_input_t *input = vam->input;
19853   vl_api_pg_capture_t *mp;
19854
19855   u32 if_id = ~0;
19856   u8 enable = 1;
19857   u32 count = 1;
19858   u8 pcap_file_set = 0;
19859   u8 *pcap_file = 0;
19860   int ret;
19861   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19862     {
19863       if (unformat (input, "if_id %d", &if_id))
19864         ;
19865       else if (unformat (input, "pcap %s", &pcap_file))
19866         pcap_file_set = 1;
19867       else if (unformat (input, "count %d", &count))
19868         ;
19869       else if (unformat (input, "disable"))
19870         enable = 0;
19871       else
19872         break;
19873     }
19874   if (if_id == ~0)
19875     {
19876       errmsg ("missing pg interface index");
19877       return -99;
19878     }
19879   if (pcap_file_set > 0)
19880     {
19881       if (vec_len (pcap_file) > 255)
19882         {
19883           errmsg ("pcap file name is too long");
19884           return -99;
19885         }
19886     }
19887
19888   u32 name_len = vec_len (pcap_file);
19889   /* Construct the API message */
19890   M (PG_CAPTURE, mp);
19891   mp->context = 0;
19892   mp->interface_id = ntohl (if_id);
19893   mp->is_enabled = enable;
19894   mp->count = ntohl (count);
19895   mp->pcap_name_length = ntohl (name_len);
19896   if (pcap_file_set != 0)
19897     {
19898       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19899     }
19900   vec_free (pcap_file);
19901
19902   S (mp);
19903   W (ret);
19904   return ret;
19905 }
19906
19907 int
19908 api_pg_enable_disable (vat_main_t * vam)
19909 {
19910   unformat_input_t *input = vam->input;
19911   vl_api_pg_enable_disable_t *mp;
19912
19913   u8 enable = 1;
19914   u8 stream_name_set = 0;
19915   u8 *stream_name = 0;
19916   int ret;
19917   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19918     {
19919       if (unformat (input, "stream %s", &stream_name))
19920         stream_name_set = 1;
19921       else if (unformat (input, "disable"))
19922         enable = 0;
19923       else
19924         break;
19925     }
19926
19927   if (stream_name_set > 0)
19928     {
19929       if (vec_len (stream_name) > 255)
19930         {
19931           errmsg ("stream name too long");
19932           return -99;
19933         }
19934     }
19935
19936   u32 name_len = vec_len (stream_name);
19937   /* Construct the API message */
19938   M (PG_ENABLE_DISABLE, mp);
19939   mp->context = 0;
19940   mp->is_enabled = enable;
19941   if (stream_name_set != 0)
19942     {
19943       mp->stream_name_length = ntohl (name_len);
19944       clib_memcpy (mp->stream_name, stream_name, name_len);
19945     }
19946   vec_free (stream_name);
19947
19948   S (mp);
19949   W (ret);
19950   return ret;
19951 }
19952
19953 int
19954 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19955 {
19956   unformat_input_t *input = vam->input;
19957   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19958
19959   u16 *low_ports = 0;
19960   u16 *high_ports = 0;
19961   u16 this_low;
19962   u16 this_hi;
19963   ip4_address_t ip4_addr;
19964   ip6_address_t ip6_addr;
19965   u32 length;
19966   u32 tmp, tmp2;
19967   u8 prefix_set = 0;
19968   u32 vrf_id = ~0;
19969   u8 is_add = 1;
19970   u8 is_ipv6 = 0;
19971   int ret;
19972
19973   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19974     {
19975       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
19976         {
19977           prefix_set = 1;
19978         }
19979       else
19980         if (unformat
19981             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
19982         {
19983           prefix_set = 1;
19984           is_ipv6 = 1;
19985         }
19986       else if (unformat (input, "vrf %d", &vrf_id))
19987         ;
19988       else if (unformat (input, "del"))
19989         is_add = 0;
19990       else if (unformat (input, "port %d", &tmp))
19991         {
19992           if (tmp == 0 || tmp > 65535)
19993             {
19994               errmsg ("port %d out of range", tmp);
19995               return -99;
19996             }
19997           this_low = tmp;
19998           this_hi = this_low + 1;
19999           vec_add1 (low_ports, this_low);
20000           vec_add1 (high_ports, this_hi);
20001         }
20002       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
20003         {
20004           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
20005             {
20006               errmsg ("incorrect range parameters");
20007               return -99;
20008             }
20009           this_low = tmp;
20010           /* Note: in debug CLI +1 is added to high before
20011              passing to real fn that does "the work"
20012              (ip_source_and_port_range_check_add_del).
20013              This fn is a wrapper around the binary API fn a
20014              control plane will call, which expects this increment
20015              to have occurred. Hence letting the binary API control
20016              plane fn do the increment for consistency between VAT
20017              and other control planes.
20018            */
20019           this_hi = tmp2;
20020           vec_add1 (low_ports, this_low);
20021           vec_add1 (high_ports, this_hi);
20022         }
20023       else
20024         break;
20025     }
20026
20027   if (prefix_set == 0)
20028     {
20029       errmsg ("<address>/<mask> not specified");
20030       return -99;
20031     }
20032
20033   if (vrf_id == ~0)
20034     {
20035       errmsg ("VRF ID required, not specified");
20036       return -99;
20037     }
20038
20039   if (vrf_id == 0)
20040     {
20041       errmsg
20042         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20043       return -99;
20044     }
20045
20046   if (vec_len (low_ports) == 0)
20047     {
20048       errmsg ("At least one port or port range required");
20049       return -99;
20050     }
20051
20052   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
20053
20054   mp->is_add = is_add;
20055
20056   if (is_ipv6)
20057     {
20058       mp->is_ipv6 = 1;
20059       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
20060     }
20061   else
20062     {
20063       mp->is_ipv6 = 0;
20064       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
20065     }
20066
20067   mp->mask_length = length;
20068   mp->number_of_ranges = vec_len (low_ports);
20069
20070   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
20071   vec_free (low_ports);
20072
20073   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
20074   vec_free (high_ports);
20075
20076   mp->vrf_id = ntohl (vrf_id);
20077
20078   S (mp);
20079   W (ret);
20080   return ret;
20081 }
20082
20083 int
20084 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
20085 {
20086   unformat_input_t *input = vam->input;
20087   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
20088   u32 sw_if_index = ~0;
20089   int vrf_set = 0;
20090   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
20091   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
20092   u8 is_add = 1;
20093   int ret;
20094
20095   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
20096     {
20097       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20098         ;
20099       else if (unformat (input, "sw_if_index %d", &sw_if_index))
20100         ;
20101       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
20102         vrf_set = 1;
20103       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
20104         vrf_set = 1;
20105       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
20106         vrf_set = 1;
20107       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
20108         vrf_set = 1;
20109       else if (unformat (input, "del"))
20110         is_add = 0;
20111       else
20112         break;
20113     }
20114
20115   if (sw_if_index == ~0)
20116     {
20117       errmsg ("Interface required but not specified");
20118       return -99;
20119     }
20120
20121   if (vrf_set == 0)
20122     {
20123       errmsg ("VRF ID required but not specified");
20124       return -99;
20125     }
20126
20127   if (tcp_out_vrf_id == 0
20128       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
20129     {
20130       errmsg
20131         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
20132       return -99;
20133     }
20134
20135   /* Construct the API message */
20136   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
20137
20138   mp->sw_if_index = ntohl (sw_if_index);
20139   mp->is_add = is_add;
20140   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20141   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20142   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20143   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20144
20145   /* send it... */
20146   S (mp);
20147
20148   /* Wait for a reply... */
20149   W (ret);
20150   return ret;
20151 }
20152
20153 static int
20154 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
20155 {
20156   unformat_input_t *i = vam->input;
20157   vl_api_ipsec_gre_add_del_tunnel_t *mp;
20158   u32 local_sa_id = 0;
20159   u32 remote_sa_id = 0;
20160   ip4_address_t src_address;
20161   ip4_address_t dst_address;
20162   u8 is_add = 1;
20163   int ret;
20164
20165   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20166     {
20167       if (unformat (i, "local_sa %d", &local_sa_id))
20168         ;
20169       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20170         ;
20171       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
20172         ;
20173       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
20174         ;
20175       else if (unformat (i, "del"))
20176         is_add = 0;
20177       else
20178         {
20179           clib_warning ("parse error '%U'", format_unformat_error, i);
20180           return -99;
20181         }
20182     }
20183
20184   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
20185
20186   mp->local_sa_id = ntohl (local_sa_id);
20187   mp->remote_sa_id = ntohl (remote_sa_id);
20188   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
20189   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
20190   mp->is_add = is_add;
20191
20192   S (mp);
20193   W (ret);
20194   return ret;
20195 }
20196
20197 static int
20198 api_punt (vat_main_t * vam)
20199 {
20200   unformat_input_t *i = vam->input;
20201   vl_api_punt_t *mp;
20202   u32 ipv = ~0;
20203   u32 protocol = ~0;
20204   u32 port = ~0;
20205   int is_add = 1;
20206   int ret;
20207
20208   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20209     {
20210       if (unformat (i, "ip %d", &ipv))
20211         ;
20212       else if (unformat (i, "protocol %d", &protocol))
20213         ;
20214       else if (unformat (i, "port %d", &port))
20215         ;
20216       else if (unformat (i, "del"))
20217         is_add = 0;
20218       else
20219         {
20220           clib_warning ("parse error '%U'", format_unformat_error, i);
20221           return -99;
20222         }
20223     }
20224
20225   M (PUNT, mp);
20226
20227   mp->is_add = (u8) is_add;
20228   mp->ipv = (u8) ipv;
20229   mp->l4_protocol = (u8) protocol;
20230   mp->l4_port = htons ((u16) port);
20231
20232   S (mp);
20233   W (ret);
20234   return ret;
20235 }
20236
20237 static void vl_api_ipsec_gre_tunnel_details_t_handler
20238   (vl_api_ipsec_gre_tunnel_details_t * mp)
20239 {
20240   vat_main_t *vam = &vat_main;
20241
20242   print (vam->ofp, "%11d%15U%15U%14d%14d",
20243          ntohl (mp->sw_if_index),
20244          format_ip4_address, &mp->src_address,
20245          format_ip4_address, &mp->dst_address,
20246          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
20247 }
20248
20249 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
20250   (vl_api_ipsec_gre_tunnel_details_t * mp)
20251 {
20252   vat_main_t *vam = &vat_main;
20253   vat_json_node_t *node = NULL;
20254   struct in_addr ip4;
20255
20256   if (VAT_JSON_ARRAY != vam->json_tree.type)
20257     {
20258       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20259       vat_json_init_array (&vam->json_tree);
20260     }
20261   node = vat_json_array_add (&vam->json_tree);
20262
20263   vat_json_init_object (node);
20264   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
20265   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
20266   vat_json_object_add_ip4 (node, "src_address", ip4);
20267   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
20268   vat_json_object_add_ip4 (node, "dst_address", ip4);
20269   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
20270   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
20271 }
20272
20273 static int
20274 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
20275 {
20276   unformat_input_t *i = vam->input;
20277   vl_api_ipsec_gre_tunnel_dump_t *mp;
20278   vl_api_control_ping_t *mp_ping;
20279   u32 sw_if_index;
20280   u8 sw_if_index_set = 0;
20281   int ret;
20282
20283   /* Parse args required to build the message */
20284   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20285     {
20286       if (unformat (i, "sw_if_index %d", &sw_if_index))
20287         sw_if_index_set = 1;
20288       else
20289         break;
20290     }
20291
20292   if (sw_if_index_set == 0)
20293     {
20294       sw_if_index = ~0;
20295     }
20296
20297   if (!vam->json_output)
20298     {
20299       print (vam->ofp, "%11s%15s%15s%14s%14s",
20300              "sw_if_index", "src_address", "dst_address",
20301              "local_sa_id", "remote_sa_id");
20302     }
20303
20304   /* Get list of gre-tunnel interfaces */
20305   M (IPSEC_GRE_TUNNEL_DUMP, mp);
20306
20307   mp->sw_if_index = htonl (sw_if_index);
20308
20309   S (mp);
20310
20311   /* Use a control ping for synchronization */
20312   MPING (CONTROL_PING, mp_ping);
20313   S (mp_ping);
20314
20315   W (ret);
20316   return ret;
20317 }
20318
20319 static int
20320 api_delete_subif (vat_main_t * vam)
20321 {
20322   unformat_input_t *i = vam->input;
20323   vl_api_delete_subif_t *mp;
20324   u32 sw_if_index = ~0;
20325   int ret;
20326
20327   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20328     {
20329       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20330         ;
20331       if (unformat (i, "sw_if_index %d", &sw_if_index))
20332         ;
20333       else
20334         break;
20335     }
20336
20337   if (sw_if_index == ~0)
20338     {
20339       errmsg ("missing sw_if_index");
20340       return -99;
20341     }
20342
20343   /* Construct the API message */
20344   M (DELETE_SUBIF, mp);
20345   mp->sw_if_index = ntohl (sw_if_index);
20346
20347   S (mp);
20348   W (ret);
20349   return ret;
20350 }
20351
20352 #define foreach_pbb_vtr_op      \
20353 _("disable",  L2_VTR_DISABLED)  \
20354 _("pop",  L2_VTR_POP_2)         \
20355 _("push",  L2_VTR_PUSH_2)
20356
20357 static int
20358 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20359 {
20360   unformat_input_t *i = vam->input;
20361   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20362   u32 sw_if_index = ~0, vtr_op = ~0;
20363   u16 outer_tag = ~0;
20364   u8 dmac[6], smac[6];
20365   u8 dmac_set = 0, smac_set = 0;
20366   u16 vlanid = 0;
20367   u32 sid = ~0;
20368   u32 tmp;
20369   int ret;
20370
20371   /* Shut up coverity */
20372   memset (dmac, 0, sizeof (dmac));
20373   memset (smac, 0, sizeof (smac));
20374
20375   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20376     {
20377       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20378         ;
20379       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20380         ;
20381       else if (unformat (i, "vtr_op %d", &vtr_op))
20382         ;
20383 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20384       foreach_pbb_vtr_op
20385 #undef _
20386         else if (unformat (i, "translate_pbb_stag"))
20387         {
20388           if (unformat (i, "%d", &tmp))
20389             {
20390               vtr_op = L2_VTR_TRANSLATE_2_1;
20391               outer_tag = tmp;
20392             }
20393           else
20394             {
20395               errmsg
20396                 ("translate_pbb_stag operation requires outer tag definition");
20397               return -99;
20398             }
20399         }
20400       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20401         dmac_set++;
20402       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20403         smac_set++;
20404       else if (unformat (i, "sid %d", &sid))
20405         ;
20406       else if (unformat (i, "vlanid %d", &tmp))
20407         vlanid = tmp;
20408       else
20409         {
20410           clib_warning ("parse error '%U'", format_unformat_error, i);
20411           return -99;
20412         }
20413     }
20414
20415   if ((sw_if_index == ~0) || (vtr_op == ~0))
20416     {
20417       errmsg ("missing sw_if_index or vtr operation");
20418       return -99;
20419     }
20420   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20421       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20422     {
20423       errmsg
20424         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20425       return -99;
20426     }
20427
20428   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20429   mp->sw_if_index = ntohl (sw_if_index);
20430   mp->vtr_op = ntohl (vtr_op);
20431   mp->outer_tag = ntohs (outer_tag);
20432   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20433   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20434   mp->b_vlanid = ntohs (vlanid);
20435   mp->i_sid = ntohl (sid);
20436
20437   S (mp);
20438   W (ret);
20439   return ret;
20440 }
20441
20442 static int
20443 api_flow_classify_set_interface (vat_main_t * vam)
20444 {
20445   unformat_input_t *i = vam->input;
20446   vl_api_flow_classify_set_interface_t *mp;
20447   u32 sw_if_index;
20448   int sw_if_index_set;
20449   u32 ip4_table_index = ~0;
20450   u32 ip6_table_index = ~0;
20451   u8 is_add = 1;
20452   int ret;
20453
20454   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20455     {
20456       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20457         sw_if_index_set = 1;
20458       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20459         sw_if_index_set = 1;
20460       else if (unformat (i, "del"))
20461         is_add = 0;
20462       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20463         ;
20464       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20465         ;
20466       else
20467         {
20468           clib_warning ("parse error '%U'", format_unformat_error, i);
20469           return -99;
20470         }
20471     }
20472
20473   if (sw_if_index_set == 0)
20474     {
20475       errmsg ("missing interface name or sw_if_index");
20476       return -99;
20477     }
20478
20479   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20480
20481   mp->sw_if_index = ntohl (sw_if_index);
20482   mp->ip4_table_index = ntohl (ip4_table_index);
20483   mp->ip6_table_index = ntohl (ip6_table_index);
20484   mp->is_add = is_add;
20485
20486   S (mp);
20487   W (ret);
20488   return ret;
20489 }
20490
20491 static int
20492 api_flow_classify_dump (vat_main_t * vam)
20493 {
20494   unformat_input_t *i = vam->input;
20495   vl_api_flow_classify_dump_t *mp;
20496   vl_api_control_ping_t *mp_ping;
20497   u8 type = FLOW_CLASSIFY_N_TABLES;
20498   int ret;
20499
20500   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20501     ;
20502   else
20503     {
20504       errmsg ("classify table type must be specified");
20505       return -99;
20506     }
20507
20508   if (!vam->json_output)
20509     {
20510       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20511     }
20512
20513   M (FLOW_CLASSIFY_DUMP, mp);
20514   mp->type = type;
20515   /* send it... */
20516   S (mp);
20517
20518   /* Use a control ping for synchronization */
20519   MPING (CONTROL_PING, mp_ping);
20520   S (mp_ping);
20521
20522   /* Wait for a reply... */
20523   W (ret);
20524   return ret;
20525 }
20526
20527 static int
20528 api_feature_enable_disable (vat_main_t * vam)
20529 {
20530   unformat_input_t *i = vam->input;
20531   vl_api_feature_enable_disable_t *mp;
20532   u8 *arc_name = 0;
20533   u8 *feature_name = 0;
20534   u32 sw_if_index = ~0;
20535   u8 enable = 1;
20536   int ret;
20537
20538   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20539     {
20540       if (unformat (i, "arc_name %s", &arc_name))
20541         ;
20542       else if (unformat (i, "feature_name %s", &feature_name))
20543         ;
20544       else
20545         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20546         ;
20547       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20548         ;
20549       else if (unformat (i, "disable"))
20550         enable = 0;
20551       else
20552         break;
20553     }
20554
20555   if (arc_name == 0)
20556     {
20557       errmsg ("missing arc name");
20558       return -99;
20559     }
20560   if (vec_len (arc_name) > 63)
20561     {
20562       errmsg ("arc name too long");
20563     }
20564
20565   if (feature_name == 0)
20566     {
20567       errmsg ("missing feature name");
20568       return -99;
20569     }
20570   if (vec_len (feature_name) > 63)
20571     {
20572       errmsg ("feature name too long");
20573     }
20574
20575   if (sw_if_index == ~0)
20576     {
20577       errmsg ("missing interface name or sw_if_index");
20578       return -99;
20579     }
20580
20581   /* Construct the API message */
20582   M (FEATURE_ENABLE_DISABLE, mp);
20583   mp->sw_if_index = ntohl (sw_if_index);
20584   mp->enable = enable;
20585   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20586   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20587   vec_free (arc_name);
20588   vec_free (feature_name);
20589
20590   S (mp);
20591   W (ret);
20592   return ret;
20593 }
20594
20595 static int
20596 api_sw_interface_tag_add_del (vat_main_t * vam)
20597 {
20598   unformat_input_t *i = vam->input;
20599   vl_api_sw_interface_tag_add_del_t *mp;
20600   u32 sw_if_index = ~0;
20601   u8 *tag = 0;
20602   u8 enable = 1;
20603   int ret;
20604
20605   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20606     {
20607       if (unformat (i, "tag %s", &tag))
20608         ;
20609       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20610         ;
20611       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20612         ;
20613       else if (unformat (i, "del"))
20614         enable = 0;
20615       else
20616         break;
20617     }
20618
20619   if (sw_if_index == ~0)
20620     {
20621       errmsg ("missing interface name or sw_if_index");
20622       return -99;
20623     }
20624
20625   if (enable && (tag == 0))
20626     {
20627       errmsg ("no tag specified");
20628       return -99;
20629     }
20630
20631   /* Construct the API message */
20632   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20633   mp->sw_if_index = ntohl (sw_if_index);
20634   mp->is_add = enable;
20635   if (enable)
20636     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20637   vec_free (tag);
20638
20639   S (mp);
20640   W (ret);
20641   return ret;
20642 }
20643
20644 static void vl_api_l2_xconnect_details_t_handler
20645   (vl_api_l2_xconnect_details_t * mp)
20646 {
20647   vat_main_t *vam = &vat_main;
20648
20649   print (vam->ofp, "%15d%15d",
20650          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20651 }
20652
20653 static void vl_api_l2_xconnect_details_t_handler_json
20654   (vl_api_l2_xconnect_details_t * mp)
20655 {
20656   vat_main_t *vam = &vat_main;
20657   vat_json_node_t *node = NULL;
20658
20659   if (VAT_JSON_ARRAY != vam->json_tree.type)
20660     {
20661       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20662       vat_json_init_array (&vam->json_tree);
20663     }
20664   node = vat_json_array_add (&vam->json_tree);
20665
20666   vat_json_init_object (node);
20667   vat_json_object_add_uint (node, "rx_sw_if_index",
20668                             ntohl (mp->rx_sw_if_index));
20669   vat_json_object_add_uint (node, "tx_sw_if_index",
20670                             ntohl (mp->tx_sw_if_index));
20671 }
20672
20673 static int
20674 api_l2_xconnect_dump (vat_main_t * vam)
20675 {
20676   vl_api_l2_xconnect_dump_t *mp;
20677   vl_api_control_ping_t *mp_ping;
20678   int ret;
20679
20680   if (!vam->json_output)
20681     {
20682       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20683     }
20684
20685   M (L2_XCONNECT_DUMP, mp);
20686
20687   S (mp);
20688
20689   /* Use a control ping for synchronization */
20690   MPING (CONTROL_PING, mp_ping);
20691   S (mp_ping);
20692
20693   W (ret);
20694   return ret;
20695 }
20696
20697 static int
20698 api_sw_interface_set_mtu (vat_main_t * vam)
20699 {
20700   unformat_input_t *i = vam->input;
20701   vl_api_sw_interface_set_mtu_t *mp;
20702   u32 sw_if_index = ~0;
20703   u32 mtu = 0;
20704   int ret;
20705
20706   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20707     {
20708       if (unformat (i, "mtu %d", &mtu))
20709         ;
20710       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20711         ;
20712       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20713         ;
20714       else
20715         break;
20716     }
20717
20718   if (sw_if_index == ~0)
20719     {
20720       errmsg ("missing interface name or sw_if_index");
20721       return -99;
20722     }
20723
20724   if (mtu == 0)
20725     {
20726       errmsg ("no mtu specified");
20727       return -99;
20728     }
20729
20730   /* Construct the API message */
20731   M (SW_INTERFACE_SET_MTU, mp);
20732   mp->sw_if_index = ntohl (sw_if_index);
20733   mp->mtu = ntohs ((u16) mtu);
20734
20735   S (mp);
20736   W (ret);
20737   return ret;
20738 }
20739
20740 static int
20741 api_p2p_ethernet_add (vat_main_t * vam)
20742 {
20743   unformat_input_t *i = vam->input;
20744   vl_api_p2p_ethernet_add_t *mp;
20745   u32 parent_if_index = ~0;
20746   u32 sub_id = ~0;
20747   u8 remote_mac[6];
20748   u8 mac_set = 0;
20749   int ret;
20750
20751   memset (remote_mac, 0, sizeof (remote_mac));
20752   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20753     {
20754       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20755         ;
20756       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20757         ;
20758       else
20759         if (unformat
20760             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20761         mac_set++;
20762       else if (unformat (i, "sub_id %d", &sub_id))
20763         ;
20764       else
20765         {
20766           clib_warning ("parse error '%U'", format_unformat_error, i);
20767           return -99;
20768         }
20769     }
20770
20771   if (parent_if_index == ~0)
20772     {
20773       errmsg ("missing interface name or sw_if_index");
20774       return -99;
20775     }
20776   if (mac_set == 0)
20777     {
20778       errmsg ("missing remote mac address");
20779       return -99;
20780     }
20781   if (sub_id == ~0)
20782     {
20783       errmsg ("missing sub-interface id");
20784       return -99;
20785     }
20786
20787   M (P2P_ETHERNET_ADD, mp);
20788   mp->parent_if_index = ntohl (parent_if_index);
20789   mp->subif_id = ntohl (sub_id);
20790   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20791
20792   S (mp);
20793   W (ret);
20794   return ret;
20795 }
20796
20797 static int
20798 api_p2p_ethernet_del (vat_main_t * vam)
20799 {
20800   unformat_input_t *i = vam->input;
20801   vl_api_p2p_ethernet_del_t *mp;
20802   u32 parent_if_index = ~0;
20803   u8 remote_mac[6];
20804   u8 mac_set = 0;
20805   int ret;
20806
20807   memset (remote_mac, 0, sizeof (remote_mac));
20808   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20809     {
20810       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20811         ;
20812       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20813         ;
20814       else
20815         if (unformat
20816             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20817         mac_set++;
20818       else
20819         {
20820           clib_warning ("parse error '%U'", format_unformat_error, i);
20821           return -99;
20822         }
20823     }
20824
20825   if (parent_if_index == ~0)
20826     {
20827       errmsg ("missing interface name or sw_if_index");
20828       return -99;
20829     }
20830   if (mac_set == 0)
20831     {
20832       errmsg ("missing remote mac address");
20833       return -99;
20834     }
20835
20836   M (P2P_ETHERNET_DEL, mp);
20837   mp->parent_if_index = ntohl (parent_if_index);
20838   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20839
20840   S (mp);
20841   W (ret);
20842   return ret;
20843 }
20844
20845 static int
20846 api_lldp_config (vat_main_t * vam)
20847 {
20848   unformat_input_t *i = vam->input;
20849   vl_api_lldp_config_t *mp;
20850   int tx_hold = 0;
20851   int tx_interval = 0;
20852   u8 *sys_name = NULL;
20853   int ret;
20854
20855   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20856     {
20857       if (unformat (i, "system-name %s", &sys_name))
20858         ;
20859       else if (unformat (i, "tx-hold %d", &tx_hold))
20860         ;
20861       else if (unformat (i, "tx-interval %d", &tx_interval))
20862         ;
20863       else
20864         {
20865           clib_warning ("parse error '%U'", format_unformat_error, i);
20866           return -99;
20867         }
20868     }
20869
20870   vec_add1 (sys_name, 0);
20871
20872   M (LLDP_CONFIG, mp);
20873   mp->tx_hold = htonl (tx_hold);
20874   mp->tx_interval = htonl (tx_interval);
20875   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20876   vec_free (sys_name);
20877
20878   S (mp);
20879   W (ret);
20880   return ret;
20881 }
20882
20883 static int
20884 api_sw_interface_set_lldp (vat_main_t * vam)
20885 {
20886   unformat_input_t *i = vam->input;
20887   vl_api_sw_interface_set_lldp_t *mp;
20888   u32 sw_if_index = ~0;
20889   u32 enable = 1;
20890   u8 *port_desc = NULL, *mgmt_oid = NULL;
20891   ip4_address_t ip4_addr;
20892   ip6_address_t ip6_addr;
20893   int ret;
20894
20895   memset (&ip4_addr, 0, sizeof (ip4_addr));
20896   memset (&ip6_addr, 0, sizeof (ip6_addr));
20897
20898   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20899     {
20900       if (unformat (i, "disable"))
20901         enable = 0;
20902       else
20903         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20904         ;
20905       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20906         ;
20907       else if (unformat (i, "port-desc %s", &port_desc))
20908         ;
20909       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20910         ;
20911       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20912         ;
20913       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20914         ;
20915       else
20916         break;
20917     }
20918
20919   if (sw_if_index == ~0)
20920     {
20921       errmsg ("missing interface name or sw_if_index");
20922       return -99;
20923     }
20924
20925   /* Construct the API message */
20926   vec_add1 (port_desc, 0);
20927   vec_add1 (mgmt_oid, 0);
20928   M (SW_INTERFACE_SET_LLDP, mp);
20929   mp->sw_if_index = ntohl (sw_if_index);
20930   mp->enable = enable;
20931   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20932   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20933   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20934   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20935   vec_free (port_desc);
20936   vec_free (mgmt_oid);
20937
20938   S (mp);
20939   W (ret);
20940   return ret;
20941 }
20942
20943 static int
20944 api_tcp_configure_src_addresses (vat_main_t * vam)
20945 {
20946   vl_api_tcp_configure_src_addresses_t *mp;
20947   unformat_input_t *i = vam->input;
20948   ip4_address_t v4first, v4last;
20949   ip6_address_t v6first, v6last;
20950   u8 range_set = 0;
20951   u32 vrf_id = 0;
20952   int ret;
20953
20954   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20955     {
20956       if (unformat (i, "%U - %U",
20957                     unformat_ip4_address, &v4first,
20958                     unformat_ip4_address, &v4last))
20959         {
20960           if (range_set)
20961             {
20962               errmsg ("one range per message (range already set)");
20963               return -99;
20964             }
20965           range_set = 1;
20966         }
20967       else if (unformat (i, "%U - %U",
20968                          unformat_ip6_address, &v6first,
20969                          unformat_ip6_address, &v6last))
20970         {
20971           if (range_set)
20972             {
20973               errmsg ("one range per message (range already set)");
20974               return -99;
20975             }
20976           range_set = 2;
20977         }
20978       else if (unformat (i, "vrf %d", &vrf_id))
20979         ;
20980       else
20981         break;
20982     }
20983
20984   if (range_set == 0)
20985     {
20986       errmsg ("address range not set");
20987       return -99;
20988     }
20989
20990   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20991   mp->vrf_id = ntohl (vrf_id);
20992   /* ipv6? */
20993   if (range_set == 2)
20994     {
20995       mp->is_ipv6 = 1;
20996       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20997       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20998     }
20999   else
21000     {
21001       mp->is_ipv6 = 0;
21002       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
21003       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
21004     }
21005   S (mp);
21006   W (ret);
21007   return ret;
21008 }
21009
21010 static int
21011 api_app_namespace_add_del (vat_main_t * vam)
21012 {
21013   vl_api_app_namespace_add_del_t *mp;
21014   unformat_input_t *i = vam->input;
21015   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
21016   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
21017   u64 secret;
21018   int ret;
21019
21020   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21021     {
21022       if (unformat (i, "id %_%v%_", &ns_id))
21023         ;
21024       else if (unformat (i, "secret %lu", &secret))
21025         secret_set = 1;
21026       else if (unformat (i, "sw_if_index %d", &sw_if_index))
21027         sw_if_index_set = 1;
21028       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
21029         ;
21030       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
21031         ;
21032       else
21033         break;
21034     }
21035   if (!ns_id || !secret_set || !sw_if_index_set)
21036     {
21037       errmsg ("namespace id, secret and sw_if_index must be set");
21038       return -99;
21039     }
21040   if (vec_len (ns_id) > 64)
21041     {
21042       errmsg ("namespace id too long");
21043       return -99;
21044     }
21045   M (APP_NAMESPACE_ADD_DEL, mp);
21046
21047   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
21048   mp->namespace_id_len = vec_len (ns_id);
21049   mp->secret = clib_host_to_net_u64 (secret);
21050   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
21051   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
21052   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
21053   vec_free (ns_id);
21054   S (mp);
21055   W (ret);
21056   return ret;
21057 }
21058
21059 static int
21060 api_memfd_segment_create (vat_main_t * vam)
21061 {
21062 #if VPP_API_TEST_BUILTIN == 0
21063   unformat_input_t *i = vam->input;
21064   vl_api_memfd_segment_create_t *mp;
21065   u64 size = 64 << 20;
21066   int ret;
21067
21068   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21069     {
21070       if (unformat (i, "size %U", unformat_memory_size, &size))
21071         ;
21072       else
21073         break;
21074     }
21075
21076   M (MEMFD_SEGMENT_CREATE, mp);
21077   mp->requested_size = size;
21078   S (mp);
21079   W (ret);
21080   return ret;
21081
21082 #else
21083   errmsg ("memfd_segment_create (builtin) not supported");
21084   return -99;
21085 #endif
21086 }
21087
21088 static int
21089 api_dns_enable_disable (vat_main_t * vam)
21090 {
21091   unformat_input_t *line_input = vam->input;
21092   vl_api_dns_enable_disable_t *mp;
21093   u8 enable_disable = 1;
21094   int ret;
21095
21096   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21097     {
21098       if (unformat (line_input, "disable"))
21099         enable_disable = 0;
21100       if (unformat (line_input, "enable"))
21101         enable_disable = 1;
21102       else
21103         break;
21104     }
21105
21106   /* Construct the API message */
21107   M (DNS_ENABLE_DISABLE, mp);
21108   mp->enable = enable_disable;
21109
21110   /* send it... */
21111   S (mp);
21112   /* Wait for the reply */
21113   W (ret);
21114   return ret;
21115 }
21116
21117 static int
21118 api_dns_resolve_name (vat_main_t * vam)
21119 {
21120   unformat_input_t *line_input = vam->input;
21121   vl_api_dns_resolve_name_t *mp;
21122   u8 *name = 0;
21123   int ret;
21124
21125   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21126     {
21127       if (unformat (line_input, "%s", &name))
21128         ;
21129       else
21130         break;
21131     }
21132
21133   if (vec_len (name) > 127)
21134     {
21135       errmsg ("name too long");
21136       return -99;
21137     }
21138
21139   /* Construct the API message */
21140   M (DNS_RESOLVE_NAME, mp);
21141   memcpy (mp->name, name, vec_len (name));
21142   vec_free (name);
21143
21144   /* send it... */
21145   S (mp);
21146   /* Wait for the reply */
21147   W (ret);
21148   return ret;
21149 }
21150
21151 static int
21152 api_dns_resolve_ip (vat_main_t * vam)
21153 {
21154   unformat_input_t *line_input = vam->input;
21155   vl_api_dns_resolve_ip_t *mp;
21156   int is_ip6 = -1;
21157   ip4_address_t addr4;
21158   ip6_address_t addr6;
21159   int ret;
21160
21161   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21162     {
21163       if (unformat (line_input, "%U", unformat_ip6_address, &addr6))
21164         is_ip6 = 1;
21165       else if (unformat (line_input, "%U", unformat_ip4_address, &addr4))
21166         is_ip6 = 0;
21167       else
21168         break;
21169     }
21170
21171   if (is_ip6 == -1)
21172     {
21173       errmsg ("missing address");
21174       return -99;
21175     }
21176
21177   /* Construct the API message */
21178   M (DNS_RESOLVE_IP, mp);
21179   mp->is_ip6 = is_ip6;
21180   if (is_ip6)
21181     memcpy (mp->address, &addr6, sizeof (addr6));
21182   else
21183     memcpy (mp->address, &addr4, sizeof (addr4));
21184
21185   /* send it... */
21186   S (mp);
21187   /* Wait for the reply */
21188   W (ret);
21189   return ret;
21190 }
21191
21192 static int
21193 api_dns_name_server_add_del (vat_main_t * vam)
21194 {
21195   unformat_input_t *i = vam->input;
21196   vl_api_dns_name_server_add_del_t *mp;
21197   u8 is_add = 1;
21198   ip6_address_t ip6_server;
21199   ip4_address_t ip4_server;
21200   int ip6_set = 0;
21201   int ip4_set = 0;
21202   int ret = 0;
21203
21204   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21205     {
21206       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21207         ip6_set = 1;
21208       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21209         ip4_set = 1;
21210       else if (unformat (i, "del"))
21211         is_add = 0;
21212       else
21213         {
21214           clib_warning ("parse error '%U'", format_unformat_error, i);
21215           return -99;
21216         }
21217     }
21218
21219   if (ip4_set && ip6_set)
21220     {
21221       errmsg ("Only one server address allowed per message");
21222       return -99;
21223     }
21224   if ((ip4_set + ip6_set) == 0)
21225     {
21226       errmsg ("Server address required");
21227       return -99;
21228     }
21229
21230   /* Construct the API message */
21231   M (DNS_NAME_SERVER_ADD_DEL, mp);
21232
21233   if (ip6_set)
21234     {
21235       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21236       mp->is_ip6 = 1;
21237     }
21238   else
21239     {
21240       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21241       mp->is_ip6 = 0;
21242     }
21243
21244   mp->is_add = is_add;
21245
21246   /* send it... */
21247   S (mp);
21248
21249   /* Wait for a reply, return good/bad news  */
21250   W (ret);
21251   return ret;
21252 }
21253
21254 static int
21255 api_session_rule_add_del (vat_main_t * vam)
21256 {
21257   vl_api_session_rule_add_del_t *mp;
21258   unformat_input_t *i = vam->input;
21259   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
21260   u32 appns_index = 0, scope = 0;
21261   ip4_address_t lcl_ip4, rmt_ip4;
21262   ip6_address_t lcl_ip6, rmt_ip6;
21263   u8 is_ip4 = 1, conn_set = 0;
21264   u8 is_add = 1;
21265   int ret;
21266
21267   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21268     {
21269       if (unformat (i, "del"))
21270         is_add = 0;
21271       else if (unformat (i, "add"))
21272         ;
21273       else if (unformat (i, "proto tcp"))
21274         proto = 0;
21275       else if (unformat (i, "proto udp"))
21276         proto = 1;
21277       else if (unformat (i, "appns %d", &appns_index))
21278         ;
21279       else if (unformat (i, "scope %d", &scope))
21280         ;
21281       else
21282         if (unformat
21283             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
21284              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
21285              &rmt_port))
21286         {
21287           is_ip4 = 1;
21288           conn_set = 1;
21289         }
21290       else
21291         if (unformat
21292             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
21293              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
21294              &rmt_port))
21295         {
21296           is_ip4 = 0;
21297           conn_set = 1;
21298         }
21299       else if (unformat (i, "action %d", &action))
21300         ;
21301       else
21302         break;
21303     }
21304   if (proto == ~0 || !conn_set || action == ~0)
21305     {
21306       errmsg ("transport proto, connection and action must be set");
21307       return -99;
21308     }
21309
21310   if (scope > 3)
21311     {
21312       errmsg ("scope should be 0-3");
21313       return -99;
21314     }
21315
21316   M (SESSION_RULE_ADD_DEL, mp);
21317
21318   mp->is_ip4 = is_ip4;
21319   mp->transport_proto = proto;
21320   mp->lcl_plen = clib_host_to_net_u16 (lcl_plen);
21321   mp->rmt_plen = clib_host_to_net_u16 (rmt_plen);
21322   mp->action_index = clib_host_to_net_u32 (action);
21323   mp->appns_index = clib_host_to_net_u32 (appns_index);
21324   mp->scope = scope;
21325   mp->is_add = is_add;
21326   if (is_ip4)
21327     {
21328       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
21329       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
21330     }
21331   else
21332     {
21333       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
21334       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
21335     }
21336
21337   S (mp);
21338   W (ret);
21339   return ret;
21340 }
21341
21342 static int
21343 q_or_quit (vat_main_t * vam)
21344 {
21345 #if VPP_API_TEST_BUILTIN == 0
21346   longjmp (vam->jump_buf, 1);
21347 #endif
21348   return 0;                     /* not so much */
21349 }
21350
21351 static int
21352 q (vat_main_t * vam)
21353 {
21354   return q_or_quit (vam);
21355 }
21356
21357 static int
21358 quit (vat_main_t * vam)
21359 {
21360   return q_or_quit (vam);
21361 }
21362
21363 static int
21364 comment (vat_main_t * vam)
21365 {
21366   return 0;
21367 }
21368
21369 static int
21370 cmd_cmp (void *a1, void *a2)
21371 {
21372   u8 **c1 = a1;
21373   u8 **c2 = a2;
21374
21375   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21376 }
21377
21378 static int
21379 help (vat_main_t * vam)
21380 {
21381   u8 **cmds = 0;
21382   u8 *name = 0;
21383   hash_pair_t *p;
21384   unformat_input_t *i = vam->input;
21385   int j;
21386
21387   if (unformat (i, "%s", &name))
21388     {
21389       uword *hs;
21390
21391       vec_add1 (name, 0);
21392
21393       hs = hash_get_mem (vam->help_by_name, name);
21394       if (hs)
21395         print (vam->ofp, "usage: %s %s", name, hs[0]);
21396       else
21397         print (vam->ofp, "No such msg / command '%s'", name);
21398       vec_free (name);
21399       return 0;
21400     }
21401
21402   print (vam->ofp, "Help is available for the following:");
21403
21404     /* *INDENT-OFF* */
21405     hash_foreach_pair (p, vam->function_by_name,
21406     ({
21407       vec_add1 (cmds, (u8 *)(p->key));
21408     }));
21409     /* *INDENT-ON* */
21410
21411   vec_sort_with_function (cmds, cmd_cmp);
21412
21413   for (j = 0; j < vec_len (cmds); j++)
21414     print (vam->ofp, "%s", cmds[j]);
21415
21416   vec_free (cmds);
21417   return 0;
21418 }
21419
21420 static int
21421 set (vat_main_t * vam)
21422 {
21423   u8 *name = 0, *value = 0;
21424   unformat_input_t *i = vam->input;
21425
21426   if (unformat (i, "%s", &name))
21427     {
21428       /* The input buffer is a vector, not a string. */
21429       value = vec_dup (i->buffer);
21430       vec_delete (value, i->index, 0);
21431       /* Almost certainly has a trailing newline */
21432       if (value[vec_len (value) - 1] == '\n')
21433         value[vec_len (value) - 1] = 0;
21434       /* Make sure it's a proper string, one way or the other */
21435       vec_add1 (value, 0);
21436       (void) clib_macro_set_value (&vam->macro_main,
21437                                    (char *) name, (char *) value);
21438     }
21439   else
21440     errmsg ("usage: set <name> <value>");
21441
21442   vec_free (name);
21443   vec_free (value);
21444   return 0;
21445 }
21446
21447 static int
21448 unset (vat_main_t * vam)
21449 {
21450   u8 *name = 0;
21451
21452   if (unformat (vam->input, "%s", &name))
21453     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21454       errmsg ("unset: %s wasn't set", name);
21455   vec_free (name);
21456   return 0;
21457 }
21458
21459 typedef struct
21460 {
21461   u8 *name;
21462   u8 *value;
21463 } macro_sort_t;
21464
21465
21466 static int
21467 macro_sort_cmp (void *a1, void *a2)
21468 {
21469   macro_sort_t *s1 = a1;
21470   macro_sort_t *s2 = a2;
21471
21472   return strcmp ((char *) (s1->name), (char *) (s2->name));
21473 }
21474
21475 static int
21476 dump_macro_table (vat_main_t * vam)
21477 {
21478   macro_sort_t *sort_me = 0, *sm;
21479   int i;
21480   hash_pair_t *p;
21481
21482     /* *INDENT-OFF* */
21483     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21484     ({
21485       vec_add2 (sort_me, sm, 1);
21486       sm->name = (u8 *)(p->key);
21487       sm->value = (u8 *) (p->value[0]);
21488     }));
21489     /* *INDENT-ON* */
21490
21491   vec_sort_with_function (sort_me, macro_sort_cmp);
21492
21493   if (vec_len (sort_me))
21494     print (vam->ofp, "%-15s%s", "Name", "Value");
21495   else
21496     print (vam->ofp, "The macro table is empty...");
21497
21498   for (i = 0; i < vec_len (sort_me); i++)
21499     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21500   return 0;
21501 }
21502
21503 static int
21504 dump_node_table (vat_main_t * vam)
21505 {
21506   int i, j;
21507   vlib_node_t *node, *next_node;
21508
21509   if (vec_len (vam->graph_nodes) == 0)
21510     {
21511       print (vam->ofp, "Node table empty, issue get_node_graph...");
21512       return 0;
21513     }
21514
21515   for (i = 0; i < vec_len (vam->graph_nodes); i++)
21516     {
21517       node = vam->graph_nodes[i];
21518       print (vam->ofp, "[%d] %s", i, node->name);
21519       for (j = 0; j < vec_len (node->next_nodes); j++)
21520         {
21521           if (node->next_nodes[j] != ~0)
21522             {
21523               next_node = vam->graph_nodes[node->next_nodes[j]];
21524               print (vam->ofp, "  [%d] %s", j, next_node->name);
21525             }
21526         }
21527     }
21528   return 0;
21529 }
21530
21531 static int
21532 value_sort_cmp (void *a1, void *a2)
21533 {
21534   name_sort_t *n1 = a1;
21535   name_sort_t *n2 = a2;
21536
21537   if (n1->value < n2->value)
21538     return -1;
21539   if (n1->value > n2->value)
21540     return 1;
21541   return 0;
21542 }
21543
21544
21545 static int
21546 dump_msg_api_table (vat_main_t * vam)
21547 {
21548   api_main_t *am = &api_main;
21549   name_sort_t *nses = 0, *ns;
21550   hash_pair_t *hp;
21551   int i;
21552
21553   /* *INDENT-OFF* */
21554   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21555   ({
21556     vec_add2 (nses, ns, 1);
21557     ns->name = (u8 *)(hp->key);
21558     ns->value = (u32) hp->value[0];
21559   }));
21560   /* *INDENT-ON* */
21561
21562   vec_sort_with_function (nses, value_sort_cmp);
21563
21564   for (i = 0; i < vec_len (nses); i++)
21565     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21566   vec_free (nses);
21567   return 0;
21568 }
21569
21570 static int
21571 get_msg_id (vat_main_t * vam)
21572 {
21573   u8 *name_and_crc;
21574   u32 message_index;
21575
21576   if (unformat (vam->input, "%s", &name_and_crc))
21577     {
21578       message_index = vl_api_get_msg_index (name_and_crc);
21579       if (message_index == ~0)
21580         {
21581           print (vam->ofp, " '%s' not found", name_and_crc);
21582           return 0;
21583         }
21584       print (vam->ofp, " '%s' has message index %d",
21585              name_and_crc, message_index);
21586       return 0;
21587     }
21588   errmsg ("name_and_crc required...");
21589   return 0;
21590 }
21591
21592 static int
21593 search_node_table (vat_main_t * vam)
21594 {
21595   unformat_input_t *line_input = vam->input;
21596   u8 *node_to_find;
21597   int j;
21598   vlib_node_t *node, *next_node;
21599   uword *p;
21600
21601   if (vam->graph_node_index_by_name == 0)
21602     {
21603       print (vam->ofp, "Node table empty, issue get_node_graph...");
21604       return 0;
21605     }
21606
21607   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21608     {
21609       if (unformat (line_input, "%s", &node_to_find))
21610         {
21611           vec_add1 (node_to_find, 0);
21612           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21613           if (p == 0)
21614             {
21615               print (vam->ofp, "%s not found...", node_to_find);
21616               goto out;
21617             }
21618           node = vam->graph_nodes[p[0]];
21619           print (vam->ofp, "[%d] %s", p[0], node->name);
21620           for (j = 0; j < vec_len (node->next_nodes); j++)
21621             {
21622               if (node->next_nodes[j] != ~0)
21623                 {
21624                   next_node = vam->graph_nodes[node->next_nodes[j]];
21625                   print (vam->ofp, "  [%d] %s", j, next_node->name);
21626                 }
21627             }
21628         }
21629
21630       else
21631         {
21632           clib_warning ("parse error '%U'", format_unformat_error,
21633                         line_input);
21634           return -99;
21635         }
21636
21637     out:
21638       vec_free (node_to_find);
21639
21640     }
21641
21642   return 0;
21643 }
21644
21645
21646 static int
21647 script (vat_main_t * vam)
21648 {
21649 #if (VPP_API_TEST_BUILTIN==0)
21650   u8 *s = 0;
21651   char *save_current_file;
21652   unformat_input_t save_input;
21653   jmp_buf save_jump_buf;
21654   u32 save_line_number;
21655
21656   FILE *new_fp, *save_ifp;
21657
21658   if (unformat (vam->input, "%s", &s))
21659     {
21660       new_fp = fopen ((char *) s, "r");
21661       if (new_fp == 0)
21662         {
21663           errmsg ("Couldn't open script file %s", s);
21664           vec_free (s);
21665           return -99;
21666         }
21667     }
21668   else
21669     {
21670       errmsg ("Missing script name");
21671       return -99;
21672     }
21673
21674   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
21675   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
21676   save_ifp = vam->ifp;
21677   save_line_number = vam->input_line_number;
21678   save_current_file = (char *) vam->current_file;
21679
21680   vam->input_line_number = 0;
21681   vam->ifp = new_fp;
21682   vam->current_file = s;
21683   do_one_file (vam);
21684
21685   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
21686   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
21687   vam->ifp = save_ifp;
21688   vam->input_line_number = save_line_number;
21689   vam->current_file = (u8 *) save_current_file;
21690   vec_free (s);
21691
21692   return 0;
21693 #else
21694   clib_warning ("use the exec command...");
21695   return -99;
21696 #endif
21697 }
21698
21699 static int
21700 echo (vat_main_t * vam)
21701 {
21702   print (vam->ofp, "%v", vam->input->buffer);
21703   return 0;
21704 }
21705
21706 /* List of API message constructors, CLI names map to api_xxx */
21707 #define foreach_vpe_api_msg                                             \
21708 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
21709 _(sw_interface_dump,"")                                                 \
21710 _(sw_interface_set_flags,                                               \
21711   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
21712 _(sw_interface_add_del_address,                                         \
21713   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
21714 _(sw_interface_set_rx_mode,                                             \
21715   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
21716 _(sw_interface_set_table,                                               \
21717   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
21718 _(sw_interface_set_mpls_enable,                                         \
21719   "<intfc> | sw_if_index [disable | dis]")                              \
21720 _(sw_interface_set_vpath,                                               \
21721   "<intfc> | sw_if_index <id> enable | disable")                        \
21722 _(sw_interface_set_vxlan_bypass,                                        \
21723   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21724 _(sw_interface_set_geneve_bypass,                                       \
21725   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21726 _(sw_interface_set_l2_xconnect,                                         \
21727   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21728   "enable | disable")                                                   \
21729 _(sw_interface_set_l2_bridge,                                           \
21730   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
21731   "[shg <split-horizon-group>] [bvi]\n"                                 \
21732   "enable | disable")                                                   \
21733 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
21734 _(bridge_domain_add_del,                                                \
21735   "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") \
21736 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
21737 _(l2fib_add_del,                                                        \
21738   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
21739 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
21740 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
21741 _(l2_flags,                                                             \
21742   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21743 _(bridge_flags,                                                         \
21744   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21745 _(tap_connect,                                                          \
21746   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
21747 _(tap_modify,                                                           \
21748   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
21749 _(tap_delete,                                                           \
21750   "<vpp-if-name> | sw_if_index <id>")                                   \
21751 _(sw_interface_tap_dump, "")                                            \
21752 _(ip_table_add_del,                                                     \
21753   "table-id <n> [ipv6]\n")                                              \
21754 _(ip_add_del_route,                                                     \
21755   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
21756   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
21757   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
21758   "[multipath] [count <n>]")                                            \
21759 _(ip_mroute_add_del,                                                    \
21760   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
21761   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
21762 _(mpls_table_add_del,                                                   \
21763   "table-id <n>\n")                                                     \
21764 _(mpls_route_add_del,                                                   \
21765   "<label> <eos> via <addr> [table-id <n>]\n"                           \
21766   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
21767   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
21768   "[multipath] [count <n>]")                                            \
21769 _(mpls_ip_bind_unbind,                                                  \
21770   "<label> <addr/len>")                                                 \
21771 _(mpls_tunnel_add_del,                                                  \
21772   " via <addr> [table-id <n>]\n"                                        \
21773   "sw_if_index <id>] [l2]  [del]")                                      \
21774 _(proxy_arp_add_del,                                                    \
21775   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
21776 _(proxy_arp_intfc_enable_disable,                                       \
21777   "<intfc> | sw_if_index <id> enable | disable")                        \
21778 _(sw_interface_set_unnumbered,                                          \
21779   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
21780 _(ip_neighbor_add_del,                                                  \
21781   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
21782   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
21783 _(reset_vrf, "vrf <id> [ipv6]")                                         \
21784 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
21785 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
21786   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
21787   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
21788   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
21789 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
21790 _(reset_fib, "vrf <n> [ipv6]")                                          \
21791 _(dhcp_proxy_config,                                                    \
21792   "svr <v46-address> src <v46-address>\n"                               \
21793    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
21794 _(dhcp_proxy_set_vss,                                                   \
21795   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
21796 _(dhcp_proxy_dump, "ip6")                                               \
21797 _(dhcp_client_config,                                                   \
21798   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
21799 _(set_ip_flow_hash,                                                     \
21800   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
21801 _(sw_interface_ip6_enable_disable,                                      \
21802   "<intfc> | sw_if_index <id> enable | disable")                        \
21803 _(sw_interface_ip6_set_link_local_address,                              \
21804   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
21805 _(ip6nd_proxy_add_del,                                                  \
21806   "<intfc> | sw_if_index <id> <ip6-address>")                           \
21807 _(ip6nd_proxy_dump, "")                                                 \
21808 _(sw_interface_ip6nd_ra_prefix,                                         \
21809   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
21810   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
21811   "[nolink] [isno]")                                                    \
21812 _(sw_interface_ip6nd_ra_config,                                         \
21813   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
21814   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
21815   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
21816 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
21817 _(l2_patch_add_del,                                                     \
21818   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21819   "enable | disable")                                                   \
21820 _(sr_localsid_add_del,                                                  \
21821   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
21822   "fib-table <num> (end.psp) sw_if_index <num>")                        \
21823 _(classify_add_del_table,                                               \
21824   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
21825   " [del] [del-chain] mask <mask-value>\n"                              \
21826   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
21827   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
21828 _(classify_add_del_session,                                             \
21829   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
21830   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
21831   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
21832   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
21833 _(classify_set_interface_ip_table,                                      \
21834   "<intfc> | sw_if_index <nn> table <nn>")                              \
21835 _(classify_set_interface_l2_tables,                                     \
21836   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21837   "  [other-table <nn>]")                                               \
21838 _(get_node_index, "node <node-name")                                    \
21839 _(add_node_next, "node <node-name> next <next-node-name>")              \
21840 _(l2tpv3_create_tunnel,                                                 \
21841   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
21842   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
21843   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
21844 _(l2tpv3_set_tunnel_cookies,                                            \
21845   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
21846   "[new_remote_cookie <nn>]\n")                                         \
21847 _(l2tpv3_interface_enable_disable,                                      \
21848   "<intfc> | sw_if_index <nn> enable | disable")                        \
21849 _(l2tpv3_set_lookup_key,                                                \
21850   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
21851 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
21852 _(vxlan_add_del_tunnel,                                                 \
21853   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21854   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21855   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21856 _(geneve_add_del_tunnel,                                                \
21857   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21858   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21859   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21860 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
21861 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
21862 _(gre_add_del_tunnel,                                                   \
21863   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
21864 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
21865 _(l2_fib_clear_table, "")                                               \
21866 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
21867 _(l2_interface_vlan_tag_rewrite,                                        \
21868   "<intfc> | sw_if_index <nn> \n"                                       \
21869   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
21870   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
21871 _(create_vhost_user_if,                                                 \
21872         "socket <filename> [server] [renumber <dev_instance>] "         \
21873         "[mac <mac_address>]")                                          \
21874 _(modify_vhost_user_if,                                                 \
21875         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
21876         "[server] [renumber <dev_instance>]")                           \
21877 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
21878 _(sw_interface_vhost_user_dump, "")                                     \
21879 _(show_version, "")                                                     \
21880 _(vxlan_gpe_add_del_tunnel,                                             \
21881   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
21882   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21883   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
21884   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
21885 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
21886 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
21887 _(interface_name_renumber,                                              \
21888   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
21889 _(input_acl_set_interface,                                              \
21890   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21891   "  [l2-table <nn>] [del]")                                            \
21892 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
21893 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
21894 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
21895 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
21896 _(ip_dump, "ipv4 | ipv6")                                               \
21897 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
21898 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
21899   "  spid_id <n> ")                                                     \
21900 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
21901   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
21902   "  integ_alg <alg> integ_key <hex>")                                  \
21903 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
21904   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
21905   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
21906   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
21907 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
21908 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
21909   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
21910   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
21911   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
21912 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
21913 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
21914   "  <alg> <hex>\n")                                                    \
21915 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
21916 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
21917 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
21918   "(auth_data 0x<data> | auth_data <data>)")                            \
21919 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
21920   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
21921 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
21922   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
21923   "(local|remote)")                                                     \
21924 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
21925 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
21926 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
21927 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
21928 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
21929 _(ikev2_initiate_sa_init, "<profile_name>")                             \
21930 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
21931 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
21932 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
21933 _(delete_loopback,"sw_if_index <nn>")                                   \
21934 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
21935 _(map_add_domain,                                                       \
21936   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
21937   "ip6-src <ip6addr> "                                                  \
21938   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
21939 _(map_del_domain, "index <n>")                                          \
21940 _(map_add_del_rule,                                                     \
21941   "index <n> psid <n> dst <ip6addr> [del]")                             \
21942 _(map_domain_dump, "")                                                  \
21943 _(map_rule_dump, "index <map-domain>")                                  \
21944 _(want_interface_events,  "enable|disable")                             \
21945 _(want_stats,"enable|disable")                                          \
21946 _(get_first_msg_id, "client <name>")                                    \
21947 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
21948 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
21949   "fib-id <nn> [ip4][ip6][default]")                                    \
21950 _(get_node_graph, " ")                                                  \
21951 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
21952 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
21953 _(ioam_disable, "")                                                     \
21954 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
21955                             " sw_if_index <sw_if_index> p <priority> "  \
21956                             "w <weight>] [del]")                        \
21957 _(one_add_del_locator, "locator-set <locator_name> "                    \
21958                         "iface <intf> | sw_if_index <sw_if_index> "     \
21959                         "p <priority> w <weight> [del]")                \
21960 _(one_add_del_local_eid,"vni <vni> eid "                                \
21961                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21962                          "locator-set <locator_name> [del]"             \
21963                          "[key-id sha1|sha256 secret-key <secret-key>]")\
21964 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
21965 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
21966 _(one_enable_disable, "enable|disable")                                 \
21967 _(one_map_register_enable_disable, "enable|disable")                    \
21968 _(one_map_register_fallback_threshold, "<value>")                       \
21969 _(one_rloc_probe_enable_disable, "enable|disable")                      \
21970 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
21971                                "[seid <seid>] "                         \
21972                                "rloc <locator> p <prio> "               \
21973                                "w <weight> [rloc <loc> ... ] "          \
21974                                "action <action> [del-all]")             \
21975 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
21976                           "<local-eid>")                                \
21977 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
21978 _(one_use_petr, "ip-address> | disable")                                \
21979 _(one_map_request_mode, "src-dst|dst-only")                             \
21980 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
21981 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
21982 _(one_locator_set_dump, "[local | remote]")                             \
21983 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
21984 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
21985                        "[local] | [remote]")                            \
21986 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
21987 _(one_ndp_bd_get, "")                                                   \
21988 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
21989 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
21990 _(one_l2_arp_bd_get, "")                                                \
21991 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
21992 _(one_stats_enable_disable, "enable|disalbe")                           \
21993 _(show_one_stats_enable_disable, "")                                    \
21994 _(one_eid_table_vni_dump, "")                                           \
21995 _(one_eid_table_map_dump, "l2|l3")                                      \
21996 _(one_map_resolver_dump, "")                                            \
21997 _(one_map_server_dump, "")                                              \
21998 _(one_adjacencies_get, "vni <vni>")                                     \
21999 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
22000 _(show_one_rloc_probe_state, "")                                        \
22001 _(show_one_map_register_state, "")                                      \
22002 _(show_one_status, "")                                                  \
22003 _(one_stats_dump, "")                                                   \
22004 _(one_stats_flush, "")                                                  \
22005 _(one_get_map_request_itr_rlocs, "")                                    \
22006 _(one_map_register_set_ttl, "<ttl>")                                    \
22007 _(one_set_transport_protocol, "udp|api")                                \
22008 _(one_get_transport_protocol, "")                                       \
22009 _(show_one_nsh_mapping, "")                                             \
22010 _(show_one_pitr, "")                                                    \
22011 _(show_one_use_petr, "")                                                \
22012 _(show_one_map_request_mode, "")                                        \
22013 _(show_one_map_register_ttl, "")                                        \
22014 _(show_one_map_register_fallback_threshold, "")                         \
22015 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
22016                             " sw_if_index <sw_if_index> p <priority> "  \
22017                             "w <weight>] [del]")                        \
22018 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
22019                         "iface <intf> | sw_if_index <sw_if_index> "     \
22020                         "p <priority> w <weight> [del]")                \
22021 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
22022                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
22023                          "locator-set <locator_name> [del]"             \
22024                          "[key-id sha1|sha256 secret-key <secret-key>]") \
22025 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
22026 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
22027 _(lisp_enable_disable, "enable|disable")                                \
22028 _(lisp_map_register_enable_disable, "enable|disable")                   \
22029 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
22030 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
22031                                "[seid <seid>] "                         \
22032                                "rloc <locator> p <prio> "               \
22033                                "w <weight> [rloc <loc> ... ] "          \
22034                                "action <action> [del-all]")             \
22035 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
22036                           "<local-eid>")                                \
22037 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
22038 _(lisp_use_petr, "<ip-address> | disable")                              \
22039 _(lisp_map_request_mode, "src-dst|dst-only")                            \
22040 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
22041 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
22042 _(lisp_locator_set_dump, "[local | remote]")                            \
22043 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
22044 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
22045                        "[local] | [remote]")                            \
22046 _(lisp_eid_table_vni_dump, "")                                          \
22047 _(lisp_eid_table_map_dump, "l2|l3")                                     \
22048 _(lisp_map_resolver_dump, "")                                           \
22049 _(lisp_map_server_dump, "")                                             \
22050 _(lisp_adjacencies_get, "vni <vni>")                                    \
22051 _(gpe_fwd_entry_vnis_get, "")                                           \
22052 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
22053 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
22054                                 "[table <table-id>]")                   \
22055 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
22056 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
22057 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
22058 _(gpe_get_encap_mode, "")                                               \
22059 _(lisp_gpe_add_del_iface, "up|down")                                    \
22060 _(lisp_gpe_enable_disable, "enable|disable")                            \
22061 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
22062   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
22063 _(show_lisp_rloc_probe_state, "")                                       \
22064 _(show_lisp_map_register_state, "")                                     \
22065 _(show_lisp_status, "")                                                 \
22066 _(lisp_get_map_request_itr_rlocs, "")                                   \
22067 _(show_lisp_pitr, "")                                                   \
22068 _(show_lisp_use_petr, "")                                               \
22069 _(show_lisp_map_request_mode, "")                                       \
22070 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
22071 _(af_packet_delete, "name <host interface name>")                       \
22072 _(policer_add_del, "name <policer name> <params> [del]")                \
22073 _(policer_dump, "[name <policer name>]")                                \
22074 _(policer_classify_set_interface,                                       \
22075   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
22076   "  [l2-table <nn>] [del]")                                            \
22077 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
22078 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
22079     "[master|slave]")                                                   \
22080 _(netmap_delete, "name <interface name>")                               \
22081 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
22082 _(mpls_fib_dump, "")                                                    \
22083 _(classify_table_ids, "")                                               \
22084 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
22085 _(classify_table_info, "table_id <nn>")                                 \
22086 _(classify_session_dump, "table_id <nn>")                               \
22087 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
22088     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
22089     "[template_interval <nn>] [udp_checksum]")                          \
22090 _(ipfix_exporter_dump, "")                                              \
22091 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
22092 _(ipfix_classify_stream_dump, "")                                       \
22093 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
22094 _(ipfix_classify_table_dump, "")                                        \
22095 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
22096 _(sw_interface_span_dump, "[l2]")                                           \
22097 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
22098 _(pg_create_interface, "if_id <nn>")                                    \
22099 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
22100 _(pg_enable_disable, "[stream <id>] disable")                           \
22101 _(ip_source_and_port_range_check_add_del,                               \
22102   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
22103 _(ip_source_and_port_range_check_interface_add_del,                     \
22104   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
22105   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
22106 _(ipsec_gre_add_del_tunnel,                                             \
22107   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
22108 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
22109 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
22110 _(l2_interface_pbb_tag_rewrite,                                         \
22111   "<intfc> | sw_if_index <nn> \n"                                       \
22112   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
22113   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
22114 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
22115 _(flow_classify_set_interface,                                          \
22116   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
22117 _(flow_classify_dump, "type [ip4|ip6]")                                 \
22118 _(ip_fib_dump, "")                                                      \
22119 _(ip_mfib_dump, "")                                                     \
22120 _(ip6_fib_dump, "")                                                     \
22121 _(ip6_mfib_dump, "")                                                    \
22122 _(feature_enable_disable, "arc_name <arc_name> "                        \
22123   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
22124 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
22125 "[disable]")                                                            \
22126 _(l2_xconnect_dump, "")                                                 \
22127 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
22128 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
22129 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
22130 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
22131 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
22132 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
22133 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
22134   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
22135 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
22136 _(memfd_segment_create,"size <nnn>")                                    \
22137 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
22138 _(dns_enable_disable, "[enable][disable]")                              \
22139 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22140 _(dns_resolve_name, "<hostname>")                                       \
22141 _(dns_resolve_ip, "<ip4|ip6>")                                          \
22142 _(dns_name_server_add_del, "<ip-address> [del]")                        \
22143 _(dns_resolve_name, "<hostname>")                                       \
22144 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
22145   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
22146
22147 /* List of command functions, CLI names map directly to functions */
22148 #define foreach_cli_function                                    \
22149 _(comment, "usage: comment <ignore-rest-of-line>")              \
22150 _(dump_interface_table, "usage: dump_interface_table")          \
22151 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
22152 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
22153 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
22154 _(dump_stats_table, "usage: dump_stats_table")                  \
22155 _(dump_macro_table, "usage: dump_macro_table ")                 \
22156 _(dump_node_table, "usage: dump_node_table")                    \
22157 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
22158 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
22159 _(echo, "usage: echo <message>")                                \
22160 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
22161 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
22162 _(help, "usage: help")                                          \
22163 _(q, "usage: quit")                                             \
22164 _(quit, "usage: quit")                                          \
22165 _(search_node_table, "usage: search_node_table <name>...")      \
22166 _(set, "usage: set <variable-name> <value>")                    \
22167 _(script, "usage: script <file-name>")                          \
22168 _(unset, "usage: unset <variable-name>")
22169 #define _(N,n)                                  \
22170     static void vl_api_##n##_t_handler_uni      \
22171     (vl_api_##n##_t * mp)                       \
22172     {                                           \
22173         vat_main_t * vam = &vat_main;           \
22174         if (vam->json_output) {                 \
22175             vl_api_##n##_t_handler_json(mp);    \
22176         } else {                                \
22177             vl_api_##n##_t_handler(mp);         \
22178         }                                       \
22179     }
22180 foreach_vpe_api_reply_msg;
22181 #if VPP_API_TEST_BUILTIN == 0
22182 foreach_standalone_reply_msg;
22183 #endif
22184 #undef _
22185
22186 void
22187 vat_api_hookup (vat_main_t * vam)
22188 {
22189 #define _(N,n)                                                  \
22190     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22191                            vl_api_##n##_t_handler_uni,          \
22192                            vl_noop_handler,                     \
22193                            vl_api_##n##_t_endian,               \
22194                            vl_api_##n##_t_print,                \
22195                            sizeof(vl_api_##n##_t), 1);
22196   foreach_vpe_api_reply_msg;
22197 #if VPP_API_TEST_BUILTIN == 0
22198   foreach_standalone_reply_msg;
22199 #endif
22200 #undef _
22201
22202 #if (VPP_API_TEST_BUILTIN==0)
22203   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22204
22205   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22206
22207   vam->function_by_name = hash_create_string (0, sizeof (uword));
22208
22209   vam->help_by_name = hash_create_string (0, sizeof (uword));
22210 #endif
22211
22212   /* API messages we can send */
22213 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22214   foreach_vpe_api_msg;
22215 #undef _
22216
22217   /* Help strings */
22218 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22219   foreach_vpe_api_msg;
22220 #undef _
22221
22222   /* CLI functions */
22223 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22224   foreach_cli_function;
22225 #undef _
22226
22227   /* Help strings */
22228 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22229   foreach_cli_function;
22230 #undef _
22231 }
22232
22233 #if VPP_API_TEST_BUILTIN
22234 static clib_error_t *
22235 vat_api_hookup_shim (vlib_main_t * vm)
22236 {
22237   vat_api_hookup (&vat_main);
22238   return 0;
22239 }
22240
22241 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22242 #endif
22243
22244 /*
22245  * fd.io coding-style-patch-verification: ON
22246  *
22247  * Local Variables:
22248  * eval: (c-set-style "gnu")
22249  * End:
22250  */