Revert "Enforce FIB table creation before use"
[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       retval = memfd_slave_init (&memfd);
2141       if (retval)
2142         clib_warning ("WARNING: segment map returned %d", retval);
2143
2144       /* Pivot to the memory client segment that vpp just created */
2145
2146       am->vlib_rp = (void *) (memfd.requested_va + MMAP_PAGESIZE);
2147
2148       am->shmem_hdr = (void *) am->vlib_rp->user_ctx;
2149
2150       vl_client_install_client_message_handlers ();
2151
2152       vl_client_connect_to_vlib_no_map ("pvt",
2153                                         "vpp_api_test(p)",
2154                                         32 /* input_queue_length */ );
2155       if (close (my_fd) < 0)
2156         clib_unix_warning ("close memfd fd pivot");
2157       vam->vl_input_queue = am->shmem_hdr->vl_input_queue;
2158
2159       vl_socket_client_enable_disable (&vam->socket_client_main,
2160                                        0 /* disable socket */ );
2161     }
2162
2163 out:
2164   if (vam->async_mode)
2165     {
2166       vam->async_errors += (retval < 0);
2167     }
2168   else
2169     {
2170       vam->retval = retval;
2171       vam->result_ready = 1;
2172     }
2173 #endif
2174 }
2175
2176 static void vl_api_memfd_segment_create_reply_t_handler_json
2177   (vl_api_memfd_segment_create_reply_t * mp)
2178 {
2179   clib_warning ("no");
2180 }
2181
2182 static void vl_api_dns_resolve_name_reply_t_handler
2183   (vl_api_dns_resolve_name_reply_t * mp)
2184 {
2185   vat_main_t *vam = &vat_main;
2186   i32 retval = ntohl (mp->retval);
2187   if (vam->async_mode)
2188     {
2189       vam->async_errors += (retval < 0);
2190     }
2191   else
2192     {
2193       vam->retval = retval;
2194       vam->result_ready = 1;
2195
2196       if (retval == 0)
2197         {
2198           if (mp->ip4_set)
2199             clib_warning ("ip4 address %U", format_ip4_address,
2200                           (ip4_address_t *) mp->ip4_address);
2201           if (mp->ip6_set)
2202             clib_warning ("ip6 address %U", format_ip6_address,
2203                           (ip6_address_t *) mp->ip6_address);
2204         }
2205       else
2206         clib_warning ("retval %d", retval);
2207     }
2208 }
2209
2210 static void vl_api_dns_resolve_name_reply_t_handler_json
2211   (vl_api_dns_resolve_name_reply_t * mp)
2212 {
2213   clib_warning ("no");
2214 }
2215
2216 static void vl_api_ip_address_details_t_handler
2217   (vl_api_ip_address_details_t * mp)
2218 {
2219   vat_main_t *vam = &vat_main;
2220   static ip_address_details_t empty_ip_address_details = { {0} };
2221   ip_address_details_t *address = NULL;
2222   ip_details_t *current_ip_details = NULL;
2223   ip_details_t *details = NULL;
2224
2225   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2226
2227   if (!details || vam->current_sw_if_index >= vec_len (details)
2228       || !details[vam->current_sw_if_index].present)
2229     {
2230       errmsg ("ip address details arrived but not stored");
2231       errmsg ("ip_dump should be called first");
2232       return;
2233     }
2234
2235   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2236
2237 #define addresses (current_ip_details->addr)
2238
2239   vec_validate_init_empty (addresses, vec_len (addresses),
2240                            empty_ip_address_details);
2241
2242   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2243
2244   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2245   address->prefix_length = mp->prefix_length;
2246 #undef addresses
2247 }
2248
2249 static void vl_api_ip_address_details_t_handler_json
2250   (vl_api_ip_address_details_t * mp)
2251 {
2252   vat_main_t *vam = &vat_main;
2253   vat_json_node_t *node = NULL;
2254   struct in6_addr ip6;
2255   struct in_addr ip4;
2256
2257   if (VAT_JSON_ARRAY != vam->json_tree.type)
2258     {
2259       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2260       vat_json_init_array (&vam->json_tree);
2261     }
2262   node = vat_json_array_add (&vam->json_tree);
2263
2264   vat_json_init_object (node);
2265   if (vam->is_ipv6)
2266     {
2267       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2268       vat_json_object_add_ip6 (node, "ip", ip6);
2269     }
2270   else
2271     {
2272       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2273       vat_json_object_add_ip4 (node, "ip", ip4);
2274     }
2275   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2276 }
2277
2278 static void
2279 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2280 {
2281   vat_main_t *vam = &vat_main;
2282   static ip_details_t empty_ip_details = { 0 };
2283   ip_details_t *ip = NULL;
2284   u32 sw_if_index = ~0;
2285
2286   sw_if_index = ntohl (mp->sw_if_index);
2287
2288   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2289                            sw_if_index, empty_ip_details);
2290
2291   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2292                          sw_if_index);
2293
2294   ip->present = 1;
2295 }
2296
2297 static void
2298 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2299 {
2300   vat_main_t *vam = &vat_main;
2301
2302   if (VAT_JSON_ARRAY != vam->json_tree.type)
2303     {
2304       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2305       vat_json_init_array (&vam->json_tree);
2306     }
2307   vat_json_array_add_uint (&vam->json_tree,
2308                            clib_net_to_host_u32 (mp->sw_if_index));
2309 }
2310
2311 static void vl_api_map_domain_details_t_handler_json
2312   (vl_api_map_domain_details_t * mp)
2313 {
2314   vat_json_node_t *node = NULL;
2315   vat_main_t *vam = &vat_main;
2316   struct in6_addr ip6;
2317   struct in_addr ip4;
2318
2319   if (VAT_JSON_ARRAY != vam->json_tree.type)
2320     {
2321       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2322       vat_json_init_array (&vam->json_tree);
2323     }
2324
2325   node = vat_json_array_add (&vam->json_tree);
2326   vat_json_init_object (node);
2327
2328   vat_json_object_add_uint (node, "domain_index",
2329                             clib_net_to_host_u32 (mp->domain_index));
2330   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
2331   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
2332   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
2333   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
2334   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
2335   vat_json_object_add_ip6 (node, "ip6_src", ip6);
2336   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
2337   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
2338   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
2339   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
2340   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
2341   vat_json_object_add_int (node, "psid_length", mp->psid_length);
2342   vat_json_object_add_uint (node, "flags", mp->flags);
2343   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
2344   vat_json_object_add_int (node, "is_translation", mp->is_translation);
2345 }
2346
2347 static void vl_api_map_domain_details_t_handler
2348   (vl_api_map_domain_details_t * mp)
2349 {
2350   vat_main_t *vam = &vat_main;
2351
2352   if (mp->is_translation)
2353     {
2354       print (vam->ofp,
2355              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2356              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2357              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2358              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2359              clib_net_to_host_u32 (mp->domain_index));
2360     }
2361   else
2362     {
2363       print (vam->ofp,
2364              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2365              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2366              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2367              format_ip6_address, mp->ip6_src,
2368              clib_net_to_host_u32 (mp->domain_index));
2369     }
2370   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2371          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2372          mp->is_translation ? "map-t" : "");
2373 }
2374
2375 static void vl_api_map_rule_details_t_handler_json
2376   (vl_api_map_rule_details_t * mp)
2377 {
2378   struct in6_addr ip6;
2379   vat_json_node_t *node = NULL;
2380   vat_main_t *vam = &vat_main;
2381
2382   if (VAT_JSON_ARRAY != vam->json_tree.type)
2383     {
2384       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2385       vat_json_init_array (&vam->json_tree);
2386     }
2387
2388   node = vat_json_array_add (&vam->json_tree);
2389   vat_json_init_object (node);
2390
2391   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2392   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2393   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2394 }
2395
2396 static void
2397 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2398 {
2399   vat_main_t *vam = &vat_main;
2400   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2401          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2402 }
2403
2404 static void
2405 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2406 {
2407   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2408           "router_addr %U host_mac %U",
2409           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2410           format_ip4_address, &mp->host_address,
2411           format_ip4_address, &mp->router_address,
2412           format_ethernet_address, mp->host_mac);
2413 }
2414
2415 static void vl_api_dhcp_compl_event_t_handler_json
2416   (vl_api_dhcp_compl_event_t * mp)
2417 {
2418   /* JSON output not supported */
2419 }
2420
2421 static void
2422 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2423                               u32 counter)
2424 {
2425   vat_main_t *vam = &vat_main;
2426   static u64 default_counter = 0;
2427
2428   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2429                            NULL);
2430   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2431                            sw_if_index, default_counter);
2432   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2433 }
2434
2435 static void
2436 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2437                                 interface_counter_t counter)
2438 {
2439   vat_main_t *vam = &vat_main;
2440   static interface_counter_t default_counter = { 0, };
2441
2442   vec_validate_init_empty (vam->combined_interface_counters,
2443                            vnet_counter_type, NULL);
2444   vec_validate_init_empty (vam->combined_interface_counters
2445                            [vnet_counter_type], sw_if_index, default_counter);
2446   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2447 }
2448
2449 static void vl_api_vnet_interface_simple_counters_t_handler
2450   (vl_api_vnet_interface_simple_counters_t * mp)
2451 {
2452   /* not supported */
2453 }
2454
2455 static void vl_api_vnet_interface_combined_counters_t_handler
2456   (vl_api_vnet_interface_combined_counters_t * mp)
2457 {
2458   /* not supported */
2459 }
2460
2461 static void vl_api_vnet_interface_simple_counters_t_handler_json
2462   (vl_api_vnet_interface_simple_counters_t * mp)
2463 {
2464   u64 *v_packets;
2465   u64 packets;
2466   u32 count;
2467   u32 first_sw_if_index;
2468   int i;
2469
2470   count = ntohl (mp->count);
2471   first_sw_if_index = ntohl (mp->first_sw_if_index);
2472
2473   v_packets = (u64 *) & mp->data;
2474   for (i = 0; i < count; i++)
2475     {
2476       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2477       set_simple_interface_counter (mp->vnet_counter_type,
2478                                     first_sw_if_index + i, packets);
2479       v_packets++;
2480     }
2481 }
2482
2483 static void vl_api_vnet_interface_combined_counters_t_handler_json
2484   (vl_api_vnet_interface_combined_counters_t * mp)
2485 {
2486   interface_counter_t counter;
2487   vlib_counter_t *v;
2488   u32 first_sw_if_index;
2489   int i;
2490   u32 count;
2491
2492   count = ntohl (mp->count);
2493   first_sw_if_index = ntohl (mp->first_sw_if_index);
2494
2495   v = (vlib_counter_t *) & mp->data;
2496   for (i = 0; i < count; i++)
2497     {
2498       counter.packets =
2499         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2500       counter.bytes =
2501         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2502       set_combined_interface_counter (mp->vnet_counter_type,
2503                                       first_sw_if_index + i, counter);
2504       v++;
2505     }
2506 }
2507
2508 static u32
2509 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2510 {
2511   vat_main_t *vam = &vat_main;
2512   u32 i;
2513
2514   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2515     {
2516       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2517         {
2518           return i;
2519         }
2520     }
2521   return ~0;
2522 }
2523
2524 static u32
2525 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2526 {
2527   vat_main_t *vam = &vat_main;
2528   u32 i;
2529
2530   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2531     {
2532       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2533         {
2534           return i;
2535         }
2536     }
2537   return ~0;
2538 }
2539
2540 static void vl_api_vnet_ip4_fib_counters_t_handler
2541   (vl_api_vnet_ip4_fib_counters_t * mp)
2542 {
2543   /* not supported */
2544 }
2545
2546 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2547   (vl_api_vnet_ip4_fib_counters_t * mp)
2548 {
2549   vat_main_t *vam = &vat_main;
2550   vl_api_ip4_fib_counter_t *v;
2551   ip4_fib_counter_t *counter;
2552   struct in_addr ip4;
2553   u32 vrf_id;
2554   u32 vrf_index;
2555   u32 count;
2556   int i;
2557
2558   vrf_id = ntohl (mp->vrf_id);
2559   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2560   if (~0 == vrf_index)
2561     {
2562       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2563       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2564       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2565       vec_validate (vam->ip4_fib_counters, vrf_index);
2566       vam->ip4_fib_counters[vrf_index] = NULL;
2567     }
2568
2569   vec_free (vam->ip4_fib_counters[vrf_index]);
2570   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2571   count = ntohl (mp->count);
2572   for (i = 0; i < count; i++)
2573     {
2574       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2575       counter = &vam->ip4_fib_counters[vrf_index][i];
2576       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2577       counter->address = ip4;
2578       counter->address_length = v->address_length;
2579       counter->packets = clib_net_to_host_u64 (v->packets);
2580       counter->bytes = clib_net_to_host_u64 (v->bytes);
2581       v++;
2582     }
2583 }
2584
2585 static void vl_api_vnet_ip4_nbr_counters_t_handler
2586   (vl_api_vnet_ip4_nbr_counters_t * mp)
2587 {
2588   /* not supported */
2589 }
2590
2591 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2592   (vl_api_vnet_ip4_nbr_counters_t * mp)
2593 {
2594   vat_main_t *vam = &vat_main;
2595   vl_api_ip4_nbr_counter_t *v;
2596   ip4_nbr_counter_t *counter;
2597   u32 sw_if_index;
2598   u32 count;
2599   int i;
2600
2601   sw_if_index = ntohl (mp->sw_if_index);
2602   count = ntohl (mp->count);
2603   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2604
2605   if (mp->begin)
2606     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2607
2608   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2609   for (i = 0; i < count; i++)
2610     {
2611       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2612       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2613       counter->address.s_addr = v->address;
2614       counter->packets = clib_net_to_host_u64 (v->packets);
2615       counter->bytes = clib_net_to_host_u64 (v->bytes);
2616       counter->linkt = v->link_type;
2617       v++;
2618     }
2619 }
2620
2621 static void vl_api_vnet_ip6_fib_counters_t_handler
2622   (vl_api_vnet_ip6_fib_counters_t * mp)
2623 {
2624   /* not supported */
2625 }
2626
2627 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2628   (vl_api_vnet_ip6_fib_counters_t * mp)
2629 {
2630   vat_main_t *vam = &vat_main;
2631   vl_api_ip6_fib_counter_t *v;
2632   ip6_fib_counter_t *counter;
2633   struct in6_addr ip6;
2634   u32 vrf_id;
2635   u32 vrf_index;
2636   u32 count;
2637   int i;
2638
2639   vrf_id = ntohl (mp->vrf_id);
2640   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2641   if (~0 == vrf_index)
2642     {
2643       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2644       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2645       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2646       vec_validate (vam->ip6_fib_counters, vrf_index);
2647       vam->ip6_fib_counters[vrf_index] = NULL;
2648     }
2649
2650   vec_free (vam->ip6_fib_counters[vrf_index]);
2651   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2652   count = ntohl (mp->count);
2653   for (i = 0; i < count; i++)
2654     {
2655       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2656       counter = &vam->ip6_fib_counters[vrf_index][i];
2657       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2658       counter->address = ip6;
2659       counter->address_length = v->address_length;
2660       counter->packets = clib_net_to_host_u64 (v->packets);
2661       counter->bytes = clib_net_to_host_u64 (v->bytes);
2662       v++;
2663     }
2664 }
2665
2666 static void vl_api_vnet_ip6_nbr_counters_t_handler
2667   (vl_api_vnet_ip6_nbr_counters_t * mp)
2668 {
2669   /* not supported */
2670 }
2671
2672 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2673   (vl_api_vnet_ip6_nbr_counters_t * mp)
2674 {
2675   vat_main_t *vam = &vat_main;
2676   vl_api_ip6_nbr_counter_t *v;
2677   ip6_nbr_counter_t *counter;
2678   struct in6_addr ip6;
2679   u32 sw_if_index;
2680   u32 count;
2681   int i;
2682
2683   sw_if_index = ntohl (mp->sw_if_index);
2684   count = ntohl (mp->count);
2685   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2686
2687   if (mp->begin)
2688     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2689
2690   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2691   for (i = 0; i < count; i++)
2692     {
2693       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2694       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2695       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2696       counter->address = ip6;
2697       counter->packets = clib_net_to_host_u64 (v->packets);
2698       counter->bytes = clib_net_to_host_u64 (v->bytes);
2699       v++;
2700     }
2701 }
2702
2703 static void vl_api_get_first_msg_id_reply_t_handler
2704   (vl_api_get_first_msg_id_reply_t * mp)
2705 {
2706   vat_main_t *vam = &vat_main;
2707   i32 retval = ntohl (mp->retval);
2708
2709   if (vam->async_mode)
2710     {
2711       vam->async_errors += (retval < 0);
2712     }
2713   else
2714     {
2715       vam->retval = retval;
2716       vam->result_ready = 1;
2717     }
2718   if (retval >= 0)
2719     {
2720       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2721     }
2722 }
2723
2724 static void vl_api_get_first_msg_id_reply_t_handler_json
2725   (vl_api_get_first_msg_id_reply_t * mp)
2726 {
2727   vat_main_t *vam = &vat_main;
2728   vat_json_node_t node;
2729
2730   vat_json_init_object (&node);
2731   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2732   vat_json_object_add_uint (&node, "first_msg_id",
2733                             (uint) ntohs (mp->first_msg_id));
2734
2735   vat_json_print (vam->ofp, &node);
2736   vat_json_free (&node);
2737
2738   vam->retval = ntohl (mp->retval);
2739   vam->result_ready = 1;
2740 }
2741
2742 static void vl_api_get_node_graph_reply_t_handler
2743   (vl_api_get_node_graph_reply_t * mp)
2744 {
2745   vat_main_t *vam = &vat_main;
2746   api_main_t *am = &api_main;
2747   i32 retval = ntohl (mp->retval);
2748   u8 *pvt_copy, *reply;
2749   void *oldheap;
2750   vlib_node_t *node;
2751   int i;
2752
2753   if (vam->async_mode)
2754     {
2755       vam->async_errors += (retval < 0);
2756     }
2757   else
2758     {
2759       vam->retval = retval;
2760       vam->result_ready = 1;
2761     }
2762
2763   /* "Should never happen..." */
2764   if (retval != 0)
2765     return;
2766
2767   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2768   pvt_copy = vec_dup (reply);
2769
2770   /* Toss the shared-memory original... */
2771   pthread_mutex_lock (&am->vlib_rp->mutex);
2772   oldheap = svm_push_data_heap (am->vlib_rp);
2773
2774   vec_free (reply);
2775
2776   svm_pop_heap (oldheap);
2777   pthread_mutex_unlock (&am->vlib_rp->mutex);
2778
2779   if (vam->graph_nodes)
2780     {
2781       hash_free (vam->graph_node_index_by_name);
2782
2783       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2784         {
2785           node = vam->graph_nodes[i];
2786           vec_free (node->name);
2787           vec_free (node->next_nodes);
2788           vec_free (node);
2789         }
2790       vec_free (vam->graph_nodes);
2791     }
2792
2793   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2794   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2795   vec_free (pvt_copy);
2796
2797   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2798     {
2799       node = vam->graph_nodes[i];
2800       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2801     }
2802 }
2803
2804 static void vl_api_get_node_graph_reply_t_handler_json
2805   (vl_api_get_node_graph_reply_t * mp)
2806 {
2807   vat_main_t *vam = &vat_main;
2808   api_main_t *am = &api_main;
2809   void *oldheap;
2810   vat_json_node_t node;
2811   u8 *reply;
2812
2813   /* $$$$ make this real? */
2814   vat_json_init_object (&node);
2815   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2816   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2817
2818   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2819
2820   /* Toss the shared-memory original... */
2821   pthread_mutex_lock (&am->vlib_rp->mutex);
2822   oldheap = svm_push_data_heap (am->vlib_rp);
2823
2824   vec_free (reply);
2825
2826   svm_pop_heap (oldheap);
2827   pthread_mutex_unlock (&am->vlib_rp->mutex);
2828
2829   vat_json_print (vam->ofp, &node);
2830   vat_json_free (&node);
2831
2832   vam->retval = ntohl (mp->retval);
2833   vam->result_ready = 1;
2834 }
2835
2836 static void
2837 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2838 {
2839   vat_main_t *vam = &vat_main;
2840   u8 *s = 0;
2841
2842   if (mp->local)
2843     {
2844       s = format (s, "%=16d%=16d%=16d",
2845                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2846     }
2847   else
2848     {
2849       s = format (s, "%=16U%=16d%=16d",
2850                   mp->is_ipv6 ? format_ip6_address :
2851                   format_ip4_address,
2852                   mp->ip_address, mp->priority, mp->weight);
2853     }
2854
2855   print (vam->ofp, "%v", s);
2856   vec_free (s);
2857 }
2858
2859 static void
2860 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2861 {
2862   vat_main_t *vam = &vat_main;
2863   vat_json_node_t *node = NULL;
2864   struct in6_addr ip6;
2865   struct in_addr ip4;
2866
2867   if (VAT_JSON_ARRAY != vam->json_tree.type)
2868     {
2869       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2870       vat_json_init_array (&vam->json_tree);
2871     }
2872   node = vat_json_array_add (&vam->json_tree);
2873   vat_json_init_object (node);
2874
2875   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2876   vat_json_object_add_uint (node, "priority", mp->priority);
2877   vat_json_object_add_uint (node, "weight", mp->weight);
2878
2879   if (mp->local)
2880     vat_json_object_add_uint (node, "sw_if_index",
2881                               clib_net_to_host_u32 (mp->sw_if_index));
2882   else
2883     {
2884       if (mp->is_ipv6)
2885         {
2886           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2887           vat_json_object_add_ip6 (node, "address", ip6);
2888         }
2889       else
2890         {
2891           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2892           vat_json_object_add_ip4 (node, "address", ip4);
2893         }
2894     }
2895 }
2896
2897 static void
2898 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2899                                           mp)
2900 {
2901   vat_main_t *vam = &vat_main;
2902   u8 *ls_name = 0;
2903
2904   ls_name = format (0, "%s", mp->ls_name);
2905
2906   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2907          ls_name);
2908   vec_free (ls_name);
2909 }
2910
2911 static void
2912   vl_api_one_locator_set_details_t_handler_json
2913   (vl_api_one_locator_set_details_t * mp)
2914 {
2915   vat_main_t *vam = &vat_main;
2916   vat_json_node_t *node = 0;
2917   u8 *ls_name = 0;
2918
2919   ls_name = format (0, "%s", mp->ls_name);
2920   vec_add1 (ls_name, 0);
2921
2922   if (VAT_JSON_ARRAY != vam->json_tree.type)
2923     {
2924       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2925       vat_json_init_array (&vam->json_tree);
2926     }
2927   node = vat_json_array_add (&vam->json_tree);
2928
2929   vat_json_init_object (node);
2930   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2931   vat_json_object_add_uint (node, "ls_index",
2932                             clib_net_to_host_u32 (mp->ls_index));
2933   vec_free (ls_name);
2934 }
2935
2936 typedef struct
2937 {
2938   u32 spi;
2939   u8 si;
2940 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2941
2942 uword
2943 unformat_nsh_address (unformat_input_t * input, va_list * args)
2944 {
2945   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2946   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2947 }
2948
2949 u8 *
2950 format_nsh_address_vat (u8 * s, va_list * args)
2951 {
2952   nsh_t *a = va_arg (*args, nsh_t *);
2953   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2954 }
2955
2956 static u8 *
2957 format_lisp_flat_eid (u8 * s, va_list * args)
2958 {
2959   u32 type = va_arg (*args, u32);
2960   u8 *eid = va_arg (*args, u8 *);
2961   u32 eid_len = va_arg (*args, u32);
2962
2963   switch (type)
2964     {
2965     case 0:
2966       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2967     case 1:
2968       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2969     case 2:
2970       return format (s, "%U", format_ethernet_address, eid);
2971     case 3:
2972       return format (s, "%U", format_nsh_address_vat, eid);
2973     }
2974   return 0;
2975 }
2976
2977 static u8 *
2978 format_lisp_eid_vat (u8 * s, va_list * args)
2979 {
2980   u32 type = va_arg (*args, u32);
2981   u8 *eid = va_arg (*args, u8 *);
2982   u32 eid_len = va_arg (*args, u32);
2983   u8 *seid = va_arg (*args, u8 *);
2984   u32 seid_len = va_arg (*args, u32);
2985   u32 is_src_dst = va_arg (*args, u32);
2986
2987   if (is_src_dst)
2988     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2989
2990   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2991
2992   return s;
2993 }
2994
2995 static void
2996 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2997 {
2998   vat_main_t *vam = &vat_main;
2999   u8 *s = 0, *eid = 0;
3000
3001   if (~0 == mp->locator_set_index)
3002     s = format (0, "action: %d", mp->action);
3003   else
3004     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
3005
3006   eid = format (0, "%U", format_lisp_eid_vat,
3007                 mp->eid_type,
3008                 mp->eid,
3009                 mp->eid_prefix_len,
3010                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3011   vec_add1 (eid, 0);
3012
3013   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
3014          clib_net_to_host_u32 (mp->vni),
3015          eid,
3016          mp->is_local ? "local" : "remote",
3017          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
3018          clib_net_to_host_u16 (mp->key_id), mp->key);
3019
3020   vec_free (s);
3021   vec_free (eid);
3022 }
3023
3024 static void
3025 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
3026                                              * mp)
3027 {
3028   vat_main_t *vam = &vat_main;
3029   vat_json_node_t *node = 0;
3030   u8 *eid = 0;
3031
3032   if (VAT_JSON_ARRAY != vam->json_tree.type)
3033     {
3034       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3035       vat_json_init_array (&vam->json_tree);
3036     }
3037   node = vat_json_array_add (&vam->json_tree);
3038
3039   vat_json_init_object (node);
3040   if (~0 == mp->locator_set_index)
3041     vat_json_object_add_uint (node, "action", mp->action);
3042   else
3043     vat_json_object_add_uint (node, "locator_set_index",
3044                               clib_net_to_host_u32 (mp->locator_set_index));
3045
3046   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3047   if (mp->eid_type == 3)
3048     {
3049       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3050       vat_json_init_object (nsh_json);
3051       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3052       vat_json_object_add_uint (nsh_json, "spi",
3053                                 clib_net_to_host_u32 (nsh->spi));
3054       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3055     }
3056   else
3057     {
3058       eid = format (0, "%U", format_lisp_eid_vat,
3059                     mp->eid_type,
3060                     mp->eid,
3061                     mp->eid_prefix_len,
3062                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3063       vec_add1 (eid, 0);
3064       vat_json_object_add_string_copy (node, "eid", eid);
3065       vec_free (eid);
3066     }
3067   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3068   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3069   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3070
3071   if (mp->key_id)
3072     {
3073       vat_json_object_add_uint (node, "key_id",
3074                                 clib_net_to_host_u16 (mp->key_id));
3075       vat_json_object_add_string_copy (node, "key", mp->key);
3076     }
3077 }
3078
3079 static void
3080 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3081 {
3082   vat_main_t *vam = &vat_main;
3083   u8 *seid = 0, *deid = 0;
3084   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3085
3086   deid = format (0, "%U", format_lisp_eid_vat,
3087                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3088
3089   seid = format (0, "%U", format_lisp_eid_vat,
3090                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3091
3092   vec_add1 (deid, 0);
3093   vec_add1 (seid, 0);
3094
3095   if (mp->is_ip4)
3096     format_ip_address_fcn = format_ip4_address;
3097   else
3098     format_ip_address_fcn = format_ip6_address;
3099
3100
3101   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3102          clib_net_to_host_u32 (mp->vni),
3103          seid, deid,
3104          format_ip_address_fcn, mp->lloc,
3105          format_ip_address_fcn, mp->rloc,
3106          clib_net_to_host_u32 (mp->pkt_count),
3107          clib_net_to_host_u32 (mp->bytes));
3108
3109   vec_free (deid);
3110   vec_free (seid);
3111 }
3112
3113 static void
3114 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3115 {
3116   struct in6_addr ip6;
3117   struct in_addr ip4;
3118   vat_main_t *vam = &vat_main;
3119   vat_json_node_t *node = 0;
3120   u8 *deid = 0, *seid = 0;
3121
3122   if (VAT_JSON_ARRAY != vam->json_tree.type)
3123     {
3124       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3125       vat_json_init_array (&vam->json_tree);
3126     }
3127   node = vat_json_array_add (&vam->json_tree);
3128
3129   vat_json_init_object (node);
3130   deid = format (0, "%U", format_lisp_eid_vat,
3131                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3132
3133   seid = format (0, "%U", format_lisp_eid_vat,
3134                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3135
3136   vec_add1 (deid, 0);
3137   vec_add1 (seid, 0);
3138
3139   vat_json_object_add_string_copy (node, "seid", seid);
3140   vat_json_object_add_string_copy (node, "deid", deid);
3141   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3142
3143   if (mp->is_ip4)
3144     {
3145       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3146       vat_json_object_add_ip4 (node, "lloc", ip4);
3147       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3148       vat_json_object_add_ip4 (node, "rloc", ip4);
3149     }
3150   else
3151     {
3152       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3153       vat_json_object_add_ip6 (node, "lloc", ip6);
3154       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3155       vat_json_object_add_ip6 (node, "rloc", ip6);
3156     }
3157   vat_json_object_add_uint (node, "pkt_count",
3158                             clib_net_to_host_u32 (mp->pkt_count));
3159   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3160
3161   vec_free (deid);
3162   vec_free (seid);
3163 }
3164
3165 static void
3166   vl_api_one_eid_table_map_details_t_handler
3167   (vl_api_one_eid_table_map_details_t * mp)
3168 {
3169   vat_main_t *vam = &vat_main;
3170
3171   u8 *line = format (0, "%=10d%=10d",
3172                      clib_net_to_host_u32 (mp->vni),
3173                      clib_net_to_host_u32 (mp->dp_table));
3174   print (vam->ofp, "%v", line);
3175   vec_free (line);
3176 }
3177
3178 static void
3179   vl_api_one_eid_table_map_details_t_handler_json
3180   (vl_api_one_eid_table_map_details_t * mp)
3181 {
3182   vat_main_t *vam = &vat_main;
3183   vat_json_node_t *node = NULL;
3184
3185   if (VAT_JSON_ARRAY != vam->json_tree.type)
3186     {
3187       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3188       vat_json_init_array (&vam->json_tree);
3189     }
3190   node = vat_json_array_add (&vam->json_tree);
3191   vat_json_init_object (node);
3192   vat_json_object_add_uint (node, "dp_table",
3193                             clib_net_to_host_u32 (mp->dp_table));
3194   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3195 }
3196
3197 static void
3198   vl_api_one_eid_table_vni_details_t_handler
3199   (vl_api_one_eid_table_vni_details_t * mp)
3200 {
3201   vat_main_t *vam = &vat_main;
3202
3203   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3204   print (vam->ofp, "%v", line);
3205   vec_free (line);
3206 }
3207
3208 static void
3209   vl_api_one_eid_table_vni_details_t_handler_json
3210   (vl_api_one_eid_table_vni_details_t * mp)
3211 {
3212   vat_main_t *vam = &vat_main;
3213   vat_json_node_t *node = NULL;
3214
3215   if (VAT_JSON_ARRAY != vam->json_tree.type)
3216     {
3217       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3218       vat_json_init_array (&vam->json_tree);
3219     }
3220   node = vat_json_array_add (&vam->json_tree);
3221   vat_json_init_object (node);
3222   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3223 }
3224
3225 static void
3226   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3227   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3228 {
3229   vat_main_t *vam = &vat_main;
3230   int retval = clib_net_to_host_u32 (mp->retval);
3231
3232   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3233   print (vam->ofp, "fallback threshold value: %d", mp->value);
3234
3235   vam->retval = retval;
3236   vam->result_ready = 1;
3237 }
3238
3239 static void
3240   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3241   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3242 {
3243   vat_main_t *vam = &vat_main;
3244   vat_json_node_t _node, *node = &_node;
3245   int retval = clib_net_to_host_u32 (mp->retval);
3246
3247   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3248   vat_json_init_object (node);
3249   vat_json_object_add_uint (node, "value", mp->value);
3250
3251   vat_json_print (vam->ofp, node);
3252   vat_json_free (node);
3253
3254   vam->retval = retval;
3255   vam->result_ready = 1;
3256 }
3257
3258 static void
3259   vl_api_show_one_map_register_state_reply_t_handler
3260   (vl_api_show_one_map_register_state_reply_t * mp)
3261 {
3262   vat_main_t *vam = &vat_main;
3263   int retval = clib_net_to_host_u32 (mp->retval);
3264
3265   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3266
3267   vam->retval = retval;
3268   vam->result_ready = 1;
3269 }
3270
3271 static void
3272   vl_api_show_one_map_register_state_reply_t_handler_json
3273   (vl_api_show_one_map_register_state_reply_t * mp)
3274 {
3275   vat_main_t *vam = &vat_main;
3276   vat_json_node_t _node, *node = &_node;
3277   int retval = clib_net_to_host_u32 (mp->retval);
3278
3279   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3280
3281   vat_json_init_object (node);
3282   vat_json_object_add_string_copy (node, "state", s);
3283
3284   vat_json_print (vam->ofp, node);
3285   vat_json_free (node);
3286
3287   vam->retval = retval;
3288   vam->result_ready = 1;
3289   vec_free (s);
3290 }
3291
3292 static void
3293   vl_api_show_one_rloc_probe_state_reply_t_handler
3294   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3295 {
3296   vat_main_t *vam = &vat_main;
3297   int retval = clib_net_to_host_u32 (mp->retval);
3298
3299   if (retval)
3300     goto end;
3301
3302   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3303 end:
3304   vam->retval = retval;
3305   vam->result_ready = 1;
3306 }
3307
3308 static void
3309   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3310   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3311 {
3312   vat_main_t *vam = &vat_main;
3313   vat_json_node_t _node, *node = &_node;
3314   int retval = clib_net_to_host_u32 (mp->retval);
3315
3316   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3317   vat_json_init_object (node);
3318   vat_json_object_add_string_copy (node, "state", s);
3319
3320   vat_json_print (vam->ofp, node);
3321   vat_json_free (node);
3322
3323   vam->retval = retval;
3324   vam->result_ready = 1;
3325   vec_free (s);
3326 }
3327
3328 static void
3329   vl_api_show_one_stats_enable_disable_reply_t_handler
3330   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3331 {
3332   vat_main_t *vam = &vat_main;
3333   int retval = clib_net_to_host_u32 (mp->retval);
3334
3335   if (retval)
3336     goto end;
3337
3338   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3339 end:
3340   vam->retval = retval;
3341   vam->result_ready = 1;
3342 }
3343
3344 static void
3345   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3346   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3347 {
3348   vat_main_t *vam = &vat_main;
3349   vat_json_node_t _node, *node = &_node;
3350   int retval = clib_net_to_host_u32 (mp->retval);
3351
3352   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3353   vat_json_init_object (node);
3354   vat_json_object_add_string_copy (node, "state", s);
3355
3356   vat_json_print (vam->ofp, node);
3357   vat_json_free (node);
3358
3359   vam->retval = retval;
3360   vam->result_ready = 1;
3361   vec_free (s);
3362 }
3363
3364 static void
3365 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3366 {
3367   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3368   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3369   e->vni = clib_net_to_host_u32 (e->vni);
3370 }
3371
3372 static void
3373   gpe_fwd_entries_get_reply_t_net_to_host
3374   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3375 {
3376   u32 i;
3377
3378   mp->count = clib_net_to_host_u32 (mp->count);
3379   for (i = 0; i < mp->count; i++)
3380     {
3381       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3382     }
3383 }
3384
3385 static u8 *
3386 format_gpe_encap_mode (u8 * s, va_list * args)
3387 {
3388   u32 mode = va_arg (*args, u32);
3389
3390   switch (mode)
3391     {
3392     case 0:
3393       return format (s, "lisp");
3394     case 1:
3395       return format (s, "vxlan");
3396     }
3397   return 0;
3398 }
3399
3400 static void
3401   vl_api_gpe_get_encap_mode_reply_t_handler
3402   (vl_api_gpe_get_encap_mode_reply_t * mp)
3403 {
3404   vat_main_t *vam = &vat_main;
3405
3406   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3407   vam->retval = ntohl (mp->retval);
3408   vam->result_ready = 1;
3409 }
3410
3411 static void
3412   vl_api_gpe_get_encap_mode_reply_t_handler_json
3413   (vl_api_gpe_get_encap_mode_reply_t * mp)
3414 {
3415   vat_main_t *vam = &vat_main;
3416   vat_json_node_t node;
3417
3418   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3419   vec_add1 (encap_mode, 0);
3420
3421   vat_json_init_object (&node);
3422   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3423
3424   vec_free (encap_mode);
3425   vat_json_print (vam->ofp, &node);
3426   vat_json_free (&node);
3427
3428   vam->retval = ntohl (mp->retval);
3429   vam->result_ready = 1;
3430 }
3431
3432 static void
3433   vl_api_gpe_fwd_entry_path_details_t_handler
3434   (vl_api_gpe_fwd_entry_path_details_t * mp)
3435 {
3436   vat_main_t *vam = &vat_main;
3437   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3438
3439   if (mp->lcl_loc.is_ip4)
3440     format_ip_address_fcn = format_ip4_address;
3441   else
3442     format_ip_address_fcn = format_ip6_address;
3443
3444   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3445          format_ip_address_fcn, &mp->lcl_loc,
3446          format_ip_address_fcn, &mp->rmt_loc);
3447 }
3448
3449 static void
3450 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3451 {
3452   struct in6_addr ip6;
3453   struct in_addr ip4;
3454
3455   if (loc->is_ip4)
3456     {
3457       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3458       vat_json_object_add_ip4 (n, "address", ip4);
3459     }
3460   else
3461     {
3462       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3463       vat_json_object_add_ip6 (n, "address", ip6);
3464     }
3465   vat_json_object_add_uint (n, "weight", loc->weight);
3466 }
3467
3468 static void
3469   vl_api_gpe_fwd_entry_path_details_t_handler_json
3470   (vl_api_gpe_fwd_entry_path_details_t * mp)
3471 {
3472   vat_main_t *vam = &vat_main;
3473   vat_json_node_t *node = NULL;
3474   vat_json_node_t *loc_node;
3475
3476   if (VAT_JSON_ARRAY != vam->json_tree.type)
3477     {
3478       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3479       vat_json_init_array (&vam->json_tree);
3480     }
3481   node = vat_json_array_add (&vam->json_tree);
3482   vat_json_init_object (node);
3483
3484   loc_node = vat_json_object_add (node, "local_locator");
3485   vat_json_init_object (loc_node);
3486   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3487
3488   loc_node = vat_json_object_add (node, "remote_locator");
3489   vat_json_init_object (loc_node);
3490   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3491 }
3492
3493 static void
3494   vl_api_gpe_fwd_entries_get_reply_t_handler
3495   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3496 {
3497   vat_main_t *vam = &vat_main;
3498   u32 i;
3499   int retval = clib_net_to_host_u32 (mp->retval);
3500   vl_api_gpe_fwd_entry_t *e;
3501
3502   if (retval)
3503     goto end;
3504
3505   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3506
3507   for (i = 0; i < mp->count; i++)
3508     {
3509       e = &mp->entries[i];
3510       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3511              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3512              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3513     }
3514
3515 end:
3516   vam->retval = retval;
3517   vam->result_ready = 1;
3518 }
3519
3520 static void
3521   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3522   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3523 {
3524   u8 *s = 0;
3525   vat_main_t *vam = &vat_main;
3526   vat_json_node_t *e = 0, root;
3527   u32 i;
3528   int retval = clib_net_to_host_u32 (mp->retval);
3529   vl_api_gpe_fwd_entry_t *fwd;
3530
3531   if (retval)
3532     goto end;
3533
3534   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3535   vat_json_init_array (&root);
3536
3537   for (i = 0; i < mp->count; i++)
3538     {
3539       e = vat_json_array_add (&root);
3540       fwd = &mp->entries[i];
3541
3542       vat_json_init_object (e);
3543       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3544       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3545       vat_json_object_add_int (e, "vni", fwd->vni);
3546       vat_json_object_add_int (e, "action", fwd->action);
3547
3548       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3549                   fwd->leid_prefix_len);
3550       vec_add1 (s, 0);
3551       vat_json_object_add_string_copy (e, "leid", s);
3552       vec_free (s);
3553
3554       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3555                   fwd->reid_prefix_len);
3556       vec_add1 (s, 0);
3557       vat_json_object_add_string_copy (e, "reid", s);
3558       vec_free (s);
3559     }
3560
3561   vat_json_print (vam->ofp, &root);
3562   vat_json_free (&root);
3563
3564 end:
3565   vam->retval = retval;
3566   vam->result_ready = 1;
3567 }
3568
3569 static void
3570   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3571   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3572 {
3573   vat_main_t *vam = &vat_main;
3574   u32 i, n;
3575   int retval = clib_net_to_host_u32 (mp->retval);
3576   vl_api_gpe_native_fwd_rpath_t *r;
3577
3578   if (retval)
3579     goto end;
3580
3581   n = clib_net_to_host_u32 (mp->count);
3582
3583   for (i = 0; i < n; i++)
3584     {
3585       r = &mp->entries[i];
3586       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3587              clib_net_to_host_u32 (r->fib_index),
3588              clib_net_to_host_u32 (r->nh_sw_if_index),
3589              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3590     }
3591
3592 end:
3593   vam->retval = retval;
3594   vam->result_ready = 1;
3595 }
3596
3597 static void
3598   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3599   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3600 {
3601   vat_main_t *vam = &vat_main;
3602   vat_json_node_t root, *e;
3603   u32 i, n;
3604   int retval = clib_net_to_host_u32 (mp->retval);
3605   vl_api_gpe_native_fwd_rpath_t *r;
3606   u8 *s;
3607
3608   if (retval)
3609     goto end;
3610
3611   n = clib_net_to_host_u32 (mp->count);
3612   vat_json_init_array (&root);
3613
3614   for (i = 0; i < n; i++)
3615     {
3616       e = vat_json_array_add (&root);
3617       vat_json_init_object (e);
3618       r = &mp->entries[i];
3619       s =
3620         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3621                 r->nh_addr);
3622       vec_add1 (s, 0);
3623       vat_json_object_add_string_copy (e, "ip4", s);
3624       vec_free (s);
3625
3626       vat_json_object_add_uint (e, "fib_index",
3627                                 clib_net_to_host_u32 (r->fib_index));
3628       vat_json_object_add_uint (e, "nh_sw_if_index",
3629                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3630     }
3631
3632   vat_json_print (vam->ofp, &root);
3633   vat_json_free (&root);
3634
3635 end:
3636   vam->retval = retval;
3637   vam->result_ready = 1;
3638 }
3639
3640 static void
3641   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3642   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3643 {
3644   vat_main_t *vam = &vat_main;
3645   u32 i, n;
3646   int retval = clib_net_to_host_u32 (mp->retval);
3647
3648   if (retval)
3649     goto end;
3650
3651   n = clib_net_to_host_u32 (mp->count);
3652
3653   for (i = 0; i < n; i++)
3654     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3655
3656 end:
3657   vam->retval = retval;
3658   vam->result_ready = 1;
3659 }
3660
3661 static void
3662   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3663   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3664 {
3665   vat_main_t *vam = &vat_main;
3666   vat_json_node_t root;
3667   u32 i, n;
3668   int retval = clib_net_to_host_u32 (mp->retval);
3669
3670   if (retval)
3671     goto end;
3672
3673   n = clib_net_to_host_u32 (mp->count);
3674   vat_json_init_array (&root);
3675
3676   for (i = 0; i < n; i++)
3677     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3678
3679   vat_json_print (vam->ofp, &root);
3680   vat_json_free (&root);
3681
3682 end:
3683   vam->retval = retval;
3684   vam->result_ready = 1;
3685 }
3686
3687 static void
3688   vl_api_one_ndp_entries_get_reply_t_handler
3689   (vl_api_one_ndp_entries_get_reply_t * mp)
3690 {
3691   vat_main_t *vam = &vat_main;
3692   u32 i, n;
3693   int retval = clib_net_to_host_u32 (mp->retval);
3694
3695   if (retval)
3696     goto end;
3697
3698   n = clib_net_to_host_u32 (mp->count);
3699
3700   for (i = 0; i < n; i++)
3701     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3702            format_ethernet_address, mp->entries[i].mac);
3703
3704 end:
3705   vam->retval = retval;
3706   vam->result_ready = 1;
3707 }
3708
3709 static void
3710   vl_api_one_ndp_entries_get_reply_t_handler_json
3711   (vl_api_one_ndp_entries_get_reply_t * mp)
3712 {
3713   u8 *s = 0;
3714   vat_main_t *vam = &vat_main;
3715   vat_json_node_t *e = 0, root;
3716   u32 i, n;
3717   int retval = clib_net_to_host_u32 (mp->retval);
3718   vl_api_one_ndp_entry_t *arp_entry;
3719
3720   if (retval)
3721     goto end;
3722
3723   n = clib_net_to_host_u32 (mp->count);
3724   vat_json_init_array (&root);
3725
3726   for (i = 0; i < n; i++)
3727     {
3728       e = vat_json_array_add (&root);
3729       arp_entry = &mp->entries[i];
3730
3731       vat_json_init_object (e);
3732       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3733       vec_add1 (s, 0);
3734
3735       vat_json_object_add_string_copy (e, "mac", s);
3736       vec_free (s);
3737
3738       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3739       vec_add1 (s, 0);
3740       vat_json_object_add_string_copy (e, "ip6", s);
3741       vec_free (s);
3742     }
3743
3744   vat_json_print (vam->ofp, &root);
3745   vat_json_free (&root);
3746
3747 end:
3748   vam->retval = retval;
3749   vam->result_ready = 1;
3750 }
3751
3752 static void
3753   vl_api_one_l2_arp_entries_get_reply_t_handler
3754   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3755 {
3756   vat_main_t *vam = &vat_main;
3757   u32 i, n;
3758   int retval = clib_net_to_host_u32 (mp->retval);
3759
3760   if (retval)
3761     goto end;
3762
3763   n = clib_net_to_host_u32 (mp->count);
3764
3765   for (i = 0; i < n; i++)
3766     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3767            format_ethernet_address, mp->entries[i].mac);
3768
3769 end:
3770   vam->retval = retval;
3771   vam->result_ready = 1;
3772 }
3773
3774 static void
3775   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3776   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3777 {
3778   u8 *s = 0;
3779   vat_main_t *vam = &vat_main;
3780   vat_json_node_t *e = 0, root;
3781   u32 i, n;
3782   int retval = clib_net_to_host_u32 (mp->retval);
3783   vl_api_one_l2_arp_entry_t *arp_entry;
3784
3785   if (retval)
3786     goto end;
3787
3788   n = clib_net_to_host_u32 (mp->count);
3789   vat_json_init_array (&root);
3790
3791   for (i = 0; i < n; i++)
3792     {
3793       e = vat_json_array_add (&root);
3794       arp_entry = &mp->entries[i];
3795
3796       vat_json_init_object (e);
3797       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3798       vec_add1 (s, 0);
3799
3800       vat_json_object_add_string_copy (e, "mac", s);
3801       vec_free (s);
3802
3803       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3804       vec_add1 (s, 0);
3805       vat_json_object_add_string_copy (e, "ip4", s);
3806       vec_free (s);
3807     }
3808
3809   vat_json_print (vam->ofp, &root);
3810   vat_json_free (&root);
3811
3812 end:
3813   vam->retval = retval;
3814   vam->result_ready = 1;
3815 }
3816
3817 static void
3818 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3819 {
3820   vat_main_t *vam = &vat_main;
3821   u32 i, n;
3822   int retval = clib_net_to_host_u32 (mp->retval);
3823
3824   if (retval)
3825     goto end;
3826
3827   n = clib_net_to_host_u32 (mp->count);
3828
3829   for (i = 0; i < n; i++)
3830     {
3831       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3832     }
3833
3834 end:
3835   vam->retval = retval;
3836   vam->result_ready = 1;
3837 }
3838
3839 static void
3840   vl_api_one_ndp_bd_get_reply_t_handler_json
3841   (vl_api_one_ndp_bd_get_reply_t * mp)
3842 {
3843   vat_main_t *vam = &vat_main;
3844   vat_json_node_t root;
3845   u32 i, n;
3846   int retval = clib_net_to_host_u32 (mp->retval);
3847
3848   if (retval)
3849     goto end;
3850
3851   n = clib_net_to_host_u32 (mp->count);
3852   vat_json_init_array (&root);
3853
3854   for (i = 0; i < n; i++)
3855     {
3856       vat_json_array_add_uint (&root,
3857                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3858     }
3859
3860   vat_json_print (vam->ofp, &root);
3861   vat_json_free (&root);
3862
3863 end:
3864   vam->retval = retval;
3865   vam->result_ready = 1;
3866 }
3867
3868 static void
3869   vl_api_one_l2_arp_bd_get_reply_t_handler
3870   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3871 {
3872   vat_main_t *vam = &vat_main;
3873   u32 i, n;
3874   int retval = clib_net_to_host_u32 (mp->retval);
3875
3876   if (retval)
3877     goto end;
3878
3879   n = clib_net_to_host_u32 (mp->count);
3880
3881   for (i = 0; i < n; i++)
3882     {
3883       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3884     }
3885
3886 end:
3887   vam->retval = retval;
3888   vam->result_ready = 1;
3889 }
3890
3891 static void
3892   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3893   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3894 {
3895   vat_main_t *vam = &vat_main;
3896   vat_json_node_t root;
3897   u32 i, n;
3898   int retval = clib_net_to_host_u32 (mp->retval);
3899
3900   if (retval)
3901     goto end;
3902
3903   n = clib_net_to_host_u32 (mp->count);
3904   vat_json_init_array (&root);
3905
3906   for (i = 0; i < n; i++)
3907     {
3908       vat_json_array_add_uint (&root,
3909                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3910     }
3911
3912   vat_json_print (vam->ofp, &root);
3913   vat_json_free (&root);
3914
3915 end:
3916   vam->retval = retval;
3917   vam->result_ready = 1;
3918 }
3919
3920 static void
3921   vl_api_one_adjacencies_get_reply_t_handler
3922   (vl_api_one_adjacencies_get_reply_t * mp)
3923 {
3924   vat_main_t *vam = &vat_main;
3925   u32 i, n;
3926   int retval = clib_net_to_host_u32 (mp->retval);
3927   vl_api_one_adjacency_t *a;
3928
3929   if (retval)
3930     goto end;
3931
3932   n = clib_net_to_host_u32 (mp->count);
3933
3934   for (i = 0; i < n; i++)
3935     {
3936       a = &mp->adjacencies[i];
3937       print (vam->ofp, "%U %40U",
3938              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3939              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3940     }
3941
3942 end:
3943   vam->retval = retval;
3944   vam->result_ready = 1;
3945 }
3946
3947 static void
3948   vl_api_one_adjacencies_get_reply_t_handler_json
3949   (vl_api_one_adjacencies_get_reply_t * mp)
3950 {
3951   u8 *s = 0;
3952   vat_main_t *vam = &vat_main;
3953   vat_json_node_t *e = 0, root;
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   vat_json_init_array (&root);
3963
3964   for (i = 0; i < n; i++)
3965     {
3966       e = vat_json_array_add (&root);
3967       a = &mp->adjacencies[i];
3968
3969       vat_json_init_object (e);
3970       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3971                   a->leid_prefix_len);
3972       vec_add1 (s, 0);
3973       vat_json_object_add_string_copy (e, "leid", s);
3974       vec_free (s);
3975
3976       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3977                   a->reid_prefix_len);
3978       vec_add1 (s, 0);
3979       vat_json_object_add_string_copy (e, "reid", s);
3980       vec_free (s);
3981     }
3982
3983   vat_json_print (vam->ofp, &root);
3984   vat_json_free (&root);
3985
3986 end:
3987   vam->retval = retval;
3988   vam->result_ready = 1;
3989 }
3990
3991 static void
3992 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3993 {
3994   vat_main_t *vam = &vat_main;
3995
3996   print (vam->ofp, "%=20U",
3997          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3998          mp->ip_address);
3999 }
4000
4001 static void
4002   vl_api_one_map_server_details_t_handler_json
4003   (vl_api_one_map_server_details_t * mp)
4004 {
4005   vat_main_t *vam = &vat_main;
4006   vat_json_node_t *node = NULL;
4007   struct in6_addr ip6;
4008   struct in_addr ip4;
4009
4010   if (VAT_JSON_ARRAY != vam->json_tree.type)
4011     {
4012       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4013       vat_json_init_array (&vam->json_tree);
4014     }
4015   node = vat_json_array_add (&vam->json_tree);
4016
4017   vat_json_init_object (node);
4018   if (mp->is_ipv6)
4019     {
4020       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4021       vat_json_object_add_ip6 (node, "map-server", ip6);
4022     }
4023   else
4024     {
4025       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4026       vat_json_object_add_ip4 (node, "map-server", ip4);
4027     }
4028 }
4029
4030 static void
4031 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4032                                            * mp)
4033 {
4034   vat_main_t *vam = &vat_main;
4035
4036   print (vam->ofp, "%=20U",
4037          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4038          mp->ip_address);
4039 }
4040
4041 static void
4042   vl_api_one_map_resolver_details_t_handler_json
4043   (vl_api_one_map_resolver_details_t * mp)
4044 {
4045   vat_main_t *vam = &vat_main;
4046   vat_json_node_t *node = NULL;
4047   struct in6_addr ip6;
4048   struct in_addr ip4;
4049
4050   if (VAT_JSON_ARRAY != vam->json_tree.type)
4051     {
4052       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4053       vat_json_init_array (&vam->json_tree);
4054     }
4055   node = vat_json_array_add (&vam->json_tree);
4056
4057   vat_json_init_object (node);
4058   if (mp->is_ipv6)
4059     {
4060       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4061       vat_json_object_add_ip6 (node, "map resolver", ip6);
4062     }
4063   else
4064     {
4065       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4066       vat_json_object_add_ip4 (node, "map resolver", ip4);
4067     }
4068 }
4069
4070 static void
4071 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4072 {
4073   vat_main_t *vam = &vat_main;
4074   i32 retval = ntohl (mp->retval);
4075
4076   if (0 <= retval)
4077     {
4078       print (vam->ofp, "feature: %s\ngpe: %s",
4079              mp->feature_status ? "enabled" : "disabled",
4080              mp->gpe_status ? "enabled" : "disabled");
4081     }
4082
4083   vam->retval = retval;
4084   vam->result_ready = 1;
4085 }
4086
4087 static void
4088   vl_api_show_one_status_reply_t_handler_json
4089   (vl_api_show_one_status_reply_t * mp)
4090 {
4091   vat_main_t *vam = &vat_main;
4092   vat_json_node_t node;
4093   u8 *gpe_status = NULL;
4094   u8 *feature_status = NULL;
4095
4096   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4097   feature_status = format (0, "%s",
4098                            mp->feature_status ? "enabled" : "disabled");
4099   vec_add1 (gpe_status, 0);
4100   vec_add1 (feature_status, 0);
4101
4102   vat_json_init_object (&node);
4103   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4104   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4105
4106   vec_free (gpe_status);
4107   vec_free (feature_status);
4108
4109   vat_json_print (vam->ofp, &node);
4110   vat_json_free (&node);
4111
4112   vam->retval = ntohl (mp->retval);
4113   vam->result_ready = 1;
4114 }
4115
4116 static void
4117   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4118   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4119 {
4120   vat_main_t *vam = &vat_main;
4121   i32 retval = ntohl (mp->retval);
4122
4123   if (retval >= 0)
4124     {
4125       print (vam->ofp, "%=20s", mp->locator_set_name);
4126     }
4127
4128   vam->retval = retval;
4129   vam->result_ready = 1;
4130 }
4131
4132 static void
4133   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4134   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4135 {
4136   vat_main_t *vam = &vat_main;
4137   vat_json_node_t *node = NULL;
4138
4139   if (VAT_JSON_ARRAY != vam->json_tree.type)
4140     {
4141       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4142       vat_json_init_array (&vam->json_tree);
4143     }
4144   node = vat_json_array_add (&vam->json_tree);
4145
4146   vat_json_init_object (node);
4147   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4148
4149   vat_json_print (vam->ofp, node);
4150   vat_json_free (node);
4151
4152   vam->retval = ntohl (mp->retval);
4153   vam->result_ready = 1;
4154 }
4155
4156 static u8 *
4157 format_lisp_map_request_mode (u8 * s, va_list * args)
4158 {
4159   u32 mode = va_arg (*args, u32);
4160
4161   switch (mode)
4162     {
4163     case 0:
4164       return format (0, "dst-only");
4165     case 1:
4166       return format (0, "src-dst");
4167     }
4168   return 0;
4169 }
4170
4171 static void
4172   vl_api_show_one_map_request_mode_reply_t_handler
4173   (vl_api_show_one_map_request_mode_reply_t * mp)
4174 {
4175   vat_main_t *vam = &vat_main;
4176   i32 retval = ntohl (mp->retval);
4177
4178   if (0 <= retval)
4179     {
4180       u32 mode = mp->mode;
4181       print (vam->ofp, "map_request_mode: %U",
4182              format_lisp_map_request_mode, mode);
4183     }
4184
4185   vam->retval = retval;
4186   vam->result_ready = 1;
4187 }
4188
4189 static void
4190   vl_api_show_one_map_request_mode_reply_t_handler_json
4191   (vl_api_show_one_map_request_mode_reply_t * mp)
4192 {
4193   vat_main_t *vam = &vat_main;
4194   vat_json_node_t node;
4195   u8 *s = 0;
4196   u32 mode;
4197
4198   mode = mp->mode;
4199   s = format (0, "%U", format_lisp_map_request_mode, mode);
4200   vec_add1 (s, 0);
4201
4202   vat_json_init_object (&node);
4203   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4204   vat_json_print (vam->ofp, &node);
4205   vat_json_free (&node);
4206
4207   vec_free (s);
4208   vam->retval = ntohl (mp->retval);
4209   vam->result_ready = 1;
4210 }
4211
4212 static void
4213   vl_api_show_one_use_petr_reply_t_handler
4214   (vl_api_show_one_use_petr_reply_t * mp)
4215 {
4216   vat_main_t *vam = &vat_main;
4217   i32 retval = ntohl (mp->retval);
4218
4219   if (0 <= retval)
4220     {
4221       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4222       if (mp->status)
4223         {
4224           print (vam->ofp, "Proxy-ETR address; %U",
4225                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4226                  mp->address);
4227         }
4228     }
4229
4230   vam->retval = retval;
4231   vam->result_ready = 1;
4232 }
4233
4234 static void
4235   vl_api_show_one_use_petr_reply_t_handler_json
4236   (vl_api_show_one_use_petr_reply_t * mp)
4237 {
4238   vat_main_t *vam = &vat_main;
4239   vat_json_node_t node;
4240   u8 *status = 0;
4241   struct in_addr ip4;
4242   struct in6_addr ip6;
4243
4244   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4245   vec_add1 (status, 0);
4246
4247   vat_json_init_object (&node);
4248   vat_json_object_add_string_copy (&node, "status", status);
4249   if (mp->status)
4250     {
4251       if (mp->is_ip4)
4252         {
4253           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4254           vat_json_object_add_ip6 (&node, "address", ip6);
4255         }
4256       else
4257         {
4258           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4259           vat_json_object_add_ip4 (&node, "address", ip4);
4260         }
4261     }
4262
4263   vec_free (status);
4264
4265   vat_json_print (vam->ofp, &node);
4266   vat_json_free (&node);
4267
4268   vam->retval = ntohl (mp->retval);
4269   vam->result_ready = 1;
4270 }
4271
4272 static void
4273   vl_api_show_one_nsh_mapping_reply_t_handler
4274   (vl_api_show_one_nsh_mapping_reply_t * mp)
4275 {
4276   vat_main_t *vam = &vat_main;
4277   i32 retval = ntohl (mp->retval);
4278
4279   if (0 <= retval)
4280     {
4281       print (vam->ofp, "%-20s%-16s",
4282              mp->is_set ? "set" : "not-set",
4283              mp->is_set ? (char *) mp->locator_set_name : "");
4284     }
4285
4286   vam->retval = retval;
4287   vam->result_ready = 1;
4288 }
4289
4290 static void
4291   vl_api_show_one_nsh_mapping_reply_t_handler_json
4292   (vl_api_show_one_nsh_mapping_reply_t * mp)
4293 {
4294   vat_main_t *vam = &vat_main;
4295   vat_json_node_t node;
4296   u8 *status = 0;
4297
4298   status = format (0, "%s", mp->is_set ? "yes" : "no");
4299   vec_add1 (status, 0);
4300
4301   vat_json_init_object (&node);
4302   vat_json_object_add_string_copy (&node, "is_set", status);
4303   if (mp->is_set)
4304     {
4305       vat_json_object_add_string_copy (&node, "locator_set",
4306                                        mp->locator_set_name);
4307     }
4308
4309   vec_free (status);
4310
4311   vat_json_print (vam->ofp, &node);
4312   vat_json_free (&node);
4313
4314   vam->retval = ntohl (mp->retval);
4315   vam->result_ready = 1;
4316 }
4317
4318 static void
4319   vl_api_show_one_map_register_ttl_reply_t_handler
4320   (vl_api_show_one_map_register_ttl_reply_t * mp)
4321 {
4322   vat_main_t *vam = &vat_main;
4323   i32 retval = ntohl (mp->retval);
4324
4325   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4326
4327   if (0 <= retval)
4328     {
4329       print (vam->ofp, "ttl: %u", mp->ttl);
4330     }
4331
4332   vam->retval = retval;
4333   vam->result_ready = 1;
4334 }
4335
4336 static void
4337   vl_api_show_one_map_register_ttl_reply_t_handler_json
4338   (vl_api_show_one_map_register_ttl_reply_t * mp)
4339 {
4340   vat_main_t *vam = &vat_main;
4341   vat_json_node_t node;
4342
4343   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4344   vat_json_init_object (&node);
4345   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4346
4347   vat_json_print (vam->ofp, &node);
4348   vat_json_free (&node);
4349
4350   vam->retval = ntohl (mp->retval);
4351   vam->result_ready = 1;
4352 }
4353
4354 static void
4355 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4356 {
4357   vat_main_t *vam = &vat_main;
4358   i32 retval = ntohl (mp->retval);
4359
4360   if (0 <= retval)
4361     {
4362       print (vam->ofp, "%-20s%-16s",
4363              mp->status ? "enabled" : "disabled",
4364              mp->status ? (char *) mp->locator_set_name : "");
4365     }
4366
4367   vam->retval = retval;
4368   vam->result_ready = 1;
4369 }
4370
4371 static void
4372 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4373 {
4374   vat_main_t *vam = &vat_main;
4375   vat_json_node_t node;
4376   u8 *status = 0;
4377
4378   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4379   vec_add1 (status, 0);
4380
4381   vat_json_init_object (&node);
4382   vat_json_object_add_string_copy (&node, "status", status);
4383   if (mp->status)
4384     {
4385       vat_json_object_add_string_copy (&node, "locator_set",
4386                                        mp->locator_set_name);
4387     }
4388
4389   vec_free (status);
4390
4391   vat_json_print (vam->ofp, &node);
4392   vat_json_free (&node);
4393
4394   vam->retval = ntohl (mp->retval);
4395   vam->result_ready = 1;
4396 }
4397
4398 static u8 *
4399 format_policer_type (u8 * s, va_list * va)
4400 {
4401   u32 i = va_arg (*va, u32);
4402
4403   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4404     s = format (s, "1r2c");
4405   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4406     s = format (s, "1r3c");
4407   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4408     s = format (s, "2r3c-2698");
4409   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4410     s = format (s, "2r3c-4115");
4411   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4412     s = format (s, "2r3c-mef5cf1");
4413   else
4414     s = format (s, "ILLEGAL");
4415   return s;
4416 }
4417
4418 static u8 *
4419 format_policer_rate_type (u8 * s, va_list * va)
4420 {
4421   u32 i = va_arg (*va, u32);
4422
4423   if (i == SSE2_QOS_RATE_KBPS)
4424     s = format (s, "kbps");
4425   else if (i == SSE2_QOS_RATE_PPS)
4426     s = format (s, "pps");
4427   else
4428     s = format (s, "ILLEGAL");
4429   return s;
4430 }
4431
4432 static u8 *
4433 format_policer_round_type (u8 * s, va_list * va)
4434 {
4435   u32 i = va_arg (*va, u32);
4436
4437   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4438     s = format (s, "closest");
4439   else if (i == SSE2_QOS_ROUND_TO_UP)
4440     s = format (s, "up");
4441   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4442     s = format (s, "down");
4443   else
4444     s = format (s, "ILLEGAL");
4445   return s;
4446 }
4447
4448 static u8 *
4449 format_policer_action_type (u8 * s, va_list * va)
4450 {
4451   u32 i = va_arg (*va, u32);
4452
4453   if (i == SSE2_QOS_ACTION_DROP)
4454     s = format (s, "drop");
4455   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4456     s = format (s, "transmit");
4457   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4458     s = format (s, "mark-and-transmit");
4459   else
4460     s = format (s, "ILLEGAL");
4461   return s;
4462 }
4463
4464 static u8 *
4465 format_dscp (u8 * s, va_list * va)
4466 {
4467   u32 i = va_arg (*va, u32);
4468   char *t = 0;
4469
4470   switch (i)
4471     {
4472 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4473       foreach_vnet_dscp
4474 #undef _
4475     default:
4476       return format (s, "ILLEGAL");
4477     }
4478   s = format (s, "%s", t);
4479   return s;
4480 }
4481
4482 static void
4483 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4484 {
4485   vat_main_t *vam = &vat_main;
4486   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4487
4488   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4489     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4490   else
4491     conform_dscp_str = format (0, "");
4492
4493   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4494     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4495   else
4496     exceed_dscp_str = format (0, "");
4497
4498   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4499     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4500   else
4501     violate_dscp_str = format (0, "");
4502
4503   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4504          "rate type %U, round type %U, %s rate, %s color-aware, "
4505          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4506          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4507          "conform action %U%s, exceed action %U%s, violate action %U%s",
4508          mp->name,
4509          format_policer_type, mp->type,
4510          ntohl (mp->cir),
4511          ntohl (mp->eir),
4512          clib_net_to_host_u64 (mp->cb),
4513          clib_net_to_host_u64 (mp->eb),
4514          format_policer_rate_type, mp->rate_type,
4515          format_policer_round_type, mp->round_type,
4516          mp->single_rate ? "single" : "dual",
4517          mp->color_aware ? "is" : "not",
4518          ntohl (mp->cir_tokens_per_period),
4519          ntohl (mp->pir_tokens_per_period),
4520          ntohl (mp->scale),
4521          ntohl (mp->current_limit),
4522          ntohl (mp->current_bucket),
4523          ntohl (mp->extended_limit),
4524          ntohl (mp->extended_bucket),
4525          clib_net_to_host_u64 (mp->last_update_time),
4526          format_policer_action_type, mp->conform_action_type,
4527          conform_dscp_str,
4528          format_policer_action_type, mp->exceed_action_type,
4529          exceed_dscp_str,
4530          format_policer_action_type, mp->violate_action_type,
4531          violate_dscp_str);
4532
4533   vec_free (conform_dscp_str);
4534   vec_free (exceed_dscp_str);
4535   vec_free (violate_dscp_str);
4536 }
4537
4538 static void vl_api_policer_details_t_handler_json
4539   (vl_api_policer_details_t * mp)
4540 {
4541   vat_main_t *vam = &vat_main;
4542   vat_json_node_t *node;
4543   u8 *rate_type_str, *round_type_str, *type_str;
4544   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4545
4546   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4547   round_type_str =
4548     format (0, "%U", format_policer_round_type, mp->round_type);
4549   type_str = format (0, "%U", format_policer_type, mp->type);
4550   conform_action_str = format (0, "%U", format_policer_action_type,
4551                                mp->conform_action_type);
4552   exceed_action_str = format (0, "%U", format_policer_action_type,
4553                               mp->exceed_action_type);
4554   violate_action_str = format (0, "%U", format_policer_action_type,
4555                                mp->violate_action_type);
4556
4557   if (VAT_JSON_ARRAY != vam->json_tree.type)
4558     {
4559       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4560       vat_json_init_array (&vam->json_tree);
4561     }
4562   node = vat_json_array_add (&vam->json_tree);
4563
4564   vat_json_init_object (node);
4565   vat_json_object_add_string_copy (node, "name", mp->name);
4566   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4567   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4568   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4569   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4570   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4571   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4572   vat_json_object_add_string_copy (node, "type", type_str);
4573   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4574   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4575   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4576   vat_json_object_add_uint (node, "cir_tokens_per_period",
4577                             ntohl (mp->cir_tokens_per_period));
4578   vat_json_object_add_uint (node, "eir_tokens_per_period",
4579                             ntohl (mp->pir_tokens_per_period));
4580   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4581   vat_json_object_add_uint (node, "current_bucket",
4582                             ntohl (mp->current_bucket));
4583   vat_json_object_add_uint (node, "extended_limit",
4584                             ntohl (mp->extended_limit));
4585   vat_json_object_add_uint (node, "extended_bucket",
4586                             ntohl (mp->extended_bucket));
4587   vat_json_object_add_uint (node, "last_update_time",
4588                             ntohl (mp->last_update_time));
4589   vat_json_object_add_string_copy (node, "conform_action",
4590                                    conform_action_str);
4591   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4592     {
4593       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4594       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4595       vec_free (dscp_str);
4596     }
4597   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4598   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4599     {
4600       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4601       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4602       vec_free (dscp_str);
4603     }
4604   vat_json_object_add_string_copy (node, "violate_action",
4605                                    violate_action_str);
4606   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4607     {
4608       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4609       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4610       vec_free (dscp_str);
4611     }
4612
4613   vec_free (rate_type_str);
4614   vec_free (round_type_str);
4615   vec_free (type_str);
4616   vec_free (conform_action_str);
4617   vec_free (exceed_action_str);
4618   vec_free (violate_action_str);
4619 }
4620
4621 static void
4622 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4623                                            mp)
4624 {
4625   vat_main_t *vam = &vat_main;
4626   int i, count = ntohl (mp->count);
4627
4628   if (count > 0)
4629     print (vam->ofp, "classify table ids (%d) : ", count);
4630   for (i = 0; i < count; i++)
4631     {
4632       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4633       print (vam->ofp, (i < count - 1) ? "," : "");
4634     }
4635   vam->retval = ntohl (mp->retval);
4636   vam->result_ready = 1;
4637 }
4638
4639 static void
4640   vl_api_classify_table_ids_reply_t_handler_json
4641   (vl_api_classify_table_ids_reply_t * mp)
4642 {
4643   vat_main_t *vam = &vat_main;
4644   int i, count = ntohl (mp->count);
4645
4646   if (count > 0)
4647     {
4648       vat_json_node_t node;
4649
4650       vat_json_init_object (&node);
4651       for (i = 0; i < count; i++)
4652         {
4653           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4654         }
4655       vat_json_print (vam->ofp, &node);
4656       vat_json_free (&node);
4657     }
4658   vam->retval = ntohl (mp->retval);
4659   vam->result_ready = 1;
4660 }
4661
4662 static void
4663   vl_api_classify_table_by_interface_reply_t_handler
4664   (vl_api_classify_table_by_interface_reply_t * mp)
4665 {
4666   vat_main_t *vam = &vat_main;
4667   u32 table_id;
4668
4669   table_id = ntohl (mp->l2_table_id);
4670   if (table_id != ~0)
4671     print (vam->ofp, "l2 table id : %d", table_id);
4672   else
4673     print (vam->ofp, "l2 table id : No input ACL tables configured");
4674   table_id = ntohl (mp->ip4_table_id);
4675   if (table_id != ~0)
4676     print (vam->ofp, "ip4 table id : %d", table_id);
4677   else
4678     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4679   table_id = ntohl (mp->ip6_table_id);
4680   if (table_id != ~0)
4681     print (vam->ofp, "ip6 table id : %d", table_id);
4682   else
4683     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4684   vam->retval = ntohl (mp->retval);
4685   vam->result_ready = 1;
4686 }
4687
4688 static void
4689   vl_api_classify_table_by_interface_reply_t_handler_json
4690   (vl_api_classify_table_by_interface_reply_t * mp)
4691 {
4692   vat_main_t *vam = &vat_main;
4693   vat_json_node_t node;
4694
4695   vat_json_init_object (&node);
4696
4697   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4698   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4699   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4700
4701   vat_json_print (vam->ofp, &node);
4702   vat_json_free (&node);
4703
4704   vam->retval = ntohl (mp->retval);
4705   vam->result_ready = 1;
4706 }
4707
4708 static void vl_api_policer_add_del_reply_t_handler
4709   (vl_api_policer_add_del_reply_t * mp)
4710 {
4711   vat_main_t *vam = &vat_main;
4712   i32 retval = ntohl (mp->retval);
4713   if (vam->async_mode)
4714     {
4715       vam->async_errors += (retval < 0);
4716     }
4717   else
4718     {
4719       vam->retval = retval;
4720       vam->result_ready = 1;
4721       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4722         /*
4723          * Note: this is just barely thread-safe, depends on
4724          * the main thread spinning waiting for an answer...
4725          */
4726         errmsg ("policer index %d", ntohl (mp->policer_index));
4727     }
4728 }
4729
4730 static void vl_api_policer_add_del_reply_t_handler_json
4731   (vl_api_policer_add_del_reply_t * mp)
4732 {
4733   vat_main_t *vam = &vat_main;
4734   vat_json_node_t node;
4735
4736   vat_json_init_object (&node);
4737   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4738   vat_json_object_add_uint (&node, "policer_index",
4739                             ntohl (mp->policer_index));
4740
4741   vat_json_print (vam->ofp, &node);
4742   vat_json_free (&node);
4743
4744   vam->retval = ntohl (mp->retval);
4745   vam->result_ready = 1;
4746 }
4747
4748 /* Format hex dump. */
4749 u8 *
4750 format_hex_bytes (u8 * s, va_list * va)
4751 {
4752   u8 *bytes = va_arg (*va, u8 *);
4753   int n_bytes = va_arg (*va, int);
4754   uword i;
4755
4756   /* Print short or long form depending on byte count. */
4757   uword short_form = n_bytes <= 32;
4758   u32 indent = format_get_indent (s);
4759
4760   if (n_bytes == 0)
4761     return s;
4762
4763   for (i = 0; i < n_bytes; i++)
4764     {
4765       if (!short_form && (i % 32) == 0)
4766         s = format (s, "%08x: ", i);
4767       s = format (s, "%02x", bytes[i]);
4768       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4769         s = format (s, "\n%U", format_white_space, indent);
4770     }
4771
4772   return s;
4773 }
4774
4775 static void
4776 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4777                                             * mp)
4778 {
4779   vat_main_t *vam = &vat_main;
4780   i32 retval = ntohl (mp->retval);
4781   if (retval == 0)
4782     {
4783       print (vam->ofp, "classify table info :");
4784       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4785              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4786              ntohl (mp->miss_next_index));
4787       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4788              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4789              ntohl (mp->match_n_vectors));
4790       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4791              ntohl (mp->mask_length));
4792     }
4793   vam->retval = retval;
4794   vam->result_ready = 1;
4795 }
4796
4797 static void
4798   vl_api_classify_table_info_reply_t_handler_json
4799   (vl_api_classify_table_info_reply_t * mp)
4800 {
4801   vat_main_t *vam = &vat_main;
4802   vat_json_node_t node;
4803
4804   i32 retval = ntohl (mp->retval);
4805   if (retval == 0)
4806     {
4807       vat_json_init_object (&node);
4808
4809       vat_json_object_add_int (&node, "sessions",
4810                                ntohl (mp->active_sessions));
4811       vat_json_object_add_int (&node, "nexttbl",
4812                                ntohl (mp->next_table_index));
4813       vat_json_object_add_int (&node, "nextnode",
4814                                ntohl (mp->miss_next_index));
4815       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4816       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4817       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4818       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4819                       ntohl (mp->mask_length), 0);
4820       vat_json_object_add_string_copy (&node, "mask", s);
4821
4822       vat_json_print (vam->ofp, &node);
4823       vat_json_free (&node);
4824     }
4825   vam->retval = ntohl (mp->retval);
4826   vam->result_ready = 1;
4827 }
4828
4829 static void
4830 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4831                                            mp)
4832 {
4833   vat_main_t *vam = &vat_main;
4834
4835   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4836          ntohl (mp->hit_next_index), ntohl (mp->advance),
4837          ntohl (mp->opaque_index));
4838   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4839          ntohl (mp->match_length));
4840 }
4841
4842 static void
4843   vl_api_classify_session_details_t_handler_json
4844   (vl_api_classify_session_details_t * mp)
4845 {
4846   vat_main_t *vam = &vat_main;
4847   vat_json_node_t *node = NULL;
4848
4849   if (VAT_JSON_ARRAY != vam->json_tree.type)
4850     {
4851       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4852       vat_json_init_array (&vam->json_tree);
4853     }
4854   node = vat_json_array_add (&vam->json_tree);
4855
4856   vat_json_init_object (node);
4857   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4858   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4859   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4860   u8 *s =
4861     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4862             0);
4863   vat_json_object_add_string_copy (node, "match", s);
4864 }
4865
4866 static void vl_api_pg_create_interface_reply_t_handler
4867   (vl_api_pg_create_interface_reply_t * mp)
4868 {
4869   vat_main_t *vam = &vat_main;
4870
4871   vam->retval = ntohl (mp->retval);
4872   vam->result_ready = 1;
4873 }
4874
4875 static void vl_api_pg_create_interface_reply_t_handler_json
4876   (vl_api_pg_create_interface_reply_t * mp)
4877 {
4878   vat_main_t *vam = &vat_main;
4879   vat_json_node_t node;
4880
4881   i32 retval = ntohl (mp->retval);
4882   if (retval == 0)
4883     {
4884       vat_json_init_object (&node);
4885
4886       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4887
4888       vat_json_print (vam->ofp, &node);
4889       vat_json_free (&node);
4890     }
4891   vam->retval = ntohl (mp->retval);
4892   vam->result_ready = 1;
4893 }
4894
4895 static void vl_api_policer_classify_details_t_handler
4896   (vl_api_policer_classify_details_t * mp)
4897 {
4898   vat_main_t *vam = &vat_main;
4899
4900   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4901          ntohl (mp->table_index));
4902 }
4903
4904 static void vl_api_policer_classify_details_t_handler_json
4905   (vl_api_policer_classify_details_t * mp)
4906 {
4907   vat_main_t *vam = &vat_main;
4908   vat_json_node_t *node;
4909
4910   if (VAT_JSON_ARRAY != vam->json_tree.type)
4911     {
4912       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4913       vat_json_init_array (&vam->json_tree);
4914     }
4915   node = vat_json_array_add (&vam->json_tree);
4916
4917   vat_json_init_object (node);
4918   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4919   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4920 }
4921
4922 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
4923   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4924 {
4925   vat_main_t *vam = &vat_main;
4926   i32 retval = ntohl (mp->retval);
4927   if (vam->async_mode)
4928     {
4929       vam->async_errors += (retval < 0);
4930     }
4931   else
4932     {
4933       vam->retval = retval;
4934       vam->sw_if_index = ntohl (mp->sw_if_index);
4935       vam->result_ready = 1;
4936     }
4937 }
4938
4939 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
4940   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4941 {
4942   vat_main_t *vam = &vat_main;
4943   vat_json_node_t node;
4944
4945   vat_json_init_object (&node);
4946   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4947   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
4948
4949   vat_json_print (vam->ofp, &node);
4950   vat_json_free (&node);
4951
4952   vam->retval = ntohl (mp->retval);
4953   vam->result_ready = 1;
4954 }
4955
4956 static void vl_api_flow_classify_details_t_handler
4957   (vl_api_flow_classify_details_t * mp)
4958 {
4959   vat_main_t *vam = &vat_main;
4960
4961   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4962          ntohl (mp->table_index));
4963 }
4964
4965 static void vl_api_flow_classify_details_t_handler_json
4966   (vl_api_flow_classify_details_t * mp)
4967 {
4968   vat_main_t *vam = &vat_main;
4969   vat_json_node_t *node;
4970
4971   if (VAT_JSON_ARRAY != vam->json_tree.type)
4972     {
4973       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4974       vat_json_init_array (&vam->json_tree);
4975     }
4976   node = vat_json_array_add (&vam->json_tree);
4977
4978   vat_json_init_object (node);
4979   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4980   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4981 }
4982
4983 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
4984 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
4985 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
4986 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
4987 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
4988 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
4989 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
4990 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
4991 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
4992 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
4993 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
4994 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
4995 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
4996 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
4997 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
4998 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
4999 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5000 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5001 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5002 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5003 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5004 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5005
5006 /*
5007  * Generate boilerplate reply handlers, which
5008  * dig the return value out of the xxx_reply_t API message,
5009  * stick it into vam->retval, and set vam->result_ready
5010  *
5011  * Could also do this by pointing N message decode slots at
5012  * a single function, but that could break in subtle ways.
5013  */
5014
5015 #define foreach_standard_reply_retval_handler           \
5016 _(sw_interface_set_flags_reply)                         \
5017 _(sw_interface_add_del_address_reply)                   \
5018 _(sw_interface_set_table_reply)                         \
5019 _(sw_interface_set_mpls_enable_reply)                   \
5020 _(sw_interface_set_vpath_reply)                         \
5021 _(sw_interface_set_vxlan_bypass_reply)                  \
5022 _(sw_interface_set_geneve_bypass_reply)                 \
5023 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5024 _(sw_interface_set_l2_bridge_reply)                     \
5025 _(bridge_domain_add_del_reply)                          \
5026 _(sw_interface_set_l2_xconnect_reply)                   \
5027 _(l2fib_add_del_reply)                                  \
5028 _(l2fib_flush_int_reply)                                \
5029 _(l2fib_flush_bd_reply)                                 \
5030 _(ip_add_del_route_reply)                               \
5031 _(ip_table_add_del_reply)                               \
5032 _(ip_mroute_add_del_reply)                              \
5033 _(mpls_route_add_del_reply)                             \
5034 _(mpls_table_add_del_reply)                             \
5035 _(mpls_ip_bind_unbind_reply)                            \
5036 _(proxy_arp_add_del_reply)                              \
5037 _(proxy_arp_intfc_enable_disable_reply)                 \
5038 _(sw_interface_set_unnumbered_reply)                    \
5039 _(ip_neighbor_add_del_reply)                            \
5040 _(reset_vrf_reply)                                      \
5041 _(oam_add_del_reply)                                    \
5042 _(reset_fib_reply)                                      \
5043 _(dhcp_proxy_config_reply)                              \
5044 _(dhcp_proxy_set_vss_reply)                             \
5045 _(dhcp_client_config_reply)                             \
5046 _(set_ip_flow_hash_reply)                               \
5047 _(sw_interface_ip6_enable_disable_reply)                \
5048 _(sw_interface_ip6_set_link_local_address_reply)        \
5049 _(ip6nd_proxy_add_del_reply)                            \
5050 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5051 _(sw_interface_ip6nd_ra_config_reply)                   \
5052 _(set_arp_neighbor_limit_reply)                         \
5053 _(l2_patch_add_del_reply)                               \
5054 _(sr_policy_add_reply)                                  \
5055 _(sr_policy_mod_reply)                                  \
5056 _(sr_policy_del_reply)                                  \
5057 _(sr_localsid_add_del_reply)                            \
5058 _(sr_steering_add_del_reply)                            \
5059 _(classify_add_del_session_reply)                       \
5060 _(classify_set_interface_ip_table_reply)                \
5061 _(classify_set_interface_l2_tables_reply)               \
5062 _(l2tpv3_set_tunnel_cookies_reply)                      \
5063 _(l2tpv3_interface_enable_disable_reply)                \
5064 _(l2tpv3_set_lookup_key_reply)                          \
5065 _(l2_fib_clear_table_reply)                             \
5066 _(l2_interface_efp_filter_reply)                        \
5067 _(l2_interface_vlan_tag_rewrite_reply)                  \
5068 _(modify_vhost_user_if_reply)                           \
5069 _(delete_vhost_user_if_reply)                           \
5070 _(want_ip4_arp_events_reply)                            \
5071 _(want_ip6_nd_events_reply)                             \
5072 _(want_l2_macs_events_reply)                            \
5073 _(input_acl_set_interface_reply)                        \
5074 _(ipsec_spd_add_del_reply)                              \
5075 _(ipsec_interface_add_del_spd_reply)                    \
5076 _(ipsec_spd_add_del_entry_reply)                        \
5077 _(ipsec_sad_add_del_entry_reply)                        \
5078 _(ipsec_sa_set_key_reply)                               \
5079 _(ipsec_tunnel_if_add_del_reply)                        \
5080 _(ipsec_tunnel_if_set_key_reply)                        \
5081 _(ikev2_profile_add_del_reply)                          \
5082 _(ikev2_profile_set_auth_reply)                         \
5083 _(ikev2_profile_set_id_reply)                           \
5084 _(ikev2_profile_set_ts_reply)                           \
5085 _(ikev2_set_local_key_reply)                            \
5086 _(ikev2_set_responder_reply)                            \
5087 _(ikev2_set_ike_transforms_reply)                       \
5088 _(ikev2_set_esp_transforms_reply)                       \
5089 _(ikev2_set_sa_lifetime_reply)                          \
5090 _(ikev2_initiate_sa_init_reply)                         \
5091 _(ikev2_initiate_del_ike_sa_reply)                      \
5092 _(ikev2_initiate_del_child_sa_reply)                    \
5093 _(ikev2_initiate_rekey_child_sa_reply)                  \
5094 _(delete_loopback_reply)                                \
5095 _(bd_ip_mac_add_del_reply)                              \
5096 _(map_del_domain_reply)                                 \
5097 _(map_add_del_rule_reply)                               \
5098 _(want_interface_events_reply)                          \
5099 _(want_stats_reply)                                     \
5100 _(cop_interface_enable_disable_reply)                   \
5101 _(cop_whitelist_enable_disable_reply)                   \
5102 _(sw_interface_clear_stats_reply)                       \
5103 _(ioam_enable_reply)                                    \
5104 _(ioam_disable_reply)                                   \
5105 _(one_add_del_locator_reply)                            \
5106 _(one_add_del_local_eid_reply)                          \
5107 _(one_add_del_remote_mapping_reply)                     \
5108 _(one_add_del_adjacency_reply)                          \
5109 _(one_add_del_map_resolver_reply)                       \
5110 _(one_add_del_map_server_reply)                         \
5111 _(one_enable_disable_reply)                             \
5112 _(one_rloc_probe_enable_disable_reply)                  \
5113 _(one_map_register_enable_disable_reply)                \
5114 _(one_map_register_set_ttl_reply)                       \
5115 _(one_set_transport_protocol_reply)                     \
5116 _(one_map_register_fallback_threshold_reply)            \
5117 _(one_pitr_set_locator_set_reply)                       \
5118 _(one_map_request_mode_reply)                           \
5119 _(one_add_del_map_request_itr_rlocs_reply)              \
5120 _(one_eid_table_add_del_map_reply)                      \
5121 _(one_use_petr_reply)                                   \
5122 _(one_stats_enable_disable_reply)                       \
5123 _(one_add_del_l2_arp_entry_reply)                       \
5124 _(one_add_del_ndp_entry_reply)                          \
5125 _(one_stats_flush_reply)                                \
5126 _(gpe_enable_disable_reply)                             \
5127 _(gpe_set_encap_mode_reply)                             \
5128 _(gpe_add_del_iface_reply)                              \
5129 _(gpe_add_del_native_fwd_rpath_reply)                   \
5130 _(af_packet_delete_reply)                               \
5131 _(policer_classify_set_interface_reply)                 \
5132 _(netmap_create_reply)                                  \
5133 _(netmap_delete_reply)                                  \
5134 _(set_ipfix_exporter_reply)                             \
5135 _(set_ipfix_classify_stream_reply)                      \
5136 _(ipfix_classify_table_add_del_reply)                   \
5137 _(flow_classify_set_interface_reply)                    \
5138 _(sw_interface_span_enable_disable_reply)               \
5139 _(pg_capture_reply)                                     \
5140 _(pg_enable_disable_reply)                              \
5141 _(ip_source_and_port_range_check_add_del_reply)         \
5142 _(ip_source_and_port_range_check_interface_add_del_reply)\
5143 _(delete_subif_reply)                                   \
5144 _(l2_interface_pbb_tag_rewrite_reply)                   \
5145 _(punt_reply)                                           \
5146 _(feature_enable_disable_reply)                         \
5147 _(sw_interface_tag_add_del_reply)                       \
5148 _(sw_interface_set_mtu_reply)                           \
5149 _(p2p_ethernet_add_reply)                               \
5150 _(p2p_ethernet_del_reply)                               \
5151 _(lldp_config_reply)                                    \
5152 _(sw_interface_set_lldp_reply)                          \
5153 _(tcp_configure_src_addresses_reply)                    \
5154 _(app_namespace_add_del_reply)                          \
5155 _(dns_enable_disable_reply)                             \
5156 _(dns_name_server_add_del_reply)
5157
5158 #define _(n)                                    \
5159     static void vl_api_##n##_t_handler          \
5160     (vl_api_##n##_t * mp)                       \
5161     {                                           \
5162         vat_main_t * vam = &vat_main;           \
5163         i32 retval = ntohl(mp->retval);         \
5164         if (vam->async_mode) {                  \
5165             vam->async_errors += (retval < 0);  \
5166         } else {                                \
5167             vam->retval = retval;               \
5168             vam->result_ready = 1;              \
5169         }                                       \
5170     }
5171 foreach_standard_reply_retval_handler;
5172 #undef _
5173
5174 #define _(n)                                    \
5175     static void vl_api_##n##_t_handler_json     \
5176     (vl_api_##n##_t * mp)                       \
5177     {                                           \
5178         vat_main_t * vam = &vat_main;           \
5179         vat_json_node_t node;                   \
5180         vat_json_init_object(&node);            \
5181         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5182         vat_json_print(vam->ofp, &node);        \
5183         vam->retval = ntohl(mp->retval);        \
5184         vam->result_ready = 1;                  \
5185     }
5186 foreach_standard_reply_retval_handler;
5187 #undef _
5188
5189 /*
5190  * Table of message reply handlers, must include boilerplate handlers
5191  * we just generated
5192  */
5193
5194 #define foreach_vpe_api_reply_msg                                       \
5195 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5196 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5197 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5198 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5199 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5200 _(CLI_REPLY, cli_reply)                                                 \
5201 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5202 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5203   sw_interface_add_del_address_reply)                                   \
5204 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5205 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5206 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5207 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5208 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5209 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5210 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5211   sw_interface_set_l2_xconnect_reply)                                   \
5212 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5213   sw_interface_set_l2_bridge_reply)                                     \
5214 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5215 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5216 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5217 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5218 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5219 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5220 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5221 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5222 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5223 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5224 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5225 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5226 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5227 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5228 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5229 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5230 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5231 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5232 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5233 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5234   proxy_arp_intfc_enable_disable_reply)                                 \
5235 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5236 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5237   sw_interface_set_unnumbered_reply)                                    \
5238 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5239 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
5240 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5241 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5242 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5243 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5244 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5245 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5246 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5247 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5248 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5249 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5250   sw_interface_ip6_enable_disable_reply)                                \
5251 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5252   sw_interface_ip6_set_link_local_address_reply)                        \
5253 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5254 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5255 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5256   sw_interface_ip6nd_ra_prefix_reply)                                   \
5257 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5258   sw_interface_ip6nd_ra_config_reply)                                   \
5259 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5260 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5261 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5262 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5263 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5264 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5265 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5266 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5267 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5268 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5269 classify_set_interface_ip_table_reply)                                  \
5270 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5271   classify_set_interface_l2_tables_reply)                               \
5272 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5273 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5274 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5275 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5276 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5277   l2tpv3_interface_enable_disable_reply)                                \
5278 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5279 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5280 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5281 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5282 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5283 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5284 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5285 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5286 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5287 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5288 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5289 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5290 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5291 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5292 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5293 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5294 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5295 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
5296 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5297 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5298 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5299 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5300 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5301 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5302 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5303 _(L2_MACS_EVENT, l2_macs_event)                                         \
5304 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5305 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5306 _(IP_DETAILS, ip_details)                                               \
5307 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5308 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5309 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5310 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5311 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5312 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5313 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5314 _(IPSEC_TUNNEL_IF_SET_KEY_REPLY, ipsec_tunnel_if_set_key_reply)         \
5315 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5316 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5317 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5318 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5319 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5320 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5321 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5322 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5323 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5324 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5325 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5326 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5327 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5328 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5329 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5330 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5331 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5332 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5333 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5334 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5335 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5336 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5337 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5338 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5339 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5340 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5341 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5342 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5343 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5344 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5345 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5346 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5347 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5348 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5349 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5350 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5351 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5352 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5353 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5354   one_map_register_enable_disable_reply)                                \
5355 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5356 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5357 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5358 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5359   one_map_register_fallback_threshold_reply)                            \
5360 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5361   one_rloc_probe_enable_disable_reply)                                  \
5362 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5363 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5364 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5365 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5366 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5367 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5368 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5369 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5370 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5371 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5372 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5373 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5374 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5375 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5376 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5377 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5378   show_one_stats_enable_disable_reply)                                  \
5379 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5380 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5381 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5382 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5383 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5384 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5385 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5386 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5387 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5388 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5389 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5390 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5391 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5392 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5393 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5394   gpe_add_del_native_fwd_rpath_reply)                                   \
5395 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5396   gpe_fwd_entry_path_details)                                           \
5397 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5398 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5399   one_add_del_map_request_itr_rlocs_reply)                              \
5400 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5401   one_get_map_request_itr_rlocs_reply)                                  \
5402 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5403 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5404 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5405 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5406 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5407 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5408   show_one_map_register_state_reply)                                    \
5409 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5410 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5411   show_one_map_register_fallback_threshold_reply)                       \
5412 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5413 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5414 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5415 _(POLICER_DETAILS, policer_details)                                     \
5416 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5417 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5418 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5419 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5420 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5421 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5422 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5423 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5424 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5425 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5426 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5427 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5428 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5429 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5430 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5431 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5432 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5433 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5434 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5435 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5436 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5437 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5438 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5439 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5440 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5441  ip_source_and_port_range_check_add_del_reply)                          \
5442 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5443  ip_source_and_port_range_check_interface_add_del_reply)                \
5444 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5445 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5446 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5447 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5448 _(PUNT_REPLY, punt_reply)                                               \
5449 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5450 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5451 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5452 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5453 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5454 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5455 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5456 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5457 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5458 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5459 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5460 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5461 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5462 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5463 _(DNS_ENABLE_DISABLE_REPLY, dns_enable_disable_reply)                   \
5464 _(DNS_NAME_SERVER_ADD_DEL_REPLY, dns_name_server_add_del_reply)         \
5465 _(DNS_RESOLVE_NAME_REPLY, dns_resolve_name_reply)
5466
5467 #define foreach_standalone_reply_msg                                    \
5468 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5469 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5470 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5471 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5472 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5473 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5474 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
5475 _(MEMFD_SEGMENT_CREATE_REPLY, memfd_segment_create_reply)               \
5476
5477 typedef struct
5478 {
5479   u8 *name;
5480   u32 value;
5481 } name_sort_t;
5482
5483
5484 #define STR_VTR_OP_CASE(op)     \
5485     case L2_VTR_ ## op:         \
5486         return "" # op;
5487
5488 static const char *
5489 str_vtr_op (u32 vtr_op)
5490 {
5491   switch (vtr_op)
5492     {
5493       STR_VTR_OP_CASE (DISABLED);
5494       STR_VTR_OP_CASE (PUSH_1);
5495       STR_VTR_OP_CASE (PUSH_2);
5496       STR_VTR_OP_CASE (POP_1);
5497       STR_VTR_OP_CASE (POP_2);
5498       STR_VTR_OP_CASE (TRANSLATE_1_1);
5499       STR_VTR_OP_CASE (TRANSLATE_1_2);
5500       STR_VTR_OP_CASE (TRANSLATE_2_1);
5501       STR_VTR_OP_CASE (TRANSLATE_2_2);
5502     }
5503
5504   return "UNKNOWN";
5505 }
5506
5507 static int
5508 dump_sub_interface_table (vat_main_t * vam)
5509 {
5510   const sw_interface_subif_t *sub = NULL;
5511
5512   if (vam->json_output)
5513     {
5514       clib_warning
5515         ("JSON output supported only for VPE API calls and dump_stats_table");
5516       return -99;
5517     }
5518
5519   print (vam->ofp,
5520          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5521          "Interface", "sw_if_index",
5522          "sub id", "dot1ad", "tags", "outer id",
5523          "inner id", "exact", "default", "outer any", "inner any");
5524
5525   vec_foreach (sub, vam->sw_if_subif_table)
5526   {
5527     print (vam->ofp,
5528            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5529            sub->interface_name,
5530            sub->sw_if_index,
5531            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5532            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5533            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5534            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5535     if (sub->vtr_op != L2_VTR_DISABLED)
5536       {
5537         print (vam->ofp,
5538                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5539                "tag1: %d tag2: %d ]",
5540                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5541                sub->vtr_tag1, sub->vtr_tag2);
5542       }
5543   }
5544
5545   return 0;
5546 }
5547
5548 static int
5549 name_sort_cmp (void *a1, void *a2)
5550 {
5551   name_sort_t *n1 = a1;
5552   name_sort_t *n2 = a2;
5553
5554   return strcmp ((char *) n1->name, (char *) n2->name);
5555 }
5556
5557 static int
5558 dump_interface_table (vat_main_t * vam)
5559 {
5560   hash_pair_t *p;
5561   name_sort_t *nses = 0, *ns;
5562
5563   if (vam->json_output)
5564     {
5565       clib_warning
5566         ("JSON output supported only for VPE API calls and dump_stats_table");
5567       return -99;
5568     }
5569
5570   /* *INDENT-OFF* */
5571   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5572   ({
5573     vec_add2 (nses, ns, 1);
5574     ns->name = (u8 *)(p->key);
5575     ns->value = (u32) p->value[0];
5576   }));
5577   /* *INDENT-ON* */
5578
5579   vec_sort_with_function (nses, name_sort_cmp);
5580
5581   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5582   vec_foreach (ns, nses)
5583   {
5584     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5585   }
5586   vec_free (nses);
5587   return 0;
5588 }
5589
5590 static int
5591 dump_ip_table (vat_main_t * vam, int is_ipv6)
5592 {
5593   const ip_details_t *det = NULL;
5594   const ip_address_details_t *address = NULL;
5595   u32 i = ~0;
5596
5597   print (vam->ofp, "%-12s", "sw_if_index");
5598
5599   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5600   {
5601     i++;
5602     if (!det->present)
5603       {
5604         continue;
5605       }
5606     print (vam->ofp, "%-12d", i);
5607     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5608     if (!det->addr)
5609       {
5610         continue;
5611       }
5612     vec_foreach (address, det->addr)
5613     {
5614       print (vam->ofp,
5615              "            %-30U%-13d",
5616              is_ipv6 ? format_ip6_address : format_ip4_address,
5617              address->ip, address->prefix_length);
5618     }
5619   }
5620
5621   return 0;
5622 }
5623
5624 static int
5625 dump_ipv4_table (vat_main_t * vam)
5626 {
5627   if (vam->json_output)
5628     {
5629       clib_warning
5630         ("JSON output supported only for VPE API calls and dump_stats_table");
5631       return -99;
5632     }
5633
5634   return dump_ip_table (vam, 0);
5635 }
5636
5637 static int
5638 dump_ipv6_table (vat_main_t * vam)
5639 {
5640   if (vam->json_output)
5641     {
5642       clib_warning
5643         ("JSON output supported only for VPE API calls and dump_stats_table");
5644       return -99;
5645     }
5646
5647   return dump_ip_table (vam, 1);
5648 }
5649
5650 static char *
5651 counter_type_to_str (u8 counter_type, u8 is_combined)
5652 {
5653   if (!is_combined)
5654     {
5655       switch (counter_type)
5656         {
5657         case VNET_INTERFACE_COUNTER_DROP:
5658           return "drop";
5659         case VNET_INTERFACE_COUNTER_PUNT:
5660           return "punt";
5661         case VNET_INTERFACE_COUNTER_IP4:
5662           return "ip4";
5663         case VNET_INTERFACE_COUNTER_IP6:
5664           return "ip6";
5665         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5666           return "rx-no-buf";
5667         case VNET_INTERFACE_COUNTER_RX_MISS:
5668           return "rx-miss";
5669         case VNET_INTERFACE_COUNTER_RX_ERROR:
5670           return "rx-error";
5671         case VNET_INTERFACE_COUNTER_TX_ERROR:
5672           return "tx-error";
5673         default:
5674           return "INVALID-COUNTER-TYPE";
5675         }
5676     }
5677   else
5678     {
5679       switch (counter_type)
5680         {
5681         case VNET_INTERFACE_COUNTER_RX:
5682           return "rx";
5683         case VNET_INTERFACE_COUNTER_TX:
5684           return "tx";
5685         default:
5686           return "INVALID-COUNTER-TYPE";
5687         }
5688     }
5689 }
5690
5691 static int
5692 dump_stats_table (vat_main_t * vam)
5693 {
5694   vat_json_node_t node;
5695   vat_json_node_t *msg_array;
5696   vat_json_node_t *msg;
5697   vat_json_node_t *counter_array;
5698   vat_json_node_t *counter;
5699   interface_counter_t c;
5700   u64 packets;
5701   ip4_fib_counter_t *c4;
5702   ip6_fib_counter_t *c6;
5703   ip4_nbr_counter_t *n4;
5704   ip6_nbr_counter_t *n6;
5705   int i, j;
5706
5707   if (!vam->json_output)
5708     {
5709       clib_warning ("dump_stats_table supported only in JSON format");
5710       return -99;
5711     }
5712
5713   vat_json_init_object (&node);
5714
5715   /* interface counters */
5716   msg_array = vat_json_object_add (&node, "interface_counters");
5717   vat_json_init_array (msg_array);
5718   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5719     {
5720       msg = vat_json_array_add (msg_array);
5721       vat_json_init_object (msg);
5722       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5723                                        (u8 *) counter_type_to_str (i, 0));
5724       vat_json_object_add_int (msg, "is_combined", 0);
5725       counter_array = vat_json_object_add (msg, "data");
5726       vat_json_init_array (counter_array);
5727       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5728         {
5729           packets = vam->simple_interface_counters[i][j];
5730           vat_json_array_add_uint (counter_array, packets);
5731         }
5732     }
5733   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5734     {
5735       msg = vat_json_array_add (msg_array);
5736       vat_json_init_object (msg);
5737       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5738                                        (u8 *) counter_type_to_str (i, 1));
5739       vat_json_object_add_int (msg, "is_combined", 1);
5740       counter_array = vat_json_object_add (msg, "data");
5741       vat_json_init_array (counter_array);
5742       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5743         {
5744           c = vam->combined_interface_counters[i][j];
5745           counter = vat_json_array_add (counter_array);
5746           vat_json_init_object (counter);
5747           vat_json_object_add_uint (counter, "packets", c.packets);
5748           vat_json_object_add_uint (counter, "bytes", c.bytes);
5749         }
5750     }
5751
5752   /* ip4 fib counters */
5753   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
5754   vat_json_init_array (msg_array);
5755   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
5756     {
5757       msg = vat_json_array_add (msg_array);
5758       vat_json_init_object (msg);
5759       vat_json_object_add_uint (msg, "vrf_id",
5760                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
5761       counter_array = vat_json_object_add (msg, "c");
5762       vat_json_init_array (counter_array);
5763       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
5764         {
5765           counter = vat_json_array_add (counter_array);
5766           vat_json_init_object (counter);
5767           c4 = &vam->ip4_fib_counters[i][j];
5768           vat_json_object_add_ip4 (counter, "address", c4->address);
5769           vat_json_object_add_uint (counter, "address_length",
5770                                     c4->address_length);
5771           vat_json_object_add_uint (counter, "packets", c4->packets);
5772           vat_json_object_add_uint (counter, "bytes", c4->bytes);
5773         }
5774     }
5775
5776   /* ip6 fib counters */
5777   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
5778   vat_json_init_array (msg_array);
5779   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
5780     {
5781       msg = vat_json_array_add (msg_array);
5782       vat_json_init_object (msg);
5783       vat_json_object_add_uint (msg, "vrf_id",
5784                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
5785       counter_array = vat_json_object_add (msg, "c");
5786       vat_json_init_array (counter_array);
5787       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
5788         {
5789           counter = vat_json_array_add (counter_array);
5790           vat_json_init_object (counter);
5791           c6 = &vam->ip6_fib_counters[i][j];
5792           vat_json_object_add_ip6 (counter, "address", c6->address);
5793           vat_json_object_add_uint (counter, "address_length",
5794                                     c6->address_length);
5795           vat_json_object_add_uint (counter, "packets", c6->packets);
5796           vat_json_object_add_uint (counter, "bytes", c6->bytes);
5797         }
5798     }
5799
5800   /* ip4 nbr counters */
5801   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
5802   vat_json_init_array (msg_array);
5803   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
5804     {
5805       msg = vat_json_array_add (msg_array);
5806       vat_json_init_object (msg);
5807       vat_json_object_add_uint (msg, "sw_if_index", i);
5808       counter_array = vat_json_object_add (msg, "c");
5809       vat_json_init_array (counter_array);
5810       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
5811         {
5812           counter = vat_json_array_add (counter_array);
5813           vat_json_init_object (counter);
5814           n4 = &vam->ip4_nbr_counters[i][j];
5815           vat_json_object_add_ip4 (counter, "address", n4->address);
5816           vat_json_object_add_uint (counter, "link-type", n4->linkt);
5817           vat_json_object_add_uint (counter, "packets", n4->packets);
5818           vat_json_object_add_uint (counter, "bytes", n4->bytes);
5819         }
5820     }
5821
5822   /* ip6 nbr counters */
5823   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
5824   vat_json_init_array (msg_array);
5825   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
5826     {
5827       msg = vat_json_array_add (msg_array);
5828       vat_json_init_object (msg);
5829       vat_json_object_add_uint (msg, "sw_if_index", i);
5830       counter_array = vat_json_object_add (msg, "c");
5831       vat_json_init_array (counter_array);
5832       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
5833         {
5834           counter = vat_json_array_add (counter_array);
5835           vat_json_init_object (counter);
5836           n6 = &vam->ip6_nbr_counters[i][j];
5837           vat_json_object_add_ip6 (counter, "address", n6->address);
5838           vat_json_object_add_uint (counter, "packets", n6->packets);
5839           vat_json_object_add_uint (counter, "bytes", n6->bytes);
5840         }
5841     }
5842
5843   vat_json_print (vam->ofp, &node);
5844   vat_json_free (&node);
5845
5846   return 0;
5847 }
5848
5849 /*
5850  * Pass CLI buffers directly in the CLI_INBAND API message,
5851  * instead of an additional shared memory area.
5852  */
5853 static int
5854 exec_inband (vat_main_t * vam)
5855 {
5856   vl_api_cli_inband_t *mp;
5857   unformat_input_t *i = vam->input;
5858   int ret;
5859
5860   if (vec_len (i->buffer) == 0)
5861     return -1;
5862
5863   if (vam->exec_mode == 0 && unformat (i, "mode"))
5864     {
5865       vam->exec_mode = 1;
5866       return 0;
5867     }
5868   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5869     {
5870       vam->exec_mode = 0;
5871       return 0;
5872     }
5873
5874   /*
5875    * In order for the CLI command to work, it
5876    * must be a vector ending in \n, not a C-string ending
5877    * in \n\0.
5878    */
5879   u32 len = vec_len (vam->input->buffer);
5880   M2 (CLI_INBAND, mp, len);
5881   clib_memcpy (mp->cmd, vam->input->buffer, len);
5882   mp->length = htonl (len);
5883
5884   S (mp);
5885   W (ret);
5886   /* json responses may or may not include a useful reply... */
5887   if (vec_len (vam->cmd_reply))
5888     print (vam->ofp, (char *) (vam->cmd_reply));
5889   return ret;
5890 }
5891
5892 int
5893 exec (vat_main_t * vam)
5894 {
5895   return exec_inband (vam);
5896 }
5897
5898 static int
5899 api_create_loopback (vat_main_t * vam)
5900 {
5901   unformat_input_t *i = vam->input;
5902   vl_api_create_loopback_t *mp;
5903   vl_api_create_loopback_instance_t *mp_lbi;
5904   u8 mac_address[6];
5905   u8 mac_set = 0;
5906   u8 is_specified = 0;
5907   u32 user_instance = 0;
5908   int ret;
5909
5910   memset (mac_address, 0, sizeof (mac_address));
5911
5912   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5913     {
5914       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5915         mac_set = 1;
5916       if (unformat (i, "instance %d", &user_instance))
5917         is_specified = 1;
5918       else
5919         break;
5920     }
5921
5922   if (is_specified)
5923     {
5924       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5925       mp_lbi->is_specified = is_specified;
5926       if (is_specified)
5927         mp_lbi->user_instance = htonl (user_instance);
5928       if (mac_set)
5929         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5930       S (mp_lbi);
5931     }
5932   else
5933     {
5934       /* Construct the API message */
5935       M (CREATE_LOOPBACK, mp);
5936       if (mac_set)
5937         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5938       S (mp);
5939     }
5940
5941   W (ret);
5942   return ret;
5943 }
5944
5945 static int
5946 api_delete_loopback (vat_main_t * vam)
5947 {
5948   unformat_input_t *i = vam->input;
5949   vl_api_delete_loopback_t *mp;
5950   u32 sw_if_index = ~0;
5951   int ret;
5952
5953   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5954     {
5955       if (unformat (i, "sw_if_index %d", &sw_if_index))
5956         ;
5957       else
5958         break;
5959     }
5960
5961   if (sw_if_index == ~0)
5962     {
5963       errmsg ("missing sw_if_index");
5964       return -99;
5965     }
5966
5967   /* Construct the API message */
5968   M (DELETE_LOOPBACK, mp);
5969   mp->sw_if_index = ntohl (sw_if_index);
5970
5971   S (mp);
5972   W (ret);
5973   return ret;
5974 }
5975
5976 static int
5977 api_want_stats (vat_main_t * vam)
5978 {
5979   unformat_input_t *i = vam->input;
5980   vl_api_want_stats_t *mp;
5981   int enable = -1;
5982   int ret;
5983
5984   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5985     {
5986       if (unformat (i, "enable"))
5987         enable = 1;
5988       else if (unformat (i, "disable"))
5989         enable = 0;
5990       else
5991         break;
5992     }
5993
5994   if (enable == -1)
5995     {
5996       errmsg ("missing enable|disable");
5997       return -99;
5998     }
5999
6000   M (WANT_STATS, mp);
6001   mp->enable_disable = enable;
6002
6003   S (mp);
6004   W (ret);
6005   return ret;
6006 }
6007
6008 static int
6009 api_want_interface_events (vat_main_t * vam)
6010 {
6011   unformat_input_t *i = vam->input;
6012   vl_api_want_interface_events_t *mp;
6013   int enable = -1;
6014   int ret;
6015
6016   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6017     {
6018       if (unformat (i, "enable"))
6019         enable = 1;
6020       else if (unformat (i, "disable"))
6021         enable = 0;
6022       else
6023         break;
6024     }
6025
6026   if (enable == -1)
6027     {
6028       errmsg ("missing enable|disable");
6029       return -99;
6030     }
6031
6032   M (WANT_INTERFACE_EVENTS, mp);
6033   mp->enable_disable = enable;
6034
6035   vam->interface_event_display = enable;
6036
6037   S (mp);
6038   W (ret);
6039   return ret;
6040 }
6041
6042
6043 /* Note: non-static, called once to set up the initial intfc table */
6044 int
6045 api_sw_interface_dump (vat_main_t * vam)
6046 {
6047   vl_api_sw_interface_dump_t *mp;
6048   vl_api_control_ping_t *mp_ping;
6049   hash_pair_t *p;
6050   name_sort_t *nses = 0, *ns;
6051   sw_interface_subif_t *sub = NULL;
6052   int ret;
6053
6054   /* Toss the old name table */
6055   /* *INDENT-OFF* */
6056   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6057   ({
6058     vec_add2 (nses, ns, 1);
6059     ns->name = (u8 *)(p->key);
6060     ns->value = (u32) p->value[0];
6061   }));
6062   /* *INDENT-ON* */
6063
6064   hash_free (vam->sw_if_index_by_interface_name);
6065
6066   vec_foreach (ns, nses) vec_free (ns->name);
6067
6068   vec_free (nses);
6069
6070   vec_foreach (sub, vam->sw_if_subif_table)
6071   {
6072     vec_free (sub->interface_name);
6073   }
6074   vec_free (vam->sw_if_subif_table);
6075
6076   /* recreate the interface name hash table */
6077   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6078
6079   /* Get list of ethernets */
6080   M (SW_INTERFACE_DUMP, mp);
6081   mp->name_filter_valid = 1;
6082   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
6083   S (mp);
6084
6085   /* and local / loopback interfaces */
6086   M (SW_INTERFACE_DUMP, mp);
6087   mp->name_filter_valid = 1;
6088   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
6089   S (mp);
6090
6091   /* and packet-generator interfaces */
6092   M (SW_INTERFACE_DUMP, mp);
6093   mp->name_filter_valid = 1;
6094   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
6095   S (mp);
6096
6097   /* and vxlan-gpe tunnel interfaces */
6098   M (SW_INTERFACE_DUMP, mp);
6099   mp->name_filter_valid = 1;
6100   strncpy ((char *) mp->name_filter, "vxlan_gpe",
6101            sizeof (mp->name_filter) - 1);
6102   S (mp);
6103
6104   /* and vxlan tunnel interfaces */
6105   M (SW_INTERFACE_DUMP, mp);
6106   mp->name_filter_valid = 1;
6107   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
6108   S (mp);
6109
6110   /* and geneve tunnel interfaces */
6111   M (SW_INTERFACE_DUMP, mp);
6112   mp->name_filter_valid = 1;
6113   strncpy ((char *) mp->name_filter, "geneve", sizeof (mp->name_filter) - 1);
6114   S (mp);
6115
6116   /* and host (af_packet) interfaces */
6117   M (SW_INTERFACE_DUMP, mp);
6118   mp->name_filter_valid = 1;
6119   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
6120   S (mp);
6121
6122   /* and l2tpv3 tunnel interfaces */
6123   M (SW_INTERFACE_DUMP, mp);
6124   mp->name_filter_valid = 1;
6125   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
6126            sizeof (mp->name_filter) - 1);
6127   S (mp);
6128
6129   /* and GRE tunnel interfaces */
6130   M (SW_INTERFACE_DUMP, mp);
6131   mp->name_filter_valid = 1;
6132   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
6133   S (mp);
6134
6135   /* and LISP-GPE interfaces */
6136   M (SW_INTERFACE_DUMP, mp);
6137   mp->name_filter_valid = 1;
6138   strncpy ((char *) mp->name_filter, "lisp_gpe",
6139            sizeof (mp->name_filter) - 1);
6140   S (mp);
6141
6142   /* and IPSEC tunnel interfaces */
6143   M (SW_INTERFACE_DUMP, mp);
6144   mp->name_filter_valid = 1;
6145   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
6146   S (mp);
6147
6148   /* Use a control ping for synchronization */
6149   MPING (CONTROL_PING, mp_ping);
6150   S (mp_ping);
6151
6152   W (ret);
6153   return ret;
6154 }
6155
6156 static int
6157 api_sw_interface_set_flags (vat_main_t * vam)
6158 {
6159   unformat_input_t *i = vam->input;
6160   vl_api_sw_interface_set_flags_t *mp;
6161   u32 sw_if_index;
6162   u8 sw_if_index_set = 0;
6163   u8 admin_up = 0;
6164   int ret;
6165
6166   /* Parse args required to build the message */
6167   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6168     {
6169       if (unformat (i, "admin-up"))
6170         admin_up = 1;
6171       else if (unformat (i, "admin-down"))
6172         admin_up = 0;
6173       else
6174         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6175         sw_if_index_set = 1;
6176       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6177         sw_if_index_set = 1;
6178       else
6179         break;
6180     }
6181
6182   if (sw_if_index_set == 0)
6183     {
6184       errmsg ("missing interface name or sw_if_index");
6185       return -99;
6186     }
6187
6188   /* Construct the API message */
6189   M (SW_INTERFACE_SET_FLAGS, mp);
6190   mp->sw_if_index = ntohl (sw_if_index);
6191   mp->admin_up_down = admin_up;
6192
6193   /* send it... */
6194   S (mp);
6195
6196   /* Wait for a reply, return the good/bad news... */
6197   W (ret);
6198   return ret;
6199 }
6200
6201 static int
6202 api_sw_interface_clear_stats (vat_main_t * vam)
6203 {
6204   unformat_input_t *i = vam->input;
6205   vl_api_sw_interface_clear_stats_t *mp;
6206   u32 sw_if_index;
6207   u8 sw_if_index_set = 0;
6208   int ret;
6209
6210   /* Parse args required to build the message */
6211   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6212     {
6213       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6214         sw_if_index_set = 1;
6215       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6216         sw_if_index_set = 1;
6217       else
6218         break;
6219     }
6220
6221   /* Construct the API message */
6222   M (SW_INTERFACE_CLEAR_STATS, mp);
6223
6224   if (sw_if_index_set == 1)
6225     mp->sw_if_index = ntohl (sw_if_index);
6226   else
6227     mp->sw_if_index = ~0;
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_add_del_address (vat_main_t * vam)
6239 {
6240   unformat_input_t *i = vam->input;
6241   vl_api_sw_interface_add_del_address_t *mp;
6242   u32 sw_if_index;
6243   u8 sw_if_index_set = 0;
6244   u8 is_add = 1, del_all = 0;
6245   u32 address_length = 0;
6246   u8 v4_address_set = 0;
6247   u8 v6_address_set = 0;
6248   ip4_address_t v4address;
6249   ip6_address_t v6address;
6250   int ret;
6251
6252   /* Parse args required to build the message */
6253   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6254     {
6255       if (unformat (i, "del-all"))
6256         del_all = 1;
6257       else if (unformat (i, "del"))
6258         is_add = 0;
6259       else
6260         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6261         sw_if_index_set = 1;
6262       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6263         sw_if_index_set = 1;
6264       else if (unformat (i, "%U/%d",
6265                          unformat_ip4_address, &v4address, &address_length))
6266         v4_address_set = 1;
6267       else if (unformat (i, "%U/%d",
6268                          unformat_ip6_address, &v6address, &address_length))
6269         v6_address_set = 1;
6270       else
6271         break;
6272     }
6273
6274   if (sw_if_index_set == 0)
6275     {
6276       errmsg ("missing interface name or sw_if_index");
6277       return -99;
6278     }
6279   if (v4_address_set && v6_address_set)
6280     {
6281       errmsg ("both v4 and v6 addresses set");
6282       return -99;
6283     }
6284   if (!v4_address_set && !v6_address_set && !del_all)
6285     {
6286       errmsg ("no addresses set");
6287       return -99;
6288     }
6289
6290   /* Construct the API message */
6291   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6292
6293   mp->sw_if_index = ntohl (sw_if_index);
6294   mp->is_add = is_add;
6295   mp->del_all = del_all;
6296   if (v6_address_set)
6297     {
6298       mp->is_ipv6 = 1;
6299       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6300     }
6301   else
6302     {
6303       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6304     }
6305   mp->address_length = address_length;
6306
6307   /* send it... */
6308   S (mp);
6309
6310   /* Wait for a reply, return good/bad news  */
6311   W (ret);
6312   return ret;
6313 }
6314
6315 static int
6316 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6317 {
6318   unformat_input_t *i = vam->input;
6319   vl_api_sw_interface_set_mpls_enable_t *mp;
6320   u32 sw_if_index;
6321   u8 sw_if_index_set = 0;
6322   u8 enable = 1;
6323   int ret;
6324
6325   /* Parse args required to build the message */
6326   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6327     {
6328       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6329         sw_if_index_set = 1;
6330       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6331         sw_if_index_set = 1;
6332       else if (unformat (i, "disable"))
6333         enable = 0;
6334       else if (unformat (i, "dis"))
6335         enable = 0;
6336       else
6337         break;
6338     }
6339
6340   if (sw_if_index_set == 0)
6341     {
6342       errmsg ("missing interface name or sw_if_index");
6343       return -99;
6344     }
6345
6346   /* Construct the API message */
6347   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6348
6349   mp->sw_if_index = ntohl (sw_if_index);
6350   mp->enable = enable;
6351
6352   /* send it... */
6353   S (mp);
6354
6355   /* Wait for a reply... */
6356   W (ret);
6357   return ret;
6358 }
6359
6360 static int
6361 api_sw_interface_set_table (vat_main_t * vam)
6362 {
6363   unformat_input_t *i = vam->input;
6364   vl_api_sw_interface_set_table_t *mp;
6365   u32 sw_if_index, vrf_id = 0;
6366   u8 sw_if_index_set = 0;
6367   u8 is_ipv6 = 0;
6368   int ret;
6369
6370   /* Parse args required to build the message */
6371   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6372     {
6373       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6374         sw_if_index_set = 1;
6375       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6376         sw_if_index_set = 1;
6377       else if (unformat (i, "vrf %d", &vrf_id))
6378         ;
6379       else if (unformat (i, "ipv6"))
6380         is_ipv6 = 1;
6381       else
6382         break;
6383     }
6384
6385   if (sw_if_index_set == 0)
6386     {
6387       errmsg ("missing interface name or sw_if_index");
6388       return -99;
6389     }
6390
6391   /* Construct the API message */
6392   M (SW_INTERFACE_SET_TABLE, mp);
6393
6394   mp->sw_if_index = ntohl (sw_if_index);
6395   mp->is_ipv6 = is_ipv6;
6396   mp->vrf_id = ntohl (vrf_id);
6397
6398   /* send it... */
6399   S (mp);
6400
6401   /* Wait for a reply... */
6402   W (ret);
6403   return ret;
6404 }
6405
6406 static void vl_api_sw_interface_get_table_reply_t_handler
6407   (vl_api_sw_interface_get_table_reply_t * mp)
6408 {
6409   vat_main_t *vam = &vat_main;
6410
6411   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6412
6413   vam->retval = ntohl (mp->retval);
6414   vam->result_ready = 1;
6415
6416 }
6417
6418 static void vl_api_sw_interface_get_table_reply_t_handler_json
6419   (vl_api_sw_interface_get_table_reply_t * mp)
6420 {
6421   vat_main_t *vam = &vat_main;
6422   vat_json_node_t node;
6423
6424   vat_json_init_object (&node);
6425   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6426   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6427
6428   vat_json_print (vam->ofp, &node);
6429   vat_json_free (&node);
6430
6431   vam->retval = ntohl (mp->retval);
6432   vam->result_ready = 1;
6433 }
6434
6435 static int
6436 api_sw_interface_get_table (vat_main_t * vam)
6437 {
6438   unformat_input_t *i = vam->input;
6439   vl_api_sw_interface_get_table_t *mp;
6440   u32 sw_if_index;
6441   u8 sw_if_index_set = 0;
6442   u8 is_ipv6 = 0;
6443   int ret;
6444
6445   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6446     {
6447       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6448         sw_if_index_set = 1;
6449       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6450         sw_if_index_set = 1;
6451       else if (unformat (i, "ipv6"))
6452         is_ipv6 = 1;
6453       else
6454         break;
6455     }
6456
6457   if (sw_if_index_set == 0)
6458     {
6459       errmsg ("missing interface name or sw_if_index");
6460       return -99;
6461     }
6462
6463   M (SW_INTERFACE_GET_TABLE, mp);
6464   mp->sw_if_index = htonl (sw_if_index);
6465   mp->is_ipv6 = is_ipv6;
6466
6467   S (mp);
6468   W (ret);
6469   return ret;
6470 }
6471
6472 static int
6473 api_sw_interface_set_vpath (vat_main_t * vam)
6474 {
6475   unformat_input_t *i = vam->input;
6476   vl_api_sw_interface_set_vpath_t *mp;
6477   u32 sw_if_index = 0;
6478   u8 sw_if_index_set = 0;
6479   u8 is_enable = 0;
6480   int ret;
6481
6482   /* Parse args required to build the message */
6483   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6484     {
6485       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6486         sw_if_index_set = 1;
6487       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6488         sw_if_index_set = 1;
6489       else if (unformat (i, "enable"))
6490         is_enable = 1;
6491       else if (unformat (i, "disable"))
6492         is_enable = 0;
6493       else
6494         break;
6495     }
6496
6497   if (sw_if_index_set == 0)
6498     {
6499       errmsg ("missing interface name or sw_if_index");
6500       return -99;
6501     }
6502
6503   /* Construct the API message */
6504   M (SW_INTERFACE_SET_VPATH, mp);
6505
6506   mp->sw_if_index = ntohl (sw_if_index);
6507   mp->enable = is_enable;
6508
6509   /* send it... */
6510   S (mp);
6511
6512   /* Wait for a reply... */
6513   W (ret);
6514   return ret;
6515 }
6516
6517 static int
6518 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6519 {
6520   unformat_input_t *i = vam->input;
6521   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6522   u32 sw_if_index = 0;
6523   u8 sw_if_index_set = 0;
6524   u8 is_enable = 1;
6525   u8 is_ipv6 = 0;
6526   int ret;
6527
6528   /* Parse args required to build the message */
6529   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6530     {
6531       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6532         sw_if_index_set = 1;
6533       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6534         sw_if_index_set = 1;
6535       else if (unformat (i, "enable"))
6536         is_enable = 1;
6537       else if (unformat (i, "disable"))
6538         is_enable = 0;
6539       else if (unformat (i, "ip4"))
6540         is_ipv6 = 0;
6541       else if (unformat (i, "ip6"))
6542         is_ipv6 = 1;
6543       else
6544         break;
6545     }
6546
6547   if (sw_if_index_set == 0)
6548     {
6549       errmsg ("missing interface name or sw_if_index");
6550       return -99;
6551     }
6552
6553   /* Construct the API message */
6554   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6555
6556   mp->sw_if_index = ntohl (sw_if_index);
6557   mp->enable = is_enable;
6558   mp->is_ipv6 = is_ipv6;
6559
6560   /* send it... */
6561   S (mp);
6562
6563   /* Wait for a reply... */
6564   W (ret);
6565   return ret;
6566 }
6567
6568 static int
6569 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6570 {
6571   unformat_input_t *i = vam->input;
6572   vl_api_sw_interface_set_geneve_bypass_t *mp;
6573   u32 sw_if_index = 0;
6574   u8 sw_if_index_set = 0;
6575   u8 is_enable = 1;
6576   u8 is_ipv6 = 0;
6577   int ret;
6578
6579   /* Parse args required to build the message */
6580   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6581     {
6582       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6583         sw_if_index_set = 1;
6584       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6585         sw_if_index_set = 1;
6586       else if (unformat (i, "enable"))
6587         is_enable = 1;
6588       else if (unformat (i, "disable"))
6589         is_enable = 0;
6590       else if (unformat (i, "ip4"))
6591         is_ipv6 = 0;
6592       else if (unformat (i, "ip6"))
6593         is_ipv6 = 1;
6594       else
6595         break;
6596     }
6597
6598   if (sw_if_index_set == 0)
6599     {
6600       errmsg ("missing interface name or sw_if_index");
6601       return -99;
6602     }
6603
6604   /* Construct the API message */
6605   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6606
6607   mp->sw_if_index = ntohl (sw_if_index);
6608   mp->enable = is_enable;
6609   mp->is_ipv6 = is_ipv6;
6610
6611   /* send it... */
6612   S (mp);
6613
6614   /* Wait for a reply... */
6615   W (ret);
6616   return ret;
6617 }
6618
6619 static int
6620 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6621 {
6622   unformat_input_t *i = vam->input;
6623   vl_api_sw_interface_set_l2_xconnect_t *mp;
6624   u32 rx_sw_if_index;
6625   u8 rx_sw_if_index_set = 0;
6626   u32 tx_sw_if_index;
6627   u8 tx_sw_if_index_set = 0;
6628   u8 enable = 1;
6629   int ret;
6630
6631   /* Parse args required to build the message */
6632   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6633     {
6634       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6635         rx_sw_if_index_set = 1;
6636       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6637         tx_sw_if_index_set = 1;
6638       else if (unformat (i, "rx"))
6639         {
6640           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6641             {
6642               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6643                             &rx_sw_if_index))
6644                 rx_sw_if_index_set = 1;
6645             }
6646           else
6647             break;
6648         }
6649       else if (unformat (i, "tx"))
6650         {
6651           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6652             {
6653               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6654                             &tx_sw_if_index))
6655                 tx_sw_if_index_set = 1;
6656             }
6657           else
6658             break;
6659         }
6660       else if (unformat (i, "enable"))
6661         enable = 1;
6662       else if (unformat (i, "disable"))
6663         enable = 0;
6664       else
6665         break;
6666     }
6667
6668   if (rx_sw_if_index_set == 0)
6669     {
6670       errmsg ("missing rx interface name or rx_sw_if_index");
6671       return -99;
6672     }
6673
6674   if (enable && (tx_sw_if_index_set == 0))
6675     {
6676       errmsg ("missing tx interface name or tx_sw_if_index");
6677       return -99;
6678     }
6679
6680   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6681
6682   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6683   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6684   mp->enable = enable;
6685
6686   S (mp);
6687   W (ret);
6688   return ret;
6689 }
6690
6691 static int
6692 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6693 {
6694   unformat_input_t *i = vam->input;
6695   vl_api_sw_interface_set_l2_bridge_t *mp;
6696   u32 rx_sw_if_index;
6697   u8 rx_sw_if_index_set = 0;
6698   u32 bd_id;
6699   u8 bd_id_set = 0;
6700   u8 bvi = 0;
6701   u32 shg = 0;
6702   u8 enable = 1;
6703   int ret;
6704
6705   /* Parse args required to build the message */
6706   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6707     {
6708       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6709         rx_sw_if_index_set = 1;
6710       else if (unformat (i, "bd_id %d", &bd_id))
6711         bd_id_set = 1;
6712       else
6713         if (unformat
6714             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6715         rx_sw_if_index_set = 1;
6716       else if (unformat (i, "shg %d", &shg))
6717         ;
6718       else if (unformat (i, "bvi"))
6719         bvi = 1;
6720       else if (unformat (i, "enable"))
6721         enable = 1;
6722       else if (unformat (i, "disable"))
6723         enable = 0;
6724       else
6725         break;
6726     }
6727
6728   if (rx_sw_if_index_set == 0)
6729     {
6730       errmsg ("missing rx interface name or sw_if_index");
6731       return -99;
6732     }
6733
6734   if (enable && (bd_id_set == 0))
6735     {
6736       errmsg ("missing bridge domain");
6737       return -99;
6738     }
6739
6740   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6741
6742   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6743   mp->bd_id = ntohl (bd_id);
6744   mp->shg = (u8) shg;
6745   mp->bvi = bvi;
6746   mp->enable = enable;
6747
6748   S (mp);
6749   W (ret);
6750   return ret;
6751 }
6752
6753 static int
6754 api_bridge_domain_dump (vat_main_t * vam)
6755 {
6756   unformat_input_t *i = vam->input;
6757   vl_api_bridge_domain_dump_t *mp;
6758   vl_api_control_ping_t *mp_ping;
6759   u32 bd_id = ~0;
6760   int ret;
6761
6762   /* Parse args required to build the message */
6763   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6764     {
6765       if (unformat (i, "bd_id %d", &bd_id))
6766         ;
6767       else
6768         break;
6769     }
6770
6771   M (BRIDGE_DOMAIN_DUMP, mp);
6772   mp->bd_id = ntohl (bd_id);
6773   S (mp);
6774
6775   /* Use a control ping for synchronization */
6776   MPING (CONTROL_PING, mp_ping);
6777   S (mp_ping);
6778
6779   W (ret);
6780   return ret;
6781 }
6782
6783 static int
6784 api_bridge_domain_add_del (vat_main_t * vam)
6785 {
6786   unformat_input_t *i = vam->input;
6787   vl_api_bridge_domain_add_del_t *mp;
6788   u32 bd_id = ~0;
6789   u8 is_add = 1;
6790   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6791   u8 *bd_tag = NULL;
6792   u32 mac_age = 0;
6793   int ret;
6794
6795   /* Parse args required to build the message */
6796   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6797     {
6798       if (unformat (i, "bd_id %d", &bd_id))
6799         ;
6800       else if (unformat (i, "flood %d", &flood))
6801         ;
6802       else if (unformat (i, "uu-flood %d", &uu_flood))
6803         ;
6804       else if (unformat (i, "forward %d", &forward))
6805         ;
6806       else if (unformat (i, "learn %d", &learn))
6807         ;
6808       else if (unformat (i, "arp-term %d", &arp_term))
6809         ;
6810       else if (unformat (i, "mac-age %d", &mac_age))
6811         ;
6812       else if (unformat (i, "bd-tag %s", &bd_tag))
6813         ;
6814       else if (unformat (i, "del"))
6815         {
6816           is_add = 0;
6817           flood = uu_flood = forward = learn = 0;
6818         }
6819       else
6820         break;
6821     }
6822
6823   if (bd_id == ~0)
6824     {
6825       errmsg ("missing bridge domain");
6826       ret = -99;
6827       goto done;
6828     }
6829
6830   if (mac_age > 255)
6831     {
6832       errmsg ("mac age must be less than 256 ");
6833       ret = -99;
6834       goto done;
6835     }
6836
6837   if ((bd_tag) && (strlen ((char *) bd_tag) > 63))
6838     {
6839       errmsg ("bd-tag cannot be longer than 63");
6840       ret = -99;
6841       goto done;
6842     }
6843
6844   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6845
6846   mp->bd_id = ntohl (bd_id);
6847   mp->flood = flood;
6848   mp->uu_flood = uu_flood;
6849   mp->forward = forward;
6850   mp->learn = learn;
6851   mp->arp_term = arp_term;
6852   mp->is_add = is_add;
6853   mp->mac_age = (u8) mac_age;
6854   if (bd_tag)
6855     strcpy ((char *) mp->bd_tag, (char *) bd_tag);
6856
6857   S (mp);
6858   W (ret);
6859
6860 done:
6861   vec_free (bd_tag);
6862   return ret;
6863 }
6864
6865 static int
6866 api_l2fib_flush_bd (vat_main_t * vam)
6867 {
6868   unformat_input_t *i = vam->input;
6869   vl_api_l2fib_flush_bd_t *mp;
6870   u32 bd_id = ~0;
6871   int ret;
6872
6873   /* Parse args required to build the message */
6874   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6875     {
6876       if (unformat (i, "bd_id %d", &bd_id));
6877       else
6878         break;
6879     }
6880
6881   if (bd_id == ~0)
6882     {
6883       errmsg ("missing bridge domain");
6884       return -99;
6885     }
6886
6887   M (L2FIB_FLUSH_BD, mp);
6888
6889   mp->bd_id = htonl (bd_id);
6890
6891   S (mp);
6892   W (ret);
6893   return ret;
6894 }
6895
6896 static int
6897 api_l2fib_flush_int (vat_main_t * vam)
6898 {
6899   unformat_input_t *i = vam->input;
6900   vl_api_l2fib_flush_int_t *mp;
6901   u32 sw_if_index = ~0;
6902   int ret;
6903
6904   /* Parse args required to build the message */
6905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6906     {
6907       if (unformat (i, "sw_if_index %d", &sw_if_index));
6908       else
6909         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6910       else
6911         break;
6912     }
6913
6914   if (sw_if_index == ~0)
6915     {
6916       errmsg ("missing interface name or sw_if_index");
6917       return -99;
6918     }
6919
6920   M (L2FIB_FLUSH_INT, mp);
6921
6922   mp->sw_if_index = ntohl (sw_if_index);
6923
6924   S (mp);
6925   W (ret);
6926   return ret;
6927 }
6928
6929 static int
6930 api_l2fib_add_del (vat_main_t * vam)
6931 {
6932   unformat_input_t *i = vam->input;
6933   vl_api_l2fib_add_del_t *mp;
6934   f64 timeout;
6935   u64 mac = 0;
6936   u8 mac_set = 0;
6937   u32 bd_id;
6938   u8 bd_id_set = 0;
6939   u32 sw_if_index = ~0;
6940   u8 sw_if_index_set = 0;
6941   u8 is_add = 1;
6942   u8 static_mac = 0;
6943   u8 filter_mac = 0;
6944   u8 bvi_mac = 0;
6945   int count = 1;
6946   f64 before = 0;
6947   int j;
6948
6949   /* Parse args required to build the message */
6950   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6951     {
6952       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
6953         mac_set = 1;
6954       else if (unformat (i, "bd_id %d", &bd_id))
6955         bd_id_set = 1;
6956       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6957         sw_if_index_set = 1;
6958       else if (unformat (i, "sw_if"))
6959         {
6960           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6961             {
6962               if (unformat
6963                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6964                 sw_if_index_set = 1;
6965             }
6966           else
6967             break;
6968         }
6969       else if (unformat (i, "static"))
6970         static_mac = 1;
6971       else if (unformat (i, "filter"))
6972         {
6973           filter_mac = 1;
6974           static_mac = 1;
6975         }
6976       else if (unformat (i, "bvi"))
6977         {
6978           bvi_mac = 1;
6979           static_mac = 1;
6980         }
6981       else if (unformat (i, "del"))
6982         is_add = 0;
6983       else if (unformat (i, "count %d", &count))
6984         ;
6985       else
6986         break;
6987     }
6988
6989   if (mac_set == 0)
6990     {
6991       errmsg ("missing mac address");
6992       return -99;
6993     }
6994
6995   if (bd_id_set == 0)
6996     {
6997       errmsg ("missing bridge domain");
6998       return -99;
6999     }
7000
7001   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
7002     {
7003       errmsg ("missing interface name or sw_if_index");
7004       return -99;
7005     }
7006
7007   if (count > 1)
7008     {
7009       /* Turn on async mode */
7010       vam->async_mode = 1;
7011       vam->async_errors = 0;
7012       before = vat_time_now (vam);
7013     }
7014
7015   for (j = 0; j < count; j++)
7016     {
7017       M (L2FIB_ADD_DEL, mp);
7018
7019       mp->mac = mac;
7020       mp->bd_id = ntohl (bd_id);
7021       mp->is_add = is_add;
7022
7023       if (is_add)
7024         {
7025           mp->sw_if_index = ntohl (sw_if_index);
7026           mp->static_mac = static_mac;
7027           mp->filter_mac = filter_mac;
7028           mp->bvi_mac = bvi_mac;
7029         }
7030       increment_mac_address (&mac);
7031       /* send it... */
7032       S (mp);
7033     }
7034
7035   if (count > 1)
7036     {
7037       vl_api_control_ping_t *mp_ping;
7038       f64 after;
7039
7040       /* Shut off async mode */
7041       vam->async_mode = 0;
7042
7043       MPING (CONTROL_PING, mp_ping);
7044       S (mp_ping);
7045
7046       timeout = vat_time_now (vam) + 1.0;
7047       while (vat_time_now (vam) < timeout)
7048         if (vam->result_ready == 1)
7049           goto out;
7050       vam->retval = -99;
7051
7052     out:
7053       if (vam->retval == -99)
7054         errmsg ("timeout");
7055
7056       if (vam->async_errors > 0)
7057         {
7058           errmsg ("%d asynchronous errors", vam->async_errors);
7059           vam->retval = -98;
7060         }
7061       vam->async_errors = 0;
7062       after = vat_time_now (vam);
7063
7064       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7065              count, after - before, count / (after - before));
7066     }
7067   else
7068     {
7069       int ret;
7070
7071       /* Wait for a reply... */
7072       W (ret);
7073       return ret;
7074     }
7075   /* Return the good/bad news */
7076   return (vam->retval);
7077 }
7078
7079 static int
7080 api_bridge_domain_set_mac_age (vat_main_t * vam)
7081 {
7082   unformat_input_t *i = vam->input;
7083   vl_api_bridge_domain_set_mac_age_t *mp;
7084   u32 bd_id = ~0;
7085   u32 mac_age = 0;
7086   int ret;
7087
7088   /* Parse args required to build the message */
7089   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7090     {
7091       if (unformat (i, "bd_id %d", &bd_id));
7092       else if (unformat (i, "mac-age %d", &mac_age));
7093       else
7094         break;
7095     }
7096
7097   if (bd_id == ~0)
7098     {
7099       errmsg ("missing bridge domain");
7100       return -99;
7101     }
7102
7103   if (mac_age > 255)
7104     {
7105       errmsg ("mac age must be less than 256 ");
7106       return -99;
7107     }
7108
7109   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7110
7111   mp->bd_id = htonl (bd_id);
7112   mp->mac_age = (u8) mac_age;
7113
7114   S (mp);
7115   W (ret);
7116   return ret;
7117 }
7118
7119 static int
7120 api_l2_flags (vat_main_t * vam)
7121 {
7122   unformat_input_t *i = vam->input;
7123   vl_api_l2_flags_t *mp;
7124   u32 sw_if_index;
7125   u32 flags = 0;
7126   u8 sw_if_index_set = 0;
7127   u8 is_set = 0;
7128   int ret;
7129
7130   /* Parse args required to build the message */
7131   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7132     {
7133       if (unformat (i, "sw_if_index %d", &sw_if_index))
7134         sw_if_index_set = 1;
7135       else if (unformat (i, "sw_if"))
7136         {
7137           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7138             {
7139               if (unformat
7140                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7141                 sw_if_index_set = 1;
7142             }
7143           else
7144             break;
7145         }
7146       else if (unformat (i, "learn"))
7147         flags |= L2_LEARN;
7148       else if (unformat (i, "forward"))
7149         flags |= L2_FWD;
7150       else if (unformat (i, "flood"))
7151         flags |= L2_FLOOD;
7152       else if (unformat (i, "uu-flood"))
7153         flags |= L2_UU_FLOOD;
7154       else if (unformat (i, "arp-term"))
7155         flags |= L2_ARP_TERM;
7156       else if (unformat (i, "off"))
7157         is_set = 0;
7158       else if (unformat (i, "disable"))
7159         is_set = 0;
7160       else
7161         break;
7162     }
7163
7164   if (sw_if_index_set == 0)
7165     {
7166       errmsg ("missing interface name or sw_if_index");
7167       return -99;
7168     }
7169
7170   M (L2_FLAGS, mp);
7171
7172   mp->sw_if_index = ntohl (sw_if_index);
7173   mp->feature_bitmap = ntohl (flags);
7174   mp->is_set = is_set;
7175
7176   S (mp);
7177   W (ret);
7178   return ret;
7179 }
7180
7181 static int
7182 api_bridge_flags (vat_main_t * vam)
7183 {
7184   unformat_input_t *i = vam->input;
7185   vl_api_bridge_flags_t *mp;
7186   u32 bd_id;
7187   u8 bd_id_set = 0;
7188   u8 is_set = 1;
7189   u32 flags = 0;
7190   int ret;
7191
7192   /* Parse args required to build the message */
7193   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7194     {
7195       if (unformat (i, "bd_id %d", &bd_id))
7196         bd_id_set = 1;
7197       else if (unformat (i, "learn"))
7198         flags |= L2_LEARN;
7199       else if (unformat (i, "forward"))
7200         flags |= L2_FWD;
7201       else if (unformat (i, "flood"))
7202         flags |= L2_FLOOD;
7203       else if (unformat (i, "uu-flood"))
7204         flags |= L2_UU_FLOOD;
7205       else if (unformat (i, "arp-term"))
7206         flags |= L2_ARP_TERM;
7207       else if (unformat (i, "off"))
7208         is_set = 0;
7209       else if (unformat (i, "disable"))
7210         is_set = 0;
7211       else
7212         break;
7213     }
7214
7215   if (bd_id_set == 0)
7216     {
7217       errmsg ("missing bridge domain");
7218       return -99;
7219     }
7220
7221   M (BRIDGE_FLAGS, mp);
7222
7223   mp->bd_id = ntohl (bd_id);
7224   mp->feature_bitmap = ntohl (flags);
7225   mp->is_set = is_set;
7226
7227   S (mp);
7228   W (ret);
7229   return ret;
7230 }
7231
7232 static int
7233 api_bd_ip_mac_add_del (vat_main_t * vam)
7234 {
7235   unformat_input_t *i = vam->input;
7236   vl_api_bd_ip_mac_add_del_t *mp;
7237   u32 bd_id;
7238   u8 is_ipv6 = 0;
7239   u8 is_add = 1;
7240   u8 bd_id_set = 0;
7241   u8 ip_set = 0;
7242   u8 mac_set = 0;
7243   ip4_address_t v4addr;
7244   ip6_address_t v6addr;
7245   u8 macaddr[6];
7246   int ret;
7247
7248
7249   /* Parse args required to build the message */
7250   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7251     {
7252       if (unformat (i, "bd_id %d", &bd_id))
7253         {
7254           bd_id_set++;
7255         }
7256       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7257         {
7258           ip_set++;
7259         }
7260       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7261         {
7262           ip_set++;
7263           is_ipv6++;
7264         }
7265       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7266         {
7267           mac_set++;
7268         }
7269       else if (unformat (i, "del"))
7270         is_add = 0;
7271       else
7272         break;
7273     }
7274
7275   if (bd_id_set == 0)
7276     {
7277       errmsg ("missing bridge domain");
7278       return -99;
7279     }
7280   else if (ip_set == 0)
7281     {
7282       errmsg ("missing IP address");
7283       return -99;
7284     }
7285   else if (mac_set == 0)
7286     {
7287       errmsg ("missing MAC address");
7288       return -99;
7289     }
7290
7291   M (BD_IP_MAC_ADD_DEL, mp);
7292
7293   mp->bd_id = ntohl (bd_id);
7294   mp->is_ipv6 = is_ipv6;
7295   mp->is_add = is_add;
7296   if (is_ipv6)
7297     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7298   else
7299     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7300   clib_memcpy (mp->mac_address, macaddr, 6);
7301   S (mp);
7302   W (ret);
7303   return ret;
7304 }
7305
7306 static int
7307 api_tap_connect (vat_main_t * vam)
7308 {
7309   unformat_input_t *i = vam->input;
7310   vl_api_tap_connect_t *mp;
7311   u8 mac_address[6];
7312   u8 random_mac = 1;
7313   u8 name_set = 0;
7314   u8 *tap_name;
7315   u8 *tag = 0;
7316   ip4_address_t ip4_address;
7317   u32 ip4_mask_width;
7318   int ip4_address_set = 0;
7319   ip6_address_t ip6_address;
7320   u32 ip6_mask_width;
7321   int ip6_address_set = 0;
7322   int ret;
7323
7324   memset (mac_address, 0, sizeof (mac_address));
7325
7326   /* Parse args required to build the message */
7327   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7328     {
7329       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7330         {
7331           random_mac = 0;
7332         }
7333       else if (unformat (i, "random-mac"))
7334         random_mac = 1;
7335       else if (unformat (i, "tapname %s", &tap_name))
7336         name_set = 1;
7337       else if (unformat (i, "tag %s", &tag))
7338         ;
7339       else if (unformat (i, "address %U/%d",
7340                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7341         ip4_address_set = 1;
7342       else if (unformat (i, "address %U/%d",
7343                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7344         ip6_address_set = 1;
7345       else
7346         break;
7347     }
7348
7349   if (name_set == 0)
7350     {
7351       errmsg ("missing tap name");
7352       return -99;
7353     }
7354   if (vec_len (tap_name) > 63)
7355     {
7356       errmsg ("tap name too long");
7357       return -99;
7358     }
7359   vec_add1 (tap_name, 0);
7360
7361   if (vec_len (tag) > 63)
7362     {
7363       errmsg ("tag too long");
7364       return -99;
7365     }
7366
7367   /* Construct the API message */
7368   M (TAP_CONNECT, mp);
7369
7370   mp->use_random_mac = random_mac;
7371   clib_memcpy (mp->mac_address, mac_address, 6);
7372   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7373   if (tag)
7374     clib_memcpy (mp->tag, tag, vec_len (tag));
7375
7376   if (ip4_address_set)
7377     {
7378       mp->ip4_address_set = 1;
7379       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7380       mp->ip4_mask_width = ip4_mask_width;
7381     }
7382   if (ip6_address_set)
7383     {
7384       mp->ip6_address_set = 1;
7385       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7386       mp->ip6_mask_width = ip6_mask_width;
7387     }
7388
7389   vec_free (tap_name);
7390   vec_free (tag);
7391
7392   /* send it... */
7393   S (mp);
7394
7395   /* Wait for a reply... */
7396   W (ret);
7397   return ret;
7398 }
7399
7400 static int
7401 api_tap_modify (vat_main_t * vam)
7402 {
7403   unformat_input_t *i = vam->input;
7404   vl_api_tap_modify_t *mp;
7405   u8 mac_address[6];
7406   u8 random_mac = 1;
7407   u8 name_set = 0;
7408   u8 *tap_name;
7409   u32 sw_if_index = ~0;
7410   u8 sw_if_index_set = 0;
7411   int ret;
7412
7413   memset (mac_address, 0, sizeof (mac_address));
7414
7415   /* Parse args required to build the message */
7416   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7417     {
7418       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7419         sw_if_index_set = 1;
7420       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7421         sw_if_index_set = 1;
7422       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7423         {
7424           random_mac = 0;
7425         }
7426       else if (unformat (i, "random-mac"))
7427         random_mac = 1;
7428       else if (unformat (i, "tapname %s", &tap_name))
7429         name_set = 1;
7430       else
7431         break;
7432     }
7433
7434   if (sw_if_index_set == 0)
7435     {
7436       errmsg ("missing vpp interface name");
7437       return -99;
7438     }
7439   if (name_set == 0)
7440     {
7441       errmsg ("missing tap name");
7442       return -99;
7443     }
7444   if (vec_len (tap_name) > 63)
7445     {
7446       errmsg ("tap name too long");
7447     }
7448   vec_add1 (tap_name, 0);
7449
7450   /* Construct the API message */
7451   M (TAP_MODIFY, mp);
7452
7453   mp->use_random_mac = random_mac;
7454   mp->sw_if_index = ntohl (sw_if_index);
7455   clib_memcpy (mp->mac_address, mac_address, 6);
7456   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7457   vec_free (tap_name);
7458
7459   /* send it... */
7460   S (mp);
7461
7462   /* Wait for a reply... */
7463   W (ret);
7464   return ret;
7465 }
7466
7467 static int
7468 api_tap_delete (vat_main_t * vam)
7469 {
7470   unformat_input_t *i = vam->input;
7471   vl_api_tap_delete_t *mp;
7472   u32 sw_if_index = ~0;
7473   u8 sw_if_index_set = 0;
7474   int ret;
7475
7476   /* Parse args required to build the message */
7477   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7478     {
7479       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7480         sw_if_index_set = 1;
7481       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7482         sw_if_index_set = 1;
7483       else
7484         break;
7485     }
7486
7487   if (sw_if_index_set == 0)
7488     {
7489       errmsg ("missing vpp interface name");
7490       return -99;
7491     }
7492
7493   /* Construct the API message */
7494   M (TAP_DELETE, mp);
7495
7496   mp->sw_if_index = ntohl (sw_if_index);
7497
7498   /* send it... */
7499   S (mp);
7500
7501   /* Wait for a reply... */
7502   W (ret);
7503   return ret;
7504 }
7505
7506 static int
7507 api_ip_table_add_del (vat_main_t * vam)
7508 {
7509   unformat_input_t *i = vam->input;
7510   vl_api_ip_table_add_del_t *mp;
7511   u32 table_id = ~0;
7512   u8 is_ipv6 = 0;
7513   u8 is_add = 1;
7514   int ret = 0;
7515
7516   /* Parse args required to build the message */
7517   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7518     {
7519       if (unformat (i, "ipv6"))
7520         is_ipv6 = 1;
7521       else if (unformat (i, "del"))
7522         is_add = 0;
7523       else if (unformat (i, "add"))
7524         is_add = 1;
7525       else if (unformat (i, "table %d", &table_id))
7526         ;
7527       else
7528         {
7529           clib_warning ("parse error '%U'", format_unformat_error, i);
7530           return -99;
7531         }
7532     }
7533
7534   if (~0 == table_id)
7535     {
7536       errmsg ("missing table-ID");
7537       return -99;
7538     }
7539
7540   /* Construct the API message */
7541   M (IP_TABLE_ADD_DEL, mp);
7542
7543   mp->table_id = ntohl (table_id);
7544   mp->is_ipv6 = is_ipv6;
7545   mp->is_add = is_add;
7546
7547   /* send it... */
7548   S (mp);
7549
7550   /* Wait for a reply... */
7551   W (ret);
7552
7553   return ret;
7554 }
7555
7556 static int
7557 api_ip_add_del_route (vat_main_t * vam)
7558 {
7559   unformat_input_t *i = vam->input;
7560   vl_api_ip_add_del_route_t *mp;
7561   u32 sw_if_index = ~0, vrf_id = 0;
7562   u8 is_ipv6 = 0;
7563   u8 is_local = 0, is_drop = 0;
7564   u8 is_unreach = 0, is_prohibit = 0;
7565   u8 create_vrf_if_needed = 0;
7566   u8 is_add = 1;
7567   u32 next_hop_weight = 1;
7568   u8 not_last = 0;
7569   u8 is_multipath = 0;
7570   u8 address_set = 0;
7571   u8 address_length_set = 0;
7572   u32 next_hop_table_id = 0;
7573   u32 resolve_attempts = 0;
7574   u32 dst_address_length = 0;
7575   u8 next_hop_set = 0;
7576   ip4_address_t v4_dst_address, v4_next_hop_address;
7577   ip6_address_t v6_dst_address, v6_next_hop_address;
7578   int count = 1;
7579   int j;
7580   f64 before = 0;
7581   u32 random_add_del = 0;
7582   u32 *random_vector = 0;
7583   uword *random_hash;
7584   u32 random_seed = 0xdeaddabe;
7585   u32 classify_table_index = ~0;
7586   u8 is_classify = 0;
7587   u8 resolve_host = 0, resolve_attached = 0;
7588   mpls_label_t *next_hop_out_label_stack = NULL;
7589   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7590   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7591
7592   /* Parse args required to build the message */
7593   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7594     {
7595       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7596         ;
7597       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7598         ;
7599       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
7600         {
7601           address_set = 1;
7602           is_ipv6 = 0;
7603         }
7604       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
7605         {
7606           address_set = 1;
7607           is_ipv6 = 1;
7608         }
7609       else if (unformat (i, "/%d", &dst_address_length))
7610         {
7611           address_length_set = 1;
7612         }
7613
7614       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
7615                                          &v4_next_hop_address))
7616         {
7617           next_hop_set = 1;
7618         }
7619       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
7620                                          &v6_next_hop_address))
7621         {
7622           next_hop_set = 1;
7623         }
7624       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
7625         ;
7626       else if (unformat (i, "weight %d", &next_hop_weight))
7627         ;
7628       else if (unformat (i, "drop"))
7629         {
7630           is_drop = 1;
7631         }
7632       else if (unformat (i, "null-send-unreach"))
7633         {
7634           is_unreach = 1;
7635         }
7636       else if (unformat (i, "null-send-prohibit"))
7637         {
7638           is_prohibit = 1;
7639         }
7640       else if (unformat (i, "local"))
7641         {
7642           is_local = 1;
7643         }
7644       else if (unformat (i, "classify %d", &classify_table_index))
7645         {
7646           is_classify = 1;
7647         }
7648       else if (unformat (i, "del"))
7649         is_add = 0;
7650       else if (unformat (i, "add"))
7651         is_add = 1;
7652       else if (unformat (i, "not-last"))
7653         not_last = 1;
7654       else if (unformat (i, "resolve-via-host"))
7655         resolve_host = 1;
7656       else if (unformat (i, "resolve-via-attached"))
7657         resolve_attached = 1;
7658       else if (unformat (i, "multipath"))
7659         is_multipath = 1;
7660       else if (unformat (i, "vrf %d", &vrf_id))
7661         ;
7662       else if (unformat (i, "create-vrf"))
7663         create_vrf_if_needed = 1;
7664       else if (unformat (i, "count %d", &count))
7665         ;
7666       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
7667         ;
7668       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7669         ;
7670       else if (unformat (i, "out-label %d", &next_hop_out_label))
7671         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7672       else if (unformat (i, "via-label %d", &next_hop_via_label))
7673         ;
7674       else if (unformat (i, "random"))
7675         random_add_del = 1;
7676       else if (unformat (i, "seed %d", &random_seed))
7677         ;
7678       else
7679         {
7680           clib_warning ("parse error '%U'", format_unformat_error, i);
7681           return -99;
7682         }
7683     }
7684
7685   if (!next_hop_set && !is_drop && !is_local &&
7686       !is_classify && !is_unreach && !is_prohibit &&
7687       MPLS_LABEL_INVALID == next_hop_via_label)
7688     {
7689       errmsg
7690         ("next hop / local / drop / unreach / prohibit / classify not set");
7691       return -99;
7692     }
7693
7694   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
7695     {
7696       errmsg ("next hop and next-hop via label set");
7697       return -99;
7698     }
7699   if (address_set == 0)
7700     {
7701       errmsg ("missing addresses");
7702       return -99;
7703     }
7704
7705   if (address_length_set == 0)
7706     {
7707       errmsg ("missing address length");
7708       return -99;
7709     }
7710
7711   /* Generate a pile of unique, random routes */
7712   if (random_add_del)
7713     {
7714       u32 this_random_address;
7715       random_hash = hash_create (count, sizeof (uword));
7716
7717       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
7718       for (j = 0; j <= count; j++)
7719         {
7720           do
7721             {
7722               this_random_address = random_u32 (&random_seed);
7723               this_random_address =
7724                 clib_host_to_net_u32 (this_random_address);
7725             }
7726           while (hash_get (random_hash, this_random_address));
7727           vec_add1 (random_vector, this_random_address);
7728           hash_set (random_hash, this_random_address, 1);
7729         }
7730       hash_free (random_hash);
7731       v4_dst_address.as_u32 = random_vector[0];
7732     }
7733
7734   if (count > 1)
7735     {
7736       /* Turn on async mode */
7737       vam->async_mode = 1;
7738       vam->async_errors = 0;
7739       before = vat_time_now (vam);
7740     }
7741
7742   for (j = 0; j < count; j++)
7743     {
7744       /* Construct the API message */
7745       M2 (IP_ADD_DEL_ROUTE, mp,
7746           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7747
7748       mp->next_hop_sw_if_index = ntohl (sw_if_index);
7749       mp->table_id = ntohl (vrf_id);
7750       mp->create_vrf_if_needed = create_vrf_if_needed;
7751
7752       mp->is_add = is_add;
7753       mp->is_drop = is_drop;
7754       mp->is_unreach = is_unreach;
7755       mp->is_prohibit = is_prohibit;
7756       mp->is_ipv6 = is_ipv6;
7757       mp->is_local = is_local;
7758       mp->is_classify = is_classify;
7759       mp->is_multipath = is_multipath;
7760       mp->is_resolve_host = resolve_host;
7761       mp->is_resolve_attached = resolve_attached;
7762       mp->not_last = not_last;
7763       mp->next_hop_weight = next_hop_weight;
7764       mp->dst_address_length = dst_address_length;
7765       mp->next_hop_table_id = ntohl (next_hop_table_id);
7766       mp->classify_table_index = ntohl (classify_table_index);
7767       mp->next_hop_via_label = ntohl (next_hop_via_label);
7768       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7769       if (0 != mp->next_hop_n_out_labels)
7770         {
7771           memcpy (mp->next_hop_out_label_stack,
7772                   next_hop_out_label_stack,
7773                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7774           vec_free (next_hop_out_label_stack);
7775         }
7776
7777       if (is_ipv6)
7778         {
7779           clib_memcpy (mp->dst_address, &v6_dst_address,
7780                        sizeof (v6_dst_address));
7781           if (next_hop_set)
7782             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
7783                          sizeof (v6_next_hop_address));
7784           increment_v6_address (&v6_dst_address);
7785         }
7786       else
7787         {
7788           clib_memcpy (mp->dst_address, &v4_dst_address,
7789                        sizeof (v4_dst_address));
7790           if (next_hop_set)
7791             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
7792                          sizeof (v4_next_hop_address));
7793           if (random_add_del)
7794             v4_dst_address.as_u32 = random_vector[j + 1];
7795           else
7796             increment_v4_address (&v4_dst_address);
7797         }
7798       /* send it... */
7799       S (mp);
7800       /* If we receive SIGTERM, stop now... */
7801       if (vam->do_exit)
7802         break;
7803     }
7804
7805   /* When testing multiple add/del ops, use a control-ping to sync */
7806   if (count > 1)
7807     {
7808       vl_api_control_ping_t *mp_ping;
7809       f64 after;
7810       f64 timeout;
7811
7812       /* Shut off async mode */
7813       vam->async_mode = 0;
7814
7815       MPING (CONTROL_PING, mp_ping);
7816       S (mp_ping);
7817
7818       timeout = vat_time_now (vam) + 1.0;
7819       while (vat_time_now (vam) < timeout)
7820         if (vam->result_ready == 1)
7821           goto out;
7822       vam->retval = -99;
7823
7824     out:
7825       if (vam->retval == -99)
7826         errmsg ("timeout");
7827
7828       if (vam->async_errors > 0)
7829         {
7830           errmsg ("%d asynchronous errors", vam->async_errors);
7831           vam->retval = -98;
7832         }
7833       vam->async_errors = 0;
7834       after = vat_time_now (vam);
7835
7836       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7837       if (j > 0)
7838         count = j;
7839
7840       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7841              count, after - before, count / (after - before));
7842     }
7843   else
7844     {
7845       int ret;
7846
7847       /* Wait for a reply... */
7848       W (ret);
7849       return ret;
7850     }
7851
7852   /* Return the good/bad news */
7853   return (vam->retval);
7854 }
7855
7856 static int
7857 api_ip_mroute_add_del (vat_main_t * vam)
7858 {
7859   unformat_input_t *i = vam->input;
7860   vl_api_ip_mroute_add_del_t *mp;
7861   u32 sw_if_index = ~0, vrf_id = 0;
7862   u8 is_ipv6 = 0;
7863   u8 is_local = 0;
7864   u8 create_vrf_if_needed = 0;
7865   u8 is_add = 1;
7866   u8 address_set = 0;
7867   u32 grp_address_length = 0;
7868   ip4_address_t v4_grp_address, v4_src_address;
7869   ip6_address_t v6_grp_address, v6_src_address;
7870   mfib_itf_flags_t iflags = 0;
7871   mfib_entry_flags_t eflags = 0;
7872   int ret;
7873
7874   /* Parse args required to build the message */
7875   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7876     {
7877       if (unformat (i, "sw_if_index %d", &sw_if_index))
7878         ;
7879       else if (unformat (i, "%U %U",
7880                          unformat_ip4_address, &v4_src_address,
7881                          unformat_ip4_address, &v4_grp_address))
7882         {
7883           grp_address_length = 64;
7884           address_set = 1;
7885           is_ipv6 = 0;
7886         }
7887       else if (unformat (i, "%U %U",
7888                          unformat_ip6_address, &v6_src_address,
7889                          unformat_ip6_address, &v6_grp_address))
7890         {
7891           grp_address_length = 256;
7892           address_set = 1;
7893           is_ipv6 = 1;
7894         }
7895       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
7896         {
7897           memset (&v4_src_address, 0, sizeof (v4_src_address));
7898           grp_address_length = 32;
7899           address_set = 1;
7900           is_ipv6 = 0;
7901         }
7902       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
7903         {
7904           memset (&v6_src_address, 0, sizeof (v6_src_address));
7905           grp_address_length = 128;
7906           address_set = 1;
7907           is_ipv6 = 1;
7908         }
7909       else if (unformat (i, "/%d", &grp_address_length))
7910         ;
7911       else if (unformat (i, "local"))
7912         {
7913           is_local = 1;
7914         }
7915       else if (unformat (i, "del"))
7916         is_add = 0;
7917       else if (unformat (i, "add"))
7918         is_add = 1;
7919       else if (unformat (i, "vrf %d", &vrf_id))
7920         ;
7921       else if (unformat (i, "create-vrf"))
7922         create_vrf_if_needed = 1;
7923       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
7924         ;
7925       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
7926         ;
7927       else
7928         {
7929           clib_warning ("parse error '%U'", format_unformat_error, i);
7930           return -99;
7931         }
7932     }
7933
7934   if (address_set == 0)
7935     {
7936       errmsg ("missing addresses\n");
7937       return -99;
7938     }
7939
7940   /* Construct the API message */
7941   M (IP_MROUTE_ADD_DEL, mp);
7942
7943   mp->next_hop_sw_if_index = ntohl (sw_if_index);
7944   mp->table_id = ntohl (vrf_id);
7945   mp->create_vrf_if_needed = create_vrf_if_needed;
7946
7947   mp->is_add = is_add;
7948   mp->is_ipv6 = is_ipv6;
7949   mp->is_local = is_local;
7950   mp->itf_flags = ntohl (iflags);
7951   mp->entry_flags = ntohl (eflags);
7952   mp->grp_address_length = grp_address_length;
7953   mp->grp_address_length = ntohs (mp->grp_address_length);
7954
7955   if (is_ipv6)
7956     {
7957       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
7958       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
7959     }
7960   else
7961     {
7962       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
7963       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
7964
7965     }
7966
7967   /* send it... */
7968   S (mp);
7969   /* Wait for a reply... */
7970   W (ret);
7971   return ret;
7972 }
7973
7974 static int
7975 api_mpls_table_add_del (vat_main_t * vam)
7976 {
7977   unformat_input_t *i = vam->input;
7978   vl_api_mpls_table_add_del_t *mp;
7979   u32 table_id = ~0;
7980   u8 is_add = 1;
7981   int ret = 0;
7982
7983   /* Parse args required to build the message */
7984   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7985     {
7986       if (unformat (i, "table %d", &table_id))
7987         ;
7988       else if (unformat (i, "del"))
7989         is_add = 0;
7990       else if (unformat (i, "add"))
7991         is_add = 1;
7992       else
7993         {
7994           clib_warning ("parse error '%U'", format_unformat_error, i);
7995           return -99;
7996         }
7997     }
7998
7999   if (~0 == table_id)
8000     {
8001       errmsg ("missing table-ID");
8002       return -99;
8003     }
8004
8005   /* Construct the API message */
8006   M (MPLS_TABLE_ADD_DEL, mp);
8007
8008   mp->mt_table_id = ntohl (table_id);
8009   mp->mt_is_add = is_add;
8010
8011   /* send it... */
8012   S (mp);
8013
8014   /* Wait for a reply... */
8015   W (ret);
8016
8017   return ret;
8018 }
8019
8020 static int
8021 api_mpls_route_add_del (vat_main_t * vam)
8022 {
8023   unformat_input_t *i = vam->input;
8024   vl_api_mpls_route_add_del_t *mp;
8025   u32 sw_if_index = ~0, table_id = 0;
8026   u8 create_table_if_needed = 0;
8027   u8 is_add = 1;
8028   u32 next_hop_weight = 1;
8029   u8 is_multipath = 0;
8030   u32 next_hop_table_id = 0;
8031   u8 next_hop_set = 0;
8032   ip4_address_t v4_next_hop_address = {
8033     .as_u32 = 0,
8034   };
8035   ip6_address_t v6_next_hop_address = { {0} };
8036   int count = 1;
8037   int j;
8038   f64 before = 0;
8039   u32 classify_table_index = ~0;
8040   u8 is_classify = 0;
8041   u8 resolve_host = 0, resolve_attached = 0;
8042   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8043   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8044   mpls_label_t *next_hop_out_label_stack = NULL;
8045   mpls_label_t local_label = MPLS_LABEL_INVALID;
8046   u8 is_eos = 0;
8047   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8048
8049   /* Parse args required to build the message */
8050   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8051     {
8052       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8053         ;
8054       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8055         ;
8056       else if (unformat (i, "%d", &local_label))
8057         ;
8058       else if (unformat (i, "eos"))
8059         is_eos = 1;
8060       else if (unformat (i, "non-eos"))
8061         is_eos = 0;
8062       else if (unformat (i, "via %U", unformat_ip4_address,
8063                          &v4_next_hop_address))
8064         {
8065           next_hop_set = 1;
8066           next_hop_proto = DPO_PROTO_IP4;
8067         }
8068       else if (unformat (i, "via %U", unformat_ip6_address,
8069                          &v6_next_hop_address))
8070         {
8071           next_hop_set = 1;
8072           next_hop_proto = DPO_PROTO_IP6;
8073         }
8074       else if (unformat (i, "weight %d", &next_hop_weight))
8075         ;
8076       else if (unformat (i, "create-table"))
8077         create_table_if_needed = 1;
8078       else if (unformat (i, "classify %d", &classify_table_index))
8079         {
8080           is_classify = 1;
8081         }
8082       else if (unformat (i, "del"))
8083         is_add = 0;
8084       else if (unformat (i, "add"))
8085         is_add = 1;
8086       else if (unformat (i, "resolve-via-host"))
8087         resolve_host = 1;
8088       else if (unformat (i, "resolve-via-attached"))
8089         resolve_attached = 1;
8090       else if (unformat (i, "multipath"))
8091         is_multipath = 1;
8092       else if (unformat (i, "count %d", &count))
8093         ;
8094       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8095         {
8096           next_hop_set = 1;
8097           next_hop_proto = DPO_PROTO_IP4;
8098         }
8099       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8100         {
8101           next_hop_set = 1;
8102           next_hop_proto = DPO_PROTO_IP6;
8103         }
8104       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8105         ;
8106       else if (unformat (i, "via-label %d", &next_hop_via_label))
8107         ;
8108       else if (unformat (i, "out-label %d", &next_hop_out_label))
8109         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8110       else
8111         {
8112           clib_warning ("parse error '%U'", format_unformat_error, i);
8113           return -99;
8114         }
8115     }
8116
8117   if (!next_hop_set && !is_classify)
8118     {
8119       errmsg ("next hop / classify not set");
8120       return -99;
8121     }
8122
8123   if (MPLS_LABEL_INVALID == local_label)
8124     {
8125       errmsg ("missing label");
8126       return -99;
8127     }
8128
8129   if (count > 1)
8130     {
8131       /* Turn on async mode */
8132       vam->async_mode = 1;
8133       vam->async_errors = 0;
8134       before = vat_time_now (vam);
8135     }
8136
8137   for (j = 0; j < count; j++)
8138     {
8139       /* Construct the API message */
8140       M2 (MPLS_ROUTE_ADD_DEL, mp,
8141           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8142
8143       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8144       mp->mr_table_id = ntohl (table_id);
8145       mp->mr_create_table_if_needed = create_table_if_needed;
8146
8147       mp->mr_is_add = is_add;
8148       mp->mr_next_hop_proto = next_hop_proto;
8149       mp->mr_is_classify = is_classify;
8150       mp->mr_is_multipath = is_multipath;
8151       mp->mr_is_resolve_host = resolve_host;
8152       mp->mr_is_resolve_attached = resolve_attached;
8153       mp->mr_next_hop_weight = next_hop_weight;
8154       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8155       mp->mr_classify_table_index = ntohl (classify_table_index);
8156       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8157       mp->mr_label = ntohl (local_label);
8158       mp->mr_eos = is_eos;
8159
8160       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8161       if (0 != mp->mr_next_hop_n_out_labels)
8162         {
8163           memcpy (mp->mr_next_hop_out_label_stack,
8164                   next_hop_out_label_stack,
8165                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8166           vec_free (next_hop_out_label_stack);
8167         }
8168
8169       if (next_hop_set)
8170         {
8171           if (DPO_PROTO_IP4 == next_hop_proto)
8172             {
8173               clib_memcpy (mp->mr_next_hop,
8174                            &v4_next_hop_address,
8175                            sizeof (v4_next_hop_address));
8176             }
8177           else if (DPO_PROTO_IP6 == next_hop_proto)
8178
8179             {
8180               clib_memcpy (mp->mr_next_hop,
8181                            &v6_next_hop_address,
8182                            sizeof (v6_next_hop_address));
8183             }
8184         }
8185       local_label++;
8186
8187       /* send it... */
8188       S (mp);
8189       /* If we receive SIGTERM, stop now... */
8190       if (vam->do_exit)
8191         break;
8192     }
8193
8194   /* When testing multiple add/del ops, use a control-ping to sync */
8195   if (count > 1)
8196     {
8197       vl_api_control_ping_t *mp_ping;
8198       f64 after;
8199       f64 timeout;
8200
8201       /* Shut off async mode */
8202       vam->async_mode = 0;
8203
8204       MPING (CONTROL_PING, mp_ping);
8205       S (mp_ping);
8206
8207       timeout = vat_time_now (vam) + 1.0;
8208       while (vat_time_now (vam) < timeout)
8209         if (vam->result_ready == 1)
8210           goto out;
8211       vam->retval = -99;
8212
8213     out:
8214       if (vam->retval == -99)
8215         errmsg ("timeout");
8216
8217       if (vam->async_errors > 0)
8218         {
8219           errmsg ("%d asynchronous errors", vam->async_errors);
8220           vam->retval = -98;
8221         }
8222       vam->async_errors = 0;
8223       after = vat_time_now (vam);
8224
8225       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8226       if (j > 0)
8227         count = j;
8228
8229       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8230              count, after - before, count / (after - before));
8231     }
8232   else
8233     {
8234       int ret;
8235
8236       /* Wait for a reply... */
8237       W (ret);
8238       return ret;
8239     }
8240
8241   /* Return the good/bad news */
8242   return (vam->retval);
8243 }
8244
8245 static int
8246 api_mpls_ip_bind_unbind (vat_main_t * vam)
8247 {
8248   unformat_input_t *i = vam->input;
8249   vl_api_mpls_ip_bind_unbind_t *mp;
8250   u32 ip_table_id = 0;
8251   u8 create_table_if_needed = 0;
8252   u8 is_bind = 1;
8253   u8 is_ip4 = 1;
8254   ip4_address_t v4_address;
8255   ip6_address_t v6_address;
8256   u32 address_length;
8257   u8 address_set = 0;
8258   mpls_label_t local_label = MPLS_LABEL_INVALID;
8259   int ret;
8260
8261   /* Parse args required to build the message */
8262   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8263     {
8264       if (unformat (i, "%U/%d", unformat_ip4_address,
8265                     &v4_address, &address_length))
8266         {
8267           is_ip4 = 1;
8268           address_set = 1;
8269         }
8270       else if (unformat (i, "%U/%d", unformat_ip6_address,
8271                          &v6_address, &address_length))
8272         {
8273           is_ip4 = 0;
8274           address_set = 1;
8275         }
8276       else if (unformat (i, "%d", &local_label))
8277         ;
8278       else if (unformat (i, "create-table"))
8279         create_table_if_needed = 1;
8280       else if (unformat (i, "table-id %d", &ip_table_id))
8281         ;
8282       else if (unformat (i, "unbind"))
8283         is_bind = 0;
8284       else if (unformat (i, "bind"))
8285         is_bind = 1;
8286       else
8287         {
8288           clib_warning ("parse error '%U'", format_unformat_error, i);
8289           return -99;
8290         }
8291     }
8292
8293   if (!address_set)
8294     {
8295       errmsg ("IP addres not set");
8296       return -99;
8297     }
8298
8299   if (MPLS_LABEL_INVALID == local_label)
8300     {
8301       errmsg ("missing label");
8302       return -99;
8303     }
8304
8305   /* Construct the API message */
8306   M (MPLS_IP_BIND_UNBIND, mp);
8307
8308   mp->mb_create_table_if_needed = create_table_if_needed;
8309   mp->mb_is_bind = is_bind;
8310   mp->mb_is_ip4 = is_ip4;
8311   mp->mb_ip_table_id = ntohl (ip_table_id);
8312   mp->mb_mpls_table_id = 0;
8313   mp->mb_label = ntohl (local_label);
8314   mp->mb_address_length = address_length;
8315
8316   if (is_ip4)
8317     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8318   else
8319     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8320
8321   /* send it... */
8322   S (mp);
8323
8324   /* Wait for a reply... */
8325   W (ret);
8326   return ret;
8327 }
8328
8329 static int
8330 api_proxy_arp_add_del (vat_main_t * vam)
8331 {
8332   unformat_input_t *i = vam->input;
8333   vl_api_proxy_arp_add_del_t *mp;
8334   u32 vrf_id = 0;
8335   u8 is_add = 1;
8336   ip4_address_t lo, hi;
8337   u8 range_set = 0;
8338   int ret;
8339
8340   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8341     {
8342       if (unformat (i, "vrf %d", &vrf_id))
8343         ;
8344       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
8345                          unformat_ip4_address, &hi))
8346         range_set = 1;
8347       else if (unformat (i, "del"))
8348         is_add = 0;
8349       else
8350         {
8351           clib_warning ("parse error '%U'", format_unformat_error, i);
8352           return -99;
8353         }
8354     }
8355
8356   if (range_set == 0)
8357     {
8358       errmsg ("address range not set");
8359       return -99;
8360     }
8361
8362   M (PROXY_ARP_ADD_DEL, mp);
8363
8364   mp->vrf_id = ntohl (vrf_id);
8365   mp->is_add = is_add;
8366   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
8367   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
8368
8369   S (mp);
8370   W (ret);
8371   return ret;
8372 }
8373
8374 static int
8375 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8376 {
8377   unformat_input_t *i = vam->input;
8378   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8379   u32 sw_if_index;
8380   u8 enable = 1;
8381   u8 sw_if_index_set = 0;
8382   int ret;
8383
8384   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8385     {
8386       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8387         sw_if_index_set = 1;
8388       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8389         sw_if_index_set = 1;
8390       else if (unformat (i, "enable"))
8391         enable = 1;
8392       else if (unformat (i, "disable"))
8393         enable = 0;
8394       else
8395         {
8396           clib_warning ("parse error '%U'", format_unformat_error, i);
8397           return -99;
8398         }
8399     }
8400
8401   if (sw_if_index_set == 0)
8402     {
8403       errmsg ("missing interface name or sw_if_index");
8404       return -99;
8405     }
8406
8407   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8408
8409   mp->sw_if_index = ntohl (sw_if_index);
8410   mp->enable_disable = enable;
8411
8412   S (mp);
8413   W (ret);
8414   return ret;
8415 }
8416
8417 static int
8418 api_mpls_tunnel_add_del (vat_main_t * vam)
8419 {
8420   unformat_input_t *i = vam->input;
8421   vl_api_mpls_tunnel_add_del_t *mp;
8422
8423   u8 is_add = 1;
8424   u8 l2_only = 0;
8425   u32 sw_if_index = ~0;
8426   u32 next_hop_sw_if_index = ~0;
8427   u32 next_hop_proto_is_ip4 = 1;
8428
8429   u32 next_hop_table_id = 0;
8430   ip4_address_t v4_next_hop_address = {
8431     .as_u32 = 0,
8432   };
8433   ip6_address_t v6_next_hop_address = { {0} };
8434   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
8435   int ret;
8436
8437   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8438     {
8439       if (unformat (i, "add"))
8440         is_add = 1;
8441       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8442         is_add = 0;
8443       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
8444         ;
8445       else if (unformat (i, "via %U",
8446                          unformat_ip4_address, &v4_next_hop_address))
8447         {
8448           next_hop_proto_is_ip4 = 1;
8449         }
8450       else if (unformat (i, "via %U",
8451                          unformat_ip6_address, &v6_next_hop_address))
8452         {
8453           next_hop_proto_is_ip4 = 0;
8454         }
8455       else if (unformat (i, "l2-only"))
8456         l2_only = 1;
8457       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8458         ;
8459       else if (unformat (i, "out-label %d", &next_hop_out_label))
8460         vec_add1 (labels, ntohl (next_hop_out_label));
8461       else
8462         {
8463           clib_warning ("parse error '%U'", format_unformat_error, i);
8464           return -99;
8465         }
8466     }
8467
8468   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
8469
8470   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
8471   mp->mt_sw_if_index = ntohl (sw_if_index);
8472   mp->mt_is_add = is_add;
8473   mp->mt_l2_only = l2_only;
8474   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
8475   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
8476
8477   mp->mt_next_hop_n_out_labels = vec_len (labels);
8478
8479   if (0 != mp->mt_next_hop_n_out_labels)
8480     {
8481       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
8482                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
8483       vec_free (labels);
8484     }
8485
8486   if (next_hop_proto_is_ip4)
8487     {
8488       clib_memcpy (mp->mt_next_hop,
8489                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8490     }
8491   else
8492     {
8493       clib_memcpy (mp->mt_next_hop,
8494                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8495     }
8496
8497   S (mp);
8498   W (ret);
8499   return ret;
8500 }
8501
8502 static int
8503 api_sw_interface_set_unnumbered (vat_main_t * vam)
8504 {
8505   unformat_input_t *i = vam->input;
8506   vl_api_sw_interface_set_unnumbered_t *mp;
8507   u32 sw_if_index;
8508   u32 unnum_sw_index = ~0;
8509   u8 is_add = 1;
8510   u8 sw_if_index_set = 0;
8511   int ret;
8512
8513   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8514     {
8515       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8516         sw_if_index_set = 1;
8517       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8518         sw_if_index_set = 1;
8519       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8520         ;
8521       else if (unformat (i, "del"))
8522         is_add = 0;
8523       else
8524         {
8525           clib_warning ("parse error '%U'", format_unformat_error, i);
8526           return -99;
8527         }
8528     }
8529
8530   if (sw_if_index_set == 0)
8531     {
8532       errmsg ("missing interface name or sw_if_index");
8533       return -99;
8534     }
8535
8536   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8537
8538   mp->sw_if_index = ntohl (sw_if_index);
8539   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8540   mp->is_add = is_add;
8541
8542   S (mp);
8543   W (ret);
8544   return ret;
8545 }
8546
8547 static int
8548 api_ip_neighbor_add_del (vat_main_t * vam)
8549 {
8550   unformat_input_t *i = vam->input;
8551   vl_api_ip_neighbor_add_del_t *mp;
8552   u32 sw_if_index;
8553   u8 sw_if_index_set = 0;
8554   u8 is_add = 1;
8555   u8 is_static = 0;
8556   u8 is_no_fib_entry = 0;
8557   u8 mac_address[6];
8558   u8 mac_set = 0;
8559   u8 v4_address_set = 0;
8560   u8 v6_address_set = 0;
8561   ip4_address_t v4address;
8562   ip6_address_t v6address;
8563   int ret;
8564
8565   memset (mac_address, 0, sizeof (mac_address));
8566
8567   /* Parse args required to build the message */
8568   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8569     {
8570       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8571         {
8572           mac_set = 1;
8573         }
8574       else if (unformat (i, "del"))
8575         is_add = 0;
8576       else
8577         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8578         sw_if_index_set = 1;
8579       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8580         sw_if_index_set = 1;
8581       else if (unformat (i, "is_static"))
8582         is_static = 1;
8583       else if (unformat (i, "no-fib-entry"))
8584         is_no_fib_entry = 1;
8585       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
8586         v4_address_set = 1;
8587       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
8588         v6_address_set = 1;
8589       else
8590         {
8591           clib_warning ("parse error '%U'", format_unformat_error, i);
8592           return -99;
8593         }
8594     }
8595
8596   if (sw_if_index_set == 0)
8597     {
8598       errmsg ("missing interface name or sw_if_index");
8599       return -99;
8600     }
8601   if (v4_address_set && v6_address_set)
8602     {
8603       errmsg ("both v4 and v6 addresses set");
8604       return -99;
8605     }
8606   if (!v4_address_set && !v6_address_set)
8607     {
8608       errmsg ("no address set");
8609       return -99;
8610     }
8611
8612   /* Construct the API message */
8613   M (IP_NEIGHBOR_ADD_DEL, mp);
8614
8615   mp->sw_if_index = ntohl (sw_if_index);
8616   mp->is_add = is_add;
8617   mp->is_static = is_static;
8618   mp->is_no_adj_fib = is_no_fib_entry;
8619   if (mac_set)
8620     clib_memcpy (mp->mac_address, mac_address, 6);
8621   if (v6_address_set)
8622     {
8623       mp->is_ipv6 = 1;
8624       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
8625     }
8626   else
8627     {
8628       /* mp->is_ipv6 = 0; via memset in M macro above */
8629       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
8630     }
8631
8632   /* send it... */
8633   S (mp);
8634
8635   /* Wait for a reply, return good/bad news  */
8636   W (ret);
8637   return ret;
8638 }
8639
8640 static int
8641 api_reset_vrf (vat_main_t * vam)
8642 {
8643   unformat_input_t *i = vam->input;
8644   vl_api_reset_vrf_t *mp;
8645   u32 vrf_id = 0;
8646   u8 is_ipv6 = 0;
8647   u8 vrf_id_set = 0;
8648   int ret;
8649
8650   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8651     {
8652       if (unformat (i, "vrf %d", &vrf_id))
8653         vrf_id_set = 1;
8654       else if (unformat (i, "ipv6"))
8655         is_ipv6 = 1;
8656       else
8657         {
8658           clib_warning ("parse error '%U'", format_unformat_error, i);
8659           return -99;
8660         }
8661     }
8662
8663   if (vrf_id_set == 0)
8664     {
8665       errmsg ("missing vrf id");
8666       return -99;
8667     }
8668
8669   M (RESET_VRF, mp);
8670
8671   mp->vrf_id = ntohl (vrf_id);
8672   mp->is_ipv6 = is_ipv6;
8673
8674   S (mp);
8675   W (ret);
8676   return ret;
8677 }
8678
8679 static int
8680 api_create_vlan_subif (vat_main_t * vam)
8681 {
8682   unformat_input_t *i = vam->input;
8683   vl_api_create_vlan_subif_t *mp;
8684   u32 sw_if_index;
8685   u8 sw_if_index_set = 0;
8686   u32 vlan_id;
8687   u8 vlan_id_set = 0;
8688   int ret;
8689
8690   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8691     {
8692       if (unformat (i, "sw_if_index %d", &sw_if_index))
8693         sw_if_index_set = 1;
8694       else
8695         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8696         sw_if_index_set = 1;
8697       else if (unformat (i, "vlan %d", &vlan_id))
8698         vlan_id_set = 1;
8699       else
8700         {
8701           clib_warning ("parse error '%U'", format_unformat_error, i);
8702           return -99;
8703         }
8704     }
8705
8706   if (sw_if_index_set == 0)
8707     {
8708       errmsg ("missing interface name or sw_if_index");
8709       return -99;
8710     }
8711
8712   if (vlan_id_set == 0)
8713     {
8714       errmsg ("missing vlan_id");
8715       return -99;
8716     }
8717   M (CREATE_VLAN_SUBIF, mp);
8718
8719   mp->sw_if_index = ntohl (sw_if_index);
8720   mp->vlan_id = ntohl (vlan_id);
8721
8722   S (mp);
8723   W (ret);
8724   return ret;
8725 }
8726
8727 #define foreach_create_subif_bit                \
8728 _(no_tags)                                      \
8729 _(one_tag)                                      \
8730 _(two_tags)                                     \
8731 _(dot1ad)                                       \
8732 _(exact_match)                                  \
8733 _(default_sub)                                  \
8734 _(outer_vlan_id_any)                            \
8735 _(inner_vlan_id_any)
8736
8737 static int
8738 api_create_subif (vat_main_t * vam)
8739 {
8740   unformat_input_t *i = vam->input;
8741   vl_api_create_subif_t *mp;
8742   u32 sw_if_index;
8743   u8 sw_if_index_set = 0;
8744   u32 sub_id;
8745   u8 sub_id_set = 0;
8746   u32 no_tags = 0;
8747   u32 one_tag = 0;
8748   u32 two_tags = 0;
8749   u32 dot1ad = 0;
8750   u32 exact_match = 0;
8751   u32 default_sub = 0;
8752   u32 outer_vlan_id_any = 0;
8753   u32 inner_vlan_id_any = 0;
8754   u32 tmp;
8755   u16 outer_vlan_id = 0;
8756   u16 inner_vlan_id = 0;
8757   int ret;
8758
8759   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8760     {
8761       if (unformat (i, "sw_if_index %d", &sw_if_index))
8762         sw_if_index_set = 1;
8763       else
8764         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8765         sw_if_index_set = 1;
8766       else if (unformat (i, "sub_id %d", &sub_id))
8767         sub_id_set = 1;
8768       else if (unformat (i, "outer_vlan_id %d", &tmp))
8769         outer_vlan_id = tmp;
8770       else if (unformat (i, "inner_vlan_id %d", &tmp))
8771         inner_vlan_id = tmp;
8772
8773 #define _(a) else if (unformat (i, #a)) a = 1 ;
8774       foreach_create_subif_bit
8775 #undef _
8776         else
8777         {
8778           clib_warning ("parse error '%U'", format_unformat_error, i);
8779           return -99;
8780         }
8781     }
8782
8783   if (sw_if_index_set == 0)
8784     {
8785       errmsg ("missing interface name or sw_if_index");
8786       return -99;
8787     }
8788
8789   if (sub_id_set == 0)
8790     {
8791       errmsg ("missing sub_id");
8792       return -99;
8793     }
8794   M (CREATE_SUBIF, mp);
8795
8796   mp->sw_if_index = ntohl (sw_if_index);
8797   mp->sub_id = ntohl (sub_id);
8798
8799 #define _(a) mp->a = a;
8800   foreach_create_subif_bit;
8801 #undef _
8802
8803   mp->outer_vlan_id = ntohs (outer_vlan_id);
8804   mp->inner_vlan_id = ntohs (inner_vlan_id);
8805
8806   S (mp);
8807   W (ret);
8808   return ret;
8809 }
8810
8811 static int
8812 api_oam_add_del (vat_main_t * vam)
8813 {
8814   unformat_input_t *i = vam->input;
8815   vl_api_oam_add_del_t *mp;
8816   u32 vrf_id = 0;
8817   u8 is_add = 1;
8818   ip4_address_t src, dst;
8819   u8 src_set = 0;
8820   u8 dst_set = 0;
8821   int ret;
8822
8823   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8824     {
8825       if (unformat (i, "vrf %d", &vrf_id))
8826         ;
8827       else if (unformat (i, "src %U", unformat_ip4_address, &src))
8828         src_set = 1;
8829       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
8830         dst_set = 1;
8831       else if (unformat (i, "del"))
8832         is_add = 0;
8833       else
8834         {
8835           clib_warning ("parse error '%U'", format_unformat_error, i);
8836           return -99;
8837         }
8838     }
8839
8840   if (src_set == 0)
8841     {
8842       errmsg ("missing src addr");
8843       return -99;
8844     }
8845
8846   if (dst_set == 0)
8847     {
8848       errmsg ("missing dst addr");
8849       return -99;
8850     }
8851
8852   M (OAM_ADD_DEL, mp);
8853
8854   mp->vrf_id = ntohl (vrf_id);
8855   mp->is_add = is_add;
8856   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
8857   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
8858
8859   S (mp);
8860   W (ret);
8861   return ret;
8862 }
8863
8864 static int
8865 api_reset_fib (vat_main_t * vam)
8866 {
8867   unformat_input_t *i = vam->input;
8868   vl_api_reset_fib_t *mp;
8869   u32 vrf_id = 0;
8870   u8 is_ipv6 = 0;
8871   u8 vrf_id_set = 0;
8872
8873   int ret;
8874   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8875     {
8876       if (unformat (i, "vrf %d", &vrf_id))
8877         vrf_id_set = 1;
8878       else if (unformat (i, "ipv6"))
8879         is_ipv6 = 1;
8880       else
8881         {
8882           clib_warning ("parse error '%U'", format_unformat_error, i);
8883           return -99;
8884         }
8885     }
8886
8887   if (vrf_id_set == 0)
8888     {
8889       errmsg ("missing vrf id");
8890       return -99;
8891     }
8892
8893   M (RESET_FIB, mp);
8894
8895   mp->vrf_id = ntohl (vrf_id);
8896   mp->is_ipv6 = is_ipv6;
8897
8898   S (mp);
8899   W (ret);
8900   return ret;
8901 }
8902
8903 static int
8904 api_dhcp_proxy_config (vat_main_t * vam)
8905 {
8906   unformat_input_t *i = vam->input;
8907   vl_api_dhcp_proxy_config_t *mp;
8908   u32 rx_vrf_id = 0;
8909   u32 server_vrf_id = 0;
8910   u8 is_add = 1;
8911   u8 v4_address_set = 0;
8912   u8 v6_address_set = 0;
8913   ip4_address_t v4address;
8914   ip6_address_t v6address;
8915   u8 v4_src_address_set = 0;
8916   u8 v6_src_address_set = 0;
8917   ip4_address_t v4srcaddress;
8918   ip6_address_t v6srcaddress;
8919   int ret;
8920
8921   /* Parse args required to build the message */
8922   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8923     {
8924       if (unformat (i, "del"))
8925         is_add = 0;
8926       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
8927         ;
8928       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
8929         ;
8930       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
8931         v4_address_set = 1;
8932       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
8933         v6_address_set = 1;
8934       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
8935         v4_src_address_set = 1;
8936       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
8937         v6_src_address_set = 1;
8938       else
8939         break;
8940     }
8941
8942   if (v4_address_set && v6_address_set)
8943     {
8944       errmsg ("both v4 and v6 server addresses set");
8945       return -99;
8946     }
8947   if (!v4_address_set && !v6_address_set)
8948     {
8949       errmsg ("no server addresses set");
8950       return -99;
8951     }
8952
8953   if (v4_src_address_set && v6_src_address_set)
8954     {
8955       errmsg ("both v4 and v6  src addresses set");
8956       return -99;
8957     }
8958   if (!v4_src_address_set && !v6_src_address_set)
8959     {
8960       errmsg ("no src addresses set");
8961       return -99;
8962     }
8963
8964   if (!(v4_src_address_set && v4_address_set) &&
8965       !(v6_src_address_set && v6_address_set))
8966     {
8967       errmsg ("no matching server and src addresses set");
8968       return -99;
8969     }
8970
8971   /* Construct the API message */
8972   M (DHCP_PROXY_CONFIG, mp);
8973
8974   mp->is_add = is_add;
8975   mp->rx_vrf_id = ntohl (rx_vrf_id);
8976   mp->server_vrf_id = ntohl (server_vrf_id);
8977   if (v6_address_set)
8978     {
8979       mp->is_ipv6 = 1;
8980       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
8981       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
8982     }
8983   else
8984     {
8985       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
8986       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
8987     }
8988
8989   /* send it... */
8990   S (mp);
8991
8992   /* Wait for a reply, return good/bad news  */
8993   W (ret);
8994   return ret;
8995 }
8996
8997 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
8998 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
8999
9000 static void
9001 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
9002 {
9003   vat_main_t *vam = &vat_main;
9004   u32 i, count = mp->count;
9005   vl_api_dhcp_server_t *s;
9006
9007   if (mp->is_ipv6)
9008     print (vam->ofp,
9009            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
9010            ntohl (mp->rx_vrf_id),
9011            format_ip6_address, mp->dhcp_src_address,
9012            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9013   else
9014     print (vam->ofp,
9015            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
9016            ntohl (mp->rx_vrf_id),
9017            format_ip4_address, mp->dhcp_src_address,
9018            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9019
9020   for (i = 0; i < count; i++)
9021     {
9022       s = &mp->servers[i];
9023
9024       if (mp->is_ipv6)
9025         print (vam->ofp,
9026                " Server Table-ID %d, Server Address %U",
9027                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9028       else
9029         print (vam->ofp,
9030                " Server Table-ID %d, Server Address %U",
9031                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9032     }
9033 }
9034
9035 static void vl_api_dhcp_proxy_details_t_handler_json
9036   (vl_api_dhcp_proxy_details_t * mp)
9037 {
9038   vat_main_t *vam = &vat_main;
9039   vat_json_node_t *node = NULL;
9040   u32 i, count = mp->count;
9041   struct in_addr ip4;
9042   struct in6_addr ip6;
9043   vl_api_dhcp_server_t *s;
9044
9045   if (VAT_JSON_ARRAY != vam->json_tree.type)
9046     {
9047       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9048       vat_json_init_array (&vam->json_tree);
9049     }
9050   node = vat_json_array_add (&vam->json_tree);
9051
9052   vat_json_init_object (node);
9053   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9054   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9055   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9056
9057   if (mp->is_ipv6)
9058     {
9059       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9060       vat_json_object_add_ip6 (node, "src_address", ip6);
9061     }
9062   else
9063     {
9064       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9065       vat_json_object_add_ip4 (node, "src_address", ip4);
9066     }
9067
9068   for (i = 0; i < count; i++)
9069     {
9070       s = &mp->servers[i];
9071
9072       vat_json_object_add_uint (node, "server-table-id",
9073                                 ntohl (s->server_vrf_id));
9074
9075       if (mp->is_ipv6)
9076         {
9077           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9078           vat_json_object_add_ip4 (node, "src_address", ip4);
9079         }
9080       else
9081         {
9082           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9083           vat_json_object_add_ip6 (node, "server_address", ip6);
9084         }
9085     }
9086 }
9087
9088 static int
9089 api_dhcp_proxy_dump (vat_main_t * vam)
9090 {
9091   unformat_input_t *i = vam->input;
9092   vl_api_control_ping_t *mp_ping;
9093   vl_api_dhcp_proxy_dump_t *mp;
9094   u8 is_ipv6 = 0;
9095   int ret;
9096
9097   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9098     {
9099       if (unformat (i, "ipv6"))
9100         is_ipv6 = 1;
9101       else
9102         {
9103           clib_warning ("parse error '%U'", format_unformat_error, i);
9104           return -99;
9105         }
9106     }
9107
9108   M (DHCP_PROXY_DUMP, mp);
9109
9110   mp->is_ip6 = is_ipv6;
9111   S (mp);
9112
9113   /* Use a control ping for synchronization */
9114   MPING (CONTROL_PING, mp_ping);
9115   S (mp_ping);
9116
9117   W (ret);
9118   return ret;
9119 }
9120
9121 static int
9122 api_dhcp_proxy_set_vss (vat_main_t * vam)
9123 {
9124   unformat_input_t *i = vam->input;
9125   vl_api_dhcp_proxy_set_vss_t *mp;
9126   u8 is_ipv6 = 0;
9127   u8 is_add = 1;
9128   u32 tbl_id;
9129   u8 tbl_id_set = 0;
9130   u32 oui;
9131   u8 oui_set = 0;
9132   u32 fib_id;
9133   u8 fib_id_set = 0;
9134   int ret;
9135
9136   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9137     {
9138       if (unformat (i, "tbl_id %d", &tbl_id))
9139         tbl_id_set = 1;
9140       if (unformat (i, "fib_id %d", &fib_id))
9141         fib_id_set = 1;
9142       if (unformat (i, "oui %d", &oui))
9143         oui_set = 1;
9144       else if (unformat (i, "ipv6"))
9145         is_ipv6 = 1;
9146       else if (unformat (i, "del"))
9147         is_add = 0;
9148       else
9149         {
9150           clib_warning ("parse error '%U'", format_unformat_error, i);
9151           return -99;
9152         }
9153     }
9154
9155   if (tbl_id_set == 0)
9156     {
9157       errmsg ("missing tbl id");
9158       return -99;
9159     }
9160
9161   if (fib_id_set == 0)
9162     {
9163       errmsg ("missing fib id");
9164       return -99;
9165     }
9166   if (oui_set == 0)
9167     {
9168       errmsg ("missing oui");
9169       return -99;
9170     }
9171
9172   M (DHCP_PROXY_SET_VSS, mp);
9173   mp->tbl_id = ntohl (tbl_id);
9174   mp->fib_id = ntohl (fib_id);
9175   mp->oui = ntohl (oui);
9176   mp->is_ipv6 = is_ipv6;
9177   mp->is_add = is_add;
9178
9179   S (mp);
9180   W (ret);
9181   return ret;
9182 }
9183
9184 static int
9185 api_dhcp_client_config (vat_main_t * vam)
9186 {
9187   unformat_input_t *i = vam->input;
9188   vl_api_dhcp_client_config_t *mp;
9189   u32 sw_if_index;
9190   u8 sw_if_index_set = 0;
9191   u8 is_add = 1;
9192   u8 *hostname = 0;
9193   u8 disable_event = 0;
9194   int ret;
9195
9196   /* Parse args required to build the message */
9197   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9198     {
9199       if (unformat (i, "del"))
9200         is_add = 0;
9201       else
9202         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9203         sw_if_index_set = 1;
9204       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9205         sw_if_index_set = 1;
9206       else if (unformat (i, "hostname %s", &hostname))
9207         ;
9208       else if (unformat (i, "disable_event"))
9209         disable_event = 1;
9210       else
9211         break;
9212     }
9213
9214   if (sw_if_index_set == 0)
9215     {
9216       errmsg ("missing interface name or sw_if_index");
9217       return -99;
9218     }
9219
9220   if (vec_len (hostname) > 63)
9221     {
9222       errmsg ("hostname too long");
9223     }
9224   vec_add1 (hostname, 0);
9225
9226   /* Construct the API message */
9227   M (DHCP_CLIENT_CONFIG, mp);
9228
9229   mp->sw_if_index = htonl (sw_if_index);
9230   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
9231   vec_free (hostname);
9232   mp->is_add = is_add;
9233   mp->want_dhcp_event = disable_event ? 0 : 1;
9234   mp->pid = htonl (getpid ());
9235
9236   /* send it... */
9237   S (mp);
9238
9239   /* Wait for a reply, return good/bad news  */
9240   W (ret);
9241   return ret;
9242 }
9243
9244 static int
9245 api_set_ip_flow_hash (vat_main_t * vam)
9246 {
9247   unformat_input_t *i = vam->input;
9248   vl_api_set_ip_flow_hash_t *mp;
9249   u32 vrf_id = 0;
9250   u8 is_ipv6 = 0;
9251   u8 vrf_id_set = 0;
9252   u8 src = 0;
9253   u8 dst = 0;
9254   u8 sport = 0;
9255   u8 dport = 0;
9256   u8 proto = 0;
9257   u8 reverse = 0;
9258   int ret;
9259
9260   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9261     {
9262       if (unformat (i, "vrf %d", &vrf_id))
9263         vrf_id_set = 1;
9264       else if (unformat (i, "ipv6"))
9265         is_ipv6 = 1;
9266       else if (unformat (i, "src"))
9267         src = 1;
9268       else if (unformat (i, "dst"))
9269         dst = 1;
9270       else if (unformat (i, "sport"))
9271         sport = 1;
9272       else if (unformat (i, "dport"))
9273         dport = 1;
9274       else if (unformat (i, "proto"))
9275         proto = 1;
9276       else if (unformat (i, "reverse"))
9277         reverse = 1;
9278
9279       else
9280         {
9281           clib_warning ("parse error '%U'", format_unformat_error, i);
9282           return -99;
9283         }
9284     }
9285
9286   if (vrf_id_set == 0)
9287     {
9288       errmsg ("missing vrf id");
9289       return -99;
9290     }
9291
9292   M (SET_IP_FLOW_HASH, mp);
9293   mp->src = src;
9294   mp->dst = dst;
9295   mp->sport = sport;
9296   mp->dport = dport;
9297   mp->proto = proto;
9298   mp->reverse = reverse;
9299   mp->vrf_id = ntohl (vrf_id);
9300   mp->is_ipv6 = is_ipv6;
9301
9302   S (mp);
9303   W (ret);
9304   return ret;
9305 }
9306
9307 static int
9308 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9309 {
9310   unformat_input_t *i = vam->input;
9311   vl_api_sw_interface_ip6_enable_disable_t *mp;
9312   u32 sw_if_index;
9313   u8 sw_if_index_set = 0;
9314   u8 enable = 0;
9315   int ret;
9316
9317   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9318     {
9319       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9320         sw_if_index_set = 1;
9321       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9322         sw_if_index_set = 1;
9323       else if (unformat (i, "enable"))
9324         enable = 1;
9325       else if (unformat (i, "disable"))
9326         enable = 0;
9327       else
9328         {
9329           clib_warning ("parse error '%U'", format_unformat_error, i);
9330           return -99;
9331         }
9332     }
9333
9334   if (sw_if_index_set == 0)
9335     {
9336       errmsg ("missing interface name or sw_if_index");
9337       return -99;
9338     }
9339
9340   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9341
9342   mp->sw_if_index = ntohl (sw_if_index);
9343   mp->enable = enable;
9344
9345   S (mp);
9346   W (ret);
9347   return ret;
9348 }
9349
9350 static int
9351 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
9352 {
9353   unformat_input_t *i = vam->input;
9354   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
9355   u32 sw_if_index;
9356   u8 sw_if_index_set = 0;
9357   u8 v6_address_set = 0;
9358   ip6_address_t v6address;
9359   int ret;
9360
9361   /* Parse args required to build the message */
9362   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9363     {
9364       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9365         sw_if_index_set = 1;
9366       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9367         sw_if_index_set = 1;
9368       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9369         v6_address_set = 1;
9370       else
9371         break;
9372     }
9373
9374   if (sw_if_index_set == 0)
9375     {
9376       errmsg ("missing interface name or sw_if_index");
9377       return -99;
9378     }
9379   if (!v6_address_set)
9380     {
9381       errmsg ("no address set");
9382       return -99;
9383     }
9384
9385   /* Construct the API message */
9386   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
9387
9388   mp->sw_if_index = ntohl (sw_if_index);
9389   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9390
9391   /* send it... */
9392   S (mp);
9393
9394   /* Wait for a reply, return good/bad news  */
9395   W (ret);
9396   return ret;
9397 }
9398
9399 static int
9400 api_ip6nd_proxy_add_del (vat_main_t * vam)
9401 {
9402   unformat_input_t *i = vam->input;
9403   vl_api_ip6nd_proxy_add_del_t *mp;
9404   u32 sw_if_index = ~0;
9405   u8 v6_address_set = 0;
9406   ip6_address_t v6address;
9407   u8 is_del = 0;
9408   int ret;
9409
9410   /* Parse args required to build the message */
9411   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9412     {
9413       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9414         ;
9415       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9416         ;
9417       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9418         v6_address_set = 1;
9419       if (unformat (i, "del"))
9420         is_del = 1;
9421       else
9422         {
9423           clib_warning ("parse error '%U'", format_unformat_error, i);
9424           return -99;
9425         }
9426     }
9427
9428   if (sw_if_index == ~0)
9429     {
9430       errmsg ("missing interface name or sw_if_index");
9431       return -99;
9432     }
9433   if (!v6_address_set)
9434     {
9435       errmsg ("no address set");
9436       return -99;
9437     }
9438
9439   /* Construct the API message */
9440   M (IP6ND_PROXY_ADD_DEL, mp);
9441
9442   mp->is_del = is_del;
9443   mp->sw_if_index = ntohl (sw_if_index);
9444   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9445
9446   /* send it... */
9447   S (mp);
9448
9449   /* Wait for a reply, return good/bad news  */
9450   W (ret);
9451   return ret;
9452 }
9453
9454 static int
9455 api_ip6nd_proxy_dump (vat_main_t * vam)
9456 {
9457   vl_api_ip6nd_proxy_dump_t *mp;
9458   vl_api_control_ping_t *mp_ping;
9459   int ret;
9460
9461   M (IP6ND_PROXY_DUMP, mp);
9462
9463   S (mp);
9464
9465   /* Use a control ping for synchronization */
9466   MPING (CONTROL_PING, mp_ping);
9467   S (mp_ping);
9468
9469   W (ret);
9470   return ret;
9471 }
9472
9473 static void vl_api_ip6nd_proxy_details_t_handler
9474   (vl_api_ip6nd_proxy_details_t * mp)
9475 {
9476   vat_main_t *vam = &vat_main;
9477
9478   print (vam->ofp, "host %U sw_if_index %d",
9479          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
9480 }
9481
9482 static void vl_api_ip6nd_proxy_details_t_handler_json
9483   (vl_api_ip6nd_proxy_details_t * mp)
9484 {
9485   vat_main_t *vam = &vat_main;
9486   struct in6_addr ip6;
9487   vat_json_node_t *node = NULL;
9488
9489   if (VAT_JSON_ARRAY != vam->json_tree.type)
9490     {
9491       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9492       vat_json_init_array (&vam->json_tree);
9493     }
9494   node = vat_json_array_add (&vam->json_tree);
9495
9496   vat_json_init_object (node);
9497   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9498
9499   clib_memcpy (&ip6, mp->address, sizeof (ip6));
9500   vat_json_object_add_ip6 (node, "host", ip6);
9501 }
9502
9503 static int
9504 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9505 {
9506   unformat_input_t *i = vam->input;
9507   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9508   u32 sw_if_index;
9509   u8 sw_if_index_set = 0;
9510   u32 address_length = 0;
9511   u8 v6_address_set = 0;
9512   ip6_address_t v6address;
9513   u8 use_default = 0;
9514   u8 no_advertise = 0;
9515   u8 off_link = 0;
9516   u8 no_autoconfig = 0;
9517   u8 no_onlink = 0;
9518   u8 is_no = 0;
9519   u32 val_lifetime = 0;
9520   u32 pref_lifetime = 0;
9521   int ret;
9522
9523   /* Parse args required to build the message */
9524   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9525     {
9526       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9527         sw_if_index_set = 1;
9528       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9529         sw_if_index_set = 1;
9530       else if (unformat (i, "%U/%d",
9531                          unformat_ip6_address, &v6address, &address_length))
9532         v6_address_set = 1;
9533       else if (unformat (i, "val_life %d", &val_lifetime))
9534         ;
9535       else if (unformat (i, "pref_life %d", &pref_lifetime))
9536         ;
9537       else if (unformat (i, "def"))
9538         use_default = 1;
9539       else if (unformat (i, "noadv"))
9540         no_advertise = 1;
9541       else if (unformat (i, "offl"))
9542         off_link = 1;
9543       else if (unformat (i, "noauto"))
9544         no_autoconfig = 1;
9545       else if (unformat (i, "nolink"))
9546         no_onlink = 1;
9547       else if (unformat (i, "isno"))
9548         is_no = 1;
9549       else
9550         {
9551           clib_warning ("parse error '%U'", format_unformat_error, i);
9552           return -99;
9553         }
9554     }
9555
9556   if (sw_if_index_set == 0)
9557     {
9558       errmsg ("missing interface name or sw_if_index");
9559       return -99;
9560     }
9561   if (!v6_address_set)
9562     {
9563       errmsg ("no address set");
9564       return -99;
9565     }
9566
9567   /* Construct the API message */
9568   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9569
9570   mp->sw_if_index = ntohl (sw_if_index);
9571   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9572   mp->address_length = address_length;
9573   mp->use_default = use_default;
9574   mp->no_advertise = no_advertise;
9575   mp->off_link = off_link;
9576   mp->no_autoconfig = no_autoconfig;
9577   mp->no_onlink = no_onlink;
9578   mp->is_no = is_no;
9579   mp->val_lifetime = ntohl (val_lifetime);
9580   mp->pref_lifetime = ntohl (pref_lifetime);
9581
9582   /* send it... */
9583   S (mp);
9584
9585   /* Wait for a reply, return good/bad news  */
9586   W (ret);
9587   return ret;
9588 }
9589
9590 static int
9591 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9592 {
9593   unformat_input_t *i = vam->input;
9594   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9595   u32 sw_if_index;
9596   u8 sw_if_index_set = 0;
9597   u8 suppress = 0;
9598   u8 managed = 0;
9599   u8 other = 0;
9600   u8 ll_option = 0;
9601   u8 send_unicast = 0;
9602   u8 cease = 0;
9603   u8 is_no = 0;
9604   u8 default_router = 0;
9605   u32 max_interval = 0;
9606   u32 min_interval = 0;
9607   u32 lifetime = 0;
9608   u32 initial_count = 0;
9609   u32 initial_interval = 0;
9610   int ret;
9611
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, "maxint %d", &max_interval))
9621         ;
9622       else if (unformat (i, "minint %d", &min_interval))
9623         ;
9624       else if (unformat (i, "life %d", &lifetime))
9625         ;
9626       else if (unformat (i, "count %d", &initial_count))
9627         ;
9628       else if (unformat (i, "interval %d", &initial_interval))
9629         ;
9630       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9631         suppress = 1;
9632       else if (unformat (i, "managed"))
9633         managed = 1;
9634       else if (unformat (i, "other"))
9635         other = 1;
9636       else if (unformat (i, "ll"))
9637         ll_option = 1;
9638       else if (unformat (i, "send"))
9639         send_unicast = 1;
9640       else if (unformat (i, "cease"))
9641         cease = 1;
9642       else if (unformat (i, "isno"))
9643         is_no = 1;
9644       else if (unformat (i, "def"))
9645         default_router = 1;
9646       else
9647         {
9648           clib_warning ("parse error '%U'", format_unformat_error, i);
9649           return -99;
9650         }
9651     }
9652
9653   if (sw_if_index_set == 0)
9654     {
9655       errmsg ("missing interface name or sw_if_index");
9656       return -99;
9657     }
9658
9659   /* Construct the API message */
9660   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9661
9662   mp->sw_if_index = ntohl (sw_if_index);
9663   mp->max_interval = ntohl (max_interval);
9664   mp->min_interval = ntohl (min_interval);
9665   mp->lifetime = ntohl (lifetime);
9666   mp->initial_count = ntohl (initial_count);
9667   mp->initial_interval = ntohl (initial_interval);
9668   mp->suppress = suppress;
9669   mp->managed = managed;
9670   mp->other = other;
9671   mp->ll_option = ll_option;
9672   mp->send_unicast = send_unicast;
9673   mp->cease = cease;
9674   mp->is_no = is_no;
9675   mp->default_router = default_router;
9676
9677   /* send it... */
9678   S (mp);
9679
9680   /* Wait for a reply, return good/bad news  */
9681   W (ret);
9682   return ret;
9683 }
9684
9685 static int
9686 api_set_arp_neighbor_limit (vat_main_t * vam)
9687 {
9688   unformat_input_t *i = vam->input;
9689   vl_api_set_arp_neighbor_limit_t *mp;
9690   u32 arp_nbr_limit;
9691   u8 limit_set = 0;
9692   u8 is_ipv6 = 0;
9693   int ret;
9694
9695   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9696     {
9697       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
9698         limit_set = 1;
9699       else if (unformat (i, "ipv6"))
9700         is_ipv6 = 1;
9701       else
9702         {
9703           clib_warning ("parse error '%U'", format_unformat_error, i);
9704           return -99;
9705         }
9706     }
9707
9708   if (limit_set == 0)
9709     {
9710       errmsg ("missing limit value");
9711       return -99;
9712     }
9713
9714   M (SET_ARP_NEIGHBOR_LIMIT, mp);
9715
9716   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
9717   mp->is_ipv6 = is_ipv6;
9718
9719   S (mp);
9720   W (ret);
9721   return ret;
9722 }
9723
9724 static int
9725 api_l2_patch_add_del (vat_main_t * vam)
9726 {
9727   unformat_input_t *i = vam->input;
9728   vl_api_l2_patch_add_del_t *mp;
9729   u32 rx_sw_if_index;
9730   u8 rx_sw_if_index_set = 0;
9731   u32 tx_sw_if_index;
9732   u8 tx_sw_if_index_set = 0;
9733   u8 is_add = 1;
9734   int ret;
9735
9736   /* Parse args required to build the message */
9737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9738     {
9739       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9740         rx_sw_if_index_set = 1;
9741       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9742         tx_sw_if_index_set = 1;
9743       else if (unformat (i, "rx"))
9744         {
9745           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9746             {
9747               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9748                             &rx_sw_if_index))
9749                 rx_sw_if_index_set = 1;
9750             }
9751           else
9752             break;
9753         }
9754       else if (unformat (i, "tx"))
9755         {
9756           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9757             {
9758               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9759                             &tx_sw_if_index))
9760                 tx_sw_if_index_set = 1;
9761             }
9762           else
9763             break;
9764         }
9765       else if (unformat (i, "del"))
9766         is_add = 0;
9767       else
9768         break;
9769     }
9770
9771   if (rx_sw_if_index_set == 0)
9772     {
9773       errmsg ("missing rx interface name or rx_sw_if_index");
9774       return -99;
9775     }
9776
9777   if (tx_sw_if_index_set == 0)
9778     {
9779       errmsg ("missing tx interface name or tx_sw_if_index");
9780       return -99;
9781     }
9782
9783   M (L2_PATCH_ADD_DEL, mp);
9784
9785   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9786   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9787   mp->is_add = is_add;
9788
9789   S (mp);
9790   W (ret);
9791   return ret;
9792 }
9793
9794 u8 is_del;
9795 u8 localsid_addr[16];
9796 u8 end_psp;
9797 u8 behavior;
9798 u32 sw_if_index;
9799 u32 vlan_index;
9800 u32 fib_table;
9801 u8 nh_addr[16];
9802
9803 static int
9804 api_sr_localsid_add_del (vat_main_t * vam)
9805 {
9806   unformat_input_t *i = vam->input;
9807   vl_api_sr_localsid_add_del_t *mp;
9808
9809   u8 is_del;
9810   ip6_address_t localsid;
9811   u8 end_psp = 0;
9812   u8 behavior = ~0;
9813   u32 sw_if_index;
9814   u32 fib_table = ~(u32) 0;
9815   ip6_address_t next_hop;
9816
9817   bool nexthop_set = 0;
9818
9819   int ret;
9820
9821   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9822     {
9823       if (unformat (i, "del"))
9824         is_del = 1;
9825       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9826       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
9827         nexthop_set = 1;
9828       else if (unformat (i, "behavior %u", &behavior));
9829       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9830       else if (unformat (i, "fib-table %u", &fib_table));
9831       else if (unformat (i, "end.psp %u", &behavior));
9832       else
9833         break;
9834     }
9835
9836   M (SR_LOCALSID_ADD_DEL, mp);
9837
9838   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
9839   if (nexthop_set)
9840     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
9841   mp->behavior = behavior;
9842   mp->sw_if_index = ntohl (sw_if_index);
9843   mp->fib_table = ntohl (fib_table);
9844   mp->end_psp = end_psp;
9845   mp->is_del = is_del;
9846
9847   S (mp);
9848   W (ret);
9849   return ret;
9850 }
9851
9852 static int
9853 api_ioam_enable (vat_main_t * vam)
9854 {
9855   unformat_input_t *input = vam->input;
9856   vl_api_ioam_enable_t *mp;
9857   u32 id = 0;
9858   int has_trace_option = 0;
9859   int has_pot_option = 0;
9860   int has_seqno_option = 0;
9861   int has_analyse_option = 0;
9862   int ret;
9863
9864   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9865     {
9866       if (unformat (input, "trace"))
9867         has_trace_option = 1;
9868       else if (unformat (input, "pot"))
9869         has_pot_option = 1;
9870       else if (unformat (input, "seqno"))
9871         has_seqno_option = 1;
9872       else if (unformat (input, "analyse"))
9873         has_analyse_option = 1;
9874       else
9875         break;
9876     }
9877   M (IOAM_ENABLE, mp);
9878   mp->id = htons (id);
9879   mp->seqno = has_seqno_option;
9880   mp->analyse = has_analyse_option;
9881   mp->pot_enable = has_pot_option;
9882   mp->trace_enable = has_trace_option;
9883
9884   S (mp);
9885   W (ret);
9886   return ret;
9887 }
9888
9889
9890 static int
9891 api_ioam_disable (vat_main_t * vam)
9892 {
9893   vl_api_ioam_disable_t *mp;
9894   int ret;
9895
9896   M (IOAM_DISABLE, mp);
9897   S (mp);
9898   W (ret);
9899   return ret;
9900 }
9901
9902 #define foreach_tcp_proto_field                 \
9903 _(src_port)                                     \
9904 _(dst_port)
9905
9906 #define foreach_udp_proto_field                 \
9907 _(src_port)                                     \
9908 _(dst_port)
9909
9910 #define foreach_ip4_proto_field                 \
9911 _(src_address)                                  \
9912 _(dst_address)                                  \
9913 _(tos)                                          \
9914 _(length)                                       \
9915 _(fragment_id)                                  \
9916 _(ttl)                                          \
9917 _(protocol)                                     \
9918 _(checksum)
9919
9920 typedef struct
9921 {
9922   u16 src_port, dst_port;
9923 } tcpudp_header_t;
9924
9925 #if VPP_API_TEST_BUILTIN == 0
9926 uword
9927 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9928 {
9929   u8 **maskp = va_arg (*args, u8 **);
9930   u8 *mask = 0;
9931   u8 found_something = 0;
9932   tcp_header_t *tcp;
9933
9934 #define _(a) u8 a=0;
9935   foreach_tcp_proto_field;
9936 #undef _
9937
9938   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9939     {
9940       if (0);
9941 #define _(a) else if (unformat (input, #a)) a=1;
9942       foreach_tcp_proto_field
9943 #undef _
9944         else
9945         break;
9946     }
9947
9948 #define _(a) found_something += a;
9949   foreach_tcp_proto_field;
9950 #undef _
9951
9952   if (found_something == 0)
9953     return 0;
9954
9955   vec_validate (mask, sizeof (*tcp) - 1);
9956
9957   tcp = (tcp_header_t *) mask;
9958
9959 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
9960   foreach_tcp_proto_field;
9961 #undef _
9962
9963   *maskp = mask;
9964   return 1;
9965 }
9966
9967 uword
9968 unformat_udp_mask (unformat_input_t * input, va_list * args)
9969 {
9970   u8 **maskp = va_arg (*args, u8 **);
9971   u8 *mask = 0;
9972   u8 found_something = 0;
9973   udp_header_t *udp;
9974
9975 #define _(a) u8 a=0;
9976   foreach_udp_proto_field;
9977 #undef _
9978
9979   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9980     {
9981       if (0);
9982 #define _(a) else if (unformat (input, #a)) a=1;
9983       foreach_udp_proto_field
9984 #undef _
9985         else
9986         break;
9987     }
9988
9989 #define _(a) found_something += a;
9990   foreach_udp_proto_field;
9991 #undef _
9992
9993   if (found_something == 0)
9994     return 0;
9995
9996   vec_validate (mask, sizeof (*udp) - 1);
9997
9998   udp = (udp_header_t *) mask;
9999
10000 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
10001   foreach_udp_proto_field;
10002 #undef _
10003
10004   *maskp = mask;
10005   return 1;
10006 }
10007
10008 uword
10009 unformat_l4_mask (unformat_input_t * input, va_list * args)
10010 {
10011   u8 **maskp = va_arg (*args, u8 **);
10012   u16 src_port = 0, dst_port = 0;
10013   tcpudp_header_t *tcpudp;
10014
10015   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10016     {
10017       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10018         return 1;
10019       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10020         return 1;
10021       else if (unformat (input, "src_port"))
10022         src_port = 0xFFFF;
10023       else if (unformat (input, "dst_port"))
10024         dst_port = 0xFFFF;
10025       else
10026         return 0;
10027     }
10028
10029   if (!src_port && !dst_port)
10030     return 0;
10031
10032   u8 *mask = 0;
10033   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10034
10035   tcpudp = (tcpudp_header_t *) mask;
10036   tcpudp->src_port = src_port;
10037   tcpudp->dst_port = dst_port;
10038
10039   *maskp = mask;
10040
10041   return 1;
10042 }
10043
10044 uword
10045 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10046 {
10047   u8 **maskp = va_arg (*args, u8 **);
10048   u8 *mask = 0;
10049   u8 found_something = 0;
10050   ip4_header_t *ip;
10051
10052 #define _(a) u8 a=0;
10053   foreach_ip4_proto_field;
10054 #undef _
10055   u8 version = 0;
10056   u8 hdr_length = 0;
10057
10058
10059   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10060     {
10061       if (unformat (input, "version"))
10062         version = 1;
10063       else if (unformat (input, "hdr_length"))
10064         hdr_length = 1;
10065       else if (unformat (input, "src"))
10066         src_address = 1;
10067       else if (unformat (input, "dst"))
10068         dst_address = 1;
10069       else if (unformat (input, "proto"))
10070         protocol = 1;
10071
10072 #define _(a) else if (unformat (input, #a)) a=1;
10073       foreach_ip4_proto_field
10074 #undef _
10075         else
10076         break;
10077     }
10078
10079 #define _(a) found_something += a;
10080   foreach_ip4_proto_field;
10081 #undef _
10082
10083   if (found_something == 0)
10084     return 0;
10085
10086   vec_validate (mask, sizeof (*ip) - 1);
10087
10088   ip = (ip4_header_t *) mask;
10089
10090 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10091   foreach_ip4_proto_field;
10092 #undef _
10093
10094   ip->ip_version_and_header_length = 0;
10095
10096   if (version)
10097     ip->ip_version_and_header_length |= 0xF0;
10098
10099   if (hdr_length)
10100     ip->ip_version_and_header_length |= 0x0F;
10101
10102   *maskp = mask;
10103   return 1;
10104 }
10105
10106 #define foreach_ip6_proto_field                 \
10107 _(src_address)                                  \
10108 _(dst_address)                                  \
10109 _(payload_length)                               \
10110 _(hop_limit)                                    \
10111 _(protocol)
10112
10113 uword
10114 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10115 {
10116   u8 **maskp = va_arg (*args, u8 **);
10117   u8 *mask = 0;
10118   u8 found_something = 0;
10119   ip6_header_t *ip;
10120   u32 ip_version_traffic_class_and_flow_label;
10121
10122 #define _(a) u8 a=0;
10123   foreach_ip6_proto_field;
10124 #undef _
10125   u8 version = 0;
10126   u8 traffic_class = 0;
10127   u8 flow_label = 0;
10128
10129   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10130     {
10131       if (unformat (input, "version"))
10132         version = 1;
10133       else if (unformat (input, "traffic-class"))
10134         traffic_class = 1;
10135       else if (unformat (input, "flow-label"))
10136         flow_label = 1;
10137       else if (unformat (input, "src"))
10138         src_address = 1;
10139       else if (unformat (input, "dst"))
10140         dst_address = 1;
10141       else if (unformat (input, "proto"))
10142         protocol = 1;
10143
10144 #define _(a) else if (unformat (input, #a)) a=1;
10145       foreach_ip6_proto_field
10146 #undef _
10147         else
10148         break;
10149     }
10150
10151 #define _(a) found_something += a;
10152   foreach_ip6_proto_field;
10153 #undef _
10154
10155   if (found_something == 0)
10156     return 0;
10157
10158   vec_validate (mask, sizeof (*ip) - 1);
10159
10160   ip = (ip6_header_t *) mask;
10161
10162 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10163   foreach_ip6_proto_field;
10164 #undef _
10165
10166   ip_version_traffic_class_and_flow_label = 0;
10167
10168   if (version)
10169     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10170
10171   if (traffic_class)
10172     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10173
10174   if (flow_label)
10175     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10176
10177   ip->ip_version_traffic_class_and_flow_label =
10178     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10179
10180   *maskp = mask;
10181   return 1;
10182 }
10183
10184 uword
10185 unformat_l3_mask (unformat_input_t * input, va_list * args)
10186 {
10187   u8 **maskp = va_arg (*args, u8 **);
10188
10189   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10190     {
10191       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10192         return 1;
10193       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10194         return 1;
10195       else
10196         break;
10197     }
10198   return 0;
10199 }
10200
10201 uword
10202 unformat_l2_mask (unformat_input_t * input, va_list * args)
10203 {
10204   u8 **maskp = va_arg (*args, u8 **);
10205   u8 *mask = 0;
10206   u8 src = 0;
10207   u8 dst = 0;
10208   u8 proto = 0;
10209   u8 tag1 = 0;
10210   u8 tag2 = 0;
10211   u8 ignore_tag1 = 0;
10212   u8 ignore_tag2 = 0;
10213   u8 cos1 = 0;
10214   u8 cos2 = 0;
10215   u8 dot1q = 0;
10216   u8 dot1ad = 0;
10217   int len = 14;
10218
10219   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10220     {
10221       if (unformat (input, "src"))
10222         src = 1;
10223       else if (unformat (input, "dst"))
10224         dst = 1;
10225       else if (unformat (input, "proto"))
10226         proto = 1;
10227       else if (unformat (input, "tag1"))
10228         tag1 = 1;
10229       else if (unformat (input, "tag2"))
10230         tag2 = 1;
10231       else if (unformat (input, "ignore-tag1"))
10232         ignore_tag1 = 1;
10233       else if (unformat (input, "ignore-tag2"))
10234         ignore_tag2 = 1;
10235       else if (unformat (input, "cos1"))
10236         cos1 = 1;
10237       else if (unformat (input, "cos2"))
10238         cos2 = 1;
10239       else if (unformat (input, "dot1q"))
10240         dot1q = 1;
10241       else if (unformat (input, "dot1ad"))
10242         dot1ad = 1;
10243       else
10244         break;
10245     }
10246   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10247        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10248     return 0;
10249
10250   if (tag1 || ignore_tag1 || cos1 || dot1q)
10251     len = 18;
10252   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10253     len = 22;
10254
10255   vec_validate (mask, len - 1);
10256
10257   if (dst)
10258     memset (mask, 0xff, 6);
10259
10260   if (src)
10261     memset (mask + 6, 0xff, 6);
10262
10263   if (tag2 || dot1ad)
10264     {
10265       /* inner vlan tag */
10266       if (tag2)
10267         {
10268           mask[19] = 0xff;
10269           mask[18] = 0x0f;
10270         }
10271       if (cos2)
10272         mask[18] |= 0xe0;
10273       if (proto)
10274         mask[21] = mask[20] = 0xff;
10275       if (tag1)
10276         {
10277           mask[15] = 0xff;
10278           mask[14] = 0x0f;
10279         }
10280       if (cos1)
10281         mask[14] |= 0xe0;
10282       *maskp = mask;
10283       return 1;
10284     }
10285   if (tag1 | dot1q)
10286     {
10287       if (tag1)
10288         {
10289           mask[15] = 0xff;
10290           mask[14] = 0x0f;
10291         }
10292       if (cos1)
10293         mask[14] |= 0xe0;
10294       if (proto)
10295         mask[16] = mask[17] = 0xff;
10296
10297       *maskp = mask;
10298       return 1;
10299     }
10300   if (cos2)
10301     mask[18] |= 0xe0;
10302   if (cos1)
10303     mask[14] |= 0xe0;
10304   if (proto)
10305     mask[12] = mask[13] = 0xff;
10306
10307   *maskp = mask;
10308   return 1;
10309 }
10310
10311 uword
10312 unformat_classify_mask (unformat_input_t * input, va_list * args)
10313 {
10314   u8 **maskp = va_arg (*args, u8 **);
10315   u32 *skipp = va_arg (*args, u32 *);
10316   u32 *matchp = va_arg (*args, u32 *);
10317   u32 match;
10318   u8 *mask = 0;
10319   u8 *l2 = 0;
10320   u8 *l3 = 0;
10321   u8 *l4 = 0;
10322   int i;
10323
10324   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10325     {
10326       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10327         ;
10328       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10329         ;
10330       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10331         ;
10332       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10333         ;
10334       else
10335         break;
10336     }
10337
10338   if (l4 && !l3)
10339     {
10340       vec_free (mask);
10341       vec_free (l2);
10342       vec_free (l4);
10343       return 0;
10344     }
10345
10346   if (mask || l2 || l3 || l4)
10347     {
10348       if (l2 || l3 || l4)
10349         {
10350           /* "With a free Ethernet header in every package" */
10351           if (l2 == 0)
10352             vec_validate (l2, 13);
10353           mask = l2;
10354           if (vec_len (l3))
10355             {
10356               vec_append (mask, l3);
10357               vec_free (l3);
10358             }
10359           if (vec_len (l4))
10360             {
10361               vec_append (mask, l4);
10362               vec_free (l4);
10363             }
10364         }
10365
10366       /* Scan forward looking for the first significant mask octet */
10367       for (i = 0; i < vec_len (mask); i++)
10368         if (mask[i])
10369           break;
10370
10371       /* compute (skip, match) params */
10372       *skipp = i / sizeof (u32x4);
10373       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10374
10375       /* Pad mask to an even multiple of the vector size */
10376       while (vec_len (mask) % sizeof (u32x4))
10377         vec_add1 (mask, 0);
10378
10379       match = vec_len (mask) / sizeof (u32x4);
10380
10381       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10382         {
10383           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10384           if (*tmp || *(tmp + 1))
10385             break;
10386           match--;
10387         }
10388       if (match == 0)
10389         clib_warning ("BUG: match 0");
10390
10391       _vec_len (mask) = match * sizeof (u32x4);
10392
10393       *matchp = match;
10394       *maskp = mask;
10395
10396       return 1;
10397     }
10398
10399   return 0;
10400 }
10401 #endif /* VPP_API_TEST_BUILTIN */
10402
10403 #define foreach_l2_next                         \
10404 _(drop, DROP)                                   \
10405 _(ethernet, ETHERNET_INPUT)                     \
10406 _(ip4, IP4_INPUT)                               \
10407 _(ip6, IP6_INPUT)
10408
10409 uword
10410 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10411 {
10412   u32 *miss_next_indexp = va_arg (*args, u32 *);
10413   u32 next_index = 0;
10414   u32 tmp;
10415
10416 #define _(n,N) \
10417   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10418   foreach_l2_next;
10419 #undef _
10420
10421   if (unformat (input, "%d", &tmp))
10422     {
10423       next_index = tmp;
10424       goto out;
10425     }
10426
10427   return 0;
10428
10429 out:
10430   *miss_next_indexp = next_index;
10431   return 1;
10432 }
10433
10434 #define foreach_ip_next                         \
10435 _(drop, DROP)                                   \
10436 _(local, LOCAL)                                 \
10437 _(rewrite, REWRITE)
10438
10439 uword
10440 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10441 {
10442   u32 *miss_next_indexp = va_arg (*args, u32 *);
10443   u32 next_index = 0;
10444   u32 tmp;
10445
10446 #define _(n,N) \
10447   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10448   foreach_ip_next;
10449 #undef _
10450
10451   if (unformat (input, "%d", &tmp))
10452     {
10453       next_index = tmp;
10454       goto out;
10455     }
10456
10457   return 0;
10458
10459 out:
10460   *miss_next_indexp = next_index;
10461   return 1;
10462 }
10463
10464 #define foreach_acl_next                        \
10465 _(deny, DENY)
10466
10467 uword
10468 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10469 {
10470   u32 *miss_next_indexp = va_arg (*args, u32 *);
10471   u32 next_index = 0;
10472   u32 tmp;
10473
10474 #define _(n,N) \
10475   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10476   foreach_acl_next;
10477 #undef _
10478
10479   if (unformat (input, "permit"))
10480     {
10481       next_index = ~0;
10482       goto out;
10483     }
10484   else if (unformat (input, "%d", &tmp))
10485     {
10486       next_index = tmp;
10487       goto out;
10488     }
10489
10490   return 0;
10491
10492 out:
10493   *miss_next_indexp = next_index;
10494   return 1;
10495 }
10496
10497 uword
10498 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10499 {
10500   u32 *r = va_arg (*args, u32 *);
10501
10502   if (unformat (input, "conform-color"))
10503     *r = POLICE_CONFORM;
10504   else if (unformat (input, "exceed-color"))
10505     *r = POLICE_EXCEED;
10506   else
10507     return 0;
10508
10509   return 1;
10510 }
10511
10512 static int
10513 api_classify_add_del_table (vat_main_t * vam)
10514 {
10515   unformat_input_t *i = vam->input;
10516   vl_api_classify_add_del_table_t *mp;
10517
10518   u32 nbuckets = 2;
10519   u32 skip = ~0;
10520   u32 match = ~0;
10521   int is_add = 1;
10522   int del_chain = 0;
10523   u32 table_index = ~0;
10524   u32 next_table_index = ~0;
10525   u32 miss_next_index = ~0;
10526   u32 memory_size = 32 << 20;
10527   u8 *mask = 0;
10528   u32 current_data_flag = 0;
10529   int current_data_offset = 0;
10530   int ret;
10531
10532   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10533     {
10534       if (unformat (i, "del"))
10535         is_add = 0;
10536       else if (unformat (i, "del-chain"))
10537         {
10538           is_add = 0;
10539           del_chain = 1;
10540         }
10541       else if (unformat (i, "buckets %d", &nbuckets))
10542         ;
10543       else if (unformat (i, "memory_size %d", &memory_size))
10544         ;
10545       else if (unformat (i, "skip %d", &skip))
10546         ;
10547       else if (unformat (i, "match %d", &match))
10548         ;
10549       else if (unformat (i, "table %d", &table_index))
10550         ;
10551       else if (unformat (i, "mask %U", unformat_classify_mask,
10552                          &mask, &skip, &match))
10553         ;
10554       else if (unformat (i, "next-table %d", &next_table_index))
10555         ;
10556       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10557                          &miss_next_index))
10558         ;
10559       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10560                          &miss_next_index))
10561         ;
10562       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10563                          &miss_next_index))
10564         ;
10565       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10566         ;
10567       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10568         ;
10569       else
10570         break;
10571     }
10572
10573   if (is_add && mask == 0)
10574     {
10575       errmsg ("Mask required");
10576       return -99;
10577     }
10578
10579   if (is_add && skip == ~0)
10580     {
10581       errmsg ("skip count required");
10582       return -99;
10583     }
10584
10585   if (is_add && match == ~0)
10586     {
10587       errmsg ("match count required");
10588       return -99;
10589     }
10590
10591   if (!is_add && table_index == ~0)
10592     {
10593       errmsg ("table index required for delete");
10594       return -99;
10595     }
10596
10597   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10598
10599   mp->is_add = is_add;
10600   mp->del_chain = del_chain;
10601   mp->table_index = ntohl (table_index);
10602   mp->nbuckets = ntohl (nbuckets);
10603   mp->memory_size = ntohl (memory_size);
10604   mp->skip_n_vectors = ntohl (skip);
10605   mp->match_n_vectors = ntohl (match);
10606   mp->next_table_index = ntohl (next_table_index);
10607   mp->miss_next_index = ntohl (miss_next_index);
10608   mp->current_data_flag = ntohl (current_data_flag);
10609   mp->current_data_offset = ntohl (current_data_offset);
10610   clib_memcpy (mp->mask, mask, vec_len (mask));
10611
10612   vec_free (mask);
10613
10614   S (mp);
10615   W (ret);
10616   return ret;
10617 }
10618
10619 #if VPP_API_TEST_BUILTIN == 0
10620 uword
10621 unformat_l4_match (unformat_input_t * input, va_list * args)
10622 {
10623   u8 **matchp = va_arg (*args, u8 **);
10624
10625   u8 *proto_header = 0;
10626   int src_port = 0;
10627   int dst_port = 0;
10628
10629   tcpudp_header_t h;
10630
10631   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10632     {
10633       if (unformat (input, "src_port %d", &src_port))
10634         ;
10635       else if (unformat (input, "dst_port %d", &dst_port))
10636         ;
10637       else
10638         return 0;
10639     }
10640
10641   h.src_port = clib_host_to_net_u16 (src_port);
10642   h.dst_port = clib_host_to_net_u16 (dst_port);
10643   vec_validate (proto_header, sizeof (h) - 1);
10644   memcpy (proto_header, &h, sizeof (h));
10645
10646   *matchp = proto_header;
10647
10648   return 1;
10649 }
10650
10651 uword
10652 unformat_ip4_match (unformat_input_t * input, va_list * args)
10653 {
10654   u8 **matchp = va_arg (*args, u8 **);
10655   u8 *match = 0;
10656   ip4_header_t *ip;
10657   int version = 0;
10658   u32 version_val;
10659   int hdr_length = 0;
10660   u32 hdr_length_val;
10661   int src = 0, dst = 0;
10662   ip4_address_t src_val, dst_val;
10663   int proto = 0;
10664   u32 proto_val;
10665   int tos = 0;
10666   u32 tos_val;
10667   int length = 0;
10668   u32 length_val;
10669   int fragment_id = 0;
10670   u32 fragment_id_val;
10671   int ttl = 0;
10672   int ttl_val;
10673   int checksum = 0;
10674   u32 checksum_val;
10675
10676   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10677     {
10678       if (unformat (input, "version %d", &version_val))
10679         version = 1;
10680       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10681         hdr_length = 1;
10682       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10683         src = 1;
10684       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10685         dst = 1;
10686       else if (unformat (input, "proto %d", &proto_val))
10687         proto = 1;
10688       else if (unformat (input, "tos %d", &tos_val))
10689         tos = 1;
10690       else if (unformat (input, "length %d", &length_val))
10691         length = 1;
10692       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10693         fragment_id = 1;
10694       else if (unformat (input, "ttl %d", &ttl_val))
10695         ttl = 1;
10696       else if (unformat (input, "checksum %d", &checksum_val))
10697         checksum = 1;
10698       else
10699         break;
10700     }
10701
10702   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10703       + ttl + checksum == 0)
10704     return 0;
10705
10706   /*
10707    * Aligned because we use the real comparison functions
10708    */
10709   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10710
10711   ip = (ip4_header_t *) match;
10712
10713   /* These are realistically matched in practice */
10714   if (src)
10715     ip->src_address.as_u32 = src_val.as_u32;
10716
10717   if (dst)
10718     ip->dst_address.as_u32 = dst_val.as_u32;
10719
10720   if (proto)
10721     ip->protocol = proto_val;
10722
10723
10724   /* These are not, but they're included for completeness */
10725   if (version)
10726     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10727
10728   if (hdr_length)
10729     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10730
10731   if (tos)
10732     ip->tos = tos_val;
10733
10734   if (length)
10735     ip->length = clib_host_to_net_u16 (length_val);
10736
10737   if (ttl)
10738     ip->ttl = ttl_val;
10739
10740   if (checksum)
10741     ip->checksum = clib_host_to_net_u16 (checksum_val);
10742
10743   *matchp = match;
10744   return 1;
10745 }
10746
10747 uword
10748 unformat_ip6_match (unformat_input_t * input, va_list * args)
10749 {
10750   u8 **matchp = va_arg (*args, u8 **);
10751   u8 *match = 0;
10752   ip6_header_t *ip;
10753   int version = 0;
10754   u32 version_val;
10755   u8 traffic_class = 0;
10756   u32 traffic_class_val = 0;
10757   u8 flow_label = 0;
10758   u8 flow_label_val;
10759   int src = 0, dst = 0;
10760   ip6_address_t src_val, dst_val;
10761   int proto = 0;
10762   u32 proto_val;
10763   int payload_length = 0;
10764   u32 payload_length_val;
10765   int hop_limit = 0;
10766   int hop_limit_val;
10767   u32 ip_version_traffic_class_and_flow_label;
10768
10769   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10770     {
10771       if (unformat (input, "version %d", &version_val))
10772         version = 1;
10773       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10774         traffic_class = 1;
10775       else if (unformat (input, "flow_label %d", &flow_label_val))
10776         flow_label = 1;
10777       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10778         src = 1;
10779       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10780         dst = 1;
10781       else if (unformat (input, "proto %d", &proto_val))
10782         proto = 1;
10783       else if (unformat (input, "payload_length %d", &payload_length_val))
10784         payload_length = 1;
10785       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10786         hop_limit = 1;
10787       else
10788         break;
10789     }
10790
10791   if (version + traffic_class + flow_label + src + dst + proto +
10792       payload_length + hop_limit == 0)
10793     return 0;
10794
10795   /*
10796    * Aligned because we use the real comparison functions
10797    */
10798   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10799
10800   ip = (ip6_header_t *) match;
10801
10802   if (src)
10803     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10804
10805   if (dst)
10806     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10807
10808   if (proto)
10809     ip->protocol = proto_val;
10810
10811   ip_version_traffic_class_and_flow_label = 0;
10812
10813   if (version)
10814     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10815
10816   if (traffic_class)
10817     ip_version_traffic_class_and_flow_label |=
10818       (traffic_class_val & 0xFF) << 20;
10819
10820   if (flow_label)
10821     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10822
10823   ip->ip_version_traffic_class_and_flow_label =
10824     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10825
10826   if (payload_length)
10827     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10828
10829   if (hop_limit)
10830     ip->hop_limit = hop_limit_val;
10831
10832   *matchp = match;
10833   return 1;
10834 }
10835
10836 uword
10837 unformat_l3_match (unformat_input_t * input, va_list * args)
10838 {
10839   u8 **matchp = va_arg (*args, u8 **);
10840
10841   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10842     {
10843       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10844         return 1;
10845       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10846         return 1;
10847       else
10848         break;
10849     }
10850   return 0;
10851 }
10852
10853 uword
10854 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10855 {
10856   u8 *tagp = va_arg (*args, u8 *);
10857   u32 tag;
10858
10859   if (unformat (input, "%d", &tag))
10860     {
10861       tagp[0] = (tag >> 8) & 0x0F;
10862       tagp[1] = tag & 0xFF;
10863       return 1;
10864     }
10865
10866   return 0;
10867 }
10868
10869 uword
10870 unformat_l2_match (unformat_input_t * input, va_list * args)
10871 {
10872   u8 **matchp = va_arg (*args, u8 **);
10873   u8 *match = 0;
10874   u8 src = 0;
10875   u8 src_val[6];
10876   u8 dst = 0;
10877   u8 dst_val[6];
10878   u8 proto = 0;
10879   u16 proto_val;
10880   u8 tag1 = 0;
10881   u8 tag1_val[2];
10882   u8 tag2 = 0;
10883   u8 tag2_val[2];
10884   int len = 14;
10885   u8 ignore_tag1 = 0;
10886   u8 ignore_tag2 = 0;
10887   u8 cos1 = 0;
10888   u8 cos2 = 0;
10889   u32 cos1_val = 0;
10890   u32 cos2_val = 0;
10891
10892   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10893     {
10894       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10895         src = 1;
10896       else
10897         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10898         dst = 1;
10899       else if (unformat (input, "proto %U",
10900                          unformat_ethernet_type_host_byte_order, &proto_val))
10901         proto = 1;
10902       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10903         tag1 = 1;
10904       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10905         tag2 = 1;
10906       else if (unformat (input, "ignore-tag1"))
10907         ignore_tag1 = 1;
10908       else if (unformat (input, "ignore-tag2"))
10909         ignore_tag2 = 1;
10910       else if (unformat (input, "cos1 %d", &cos1_val))
10911         cos1 = 1;
10912       else if (unformat (input, "cos2 %d", &cos2_val))
10913         cos2 = 1;
10914       else
10915         break;
10916     }
10917   if ((src + dst + proto + tag1 + tag2 +
10918        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10919     return 0;
10920
10921   if (tag1 || ignore_tag1 || cos1)
10922     len = 18;
10923   if (tag2 || ignore_tag2 || cos2)
10924     len = 22;
10925
10926   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10927
10928   if (dst)
10929     clib_memcpy (match, dst_val, 6);
10930
10931   if (src)
10932     clib_memcpy (match + 6, src_val, 6);
10933
10934   if (tag2)
10935     {
10936       /* inner vlan tag */
10937       match[19] = tag2_val[1];
10938       match[18] = tag2_val[0];
10939       if (cos2)
10940         match[18] |= (cos2_val & 0x7) << 5;
10941       if (proto)
10942         {
10943           match[21] = proto_val & 0xff;
10944           match[20] = proto_val >> 8;
10945         }
10946       if (tag1)
10947         {
10948           match[15] = tag1_val[1];
10949           match[14] = tag1_val[0];
10950         }
10951       if (cos1)
10952         match[14] |= (cos1_val & 0x7) << 5;
10953       *matchp = match;
10954       return 1;
10955     }
10956   if (tag1)
10957     {
10958       match[15] = tag1_val[1];
10959       match[14] = tag1_val[0];
10960       if (proto)
10961         {
10962           match[17] = proto_val & 0xff;
10963           match[16] = proto_val >> 8;
10964         }
10965       if (cos1)
10966         match[14] |= (cos1_val & 0x7) << 5;
10967
10968       *matchp = match;
10969       return 1;
10970     }
10971   if (cos2)
10972     match[18] |= (cos2_val & 0x7) << 5;
10973   if (cos1)
10974     match[14] |= (cos1_val & 0x7) << 5;
10975   if (proto)
10976     {
10977       match[13] = proto_val & 0xff;
10978       match[12] = proto_val >> 8;
10979     }
10980
10981   *matchp = match;
10982   return 1;
10983 }
10984 #endif
10985
10986 uword
10987 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10988 {
10989   u8 **matchp = va_arg (*args, u8 **);
10990   u32 skip_n_vectors = va_arg (*args, u32);
10991   u32 match_n_vectors = va_arg (*args, u32);
10992
10993   u8 *match = 0;
10994   u8 *l2 = 0;
10995   u8 *l3 = 0;
10996   u8 *l4 = 0;
10997
10998   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10999     {
11000       if (unformat (input, "hex %U", unformat_hex_string, &match))
11001         ;
11002       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11003         ;
11004       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11005         ;
11006       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11007         ;
11008       else
11009         break;
11010     }
11011
11012   if (l4 && !l3)
11013     {
11014       vec_free (match);
11015       vec_free (l2);
11016       vec_free (l4);
11017       return 0;
11018     }
11019
11020   if (match || l2 || l3 || l4)
11021     {
11022       if (l2 || l3 || l4)
11023         {
11024           /* "Win a free Ethernet header in every packet" */
11025           if (l2 == 0)
11026             vec_validate_aligned (l2, 13, sizeof (u32x4));
11027           match = l2;
11028           if (vec_len (l3))
11029             {
11030               vec_append_aligned (match, l3, sizeof (u32x4));
11031               vec_free (l3);
11032             }
11033           if (vec_len (l4))
11034             {
11035               vec_append_aligned (match, l4, sizeof (u32x4));
11036               vec_free (l4);
11037             }
11038         }
11039
11040       /* Make sure the vector is big enough even if key is all 0's */
11041       vec_validate_aligned
11042         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11043          sizeof (u32x4));
11044
11045       /* Set size, include skipped vectors */
11046       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11047
11048       *matchp = match;
11049
11050       return 1;
11051     }
11052
11053   return 0;
11054 }
11055
11056 static int
11057 api_classify_add_del_session (vat_main_t * vam)
11058 {
11059   unformat_input_t *i = vam->input;
11060   vl_api_classify_add_del_session_t *mp;
11061   int is_add = 1;
11062   u32 table_index = ~0;
11063   u32 hit_next_index = ~0;
11064   u32 opaque_index = ~0;
11065   u8 *match = 0;
11066   i32 advance = 0;
11067   u32 skip_n_vectors = 0;
11068   u32 match_n_vectors = 0;
11069   u32 action = 0;
11070   u32 metadata = 0;
11071   int ret;
11072
11073   /*
11074    * Warning: you have to supply skip_n and match_n
11075    * because the API client cant simply look at the classify
11076    * table object.
11077    */
11078
11079   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11080     {
11081       if (unformat (i, "del"))
11082         is_add = 0;
11083       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11084                          &hit_next_index))
11085         ;
11086       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11087                          &hit_next_index))
11088         ;
11089       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11090                          &hit_next_index))
11091         ;
11092       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11093         ;
11094       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11095         ;
11096       else if (unformat (i, "opaque-index %d", &opaque_index))
11097         ;
11098       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11099         ;
11100       else if (unformat (i, "match_n %d", &match_n_vectors))
11101         ;
11102       else if (unformat (i, "match %U", api_unformat_classify_match,
11103                          &match, skip_n_vectors, match_n_vectors))
11104         ;
11105       else if (unformat (i, "advance %d", &advance))
11106         ;
11107       else if (unformat (i, "table-index %d", &table_index))
11108         ;
11109       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11110         action = 1;
11111       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11112         action = 2;
11113       else if (unformat (i, "action %d", &action))
11114         ;
11115       else if (unformat (i, "metadata %d", &metadata))
11116         ;
11117       else
11118         break;
11119     }
11120
11121   if (table_index == ~0)
11122     {
11123       errmsg ("Table index required");
11124       return -99;
11125     }
11126
11127   if (is_add && match == 0)
11128     {
11129       errmsg ("Match value required");
11130       return -99;
11131     }
11132
11133   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11134
11135   mp->is_add = is_add;
11136   mp->table_index = ntohl (table_index);
11137   mp->hit_next_index = ntohl (hit_next_index);
11138   mp->opaque_index = ntohl (opaque_index);
11139   mp->advance = ntohl (advance);
11140   mp->action = action;
11141   mp->metadata = ntohl (metadata);
11142   clib_memcpy (mp->match, match, vec_len (match));
11143   vec_free (match);
11144
11145   S (mp);
11146   W (ret);
11147   return ret;
11148 }
11149
11150 static int
11151 api_classify_set_interface_ip_table (vat_main_t * vam)
11152 {
11153   unformat_input_t *i = vam->input;
11154   vl_api_classify_set_interface_ip_table_t *mp;
11155   u32 sw_if_index;
11156   int sw_if_index_set;
11157   u32 table_index = ~0;
11158   u8 is_ipv6 = 0;
11159   int ret;
11160
11161   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11162     {
11163       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11164         sw_if_index_set = 1;
11165       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11166         sw_if_index_set = 1;
11167       else if (unformat (i, "table %d", &table_index))
11168         ;
11169       else
11170         {
11171           clib_warning ("parse error '%U'", format_unformat_error, i);
11172           return -99;
11173         }
11174     }
11175
11176   if (sw_if_index_set == 0)
11177     {
11178       errmsg ("missing interface name or sw_if_index");
11179       return -99;
11180     }
11181
11182
11183   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11184
11185   mp->sw_if_index = ntohl (sw_if_index);
11186   mp->table_index = ntohl (table_index);
11187   mp->is_ipv6 = is_ipv6;
11188
11189   S (mp);
11190   W (ret);
11191   return ret;
11192 }
11193
11194 static int
11195 api_classify_set_interface_l2_tables (vat_main_t * vam)
11196 {
11197   unformat_input_t *i = vam->input;
11198   vl_api_classify_set_interface_l2_tables_t *mp;
11199   u32 sw_if_index;
11200   int sw_if_index_set;
11201   u32 ip4_table_index = ~0;
11202   u32 ip6_table_index = ~0;
11203   u32 other_table_index = ~0;
11204   u32 is_input = 1;
11205   int ret;
11206
11207   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11208     {
11209       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11210         sw_if_index_set = 1;
11211       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11212         sw_if_index_set = 1;
11213       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11214         ;
11215       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11216         ;
11217       else if (unformat (i, "other-table %d", &other_table_index))
11218         ;
11219       else if (unformat (i, "is-input %d", &is_input))
11220         ;
11221       else
11222         {
11223           clib_warning ("parse error '%U'", format_unformat_error, i);
11224           return -99;
11225         }
11226     }
11227
11228   if (sw_if_index_set == 0)
11229     {
11230       errmsg ("missing interface name or sw_if_index");
11231       return -99;
11232     }
11233
11234
11235   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11236
11237   mp->sw_if_index = ntohl (sw_if_index);
11238   mp->ip4_table_index = ntohl (ip4_table_index);
11239   mp->ip6_table_index = ntohl (ip6_table_index);
11240   mp->other_table_index = ntohl (other_table_index);
11241   mp->is_input = (u8) is_input;
11242
11243   S (mp);
11244   W (ret);
11245   return ret;
11246 }
11247
11248 static int
11249 api_set_ipfix_exporter (vat_main_t * vam)
11250 {
11251   unformat_input_t *i = vam->input;
11252   vl_api_set_ipfix_exporter_t *mp;
11253   ip4_address_t collector_address;
11254   u8 collector_address_set = 0;
11255   u32 collector_port = ~0;
11256   ip4_address_t src_address;
11257   u8 src_address_set = 0;
11258   u32 vrf_id = ~0;
11259   u32 path_mtu = ~0;
11260   u32 template_interval = ~0;
11261   u8 udp_checksum = 0;
11262   int ret;
11263
11264   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11265     {
11266       if (unformat (i, "collector_address %U", unformat_ip4_address,
11267                     &collector_address))
11268         collector_address_set = 1;
11269       else if (unformat (i, "collector_port %d", &collector_port))
11270         ;
11271       else if (unformat (i, "src_address %U", unformat_ip4_address,
11272                          &src_address))
11273         src_address_set = 1;
11274       else if (unformat (i, "vrf_id %d", &vrf_id))
11275         ;
11276       else if (unformat (i, "path_mtu %d", &path_mtu))
11277         ;
11278       else if (unformat (i, "template_interval %d", &template_interval))
11279         ;
11280       else if (unformat (i, "udp_checksum"))
11281         udp_checksum = 1;
11282       else
11283         break;
11284     }
11285
11286   if (collector_address_set == 0)
11287     {
11288       errmsg ("collector_address required");
11289       return -99;
11290     }
11291
11292   if (src_address_set == 0)
11293     {
11294       errmsg ("src_address required");
11295       return -99;
11296     }
11297
11298   M (SET_IPFIX_EXPORTER, mp);
11299
11300   memcpy (mp->collector_address, collector_address.data,
11301           sizeof (collector_address.data));
11302   mp->collector_port = htons ((u16) collector_port);
11303   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11304   mp->vrf_id = htonl (vrf_id);
11305   mp->path_mtu = htonl (path_mtu);
11306   mp->template_interval = htonl (template_interval);
11307   mp->udp_checksum = udp_checksum;
11308
11309   S (mp);
11310   W (ret);
11311   return ret;
11312 }
11313
11314 static int
11315 api_set_ipfix_classify_stream (vat_main_t * vam)
11316 {
11317   unformat_input_t *i = vam->input;
11318   vl_api_set_ipfix_classify_stream_t *mp;
11319   u32 domain_id = 0;
11320   u32 src_port = UDP_DST_PORT_ipfix;
11321   int ret;
11322
11323   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11324     {
11325       if (unformat (i, "domain %d", &domain_id))
11326         ;
11327       else if (unformat (i, "src_port %d", &src_port))
11328         ;
11329       else
11330         {
11331           errmsg ("unknown input `%U'", format_unformat_error, i);
11332           return -99;
11333         }
11334     }
11335
11336   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11337
11338   mp->domain_id = htonl (domain_id);
11339   mp->src_port = htons ((u16) src_port);
11340
11341   S (mp);
11342   W (ret);
11343   return ret;
11344 }
11345
11346 static int
11347 api_ipfix_classify_table_add_del (vat_main_t * vam)
11348 {
11349   unformat_input_t *i = vam->input;
11350   vl_api_ipfix_classify_table_add_del_t *mp;
11351   int is_add = -1;
11352   u32 classify_table_index = ~0;
11353   u8 ip_version = 0;
11354   u8 transport_protocol = 255;
11355   int ret;
11356
11357   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11358     {
11359       if (unformat (i, "add"))
11360         is_add = 1;
11361       else if (unformat (i, "del"))
11362         is_add = 0;
11363       else if (unformat (i, "table %d", &classify_table_index))
11364         ;
11365       else if (unformat (i, "ip4"))
11366         ip_version = 4;
11367       else if (unformat (i, "ip6"))
11368         ip_version = 6;
11369       else if (unformat (i, "tcp"))
11370         transport_protocol = 6;
11371       else if (unformat (i, "udp"))
11372         transport_protocol = 17;
11373       else
11374         {
11375           errmsg ("unknown input `%U'", format_unformat_error, i);
11376           return -99;
11377         }
11378     }
11379
11380   if (is_add == -1)
11381     {
11382       errmsg ("expecting: add|del");
11383       return -99;
11384     }
11385   if (classify_table_index == ~0)
11386     {
11387       errmsg ("classifier table not specified");
11388       return -99;
11389     }
11390   if (ip_version == 0)
11391     {
11392       errmsg ("IP version not specified");
11393       return -99;
11394     }
11395
11396   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11397
11398   mp->is_add = is_add;
11399   mp->table_id = htonl (classify_table_index);
11400   mp->ip_version = ip_version;
11401   mp->transport_protocol = transport_protocol;
11402
11403   S (mp);
11404   W (ret);
11405   return ret;
11406 }
11407
11408 static int
11409 api_get_node_index (vat_main_t * vam)
11410 {
11411   unformat_input_t *i = vam->input;
11412   vl_api_get_node_index_t *mp;
11413   u8 *name = 0;
11414   int ret;
11415
11416   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11417     {
11418       if (unformat (i, "node %s", &name))
11419         ;
11420       else
11421         break;
11422     }
11423   if (name == 0)
11424     {
11425       errmsg ("node name required");
11426       return -99;
11427     }
11428   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11429     {
11430       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11431       return -99;
11432     }
11433
11434   M (GET_NODE_INDEX, mp);
11435   clib_memcpy (mp->node_name, name, vec_len (name));
11436   vec_free (name);
11437
11438   S (mp);
11439   W (ret);
11440   return ret;
11441 }
11442
11443 static int
11444 api_get_next_index (vat_main_t * vam)
11445 {
11446   unformat_input_t *i = vam->input;
11447   vl_api_get_next_index_t *mp;
11448   u8 *node_name = 0, *next_node_name = 0;
11449   int ret;
11450
11451   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11452     {
11453       if (unformat (i, "node-name %s", &node_name))
11454         ;
11455       else if (unformat (i, "next-node-name %s", &next_node_name))
11456         break;
11457     }
11458
11459   if (node_name == 0)
11460     {
11461       errmsg ("node name required");
11462       return -99;
11463     }
11464   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11465     {
11466       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11467       return -99;
11468     }
11469
11470   if (next_node_name == 0)
11471     {
11472       errmsg ("next node name required");
11473       return -99;
11474     }
11475   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11476     {
11477       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11478       return -99;
11479     }
11480
11481   M (GET_NEXT_INDEX, mp);
11482   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11483   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11484   vec_free (node_name);
11485   vec_free (next_node_name);
11486
11487   S (mp);
11488   W (ret);
11489   return ret;
11490 }
11491
11492 static int
11493 api_add_node_next (vat_main_t * vam)
11494 {
11495   unformat_input_t *i = vam->input;
11496   vl_api_add_node_next_t *mp;
11497   u8 *name = 0;
11498   u8 *next = 0;
11499   int ret;
11500
11501   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11502     {
11503       if (unformat (i, "node %s", &name))
11504         ;
11505       else if (unformat (i, "next %s", &next))
11506         ;
11507       else
11508         break;
11509     }
11510   if (name == 0)
11511     {
11512       errmsg ("node name required");
11513       return -99;
11514     }
11515   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11516     {
11517       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11518       return -99;
11519     }
11520   if (next == 0)
11521     {
11522       errmsg ("next node required");
11523       return -99;
11524     }
11525   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11526     {
11527       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11528       return -99;
11529     }
11530
11531   M (ADD_NODE_NEXT, mp);
11532   clib_memcpy (mp->node_name, name, vec_len (name));
11533   clib_memcpy (mp->next_name, next, vec_len (next));
11534   vec_free (name);
11535   vec_free (next);
11536
11537   S (mp);
11538   W (ret);
11539   return ret;
11540 }
11541
11542 static int
11543 api_l2tpv3_create_tunnel (vat_main_t * vam)
11544 {
11545   unformat_input_t *i = vam->input;
11546   ip6_address_t client_address, our_address;
11547   int client_address_set = 0;
11548   int our_address_set = 0;
11549   u32 local_session_id = 0;
11550   u32 remote_session_id = 0;
11551   u64 local_cookie = 0;
11552   u64 remote_cookie = 0;
11553   u8 l2_sublayer_present = 0;
11554   vl_api_l2tpv3_create_tunnel_t *mp;
11555   int ret;
11556
11557   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11558     {
11559       if (unformat (i, "client_address %U", unformat_ip6_address,
11560                     &client_address))
11561         client_address_set = 1;
11562       else if (unformat (i, "our_address %U", unformat_ip6_address,
11563                          &our_address))
11564         our_address_set = 1;
11565       else if (unformat (i, "local_session_id %d", &local_session_id))
11566         ;
11567       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11568         ;
11569       else if (unformat (i, "local_cookie %lld", &local_cookie))
11570         ;
11571       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11572         ;
11573       else if (unformat (i, "l2-sublayer-present"))
11574         l2_sublayer_present = 1;
11575       else
11576         break;
11577     }
11578
11579   if (client_address_set == 0)
11580     {
11581       errmsg ("client_address required");
11582       return -99;
11583     }
11584
11585   if (our_address_set == 0)
11586     {
11587       errmsg ("our_address required");
11588       return -99;
11589     }
11590
11591   M (L2TPV3_CREATE_TUNNEL, mp);
11592
11593   clib_memcpy (mp->client_address, client_address.as_u8,
11594                sizeof (mp->client_address));
11595
11596   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11597
11598   mp->local_session_id = ntohl (local_session_id);
11599   mp->remote_session_id = ntohl (remote_session_id);
11600   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11601   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11602   mp->l2_sublayer_present = l2_sublayer_present;
11603   mp->is_ipv6 = 1;
11604
11605   S (mp);
11606   W (ret);
11607   return ret;
11608 }
11609
11610 static int
11611 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11612 {
11613   unformat_input_t *i = vam->input;
11614   u32 sw_if_index;
11615   u8 sw_if_index_set = 0;
11616   u64 new_local_cookie = 0;
11617   u64 new_remote_cookie = 0;
11618   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11619   int ret;
11620
11621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11622     {
11623       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11624         sw_if_index_set = 1;
11625       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11626         sw_if_index_set = 1;
11627       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11628         ;
11629       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11630         ;
11631       else
11632         break;
11633     }
11634
11635   if (sw_if_index_set == 0)
11636     {
11637       errmsg ("missing interface name or sw_if_index");
11638       return -99;
11639     }
11640
11641   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11642
11643   mp->sw_if_index = ntohl (sw_if_index);
11644   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11645   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11646
11647   S (mp);
11648   W (ret);
11649   return ret;
11650 }
11651
11652 static int
11653 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11654 {
11655   unformat_input_t *i = vam->input;
11656   vl_api_l2tpv3_interface_enable_disable_t *mp;
11657   u32 sw_if_index;
11658   u8 sw_if_index_set = 0;
11659   u8 enable_disable = 1;
11660   int ret;
11661
11662   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11663     {
11664       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11665         sw_if_index_set = 1;
11666       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11667         sw_if_index_set = 1;
11668       else if (unformat (i, "enable"))
11669         enable_disable = 1;
11670       else if (unformat (i, "disable"))
11671         enable_disable = 0;
11672       else
11673         break;
11674     }
11675
11676   if (sw_if_index_set == 0)
11677     {
11678       errmsg ("missing interface name or sw_if_index");
11679       return -99;
11680     }
11681
11682   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11683
11684   mp->sw_if_index = ntohl (sw_if_index);
11685   mp->enable_disable = enable_disable;
11686
11687   S (mp);
11688   W (ret);
11689   return ret;
11690 }
11691
11692 static int
11693 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11694 {
11695   unformat_input_t *i = vam->input;
11696   vl_api_l2tpv3_set_lookup_key_t *mp;
11697   u8 key = ~0;
11698   int ret;
11699
11700   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11701     {
11702       if (unformat (i, "lookup_v6_src"))
11703         key = L2T_LOOKUP_SRC_ADDRESS;
11704       else if (unformat (i, "lookup_v6_dst"))
11705         key = L2T_LOOKUP_DST_ADDRESS;
11706       else if (unformat (i, "lookup_session_id"))
11707         key = L2T_LOOKUP_SESSION_ID;
11708       else
11709         break;
11710     }
11711
11712   if (key == (u8) ~ 0)
11713     {
11714       errmsg ("l2tp session lookup key unset");
11715       return -99;
11716     }
11717
11718   M (L2TPV3_SET_LOOKUP_KEY, mp);
11719
11720   mp->key = key;
11721
11722   S (mp);
11723   W (ret);
11724   return ret;
11725 }
11726
11727 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11728   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11729 {
11730   vat_main_t *vam = &vat_main;
11731
11732   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11733          format_ip6_address, mp->our_address,
11734          format_ip6_address, mp->client_address,
11735          clib_net_to_host_u32 (mp->sw_if_index));
11736
11737   print (vam->ofp,
11738          "   local cookies %016llx %016llx remote cookie %016llx",
11739          clib_net_to_host_u64 (mp->local_cookie[0]),
11740          clib_net_to_host_u64 (mp->local_cookie[1]),
11741          clib_net_to_host_u64 (mp->remote_cookie));
11742
11743   print (vam->ofp, "   local session-id %d remote session-id %d",
11744          clib_net_to_host_u32 (mp->local_session_id),
11745          clib_net_to_host_u32 (mp->remote_session_id));
11746
11747   print (vam->ofp, "   l2 specific sublayer %s\n",
11748          mp->l2_sublayer_present ? "preset" : "absent");
11749
11750 }
11751
11752 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11753   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11754 {
11755   vat_main_t *vam = &vat_main;
11756   vat_json_node_t *node = NULL;
11757   struct in6_addr addr;
11758
11759   if (VAT_JSON_ARRAY != vam->json_tree.type)
11760     {
11761       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11762       vat_json_init_array (&vam->json_tree);
11763     }
11764   node = vat_json_array_add (&vam->json_tree);
11765
11766   vat_json_init_object (node);
11767
11768   clib_memcpy (&addr, mp->our_address, sizeof (addr));
11769   vat_json_object_add_ip6 (node, "our_address", addr);
11770   clib_memcpy (&addr, mp->client_address, sizeof (addr));
11771   vat_json_object_add_ip6 (node, "client_address", addr);
11772
11773   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11774   vat_json_init_array (lc);
11775   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11776   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11777   vat_json_object_add_uint (node, "remote_cookie",
11778                             clib_net_to_host_u64 (mp->remote_cookie));
11779
11780   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11781   vat_json_object_add_uint (node, "local_session_id",
11782                             clib_net_to_host_u32 (mp->local_session_id));
11783   vat_json_object_add_uint (node, "remote_session_id",
11784                             clib_net_to_host_u32 (mp->remote_session_id));
11785   vat_json_object_add_string_copy (node, "l2_sublayer",
11786                                    mp->l2_sublayer_present ? (u8 *) "present"
11787                                    : (u8 *) "absent");
11788 }
11789
11790 static int
11791 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11792 {
11793   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11794   vl_api_control_ping_t *mp_ping;
11795   int ret;
11796
11797   /* Get list of l2tpv3-tunnel interfaces */
11798   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11799   S (mp);
11800
11801   /* Use a control ping for synchronization */
11802   MPING (CONTROL_PING, mp_ping);
11803   S (mp_ping);
11804
11805   W (ret);
11806   return ret;
11807 }
11808
11809
11810 static void vl_api_sw_interface_tap_details_t_handler
11811   (vl_api_sw_interface_tap_details_t * mp)
11812 {
11813   vat_main_t *vam = &vat_main;
11814
11815   print (vam->ofp, "%-16s %d",
11816          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
11817 }
11818
11819 static void vl_api_sw_interface_tap_details_t_handler_json
11820   (vl_api_sw_interface_tap_details_t * mp)
11821 {
11822   vat_main_t *vam = &vat_main;
11823   vat_json_node_t *node = NULL;
11824
11825   if (VAT_JSON_ARRAY != vam->json_tree.type)
11826     {
11827       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11828       vat_json_init_array (&vam->json_tree);
11829     }
11830   node = vat_json_array_add (&vam->json_tree);
11831
11832   vat_json_init_object (node);
11833   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11834   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11835 }
11836
11837 static int
11838 api_sw_interface_tap_dump (vat_main_t * vam)
11839 {
11840   vl_api_sw_interface_tap_dump_t *mp;
11841   vl_api_control_ping_t *mp_ping;
11842   int ret;
11843
11844   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
11845   /* Get list of tap interfaces */
11846   M (SW_INTERFACE_TAP_DUMP, mp);
11847   S (mp);
11848
11849   /* Use a control ping for synchronization */
11850   MPING (CONTROL_PING, mp_ping);
11851   S (mp_ping);
11852
11853   W (ret);
11854   return ret;
11855 }
11856
11857 static uword unformat_vxlan_decap_next
11858   (unformat_input_t * input, va_list * args)
11859 {
11860   u32 *result = va_arg (*args, u32 *);
11861   u32 tmp;
11862
11863   if (unformat (input, "l2"))
11864     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11865   else if (unformat (input, "%d", &tmp))
11866     *result = tmp;
11867   else
11868     return 0;
11869   return 1;
11870 }
11871
11872 static int
11873 api_vxlan_add_del_tunnel (vat_main_t * vam)
11874 {
11875   unformat_input_t *line_input = vam->input;
11876   vl_api_vxlan_add_del_tunnel_t *mp;
11877   ip46_address_t src, dst;
11878   u8 is_add = 1;
11879   u8 ipv4_set = 0, ipv6_set = 0;
11880   u8 src_set = 0;
11881   u8 dst_set = 0;
11882   u8 grp_set = 0;
11883   u32 mcast_sw_if_index = ~0;
11884   u32 encap_vrf_id = 0;
11885   u32 decap_next_index = ~0;
11886   u32 vni = 0;
11887   int ret;
11888
11889   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11890   memset (&src, 0, sizeof src);
11891   memset (&dst, 0, sizeof dst);
11892
11893   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11894     {
11895       if (unformat (line_input, "del"))
11896         is_add = 0;
11897       else
11898         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11899         {
11900           ipv4_set = 1;
11901           src_set = 1;
11902         }
11903       else
11904         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11905         {
11906           ipv4_set = 1;
11907           dst_set = 1;
11908         }
11909       else
11910         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11911         {
11912           ipv6_set = 1;
11913           src_set = 1;
11914         }
11915       else
11916         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11917         {
11918           ipv6_set = 1;
11919           dst_set = 1;
11920         }
11921       else if (unformat (line_input, "group %U %U",
11922                          unformat_ip4_address, &dst.ip4,
11923                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11924         {
11925           grp_set = dst_set = 1;
11926           ipv4_set = 1;
11927         }
11928       else if (unformat (line_input, "group %U",
11929                          unformat_ip4_address, &dst.ip4))
11930         {
11931           grp_set = dst_set = 1;
11932           ipv4_set = 1;
11933         }
11934       else if (unformat (line_input, "group %U %U",
11935                          unformat_ip6_address, &dst.ip6,
11936                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11937         {
11938           grp_set = dst_set = 1;
11939           ipv6_set = 1;
11940         }
11941       else if (unformat (line_input, "group %U",
11942                          unformat_ip6_address, &dst.ip6))
11943         {
11944           grp_set = dst_set = 1;
11945           ipv6_set = 1;
11946         }
11947       else
11948         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11949         ;
11950       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11951         ;
11952       else if (unformat (line_input, "decap-next %U",
11953                          unformat_vxlan_decap_next, &decap_next_index))
11954         ;
11955       else if (unformat (line_input, "vni %d", &vni))
11956         ;
11957       else
11958         {
11959           errmsg ("parse error '%U'", format_unformat_error, line_input);
11960           return -99;
11961         }
11962     }
11963
11964   if (src_set == 0)
11965     {
11966       errmsg ("tunnel src address not specified");
11967       return -99;
11968     }
11969   if (dst_set == 0)
11970     {
11971       errmsg ("tunnel dst address not specified");
11972       return -99;
11973     }
11974
11975   if (grp_set && !ip46_address_is_multicast (&dst))
11976     {
11977       errmsg ("tunnel group address not multicast");
11978       return -99;
11979     }
11980   if (grp_set && mcast_sw_if_index == ~0)
11981     {
11982       errmsg ("tunnel nonexistent multicast device");
11983       return -99;
11984     }
11985   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11986     {
11987       errmsg ("tunnel dst address must be unicast");
11988       return -99;
11989     }
11990
11991
11992   if (ipv4_set && ipv6_set)
11993     {
11994       errmsg ("both IPv4 and IPv6 addresses specified");
11995       return -99;
11996     }
11997
11998   if ((vni == 0) || (vni >> 24))
11999     {
12000       errmsg ("vni not specified or out of range");
12001       return -99;
12002     }
12003
12004   M (VXLAN_ADD_DEL_TUNNEL, mp);
12005
12006   if (ipv6_set)
12007     {
12008       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12009       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12010     }
12011   else
12012     {
12013       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12014       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12015     }
12016   mp->encap_vrf_id = ntohl (encap_vrf_id);
12017   mp->decap_next_index = ntohl (decap_next_index);
12018   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12019   mp->vni = ntohl (vni);
12020   mp->is_add = is_add;
12021   mp->is_ipv6 = ipv6_set;
12022
12023   S (mp);
12024   W (ret);
12025   return ret;
12026 }
12027
12028 static void vl_api_vxlan_tunnel_details_t_handler
12029   (vl_api_vxlan_tunnel_details_t * mp)
12030 {
12031   vat_main_t *vam = &vat_main;
12032   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12033   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12034
12035   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12036          ntohl (mp->sw_if_index),
12037          format_ip46_address, &src, IP46_TYPE_ANY,
12038          format_ip46_address, &dst, IP46_TYPE_ANY,
12039          ntohl (mp->encap_vrf_id),
12040          ntohl (mp->decap_next_index), ntohl (mp->vni),
12041          ntohl (mp->mcast_sw_if_index));
12042 }
12043
12044 static void vl_api_vxlan_tunnel_details_t_handler_json
12045   (vl_api_vxlan_tunnel_details_t * mp)
12046 {
12047   vat_main_t *vam = &vat_main;
12048   vat_json_node_t *node = NULL;
12049
12050   if (VAT_JSON_ARRAY != vam->json_tree.type)
12051     {
12052       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12053       vat_json_init_array (&vam->json_tree);
12054     }
12055   node = vat_json_array_add (&vam->json_tree);
12056
12057   vat_json_init_object (node);
12058   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12059   if (mp->is_ipv6)
12060     {
12061       struct in6_addr ip6;
12062
12063       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12064       vat_json_object_add_ip6 (node, "src_address", ip6);
12065       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12066       vat_json_object_add_ip6 (node, "dst_address", ip6);
12067     }
12068   else
12069     {
12070       struct in_addr ip4;
12071
12072       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12073       vat_json_object_add_ip4 (node, "src_address", ip4);
12074       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12075       vat_json_object_add_ip4 (node, "dst_address", ip4);
12076     }
12077   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12078   vat_json_object_add_uint (node, "decap_next_index",
12079                             ntohl (mp->decap_next_index));
12080   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12081   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12082   vat_json_object_add_uint (node, "mcast_sw_if_index",
12083                             ntohl (mp->mcast_sw_if_index));
12084 }
12085
12086 static int
12087 api_vxlan_tunnel_dump (vat_main_t * vam)
12088 {
12089   unformat_input_t *i = vam->input;
12090   vl_api_vxlan_tunnel_dump_t *mp;
12091   vl_api_control_ping_t *mp_ping;
12092   u32 sw_if_index;
12093   u8 sw_if_index_set = 0;
12094   int ret;
12095
12096   /* Parse args required to build the message */
12097   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12098     {
12099       if (unformat (i, "sw_if_index %d", &sw_if_index))
12100         sw_if_index_set = 1;
12101       else
12102         break;
12103     }
12104
12105   if (sw_if_index_set == 0)
12106     {
12107       sw_if_index = ~0;
12108     }
12109
12110   if (!vam->json_output)
12111     {
12112       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12113              "sw_if_index", "src_address", "dst_address",
12114              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12115     }
12116
12117   /* Get list of vxlan-tunnel interfaces */
12118   M (VXLAN_TUNNEL_DUMP, mp);
12119
12120   mp->sw_if_index = htonl (sw_if_index);
12121
12122   S (mp);
12123
12124   /* Use a control ping for synchronization */
12125   MPING (CONTROL_PING, mp_ping);
12126   S (mp_ping);
12127
12128   W (ret);
12129   return ret;
12130 }
12131
12132 static uword unformat_geneve_decap_next
12133   (unformat_input_t * input, va_list * args)
12134 {
12135   u32 *result = va_arg (*args, u32 *);
12136   u32 tmp;
12137
12138   if (unformat (input, "l2"))
12139     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12140   else if (unformat (input, "%d", &tmp))
12141     *result = tmp;
12142   else
12143     return 0;
12144   return 1;
12145 }
12146
12147 static int
12148 api_geneve_add_del_tunnel (vat_main_t * vam)
12149 {
12150   unformat_input_t *line_input = vam->input;
12151   vl_api_geneve_add_del_tunnel_t *mp;
12152   ip46_address_t src, dst;
12153   u8 is_add = 1;
12154   u8 ipv4_set = 0, ipv6_set = 0;
12155   u8 src_set = 0;
12156   u8 dst_set = 0;
12157   u8 grp_set = 0;
12158   u32 mcast_sw_if_index = ~0;
12159   u32 encap_vrf_id = 0;
12160   u32 decap_next_index = ~0;
12161   u32 vni = 0;
12162   int ret;
12163
12164   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12165   memset (&src, 0, sizeof src);
12166   memset (&dst, 0, sizeof dst);
12167
12168   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12169     {
12170       if (unformat (line_input, "del"))
12171         is_add = 0;
12172       else
12173         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12174         {
12175           ipv4_set = 1;
12176           src_set = 1;
12177         }
12178       else
12179         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12180         {
12181           ipv4_set = 1;
12182           dst_set = 1;
12183         }
12184       else
12185         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12186         {
12187           ipv6_set = 1;
12188           src_set = 1;
12189         }
12190       else
12191         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12192         {
12193           ipv6_set = 1;
12194           dst_set = 1;
12195         }
12196       else if (unformat (line_input, "group %U %U",
12197                          unformat_ip4_address, &dst.ip4,
12198                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12199         {
12200           grp_set = dst_set = 1;
12201           ipv4_set = 1;
12202         }
12203       else if (unformat (line_input, "group %U",
12204                          unformat_ip4_address, &dst.ip4))
12205         {
12206           grp_set = dst_set = 1;
12207           ipv4_set = 1;
12208         }
12209       else if (unformat (line_input, "group %U %U",
12210                          unformat_ip6_address, &dst.ip6,
12211                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12212         {
12213           grp_set = dst_set = 1;
12214           ipv6_set = 1;
12215         }
12216       else if (unformat (line_input, "group %U",
12217                          unformat_ip6_address, &dst.ip6))
12218         {
12219           grp_set = dst_set = 1;
12220           ipv6_set = 1;
12221         }
12222       else
12223         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12224         ;
12225       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12226         ;
12227       else if (unformat (line_input, "decap-next %U",
12228                          unformat_geneve_decap_next, &decap_next_index))
12229         ;
12230       else if (unformat (line_input, "vni %d", &vni))
12231         ;
12232       else
12233         {
12234           errmsg ("parse error '%U'", format_unformat_error, line_input);
12235           return -99;
12236         }
12237     }
12238
12239   if (src_set == 0)
12240     {
12241       errmsg ("tunnel src address not specified");
12242       return -99;
12243     }
12244   if (dst_set == 0)
12245     {
12246       errmsg ("tunnel dst address not specified");
12247       return -99;
12248     }
12249
12250   if (grp_set && !ip46_address_is_multicast (&dst))
12251     {
12252       errmsg ("tunnel group address not multicast");
12253       return -99;
12254     }
12255   if (grp_set && mcast_sw_if_index == ~0)
12256     {
12257       errmsg ("tunnel nonexistent multicast device");
12258       return -99;
12259     }
12260   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12261     {
12262       errmsg ("tunnel dst address must be unicast");
12263       return -99;
12264     }
12265
12266
12267   if (ipv4_set && ipv6_set)
12268     {
12269       errmsg ("both IPv4 and IPv6 addresses specified");
12270       return -99;
12271     }
12272
12273   if ((vni == 0) || (vni >> 24))
12274     {
12275       errmsg ("vni not specified or out of range");
12276       return -99;
12277     }
12278
12279   M (GENEVE_ADD_DEL_TUNNEL, mp);
12280
12281   if (ipv6_set)
12282     {
12283       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12284       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12285     }
12286   else
12287     {
12288       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12289       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12290     }
12291   mp->encap_vrf_id = ntohl (encap_vrf_id);
12292   mp->decap_next_index = ntohl (decap_next_index);
12293   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12294   mp->vni = ntohl (vni);
12295   mp->is_add = is_add;
12296   mp->is_ipv6 = ipv6_set;
12297
12298   S (mp);
12299   W (ret);
12300   return ret;
12301 }
12302
12303 static void vl_api_geneve_tunnel_details_t_handler
12304   (vl_api_geneve_tunnel_details_t * mp)
12305 {
12306   vat_main_t *vam = &vat_main;
12307   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12308   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12309
12310   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12311          ntohl (mp->sw_if_index),
12312          format_ip46_address, &src, IP46_TYPE_ANY,
12313          format_ip46_address, &dst, IP46_TYPE_ANY,
12314          ntohl (mp->encap_vrf_id),
12315          ntohl (mp->decap_next_index), ntohl (mp->vni),
12316          ntohl (mp->mcast_sw_if_index));
12317 }
12318
12319 static void vl_api_geneve_tunnel_details_t_handler_json
12320   (vl_api_geneve_tunnel_details_t * mp)
12321 {
12322   vat_main_t *vam = &vat_main;
12323   vat_json_node_t *node = NULL;
12324
12325   if (VAT_JSON_ARRAY != vam->json_tree.type)
12326     {
12327       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12328       vat_json_init_array (&vam->json_tree);
12329     }
12330   node = vat_json_array_add (&vam->json_tree);
12331
12332   vat_json_init_object (node);
12333   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12334   if (mp->is_ipv6)
12335     {
12336       struct in6_addr ip6;
12337
12338       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12339       vat_json_object_add_ip6 (node, "src_address", ip6);
12340       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12341       vat_json_object_add_ip6 (node, "dst_address", ip6);
12342     }
12343   else
12344     {
12345       struct in_addr ip4;
12346
12347       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12348       vat_json_object_add_ip4 (node, "src_address", ip4);
12349       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12350       vat_json_object_add_ip4 (node, "dst_address", ip4);
12351     }
12352   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12353   vat_json_object_add_uint (node, "decap_next_index",
12354                             ntohl (mp->decap_next_index));
12355   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12356   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12357   vat_json_object_add_uint (node, "mcast_sw_if_index",
12358                             ntohl (mp->mcast_sw_if_index));
12359 }
12360
12361 static int
12362 api_geneve_tunnel_dump (vat_main_t * vam)
12363 {
12364   unformat_input_t *i = vam->input;
12365   vl_api_geneve_tunnel_dump_t *mp;
12366   vl_api_control_ping_t *mp_ping;
12367   u32 sw_if_index;
12368   u8 sw_if_index_set = 0;
12369   int ret;
12370
12371   /* Parse args required to build the message */
12372   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12373     {
12374       if (unformat (i, "sw_if_index %d", &sw_if_index))
12375         sw_if_index_set = 1;
12376       else
12377         break;
12378     }
12379
12380   if (sw_if_index_set == 0)
12381     {
12382       sw_if_index = ~0;
12383     }
12384
12385   if (!vam->json_output)
12386     {
12387       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12388              "sw_if_index", "local_address", "remote_address",
12389              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12390     }
12391
12392   /* Get list of geneve-tunnel interfaces */
12393   M (GENEVE_TUNNEL_DUMP, mp);
12394
12395   mp->sw_if_index = htonl (sw_if_index);
12396
12397   S (mp);
12398
12399   /* Use a control ping for synchronization */
12400   M (CONTROL_PING, mp_ping);
12401   S (mp_ping);
12402
12403   W (ret);
12404   return ret;
12405 }
12406
12407 static int
12408 api_gre_add_del_tunnel (vat_main_t * vam)
12409 {
12410   unformat_input_t *line_input = vam->input;
12411   vl_api_gre_add_del_tunnel_t *mp;
12412   ip4_address_t src4, dst4;
12413   ip6_address_t src6, dst6;
12414   u8 is_add = 1;
12415   u8 ipv4_set = 0;
12416   u8 ipv6_set = 0;
12417   u8 teb = 0;
12418   u8 src_set = 0;
12419   u8 dst_set = 0;
12420   u32 outer_fib_id = 0;
12421   int ret;
12422
12423   memset (&src4, 0, sizeof src4);
12424   memset (&dst4, 0, sizeof dst4);
12425   memset (&src6, 0, sizeof src6);
12426   memset (&dst6, 0, sizeof dst6);
12427
12428   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12429     {
12430       if (unformat (line_input, "del"))
12431         is_add = 0;
12432       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
12433         {
12434           src_set = 1;
12435           ipv4_set = 1;
12436         }
12437       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
12438         {
12439           dst_set = 1;
12440           ipv4_set = 1;
12441         }
12442       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
12443         {
12444           src_set = 1;
12445           ipv6_set = 1;
12446         }
12447       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
12448         {
12449           dst_set = 1;
12450           ipv6_set = 1;
12451         }
12452       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
12453         ;
12454       else if (unformat (line_input, "teb"))
12455         teb = 1;
12456       else
12457         {
12458           errmsg ("parse error '%U'", format_unformat_error, line_input);
12459           return -99;
12460         }
12461     }
12462
12463   if (src_set == 0)
12464     {
12465       errmsg ("tunnel src address not specified");
12466       return -99;
12467     }
12468   if (dst_set == 0)
12469     {
12470       errmsg ("tunnel dst address not specified");
12471       return -99;
12472     }
12473   if (ipv4_set && ipv6_set)
12474     {
12475       errmsg ("both IPv4 and IPv6 addresses specified");
12476       return -99;
12477     }
12478
12479
12480   M (GRE_ADD_DEL_TUNNEL, mp);
12481
12482   if (ipv4_set)
12483     {
12484       clib_memcpy (&mp->src_address, &src4, 4);
12485       clib_memcpy (&mp->dst_address, &dst4, 4);
12486     }
12487   else
12488     {
12489       clib_memcpy (&mp->src_address, &src6, 16);
12490       clib_memcpy (&mp->dst_address, &dst6, 16);
12491     }
12492   mp->outer_fib_id = ntohl (outer_fib_id);
12493   mp->is_add = is_add;
12494   mp->teb = teb;
12495   mp->is_ipv6 = ipv6_set;
12496
12497   S (mp);
12498   W (ret);
12499   return ret;
12500 }
12501
12502 static void vl_api_gre_tunnel_details_t_handler
12503   (vl_api_gre_tunnel_details_t * mp)
12504 {
12505   vat_main_t *vam = &vat_main;
12506   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
12507   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
12508
12509   print (vam->ofp, "%11d%24U%24U%6d%14d",
12510          ntohl (mp->sw_if_index),
12511          format_ip46_address, &src, IP46_TYPE_ANY,
12512          format_ip46_address, &dst, IP46_TYPE_ANY,
12513          mp->teb, ntohl (mp->outer_fib_id));
12514 }
12515
12516 static void vl_api_gre_tunnel_details_t_handler_json
12517   (vl_api_gre_tunnel_details_t * mp)
12518 {
12519   vat_main_t *vam = &vat_main;
12520   vat_json_node_t *node = NULL;
12521   struct in_addr ip4;
12522   struct in6_addr ip6;
12523
12524   if (VAT_JSON_ARRAY != vam->json_tree.type)
12525     {
12526       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12527       vat_json_init_array (&vam->json_tree);
12528     }
12529   node = vat_json_array_add (&vam->json_tree);
12530
12531   vat_json_init_object (node);
12532   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12533   if (!mp->is_ipv6)
12534     {
12535       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
12536       vat_json_object_add_ip4 (node, "src_address", ip4);
12537       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
12538       vat_json_object_add_ip4 (node, "dst_address", ip4);
12539     }
12540   else
12541     {
12542       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
12543       vat_json_object_add_ip6 (node, "src_address", ip6);
12544       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
12545       vat_json_object_add_ip6 (node, "dst_address", ip6);
12546     }
12547   vat_json_object_add_uint (node, "teb", mp->teb);
12548   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
12549   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
12550 }
12551
12552 static int
12553 api_gre_tunnel_dump (vat_main_t * vam)
12554 {
12555   unformat_input_t *i = vam->input;
12556   vl_api_gre_tunnel_dump_t *mp;
12557   vl_api_control_ping_t *mp_ping;
12558   u32 sw_if_index;
12559   u8 sw_if_index_set = 0;
12560   int ret;
12561
12562   /* Parse args required to build the message */
12563   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12564     {
12565       if (unformat (i, "sw_if_index %d", &sw_if_index))
12566         sw_if_index_set = 1;
12567       else
12568         break;
12569     }
12570
12571   if (sw_if_index_set == 0)
12572     {
12573       sw_if_index = ~0;
12574     }
12575
12576   if (!vam->json_output)
12577     {
12578       print (vam->ofp, "%11s%24s%24s%6s%14s",
12579              "sw_if_index", "src_address", "dst_address", "teb",
12580              "outer_fib_id");
12581     }
12582
12583   /* Get list of gre-tunnel interfaces */
12584   M (GRE_TUNNEL_DUMP, mp);
12585
12586   mp->sw_if_index = htonl (sw_if_index);
12587
12588   S (mp);
12589
12590   /* Use a control ping for synchronization */
12591   MPING (CONTROL_PING, mp_ping);
12592   S (mp_ping);
12593
12594   W (ret);
12595   return ret;
12596 }
12597
12598 static int
12599 api_l2_fib_clear_table (vat_main_t * vam)
12600 {
12601 //  unformat_input_t * i = vam->input;
12602   vl_api_l2_fib_clear_table_t *mp;
12603   int ret;
12604
12605   M (L2_FIB_CLEAR_TABLE, mp);
12606
12607   S (mp);
12608   W (ret);
12609   return ret;
12610 }
12611
12612 static int
12613 api_l2_interface_efp_filter (vat_main_t * vam)
12614 {
12615   unformat_input_t *i = vam->input;
12616   vl_api_l2_interface_efp_filter_t *mp;
12617   u32 sw_if_index;
12618   u8 enable = 1;
12619   u8 sw_if_index_set = 0;
12620   int ret;
12621
12622   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12623     {
12624       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12625         sw_if_index_set = 1;
12626       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12627         sw_if_index_set = 1;
12628       else if (unformat (i, "enable"))
12629         enable = 1;
12630       else if (unformat (i, "disable"))
12631         enable = 0;
12632       else
12633         {
12634           clib_warning ("parse error '%U'", format_unformat_error, i);
12635           return -99;
12636         }
12637     }
12638
12639   if (sw_if_index_set == 0)
12640     {
12641       errmsg ("missing sw_if_index");
12642       return -99;
12643     }
12644
12645   M (L2_INTERFACE_EFP_FILTER, mp);
12646
12647   mp->sw_if_index = ntohl (sw_if_index);
12648   mp->enable_disable = enable;
12649
12650   S (mp);
12651   W (ret);
12652   return ret;
12653 }
12654
12655 #define foreach_vtr_op                          \
12656 _("disable",  L2_VTR_DISABLED)                  \
12657 _("push-1",  L2_VTR_PUSH_1)                     \
12658 _("push-2",  L2_VTR_PUSH_2)                     \
12659 _("pop-1",  L2_VTR_POP_1)                       \
12660 _("pop-2",  L2_VTR_POP_2)                       \
12661 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12662 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12663 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12664 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12665
12666 static int
12667 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12668 {
12669   unformat_input_t *i = vam->input;
12670   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12671   u32 sw_if_index;
12672   u8 sw_if_index_set = 0;
12673   u8 vtr_op_set = 0;
12674   u32 vtr_op = 0;
12675   u32 push_dot1q = 1;
12676   u32 tag1 = ~0;
12677   u32 tag2 = ~0;
12678   int ret;
12679
12680   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12681     {
12682       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12683         sw_if_index_set = 1;
12684       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12685         sw_if_index_set = 1;
12686       else if (unformat (i, "vtr_op %d", &vtr_op))
12687         vtr_op_set = 1;
12688 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12689       foreach_vtr_op
12690 #undef _
12691         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12692         ;
12693       else if (unformat (i, "tag1 %d", &tag1))
12694         ;
12695       else if (unformat (i, "tag2 %d", &tag2))
12696         ;
12697       else
12698         {
12699           clib_warning ("parse error '%U'", format_unformat_error, i);
12700           return -99;
12701         }
12702     }
12703
12704   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12705     {
12706       errmsg ("missing vtr operation or sw_if_index");
12707       return -99;
12708     }
12709
12710   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12711   mp->sw_if_index = ntohl (sw_if_index);
12712   mp->vtr_op = ntohl (vtr_op);
12713   mp->push_dot1q = ntohl (push_dot1q);
12714   mp->tag1 = ntohl (tag1);
12715   mp->tag2 = ntohl (tag2);
12716
12717   S (mp);
12718   W (ret);
12719   return ret;
12720 }
12721
12722 static int
12723 api_create_vhost_user_if (vat_main_t * vam)
12724 {
12725   unformat_input_t *i = vam->input;
12726   vl_api_create_vhost_user_if_t *mp;
12727   u8 *file_name;
12728   u8 is_server = 0;
12729   u8 file_name_set = 0;
12730   u32 custom_dev_instance = ~0;
12731   u8 hwaddr[6];
12732   u8 use_custom_mac = 0;
12733   u8 *tag = 0;
12734   int ret;
12735
12736   /* Shut up coverity */
12737   memset (hwaddr, 0, sizeof (hwaddr));
12738
12739   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12740     {
12741       if (unformat (i, "socket %s", &file_name))
12742         {
12743           file_name_set = 1;
12744         }
12745       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12746         ;
12747       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12748         use_custom_mac = 1;
12749       else if (unformat (i, "server"))
12750         is_server = 1;
12751       else if (unformat (i, "tag %s", &tag))
12752         ;
12753       else
12754         break;
12755     }
12756
12757   if (file_name_set == 0)
12758     {
12759       errmsg ("missing socket file name");
12760       return -99;
12761     }
12762
12763   if (vec_len (file_name) > 255)
12764     {
12765       errmsg ("socket file name too long");
12766       return -99;
12767     }
12768   vec_add1 (file_name, 0);
12769
12770   M (CREATE_VHOST_USER_IF, mp);
12771
12772   mp->is_server = is_server;
12773   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12774   vec_free (file_name);
12775   if (custom_dev_instance != ~0)
12776     {
12777       mp->renumber = 1;
12778       mp->custom_dev_instance = ntohl (custom_dev_instance);
12779     }
12780   mp->use_custom_mac = use_custom_mac;
12781   clib_memcpy (mp->mac_address, hwaddr, 6);
12782   if (tag)
12783     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12784   vec_free (tag);
12785
12786   S (mp);
12787   W (ret);
12788   return ret;
12789 }
12790
12791 static int
12792 api_modify_vhost_user_if (vat_main_t * vam)
12793 {
12794   unformat_input_t *i = vam->input;
12795   vl_api_modify_vhost_user_if_t *mp;
12796   u8 *file_name;
12797   u8 is_server = 0;
12798   u8 file_name_set = 0;
12799   u32 custom_dev_instance = ~0;
12800   u8 sw_if_index_set = 0;
12801   u32 sw_if_index = (u32) ~ 0;
12802   int ret;
12803
12804   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12805     {
12806       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12807         sw_if_index_set = 1;
12808       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12809         sw_if_index_set = 1;
12810       else if (unformat (i, "socket %s", &file_name))
12811         {
12812           file_name_set = 1;
12813         }
12814       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12815         ;
12816       else if (unformat (i, "server"))
12817         is_server = 1;
12818       else
12819         break;
12820     }
12821
12822   if (sw_if_index_set == 0)
12823     {
12824       errmsg ("missing sw_if_index or interface name");
12825       return -99;
12826     }
12827
12828   if (file_name_set == 0)
12829     {
12830       errmsg ("missing socket file name");
12831       return -99;
12832     }
12833
12834   if (vec_len (file_name) > 255)
12835     {
12836       errmsg ("socket file name too long");
12837       return -99;
12838     }
12839   vec_add1 (file_name, 0);
12840
12841   M (MODIFY_VHOST_USER_IF, mp);
12842
12843   mp->sw_if_index = ntohl (sw_if_index);
12844   mp->is_server = is_server;
12845   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12846   vec_free (file_name);
12847   if (custom_dev_instance != ~0)
12848     {
12849       mp->renumber = 1;
12850       mp->custom_dev_instance = ntohl (custom_dev_instance);
12851     }
12852
12853   S (mp);
12854   W (ret);
12855   return ret;
12856 }
12857
12858 static int
12859 api_delete_vhost_user_if (vat_main_t * vam)
12860 {
12861   unformat_input_t *i = vam->input;
12862   vl_api_delete_vhost_user_if_t *mp;
12863   u32 sw_if_index = ~0;
12864   u8 sw_if_index_set = 0;
12865   int ret;
12866
12867   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12868     {
12869       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12870         sw_if_index_set = 1;
12871       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12872         sw_if_index_set = 1;
12873       else
12874         break;
12875     }
12876
12877   if (sw_if_index_set == 0)
12878     {
12879       errmsg ("missing sw_if_index or interface name");
12880       return -99;
12881     }
12882
12883
12884   M (DELETE_VHOST_USER_IF, mp);
12885
12886   mp->sw_if_index = ntohl (sw_if_index);
12887
12888   S (mp);
12889   W (ret);
12890   return ret;
12891 }
12892
12893 static void vl_api_sw_interface_vhost_user_details_t_handler
12894   (vl_api_sw_interface_vhost_user_details_t * mp)
12895 {
12896   vat_main_t *vam = &vat_main;
12897
12898   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12899          (char *) mp->interface_name,
12900          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12901          clib_net_to_host_u64 (mp->features), mp->is_server,
12902          ntohl (mp->num_regions), (char *) mp->sock_filename);
12903   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12904 }
12905
12906 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12907   (vl_api_sw_interface_vhost_user_details_t * mp)
12908 {
12909   vat_main_t *vam = &vat_main;
12910   vat_json_node_t *node = NULL;
12911
12912   if (VAT_JSON_ARRAY != vam->json_tree.type)
12913     {
12914       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12915       vat_json_init_array (&vam->json_tree);
12916     }
12917   node = vat_json_array_add (&vam->json_tree);
12918
12919   vat_json_init_object (node);
12920   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12921   vat_json_object_add_string_copy (node, "interface_name",
12922                                    mp->interface_name);
12923   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12924                             ntohl (mp->virtio_net_hdr_sz));
12925   vat_json_object_add_uint (node, "features",
12926                             clib_net_to_host_u64 (mp->features));
12927   vat_json_object_add_uint (node, "is_server", mp->is_server);
12928   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12929   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12930   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12931 }
12932
12933 static int
12934 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12935 {
12936   vl_api_sw_interface_vhost_user_dump_t *mp;
12937   vl_api_control_ping_t *mp_ping;
12938   int ret;
12939   print (vam->ofp,
12940          "Interface name            idx hdr_sz features server regions filename");
12941
12942   /* Get list of vhost-user interfaces */
12943   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12944   S (mp);
12945
12946   /* Use a control ping for synchronization */
12947   MPING (CONTROL_PING, mp_ping);
12948   S (mp_ping);
12949
12950   W (ret);
12951   return ret;
12952 }
12953
12954 static int
12955 api_show_version (vat_main_t * vam)
12956 {
12957   vl_api_show_version_t *mp;
12958   int ret;
12959
12960   M (SHOW_VERSION, mp);
12961
12962   S (mp);
12963   W (ret);
12964   return ret;
12965 }
12966
12967
12968 static int
12969 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12970 {
12971   unformat_input_t *line_input = vam->input;
12972   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12973   ip4_address_t local4, remote4;
12974   ip6_address_t local6, remote6;
12975   u8 is_add = 1;
12976   u8 ipv4_set = 0, ipv6_set = 0;
12977   u8 local_set = 0;
12978   u8 remote_set = 0;
12979   u8 grp_set = 0;
12980   u32 mcast_sw_if_index = ~0;
12981   u32 encap_vrf_id = 0;
12982   u32 decap_vrf_id = 0;
12983   u8 protocol = ~0;
12984   u32 vni;
12985   u8 vni_set = 0;
12986   int ret;
12987
12988   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12989   memset (&local4, 0, sizeof local4);
12990   memset (&remote4, 0, sizeof remote4);
12991   memset (&local6, 0, sizeof local6);
12992   memset (&remote6, 0, sizeof remote6);
12993
12994   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12995     {
12996       if (unformat (line_input, "del"))
12997         is_add = 0;
12998       else if (unformat (line_input, "local %U",
12999                          unformat_ip4_address, &local4))
13000         {
13001           local_set = 1;
13002           ipv4_set = 1;
13003         }
13004       else if (unformat (line_input, "remote %U",
13005                          unformat_ip4_address, &remote4))
13006         {
13007           remote_set = 1;
13008           ipv4_set = 1;
13009         }
13010       else if (unformat (line_input, "local %U",
13011                          unformat_ip6_address, &local6))
13012         {
13013           local_set = 1;
13014           ipv6_set = 1;
13015         }
13016       else if (unformat (line_input, "remote %U",
13017                          unformat_ip6_address, &remote6))
13018         {
13019           remote_set = 1;
13020           ipv6_set = 1;
13021         }
13022       else if (unformat (line_input, "group %U %U",
13023                          unformat_ip4_address, &remote4,
13024                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13025         {
13026           grp_set = remote_set = 1;
13027           ipv4_set = 1;
13028         }
13029       else if (unformat (line_input, "group %U",
13030                          unformat_ip4_address, &remote4))
13031         {
13032           grp_set = remote_set = 1;
13033           ipv4_set = 1;
13034         }
13035       else if (unformat (line_input, "group %U %U",
13036                          unformat_ip6_address, &remote6,
13037                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13038         {
13039           grp_set = remote_set = 1;
13040           ipv6_set = 1;
13041         }
13042       else if (unformat (line_input, "group %U",
13043                          unformat_ip6_address, &remote6))
13044         {
13045           grp_set = remote_set = 1;
13046           ipv6_set = 1;
13047         }
13048       else
13049         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13050         ;
13051       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13052         ;
13053       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13054         ;
13055       else if (unformat (line_input, "vni %d", &vni))
13056         vni_set = 1;
13057       else if (unformat (line_input, "next-ip4"))
13058         protocol = 1;
13059       else if (unformat (line_input, "next-ip6"))
13060         protocol = 2;
13061       else if (unformat (line_input, "next-ethernet"))
13062         protocol = 3;
13063       else if (unformat (line_input, "next-nsh"))
13064         protocol = 4;
13065       else
13066         {
13067           errmsg ("parse error '%U'", format_unformat_error, line_input);
13068           return -99;
13069         }
13070     }
13071
13072   if (local_set == 0)
13073     {
13074       errmsg ("tunnel local address not specified");
13075       return -99;
13076     }
13077   if (remote_set == 0)
13078     {
13079       errmsg ("tunnel remote address not specified");
13080       return -99;
13081     }
13082   if (grp_set && mcast_sw_if_index == ~0)
13083     {
13084       errmsg ("tunnel nonexistent multicast device");
13085       return -99;
13086     }
13087   if (ipv4_set && ipv6_set)
13088     {
13089       errmsg ("both IPv4 and IPv6 addresses specified");
13090       return -99;
13091     }
13092
13093   if (vni_set == 0)
13094     {
13095       errmsg ("vni not specified");
13096       return -99;
13097     }
13098
13099   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13100
13101
13102   if (ipv6_set)
13103     {
13104       clib_memcpy (&mp->local, &local6, sizeof (local6));
13105       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13106     }
13107   else
13108     {
13109       clib_memcpy (&mp->local, &local4, sizeof (local4));
13110       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13111     }
13112
13113   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13114   mp->encap_vrf_id = ntohl (encap_vrf_id);
13115   mp->decap_vrf_id = ntohl (decap_vrf_id);
13116   mp->protocol = protocol;
13117   mp->vni = ntohl (vni);
13118   mp->is_add = is_add;
13119   mp->is_ipv6 = ipv6_set;
13120
13121   S (mp);
13122   W (ret);
13123   return ret;
13124 }
13125
13126 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13127   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13128 {
13129   vat_main_t *vam = &vat_main;
13130   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13131   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13132
13133   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13134          ntohl (mp->sw_if_index),
13135          format_ip46_address, &local, IP46_TYPE_ANY,
13136          format_ip46_address, &remote, IP46_TYPE_ANY,
13137          ntohl (mp->vni), mp->protocol,
13138          ntohl (mp->mcast_sw_if_index),
13139          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13140 }
13141
13142
13143 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13144   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13145 {
13146   vat_main_t *vam = &vat_main;
13147   vat_json_node_t *node = NULL;
13148   struct in_addr ip4;
13149   struct in6_addr ip6;
13150
13151   if (VAT_JSON_ARRAY != vam->json_tree.type)
13152     {
13153       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13154       vat_json_init_array (&vam->json_tree);
13155     }
13156   node = vat_json_array_add (&vam->json_tree);
13157
13158   vat_json_init_object (node);
13159   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13160   if (mp->is_ipv6)
13161     {
13162       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13163       vat_json_object_add_ip6 (node, "local", ip6);
13164       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13165       vat_json_object_add_ip6 (node, "remote", ip6);
13166     }
13167   else
13168     {
13169       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13170       vat_json_object_add_ip4 (node, "local", ip4);
13171       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13172       vat_json_object_add_ip4 (node, "remote", ip4);
13173     }
13174   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13175   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13176   vat_json_object_add_uint (node, "mcast_sw_if_index",
13177                             ntohl (mp->mcast_sw_if_index));
13178   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13179   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13180   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13181 }
13182
13183 static int
13184 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13185 {
13186   unformat_input_t *i = vam->input;
13187   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13188   vl_api_control_ping_t *mp_ping;
13189   u32 sw_if_index;
13190   u8 sw_if_index_set = 0;
13191   int ret;
13192
13193   /* Parse args required to build the message */
13194   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13195     {
13196       if (unformat (i, "sw_if_index %d", &sw_if_index))
13197         sw_if_index_set = 1;
13198       else
13199         break;
13200     }
13201
13202   if (sw_if_index_set == 0)
13203     {
13204       sw_if_index = ~0;
13205     }
13206
13207   if (!vam->json_output)
13208     {
13209       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13210              "sw_if_index", "local", "remote", "vni",
13211              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13212     }
13213
13214   /* Get list of vxlan-tunnel interfaces */
13215   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13216
13217   mp->sw_if_index = htonl (sw_if_index);
13218
13219   S (mp);
13220
13221   /* Use a control ping for synchronization */
13222   MPING (CONTROL_PING, mp_ping);
13223   S (mp_ping);
13224
13225   W (ret);
13226   return ret;
13227 }
13228
13229
13230 u8 *
13231 format_l2_fib_mac_address (u8 * s, va_list * args)
13232 {
13233   u8 *a = va_arg (*args, u8 *);
13234
13235   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
13236                  a[2], a[3], a[4], a[5], a[6], a[7]);
13237 }
13238
13239 static void vl_api_l2_fib_table_details_t_handler
13240   (vl_api_l2_fib_table_details_t * mp)
13241 {
13242   vat_main_t *vam = &vat_main;
13243
13244   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13245          "       %d       %d     %d",
13246          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
13247          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13248          mp->bvi_mac);
13249 }
13250
13251 static void vl_api_l2_fib_table_details_t_handler_json
13252   (vl_api_l2_fib_table_details_t * mp)
13253 {
13254   vat_main_t *vam = &vat_main;
13255   vat_json_node_t *node = NULL;
13256
13257   if (VAT_JSON_ARRAY != vam->json_tree.type)
13258     {
13259       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13260       vat_json_init_array (&vam->json_tree);
13261     }
13262   node = vat_json_array_add (&vam->json_tree);
13263
13264   vat_json_init_object (node);
13265   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13266   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
13267   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13268   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13269   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13270   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13271 }
13272
13273 static int
13274 api_l2_fib_table_dump (vat_main_t * vam)
13275 {
13276   unformat_input_t *i = vam->input;
13277   vl_api_l2_fib_table_dump_t *mp;
13278   vl_api_control_ping_t *mp_ping;
13279   u32 bd_id;
13280   u8 bd_id_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, "bd_id %d", &bd_id))
13287         bd_id_set = 1;
13288       else
13289         break;
13290     }
13291
13292   if (bd_id_set == 0)
13293     {
13294       errmsg ("missing bridge domain");
13295       return -99;
13296     }
13297
13298   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13299
13300   /* Get list of l2 fib entries */
13301   M (L2_FIB_TABLE_DUMP, mp);
13302
13303   mp->bd_id = ntohl (bd_id);
13304   S (mp);
13305
13306   /* Use a control ping for synchronization */
13307   MPING (CONTROL_PING, mp_ping);
13308   S (mp_ping);
13309
13310   W (ret);
13311   return ret;
13312 }
13313
13314
13315 static int
13316 api_interface_name_renumber (vat_main_t * vam)
13317 {
13318   unformat_input_t *line_input = vam->input;
13319   vl_api_interface_name_renumber_t *mp;
13320   u32 sw_if_index = ~0;
13321   u32 new_show_dev_instance = ~0;
13322   int ret;
13323
13324   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13325     {
13326       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13327                     &sw_if_index))
13328         ;
13329       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13330         ;
13331       else if (unformat (line_input, "new_show_dev_instance %d",
13332                          &new_show_dev_instance))
13333         ;
13334       else
13335         break;
13336     }
13337
13338   if (sw_if_index == ~0)
13339     {
13340       errmsg ("missing interface name or sw_if_index");
13341       return -99;
13342     }
13343
13344   if (new_show_dev_instance == ~0)
13345     {
13346       errmsg ("missing new_show_dev_instance");
13347       return -99;
13348     }
13349
13350   M (INTERFACE_NAME_RENUMBER, mp);
13351
13352   mp->sw_if_index = ntohl (sw_if_index);
13353   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13354
13355   S (mp);
13356   W (ret);
13357   return ret;
13358 }
13359
13360 static int
13361 api_want_ip4_arp_events (vat_main_t * vam)
13362 {
13363   unformat_input_t *line_input = vam->input;
13364   vl_api_want_ip4_arp_events_t *mp;
13365   ip4_address_t address;
13366   int address_set = 0;
13367   u32 enable_disable = 1;
13368   int ret;
13369
13370   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13371     {
13372       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
13373         address_set = 1;
13374       else if (unformat (line_input, "del"))
13375         enable_disable = 0;
13376       else
13377         break;
13378     }
13379
13380   if (address_set == 0)
13381     {
13382       errmsg ("missing addresses");
13383       return -99;
13384     }
13385
13386   M (WANT_IP4_ARP_EVENTS, mp);
13387   mp->enable_disable = enable_disable;
13388   mp->pid = htonl (getpid ());
13389   mp->address = address.as_u32;
13390
13391   S (mp);
13392   W (ret);
13393   return ret;
13394 }
13395
13396 static int
13397 api_want_ip6_nd_events (vat_main_t * vam)
13398 {
13399   unformat_input_t *line_input = vam->input;
13400   vl_api_want_ip6_nd_events_t *mp;
13401   ip6_address_t address;
13402   int address_set = 0;
13403   u32 enable_disable = 1;
13404   int ret;
13405
13406   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13407     {
13408       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
13409         address_set = 1;
13410       else if (unformat (line_input, "del"))
13411         enable_disable = 0;
13412       else
13413         break;
13414     }
13415
13416   if (address_set == 0)
13417     {
13418       errmsg ("missing addresses");
13419       return -99;
13420     }
13421
13422   M (WANT_IP6_ND_EVENTS, mp);
13423   mp->enable_disable = enable_disable;
13424   mp->pid = htonl (getpid ());
13425   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
13426
13427   S (mp);
13428   W (ret);
13429   return ret;
13430 }
13431
13432 static int
13433 api_want_l2_macs_events (vat_main_t * vam)
13434 {
13435   unformat_input_t *line_input = vam->input;
13436   vl_api_want_l2_macs_events_t *mp;
13437   u8 enable_disable = 1;
13438   u32 scan_delay = 0;
13439   u32 max_macs_in_event = 0;
13440   u32 learn_limit = 0;
13441   int ret;
13442
13443   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13444     {
13445       if (unformat (line_input, "learn-limit %d", &learn_limit))
13446         ;
13447       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13448         ;
13449       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13450         ;
13451       else if (unformat (line_input, "disable"))
13452         enable_disable = 0;
13453       else
13454         break;
13455     }
13456
13457   M (WANT_L2_MACS_EVENTS, mp);
13458   mp->enable_disable = enable_disable;
13459   mp->pid = htonl (getpid ());
13460   mp->learn_limit = htonl (learn_limit);
13461   mp->scan_delay = (u8) scan_delay;
13462   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13463   S (mp);
13464   W (ret);
13465   return ret;
13466 }
13467
13468 static int
13469 api_input_acl_set_interface (vat_main_t * vam)
13470 {
13471   unformat_input_t *i = vam->input;
13472   vl_api_input_acl_set_interface_t *mp;
13473   u32 sw_if_index;
13474   int sw_if_index_set;
13475   u32 ip4_table_index = ~0;
13476   u32 ip6_table_index = ~0;
13477   u32 l2_table_index = ~0;
13478   u8 is_add = 1;
13479   int ret;
13480
13481   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13482     {
13483       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13484         sw_if_index_set = 1;
13485       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13486         sw_if_index_set = 1;
13487       else if (unformat (i, "del"))
13488         is_add = 0;
13489       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13490         ;
13491       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13492         ;
13493       else if (unformat (i, "l2-table %d", &l2_table_index))
13494         ;
13495       else
13496         {
13497           clib_warning ("parse error '%U'", format_unformat_error, i);
13498           return -99;
13499         }
13500     }
13501
13502   if (sw_if_index_set == 0)
13503     {
13504       errmsg ("missing interface name or sw_if_index");
13505       return -99;
13506     }
13507
13508   M (INPUT_ACL_SET_INTERFACE, mp);
13509
13510   mp->sw_if_index = ntohl (sw_if_index);
13511   mp->ip4_table_index = ntohl (ip4_table_index);
13512   mp->ip6_table_index = ntohl (ip6_table_index);
13513   mp->l2_table_index = ntohl (l2_table_index);
13514   mp->is_add = is_add;
13515
13516   S (mp);
13517   W (ret);
13518   return ret;
13519 }
13520
13521 static int
13522 api_ip_address_dump (vat_main_t * vam)
13523 {
13524   unformat_input_t *i = vam->input;
13525   vl_api_ip_address_dump_t *mp;
13526   vl_api_control_ping_t *mp_ping;
13527   u32 sw_if_index = ~0;
13528   u8 sw_if_index_set = 0;
13529   u8 ipv4_set = 0;
13530   u8 ipv6_set = 0;
13531   int ret;
13532
13533   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13534     {
13535       if (unformat (i, "sw_if_index %d", &sw_if_index))
13536         sw_if_index_set = 1;
13537       else
13538         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13539         sw_if_index_set = 1;
13540       else if (unformat (i, "ipv4"))
13541         ipv4_set = 1;
13542       else if (unformat (i, "ipv6"))
13543         ipv6_set = 1;
13544       else
13545         break;
13546     }
13547
13548   if (ipv4_set && ipv6_set)
13549     {
13550       errmsg ("ipv4 and ipv6 flags cannot be both set");
13551       return -99;
13552     }
13553
13554   if ((!ipv4_set) && (!ipv6_set))
13555     {
13556       errmsg ("no ipv4 nor ipv6 flag set");
13557       return -99;
13558     }
13559
13560   if (sw_if_index_set == 0)
13561     {
13562       errmsg ("missing interface name or sw_if_index");
13563       return -99;
13564     }
13565
13566   vam->current_sw_if_index = sw_if_index;
13567   vam->is_ipv6 = ipv6_set;
13568
13569   M (IP_ADDRESS_DUMP, mp);
13570   mp->sw_if_index = ntohl (sw_if_index);
13571   mp->is_ipv6 = ipv6_set;
13572   S (mp);
13573
13574   /* Use a control ping for synchronization */
13575   MPING (CONTROL_PING, mp_ping);
13576   S (mp_ping);
13577
13578   W (ret);
13579   return ret;
13580 }
13581
13582 static int
13583 api_ip_dump (vat_main_t * vam)
13584 {
13585   vl_api_ip_dump_t *mp;
13586   vl_api_control_ping_t *mp_ping;
13587   unformat_input_t *in = vam->input;
13588   int ipv4_set = 0;
13589   int ipv6_set = 0;
13590   int is_ipv6;
13591   int i;
13592   int ret;
13593
13594   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13595     {
13596       if (unformat (in, "ipv4"))
13597         ipv4_set = 1;
13598       else if (unformat (in, "ipv6"))
13599         ipv6_set = 1;
13600       else
13601         break;
13602     }
13603
13604   if (ipv4_set && ipv6_set)
13605     {
13606       errmsg ("ipv4 and ipv6 flags cannot be both set");
13607       return -99;
13608     }
13609
13610   if ((!ipv4_set) && (!ipv6_set))
13611     {
13612       errmsg ("no ipv4 nor ipv6 flag set");
13613       return -99;
13614     }
13615
13616   is_ipv6 = ipv6_set;
13617   vam->is_ipv6 = is_ipv6;
13618
13619   /* free old data */
13620   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13621     {
13622       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13623     }
13624   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13625
13626   M (IP_DUMP, mp);
13627   mp->is_ipv6 = ipv6_set;
13628   S (mp);
13629
13630   /* Use a control ping for synchronization */
13631   MPING (CONTROL_PING, mp_ping);
13632   S (mp_ping);
13633
13634   W (ret);
13635   return ret;
13636 }
13637
13638 static int
13639 api_ipsec_spd_add_del (vat_main_t * vam)
13640 {
13641   unformat_input_t *i = vam->input;
13642   vl_api_ipsec_spd_add_del_t *mp;
13643   u32 spd_id = ~0;
13644   u8 is_add = 1;
13645   int ret;
13646
13647   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13648     {
13649       if (unformat (i, "spd_id %d", &spd_id))
13650         ;
13651       else if (unformat (i, "del"))
13652         is_add = 0;
13653       else
13654         {
13655           clib_warning ("parse error '%U'", format_unformat_error, i);
13656           return -99;
13657         }
13658     }
13659   if (spd_id == ~0)
13660     {
13661       errmsg ("spd_id must be set");
13662       return -99;
13663     }
13664
13665   M (IPSEC_SPD_ADD_DEL, mp);
13666
13667   mp->spd_id = ntohl (spd_id);
13668   mp->is_add = is_add;
13669
13670   S (mp);
13671   W (ret);
13672   return ret;
13673 }
13674
13675 static int
13676 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13677 {
13678   unformat_input_t *i = vam->input;
13679   vl_api_ipsec_interface_add_del_spd_t *mp;
13680   u32 sw_if_index;
13681   u8 sw_if_index_set = 0;
13682   u32 spd_id = (u32) ~ 0;
13683   u8 is_add = 1;
13684   int ret;
13685
13686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13687     {
13688       if (unformat (i, "del"))
13689         is_add = 0;
13690       else if (unformat (i, "spd_id %d", &spd_id))
13691         ;
13692       else
13693         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13694         sw_if_index_set = 1;
13695       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13696         sw_if_index_set = 1;
13697       else
13698         {
13699           clib_warning ("parse error '%U'", format_unformat_error, i);
13700           return -99;
13701         }
13702
13703     }
13704
13705   if (spd_id == (u32) ~ 0)
13706     {
13707       errmsg ("spd_id must be set");
13708       return -99;
13709     }
13710
13711   if (sw_if_index_set == 0)
13712     {
13713       errmsg ("missing interface name or sw_if_index");
13714       return -99;
13715     }
13716
13717   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13718
13719   mp->spd_id = ntohl (spd_id);
13720   mp->sw_if_index = ntohl (sw_if_index);
13721   mp->is_add = is_add;
13722
13723   S (mp);
13724   W (ret);
13725   return ret;
13726 }
13727
13728 static int
13729 api_ipsec_spd_add_del_entry (vat_main_t * vam)
13730 {
13731   unformat_input_t *i = vam->input;
13732   vl_api_ipsec_spd_add_del_entry_t *mp;
13733   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
13734   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13735   i32 priority = 0;
13736   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13737   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13738   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
13739   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
13740   int ret;
13741
13742   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
13743   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
13744   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
13745   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
13746   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
13747   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
13748
13749   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13750     {
13751       if (unformat (i, "del"))
13752         is_add = 0;
13753       if (unformat (i, "outbound"))
13754         is_outbound = 1;
13755       if (unformat (i, "inbound"))
13756         is_outbound = 0;
13757       else if (unformat (i, "spd_id %d", &spd_id))
13758         ;
13759       else if (unformat (i, "sa_id %d", &sa_id))
13760         ;
13761       else if (unformat (i, "priority %d", &priority))
13762         ;
13763       else if (unformat (i, "protocol %d", &protocol))
13764         ;
13765       else if (unformat (i, "lport_start %d", &lport_start))
13766         ;
13767       else if (unformat (i, "lport_stop %d", &lport_stop))
13768         ;
13769       else if (unformat (i, "rport_start %d", &rport_start))
13770         ;
13771       else if (unformat (i, "rport_stop %d", &rport_stop))
13772         ;
13773       else
13774         if (unformat
13775             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
13776         {
13777           is_ipv6 = 0;
13778           is_ip_any = 0;
13779         }
13780       else
13781         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
13782         {
13783           is_ipv6 = 0;
13784           is_ip_any = 0;
13785         }
13786       else
13787         if (unformat
13788             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
13789         {
13790           is_ipv6 = 0;
13791           is_ip_any = 0;
13792         }
13793       else
13794         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
13795         {
13796           is_ipv6 = 0;
13797           is_ip_any = 0;
13798         }
13799       else
13800         if (unformat
13801             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
13802         {
13803           is_ipv6 = 1;
13804           is_ip_any = 0;
13805         }
13806       else
13807         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
13808         {
13809           is_ipv6 = 1;
13810           is_ip_any = 0;
13811         }
13812       else
13813         if (unformat
13814             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
13815         {
13816           is_ipv6 = 1;
13817           is_ip_any = 0;
13818         }
13819       else
13820         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
13821         {
13822           is_ipv6 = 1;
13823           is_ip_any = 0;
13824         }
13825       else
13826         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13827         {
13828           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13829             {
13830               clib_warning ("unsupported action: 'resolve'");
13831               return -99;
13832             }
13833         }
13834       else
13835         {
13836           clib_warning ("parse error '%U'", format_unformat_error, i);
13837           return -99;
13838         }
13839
13840     }
13841
13842   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
13843
13844   mp->spd_id = ntohl (spd_id);
13845   mp->priority = ntohl (priority);
13846   mp->is_outbound = is_outbound;
13847
13848   mp->is_ipv6 = is_ipv6;
13849   if (is_ipv6 || is_ip_any)
13850     {
13851       clib_memcpy (mp->remote_address_start, &raddr6_start,
13852                    sizeof (ip6_address_t));
13853       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
13854                    sizeof (ip6_address_t));
13855       clib_memcpy (mp->local_address_start, &laddr6_start,
13856                    sizeof (ip6_address_t));
13857       clib_memcpy (mp->local_address_stop, &laddr6_stop,
13858                    sizeof (ip6_address_t));
13859     }
13860   else
13861     {
13862       clib_memcpy (mp->remote_address_start, &raddr4_start,
13863                    sizeof (ip4_address_t));
13864       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
13865                    sizeof (ip4_address_t));
13866       clib_memcpy (mp->local_address_start, &laddr4_start,
13867                    sizeof (ip4_address_t));
13868       clib_memcpy (mp->local_address_stop, &laddr4_stop,
13869                    sizeof (ip4_address_t));
13870     }
13871   mp->protocol = (u8) protocol;
13872   mp->local_port_start = ntohs ((u16) lport_start);
13873   mp->local_port_stop = ntohs ((u16) lport_stop);
13874   mp->remote_port_start = ntohs ((u16) rport_start);
13875   mp->remote_port_stop = ntohs ((u16) rport_stop);
13876   mp->policy = (u8) policy;
13877   mp->sa_id = ntohl (sa_id);
13878   mp->is_add = is_add;
13879   mp->is_ip_any = is_ip_any;
13880   S (mp);
13881   W (ret);
13882   return ret;
13883 }
13884
13885 static int
13886 api_ipsec_sad_add_del_entry (vat_main_t * vam)
13887 {
13888   unformat_input_t *i = vam->input;
13889   vl_api_ipsec_sad_add_del_entry_t *mp;
13890   u32 sad_id = 0, spi = 0;
13891   u8 *ck = 0, *ik = 0;
13892   u8 is_add = 1;
13893
13894   u8 protocol = IPSEC_PROTOCOL_AH;
13895   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
13896   u32 crypto_alg = 0, integ_alg = 0;
13897   ip4_address_t tun_src4;
13898   ip4_address_t tun_dst4;
13899   ip6_address_t tun_src6;
13900   ip6_address_t tun_dst6;
13901   int ret;
13902
13903   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13904     {
13905       if (unformat (i, "del"))
13906         is_add = 0;
13907       else if (unformat (i, "sad_id %d", &sad_id))
13908         ;
13909       else if (unformat (i, "spi %d", &spi))
13910         ;
13911       else if (unformat (i, "esp"))
13912         protocol = IPSEC_PROTOCOL_ESP;
13913       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
13914         {
13915           is_tunnel = 1;
13916           is_tunnel_ipv6 = 0;
13917         }
13918       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
13919         {
13920           is_tunnel = 1;
13921           is_tunnel_ipv6 = 0;
13922         }
13923       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
13924         {
13925           is_tunnel = 1;
13926           is_tunnel_ipv6 = 1;
13927         }
13928       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
13929         {
13930           is_tunnel = 1;
13931           is_tunnel_ipv6 = 1;
13932         }
13933       else
13934         if (unformat
13935             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
13936         {
13937           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
13938               crypto_alg >= IPSEC_CRYPTO_N_ALG)
13939             {
13940               clib_warning ("unsupported crypto-alg: '%U'",
13941                             format_ipsec_crypto_alg, crypto_alg);
13942               return -99;
13943             }
13944         }
13945       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13946         ;
13947       else
13948         if (unformat
13949             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
13950         {
13951           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
13952               integ_alg >= IPSEC_INTEG_N_ALG)
13953             {
13954               clib_warning ("unsupported integ-alg: '%U'",
13955                             format_ipsec_integ_alg, integ_alg);
13956               return -99;
13957             }
13958         }
13959       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13960         ;
13961       else
13962         {
13963           clib_warning ("parse error '%U'", format_unformat_error, i);
13964           return -99;
13965         }
13966
13967     }
13968
13969   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
13970
13971   mp->sad_id = ntohl (sad_id);
13972   mp->is_add = is_add;
13973   mp->protocol = protocol;
13974   mp->spi = ntohl (spi);
13975   mp->is_tunnel = is_tunnel;
13976   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
13977   mp->crypto_algorithm = crypto_alg;
13978   mp->integrity_algorithm = integ_alg;
13979   mp->crypto_key_length = vec_len (ck);
13980   mp->integrity_key_length = vec_len (ik);
13981
13982   if (mp->crypto_key_length > sizeof (mp->crypto_key))
13983     mp->crypto_key_length = sizeof (mp->crypto_key);
13984
13985   if (mp->integrity_key_length > sizeof (mp->integrity_key))
13986     mp->integrity_key_length = sizeof (mp->integrity_key);
13987
13988   if (ck)
13989     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
13990   if (ik)
13991     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
13992
13993   if (is_tunnel)
13994     {
13995       if (is_tunnel_ipv6)
13996         {
13997           clib_memcpy (mp->tunnel_src_address, &tun_src6,
13998                        sizeof (ip6_address_t));
13999           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
14000                        sizeof (ip6_address_t));
14001         }
14002       else
14003         {
14004           clib_memcpy (mp->tunnel_src_address, &tun_src4,
14005                        sizeof (ip4_address_t));
14006           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
14007                        sizeof (ip4_address_t));
14008         }
14009     }
14010
14011   S (mp);
14012   W (ret);
14013   return ret;
14014 }
14015
14016 static int
14017 api_ipsec_sa_set_key (vat_main_t * vam)
14018 {
14019   unformat_input_t *i = vam->input;
14020   vl_api_ipsec_sa_set_key_t *mp;
14021   u32 sa_id;
14022   u8 *ck = 0, *ik = 0;
14023   int ret;
14024
14025   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14026     {
14027       if (unformat (i, "sa_id %d", &sa_id))
14028         ;
14029       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14030         ;
14031       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14032         ;
14033       else
14034         {
14035           clib_warning ("parse error '%U'", format_unformat_error, i);
14036           return -99;
14037         }
14038     }
14039
14040   M (IPSEC_SA_SET_KEY, mp);
14041
14042   mp->sa_id = ntohl (sa_id);
14043   mp->crypto_key_length = vec_len (ck);
14044   mp->integrity_key_length = vec_len (ik);
14045
14046   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14047     mp->crypto_key_length = sizeof (mp->crypto_key);
14048
14049   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14050     mp->integrity_key_length = sizeof (mp->integrity_key);
14051
14052   if (ck)
14053     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14054   if (ik)
14055     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14056
14057   S (mp);
14058   W (ret);
14059   return ret;
14060 }
14061
14062 static int
14063 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14064 {
14065   unformat_input_t *i = vam->input;
14066   vl_api_ipsec_tunnel_if_add_del_t *mp;
14067   u32 local_spi = 0, remote_spi = 0;
14068   u32 crypto_alg = 0, integ_alg = 0;
14069   u8 *lck = NULL, *rck = NULL;
14070   u8 *lik = NULL, *rik = NULL;
14071   ip4_address_t local_ip = { {0} };
14072   ip4_address_t remote_ip = { {0} };
14073   u8 is_add = 1;
14074   u8 esn = 0;
14075   u8 anti_replay = 0;
14076   int ret;
14077
14078   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14079     {
14080       if (unformat (i, "del"))
14081         is_add = 0;
14082       else if (unformat (i, "esn"))
14083         esn = 1;
14084       else if (unformat (i, "anti_replay"))
14085         anti_replay = 1;
14086       else if (unformat (i, "local_spi %d", &local_spi))
14087         ;
14088       else if (unformat (i, "remote_spi %d", &remote_spi))
14089         ;
14090       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
14091         ;
14092       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
14093         ;
14094       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14095         ;
14096       else
14097         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14098         ;
14099       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14100         ;
14101       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14102         ;
14103       else
14104         if (unformat
14105             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14106         {
14107           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14108               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14109             {
14110               errmsg ("unsupported crypto-alg: '%U'\n",
14111                       format_ipsec_crypto_alg, crypto_alg);
14112               return -99;
14113             }
14114         }
14115       else
14116         if (unformat
14117             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14118         {
14119           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14120               integ_alg >= IPSEC_INTEG_N_ALG)
14121             {
14122               errmsg ("unsupported integ-alg: '%U'\n",
14123                       format_ipsec_integ_alg, integ_alg);
14124               return -99;
14125             }
14126         }
14127       else
14128         {
14129           errmsg ("parse error '%U'\n", format_unformat_error, i);
14130           return -99;
14131         }
14132     }
14133
14134   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14135
14136   mp->is_add = is_add;
14137   mp->esn = esn;
14138   mp->anti_replay = anti_replay;
14139
14140   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
14141   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
14142
14143   mp->local_spi = htonl (local_spi);
14144   mp->remote_spi = htonl (remote_spi);
14145   mp->crypto_alg = (u8) crypto_alg;
14146
14147   mp->local_crypto_key_len = 0;
14148   if (lck)
14149     {
14150       mp->local_crypto_key_len = vec_len (lck);
14151       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14152         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14153       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14154     }
14155
14156   mp->remote_crypto_key_len = 0;
14157   if (rck)
14158     {
14159       mp->remote_crypto_key_len = vec_len (rck);
14160       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14161         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14162       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14163     }
14164
14165   mp->integ_alg = (u8) integ_alg;
14166
14167   mp->local_integ_key_len = 0;
14168   if (lik)
14169     {
14170       mp->local_integ_key_len = vec_len (lik);
14171       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14172         mp->local_integ_key_len = sizeof (mp->local_integ_key);
14173       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14174     }
14175
14176   mp->remote_integ_key_len = 0;
14177   if (rik)
14178     {
14179       mp->remote_integ_key_len = vec_len (rik);
14180       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14181         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14182       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14183     }
14184
14185   S (mp);
14186   W (ret);
14187   return ret;
14188 }
14189
14190 static void
14191 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14192 {
14193   vat_main_t *vam = &vat_main;
14194
14195   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14196          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
14197          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
14198          "tunnel_src_addr %U tunnel_dst_addr %U "
14199          "salt %u seq_outbound %lu last_seq_inbound %lu "
14200          "replay_window %lu total_data_size %lu\n",
14201          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
14202          mp->protocol,
14203          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
14204          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
14205          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
14206          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14207          mp->tunnel_src_addr,
14208          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14209          mp->tunnel_dst_addr,
14210          ntohl (mp->salt),
14211          clib_net_to_host_u64 (mp->seq_outbound),
14212          clib_net_to_host_u64 (mp->last_seq_inbound),
14213          clib_net_to_host_u64 (mp->replay_window),
14214          clib_net_to_host_u64 (mp->total_data_size));
14215 }
14216
14217 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14218 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14219
14220 static void vl_api_ipsec_sa_details_t_handler_json
14221   (vl_api_ipsec_sa_details_t * mp)
14222 {
14223   vat_main_t *vam = &vat_main;
14224   vat_json_node_t *node = NULL;
14225   struct in_addr src_ip4, dst_ip4;
14226   struct in6_addr src_ip6, dst_ip6;
14227
14228   if (VAT_JSON_ARRAY != vam->json_tree.type)
14229     {
14230       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14231       vat_json_init_array (&vam->json_tree);
14232     }
14233   node = vat_json_array_add (&vam->json_tree);
14234
14235   vat_json_init_object (node);
14236   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
14237   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14238   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
14239   vat_json_object_add_uint (node, "proto", mp->protocol);
14240   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
14241   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
14242   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
14243   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
14244   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
14245   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
14246   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
14247                              mp->crypto_key_len);
14248   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
14249                              mp->integ_key_len);
14250   if (mp->is_tunnel_ip6)
14251     {
14252       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
14253       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
14254       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
14255       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
14256     }
14257   else
14258     {
14259       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
14260       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
14261       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
14262       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
14263     }
14264   vat_json_object_add_uint (node, "replay_window",
14265                             clib_net_to_host_u64 (mp->replay_window));
14266   vat_json_object_add_uint (node, "total_data_size",
14267                             clib_net_to_host_u64 (mp->total_data_size));
14268
14269 }
14270
14271 static int
14272 api_ipsec_sa_dump (vat_main_t * vam)
14273 {
14274   unformat_input_t *i = vam->input;
14275   vl_api_ipsec_sa_dump_t *mp;
14276   vl_api_control_ping_t *mp_ping;
14277   u32 sa_id = ~0;
14278   int ret;
14279
14280   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14281     {
14282       if (unformat (i, "sa_id %d", &sa_id))
14283         ;
14284       else
14285         {
14286           clib_warning ("parse error '%U'", format_unformat_error, i);
14287           return -99;
14288         }
14289     }
14290
14291   M (IPSEC_SA_DUMP, mp);
14292
14293   mp->sa_id = ntohl (sa_id);
14294
14295   S (mp);
14296
14297   /* Use a control ping for synchronization */
14298   M (CONTROL_PING, mp_ping);
14299   S (mp_ping);
14300
14301   W (ret);
14302   return ret;
14303 }
14304
14305 static int
14306 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
14307 {
14308   unformat_input_t *i = vam->input;
14309   vl_api_ipsec_tunnel_if_set_key_t *mp;
14310   u32 sw_if_index = ~0;
14311   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
14312   u8 *key = 0;
14313   u32 alg = ~0;
14314   int ret;
14315
14316   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14317     {
14318       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14319         ;
14320       else
14321         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
14322         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
14323       else
14324         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
14325         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
14326       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
14327         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
14328       else
14329         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
14330         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
14331       else if (unformat (i, "%U", unformat_hex_string, &key))
14332         ;
14333       else
14334         {
14335           clib_warning ("parse error '%U'", format_unformat_error, i);
14336           return -99;
14337         }
14338     }
14339
14340   if (sw_if_index == ~0)
14341     {
14342       errmsg ("interface must be specified");
14343       return -99;
14344     }
14345
14346   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
14347     {
14348       errmsg ("key type must be specified");
14349       return -99;
14350     }
14351
14352   if (alg == ~0)
14353     {
14354       errmsg ("algorithm must be specified");
14355       return -99;
14356     }
14357
14358   if (vec_len (key) == 0)
14359     {
14360       errmsg ("key must be specified");
14361       return -99;
14362     }
14363
14364   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
14365
14366   mp->sw_if_index = htonl (sw_if_index);
14367   mp->alg = alg;
14368   mp->key_type = key_type;
14369   mp->key_len = vec_len (key);
14370   clib_memcpy (mp->key, key, vec_len (key));
14371
14372   S (mp);
14373   W (ret);
14374
14375   return ret;
14376 }
14377
14378 static int
14379 api_ikev2_profile_add_del (vat_main_t * vam)
14380 {
14381   unformat_input_t *i = vam->input;
14382   vl_api_ikev2_profile_add_del_t *mp;
14383   u8 is_add = 1;
14384   u8 *name = 0;
14385   int ret;
14386
14387   const char *valid_chars = "a-zA-Z0-9_";
14388
14389   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14390     {
14391       if (unformat (i, "del"))
14392         is_add = 0;
14393       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14394         vec_add1 (name, 0);
14395       else
14396         {
14397           errmsg ("parse error '%U'", format_unformat_error, i);
14398           return -99;
14399         }
14400     }
14401
14402   if (!vec_len (name))
14403     {
14404       errmsg ("profile name must be specified");
14405       return -99;
14406     }
14407
14408   if (vec_len (name) > 64)
14409     {
14410       errmsg ("profile name too long");
14411       return -99;
14412     }
14413
14414   M (IKEV2_PROFILE_ADD_DEL, mp);
14415
14416   clib_memcpy (mp->name, name, vec_len (name));
14417   mp->is_add = is_add;
14418   vec_free (name);
14419
14420   S (mp);
14421   W (ret);
14422   return ret;
14423 }
14424
14425 static int
14426 api_ikev2_profile_set_auth (vat_main_t * vam)
14427 {
14428   unformat_input_t *i = vam->input;
14429   vl_api_ikev2_profile_set_auth_t *mp;
14430   u8 *name = 0;
14431   u8 *data = 0;
14432   u32 auth_method = 0;
14433   u8 is_hex = 0;
14434   int ret;
14435
14436   const char *valid_chars = "a-zA-Z0-9_";
14437
14438   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14439     {
14440       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14441         vec_add1 (name, 0);
14442       else if (unformat (i, "auth_method %U",
14443                          unformat_ikev2_auth_method, &auth_method))
14444         ;
14445       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
14446         is_hex = 1;
14447       else if (unformat (i, "auth_data %v", &data))
14448         ;
14449       else
14450         {
14451           errmsg ("parse error '%U'", format_unformat_error, i);
14452           return -99;
14453         }
14454     }
14455
14456   if (!vec_len (name))
14457     {
14458       errmsg ("profile name must be specified");
14459       return -99;
14460     }
14461
14462   if (vec_len (name) > 64)
14463     {
14464       errmsg ("profile name too long");
14465       return -99;
14466     }
14467
14468   if (!vec_len (data))
14469     {
14470       errmsg ("auth_data must be specified");
14471       return -99;
14472     }
14473
14474   if (!auth_method)
14475     {
14476       errmsg ("auth_method must be specified");
14477       return -99;
14478     }
14479
14480   M (IKEV2_PROFILE_SET_AUTH, mp);
14481
14482   mp->is_hex = is_hex;
14483   mp->auth_method = (u8) auth_method;
14484   mp->data_len = vec_len (data);
14485   clib_memcpy (mp->name, name, vec_len (name));
14486   clib_memcpy (mp->data, data, vec_len (data));
14487   vec_free (name);
14488   vec_free (data);
14489
14490   S (mp);
14491   W (ret);
14492   return ret;
14493 }
14494
14495 static int
14496 api_ikev2_profile_set_id (vat_main_t * vam)
14497 {
14498   unformat_input_t *i = vam->input;
14499   vl_api_ikev2_profile_set_id_t *mp;
14500   u8 *name = 0;
14501   u8 *data = 0;
14502   u8 is_local = 0;
14503   u32 id_type = 0;
14504   ip4_address_t ip4;
14505   int ret;
14506
14507   const char *valid_chars = "a-zA-Z0-9_";
14508
14509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14510     {
14511       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14512         vec_add1 (name, 0);
14513       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
14514         ;
14515       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
14516         {
14517           data = vec_new (u8, 4);
14518           clib_memcpy (data, ip4.as_u8, 4);
14519         }
14520       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
14521         ;
14522       else if (unformat (i, "id_data %v", &data))
14523         ;
14524       else if (unformat (i, "local"))
14525         is_local = 1;
14526       else if (unformat (i, "remote"))
14527         is_local = 0;
14528       else
14529         {
14530           errmsg ("parse error '%U'", format_unformat_error, i);
14531           return -99;
14532         }
14533     }
14534
14535   if (!vec_len (name))
14536     {
14537       errmsg ("profile name must be specified");
14538       return -99;
14539     }
14540
14541   if (vec_len (name) > 64)
14542     {
14543       errmsg ("profile name too long");
14544       return -99;
14545     }
14546
14547   if (!vec_len (data))
14548     {
14549       errmsg ("id_data must be specified");
14550       return -99;
14551     }
14552
14553   if (!id_type)
14554     {
14555       errmsg ("id_type must be specified");
14556       return -99;
14557     }
14558
14559   M (IKEV2_PROFILE_SET_ID, mp);
14560
14561   mp->is_local = is_local;
14562   mp->id_type = (u8) id_type;
14563   mp->data_len = vec_len (data);
14564   clib_memcpy (mp->name, name, vec_len (name));
14565   clib_memcpy (mp->data, data, vec_len (data));
14566   vec_free (name);
14567   vec_free (data);
14568
14569   S (mp);
14570   W (ret);
14571   return ret;
14572 }
14573
14574 static int
14575 api_ikev2_profile_set_ts (vat_main_t * vam)
14576 {
14577   unformat_input_t *i = vam->input;
14578   vl_api_ikev2_profile_set_ts_t *mp;
14579   u8 *name = 0;
14580   u8 is_local = 0;
14581   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
14582   ip4_address_t start_addr, end_addr;
14583
14584   const char *valid_chars = "a-zA-Z0-9_";
14585   int ret;
14586
14587   start_addr.as_u32 = 0;
14588   end_addr.as_u32 = (u32) ~ 0;
14589
14590   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14591     {
14592       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14593         vec_add1 (name, 0);
14594       else if (unformat (i, "protocol %d", &proto))
14595         ;
14596       else if (unformat (i, "start_port %d", &start_port))
14597         ;
14598       else if (unformat (i, "end_port %d", &end_port))
14599         ;
14600       else
14601         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
14602         ;
14603       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
14604         ;
14605       else if (unformat (i, "local"))
14606         is_local = 1;
14607       else if (unformat (i, "remote"))
14608         is_local = 0;
14609       else
14610         {
14611           errmsg ("parse error '%U'", format_unformat_error, i);
14612           return -99;
14613         }
14614     }
14615
14616   if (!vec_len (name))
14617     {
14618       errmsg ("profile name must be specified");
14619       return -99;
14620     }
14621
14622   if (vec_len (name) > 64)
14623     {
14624       errmsg ("profile name too long");
14625       return -99;
14626     }
14627
14628   M (IKEV2_PROFILE_SET_TS, mp);
14629
14630   mp->is_local = is_local;
14631   mp->proto = (u8) proto;
14632   mp->start_port = (u16) start_port;
14633   mp->end_port = (u16) end_port;
14634   mp->start_addr = start_addr.as_u32;
14635   mp->end_addr = end_addr.as_u32;
14636   clib_memcpy (mp->name, name, vec_len (name));
14637   vec_free (name);
14638
14639   S (mp);
14640   W (ret);
14641   return ret;
14642 }
14643
14644 static int
14645 api_ikev2_set_local_key (vat_main_t * vam)
14646 {
14647   unformat_input_t *i = vam->input;
14648   vl_api_ikev2_set_local_key_t *mp;
14649   u8 *file = 0;
14650   int ret;
14651
14652   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14653     {
14654       if (unformat (i, "file %v", &file))
14655         vec_add1 (file, 0);
14656       else
14657         {
14658           errmsg ("parse error '%U'", format_unformat_error, i);
14659           return -99;
14660         }
14661     }
14662
14663   if (!vec_len (file))
14664     {
14665       errmsg ("RSA key file must be specified");
14666       return -99;
14667     }
14668
14669   if (vec_len (file) > 256)
14670     {
14671       errmsg ("file name too long");
14672       return -99;
14673     }
14674
14675   M (IKEV2_SET_LOCAL_KEY, mp);
14676
14677   clib_memcpy (mp->key_file, file, vec_len (file));
14678   vec_free (file);
14679
14680   S (mp);
14681   W (ret);
14682   return ret;
14683 }
14684
14685 static int
14686 api_ikev2_set_responder (vat_main_t * vam)
14687 {
14688   unformat_input_t *i = vam->input;
14689   vl_api_ikev2_set_responder_t *mp;
14690   int ret;
14691   u8 *name = 0;
14692   u32 sw_if_index = ~0;
14693   ip4_address_t address;
14694
14695   const char *valid_chars = "a-zA-Z0-9_";
14696
14697   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14698     {
14699       if (unformat
14700           (i, "%U interface %d address %U", unformat_token, valid_chars,
14701            &name, &sw_if_index, unformat_ip4_address, &address))
14702         vec_add1 (name, 0);
14703       else
14704         {
14705           errmsg ("parse error '%U'", format_unformat_error, i);
14706           return -99;
14707         }
14708     }
14709
14710   if (!vec_len (name))
14711     {
14712       errmsg ("profile name must be specified");
14713       return -99;
14714     }
14715
14716   if (vec_len (name) > 64)
14717     {
14718       errmsg ("profile name too long");
14719       return -99;
14720     }
14721
14722   M (IKEV2_SET_RESPONDER, mp);
14723
14724   clib_memcpy (mp->name, name, vec_len (name));
14725   vec_free (name);
14726
14727   mp->sw_if_index = sw_if_index;
14728   clib_memcpy (mp->address, &address, sizeof (address));
14729
14730   S (mp);
14731   W (ret);
14732   return ret;
14733 }
14734
14735 static int
14736 api_ikev2_set_ike_transforms (vat_main_t * vam)
14737 {
14738   unformat_input_t *i = vam->input;
14739   vl_api_ikev2_set_ike_transforms_t *mp;
14740   int ret;
14741   u8 *name = 0;
14742   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
14743
14744   const char *valid_chars = "a-zA-Z0-9_";
14745
14746   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14747     {
14748       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
14749                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
14750         vec_add1 (name, 0);
14751       else
14752         {
14753           errmsg ("parse error '%U'", format_unformat_error, i);
14754           return -99;
14755         }
14756     }
14757
14758   if (!vec_len (name))
14759     {
14760       errmsg ("profile name must be specified");
14761       return -99;
14762     }
14763
14764   if (vec_len (name) > 64)
14765     {
14766       errmsg ("profile name too long");
14767       return -99;
14768     }
14769
14770   M (IKEV2_SET_IKE_TRANSFORMS, mp);
14771
14772   clib_memcpy (mp->name, name, vec_len (name));
14773   vec_free (name);
14774   mp->crypto_alg = crypto_alg;
14775   mp->crypto_key_size = crypto_key_size;
14776   mp->integ_alg = integ_alg;
14777   mp->dh_group = dh_group;
14778
14779   S (mp);
14780   W (ret);
14781   return ret;
14782 }
14783
14784
14785 static int
14786 api_ikev2_set_esp_transforms (vat_main_t * vam)
14787 {
14788   unformat_input_t *i = vam->input;
14789   vl_api_ikev2_set_esp_transforms_t *mp;
14790   int ret;
14791   u8 *name = 0;
14792   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
14793
14794   const char *valid_chars = "a-zA-Z0-9_";
14795
14796   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14797     {
14798       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
14799                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
14800         vec_add1 (name, 0);
14801       else
14802         {
14803           errmsg ("parse error '%U'", format_unformat_error, i);
14804           return -99;
14805         }
14806     }
14807
14808   if (!vec_len (name))
14809     {
14810       errmsg ("profile name must be specified");
14811       return -99;
14812     }
14813
14814   if (vec_len (name) > 64)
14815     {
14816       errmsg ("profile name too long");
14817       return -99;
14818     }
14819
14820   M (IKEV2_SET_ESP_TRANSFORMS, mp);
14821
14822   clib_memcpy (mp->name, name, vec_len (name));
14823   vec_free (name);
14824   mp->crypto_alg = crypto_alg;
14825   mp->crypto_key_size = crypto_key_size;
14826   mp->integ_alg = integ_alg;
14827   mp->dh_group = dh_group;
14828
14829   S (mp);
14830   W (ret);
14831   return ret;
14832 }
14833
14834 static int
14835 api_ikev2_set_sa_lifetime (vat_main_t * vam)
14836 {
14837   unformat_input_t *i = vam->input;
14838   vl_api_ikev2_set_sa_lifetime_t *mp;
14839   int ret;
14840   u8 *name = 0;
14841   u64 lifetime, lifetime_maxdata;
14842   u32 lifetime_jitter, handover;
14843
14844   const char *valid_chars = "a-zA-Z0-9_";
14845
14846   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14847     {
14848       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
14849                     &lifetime, &lifetime_jitter, &handover,
14850                     &lifetime_maxdata))
14851         vec_add1 (name, 0);
14852       else
14853         {
14854           errmsg ("parse error '%U'", format_unformat_error, i);
14855           return -99;
14856         }
14857     }
14858
14859   if (!vec_len (name))
14860     {
14861       errmsg ("profile name must be specified");
14862       return -99;
14863     }
14864
14865   if (vec_len (name) > 64)
14866     {
14867       errmsg ("profile name too long");
14868       return -99;
14869     }
14870
14871   M (IKEV2_SET_SA_LIFETIME, mp);
14872
14873   clib_memcpy (mp->name, name, vec_len (name));
14874   vec_free (name);
14875   mp->lifetime = lifetime;
14876   mp->lifetime_jitter = lifetime_jitter;
14877   mp->handover = handover;
14878   mp->lifetime_maxdata = lifetime_maxdata;
14879
14880   S (mp);
14881   W (ret);
14882   return ret;
14883 }
14884
14885 static int
14886 api_ikev2_initiate_sa_init (vat_main_t * vam)
14887 {
14888   unformat_input_t *i = vam->input;
14889   vl_api_ikev2_initiate_sa_init_t *mp;
14890   int ret;
14891   u8 *name = 0;
14892
14893   const char *valid_chars = "a-zA-Z0-9_";
14894
14895   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14896     {
14897       if (unformat (i, "%U", unformat_token, valid_chars, &name))
14898         vec_add1 (name, 0);
14899       else
14900         {
14901           errmsg ("parse error '%U'", format_unformat_error, i);
14902           return -99;
14903         }
14904     }
14905
14906   if (!vec_len (name))
14907     {
14908       errmsg ("profile name must be specified");
14909       return -99;
14910     }
14911
14912   if (vec_len (name) > 64)
14913     {
14914       errmsg ("profile name too long");
14915       return -99;
14916     }
14917
14918   M (IKEV2_INITIATE_SA_INIT, mp);
14919
14920   clib_memcpy (mp->name, name, vec_len (name));
14921   vec_free (name);
14922
14923   S (mp);
14924   W (ret);
14925   return ret;
14926 }
14927
14928 static int
14929 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
14930 {
14931   unformat_input_t *i = vam->input;
14932   vl_api_ikev2_initiate_del_ike_sa_t *mp;
14933   int ret;
14934   u64 ispi;
14935
14936
14937   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14938     {
14939       if (unformat (i, "%lx", &ispi))
14940         ;
14941       else
14942         {
14943           errmsg ("parse error '%U'", format_unformat_error, i);
14944           return -99;
14945         }
14946     }
14947
14948   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
14949
14950   mp->ispi = ispi;
14951
14952   S (mp);
14953   W (ret);
14954   return ret;
14955 }
14956
14957 static int
14958 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
14959 {
14960   unformat_input_t *i = vam->input;
14961   vl_api_ikev2_initiate_del_child_sa_t *mp;
14962   int ret;
14963   u32 ispi;
14964
14965
14966   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14967     {
14968       if (unformat (i, "%x", &ispi))
14969         ;
14970       else
14971         {
14972           errmsg ("parse error '%U'", format_unformat_error, i);
14973           return -99;
14974         }
14975     }
14976
14977   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
14978
14979   mp->ispi = ispi;
14980
14981   S (mp);
14982   W (ret);
14983   return ret;
14984 }
14985
14986 static int
14987 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
14988 {
14989   unformat_input_t *i = vam->input;
14990   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
14991   int ret;
14992   u32 ispi;
14993
14994
14995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14996     {
14997       if (unformat (i, "%x", &ispi))
14998         ;
14999       else
15000         {
15001           errmsg ("parse error '%U'", format_unformat_error, i);
15002           return -99;
15003         }
15004     }
15005
15006   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
15007
15008   mp->ispi = ispi;
15009
15010   S (mp);
15011   W (ret);
15012   return ret;
15013 }
15014
15015 /*
15016  * MAP
15017  */
15018 static int
15019 api_map_add_domain (vat_main_t * vam)
15020 {
15021   unformat_input_t *i = vam->input;
15022   vl_api_map_add_domain_t *mp;
15023
15024   ip4_address_t ip4_prefix;
15025   ip6_address_t ip6_prefix;
15026   ip6_address_t ip6_src;
15027   u32 num_m_args = 0;
15028   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
15029     0, psid_length = 0;
15030   u8 is_translation = 0;
15031   u32 mtu = 0;
15032   u32 ip6_src_len = 128;
15033   int ret;
15034
15035   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15036     {
15037       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
15038                     &ip4_prefix, &ip4_prefix_len))
15039         num_m_args++;
15040       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
15041                          &ip6_prefix, &ip6_prefix_len))
15042         num_m_args++;
15043       else
15044         if (unformat
15045             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
15046              &ip6_src_len))
15047         num_m_args++;
15048       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
15049         num_m_args++;
15050       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
15051         num_m_args++;
15052       else if (unformat (i, "psid-offset %d", &psid_offset))
15053         num_m_args++;
15054       else if (unformat (i, "psid-len %d", &psid_length))
15055         num_m_args++;
15056       else if (unformat (i, "mtu %d", &mtu))
15057         num_m_args++;
15058       else if (unformat (i, "map-t"))
15059         is_translation = 1;
15060       else
15061         {
15062           clib_warning ("parse error '%U'", format_unformat_error, i);
15063           return -99;
15064         }
15065     }
15066
15067   if (num_m_args < 3)
15068     {
15069       errmsg ("mandatory argument(s) missing");
15070       return -99;
15071     }
15072
15073   /* Construct the API message */
15074   M (MAP_ADD_DOMAIN, mp);
15075
15076   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
15077   mp->ip4_prefix_len = ip4_prefix_len;
15078
15079   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
15080   mp->ip6_prefix_len = ip6_prefix_len;
15081
15082   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
15083   mp->ip6_src_prefix_len = ip6_src_len;
15084
15085   mp->ea_bits_len = ea_bits_len;
15086   mp->psid_offset = psid_offset;
15087   mp->psid_length = psid_length;
15088   mp->is_translation = is_translation;
15089   mp->mtu = htons (mtu);
15090
15091   /* send it... */
15092   S (mp);
15093
15094   /* Wait for a reply, return good/bad news  */
15095   W (ret);
15096   return ret;
15097 }
15098
15099 static int
15100 api_map_del_domain (vat_main_t * vam)
15101 {
15102   unformat_input_t *i = vam->input;
15103   vl_api_map_del_domain_t *mp;
15104
15105   u32 num_m_args = 0;
15106   u32 index;
15107   int ret;
15108
15109   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15110     {
15111       if (unformat (i, "index %d", &index))
15112         num_m_args++;
15113       else
15114         {
15115           clib_warning ("parse error '%U'", format_unformat_error, i);
15116           return -99;
15117         }
15118     }
15119
15120   if (num_m_args != 1)
15121     {
15122       errmsg ("mandatory argument(s) missing");
15123       return -99;
15124     }
15125
15126   /* Construct the API message */
15127   M (MAP_DEL_DOMAIN, mp);
15128
15129   mp->index = ntohl (index);
15130
15131   /* send it... */
15132   S (mp);
15133
15134   /* Wait for a reply, return good/bad news  */
15135   W (ret);
15136   return ret;
15137 }
15138
15139 static int
15140 api_map_add_del_rule (vat_main_t * vam)
15141 {
15142   unformat_input_t *i = vam->input;
15143   vl_api_map_add_del_rule_t *mp;
15144   u8 is_add = 1;
15145   ip6_address_t ip6_dst;
15146   u32 num_m_args = 0, index, psid = 0;
15147   int ret;
15148
15149   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15150     {
15151       if (unformat (i, "index %d", &index))
15152         num_m_args++;
15153       else if (unformat (i, "psid %d", &psid))
15154         num_m_args++;
15155       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
15156         num_m_args++;
15157       else if (unformat (i, "del"))
15158         {
15159           is_add = 0;
15160         }
15161       else
15162         {
15163           clib_warning ("parse error '%U'", format_unformat_error, i);
15164           return -99;
15165         }
15166     }
15167
15168   /* Construct the API message */
15169   M (MAP_ADD_DEL_RULE, mp);
15170
15171   mp->index = ntohl (index);
15172   mp->is_add = is_add;
15173   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
15174   mp->psid = ntohs (psid);
15175
15176   /* send it... */
15177   S (mp);
15178
15179   /* Wait for a reply, return good/bad news  */
15180   W (ret);
15181   return ret;
15182 }
15183
15184 static int
15185 api_map_domain_dump (vat_main_t * vam)
15186 {
15187   vl_api_map_domain_dump_t *mp;
15188   vl_api_control_ping_t *mp_ping;
15189   int ret;
15190
15191   /* Construct the API message */
15192   M (MAP_DOMAIN_DUMP, mp);
15193
15194   /* send it... */
15195   S (mp);
15196
15197   /* Use a control ping for synchronization */
15198   MPING (CONTROL_PING, mp_ping);
15199   S (mp_ping);
15200
15201   W (ret);
15202   return ret;
15203 }
15204
15205 static int
15206 api_map_rule_dump (vat_main_t * vam)
15207 {
15208   unformat_input_t *i = vam->input;
15209   vl_api_map_rule_dump_t *mp;
15210   vl_api_control_ping_t *mp_ping;
15211   u32 domain_index = ~0;
15212   int ret;
15213
15214   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15215     {
15216       if (unformat (i, "index %u", &domain_index))
15217         ;
15218       else
15219         break;
15220     }
15221
15222   if (domain_index == ~0)
15223     {
15224       clib_warning ("parse error: domain index expected");
15225       return -99;
15226     }
15227
15228   /* Construct the API message */
15229   M (MAP_RULE_DUMP, mp);
15230
15231   mp->domain_index = htonl (domain_index);
15232
15233   /* send it... */
15234   S (mp);
15235
15236   /* Use a control ping for synchronization */
15237   MPING (CONTROL_PING, mp_ping);
15238   S (mp_ping);
15239
15240   W (ret);
15241   return ret;
15242 }
15243
15244 static void vl_api_map_add_domain_reply_t_handler
15245   (vl_api_map_add_domain_reply_t * mp)
15246 {
15247   vat_main_t *vam = &vat_main;
15248   i32 retval = ntohl (mp->retval);
15249
15250   if (vam->async_mode)
15251     {
15252       vam->async_errors += (retval < 0);
15253     }
15254   else
15255     {
15256       vam->retval = retval;
15257       vam->result_ready = 1;
15258     }
15259 }
15260
15261 static void vl_api_map_add_domain_reply_t_handler_json
15262   (vl_api_map_add_domain_reply_t * mp)
15263 {
15264   vat_main_t *vam = &vat_main;
15265   vat_json_node_t node;
15266
15267   vat_json_init_object (&node);
15268   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
15269   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
15270
15271   vat_json_print (vam->ofp, &node);
15272   vat_json_free (&node);
15273
15274   vam->retval = ntohl (mp->retval);
15275   vam->result_ready = 1;
15276 }
15277
15278 static int
15279 api_get_first_msg_id (vat_main_t * vam)
15280 {
15281   vl_api_get_first_msg_id_t *mp;
15282   unformat_input_t *i = vam->input;
15283   u8 *name;
15284   u8 name_set = 0;
15285   int ret;
15286
15287   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15288     {
15289       if (unformat (i, "client %s", &name))
15290         name_set = 1;
15291       else
15292         break;
15293     }
15294
15295   if (name_set == 0)
15296     {
15297       errmsg ("missing client name");
15298       return -99;
15299     }
15300   vec_add1 (name, 0);
15301
15302   if (vec_len (name) > 63)
15303     {
15304       errmsg ("client name too long");
15305       return -99;
15306     }
15307
15308   M (GET_FIRST_MSG_ID, mp);
15309   clib_memcpy (mp->name, name, vec_len (name));
15310   S (mp);
15311   W (ret);
15312   return ret;
15313 }
15314
15315 static int
15316 api_cop_interface_enable_disable (vat_main_t * vam)
15317 {
15318   unformat_input_t *line_input = vam->input;
15319   vl_api_cop_interface_enable_disable_t *mp;
15320   u32 sw_if_index = ~0;
15321   u8 enable_disable = 1;
15322   int ret;
15323
15324   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15325     {
15326       if (unformat (line_input, "disable"))
15327         enable_disable = 0;
15328       if (unformat (line_input, "enable"))
15329         enable_disable = 1;
15330       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15331                          vam, &sw_if_index))
15332         ;
15333       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15334         ;
15335       else
15336         break;
15337     }
15338
15339   if (sw_if_index == ~0)
15340     {
15341       errmsg ("missing interface name or sw_if_index");
15342       return -99;
15343     }
15344
15345   /* Construct the API message */
15346   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15347   mp->sw_if_index = ntohl (sw_if_index);
15348   mp->enable_disable = enable_disable;
15349
15350   /* send it... */
15351   S (mp);
15352   /* Wait for the reply */
15353   W (ret);
15354   return ret;
15355 }
15356
15357 static int
15358 api_cop_whitelist_enable_disable (vat_main_t * vam)
15359 {
15360   unformat_input_t *line_input = vam->input;
15361   vl_api_cop_whitelist_enable_disable_t *mp;
15362   u32 sw_if_index = ~0;
15363   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15364   u32 fib_id = 0;
15365   int ret;
15366
15367   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15368     {
15369       if (unformat (line_input, "ip4"))
15370         ip4 = 1;
15371       else if (unformat (line_input, "ip6"))
15372         ip6 = 1;
15373       else if (unformat (line_input, "default"))
15374         default_cop = 1;
15375       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15376                          vam, &sw_if_index))
15377         ;
15378       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15379         ;
15380       else if (unformat (line_input, "fib-id %d", &fib_id))
15381         ;
15382       else
15383         break;
15384     }
15385
15386   if (sw_if_index == ~0)
15387     {
15388       errmsg ("missing interface name or sw_if_index");
15389       return -99;
15390     }
15391
15392   /* Construct the API message */
15393   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15394   mp->sw_if_index = ntohl (sw_if_index);
15395   mp->fib_id = ntohl (fib_id);
15396   mp->ip4 = ip4;
15397   mp->ip6 = ip6;
15398   mp->default_cop = default_cop;
15399
15400   /* send it... */
15401   S (mp);
15402   /* Wait for the reply */
15403   W (ret);
15404   return ret;
15405 }
15406
15407 static int
15408 api_get_node_graph (vat_main_t * vam)
15409 {
15410   vl_api_get_node_graph_t *mp;
15411   int ret;
15412
15413   M (GET_NODE_GRAPH, mp);
15414
15415   /* send it... */
15416   S (mp);
15417   /* Wait for the reply */
15418   W (ret);
15419   return ret;
15420 }
15421
15422 /* *INDENT-OFF* */
15423 /** Used for parsing LISP eids */
15424 typedef CLIB_PACKED(struct{
15425   u8 addr[16];   /**< eid address */
15426   u32 len;       /**< prefix length if IP */
15427   u8 type;      /**< type of eid */
15428 }) lisp_eid_vat_t;
15429 /* *INDENT-ON* */
15430
15431 static uword
15432 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15433 {
15434   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15435
15436   memset (a, 0, sizeof (a[0]));
15437
15438   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15439     {
15440       a->type = 0;              /* ipv4 type */
15441     }
15442   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15443     {
15444       a->type = 1;              /* ipv6 type */
15445     }
15446   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15447     {
15448       a->type = 2;              /* mac type */
15449     }
15450   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15451     {
15452       a->type = 3;              /* NSH type */
15453       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15454       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15455     }
15456   else
15457     {
15458       return 0;
15459     }
15460
15461   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15462     {
15463       return 0;
15464     }
15465
15466   return 1;
15467 }
15468
15469 static int
15470 lisp_eid_size_vat (u8 type)
15471 {
15472   switch (type)
15473     {
15474     case 0:
15475       return 4;
15476     case 1:
15477       return 16;
15478     case 2:
15479       return 6;
15480     case 3:
15481       return 5;
15482     }
15483   return 0;
15484 }
15485
15486 static void
15487 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15488 {
15489   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15490 }
15491
15492 static int
15493 api_one_add_del_locator_set (vat_main_t * vam)
15494 {
15495   unformat_input_t *input = vam->input;
15496   vl_api_one_add_del_locator_set_t *mp;
15497   u8 is_add = 1;
15498   u8 *locator_set_name = NULL;
15499   u8 locator_set_name_set = 0;
15500   vl_api_local_locator_t locator, *locators = 0;
15501   u32 sw_if_index, priority, weight;
15502   u32 data_len = 0;
15503
15504   int ret;
15505   /* Parse args required to build the message */
15506   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15507     {
15508       if (unformat (input, "del"))
15509         {
15510           is_add = 0;
15511         }
15512       else if (unformat (input, "locator-set %s", &locator_set_name))
15513         {
15514           locator_set_name_set = 1;
15515         }
15516       else if (unformat (input, "sw_if_index %u p %u w %u",
15517                          &sw_if_index, &priority, &weight))
15518         {
15519           locator.sw_if_index = htonl (sw_if_index);
15520           locator.priority = priority;
15521           locator.weight = weight;
15522           vec_add1 (locators, locator);
15523         }
15524       else
15525         if (unformat
15526             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15527              &sw_if_index, &priority, &weight))
15528         {
15529           locator.sw_if_index = htonl (sw_if_index);
15530           locator.priority = priority;
15531           locator.weight = weight;
15532           vec_add1 (locators, locator);
15533         }
15534       else
15535         break;
15536     }
15537
15538   if (locator_set_name_set == 0)
15539     {
15540       errmsg ("missing locator-set name");
15541       vec_free (locators);
15542       return -99;
15543     }
15544
15545   if (vec_len (locator_set_name) > 64)
15546     {
15547       errmsg ("locator-set name too long");
15548       vec_free (locator_set_name);
15549       vec_free (locators);
15550       return -99;
15551     }
15552   vec_add1 (locator_set_name, 0);
15553
15554   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15555
15556   /* Construct the API message */
15557   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15558
15559   mp->is_add = is_add;
15560   clib_memcpy (mp->locator_set_name, locator_set_name,
15561                vec_len (locator_set_name));
15562   vec_free (locator_set_name);
15563
15564   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15565   if (locators)
15566     clib_memcpy (mp->locators, locators, data_len);
15567   vec_free (locators);
15568
15569   /* send it... */
15570   S (mp);
15571
15572   /* Wait for a reply... */
15573   W (ret);
15574   return ret;
15575 }
15576
15577 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15578
15579 static int
15580 api_one_add_del_locator (vat_main_t * vam)
15581 {
15582   unformat_input_t *input = vam->input;
15583   vl_api_one_add_del_locator_t *mp;
15584   u32 tmp_if_index = ~0;
15585   u32 sw_if_index = ~0;
15586   u8 sw_if_index_set = 0;
15587   u8 sw_if_index_if_name_set = 0;
15588   u32 priority = ~0;
15589   u8 priority_set = 0;
15590   u32 weight = ~0;
15591   u8 weight_set = 0;
15592   u8 is_add = 1;
15593   u8 *locator_set_name = NULL;
15594   u8 locator_set_name_set = 0;
15595   int ret;
15596
15597   /* Parse args required to build the message */
15598   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15599     {
15600       if (unformat (input, "del"))
15601         {
15602           is_add = 0;
15603         }
15604       else if (unformat (input, "locator-set %s", &locator_set_name))
15605         {
15606           locator_set_name_set = 1;
15607         }
15608       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15609                          &tmp_if_index))
15610         {
15611           sw_if_index_if_name_set = 1;
15612           sw_if_index = tmp_if_index;
15613         }
15614       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15615         {
15616           sw_if_index_set = 1;
15617           sw_if_index = tmp_if_index;
15618         }
15619       else if (unformat (input, "p %d", &priority))
15620         {
15621           priority_set = 1;
15622         }
15623       else if (unformat (input, "w %d", &weight))
15624         {
15625           weight_set = 1;
15626         }
15627       else
15628         break;
15629     }
15630
15631   if (locator_set_name_set == 0)
15632     {
15633       errmsg ("missing locator-set name");
15634       return -99;
15635     }
15636
15637   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15638     {
15639       errmsg ("missing sw_if_index");
15640       vec_free (locator_set_name);
15641       return -99;
15642     }
15643
15644   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15645     {
15646       errmsg ("cannot use both params interface name and sw_if_index");
15647       vec_free (locator_set_name);
15648       return -99;
15649     }
15650
15651   if (priority_set == 0)
15652     {
15653       errmsg ("missing locator-set priority");
15654       vec_free (locator_set_name);
15655       return -99;
15656     }
15657
15658   if (weight_set == 0)
15659     {
15660       errmsg ("missing locator-set weight");
15661       vec_free (locator_set_name);
15662       return -99;
15663     }
15664
15665   if (vec_len (locator_set_name) > 64)
15666     {
15667       errmsg ("locator-set name too long");
15668       vec_free (locator_set_name);
15669       return -99;
15670     }
15671   vec_add1 (locator_set_name, 0);
15672
15673   /* Construct the API message */
15674   M (ONE_ADD_DEL_LOCATOR, mp);
15675
15676   mp->is_add = is_add;
15677   mp->sw_if_index = ntohl (sw_if_index);
15678   mp->priority = priority;
15679   mp->weight = weight;
15680   clib_memcpy (mp->locator_set_name, locator_set_name,
15681                vec_len (locator_set_name));
15682   vec_free (locator_set_name);
15683
15684   /* send it... */
15685   S (mp);
15686
15687   /* Wait for a reply... */
15688   W (ret);
15689   return ret;
15690 }
15691
15692 #define api_lisp_add_del_locator api_one_add_del_locator
15693
15694 uword
15695 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15696 {
15697   u32 *key_id = va_arg (*args, u32 *);
15698   u8 *s = 0;
15699
15700   if (unformat (input, "%s", &s))
15701     {
15702       if (!strcmp ((char *) s, "sha1"))
15703         key_id[0] = HMAC_SHA_1_96;
15704       else if (!strcmp ((char *) s, "sha256"))
15705         key_id[0] = HMAC_SHA_256_128;
15706       else
15707         {
15708           clib_warning ("invalid key_id: '%s'", s);
15709           key_id[0] = HMAC_NO_KEY;
15710         }
15711     }
15712   else
15713     return 0;
15714
15715   vec_free (s);
15716   return 1;
15717 }
15718
15719 static int
15720 api_one_add_del_local_eid (vat_main_t * vam)
15721 {
15722   unformat_input_t *input = vam->input;
15723   vl_api_one_add_del_local_eid_t *mp;
15724   u8 is_add = 1;
15725   u8 eid_set = 0;
15726   lisp_eid_vat_t _eid, *eid = &_eid;
15727   u8 *locator_set_name = 0;
15728   u8 locator_set_name_set = 0;
15729   u32 vni = 0;
15730   u16 key_id = 0;
15731   u8 *key = 0;
15732   int ret;
15733
15734   /* Parse args required to build the message */
15735   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15736     {
15737       if (unformat (input, "del"))
15738         {
15739           is_add = 0;
15740         }
15741       else if (unformat (input, "vni %d", &vni))
15742         {
15743           ;
15744         }
15745       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15746         {
15747           eid_set = 1;
15748         }
15749       else if (unformat (input, "locator-set %s", &locator_set_name))
15750         {
15751           locator_set_name_set = 1;
15752         }
15753       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15754         ;
15755       else if (unformat (input, "secret-key %_%v%_", &key))
15756         ;
15757       else
15758         break;
15759     }
15760
15761   if (locator_set_name_set == 0)
15762     {
15763       errmsg ("missing locator-set name");
15764       return -99;
15765     }
15766
15767   if (0 == eid_set)
15768     {
15769       errmsg ("EID address not set!");
15770       vec_free (locator_set_name);
15771       return -99;
15772     }
15773
15774   if (key && (0 == key_id))
15775     {
15776       errmsg ("invalid key_id!");
15777       return -99;
15778     }
15779
15780   if (vec_len (key) > 64)
15781     {
15782       errmsg ("key too long");
15783       vec_free (key);
15784       return -99;
15785     }
15786
15787   if (vec_len (locator_set_name) > 64)
15788     {
15789       errmsg ("locator-set name too long");
15790       vec_free (locator_set_name);
15791       return -99;
15792     }
15793   vec_add1 (locator_set_name, 0);
15794
15795   /* Construct the API message */
15796   M (ONE_ADD_DEL_LOCAL_EID, mp);
15797
15798   mp->is_add = is_add;
15799   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15800   mp->eid_type = eid->type;
15801   mp->prefix_len = eid->len;
15802   mp->vni = clib_host_to_net_u32 (vni);
15803   mp->key_id = clib_host_to_net_u16 (key_id);
15804   clib_memcpy (mp->locator_set_name, locator_set_name,
15805                vec_len (locator_set_name));
15806   clib_memcpy (mp->key, key, vec_len (key));
15807
15808   vec_free (locator_set_name);
15809   vec_free (key);
15810
15811   /* send it... */
15812   S (mp);
15813
15814   /* Wait for a reply... */
15815   W (ret);
15816   return ret;
15817 }
15818
15819 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15820
15821 static int
15822 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15823 {
15824   u32 dp_table = 0, vni = 0;;
15825   unformat_input_t *input = vam->input;
15826   vl_api_gpe_add_del_fwd_entry_t *mp;
15827   u8 is_add = 1;
15828   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15829   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15830   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15831   u32 action = ~0, w;
15832   ip4_address_t rmt_rloc4, lcl_rloc4;
15833   ip6_address_t rmt_rloc6, lcl_rloc6;
15834   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15835   int ret;
15836
15837   memset (&rloc, 0, sizeof (rloc));
15838
15839   /* Parse args required to build the message */
15840   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15841     {
15842       if (unformat (input, "del"))
15843         is_add = 0;
15844       else if (unformat (input, "add"))
15845         is_add = 1;
15846       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15847         {
15848           rmt_eid_set = 1;
15849         }
15850       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15851         {
15852           lcl_eid_set = 1;
15853         }
15854       else if (unformat (input, "vrf %d", &dp_table))
15855         ;
15856       else if (unformat (input, "bd %d", &dp_table))
15857         ;
15858       else if (unformat (input, "vni %d", &vni))
15859         ;
15860       else if (unformat (input, "w %d", &w))
15861         {
15862           if (!curr_rloc)
15863             {
15864               errmsg ("No RLOC configured for setting priority/weight!");
15865               return -99;
15866             }
15867           curr_rloc->weight = w;
15868         }
15869       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15870                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15871         {
15872           rloc.is_ip4 = 1;
15873
15874           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15875           rloc.weight = 0;
15876           vec_add1 (lcl_locs, rloc);
15877
15878           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15879           vec_add1 (rmt_locs, rloc);
15880           /* weight saved in rmt loc */
15881           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15882         }
15883       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15884                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15885         {
15886           rloc.is_ip4 = 0;
15887           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15888           rloc.weight = 0;
15889           vec_add1 (lcl_locs, rloc);
15890
15891           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15892           vec_add1 (rmt_locs, rloc);
15893           /* weight saved in rmt loc */
15894           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15895         }
15896       else if (unformat (input, "action %d", &action))
15897         {
15898           ;
15899         }
15900       else
15901         {
15902           clib_warning ("parse error '%U'", format_unformat_error, input);
15903           return -99;
15904         }
15905     }
15906
15907   if (!rmt_eid_set)
15908     {
15909       errmsg ("remote eid addresses not set");
15910       return -99;
15911     }
15912
15913   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15914     {
15915       errmsg ("eid types don't match");
15916       return -99;
15917     }
15918
15919   if (0 == rmt_locs && (u32) ~ 0 == action)
15920     {
15921       errmsg ("action not set for negative mapping");
15922       return -99;
15923     }
15924
15925   /* Construct the API message */
15926   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15927       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15928
15929   mp->is_add = is_add;
15930   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15931   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15932   mp->eid_type = rmt_eid->type;
15933   mp->dp_table = clib_host_to_net_u32 (dp_table);
15934   mp->vni = clib_host_to_net_u32 (vni);
15935   mp->rmt_len = rmt_eid->len;
15936   mp->lcl_len = lcl_eid->len;
15937   mp->action = action;
15938
15939   if (0 != rmt_locs && 0 != lcl_locs)
15940     {
15941       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15942       clib_memcpy (mp->locs, lcl_locs,
15943                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15944
15945       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15946       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15947                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15948     }
15949   vec_free (lcl_locs);
15950   vec_free (rmt_locs);
15951
15952   /* send it... */
15953   S (mp);
15954
15955   /* Wait for a reply... */
15956   W (ret);
15957   return ret;
15958 }
15959
15960 static int
15961 api_one_add_del_map_server (vat_main_t * vam)
15962 {
15963   unformat_input_t *input = vam->input;
15964   vl_api_one_add_del_map_server_t *mp;
15965   u8 is_add = 1;
15966   u8 ipv4_set = 0;
15967   u8 ipv6_set = 0;
15968   ip4_address_t ipv4;
15969   ip6_address_t ipv6;
15970   int ret;
15971
15972   /* Parse args required to build the message */
15973   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15974     {
15975       if (unformat (input, "del"))
15976         {
15977           is_add = 0;
15978         }
15979       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15980         {
15981           ipv4_set = 1;
15982         }
15983       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15984         {
15985           ipv6_set = 1;
15986         }
15987       else
15988         break;
15989     }
15990
15991   if (ipv4_set && ipv6_set)
15992     {
15993       errmsg ("both eid v4 and v6 addresses set");
15994       return -99;
15995     }
15996
15997   if (!ipv4_set && !ipv6_set)
15998     {
15999       errmsg ("eid addresses not set");
16000       return -99;
16001     }
16002
16003   /* Construct the API message */
16004   M (ONE_ADD_DEL_MAP_SERVER, mp);
16005
16006   mp->is_add = is_add;
16007   if (ipv6_set)
16008     {
16009       mp->is_ipv6 = 1;
16010       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16011     }
16012   else
16013     {
16014       mp->is_ipv6 = 0;
16015       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16016     }
16017
16018   /* send it... */
16019   S (mp);
16020
16021   /* Wait for a reply... */
16022   W (ret);
16023   return ret;
16024 }
16025
16026 #define api_lisp_add_del_map_server api_one_add_del_map_server
16027
16028 static int
16029 api_one_add_del_map_resolver (vat_main_t * vam)
16030 {
16031   unformat_input_t *input = vam->input;
16032   vl_api_one_add_del_map_resolver_t *mp;
16033   u8 is_add = 1;
16034   u8 ipv4_set = 0;
16035   u8 ipv6_set = 0;
16036   ip4_address_t ipv4;
16037   ip6_address_t ipv6;
16038   int ret;
16039
16040   /* Parse args required to build the message */
16041   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16042     {
16043       if (unformat (input, "del"))
16044         {
16045           is_add = 0;
16046         }
16047       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16048         {
16049           ipv4_set = 1;
16050         }
16051       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16052         {
16053           ipv6_set = 1;
16054         }
16055       else
16056         break;
16057     }
16058
16059   if (ipv4_set && ipv6_set)
16060     {
16061       errmsg ("both eid v4 and v6 addresses set");
16062       return -99;
16063     }
16064
16065   if (!ipv4_set && !ipv6_set)
16066     {
16067       errmsg ("eid addresses not set");
16068       return -99;
16069     }
16070
16071   /* Construct the API message */
16072   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16073
16074   mp->is_add = is_add;
16075   if (ipv6_set)
16076     {
16077       mp->is_ipv6 = 1;
16078       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16079     }
16080   else
16081     {
16082       mp->is_ipv6 = 0;
16083       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16084     }
16085
16086   /* send it... */
16087   S (mp);
16088
16089   /* Wait for a reply... */
16090   W (ret);
16091   return ret;
16092 }
16093
16094 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16095
16096 static int
16097 api_lisp_gpe_enable_disable (vat_main_t * vam)
16098 {
16099   unformat_input_t *input = vam->input;
16100   vl_api_gpe_enable_disable_t *mp;
16101   u8 is_set = 0;
16102   u8 is_en = 1;
16103   int ret;
16104
16105   /* Parse args required to build the message */
16106   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16107     {
16108       if (unformat (input, "enable"))
16109         {
16110           is_set = 1;
16111           is_en = 1;
16112         }
16113       else if (unformat (input, "disable"))
16114         {
16115           is_set = 1;
16116           is_en = 0;
16117         }
16118       else
16119         break;
16120     }
16121
16122   if (is_set == 0)
16123     {
16124       errmsg ("Value not set");
16125       return -99;
16126     }
16127
16128   /* Construct the API message */
16129   M (GPE_ENABLE_DISABLE, mp);
16130
16131   mp->is_en = is_en;
16132
16133   /* send it... */
16134   S (mp);
16135
16136   /* Wait for a reply... */
16137   W (ret);
16138   return ret;
16139 }
16140
16141 static int
16142 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16143 {
16144   unformat_input_t *input = vam->input;
16145   vl_api_one_rloc_probe_enable_disable_t *mp;
16146   u8 is_set = 0;
16147   u8 is_en = 0;
16148   int ret;
16149
16150   /* Parse args required to build the message */
16151   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16152     {
16153       if (unformat (input, "enable"))
16154         {
16155           is_set = 1;
16156           is_en = 1;
16157         }
16158       else if (unformat (input, "disable"))
16159         is_set = 1;
16160       else
16161         break;
16162     }
16163
16164   if (!is_set)
16165     {
16166       errmsg ("Value not set");
16167       return -99;
16168     }
16169
16170   /* Construct the API message */
16171   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16172
16173   mp->is_enabled = is_en;
16174
16175   /* send it... */
16176   S (mp);
16177
16178   /* Wait for a reply... */
16179   W (ret);
16180   return ret;
16181 }
16182
16183 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16184
16185 static int
16186 api_one_map_register_enable_disable (vat_main_t * vam)
16187 {
16188   unformat_input_t *input = vam->input;
16189   vl_api_one_map_register_enable_disable_t *mp;
16190   u8 is_set = 0;
16191   u8 is_en = 0;
16192   int ret;
16193
16194   /* Parse args required to build the message */
16195   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16196     {
16197       if (unformat (input, "enable"))
16198         {
16199           is_set = 1;
16200           is_en = 1;
16201         }
16202       else if (unformat (input, "disable"))
16203         is_set = 1;
16204       else
16205         break;
16206     }
16207
16208   if (!is_set)
16209     {
16210       errmsg ("Value not set");
16211       return -99;
16212     }
16213
16214   /* Construct the API message */
16215   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16216
16217   mp->is_enabled = is_en;
16218
16219   /* send it... */
16220   S (mp);
16221
16222   /* Wait for a reply... */
16223   W (ret);
16224   return ret;
16225 }
16226
16227 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16228
16229 static int
16230 api_one_enable_disable (vat_main_t * vam)
16231 {
16232   unformat_input_t *input = vam->input;
16233   vl_api_one_enable_disable_t *mp;
16234   u8 is_set = 0;
16235   u8 is_en = 0;
16236   int ret;
16237
16238   /* Parse args required to build the message */
16239   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16240     {
16241       if (unformat (input, "enable"))
16242         {
16243           is_set = 1;
16244           is_en = 1;
16245         }
16246       else if (unformat (input, "disable"))
16247         {
16248           is_set = 1;
16249         }
16250       else
16251         break;
16252     }
16253
16254   if (!is_set)
16255     {
16256       errmsg ("Value not set");
16257       return -99;
16258     }
16259
16260   /* Construct the API message */
16261   M (ONE_ENABLE_DISABLE, mp);
16262
16263   mp->is_en = is_en;
16264
16265   /* send it... */
16266   S (mp);
16267
16268   /* Wait for a reply... */
16269   W (ret);
16270   return ret;
16271 }
16272
16273 #define api_lisp_enable_disable api_one_enable_disable
16274
16275 static int
16276 api_show_one_map_register_state (vat_main_t * vam)
16277 {
16278   vl_api_show_one_map_register_state_t *mp;
16279   int ret;
16280
16281   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16282
16283   /* send */
16284   S (mp);
16285
16286   /* wait for reply */
16287   W (ret);
16288   return ret;
16289 }
16290
16291 #define api_show_lisp_map_register_state api_show_one_map_register_state
16292
16293 static int
16294 api_show_one_rloc_probe_state (vat_main_t * vam)
16295 {
16296   vl_api_show_one_rloc_probe_state_t *mp;
16297   int ret;
16298
16299   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16300
16301   /* send */
16302   S (mp);
16303
16304   /* wait for reply */
16305   W (ret);
16306   return ret;
16307 }
16308
16309 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16310
16311 static int
16312 api_one_add_del_ndp_entry (vat_main_t * vam)
16313 {
16314   vl_api_one_add_del_ndp_entry_t *mp;
16315   unformat_input_t *input = vam->input;
16316   u8 is_add = 1;
16317   u8 mac_set = 0;
16318   u8 bd_set = 0;
16319   u8 ip_set = 0;
16320   u8 mac[6] = { 0, };
16321   u8 ip6[16] = { 0, };
16322   u32 bd = ~0;
16323   int ret;
16324
16325   /* Parse args required to build the message */
16326   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16327     {
16328       if (unformat (input, "del"))
16329         is_add = 0;
16330       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16331         mac_set = 1;
16332       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16333         ip_set = 1;
16334       else if (unformat (input, "bd %d", &bd))
16335         bd_set = 1;
16336       else
16337         {
16338           errmsg ("parse error '%U'", format_unformat_error, input);
16339           return -99;
16340         }
16341     }
16342
16343   if (!bd_set || !ip_set || (!mac_set && is_add))
16344     {
16345       errmsg ("Missing BD, IP or MAC!");
16346       return -99;
16347     }
16348
16349   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16350   mp->is_add = is_add;
16351   clib_memcpy (mp->mac, mac, 6);
16352   mp->bd = clib_host_to_net_u32 (bd);
16353   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16354
16355   /* send */
16356   S (mp);
16357
16358   /* wait for reply */
16359   W (ret);
16360   return ret;
16361 }
16362
16363 static int
16364 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16365 {
16366   vl_api_one_add_del_l2_arp_entry_t *mp;
16367   unformat_input_t *input = vam->input;
16368   u8 is_add = 1;
16369   u8 mac_set = 0;
16370   u8 bd_set = 0;
16371   u8 ip_set = 0;
16372   u8 mac[6] = { 0, };
16373   u32 ip4 = 0, bd = ~0;
16374   int ret;
16375
16376   /* Parse args required to build the message */
16377   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16378     {
16379       if (unformat (input, "del"))
16380         is_add = 0;
16381       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16382         mac_set = 1;
16383       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16384         ip_set = 1;
16385       else if (unformat (input, "bd %d", &bd))
16386         bd_set = 1;
16387       else
16388         {
16389           errmsg ("parse error '%U'", format_unformat_error, input);
16390           return -99;
16391         }
16392     }
16393
16394   if (!bd_set || !ip_set || (!mac_set && is_add))
16395     {
16396       errmsg ("Missing BD, IP or MAC!");
16397       return -99;
16398     }
16399
16400   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16401   mp->is_add = is_add;
16402   clib_memcpy (mp->mac, mac, 6);
16403   mp->bd = clib_host_to_net_u32 (bd);
16404   mp->ip4 = ip4;
16405
16406   /* send */
16407   S (mp);
16408
16409   /* wait for reply */
16410   W (ret);
16411   return ret;
16412 }
16413
16414 static int
16415 api_one_ndp_bd_get (vat_main_t * vam)
16416 {
16417   vl_api_one_ndp_bd_get_t *mp;
16418   int ret;
16419
16420   M (ONE_NDP_BD_GET, mp);
16421
16422   /* send */
16423   S (mp);
16424
16425   /* wait for reply */
16426   W (ret);
16427   return ret;
16428 }
16429
16430 static int
16431 api_one_ndp_entries_get (vat_main_t * vam)
16432 {
16433   vl_api_one_ndp_entries_get_t *mp;
16434   unformat_input_t *input = vam->input;
16435   u8 bd_set = 0;
16436   u32 bd = ~0;
16437   int ret;
16438
16439   /* Parse args required to build the message */
16440   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16441     {
16442       if (unformat (input, "bd %d", &bd))
16443         bd_set = 1;
16444       else
16445         {
16446           errmsg ("parse error '%U'", format_unformat_error, input);
16447           return -99;
16448         }
16449     }
16450
16451   if (!bd_set)
16452     {
16453       errmsg ("Expected bridge domain!");
16454       return -99;
16455     }
16456
16457   M (ONE_NDP_ENTRIES_GET, mp);
16458   mp->bd = clib_host_to_net_u32 (bd);
16459
16460   /* send */
16461   S (mp);
16462
16463   /* wait for reply */
16464   W (ret);
16465   return ret;
16466 }
16467
16468 static int
16469 api_one_l2_arp_bd_get (vat_main_t * vam)
16470 {
16471   vl_api_one_l2_arp_bd_get_t *mp;
16472   int ret;
16473
16474   M (ONE_L2_ARP_BD_GET, mp);
16475
16476   /* send */
16477   S (mp);
16478
16479   /* wait for reply */
16480   W (ret);
16481   return ret;
16482 }
16483
16484 static int
16485 api_one_l2_arp_entries_get (vat_main_t * vam)
16486 {
16487   vl_api_one_l2_arp_entries_get_t *mp;
16488   unformat_input_t *input = vam->input;
16489   u8 bd_set = 0;
16490   u32 bd = ~0;
16491   int ret;
16492
16493   /* Parse args required to build the message */
16494   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16495     {
16496       if (unformat (input, "bd %d", &bd))
16497         bd_set = 1;
16498       else
16499         {
16500           errmsg ("parse error '%U'", format_unformat_error, input);
16501           return -99;
16502         }
16503     }
16504
16505   if (!bd_set)
16506     {
16507       errmsg ("Expected bridge domain!");
16508       return -99;
16509     }
16510
16511   M (ONE_L2_ARP_ENTRIES_GET, mp);
16512   mp->bd = clib_host_to_net_u32 (bd);
16513
16514   /* send */
16515   S (mp);
16516
16517   /* wait for reply */
16518   W (ret);
16519   return ret;
16520 }
16521
16522 static int
16523 api_one_stats_enable_disable (vat_main_t * vam)
16524 {
16525   vl_api_one_stats_enable_disable_t *mp;
16526   unformat_input_t *input = vam->input;
16527   u8 is_set = 0;
16528   u8 is_en = 0;
16529   int ret;
16530
16531   /* Parse args required to build the message */
16532   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16533     {
16534       if (unformat (input, "enable"))
16535         {
16536           is_set = 1;
16537           is_en = 1;
16538         }
16539       else if (unformat (input, "disable"))
16540         {
16541           is_set = 1;
16542         }
16543       else
16544         break;
16545     }
16546
16547   if (!is_set)
16548     {
16549       errmsg ("Value not set");
16550       return -99;
16551     }
16552
16553   M (ONE_STATS_ENABLE_DISABLE, mp);
16554   mp->is_en = is_en;
16555
16556   /* send */
16557   S (mp);
16558
16559   /* wait for reply */
16560   W (ret);
16561   return ret;
16562 }
16563
16564 static int
16565 api_show_one_stats_enable_disable (vat_main_t * vam)
16566 {
16567   vl_api_show_one_stats_enable_disable_t *mp;
16568   int ret;
16569
16570   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16571
16572   /* send */
16573   S (mp);
16574
16575   /* wait for reply */
16576   W (ret);
16577   return ret;
16578 }
16579
16580 static int
16581 api_show_one_map_request_mode (vat_main_t * vam)
16582 {
16583   vl_api_show_one_map_request_mode_t *mp;
16584   int ret;
16585
16586   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16587
16588   /* send */
16589   S (mp);
16590
16591   /* wait for reply */
16592   W (ret);
16593   return ret;
16594 }
16595
16596 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16597
16598 static int
16599 api_one_map_request_mode (vat_main_t * vam)
16600 {
16601   unformat_input_t *input = vam->input;
16602   vl_api_one_map_request_mode_t *mp;
16603   u8 mode = 0;
16604   int ret;
16605
16606   /* Parse args required to build the message */
16607   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16608     {
16609       if (unformat (input, "dst-only"))
16610         mode = 0;
16611       else if (unformat (input, "src-dst"))
16612         mode = 1;
16613       else
16614         {
16615           errmsg ("parse error '%U'", format_unformat_error, input);
16616           return -99;
16617         }
16618     }
16619
16620   M (ONE_MAP_REQUEST_MODE, mp);
16621
16622   mp->mode = mode;
16623
16624   /* send */
16625   S (mp);
16626
16627   /* wait for reply */
16628   W (ret);
16629   return ret;
16630 }
16631
16632 #define api_lisp_map_request_mode api_one_map_request_mode
16633
16634 /**
16635  * Enable/disable ONE proxy ITR.
16636  *
16637  * @param vam vpp API test context
16638  * @return return code
16639  */
16640 static int
16641 api_one_pitr_set_locator_set (vat_main_t * vam)
16642 {
16643   u8 ls_name_set = 0;
16644   unformat_input_t *input = vam->input;
16645   vl_api_one_pitr_set_locator_set_t *mp;
16646   u8 is_add = 1;
16647   u8 *ls_name = 0;
16648   int ret;
16649
16650   /* Parse args required to build the message */
16651   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16652     {
16653       if (unformat (input, "del"))
16654         is_add = 0;
16655       else if (unformat (input, "locator-set %s", &ls_name))
16656         ls_name_set = 1;
16657       else
16658         {
16659           errmsg ("parse error '%U'", format_unformat_error, input);
16660           return -99;
16661         }
16662     }
16663
16664   if (!ls_name_set)
16665     {
16666       errmsg ("locator-set name not set!");
16667       return -99;
16668     }
16669
16670   M (ONE_PITR_SET_LOCATOR_SET, mp);
16671
16672   mp->is_add = is_add;
16673   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16674   vec_free (ls_name);
16675
16676   /* send */
16677   S (mp);
16678
16679   /* wait for reply */
16680   W (ret);
16681   return ret;
16682 }
16683
16684 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16685
16686 static int
16687 api_one_nsh_set_locator_set (vat_main_t * vam)
16688 {
16689   u8 ls_name_set = 0;
16690   unformat_input_t *input = vam->input;
16691   vl_api_one_nsh_set_locator_set_t *mp;
16692   u8 is_add = 1;
16693   u8 *ls_name = 0;
16694   int ret;
16695
16696   /* Parse args required to build the message */
16697   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16698     {
16699       if (unformat (input, "del"))
16700         is_add = 0;
16701       else if (unformat (input, "ls %s", &ls_name))
16702         ls_name_set = 1;
16703       else
16704         {
16705           errmsg ("parse error '%U'", format_unformat_error, input);
16706           return -99;
16707         }
16708     }
16709
16710   if (!ls_name_set && is_add)
16711     {
16712       errmsg ("locator-set name not set!");
16713       return -99;
16714     }
16715
16716   M (ONE_NSH_SET_LOCATOR_SET, mp);
16717
16718   mp->is_add = is_add;
16719   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16720   vec_free (ls_name);
16721
16722   /* send */
16723   S (mp);
16724
16725   /* wait for reply */
16726   W (ret);
16727   return ret;
16728 }
16729
16730 static int
16731 api_show_one_pitr (vat_main_t * vam)
16732 {
16733   vl_api_show_one_pitr_t *mp;
16734   int ret;
16735
16736   if (!vam->json_output)
16737     {
16738       print (vam->ofp, "%=20s", "lisp status:");
16739     }
16740
16741   M (SHOW_ONE_PITR, mp);
16742   /* send it... */
16743   S (mp);
16744
16745   /* Wait for a reply... */
16746   W (ret);
16747   return ret;
16748 }
16749
16750 #define api_show_lisp_pitr api_show_one_pitr
16751
16752 static int
16753 api_one_use_petr (vat_main_t * vam)
16754 {
16755   unformat_input_t *input = vam->input;
16756   vl_api_one_use_petr_t *mp;
16757   u8 is_add = 0;
16758   ip_address_t ip;
16759   int ret;
16760
16761   memset (&ip, 0, sizeof (ip));
16762
16763   /* Parse args required to build the message */
16764   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16765     {
16766       if (unformat (input, "disable"))
16767         is_add = 0;
16768       else
16769         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16770         {
16771           is_add = 1;
16772           ip_addr_version (&ip) = IP4;
16773         }
16774       else
16775         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16776         {
16777           is_add = 1;
16778           ip_addr_version (&ip) = IP6;
16779         }
16780       else
16781         {
16782           errmsg ("parse error '%U'", format_unformat_error, input);
16783           return -99;
16784         }
16785     }
16786
16787   M (ONE_USE_PETR, mp);
16788
16789   mp->is_add = is_add;
16790   if (is_add)
16791     {
16792       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16793       if (mp->is_ip4)
16794         clib_memcpy (mp->address, &ip, 4);
16795       else
16796         clib_memcpy (mp->address, &ip, 16);
16797     }
16798
16799   /* send */
16800   S (mp);
16801
16802   /* wait for reply */
16803   W (ret);
16804   return ret;
16805 }
16806
16807 #define api_lisp_use_petr api_one_use_petr
16808
16809 static int
16810 api_show_one_nsh_mapping (vat_main_t * vam)
16811 {
16812   vl_api_show_one_use_petr_t *mp;
16813   int ret;
16814
16815   if (!vam->json_output)
16816     {
16817       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16818     }
16819
16820   M (SHOW_ONE_NSH_MAPPING, mp);
16821   /* send it... */
16822   S (mp);
16823
16824   /* Wait for a reply... */
16825   W (ret);
16826   return ret;
16827 }
16828
16829 static int
16830 api_show_one_use_petr (vat_main_t * vam)
16831 {
16832   vl_api_show_one_use_petr_t *mp;
16833   int ret;
16834
16835   if (!vam->json_output)
16836     {
16837       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16838     }
16839
16840   M (SHOW_ONE_USE_PETR, mp);
16841   /* send it... */
16842   S (mp);
16843
16844   /* Wait for a reply... */
16845   W (ret);
16846   return ret;
16847 }
16848
16849 #define api_show_lisp_use_petr api_show_one_use_petr
16850
16851 /**
16852  * Add/delete mapping between vni and vrf
16853  */
16854 static int
16855 api_one_eid_table_add_del_map (vat_main_t * vam)
16856 {
16857   unformat_input_t *input = vam->input;
16858   vl_api_one_eid_table_add_del_map_t *mp;
16859   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16860   u32 vni, vrf, bd_index;
16861   int ret;
16862
16863   /* Parse args required to build the message */
16864   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16865     {
16866       if (unformat (input, "del"))
16867         is_add = 0;
16868       else if (unformat (input, "vrf %d", &vrf))
16869         vrf_set = 1;
16870       else if (unformat (input, "bd_index %d", &bd_index))
16871         bd_index_set = 1;
16872       else if (unformat (input, "vni %d", &vni))
16873         vni_set = 1;
16874       else
16875         break;
16876     }
16877
16878   if (!vni_set || (!vrf_set && !bd_index_set))
16879     {
16880       errmsg ("missing arguments!");
16881       return -99;
16882     }
16883
16884   if (vrf_set && bd_index_set)
16885     {
16886       errmsg ("error: both vrf and bd entered!");
16887       return -99;
16888     }
16889
16890   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16891
16892   mp->is_add = is_add;
16893   mp->vni = htonl (vni);
16894   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16895   mp->is_l2 = bd_index_set;
16896
16897   /* send */
16898   S (mp);
16899
16900   /* wait for reply */
16901   W (ret);
16902   return ret;
16903 }
16904
16905 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16906
16907 uword
16908 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16909 {
16910   u32 *action = va_arg (*args, u32 *);
16911   u8 *s = 0;
16912
16913   if (unformat (input, "%s", &s))
16914     {
16915       if (!strcmp ((char *) s, "no-action"))
16916         action[0] = 0;
16917       else if (!strcmp ((char *) s, "natively-forward"))
16918         action[0] = 1;
16919       else if (!strcmp ((char *) s, "send-map-request"))
16920         action[0] = 2;
16921       else if (!strcmp ((char *) s, "drop"))
16922         action[0] = 3;
16923       else
16924         {
16925           clib_warning ("invalid action: '%s'", s);
16926           action[0] = 3;
16927         }
16928     }
16929   else
16930     return 0;
16931
16932   vec_free (s);
16933   return 1;
16934 }
16935
16936 /**
16937  * Add/del remote mapping to/from ONE control plane
16938  *
16939  * @param vam vpp API test context
16940  * @return return code
16941  */
16942 static int
16943 api_one_add_del_remote_mapping (vat_main_t * vam)
16944 {
16945   unformat_input_t *input = vam->input;
16946   vl_api_one_add_del_remote_mapping_t *mp;
16947   u32 vni = 0;
16948   lisp_eid_vat_t _eid, *eid = &_eid;
16949   lisp_eid_vat_t _seid, *seid = &_seid;
16950   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
16951   u32 action = ~0, p, w, data_len;
16952   ip4_address_t rloc4;
16953   ip6_address_t rloc6;
16954   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
16955   int ret;
16956
16957   memset (&rloc, 0, sizeof (rloc));
16958
16959   /* Parse args required to build the message */
16960   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16961     {
16962       if (unformat (input, "del-all"))
16963         {
16964           del_all = 1;
16965         }
16966       else if (unformat (input, "del"))
16967         {
16968           is_add = 0;
16969         }
16970       else if (unformat (input, "add"))
16971         {
16972           is_add = 1;
16973         }
16974       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16975         {
16976           eid_set = 1;
16977         }
16978       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
16979         {
16980           seid_set = 1;
16981         }
16982       else if (unformat (input, "vni %d", &vni))
16983         {
16984           ;
16985         }
16986       else if (unformat (input, "p %d w %d", &p, &w))
16987         {
16988           if (!curr_rloc)
16989             {
16990               errmsg ("No RLOC configured for setting priority/weight!");
16991               return -99;
16992             }
16993           curr_rloc->priority = p;
16994           curr_rloc->weight = w;
16995         }
16996       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
16997         {
16998           rloc.is_ip4 = 1;
16999           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
17000           vec_add1 (rlocs, rloc);
17001           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17002         }
17003       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
17004         {
17005           rloc.is_ip4 = 0;
17006           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
17007           vec_add1 (rlocs, rloc);
17008           curr_rloc = &rlocs[vec_len (rlocs) - 1];
17009         }
17010       else if (unformat (input, "action %U",
17011                          unformat_negative_mapping_action, &action))
17012         {
17013           ;
17014         }
17015       else
17016         {
17017           clib_warning ("parse error '%U'", format_unformat_error, input);
17018           return -99;
17019         }
17020     }
17021
17022   if (0 == eid_set)
17023     {
17024       errmsg ("missing params!");
17025       return -99;
17026     }
17027
17028   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17029     {
17030       errmsg ("no action set for negative map-reply!");
17031       return -99;
17032     }
17033
17034   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17035
17036   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17037   mp->is_add = is_add;
17038   mp->vni = htonl (vni);
17039   mp->action = (u8) action;
17040   mp->is_src_dst = seid_set;
17041   mp->eid_len = eid->len;
17042   mp->seid_len = seid->len;
17043   mp->del_all = del_all;
17044   mp->eid_type = eid->type;
17045   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17046   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17047
17048   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17049   clib_memcpy (mp->rlocs, rlocs, data_len);
17050   vec_free (rlocs);
17051
17052   /* send it... */
17053   S (mp);
17054
17055   /* Wait for a reply... */
17056   W (ret);
17057   return ret;
17058 }
17059
17060 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17061
17062 /**
17063  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17064  * forwarding entries in data-plane accordingly.
17065  *
17066  * @param vam vpp API test context
17067  * @return return code
17068  */
17069 static int
17070 api_one_add_del_adjacency (vat_main_t * vam)
17071 {
17072   unformat_input_t *input = vam->input;
17073   vl_api_one_add_del_adjacency_t *mp;
17074   u32 vni = 0;
17075   ip4_address_t leid4, reid4;
17076   ip6_address_t leid6, reid6;
17077   u8 reid_mac[6] = { 0 };
17078   u8 leid_mac[6] = { 0 };
17079   u8 reid_type, leid_type;
17080   u32 leid_len = 0, reid_len = 0, len;
17081   u8 is_add = 1;
17082   int ret;
17083
17084   leid_type = reid_type = (u8) ~ 0;
17085
17086   /* Parse args required to build the message */
17087   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17088     {
17089       if (unformat (input, "del"))
17090         {
17091           is_add = 0;
17092         }
17093       else if (unformat (input, "add"))
17094         {
17095           is_add = 1;
17096         }
17097       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17098                          &reid4, &len))
17099         {
17100           reid_type = 0;        /* ipv4 */
17101           reid_len = len;
17102         }
17103       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17104                          &reid6, &len))
17105         {
17106           reid_type = 1;        /* ipv6 */
17107           reid_len = len;
17108         }
17109       else if (unformat (input, "reid %U", unformat_ethernet_address,
17110                          reid_mac))
17111         {
17112           reid_type = 2;        /* mac */
17113         }
17114       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17115                          &leid4, &len))
17116         {
17117           leid_type = 0;        /* ipv4 */
17118           leid_len = len;
17119         }
17120       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17121                          &leid6, &len))
17122         {
17123           leid_type = 1;        /* ipv6 */
17124           leid_len = len;
17125         }
17126       else if (unformat (input, "leid %U", unformat_ethernet_address,
17127                          leid_mac))
17128         {
17129           leid_type = 2;        /* mac */
17130         }
17131       else if (unformat (input, "vni %d", &vni))
17132         {
17133           ;
17134         }
17135       else
17136         {
17137           errmsg ("parse error '%U'", format_unformat_error, input);
17138           return -99;
17139         }
17140     }
17141
17142   if ((u8) ~ 0 == reid_type)
17143     {
17144       errmsg ("missing params!");
17145       return -99;
17146     }
17147
17148   if (leid_type != reid_type)
17149     {
17150       errmsg ("remote and local EIDs are of different types!");
17151       return -99;
17152     }
17153
17154   M (ONE_ADD_DEL_ADJACENCY, mp);
17155   mp->is_add = is_add;
17156   mp->vni = htonl (vni);
17157   mp->leid_len = leid_len;
17158   mp->reid_len = reid_len;
17159   mp->eid_type = reid_type;
17160
17161   switch (mp->eid_type)
17162     {
17163     case 0:
17164       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17165       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17166       break;
17167     case 1:
17168       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17169       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17170       break;
17171     case 2:
17172       clib_memcpy (mp->leid, leid_mac, 6);
17173       clib_memcpy (mp->reid, reid_mac, 6);
17174       break;
17175     default:
17176       errmsg ("unknown EID type %d!", mp->eid_type);
17177       return 0;
17178     }
17179
17180   /* send it... */
17181   S (mp);
17182
17183   /* Wait for a reply... */
17184   W (ret);
17185   return ret;
17186 }
17187
17188 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17189
17190 uword
17191 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17192 {
17193   u32 *mode = va_arg (*args, u32 *);
17194
17195   if (unformat (input, "lisp"))
17196     *mode = 0;
17197   else if (unformat (input, "vxlan"))
17198     *mode = 1;
17199   else
17200     return 0;
17201
17202   return 1;
17203 }
17204
17205 static int
17206 api_gpe_get_encap_mode (vat_main_t * vam)
17207 {
17208   vl_api_gpe_get_encap_mode_t *mp;
17209   int ret;
17210
17211   /* Construct the API message */
17212   M (GPE_GET_ENCAP_MODE, mp);
17213
17214   /* send it... */
17215   S (mp);
17216
17217   /* Wait for a reply... */
17218   W (ret);
17219   return ret;
17220 }
17221
17222 static int
17223 api_gpe_set_encap_mode (vat_main_t * vam)
17224 {
17225   unformat_input_t *input = vam->input;
17226   vl_api_gpe_set_encap_mode_t *mp;
17227   int ret;
17228   u32 mode = 0;
17229
17230   /* Parse args required to build the message */
17231   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17232     {
17233       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17234         ;
17235       else
17236         break;
17237     }
17238
17239   /* Construct the API message */
17240   M (GPE_SET_ENCAP_MODE, mp);
17241
17242   mp->mode = mode;
17243
17244   /* send it... */
17245   S (mp);
17246
17247   /* Wait for a reply... */
17248   W (ret);
17249   return ret;
17250 }
17251
17252 static int
17253 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17254 {
17255   unformat_input_t *input = vam->input;
17256   vl_api_gpe_add_del_iface_t *mp;
17257   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17258   u32 dp_table = 0, vni = 0;
17259   int ret;
17260
17261   /* Parse args required to build the message */
17262   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17263     {
17264       if (unformat (input, "up"))
17265         {
17266           action_set = 1;
17267           is_add = 1;
17268         }
17269       else if (unformat (input, "down"))
17270         {
17271           action_set = 1;
17272           is_add = 0;
17273         }
17274       else if (unformat (input, "table_id %d", &dp_table))
17275         {
17276           dp_table_set = 1;
17277         }
17278       else if (unformat (input, "bd_id %d", &dp_table))
17279         {
17280           dp_table_set = 1;
17281           is_l2 = 1;
17282         }
17283       else if (unformat (input, "vni %d", &vni))
17284         {
17285           vni_set = 1;
17286         }
17287       else
17288         break;
17289     }
17290
17291   if (action_set == 0)
17292     {
17293       errmsg ("Action not set");
17294       return -99;
17295     }
17296   if (dp_table_set == 0 || vni_set == 0)
17297     {
17298       errmsg ("vni and dp_table must be set");
17299       return -99;
17300     }
17301
17302   /* Construct the API message */
17303   M (GPE_ADD_DEL_IFACE, mp);
17304
17305   mp->is_add = is_add;
17306   mp->dp_table = clib_host_to_net_u32 (dp_table);
17307   mp->is_l2 = is_l2;
17308   mp->vni = clib_host_to_net_u32 (vni);
17309
17310   /* send it... */
17311   S (mp);
17312
17313   /* Wait for a reply... */
17314   W (ret);
17315   return ret;
17316 }
17317
17318 static int
17319 api_one_map_register_fallback_threshold (vat_main_t * vam)
17320 {
17321   unformat_input_t *input = vam->input;
17322   vl_api_one_map_register_fallback_threshold_t *mp;
17323   u32 value = 0;
17324   u8 is_set = 0;
17325   int ret;
17326
17327   /* Parse args required to build the message */
17328   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17329     {
17330       if (unformat (input, "%u", &value))
17331         is_set = 1;
17332       else
17333         {
17334           clib_warning ("parse error '%U'", format_unformat_error, input);
17335           return -99;
17336         }
17337     }
17338
17339   if (!is_set)
17340     {
17341       errmsg ("fallback threshold value is missing!");
17342       return -99;
17343     }
17344
17345   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17346   mp->value = clib_host_to_net_u32 (value);
17347
17348   /* send it... */
17349   S (mp);
17350
17351   /* Wait for a reply... */
17352   W (ret);
17353   return ret;
17354 }
17355
17356 static int
17357 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17358 {
17359   vl_api_show_one_map_register_fallback_threshold_t *mp;
17360   int ret;
17361
17362   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17363
17364   /* send it... */
17365   S (mp);
17366
17367   /* Wait for a reply... */
17368   W (ret);
17369   return ret;
17370 }
17371
17372 uword
17373 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17374 {
17375   u32 *proto = va_arg (*args, u32 *);
17376
17377   if (unformat (input, "udp"))
17378     *proto = 1;
17379   else if (unformat (input, "api"))
17380     *proto = 2;
17381   else
17382     return 0;
17383
17384   return 1;
17385 }
17386
17387 static int
17388 api_one_set_transport_protocol (vat_main_t * vam)
17389 {
17390   unformat_input_t *input = vam->input;
17391   vl_api_one_set_transport_protocol_t *mp;
17392   u8 is_set = 0;
17393   u32 protocol = 0;
17394   int ret;
17395
17396   /* Parse args required to build the message */
17397   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17398     {
17399       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17400         is_set = 1;
17401       else
17402         {
17403           clib_warning ("parse error '%U'", format_unformat_error, input);
17404           return -99;
17405         }
17406     }
17407
17408   if (!is_set)
17409     {
17410       errmsg ("Transport protocol missing!");
17411       return -99;
17412     }
17413
17414   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17415   mp->protocol = (u8) protocol;
17416
17417   /* send it... */
17418   S (mp);
17419
17420   /* Wait for a reply... */
17421   W (ret);
17422   return ret;
17423 }
17424
17425 static int
17426 api_one_get_transport_protocol (vat_main_t * vam)
17427 {
17428   vl_api_one_get_transport_protocol_t *mp;
17429   int ret;
17430
17431   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17432
17433   /* send it... */
17434   S (mp);
17435
17436   /* Wait for a reply... */
17437   W (ret);
17438   return ret;
17439 }
17440
17441 static int
17442 api_one_map_register_set_ttl (vat_main_t * vam)
17443 {
17444   unformat_input_t *input = vam->input;
17445   vl_api_one_map_register_set_ttl_t *mp;
17446   u32 ttl = 0;
17447   u8 is_set = 0;
17448   int ret;
17449
17450   /* Parse args required to build the message */
17451   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17452     {
17453       if (unformat (input, "%u", &ttl))
17454         is_set = 1;
17455       else
17456         {
17457           clib_warning ("parse error '%U'", format_unformat_error, input);
17458           return -99;
17459         }
17460     }
17461
17462   if (!is_set)
17463     {
17464       errmsg ("TTL value missing!");
17465       return -99;
17466     }
17467
17468   M (ONE_MAP_REGISTER_SET_TTL, mp);
17469   mp->ttl = clib_host_to_net_u32 (ttl);
17470
17471   /* send it... */
17472   S (mp);
17473
17474   /* Wait for a reply... */
17475   W (ret);
17476   return ret;
17477 }
17478
17479 static int
17480 api_show_one_map_register_ttl (vat_main_t * vam)
17481 {
17482   vl_api_show_one_map_register_ttl_t *mp;
17483   int ret;
17484
17485   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17486
17487   /* send it... */
17488   S (mp);
17489
17490   /* Wait for a reply... */
17491   W (ret);
17492   return ret;
17493 }
17494
17495 /**
17496  * Add/del map request itr rlocs from ONE control plane and updates
17497  *
17498  * @param vam vpp API test context
17499  * @return return code
17500  */
17501 static int
17502 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17503 {
17504   unformat_input_t *input = vam->input;
17505   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17506   u8 *locator_set_name = 0;
17507   u8 locator_set_name_set = 0;
17508   u8 is_add = 1;
17509   int ret;
17510
17511   /* Parse args required to build the message */
17512   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17513     {
17514       if (unformat (input, "del"))
17515         {
17516           is_add = 0;
17517         }
17518       else if (unformat (input, "%_%v%_", &locator_set_name))
17519         {
17520           locator_set_name_set = 1;
17521         }
17522       else
17523         {
17524           clib_warning ("parse error '%U'", format_unformat_error, input);
17525           return -99;
17526         }
17527     }
17528
17529   if (is_add && !locator_set_name_set)
17530     {
17531       errmsg ("itr-rloc is not set!");
17532       return -99;
17533     }
17534
17535   if (is_add && vec_len (locator_set_name) > 64)
17536     {
17537       errmsg ("itr-rloc locator-set name too long");
17538       vec_free (locator_set_name);
17539       return -99;
17540     }
17541
17542   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17543   mp->is_add = is_add;
17544   if (is_add)
17545     {
17546       clib_memcpy (mp->locator_set_name, locator_set_name,
17547                    vec_len (locator_set_name));
17548     }
17549   else
17550     {
17551       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17552     }
17553   vec_free (locator_set_name);
17554
17555   /* send it... */
17556   S (mp);
17557
17558   /* Wait for a reply... */
17559   W (ret);
17560   return ret;
17561 }
17562
17563 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17564
17565 static int
17566 api_one_locator_dump (vat_main_t * vam)
17567 {
17568   unformat_input_t *input = vam->input;
17569   vl_api_one_locator_dump_t *mp;
17570   vl_api_control_ping_t *mp_ping;
17571   u8 is_index_set = 0, is_name_set = 0;
17572   u8 *ls_name = 0;
17573   u32 ls_index = ~0;
17574   int ret;
17575
17576   /* Parse args required to build the message */
17577   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17578     {
17579       if (unformat (input, "ls_name %_%v%_", &ls_name))
17580         {
17581           is_name_set = 1;
17582         }
17583       else if (unformat (input, "ls_index %d", &ls_index))
17584         {
17585           is_index_set = 1;
17586         }
17587       else
17588         {
17589           errmsg ("parse error '%U'", format_unformat_error, input);
17590           return -99;
17591         }
17592     }
17593
17594   if (!is_index_set && !is_name_set)
17595     {
17596       errmsg ("error: expected one of index or name!");
17597       return -99;
17598     }
17599
17600   if (is_index_set && is_name_set)
17601     {
17602       errmsg ("error: only one param expected!");
17603       return -99;
17604     }
17605
17606   if (vec_len (ls_name) > 62)
17607     {
17608       errmsg ("error: locator set name too long!");
17609       return -99;
17610     }
17611
17612   if (!vam->json_output)
17613     {
17614       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17615     }
17616
17617   M (ONE_LOCATOR_DUMP, mp);
17618   mp->is_index_set = is_index_set;
17619
17620   if (is_index_set)
17621     mp->ls_index = clib_host_to_net_u32 (ls_index);
17622   else
17623     {
17624       vec_add1 (ls_name, 0);
17625       strncpy ((char *) mp->ls_name, (char *) ls_name,
17626                sizeof (mp->ls_name) - 1);
17627     }
17628
17629   /* send it... */
17630   S (mp);
17631
17632   /* Use a control ping for synchronization */
17633   MPING (CONTROL_PING, mp_ping);
17634   S (mp_ping);
17635
17636   /* Wait for a reply... */
17637   W (ret);
17638   return ret;
17639 }
17640
17641 #define api_lisp_locator_dump api_one_locator_dump
17642
17643 static int
17644 api_one_locator_set_dump (vat_main_t * vam)
17645 {
17646   vl_api_one_locator_set_dump_t *mp;
17647   vl_api_control_ping_t *mp_ping;
17648   unformat_input_t *input = vam->input;
17649   u8 filter = 0;
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, "local"))
17656         {
17657           filter = 1;
17658         }
17659       else if (unformat (input, "remote"))
17660         {
17661           filter = 2;
17662         }
17663       else
17664         {
17665           errmsg ("parse error '%U'", format_unformat_error, input);
17666           return -99;
17667         }
17668     }
17669
17670   if (!vam->json_output)
17671     {
17672       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17673     }
17674
17675   M (ONE_LOCATOR_SET_DUMP, mp);
17676
17677   mp->filter = filter;
17678
17679   /* send it... */
17680   S (mp);
17681
17682   /* Use a control ping for synchronization */
17683   MPING (CONTROL_PING, mp_ping);
17684   S (mp_ping);
17685
17686   /* Wait for a reply... */
17687   W (ret);
17688   return ret;
17689 }
17690
17691 #define api_lisp_locator_set_dump api_one_locator_set_dump
17692
17693 static int
17694 api_one_eid_table_map_dump (vat_main_t * vam)
17695 {
17696   u8 is_l2 = 0;
17697   u8 mode_set = 0;
17698   unformat_input_t *input = vam->input;
17699   vl_api_one_eid_table_map_dump_t *mp;
17700   vl_api_control_ping_t *mp_ping;
17701   int ret;
17702
17703   /* Parse args required to build the message */
17704   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17705     {
17706       if (unformat (input, "l2"))
17707         {
17708           is_l2 = 1;
17709           mode_set = 1;
17710         }
17711       else if (unformat (input, "l3"))
17712         {
17713           is_l2 = 0;
17714           mode_set = 1;
17715         }
17716       else
17717         {
17718           errmsg ("parse error '%U'", format_unformat_error, input);
17719           return -99;
17720         }
17721     }
17722
17723   if (!mode_set)
17724     {
17725       errmsg ("expected one of 'l2' or 'l3' parameter!");
17726       return -99;
17727     }
17728
17729   if (!vam->json_output)
17730     {
17731       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17732     }
17733
17734   M (ONE_EID_TABLE_MAP_DUMP, mp);
17735   mp->is_l2 = is_l2;
17736
17737   /* send it... */
17738   S (mp);
17739
17740   /* Use a control ping for synchronization */
17741   MPING (CONTROL_PING, mp_ping);
17742   S (mp_ping);
17743
17744   /* Wait for a reply... */
17745   W (ret);
17746   return ret;
17747 }
17748
17749 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17750
17751 static int
17752 api_one_eid_table_vni_dump (vat_main_t * vam)
17753 {
17754   vl_api_one_eid_table_vni_dump_t *mp;
17755   vl_api_control_ping_t *mp_ping;
17756   int ret;
17757
17758   if (!vam->json_output)
17759     {
17760       print (vam->ofp, "VNI");
17761     }
17762
17763   M (ONE_EID_TABLE_VNI_DUMP, mp);
17764
17765   /* send it... */
17766   S (mp);
17767
17768   /* Use a control ping for synchronization */
17769   MPING (CONTROL_PING, mp_ping);
17770   S (mp_ping);
17771
17772   /* Wait for a reply... */
17773   W (ret);
17774   return ret;
17775 }
17776
17777 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17778
17779 static int
17780 api_one_eid_table_dump (vat_main_t * vam)
17781 {
17782   unformat_input_t *i = vam->input;
17783   vl_api_one_eid_table_dump_t *mp;
17784   vl_api_control_ping_t *mp_ping;
17785   struct in_addr ip4;
17786   struct in6_addr ip6;
17787   u8 mac[6];
17788   u8 eid_type = ~0, eid_set = 0;
17789   u32 prefix_length = ~0, t, vni = 0;
17790   u8 filter = 0;
17791   int ret;
17792   lisp_nsh_api_t nsh;
17793
17794   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17795     {
17796       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17797         {
17798           eid_set = 1;
17799           eid_type = 0;
17800           prefix_length = t;
17801         }
17802       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17803         {
17804           eid_set = 1;
17805           eid_type = 1;
17806           prefix_length = t;
17807         }
17808       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17809         {
17810           eid_set = 1;
17811           eid_type = 2;
17812         }
17813       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17814         {
17815           eid_set = 1;
17816           eid_type = 3;
17817         }
17818       else if (unformat (i, "vni %d", &t))
17819         {
17820           vni = t;
17821         }
17822       else if (unformat (i, "local"))
17823         {
17824           filter = 1;
17825         }
17826       else if (unformat (i, "remote"))
17827         {
17828           filter = 2;
17829         }
17830       else
17831         {
17832           errmsg ("parse error '%U'", format_unformat_error, i);
17833           return -99;
17834         }
17835     }
17836
17837   if (!vam->json_output)
17838     {
17839       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17840              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17841     }
17842
17843   M (ONE_EID_TABLE_DUMP, mp);
17844
17845   mp->filter = filter;
17846   if (eid_set)
17847     {
17848       mp->eid_set = 1;
17849       mp->vni = htonl (vni);
17850       mp->eid_type = eid_type;
17851       switch (eid_type)
17852         {
17853         case 0:
17854           mp->prefix_length = prefix_length;
17855           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17856           break;
17857         case 1:
17858           mp->prefix_length = prefix_length;
17859           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17860           break;
17861         case 2:
17862           clib_memcpy (mp->eid, mac, sizeof (mac));
17863           break;
17864         case 3:
17865           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17866           break;
17867         default:
17868           errmsg ("unknown EID type %d!", eid_type);
17869           return -99;
17870         }
17871     }
17872
17873   /* send it... */
17874   S (mp);
17875
17876   /* Use a control ping for synchronization */
17877   MPING (CONTROL_PING, mp_ping);
17878   S (mp_ping);
17879
17880   /* Wait for a reply... */
17881   W (ret);
17882   return ret;
17883 }
17884
17885 #define api_lisp_eid_table_dump api_one_eid_table_dump
17886
17887 static int
17888 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17889 {
17890   unformat_input_t *i = vam->input;
17891   vl_api_gpe_fwd_entries_get_t *mp;
17892   u8 vni_set = 0;
17893   u32 vni = ~0;
17894   int ret;
17895
17896   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17897     {
17898       if (unformat (i, "vni %d", &vni))
17899         {
17900           vni_set = 1;
17901         }
17902       else
17903         {
17904           errmsg ("parse error '%U'", format_unformat_error, i);
17905           return -99;
17906         }
17907     }
17908
17909   if (!vni_set)
17910     {
17911       errmsg ("vni not set!");
17912       return -99;
17913     }
17914
17915   if (!vam->json_output)
17916     {
17917       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17918              "leid", "reid");
17919     }
17920
17921   M (GPE_FWD_ENTRIES_GET, mp);
17922   mp->vni = clib_host_to_net_u32 (vni);
17923
17924   /* send it... */
17925   S (mp);
17926
17927   /* Wait for a reply... */
17928   W (ret);
17929   return ret;
17930 }
17931
17932 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
17933 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
17934 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
17935 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
17936 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
17937 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
17938 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
17939 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
17940
17941 static int
17942 api_one_adjacencies_get (vat_main_t * vam)
17943 {
17944   unformat_input_t *i = vam->input;
17945   vl_api_one_adjacencies_get_t *mp;
17946   u8 vni_set = 0;
17947   u32 vni = ~0;
17948   int ret;
17949
17950   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17951     {
17952       if (unformat (i, "vni %d", &vni))
17953         {
17954           vni_set = 1;
17955         }
17956       else
17957         {
17958           errmsg ("parse error '%U'", format_unformat_error, i);
17959           return -99;
17960         }
17961     }
17962
17963   if (!vni_set)
17964     {
17965       errmsg ("vni not set!");
17966       return -99;
17967     }
17968
17969   if (!vam->json_output)
17970     {
17971       print (vam->ofp, "%s %40s", "leid", "reid");
17972     }
17973
17974   M (ONE_ADJACENCIES_GET, mp);
17975   mp->vni = clib_host_to_net_u32 (vni);
17976
17977   /* send it... */
17978   S (mp);
17979
17980   /* Wait for a reply... */
17981   W (ret);
17982   return ret;
17983 }
17984
17985 #define api_lisp_adjacencies_get api_one_adjacencies_get
17986
17987 static int
17988 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
17989 {
17990   unformat_input_t *i = vam->input;
17991   vl_api_gpe_native_fwd_rpaths_get_t *mp;
17992   int ret;
17993   u8 ip_family_set = 0, is_ip4 = 1;
17994
17995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17996     {
17997       if (unformat (i, "ip4"))
17998         {
17999           ip_family_set = 1;
18000           is_ip4 = 1;
18001         }
18002       else if (unformat (i, "ip6"))
18003         {
18004           ip_family_set = 1;
18005           is_ip4 = 0;
18006         }
18007       else
18008         {
18009           errmsg ("parse error '%U'", format_unformat_error, i);
18010           return -99;
18011         }
18012     }
18013
18014   if (!ip_family_set)
18015     {
18016       errmsg ("ip family not set!");
18017       return -99;
18018     }
18019
18020   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18021   mp->is_ip4 = is_ip4;
18022
18023   /* send it... */
18024   S (mp);
18025
18026   /* Wait for a reply... */
18027   W (ret);
18028   return ret;
18029 }
18030
18031 static int
18032 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18033 {
18034   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18035   int ret;
18036
18037   if (!vam->json_output)
18038     {
18039       print (vam->ofp, "VNIs");
18040     }
18041
18042   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18043
18044   /* send it... */
18045   S (mp);
18046
18047   /* Wait for a reply... */
18048   W (ret);
18049   return ret;
18050 }
18051
18052 static int
18053 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18054 {
18055   unformat_input_t *i = vam->input;
18056   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18057   int ret = 0;
18058   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18059   struct in_addr ip4;
18060   struct in6_addr ip6;
18061   u32 table_id = 0, nh_sw_if_index = ~0;
18062
18063   memset (&ip4, 0, sizeof (ip4));
18064   memset (&ip6, 0, sizeof (ip6));
18065
18066   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18067     {
18068       if (unformat (i, "del"))
18069         is_add = 0;
18070       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18071                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18072         {
18073           ip_set = 1;
18074           is_ip4 = 1;
18075         }
18076       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18077                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18078         {
18079           ip_set = 1;
18080           is_ip4 = 0;
18081         }
18082       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18083         {
18084           ip_set = 1;
18085           is_ip4 = 1;
18086           nh_sw_if_index = ~0;
18087         }
18088       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18089         {
18090           ip_set = 1;
18091           is_ip4 = 0;
18092           nh_sw_if_index = ~0;
18093         }
18094       else if (unformat (i, "table %d", &table_id))
18095         ;
18096       else
18097         {
18098           errmsg ("parse error '%U'", format_unformat_error, i);
18099           return -99;
18100         }
18101     }
18102
18103   if (!ip_set)
18104     {
18105       errmsg ("nh addr not set!");
18106       return -99;
18107     }
18108
18109   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18110   mp->is_add = is_add;
18111   mp->table_id = clib_host_to_net_u32 (table_id);
18112   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18113   mp->is_ip4 = is_ip4;
18114   if (is_ip4)
18115     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18116   else
18117     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18118
18119   /* send it... */
18120   S (mp);
18121
18122   /* Wait for a reply... */
18123   W (ret);
18124   return ret;
18125 }
18126
18127 static int
18128 api_one_map_server_dump (vat_main_t * vam)
18129 {
18130   vl_api_one_map_server_dump_t *mp;
18131   vl_api_control_ping_t *mp_ping;
18132   int ret;
18133
18134   if (!vam->json_output)
18135     {
18136       print (vam->ofp, "%=20s", "Map server");
18137     }
18138
18139   M (ONE_MAP_SERVER_DUMP, mp);
18140   /* send it... */
18141   S (mp);
18142
18143   /* Use a control ping for synchronization */
18144   MPING (CONTROL_PING, mp_ping);
18145   S (mp_ping);
18146
18147   /* Wait for a reply... */
18148   W (ret);
18149   return ret;
18150 }
18151
18152 #define api_lisp_map_server_dump api_one_map_server_dump
18153
18154 static int
18155 api_one_map_resolver_dump (vat_main_t * vam)
18156 {
18157   vl_api_one_map_resolver_dump_t *mp;
18158   vl_api_control_ping_t *mp_ping;
18159   int ret;
18160
18161   if (!vam->json_output)
18162     {
18163       print (vam->ofp, "%=20s", "Map resolver");
18164     }
18165
18166   M (ONE_MAP_RESOLVER_DUMP, mp);
18167   /* send it... */
18168   S (mp);
18169
18170   /* Use a control ping for synchronization */
18171   MPING (CONTROL_PING, mp_ping);
18172   S (mp_ping);
18173
18174   /* Wait for a reply... */
18175   W (ret);
18176   return ret;
18177 }
18178
18179 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18180
18181 static int
18182 api_one_stats_flush (vat_main_t * vam)
18183 {
18184   vl_api_one_stats_flush_t *mp;
18185   int ret = 0;
18186
18187   M (ONE_STATS_FLUSH, mp);
18188   S (mp);
18189   W (ret);
18190   return ret;
18191 }
18192
18193 static int
18194 api_one_stats_dump (vat_main_t * vam)
18195 {
18196   vl_api_one_stats_dump_t *mp;
18197   vl_api_control_ping_t *mp_ping;
18198   int ret;
18199
18200   M (ONE_STATS_DUMP, mp);
18201   /* send it... */
18202   S (mp);
18203
18204   /* Use a control ping for synchronization */
18205   MPING (CONTROL_PING, mp_ping);
18206   S (mp_ping);
18207
18208   /* Wait for a reply... */
18209   W (ret);
18210   return ret;
18211 }
18212
18213 static int
18214 api_show_one_status (vat_main_t * vam)
18215 {
18216   vl_api_show_one_status_t *mp;
18217   int ret;
18218
18219   if (!vam->json_output)
18220     {
18221       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18222     }
18223
18224   M (SHOW_ONE_STATUS, mp);
18225   /* send it... */
18226   S (mp);
18227   /* Wait for a reply... */
18228   W (ret);
18229   return ret;
18230 }
18231
18232 #define api_show_lisp_status api_show_one_status
18233
18234 static int
18235 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18236 {
18237   vl_api_gpe_fwd_entry_path_dump_t *mp;
18238   vl_api_control_ping_t *mp_ping;
18239   unformat_input_t *i = vam->input;
18240   u32 fwd_entry_index = ~0;
18241   int ret;
18242
18243   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18244     {
18245       if (unformat (i, "index %d", &fwd_entry_index))
18246         ;
18247       else
18248         break;
18249     }
18250
18251   if (~0 == fwd_entry_index)
18252     {
18253       errmsg ("no index specified!");
18254       return -99;
18255     }
18256
18257   if (!vam->json_output)
18258     {
18259       print (vam->ofp, "first line");
18260     }
18261
18262   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18263
18264   /* send it... */
18265   S (mp);
18266   /* Use a control ping for synchronization */
18267   MPING (CONTROL_PING, mp_ping);
18268   S (mp_ping);
18269
18270   /* Wait for a reply... */
18271   W (ret);
18272   return ret;
18273 }
18274
18275 static int
18276 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18277 {
18278   vl_api_one_get_map_request_itr_rlocs_t *mp;
18279   int ret;
18280
18281   if (!vam->json_output)
18282     {
18283       print (vam->ofp, "%=20s", "itr-rlocs:");
18284     }
18285
18286   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18287   /* send it... */
18288   S (mp);
18289   /* Wait for a reply... */
18290   W (ret);
18291   return ret;
18292 }
18293
18294 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18295
18296 static int
18297 api_af_packet_create (vat_main_t * vam)
18298 {
18299   unformat_input_t *i = vam->input;
18300   vl_api_af_packet_create_t *mp;
18301   u8 *host_if_name = 0;
18302   u8 hw_addr[6];
18303   u8 random_hw_addr = 1;
18304   int ret;
18305
18306   memset (hw_addr, 0, sizeof (hw_addr));
18307
18308   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18309     {
18310       if (unformat (i, "name %s", &host_if_name))
18311         vec_add1 (host_if_name, 0);
18312       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18313         random_hw_addr = 0;
18314       else
18315         break;
18316     }
18317
18318   if (!vec_len (host_if_name))
18319     {
18320       errmsg ("host-interface name must be specified");
18321       return -99;
18322     }
18323
18324   if (vec_len (host_if_name) > 64)
18325     {
18326       errmsg ("host-interface name too long");
18327       return -99;
18328     }
18329
18330   M (AF_PACKET_CREATE, mp);
18331
18332   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18333   clib_memcpy (mp->hw_addr, hw_addr, 6);
18334   mp->use_random_hw_addr = random_hw_addr;
18335   vec_free (host_if_name);
18336
18337   S (mp);
18338
18339   /* *INDENT-OFF* */
18340   W2 (ret,
18341       ({
18342         if (ret == 0)
18343           fprintf (vam->ofp ? vam->ofp : stderr,
18344                    " new sw_if_index = %d\n", vam->sw_if_index);
18345       }));
18346   /* *INDENT-ON* */
18347   return ret;
18348 }
18349
18350 static int
18351 api_af_packet_delete (vat_main_t * vam)
18352 {
18353   unformat_input_t *i = vam->input;
18354   vl_api_af_packet_delete_t *mp;
18355   u8 *host_if_name = 0;
18356   int ret;
18357
18358   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18359     {
18360       if (unformat (i, "name %s", &host_if_name))
18361         vec_add1 (host_if_name, 0);
18362       else
18363         break;
18364     }
18365
18366   if (!vec_len (host_if_name))
18367     {
18368       errmsg ("host-interface name must be specified");
18369       return -99;
18370     }
18371
18372   if (vec_len (host_if_name) > 64)
18373     {
18374       errmsg ("host-interface name too long");
18375       return -99;
18376     }
18377
18378   M (AF_PACKET_DELETE, mp);
18379
18380   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18381   vec_free (host_if_name);
18382
18383   S (mp);
18384   W (ret);
18385   return ret;
18386 }
18387
18388 static int
18389 api_policer_add_del (vat_main_t * vam)
18390 {
18391   unformat_input_t *i = vam->input;
18392   vl_api_policer_add_del_t *mp;
18393   u8 is_add = 1;
18394   u8 *name = 0;
18395   u32 cir = 0;
18396   u32 eir = 0;
18397   u64 cb = 0;
18398   u64 eb = 0;
18399   u8 rate_type = 0;
18400   u8 round_type = 0;
18401   u8 type = 0;
18402   u8 color_aware = 0;
18403   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18404   int ret;
18405
18406   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18407   conform_action.dscp = 0;
18408   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18409   exceed_action.dscp = 0;
18410   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18411   violate_action.dscp = 0;
18412
18413   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18414     {
18415       if (unformat (i, "del"))
18416         is_add = 0;
18417       else if (unformat (i, "name %s", &name))
18418         vec_add1 (name, 0);
18419       else if (unformat (i, "cir %u", &cir))
18420         ;
18421       else if (unformat (i, "eir %u", &eir))
18422         ;
18423       else if (unformat (i, "cb %u", &cb))
18424         ;
18425       else if (unformat (i, "eb %u", &eb))
18426         ;
18427       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18428                          &rate_type))
18429         ;
18430       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18431                          &round_type))
18432         ;
18433       else if (unformat (i, "type %U", unformat_policer_type, &type))
18434         ;
18435       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18436                          &conform_action))
18437         ;
18438       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18439                          &exceed_action))
18440         ;
18441       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18442                          &violate_action))
18443         ;
18444       else if (unformat (i, "color-aware"))
18445         color_aware = 1;
18446       else
18447         break;
18448     }
18449
18450   if (!vec_len (name))
18451     {
18452       errmsg ("policer name must be specified");
18453       return -99;
18454     }
18455
18456   if (vec_len (name) > 64)
18457     {
18458       errmsg ("policer name too long");
18459       return -99;
18460     }
18461
18462   M (POLICER_ADD_DEL, mp);
18463
18464   clib_memcpy (mp->name, name, vec_len (name));
18465   vec_free (name);
18466   mp->is_add = is_add;
18467   mp->cir = ntohl (cir);
18468   mp->eir = ntohl (eir);
18469   mp->cb = clib_net_to_host_u64 (cb);
18470   mp->eb = clib_net_to_host_u64 (eb);
18471   mp->rate_type = rate_type;
18472   mp->round_type = round_type;
18473   mp->type = type;
18474   mp->conform_action_type = conform_action.action_type;
18475   mp->conform_dscp = conform_action.dscp;
18476   mp->exceed_action_type = exceed_action.action_type;
18477   mp->exceed_dscp = exceed_action.dscp;
18478   mp->violate_action_type = violate_action.action_type;
18479   mp->violate_dscp = violate_action.dscp;
18480   mp->color_aware = color_aware;
18481
18482   S (mp);
18483   W (ret);
18484   return ret;
18485 }
18486
18487 static int
18488 api_policer_dump (vat_main_t * vam)
18489 {
18490   unformat_input_t *i = vam->input;
18491   vl_api_policer_dump_t *mp;
18492   vl_api_control_ping_t *mp_ping;
18493   u8 *match_name = 0;
18494   u8 match_name_valid = 0;
18495   int ret;
18496
18497   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18498     {
18499       if (unformat (i, "name %s", &match_name))
18500         {
18501           vec_add1 (match_name, 0);
18502           match_name_valid = 1;
18503         }
18504       else
18505         break;
18506     }
18507
18508   M (POLICER_DUMP, mp);
18509   mp->match_name_valid = match_name_valid;
18510   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18511   vec_free (match_name);
18512   /* send it... */
18513   S (mp);
18514
18515   /* Use a control ping for synchronization */
18516   MPING (CONTROL_PING, mp_ping);
18517   S (mp_ping);
18518
18519   /* Wait for a reply... */
18520   W (ret);
18521   return ret;
18522 }
18523
18524 static int
18525 api_policer_classify_set_interface (vat_main_t * vam)
18526 {
18527   unformat_input_t *i = vam->input;
18528   vl_api_policer_classify_set_interface_t *mp;
18529   u32 sw_if_index;
18530   int sw_if_index_set;
18531   u32 ip4_table_index = ~0;
18532   u32 ip6_table_index = ~0;
18533   u32 l2_table_index = ~0;
18534   u8 is_add = 1;
18535   int ret;
18536
18537   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18538     {
18539       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18540         sw_if_index_set = 1;
18541       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18542         sw_if_index_set = 1;
18543       else if (unformat (i, "del"))
18544         is_add = 0;
18545       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18546         ;
18547       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18548         ;
18549       else if (unformat (i, "l2-table %d", &l2_table_index))
18550         ;
18551       else
18552         {
18553           clib_warning ("parse error '%U'", format_unformat_error, i);
18554           return -99;
18555         }
18556     }
18557
18558   if (sw_if_index_set == 0)
18559     {
18560       errmsg ("missing interface name or sw_if_index");
18561       return -99;
18562     }
18563
18564   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18565
18566   mp->sw_if_index = ntohl (sw_if_index);
18567   mp->ip4_table_index = ntohl (ip4_table_index);
18568   mp->ip6_table_index = ntohl (ip6_table_index);
18569   mp->l2_table_index = ntohl (l2_table_index);
18570   mp->is_add = is_add;
18571
18572   S (mp);
18573   W (ret);
18574   return ret;
18575 }
18576
18577 static int
18578 api_policer_classify_dump (vat_main_t * vam)
18579 {
18580   unformat_input_t *i = vam->input;
18581   vl_api_policer_classify_dump_t *mp;
18582   vl_api_control_ping_t *mp_ping;
18583   u8 type = POLICER_CLASSIFY_N_TABLES;
18584   int ret;
18585
18586   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18587     ;
18588   else
18589     {
18590       errmsg ("classify table type must be specified");
18591       return -99;
18592     }
18593
18594   if (!vam->json_output)
18595     {
18596       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18597     }
18598
18599   M (POLICER_CLASSIFY_DUMP, mp);
18600   mp->type = type;
18601   /* send it... */
18602   S (mp);
18603
18604   /* Use a control ping for synchronization */
18605   MPING (CONTROL_PING, mp_ping);
18606   S (mp_ping);
18607
18608   /* Wait for a reply... */
18609   W (ret);
18610   return ret;
18611 }
18612
18613 static int
18614 api_netmap_create (vat_main_t * vam)
18615 {
18616   unformat_input_t *i = vam->input;
18617   vl_api_netmap_create_t *mp;
18618   u8 *if_name = 0;
18619   u8 hw_addr[6];
18620   u8 random_hw_addr = 1;
18621   u8 is_pipe = 0;
18622   u8 is_master = 0;
18623   int ret;
18624
18625   memset (hw_addr, 0, sizeof (hw_addr));
18626
18627   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18628     {
18629       if (unformat (i, "name %s", &if_name))
18630         vec_add1 (if_name, 0);
18631       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18632         random_hw_addr = 0;
18633       else if (unformat (i, "pipe"))
18634         is_pipe = 1;
18635       else if (unformat (i, "master"))
18636         is_master = 1;
18637       else if (unformat (i, "slave"))
18638         is_master = 0;
18639       else
18640         break;
18641     }
18642
18643   if (!vec_len (if_name))
18644     {
18645       errmsg ("interface name must be specified");
18646       return -99;
18647     }
18648
18649   if (vec_len (if_name) > 64)
18650     {
18651       errmsg ("interface name too long");
18652       return -99;
18653     }
18654
18655   M (NETMAP_CREATE, mp);
18656
18657   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18658   clib_memcpy (mp->hw_addr, hw_addr, 6);
18659   mp->use_random_hw_addr = random_hw_addr;
18660   mp->is_pipe = is_pipe;
18661   mp->is_master = is_master;
18662   vec_free (if_name);
18663
18664   S (mp);
18665   W (ret);
18666   return ret;
18667 }
18668
18669 static int
18670 api_netmap_delete (vat_main_t * vam)
18671 {
18672   unformat_input_t *i = vam->input;
18673   vl_api_netmap_delete_t *mp;
18674   u8 *if_name = 0;
18675   int ret;
18676
18677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18678     {
18679       if (unformat (i, "name %s", &if_name))
18680         vec_add1 (if_name, 0);
18681       else
18682         break;
18683     }
18684
18685   if (!vec_len (if_name))
18686     {
18687       errmsg ("interface name must be specified");
18688       return -99;
18689     }
18690
18691   if (vec_len (if_name) > 64)
18692     {
18693       errmsg ("interface name too long");
18694       return -99;
18695     }
18696
18697   M (NETMAP_DELETE, mp);
18698
18699   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18700   vec_free (if_name);
18701
18702   S (mp);
18703   W (ret);
18704   return ret;
18705 }
18706
18707 static void
18708 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
18709 {
18710   if (fp->afi == IP46_TYPE_IP6)
18711     print (vam->ofp,
18712            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18713            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18714            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18715            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18716            format_ip6_address, fp->next_hop);
18717   else if (fp->afi == IP46_TYPE_IP4)
18718     print (vam->ofp,
18719            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18720            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18721            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18722            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18723            format_ip4_address, fp->next_hop);
18724 }
18725
18726 static void
18727 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18728                                  vl_api_fib_path2_t * fp)
18729 {
18730   struct in_addr ip4;
18731   struct in6_addr ip6;
18732
18733   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18734   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18735   vat_json_object_add_uint (node, "is_local", fp->is_local);
18736   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
18737   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
18738   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
18739   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
18740   if (fp->afi == IP46_TYPE_IP4)
18741     {
18742       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
18743       vat_json_object_add_ip4 (node, "next_hop", ip4);
18744     }
18745   else if (fp->afi == IP46_TYPE_IP6)
18746     {
18747       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
18748       vat_json_object_add_ip6 (node, "next_hop", ip6);
18749     }
18750 }
18751
18752 static void
18753 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18754 {
18755   vat_main_t *vam = &vat_main;
18756   int count = ntohl (mp->mt_count);
18757   vl_api_fib_path2_t *fp;
18758   i32 i;
18759
18760   print (vam->ofp, "[%d]: sw_if_index %d via:",
18761          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
18762   fp = mp->mt_paths;
18763   for (i = 0; i < count; i++)
18764     {
18765       vl_api_mpls_fib_path_print (vam, fp);
18766       fp++;
18767     }
18768
18769   print (vam->ofp, "");
18770 }
18771
18772 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18773 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18774
18775 static void
18776 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18777 {
18778   vat_main_t *vam = &vat_main;
18779   vat_json_node_t *node = NULL;
18780   int count = ntohl (mp->mt_count);
18781   vl_api_fib_path2_t *fp;
18782   i32 i;
18783
18784   if (VAT_JSON_ARRAY != vam->json_tree.type)
18785     {
18786       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18787       vat_json_init_array (&vam->json_tree);
18788     }
18789   node = vat_json_array_add (&vam->json_tree);
18790
18791   vat_json_init_object (node);
18792   vat_json_object_add_uint (node, "tunnel_index",
18793                             ntohl (mp->mt_tunnel_index));
18794   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
18795
18796   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
18797
18798   fp = mp->mt_paths;
18799   for (i = 0; i < count; i++)
18800     {
18801       vl_api_mpls_fib_path_json_print (node, fp);
18802       fp++;
18803     }
18804 }
18805
18806 static int
18807 api_mpls_tunnel_dump (vat_main_t * vam)
18808 {
18809   vl_api_mpls_tunnel_dump_t *mp;
18810   vl_api_control_ping_t *mp_ping;
18811   i32 index = -1;
18812   int ret;
18813
18814   /* Parse args required to build the message */
18815   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
18816     {
18817       if (!unformat (vam->input, "tunnel_index %d", &index))
18818         {
18819           index = -1;
18820           break;
18821         }
18822     }
18823
18824   print (vam->ofp, "  tunnel_index %d", index);
18825
18826   M (MPLS_TUNNEL_DUMP, mp);
18827   mp->tunnel_index = htonl (index);
18828   S (mp);
18829
18830   /* Use a control ping for synchronization */
18831   MPING (CONTROL_PING, mp_ping);
18832   S (mp_ping);
18833
18834   W (ret);
18835   return ret;
18836 }
18837
18838 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
18839 #define vl_api_mpls_fib_details_t_print vl_noop_handler
18840
18841
18842 static void
18843 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
18844 {
18845   vat_main_t *vam = &vat_main;
18846   int count = ntohl (mp->count);
18847   vl_api_fib_path2_t *fp;
18848   int i;
18849
18850   print (vam->ofp,
18851          "table-id %d, label %u, ess_bit %u",
18852          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
18853   fp = mp->path;
18854   for (i = 0; i < count; i++)
18855     {
18856       vl_api_mpls_fib_path_print (vam, fp);
18857       fp++;
18858     }
18859 }
18860
18861 static void vl_api_mpls_fib_details_t_handler_json
18862   (vl_api_mpls_fib_details_t * mp)
18863 {
18864   vat_main_t *vam = &vat_main;
18865   int count = ntohl (mp->count);
18866   vat_json_node_t *node = NULL;
18867   vl_api_fib_path2_t *fp;
18868   int i;
18869
18870   if (VAT_JSON_ARRAY != vam->json_tree.type)
18871     {
18872       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18873       vat_json_init_array (&vam->json_tree);
18874     }
18875   node = vat_json_array_add (&vam->json_tree);
18876
18877   vat_json_init_object (node);
18878   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
18879   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
18880   vat_json_object_add_uint (node, "label", ntohl (mp->label));
18881   vat_json_object_add_uint (node, "path_count", count);
18882   fp = mp->path;
18883   for (i = 0; i < count; i++)
18884     {
18885       vl_api_mpls_fib_path_json_print (node, fp);
18886       fp++;
18887     }
18888 }
18889
18890 static int
18891 api_mpls_fib_dump (vat_main_t * vam)
18892 {
18893   vl_api_mpls_fib_dump_t *mp;
18894   vl_api_control_ping_t *mp_ping;
18895   int ret;
18896
18897   M (MPLS_FIB_DUMP, mp);
18898   S (mp);
18899
18900   /* Use a control ping for synchronization */
18901   MPING (CONTROL_PING, mp_ping);
18902   S (mp_ping);
18903
18904   W (ret);
18905   return ret;
18906 }
18907
18908 #define vl_api_ip_fib_details_t_endian vl_noop_handler
18909 #define vl_api_ip_fib_details_t_print vl_noop_handler
18910
18911 static void
18912 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
18913 {
18914   vat_main_t *vam = &vat_main;
18915   int count = ntohl (mp->count);
18916   vl_api_fib_path_t *fp;
18917   int i;
18918
18919   print (vam->ofp,
18920          "table-id %d, prefix %U/%d",
18921          ntohl (mp->table_id), format_ip4_address, mp->address,
18922          mp->address_length);
18923   fp = mp->path;
18924   for (i = 0; i < count; i++)
18925     {
18926       if (fp->afi == IP46_TYPE_IP6)
18927         print (vam->ofp,
18928                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18929                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18930                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18931                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18932                format_ip6_address, fp->next_hop);
18933       else if (fp->afi == IP46_TYPE_IP4)
18934         print (vam->ofp,
18935                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18936                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18937                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18938                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18939                format_ip4_address, fp->next_hop);
18940       fp++;
18941     }
18942 }
18943
18944 static void vl_api_ip_fib_details_t_handler_json
18945   (vl_api_ip_fib_details_t * mp)
18946 {
18947   vat_main_t *vam = &vat_main;
18948   int count = ntohl (mp->count);
18949   vat_json_node_t *node = NULL;
18950   struct in_addr ip4;
18951   struct in6_addr ip6;
18952   vl_api_fib_path_t *fp;
18953   int i;
18954
18955   if (VAT_JSON_ARRAY != vam->json_tree.type)
18956     {
18957       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18958       vat_json_init_array (&vam->json_tree);
18959     }
18960   node = vat_json_array_add (&vam->json_tree);
18961
18962   vat_json_init_object (node);
18963   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
18964   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
18965   vat_json_object_add_ip4 (node, "prefix", ip4);
18966   vat_json_object_add_uint (node, "mask_length", mp->address_length);
18967   vat_json_object_add_uint (node, "path_count", count);
18968   fp = mp->path;
18969   for (i = 0; i < count; i++)
18970     {
18971       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18972       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18973       vat_json_object_add_uint (node, "is_local", fp->is_local);
18974       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
18975       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
18976       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
18977       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
18978       if (fp->afi == IP46_TYPE_IP4)
18979         {
18980           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
18981           vat_json_object_add_ip4 (node, "next_hop", ip4);
18982         }
18983       else if (fp->afi == IP46_TYPE_IP6)
18984         {
18985           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
18986           vat_json_object_add_ip6 (node, "next_hop", ip6);
18987         }
18988     }
18989 }
18990
18991 static int
18992 api_ip_fib_dump (vat_main_t * vam)
18993 {
18994   vl_api_ip_fib_dump_t *mp;
18995   vl_api_control_ping_t *mp_ping;
18996   int ret;
18997
18998   M (IP_FIB_DUMP, mp);
18999   S (mp);
19000
19001   /* Use a control ping for synchronization */
19002   MPING (CONTROL_PING, mp_ping);
19003   S (mp_ping);
19004
19005   W (ret);
19006   return ret;
19007 }
19008
19009 static int
19010 api_ip_mfib_dump (vat_main_t * vam)
19011 {
19012   vl_api_ip_mfib_dump_t *mp;
19013   vl_api_control_ping_t *mp_ping;
19014   int ret;
19015
19016   M (IP_MFIB_DUMP, mp);
19017   S (mp);
19018
19019   /* Use a control ping for synchronization */
19020   MPING (CONTROL_PING, mp_ping);
19021   S (mp_ping);
19022
19023   W (ret);
19024   return ret;
19025 }
19026
19027 static void vl_api_ip_neighbor_details_t_handler
19028   (vl_api_ip_neighbor_details_t * mp)
19029 {
19030   vat_main_t *vam = &vat_main;
19031
19032   print (vam->ofp, "%c %U %U",
19033          (mp->is_static) ? 'S' : 'D',
19034          format_ethernet_address, &mp->mac_address,
19035          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
19036          &mp->ip_address);
19037 }
19038
19039 static void vl_api_ip_neighbor_details_t_handler_json
19040   (vl_api_ip_neighbor_details_t * mp)
19041 {
19042
19043   vat_main_t *vam = &vat_main;
19044   vat_json_node_t *node;
19045   struct in_addr ip4;
19046   struct in6_addr ip6;
19047
19048   if (VAT_JSON_ARRAY != vam->json_tree.type)
19049     {
19050       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19051       vat_json_init_array (&vam->json_tree);
19052     }
19053   node = vat_json_array_add (&vam->json_tree);
19054
19055   vat_json_init_object (node);
19056   vat_json_object_add_string_copy (node, "flag",
19057                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
19058                                    "dynamic");
19059
19060   vat_json_object_add_string_copy (node, "link_layer",
19061                                    format (0, "%U", format_ethernet_address,
19062                                            &mp->mac_address));
19063
19064   if (mp->is_ipv6)
19065     {
19066       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
19067       vat_json_object_add_ip6 (node, "ip_address", ip6);
19068     }
19069   else
19070     {
19071       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
19072       vat_json_object_add_ip4 (node, "ip_address", ip4);
19073     }
19074 }
19075
19076 static int
19077 api_ip_neighbor_dump (vat_main_t * vam)
19078 {
19079   unformat_input_t *i = vam->input;
19080   vl_api_ip_neighbor_dump_t *mp;
19081   vl_api_control_ping_t *mp_ping;
19082   u8 is_ipv6 = 0;
19083   u32 sw_if_index = ~0;
19084   int ret;
19085
19086   /* Parse args required to build the message */
19087   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19088     {
19089       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19090         ;
19091       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19092         ;
19093       else if (unformat (i, "ip6"))
19094         is_ipv6 = 1;
19095       else
19096         break;
19097     }
19098
19099   if (sw_if_index == ~0)
19100     {
19101       errmsg ("missing interface name or sw_if_index");
19102       return -99;
19103     }
19104
19105   M (IP_NEIGHBOR_DUMP, mp);
19106   mp->is_ipv6 = (u8) is_ipv6;
19107   mp->sw_if_index = ntohl (sw_if_index);
19108   S (mp);
19109
19110   /* Use a control ping for synchronization */
19111   MPING (CONTROL_PING, mp_ping);
19112   S (mp_ping);
19113
19114   W (ret);
19115   return ret;
19116 }
19117
19118 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
19119 #define vl_api_ip6_fib_details_t_print vl_noop_handler
19120
19121 static void
19122 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
19123 {
19124   vat_main_t *vam = &vat_main;
19125   int count = ntohl (mp->count);
19126   vl_api_fib_path_t *fp;
19127   int i;
19128
19129   print (vam->ofp,
19130          "table-id %d, prefix %U/%d",
19131          ntohl (mp->table_id), format_ip6_address, mp->address,
19132          mp->address_length);
19133   fp = mp->path;
19134   for (i = 0; i < count; i++)
19135     {
19136       if (fp->afi == IP46_TYPE_IP6)
19137         print (vam->ofp,
19138                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19139                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19140                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19141                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19142                format_ip6_address, fp->next_hop);
19143       else if (fp->afi == IP46_TYPE_IP4)
19144         print (vam->ofp,
19145                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19146                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19147                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19148                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19149                format_ip4_address, fp->next_hop);
19150       fp++;
19151     }
19152 }
19153
19154 static void vl_api_ip6_fib_details_t_handler_json
19155   (vl_api_ip6_fib_details_t * mp)
19156 {
19157   vat_main_t *vam = &vat_main;
19158   int count = ntohl (mp->count);
19159   vat_json_node_t *node = NULL;
19160   struct in_addr ip4;
19161   struct in6_addr ip6;
19162   vl_api_fib_path_t *fp;
19163   int i;
19164
19165   if (VAT_JSON_ARRAY != vam->json_tree.type)
19166     {
19167       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19168       vat_json_init_array (&vam->json_tree);
19169     }
19170   node = vat_json_array_add (&vam->json_tree);
19171
19172   vat_json_init_object (node);
19173   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19174   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
19175   vat_json_object_add_ip6 (node, "prefix", ip6);
19176   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19177   vat_json_object_add_uint (node, "path_count", count);
19178   fp = mp->path;
19179   for (i = 0; i < count; i++)
19180     {
19181       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19182       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19183       vat_json_object_add_uint (node, "is_local", fp->is_local);
19184       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19185       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19186       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19187       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19188       if (fp->afi == IP46_TYPE_IP4)
19189         {
19190           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19191           vat_json_object_add_ip4 (node, "next_hop", ip4);
19192         }
19193       else if (fp->afi == IP46_TYPE_IP6)
19194         {
19195           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19196           vat_json_object_add_ip6 (node, "next_hop", ip6);
19197         }
19198     }
19199 }
19200
19201 static int
19202 api_ip6_fib_dump (vat_main_t * vam)
19203 {
19204   vl_api_ip6_fib_dump_t *mp;
19205   vl_api_control_ping_t *mp_ping;
19206   int ret;
19207
19208   M (IP6_FIB_DUMP, mp);
19209   S (mp);
19210
19211   /* Use a control ping for synchronization */
19212   MPING (CONTROL_PING, mp_ping);
19213   S (mp_ping);
19214
19215   W (ret);
19216   return ret;
19217 }
19218
19219 static int
19220 api_ip6_mfib_dump (vat_main_t * vam)
19221 {
19222   vl_api_ip6_mfib_dump_t *mp;
19223   vl_api_control_ping_t *mp_ping;
19224   int ret;
19225
19226   M (IP6_MFIB_DUMP, mp);
19227   S (mp);
19228
19229   /* Use a control ping for synchronization */
19230   MPING (CONTROL_PING, mp_ping);
19231   S (mp_ping);
19232
19233   W (ret);
19234   return ret;
19235 }
19236
19237 int
19238 api_classify_table_ids (vat_main_t * vam)
19239 {
19240   vl_api_classify_table_ids_t *mp;
19241   int ret;
19242
19243   /* Construct the API message */
19244   M (CLASSIFY_TABLE_IDS, mp);
19245   mp->context = 0;
19246
19247   S (mp);
19248   W (ret);
19249   return ret;
19250 }
19251
19252 int
19253 api_classify_table_by_interface (vat_main_t * vam)
19254 {
19255   unformat_input_t *input = vam->input;
19256   vl_api_classify_table_by_interface_t *mp;
19257
19258   u32 sw_if_index = ~0;
19259   int ret;
19260   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19261     {
19262       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19263         ;
19264       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19265         ;
19266       else
19267         break;
19268     }
19269   if (sw_if_index == ~0)
19270     {
19271       errmsg ("missing interface name or sw_if_index");
19272       return -99;
19273     }
19274
19275   /* Construct the API message */
19276   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19277   mp->context = 0;
19278   mp->sw_if_index = ntohl (sw_if_index);
19279
19280   S (mp);
19281   W (ret);
19282   return ret;
19283 }
19284
19285 int
19286 api_classify_table_info (vat_main_t * vam)
19287 {
19288   unformat_input_t *input = vam->input;
19289   vl_api_classify_table_info_t *mp;
19290
19291   u32 table_id = ~0;
19292   int ret;
19293   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19294     {
19295       if (unformat (input, "table_id %d", &table_id))
19296         ;
19297       else
19298         break;
19299     }
19300   if (table_id == ~0)
19301     {
19302       errmsg ("missing table id");
19303       return -99;
19304     }
19305
19306   /* Construct the API message */
19307   M (CLASSIFY_TABLE_INFO, mp);
19308   mp->context = 0;
19309   mp->table_id = ntohl (table_id);
19310
19311   S (mp);
19312   W (ret);
19313   return ret;
19314 }
19315
19316 int
19317 api_classify_session_dump (vat_main_t * vam)
19318 {
19319   unformat_input_t *input = vam->input;
19320   vl_api_classify_session_dump_t *mp;
19321   vl_api_control_ping_t *mp_ping;
19322
19323   u32 table_id = ~0;
19324   int ret;
19325   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19326     {
19327       if (unformat (input, "table_id %d", &table_id))
19328         ;
19329       else
19330         break;
19331     }
19332   if (table_id == ~0)
19333     {
19334       errmsg ("missing table id");
19335       return -99;
19336     }
19337
19338   /* Construct the API message */
19339   M (CLASSIFY_SESSION_DUMP, mp);
19340   mp->context = 0;
19341   mp->table_id = ntohl (table_id);
19342   S (mp);
19343
19344   /* Use a control ping for synchronization */
19345   MPING (CONTROL_PING, mp_ping);
19346   S (mp_ping);
19347
19348   W (ret);
19349   return ret;
19350 }
19351
19352 static void
19353 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19354 {
19355   vat_main_t *vam = &vat_main;
19356
19357   print (vam->ofp, "collector_address %U, collector_port %d, "
19358          "src_address %U, vrf_id %d, path_mtu %u, "
19359          "template_interval %u, udp_checksum %d",
19360          format_ip4_address, mp->collector_address,
19361          ntohs (mp->collector_port),
19362          format_ip4_address, mp->src_address,
19363          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19364          ntohl (mp->template_interval), mp->udp_checksum);
19365
19366   vam->retval = 0;
19367   vam->result_ready = 1;
19368 }
19369
19370 static void
19371   vl_api_ipfix_exporter_details_t_handler_json
19372   (vl_api_ipfix_exporter_details_t * mp)
19373 {
19374   vat_main_t *vam = &vat_main;
19375   vat_json_node_t node;
19376   struct in_addr collector_address;
19377   struct in_addr src_address;
19378
19379   vat_json_init_object (&node);
19380   clib_memcpy (&collector_address, &mp->collector_address,
19381                sizeof (collector_address));
19382   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19383   vat_json_object_add_uint (&node, "collector_port",
19384                             ntohs (mp->collector_port));
19385   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19386   vat_json_object_add_ip4 (&node, "src_address", src_address);
19387   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19388   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19389   vat_json_object_add_uint (&node, "template_interval",
19390                             ntohl (mp->template_interval));
19391   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19392
19393   vat_json_print (vam->ofp, &node);
19394   vat_json_free (&node);
19395   vam->retval = 0;
19396   vam->result_ready = 1;
19397 }
19398
19399 int
19400 api_ipfix_exporter_dump (vat_main_t * vam)
19401 {
19402   vl_api_ipfix_exporter_dump_t *mp;
19403   int ret;
19404
19405   /* Construct the API message */
19406   M (IPFIX_EXPORTER_DUMP, mp);
19407   mp->context = 0;
19408
19409   S (mp);
19410   W (ret);
19411   return ret;
19412 }
19413
19414 static int
19415 api_ipfix_classify_stream_dump (vat_main_t * vam)
19416 {
19417   vl_api_ipfix_classify_stream_dump_t *mp;
19418   int ret;
19419
19420   /* Construct the API message */
19421   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19422   mp->context = 0;
19423
19424   S (mp);
19425   W (ret);
19426   return ret;
19427   /* NOTREACHED */
19428   return 0;
19429 }
19430
19431 static void
19432   vl_api_ipfix_classify_stream_details_t_handler
19433   (vl_api_ipfix_classify_stream_details_t * mp)
19434 {
19435   vat_main_t *vam = &vat_main;
19436   print (vam->ofp, "domain_id %d, src_port %d",
19437          ntohl (mp->domain_id), ntohs (mp->src_port));
19438   vam->retval = 0;
19439   vam->result_ready = 1;
19440 }
19441
19442 static void
19443   vl_api_ipfix_classify_stream_details_t_handler_json
19444   (vl_api_ipfix_classify_stream_details_t * mp)
19445 {
19446   vat_main_t *vam = &vat_main;
19447   vat_json_node_t node;
19448
19449   vat_json_init_object (&node);
19450   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19451   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19452
19453   vat_json_print (vam->ofp, &node);
19454   vat_json_free (&node);
19455   vam->retval = 0;
19456   vam->result_ready = 1;
19457 }
19458
19459 static int
19460 api_ipfix_classify_table_dump (vat_main_t * vam)
19461 {
19462   vl_api_ipfix_classify_table_dump_t *mp;
19463   vl_api_control_ping_t *mp_ping;
19464   int ret;
19465
19466   if (!vam->json_output)
19467     {
19468       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19469              "transport_protocol");
19470     }
19471
19472   /* Construct the API message */
19473   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19474
19475   /* send it... */
19476   S (mp);
19477
19478   /* Use a control ping for synchronization */
19479   MPING (CONTROL_PING, mp_ping);
19480   S (mp_ping);
19481
19482   W (ret);
19483   return ret;
19484 }
19485
19486 static void
19487   vl_api_ipfix_classify_table_details_t_handler
19488   (vl_api_ipfix_classify_table_details_t * mp)
19489 {
19490   vat_main_t *vam = &vat_main;
19491   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19492          mp->transport_protocol);
19493 }
19494
19495 static void
19496   vl_api_ipfix_classify_table_details_t_handler_json
19497   (vl_api_ipfix_classify_table_details_t * mp)
19498 {
19499   vat_json_node_t *node = NULL;
19500   vat_main_t *vam = &vat_main;
19501
19502   if (VAT_JSON_ARRAY != vam->json_tree.type)
19503     {
19504       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19505       vat_json_init_array (&vam->json_tree);
19506     }
19507
19508   node = vat_json_array_add (&vam->json_tree);
19509   vat_json_init_object (node);
19510
19511   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19512   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19513   vat_json_object_add_uint (node, "transport_protocol",
19514                             mp->transport_protocol);
19515 }
19516
19517 static int
19518 api_sw_interface_span_enable_disable (vat_main_t * vam)
19519 {
19520   unformat_input_t *i = vam->input;
19521   vl_api_sw_interface_span_enable_disable_t *mp;
19522   u32 src_sw_if_index = ~0;
19523   u32 dst_sw_if_index = ~0;
19524   u8 state = 3;
19525   int ret;
19526   u8 is_l2 = 0;
19527
19528   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19529     {
19530       if (unformat
19531           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19532         ;
19533       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19534         ;
19535       else
19536         if (unformat
19537             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19538         ;
19539       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19540         ;
19541       else if (unformat (i, "disable"))
19542         state = 0;
19543       else if (unformat (i, "rx"))
19544         state = 1;
19545       else if (unformat (i, "tx"))
19546         state = 2;
19547       else if (unformat (i, "both"))
19548         state = 3;
19549       else if (unformat (i, "l2"))
19550         is_l2 = 1;
19551       else
19552         break;
19553     }
19554
19555   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19556
19557   mp->sw_if_index_from = htonl (src_sw_if_index);
19558   mp->sw_if_index_to = htonl (dst_sw_if_index);
19559   mp->state = state;
19560   mp->is_l2 = is_l2;
19561
19562   S (mp);
19563   W (ret);
19564   return ret;
19565 }
19566
19567 static void
19568 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19569                                             * mp)
19570 {
19571   vat_main_t *vam = &vat_main;
19572   u8 *sw_if_from_name = 0;
19573   u8 *sw_if_to_name = 0;
19574   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19575   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19576   char *states[] = { "none", "rx", "tx", "both" };
19577   hash_pair_t *p;
19578
19579   /* *INDENT-OFF* */
19580   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19581   ({
19582     if ((u32) p->value[0] == sw_if_index_from)
19583       {
19584         sw_if_from_name = (u8 *)(p->key);
19585         if (sw_if_to_name)
19586           break;
19587       }
19588     if ((u32) p->value[0] == sw_if_index_to)
19589       {
19590         sw_if_to_name = (u8 *)(p->key);
19591         if (sw_if_from_name)
19592           break;
19593       }
19594   }));
19595   /* *INDENT-ON* */
19596   print (vam->ofp, "%20s => %20s (%s)",
19597          sw_if_from_name, sw_if_to_name, states[mp->state]);
19598 }
19599
19600 static void
19601   vl_api_sw_interface_span_details_t_handler_json
19602   (vl_api_sw_interface_span_details_t * mp)
19603 {
19604   vat_main_t *vam = &vat_main;
19605   vat_json_node_t *node = NULL;
19606   u8 *sw_if_from_name = 0;
19607   u8 *sw_if_to_name = 0;
19608   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19609   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19610   hash_pair_t *p;
19611
19612   /* *INDENT-OFF* */
19613   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19614   ({
19615     if ((u32) p->value[0] == sw_if_index_from)
19616       {
19617         sw_if_from_name = (u8 *)(p->key);
19618         if (sw_if_to_name)
19619           break;
19620       }
19621     if ((u32) p->value[0] == sw_if_index_to)
19622       {
19623         sw_if_to_name = (u8 *)(p->key);
19624         if (sw_if_from_name)
19625           break;
19626       }
19627   }));
19628   /* *INDENT-ON* */
19629
19630   if (VAT_JSON_ARRAY != vam->json_tree.type)
19631     {
19632       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19633       vat_json_init_array (&vam->json_tree);
19634     }
19635   node = vat_json_array_add (&vam->json_tree);
19636
19637   vat_json_init_object (node);
19638   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19639   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19640   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19641   if (0 != sw_if_to_name)
19642     {
19643       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19644     }
19645   vat_json_object_add_uint (node, "state", mp->state);
19646 }
19647
19648 static int
19649 api_sw_interface_span_dump (vat_main_t * vam)
19650 {
19651   unformat_input_t *input = vam->input;
19652   vl_api_sw_interface_span_dump_t *mp;
19653   vl_api_control_ping_t *mp_ping;
19654   u8 is_l2 = 0;
19655   int ret;
19656
19657   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19658     {
19659       if (unformat (input, "l2"))
19660         is_l2 = 1;
19661       else
19662         break;
19663     }
19664
19665   M (SW_INTERFACE_SPAN_DUMP, mp);
19666   mp->is_l2 = is_l2;
19667   S (mp);
19668
19669   /* Use a control ping for synchronization */
19670   MPING (CONTROL_PING, mp_ping);
19671   S (mp_ping);
19672
19673   W (ret);
19674   return ret;
19675 }
19676
19677 int
19678 api_pg_create_interface (vat_main_t * vam)
19679 {
19680   unformat_input_t *input = vam->input;
19681   vl_api_pg_create_interface_t *mp;
19682
19683   u32 if_id = ~0;
19684   int ret;
19685   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19686     {
19687       if (unformat (input, "if_id %d", &if_id))
19688         ;
19689       else
19690         break;
19691     }
19692   if (if_id == ~0)
19693     {
19694       errmsg ("missing pg interface index");
19695       return -99;
19696     }
19697
19698   /* Construct the API message */
19699   M (PG_CREATE_INTERFACE, mp);
19700   mp->context = 0;
19701   mp->interface_id = ntohl (if_id);
19702
19703   S (mp);
19704   W (ret);
19705   return ret;
19706 }
19707
19708 int
19709 api_pg_capture (vat_main_t * vam)
19710 {
19711   unformat_input_t *input = vam->input;
19712   vl_api_pg_capture_t *mp;
19713
19714   u32 if_id = ~0;
19715   u8 enable = 1;
19716   u32 count = 1;
19717   u8 pcap_file_set = 0;
19718   u8 *pcap_file = 0;
19719   int ret;
19720   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19721     {
19722       if (unformat (input, "if_id %d", &if_id))
19723         ;
19724       else if (unformat (input, "pcap %s", &pcap_file))
19725         pcap_file_set = 1;
19726       else if (unformat (input, "count %d", &count))
19727         ;
19728       else if (unformat (input, "disable"))
19729         enable = 0;
19730       else
19731         break;
19732     }
19733   if (if_id == ~0)
19734     {
19735       errmsg ("missing pg interface index");
19736       return -99;
19737     }
19738   if (pcap_file_set > 0)
19739     {
19740       if (vec_len (pcap_file) > 255)
19741         {
19742           errmsg ("pcap file name is too long");
19743           return -99;
19744         }
19745     }
19746
19747   u32 name_len = vec_len (pcap_file);
19748   /* Construct the API message */
19749   M (PG_CAPTURE, mp);
19750   mp->context = 0;
19751   mp->interface_id = ntohl (if_id);
19752   mp->is_enabled = enable;
19753   mp->count = ntohl (count);
19754   mp->pcap_name_length = ntohl (name_len);
19755   if (pcap_file_set != 0)
19756     {
19757       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19758     }
19759   vec_free (pcap_file);
19760
19761   S (mp);
19762   W (ret);
19763   return ret;
19764 }
19765
19766 int
19767 api_pg_enable_disable (vat_main_t * vam)
19768 {
19769   unformat_input_t *input = vam->input;
19770   vl_api_pg_enable_disable_t *mp;
19771
19772   u8 enable = 1;
19773   u8 stream_name_set = 0;
19774   u8 *stream_name = 0;
19775   int ret;
19776   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19777     {
19778       if (unformat (input, "stream %s", &stream_name))
19779         stream_name_set = 1;
19780       else if (unformat (input, "disable"))
19781         enable = 0;
19782       else
19783         break;
19784     }
19785
19786   if (stream_name_set > 0)
19787     {
19788       if (vec_len (stream_name) > 255)
19789         {
19790           errmsg ("stream name too long");
19791           return -99;
19792         }
19793     }
19794
19795   u32 name_len = vec_len (stream_name);
19796   /* Construct the API message */
19797   M (PG_ENABLE_DISABLE, mp);
19798   mp->context = 0;
19799   mp->is_enabled = enable;
19800   if (stream_name_set != 0)
19801     {
19802       mp->stream_name_length = ntohl (name_len);
19803       clib_memcpy (mp->stream_name, stream_name, name_len);
19804     }
19805   vec_free (stream_name);
19806
19807   S (mp);
19808   W (ret);
19809   return ret;
19810 }
19811
19812 int
19813 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19814 {
19815   unformat_input_t *input = vam->input;
19816   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19817
19818   u16 *low_ports = 0;
19819   u16 *high_ports = 0;
19820   u16 this_low;
19821   u16 this_hi;
19822   ip4_address_t ip4_addr;
19823   ip6_address_t ip6_addr;
19824   u32 length;
19825   u32 tmp, tmp2;
19826   u8 prefix_set = 0;
19827   u32 vrf_id = ~0;
19828   u8 is_add = 1;
19829   u8 is_ipv6 = 0;
19830   int ret;
19831
19832   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19833     {
19834       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
19835         {
19836           prefix_set = 1;
19837         }
19838       else
19839         if (unformat
19840             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
19841         {
19842           prefix_set = 1;
19843           is_ipv6 = 1;
19844         }
19845       else if (unformat (input, "vrf %d", &vrf_id))
19846         ;
19847       else if (unformat (input, "del"))
19848         is_add = 0;
19849       else if (unformat (input, "port %d", &tmp))
19850         {
19851           if (tmp == 0 || tmp > 65535)
19852             {
19853               errmsg ("port %d out of range", tmp);
19854               return -99;
19855             }
19856           this_low = tmp;
19857           this_hi = this_low + 1;
19858           vec_add1 (low_ports, this_low);
19859           vec_add1 (high_ports, this_hi);
19860         }
19861       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19862         {
19863           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19864             {
19865               errmsg ("incorrect range parameters");
19866               return -99;
19867             }
19868           this_low = tmp;
19869           /* Note: in debug CLI +1 is added to high before
19870              passing to real fn that does "the work"
19871              (ip_source_and_port_range_check_add_del).
19872              This fn is a wrapper around the binary API fn a
19873              control plane will call, which expects this increment
19874              to have occurred. Hence letting the binary API control
19875              plane fn do the increment for consistency between VAT
19876              and other control planes.
19877            */
19878           this_hi = tmp2;
19879           vec_add1 (low_ports, this_low);
19880           vec_add1 (high_ports, this_hi);
19881         }
19882       else
19883         break;
19884     }
19885
19886   if (prefix_set == 0)
19887     {
19888       errmsg ("<address>/<mask> not specified");
19889       return -99;
19890     }
19891
19892   if (vrf_id == ~0)
19893     {
19894       errmsg ("VRF ID required, not specified");
19895       return -99;
19896     }
19897
19898   if (vrf_id == 0)
19899     {
19900       errmsg
19901         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19902       return -99;
19903     }
19904
19905   if (vec_len (low_ports) == 0)
19906     {
19907       errmsg ("At least one port or port range required");
19908       return -99;
19909     }
19910
19911   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19912
19913   mp->is_add = is_add;
19914
19915   if (is_ipv6)
19916     {
19917       mp->is_ipv6 = 1;
19918       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
19919     }
19920   else
19921     {
19922       mp->is_ipv6 = 0;
19923       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
19924     }
19925
19926   mp->mask_length = length;
19927   mp->number_of_ranges = vec_len (low_ports);
19928
19929   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
19930   vec_free (low_ports);
19931
19932   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
19933   vec_free (high_ports);
19934
19935   mp->vrf_id = ntohl (vrf_id);
19936
19937   S (mp);
19938   W (ret);
19939   return ret;
19940 }
19941
19942 int
19943 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
19944 {
19945   unformat_input_t *input = vam->input;
19946   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
19947   u32 sw_if_index = ~0;
19948   int vrf_set = 0;
19949   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
19950   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
19951   u8 is_add = 1;
19952   int ret;
19953
19954   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19955     {
19956       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19957         ;
19958       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19959         ;
19960       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
19961         vrf_set = 1;
19962       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
19963         vrf_set = 1;
19964       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
19965         vrf_set = 1;
19966       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
19967         vrf_set = 1;
19968       else if (unformat (input, "del"))
19969         is_add = 0;
19970       else
19971         break;
19972     }
19973
19974   if (sw_if_index == ~0)
19975     {
19976       errmsg ("Interface required but not specified");
19977       return -99;
19978     }
19979
19980   if (vrf_set == 0)
19981     {
19982       errmsg ("VRF ID required but not specified");
19983       return -99;
19984     }
19985
19986   if (tcp_out_vrf_id == 0
19987       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
19988     {
19989       errmsg
19990         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19991       return -99;
19992     }
19993
19994   /* Construct the API message */
19995   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
19996
19997   mp->sw_if_index = ntohl (sw_if_index);
19998   mp->is_add = is_add;
19999   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
20000   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
20001   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
20002   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
20003
20004   /* send it... */
20005   S (mp);
20006
20007   /* Wait for a reply... */
20008   W (ret);
20009   return ret;
20010 }
20011
20012 static int
20013 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
20014 {
20015   unformat_input_t *i = vam->input;
20016   vl_api_ipsec_gre_add_del_tunnel_t *mp;
20017   u32 local_sa_id = 0;
20018   u32 remote_sa_id = 0;
20019   ip4_address_t src_address;
20020   ip4_address_t dst_address;
20021   u8 is_add = 1;
20022   int ret;
20023
20024   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20025     {
20026       if (unformat (i, "local_sa %d", &local_sa_id))
20027         ;
20028       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20029         ;
20030       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
20031         ;
20032       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
20033         ;
20034       else if (unformat (i, "del"))
20035         is_add = 0;
20036       else
20037         {
20038           clib_warning ("parse error '%U'", format_unformat_error, i);
20039           return -99;
20040         }
20041     }
20042
20043   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
20044
20045   mp->local_sa_id = ntohl (local_sa_id);
20046   mp->remote_sa_id = ntohl (remote_sa_id);
20047   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
20048   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
20049   mp->is_add = is_add;
20050
20051   S (mp);
20052   W (ret);
20053   return ret;
20054 }
20055
20056 static int
20057 api_punt (vat_main_t * vam)
20058 {
20059   unformat_input_t *i = vam->input;
20060   vl_api_punt_t *mp;
20061   u32 ipv = ~0;
20062   u32 protocol = ~0;
20063   u32 port = ~0;
20064   int is_add = 1;
20065   int ret;
20066
20067   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20068     {
20069       if (unformat (i, "ip %d", &ipv))
20070         ;
20071       else if (unformat (i, "protocol %d", &protocol))
20072         ;
20073       else if (unformat (i, "port %d", &port))
20074         ;
20075       else if (unformat (i, "del"))
20076         is_add = 0;
20077       else
20078         {
20079           clib_warning ("parse error '%U'", format_unformat_error, i);
20080           return -99;
20081         }
20082     }
20083
20084   M (PUNT, mp);
20085
20086   mp->is_add = (u8) is_add;
20087   mp->ipv = (u8) ipv;
20088   mp->l4_protocol = (u8) protocol;
20089   mp->l4_port = htons ((u16) port);
20090
20091   S (mp);
20092   W (ret);
20093   return ret;
20094 }
20095
20096 static void vl_api_ipsec_gre_tunnel_details_t_handler
20097   (vl_api_ipsec_gre_tunnel_details_t * mp)
20098 {
20099   vat_main_t *vam = &vat_main;
20100
20101   print (vam->ofp, "%11d%15U%15U%14d%14d",
20102          ntohl (mp->sw_if_index),
20103          format_ip4_address, &mp->src_address,
20104          format_ip4_address, &mp->dst_address,
20105          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
20106 }
20107
20108 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
20109   (vl_api_ipsec_gre_tunnel_details_t * mp)
20110 {
20111   vat_main_t *vam = &vat_main;
20112   vat_json_node_t *node = NULL;
20113   struct in_addr ip4;
20114
20115   if (VAT_JSON_ARRAY != vam->json_tree.type)
20116     {
20117       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20118       vat_json_init_array (&vam->json_tree);
20119     }
20120   node = vat_json_array_add (&vam->json_tree);
20121
20122   vat_json_init_object (node);
20123   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
20124   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
20125   vat_json_object_add_ip4 (node, "src_address", ip4);
20126   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
20127   vat_json_object_add_ip4 (node, "dst_address", ip4);
20128   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
20129   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
20130 }
20131
20132 static int
20133 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
20134 {
20135   unformat_input_t *i = vam->input;
20136   vl_api_ipsec_gre_tunnel_dump_t *mp;
20137   vl_api_control_ping_t *mp_ping;
20138   u32 sw_if_index;
20139   u8 sw_if_index_set = 0;
20140   int ret;
20141
20142   /* Parse args required to build the message */
20143   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20144     {
20145       if (unformat (i, "sw_if_index %d", &sw_if_index))
20146         sw_if_index_set = 1;
20147       else
20148         break;
20149     }
20150
20151   if (sw_if_index_set == 0)
20152     {
20153       sw_if_index = ~0;
20154     }
20155
20156   if (!vam->json_output)
20157     {
20158       print (vam->ofp, "%11s%15s%15s%14s%14s",
20159              "sw_if_index", "src_address", "dst_address",
20160              "local_sa_id", "remote_sa_id");
20161     }
20162
20163   /* Get list of gre-tunnel interfaces */
20164   M (IPSEC_GRE_TUNNEL_DUMP, mp);
20165
20166   mp->sw_if_index = htonl (sw_if_index);
20167
20168   S (mp);
20169
20170   /* Use a control ping for synchronization */
20171   MPING (CONTROL_PING, mp_ping);
20172   S (mp_ping);
20173
20174   W (ret);
20175   return ret;
20176 }
20177
20178 static int
20179 api_delete_subif (vat_main_t * vam)
20180 {
20181   unformat_input_t *i = vam->input;
20182   vl_api_delete_subif_t *mp;
20183   u32 sw_if_index = ~0;
20184   int ret;
20185
20186   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20187     {
20188       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20189         ;
20190       if (unformat (i, "sw_if_index %d", &sw_if_index))
20191         ;
20192       else
20193         break;
20194     }
20195
20196   if (sw_if_index == ~0)
20197     {
20198       errmsg ("missing sw_if_index");
20199       return -99;
20200     }
20201
20202   /* Construct the API message */
20203   M (DELETE_SUBIF, mp);
20204   mp->sw_if_index = ntohl (sw_if_index);
20205
20206   S (mp);
20207   W (ret);
20208   return ret;
20209 }
20210
20211 #define foreach_pbb_vtr_op      \
20212 _("disable",  L2_VTR_DISABLED)  \
20213 _("pop",  L2_VTR_POP_2)         \
20214 _("push",  L2_VTR_PUSH_2)
20215
20216 static int
20217 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20218 {
20219   unformat_input_t *i = vam->input;
20220   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20221   u32 sw_if_index = ~0, vtr_op = ~0;
20222   u16 outer_tag = ~0;
20223   u8 dmac[6], smac[6];
20224   u8 dmac_set = 0, smac_set = 0;
20225   u16 vlanid = 0;
20226   u32 sid = ~0;
20227   u32 tmp;
20228   int ret;
20229
20230   /* Shut up coverity */
20231   memset (dmac, 0, sizeof (dmac));
20232   memset (smac, 0, sizeof (smac));
20233
20234   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20235     {
20236       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20237         ;
20238       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20239         ;
20240       else if (unformat (i, "vtr_op %d", &vtr_op))
20241         ;
20242 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20243       foreach_pbb_vtr_op
20244 #undef _
20245         else if (unformat (i, "translate_pbb_stag"))
20246         {
20247           if (unformat (i, "%d", &tmp))
20248             {
20249               vtr_op = L2_VTR_TRANSLATE_2_1;
20250               outer_tag = tmp;
20251             }
20252           else
20253             {
20254               errmsg
20255                 ("translate_pbb_stag operation requires outer tag definition");
20256               return -99;
20257             }
20258         }
20259       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20260         dmac_set++;
20261       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20262         smac_set++;
20263       else if (unformat (i, "sid %d", &sid))
20264         ;
20265       else if (unformat (i, "vlanid %d", &tmp))
20266         vlanid = tmp;
20267       else
20268         {
20269           clib_warning ("parse error '%U'", format_unformat_error, i);
20270           return -99;
20271         }
20272     }
20273
20274   if ((sw_if_index == ~0) || (vtr_op == ~0))
20275     {
20276       errmsg ("missing sw_if_index or vtr operation");
20277       return -99;
20278     }
20279   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20280       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20281     {
20282       errmsg
20283         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20284       return -99;
20285     }
20286
20287   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20288   mp->sw_if_index = ntohl (sw_if_index);
20289   mp->vtr_op = ntohl (vtr_op);
20290   mp->outer_tag = ntohs (outer_tag);
20291   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20292   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20293   mp->b_vlanid = ntohs (vlanid);
20294   mp->i_sid = ntohl (sid);
20295
20296   S (mp);
20297   W (ret);
20298   return ret;
20299 }
20300
20301 static int
20302 api_flow_classify_set_interface (vat_main_t * vam)
20303 {
20304   unformat_input_t *i = vam->input;
20305   vl_api_flow_classify_set_interface_t *mp;
20306   u32 sw_if_index;
20307   int sw_if_index_set;
20308   u32 ip4_table_index = ~0;
20309   u32 ip6_table_index = ~0;
20310   u8 is_add = 1;
20311   int ret;
20312
20313   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20314     {
20315       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20316         sw_if_index_set = 1;
20317       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20318         sw_if_index_set = 1;
20319       else if (unformat (i, "del"))
20320         is_add = 0;
20321       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20322         ;
20323       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20324         ;
20325       else
20326         {
20327           clib_warning ("parse error '%U'", format_unformat_error, i);
20328           return -99;
20329         }
20330     }
20331
20332   if (sw_if_index_set == 0)
20333     {
20334       errmsg ("missing interface name or sw_if_index");
20335       return -99;
20336     }
20337
20338   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20339
20340   mp->sw_if_index = ntohl (sw_if_index);
20341   mp->ip4_table_index = ntohl (ip4_table_index);
20342   mp->ip6_table_index = ntohl (ip6_table_index);
20343   mp->is_add = is_add;
20344
20345   S (mp);
20346   W (ret);
20347   return ret;
20348 }
20349
20350 static int
20351 api_flow_classify_dump (vat_main_t * vam)
20352 {
20353   unformat_input_t *i = vam->input;
20354   vl_api_flow_classify_dump_t *mp;
20355   vl_api_control_ping_t *mp_ping;
20356   u8 type = FLOW_CLASSIFY_N_TABLES;
20357   int ret;
20358
20359   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20360     ;
20361   else
20362     {
20363       errmsg ("classify table type must be specified");
20364       return -99;
20365     }
20366
20367   if (!vam->json_output)
20368     {
20369       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20370     }
20371
20372   M (FLOW_CLASSIFY_DUMP, mp);
20373   mp->type = type;
20374   /* send it... */
20375   S (mp);
20376
20377   /* Use a control ping for synchronization */
20378   MPING (CONTROL_PING, mp_ping);
20379   S (mp_ping);
20380
20381   /* Wait for a reply... */
20382   W (ret);
20383   return ret;
20384 }
20385
20386 static int
20387 api_feature_enable_disable (vat_main_t * vam)
20388 {
20389   unformat_input_t *i = vam->input;
20390   vl_api_feature_enable_disable_t *mp;
20391   u8 *arc_name = 0;
20392   u8 *feature_name = 0;
20393   u32 sw_if_index = ~0;
20394   u8 enable = 1;
20395   int ret;
20396
20397   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20398     {
20399       if (unformat (i, "arc_name %s", &arc_name))
20400         ;
20401       else if (unformat (i, "feature_name %s", &feature_name))
20402         ;
20403       else
20404         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20405         ;
20406       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20407         ;
20408       else if (unformat (i, "disable"))
20409         enable = 0;
20410       else
20411         break;
20412     }
20413
20414   if (arc_name == 0)
20415     {
20416       errmsg ("missing arc name");
20417       return -99;
20418     }
20419   if (vec_len (arc_name) > 63)
20420     {
20421       errmsg ("arc name too long");
20422     }
20423
20424   if (feature_name == 0)
20425     {
20426       errmsg ("missing feature name");
20427       return -99;
20428     }
20429   if (vec_len (feature_name) > 63)
20430     {
20431       errmsg ("feature name too long");
20432     }
20433
20434   if (sw_if_index == ~0)
20435     {
20436       errmsg ("missing interface name or sw_if_index");
20437       return -99;
20438     }
20439
20440   /* Construct the API message */
20441   M (FEATURE_ENABLE_DISABLE, mp);
20442   mp->sw_if_index = ntohl (sw_if_index);
20443   mp->enable = enable;
20444   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20445   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20446   vec_free (arc_name);
20447   vec_free (feature_name);
20448
20449   S (mp);
20450   W (ret);
20451   return ret;
20452 }
20453
20454 static int
20455 api_sw_interface_tag_add_del (vat_main_t * vam)
20456 {
20457   unformat_input_t *i = vam->input;
20458   vl_api_sw_interface_tag_add_del_t *mp;
20459   u32 sw_if_index = ~0;
20460   u8 *tag = 0;
20461   u8 enable = 1;
20462   int ret;
20463
20464   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20465     {
20466       if (unformat (i, "tag %s", &tag))
20467         ;
20468       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20469         ;
20470       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20471         ;
20472       else if (unformat (i, "del"))
20473         enable = 0;
20474       else
20475         break;
20476     }
20477
20478   if (sw_if_index == ~0)
20479     {
20480       errmsg ("missing interface name or sw_if_index");
20481       return -99;
20482     }
20483
20484   if (enable && (tag == 0))
20485     {
20486       errmsg ("no tag specified");
20487       return -99;
20488     }
20489
20490   /* Construct the API message */
20491   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20492   mp->sw_if_index = ntohl (sw_if_index);
20493   mp->is_add = enable;
20494   if (enable)
20495     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20496   vec_free (tag);
20497
20498   S (mp);
20499   W (ret);
20500   return ret;
20501 }
20502
20503 static void vl_api_l2_xconnect_details_t_handler
20504   (vl_api_l2_xconnect_details_t * mp)
20505 {
20506   vat_main_t *vam = &vat_main;
20507
20508   print (vam->ofp, "%15d%15d",
20509          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20510 }
20511
20512 static void vl_api_l2_xconnect_details_t_handler_json
20513   (vl_api_l2_xconnect_details_t * mp)
20514 {
20515   vat_main_t *vam = &vat_main;
20516   vat_json_node_t *node = NULL;
20517
20518   if (VAT_JSON_ARRAY != vam->json_tree.type)
20519     {
20520       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20521       vat_json_init_array (&vam->json_tree);
20522     }
20523   node = vat_json_array_add (&vam->json_tree);
20524
20525   vat_json_init_object (node);
20526   vat_json_object_add_uint (node, "rx_sw_if_index",
20527                             ntohl (mp->rx_sw_if_index));
20528   vat_json_object_add_uint (node, "tx_sw_if_index",
20529                             ntohl (mp->tx_sw_if_index));
20530 }
20531
20532 static int
20533 api_l2_xconnect_dump (vat_main_t * vam)
20534 {
20535   vl_api_l2_xconnect_dump_t *mp;
20536   vl_api_control_ping_t *mp_ping;
20537   int ret;
20538
20539   if (!vam->json_output)
20540     {
20541       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20542     }
20543
20544   M (L2_XCONNECT_DUMP, mp);
20545
20546   S (mp);
20547
20548   /* Use a control ping for synchronization */
20549   MPING (CONTROL_PING, mp_ping);
20550   S (mp_ping);
20551
20552   W (ret);
20553   return ret;
20554 }
20555
20556 static int
20557 api_sw_interface_set_mtu (vat_main_t * vam)
20558 {
20559   unformat_input_t *i = vam->input;
20560   vl_api_sw_interface_set_mtu_t *mp;
20561   u32 sw_if_index = ~0;
20562   u32 mtu = 0;
20563   int ret;
20564
20565   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20566     {
20567       if (unformat (i, "mtu %d", &mtu))
20568         ;
20569       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20570         ;
20571       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20572         ;
20573       else
20574         break;
20575     }
20576
20577   if (sw_if_index == ~0)
20578     {
20579       errmsg ("missing interface name or sw_if_index");
20580       return -99;
20581     }
20582
20583   if (mtu == 0)
20584     {
20585       errmsg ("no mtu specified");
20586       return -99;
20587     }
20588
20589   /* Construct the API message */
20590   M (SW_INTERFACE_SET_MTU, mp);
20591   mp->sw_if_index = ntohl (sw_if_index);
20592   mp->mtu = ntohs ((u16) mtu);
20593
20594   S (mp);
20595   W (ret);
20596   return ret;
20597 }
20598
20599 static int
20600 api_p2p_ethernet_add (vat_main_t * vam)
20601 {
20602   unformat_input_t *i = vam->input;
20603   vl_api_p2p_ethernet_add_t *mp;
20604   u32 parent_if_index = ~0;
20605   u32 sub_id = ~0;
20606   u8 remote_mac[6];
20607   u8 mac_set = 0;
20608   int ret;
20609
20610   memset (remote_mac, 0, sizeof (remote_mac));
20611   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20612     {
20613       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20614         ;
20615       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20616         ;
20617       else
20618         if (unformat
20619             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20620         mac_set++;
20621       else if (unformat (i, "sub_id %d", &sub_id))
20622         ;
20623       else
20624         {
20625           clib_warning ("parse error '%U'", format_unformat_error, i);
20626           return -99;
20627         }
20628     }
20629
20630   if (parent_if_index == ~0)
20631     {
20632       errmsg ("missing interface name or sw_if_index");
20633       return -99;
20634     }
20635   if (mac_set == 0)
20636     {
20637       errmsg ("missing remote mac address");
20638       return -99;
20639     }
20640   if (sub_id == ~0)
20641     {
20642       errmsg ("missing sub-interface id");
20643       return -99;
20644     }
20645
20646   M (P2P_ETHERNET_ADD, mp);
20647   mp->parent_if_index = ntohl (parent_if_index);
20648   mp->subif_id = ntohl (sub_id);
20649   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20650
20651   S (mp);
20652   W (ret);
20653   return ret;
20654 }
20655
20656 static int
20657 api_p2p_ethernet_del (vat_main_t * vam)
20658 {
20659   unformat_input_t *i = vam->input;
20660   vl_api_p2p_ethernet_del_t *mp;
20661   u32 parent_if_index = ~0;
20662   u8 remote_mac[6];
20663   u8 mac_set = 0;
20664   int ret;
20665
20666   memset (remote_mac, 0, sizeof (remote_mac));
20667   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20668     {
20669       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20670         ;
20671       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20672         ;
20673       else
20674         if (unformat
20675             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20676         mac_set++;
20677       else
20678         {
20679           clib_warning ("parse error '%U'", format_unformat_error, i);
20680           return -99;
20681         }
20682     }
20683
20684   if (parent_if_index == ~0)
20685     {
20686       errmsg ("missing interface name or sw_if_index");
20687       return -99;
20688     }
20689   if (mac_set == 0)
20690     {
20691       errmsg ("missing remote mac address");
20692       return -99;
20693     }
20694
20695   M (P2P_ETHERNET_DEL, mp);
20696   mp->parent_if_index = ntohl (parent_if_index);
20697   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20698
20699   S (mp);
20700   W (ret);
20701   return ret;
20702 }
20703
20704 static int
20705 api_lldp_config (vat_main_t * vam)
20706 {
20707   unformat_input_t *i = vam->input;
20708   vl_api_lldp_config_t *mp;
20709   int tx_hold = 0;
20710   int tx_interval = 0;
20711   u8 *sys_name = NULL;
20712   int ret;
20713
20714   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20715     {
20716       if (unformat (i, "system-name %s", &sys_name))
20717         ;
20718       else if (unformat (i, "tx-hold %d", &tx_hold))
20719         ;
20720       else if (unformat (i, "tx-interval %d", &tx_interval))
20721         ;
20722       else
20723         {
20724           clib_warning ("parse error '%U'", format_unformat_error, i);
20725           return -99;
20726         }
20727     }
20728
20729   vec_add1 (sys_name, 0);
20730
20731   M (LLDP_CONFIG, mp);
20732   mp->tx_hold = htonl (tx_hold);
20733   mp->tx_interval = htonl (tx_interval);
20734   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20735   vec_free (sys_name);
20736
20737   S (mp);
20738   W (ret);
20739   return ret;
20740 }
20741
20742 static int
20743 api_sw_interface_set_lldp (vat_main_t * vam)
20744 {
20745   unformat_input_t *i = vam->input;
20746   vl_api_sw_interface_set_lldp_t *mp;
20747   u32 sw_if_index = ~0;
20748   u32 enable = 1;
20749   u8 *port_desc = NULL, *mgmt_oid = NULL;
20750   ip4_address_t ip4_addr;
20751   ip6_address_t ip6_addr;
20752   int ret;
20753
20754   memset (&ip4_addr, 0, sizeof (ip4_addr));
20755   memset (&ip6_addr, 0, sizeof (ip6_addr));
20756
20757   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20758     {
20759       if (unformat (i, "disable"))
20760         enable = 0;
20761       else
20762         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20763         ;
20764       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20765         ;
20766       else if (unformat (i, "port-desc %s", &port_desc))
20767         ;
20768       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20769         ;
20770       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20771         ;
20772       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20773         ;
20774       else
20775         break;
20776     }
20777
20778   if (sw_if_index == ~0)
20779     {
20780       errmsg ("missing interface name or sw_if_index");
20781       return -99;
20782     }
20783
20784   /* Construct the API message */
20785   vec_add1 (port_desc, 0);
20786   vec_add1 (mgmt_oid, 0);
20787   M (SW_INTERFACE_SET_LLDP, mp);
20788   mp->sw_if_index = ntohl (sw_if_index);
20789   mp->enable = enable;
20790   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20791   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20792   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20793   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20794   vec_free (port_desc);
20795   vec_free (mgmt_oid);
20796
20797   S (mp);
20798   W (ret);
20799   return ret;
20800 }
20801
20802 static int
20803 api_tcp_configure_src_addresses (vat_main_t * vam)
20804 {
20805   vl_api_tcp_configure_src_addresses_t *mp;
20806   unformat_input_t *i = vam->input;
20807   ip4_address_t v4first, v4last;
20808   ip6_address_t v6first, v6last;
20809   u8 range_set = 0;
20810   u32 vrf_id = 0;
20811   int ret;
20812
20813   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20814     {
20815       if (unformat (i, "%U - %U",
20816                     unformat_ip4_address, &v4first,
20817                     unformat_ip4_address, &v4last))
20818         {
20819           if (range_set)
20820             {
20821               errmsg ("one range per message (range already set)");
20822               return -99;
20823             }
20824           range_set = 1;
20825         }
20826       else if (unformat (i, "%U - %U",
20827                          unformat_ip6_address, &v6first,
20828                          unformat_ip6_address, &v6last))
20829         {
20830           if (range_set)
20831             {
20832               errmsg ("one range per message (range already set)");
20833               return -99;
20834             }
20835           range_set = 2;
20836         }
20837       else if (unformat (i, "vrf %d", &vrf_id))
20838         ;
20839       else
20840         break;
20841     }
20842
20843   if (range_set == 0)
20844     {
20845       errmsg ("address range not set");
20846       return -99;
20847     }
20848
20849   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20850   mp->vrf_id = ntohl (vrf_id);
20851   /* ipv6? */
20852   if (range_set == 2)
20853     {
20854       mp->is_ipv6 = 1;
20855       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20856       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20857     }
20858   else
20859     {
20860       mp->is_ipv6 = 0;
20861       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20862       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20863     }
20864   S (mp);
20865   W (ret);
20866   return ret;
20867 }
20868
20869 static int
20870 api_app_namespace_add_del (vat_main_t * vam)
20871 {
20872   vl_api_app_namespace_add_del_t *mp;
20873   unformat_input_t *i = vam->input;
20874   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
20875   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
20876   u64 secret;
20877   int ret;
20878
20879   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20880     {
20881       if (unformat (i, "id %_%v%_", &ns_id))
20882         ;
20883       else if (unformat (i, "secret %lu", &secret))
20884         secret_set = 1;
20885       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20886         sw_if_index_set = 1;
20887       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
20888         ;
20889       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
20890         ;
20891       else
20892         break;
20893     }
20894   if (!ns_id || !secret_set || !sw_if_index_set)
20895     {
20896       errmsg ("namespace id, secret and sw_if_index must be set");
20897       return -99;
20898     }
20899   if (vec_len (ns_id) > 64)
20900     {
20901       errmsg ("namespace id too long");
20902       return -99;
20903     }
20904   M (APP_NAMESPACE_ADD_DEL, mp);
20905
20906   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
20907   mp->namespace_id_len = vec_len (ns_id);
20908   mp->secret = secret;
20909   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20910   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
20911   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
20912   vec_free (ns_id);
20913   S (mp);
20914   W (ret);
20915   return ret;
20916 }
20917
20918 static int
20919 api_memfd_segment_create (vat_main_t * vam)
20920 {
20921   unformat_input_t *i = vam->input;
20922   vl_api_memfd_segment_create_t *mp;
20923   u64 size = 64 << 20;
20924   int ret;
20925
20926 #if VPP_API_TEST_BUILTIN == 1
20927   errmsg ("memfd_segment_create (builtin) not supported");
20928   return -99;
20929 #endif
20930
20931   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20932     {
20933       if (unformat (i, "size %U", unformat_memory_size, &size))
20934         ;
20935       else
20936         break;
20937     }
20938
20939   M (MEMFD_SEGMENT_CREATE, mp);
20940   mp->requested_size = size;
20941   S (mp);
20942   W (ret);
20943   return ret;
20944 }
20945
20946 static int
20947 api_dns_enable_disable (vat_main_t * vam)
20948 {
20949   unformat_input_t *line_input = vam->input;
20950   vl_api_dns_enable_disable_t *mp;
20951   u8 enable_disable = 1;
20952   int ret;
20953
20954   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20955     {
20956       if (unformat (line_input, "disable"))
20957         enable_disable = 0;
20958       if (unformat (line_input, "enable"))
20959         enable_disable = 1;
20960       else
20961         break;
20962     }
20963
20964   /* Construct the API message */
20965   M (DNS_ENABLE_DISABLE, mp);
20966   mp->enable = enable_disable;
20967
20968   /* send it... */
20969   S (mp);
20970   /* Wait for the reply */
20971   W (ret);
20972   return ret;
20973 }
20974
20975 static int
20976 api_dns_resolve_name (vat_main_t * vam)
20977 {
20978   unformat_input_t *line_input = vam->input;
20979   vl_api_dns_resolve_name_t *mp;
20980   u8 *name = 0;
20981   int ret;
20982
20983   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20984     {
20985       if (unformat (line_input, "%s", &name))
20986         ;
20987       else
20988         break;
20989     }
20990
20991   if (vec_len (name) > 127)
20992     {
20993       errmsg ("name too long");
20994       return -99;
20995     }
20996
20997   /* Construct the API message */
20998   M (DNS_RESOLVE_NAME, mp);
20999   memcpy (mp->name, name, vec_len (name));
21000   vec_free (name);
21001
21002   /* send it... */
21003   S (mp);
21004   /* Wait for the reply */
21005   W (ret);
21006   return ret;
21007 }
21008
21009 static int
21010 api_dns_name_server_add_del (vat_main_t * vam)
21011 {
21012   unformat_input_t *i = vam->input;
21013   vl_api_dns_name_server_add_del_t *mp;
21014   u8 is_add = 1;
21015   ip6_address_t ip6_server;
21016   ip4_address_t ip4_server;
21017   int ip6_set = 0;
21018   int ip4_set = 0;
21019   int ret = 0;
21020
21021   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21022     {
21023       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21024         ip6_set = 1;
21025       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21026         ip4_set = 1;
21027       else if (unformat (i, "del"))
21028         is_add = 0;
21029       else
21030         {
21031           clib_warning ("parse error '%U'", format_unformat_error, i);
21032           return -99;
21033         }
21034     }
21035
21036   if (ip4_set && ip6_set)
21037     {
21038       errmsg ("Only one server address allowed per message");
21039       return -99;
21040     }
21041   if ((ip4_set + ip6_set) == 0)
21042     {
21043       errmsg ("Server address required");
21044       return -99;
21045     }
21046
21047   /* Construct the API message */
21048   M (DNS_NAME_SERVER_ADD_DEL, mp);
21049
21050   if (ip6_set)
21051     {
21052       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21053       mp->is_ip6 = 1;
21054     }
21055   else
21056     {
21057       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21058       mp->is_ip6 = 0;
21059     }
21060
21061   mp->is_add = is_add;
21062
21063   /* send it... */
21064   S (mp);
21065
21066   /* Wait for a reply, return good/bad news  */
21067   W (ret);
21068   return ret;
21069 }
21070
21071
21072 static int
21073 q_or_quit (vat_main_t * vam)
21074 {
21075 #if VPP_API_TEST_BUILTIN == 0
21076   longjmp (vam->jump_buf, 1);
21077 #endif
21078   return 0;                     /* not so much */
21079 }
21080
21081 static int
21082 q (vat_main_t * vam)
21083 {
21084   return q_or_quit (vam);
21085 }
21086
21087 static int
21088 quit (vat_main_t * vam)
21089 {
21090   return q_or_quit (vam);
21091 }
21092
21093 static int
21094 comment (vat_main_t * vam)
21095 {
21096   return 0;
21097 }
21098
21099 static int
21100 cmd_cmp (void *a1, void *a2)
21101 {
21102   u8 **c1 = a1;
21103   u8 **c2 = a2;
21104
21105   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21106 }
21107
21108 static int
21109 help (vat_main_t * vam)
21110 {
21111   u8 **cmds = 0;
21112   u8 *name = 0;
21113   hash_pair_t *p;
21114   unformat_input_t *i = vam->input;
21115   int j;
21116
21117   if (unformat (i, "%s", &name))
21118     {
21119       uword *hs;
21120
21121       vec_add1 (name, 0);
21122
21123       hs = hash_get_mem (vam->help_by_name, name);
21124       if (hs)
21125         print (vam->ofp, "usage: %s %s", name, hs[0]);
21126       else
21127         print (vam->ofp, "No such msg / command '%s'", name);
21128       vec_free (name);
21129       return 0;
21130     }
21131
21132   print (vam->ofp, "Help is available for the following:");
21133
21134     /* *INDENT-OFF* */
21135     hash_foreach_pair (p, vam->function_by_name,
21136     ({
21137       vec_add1 (cmds, (u8 *)(p->key));
21138     }));
21139     /* *INDENT-ON* */
21140
21141   vec_sort_with_function (cmds, cmd_cmp);
21142
21143   for (j = 0; j < vec_len (cmds); j++)
21144     print (vam->ofp, "%s", cmds[j]);
21145
21146   vec_free (cmds);
21147   return 0;
21148 }
21149
21150 static int
21151 set (vat_main_t * vam)
21152 {
21153   u8 *name = 0, *value = 0;
21154   unformat_input_t *i = vam->input;
21155
21156   if (unformat (i, "%s", &name))
21157     {
21158       /* The input buffer is a vector, not a string. */
21159       value = vec_dup (i->buffer);
21160       vec_delete (value, i->index, 0);
21161       /* Almost certainly has a trailing newline */
21162       if (value[vec_len (value) - 1] == '\n')
21163         value[vec_len (value) - 1] = 0;
21164       /* Make sure it's a proper string, one way or the other */
21165       vec_add1 (value, 0);
21166       (void) clib_macro_set_value (&vam->macro_main,
21167                                    (char *) name, (char *) value);
21168     }
21169   else
21170     errmsg ("usage: set <name> <value>");
21171
21172   vec_free (name);
21173   vec_free (value);
21174   return 0;
21175 }
21176
21177 static int
21178 unset (vat_main_t * vam)
21179 {
21180   u8 *name = 0;
21181
21182   if (unformat (vam->input, "%s", &name))
21183     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21184       errmsg ("unset: %s wasn't set", name);
21185   vec_free (name);
21186   return 0;
21187 }
21188
21189 typedef struct
21190 {
21191   u8 *name;
21192   u8 *value;
21193 } macro_sort_t;
21194
21195
21196 static int
21197 macro_sort_cmp (void *a1, void *a2)
21198 {
21199   macro_sort_t *s1 = a1;
21200   macro_sort_t *s2 = a2;
21201
21202   return strcmp ((char *) (s1->name), (char *) (s2->name));
21203 }
21204
21205 static int
21206 dump_macro_table (vat_main_t * vam)
21207 {
21208   macro_sort_t *sort_me = 0, *sm;
21209   int i;
21210   hash_pair_t *p;
21211
21212     /* *INDENT-OFF* */
21213     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21214     ({
21215       vec_add2 (sort_me, sm, 1);
21216       sm->name = (u8 *)(p->key);
21217       sm->value = (u8 *) (p->value[0]);
21218     }));
21219     /* *INDENT-ON* */
21220
21221   vec_sort_with_function (sort_me, macro_sort_cmp);
21222
21223   if (vec_len (sort_me))
21224     print (vam->ofp, "%-15s%s", "Name", "Value");
21225   else
21226     print (vam->ofp, "The macro table is empty...");
21227
21228   for (i = 0; i < vec_len (sort_me); i++)
21229     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21230   return 0;
21231 }
21232
21233 static int
21234 dump_node_table (vat_main_t * vam)
21235 {
21236   int i, j;
21237   vlib_node_t *node, *next_node;
21238
21239   if (vec_len (vam->graph_nodes) == 0)
21240     {
21241       print (vam->ofp, "Node table empty, issue get_node_graph...");
21242       return 0;
21243     }
21244
21245   for (i = 0; i < vec_len (vam->graph_nodes); i++)
21246     {
21247       node = vam->graph_nodes[i];
21248       print (vam->ofp, "[%d] %s", i, node->name);
21249       for (j = 0; j < vec_len (node->next_nodes); j++)
21250         {
21251           if (node->next_nodes[j] != ~0)
21252             {
21253               next_node = vam->graph_nodes[node->next_nodes[j]];
21254               print (vam->ofp, "  [%d] %s", j, next_node->name);
21255             }
21256         }
21257     }
21258   return 0;
21259 }
21260
21261 static int
21262 value_sort_cmp (void *a1, void *a2)
21263 {
21264   name_sort_t *n1 = a1;
21265   name_sort_t *n2 = a2;
21266
21267   if (n1->value < n2->value)
21268     return -1;
21269   if (n1->value > n2->value)
21270     return 1;
21271   return 0;
21272 }
21273
21274
21275 static int
21276 dump_msg_api_table (vat_main_t * vam)
21277 {
21278   api_main_t *am = &api_main;
21279   name_sort_t *nses = 0, *ns;
21280   hash_pair_t *hp;
21281   int i;
21282
21283   /* *INDENT-OFF* */
21284   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21285   ({
21286     vec_add2 (nses, ns, 1);
21287     ns->name = (u8 *)(hp->key);
21288     ns->value = (u32) hp->value[0];
21289   }));
21290   /* *INDENT-ON* */
21291
21292   vec_sort_with_function (nses, value_sort_cmp);
21293
21294   for (i = 0; i < vec_len (nses); i++)
21295     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21296   vec_free (nses);
21297   return 0;
21298 }
21299
21300 static int
21301 get_msg_id (vat_main_t * vam)
21302 {
21303   u8 *name_and_crc;
21304   u32 message_index;
21305
21306   if (unformat (vam->input, "%s", &name_and_crc))
21307     {
21308       message_index = vl_api_get_msg_index (name_and_crc);
21309       if (message_index == ~0)
21310         {
21311           print (vam->ofp, " '%s' not found", name_and_crc);
21312           return 0;
21313         }
21314       print (vam->ofp, " '%s' has message index %d",
21315              name_and_crc, message_index);
21316       return 0;
21317     }
21318   errmsg ("name_and_crc required...");
21319   return 0;
21320 }
21321
21322 static int
21323 search_node_table (vat_main_t * vam)
21324 {
21325   unformat_input_t *line_input = vam->input;
21326   u8 *node_to_find;
21327   int j;
21328   vlib_node_t *node, *next_node;
21329   uword *p;
21330
21331   if (vam->graph_node_index_by_name == 0)
21332     {
21333       print (vam->ofp, "Node table empty, issue get_node_graph...");
21334       return 0;
21335     }
21336
21337   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21338     {
21339       if (unformat (line_input, "%s", &node_to_find))
21340         {
21341           vec_add1 (node_to_find, 0);
21342           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21343           if (p == 0)
21344             {
21345               print (vam->ofp, "%s not found...", node_to_find);
21346               goto out;
21347             }
21348           node = vam->graph_nodes[p[0]];
21349           print (vam->ofp, "[%d] %s", p[0], node->name);
21350           for (j = 0; j < vec_len (node->next_nodes); j++)
21351             {
21352               if (node->next_nodes[j] != ~0)
21353                 {
21354                   next_node = vam->graph_nodes[node->next_nodes[j]];
21355                   print (vam->ofp, "  [%d] %s", j, next_node->name);
21356                 }
21357             }
21358         }
21359
21360       else
21361         {
21362           clib_warning ("parse error '%U'", format_unformat_error,
21363                         line_input);
21364           return -99;
21365         }
21366
21367     out:
21368       vec_free (node_to_find);
21369
21370     }
21371
21372   return 0;
21373 }
21374
21375
21376 static int
21377 script (vat_main_t * vam)
21378 {
21379 #if (VPP_API_TEST_BUILTIN==0)
21380   u8 *s = 0;
21381   char *save_current_file;
21382   unformat_input_t save_input;
21383   jmp_buf save_jump_buf;
21384   u32 save_line_number;
21385
21386   FILE *new_fp, *save_ifp;
21387
21388   if (unformat (vam->input, "%s", &s))
21389     {
21390       new_fp = fopen ((char *) s, "r");
21391       if (new_fp == 0)
21392         {
21393           errmsg ("Couldn't open script file %s", s);
21394           vec_free (s);
21395           return -99;
21396         }
21397     }
21398   else
21399     {
21400       errmsg ("Missing script name");
21401       return -99;
21402     }
21403
21404   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
21405   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
21406   save_ifp = vam->ifp;
21407   save_line_number = vam->input_line_number;
21408   save_current_file = (char *) vam->current_file;
21409
21410   vam->input_line_number = 0;
21411   vam->ifp = new_fp;
21412   vam->current_file = s;
21413   do_one_file (vam);
21414
21415   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
21416   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
21417   vam->ifp = save_ifp;
21418   vam->input_line_number = save_line_number;
21419   vam->current_file = (u8 *) save_current_file;
21420   vec_free (s);
21421
21422   return 0;
21423 #else
21424   clib_warning ("use the exec command...");
21425   return -99;
21426 #endif
21427 }
21428
21429 static int
21430 echo (vat_main_t * vam)
21431 {
21432   print (vam->ofp, "%v", vam->input->buffer);
21433   return 0;
21434 }
21435
21436 /* List of API message constructors, CLI names map to api_xxx */
21437 #define foreach_vpe_api_msg                                             \
21438 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
21439 _(sw_interface_dump,"")                                                 \
21440 _(sw_interface_set_flags,                                               \
21441   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
21442 _(sw_interface_add_del_address,                                         \
21443   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
21444 _(sw_interface_set_table,                                               \
21445   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
21446 _(sw_interface_set_mpls_enable,                                         \
21447   "<intfc> | sw_if_index [disable | dis]")                              \
21448 _(sw_interface_set_vpath,                                               \
21449   "<intfc> | sw_if_index <id> enable | disable")                        \
21450 _(sw_interface_set_vxlan_bypass,                                        \
21451   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21452 _(sw_interface_set_geneve_bypass,                                       \
21453   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21454 _(sw_interface_set_l2_xconnect,                                         \
21455   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21456   "enable | disable")                                                   \
21457 _(sw_interface_set_l2_bridge,                                           \
21458   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
21459   "[shg <split-horizon-group>] [bvi]\n"                                 \
21460   "enable | disable")                                                   \
21461 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
21462 _(bridge_domain_add_del,                                                \
21463   "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") \
21464 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
21465 _(l2fib_add_del,                                                        \
21466   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
21467 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
21468 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
21469 _(l2_flags,                                                             \
21470   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21471 _(bridge_flags,                                                         \
21472   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21473 _(tap_connect,                                                          \
21474   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
21475 _(tap_modify,                                                           \
21476   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
21477 _(tap_delete,                                                           \
21478   "<vpp-if-name> | sw_if_index <id>")                                   \
21479 _(sw_interface_tap_dump, "")                                            \
21480 _(ip_table_add_del,                                                     \
21481   "table-id <n> [ipv6]\n")                                              \
21482 _(ip_add_del_route,                                                     \
21483   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
21484   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
21485   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
21486   "[multipath] [count <n>]")                                            \
21487 _(ip_mroute_add_del,                                                    \
21488   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
21489   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
21490 _(mpls_table_add_del,                                                   \
21491   "table-id <n>\n")                                                     \
21492 _(mpls_route_add_del,                                                   \
21493   "<label> <eos> via <addr> [table-id <n>]\n"                           \
21494   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
21495   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
21496   "[multipath] [count <n>]")                                            \
21497 _(mpls_ip_bind_unbind,                                                  \
21498   "<label> <addr/len>")                                                 \
21499 _(mpls_tunnel_add_del,                                                  \
21500   " via <addr> [table-id <n>]\n"                                        \
21501   "sw_if_index <id>] [l2]  [del]")                                      \
21502 _(proxy_arp_add_del,                                                    \
21503   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
21504 _(proxy_arp_intfc_enable_disable,                                       \
21505   "<intfc> | sw_if_index <id> enable | disable")                        \
21506 _(sw_interface_set_unnumbered,                                          \
21507   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
21508 _(ip_neighbor_add_del,                                                  \
21509   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
21510   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
21511 _(reset_vrf, "vrf <id> [ipv6]")                                         \
21512 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
21513 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
21514   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
21515   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
21516   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
21517 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
21518 _(reset_fib, "vrf <n> [ipv6]")                                          \
21519 _(dhcp_proxy_config,                                                    \
21520   "svr <v46-address> src <v46-address>\n"                               \
21521    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
21522 _(dhcp_proxy_set_vss,                                                   \
21523   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
21524 _(dhcp_proxy_dump, "ip6")                                               \
21525 _(dhcp_client_config,                                                   \
21526   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
21527 _(set_ip_flow_hash,                                                     \
21528   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
21529 _(sw_interface_ip6_enable_disable,                                      \
21530   "<intfc> | sw_if_index <id> enable | disable")                        \
21531 _(sw_interface_ip6_set_link_local_address,                              \
21532   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
21533 _(ip6nd_proxy_add_del,                                                  \
21534   "<intfc> | sw_if_index <id> <ip6-address>")                           \
21535 _(ip6nd_proxy_dump, "")                                                 \
21536 _(sw_interface_ip6nd_ra_prefix,                                         \
21537   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
21538   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
21539   "[nolink] [isno]")                                                    \
21540 _(sw_interface_ip6nd_ra_config,                                         \
21541   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
21542   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
21543   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
21544 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
21545 _(l2_patch_add_del,                                                     \
21546   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21547   "enable | disable")                                                   \
21548 _(sr_localsid_add_del,                                                  \
21549   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
21550   "fib-table <num> (end.psp) sw_if_index <num>")                        \
21551 _(classify_add_del_table,                                               \
21552   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
21553   " [del] [del-chain] mask <mask-value>\n"                              \
21554   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
21555   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
21556 _(classify_add_del_session,                                             \
21557   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
21558   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
21559   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
21560   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
21561 _(classify_set_interface_ip_table,                                      \
21562   "<intfc> | sw_if_index <nn> table <nn>")                              \
21563 _(classify_set_interface_l2_tables,                                     \
21564   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21565   "  [other-table <nn>]")                                               \
21566 _(get_node_index, "node <node-name")                                    \
21567 _(add_node_next, "node <node-name> next <next-node-name>")              \
21568 _(l2tpv3_create_tunnel,                                                 \
21569   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
21570   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
21571   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
21572 _(l2tpv3_set_tunnel_cookies,                                            \
21573   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
21574   "[new_remote_cookie <nn>]\n")                                         \
21575 _(l2tpv3_interface_enable_disable,                                      \
21576   "<intfc> | sw_if_index <nn> enable | disable")                        \
21577 _(l2tpv3_set_lookup_key,                                                \
21578   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
21579 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
21580 _(vxlan_add_del_tunnel,                                                 \
21581   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21582   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21583   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21584 _(geneve_add_del_tunnel,                                                \
21585   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21586   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21587   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21588 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
21589 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
21590 _(gre_add_del_tunnel,                                                   \
21591   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
21592 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
21593 _(l2_fib_clear_table, "")                                               \
21594 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
21595 _(l2_interface_vlan_tag_rewrite,                                        \
21596   "<intfc> | sw_if_index <nn> \n"                                       \
21597   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
21598   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
21599 _(create_vhost_user_if,                                                 \
21600         "socket <filename> [server] [renumber <dev_instance>] "         \
21601         "[mac <mac_address>]")                                          \
21602 _(modify_vhost_user_if,                                                 \
21603         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
21604         "[server] [renumber <dev_instance>]")                           \
21605 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
21606 _(sw_interface_vhost_user_dump, "")                                     \
21607 _(show_version, "")                                                     \
21608 _(vxlan_gpe_add_del_tunnel,                                             \
21609   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
21610   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21611   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
21612   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
21613 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
21614 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
21615 _(interface_name_renumber,                                              \
21616   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
21617 _(input_acl_set_interface,                                              \
21618   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21619   "  [l2-table <nn>] [del]")                                            \
21620 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
21621 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
21622 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
21623 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
21624 _(ip_dump, "ipv4 | ipv6")                                               \
21625 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
21626 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
21627   "  spid_id <n> ")                                                     \
21628 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
21629   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
21630   "  integ_alg <alg> integ_key <hex>")                                  \
21631 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
21632   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
21633   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
21634   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
21635 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
21636 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
21637   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
21638   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
21639   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
21640 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
21641 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
21642   "  <alg> <hex>\n")                                                    \
21643 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
21644 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
21645   "(auth_data 0x<data> | auth_data <data>)")                            \
21646 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
21647   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
21648 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
21649   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
21650   "(local|remote)")                                                     \
21651 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
21652 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
21653 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
21654 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
21655 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
21656 _(ikev2_initiate_sa_init, "<profile_name>")                             \
21657 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
21658 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
21659 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
21660 _(delete_loopback,"sw_if_index <nn>")                                   \
21661 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
21662 _(map_add_domain,                                                       \
21663   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
21664   "ip6-src <ip6addr> "                                                  \
21665   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
21666 _(map_del_domain, "index <n>")                                          \
21667 _(map_add_del_rule,                                                     \
21668   "index <n> psid <n> dst <ip6addr> [del]")                             \
21669 _(map_domain_dump, "")                                                  \
21670 _(map_rule_dump, "index <map-domain>")                                  \
21671 _(want_interface_events,  "enable|disable")                             \
21672 _(want_stats,"enable|disable")                                          \
21673 _(get_first_msg_id, "client <name>")                                    \
21674 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
21675 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
21676   "fib-id <nn> [ip4][ip6][default]")                                    \
21677 _(get_node_graph, " ")                                                  \
21678 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
21679 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
21680 _(ioam_disable, "")                                                     \
21681 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
21682                             " sw_if_index <sw_if_index> p <priority> "  \
21683                             "w <weight>] [del]")                        \
21684 _(one_add_del_locator, "locator-set <locator_name> "                    \
21685                         "iface <intf> | sw_if_index <sw_if_index> "     \
21686                         "p <priority> w <weight> [del]")                \
21687 _(one_add_del_local_eid,"vni <vni> eid "                                \
21688                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21689                          "locator-set <locator_name> [del]"             \
21690                          "[key-id sha1|sha256 secret-key <secret-key>]")\
21691 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
21692 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
21693 _(one_enable_disable, "enable|disable")                                 \
21694 _(one_map_register_enable_disable, "enable|disable")                    \
21695 _(one_map_register_fallback_threshold, "<value>")                       \
21696 _(one_rloc_probe_enable_disable, "enable|disable")                      \
21697 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
21698                                "[seid <seid>] "                         \
21699                                "rloc <locator> p <prio> "               \
21700                                "w <weight> [rloc <loc> ... ] "          \
21701                                "action <action> [del-all]")             \
21702 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
21703                           "<local-eid>")                                \
21704 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
21705 _(one_use_petr, "ip-address> | disable")                                \
21706 _(one_map_request_mode, "src-dst|dst-only")                             \
21707 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
21708 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
21709 _(one_locator_set_dump, "[local | remote]")                             \
21710 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
21711 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
21712                        "[local] | [remote]")                            \
21713 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
21714 _(one_ndp_bd_get, "")                                                   \
21715 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
21716 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
21717 _(one_l2_arp_bd_get, "")                                                \
21718 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
21719 _(one_stats_enable_disable, "enable|disalbe")                           \
21720 _(show_one_stats_enable_disable, "")                                    \
21721 _(one_eid_table_vni_dump, "")                                           \
21722 _(one_eid_table_map_dump, "l2|l3")                                      \
21723 _(one_map_resolver_dump, "")                                            \
21724 _(one_map_server_dump, "")                                              \
21725 _(one_adjacencies_get, "vni <vni>")                                     \
21726 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
21727 _(show_one_rloc_probe_state, "")                                        \
21728 _(show_one_map_register_state, "")                                      \
21729 _(show_one_status, "")                                                  \
21730 _(one_stats_dump, "")                                                   \
21731 _(one_stats_flush, "")                                                  \
21732 _(one_get_map_request_itr_rlocs, "")                                    \
21733 _(one_map_register_set_ttl, "<ttl>")                                    \
21734 _(one_set_transport_protocol, "udp|api")                                \
21735 _(one_get_transport_protocol, "")                                       \
21736 _(show_one_nsh_mapping, "")                                             \
21737 _(show_one_pitr, "")                                                    \
21738 _(show_one_use_petr, "")                                                \
21739 _(show_one_map_request_mode, "")                                        \
21740 _(show_one_map_register_ttl, "")                                        \
21741 _(show_one_map_register_fallback_threshold, "")                         \
21742 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
21743                             " sw_if_index <sw_if_index> p <priority> "  \
21744                             "w <weight>] [del]")                        \
21745 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
21746                         "iface <intf> | sw_if_index <sw_if_index> "     \
21747                         "p <priority> w <weight> [del]")                \
21748 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
21749                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21750                          "locator-set <locator_name> [del]"             \
21751                          "[key-id sha1|sha256 secret-key <secret-key>]") \
21752 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
21753 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
21754 _(lisp_enable_disable, "enable|disable")                                \
21755 _(lisp_map_register_enable_disable, "enable|disable")                   \
21756 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
21757 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
21758                                "[seid <seid>] "                         \
21759                                "rloc <locator> p <prio> "               \
21760                                "w <weight> [rloc <loc> ... ] "          \
21761                                "action <action> [del-all]")             \
21762 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
21763                           "<local-eid>")                                \
21764 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
21765 _(lisp_use_petr, "<ip-address> | disable")                              \
21766 _(lisp_map_request_mode, "src-dst|dst-only")                            \
21767 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
21768 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
21769 _(lisp_locator_set_dump, "[local | remote]")                            \
21770 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
21771 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
21772                        "[local] | [remote]")                            \
21773 _(lisp_eid_table_vni_dump, "")                                          \
21774 _(lisp_eid_table_map_dump, "l2|l3")                                     \
21775 _(lisp_map_resolver_dump, "")                                           \
21776 _(lisp_map_server_dump, "")                                             \
21777 _(lisp_adjacencies_get, "vni <vni>")                                    \
21778 _(gpe_fwd_entry_vnis_get, "")                                           \
21779 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
21780 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
21781                                 "[table <table-id>]")                   \
21782 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
21783 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
21784 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
21785 _(gpe_get_encap_mode, "")                                               \
21786 _(lisp_gpe_add_del_iface, "up|down")                                    \
21787 _(lisp_gpe_enable_disable, "enable|disable")                            \
21788 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
21789   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
21790 _(show_lisp_rloc_probe_state, "")                                       \
21791 _(show_lisp_map_register_state, "")                                     \
21792 _(show_lisp_status, "")                                                 \
21793 _(lisp_get_map_request_itr_rlocs, "")                                   \
21794 _(show_lisp_pitr, "")                                                   \
21795 _(show_lisp_use_petr, "")                                               \
21796 _(show_lisp_map_request_mode, "")                                       \
21797 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
21798 _(af_packet_delete, "name <host interface name>")                       \
21799 _(policer_add_del, "name <policer name> <params> [del]")                \
21800 _(policer_dump, "[name <policer name>]")                                \
21801 _(policer_classify_set_interface,                                       \
21802   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21803   "  [l2-table <nn>] [del]")                                            \
21804 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
21805 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
21806     "[master|slave]")                                                   \
21807 _(netmap_delete, "name <interface name>")                               \
21808 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
21809 _(mpls_fib_dump, "")                                                    \
21810 _(classify_table_ids, "")                                               \
21811 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
21812 _(classify_table_info, "table_id <nn>")                                 \
21813 _(classify_session_dump, "table_id <nn>")                               \
21814 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
21815     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
21816     "[template_interval <nn>] [udp_checksum]")                          \
21817 _(ipfix_exporter_dump, "")                                              \
21818 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
21819 _(ipfix_classify_stream_dump, "")                                       \
21820 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
21821 _(ipfix_classify_table_dump, "")                                        \
21822 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
21823 _(sw_interface_span_dump, "[l2]")                                           \
21824 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
21825 _(pg_create_interface, "if_id <nn>")                                    \
21826 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
21827 _(pg_enable_disable, "[stream <id>] disable")                           \
21828 _(ip_source_and_port_range_check_add_del,                               \
21829   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
21830 _(ip_source_and_port_range_check_interface_add_del,                     \
21831   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
21832   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
21833 _(ipsec_gre_add_del_tunnel,                                             \
21834   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
21835 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
21836 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
21837 _(l2_interface_pbb_tag_rewrite,                                         \
21838   "<intfc> | sw_if_index <nn> \n"                                       \
21839   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
21840   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
21841 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
21842 _(flow_classify_set_interface,                                          \
21843   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
21844 _(flow_classify_dump, "type [ip4|ip6]")                                 \
21845 _(ip_fib_dump, "")                                                      \
21846 _(ip_mfib_dump, "")                                                     \
21847 _(ip6_fib_dump, "")                                                     \
21848 _(ip6_mfib_dump, "")                                                    \
21849 _(feature_enable_disable, "arc_name <arc_name> "                        \
21850   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
21851 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
21852 "[disable]")                                                            \
21853 _(l2_xconnect_dump, "")                                                 \
21854 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
21855 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
21856 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
21857 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
21858 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
21859 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
21860 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
21861   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
21862 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
21863 _(memfd_segment_create,"size <nnn>")                                    \
21864 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
21865 _(dns_enable_disable, "[enable][disable]")                              \
21866 _(dns_name_server_add_del, "<ip-address> [del]")                        \
21867 _(dns_resolve_name, "<hostname>")
21868
21869 /* List of command functions, CLI names map directly to functions */
21870 #define foreach_cli_function                                    \
21871 _(comment, "usage: comment <ignore-rest-of-line>")              \
21872 _(dump_interface_table, "usage: dump_interface_table")          \
21873 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21874 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21875 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21876 _(dump_stats_table, "usage: dump_stats_table")                  \
21877 _(dump_macro_table, "usage: dump_macro_table ")                 \
21878 _(dump_node_table, "usage: dump_node_table")                    \
21879 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21880 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21881 _(echo, "usage: echo <message>")                                \
21882 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21883 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21884 _(help, "usage: help")                                          \
21885 _(q, "usage: quit")                                             \
21886 _(quit, "usage: quit")                                          \
21887 _(search_node_table, "usage: search_node_table <name>...")      \
21888 _(set, "usage: set <variable-name> <value>")                    \
21889 _(script, "usage: script <file-name>")                          \
21890 _(unset, "usage: unset <variable-name>")
21891 #define _(N,n)                                  \
21892     static void vl_api_##n##_t_handler_uni      \
21893     (vl_api_##n##_t * mp)                       \
21894     {                                           \
21895         vat_main_t * vam = &vat_main;           \
21896         if (vam->json_output) {                 \
21897             vl_api_##n##_t_handler_json(mp);    \
21898         } else {                                \
21899             vl_api_##n##_t_handler(mp);         \
21900         }                                       \
21901     }
21902 foreach_vpe_api_reply_msg;
21903 #if VPP_API_TEST_BUILTIN == 0
21904 foreach_standalone_reply_msg;
21905 #endif
21906 #undef _
21907
21908 void
21909 vat_api_hookup (vat_main_t * vam)
21910 {
21911 #define _(N,n)                                                  \
21912     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21913                            vl_api_##n##_t_handler_uni,          \
21914                            vl_noop_handler,                     \
21915                            vl_api_##n##_t_endian,               \
21916                            vl_api_##n##_t_print,                \
21917                            sizeof(vl_api_##n##_t), 1);
21918   foreach_vpe_api_reply_msg;
21919 #if VPP_API_TEST_BUILTIN == 0
21920   foreach_standalone_reply_msg;
21921 #endif
21922 #undef _
21923
21924 #if (VPP_API_TEST_BUILTIN==0)
21925   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
21926
21927   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
21928
21929   vam->function_by_name = hash_create_string (0, sizeof (uword));
21930
21931   vam->help_by_name = hash_create_string (0, sizeof (uword));
21932 #endif
21933
21934   /* API messages we can send */
21935 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
21936   foreach_vpe_api_msg;
21937 #undef _
21938
21939   /* Help strings */
21940 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21941   foreach_vpe_api_msg;
21942 #undef _
21943
21944   /* CLI functions */
21945 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
21946   foreach_cli_function;
21947 #undef _
21948
21949   /* Help strings */
21950 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21951   foreach_cli_function;
21952 #undef _
21953 }
21954
21955 #if VPP_API_TEST_BUILTIN
21956 static clib_error_t *
21957 vat_api_hookup_shim (vlib_main_t * vm)
21958 {
21959   vat_api_hookup (&vat_main);
21960   return 0;
21961 }
21962
21963 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
21964 #endif
21965
21966 /*
21967  * fd.io coding-style-patch-verification: ON
21968  *
21969  * Local Variables:
21970  * eval: (c-set-style "gnu")
21971  * End:
21972  */