Add API call to set keys on IPsec tunnel intf
[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 is_add = 1;
7566   u32 next_hop_weight = 1;
7567   u8 not_last = 0;
7568   u8 is_multipath = 0;
7569   u8 address_set = 0;
7570   u8 address_length_set = 0;
7571   u32 next_hop_table_id = 0;
7572   u32 resolve_attempts = 0;
7573   u32 dst_address_length = 0;
7574   u8 next_hop_set = 0;
7575   ip4_address_t v4_dst_address, v4_next_hop_address;
7576   ip6_address_t v6_dst_address, v6_next_hop_address;
7577   int count = 1;
7578   int j;
7579   f64 before = 0;
7580   u32 random_add_del = 0;
7581   u32 *random_vector = 0;
7582   uword *random_hash;
7583   u32 random_seed = 0xdeaddabe;
7584   u32 classify_table_index = ~0;
7585   u8 is_classify = 0;
7586   u8 resolve_host = 0, resolve_attached = 0;
7587   mpls_label_t *next_hop_out_label_stack = NULL;
7588   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7589   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7590
7591   /* Parse args required to build the message */
7592   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7593     {
7594       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7595         ;
7596       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7597         ;
7598       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
7599         {
7600           address_set = 1;
7601           is_ipv6 = 0;
7602         }
7603       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
7604         {
7605           address_set = 1;
7606           is_ipv6 = 1;
7607         }
7608       else if (unformat (i, "/%d", &dst_address_length))
7609         {
7610           address_length_set = 1;
7611         }
7612
7613       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
7614                                          &v4_next_hop_address))
7615         {
7616           next_hop_set = 1;
7617         }
7618       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
7619                                          &v6_next_hop_address))
7620         {
7621           next_hop_set = 1;
7622         }
7623       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
7624         ;
7625       else if (unformat (i, "weight %d", &next_hop_weight))
7626         ;
7627       else if (unformat (i, "drop"))
7628         {
7629           is_drop = 1;
7630         }
7631       else if (unformat (i, "null-send-unreach"))
7632         {
7633           is_unreach = 1;
7634         }
7635       else if (unformat (i, "null-send-prohibit"))
7636         {
7637           is_prohibit = 1;
7638         }
7639       else if (unformat (i, "local"))
7640         {
7641           is_local = 1;
7642         }
7643       else if (unformat (i, "classify %d", &classify_table_index))
7644         {
7645           is_classify = 1;
7646         }
7647       else if (unformat (i, "del"))
7648         is_add = 0;
7649       else if (unformat (i, "add"))
7650         is_add = 1;
7651       else if (unformat (i, "not-last"))
7652         not_last = 1;
7653       else if (unformat (i, "resolve-via-host"))
7654         resolve_host = 1;
7655       else if (unformat (i, "resolve-via-attached"))
7656         resolve_attached = 1;
7657       else if (unformat (i, "multipath"))
7658         is_multipath = 1;
7659       else if (unformat (i, "vrf %d", &vrf_id))
7660         ;
7661       else if (unformat (i, "count %d", &count))
7662         ;
7663       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
7664         ;
7665       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7666         ;
7667       else if (unformat (i, "out-label %d", &next_hop_out_label))
7668         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7669       else if (unformat (i, "via-label %d", &next_hop_via_label))
7670         ;
7671       else if (unformat (i, "random"))
7672         random_add_del = 1;
7673       else if (unformat (i, "seed %d", &random_seed))
7674         ;
7675       else
7676         {
7677           clib_warning ("parse error '%U'", format_unformat_error, i);
7678           return -99;
7679         }
7680     }
7681
7682   if (!next_hop_set && !is_drop && !is_local &&
7683       !is_classify && !is_unreach && !is_prohibit &&
7684       MPLS_LABEL_INVALID == next_hop_via_label)
7685     {
7686       errmsg
7687         ("next hop / local / drop / unreach / prohibit / classify not set");
7688       return -99;
7689     }
7690
7691   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
7692     {
7693       errmsg ("next hop and next-hop via label set");
7694       return -99;
7695     }
7696   if (address_set == 0)
7697     {
7698       errmsg ("missing addresses");
7699       return -99;
7700     }
7701
7702   if (address_length_set == 0)
7703     {
7704       errmsg ("missing address length");
7705       return -99;
7706     }
7707
7708   /* Generate a pile of unique, random routes */
7709   if (random_add_del)
7710     {
7711       u32 this_random_address;
7712       random_hash = hash_create (count, sizeof (uword));
7713
7714       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
7715       for (j = 0; j <= count; j++)
7716         {
7717           do
7718             {
7719               this_random_address = random_u32 (&random_seed);
7720               this_random_address =
7721                 clib_host_to_net_u32 (this_random_address);
7722             }
7723           while (hash_get (random_hash, this_random_address));
7724           vec_add1 (random_vector, this_random_address);
7725           hash_set (random_hash, this_random_address, 1);
7726         }
7727       hash_free (random_hash);
7728       v4_dst_address.as_u32 = random_vector[0];
7729     }
7730
7731   if (count > 1)
7732     {
7733       /* Turn on async mode */
7734       vam->async_mode = 1;
7735       vam->async_errors = 0;
7736       before = vat_time_now (vam);
7737     }
7738
7739   for (j = 0; j < count; j++)
7740     {
7741       /* Construct the API message */
7742       M2 (IP_ADD_DEL_ROUTE, mp,
7743           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7744
7745       mp->next_hop_sw_if_index = ntohl (sw_if_index);
7746       mp->table_id = ntohl (vrf_id);
7747
7748       mp->is_add = is_add;
7749       mp->is_drop = is_drop;
7750       mp->is_unreach = is_unreach;
7751       mp->is_prohibit = is_prohibit;
7752       mp->is_ipv6 = is_ipv6;
7753       mp->is_local = is_local;
7754       mp->is_classify = is_classify;
7755       mp->is_multipath = is_multipath;
7756       mp->is_resolve_host = resolve_host;
7757       mp->is_resolve_attached = resolve_attached;
7758       mp->not_last = not_last;
7759       mp->next_hop_weight = next_hop_weight;
7760       mp->dst_address_length = dst_address_length;
7761       mp->next_hop_table_id = ntohl (next_hop_table_id);
7762       mp->classify_table_index = ntohl (classify_table_index);
7763       mp->next_hop_via_label = ntohl (next_hop_via_label);
7764       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7765       if (0 != mp->next_hop_n_out_labels)
7766         {
7767           memcpy (mp->next_hop_out_label_stack,
7768                   next_hop_out_label_stack,
7769                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7770           vec_free (next_hop_out_label_stack);
7771         }
7772
7773       if (is_ipv6)
7774         {
7775           clib_memcpy (mp->dst_address, &v6_dst_address,
7776                        sizeof (v6_dst_address));
7777           if (next_hop_set)
7778             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
7779                          sizeof (v6_next_hop_address));
7780           increment_v6_address (&v6_dst_address);
7781         }
7782       else
7783         {
7784           clib_memcpy (mp->dst_address, &v4_dst_address,
7785                        sizeof (v4_dst_address));
7786           if (next_hop_set)
7787             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
7788                          sizeof (v4_next_hop_address));
7789           if (random_add_del)
7790             v4_dst_address.as_u32 = random_vector[j + 1];
7791           else
7792             increment_v4_address (&v4_dst_address);
7793         }
7794       /* send it... */
7795       S (mp);
7796       /* If we receive SIGTERM, stop now... */
7797       if (vam->do_exit)
7798         break;
7799     }
7800
7801   /* When testing multiple add/del ops, use a control-ping to sync */
7802   if (count > 1)
7803     {
7804       vl_api_control_ping_t *mp_ping;
7805       f64 after;
7806       f64 timeout;
7807
7808       /* Shut off async mode */
7809       vam->async_mode = 0;
7810
7811       MPING (CONTROL_PING, mp_ping);
7812       S (mp_ping);
7813
7814       timeout = vat_time_now (vam) + 1.0;
7815       while (vat_time_now (vam) < timeout)
7816         if (vam->result_ready == 1)
7817           goto out;
7818       vam->retval = -99;
7819
7820     out:
7821       if (vam->retval == -99)
7822         errmsg ("timeout");
7823
7824       if (vam->async_errors > 0)
7825         {
7826           errmsg ("%d asynchronous errors", vam->async_errors);
7827           vam->retval = -98;
7828         }
7829       vam->async_errors = 0;
7830       after = vat_time_now (vam);
7831
7832       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7833       if (j > 0)
7834         count = j;
7835
7836       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7837              count, after - before, count / (after - before));
7838     }
7839   else
7840     {
7841       int ret;
7842
7843       /* Wait for a reply... */
7844       W (ret);
7845       return ret;
7846     }
7847
7848   /* Return the good/bad news */
7849   return (vam->retval);
7850 }
7851
7852 static int
7853 api_ip_mroute_add_del (vat_main_t * vam)
7854 {
7855   unformat_input_t *i = vam->input;
7856   vl_api_ip_mroute_add_del_t *mp;
7857   u32 sw_if_index = ~0, vrf_id = 0;
7858   u8 is_ipv6 = 0;
7859   u8 is_local = 0;
7860   u8 is_add = 1;
7861   u8 address_set = 0;
7862   u32 grp_address_length = 0;
7863   ip4_address_t v4_grp_address, v4_src_address;
7864   ip6_address_t v6_grp_address, v6_src_address;
7865   mfib_itf_flags_t iflags = 0;
7866   mfib_entry_flags_t eflags = 0;
7867   int ret;
7868
7869   /* Parse args required to build the message */
7870   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7871     {
7872       if (unformat (i, "sw_if_index %d", &sw_if_index))
7873         ;
7874       else if (unformat (i, "%U %U",
7875                          unformat_ip4_address, &v4_src_address,
7876                          unformat_ip4_address, &v4_grp_address))
7877         {
7878           grp_address_length = 64;
7879           address_set = 1;
7880           is_ipv6 = 0;
7881         }
7882       else if (unformat (i, "%U %U",
7883                          unformat_ip6_address, &v6_src_address,
7884                          unformat_ip6_address, &v6_grp_address))
7885         {
7886           grp_address_length = 256;
7887           address_set = 1;
7888           is_ipv6 = 1;
7889         }
7890       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
7891         {
7892           memset (&v4_src_address, 0, sizeof (v4_src_address));
7893           grp_address_length = 32;
7894           address_set = 1;
7895           is_ipv6 = 0;
7896         }
7897       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
7898         {
7899           memset (&v6_src_address, 0, sizeof (v6_src_address));
7900           grp_address_length = 128;
7901           address_set = 1;
7902           is_ipv6 = 1;
7903         }
7904       else if (unformat (i, "/%d", &grp_address_length))
7905         ;
7906       else if (unformat (i, "local"))
7907         {
7908           is_local = 1;
7909         }
7910       else if (unformat (i, "del"))
7911         is_add = 0;
7912       else if (unformat (i, "add"))
7913         is_add = 1;
7914       else if (unformat (i, "vrf %d", &vrf_id))
7915         ;
7916       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
7917         ;
7918       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
7919         ;
7920       else
7921         {
7922           clib_warning ("parse error '%U'", format_unformat_error, i);
7923           return -99;
7924         }
7925     }
7926
7927   if (address_set == 0)
7928     {
7929       errmsg ("missing addresses\n");
7930       return -99;
7931     }
7932
7933   /* Construct the API message */
7934   M (IP_MROUTE_ADD_DEL, mp);
7935
7936   mp->next_hop_sw_if_index = ntohl (sw_if_index);
7937   mp->table_id = ntohl (vrf_id);
7938
7939   mp->is_add = is_add;
7940   mp->is_ipv6 = is_ipv6;
7941   mp->is_local = is_local;
7942   mp->itf_flags = ntohl (iflags);
7943   mp->entry_flags = ntohl (eflags);
7944   mp->grp_address_length = grp_address_length;
7945   mp->grp_address_length = ntohs (mp->grp_address_length);
7946
7947   if (is_ipv6)
7948     {
7949       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
7950       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
7951     }
7952   else
7953     {
7954       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
7955       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
7956
7957     }
7958
7959   /* send it... */
7960   S (mp);
7961   /* Wait for a reply... */
7962   W (ret);
7963   return ret;
7964 }
7965
7966 static int
7967 api_mpls_table_add_del (vat_main_t * vam)
7968 {
7969   unformat_input_t *i = vam->input;
7970   vl_api_mpls_table_add_del_t *mp;
7971   u32 table_id = ~0;
7972   u8 is_add = 1;
7973   int ret = 0;
7974
7975   /* Parse args required to build the message */
7976   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7977     {
7978       if (unformat (i, "del"))
7979         is_add = 0;
7980       else if (unformat (i, "add"))
7981         is_add = 1;
7982       else if (unformat (i, "table-id %d", &table_id))
7983         ;
7984       else
7985         {
7986           clib_warning ("parse error '%U'", format_unformat_error, i);
7987           return -99;
7988         }
7989     }
7990
7991   if (~0 == table_id)
7992     {
7993       errmsg ("missing table-ID");
7994       return -99;
7995     }
7996
7997   /* Construct the API message */
7998   M (MPLS_TABLE_ADD_DEL, mp);
7999
8000   mp->mt_table_id = ntohl (table_id);
8001   mp->mt_is_add = is_add;
8002
8003   /* send it... */
8004   S (mp);
8005
8006   /* Wait for a reply... */
8007   W (ret);
8008
8009   return ret;
8010 }
8011
8012 static int
8013 api_mpls_route_add_del (vat_main_t * vam)
8014 {
8015   unformat_input_t *i = vam->input;
8016   vl_api_mpls_route_add_del_t *mp;
8017   u32 sw_if_index = ~0, table_id = 0;
8018   u8 is_add = 1;
8019   u32 next_hop_weight = 1;
8020   u8 is_multipath = 0;
8021   u32 next_hop_table_id = 0;
8022   u8 next_hop_set = 0;
8023   ip4_address_t v4_next_hop_address = {
8024     .as_u32 = 0,
8025   };
8026   ip6_address_t v6_next_hop_address = { {0} };
8027   int count = 1;
8028   int j;
8029   f64 before = 0;
8030   u32 classify_table_index = ~0;
8031   u8 is_classify = 0;
8032   u8 resolve_host = 0, resolve_attached = 0;
8033   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8034   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8035   mpls_label_t *next_hop_out_label_stack = NULL;
8036   mpls_label_t local_label = MPLS_LABEL_INVALID;
8037   u8 is_eos = 0;
8038   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8039
8040   /* Parse args required to build the message */
8041   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8042     {
8043       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8044         ;
8045       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8046         ;
8047       else if (unformat (i, "%d", &local_label))
8048         ;
8049       else if (unformat (i, "eos"))
8050         is_eos = 1;
8051       else if (unformat (i, "non-eos"))
8052         is_eos = 0;
8053       else if (unformat (i, "via %U", unformat_ip4_address,
8054                          &v4_next_hop_address))
8055         {
8056           next_hop_set = 1;
8057           next_hop_proto = DPO_PROTO_IP4;
8058         }
8059       else if (unformat (i, "via %U", unformat_ip6_address,
8060                          &v6_next_hop_address))
8061         {
8062           next_hop_set = 1;
8063           next_hop_proto = DPO_PROTO_IP6;
8064         }
8065       else if (unformat (i, "weight %d", &next_hop_weight))
8066         ;
8067       else if (unformat (i, "classify %d", &classify_table_index))
8068         {
8069           is_classify = 1;
8070         }
8071       else if (unformat (i, "del"))
8072         is_add = 0;
8073       else if (unformat (i, "add"))
8074         is_add = 1;
8075       else if (unformat (i, "resolve-via-host"))
8076         resolve_host = 1;
8077       else if (unformat (i, "resolve-via-attached"))
8078         resolve_attached = 1;
8079       else if (unformat (i, "multipath"))
8080         is_multipath = 1;
8081       else if (unformat (i, "count %d", &count))
8082         ;
8083       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8084         {
8085           next_hop_set = 1;
8086           next_hop_proto = DPO_PROTO_IP4;
8087         }
8088       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8089         {
8090           next_hop_set = 1;
8091           next_hop_proto = DPO_PROTO_IP6;
8092         }
8093       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8094         ;
8095       else if (unformat (i, "via-label %d", &next_hop_via_label))
8096         ;
8097       else if (unformat (i, "out-label %d", &next_hop_out_label))
8098         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8099       else
8100         {
8101           clib_warning ("parse error '%U'", format_unformat_error, i);
8102           return -99;
8103         }
8104     }
8105
8106   if (!next_hop_set && !is_classify)
8107     {
8108       errmsg ("next hop / classify not set");
8109       return -99;
8110     }
8111
8112   if (MPLS_LABEL_INVALID == local_label)
8113     {
8114       errmsg ("missing label");
8115       return -99;
8116     }
8117
8118   if (count > 1)
8119     {
8120       /* Turn on async mode */
8121       vam->async_mode = 1;
8122       vam->async_errors = 0;
8123       before = vat_time_now (vam);
8124     }
8125
8126   for (j = 0; j < count; j++)
8127     {
8128       /* Construct the API message */
8129       M2 (MPLS_ROUTE_ADD_DEL, mp,
8130           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8131
8132       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8133       mp->mr_table_id = ntohl (table_id);
8134
8135       mp->mr_is_add = is_add;
8136       mp->mr_next_hop_proto = next_hop_proto;
8137       mp->mr_is_classify = is_classify;
8138       mp->mr_is_multipath = is_multipath;
8139       mp->mr_is_resolve_host = resolve_host;
8140       mp->mr_is_resolve_attached = resolve_attached;
8141       mp->mr_next_hop_weight = next_hop_weight;
8142       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8143       mp->mr_classify_table_index = ntohl (classify_table_index);
8144       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8145       mp->mr_label = ntohl (local_label);
8146       mp->mr_eos = is_eos;
8147
8148       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8149       if (0 != mp->mr_next_hop_n_out_labels)
8150         {
8151           memcpy (mp->mr_next_hop_out_label_stack,
8152                   next_hop_out_label_stack,
8153                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8154           vec_free (next_hop_out_label_stack);
8155         }
8156
8157       if (next_hop_set)
8158         {
8159           if (DPO_PROTO_IP4 == next_hop_proto)
8160             {
8161               clib_memcpy (mp->mr_next_hop,
8162                            &v4_next_hop_address,
8163                            sizeof (v4_next_hop_address));
8164             }
8165           else if (DPO_PROTO_IP6 == next_hop_proto)
8166
8167             {
8168               clib_memcpy (mp->mr_next_hop,
8169                            &v6_next_hop_address,
8170                            sizeof (v6_next_hop_address));
8171             }
8172         }
8173       local_label++;
8174
8175       /* send it... */
8176       S (mp);
8177       /* If we receive SIGTERM, stop now... */
8178       if (vam->do_exit)
8179         break;
8180     }
8181
8182   /* When testing multiple add/del ops, use a control-ping to sync */
8183   if (count > 1)
8184     {
8185       vl_api_control_ping_t *mp_ping;
8186       f64 after;
8187       f64 timeout;
8188
8189       /* Shut off async mode */
8190       vam->async_mode = 0;
8191
8192       MPING (CONTROL_PING, mp_ping);
8193       S (mp_ping);
8194
8195       timeout = vat_time_now (vam) + 1.0;
8196       while (vat_time_now (vam) < timeout)
8197         if (vam->result_ready == 1)
8198           goto out;
8199       vam->retval = -99;
8200
8201     out:
8202       if (vam->retval == -99)
8203         errmsg ("timeout");
8204
8205       if (vam->async_errors > 0)
8206         {
8207           errmsg ("%d asynchronous errors", vam->async_errors);
8208           vam->retval = -98;
8209         }
8210       vam->async_errors = 0;
8211       after = vat_time_now (vam);
8212
8213       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8214       if (j > 0)
8215         count = j;
8216
8217       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8218              count, after - before, count / (after - before));
8219     }
8220   else
8221     {
8222       int ret;
8223
8224       /* Wait for a reply... */
8225       W (ret);
8226       return ret;
8227     }
8228
8229   /* Return the good/bad news */
8230   return (vam->retval);
8231 }
8232
8233 static int
8234 api_mpls_ip_bind_unbind (vat_main_t * vam)
8235 {
8236   unformat_input_t *i = vam->input;
8237   vl_api_mpls_ip_bind_unbind_t *mp;
8238   u32 ip_table_id = 0;
8239   u8 is_bind = 1;
8240   u8 is_ip4 = 1;
8241   ip4_address_t v4_address;
8242   ip6_address_t v6_address;
8243   u32 address_length;
8244   u8 address_set = 0;
8245   mpls_label_t local_label = MPLS_LABEL_INVALID;
8246   int ret;
8247
8248   /* Parse args required to build the message */
8249   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8250     {
8251       if (unformat (i, "%U/%d", unformat_ip4_address,
8252                     &v4_address, &address_length))
8253         {
8254           is_ip4 = 1;
8255           address_set = 1;
8256         }
8257       else if (unformat (i, "%U/%d", unformat_ip6_address,
8258                          &v6_address, &address_length))
8259         {
8260           is_ip4 = 0;
8261           address_set = 1;
8262         }
8263       else if (unformat (i, "%d", &local_label))
8264         ;
8265       else if (unformat (i, "table-id %d", &ip_table_id))
8266         ;
8267       else if (unformat (i, "unbind"))
8268         is_bind = 0;
8269       else if (unformat (i, "bind"))
8270         is_bind = 1;
8271       else
8272         {
8273           clib_warning ("parse error '%U'", format_unformat_error, i);
8274           return -99;
8275         }
8276     }
8277
8278   if (!address_set)
8279     {
8280       errmsg ("IP addres not set");
8281       return -99;
8282     }
8283
8284   if (MPLS_LABEL_INVALID == local_label)
8285     {
8286       errmsg ("missing label");
8287       return -99;
8288     }
8289
8290   /* Construct the API message */
8291   M (MPLS_IP_BIND_UNBIND, mp);
8292
8293   mp->mb_is_bind = is_bind;
8294   mp->mb_is_ip4 = is_ip4;
8295   mp->mb_ip_table_id = ntohl (ip_table_id);
8296   mp->mb_mpls_table_id = 0;
8297   mp->mb_label = ntohl (local_label);
8298   mp->mb_address_length = address_length;
8299
8300   if (is_ip4)
8301     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8302   else
8303     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8304
8305   /* send it... */
8306   S (mp);
8307
8308   /* Wait for a reply... */
8309   W (ret);
8310   return ret;
8311 }
8312
8313 static int
8314 api_proxy_arp_add_del (vat_main_t * vam)
8315 {
8316   unformat_input_t *i = vam->input;
8317   vl_api_proxy_arp_add_del_t *mp;
8318   u32 vrf_id = 0;
8319   u8 is_add = 1;
8320   ip4_address_t lo, hi;
8321   u8 range_set = 0;
8322   int ret;
8323
8324   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8325     {
8326       if (unformat (i, "vrf %d", &vrf_id))
8327         ;
8328       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
8329                          unformat_ip4_address, &hi))
8330         range_set = 1;
8331       else if (unformat (i, "del"))
8332         is_add = 0;
8333       else
8334         {
8335           clib_warning ("parse error '%U'", format_unformat_error, i);
8336           return -99;
8337         }
8338     }
8339
8340   if (range_set == 0)
8341     {
8342       errmsg ("address range not set");
8343       return -99;
8344     }
8345
8346   M (PROXY_ARP_ADD_DEL, mp);
8347
8348   mp->vrf_id = ntohl (vrf_id);
8349   mp->is_add = is_add;
8350   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
8351   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
8352
8353   S (mp);
8354   W (ret);
8355   return ret;
8356 }
8357
8358 static int
8359 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8360 {
8361   unformat_input_t *i = vam->input;
8362   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8363   u32 sw_if_index;
8364   u8 enable = 1;
8365   u8 sw_if_index_set = 0;
8366   int ret;
8367
8368   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8369     {
8370       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8371         sw_if_index_set = 1;
8372       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8373         sw_if_index_set = 1;
8374       else if (unformat (i, "enable"))
8375         enable = 1;
8376       else if (unformat (i, "disable"))
8377         enable = 0;
8378       else
8379         {
8380           clib_warning ("parse error '%U'", format_unformat_error, i);
8381           return -99;
8382         }
8383     }
8384
8385   if (sw_if_index_set == 0)
8386     {
8387       errmsg ("missing interface name or sw_if_index");
8388       return -99;
8389     }
8390
8391   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8392
8393   mp->sw_if_index = ntohl (sw_if_index);
8394   mp->enable_disable = enable;
8395
8396   S (mp);
8397   W (ret);
8398   return ret;
8399 }
8400
8401 static int
8402 api_mpls_tunnel_add_del (vat_main_t * vam)
8403 {
8404   unformat_input_t *i = vam->input;
8405   vl_api_mpls_tunnel_add_del_t *mp;
8406
8407   u8 is_add = 1;
8408   u8 l2_only = 0;
8409   u32 sw_if_index = ~0;
8410   u32 next_hop_sw_if_index = ~0;
8411   u32 next_hop_proto_is_ip4 = 1;
8412
8413   u32 next_hop_table_id = 0;
8414   ip4_address_t v4_next_hop_address = {
8415     .as_u32 = 0,
8416   };
8417   ip6_address_t v6_next_hop_address = { {0} };
8418   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
8419   int ret;
8420
8421   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8422     {
8423       if (unformat (i, "add"))
8424         is_add = 1;
8425       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8426         is_add = 0;
8427       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
8428         ;
8429       else if (unformat (i, "via %U",
8430                          unformat_ip4_address, &v4_next_hop_address))
8431         {
8432           next_hop_proto_is_ip4 = 1;
8433         }
8434       else if (unformat (i, "via %U",
8435                          unformat_ip6_address, &v6_next_hop_address))
8436         {
8437           next_hop_proto_is_ip4 = 0;
8438         }
8439       else if (unformat (i, "l2-only"))
8440         l2_only = 1;
8441       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8442         ;
8443       else if (unformat (i, "out-label %d", &next_hop_out_label))
8444         vec_add1 (labels, ntohl (next_hop_out_label));
8445       else
8446         {
8447           clib_warning ("parse error '%U'", format_unformat_error, i);
8448           return -99;
8449         }
8450     }
8451
8452   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
8453
8454   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
8455   mp->mt_sw_if_index = ntohl (sw_if_index);
8456   mp->mt_is_add = is_add;
8457   mp->mt_l2_only = l2_only;
8458   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
8459   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
8460
8461   mp->mt_next_hop_n_out_labels = vec_len (labels);
8462
8463   if (0 != mp->mt_next_hop_n_out_labels)
8464     {
8465       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
8466                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
8467       vec_free (labels);
8468     }
8469
8470   if (next_hop_proto_is_ip4)
8471     {
8472       clib_memcpy (mp->mt_next_hop,
8473                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8474     }
8475   else
8476     {
8477       clib_memcpy (mp->mt_next_hop,
8478                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8479     }
8480
8481   S (mp);
8482   W (ret);
8483   return ret;
8484 }
8485
8486 static int
8487 api_sw_interface_set_unnumbered (vat_main_t * vam)
8488 {
8489   unformat_input_t *i = vam->input;
8490   vl_api_sw_interface_set_unnumbered_t *mp;
8491   u32 sw_if_index;
8492   u32 unnum_sw_index = ~0;
8493   u8 is_add = 1;
8494   u8 sw_if_index_set = 0;
8495   int ret;
8496
8497   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8498     {
8499       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8500         sw_if_index_set = 1;
8501       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8502         sw_if_index_set = 1;
8503       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8504         ;
8505       else if (unformat (i, "del"))
8506         is_add = 0;
8507       else
8508         {
8509           clib_warning ("parse error '%U'", format_unformat_error, i);
8510           return -99;
8511         }
8512     }
8513
8514   if (sw_if_index_set == 0)
8515     {
8516       errmsg ("missing interface name or sw_if_index");
8517       return -99;
8518     }
8519
8520   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8521
8522   mp->sw_if_index = ntohl (sw_if_index);
8523   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8524   mp->is_add = is_add;
8525
8526   S (mp);
8527   W (ret);
8528   return ret;
8529 }
8530
8531 static int
8532 api_ip_neighbor_add_del (vat_main_t * vam)
8533 {
8534   unformat_input_t *i = vam->input;
8535   vl_api_ip_neighbor_add_del_t *mp;
8536   u32 sw_if_index;
8537   u8 sw_if_index_set = 0;
8538   u8 is_add = 1;
8539   u8 is_static = 0;
8540   u8 is_no_fib_entry = 0;
8541   u8 mac_address[6];
8542   u8 mac_set = 0;
8543   u8 v4_address_set = 0;
8544   u8 v6_address_set = 0;
8545   ip4_address_t v4address;
8546   ip6_address_t v6address;
8547   int ret;
8548
8549   memset (mac_address, 0, sizeof (mac_address));
8550
8551   /* Parse args required to build the message */
8552   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8553     {
8554       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8555         {
8556           mac_set = 1;
8557         }
8558       else if (unformat (i, "del"))
8559         is_add = 0;
8560       else
8561         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8562         sw_if_index_set = 1;
8563       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8564         sw_if_index_set = 1;
8565       else if (unformat (i, "is_static"))
8566         is_static = 1;
8567       else if (unformat (i, "no-fib-entry"))
8568         is_no_fib_entry = 1;
8569       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
8570         v4_address_set = 1;
8571       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
8572         v6_address_set = 1;
8573       else
8574         {
8575           clib_warning ("parse error '%U'", format_unformat_error, i);
8576           return -99;
8577         }
8578     }
8579
8580   if (sw_if_index_set == 0)
8581     {
8582       errmsg ("missing interface name or sw_if_index");
8583       return -99;
8584     }
8585   if (v4_address_set && v6_address_set)
8586     {
8587       errmsg ("both v4 and v6 addresses set");
8588       return -99;
8589     }
8590   if (!v4_address_set && !v6_address_set)
8591     {
8592       errmsg ("no address set");
8593       return -99;
8594     }
8595
8596   /* Construct the API message */
8597   M (IP_NEIGHBOR_ADD_DEL, mp);
8598
8599   mp->sw_if_index = ntohl (sw_if_index);
8600   mp->is_add = is_add;
8601   mp->is_static = is_static;
8602   mp->is_no_adj_fib = is_no_fib_entry;
8603   if (mac_set)
8604     clib_memcpy (mp->mac_address, mac_address, 6);
8605   if (v6_address_set)
8606     {
8607       mp->is_ipv6 = 1;
8608       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
8609     }
8610   else
8611     {
8612       /* mp->is_ipv6 = 0; via memset in M macro above */
8613       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
8614     }
8615
8616   /* send it... */
8617   S (mp);
8618
8619   /* Wait for a reply, return good/bad news  */
8620   W (ret);
8621   return ret;
8622 }
8623
8624 static int
8625 api_reset_vrf (vat_main_t * vam)
8626 {
8627   unformat_input_t *i = vam->input;
8628   vl_api_reset_vrf_t *mp;
8629   u32 vrf_id = 0;
8630   u8 is_ipv6 = 0;
8631   u8 vrf_id_set = 0;
8632   int ret;
8633
8634   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8635     {
8636       if (unformat (i, "vrf %d", &vrf_id))
8637         vrf_id_set = 1;
8638       else if (unformat (i, "ipv6"))
8639         is_ipv6 = 1;
8640       else
8641         {
8642           clib_warning ("parse error '%U'", format_unformat_error, i);
8643           return -99;
8644         }
8645     }
8646
8647   if (vrf_id_set == 0)
8648     {
8649       errmsg ("missing vrf id");
8650       return -99;
8651     }
8652
8653   M (RESET_VRF, mp);
8654
8655   mp->vrf_id = ntohl (vrf_id);
8656   mp->is_ipv6 = is_ipv6;
8657
8658   S (mp);
8659   W (ret);
8660   return ret;
8661 }
8662
8663 static int
8664 api_create_vlan_subif (vat_main_t * vam)
8665 {
8666   unformat_input_t *i = vam->input;
8667   vl_api_create_vlan_subif_t *mp;
8668   u32 sw_if_index;
8669   u8 sw_if_index_set = 0;
8670   u32 vlan_id;
8671   u8 vlan_id_set = 0;
8672   int ret;
8673
8674   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8675     {
8676       if (unformat (i, "sw_if_index %d", &sw_if_index))
8677         sw_if_index_set = 1;
8678       else
8679         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8680         sw_if_index_set = 1;
8681       else if (unformat (i, "vlan %d", &vlan_id))
8682         vlan_id_set = 1;
8683       else
8684         {
8685           clib_warning ("parse error '%U'", format_unformat_error, i);
8686           return -99;
8687         }
8688     }
8689
8690   if (sw_if_index_set == 0)
8691     {
8692       errmsg ("missing interface name or sw_if_index");
8693       return -99;
8694     }
8695
8696   if (vlan_id_set == 0)
8697     {
8698       errmsg ("missing vlan_id");
8699       return -99;
8700     }
8701   M (CREATE_VLAN_SUBIF, mp);
8702
8703   mp->sw_if_index = ntohl (sw_if_index);
8704   mp->vlan_id = ntohl (vlan_id);
8705
8706   S (mp);
8707   W (ret);
8708   return ret;
8709 }
8710
8711 #define foreach_create_subif_bit                \
8712 _(no_tags)                                      \
8713 _(one_tag)                                      \
8714 _(two_tags)                                     \
8715 _(dot1ad)                                       \
8716 _(exact_match)                                  \
8717 _(default_sub)                                  \
8718 _(outer_vlan_id_any)                            \
8719 _(inner_vlan_id_any)
8720
8721 static int
8722 api_create_subif (vat_main_t * vam)
8723 {
8724   unformat_input_t *i = vam->input;
8725   vl_api_create_subif_t *mp;
8726   u32 sw_if_index;
8727   u8 sw_if_index_set = 0;
8728   u32 sub_id;
8729   u8 sub_id_set = 0;
8730   u32 no_tags = 0;
8731   u32 one_tag = 0;
8732   u32 two_tags = 0;
8733   u32 dot1ad = 0;
8734   u32 exact_match = 0;
8735   u32 default_sub = 0;
8736   u32 outer_vlan_id_any = 0;
8737   u32 inner_vlan_id_any = 0;
8738   u32 tmp;
8739   u16 outer_vlan_id = 0;
8740   u16 inner_vlan_id = 0;
8741   int ret;
8742
8743   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8744     {
8745       if (unformat (i, "sw_if_index %d", &sw_if_index))
8746         sw_if_index_set = 1;
8747       else
8748         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8749         sw_if_index_set = 1;
8750       else if (unformat (i, "sub_id %d", &sub_id))
8751         sub_id_set = 1;
8752       else if (unformat (i, "outer_vlan_id %d", &tmp))
8753         outer_vlan_id = tmp;
8754       else if (unformat (i, "inner_vlan_id %d", &tmp))
8755         inner_vlan_id = tmp;
8756
8757 #define _(a) else if (unformat (i, #a)) a = 1 ;
8758       foreach_create_subif_bit
8759 #undef _
8760         else
8761         {
8762           clib_warning ("parse error '%U'", format_unformat_error, i);
8763           return -99;
8764         }
8765     }
8766
8767   if (sw_if_index_set == 0)
8768     {
8769       errmsg ("missing interface name or sw_if_index");
8770       return -99;
8771     }
8772
8773   if (sub_id_set == 0)
8774     {
8775       errmsg ("missing sub_id");
8776       return -99;
8777     }
8778   M (CREATE_SUBIF, mp);
8779
8780   mp->sw_if_index = ntohl (sw_if_index);
8781   mp->sub_id = ntohl (sub_id);
8782
8783 #define _(a) mp->a = a;
8784   foreach_create_subif_bit;
8785 #undef _
8786
8787   mp->outer_vlan_id = ntohs (outer_vlan_id);
8788   mp->inner_vlan_id = ntohs (inner_vlan_id);
8789
8790   S (mp);
8791   W (ret);
8792   return ret;
8793 }
8794
8795 static int
8796 api_oam_add_del (vat_main_t * vam)
8797 {
8798   unformat_input_t *i = vam->input;
8799   vl_api_oam_add_del_t *mp;
8800   u32 vrf_id = 0;
8801   u8 is_add = 1;
8802   ip4_address_t src, dst;
8803   u8 src_set = 0;
8804   u8 dst_set = 0;
8805   int ret;
8806
8807   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8808     {
8809       if (unformat (i, "vrf %d", &vrf_id))
8810         ;
8811       else if (unformat (i, "src %U", unformat_ip4_address, &src))
8812         src_set = 1;
8813       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
8814         dst_set = 1;
8815       else if (unformat (i, "del"))
8816         is_add = 0;
8817       else
8818         {
8819           clib_warning ("parse error '%U'", format_unformat_error, i);
8820           return -99;
8821         }
8822     }
8823
8824   if (src_set == 0)
8825     {
8826       errmsg ("missing src addr");
8827       return -99;
8828     }
8829
8830   if (dst_set == 0)
8831     {
8832       errmsg ("missing dst addr");
8833       return -99;
8834     }
8835
8836   M (OAM_ADD_DEL, mp);
8837
8838   mp->vrf_id = ntohl (vrf_id);
8839   mp->is_add = is_add;
8840   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
8841   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
8842
8843   S (mp);
8844   W (ret);
8845   return ret;
8846 }
8847
8848 static int
8849 api_reset_fib (vat_main_t * vam)
8850 {
8851   unformat_input_t *i = vam->input;
8852   vl_api_reset_fib_t *mp;
8853   u32 vrf_id = 0;
8854   u8 is_ipv6 = 0;
8855   u8 vrf_id_set = 0;
8856
8857   int ret;
8858   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8859     {
8860       if (unformat (i, "vrf %d", &vrf_id))
8861         vrf_id_set = 1;
8862       else if (unformat (i, "ipv6"))
8863         is_ipv6 = 1;
8864       else
8865         {
8866           clib_warning ("parse error '%U'", format_unformat_error, i);
8867           return -99;
8868         }
8869     }
8870
8871   if (vrf_id_set == 0)
8872     {
8873       errmsg ("missing vrf id");
8874       return -99;
8875     }
8876
8877   M (RESET_FIB, mp);
8878
8879   mp->vrf_id = ntohl (vrf_id);
8880   mp->is_ipv6 = is_ipv6;
8881
8882   S (mp);
8883   W (ret);
8884   return ret;
8885 }
8886
8887 static int
8888 api_dhcp_proxy_config (vat_main_t * vam)
8889 {
8890   unformat_input_t *i = vam->input;
8891   vl_api_dhcp_proxy_config_t *mp;
8892   u32 rx_vrf_id = 0;
8893   u32 server_vrf_id = 0;
8894   u8 is_add = 1;
8895   u8 v4_address_set = 0;
8896   u8 v6_address_set = 0;
8897   ip4_address_t v4address;
8898   ip6_address_t v6address;
8899   u8 v4_src_address_set = 0;
8900   u8 v6_src_address_set = 0;
8901   ip4_address_t v4srcaddress;
8902   ip6_address_t v6srcaddress;
8903   int ret;
8904
8905   /* Parse args required to build the message */
8906   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8907     {
8908       if (unformat (i, "del"))
8909         is_add = 0;
8910       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
8911         ;
8912       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
8913         ;
8914       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
8915         v4_address_set = 1;
8916       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
8917         v6_address_set = 1;
8918       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
8919         v4_src_address_set = 1;
8920       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
8921         v6_src_address_set = 1;
8922       else
8923         break;
8924     }
8925
8926   if (v4_address_set && v6_address_set)
8927     {
8928       errmsg ("both v4 and v6 server addresses set");
8929       return -99;
8930     }
8931   if (!v4_address_set && !v6_address_set)
8932     {
8933       errmsg ("no server addresses set");
8934       return -99;
8935     }
8936
8937   if (v4_src_address_set && v6_src_address_set)
8938     {
8939       errmsg ("both v4 and v6  src addresses set");
8940       return -99;
8941     }
8942   if (!v4_src_address_set && !v6_src_address_set)
8943     {
8944       errmsg ("no src addresses set");
8945       return -99;
8946     }
8947
8948   if (!(v4_src_address_set && v4_address_set) &&
8949       !(v6_src_address_set && v6_address_set))
8950     {
8951       errmsg ("no matching server and src addresses set");
8952       return -99;
8953     }
8954
8955   /* Construct the API message */
8956   M (DHCP_PROXY_CONFIG, mp);
8957
8958   mp->is_add = is_add;
8959   mp->rx_vrf_id = ntohl (rx_vrf_id);
8960   mp->server_vrf_id = ntohl (server_vrf_id);
8961   if (v6_address_set)
8962     {
8963       mp->is_ipv6 = 1;
8964       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
8965       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
8966     }
8967   else
8968     {
8969       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
8970       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
8971     }
8972
8973   /* send it... */
8974   S (mp);
8975
8976   /* Wait for a reply, return good/bad news  */
8977   W (ret);
8978   return ret;
8979 }
8980
8981 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
8982 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
8983
8984 static void
8985 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
8986 {
8987   vat_main_t *vam = &vat_main;
8988   u32 i, count = mp->count;
8989   vl_api_dhcp_server_t *s;
8990
8991   if (mp->is_ipv6)
8992     print (vam->ofp,
8993            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8994            ntohl (mp->rx_vrf_id),
8995            format_ip6_address, mp->dhcp_src_address,
8996            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8997   else
8998     print (vam->ofp,
8999            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
9000            ntohl (mp->rx_vrf_id),
9001            format_ip4_address, mp->dhcp_src_address,
9002            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
9003
9004   for (i = 0; i < count; i++)
9005     {
9006       s = &mp->servers[i];
9007
9008       if (mp->is_ipv6)
9009         print (vam->ofp,
9010                " Server Table-ID %d, Server Address %U",
9011                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
9012       else
9013         print (vam->ofp,
9014                " Server Table-ID %d, Server Address %U",
9015                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
9016     }
9017 }
9018
9019 static void vl_api_dhcp_proxy_details_t_handler_json
9020   (vl_api_dhcp_proxy_details_t * mp)
9021 {
9022   vat_main_t *vam = &vat_main;
9023   vat_json_node_t *node = NULL;
9024   u32 i, count = mp->count;
9025   struct in_addr ip4;
9026   struct in6_addr ip6;
9027   vl_api_dhcp_server_t *s;
9028
9029   if (VAT_JSON_ARRAY != vam->json_tree.type)
9030     {
9031       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9032       vat_json_init_array (&vam->json_tree);
9033     }
9034   node = vat_json_array_add (&vam->json_tree);
9035
9036   vat_json_init_object (node);
9037   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9038   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9039   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9040
9041   if (mp->is_ipv6)
9042     {
9043       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9044       vat_json_object_add_ip6 (node, "src_address", ip6);
9045     }
9046   else
9047     {
9048       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9049       vat_json_object_add_ip4 (node, "src_address", ip4);
9050     }
9051
9052   for (i = 0; i < count; i++)
9053     {
9054       s = &mp->servers[i];
9055
9056       vat_json_object_add_uint (node, "server-table-id",
9057                                 ntohl (s->server_vrf_id));
9058
9059       if (mp->is_ipv6)
9060         {
9061           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9062           vat_json_object_add_ip4 (node, "src_address", ip4);
9063         }
9064       else
9065         {
9066           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9067           vat_json_object_add_ip6 (node, "server_address", ip6);
9068         }
9069     }
9070 }
9071
9072 static int
9073 api_dhcp_proxy_dump (vat_main_t * vam)
9074 {
9075   unformat_input_t *i = vam->input;
9076   vl_api_control_ping_t *mp_ping;
9077   vl_api_dhcp_proxy_dump_t *mp;
9078   u8 is_ipv6 = 0;
9079   int ret;
9080
9081   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9082     {
9083       if (unformat (i, "ipv6"))
9084         is_ipv6 = 1;
9085       else
9086         {
9087           clib_warning ("parse error '%U'", format_unformat_error, i);
9088           return -99;
9089         }
9090     }
9091
9092   M (DHCP_PROXY_DUMP, mp);
9093
9094   mp->is_ip6 = is_ipv6;
9095   S (mp);
9096
9097   /* Use a control ping for synchronization */
9098   MPING (CONTROL_PING, mp_ping);
9099   S (mp_ping);
9100
9101   W (ret);
9102   return ret;
9103 }
9104
9105 static int
9106 api_dhcp_proxy_set_vss (vat_main_t * vam)
9107 {
9108   unformat_input_t *i = vam->input;
9109   vl_api_dhcp_proxy_set_vss_t *mp;
9110   u8 is_ipv6 = 0;
9111   u8 is_add = 1;
9112   u32 tbl_id;
9113   u8 tbl_id_set = 0;
9114   u32 oui;
9115   u8 oui_set = 0;
9116   u32 fib_id;
9117   u8 fib_id_set = 0;
9118   int ret;
9119
9120   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9121     {
9122       if (unformat (i, "tbl_id %d", &tbl_id))
9123         tbl_id_set = 1;
9124       if (unformat (i, "fib_id %d", &fib_id))
9125         fib_id_set = 1;
9126       if (unformat (i, "oui %d", &oui))
9127         oui_set = 1;
9128       else if (unformat (i, "ipv6"))
9129         is_ipv6 = 1;
9130       else if (unformat (i, "del"))
9131         is_add = 0;
9132       else
9133         {
9134           clib_warning ("parse error '%U'", format_unformat_error, i);
9135           return -99;
9136         }
9137     }
9138
9139   if (tbl_id_set == 0)
9140     {
9141       errmsg ("missing tbl id");
9142       return -99;
9143     }
9144
9145   if (fib_id_set == 0)
9146     {
9147       errmsg ("missing fib id");
9148       return -99;
9149     }
9150   if (oui_set == 0)
9151     {
9152       errmsg ("missing oui");
9153       return -99;
9154     }
9155
9156   M (DHCP_PROXY_SET_VSS, mp);
9157   mp->tbl_id = ntohl (tbl_id);
9158   mp->fib_id = ntohl (fib_id);
9159   mp->oui = ntohl (oui);
9160   mp->is_ipv6 = is_ipv6;
9161   mp->is_add = is_add;
9162
9163   S (mp);
9164   W (ret);
9165   return ret;
9166 }
9167
9168 static int
9169 api_dhcp_client_config (vat_main_t * vam)
9170 {
9171   unformat_input_t *i = vam->input;
9172   vl_api_dhcp_client_config_t *mp;
9173   u32 sw_if_index;
9174   u8 sw_if_index_set = 0;
9175   u8 is_add = 1;
9176   u8 *hostname = 0;
9177   u8 disable_event = 0;
9178   int ret;
9179
9180   /* Parse args required to build the message */
9181   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9182     {
9183       if (unformat (i, "del"))
9184         is_add = 0;
9185       else
9186         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9187         sw_if_index_set = 1;
9188       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9189         sw_if_index_set = 1;
9190       else if (unformat (i, "hostname %s", &hostname))
9191         ;
9192       else if (unformat (i, "disable_event"))
9193         disable_event = 1;
9194       else
9195         break;
9196     }
9197
9198   if (sw_if_index_set == 0)
9199     {
9200       errmsg ("missing interface name or sw_if_index");
9201       return -99;
9202     }
9203
9204   if (vec_len (hostname) > 63)
9205     {
9206       errmsg ("hostname too long");
9207     }
9208   vec_add1 (hostname, 0);
9209
9210   /* Construct the API message */
9211   M (DHCP_CLIENT_CONFIG, mp);
9212
9213   mp->sw_if_index = htonl (sw_if_index);
9214   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
9215   vec_free (hostname);
9216   mp->is_add = is_add;
9217   mp->want_dhcp_event = disable_event ? 0 : 1;
9218   mp->pid = htonl (getpid ());
9219
9220   /* send it... */
9221   S (mp);
9222
9223   /* Wait for a reply, return good/bad news  */
9224   W (ret);
9225   return ret;
9226 }
9227
9228 static int
9229 api_set_ip_flow_hash (vat_main_t * vam)
9230 {
9231   unformat_input_t *i = vam->input;
9232   vl_api_set_ip_flow_hash_t *mp;
9233   u32 vrf_id = 0;
9234   u8 is_ipv6 = 0;
9235   u8 vrf_id_set = 0;
9236   u8 src = 0;
9237   u8 dst = 0;
9238   u8 sport = 0;
9239   u8 dport = 0;
9240   u8 proto = 0;
9241   u8 reverse = 0;
9242   int ret;
9243
9244   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9245     {
9246       if (unformat (i, "vrf %d", &vrf_id))
9247         vrf_id_set = 1;
9248       else if (unformat (i, "ipv6"))
9249         is_ipv6 = 1;
9250       else if (unformat (i, "src"))
9251         src = 1;
9252       else if (unformat (i, "dst"))
9253         dst = 1;
9254       else if (unformat (i, "sport"))
9255         sport = 1;
9256       else if (unformat (i, "dport"))
9257         dport = 1;
9258       else if (unformat (i, "proto"))
9259         proto = 1;
9260       else if (unformat (i, "reverse"))
9261         reverse = 1;
9262
9263       else
9264         {
9265           clib_warning ("parse error '%U'", format_unformat_error, i);
9266           return -99;
9267         }
9268     }
9269
9270   if (vrf_id_set == 0)
9271     {
9272       errmsg ("missing vrf id");
9273       return -99;
9274     }
9275
9276   M (SET_IP_FLOW_HASH, mp);
9277   mp->src = src;
9278   mp->dst = dst;
9279   mp->sport = sport;
9280   mp->dport = dport;
9281   mp->proto = proto;
9282   mp->reverse = reverse;
9283   mp->vrf_id = ntohl (vrf_id);
9284   mp->is_ipv6 = is_ipv6;
9285
9286   S (mp);
9287   W (ret);
9288   return ret;
9289 }
9290
9291 static int
9292 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9293 {
9294   unformat_input_t *i = vam->input;
9295   vl_api_sw_interface_ip6_enable_disable_t *mp;
9296   u32 sw_if_index;
9297   u8 sw_if_index_set = 0;
9298   u8 enable = 0;
9299   int ret;
9300
9301   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9302     {
9303       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9304         sw_if_index_set = 1;
9305       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9306         sw_if_index_set = 1;
9307       else if (unformat (i, "enable"))
9308         enable = 1;
9309       else if (unformat (i, "disable"))
9310         enable = 0;
9311       else
9312         {
9313           clib_warning ("parse error '%U'", format_unformat_error, i);
9314           return -99;
9315         }
9316     }
9317
9318   if (sw_if_index_set == 0)
9319     {
9320       errmsg ("missing interface name or sw_if_index");
9321       return -99;
9322     }
9323
9324   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9325
9326   mp->sw_if_index = ntohl (sw_if_index);
9327   mp->enable = enable;
9328
9329   S (mp);
9330   W (ret);
9331   return ret;
9332 }
9333
9334 static int
9335 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
9336 {
9337   unformat_input_t *i = vam->input;
9338   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
9339   u32 sw_if_index;
9340   u8 sw_if_index_set = 0;
9341   u8 v6_address_set = 0;
9342   ip6_address_t v6address;
9343   int ret;
9344
9345   /* Parse args required to build the message */
9346   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9347     {
9348       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9349         sw_if_index_set = 1;
9350       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9351         sw_if_index_set = 1;
9352       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9353         v6_address_set = 1;
9354       else
9355         break;
9356     }
9357
9358   if (sw_if_index_set == 0)
9359     {
9360       errmsg ("missing interface name or sw_if_index");
9361       return -99;
9362     }
9363   if (!v6_address_set)
9364     {
9365       errmsg ("no address set");
9366       return -99;
9367     }
9368
9369   /* Construct the API message */
9370   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
9371
9372   mp->sw_if_index = ntohl (sw_if_index);
9373   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9374
9375   /* send it... */
9376   S (mp);
9377
9378   /* Wait for a reply, return good/bad news  */
9379   W (ret);
9380   return ret;
9381 }
9382
9383 static int
9384 api_ip6nd_proxy_add_del (vat_main_t * vam)
9385 {
9386   unformat_input_t *i = vam->input;
9387   vl_api_ip6nd_proxy_add_del_t *mp;
9388   u32 sw_if_index = ~0;
9389   u8 v6_address_set = 0;
9390   ip6_address_t v6address;
9391   u8 is_del = 0;
9392   int ret;
9393
9394   /* Parse args required to build the message */
9395   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9396     {
9397       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9398         ;
9399       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9400         ;
9401       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9402         v6_address_set = 1;
9403       if (unformat (i, "del"))
9404         is_del = 1;
9405       else
9406         {
9407           clib_warning ("parse error '%U'", format_unformat_error, i);
9408           return -99;
9409         }
9410     }
9411
9412   if (sw_if_index == ~0)
9413     {
9414       errmsg ("missing interface name or sw_if_index");
9415       return -99;
9416     }
9417   if (!v6_address_set)
9418     {
9419       errmsg ("no address set");
9420       return -99;
9421     }
9422
9423   /* Construct the API message */
9424   M (IP6ND_PROXY_ADD_DEL, mp);
9425
9426   mp->is_del = is_del;
9427   mp->sw_if_index = ntohl (sw_if_index);
9428   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9429
9430   /* send it... */
9431   S (mp);
9432
9433   /* Wait for a reply, return good/bad news  */
9434   W (ret);
9435   return ret;
9436 }
9437
9438 static int
9439 api_ip6nd_proxy_dump (vat_main_t * vam)
9440 {
9441   vl_api_ip6nd_proxy_dump_t *mp;
9442   vl_api_control_ping_t *mp_ping;
9443   int ret;
9444
9445   M (IP6ND_PROXY_DUMP, mp);
9446
9447   S (mp);
9448
9449   /* Use a control ping for synchronization */
9450   MPING (CONTROL_PING, mp_ping);
9451   S (mp_ping);
9452
9453   W (ret);
9454   return ret;
9455 }
9456
9457 static void vl_api_ip6nd_proxy_details_t_handler
9458   (vl_api_ip6nd_proxy_details_t * mp)
9459 {
9460   vat_main_t *vam = &vat_main;
9461
9462   print (vam->ofp, "host %U sw_if_index %d",
9463          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
9464 }
9465
9466 static void vl_api_ip6nd_proxy_details_t_handler_json
9467   (vl_api_ip6nd_proxy_details_t * mp)
9468 {
9469   vat_main_t *vam = &vat_main;
9470   struct in6_addr ip6;
9471   vat_json_node_t *node = NULL;
9472
9473   if (VAT_JSON_ARRAY != vam->json_tree.type)
9474     {
9475       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9476       vat_json_init_array (&vam->json_tree);
9477     }
9478   node = vat_json_array_add (&vam->json_tree);
9479
9480   vat_json_init_object (node);
9481   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9482
9483   clib_memcpy (&ip6, mp->address, sizeof (ip6));
9484   vat_json_object_add_ip6 (node, "host", ip6);
9485 }
9486
9487 static int
9488 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9489 {
9490   unformat_input_t *i = vam->input;
9491   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9492   u32 sw_if_index;
9493   u8 sw_if_index_set = 0;
9494   u32 address_length = 0;
9495   u8 v6_address_set = 0;
9496   ip6_address_t v6address;
9497   u8 use_default = 0;
9498   u8 no_advertise = 0;
9499   u8 off_link = 0;
9500   u8 no_autoconfig = 0;
9501   u8 no_onlink = 0;
9502   u8 is_no = 0;
9503   u32 val_lifetime = 0;
9504   u32 pref_lifetime = 0;
9505   int ret;
9506
9507   /* Parse args required to build the message */
9508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9509     {
9510       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9511         sw_if_index_set = 1;
9512       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9513         sw_if_index_set = 1;
9514       else if (unformat (i, "%U/%d",
9515                          unformat_ip6_address, &v6address, &address_length))
9516         v6_address_set = 1;
9517       else if (unformat (i, "val_life %d", &val_lifetime))
9518         ;
9519       else if (unformat (i, "pref_life %d", &pref_lifetime))
9520         ;
9521       else if (unformat (i, "def"))
9522         use_default = 1;
9523       else if (unformat (i, "noadv"))
9524         no_advertise = 1;
9525       else if (unformat (i, "offl"))
9526         off_link = 1;
9527       else if (unformat (i, "noauto"))
9528         no_autoconfig = 1;
9529       else if (unformat (i, "nolink"))
9530         no_onlink = 1;
9531       else if (unformat (i, "isno"))
9532         is_no = 1;
9533       else
9534         {
9535           clib_warning ("parse error '%U'", format_unformat_error, i);
9536           return -99;
9537         }
9538     }
9539
9540   if (sw_if_index_set == 0)
9541     {
9542       errmsg ("missing interface name or sw_if_index");
9543       return -99;
9544     }
9545   if (!v6_address_set)
9546     {
9547       errmsg ("no address set");
9548       return -99;
9549     }
9550
9551   /* Construct the API message */
9552   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9553
9554   mp->sw_if_index = ntohl (sw_if_index);
9555   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9556   mp->address_length = address_length;
9557   mp->use_default = use_default;
9558   mp->no_advertise = no_advertise;
9559   mp->off_link = off_link;
9560   mp->no_autoconfig = no_autoconfig;
9561   mp->no_onlink = no_onlink;
9562   mp->is_no = is_no;
9563   mp->val_lifetime = ntohl (val_lifetime);
9564   mp->pref_lifetime = ntohl (pref_lifetime);
9565
9566   /* send it... */
9567   S (mp);
9568
9569   /* Wait for a reply, return good/bad news  */
9570   W (ret);
9571   return ret;
9572 }
9573
9574 static int
9575 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9576 {
9577   unformat_input_t *i = vam->input;
9578   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9579   u32 sw_if_index;
9580   u8 sw_if_index_set = 0;
9581   u8 suppress = 0;
9582   u8 managed = 0;
9583   u8 other = 0;
9584   u8 ll_option = 0;
9585   u8 send_unicast = 0;
9586   u8 cease = 0;
9587   u8 is_no = 0;
9588   u8 default_router = 0;
9589   u32 max_interval = 0;
9590   u32 min_interval = 0;
9591   u32 lifetime = 0;
9592   u32 initial_count = 0;
9593   u32 initial_interval = 0;
9594   int ret;
9595
9596
9597   /* Parse args required to build the message */
9598   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9599     {
9600       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9601         sw_if_index_set = 1;
9602       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9603         sw_if_index_set = 1;
9604       else if (unformat (i, "maxint %d", &max_interval))
9605         ;
9606       else if (unformat (i, "minint %d", &min_interval))
9607         ;
9608       else if (unformat (i, "life %d", &lifetime))
9609         ;
9610       else if (unformat (i, "count %d", &initial_count))
9611         ;
9612       else if (unformat (i, "interval %d", &initial_interval))
9613         ;
9614       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9615         suppress = 1;
9616       else if (unformat (i, "managed"))
9617         managed = 1;
9618       else if (unformat (i, "other"))
9619         other = 1;
9620       else if (unformat (i, "ll"))
9621         ll_option = 1;
9622       else if (unformat (i, "send"))
9623         send_unicast = 1;
9624       else if (unformat (i, "cease"))
9625         cease = 1;
9626       else if (unformat (i, "isno"))
9627         is_no = 1;
9628       else if (unformat (i, "def"))
9629         default_router = 1;
9630       else
9631         {
9632           clib_warning ("parse error '%U'", format_unformat_error, i);
9633           return -99;
9634         }
9635     }
9636
9637   if (sw_if_index_set == 0)
9638     {
9639       errmsg ("missing interface name or sw_if_index");
9640       return -99;
9641     }
9642
9643   /* Construct the API message */
9644   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9645
9646   mp->sw_if_index = ntohl (sw_if_index);
9647   mp->max_interval = ntohl (max_interval);
9648   mp->min_interval = ntohl (min_interval);
9649   mp->lifetime = ntohl (lifetime);
9650   mp->initial_count = ntohl (initial_count);
9651   mp->initial_interval = ntohl (initial_interval);
9652   mp->suppress = suppress;
9653   mp->managed = managed;
9654   mp->other = other;
9655   mp->ll_option = ll_option;
9656   mp->send_unicast = send_unicast;
9657   mp->cease = cease;
9658   mp->is_no = is_no;
9659   mp->default_router = default_router;
9660
9661   /* send it... */
9662   S (mp);
9663
9664   /* Wait for a reply, return good/bad news  */
9665   W (ret);
9666   return ret;
9667 }
9668
9669 static int
9670 api_set_arp_neighbor_limit (vat_main_t * vam)
9671 {
9672   unformat_input_t *i = vam->input;
9673   vl_api_set_arp_neighbor_limit_t *mp;
9674   u32 arp_nbr_limit;
9675   u8 limit_set = 0;
9676   u8 is_ipv6 = 0;
9677   int ret;
9678
9679   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9680     {
9681       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
9682         limit_set = 1;
9683       else if (unformat (i, "ipv6"))
9684         is_ipv6 = 1;
9685       else
9686         {
9687           clib_warning ("parse error '%U'", format_unformat_error, i);
9688           return -99;
9689         }
9690     }
9691
9692   if (limit_set == 0)
9693     {
9694       errmsg ("missing limit value");
9695       return -99;
9696     }
9697
9698   M (SET_ARP_NEIGHBOR_LIMIT, mp);
9699
9700   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
9701   mp->is_ipv6 = is_ipv6;
9702
9703   S (mp);
9704   W (ret);
9705   return ret;
9706 }
9707
9708 static int
9709 api_l2_patch_add_del (vat_main_t * vam)
9710 {
9711   unformat_input_t *i = vam->input;
9712   vl_api_l2_patch_add_del_t *mp;
9713   u32 rx_sw_if_index;
9714   u8 rx_sw_if_index_set = 0;
9715   u32 tx_sw_if_index;
9716   u8 tx_sw_if_index_set = 0;
9717   u8 is_add = 1;
9718   int ret;
9719
9720   /* Parse args required to build the message */
9721   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9722     {
9723       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9724         rx_sw_if_index_set = 1;
9725       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9726         tx_sw_if_index_set = 1;
9727       else if (unformat (i, "rx"))
9728         {
9729           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9730             {
9731               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9732                             &rx_sw_if_index))
9733                 rx_sw_if_index_set = 1;
9734             }
9735           else
9736             break;
9737         }
9738       else if (unformat (i, "tx"))
9739         {
9740           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9741             {
9742               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9743                             &tx_sw_if_index))
9744                 tx_sw_if_index_set = 1;
9745             }
9746           else
9747             break;
9748         }
9749       else if (unformat (i, "del"))
9750         is_add = 0;
9751       else
9752         break;
9753     }
9754
9755   if (rx_sw_if_index_set == 0)
9756     {
9757       errmsg ("missing rx interface name or rx_sw_if_index");
9758       return -99;
9759     }
9760
9761   if (tx_sw_if_index_set == 0)
9762     {
9763       errmsg ("missing tx interface name or tx_sw_if_index");
9764       return -99;
9765     }
9766
9767   M (L2_PATCH_ADD_DEL, mp);
9768
9769   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9770   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9771   mp->is_add = is_add;
9772
9773   S (mp);
9774   W (ret);
9775   return ret;
9776 }
9777
9778 u8 is_del;
9779 u8 localsid_addr[16];
9780 u8 end_psp;
9781 u8 behavior;
9782 u32 sw_if_index;
9783 u32 vlan_index;
9784 u32 fib_table;
9785 u8 nh_addr[16];
9786
9787 static int
9788 api_sr_localsid_add_del (vat_main_t * vam)
9789 {
9790   unformat_input_t *i = vam->input;
9791   vl_api_sr_localsid_add_del_t *mp;
9792
9793   u8 is_del;
9794   ip6_address_t localsid;
9795   u8 end_psp = 0;
9796   u8 behavior = ~0;
9797   u32 sw_if_index;
9798   u32 fib_table = ~(u32) 0;
9799   ip6_address_t next_hop;
9800
9801   bool nexthop_set = 0;
9802
9803   int ret;
9804
9805   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9806     {
9807       if (unformat (i, "del"))
9808         is_del = 1;
9809       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9810       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
9811         nexthop_set = 1;
9812       else if (unformat (i, "behavior %u", &behavior));
9813       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9814       else if (unformat (i, "fib-table %u", &fib_table));
9815       else if (unformat (i, "end.psp %u", &behavior));
9816       else
9817         break;
9818     }
9819
9820   M (SR_LOCALSID_ADD_DEL, mp);
9821
9822   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
9823   if (nexthop_set)
9824     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
9825   mp->behavior = behavior;
9826   mp->sw_if_index = ntohl (sw_if_index);
9827   mp->fib_table = ntohl (fib_table);
9828   mp->end_psp = end_psp;
9829   mp->is_del = is_del;
9830
9831   S (mp);
9832   W (ret);
9833   return ret;
9834 }
9835
9836 static int
9837 api_ioam_enable (vat_main_t * vam)
9838 {
9839   unformat_input_t *input = vam->input;
9840   vl_api_ioam_enable_t *mp;
9841   u32 id = 0;
9842   int has_trace_option = 0;
9843   int has_pot_option = 0;
9844   int has_seqno_option = 0;
9845   int has_analyse_option = 0;
9846   int ret;
9847
9848   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9849     {
9850       if (unformat (input, "trace"))
9851         has_trace_option = 1;
9852       else if (unformat (input, "pot"))
9853         has_pot_option = 1;
9854       else if (unformat (input, "seqno"))
9855         has_seqno_option = 1;
9856       else if (unformat (input, "analyse"))
9857         has_analyse_option = 1;
9858       else
9859         break;
9860     }
9861   M (IOAM_ENABLE, mp);
9862   mp->id = htons (id);
9863   mp->seqno = has_seqno_option;
9864   mp->analyse = has_analyse_option;
9865   mp->pot_enable = has_pot_option;
9866   mp->trace_enable = has_trace_option;
9867
9868   S (mp);
9869   W (ret);
9870   return ret;
9871 }
9872
9873
9874 static int
9875 api_ioam_disable (vat_main_t * vam)
9876 {
9877   vl_api_ioam_disable_t *mp;
9878   int ret;
9879
9880   M (IOAM_DISABLE, mp);
9881   S (mp);
9882   W (ret);
9883   return ret;
9884 }
9885
9886 #define foreach_tcp_proto_field                 \
9887 _(src_port)                                     \
9888 _(dst_port)
9889
9890 #define foreach_udp_proto_field                 \
9891 _(src_port)                                     \
9892 _(dst_port)
9893
9894 #define foreach_ip4_proto_field                 \
9895 _(src_address)                                  \
9896 _(dst_address)                                  \
9897 _(tos)                                          \
9898 _(length)                                       \
9899 _(fragment_id)                                  \
9900 _(ttl)                                          \
9901 _(protocol)                                     \
9902 _(checksum)
9903
9904 typedef struct
9905 {
9906   u16 src_port, dst_port;
9907 } tcpudp_header_t;
9908
9909 #if VPP_API_TEST_BUILTIN == 0
9910 uword
9911 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9912 {
9913   u8 **maskp = va_arg (*args, u8 **);
9914   u8 *mask = 0;
9915   u8 found_something = 0;
9916   tcp_header_t *tcp;
9917
9918 #define _(a) u8 a=0;
9919   foreach_tcp_proto_field;
9920 #undef _
9921
9922   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9923     {
9924       if (0);
9925 #define _(a) else if (unformat (input, #a)) a=1;
9926       foreach_tcp_proto_field
9927 #undef _
9928         else
9929         break;
9930     }
9931
9932 #define _(a) found_something += a;
9933   foreach_tcp_proto_field;
9934 #undef _
9935
9936   if (found_something == 0)
9937     return 0;
9938
9939   vec_validate (mask, sizeof (*tcp) - 1);
9940
9941   tcp = (tcp_header_t *) mask;
9942
9943 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
9944   foreach_tcp_proto_field;
9945 #undef _
9946
9947   *maskp = mask;
9948   return 1;
9949 }
9950
9951 uword
9952 unformat_udp_mask (unformat_input_t * input, va_list * args)
9953 {
9954   u8 **maskp = va_arg (*args, u8 **);
9955   u8 *mask = 0;
9956   u8 found_something = 0;
9957   udp_header_t *udp;
9958
9959 #define _(a) u8 a=0;
9960   foreach_udp_proto_field;
9961 #undef _
9962
9963   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9964     {
9965       if (0);
9966 #define _(a) else if (unformat (input, #a)) a=1;
9967       foreach_udp_proto_field
9968 #undef _
9969         else
9970         break;
9971     }
9972
9973 #define _(a) found_something += a;
9974   foreach_udp_proto_field;
9975 #undef _
9976
9977   if (found_something == 0)
9978     return 0;
9979
9980   vec_validate (mask, sizeof (*udp) - 1);
9981
9982   udp = (udp_header_t *) mask;
9983
9984 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
9985   foreach_udp_proto_field;
9986 #undef _
9987
9988   *maskp = mask;
9989   return 1;
9990 }
9991
9992 uword
9993 unformat_l4_mask (unformat_input_t * input, va_list * args)
9994 {
9995   u8 **maskp = va_arg (*args, u8 **);
9996   u16 src_port = 0, dst_port = 0;
9997   tcpudp_header_t *tcpudp;
9998
9999   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10000     {
10001       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10002         return 1;
10003       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10004         return 1;
10005       else if (unformat (input, "src_port"))
10006         src_port = 0xFFFF;
10007       else if (unformat (input, "dst_port"))
10008         dst_port = 0xFFFF;
10009       else
10010         return 0;
10011     }
10012
10013   if (!src_port && !dst_port)
10014     return 0;
10015
10016   u8 *mask = 0;
10017   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10018
10019   tcpudp = (tcpudp_header_t *) mask;
10020   tcpudp->src_port = src_port;
10021   tcpudp->dst_port = dst_port;
10022
10023   *maskp = mask;
10024
10025   return 1;
10026 }
10027
10028 uword
10029 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10030 {
10031   u8 **maskp = va_arg (*args, u8 **);
10032   u8 *mask = 0;
10033   u8 found_something = 0;
10034   ip4_header_t *ip;
10035
10036 #define _(a) u8 a=0;
10037   foreach_ip4_proto_field;
10038 #undef _
10039   u8 version = 0;
10040   u8 hdr_length = 0;
10041
10042
10043   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10044     {
10045       if (unformat (input, "version"))
10046         version = 1;
10047       else if (unformat (input, "hdr_length"))
10048         hdr_length = 1;
10049       else if (unformat (input, "src"))
10050         src_address = 1;
10051       else if (unformat (input, "dst"))
10052         dst_address = 1;
10053       else if (unformat (input, "proto"))
10054         protocol = 1;
10055
10056 #define _(a) else if (unformat (input, #a)) a=1;
10057       foreach_ip4_proto_field
10058 #undef _
10059         else
10060         break;
10061     }
10062
10063 #define _(a) found_something += a;
10064   foreach_ip4_proto_field;
10065 #undef _
10066
10067   if (found_something == 0)
10068     return 0;
10069
10070   vec_validate (mask, sizeof (*ip) - 1);
10071
10072   ip = (ip4_header_t *) mask;
10073
10074 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10075   foreach_ip4_proto_field;
10076 #undef _
10077
10078   ip->ip_version_and_header_length = 0;
10079
10080   if (version)
10081     ip->ip_version_and_header_length |= 0xF0;
10082
10083   if (hdr_length)
10084     ip->ip_version_and_header_length |= 0x0F;
10085
10086   *maskp = mask;
10087   return 1;
10088 }
10089
10090 #define foreach_ip6_proto_field                 \
10091 _(src_address)                                  \
10092 _(dst_address)                                  \
10093 _(payload_length)                               \
10094 _(hop_limit)                                    \
10095 _(protocol)
10096
10097 uword
10098 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10099 {
10100   u8 **maskp = va_arg (*args, u8 **);
10101   u8 *mask = 0;
10102   u8 found_something = 0;
10103   ip6_header_t *ip;
10104   u32 ip_version_traffic_class_and_flow_label;
10105
10106 #define _(a) u8 a=0;
10107   foreach_ip6_proto_field;
10108 #undef _
10109   u8 version = 0;
10110   u8 traffic_class = 0;
10111   u8 flow_label = 0;
10112
10113   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10114     {
10115       if (unformat (input, "version"))
10116         version = 1;
10117       else if (unformat (input, "traffic-class"))
10118         traffic_class = 1;
10119       else if (unformat (input, "flow-label"))
10120         flow_label = 1;
10121       else if (unformat (input, "src"))
10122         src_address = 1;
10123       else if (unformat (input, "dst"))
10124         dst_address = 1;
10125       else if (unformat (input, "proto"))
10126         protocol = 1;
10127
10128 #define _(a) else if (unformat (input, #a)) a=1;
10129       foreach_ip6_proto_field
10130 #undef _
10131         else
10132         break;
10133     }
10134
10135 #define _(a) found_something += a;
10136   foreach_ip6_proto_field;
10137 #undef _
10138
10139   if (found_something == 0)
10140     return 0;
10141
10142   vec_validate (mask, sizeof (*ip) - 1);
10143
10144   ip = (ip6_header_t *) mask;
10145
10146 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10147   foreach_ip6_proto_field;
10148 #undef _
10149
10150   ip_version_traffic_class_and_flow_label = 0;
10151
10152   if (version)
10153     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10154
10155   if (traffic_class)
10156     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10157
10158   if (flow_label)
10159     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10160
10161   ip->ip_version_traffic_class_and_flow_label =
10162     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10163
10164   *maskp = mask;
10165   return 1;
10166 }
10167
10168 uword
10169 unformat_l3_mask (unformat_input_t * input, va_list * args)
10170 {
10171   u8 **maskp = va_arg (*args, u8 **);
10172
10173   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10174     {
10175       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10176         return 1;
10177       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10178         return 1;
10179       else
10180         break;
10181     }
10182   return 0;
10183 }
10184
10185 uword
10186 unformat_l2_mask (unformat_input_t * input, va_list * args)
10187 {
10188   u8 **maskp = va_arg (*args, u8 **);
10189   u8 *mask = 0;
10190   u8 src = 0;
10191   u8 dst = 0;
10192   u8 proto = 0;
10193   u8 tag1 = 0;
10194   u8 tag2 = 0;
10195   u8 ignore_tag1 = 0;
10196   u8 ignore_tag2 = 0;
10197   u8 cos1 = 0;
10198   u8 cos2 = 0;
10199   u8 dot1q = 0;
10200   u8 dot1ad = 0;
10201   int len = 14;
10202
10203   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10204     {
10205       if (unformat (input, "src"))
10206         src = 1;
10207       else if (unformat (input, "dst"))
10208         dst = 1;
10209       else if (unformat (input, "proto"))
10210         proto = 1;
10211       else if (unformat (input, "tag1"))
10212         tag1 = 1;
10213       else if (unformat (input, "tag2"))
10214         tag2 = 1;
10215       else if (unformat (input, "ignore-tag1"))
10216         ignore_tag1 = 1;
10217       else if (unformat (input, "ignore-tag2"))
10218         ignore_tag2 = 1;
10219       else if (unformat (input, "cos1"))
10220         cos1 = 1;
10221       else if (unformat (input, "cos2"))
10222         cos2 = 1;
10223       else if (unformat (input, "dot1q"))
10224         dot1q = 1;
10225       else if (unformat (input, "dot1ad"))
10226         dot1ad = 1;
10227       else
10228         break;
10229     }
10230   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10231        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10232     return 0;
10233
10234   if (tag1 || ignore_tag1 || cos1 || dot1q)
10235     len = 18;
10236   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10237     len = 22;
10238
10239   vec_validate (mask, len - 1);
10240
10241   if (dst)
10242     memset (mask, 0xff, 6);
10243
10244   if (src)
10245     memset (mask + 6, 0xff, 6);
10246
10247   if (tag2 || dot1ad)
10248     {
10249       /* inner vlan tag */
10250       if (tag2)
10251         {
10252           mask[19] = 0xff;
10253           mask[18] = 0x0f;
10254         }
10255       if (cos2)
10256         mask[18] |= 0xe0;
10257       if (proto)
10258         mask[21] = mask[20] = 0xff;
10259       if (tag1)
10260         {
10261           mask[15] = 0xff;
10262           mask[14] = 0x0f;
10263         }
10264       if (cos1)
10265         mask[14] |= 0xe0;
10266       *maskp = mask;
10267       return 1;
10268     }
10269   if (tag1 | dot1q)
10270     {
10271       if (tag1)
10272         {
10273           mask[15] = 0xff;
10274           mask[14] = 0x0f;
10275         }
10276       if (cos1)
10277         mask[14] |= 0xe0;
10278       if (proto)
10279         mask[16] = mask[17] = 0xff;
10280
10281       *maskp = mask;
10282       return 1;
10283     }
10284   if (cos2)
10285     mask[18] |= 0xe0;
10286   if (cos1)
10287     mask[14] |= 0xe0;
10288   if (proto)
10289     mask[12] = mask[13] = 0xff;
10290
10291   *maskp = mask;
10292   return 1;
10293 }
10294
10295 uword
10296 unformat_classify_mask (unformat_input_t * input, va_list * args)
10297 {
10298   u8 **maskp = va_arg (*args, u8 **);
10299   u32 *skipp = va_arg (*args, u32 *);
10300   u32 *matchp = va_arg (*args, u32 *);
10301   u32 match;
10302   u8 *mask = 0;
10303   u8 *l2 = 0;
10304   u8 *l3 = 0;
10305   u8 *l4 = 0;
10306   int i;
10307
10308   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10309     {
10310       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10311         ;
10312       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10313         ;
10314       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10315         ;
10316       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10317         ;
10318       else
10319         break;
10320     }
10321
10322   if (l4 && !l3)
10323     {
10324       vec_free (mask);
10325       vec_free (l2);
10326       vec_free (l4);
10327       return 0;
10328     }
10329
10330   if (mask || l2 || l3 || l4)
10331     {
10332       if (l2 || l3 || l4)
10333         {
10334           /* "With a free Ethernet header in every package" */
10335           if (l2 == 0)
10336             vec_validate (l2, 13);
10337           mask = l2;
10338           if (vec_len (l3))
10339             {
10340               vec_append (mask, l3);
10341               vec_free (l3);
10342             }
10343           if (vec_len (l4))
10344             {
10345               vec_append (mask, l4);
10346               vec_free (l4);
10347             }
10348         }
10349
10350       /* Scan forward looking for the first significant mask octet */
10351       for (i = 0; i < vec_len (mask); i++)
10352         if (mask[i])
10353           break;
10354
10355       /* compute (skip, match) params */
10356       *skipp = i / sizeof (u32x4);
10357       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10358
10359       /* Pad mask to an even multiple of the vector size */
10360       while (vec_len (mask) % sizeof (u32x4))
10361         vec_add1 (mask, 0);
10362
10363       match = vec_len (mask) / sizeof (u32x4);
10364
10365       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10366         {
10367           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10368           if (*tmp || *(tmp + 1))
10369             break;
10370           match--;
10371         }
10372       if (match == 0)
10373         clib_warning ("BUG: match 0");
10374
10375       _vec_len (mask) = match * sizeof (u32x4);
10376
10377       *matchp = match;
10378       *maskp = mask;
10379
10380       return 1;
10381     }
10382
10383   return 0;
10384 }
10385 #endif /* VPP_API_TEST_BUILTIN */
10386
10387 #define foreach_l2_next                         \
10388 _(drop, DROP)                                   \
10389 _(ethernet, ETHERNET_INPUT)                     \
10390 _(ip4, IP4_INPUT)                               \
10391 _(ip6, IP6_INPUT)
10392
10393 uword
10394 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10395 {
10396   u32 *miss_next_indexp = va_arg (*args, u32 *);
10397   u32 next_index = 0;
10398   u32 tmp;
10399
10400 #define _(n,N) \
10401   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10402   foreach_l2_next;
10403 #undef _
10404
10405   if (unformat (input, "%d", &tmp))
10406     {
10407       next_index = tmp;
10408       goto out;
10409     }
10410
10411   return 0;
10412
10413 out:
10414   *miss_next_indexp = next_index;
10415   return 1;
10416 }
10417
10418 #define foreach_ip_next                         \
10419 _(drop, DROP)                                   \
10420 _(local, LOCAL)                                 \
10421 _(rewrite, REWRITE)
10422
10423 uword
10424 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10425 {
10426   u32 *miss_next_indexp = va_arg (*args, u32 *);
10427   u32 next_index = 0;
10428   u32 tmp;
10429
10430 #define _(n,N) \
10431   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10432   foreach_ip_next;
10433 #undef _
10434
10435   if (unformat (input, "%d", &tmp))
10436     {
10437       next_index = tmp;
10438       goto out;
10439     }
10440
10441   return 0;
10442
10443 out:
10444   *miss_next_indexp = next_index;
10445   return 1;
10446 }
10447
10448 #define foreach_acl_next                        \
10449 _(deny, DENY)
10450
10451 uword
10452 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10453 {
10454   u32 *miss_next_indexp = va_arg (*args, u32 *);
10455   u32 next_index = 0;
10456   u32 tmp;
10457
10458 #define _(n,N) \
10459   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10460   foreach_acl_next;
10461 #undef _
10462
10463   if (unformat (input, "permit"))
10464     {
10465       next_index = ~0;
10466       goto out;
10467     }
10468   else if (unformat (input, "%d", &tmp))
10469     {
10470       next_index = tmp;
10471       goto out;
10472     }
10473
10474   return 0;
10475
10476 out:
10477   *miss_next_indexp = next_index;
10478   return 1;
10479 }
10480
10481 uword
10482 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10483 {
10484   u32 *r = va_arg (*args, u32 *);
10485
10486   if (unformat (input, "conform-color"))
10487     *r = POLICE_CONFORM;
10488   else if (unformat (input, "exceed-color"))
10489     *r = POLICE_EXCEED;
10490   else
10491     return 0;
10492
10493   return 1;
10494 }
10495
10496 static int
10497 api_classify_add_del_table (vat_main_t * vam)
10498 {
10499   unformat_input_t *i = vam->input;
10500   vl_api_classify_add_del_table_t *mp;
10501
10502   u32 nbuckets = 2;
10503   u32 skip = ~0;
10504   u32 match = ~0;
10505   int is_add = 1;
10506   int del_chain = 0;
10507   u32 table_index = ~0;
10508   u32 next_table_index = ~0;
10509   u32 miss_next_index = ~0;
10510   u32 memory_size = 32 << 20;
10511   u8 *mask = 0;
10512   u32 current_data_flag = 0;
10513   int current_data_offset = 0;
10514   int ret;
10515
10516   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10517     {
10518       if (unformat (i, "del"))
10519         is_add = 0;
10520       else if (unformat (i, "del-chain"))
10521         {
10522           is_add = 0;
10523           del_chain = 1;
10524         }
10525       else if (unformat (i, "buckets %d", &nbuckets))
10526         ;
10527       else if (unformat (i, "memory_size %d", &memory_size))
10528         ;
10529       else if (unformat (i, "skip %d", &skip))
10530         ;
10531       else if (unformat (i, "match %d", &match))
10532         ;
10533       else if (unformat (i, "table %d", &table_index))
10534         ;
10535       else if (unformat (i, "mask %U", unformat_classify_mask,
10536                          &mask, &skip, &match))
10537         ;
10538       else if (unformat (i, "next-table %d", &next_table_index))
10539         ;
10540       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10541                          &miss_next_index))
10542         ;
10543       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10544                          &miss_next_index))
10545         ;
10546       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10547                          &miss_next_index))
10548         ;
10549       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10550         ;
10551       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10552         ;
10553       else
10554         break;
10555     }
10556
10557   if (is_add && mask == 0)
10558     {
10559       errmsg ("Mask required");
10560       return -99;
10561     }
10562
10563   if (is_add && skip == ~0)
10564     {
10565       errmsg ("skip count required");
10566       return -99;
10567     }
10568
10569   if (is_add && match == ~0)
10570     {
10571       errmsg ("match count required");
10572       return -99;
10573     }
10574
10575   if (!is_add && table_index == ~0)
10576     {
10577       errmsg ("table index required for delete");
10578       return -99;
10579     }
10580
10581   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10582
10583   mp->is_add = is_add;
10584   mp->del_chain = del_chain;
10585   mp->table_index = ntohl (table_index);
10586   mp->nbuckets = ntohl (nbuckets);
10587   mp->memory_size = ntohl (memory_size);
10588   mp->skip_n_vectors = ntohl (skip);
10589   mp->match_n_vectors = ntohl (match);
10590   mp->next_table_index = ntohl (next_table_index);
10591   mp->miss_next_index = ntohl (miss_next_index);
10592   mp->current_data_flag = ntohl (current_data_flag);
10593   mp->current_data_offset = ntohl (current_data_offset);
10594   clib_memcpy (mp->mask, mask, vec_len (mask));
10595
10596   vec_free (mask);
10597
10598   S (mp);
10599   W (ret);
10600   return ret;
10601 }
10602
10603 #if VPP_API_TEST_BUILTIN == 0
10604 uword
10605 unformat_l4_match (unformat_input_t * input, va_list * args)
10606 {
10607   u8 **matchp = va_arg (*args, u8 **);
10608
10609   u8 *proto_header = 0;
10610   int src_port = 0;
10611   int dst_port = 0;
10612
10613   tcpudp_header_t h;
10614
10615   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10616     {
10617       if (unformat (input, "src_port %d", &src_port))
10618         ;
10619       else if (unformat (input, "dst_port %d", &dst_port))
10620         ;
10621       else
10622         return 0;
10623     }
10624
10625   h.src_port = clib_host_to_net_u16 (src_port);
10626   h.dst_port = clib_host_to_net_u16 (dst_port);
10627   vec_validate (proto_header, sizeof (h) - 1);
10628   memcpy (proto_header, &h, sizeof (h));
10629
10630   *matchp = proto_header;
10631
10632   return 1;
10633 }
10634
10635 uword
10636 unformat_ip4_match (unformat_input_t * input, va_list * args)
10637 {
10638   u8 **matchp = va_arg (*args, u8 **);
10639   u8 *match = 0;
10640   ip4_header_t *ip;
10641   int version = 0;
10642   u32 version_val;
10643   int hdr_length = 0;
10644   u32 hdr_length_val;
10645   int src = 0, dst = 0;
10646   ip4_address_t src_val, dst_val;
10647   int proto = 0;
10648   u32 proto_val;
10649   int tos = 0;
10650   u32 tos_val;
10651   int length = 0;
10652   u32 length_val;
10653   int fragment_id = 0;
10654   u32 fragment_id_val;
10655   int ttl = 0;
10656   int ttl_val;
10657   int checksum = 0;
10658   u32 checksum_val;
10659
10660   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10661     {
10662       if (unformat (input, "version %d", &version_val))
10663         version = 1;
10664       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10665         hdr_length = 1;
10666       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10667         src = 1;
10668       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10669         dst = 1;
10670       else if (unformat (input, "proto %d", &proto_val))
10671         proto = 1;
10672       else if (unformat (input, "tos %d", &tos_val))
10673         tos = 1;
10674       else if (unformat (input, "length %d", &length_val))
10675         length = 1;
10676       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10677         fragment_id = 1;
10678       else if (unformat (input, "ttl %d", &ttl_val))
10679         ttl = 1;
10680       else if (unformat (input, "checksum %d", &checksum_val))
10681         checksum = 1;
10682       else
10683         break;
10684     }
10685
10686   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10687       + ttl + checksum == 0)
10688     return 0;
10689
10690   /*
10691    * Aligned because we use the real comparison functions
10692    */
10693   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10694
10695   ip = (ip4_header_t *) match;
10696
10697   /* These are realistically matched in practice */
10698   if (src)
10699     ip->src_address.as_u32 = src_val.as_u32;
10700
10701   if (dst)
10702     ip->dst_address.as_u32 = dst_val.as_u32;
10703
10704   if (proto)
10705     ip->protocol = proto_val;
10706
10707
10708   /* These are not, but they're included for completeness */
10709   if (version)
10710     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10711
10712   if (hdr_length)
10713     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10714
10715   if (tos)
10716     ip->tos = tos_val;
10717
10718   if (length)
10719     ip->length = clib_host_to_net_u16 (length_val);
10720
10721   if (ttl)
10722     ip->ttl = ttl_val;
10723
10724   if (checksum)
10725     ip->checksum = clib_host_to_net_u16 (checksum_val);
10726
10727   *matchp = match;
10728   return 1;
10729 }
10730
10731 uword
10732 unformat_ip6_match (unformat_input_t * input, va_list * args)
10733 {
10734   u8 **matchp = va_arg (*args, u8 **);
10735   u8 *match = 0;
10736   ip6_header_t *ip;
10737   int version = 0;
10738   u32 version_val;
10739   u8 traffic_class = 0;
10740   u32 traffic_class_val = 0;
10741   u8 flow_label = 0;
10742   u8 flow_label_val;
10743   int src = 0, dst = 0;
10744   ip6_address_t src_val, dst_val;
10745   int proto = 0;
10746   u32 proto_val;
10747   int payload_length = 0;
10748   u32 payload_length_val;
10749   int hop_limit = 0;
10750   int hop_limit_val;
10751   u32 ip_version_traffic_class_and_flow_label;
10752
10753   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10754     {
10755       if (unformat (input, "version %d", &version_val))
10756         version = 1;
10757       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10758         traffic_class = 1;
10759       else if (unformat (input, "flow_label %d", &flow_label_val))
10760         flow_label = 1;
10761       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10762         src = 1;
10763       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10764         dst = 1;
10765       else if (unformat (input, "proto %d", &proto_val))
10766         proto = 1;
10767       else if (unformat (input, "payload_length %d", &payload_length_val))
10768         payload_length = 1;
10769       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10770         hop_limit = 1;
10771       else
10772         break;
10773     }
10774
10775   if (version + traffic_class + flow_label + src + dst + proto +
10776       payload_length + hop_limit == 0)
10777     return 0;
10778
10779   /*
10780    * Aligned because we use the real comparison functions
10781    */
10782   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10783
10784   ip = (ip6_header_t *) match;
10785
10786   if (src)
10787     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10788
10789   if (dst)
10790     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10791
10792   if (proto)
10793     ip->protocol = proto_val;
10794
10795   ip_version_traffic_class_and_flow_label = 0;
10796
10797   if (version)
10798     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10799
10800   if (traffic_class)
10801     ip_version_traffic_class_and_flow_label |=
10802       (traffic_class_val & 0xFF) << 20;
10803
10804   if (flow_label)
10805     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10806
10807   ip->ip_version_traffic_class_and_flow_label =
10808     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10809
10810   if (payload_length)
10811     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10812
10813   if (hop_limit)
10814     ip->hop_limit = hop_limit_val;
10815
10816   *matchp = match;
10817   return 1;
10818 }
10819
10820 uword
10821 unformat_l3_match (unformat_input_t * input, va_list * args)
10822 {
10823   u8 **matchp = va_arg (*args, u8 **);
10824
10825   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10826     {
10827       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10828         return 1;
10829       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10830         return 1;
10831       else
10832         break;
10833     }
10834   return 0;
10835 }
10836
10837 uword
10838 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10839 {
10840   u8 *tagp = va_arg (*args, u8 *);
10841   u32 tag;
10842
10843   if (unformat (input, "%d", &tag))
10844     {
10845       tagp[0] = (tag >> 8) & 0x0F;
10846       tagp[1] = tag & 0xFF;
10847       return 1;
10848     }
10849
10850   return 0;
10851 }
10852
10853 uword
10854 unformat_l2_match (unformat_input_t * input, va_list * args)
10855 {
10856   u8 **matchp = va_arg (*args, u8 **);
10857   u8 *match = 0;
10858   u8 src = 0;
10859   u8 src_val[6];
10860   u8 dst = 0;
10861   u8 dst_val[6];
10862   u8 proto = 0;
10863   u16 proto_val;
10864   u8 tag1 = 0;
10865   u8 tag1_val[2];
10866   u8 tag2 = 0;
10867   u8 tag2_val[2];
10868   int len = 14;
10869   u8 ignore_tag1 = 0;
10870   u8 ignore_tag2 = 0;
10871   u8 cos1 = 0;
10872   u8 cos2 = 0;
10873   u32 cos1_val = 0;
10874   u32 cos2_val = 0;
10875
10876   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10877     {
10878       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10879         src = 1;
10880       else
10881         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10882         dst = 1;
10883       else if (unformat (input, "proto %U",
10884                          unformat_ethernet_type_host_byte_order, &proto_val))
10885         proto = 1;
10886       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10887         tag1 = 1;
10888       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10889         tag2 = 1;
10890       else if (unformat (input, "ignore-tag1"))
10891         ignore_tag1 = 1;
10892       else if (unformat (input, "ignore-tag2"))
10893         ignore_tag2 = 1;
10894       else if (unformat (input, "cos1 %d", &cos1_val))
10895         cos1 = 1;
10896       else if (unformat (input, "cos2 %d", &cos2_val))
10897         cos2 = 1;
10898       else
10899         break;
10900     }
10901   if ((src + dst + proto + tag1 + tag2 +
10902        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10903     return 0;
10904
10905   if (tag1 || ignore_tag1 || cos1)
10906     len = 18;
10907   if (tag2 || ignore_tag2 || cos2)
10908     len = 22;
10909
10910   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10911
10912   if (dst)
10913     clib_memcpy (match, dst_val, 6);
10914
10915   if (src)
10916     clib_memcpy (match + 6, src_val, 6);
10917
10918   if (tag2)
10919     {
10920       /* inner vlan tag */
10921       match[19] = tag2_val[1];
10922       match[18] = tag2_val[0];
10923       if (cos2)
10924         match[18] |= (cos2_val & 0x7) << 5;
10925       if (proto)
10926         {
10927           match[21] = proto_val & 0xff;
10928           match[20] = proto_val >> 8;
10929         }
10930       if (tag1)
10931         {
10932           match[15] = tag1_val[1];
10933           match[14] = tag1_val[0];
10934         }
10935       if (cos1)
10936         match[14] |= (cos1_val & 0x7) << 5;
10937       *matchp = match;
10938       return 1;
10939     }
10940   if (tag1)
10941     {
10942       match[15] = tag1_val[1];
10943       match[14] = tag1_val[0];
10944       if (proto)
10945         {
10946           match[17] = proto_val & 0xff;
10947           match[16] = proto_val >> 8;
10948         }
10949       if (cos1)
10950         match[14] |= (cos1_val & 0x7) << 5;
10951
10952       *matchp = match;
10953       return 1;
10954     }
10955   if (cos2)
10956     match[18] |= (cos2_val & 0x7) << 5;
10957   if (cos1)
10958     match[14] |= (cos1_val & 0x7) << 5;
10959   if (proto)
10960     {
10961       match[13] = proto_val & 0xff;
10962       match[12] = proto_val >> 8;
10963     }
10964
10965   *matchp = match;
10966   return 1;
10967 }
10968 #endif
10969
10970 uword
10971 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10972 {
10973   u8 **matchp = va_arg (*args, u8 **);
10974   u32 skip_n_vectors = va_arg (*args, u32);
10975   u32 match_n_vectors = va_arg (*args, u32);
10976
10977   u8 *match = 0;
10978   u8 *l2 = 0;
10979   u8 *l3 = 0;
10980   u8 *l4 = 0;
10981
10982   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10983     {
10984       if (unformat (input, "hex %U", unformat_hex_string, &match))
10985         ;
10986       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10987         ;
10988       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10989         ;
10990       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10991         ;
10992       else
10993         break;
10994     }
10995
10996   if (l4 && !l3)
10997     {
10998       vec_free (match);
10999       vec_free (l2);
11000       vec_free (l4);
11001       return 0;
11002     }
11003
11004   if (match || l2 || l3 || l4)
11005     {
11006       if (l2 || l3 || l4)
11007         {
11008           /* "Win a free Ethernet header in every packet" */
11009           if (l2 == 0)
11010             vec_validate_aligned (l2, 13, sizeof (u32x4));
11011           match = l2;
11012           if (vec_len (l3))
11013             {
11014               vec_append_aligned (match, l3, sizeof (u32x4));
11015               vec_free (l3);
11016             }
11017           if (vec_len (l4))
11018             {
11019               vec_append_aligned (match, l4, sizeof (u32x4));
11020               vec_free (l4);
11021             }
11022         }
11023
11024       /* Make sure the vector is big enough even if key is all 0's */
11025       vec_validate_aligned
11026         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11027          sizeof (u32x4));
11028
11029       /* Set size, include skipped vectors */
11030       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11031
11032       *matchp = match;
11033
11034       return 1;
11035     }
11036
11037   return 0;
11038 }
11039
11040 static int
11041 api_classify_add_del_session (vat_main_t * vam)
11042 {
11043   unformat_input_t *i = vam->input;
11044   vl_api_classify_add_del_session_t *mp;
11045   int is_add = 1;
11046   u32 table_index = ~0;
11047   u32 hit_next_index = ~0;
11048   u32 opaque_index = ~0;
11049   u8 *match = 0;
11050   i32 advance = 0;
11051   u32 skip_n_vectors = 0;
11052   u32 match_n_vectors = 0;
11053   u32 action = 0;
11054   u32 metadata = 0;
11055   int ret;
11056
11057   /*
11058    * Warning: you have to supply skip_n and match_n
11059    * because the API client cant simply look at the classify
11060    * table object.
11061    */
11062
11063   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11064     {
11065       if (unformat (i, "del"))
11066         is_add = 0;
11067       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11068                          &hit_next_index))
11069         ;
11070       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11071                          &hit_next_index))
11072         ;
11073       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11074                          &hit_next_index))
11075         ;
11076       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11077         ;
11078       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11079         ;
11080       else if (unformat (i, "opaque-index %d", &opaque_index))
11081         ;
11082       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11083         ;
11084       else if (unformat (i, "match_n %d", &match_n_vectors))
11085         ;
11086       else if (unformat (i, "match %U", api_unformat_classify_match,
11087                          &match, skip_n_vectors, match_n_vectors))
11088         ;
11089       else if (unformat (i, "advance %d", &advance))
11090         ;
11091       else if (unformat (i, "table-index %d", &table_index))
11092         ;
11093       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11094         action = 1;
11095       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11096         action = 2;
11097       else if (unformat (i, "action %d", &action))
11098         ;
11099       else if (unformat (i, "metadata %d", &metadata))
11100         ;
11101       else
11102         break;
11103     }
11104
11105   if (table_index == ~0)
11106     {
11107       errmsg ("Table index required");
11108       return -99;
11109     }
11110
11111   if (is_add && match == 0)
11112     {
11113       errmsg ("Match value required");
11114       return -99;
11115     }
11116
11117   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11118
11119   mp->is_add = is_add;
11120   mp->table_index = ntohl (table_index);
11121   mp->hit_next_index = ntohl (hit_next_index);
11122   mp->opaque_index = ntohl (opaque_index);
11123   mp->advance = ntohl (advance);
11124   mp->action = action;
11125   mp->metadata = ntohl (metadata);
11126   clib_memcpy (mp->match, match, vec_len (match));
11127   vec_free (match);
11128
11129   S (mp);
11130   W (ret);
11131   return ret;
11132 }
11133
11134 static int
11135 api_classify_set_interface_ip_table (vat_main_t * vam)
11136 {
11137   unformat_input_t *i = vam->input;
11138   vl_api_classify_set_interface_ip_table_t *mp;
11139   u32 sw_if_index;
11140   int sw_if_index_set;
11141   u32 table_index = ~0;
11142   u8 is_ipv6 = 0;
11143   int ret;
11144
11145   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11146     {
11147       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11148         sw_if_index_set = 1;
11149       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11150         sw_if_index_set = 1;
11151       else if (unformat (i, "table %d", &table_index))
11152         ;
11153       else
11154         {
11155           clib_warning ("parse error '%U'", format_unformat_error, i);
11156           return -99;
11157         }
11158     }
11159
11160   if (sw_if_index_set == 0)
11161     {
11162       errmsg ("missing interface name or sw_if_index");
11163       return -99;
11164     }
11165
11166
11167   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11168
11169   mp->sw_if_index = ntohl (sw_if_index);
11170   mp->table_index = ntohl (table_index);
11171   mp->is_ipv6 = is_ipv6;
11172
11173   S (mp);
11174   W (ret);
11175   return ret;
11176 }
11177
11178 static int
11179 api_classify_set_interface_l2_tables (vat_main_t * vam)
11180 {
11181   unformat_input_t *i = vam->input;
11182   vl_api_classify_set_interface_l2_tables_t *mp;
11183   u32 sw_if_index;
11184   int sw_if_index_set;
11185   u32 ip4_table_index = ~0;
11186   u32 ip6_table_index = ~0;
11187   u32 other_table_index = ~0;
11188   u32 is_input = 1;
11189   int ret;
11190
11191   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11192     {
11193       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11194         sw_if_index_set = 1;
11195       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11196         sw_if_index_set = 1;
11197       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11198         ;
11199       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11200         ;
11201       else if (unformat (i, "other-table %d", &other_table_index))
11202         ;
11203       else if (unformat (i, "is-input %d", &is_input))
11204         ;
11205       else
11206         {
11207           clib_warning ("parse error '%U'", format_unformat_error, i);
11208           return -99;
11209         }
11210     }
11211
11212   if (sw_if_index_set == 0)
11213     {
11214       errmsg ("missing interface name or sw_if_index");
11215       return -99;
11216     }
11217
11218
11219   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11220
11221   mp->sw_if_index = ntohl (sw_if_index);
11222   mp->ip4_table_index = ntohl (ip4_table_index);
11223   mp->ip6_table_index = ntohl (ip6_table_index);
11224   mp->other_table_index = ntohl (other_table_index);
11225   mp->is_input = (u8) is_input;
11226
11227   S (mp);
11228   W (ret);
11229   return ret;
11230 }
11231
11232 static int
11233 api_set_ipfix_exporter (vat_main_t * vam)
11234 {
11235   unformat_input_t *i = vam->input;
11236   vl_api_set_ipfix_exporter_t *mp;
11237   ip4_address_t collector_address;
11238   u8 collector_address_set = 0;
11239   u32 collector_port = ~0;
11240   ip4_address_t src_address;
11241   u8 src_address_set = 0;
11242   u32 vrf_id = ~0;
11243   u32 path_mtu = ~0;
11244   u32 template_interval = ~0;
11245   u8 udp_checksum = 0;
11246   int ret;
11247
11248   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11249     {
11250       if (unformat (i, "collector_address %U", unformat_ip4_address,
11251                     &collector_address))
11252         collector_address_set = 1;
11253       else if (unformat (i, "collector_port %d", &collector_port))
11254         ;
11255       else if (unformat (i, "src_address %U", unformat_ip4_address,
11256                          &src_address))
11257         src_address_set = 1;
11258       else if (unformat (i, "vrf_id %d", &vrf_id))
11259         ;
11260       else if (unformat (i, "path_mtu %d", &path_mtu))
11261         ;
11262       else if (unformat (i, "template_interval %d", &template_interval))
11263         ;
11264       else if (unformat (i, "udp_checksum"))
11265         udp_checksum = 1;
11266       else
11267         break;
11268     }
11269
11270   if (collector_address_set == 0)
11271     {
11272       errmsg ("collector_address required");
11273       return -99;
11274     }
11275
11276   if (src_address_set == 0)
11277     {
11278       errmsg ("src_address required");
11279       return -99;
11280     }
11281
11282   M (SET_IPFIX_EXPORTER, mp);
11283
11284   memcpy (mp->collector_address, collector_address.data,
11285           sizeof (collector_address.data));
11286   mp->collector_port = htons ((u16) collector_port);
11287   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11288   mp->vrf_id = htonl (vrf_id);
11289   mp->path_mtu = htonl (path_mtu);
11290   mp->template_interval = htonl (template_interval);
11291   mp->udp_checksum = udp_checksum;
11292
11293   S (mp);
11294   W (ret);
11295   return ret;
11296 }
11297
11298 static int
11299 api_set_ipfix_classify_stream (vat_main_t * vam)
11300 {
11301   unformat_input_t *i = vam->input;
11302   vl_api_set_ipfix_classify_stream_t *mp;
11303   u32 domain_id = 0;
11304   u32 src_port = UDP_DST_PORT_ipfix;
11305   int ret;
11306
11307   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11308     {
11309       if (unformat (i, "domain %d", &domain_id))
11310         ;
11311       else if (unformat (i, "src_port %d", &src_port))
11312         ;
11313       else
11314         {
11315           errmsg ("unknown input `%U'", format_unformat_error, i);
11316           return -99;
11317         }
11318     }
11319
11320   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11321
11322   mp->domain_id = htonl (domain_id);
11323   mp->src_port = htons ((u16) src_port);
11324
11325   S (mp);
11326   W (ret);
11327   return ret;
11328 }
11329
11330 static int
11331 api_ipfix_classify_table_add_del (vat_main_t * vam)
11332 {
11333   unformat_input_t *i = vam->input;
11334   vl_api_ipfix_classify_table_add_del_t *mp;
11335   int is_add = -1;
11336   u32 classify_table_index = ~0;
11337   u8 ip_version = 0;
11338   u8 transport_protocol = 255;
11339   int ret;
11340
11341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11342     {
11343       if (unformat (i, "add"))
11344         is_add = 1;
11345       else if (unformat (i, "del"))
11346         is_add = 0;
11347       else if (unformat (i, "table %d", &classify_table_index))
11348         ;
11349       else if (unformat (i, "ip4"))
11350         ip_version = 4;
11351       else if (unformat (i, "ip6"))
11352         ip_version = 6;
11353       else if (unformat (i, "tcp"))
11354         transport_protocol = 6;
11355       else if (unformat (i, "udp"))
11356         transport_protocol = 17;
11357       else
11358         {
11359           errmsg ("unknown input `%U'", format_unformat_error, i);
11360           return -99;
11361         }
11362     }
11363
11364   if (is_add == -1)
11365     {
11366       errmsg ("expecting: add|del");
11367       return -99;
11368     }
11369   if (classify_table_index == ~0)
11370     {
11371       errmsg ("classifier table not specified");
11372       return -99;
11373     }
11374   if (ip_version == 0)
11375     {
11376       errmsg ("IP version not specified");
11377       return -99;
11378     }
11379
11380   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11381
11382   mp->is_add = is_add;
11383   mp->table_id = htonl (classify_table_index);
11384   mp->ip_version = ip_version;
11385   mp->transport_protocol = transport_protocol;
11386
11387   S (mp);
11388   W (ret);
11389   return ret;
11390 }
11391
11392 static int
11393 api_get_node_index (vat_main_t * vam)
11394 {
11395   unformat_input_t *i = vam->input;
11396   vl_api_get_node_index_t *mp;
11397   u8 *name = 0;
11398   int ret;
11399
11400   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11401     {
11402       if (unformat (i, "node %s", &name))
11403         ;
11404       else
11405         break;
11406     }
11407   if (name == 0)
11408     {
11409       errmsg ("node name required");
11410       return -99;
11411     }
11412   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11413     {
11414       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11415       return -99;
11416     }
11417
11418   M (GET_NODE_INDEX, mp);
11419   clib_memcpy (mp->node_name, name, vec_len (name));
11420   vec_free (name);
11421
11422   S (mp);
11423   W (ret);
11424   return ret;
11425 }
11426
11427 static int
11428 api_get_next_index (vat_main_t * vam)
11429 {
11430   unformat_input_t *i = vam->input;
11431   vl_api_get_next_index_t *mp;
11432   u8 *node_name = 0, *next_node_name = 0;
11433   int ret;
11434
11435   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11436     {
11437       if (unformat (i, "node-name %s", &node_name))
11438         ;
11439       else if (unformat (i, "next-node-name %s", &next_node_name))
11440         break;
11441     }
11442
11443   if (node_name == 0)
11444     {
11445       errmsg ("node name required");
11446       return -99;
11447     }
11448   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11449     {
11450       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11451       return -99;
11452     }
11453
11454   if (next_node_name == 0)
11455     {
11456       errmsg ("next node name required");
11457       return -99;
11458     }
11459   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11460     {
11461       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11462       return -99;
11463     }
11464
11465   M (GET_NEXT_INDEX, mp);
11466   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11467   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11468   vec_free (node_name);
11469   vec_free (next_node_name);
11470
11471   S (mp);
11472   W (ret);
11473   return ret;
11474 }
11475
11476 static int
11477 api_add_node_next (vat_main_t * vam)
11478 {
11479   unformat_input_t *i = vam->input;
11480   vl_api_add_node_next_t *mp;
11481   u8 *name = 0;
11482   u8 *next = 0;
11483   int ret;
11484
11485   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11486     {
11487       if (unformat (i, "node %s", &name))
11488         ;
11489       else if (unformat (i, "next %s", &next))
11490         ;
11491       else
11492         break;
11493     }
11494   if (name == 0)
11495     {
11496       errmsg ("node name required");
11497       return -99;
11498     }
11499   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11500     {
11501       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11502       return -99;
11503     }
11504   if (next == 0)
11505     {
11506       errmsg ("next node required");
11507       return -99;
11508     }
11509   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11510     {
11511       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11512       return -99;
11513     }
11514
11515   M (ADD_NODE_NEXT, mp);
11516   clib_memcpy (mp->node_name, name, vec_len (name));
11517   clib_memcpy (mp->next_name, next, vec_len (next));
11518   vec_free (name);
11519   vec_free (next);
11520
11521   S (mp);
11522   W (ret);
11523   return ret;
11524 }
11525
11526 static int
11527 api_l2tpv3_create_tunnel (vat_main_t * vam)
11528 {
11529   unformat_input_t *i = vam->input;
11530   ip6_address_t client_address, our_address;
11531   int client_address_set = 0;
11532   int our_address_set = 0;
11533   u32 local_session_id = 0;
11534   u32 remote_session_id = 0;
11535   u64 local_cookie = 0;
11536   u64 remote_cookie = 0;
11537   u8 l2_sublayer_present = 0;
11538   vl_api_l2tpv3_create_tunnel_t *mp;
11539   int ret;
11540
11541   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11542     {
11543       if (unformat (i, "client_address %U", unformat_ip6_address,
11544                     &client_address))
11545         client_address_set = 1;
11546       else if (unformat (i, "our_address %U", unformat_ip6_address,
11547                          &our_address))
11548         our_address_set = 1;
11549       else if (unformat (i, "local_session_id %d", &local_session_id))
11550         ;
11551       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11552         ;
11553       else if (unformat (i, "local_cookie %lld", &local_cookie))
11554         ;
11555       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11556         ;
11557       else if (unformat (i, "l2-sublayer-present"))
11558         l2_sublayer_present = 1;
11559       else
11560         break;
11561     }
11562
11563   if (client_address_set == 0)
11564     {
11565       errmsg ("client_address required");
11566       return -99;
11567     }
11568
11569   if (our_address_set == 0)
11570     {
11571       errmsg ("our_address required");
11572       return -99;
11573     }
11574
11575   M (L2TPV3_CREATE_TUNNEL, mp);
11576
11577   clib_memcpy (mp->client_address, client_address.as_u8,
11578                sizeof (mp->client_address));
11579
11580   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11581
11582   mp->local_session_id = ntohl (local_session_id);
11583   mp->remote_session_id = ntohl (remote_session_id);
11584   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11585   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11586   mp->l2_sublayer_present = l2_sublayer_present;
11587   mp->is_ipv6 = 1;
11588
11589   S (mp);
11590   W (ret);
11591   return ret;
11592 }
11593
11594 static int
11595 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11596 {
11597   unformat_input_t *i = vam->input;
11598   u32 sw_if_index;
11599   u8 sw_if_index_set = 0;
11600   u64 new_local_cookie = 0;
11601   u64 new_remote_cookie = 0;
11602   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11603   int ret;
11604
11605   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11606     {
11607       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11608         sw_if_index_set = 1;
11609       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11610         sw_if_index_set = 1;
11611       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11612         ;
11613       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11614         ;
11615       else
11616         break;
11617     }
11618
11619   if (sw_if_index_set == 0)
11620     {
11621       errmsg ("missing interface name or sw_if_index");
11622       return -99;
11623     }
11624
11625   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11626
11627   mp->sw_if_index = ntohl (sw_if_index);
11628   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11629   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11630
11631   S (mp);
11632   W (ret);
11633   return ret;
11634 }
11635
11636 static int
11637 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11638 {
11639   unformat_input_t *i = vam->input;
11640   vl_api_l2tpv3_interface_enable_disable_t *mp;
11641   u32 sw_if_index;
11642   u8 sw_if_index_set = 0;
11643   u8 enable_disable = 1;
11644   int ret;
11645
11646   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11647     {
11648       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11649         sw_if_index_set = 1;
11650       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11651         sw_if_index_set = 1;
11652       else if (unformat (i, "enable"))
11653         enable_disable = 1;
11654       else if (unformat (i, "disable"))
11655         enable_disable = 0;
11656       else
11657         break;
11658     }
11659
11660   if (sw_if_index_set == 0)
11661     {
11662       errmsg ("missing interface name or sw_if_index");
11663       return -99;
11664     }
11665
11666   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11667
11668   mp->sw_if_index = ntohl (sw_if_index);
11669   mp->enable_disable = enable_disable;
11670
11671   S (mp);
11672   W (ret);
11673   return ret;
11674 }
11675
11676 static int
11677 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11678 {
11679   unformat_input_t *i = vam->input;
11680   vl_api_l2tpv3_set_lookup_key_t *mp;
11681   u8 key = ~0;
11682   int ret;
11683
11684   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11685     {
11686       if (unformat (i, "lookup_v6_src"))
11687         key = L2T_LOOKUP_SRC_ADDRESS;
11688       else if (unformat (i, "lookup_v6_dst"))
11689         key = L2T_LOOKUP_DST_ADDRESS;
11690       else if (unformat (i, "lookup_session_id"))
11691         key = L2T_LOOKUP_SESSION_ID;
11692       else
11693         break;
11694     }
11695
11696   if (key == (u8) ~ 0)
11697     {
11698       errmsg ("l2tp session lookup key unset");
11699       return -99;
11700     }
11701
11702   M (L2TPV3_SET_LOOKUP_KEY, mp);
11703
11704   mp->key = key;
11705
11706   S (mp);
11707   W (ret);
11708   return ret;
11709 }
11710
11711 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11712   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11713 {
11714   vat_main_t *vam = &vat_main;
11715
11716   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11717          format_ip6_address, mp->our_address,
11718          format_ip6_address, mp->client_address,
11719          clib_net_to_host_u32 (mp->sw_if_index));
11720
11721   print (vam->ofp,
11722          "   local cookies %016llx %016llx remote cookie %016llx",
11723          clib_net_to_host_u64 (mp->local_cookie[0]),
11724          clib_net_to_host_u64 (mp->local_cookie[1]),
11725          clib_net_to_host_u64 (mp->remote_cookie));
11726
11727   print (vam->ofp, "   local session-id %d remote session-id %d",
11728          clib_net_to_host_u32 (mp->local_session_id),
11729          clib_net_to_host_u32 (mp->remote_session_id));
11730
11731   print (vam->ofp, "   l2 specific sublayer %s\n",
11732          mp->l2_sublayer_present ? "preset" : "absent");
11733
11734 }
11735
11736 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11737   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11738 {
11739   vat_main_t *vam = &vat_main;
11740   vat_json_node_t *node = NULL;
11741   struct in6_addr addr;
11742
11743   if (VAT_JSON_ARRAY != vam->json_tree.type)
11744     {
11745       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11746       vat_json_init_array (&vam->json_tree);
11747     }
11748   node = vat_json_array_add (&vam->json_tree);
11749
11750   vat_json_init_object (node);
11751
11752   clib_memcpy (&addr, mp->our_address, sizeof (addr));
11753   vat_json_object_add_ip6 (node, "our_address", addr);
11754   clib_memcpy (&addr, mp->client_address, sizeof (addr));
11755   vat_json_object_add_ip6 (node, "client_address", addr);
11756
11757   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11758   vat_json_init_array (lc);
11759   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11760   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11761   vat_json_object_add_uint (node, "remote_cookie",
11762                             clib_net_to_host_u64 (mp->remote_cookie));
11763
11764   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11765   vat_json_object_add_uint (node, "local_session_id",
11766                             clib_net_to_host_u32 (mp->local_session_id));
11767   vat_json_object_add_uint (node, "remote_session_id",
11768                             clib_net_to_host_u32 (mp->remote_session_id));
11769   vat_json_object_add_string_copy (node, "l2_sublayer",
11770                                    mp->l2_sublayer_present ? (u8 *) "present"
11771                                    : (u8 *) "absent");
11772 }
11773
11774 static int
11775 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11776 {
11777   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11778   vl_api_control_ping_t *mp_ping;
11779   int ret;
11780
11781   /* Get list of l2tpv3-tunnel interfaces */
11782   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11783   S (mp);
11784
11785   /* Use a control ping for synchronization */
11786   MPING (CONTROL_PING, mp_ping);
11787   S (mp_ping);
11788
11789   W (ret);
11790   return ret;
11791 }
11792
11793
11794 static void vl_api_sw_interface_tap_details_t_handler
11795   (vl_api_sw_interface_tap_details_t * mp)
11796 {
11797   vat_main_t *vam = &vat_main;
11798
11799   print (vam->ofp, "%-16s %d",
11800          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
11801 }
11802
11803 static void vl_api_sw_interface_tap_details_t_handler_json
11804   (vl_api_sw_interface_tap_details_t * mp)
11805 {
11806   vat_main_t *vam = &vat_main;
11807   vat_json_node_t *node = NULL;
11808
11809   if (VAT_JSON_ARRAY != vam->json_tree.type)
11810     {
11811       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11812       vat_json_init_array (&vam->json_tree);
11813     }
11814   node = vat_json_array_add (&vam->json_tree);
11815
11816   vat_json_init_object (node);
11817   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11818   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11819 }
11820
11821 static int
11822 api_sw_interface_tap_dump (vat_main_t * vam)
11823 {
11824   vl_api_sw_interface_tap_dump_t *mp;
11825   vl_api_control_ping_t *mp_ping;
11826   int ret;
11827
11828   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
11829   /* Get list of tap interfaces */
11830   M (SW_INTERFACE_TAP_DUMP, mp);
11831   S (mp);
11832
11833   /* Use a control ping for synchronization */
11834   MPING (CONTROL_PING, mp_ping);
11835   S (mp_ping);
11836
11837   W (ret);
11838   return ret;
11839 }
11840
11841 static uword unformat_vxlan_decap_next
11842   (unformat_input_t * input, va_list * args)
11843 {
11844   u32 *result = va_arg (*args, u32 *);
11845   u32 tmp;
11846
11847   if (unformat (input, "l2"))
11848     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11849   else if (unformat (input, "%d", &tmp))
11850     *result = tmp;
11851   else
11852     return 0;
11853   return 1;
11854 }
11855
11856 static int
11857 api_vxlan_add_del_tunnel (vat_main_t * vam)
11858 {
11859   unformat_input_t *line_input = vam->input;
11860   vl_api_vxlan_add_del_tunnel_t *mp;
11861   ip46_address_t src, dst;
11862   u8 is_add = 1;
11863   u8 ipv4_set = 0, ipv6_set = 0;
11864   u8 src_set = 0;
11865   u8 dst_set = 0;
11866   u8 grp_set = 0;
11867   u32 mcast_sw_if_index = ~0;
11868   u32 encap_vrf_id = 0;
11869   u32 decap_next_index = ~0;
11870   u32 vni = 0;
11871   int ret;
11872
11873   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11874   memset (&src, 0, sizeof src);
11875   memset (&dst, 0, sizeof dst);
11876
11877   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11878     {
11879       if (unformat (line_input, "del"))
11880         is_add = 0;
11881       else
11882         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11883         {
11884           ipv4_set = 1;
11885           src_set = 1;
11886         }
11887       else
11888         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11889         {
11890           ipv4_set = 1;
11891           dst_set = 1;
11892         }
11893       else
11894         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11895         {
11896           ipv6_set = 1;
11897           src_set = 1;
11898         }
11899       else
11900         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11901         {
11902           ipv6_set = 1;
11903           dst_set = 1;
11904         }
11905       else if (unformat (line_input, "group %U %U",
11906                          unformat_ip4_address, &dst.ip4,
11907                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11908         {
11909           grp_set = dst_set = 1;
11910           ipv4_set = 1;
11911         }
11912       else if (unformat (line_input, "group %U",
11913                          unformat_ip4_address, &dst.ip4))
11914         {
11915           grp_set = dst_set = 1;
11916           ipv4_set = 1;
11917         }
11918       else if (unformat (line_input, "group %U %U",
11919                          unformat_ip6_address, &dst.ip6,
11920                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11921         {
11922           grp_set = dst_set = 1;
11923           ipv6_set = 1;
11924         }
11925       else if (unformat (line_input, "group %U",
11926                          unformat_ip6_address, &dst.ip6))
11927         {
11928           grp_set = dst_set = 1;
11929           ipv6_set = 1;
11930         }
11931       else
11932         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11933         ;
11934       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11935         ;
11936       else if (unformat (line_input, "decap-next %U",
11937                          unformat_vxlan_decap_next, &decap_next_index))
11938         ;
11939       else if (unformat (line_input, "vni %d", &vni))
11940         ;
11941       else
11942         {
11943           errmsg ("parse error '%U'", format_unformat_error, line_input);
11944           return -99;
11945         }
11946     }
11947
11948   if (src_set == 0)
11949     {
11950       errmsg ("tunnel src address not specified");
11951       return -99;
11952     }
11953   if (dst_set == 0)
11954     {
11955       errmsg ("tunnel dst address not specified");
11956       return -99;
11957     }
11958
11959   if (grp_set && !ip46_address_is_multicast (&dst))
11960     {
11961       errmsg ("tunnel group address not multicast");
11962       return -99;
11963     }
11964   if (grp_set && mcast_sw_if_index == ~0)
11965     {
11966       errmsg ("tunnel nonexistent multicast device");
11967       return -99;
11968     }
11969   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11970     {
11971       errmsg ("tunnel dst address must be unicast");
11972       return -99;
11973     }
11974
11975
11976   if (ipv4_set && ipv6_set)
11977     {
11978       errmsg ("both IPv4 and IPv6 addresses specified");
11979       return -99;
11980     }
11981
11982   if ((vni == 0) || (vni >> 24))
11983     {
11984       errmsg ("vni not specified or out of range");
11985       return -99;
11986     }
11987
11988   M (VXLAN_ADD_DEL_TUNNEL, mp);
11989
11990   if (ipv6_set)
11991     {
11992       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
11993       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
11994     }
11995   else
11996     {
11997       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
11998       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
11999     }
12000   mp->encap_vrf_id = ntohl (encap_vrf_id);
12001   mp->decap_next_index = ntohl (decap_next_index);
12002   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12003   mp->vni = ntohl (vni);
12004   mp->is_add = is_add;
12005   mp->is_ipv6 = ipv6_set;
12006
12007   S (mp);
12008   W (ret);
12009   return ret;
12010 }
12011
12012 static void vl_api_vxlan_tunnel_details_t_handler
12013   (vl_api_vxlan_tunnel_details_t * mp)
12014 {
12015   vat_main_t *vam = &vat_main;
12016   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12017   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12018
12019   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12020          ntohl (mp->sw_if_index),
12021          format_ip46_address, &src, IP46_TYPE_ANY,
12022          format_ip46_address, &dst, IP46_TYPE_ANY,
12023          ntohl (mp->encap_vrf_id),
12024          ntohl (mp->decap_next_index), ntohl (mp->vni),
12025          ntohl (mp->mcast_sw_if_index));
12026 }
12027
12028 static void vl_api_vxlan_tunnel_details_t_handler_json
12029   (vl_api_vxlan_tunnel_details_t * mp)
12030 {
12031   vat_main_t *vam = &vat_main;
12032   vat_json_node_t *node = NULL;
12033
12034   if (VAT_JSON_ARRAY != vam->json_tree.type)
12035     {
12036       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12037       vat_json_init_array (&vam->json_tree);
12038     }
12039   node = vat_json_array_add (&vam->json_tree);
12040
12041   vat_json_init_object (node);
12042   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12043   if (mp->is_ipv6)
12044     {
12045       struct in6_addr ip6;
12046
12047       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12048       vat_json_object_add_ip6 (node, "src_address", ip6);
12049       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12050       vat_json_object_add_ip6 (node, "dst_address", ip6);
12051     }
12052   else
12053     {
12054       struct in_addr ip4;
12055
12056       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12057       vat_json_object_add_ip4 (node, "src_address", ip4);
12058       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12059       vat_json_object_add_ip4 (node, "dst_address", ip4);
12060     }
12061   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12062   vat_json_object_add_uint (node, "decap_next_index",
12063                             ntohl (mp->decap_next_index));
12064   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12065   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12066   vat_json_object_add_uint (node, "mcast_sw_if_index",
12067                             ntohl (mp->mcast_sw_if_index));
12068 }
12069
12070 static int
12071 api_vxlan_tunnel_dump (vat_main_t * vam)
12072 {
12073   unformat_input_t *i = vam->input;
12074   vl_api_vxlan_tunnel_dump_t *mp;
12075   vl_api_control_ping_t *mp_ping;
12076   u32 sw_if_index;
12077   u8 sw_if_index_set = 0;
12078   int ret;
12079
12080   /* Parse args required to build the message */
12081   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12082     {
12083       if (unformat (i, "sw_if_index %d", &sw_if_index))
12084         sw_if_index_set = 1;
12085       else
12086         break;
12087     }
12088
12089   if (sw_if_index_set == 0)
12090     {
12091       sw_if_index = ~0;
12092     }
12093
12094   if (!vam->json_output)
12095     {
12096       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12097              "sw_if_index", "src_address", "dst_address",
12098              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12099     }
12100
12101   /* Get list of vxlan-tunnel interfaces */
12102   M (VXLAN_TUNNEL_DUMP, mp);
12103
12104   mp->sw_if_index = htonl (sw_if_index);
12105
12106   S (mp);
12107
12108   /* Use a control ping for synchronization */
12109   MPING (CONTROL_PING, mp_ping);
12110   S (mp_ping);
12111
12112   W (ret);
12113   return ret;
12114 }
12115
12116 static uword unformat_geneve_decap_next
12117   (unformat_input_t * input, va_list * args)
12118 {
12119   u32 *result = va_arg (*args, u32 *);
12120   u32 tmp;
12121
12122   if (unformat (input, "l2"))
12123     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12124   else if (unformat (input, "%d", &tmp))
12125     *result = tmp;
12126   else
12127     return 0;
12128   return 1;
12129 }
12130
12131 static int
12132 api_geneve_add_del_tunnel (vat_main_t * vam)
12133 {
12134   unformat_input_t *line_input = vam->input;
12135   vl_api_geneve_add_del_tunnel_t *mp;
12136   ip46_address_t src, dst;
12137   u8 is_add = 1;
12138   u8 ipv4_set = 0, ipv6_set = 0;
12139   u8 src_set = 0;
12140   u8 dst_set = 0;
12141   u8 grp_set = 0;
12142   u32 mcast_sw_if_index = ~0;
12143   u32 encap_vrf_id = 0;
12144   u32 decap_next_index = ~0;
12145   u32 vni = 0;
12146   int ret;
12147
12148   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12149   memset (&src, 0, sizeof src);
12150   memset (&dst, 0, sizeof dst);
12151
12152   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12153     {
12154       if (unformat (line_input, "del"))
12155         is_add = 0;
12156       else
12157         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12158         {
12159           ipv4_set = 1;
12160           src_set = 1;
12161         }
12162       else
12163         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12164         {
12165           ipv4_set = 1;
12166           dst_set = 1;
12167         }
12168       else
12169         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12170         {
12171           ipv6_set = 1;
12172           src_set = 1;
12173         }
12174       else
12175         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12176         {
12177           ipv6_set = 1;
12178           dst_set = 1;
12179         }
12180       else if (unformat (line_input, "group %U %U",
12181                          unformat_ip4_address, &dst.ip4,
12182                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12183         {
12184           grp_set = dst_set = 1;
12185           ipv4_set = 1;
12186         }
12187       else if (unformat (line_input, "group %U",
12188                          unformat_ip4_address, &dst.ip4))
12189         {
12190           grp_set = dst_set = 1;
12191           ipv4_set = 1;
12192         }
12193       else if (unformat (line_input, "group %U %U",
12194                          unformat_ip6_address, &dst.ip6,
12195                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12196         {
12197           grp_set = dst_set = 1;
12198           ipv6_set = 1;
12199         }
12200       else if (unformat (line_input, "group %U",
12201                          unformat_ip6_address, &dst.ip6))
12202         {
12203           grp_set = dst_set = 1;
12204           ipv6_set = 1;
12205         }
12206       else
12207         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12208         ;
12209       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12210         ;
12211       else if (unformat (line_input, "decap-next %U",
12212                          unformat_geneve_decap_next, &decap_next_index))
12213         ;
12214       else if (unformat (line_input, "vni %d", &vni))
12215         ;
12216       else
12217         {
12218           errmsg ("parse error '%U'", format_unformat_error, line_input);
12219           return -99;
12220         }
12221     }
12222
12223   if (src_set == 0)
12224     {
12225       errmsg ("tunnel src address not specified");
12226       return -99;
12227     }
12228   if (dst_set == 0)
12229     {
12230       errmsg ("tunnel dst address not specified");
12231       return -99;
12232     }
12233
12234   if (grp_set && !ip46_address_is_multicast (&dst))
12235     {
12236       errmsg ("tunnel group address not multicast");
12237       return -99;
12238     }
12239   if (grp_set && mcast_sw_if_index == ~0)
12240     {
12241       errmsg ("tunnel nonexistent multicast device");
12242       return -99;
12243     }
12244   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12245     {
12246       errmsg ("tunnel dst address must be unicast");
12247       return -99;
12248     }
12249
12250
12251   if (ipv4_set && ipv6_set)
12252     {
12253       errmsg ("both IPv4 and IPv6 addresses specified");
12254       return -99;
12255     }
12256
12257   if ((vni == 0) || (vni >> 24))
12258     {
12259       errmsg ("vni not specified or out of range");
12260       return -99;
12261     }
12262
12263   M (GENEVE_ADD_DEL_TUNNEL, mp);
12264
12265   if (ipv6_set)
12266     {
12267       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12268       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12269     }
12270   else
12271     {
12272       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12273       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12274     }
12275   mp->encap_vrf_id = ntohl (encap_vrf_id);
12276   mp->decap_next_index = ntohl (decap_next_index);
12277   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12278   mp->vni = ntohl (vni);
12279   mp->is_add = is_add;
12280   mp->is_ipv6 = ipv6_set;
12281
12282   S (mp);
12283   W (ret);
12284   return ret;
12285 }
12286
12287 static void vl_api_geneve_tunnel_details_t_handler
12288   (vl_api_geneve_tunnel_details_t * mp)
12289 {
12290   vat_main_t *vam = &vat_main;
12291   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12292   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12293
12294   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12295          ntohl (mp->sw_if_index),
12296          format_ip46_address, &src, IP46_TYPE_ANY,
12297          format_ip46_address, &dst, IP46_TYPE_ANY,
12298          ntohl (mp->encap_vrf_id),
12299          ntohl (mp->decap_next_index), ntohl (mp->vni),
12300          ntohl (mp->mcast_sw_if_index));
12301 }
12302
12303 static void vl_api_geneve_tunnel_details_t_handler_json
12304   (vl_api_geneve_tunnel_details_t * mp)
12305 {
12306   vat_main_t *vam = &vat_main;
12307   vat_json_node_t *node = NULL;
12308
12309   if (VAT_JSON_ARRAY != vam->json_tree.type)
12310     {
12311       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12312       vat_json_init_array (&vam->json_tree);
12313     }
12314   node = vat_json_array_add (&vam->json_tree);
12315
12316   vat_json_init_object (node);
12317   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12318   if (mp->is_ipv6)
12319     {
12320       struct in6_addr ip6;
12321
12322       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12323       vat_json_object_add_ip6 (node, "src_address", ip6);
12324       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12325       vat_json_object_add_ip6 (node, "dst_address", ip6);
12326     }
12327   else
12328     {
12329       struct in_addr ip4;
12330
12331       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12332       vat_json_object_add_ip4 (node, "src_address", ip4);
12333       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12334       vat_json_object_add_ip4 (node, "dst_address", ip4);
12335     }
12336   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12337   vat_json_object_add_uint (node, "decap_next_index",
12338                             ntohl (mp->decap_next_index));
12339   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12340   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12341   vat_json_object_add_uint (node, "mcast_sw_if_index",
12342                             ntohl (mp->mcast_sw_if_index));
12343 }
12344
12345 static int
12346 api_geneve_tunnel_dump (vat_main_t * vam)
12347 {
12348   unformat_input_t *i = vam->input;
12349   vl_api_geneve_tunnel_dump_t *mp;
12350   vl_api_control_ping_t *mp_ping;
12351   u32 sw_if_index;
12352   u8 sw_if_index_set = 0;
12353   int ret;
12354
12355   /* Parse args required to build the message */
12356   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12357     {
12358       if (unformat (i, "sw_if_index %d", &sw_if_index))
12359         sw_if_index_set = 1;
12360       else
12361         break;
12362     }
12363
12364   if (sw_if_index_set == 0)
12365     {
12366       sw_if_index = ~0;
12367     }
12368
12369   if (!vam->json_output)
12370     {
12371       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12372              "sw_if_index", "local_address", "remote_address",
12373              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12374     }
12375
12376   /* Get list of geneve-tunnel interfaces */
12377   M (GENEVE_TUNNEL_DUMP, mp);
12378
12379   mp->sw_if_index = htonl (sw_if_index);
12380
12381   S (mp);
12382
12383   /* Use a control ping for synchronization */
12384   M (CONTROL_PING, mp_ping);
12385   S (mp_ping);
12386
12387   W (ret);
12388   return ret;
12389 }
12390
12391 static int
12392 api_gre_add_del_tunnel (vat_main_t * vam)
12393 {
12394   unformat_input_t *line_input = vam->input;
12395   vl_api_gre_add_del_tunnel_t *mp;
12396   ip4_address_t src4, dst4;
12397   ip6_address_t src6, dst6;
12398   u8 is_add = 1;
12399   u8 ipv4_set = 0;
12400   u8 ipv6_set = 0;
12401   u8 teb = 0;
12402   u8 src_set = 0;
12403   u8 dst_set = 0;
12404   u32 outer_fib_id = 0;
12405   int ret;
12406
12407   memset (&src4, 0, sizeof src4);
12408   memset (&dst4, 0, sizeof dst4);
12409   memset (&src6, 0, sizeof src6);
12410   memset (&dst6, 0, sizeof dst6);
12411
12412   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12413     {
12414       if (unformat (line_input, "del"))
12415         is_add = 0;
12416       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
12417         {
12418           src_set = 1;
12419           ipv4_set = 1;
12420         }
12421       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
12422         {
12423           dst_set = 1;
12424           ipv4_set = 1;
12425         }
12426       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
12427         {
12428           src_set = 1;
12429           ipv6_set = 1;
12430         }
12431       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
12432         {
12433           dst_set = 1;
12434           ipv6_set = 1;
12435         }
12436       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
12437         ;
12438       else if (unformat (line_input, "teb"))
12439         teb = 1;
12440       else
12441         {
12442           errmsg ("parse error '%U'", format_unformat_error, line_input);
12443           return -99;
12444         }
12445     }
12446
12447   if (src_set == 0)
12448     {
12449       errmsg ("tunnel src address not specified");
12450       return -99;
12451     }
12452   if (dst_set == 0)
12453     {
12454       errmsg ("tunnel dst address not specified");
12455       return -99;
12456     }
12457   if (ipv4_set && ipv6_set)
12458     {
12459       errmsg ("both IPv4 and IPv6 addresses specified");
12460       return -99;
12461     }
12462
12463
12464   M (GRE_ADD_DEL_TUNNEL, mp);
12465
12466   if (ipv4_set)
12467     {
12468       clib_memcpy (&mp->src_address, &src4, 4);
12469       clib_memcpy (&mp->dst_address, &dst4, 4);
12470     }
12471   else
12472     {
12473       clib_memcpy (&mp->src_address, &src6, 16);
12474       clib_memcpy (&mp->dst_address, &dst6, 16);
12475     }
12476   mp->outer_fib_id = ntohl (outer_fib_id);
12477   mp->is_add = is_add;
12478   mp->teb = teb;
12479   mp->is_ipv6 = ipv6_set;
12480
12481   S (mp);
12482   W (ret);
12483   return ret;
12484 }
12485
12486 static void vl_api_gre_tunnel_details_t_handler
12487   (vl_api_gre_tunnel_details_t * mp)
12488 {
12489   vat_main_t *vam = &vat_main;
12490   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
12491   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
12492
12493   print (vam->ofp, "%11d%24U%24U%6d%14d",
12494          ntohl (mp->sw_if_index),
12495          format_ip46_address, &src, IP46_TYPE_ANY,
12496          format_ip46_address, &dst, IP46_TYPE_ANY,
12497          mp->teb, ntohl (mp->outer_fib_id));
12498 }
12499
12500 static void vl_api_gre_tunnel_details_t_handler_json
12501   (vl_api_gre_tunnel_details_t * mp)
12502 {
12503   vat_main_t *vam = &vat_main;
12504   vat_json_node_t *node = NULL;
12505   struct in_addr ip4;
12506   struct in6_addr ip6;
12507
12508   if (VAT_JSON_ARRAY != vam->json_tree.type)
12509     {
12510       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12511       vat_json_init_array (&vam->json_tree);
12512     }
12513   node = vat_json_array_add (&vam->json_tree);
12514
12515   vat_json_init_object (node);
12516   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12517   if (!mp->is_ipv6)
12518     {
12519       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
12520       vat_json_object_add_ip4 (node, "src_address", ip4);
12521       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
12522       vat_json_object_add_ip4 (node, "dst_address", ip4);
12523     }
12524   else
12525     {
12526       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
12527       vat_json_object_add_ip6 (node, "src_address", ip6);
12528       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
12529       vat_json_object_add_ip6 (node, "dst_address", ip6);
12530     }
12531   vat_json_object_add_uint (node, "teb", mp->teb);
12532   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
12533   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
12534 }
12535
12536 static int
12537 api_gre_tunnel_dump (vat_main_t * vam)
12538 {
12539   unformat_input_t *i = vam->input;
12540   vl_api_gre_tunnel_dump_t *mp;
12541   vl_api_control_ping_t *mp_ping;
12542   u32 sw_if_index;
12543   u8 sw_if_index_set = 0;
12544   int ret;
12545
12546   /* Parse args required to build the message */
12547   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12548     {
12549       if (unformat (i, "sw_if_index %d", &sw_if_index))
12550         sw_if_index_set = 1;
12551       else
12552         break;
12553     }
12554
12555   if (sw_if_index_set == 0)
12556     {
12557       sw_if_index = ~0;
12558     }
12559
12560   if (!vam->json_output)
12561     {
12562       print (vam->ofp, "%11s%24s%24s%6s%14s",
12563              "sw_if_index", "src_address", "dst_address", "teb",
12564              "outer_fib_id");
12565     }
12566
12567   /* Get list of gre-tunnel interfaces */
12568   M (GRE_TUNNEL_DUMP, mp);
12569
12570   mp->sw_if_index = htonl (sw_if_index);
12571
12572   S (mp);
12573
12574   /* Use a control ping for synchronization */
12575   MPING (CONTROL_PING, mp_ping);
12576   S (mp_ping);
12577
12578   W (ret);
12579   return ret;
12580 }
12581
12582 static int
12583 api_l2_fib_clear_table (vat_main_t * vam)
12584 {
12585 //  unformat_input_t * i = vam->input;
12586   vl_api_l2_fib_clear_table_t *mp;
12587   int ret;
12588
12589   M (L2_FIB_CLEAR_TABLE, mp);
12590
12591   S (mp);
12592   W (ret);
12593   return ret;
12594 }
12595
12596 static int
12597 api_l2_interface_efp_filter (vat_main_t * vam)
12598 {
12599   unformat_input_t *i = vam->input;
12600   vl_api_l2_interface_efp_filter_t *mp;
12601   u32 sw_if_index;
12602   u8 enable = 1;
12603   u8 sw_if_index_set = 0;
12604   int ret;
12605
12606   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12607     {
12608       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12609         sw_if_index_set = 1;
12610       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12611         sw_if_index_set = 1;
12612       else if (unformat (i, "enable"))
12613         enable = 1;
12614       else if (unformat (i, "disable"))
12615         enable = 0;
12616       else
12617         {
12618           clib_warning ("parse error '%U'", format_unformat_error, i);
12619           return -99;
12620         }
12621     }
12622
12623   if (sw_if_index_set == 0)
12624     {
12625       errmsg ("missing sw_if_index");
12626       return -99;
12627     }
12628
12629   M (L2_INTERFACE_EFP_FILTER, mp);
12630
12631   mp->sw_if_index = ntohl (sw_if_index);
12632   mp->enable_disable = enable;
12633
12634   S (mp);
12635   W (ret);
12636   return ret;
12637 }
12638
12639 #define foreach_vtr_op                          \
12640 _("disable",  L2_VTR_DISABLED)                  \
12641 _("push-1",  L2_VTR_PUSH_1)                     \
12642 _("push-2",  L2_VTR_PUSH_2)                     \
12643 _("pop-1",  L2_VTR_POP_1)                       \
12644 _("pop-2",  L2_VTR_POP_2)                       \
12645 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12646 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12647 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12648 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12649
12650 static int
12651 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12652 {
12653   unformat_input_t *i = vam->input;
12654   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12655   u32 sw_if_index;
12656   u8 sw_if_index_set = 0;
12657   u8 vtr_op_set = 0;
12658   u32 vtr_op = 0;
12659   u32 push_dot1q = 1;
12660   u32 tag1 = ~0;
12661   u32 tag2 = ~0;
12662   int ret;
12663
12664   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12665     {
12666       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12667         sw_if_index_set = 1;
12668       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12669         sw_if_index_set = 1;
12670       else if (unformat (i, "vtr_op %d", &vtr_op))
12671         vtr_op_set = 1;
12672 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12673       foreach_vtr_op
12674 #undef _
12675         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12676         ;
12677       else if (unformat (i, "tag1 %d", &tag1))
12678         ;
12679       else if (unformat (i, "tag2 %d", &tag2))
12680         ;
12681       else
12682         {
12683           clib_warning ("parse error '%U'", format_unformat_error, i);
12684           return -99;
12685         }
12686     }
12687
12688   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12689     {
12690       errmsg ("missing vtr operation or sw_if_index");
12691       return -99;
12692     }
12693
12694   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12695   mp->sw_if_index = ntohl (sw_if_index);
12696   mp->vtr_op = ntohl (vtr_op);
12697   mp->push_dot1q = ntohl (push_dot1q);
12698   mp->tag1 = ntohl (tag1);
12699   mp->tag2 = ntohl (tag2);
12700
12701   S (mp);
12702   W (ret);
12703   return ret;
12704 }
12705
12706 static int
12707 api_create_vhost_user_if (vat_main_t * vam)
12708 {
12709   unformat_input_t *i = vam->input;
12710   vl_api_create_vhost_user_if_t *mp;
12711   u8 *file_name;
12712   u8 is_server = 0;
12713   u8 file_name_set = 0;
12714   u32 custom_dev_instance = ~0;
12715   u8 hwaddr[6];
12716   u8 use_custom_mac = 0;
12717   u8 *tag = 0;
12718   int ret;
12719
12720   /* Shut up coverity */
12721   memset (hwaddr, 0, sizeof (hwaddr));
12722
12723   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12724     {
12725       if (unformat (i, "socket %s", &file_name))
12726         {
12727           file_name_set = 1;
12728         }
12729       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12730         ;
12731       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12732         use_custom_mac = 1;
12733       else if (unformat (i, "server"))
12734         is_server = 1;
12735       else if (unformat (i, "tag %s", &tag))
12736         ;
12737       else
12738         break;
12739     }
12740
12741   if (file_name_set == 0)
12742     {
12743       errmsg ("missing socket file name");
12744       return -99;
12745     }
12746
12747   if (vec_len (file_name) > 255)
12748     {
12749       errmsg ("socket file name too long");
12750       return -99;
12751     }
12752   vec_add1 (file_name, 0);
12753
12754   M (CREATE_VHOST_USER_IF, mp);
12755
12756   mp->is_server = is_server;
12757   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12758   vec_free (file_name);
12759   if (custom_dev_instance != ~0)
12760     {
12761       mp->renumber = 1;
12762       mp->custom_dev_instance = ntohl (custom_dev_instance);
12763     }
12764   mp->use_custom_mac = use_custom_mac;
12765   clib_memcpy (mp->mac_address, hwaddr, 6);
12766   if (tag)
12767     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12768   vec_free (tag);
12769
12770   S (mp);
12771   W (ret);
12772   return ret;
12773 }
12774
12775 static int
12776 api_modify_vhost_user_if (vat_main_t * vam)
12777 {
12778   unformat_input_t *i = vam->input;
12779   vl_api_modify_vhost_user_if_t *mp;
12780   u8 *file_name;
12781   u8 is_server = 0;
12782   u8 file_name_set = 0;
12783   u32 custom_dev_instance = ~0;
12784   u8 sw_if_index_set = 0;
12785   u32 sw_if_index = (u32) ~ 0;
12786   int ret;
12787
12788   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12789     {
12790       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12791         sw_if_index_set = 1;
12792       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12793         sw_if_index_set = 1;
12794       else if (unformat (i, "socket %s", &file_name))
12795         {
12796           file_name_set = 1;
12797         }
12798       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12799         ;
12800       else if (unformat (i, "server"))
12801         is_server = 1;
12802       else
12803         break;
12804     }
12805
12806   if (sw_if_index_set == 0)
12807     {
12808       errmsg ("missing sw_if_index or interface name");
12809       return -99;
12810     }
12811
12812   if (file_name_set == 0)
12813     {
12814       errmsg ("missing socket file name");
12815       return -99;
12816     }
12817
12818   if (vec_len (file_name) > 255)
12819     {
12820       errmsg ("socket file name too long");
12821       return -99;
12822     }
12823   vec_add1 (file_name, 0);
12824
12825   M (MODIFY_VHOST_USER_IF, mp);
12826
12827   mp->sw_if_index = ntohl (sw_if_index);
12828   mp->is_server = is_server;
12829   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12830   vec_free (file_name);
12831   if (custom_dev_instance != ~0)
12832     {
12833       mp->renumber = 1;
12834       mp->custom_dev_instance = ntohl (custom_dev_instance);
12835     }
12836
12837   S (mp);
12838   W (ret);
12839   return ret;
12840 }
12841
12842 static int
12843 api_delete_vhost_user_if (vat_main_t * vam)
12844 {
12845   unformat_input_t *i = vam->input;
12846   vl_api_delete_vhost_user_if_t *mp;
12847   u32 sw_if_index = ~0;
12848   u8 sw_if_index_set = 0;
12849   int ret;
12850
12851   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12852     {
12853       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12854         sw_if_index_set = 1;
12855       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12856         sw_if_index_set = 1;
12857       else
12858         break;
12859     }
12860
12861   if (sw_if_index_set == 0)
12862     {
12863       errmsg ("missing sw_if_index or interface name");
12864       return -99;
12865     }
12866
12867
12868   M (DELETE_VHOST_USER_IF, mp);
12869
12870   mp->sw_if_index = ntohl (sw_if_index);
12871
12872   S (mp);
12873   W (ret);
12874   return ret;
12875 }
12876
12877 static void vl_api_sw_interface_vhost_user_details_t_handler
12878   (vl_api_sw_interface_vhost_user_details_t * mp)
12879 {
12880   vat_main_t *vam = &vat_main;
12881
12882   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12883          (char *) mp->interface_name,
12884          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12885          clib_net_to_host_u64 (mp->features), mp->is_server,
12886          ntohl (mp->num_regions), (char *) mp->sock_filename);
12887   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12888 }
12889
12890 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12891   (vl_api_sw_interface_vhost_user_details_t * mp)
12892 {
12893   vat_main_t *vam = &vat_main;
12894   vat_json_node_t *node = NULL;
12895
12896   if (VAT_JSON_ARRAY != vam->json_tree.type)
12897     {
12898       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12899       vat_json_init_array (&vam->json_tree);
12900     }
12901   node = vat_json_array_add (&vam->json_tree);
12902
12903   vat_json_init_object (node);
12904   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12905   vat_json_object_add_string_copy (node, "interface_name",
12906                                    mp->interface_name);
12907   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12908                             ntohl (mp->virtio_net_hdr_sz));
12909   vat_json_object_add_uint (node, "features",
12910                             clib_net_to_host_u64 (mp->features));
12911   vat_json_object_add_uint (node, "is_server", mp->is_server);
12912   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12913   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12914   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12915 }
12916
12917 static int
12918 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12919 {
12920   vl_api_sw_interface_vhost_user_dump_t *mp;
12921   vl_api_control_ping_t *mp_ping;
12922   int ret;
12923   print (vam->ofp,
12924          "Interface name            idx hdr_sz features server regions filename");
12925
12926   /* Get list of vhost-user interfaces */
12927   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12928   S (mp);
12929
12930   /* Use a control ping for synchronization */
12931   MPING (CONTROL_PING, mp_ping);
12932   S (mp_ping);
12933
12934   W (ret);
12935   return ret;
12936 }
12937
12938 static int
12939 api_show_version (vat_main_t * vam)
12940 {
12941   vl_api_show_version_t *mp;
12942   int ret;
12943
12944   M (SHOW_VERSION, mp);
12945
12946   S (mp);
12947   W (ret);
12948   return ret;
12949 }
12950
12951
12952 static int
12953 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12954 {
12955   unformat_input_t *line_input = vam->input;
12956   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12957   ip4_address_t local4, remote4;
12958   ip6_address_t local6, remote6;
12959   u8 is_add = 1;
12960   u8 ipv4_set = 0, ipv6_set = 0;
12961   u8 local_set = 0;
12962   u8 remote_set = 0;
12963   u8 grp_set = 0;
12964   u32 mcast_sw_if_index = ~0;
12965   u32 encap_vrf_id = 0;
12966   u32 decap_vrf_id = 0;
12967   u8 protocol = ~0;
12968   u32 vni;
12969   u8 vni_set = 0;
12970   int ret;
12971
12972   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12973   memset (&local4, 0, sizeof local4);
12974   memset (&remote4, 0, sizeof remote4);
12975   memset (&local6, 0, sizeof local6);
12976   memset (&remote6, 0, sizeof remote6);
12977
12978   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12979     {
12980       if (unformat (line_input, "del"))
12981         is_add = 0;
12982       else if (unformat (line_input, "local %U",
12983                          unformat_ip4_address, &local4))
12984         {
12985           local_set = 1;
12986           ipv4_set = 1;
12987         }
12988       else if (unformat (line_input, "remote %U",
12989                          unformat_ip4_address, &remote4))
12990         {
12991           remote_set = 1;
12992           ipv4_set = 1;
12993         }
12994       else if (unformat (line_input, "local %U",
12995                          unformat_ip6_address, &local6))
12996         {
12997           local_set = 1;
12998           ipv6_set = 1;
12999         }
13000       else if (unformat (line_input, "remote %U",
13001                          unformat_ip6_address, &remote6))
13002         {
13003           remote_set = 1;
13004           ipv6_set = 1;
13005         }
13006       else if (unformat (line_input, "group %U %U",
13007                          unformat_ip4_address, &remote4,
13008                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13009         {
13010           grp_set = remote_set = 1;
13011           ipv4_set = 1;
13012         }
13013       else if (unformat (line_input, "group %U",
13014                          unformat_ip4_address, &remote4))
13015         {
13016           grp_set = remote_set = 1;
13017           ipv4_set = 1;
13018         }
13019       else if (unformat (line_input, "group %U %U",
13020                          unformat_ip6_address, &remote6,
13021                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13022         {
13023           grp_set = remote_set = 1;
13024           ipv6_set = 1;
13025         }
13026       else if (unformat (line_input, "group %U",
13027                          unformat_ip6_address, &remote6))
13028         {
13029           grp_set = remote_set = 1;
13030           ipv6_set = 1;
13031         }
13032       else
13033         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13034         ;
13035       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13036         ;
13037       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13038         ;
13039       else if (unformat (line_input, "vni %d", &vni))
13040         vni_set = 1;
13041       else if (unformat (line_input, "next-ip4"))
13042         protocol = 1;
13043       else if (unformat (line_input, "next-ip6"))
13044         protocol = 2;
13045       else if (unformat (line_input, "next-ethernet"))
13046         protocol = 3;
13047       else if (unformat (line_input, "next-nsh"))
13048         protocol = 4;
13049       else
13050         {
13051           errmsg ("parse error '%U'", format_unformat_error, line_input);
13052           return -99;
13053         }
13054     }
13055
13056   if (local_set == 0)
13057     {
13058       errmsg ("tunnel local address not specified");
13059       return -99;
13060     }
13061   if (remote_set == 0)
13062     {
13063       errmsg ("tunnel remote address not specified");
13064       return -99;
13065     }
13066   if (grp_set && mcast_sw_if_index == ~0)
13067     {
13068       errmsg ("tunnel nonexistent multicast device");
13069       return -99;
13070     }
13071   if (ipv4_set && ipv6_set)
13072     {
13073       errmsg ("both IPv4 and IPv6 addresses specified");
13074       return -99;
13075     }
13076
13077   if (vni_set == 0)
13078     {
13079       errmsg ("vni not specified");
13080       return -99;
13081     }
13082
13083   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13084
13085
13086   if (ipv6_set)
13087     {
13088       clib_memcpy (&mp->local, &local6, sizeof (local6));
13089       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13090     }
13091   else
13092     {
13093       clib_memcpy (&mp->local, &local4, sizeof (local4));
13094       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13095     }
13096
13097   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13098   mp->encap_vrf_id = ntohl (encap_vrf_id);
13099   mp->decap_vrf_id = ntohl (decap_vrf_id);
13100   mp->protocol = protocol;
13101   mp->vni = ntohl (vni);
13102   mp->is_add = is_add;
13103   mp->is_ipv6 = ipv6_set;
13104
13105   S (mp);
13106   W (ret);
13107   return ret;
13108 }
13109
13110 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13111   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13112 {
13113   vat_main_t *vam = &vat_main;
13114   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13115   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13116
13117   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13118          ntohl (mp->sw_if_index),
13119          format_ip46_address, &local, IP46_TYPE_ANY,
13120          format_ip46_address, &remote, IP46_TYPE_ANY,
13121          ntohl (mp->vni), mp->protocol,
13122          ntohl (mp->mcast_sw_if_index),
13123          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13124 }
13125
13126
13127 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13128   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13129 {
13130   vat_main_t *vam = &vat_main;
13131   vat_json_node_t *node = NULL;
13132   struct in_addr ip4;
13133   struct in6_addr ip6;
13134
13135   if (VAT_JSON_ARRAY != vam->json_tree.type)
13136     {
13137       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13138       vat_json_init_array (&vam->json_tree);
13139     }
13140   node = vat_json_array_add (&vam->json_tree);
13141
13142   vat_json_init_object (node);
13143   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13144   if (mp->is_ipv6)
13145     {
13146       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13147       vat_json_object_add_ip6 (node, "local", ip6);
13148       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13149       vat_json_object_add_ip6 (node, "remote", ip6);
13150     }
13151   else
13152     {
13153       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13154       vat_json_object_add_ip4 (node, "local", ip4);
13155       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13156       vat_json_object_add_ip4 (node, "remote", ip4);
13157     }
13158   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13159   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13160   vat_json_object_add_uint (node, "mcast_sw_if_index",
13161                             ntohl (mp->mcast_sw_if_index));
13162   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13163   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13164   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13165 }
13166
13167 static int
13168 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13169 {
13170   unformat_input_t *i = vam->input;
13171   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13172   vl_api_control_ping_t *mp_ping;
13173   u32 sw_if_index;
13174   u8 sw_if_index_set = 0;
13175   int ret;
13176
13177   /* Parse args required to build the message */
13178   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13179     {
13180       if (unformat (i, "sw_if_index %d", &sw_if_index))
13181         sw_if_index_set = 1;
13182       else
13183         break;
13184     }
13185
13186   if (sw_if_index_set == 0)
13187     {
13188       sw_if_index = ~0;
13189     }
13190
13191   if (!vam->json_output)
13192     {
13193       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13194              "sw_if_index", "local", "remote", "vni",
13195              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13196     }
13197
13198   /* Get list of vxlan-tunnel interfaces */
13199   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13200
13201   mp->sw_if_index = htonl (sw_if_index);
13202
13203   S (mp);
13204
13205   /* Use a control ping for synchronization */
13206   MPING (CONTROL_PING, mp_ping);
13207   S (mp_ping);
13208
13209   W (ret);
13210   return ret;
13211 }
13212
13213
13214 u8 *
13215 format_l2_fib_mac_address (u8 * s, va_list * args)
13216 {
13217   u8 *a = va_arg (*args, u8 *);
13218
13219   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
13220                  a[2], a[3], a[4], a[5], a[6], a[7]);
13221 }
13222
13223 static void vl_api_l2_fib_table_details_t_handler
13224   (vl_api_l2_fib_table_details_t * mp)
13225 {
13226   vat_main_t *vam = &vat_main;
13227
13228   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13229          "       %d       %d     %d",
13230          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
13231          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13232          mp->bvi_mac);
13233 }
13234
13235 static void vl_api_l2_fib_table_details_t_handler_json
13236   (vl_api_l2_fib_table_details_t * mp)
13237 {
13238   vat_main_t *vam = &vat_main;
13239   vat_json_node_t *node = NULL;
13240
13241   if (VAT_JSON_ARRAY != vam->json_tree.type)
13242     {
13243       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13244       vat_json_init_array (&vam->json_tree);
13245     }
13246   node = vat_json_array_add (&vam->json_tree);
13247
13248   vat_json_init_object (node);
13249   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13250   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
13251   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13252   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13253   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13254   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13255 }
13256
13257 static int
13258 api_l2_fib_table_dump (vat_main_t * vam)
13259 {
13260   unformat_input_t *i = vam->input;
13261   vl_api_l2_fib_table_dump_t *mp;
13262   vl_api_control_ping_t *mp_ping;
13263   u32 bd_id;
13264   u8 bd_id_set = 0;
13265   int ret;
13266
13267   /* Parse args required to build the message */
13268   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13269     {
13270       if (unformat (i, "bd_id %d", &bd_id))
13271         bd_id_set = 1;
13272       else
13273         break;
13274     }
13275
13276   if (bd_id_set == 0)
13277     {
13278       errmsg ("missing bridge domain");
13279       return -99;
13280     }
13281
13282   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13283
13284   /* Get list of l2 fib entries */
13285   M (L2_FIB_TABLE_DUMP, mp);
13286
13287   mp->bd_id = ntohl (bd_id);
13288   S (mp);
13289
13290   /* Use a control ping for synchronization */
13291   MPING (CONTROL_PING, mp_ping);
13292   S (mp_ping);
13293
13294   W (ret);
13295   return ret;
13296 }
13297
13298
13299 static int
13300 api_interface_name_renumber (vat_main_t * vam)
13301 {
13302   unformat_input_t *line_input = vam->input;
13303   vl_api_interface_name_renumber_t *mp;
13304   u32 sw_if_index = ~0;
13305   u32 new_show_dev_instance = ~0;
13306   int ret;
13307
13308   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13309     {
13310       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13311                     &sw_if_index))
13312         ;
13313       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13314         ;
13315       else if (unformat (line_input, "new_show_dev_instance %d",
13316                          &new_show_dev_instance))
13317         ;
13318       else
13319         break;
13320     }
13321
13322   if (sw_if_index == ~0)
13323     {
13324       errmsg ("missing interface name or sw_if_index");
13325       return -99;
13326     }
13327
13328   if (new_show_dev_instance == ~0)
13329     {
13330       errmsg ("missing new_show_dev_instance");
13331       return -99;
13332     }
13333
13334   M (INTERFACE_NAME_RENUMBER, mp);
13335
13336   mp->sw_if_index = ntohl (sw_if_index);
13337   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13338
13339   S (mp);
13340   W (ret);
13341   return ret;
13342 }
13343
13344 static int
13345 api_want_ip4_arp_events (vat_main_t * vam)
13346 {
13347   unformat_input_t *line_input = vam->input;
13348   vl_api_want_ip4_arp_events_t *mp;
13349   ip4_address_t address;
13350   int address_set = 0;
13351   u32 enable_disable = 1;
13352   int ret;
13353
13354   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13355     {
13356       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
13357         address_set = 1;
13358       else if (unformat (line_input, "del"))
13359         enable_disable = 0;
13360       else
13361         break;
13362     }
13363
13364   if (address_set == 0)
13365     {
13366       errmsg ("missing addresses");
13367       return -99;
13368     }
13369
13370   M (WANT_IP4_ARP_EVENTS, mp);
13371   mp->enable_disable = enable_disable;
13372   mp->pid = htonl (getpid ());
13373   mp->address = address.as_u32;
13374
13375   S (mp);
13376   W (ret);
13377   return ret;
13378 }
13379
13380 static int
13381 api_want_ip6_nd_events (vat_main_t * vam)
13382 {
13383   unformat_input_t *line_input = vam->input;
13384   vl_api_want_ip6_nd_events_t *mp;
13385   ip6_address_t address;
13386   int address_set = 0;
13387   u32 enable_disable = 1;
13388   int ret;
13389
13390   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13391     {
13392       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
13393         address_set = 1;
13394       else if (unformat (line_input, "del"))
13395         enable_disable = 0;
13396       else
13397         break;
13398     }
13399
13400   if (address_set == 0)
13401     {
13402       errmsg ("missing addresses");
13403       return -99;
13404     }
13405
13406   M (WANT_IP6_ND_EVENTS, mp);
13407   mp->enable_disable = enable_disable;
13408   mp->pid = htonl (getpid ());
13409   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
13410
13411   S (mp);
13412   W (ret);
13413   return ret;
13414 }
13415
13416 static int
13417 api_want_l2_macs_events (vat_main_t * vam)
13418 {
13419   unformat_input_t *line_input = vam->input;
13420   vl_api_want_l2_macs_events_t *mp;
13421   u8 enable_disable = 1;
13422   u32 scan_delay = 0;
13423   u32 max_macs_in_event = 0;
13424   u32 learn_limit = 0;
13425   int ret;
13426
13427   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13428     {
13429       if (unformat (line_input, "learn-limit %d", &learn_limit))
13430         ;
13431       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13432         ;
13433       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13434         ;
13435       else if (unformat (line_input, "disable"))
13436         enable_disable = 0;
13437       else
13438         break;
13439     }
13440
13441   M (WANT_L2_MACS_EVENTS, mp);
13442   mp->enable_disable = enable_disable;
13443   mp->pid = htonl (getpid ());
13444   mp->learn_limit = htonl (learn_limit);
13445   mp->scan_delay = (u8) scan_delay;
13446   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13447   S (mp);
13448   W (ret);
13449   return ret;
13450 }
13451
13452 static int
13453 api_input_acl_set_interface (vat_main_t * vam)
13454 {
13455   unformat_input_t *i = vam->input;
13456   vl_api_input_acl_set_interface_t *mp;
13457   u32 sw_if_index;
13458   int sw_if_index_set;
13459   u32 ip4_table_index = ~0;
13460   u32 ip6_table_index = ~0;
13461   u32 l2_table_index = ~0;
13462   u8 is_add = 1;
13463   int ret;
13464
13465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13466     {
13467       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13468         sw_if_index_set = 1;
13469       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13470         sw_if_index_set = 1;
13471       else if (unformat (i, "del"))
13472         is_add = 0;
13473       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13474         ;
13475       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13476         ;
13477       else if (unformat (i, "l2-table %d", &l2_table_index))
13478         ;
13479       else
13480         {
13481           clib_warning ("parse error '%U'", format_unformat_error, i);
13482           return -99;
13483         }
13484     }
13485
13486   if (sw_if_index_set == 0)
13487     {
13488       errmsg ("missing interface name or sw_if_index");
13489       return -99;
13490     }
13491
13492   M (INPUT_ACL_SET_INTERFACE, mp);
13493
13494   mp->sw_if_index = ntohl (sw_if_index);
13495   mp->ip4_table_index = ntohl (ip4_table_index);
13496   mp->ip6_table_index = ntohl (ip6_table_index);
13497   mp->l2_table_index = ntohl (l2_table_index);
13498   mp->is_add = is_add;
13499
13500   S (mp);
13501   W (ret);
13502   return ret;
13503 }
13504
13505 static int
13506 api_ip_address_dump (vat_main_t * vam)
13507 {
13508   unformat_input_t *i = vam->input;
13509   vl_api_ip_address_dump_t *mp;
13510   vl_api_control_ping_t *mp_ping;
13511   u32 sw_if_index = ~0;
13512   u8 sw_if_index_set = 0;
13513   u8 ipv4_set = 0;
13514   u8 ipv6_set = 0;
13515   int ret;
13516
13517   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13518     {
13519       if (unformat (i, "sw_if_index %d", &sw_if_index))
13520         sw_if_index_set = 1;
13521       else
13522         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13523         sw_if_index_set = 1;
13524       else if (unformat (i, "ipv4"))
13525         ipv4_set = 1;
13526       else if (unformat (i, "ipv6"))
13527         ipv6_set = 1;
13528       else
13529         break;
13530     }
13531
13532   if (ipv4_set && ipv6_set)
13533     {
13534       errmsg ("ipv4 and ipv6 flags cannot be both set");
13535       return -99;
13536     }
13537
13538   if ((!ipv4_set) && (!ipv6_set))
13539     {
13540       errmsg ("no ipv4 nor ipv6 flag set");
13541       return -99;
13542     }
13543
13544   if (sw_if_index_set == 0)
13545     {
13546       errmsg ("missing interface name or sw_if_index");
13547       return -99;
13548     }
13549
13550   vam->current_sw_if_index = sw_if_index;
13551   vam->is_ipv6 = ipv6_set;
13552
13553   M (IP_ADDRESS_DUMP, mp);
13554   mp->sw_if_index = ntohl (sw_if_index);
13555   mp->is_ipv6 = ipv6_set;
13556   S (mp);
13557
13558   /* Use a control ping for synchronization */
13559   MPING (CONTROL_PING, mp_ping);
13560   S (mp_ping);
13561
13562   W (ret);
13563   return ret;
13564 }
13565
13566 static int
13567 api_ip_dump (vat_main_t * vam)
13568 {
13569   vl_api_ip_dump_t *mp;
13570   vl_api_control_ping_t *mp_ping;
13571   unformat_input_t *in = vam->input;
13572   int ipv4_set = 0;
13573   int ipv6_set = 0;
13574   int is_ipv6;
13575   int i;
13576   int ret;
13577
13578   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13579     {
13580       if (unformat (in, "ipv4"))
13581         ipv4_set = 1;
13582       else if (unformat (in, "ipv6"))
13583         ipv6_set = 1;
13584       else
13585         break;
13586     }
13587
13588   if (ipv4_set && ipv6_set)
13589     {
13590       errmsg ("ipv4 and ipv6 flags cannot be both set");
13591       return -99;
13592     }
13593
13594   if ((!ipv4_set) && (!ipv6_set))
13595     {
13596       errmsg ("no ipv4 nor ipv6 flag set");
13597       return -99;
13598     }
13599
13600   is_ipv6 = ipv6_set;
13601   vam->is_ipv6 = is_ipv6;
13602
13603   /* free old data */
13604   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13605     {
13606       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13607     }
13608   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13609
13610   M (IP_DUMP, mp);
13611   mp->is_ipv6 = ipv6_set;
13612   S (mp);
13613
13614   /* Use a control ping for synchronization */
13615   MPING (CONTROL_PING, mp_ping);
13616   S (mp_ping);
13617
13618   W (ret);
13619   return ret;
13620 }
13621
13622 static int
13623 api_ipsec_spd_add_del (vat_main_t * vam)
13624 {
13625   unformat_input_t *i = vam->input;
13626   vl_api_ipsec_spd_add_del_t *mp;
13627   u32 spd_id = ~0;
13628   u8 is_add = 1;
13629   int ret;
13630
13631   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13632     {
13633       if (unformat (i, "spd_id %d", &spd_id))
13634         ;
13635       else if (unformat (i, "del"))
13636         is_add = 0;
13637       else
13638         {
13639           clib_warning ("parse error '%U'", format_unformat_error, i);
13640           return -99;
13641         }
13642     }
13643   if (spd_id == ~0)
13644     {
13645       errmsg ("spd_id must be set");
13646       return -99;
13647     }
13648
13649   M (IPSEC_SPD_ADD_DEL, mp);
13650
13651   mp->spd_id = ntohl (spd_id);
13652   mp->is_add = is_add;
13653
13654   S (mp);
13655   W (ret);
13656   return ret;
13657 }
13658
13659 static int
13660 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13661 {
13662   unformat_input_t *i = vam->input;
13663   vl_api_ipsec_interface_add_del_spd_t *mp;
13664   u32 sw_if_index;
13665   u8 sw_if_index_set = 0;
13666   u32 spd_id = (u32) ~ 0;
13667   u8 is_add = 1;
13668   int ret;
13669
13670   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13671     {
13672       if (unformat (i, "del"))
13673         is_add = 0;
13674       else if (unformat (i, "spd_id %d", &spd_id))
13675         ;
13676       else
13677         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13678         sw_if_index_set = 1;
13679       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13680         sw_if_index_set = 1;
13681       else
13682         {
13683           clib_warning ("parse error '%U'", format_unformat_error, i);
13684           return -99;
13685         }
13686
13687     }
13688
13689   if (spd_id == (u32) ~ 0)
13690     {
13691       errmsg ("spd_id must be set");
13692       return -99;
13693     }
13694
13695   if (sw_if_index_set == 0)
13696     {
13697       errmsg ("missing interface name or sw_if_index");
13698       return -99;
13699     }
13700
13701   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13702
13703   mp->spd_id = ntohl (spd_id);
13704   mp->sw_if_index = ntohl (sw_if_index);
13705   mp->is_add = is_add;
13706
13707   S (mp);
13708   W (ret);
13709   return ret;
13710 }
13711
13712 static int
13713 api_ipsec_spd_add_del_entry (vat_main_t * vam)
13714 {
13715   unformat_input_t *i = vam->input;
13716   vl_api_ipsec_spd_add_del_entry_t *mp;
13717   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
13718   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13719   i32 priority = 0;
13720   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13721   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13722   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
13723   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
13724   int ret;
13725
13726   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
13727   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
13728   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
13729   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
13730   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
13731   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
13732
13733   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13734     {
13735       if (unformat (i, "del"))
13736         is_add = 0;
13737       if (unformat (i, "outbound"))
13738         is_outbound = 1;
13739       if (unformat (i, "inbound"))
13740         is_outbound = 0;
13741       else if (unformat (i, "spd_id %d", &spd_id))
13742         ;
13743       else if (unformat (i, "sa_id %d", &sa_id))
13744         ;
13745       else if (unformat (i, "priority %d", &priority))
13746         ;
13747       else if (unformat (i, "protocol %d", &protocol))
13748         ;
13749       else if (unformat (i, "lport_start %d", &lport_start))
13750         ;
13751       else if (unformat (i, "lport_stop %d", &lport_stop))
13752         ;
13753       else if (unformat (i, "rport_start %d", &rport_start))
13754         ;
13755       else if (unformat (i, "rport_stop %d", &rport_stop))
13756         ;
13757       else
13758         if (unformat
13759             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
13760         {
13761           is_ipv6 = 0;
13762           is_ip_any = 0;
13763         }
13764       else
13765         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
13766         {
13767           is_ipv6 = 0;
13768           is_ip_any = 0;
13769         }
13770       else
13771         if (unformat
13772             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
13773         {
13774           is_ipv6 = 0;
13775           is_ip_any = 0;
13776         }
13777       else
13778         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
13779         {
13780           is_ipv6 = 0;
13781           is_ip_any = 0;
13782         }
13783       else
13784         if (unformat
13785             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
13786         {
13787           is_ipv6 = 1;
13788           is_ip_any = 0;
13789         }
13790       else
13791         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
13792         {
13793           is_ipv6 = 1;
13794           is_ip_any = 0;
13795         }
13796       else
13797         if (unformat
13798             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
13799         {
13800           is_ipv6 = 1;
13801           is_ip_any = 0;
13802         }
13803       else
13804         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
13805         {
13806           is_ipv6 = 1;
13807           is_ip_any = 0;
13808         }
13809       else
13810         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13811         {
13812           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13813             {
13814               clib_warning ("unsupported action: 'resolve'");
13815               return -99;
13816             }
13817         }
13818       else
13819         {
13820           clib_warning ("parse error '%U'", format_unformat_error, i);
13821           return -99;
13822         }
13823
13824     }
13825
13826   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
13827
13828   mp->spd_id = ntohl (spd_id);
13829   mp->priority = ntohl (priority);
13830   mp->is_outbound = is_outbound;
13831
13832   mp->is_ipv6 = is_ipv6;
13833   if (is_ipv6 || is_ip_any)
13834     {
13835       clib_memcpy (mp->remote_address_start, &raddr6_start,
13836                    sizeof (ip6_address_t));
13837       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
13838                    sizeof (ip6_address_t));
13839       clib_memcpy (mp->local_address_start, &laddr6_start,
13840                    sizeof (ip6_address_t));
13841       clib_memcpy (mp->local_address_stop, &laddr6_stop,
13842                    sizeof (ip6_address_t));
13843     }
13844   else
13845     {
13846       clib_memcpy (mp->remote_address_start, &raddr4_start,
13847                    sizeof (ip4_address_t));
13848       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
13849                    sizeof (ip4_address_t));
13850       clib_memcpy (mp->local_address_start, &laddr4_start,
13851                    sizeof (ip4_address_t));
13852       clib_memcpy (mp->local_address_stop, &laddr4_stop,
13853                    sizeof (ip4_address_t));
13854     }
13855   mp->protocol = (u8) protocol;
13856   mp->local_port_start = ntohs ((u16) lport_start);
13857   mp->local_port_stop = ntohs ((u16) lport_stop);
13858   mp->remote_port_start = ntohs ((u16) rport_start);
13859   mp->remote_port_stop = ntohs ((u16) rport_stop);
13860   mp->policy = (u8) policy;
13861   mp->sa_id = ntohl (sa_id);
13862   mp->is_add = is_add;
13863   mp->is_ip_any = is_ip_any;
13864   S (mp);
13865   W (ret);
13866   return ret;
13867 }
13868
13869 static int
13870 api_ipsec_sad_add_del_entry (vat_main_t * vam)
13871 {
13872   unformat_input_t *i = vam->input;
13873   vl_api_ipsec_sad_add_del_entry_t *mp;
13874   u32 sad_id = 0, spi = 0;
13875   u8 *ck = 0, *ik = 0;
13876   u8 is_add = 1;
13877
13878   u8 protocol = IPSEC_PROTOCOL_AH;
13879   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
13880   u32 crypto_alg = 0, integ_alg = 0;
13881   ip4_address_t tun_src4;
13882   ip4_address_t tun_dst4;
13883   ip6_address_t tun_src6;
13884   ip6_address_t tun_dst6;
13885   int ret;
13886
13887   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13888     {
13889       if (unformat (i, "del"))
13890         is_add = 0;
13891       else if (unformat (i, "sad_id %d", &sad_id))
13892         ;
13893       else if (unformat (i, "spi %d", &spi))
13894         ;
13895       else if (unformat (i, "esp"))
13896         protocol = IPSEC_PROTOCOL_ESP;
13897       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
13898         {
13899           is_tunnel = 1;
13900           is_tunnel_ipv6 = 0;
13901         }
13902       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
13903         {
13904           is_tunnel = 1;
13905           is_tunnel_ipv6 = 0;
13906         }
13907       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
13908         {
13909           is_tunnel = 1;
13910           is_tunnel_ipv6 = 1;
13911         }
13912       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
13913         {
13914           is_tunnel = 1;
13915           is_tunnel_ipv6 = 1;
13916         }
13917       else
13918         if (unformat
13919             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
13920         {
13921           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
13922               crypto_alg >= IPSEC_CRYPTO_N_ALG)
13923             {
13924               clib_warning ("unsupported crypto-alg: '%U'",
13925                             format_ipsec_crypto_alg, crypto_alg);
13926               return -99;
13927             }
13928         }
13929       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13930         ;
13931       else
13932         if (unformat
13933             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
13934         {
13935           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
13936               integ_alg >= IPSEC_INTEG_N_ALG)
13937             {
13938               clib_warning ("unsupported integ-alg: '%U'",
13939                             format_ipsec_integ_alg, integ_alg);
13940               return -99;
13941             }
13942         }
13943       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13944         ;
13945       else
13946         {
13947           clib_warning ("parse error '%U'", format_unformat_error, i);
13948           return -99;
13949         }
13950
13951     }
13952
13953   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
13954
13955   mp->sad_id = ntohl (sad_id);
13956   mp->is_add = is_add;
13957   mp->protocol = protocol;
13958   mp->spi = ntohl (spi);
13959   mp->is_tunnel = is_tunnel;
13960   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
13961   mp->crypto_algorithm = crypto_alg;
13962   mp->integrity_algorithm = integ_alg;
13963   mp->crypto_key_length = vec_len (ck);
13964   mp->integrity_key_length = vec_len (ik);
13965
13966   if (mp->crypto_key_length > sizeof (mp->crypto_key))
13967     mp->crypto_key_length = sizeof (mp->crypto_key);
13968
13969   if (mp->integrity_key_length > sizeof (mp->integrity_key))
13970     mp->integrity_key_length = sizeof (mp->integrity_key);
13971
13972   if (ck)
13973     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
13974   if (ik)
13975     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
13976
13977   if (is_tunnel)
13978     {
13979       if (is_tunnel_ipv6)
13980         {
13981           clib_memcpy (mp->tunnel_src_address, &tun_src6,
13982                        sizeof (ip6_address_t));
13983           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
13984                        sizeof (ip6_address_t));
13985         }
13986       else
13987         {
13988           clib_memcpy (mp->tunnel_src_address, &tun_src4,
13989                        sizeof (ip4_address_t));
13990           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
13991                        sizeof (ip4_address_t));
13992         }
13993     }
13994
13995   S (mp);
13996   W (ret);
13997   return ret;
13998 }
13999
14000 static int
14001 api_ipsec_sa_set_key (vat_main_t * vam)
14002 {
14003   unformat_input_t *i = vam->input;
14004   vl_api_ipsec_sa_set_key_t *mp;
14005   u32 sa_id;
14006   u8 *ck = 0, *ik = 0;
14007   int ret;
14008
14009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14010     {
14011       if (unformat (i, "sa_id %d", &sa_id))
14012         ;
14013       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14014         ;
14015       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14016         ;
14017       else
14018         {
14019           clib_warning ("parse error '%U'", format_unformat_error, i);
14020           return -99;
14021         }
14022     }
14023
14024   M (IPSEC_SA_SET_KEY, mp);
14025
14026   mp->sa_id = ntohl (sa_id);
14027   mp->crypto_key_length = vec_len (ck);
14028   mp->integrity_key_length = vec_len (ik);
14029
14030   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14031     mp->crypto_key_length = sizeof (mp->crypto_key);
14032
14033   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14034     mp->integrity_key_length = sizeof (mp->integrity_key);
14035
14036   if (ck)
14037     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14038   if (ik)
14039     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14040
14041   S (mp);
14042   W (ret);
14043   return ret;
14044 }
14045
14046 static int
14047 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14048 {
14049   unformat_input_t *i = vam->input;
14050   vl_api_ipsec_tunnel_if_add_del_t *mp;
14051   u32 local_spi = 0, remote_spi = 0;
14052   u32 crypto_alg = 0, integ_alg = 0;
14053   u8 *lck = NULL, *rck = NULL;
14054   u8 *lik = NULL, *rik = NULL;
14055   ip4_address_t local_ip = { {0} };
14056   ip4_address_t remote_ip = { {0} };
14057   u8 is_add = 1;
14058   u8 esn = 0;
14059   u8 anti_replay = 0;
14060   int ret;
14061
14062   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14063     {
14064       if (unformat (i, "del"))
14065         is_add = 0;
14066       else if (unformat (i, "esn"))
14067         esn = 1;
14068       else if (unformat (i, "anti_replay"))
14069         anti_replay = 1;
14070       else if (unformat (i, "local_spi %d", &local_spi))
14071         ;
14072       else if (unformat (i, "remote_spi %d", &remote_spi))
14073         ;
14074       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
14075         ;
14076       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
14077         ;
14078       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14079         ;
14080       else
14081         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14082         ;
14083       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14084         ;
14085       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14086         ;
14087       else
14088         if (unformat
14089             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14090         {
14091           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14092               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14093             {
14094               errmsg ("unsupported crypto-alg: '%U'\n",
14095                       format_ipsec_crypto_alg, crypto_alg);
14096               return -99;
14097             }
14098         }
14099       else
14100         if (unformat
14101             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14102         {
14103           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14104               integ_alg >= IPSEC_INTEG_N_ALG)
14105             {
14106               errmsg ("unsupported integ-alg: '%U'\n",
14107                       format_ipsec_integ_alg, integ_alg);
14108               return -99;
14109             }
14110         }
14111       else
14112         {
14113           errmsg ("parse error '%U'\n", format_unformat_error, i);
14114           return -99;
14115         }
14116     }
14117
14118   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14119
14120   mp->is_add = is_add;
14121   mp->esn = esn;
14122   mp->anti_replay = anti_replay;
14123
14124   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
14125   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
14126
14127   mp->local_spi = htonl (local_spi);
14128   mp->remote_spi = htonl (remote_spi);
14129   mp->crypto_alg = (u8) crypto_alg;
14130
14131   mp->local_crypto_key_len = 0;
14132   if (lck)
14133     {
14134       mp->local_crypto_key_len = vec_len (lck);
14135       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14136         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14137       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14138     }
14139
14140   mp->remote_crypto_key_len = 0;
14141   if (rck)
14142     {
14143       mp->remote_crypto_key_len = vec_len (rck);
14144       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14145         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14146       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14147     }
14148
14149   mp->integ_alg = (u8) integ_alg;
14150
14151   mp->local_integ_key_len = 0;
14152   if (lik)
14153     {
14154       mp->local_integ_key_len = vec_len (lik);
14155       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14156         mp->local_integ_key_len = sizeof (mp->local_integ_key);
14157       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14158     }
14159
14160   mp->remote_integ_key_len = 0;
14161   if (rik)
14162     {
14163       mp->remote_integ_key_len = vec_len (rik);
14164       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14165         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14166       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14167     }
14168
14169   S (mp);
14170   W (ret);
14171   return ret;
14172 }
14173
14174 static void
14175 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14176 {
14177   vat_main_t *vam = &vat_main;
14178
14179   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14180          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
14181          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
14182          "tunnel_src_addr %U tunnel_dst_addr %U "
14183          "salt %u seq_outbound %lu last_seq_inbound %lu "
14184          "replay_window %lu total_data_size %lu\n",
14185          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
14186          mp->protocol,
14187          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
14188          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
14189          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
14190          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14191          mp->tunnel_src_addr,
14192          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14193          mp->tunnel_dst_addr,
14194          ntohl (mp->salt),
14195          clib_net_to_host_u64 (mp->seq_outbound),
14196          clib_net_to_host_u64 (mp->last_seq_inbound),
14197          clib_net_to_host_u64 (mp->replay_window),
14198          clib_net_to_host_u64 (mp->total_data_size));
14199 }
14200
14201 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14202 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14203
14204 static void vl_api_ipsec_sa_details_t_handler_json
14205   (vl_api_ipsec_sa_details_t * mp)
14206 {
14207   vat_main_t *vam = &vat_main;
14208   vat_json_node_t *node = NULL;
14209   struct in_addr src_ip4, dst_ip4;
14210   struct in6_addr src_ip6, dst_ip6;
14211
14212   if (VAT_JSON_ARRAY != vam->json_tree.type)
14213     {
14214       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14215       vat_json_init_array (&vam->json_tree);
14216     }
14217   node = vat_json_array_add (&vam->json_tree);
14218
14219   vat_json_init_object (node);
14220   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
14221   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14222   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
14223   vat_json_object_add_uint (node, "proto", mp->protocol);
14224   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
14225   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
14226   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
14227   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
14228   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
14229   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
14230   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
14231                              mp->crypto_key_len);
14232   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
14233                              mp->integ_key_len);
14234   if (mp->is_tunnel_ip6)
14235     {
14236       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
14237       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
14238       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
14239       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
14240     }
14241   else
14242     {
14243       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
14244       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
14245       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
14246       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
14247     }
14248   vat_json_object_add_uint (node, "replay_window",
14249                             clib_net_to_host_u64 (mp->replay_window));
14250   vat_json_object_add_uint (node, "total_data_size",
14251                             clib_net_to_host_u64 (mp->total_data_size));
14252
14253 }
14254
14255 static int
14256 api_ipsec_sa_dump (vat_main_t * vam)
14257 {
14258   unformat_input_t *i = vam->input;
14259   vl_api_ipsec_sa_dump_t *mp;
14260   vl_api_control_ping_t *mp_ping;
14261   u32 sa_id = ~0;
14262   int ret;
14263
14264   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14265     {
14266       if (unformat (i, "sa_id %d", &sa_id))
14267         ;
14268       else
14269         {
14270           clib_warning ("parse error '%U'", format_unformat_error, i);
14271           return -99;
14272         }
14273     }
14274
14275   M (IPSEC_SA_DUMP, mp);
14276
14277   mp->sa_id = ntohl (sa_id);
14278
14279   S (mp);
14280
14281   /* Use a control ping for synchronization */
14282   M (CONTROL_PING, mp_ping);
14283   S (mp_ping);
14284
14285   W (ret);
14286   return ret;
14287 }
14288
14289 static int
14290 api_ipsec_tunnel_if_set_key (vat_main_t * vam)
14291 {
14292   unformat_input_t *i = vam->input;
14293   vl_api_ipsec_tunnel_if_set_key_t *mp;
14294   u32 sw_if_index = ~0;
14295   u8 key_type = IPSEC_IF_SET_KEY_TYPE_NONE;
14296   u8 *key = 0;
14297   u32 alg = ~0;
14298   int ret;
14299
14300   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14301     {
14302       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14303         ;
14304       else
14305         if (unformat (i, "local crypto %U", unformat_ipsec_crypto_alg, &alg))
14306         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_CRYPTO;
14307       else
14308         if (unformat (i, "remote crypto %U", unformat_ipsec_crypto_alg, &alg))
14309         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO;
14310       else if (unformat (i, "local integ %U", unformat_ipsec_integ_alg, &alg))
14311         key_type = IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG;
14312       else
14313         if (unformat (i, "remote integ %U", unformat_ipsec_integ_alg, &alg))
14314         key_type = IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG;
14315       else if (unformat (i, "%U", unformat_hex_string, &key))
14316         ;
14317       else
14318         {
14319           clib_warning ("parse error '%U'", format_unformat_error, i);
14320           return -99;
14321         }
14322     }
14323
14324   if (sw_if_index == ~0)
14325     {
14326       errmsg ("interface must be specified");
14327       return -99;
14328     }
14329
14330   if (key_type == IPSEC_IF_SET_KEY_TYPE_NONE)
14331     {
14332       errmsg ("key type must be specified");
14333       return -99;
14334     }
14335
14336   if (alg == ~0)
14337     {
14338       errmsg ("algorithm must be specified");
14339       return -99;
14340     }
14341
14342   if (vec_len (key) == 0)
14343     {
14344       errmsg ("key must be specified");
14345       return -99;
14346     }
14347
14348   M (IPSEC_TUNNEL_IF_SET_KEY, mp);
14349
14350   mp->sw_if_index = htonl (sw_if_index);
14351   mp->alg = alg;
14352   mp->key_type = key_type;
14353   mp->key_len = vec_len (key);
14354   clib_memcpy (mp->key, key, vec_len (key));
14355
14356   S (mp);
14357   W (ret);
14358
14359   return ret;
14360 }
14361
14362 static int
14363 api_ikev2_profile_add_del (vat_main_t * vam)
14364 {
14365   unformat_input_t *i = vam->input;
14366   vl_api_ikev2_profile_add_del_t *mp;
14367   u8 is_add = 1;
14368   u8 *name = 0;
14369   int ret;
14370
14371   const char *valid_chars = "a-zA-Z0-9_";
14372
14373   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14374     {
14375       if (unformat (i, "del"))
14376         is_add = 0;
14377       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14378         vec_add1 (name, 0);
14379       else
14380         {
14381           errmsg ("parse error '%U'", format_unformat_error, i);
14382           return -99;
14383         }
14384     }
14385
14386   if (!vec_len (name))
14387     {
14388       errmsg ("profile name must be specified");
14389       return -99;
14390     }
14391
14392   if (vec_len (name) > 64)
14393     {
14394       errmsg ("profile name too long");
14395       return -99;
14396     }
14397
14398   M (IKEV2_PROFILE_ADD_DEL, mp);
14399
14400   clib_memcpy (mp->name, name, vec_len (name));
14401   mp->is_add = is_add;
14402   vec_free (name);
14403
14404   S (mp);
14405   W (ret);
14406   return ret;
14407 }
14408
14409 static int
14410 api_ikev2_profile_set_auth (vat_main_t * vam)
14411 {
14412   unformat_input_t *i = vam->input;
14413   vl_api_ikev2_profile_set_auth_t *mp;
14414   u8 *name = 0;
14415   u8 *data = 0;
14416   u32 auth_method = 0;
14417   u8 is_hex = 0;
14418   int ret;
14419
14420   const char *valid_chars = "a-zA-Z0-9_";
14421
14422   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14423     {
14424       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14425         vec_add1 (name, 0);
14426       else if (unformat (i, "auth_method %U",
14427                          unformat_ikev2_auth_method, &auth_method))
14428         ;
14429       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
14430         is_hex = 1;
14431       else if (unformat (i, "auth_data %v", &data))
14432         ;
14433       else
14434         {
14435           errmsg ("parse error '%U'", format_unformat_error, i);
14436           return -99;
14437         }
14438     }
14439
14440   if (!vec_len (name))
14441     {
14442       errmsg ("profile name must be specified");
14443       return -99;
14444     }
14445
14446   if (vec_len (name) > 64)
14447     {
14448       errmsg ("profile name too long");
14449       return -99;
14450     }
14451
14452   if (!vec_len (data))
14453     {
14454       errmsg ("auth_data must be specified");
14455       return -99;
14456     }
14457
14458   if (!auth_method)
14459     {
14460       errmsg ("auth_method must be specified");
14461       return -99;
14462     }
14463
14464   M (IKEV2_PROFILE_SET_AUTH, mp);
14465
14466   mp->is_hex = is_hex;
14467   mp->auth_method = (u8) auth_method;
14468   mp->data_len = vec_len (data);
14469   clib_memcpy (mp->name, name, vec_len (name));
14470   clib_memcpy (mp->data, data, vec_len (data));
14471   vec_free (name);
14472   vec_free (data);
14473
14474   S (mp);
14475   W (ret);
14476   return ret;
14477 }
14478
14479 static int
14480 api_ikev2_profile_set_id (vat_main_t * vam)
14481 {
14482   unformat_input_t *i = vam->input;
14483   vl_api_ikev2_profile_set_id_t *mp;
14484   u8 *name = 0;
14485   u8 *data = 0;
14486   u8 is_local = 0;
14487   u32 id_type = 0;
14488   ip4_address_t ip4;
14489   int ret;
14490
14491   const char *valid_chars = "a-zA-Z0-9_";
14492
14493   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14494     {
14495       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14496         vec_add1 (name, 0);
14497       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
14498         ;
14499       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
14500         {
14501           data = vec_new (u8, 4);
14502           clib_memcpy (data, ip4.as_u8, 4);
14503         }
14504       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
14505         ;
14506       else if (unformat (i, "id_data %v", &data))
14507         ;
14508       else if (unformat (i, "local"))
14509         is_local = 1;
14510       else if (unformat (i, "remote"))
14511         is_local = 0;
14512       else
14513         {
14514           errmsg ("parse error '%U'", format_unformat_error, i);
14515           return -99;
14516         }
14517     }
14518
14519   if (!vec_len (name))
14520     {
14521       errmsg ("profile name must be specified");
14522       return -99;
14523     }
14524
14525   if (vec_len (name) > 64)
14526     {
14527       errmsg ("profile name too long");
14528       return -99;
14529     }
14530
14531   if (!vec_len (data))
14532     {
14533       errmsg ("id_data must be specified");
14534       return -99;
14535     }
14536
14537   if (!id_type)
14538     {
14539       errmsg ("id_type must be specified");
14540       return -99;
14541     }
14542
14543   M (IKEV2_PROFILE_SET_ID, mp);
14544
14545   mp->is_local = is_local;
14546   mp->id_type = (u8) id_type;
14547   mp->data_len = vec_len (data);
14548   clib_memcpy (mp->name, name, vec_len (name));
14549   clib_memcpy (mp->data, data, vec_len (data));
14550   vec_free (name);
14551   vec_free (data);
14552
14553   S (mp);
14554   W (ret);
14555   return ret;
14556 }
14557
14558 static int
14559 api_ikev2_profile_set_ts (vat_main_t * vam)
14560 {
14561   unformat_input_t *i = vam->input;
14562   vl_api_ikev2_profile_set_ts_t *mp;
14563   u8 *name = 0;
14564   u8 is_local = 0;
14565   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
14566   ip4_address_t start_addr, end_addr;
14567
14568   const char *valid_chars = "a-zA-Z0-9_";
14569   int ret;
14570
14571   start_addr.as_u32 = 0;
14572   end_addr.as_u32 = (u32) ~ 0;
14573
14574   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14575     {
14576       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14577         vec_add1 (name, 0);
14578       else if (unformat (i, "protocol %d", &proto))
14579         ;
14580       else if (unformat (i, "start_port %d", &start_port))
14581         ;
14582       else if (unformat (i, "end_port %d", &end_port))
14583         ;
14584       else
14585         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
14586         ;
14587       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
14588         ;
14589       else if (unformat (i, "local"))
14590         is_local = 1;
14591       else if (unformat (i, "remote"))
14592         is_local = 0;
14593       else
14594         {
14595           errmsg ("parse error '%U'", format_unformat_error, i);
14596           return -99;
14597         }
14598     }
14599
14600   if (!vec_len (name))
14601     {
14602       errmsg ("profile name must be specified");
14603       return -99;
14604     }
14605
14606   if (vec_len (name) > 64)
14607     {
14608       errmsg ("profile name too long");
14609       return -99;
14610     }
14611
14612   M (IKEV2_PROFILE_SET_TS, mp);
14613
14614   mp->is_local = is_local;
14615   mp->proto = (u8) proto;
14616   mp->start_port = (u16) start_port;
14617   mp->end_port = (u16) end_port;
14618   mp->start_addr = start_addr.as_u32;
14619   mp->end_addr = end_addr.as_u32;
14620   clib_memcpy (mp->name, name, vec_len (name));
14621   vec_free (name);
14622
14623   S (mp);
14624   W (ret);
14625   return ret;
14626 }
14627
14628 static int
14629 api_ikev2_set_local_key (vat_main_t * vam)
14630 {
14631   unformat_input_t *i = vam->input;
14632   vl_api_ikev2_set_local_key_t *mp;
14633   u8 *file = 0;
14634   int ret;
14635
14636   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14637     {
14638       if (unformat (i, "file %v", &file))
14639         vec_add1 (file, 0);
14640       else
14641         {
14642           errmsg ("parse error '%U'", format_unformat_error, i);
14643           return -99;
14644         }
14645     }
14646
14647   if (!vec_len (file))
14648     {
14649       errmsg ("RSA key file must be specified");
14650       return -99;
14651     }
14652
14653   if (vec_len (file) > 256)
14654     {
14655       errmsg ("file name too long");
14656       return -99;
14657     }
14658
14659   M (IKEV2_SET_LOCAL_KEY, mp);
14660
14661   clib_memcpy (mp->key_file, file, vec_len (file));
14662   vec_free (file);
14663
14664   S (mp);
14665   W (ret);
14666   return ret;
14667 }
14668
14669 static int
14670 api_ikev2_set_responder (vat_main_t * vam)
14671 {
14672   unformat_input_t *i = vam->input;
14673   vl_api_ikev2_set_responder_t *mp;
14674   int ret;
14675   u8 *name = 0;
14676   u32 sw_if_index = ~0;
14677   ip4_address_t address;
14678
14679   const char *valid_chars = "a-zA-Z0-9_";
14680
14681   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14682     {
14683       if (unformat
14684           (i, "%U interface %d address %U", unformat_token, valid_chars,
14685            &name, &sw_if_index, unformat_ip4_address, &address))
14686         vec_add1 (name, 0);
14687       else
14688         {
14689           errmsg ("parse error '%U'", format_unformat_error, i);
14690           return -99;
14691         }
14692     }
14693
14694   if (!vec_len (name))
14695     {
14696       errmsg ("profile name must be specified");
14697       return -99;
14698     }
14699
14700   if (vec_len (name) > 64)
14701     {
14702       errmsg ("profile name too long");
14703       return -99;
14704     }
14705
14706   M (IKEV2_SET_RESPONDER, mp);
14707
14708   clib_memcpy (mp->name, name, vec_len (name));
14709   vec_free (name);
14710
14711   mp->sw_if_index = sw_if_index;
14712   clib_memcpy (mp->address, &address, sizeof (address));
14713
14714   S (mp);
14715   W (ret);
14716   return ret;
14717 }
14718
14719 static int
14720 api_ikev2_set_ike_transforms (vat_main_t * vam)
14721 {
14722   unformat_input_t *i = vam->input;
14723   vl_api_ikev2_set_ike_transforms_t *mp;
14724   int ret;
14725   u8 *name = 0;
14726   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
14727
14728   const char *valid_chars = "a-zA-Z0-9_";
14729
14730   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14731     {
14732       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
14733                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
14734         vec_add1 (name, 0);
14735       else
14736         {
14737           errmsg ("parse error '%U'", format_unformat_error, i);
14738           return -99;
14739         }
14740     }
14741
14742   if (!vec_len (name))
14743     {
14744       errmsg ("profile name must be specified");
14745       return -99;
14746     }
14747
14748   if (vec_len (name) > 64)
14749     {
14750       errmsg ("profile name too long");
14751       return -99;
14752     }
14753
14754   M (IKEV2_SET_IKE_TRANSFORMS, mp);
14755
14756   clib_memcpy (mp->name, name, vec_len (name));
14757   vec_free (name);
14758   mp->crypto_alg = crypto_alg;
14759   mp->crypto_key_size = crypto_key_size;
14760   mp->integ_alg = integ_alg;
14761   mp->dh_group = dh_group;
14762
14763   S (mp);
14764   W (ret);
14765   return ret;
14766 }
14767
14768
14769 static int
14770 api_ikev2_set_esp_transforms (vat_main_t * vam)
14771 {
14772   unformat_input_t *i = vam->input;
14773   vl_api_ikev2_set_esp_transforms_t *mp;
14774   int ret;
14775   u8 *name = 0;
14776   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
14777
14778   const char *valid_chars = "a-zA-Z0-9_";
14779
14780   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14781     {
14782       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
14783                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
14784         vec_add1 (name, 0);
14785       else
14786         {
14787           errmsg ("parse error '%U'", format_unformat_error, i);
14788           return -99;
14789         }
14790     }
14791
14792   if (!vec_len (name))
14793     {
14794       errmsg ("profile name must be specified");
14795       return -99;
14796     }
14797
14798   if (vec_len (name) > 64)
14799     {
14800       errmsg ("profile name too long");
14801       return -99;
14802     }
14803
14804   M (IKEV2_SET_ESP_TRANSFORMS, mp);
14805
14806   clib_memcpy (mp->name, name, vec_len (name));
14807   vec_free (name);
14808   mp->crypto_alg = crypto_alg;
14809   mp->crypto_key_size = crypto_key_size;
14810   mp->integ_alg = integ_alg;
14811   mp->dh_group = dh_group;
14812
14813   S (mp);
14814   W (ret);
14815   return ret;
14816 }
14817
14818 static int
14819 api_ikev2_set_sa_lifetime (vat_main_t * vam)
14820 {
14821   unformat_input_t *i = vam->input;
14822   vl_api_ikev2_set_sa_lifetime_t *mp;
14823   int ret;
14824   u8 *name = 0;
14825   u64 lifetime, lifetime_maxdata;
14826   u32 lifetime_jitter, handover;
14827
14828   const char *valid_chars = "a-zA-Z0-9_";
14829
14830   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14831     {
14832       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
14833                     &lifetime, &lifetime_jitter, &handover,
14834                     &lifetime_maxdata))
14835         vec_add1 (name, 0);
14836       else
14837         {
14838           errmsg ("parse error '%U'", format_unformat_error, i);
14839           return -99;
14840         }
14841     }
14842
14843   if (!vec_len (name))
14844     {
14845       errmsg ("profile name must be specified");
14846       return -99;
14847     }
14848
14849   if (vec_len (name) > 64)
14850     {
14851       errmsg ("profile name too long");
14852       return -99;
14853     }
14854
14855   M (IKEV2_SET_SA_LIFETIME, mp);
14856
14857   clib_memcpy (mp->name, name, vec_len (name));
14858   vec_free (name);
14859   mp->lifetime = lifetime;
14860   mp->lifetime_jitter = lifetime_jitter;
14861   mp->handover = handover;
14862   mp->lifetime_maxdata = lifetime_maxdata;
14863
14864   S (mp);
14865   W (ret);
14866   return ret;
14867 }
14868
14869 static int
14870 api_ikev2_initiate_sa_init (vat_main_t * vam)
14871 {
14872   unformat_input_t *i = vam->input;
14873   vl_api_ikev2_initiate_sa_init_t *mp;
14874   int ret;
14875   u8 *name = 0;
14876
14877   const char *valid_chars = "a-zA-Z0-9_";
14878
14879   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14880     {
14881       if (unformat (i, "%U", unformat_token, valid_chars, &name))
14882         vec_add1 (name, 0);
14883       else
14884         {
14885           errmsg ("parse error '%U'", format_unformat_error, i);
14886           return -99;
14887         }
14888     }
14889
14890   if (!vec_len (name))
14891     {
14892       errmsg ("profile name must be specified");
14893       return -99;
14894     }
14895
14896   if (vec_len (name) > 64)
14897     {
14898       errmsg ("profile name too long");
14899       return -99;
14900     }
14901
14902   M (IKEV2_INITIATE_SA_INIT, mp);
14903
14904   clib_memcpy (mp->name, name, vec_len (name));
14905   vec_free (name);
14906
14907   S (mp);
14908   W (ret);
14909   return ret;
14910 }
14911
14912 static int
14913 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
14914 {
14915   unformat_input_t *i = vam->input;
14916   vl_api_ikev2_initiate_del_ike_sa_t *mp;
14917   int ret;
14918   u64 ispi;
14919
14920
14921   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14922     {
14923       if (unformat (i, "%lx", &ispi))
14924         ;
14925       else
14926         {
14927           errmsg ("parse error '%U'", format_unformat_error, i);
14928           return -99;
14929         }
14930     }
14931
14932   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
14933
14934   mp->ispi = ispi;
14935
14936   S (mp);
14937   W (ret);
14938   return ret;
14939 }
14940
14941 static int
14942 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
14943 {
14944   unformat_input_t *i = vam->input;
14945   vl_api_ikev2_initiate_del_child_sa_t *mp;
14946   int ret;
14947   u32 ispi;
14948
14949
14950   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14951     {
14952       if (unformat (i, "%x", &ispi))
14953         ;
14954       else
14955         {
14956           errmsg ("parse error '%U'", format_unformat_error, i);
14957           return -99;
14958         }
14959     }
14960
14961   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
14962
14963   mp->ispi = ispi;
14964
14965   S (mp);
14966   W (ret);
14967   return ret;
14968 }
14969
14970 static int
14971 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
14972 {
14973   unformat_input_t *i = vam->input;
14974   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
14975   int ret;
14976   u32 ispi;
14977
14978
14979   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14980     {
14981       if (unformat (i, "%x", &ispi))
14982         ;
14983       else
14984         {
14985           errmsg ("parse error '%U'", format_unformat_error, i);
14986           return -99;
14987         }
14988     }
14989
14990   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
14991
14992   mp->ispi = ispi;
14993
14994   S (mp);
14995   W (ret);
14996   return ret;
14997 }
14998
14999 /*
15000  * MAP
15001  */
15002 static int
15003 api_map_add_domain (vat_main_t * vam)
15004 {
15005   unformat_input_t *i = vam->input;
15006   vl_api_map_add_domain_t *mp;
15007
15008   ip4_address_t ip4_prefix;
15009   ip6_address_t ip6_prefix;
15010   ip6_address_t ip6_src;
15011   u32 num_m_args = 0;
15012   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
15013     0, psid_length = 0;
15014   u8 is_translation = 0;
15015   u32 mtu = 0;
15016   u32 ip6_src_len = 128;
15017   int ret;
15018
15019   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15020     {
15021       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
15022                     &ip4_prefix, &ip4_prefix_len))
15023         num_m_args++;
15024       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
15025                          &ip6_prefix, &ip6_prefix_len))
15026         num_m_args++;
15027       else
15028         if (unformat
15029             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
15030              &ip6_src_len))
15031         num_m_args++;
15032       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
15033         num_m_args++;
15034       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
15035         num_m_args++;
15036       else if (unformat (i, "psid-offset %d", &psid_offset))
15037         num_m_args++;
15038       else if (unformat (i, "psid-len %d", &psid_length))
15039         num_m_args++;
15040       else if (unformat (i, "mtu %d", &mtu))
15041         num_m_args++;
15042       else if (unformat (i, "map-t"))
15043         is_translation = 1;
15044       else
15045         {
15046           clib_warning ("parse error '%U'", format_unformat_error, i);
15047           return -99;
15048         }
15049     }
15050
15051   if (num_m_args < 3)
15052     {
15053       errmsg ("mandatory argument(s) missing");
15054       return -99;
15055     }
15056
15057   /* Construct the API message */
15058   M (MAP_ADD_DOMAIN, mp);
15059
15060   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
15061   mp->ip4_prefix_len = ip4_prefix_len;
15062
15063   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
15064   mp->ip6_prefix_len = ip6_prefix_len;
15065
15066   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
15067   mp->ip6_src_prefix_len = ip6_src_len;
15068
15069   mp->ea_bits_len = ea_bits_len;
15070   mp->psid_offset = psid_offset;
15071   mp->psid_length = psid_length;
15072   mp->is_translation = is_translation;
15073   mp->mtu = htons (mtu);
15074
15075   /* send it... */
15076   S (mp);
15077
15078   /* Wait for a reply, return good/bad news  */
15079   W (ret);
15080   return ret;
15081 }
15082
15083 static int
15084 api_map_del_domain (vat_main_t * vam)
15085 {
15086   unformat_input_t *i = vam->input;
15087   vl_api_map_del_domain_t *mp;
15088
15089   u32 num_m_args = 0;
15090   u32 index;
15091   int ret;
15092
15093   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15094     {
15095       if (unformat (i, "index %d", &index))
15096         num_m_args++;
15097       else
15098         {
15099           clib_warning ("parse error '%U'", format_unformat_error, i);
15100           return -99;
15101         }
15102     }
15103
15104   if (num_m_args != 1)
15105     {
15106       errmsg ("mandatory argument(s) missing");
15107       return -99;
15108     }
15109
15110   /* Construct the API message */
15111   M (MAP_DEL_DOMAIN, mp);
15112
15113   mp->index = ntohl (index);
15114
15115   /* send it... */
15116   S (mp);
15117
15118   /* Wait for a reply, return good/bad news  */
15119   W (ret);
15120   return ret;
15121 }
15122
15123 static int
15124 api_map_add_del_rule (vat_main_t * vam)
15125 {
15126   unformat_input_t *i = vam->input;
15127   vl_api_map_add_del_rule_t *mp;
15128   u8 is_add = 1;
15129   ip6_address_t ip6_dst;
15130   u32 num_m_args = 0, index, psid = 0;
15131   int ret;
15132
15133   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15134     {
15135       if (unformat (i, "index %d", &index))
15136         num_m_args++;
15137       else if (unformat (i, "psid %d", &psid))
15138         num_m_args++;
15139       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
15140         num_m_args++;
15141       else if (unformat (i, "del"))
15142         {
15143           is_add = 0;
15144         }
15145       else
15146         {
15147           clib_warning ("parse error '%U'", format_unformat_error, i);
15148           return -99;
15149         }
15150     }
15151
15152   /* Construct the API message */
15153   M (MAP_ADD_DEL_RULE, mp);
15154
15155   mp->index = ntohl (index);
15156   mp->is_add = is_add;
15157   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
15158   mp->psid = ntohs (psid);
15159
15160   /* send it... */
15161   S (mp);
15162
15163   /* Wait for a reply, return good/bad news  */
15164   W (ret);
15165   return ret;
15166 }
15167
15168 static int
15169 api_map_domain_dump (vat_main_t * vam)
15170 {
15171   vl_api_map_domain_dump_t *mp;
15172   vl_api_control_ping_t *mp_ping;
15173   int ret;
15174
15175   /* Construct the API message */
15176   M (MAP_DOMAIN_DUMP, mp);
15177
15178   /* send it... */
15179   S (mp);
15180
15181   /* Use a control ping for synchronization */
15182   MPING (CONTROL_PING, mp_ping);
15183   S (mp_ping);
15184
15185   W (ret);
15186   return ret;
15187 }
15188
15189 static int
15190 api_map_rule_dump (vat_main_t * vam)
15191 {
15192   unformat_input_t *i = vam->input;
15193   vl_api_map_rule_dump_t *mp;
15194   vl_api_control_ping_t *mp_ping;
15195   u32 domain_index = ~0;
15196   int ret;
15197
15198   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15199     {
15200       if (unformat (i, "index %u", &domain_index))
15201         ;
15202       else
15203         break;
15204     }
15205
15206   if (domain_index == ~0)
15207     {
15208       clib_warning ("parse error: domain index expected");
15209       return -99;
15210     }
15211
15212   /* Construct the API message */
15213   M (MAP_RULE_DUMP, mp);
15214
15215   mp->domain_index = htonl (domain_index);
15216
15217   /* send it... */
15218   S (mp);
15219
15220   /* Use a control ping for synchronization */
15221   MPING (CONTROL_PING, mp_ping);
15222   S (mp_ping);
15223
15224   W (ret);
15225   return ret;
15226 }
15227
15228 static void vl_api_map_add_domain_reply_t_handler
15229   (vl_api_map_add_domain_reply_t * mp)
15230 {
15231   vat_main_t *vam = &vat_main;
15232   i32 retval = ntohl (mp->retval);
15233
15234   if (vam->async_mode)
15235     {
15236       vam->async_errors += (retval < 0);
15237     }
15238   else
15239     {
15240       vam->retval = retval;
15241       vam->result_ready = 1;
15242     }
15243 }
15244
15245 static void vl_api_map_add_domain_reply_t_handler_json
15246   (vl_api_map_add_domain_reply_t * mp)
15247 {
15248   vat_main_t *vam = &vat_main;
15249   vat_json_node_t node;
15250
15251   vat_json_init_object (&node);
15252   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
15253   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
15254
15255   vat_json_print (vam->ofp, &node);
15256   vat_json_free (&node);
15257
15258   vam->retval = ntohl (mp->retval);
15259   vam->result_ready = 1;
15260 }
15261
15262 static int
15263 api_get_first_msg_id (vat_main_t * vam)
15264 {
15265   vl_api_get_first_msg_id_t *mp;
15266   unformat_input_t *i = vam->input;
15267   u8 *name;
15268   u8 name_set = 0;
15269   int ret;
15270
15271   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15272     {
15273       if (unformat (i, "client %s", &name))
15274         name_set = 1;
15275       else
15276         break;
15277     }
15278
15279   if (name_set == 0)
15280     {
15281       errmsg ("missing client name");
15282       return -99;
15283     }
15284   vec_add1 (name, 0);
15285
15286   if (vec_len (name) > 63)
15287     {
15288       errmsg ("client name too long");
15289       return -99;
15290     }
15291
15292   M (GET_FIRST_MSG_ID, mp);
15293   clib_memcpy (mp->name, name, vec_len (name));
15294   S (mp);
15295   W (ret);
15296   return ret;
15297 }
15298
15299 static int
15300 api_cop_interface_enable_disable (vat_main_t * vam)
15301 {
15302   unformat_input_t *line_input = vam->input;
15303   vl_api_cop_interface_enable_disable_t *mp;
15304   u32 sw_if_index = ~0;
15305   u8 enable_disable = 1;
15306   int ret;
15307
15308   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15309     {
15310       if (unformat (line_input, "disable"))
15311         enable_disable = 0;
15312       if (unformat (line_input, "enable"))
15313         enable_disable = 1;
15314       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15315                          vam, &sw_if_index))
15316         ;
15317       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15318         ;
15319       else
15320         break;
15321     }
15322
15323   if (sw_if_index == ~0)
15324     {
15325       errmsg ("missing interface name or sw_if_index");
15326       return -99;
15327     }
15328
15329   /* Construct the API message */
15330   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15331   mp->sw_if_index = ntohl (sw_if_index);
15332   mp->enable_disable = enable_disable;
15333
15334   /* send it... */
15335   S (mp);
15336   /* Wait for the reply */
15337   W (ret);
15338   return ret;
15339 }
15340
15341 static int
15342 api_cop_whitelist_enable_disable (vat_main_t * vam)
15343 {
15344   unformat_input_t *line_input = vam->input;
15345   vl_api_cop_whitelist_enable_disable_t *mp;
15346   u32 sw_if_index = ~0;
15347   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15348   u32 fib_id = 0;
15349   int ret;
15350
15351   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15352     {
15353       if (unformat (line_input, "ip4"))
15354         ip4 = 1;
15355       else if (unformat (line_input, "ip6"))
15356         ip6 = 1;
15357       else if (unformat (line_input, "default"))
15358         default_cop = 1;
15359       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15360                          vam, &sw_if_index))
15361         ;
15362       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15363         ;
15364       else if (unformat (line_input, "fib-id %d", &fib_id))
15365         ;
15366       else
15367         break;
15368     }
15369
15370   if (sw_if_index == ~0)
15371     {
15372       errmsg ("missing interface name or sw_if_index");
15373       return -99;
15374     }
15375
15376   /* Construct the API message */
15377   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15378   mp->sw_if_index = ntohl (sw_if_index);
15379   mp->fib_id = ntohl (fib_id);
15380   mp->ip4 = ip4;
15381   mp->ip6 = ip6;
15382   mp->default_cop = default_cop;
15383
15384   /* send it... */
15385   S (mp);
15386   /* Wait for the reply */
15387   W (ret);
15388   return ret;
15389 }
15390
15391 static int
15392 api_get_node_graph (vat_main_t * vam)
15393 {
15394   vl_api_get_node_graph_t *mp;
15395   int ret;
15396
15397   M (GET_NODE_GRAPH, mp);
15398
15399   /* send it... */
15400   S (mp);
15401   /* Wait for the reply */
15402   W (ret);
15403   return ret;
15404 }
15405
15406 /* *INDENT-OFF* */
15407 /** Used for parsing LISP eids */
15408 typedef CLIB_PACKED(struct{
15409   u8 addr[16];   /**< eid address */
15410   u32 len;       /**< prefix length if IP */
15411   u8 type;      /**< type of eid */
15412 }) lisp_eid_vat_t;
15413 /* *INDENT-ON* */
15414
15415 static uword
15416 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15417 {
15418   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15419
15420   memset (a, 0, sizeof (a[0]));
15421
15422   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15423     {
15424       a->type = 0;              /* ipv4 type */
15425     }
15426   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15427     {
15428       a->type = 1;              /* ipv6 type */
15429     }
15430   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15431     {
15432       a->type = 2;              /* mac type */
15433     }
15434   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15435     {
15436       a->type = 3;              /* NSH type */
15437       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15438       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15439     }
15440   else
15441     {
15442       return 0;
15443     }
15444
15445   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15446     {
15447       return 0;
15448     }
15449
15450   return 1;
15451 }
15452
15453 static int
15454 lisp_eid_size_vat (u8 type)
15455 {
15456   switch (type)
15457     {
15458     case 0:
15459       return 4;
15460     case 1:
15461       return 16;
15462     case 2:
15463       return 6;
15464     case 3:
15465       return 5;
15466     }
15467   return 0;
15468 }
15469
15470 static void
15471 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15472 {
15473   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15474 }
15475
15476 static int
15477 api_one_add_del_locator_set (vat_main_t * vam)
15478 {
15479   unformat_input_t *input = vam->input;
15480   vl_api_one_add_del_locator_set_t *mp;
15481   u8 is_add = 1;
15482   u8 *locator_set_name = NULL;
15483   u8 locator_set_name_set = 0;
15484   vl_api_local_locator_t locator, *locators = 0;
15485   u32 sw_if_index, priority, weight;
15486   u32 data_len = 0;
15487
15488   int ret;
15489   /* Parse args required to build the message */
15490   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15491     {
15492       if (unformat (input, "del"))
15493         {
15494           is_add = 0;
15495         }
15496       else if (unformat (input, "locator-set %s", &locator_set_name))
15497         {
15498           locator_set_name_set = 1;
15499         }
15500       else if (unformat (input, "sw_if_index %u p %u w %u",
15501                          &sw_if_index, &priority, &weight))
15502         {
15503           locator.sw_if_index = htonl (sw_if_index);
15504           locator.priority = priority;
15505           locator.weight = weight;
15506           vec_add1 (locators, locator);
15507         }
15508       else
15509         if (unformat
15510             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15511              &sw_if_index, &priority, &weight))
15512         {
15513           locator.sw_if_index = htonl (sw_if_index);
15514           locator.priority = priority;
15515           locator.weight = weight;
15516           vec_add1 (locators, locator);
15517         }
15518       else
15519         break;
15520     }
15521
15522   if (locator_set_name_set == 0)
15523     {
15524       errmsg ("missing locator-set name");
15525       vec_free (locators);
15526       return -99;
15527     }
15528
15529   if (vec_len (locator_set_name) > 64)
15530     {
15531       errmsg ("locator-set name too long");
15532       vec_free (locator_set_name);
15533       vec_free (locators);
15534       return -99;
15535     }
15536   vec_add1 (locator_set_name, 0);
15537
15538   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15539
15540   /* Construct the API message */
15541   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15542
15543   mp->is_add = is_add;
15544   clib_memcpy (mp->locator_set_name, locator_set_name,
15545                vec_len (locator_set_name));
15546   vec_free (locator_set_name);
15547
15548   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15549   if (locators)
15550     clib_memcpy (mp->locators, locators, data_len);
15551   vec_free (locators);
15552
15553   /* send it... */
15554   S (mp);
15555
15556   /* Wait for a reply... */
15557   W (ret);
15558   return ret;
15559 }
15560
15561 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15562
15563 static int
15564 api_one_add_del_locator (vat_main_t * vam)
15565 {
15566   unformat_input_t *input = vam->input;
15567   vl_api_one_add_del_locator_t *mp;
15568   u32 tmp_if_index = ~0;
15569   u32 sw_if_index = ~0;
15570   u8 sw_if_index_set = 0;
15571   u8 sw_if_index_if_name_set = 0;
15572   u32 priority = ~0;
15573   u8 priority_set = 0;
15574   u32 weight = ~0;
15575   u8 weight_set = 0;
15576   u8 is_add = 1;
15577   u8 *locator_set_name = NULL;
15578   u8 locator_set_name_set = 0;
15579   int ret;
15580
15581   /* Parse args required to build the message */
15582   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15583     {
15584       if (unformat (input, "del"))
15585         {
15586           is_add = 0;
15587         }
15588       else if (unformat (input, "locator-set %s", &locator_set_name))
15589         {
15590           locator_set_name_set = 1;
15591         }
15592       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15593                          &tmp_if_index))
15594         {
15595           sw_if_index_if_name_set = 1;
15596           sw_if_index = tmp_if_index;
15597         }
15598       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15599         {
15600           sw_if_index_set = 1;
15601           sw_if_index = tmp_if_index;
15602         }
15603       else if (unformat (input, "p %d", &priority))
15604         {
15605           priority_set = 1;
15606         }
15607       else if (unformat (input, "w %d", &weight))
15608         {
15609           weight_set = 1;
15610         }
15611       else
15612         break;
15613     }
15614
15615   if (locator_set_name_set == 0)
15616     {
15617       errmsg ("missing locator-set name");
15618       return -99;
15619     }
15620
15621   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15622     {
15623       errmsg ("missing sw_if_index");
15624       vec_free (locator_set_name);
15625       return -99;
15626     }
15627
15628   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15629     {
15630       errmsg ("cannot use both params interface name and sw_if_index");
15631       vec_free (locator_set_name);
15632       return -99;
15633     }
15634
15635   if (priority_set == 0)
15636     {
15637       errmsg ("missing locator-set priority");
15638       vec_free (locator_set_name);
15639       return -99;
15640     }
15641
15642   if (weight_set == 0)
15643     {
15644       errmsg ("missing locator-set weight");
15645       vec_free (locator_set_name);
15646       return -99;
15647     }
15648
15649   if (vec_len (locator_set_name) > 64)
15650     {
15651       errmsg ("locator-set name too long");
15652       vec_free (locator_set_name);
15653       return -99;
15654     }
15655   vec_add1 (locator_set_name, 0);
15656
15657   /* Construct the API message */
15658   M (ONE_ADD_DEL_LOCATOR, mp);
15659
15660   mp->is_add = is_add;
15661   mp->sw_if_index = ntohl (sw_if_index);
15662   mp->priority = priority;
15663   mp->weight = weight;
15664   clib_memcpy (mp->locator_set_name, locator_set_name,
15665                vec_len (locator_set_name));
15666   vec_free (locator_set_name);
15667
15668   /* send it... */
15669   S (mp);
15670
15671   /* Wait for a reply... */
15672   W (ret);
15673   return ret;
15674 }
15675
15676 #define api_lisp_add_del_locator api_one_add_del_locator
15677
15678 uword
15679 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15680 {
15681   u32 *key_id = va_arg (*args, u32 *);
15682   u8 *s = 0;
15683
15684   if (unformat (input, "%s", &s))
15685     {
15686       if (!strcmp ((char *) s, "sha1"))
15687         key_id[0] = HMAC_SHA_1_96;
15688       else if (!strcmp ((char *) s, "sha256"))
15689         key_id[0] = HMAC_SHA_256_128;
15690       else
15691         {
15692           clib_warning ("invalid key_id: '%s'", s);
15693           key_id[0] = HMAC_NO_KEY;
15694         }
15695     }
15696   else
15697     return 0;
15698
15699   vec_free (s);
15700   return 1;
15701 }
15702
15703 static int
15704 api_one_add_del_local_eid (vat_main_t * vam)
15705 {
15706   unformat_input_t *input = vam->input;
15707   vl_api_one_add_del_local_eid_t *mp;
15708   u8 is_add = 1;
15709   u8 eid_set = 0;
15710   lisp_eid_vat_t _eid, *eid = &_eid;
15711   u8 *locator_set_name = 0;
15712   u8 locator_set_name_set = 0;
15713   u32 vni = 0;
15714   u16 key_id = 0;
15715   u8 *key = 0;
15716   int ret;
15717
15718   /* Parse args required to build the message */
15719   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15720     {
15721       if (unformat (input, "del"))
15722         {
15723           is_add = 0;
15724         }
15725       else if (unformat (input, "vni %d", &vni))
15726         {
15727           ;
15728         }
15729       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15730         {
15731           eid_set = 1;
15732         }
15733       else if (unformat (input, "locator-set %s", &locator_set_name))
15734         {
15735           locator_set_name_set = 1;
15736         }
15737       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15738         ;
15739       else if (unformat (input, "secret-key %_%v%_", &key))
15740         ;
15741       else
15742         break;
15743     }
15744
15745   if (locator_set_name_set == 0)
15746     {
15747       errmsg ("missing locator-set name");
15748       return -99;
15749     }
15750
15751   if (0 == eid_set)
15752     {
15753       errmsg ("EID address not set!");
15754       vec_free (locator_set_name);
15755       return -99;
15756     }
15757
15758   if (key && (0 == key_id))
15759     {
15760       errmsg ("invalid key_id!");
15761       return -99;
15762     }
15763
15764   if (vec_len (key) > 64)
15765     {
15766       errmsg ("key too long");
15767       vec_free (key);
15768       return -99;
15769     }
15770
15771   if (vec_len (locator_set_name) > 64)
15772     {
15773       errmsg ("locator-set name too long");
15774       vec_free (locator_set_name);
15775       return -99;
15776     }
15777   vec_add1 (locator_set_name, 0);
15778
15779   /* Construct the API message */
15780   M (ONE_ADD_DEL_LOCAL_EID, mp);
15781
15782   mp->is_add = is_add;
15783   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15784   mp->eid_type = eid->type;
15785   mp->prefix_len = eid->len;
15786   mp->vni = clib_host_to_net_u32 (vni);
15787   mp->key_id = clib_host_to_net_u16 (key_id);
15788   clib_memcpy (mp->locator_set_name, locator_set_name,
15789                vec_len (locator_set_name));
15790   clib_memcpy (mp->key, key, vec_len (key));
15791
15792   vec_free (locator_set_name);
15793   vec_free (key);
15794
15795   /* send it... */
15796   S (mp);
15797
15798   /* Wait for a reply... */
15799   W (ret);
15800   return ret;
15801 }
15802
15803 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15804
15805 static int
15806 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15807 {
15808   u32 dp_table = 0, vni = 0;;
15809   unformat_input_t *input = vam->input;
15810   vl_api_gpe_add_del_fwd_entry_t *mp;
15811   u8 is_add = 1;
15812   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15813   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15814   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15815   u32 action = ~0, w;
15816   ip4_address_t rmt_rloc4, lcl_rloc4;
15817   ip6_address_t rmt_rloc6, lcl_rloc6;
15818   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15819   int ret;
15820
15821   memset (&rloc, 0, sizeof (rloc));
15822
15823   /* Parse args required to build the message */
15824   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15825     {
15826       if (unformat (input, "del"))
15827         is_add = 0;
15828       else if (unformat (input, "add"))
15829         is_add = 1;
15830       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15831         {
15832           rmt_eid_set = 1;
15833         }
15834       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15835         {
15836           lcl_eid_set = 1;
15837         }
15838       else if (unformat (input, "vrf %d", &dp_table))
15839         ;
15840       else if (unformat (input, "bd %d", &dp_table))
15841         ;
15842       else if (unformat (input, "vni %d", &vni))
15843         ;
15844       else if (unformat (input, "w %d", &w))
15845         {
15846           if (!curr_rloc)
15847             {
15848               errmsg ("No RLOC configured for setting priority/weight!");
15849               return -99;
15850             }
15851           curr_rloc->weight = w;
15852         }
15853       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15854                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15855         {
15856           rloc.is_ip4 = 1;
15857
15858           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15859           rloc.weight = 0;
15860           vec_add1 (lcl_locs, rloc);
15861
15862           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15863           vec_add1 (rmt_locs, rloc);
15864           /* weight saved in rmt loc */
15865           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15866         }
15867       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15868                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15869         {
15870           rloc.is_ip4 = 0;
15871           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15872           rloc.weight = 0;
15873           vec_add1 (lcl_locs, rloc);
15874
15875           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15876           vec_add1 (rmt_locs, rloc);
15877           /* weight saved in rmt loc */
15878           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15879         }
15880       else if (unformat (input, "action %d", &action))
15881         {
15882           ;
15883         }
15884       else
15885         {
15886           clib_warning ("parse error '%U'", format_unformat_error, input);
15887           return -99;
15888         }
15889     }
15890
15891   if (!rmt_eid_set)
15892     {
15893       errmsg ("remote eid addresses not set");
15894       return -99;
15895     }
15896
15897   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15898     {
15899       errmsg ("eid types don't match");
15900       return -99;
15901     }
15902
15903   if (0 == rmt_locs && (u32) ~ 0 == action)
15904     {
15905       errmsg ("action not set for negative mapping");
15906       return -99;
15907     }
15908
15909   /* Construct the API message */
15910   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15911       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15912
15913   mp->is_add = is_add;
15914   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15915   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15916   mp->eid_type = rmt_eid->type;
15917   mp->dp_table = clib_host_to_net_u32 (dp_table);
15918   mp->vni = clib_host_to_net_u32 (vni);
15919   mp->rmt_len = rmt_eid->len;
15920   mp->lcl_len = lcl_eid->len;
15921   mp->action = action;
15922
15923   if (0 != rmt_locs && 0 != lcl_locs)
15924     {
15925       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15926       clib_memcpy (mp->locs, lcl_locs,
15927                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15928
15929       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15930       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15931                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15932     }
15933   vec_free (lcl_locs);
15934   vec_free (rmt_locs);
15935
15936   /* send it... */
15937   S (mp);
15938
15939   /* Wait for a reply... */
15940   W (ret);
15941   return ret;
15942 }
15943
15944 static int
15945 api_one_add_del_map_server (vat_main_t * vam)
15946 {
15947   unformat_input_t *input = vam->input;
15948   vl_api_one_add_del_map_server_t *mp;
15949   u8 is_add = 1;
15950   u8 ipv4_set = 0;
15951   u8 ipv6_set = 0;
15952   ip4_address_t ipv4;
15953   ip6_address_t ipv6;
15954   int ret;
15955
15956   /* Parse args required to build the message */
15957   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15958     {
15959       if (unformat (input, "del"))
15960         {
15961           is_add = 0;
15962         }
15963       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15964         {
15965           ipv4_set = 1;
15966         }
15967       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15968         {
15969           ipv6_set = 1;
15970         }
15971       else
15972         break;
15973     }
15974
15975   if (ipv4_set && ipv6_set)
15976     {
15977       errmsg ("both eid v4 and v6 addresses set");
15978       return -99;
15979     }
15980
15981   if (!ipv4_set && !ipv6_set)
15982     {
15983       errmsg ("eid addresses not set");
15984       return -99;
15985     }
15986
15987   /* Construct the API message */
15988   M (ONE_ADD_DEL_MAP_SERVER, mp);
15989
15990   mp->is_add = is_add;
15991   if (ipv6_set)
15992     {
15993       mp->is_ipv6 = 1;
15994       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15995     }
15996   else
15997     {
15998       mp->is_ipv6 = 0;
15999       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16000     }
16001
16002   /* send it... */
16003   S (mp);
16004
16005   /* Wait for a reply... */
16006   W (ret);
16007   return ret;
16008 }
16009
16010 #define api_lisp_add_del_map_server api_one_add_del_map_server
16011
16012 static int
16013 api_one_add_del_map_resolver (vat_main_t * vam)
16014 {
16015   unformat_input_t *input = vam->input;
16016   vl_api_one_add_del_map_resolver_t *mp;
16017   u8 is_add = 1;
16018   u8 ipv4_set = 0;
16019   u8 ipv6_set = 0;
16020   ip4_address_t ipv4;
16021   ip6_address_t ipv6;
16022   int ret;
16023
16024   /* Parse args required to build the message */
16025   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16026     {
16027       if (unformat (input, "del"))
16028         {
16029           is_add = 0;
16030         }
16031       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
16032         {
16033           ipv4_set = 1;
16034         }
16035       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
16036         {
16037           ipv6_set = 1;
16038         }
16039       else
16040         break;
16041     }
16042
16043   if (ipv4_set && ipv6_set)
16044     {
16045       errmsg ("both eid v4 and v6 addresses set");
16046       return -99;
16047     }
16048
16049   if (!ipv4_set && !ipv6_set)
16050     {
16051       errmsg ("eid addresses not set");
16052       return -99;
16053     }
16054
16055   /* Construct the API message */
16056   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
16057
16058   mp->is_add = is_add;
16059   if (ipv6_set)
16060     {
16061       mp->is_ipv6 = 1;
16062       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
16063     }
16064   else
16065     {
16066       mp->is_ipv6 = 0;
16067       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
16068     }
16069
16070   /* send it... */
16071   S (mp);
16072
16073   /* Wait for a reply... */
16074   W (ret);
16075   return ret;
16076 }
16077
16078 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
16079
16080 static int
16081 api_lisp_gpe_enable_disable (vat_main_t * vam)
16082 {
16083   unformat_input_t *input = vam->input;
16084   vl_api_gpe_enable_disable_t *mp;
16085   u8 is_set = 0;
16086   u8 is_en = 1;
16087   int ret;
16088
16089   /* Parse args required to build the message */
16090   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16091     {
16092       if (unformat (input, "enable"))
16093         {
16094           is_set = 1;
16095           is_en = 1;
16096         }
16097       else if (unformat (input, "disable"))
16098         {
16099           is_set = 1;
16100           is_en = 0;
16101         }
16102       else
16103         break;
16104     }
16105
16106   if (is_set == 0)
16107     {
16108       errmsg ("Value not set");
16109       return -99;
16110     }
16111
16112   /* Construct the API message */
16113   M (GPE_ENABLE_DISABLE, mp);
16114
16115   mp->is_en = is_en;
16116
16117   /* send it... */
16118   S (mp);
16119
16120   /* Wait for a reply... */
16121   W (ret);
16122   return ret;
16123 }
16124
16125 static int
16126 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16127 {
16128   unformat_input_t *input = vam->input;
16129   vl_api_one_rloc_probe_enable_disable_t *mp;
16130   u8 is_set = 0;
16131   u8 is_en = 0;
16132   int ret;
16133
16134   /* Parse args required to build the message */
16135   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16136     {
16137       if (unformat (input, "enable"))
16138         {
16139           is_set = 1;
16140           is_en = 1;
16141         }
16142       else if (unformat (input, "disable"))
16143         is_set = 1;
16144       else
16145         break;
16146     }
16147
16148   if (!is_set)
16149     {
16150       errmsg ("Value not set");
16151       return -99;
16152     }
16153
16154   /* Construct the API message */
16155   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16156
16157   mp->is_enabled = is_en;
16158
16159   /* send it... */
16160   S (mp);
16161
16162   /* Wait for a reply... */
16163   W (ret);
16164   return ret;
16165 }
16166
16167 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16168
16169 static int
16170 api_one_map_register_enable_disable (vat_main_t * vam)
16171 {
16172   unformat_input_t *input = vam->input;
16173   vl_api_one_map_register_enable_disable_t *mp;
16174   u8 is_set = 0;
16175   u8 is_en = 0;
16176   int ret;
16177
16178   /* Parse args required to build the message */
16179   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16180     {
16181       if (unformat (input, "enable"))
16182         {
16183           is_set = 1;
16184           is_en = 1;
16185         }
16186       else if (unformat (input, "disable"))
16187         is_set = 1;
16188       else
16189         break;
16190     }
16191
16192   if (!is_set)
16193     {
16194       errmsg ("Value not set");
16195       return -99;
16196     }
16197
16198   /* Construct the API message */
16199   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16200
16201   mp->is_enabled = is_en;
16202
16203   /* send it... */
16204   S (mp);
16205
16206   /* Wait for a reply... */
16207   W (ret);
16208   return ret;
16209 }
16210
16211 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16212
16213 static int
16214 api_one_enable_disable (vat_main_t * vam)
16215 {
16216   unformat_input_t *input = vam->input;
16217   vl_api_one_enable_disable_t *mp;
16218   u8 is_set = 0;
16219   u8 is_en = 0;
16220   int ret;
16221
16222   /* Parse args required to build the message */
16223   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16224     {
16225       if (unformat (input, "enable"))
16226         {
16227           is_set = 1;
16228           is_en = 1;
16229         }
16230       else if (unformat (input, "disable"))
16231         {
16232           is_set = 1;
16233         }
16234       else
16235         break;
16236     }
16237
16238   if (!is_set)
16239     {
16240       errmsg ("Value not set");
16241       return -99;
16242     }
16243
16244   /* Construct the API message */
16245   M (ONE_ENABLE_DISABLE, mp);
16246
16247   mp->is_en = is_en;
16248
16249   /* send it... */
16250   S (mp);
16251
16252   /* Wait for a reply... */
16253   W (ret);
16254   return ret;
16255 }
16256
16257 #define api_lisp_enable_disable api_one_enable_disable
16258
16259 static int
16260 api_show_one_map_register_state (vat_main_t * vam)
16261 {
16262   vl_api_show_one_map_register_state_t *mp;
16263   int ret;
16264
16265   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16266
16267   /* send */
16268   S (mp);
16269
16270   /* wait for reply */
16271   W (ret);
16272   return ret;
16273 }
16274
16275 #define api_show_lisp_map_register_state api_show_one_map_register_state
16276
16277 static int
16278 api_show_one_rloc_probe_state (vat_main_t * vam)
16279 {
16280   vl_api_show_one_rloc_probe_state_t *mp;
16281   int ret;
16282
16283   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16284
16285   /* send */
16286   S (mp);
16287
16288   /* wait for reply */
16289   W (ret);
16290   return ret;
16291 }
16292
16293 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16294
16295 static int
16296 api_one_add_del_ndp_entry (vat_main_t * vam)
16297 {
16298   vl_api_one_add_del_ndp_entry_t *mp;
16299   unformat_input_t *input = vam->input;
16300   u8 is_add = 1;
16301   u8 mac_set = 0;
16302   u8 bd_set = 0;
16303   u8 ip_set = 0;
16304   u8 mac[6] = { 0, };
16305   u8 ip6[16] = { 0, };
16306   u32 bd = ~0;
16307   int ret;
16308
16309   /* Parse args required to build the message */
16310   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16311     {
16312       if (unformat (input, "del"))
16313         is_add = 0;
16314       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16315         mac_set = 1;
16316       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16317         ip_set = 1;
16318       else if (unformat (input, "bd %d", &bd))
16319         bd_set = 1;
16320       else
16321         {
16322           errmsg ("parse error '%U'", format_unformat_error, input);
16323           return -99;
16324         }
16325     }
16326
16327   if (!bd_set || !ip_set || (!mac_set && is_add))
16328     {
16329       errmsg ("Missing BD, IP or MAC!");
16330       return -99;
16331     }
16332
16333   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16334   mp->is_add = is_add;
16335   clib_memcpy (mp->mac, mac, 6);
16336   mp->bd = clib_host_to_net_u32 (bd);
16337   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16338
16339   /* send */
16340   S (mp);
16341
16342   /* wait for reply */
16343   W (ret);
16344   return ret;
16345 }
16346
16347 static int
16348 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16349 {
16350   vl_api_one_add_del_l2_arp_entry_t *mp;
16351   unformat_input_t *input = vam->input;
16352   u8 is_add = 1;
16353   u8 mac_set = 0;
16354   u8 bd_set = 0;
16355   u8 ip_set = 0;
16356   u8 mac[6] = { 0, };
16357   u32 ip4 = 0, bd = ~0;
16358   int ret;
16359
16360   /* Parse args required to build the message */
16361   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16362     {
16363       if (unformat (input, "del"))
16364         is_add = 0;
16365       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16366         mac_set = 1;
16367       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16368         ip_set = 1;
16369       else if (unformat (input, "bd %d", &bd))
16370         bd_set = 1;
16371       else
16372         {
16373           errmsg ("parse error '%U'", format_unformat_error, input);
16374           return -99;
16375         }
16376     }
16377
16378   if (!bd_set || !ip_set || (!mac_set && is_add))
16379     {
16380       errmsg ("Missing BD, IP or MAC!");
16381       return -99;
16382     }
16383
16384   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16385   mp->is_add = is_add;
16386   clib_memcpy (mp->mac, mac, 6);
16387   mp->bd = clib_host_to_net_u32 (bd);
16388   mp->ip4 = ip4;
16389
16390   /* send */
16391   S (mp);
16392
16393   /* wait for reply */
16394   W (ret);
16395   return ret;
16396 }
16397
16398 static int
16399 api_one_ndp_bd_get (vat_main_t * vam)
16400 {
16401   vl_api_one_ndp_bd_get_t *mp;
16402   int ret;
16403
16404   M (ONE_NDP_BD_GET, mp);
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_entries_get (vat_main_t * vam)
16416 {
16417   vl_api_one_ndp_entries_get_t *mp;
16418   unformat_input_t *input = vam->input;
16419   u8 bd_set = 0;
16420   u32 bd = ~0;
16421   int ret;
16422
16423   /* Parse args required to build the message */
16424   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16425     {
16426       if (unformat (input, "bd %d", &bd))
16427         bd_set = 1;
16428       else
16429         {
16430           errmsg ("parse error '%U'", format_unformat_error, input);
16431           return -99;
16432         }
16433     }
16434
16435   if (!bd_set)
16436     {
16437       errmsg ("Expected bridge domain!");
16438       return -99;
16439     }
16440
16441   M (ONE_NDP_ENTRIES_GET, mp);
16442   mp->bd = clib_host_to_net_u32 (bd);
16443
16444   /* send */
16445   S (mp);
16446
16447   /* wait for reply */
16448   W (ret);
16449   return ret;
16450 }
16451
16452 static int
16453 api_one_l2_arp_bd_get (vat_main_t * vam)
16454 {
16455   vl_api_one_l2_arp_bd_get_t *mp;
16456   int ret;
16457
16458   M (ONE_L2_ARP_BD_GET, mp);
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_entries_get (vat_main_t * vam)
16470 {
16471   vl_api_one_l2_arp_entries_get_t *mp;
16472   unformat_input_t *input = vam->input;
16473   u8 bd_set = 0;
16474   u32 bd = ~0;
16475   int ret;
16476
16477   /* Parse args required to build the message */
16478   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16479     {
16480       if (unformat (input, "bd %d", &bd))
16481         bd_set = 1;
16482       else
16483         {
16484           errmsg ("parse error '%U'", format_unformat_error, input);
16485           return -99;
16486         }
16487     }
16488
16489   if (!bd_set)
16490     {
16491       errmsg ("Expected bridge domain!");
16492       return -99;
16493     }
16494
16495   M (ONE_L2_ARP_ENTRIES_GET, mp);
16496   mp->bd = clib_host_to_net_u32 (bd);
16497
16498   /* send */
16499   S (mp);
16500
16501   /* wait for reply */
16502   W (ret);
16503   return ret;
16504 }
16505
16506 static int
16507 api_one_stats_enable_disable (vat_main_t * vam)
16508 {
16509   vl_api_one_stats_enable_disable_t *mp;
16510   unformat_input_t *input = vam->input;
16511   u8 is_set = 0;
16512   u8 is_en = 0;
16513   int ret;
16514
16515   /* Parse args required to build the message */
16516   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16517     {
16518       if (unformat (input, "enable"))
16519         {
16520           is_set = 1;
16521           is_en = 1;
16522         }
16523       else if (unformat (input, "disable"))
16524         {
16525           is_set = 1;
16526         }
16527       else
16528         break;
16529     }
16530
16531   if (!is_set)
16532     {
16533       errmsg ("Value not set");
16534       return -99;
16535     }
16536
16537   M (ONE_STATS_ENABLE_DISABLE, mp);
16538   mp->is_en = is_en;
16539
16540   /* send */
16541   S (mp);
16542
16543   /* wait for reply */
16544   W (ret);
16545   return ret;
16546 }
16547
16548 static int
16549 api_show_one_stats_enable_disable (vat_main_t * vam)
16550 {
16551   vl_api_show_one_stats_enable_disable_t *mp;
16552   int ret;
16553
16554   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
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_map_request_mode (vat_main_t * vam)
16566 {
16567   vl_api_show_one_map_request_mode_t *mp;
16568   int ret;
16569
16570   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16571
16572   /* send */
16573   S (mp);
16574
16575   /* wait for reply */
16576   W (ret);
16577   return ret;
16578 }
16579
16580 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16581
16582 static int
16583 api_one_map_request_mode (vat_main_t * vam)
16584 {
16585   unformat_input_t *input = vam->input;
16586   vl_api_one_map_request_mode_t *mp;
16587   u8 mode = 0;
16588   int ret;
16589
16590   /* Parse args required to build the message */
16591   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16592     {
16593       if (unformat (input, "dst-only"))
16594         mode = 0;
16595       else if (unformat (input, "src-dst"))
16596         mode = 1;
16597       else
16598         {
16599           errmsg ("parse error '%U'", format_unformat_error, input);
16600           return -99;
16601         }
16602     }
16603
16604   M (ONE_MAP_REQUEST_MODE, mp);
16605
16606   mp->mode = mode;
16607
16608   /* send */
16609   S (mp);
16610
16611   /* wait for reply */
16612   W (ret);
16613   return ret;
16614 }
16615
16616 #define api_lisp_map_request_mode api_one_map_request_mode
16617
16618 /**
16619  * Enable/disable ONE proxy ITR.
16620  *
16621  * @param vam vpp API test context
16622  * @return return code
16623  */
16624 static int
16625 api_one_pitr_set_locator_set (vat_main_t * vam)
16626 {
16627   u8 ls_name_set = 0;
16628   unformat_input_t *input = vam->input;
16629   vl_api_one_pitr_set_locator_set_t *mp;
16630   u8 is_add = 1;
16631   u8 *ls_name = 0;
16632   int ret;
16633
16634   /* Parse args required to build the message */
16635   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16636     {
16637       if (unformat (input, "del"))
16638         is_add = 0;
16639       else if (unformat (input, "locator-set %s", &ls_name))
16640         ls_name_set = 1;
16641       else
16642         {
16643           errmsg ("parse error '%U'", format_unformat_error, input);
16644           return -99;
16645         }
16646     }
16647
16648   if (!ls_name_set)
16649     {
16650       errmsg ("locator-set name not set!");
16651       return -99;
16652     }
16653
16654   M (ONE_PITR_SET_LOCATOR_SET, mp);
16655
16656   mp->is_add = is_add;
16657   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16658   vec_free (ls_name);
16659
16660   /* send */
16661   S (mp);
16662
16663   /* wait for reply */
16664   W (ret);
16665   return ret;
16666 }
16667
16668 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16669
16670 static int
16671 api_one_nsh_set_locator_set (vat_main_t * vam)
16672 {
16673   u8 ls_name_set = 0;
16674   unformat_input_t *input = vam->input;
16675   vl_api_one_nsh_set_locator_set_t *mp;
16676   u8 is_add = 1;
16677   u8 *ls_name = 0;
16678   int ret;
16679
16680   /* Parse args required to build the message */
16681   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16682     {
16683       if (unformat (input, "del"))
16684         is_add = 0;
16685       else if (unformat (input, "ls %s", &ls_name))
16686         ls_name_set = 1;
16687       else
16688         {
16689           errmsg ("parse error '%U'", format_unformat_error, input);
16690           return -99;
16691         }
16692     }
16693
16694   if (!ls_name_set && is_add)
16695     {
16696       errmsg ("locator-set name not set!");
16697       return -99;
16698     }
16699
16700   M (ONE_NSH_SET_LOCATOR_SET, mp);
16701
16702   mp->is_add = is_add;
16703   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16704   vec_free (ls_name);
16705
16706   /* send */
16707   S (mp);
16708
16709   /* wait for reply */
16710   W (ret);
16711   return ret;
16712 }
16713
16714 static int
16715 api_show_one_pitr (vat_main_t * vam)
16716 {
16717   vl_api_show_one_pitr_t *mp;
16718   int ret;
16719
16720   if (!vam->json_output)
16721     {
16722       print (vam->ofp, "%=20s", "lisp status:");
16723     }
16724
16725   M (SHOW_ONE_PITR, mp);
16726   /* send it... */
16727   S (mp);
16728
16729   /* Wait for a reply... */
16730   W (ret);
16731   return ret;
16732 }
16733
16734 #define api_show_lisp_pitr api_show_one_pitr
16735
16736 static int
16737 api_one_use_petr (vat_main_t * vam)
16738 {
16739   unformat_input_t *input = vam->input;
16740   vl_api_one_use_petr_t *mp;
16741   u8 is_add = 0;
16742   ip_address_t ip;
16743   int ret;
16744
16745   memset (&ip, 0, sizeof (ip));
16746
16747   /* Parse args required to build the message */
16748   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16749     {
16750       if (unformat (input, "disable"))
16751         is_add = 0;
16752       else
16753         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16754         {
16755           is_add = 1;
16756           ip_addr_version (&ip) = IP4;
16757         }
16758       else
16759         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16760         {
16761           is_add = 1;
16762           ip_addr_version (&ip) = IP6;
16763         }
16764       else
16765         {
16766           errmsg ("parse error '%U'", format_unformat_error, input);
16767           return -99;
16768         }
16769     }
16770
16771   M (ONE_USE_PETR, mp);
16772
16773   mp->is_add = is_add;
16774   if (is_add)
16775     {
16776       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16777       if (mp->is_ip4)
16778         clib_memcpy (mp->address, &ip, 4);
16779       else
16780         clib_memcpy (mp->address, &ip, 16);
16781     }
16782
16783   /* send */
16784   S (mp);
16785
16786   /* wait for reply */
16787   W (ret);
16788   return ret;
16789 }
16790
16791 #define api_lisp_use_petr api_one_use_petr
16792
16793 static int
16794 api_show_one_nsh_mapping (vat_main_t * vam)
16795 {
16796   vl_api_show_one_use_petr_t *mp;
16797   int ret;
16798
16799   if (!vam->json_output)
16800     {
16801       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16802     }
16803
16804   M (SHOW_ONE_NSH_MAPPING, mp);
16805   /* send it... */
16806   S (mp);
16807
16808   /* Wait for a reply... */
16809   W (ret);
16810   return ret;
16811 }
16812
16813 static int
16814 api_show_one_use_petr (vat_main_t * vam)
16815 {
16816   vl_api_show_one_use_petr_t *mp;
16817   int ret;
16818
16819   if (!vam->json_output)
16820     {
16821       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16822     }
16823
16824   M (SHOW_ONE_USE_PETR, mp);
16825   /* send it... */
16826   S (mp);
16827
16828   /* Wait for a reply... */
16829   W (ret);
16830   return ret;
16831 }
16832
16833 #define api_show_lisp_use_petr api_show_one_use_petr
16834
16835 /**
16836  * Add/delete mapping between vni and vrf
16837  */
16838 static int
16839 api_one_eid_table_add_del_map (vat_main_t * vam)
16840 {
16841   unformat_input_t *input = vam->input;
16842   vl_api_one_eid_table_add_del_map_t *mp;
16843   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16844   u32 vni, vrf, bd_index;
16845   int ret;
16846
16847   /* Parse args required to build the message */
16848   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16849     {
16850       if (unformat (input, "del"))
16851         is_add = 0;
16852       else if (unformat (input, "vrf %d", &vrf))
16853         vrf_set = 1;
16854       else if (unformat (input, "bd_index %d", &bd_index))
16855         bd_index_set = 1;
16856       else if (unformat (input, "vni %d", &vni))
16857         vni_set = 1;
16858       else
16859         break;
16860     }
16861
16862   if (!vni_set || (!vrf_set && !bd_index_set))
16863     {
16864       errmsg ("missing arguments!");
16865       return -99;
16866     }
16867
16868   if (vrf_set && bd_index_set)
16869     {
16870       errmsg ("error: both vrf and bd entered!");
16871       return -99;
16872     }
16873
16874   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16875
16876   mp->is_add = is_add;
16877   mp->vni = htonl (vni);
16878   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16879   mp->is_l2 = bd_index_set;
16880
16881   /* send */
16882   S (mp);
16883
16884   /* wait for reply */
16885   W (ret);
16886   return ret;
16887 }
16888
16889 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16890
16891 uword
16892 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16893 {
16894   u32 *action = va_arg (*args, u32 *);
16895   u8 *s = 0;
16896
16897   if (unformat (input, "%s", &s))
16898     {
16899       if (!strcmp ((char *) s, "no-action"))
16900         action[0] = 0;
16901       else if (!strcmp ((char *) s, "natively-forward"))
16902         action[0] = 1;
16903       else if (!strcmp ((char *) s, "send-map-request"))
16904         action[0] = 2;
16905       else if (!strcmp ((char *) s, "drop"))
16906         action[0] = 3;
16907       else
16908         {
16909           clib_warning ("invalid action: '%s'", s);
16910           action[0] = 3;
16911         }
16912     }
16913   else
16914     return 0;
16915
16916   vec_free (s);
16917   return 1;
16918 }
16919
16920 /**
16921  * Add/del remote mapping to/from ONE control plane
16922  *
16923  * @param vam vpp API test context
16924  * @return return code
16925  */
16926 static int
16927 api_one_add_del_remote_mapping (vat_main_t * vam)
16928 {
16929   unformat_input_t *input = vam->input;
16930   vl_api_one_add_del_remote_mapping_t *mp;
16931   u32 vni = 0;
16932   lisp_eid_vat_t _eid, *eid = &_eid;
16933   lisp_eid_vat_t _seid, *seid = &_seid;
16934   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
16935   u32 action = ~0, p, w, data_len;
16936   ip4_address_t rloc4;
16937   ip6_address_t rloc6;
16938   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
16939   int ret;
16940
16941   memset (&rloc, 0, sizeof (rloc));
16942
16943   /* Parse args required to build the message */
16944   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16945     {
16946       if (unformat (input, "del-all"))
16947         {
16948           del_all = 1;
16949         }
16950       else if (unformat (input, "del"))
16951         {
16952           is_add = 0;
16953         }
16954       else if (unformat (input, "add"))
16955         {
16956           is_add = 1;
16957         }
16958       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16959         {
16960           eid_set = 1;
16961         }
16962       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
16963         {
16964           seid_set = 1;
16965         }
16966       else if (unformat (input, "vni %d", &vni))
16967         {
16968           ;
16969         }
16970       else if (unformat (input, "p %d w %d", &p, &w))
16971         {
16972           if (!curr_rloc)
16973             {
16974               errmsg ("No RLOC configured for setting priority/weight!");
16975               return -99;
16976             }
16977           curr_rloc->priority = p;
16978           curr_rloc->weight = w;
16979         }
16980       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
16981         {
16982           rloc.is_ip4 = 1;
16983           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
16984           vec_add1 (rlocs, rloc);
16985           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16986         }
16987       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
16988         {
16989           rloc.is_ip4 = 0;
16990           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
16991           vec_add1 (rlocs, rloc);
16992           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16993         }
16994       else if (unformat (input, "action %U",
16995                          unformat_negative_mapping_action, &action))
16996         {
16997           ;
16998         }
16999       else
17000         {
17001           clib_warning ("parse error '%U'", format_unformat_error, input);
17002           return -99;
17003         }
17004     }
17005
17006   if (0 == eid_set)
17007     {
17008       errmsg ("missing params!");
17009       return -99;
17010     }
17011
17012   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
17013     {
17014       errmsg ("no action set for negative map-reply!");
17015       return -99;
17016     }
17017
17018   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
17019
17020   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
17021   mp->is_add = is_add;
17022   mp->vni = htonl (vni);
17023   mp->action = (u8) action;
17024   mp->is_src_dst = seid_set;
17025   mp->eid_len = eid->len;
17026   mp->seid_len = seid->len;
17027   mp->del_all = del_all;
17028   mp->eid_type = eid->type;
17029   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
17030   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
17031
17032   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
17033   clib_memcpy (mp->rlocs, rlocs, data_len);
17034   vec_free (rlocs);
17035
17036   /* send it... */
17037   S (mp);
17038
17039   /* Wait for a reply... */
17040   W (ret);
17041   return ret;
17042 }
17043
17044 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
17045
17046 /**
17047  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
17048  * forwarding entries in data-plane accordingly.
17049  *
17050  * @param vam vpp API test context
17051  * @return return code
17052  */
17053 static int
17054 api_one_add_del_adjacency (vat_main_t * vam)
17055 {
17056   unformat_input_t *input = vam->input;
17057   vl_api_one_add_del_adjacency_t *mp;
17058   u32 vni = 0;
17059   ip4_address_t leid4, reid4;
17060   ip6_address_t leid6, reid6;
17061   u8 reid_mac[6] = { 0 };
17062   u8 leid_mac[6] = { 0 };
17063   u8 reid_type, leid_type;
17064   u32 leid_len = 0, reid_len = 0, len;
17065   u8 is_add = 1;
17066   int ret;
17067
17068   leid_type = reid_type = (u8) ~ 0;
17069
17070   /* Parse args required to build the message */
17071   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17072     {
17073       if (unformat (input, "del"))
17074         {
17075           is_add = 0;
17076         }
17077       else if (unformat (input, "add"))
17078         {
17079           is_add = 1;
17080         }
17081       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
17082                          &reid4, &len))
17083         {
17084           reid_type = 0;        /* ipv4 */
17085           reid_len = len;
17086         }
17087       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
17088                          &reid6, &len))
17089         {
17090           reid_type = 1;        /* ipv6 */
17091           reid_len = len;
17092         }
17093       else if (unformat (input, "reid %U", unformat_ethernet_address,
17094                          reid_mac))
17095         {
17096           reid_type = 2;        /* mac */
17097         }
17098       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17099                          &leid4, &len))
17100         {
17101           leid_type = 0;        /* ipv4 */
17102           leid_len = len;
17103         }
17104       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17105                          &leid6, &len))
17106         {
17107           leid_type = 1;        /* ipv6 */
17108           leid_len = len;
17109         }
17110       else if (unformat (input, "leid %U", unformat_ethernet_address,
17111                          leid_mac))
17112         {
17113           leid_type = 2;        /* mac */
17114         }
17115       else if (unformat (input, "vni %d", &vni))
17116         {
17117           ;
17118         }
17119       else
17120         {
17121           errmsg ("parse error '%U'", format_unformat_error, input);
17122           return -99;
17123         }
17124     }
17125
17126   if ((u8) ~ 0 == reid_type)
17127     {
17128       errmsg ("missing params!");
17129       return -99;
17130     }
17131
17132   if (leid_type != reid_type)
17133     {
17134       errmsg ("remote and local EIDs are of different types!");
17135       return -99;
17136     }
17137
17138   M (ONE_ADD_DEL_ADJACENCY, mp);
17139   mp->is_add = is_add;
17140   mp->vni = htonl (vni);
17141   mp->leid_len = leid_len;
17142   mp->reid_len = reid_len;
17143   mp->eid_type = reid_type;
17144
17145   switch (mp->eid_type)
17146     {
17147     case 0:
17148       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17149       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17150       break;
17151     case 1:
17152       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17153       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17154       break;
17155     case 2:
17156       clib_memcpy (mp->leid, leid_mac, 6);
17157       clib_memcpy (mp->reid, reid_mac, 6);
17158       break;
17159     default:
17160       errmsg ("unknown EID type %d!", mp->eid_type);
17161       return 0;
17162     }
17163
17164   /* send it... */
17165   S (mp);
17166
17167   /* Wait for a reply... */
17168   W (ret);
17169   return ret;
17170 }
17171
17172 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17173
17174 uword
17175 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17176 {
17177   u32 *mode = va_arg (*args, u32 *);
17178
17179   if (unformat (input, "lisp"))
17180     *mode = 0;
17181   else if (unformat (input, "vxlan"))
17182     *mode = 1;
17183   else
17184     return 0;
17185
17186   return 1;
17187 }
17188
17189 static int
17190 api_gpe_get_encap_mode (vat_main_t * vam)
17191 {
17192   vl_api_gpe_get_encap_mode_t *mp;
17193   int ret;
17194
17195   /* Construct the API message */
17196   M (GPE_GET_ENCAP_MODE, mp);
17197
17198   /* send it... */
17199   S (mp);
17200
17201   /* Wait for a reply... */
17202   W (ret);
17203   return ret;
17204 }
17205
17206 static int
17207 api_gpe_set_encap_mode (vat_main_t * vam)
17208 {
17209   unformat_input_t *input = vam->input;
17210   vl_api_gpe_set_encap_mode_t *mp;
17211   int ret;
17212   u32 mode = 0;
17213
17214   /* Parse args required to build the message */
17215   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17216     {
17217       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17218         ;
17219       else
17220         break;
17221     }
17222
17223   /* Construct the API message */
17224   M (GPE_SET_ENCAP_MODE, mp);
17225
17226   mp->mode = mode;
17227
17228   /* send it... */
17229   S (mp);
17230
17231   /* Wait for a reply... */
17232   W (ret);
17233   return ret;
17234 }
17235
17236 static int
17237 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17238 {
17239   unformat_input_t *input = vam->input;
17240   vl_api_gpe_add_del_iface_t *mp;
17241   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17242   u32 dp_table = 0, vni = 0;
17243   int ret;
17244
17245   /* Parse args required to build the message */
17246   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17247     {
17248       if (unformat (input, "up"))
17249         {
17250           action_set = 1;
17251           is_add = 1;
17252         }
17253       else if (unformat (input, "down"))
17254         {
17255           action_set = 1;
17256           is_add = 0;
17257         }
17258       else if (unformat (input, "table_id %d", &dp_table))
17259         {
17260           dp_table_set = 1;
17261         }
17262       else if (unformat (input, "bd_id %d", &dp_table))
17263         {
17264           dp_table_set = 1;
17265           is_l2 = 1;
17266         }
17267       else if (unformat (input, "vni %d", &vni))
17268         {
17269           vni_set = 1;
17270         }
17271       else
17272         break;
17273     }
17274
17275   if (action_set == 0)
17276     {
17277       errmsg ("Action not set");
17278       return -99;
17279     }
17280   if (dp_table_set == 0 || vni_set == 0)
17281     {
17282       errmsg ("vni and dp_table must be set");
17283       return -99;
17284     }
17285
17286   /* Construct the API message */
17287   M (GPE_ADD_DEL_IFACE, mp);
17288
17289   mp->is_add = is_add;
17290   mp->dp_table = clib_host_to_net_u32 (dp_table);
17291   mp->is_l2 = is_l2;
17292   mp->vni = clib_host_to_net_u32 (vni);
17293
17294   /* send it... */
17295   S (mp);
17296
17297   /* Wait for a reply... */
17298   W (ret);
17299   return ret;
17300 }
17301
17302 static int
17303 api_one_map_register_fallback_threshold (vat_main_t * vam)
17304 {
17305   unformat_input_t *input = vam->input;
17306   vl_api_one_map_register_fallback_threshold_t *mp;
17307   u32 value = 0;
17308   u8 is_set = 0;
17309   int ret;
17310
17311   /* Parse args required to build the message */
17312   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17313     {
17314       if (unformat (input, "%u", &value))
17315         is_set = 1;
17316       else
17317         {
17318           clib_warning ("parse error '%U'", format_unformat_error, input);
17319           return -99;
17320         }
17321     }
17322
17323   if (!is_set)
17324     {
17325       errmsg ("fallback threshold value is missing!");
17326       return -99;
17327     }
17328
17329   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17330   mp->value = clib_host_to_net_u32 (value);
17331
17332   /* send it... */
17333   S (mp);
17334
17335   /* Wait for a reply... */
17336   W (ret);
17337   return ret;
17338 }
17339
17340 static int
17341 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17342 {
17343   vl_api_show_one_map_register_fallback_threshold_t *mp;
17344   int ret;
17345
17346   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17347
17348   /* send it... */
17349   S (mp);
17350
17351   /* Wait for a reply... */
17352   W (ret);
17353   return ret;
17354 }
17355
17356 uword
17357 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17358 {
17359   u32 *proto = va_arg (*args, u32 *);
17360
17361   if (unformat (input, "udp"))
17362     *proto = 1;
17363   else if (unformat (input, "api"))
17364     *proto = 2;
17365   else
17366     return 0;
17367
17368   return 1;
17369 }
17370
17371 static int
17372 api_one_set_transport_protocol (vat_main_t * vam)
17373 {
17374   unformat_input_t *input = vam->input;
17375   vl_api_one_set_transport_protocol_t *mp;
17376   u8 is_set = 0;
17377   u32 protocol = 0;
17378   int ret;
17379
17380   /* Parse args required to build the message */
17381   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17382     {
17383       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17384         is_set = 1;
17385       else
17386         {
17387           clib_warning ("parse error '%U'", format_unformat_error, input);
17388           return -99;
17389         }
17390     }
17391
17392   if (!is_set)
17393     {
17394       errmsg ("Transport protocol missing!");
17395       return -99;
17396     }
17397
17398   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17399   mp->protocol = (u8) protocol;
17400
17401   /* send it... */
17402   S (mp);
17403
17404   /* Wait for a reply... */
17405   W (ret);
17406   return ret;
17407 }
17408
17409 static int
17410 api_one_get_transport_protocol (vat_main_t * vam)
17411 {
17412   vl_api_one_get_transport_protocol_t *mp;
17413   int ret;
17414
17415   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
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_map_register_set_ttl (vat_main_t * vam)
17427 {
17428   unformat_input_t *input = vam->input;
17429   vl_api_one_map_register_set_ttl_t *mp;
17430   u32 ttl = 0;
17431   u8 is_set = 0;
17432   int ret;
17433
17434   /* Parse args required to build the message */
17435   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17436     {
17437       if (unformat (input, "%u", &ttl))
17438         is_set = 1;
17439       else
17440         {
17441           clib_warning ("parse error '%U'", format_unformat_error, input);
17442           return -99;
17443         }
17444     }
17445
17446   if (!is_set)
17447     {
17448       errmsg ("TTL value missing!");
17449       return -99;
17450     }
17451
17452   M (ONE_MAP_REGISTER_SET_TTL, mp);
17453   mp->ttl = clib_host_to_net_u32 (ttl);
17454
17455   /* send it... */
17456   S (mp);
17457
17458   /* Wait for a reply... */
17459   W (ret);
17460   return ret;
17461 }
17462
17463 static int
17464 api_show_one_map_register_ttl (vat_main_t * vam)
17465 {
17466   vl_api_show_one_map_register_ttl_t *mp;
17467   int ret;
17468
17469   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17470
17471   /* send it... */
17472   S (mp);
17473
17474   /* Wait for a reply... */
17475   W (ret);
17476   return ret;
17477 }
17478
17479 /**
17480  * Add/del map request itr rlocs from ONE control plane and updates
17481  *
17482  * @param vam vpp API test context
17483  * @return return code
17484  */
17485 static int
17486 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17487 {
17488   unformat_input_t *input = vam->input;
17489   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17490   u8 *locator_set_name = 0;
17491   u8 locator_set_name_set = 0;
17492   u8 is_add = 1;
17493   int ret;
17494
17495   /* Parse args required to build the message */
17496   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17497     {
17498       if (unformat (input, "del"))
17499         {
17500           is_add = 0;
17501         }
17502       else if (unformat (input, "%_%v%_", &locator_set_name))
17503         {
17504           locator_set_name_set = 1;
17505         }
17506       else
17507         {
17508           clib_warning ("parse error '%U'", format_unformat_error, input);
17509           return -99;
17510         }
17511     }
17512
17513   if (is_add && !locator_set_name_set)
17514     {
17515       errmsg ("itr-rloc is not set!");
17516       return -99;
17517     }
17518
17519   if (is_add && vec_len (locator_set_name) > 64)
17520     {
17521       errmsg ("itr-rloc locator-set name too long");
17522       vec_free (locator_set_name);
17523       return -99;
17524     }
17525
17526   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17527   mp->is_add = is_add;
17528   if (is_add)
17529     {
17530       clib_memcpy (mp->locator_set_name, locator_set_name,
17531                    vec_len (locator_set_name));
17532     }
17533   else
17534     {
17535       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17536     }
17537   vec_free (locator_set_name);
17538
17539   /* send it... */
17540   S (mp);
17541
17542   /* Wait for a reply... */
17543   W (ret);
17544   return ret;
17545 }
17546
17547 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17548
17549 static int
17550 api_one_locator_dump (vat_main_t * vam)
17551 {
17552   unformat_input_t *input = vam->input;
17553   vl_api_one_locator_dump_t *mp;
17554   vl_api_control_ping_t *mp_ping;
17555   u8 is_index_set = 0, is_name_set = 0;
17556   u8 *ls_name = 0;
17557   u32 ls_index = ~0;
17558   int ret;
17559
17560   /* Parse args required to build the message */
17561   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17562     {
17563       if (unformat (input, "ls_name %_%v%_", &ls_name))
17564         {
17565           is_name_set = 1;
17566         }
17567       else if (unformat (input, "ls_index %d", &ls_index))
17568         {
17569           is_index_set = 1;
17570         }
17571       else
17572         {
17573           errmsg ("parse error '%U'", format_unformat_error, input);
17574           return -99;
17575         }
17576     }
17577
17578   if (!is_index_set && !is_name_set)
17579     {
17580       errmsg ("error: expected one of index or name!");
17581       return -99;
17582     }
17583
17584   if (is_index_set && is_name_set)
17585     {
17586       errmsg ("error: only one param expected!");
17587       return -99;
17588     }
17589
17590   if (vec_len (ls_name) > 62)
17591     {
17592       errmsg ("error: locator set name too long!");
17593       return -99;
17594     }
17595
17596   if (!vam->json_output)
17597     {
17598       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17599     }
17600
17601   M (ONE_LOCATOR_DUMP, mp);
17602   mp->is_index_set = is_index_set;
17603
17604   if (is_index_set)
17605     mp->ls_index = clib_host_to_net_u32 (ls_index);
17606   else
17607     {
17608       vec_add1 (ls_name, 0);
17609       strncpy ((char *) mp->ls_name, (char *) ls_name,
17610                sizeof (mp->ls_name) - 1);
17611     }
17612
17613   /* send it... */
17614   S (mp);
17615
17616   /* Use a control ping for synchronization */
17617   MPING (CONTROL_PING, mp_ping);
17618   S (mp_ping);
17619
17620   /* Wait for a reply... */
17621   W (ret);
17622   return ret;
17623 }
17624
17625 #define api_lisp_locator_dump api_one_locator_dump
17626
17627 static int
17628 api_one_locator_set_dump (vat_main_t * vam)
17629 {
17630   vl_api_one_locator_set_dump_t *mp;
17631   vl_api_control_ping_t *mp_ping;
17632   unformat_input_t *input = vam->input;
17633   u8 filter = 0;
17634   int ret;
17635
17636   /* Parse args required to build the message */
17637   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17638     {
17639       if (unformat (input, "local"))
17640         {
17641           filter = 1;
17642         }
17643       else if (unformat (input, "remote"))
17644         {
17645           filter = 2;
17646         }
17647       else
17648         {
17649           errmsg ("parse error '%U'", format_unformat_error, input);
17650           return -99;
17651         }
17652     }
17653
17654   if (!vam->json_output)
17655     {
17656       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17657     }
17658
17659   M (ONE_LOCATOR_SET_DUMP, mp);
17660
17661   mp->filter = filter;
17662
17663   /* send it... */
17664   S (mp);
17665
17666   /* Use a control ping for synchronization */
17667   MPING (CONTROL_PING, mp_ping);
17668   S (mp_ping);
17669
17670   /* Wait for a reply... */
17671   W (ret);
17672   return ret;
17673 }
17674
17675 #define api_lisp_locator_set_dump api_one_locator_set_dump
17676
17677 static int
17678 api_one_eid_table_map_dump (vat_main_t * vam)
17679 {
17680   u8 is_l2 = 0;
17681   u8 mode_set = 0;
17682   unformat_input_t *input = vam->input;
17683   vl_api_one_eid_table_map_dump_t *mp;
17684   vl_api_control_ping_t *mp_ping;
17685   int ret;
17686
17687   /* Parse args required to build the message */
17688   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17689     {
17690       if (unformat (input, "l2"))
17691         {
17692           is_l2 = 1;
17693           mode_set = 1;
17694         }
17695       else if (unformat (input, "l3"))
17696         {
17697           is_l2 = 0;
17698           mode_set = 1;
17699         }
17700       else
17701         {
17702           errmsg ("parse error '%U'", format_unformat_error, input);
17703           return -99;
17704         }
17705     }
17706
17707   if (!mode_set)
17708     {
17709       errmsg ("expected one of 'l2' or 'l3' parameter!");
17710       return -99;
17711     }
17712
17713   if (!vam->json_output)
17714     {
17715       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17716     }
17717
17718   M (ONE_EID_TABLE_MAP_DUMP, mp);
17719   mp->is_l2 = is_l2;
17720
17721   /* send it... */
17722   S (mp);
17723
17724   /* Use a control ping for synchronization */
17725   MPING (CONTROL_PING, mp_ping);
17726   S (mp_ping);
17727
17728   /* Wait for a reply... */
17729   W (ret);
17730   return ret;
17731 }
17732
17733 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17734
17735 static int
17736 api_one_eid_table_vni_dump (vat_main_t * vam)
17737 {
17738   vl_api_one_eid_table_vni_dump_t *mp;
17739   vl_api_control_ping_t *mp_ping;
17740   int ret;
17741
17742   if (!vam->json_output)
17743     {
17744       print (vam->ofp, "VNI");
17745     }
17746
17747   M (ONE_EID_TABLE_VNI_DUMP, mp);
17748
17749   /* send it... */
17750   S (mp);
17751
17752   /* Use a control ping for synchronization */
17753   MPING (CONTROL_PING, mp_ping);
17754   S (mp_ping);
17755
17756   /* Wait for a reply... */
17757   W (ret);
17758   return ret;
17759 }
17760
17761 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17762
17763 static int
17764 api_one_eid_table_dump (vat_main_t * vam)
17765 {
17766   unformat_input_t *i = vam->input;
17767   vl_api_one_eid_table_dump_t *mp;
17768   vl_api_control_ping_t *mp_ping;
17769   struct in_addr ip4;
17770   struct in6_addr ip6;
17771   u8 mac[6];
17772   u8 eid_type = ~0, eid_set = 0;
17773   u32 prefix_length = ~0, t, vni = 0;
17774   u8 filter = 0;
17775   int ret;
17776   lisp_nsh_api_t nsh;
17777
17778   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17779     {
17780       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17781         {
17782           eid_set = 1;
17783           eid_type = 0;
17784           prefix_length = t;
17785         }
17786       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17787         {
17788           eid_set = 1;
17789           eid_type = 1;
17790           prefix_length = t;
17791         }
17792       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17793         {
17794           eid_set = 1;
17795           eid_type = 2;
17796         }
17797       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17798         {
17799           eid_set = 1;
17800           eid_type = 3;
17801         }
17802       else if (unformat (i, "vni %d", &t))
17803         {
17804           vni = t;
17805         }
17806       else if (unformat (i, "local"))
17807         {
17808           filter = 1;
17809         }
17810       else if (unformat (i, "remote"))
17811         {
17812           filter = 2;
17813         }
17814       else
17815         {
17816           errmsg ("parse error '%U'", format_unformat_error, i);
17817           return -99;
17818         }
17819     }
17820
17821   if (!vam->json_output)
17822     {
17823       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17824              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17825     }
17826
17827   M (ONE_EID_TABLE_DUMP, mp);
17828
17829   mp->filter = filter;
17830   if (eid_set)
17831     {
17832       mp->eid_set = 1;
17833       mp->vni = htonl (vni);
17834       mp->eid_type = eid_type;
17835       switch (eid_type)
17836         {
17837         case 0:
17838           mp->prefix_length = prefix_length;
17839           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17840           break;
17841         case 1:
17842           mp->prefix_length = prefix_length;
17843           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17844           break;
17845         case 2:
17846           clib_memcpy (mp->eid, mac, sizeof (mac));
17847           break;
17848         case 3:
17849           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17850           break;
17851         default:
17852           errmsg ("unknown EID type %d!", eid_type);
17853           return -99;
17854         }
17855     }
17856
17857   /* send it... */
17858   S (mp);
17859
17860   /* Use a control ping for synchronization */
17861   MPING (CONTROL_PING, mp_ping);
17862   S (mp_ping);
17863
17864   /* Wait for a reply... */
17865   W (ret);
17866   return ret;
17867 }
17868
17869 #define api_lisp_eid_table_dump api_one_eid_table_dump
17870
17871 static int
17872 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17873 {
17874   unformat_input_t *i = vam->input;
17875   vl_api_gpe_fwd_entries_get_t *mp;
17876   u8 vni_set = 0;
17877   u32 vni = ~0;
17878   int ret;
17879
17880   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17881     {
17882       if (unformat (i, "vni %d", &vni))
17883         {
17884           vni_set = 1;
17885         }
17886       else
17887         {
17888           errmsg ("parse error '%U'", format_unformat_error, i);
17889           return -99;
17890         }
17891     }
17892
17893   if (!vni_set)
17894     {
17895       errmsg ("vni not set!");
17896       return -99;
17897     }
17898
17899   if (!vam->json_output)
17900     {
17901       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17902              "leid", "reid");
17903     }
17904
17905   M (GPE_FWD_ENTRIES_GET, mp);
17906   mp->vni = clib_host_to_net_u32 (vni);
17907
17908   /* send it... */
17909   S (mp);
17910
17911   /* Wait for a reply... */
17912   W (ret);
17913   return ret;
17914 }
17915
17916 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
17917 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
17918 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
17919 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
17920 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
17921 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
17922 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
17923 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
17924
17925 static int
17926 api_one_adjacencies_get (vat_main_t * vam)
17927 {
17928   unformat_input_t *i = vam->input;
17929   vl_api_one_adjacencies_get_t *mp;
17930   u8 vni_set = 0;
17931   u32 vni = ~0;
17932   int ret;
17933
17934   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17935     {
17936       if (unformat (i, "vni %d", &vni))
17937         {
17938           vni_set = 1;
17939         }
17940       else
17941         {
17942           errmsg ("parse error '%U'", format_unformat_error, i);
17943           return -99;
17944         }
17945     }
17946
17947   if (!vni_set)
17948     {
17949       errmsg ("vni not set!");
17950       return -99;
17951     }
17952
17953   if (!vam->json_output)
17954     {
17955       print (vam->ofp, "%s %40s", "leid", "reid");
17956     }
17957
17958   M (ONE_ADJACENCIES_GET, mp);
17959   mp->vni = clib_host_to_net_u32 (vni);
17960
17961   /* send it... */
17962   S (mp);
17963
17964   /* Wait for a reply... */
17965   W (ret);
17966   return ret;
17967 }
17968
17969 #define api_lisp_adjacencies_get api_one_adjacencies_get
17970
17971 static int
17972 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
17973 {
17974   unformat_input_t *i = vam->input;
17975   vl_api_gpe_native_fwd_rpaths_get_t *mp;
17976   int ret;
17977   u8 ip_family_set = 0, is_ip4 = 1;
17978
17979   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17980     {
17981       if (unformat (i, "ip4"))
17982         {
17983           ip_family_set = 1;
17984           is_ip4 = 1;
17985         }
17986       else if (unformat (i, "ip6"))
17987         {
17988           ip_family_set = 1;
17989           is_ip4 = 0;
17990         }
17991       else
17992         {
17993           errmsg ("parse error '%U'", format_unformat_error, i);
17994           return -99;
17995         }
17996     }
17997
17998   if (!ip_family_set)
17999     {
18000       errmsg ("ip family not set!");
18001       return -99;
18002     }
18003
18004   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
18005   mp->is_ip4 = is_ip4;
18006
18007   /* send it... */
18008   S (mp);
18009
18010   /* Wait for a reply... */
18011   W (ret);
18012   return ret;
18013 }
18014
18015 static int
18016 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
18017 {
18018   vl_api_gpe_fwd_entry_vnis_get_t *mp;
18019   int ret;
18020
18021   if (!vam->json_output)
18022     {
18023       print (vam->ofp, "VNIs");
18024     }
18025
18026   M (GPE_FWD_ENTRY_VNIS_GET, mp);
18027
18028   /* send it... */
18029   S (mp);
18030
18031   /* Wait for a reply... */
18032   W (ret);
18033   return ret;
18034 }
18035
18036 static int
18037 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
18038 {
18039   unformat_input_t *i = vam->input;
18040   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
18041   int ret = 0;
18042   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
18043   struct in_addr ip4;
18044   struct in6_addr ip6;
18045   u32 table_id = 0, nh_sw_if_index = ~0;
18046
18047   memset (&ip4, 0, sizeof (ip4));
18048   memset (&ip6, 0, sizeof (ip6));
18049
18050   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18051     {
18052       if (unformat (i, "del"))
18053         is_add = 0;
18054       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
18055                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18056         {
18057           ip_set = 1;
18058           is_ip4 = 1;
18059         }
18060       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
18061                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
18062         {
18063           ip_set = 1;
18064           is_ip4 = 0;
18065         }
18066       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
18067         {
18068           ip_set = 1;
18069           is_ip4 = 1;
18070           nh_sw_if_index = ~0;
18071         }
18072       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
18073         {
18074           ip_set = 1;
18075           is_ip4 = 0;
18076           nh_sw_if_index = ~0;
18077         }
18078       else if (unformat (i, "table %d", &table_id))
18079         ;
18080       else
18081         {
18082           errmsg ("parse error '%U'", format_unformat_error, i);
18083           return -99;
18084         }
18085     }
18086
18087   if (!ip_set)
18088     {
18089       errmsg ("nh addr not set!");
18090       return -99;
18091     }
18092
18093   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
18094   mp->is_add = is_add;
18095   mp->table_id = clib_host_to_net_u32 (table_id);
18096   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18097   mp->is_ip4 = is_ip4;
18098   if (is_ip4)
18099     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18100   else
18101     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18102
18103   /* send it... */
18104   S (mp);
18105
18106   /* Wait for a reply... */
18107   W (ret);
18108   return ret;
18109 }
18110
18111 static int
18112 api_one_map_server_dump (vat_main_t * vam)
18113 {
18114   vl_api_one_map_server_dump_t *mp;
18115   vl_api_control_ping_t *mp_ping;
18116   int ret;
18117
18118   if (!vam->json_output)
18119     {
18120       print (vam->ofp, "%=20s", "Map server");
18121     }
18122
18123   M (ONE_MAP_SERVER_DUMP, mp);
18124   /* send it... */
18125   S (mp);
18126
18127   /* Use a control ping for synchronization */
18128   MPING (CONTROL_PING, mp_ping);
18129   S (mp_ping);
18130
18131   /* Wait for a reply... */
18132   W (ret);
18133   return ret;
18134 }
18135
18136 #define api_lisp_map_server_dump api_one_map_server_dump
18137
18138 static int
18139 api_one_map_resolver_dump (vat_main_t * vam)
18140 {
18141   vl_api_one_map_resolver_dump_t *mp;
18142   vl_api_control_ping_t *mp_ping;
18143   int ret;
18144
18145   if (!vam->json_output)
18146     {
18147       print (vam->ofp, "%=20s", "Map resolver");
18148     }
18149
18150   M (ONE_MAP_RESOLVER_DUMP, mp);
18151   /* send it... */
18152   S (mp);
18153
18154   /* Use a control ping for synchronization */
18155   MPING (CONTROL_PING, mp_ping);
18156   S (mp_ping);
18157
18158   /* Wait for a reply... */
18159   W (ret);
18160   return ret;
18161 }
18162
18163 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18164
18165 static int
18166 api_one_stats_flush (vat_main_t * vam)
18167 {
18168   vl_api_one_stats_flush_t *mp;
18169   int ret = 0;
18170
18171   M (ONE_STATS_FLUSH, mp);
18172   S (mp);
18173   W (ret);
18174   return ret;
18175 }
18176
18177 static int
18178 api_one_stats_dump (vat_main_t * vam)
18179 {
18180   vl_api_one_stats_dump_t *mp;
18181   vl_api_control_ping_t *mp_ping;
18182   int ret;
18183
18184   M (ONE_STATS_DUMP, mp);
18185   /* send it... */
18186   S (mp);
18187
18188   /* Use a control ping for synchronization */
18189   MPING (CONTROL_PING, mp_ping);
18190   S (mp_ping);
18191
18192   /* Wait for a reply... */
18193   W (ret);
18194   return ret;
18195 }
18196
18197 static int
18198 api_show_one_status (vat_main_t * vam)
18199 {
18200   vl_api_show_one_status_t *mp;
18201   int ret;
18202
18203   if (!vam->json_output)
18204     {
18205       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18206     }
18207
18208   M (SHOW_ONE_STATUS, mp);
18209   /* send it... */
18210   S (mp);
18211   /* Wait for a reply... */
18212   W (ret);
18213   return ret;
18214 }
18215
18216 #define api_show_lisp_status api_show_one_status
18217
18218 static int
18219 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18220 {
18221   vl_api_gpe_fwd_entry_path_dump_t *mp;
18222   vl_api_control_ping_t *mp_ping;
18223   unformat_input_t *i = vam->input;
18224   u32 fwd_entry_index = ~0;
18225   int ret;
18226
18227   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18228     {
18229       if (unformat (i, "index %d", &fwd_entry_index))
18230         ;
18231       else
18232         break;
18233     }
18234
18235   if (~0 == fwd_entry_index)
18236     {
18237       errmsg ("no index specified!");
18238       return -99;
18239     }
18240
18241   if (!vam->json_output)
18242     {
18243       print (vam->ofp, "first line");
18244     }
18245
18246   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18247
18248   /* send it... */
18249   S (mp);
18250   /* Use a control ping for synchronization */
18251   MPING (CONTROL_PING, mp_ping);
18252   S (mp_ping);
18253
18254   /* Wait for a reply... */
18255   W (ret);
18256   return ret;
18257 }
18258
18259 static int
18260 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18261 {
18262   vl_api_one_get_map_request_itr_rlocs_t *mp;
18263   int ret;
18264
18265   if (!vam->json_output)
18266     {
18267       print (vam->ofp, "%=20s", "itr-rlocs:");
18268     }
18269
18270   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18271   /* send it... */
18272   S (mp);
18273   /* Wait for a reply... */
18274   W (ret);
18275   return ret;
18276 }
18277
18278 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18279
18280 static int
18281 api_af_packet_create (vat_main_t * vam)
18282 {
18283   unformat_input_t *i = vam->input;
18284   vl_api_af_packet_create_t *mp;
18285   u8 *host_if_name = 0;
18286   u8 hw_addr[6];
18287   u8 random_hw_addr = 1;
18288   int ret;
18289
18290   memset (hw_addr, 0, sizeof (hw_addr));
18291
18292   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18293     {
18294       if (unformat (i, "name %s", &host_if_name))
18295         vec_add1 (host_if_name, 0);
18296       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18297         random_hw_addr = 0;
18298       else
18299         break;
18300     }
18301
18302   if (!vec_len (host_if_name))
18303     {
18304       errmsg ("host-interface name must be specified");
18305       return -99;
18306     }
18307
18308   if (vec_len (host_if_name) > 64)
18309     {
18310       errmsg ("host-interface name too long");
18311       return -99;
18312     }
18313
18314   M (AF_PACKET_CREATE, mp);
18315
18316   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18317   clib_memcpy (mp->hw_addr, hw_addr, 6);
18318   mp->use_random_hw_addr = random_hw_addr;
18319   vec_free (host_if_name);
18320
18321   S (mp);
18322
18323   /* *INDENT-OFF* */
18324   W2 (ret,
18325       ({
18326         if (ret == 0)
18327           fprintf (vam->ofp ? vam->ofp : stderr,
18328                    " new sw_if_index = %d\n", vam->sw_if_index);
18329       }));
18330   /* *INDENT-ON* */
18331   return ret;
18332 }
18333
18334 static int
18335 api_af_packet_delete (vat_main_t * vam)
18336 {
18337   unformat_input_t *i = vam->input;
18338   vl_api_af_packet_delete_t *mp;
18339   u8 *host_if_name = 0;
18340   int ret;
18341
18342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18343     {
18344       if (unformat (i, "name %s", &host_if_name))
18345         vec_add1 (host_if_name, 0);
18346       else
18347         break;
18348     }
18349
18350   if (!vec_len (host_if_name))
18351     {
18352       errmsg ("host-interface name must be specified");
18353       return -99;
18354     }
18355
18356   if (vec_len (host_if_name) > 64)
18357     {
18358       errmsg ("host-interface name too long");
18359       return -99;
18360     }
18361
18362   M (AF_PACKET_DELETE, mp);
18363
18364   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18365   vec_free (host_if_name);
18366
18367   S (mp);
18368   W (ret);
18369   return ret;
18370 }
18371
18372 static int
18373 api_policer_add_del (vat_main_t * vam)
18374 {
18375   unformat_input_t *i = vam->input;
18376   vl_api_policer_add_del_t *mp;
18377   u8 is_add = 1;
18378   u8 *name = 0;
18379   u32 cir = 0;
18380   u32 eir = 0;
18381   u64 cb = 0;
18382   u64 eb = 0;
18383   u8 rate_type = 0;
18384   u8 round_type = 0;
18385   u8 type = 0;
18386   u8 color_aware = 0;
18387   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18388   int ret;
18389
18390   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18391   conform_action.dscp = 0;
18392   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18393   exceed_action.dscp = 0;
18394   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18395   violate_action.dscp = 0;
18396
18397   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18398     {
18399       if (unformat (i, "del"))
18400         is_add = 0;
18401       else if (unformat (i, "name %s", &name))
18402         vec_add1 (name, 0);
18403       else if (unformat (i, "cir %u", &cir))
18404         ;
18405       else if (unformat (i, "eir %u", &eir))
18406         ;
18407       else if (unformat (i, "cb %u", &cb))
18408         ;
18409       else if (unformat (i, "eb %u", &eb))
18410         ;
18411       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18412                          &rate_type))
18413         ;
18414       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18415                          &round_type))
18416         ;
18417       else if (unformat (i, "type %U", unformat_policer_type, &type))
18418         ;
18419       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18420                          &conform_action))
18421         ;
18422       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18423                          &exceed_action))
18424         ;
18425       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18426                          &violate_action))
18427         ;
18428       else if (unformat (i, "color-aware"))
18429         color_aware = 1;
18430       else
18431         break;
18432     }
18433
18434   if (!vec_len (name))
18435     {
18436       errmsg ("policer name must be specified");
18437       return -99;
18438     }
18439
18440   if (vec_len (name) > 64)
18441     {
18442       errmsg ("policer name too long");
18443       return -99;
18444     }
18445
18446   M (POLICER_ADD_DEL, mp);
18447
18448   clib_memcpy (mp->name, name, vec_len (name));
18449   vec_free (name);
18450   mp->is_add = is_add;
18451   mp->cir = ntohl (cir);
18452   mp->eir = ntohl (eir);
18453   mp->cb = clib_net_to_host_u64 (cb);
18454   mp->eb = clib_net_to_host_u64 (eb);
18455   mp->rate_type = rate_type;
18456   mp->round_type = round_type;
18457   mp->type = type;
18458   mp->conform_action_type = conform_action.action_type;
18459   mp->conform_dscp = conform_action.dscp;
18460   mp->exceed_action_type = exceed_action.action_type;
18461   mp->exceed_dscp = exceed_action.dscp;
18462   mp->violate_action_type = violate_action.action_type;
18463   mp->violate_dscp = violate_action.dscp;
18464   mp->color_aware = color_aware;
18465
18466   S (mp);
18467   W (ret);
18468   return ret;
18469 }
18470
18471 static int
18472 api_policer_dump (vat_main_t * vam)
18473 {
18474   unformat_input_t *i = vam->input;
18475   vl_api_policer_dump_t *mp;
18476   vl_api_control_ping_t *mp_ping;
18477   u8 *match_name = 0;
18478   u8 match_name_valid = 0;
18479   int ret;
18480
18481   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18482     {
18483       if (unformat (i, "name %s", &match_name))
18484         {
18485           vec_add1 (match_name, 0);
18486           match_name_valid = 1;
18487         }
18488       else
18489         break;
18490     }
18491
18492   M (POLICER_DUMP, mp);
18493   mp->match_name_valid = match_name_valid;
18494   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18495   vec_free (match_name);
18496   /* send it... */
18497   S (mp);
18498
18499   /* Use a control ping for synchronization */
18500   MPING (CONTROL_PING, mp_ping);
18501   S (mp_ping);
18502
18503   /* Wait for a reply... */
18504   W (ret);
18505   return ret;
18506 }
18507
18508 static int
18509 api_policer_classify_set_interface (vat_main_t * vam)
18510 {
18511   unformat_input_t *i = vam->input;
18512   vl_api_policer_classify_set_interface_t *mp;
18513   u32 sw_if_index;
18514   int sw_if_index_set;
18515   u32 ip4_table_index = ~0;
18516   u32 ip6_table_index = ~0;
18517   u32 l2_table_index = ~0;
18518   u8 is_add = 1;
18519   int ret;
18520
18521   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18522     {
18523       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18524         sw_if_index_set = 1;
18525       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18526         sw_if_index_set = 1;
18527       else if (unformat (i, "del"))
18528         is_add = 0;
18529       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18530         ;
18531       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18532         ;
18533       else if (unformat (i, "l2-table %d", &l2_table_index))
18534         ;
18535       else
18536         {
18537           clib_warning ("parse error '%U'", format_unformat_error, i);
18538           return -99;
18539         }
18540     }
18541
18542   if (sw_if_index_set == 0)
18543     {
18544       errmsg ("missing interface name or sw_if_index");
18545       return -99;
18546     }
18547
18548   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18549
18550   mp->sw_if_index = ntohl (sw_if_index);
18551   mp->ip4_table_index = ntohl (ip4_table_index);
18552   mp->ip6_table_index = ntohl (ip6_table_index);
18553   mp->l2_table_index = ntohl (l2_table_index);
18554   mp->is_add = is_add;
18555
18556   S (mp);
18557   W (ret);
18558   return ret;
18559 }
18560
18561 static int
18562 api_policer_classify_dump (vat_main_t * vam)
18563 {
18564   unformat_input_t *i = vam->input;
18565   vl_api_policer_classify_dump_t *mp;
18566   vl_api_control_ping_t *mp_ping;
18567   u8 type = POLICER_CLASSIFY_N_TABLES;
18568   int ret;
18569
18570   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18571     ;
18572   else
18573     {
18574       errmsg ("classify table type must be specified");
18575       return -99;
18576     }
18577
18578   if (!vam->json_output)
18579     {
18580       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18581     }
18582
18583   M (POLICER_CLASSIFY_DUMP, mp);
18584   mp->type = type;
18585   /* send it... */
18586   S (mp);
18587
18588   /* Use a control ping for synchronization */
18589   MPING (CONTROL_PING, mp_ping);
18590   S (mp_ping);
18591
18592   /* Wait for a reply... */
18593   W (ret);
18594   return ret;
18595 }
18596
18597 static int
18598 api_netmap_create (vat_main_t * vam)
18599 {
18600   unformat_input_t *i = vam->input;
18601   vl_api_netmap_create_t *mp;
18602   u8 *if_name = 0;
18603   u8 hw_addr[6];
18604   u8 random_hw_addr = 1;
18605   u8 is_pipe = 0;
18606   u8 is_master = 0;
18607   int ret;
18608
18609   memset (hw_addr, 0, sizeof (hw_addr));
18610
18611   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18612     {
18613       if (unformat (i, "name %s", &if_name))
18614         vec_add1 (if_name, 0);
18615       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18616         random_hw_addr = 0;
18617       else if (unformat (i, "pipe"))
18618         is_pipe = 1;
18619       else if (unformat (i, "master"))
18620         is_master = 1;
18621       else if (unformat (i, "slave"))
18622         is_master = 0;
18623       else
18624         break;
18625     }
18626
18627   if (!vec_len (if_name))
18628     {
18629       errmsg ("interface name must be specified");
18630       return -99;
18631     }
18632
18633   if (vec_len (if_name) > 64)
18634     {
18635       errmsg ("interface name too long");
18636       return -99;
18637     }
18638
18639   M (NETMAP_CREATE, mp);
18640
18641   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18642   clib_memcpy (mp->hw_addr, hw_addr, 6);
18643   mp->use_random_hw_addr = random_hw_addr;
18644   mp->is_pipe = is_pipe;
18645   mp->is_master = is_master;
18646   vec_free (if_name);
18647
18648   S (mp);
18649   W (ret);
18650   return ret;
18651 }
18652
18653 static int
18654 api_netmap_delete (vat_main_t * vam)
18655 {
18656   unformat_input_t *i = vam->input;
18657   vl_api_netmap_delete_t *mp;
18658   u8 *if_name = 0;
18659   int ret;
18660
18661   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18662     {
18663       if (unformat (i, "name %s", &if_name))
18664         vec_add1 (if_name, 0);
18665       else
18666         break;
18667     }
18668
18669   if (!vec_len (if_name))
18670     {
18671       errmsg ("interface name must be specified");
18672       return -99;
18673     }
18674
18675   if (vec_len (if_name) > 64)
18676     {
18677       errmsg ("interface name too long");
18678       return -99;
18679     }
18680
18681   M (NETMAP_DELETE, mp);
18682
18683   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18684   vec_free (if_name);
18685
18686   S (mp);
18687   W (ret);
18688   return ret;
18689 }
18690
18691 static void
18692 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
18693 {
18694   if (fp->afi == IP46_TYPE_IP6)
18695     print (vam->ofp,
18696            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18697            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18698            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18699            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18700            format_ip6_address, fp->next_hop);
18701   else if (fp->afi == IP46_TYPE_IP4)
18702     print (vam->ofp,
18703            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18704            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18705            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18706            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18707            format_ip4_address, fp->next_hop);
18708 }
18709
18710 static void
18711 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18712                                  vl_api_fib_path2_t * fp)
18713 {
18714   struct in_addr ip4;
18715   struct in6_addr ip6;
18716
18717   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18718   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18719   vat_json_object_add_uint (node, "is_local", fp->is_local);
18720   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
18721   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
18722   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
18723   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
18724   if (fp->afi == IP46_TYPE_IP4)
18725     {
18726       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
18727       vat_json_object_add_ip4 (node, "next_hop", ip4);
18728     }
18729   else if (fp->afi == IP46_TYPE_IP6)
18730     {
18731       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
18732       vat_json_object_add_ip6 (node, "next_hop", ip6);
18733     }
18734 }
18735
18736 static void
18737 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18738 {
18739   vat_main_t *vam = &vat_main;
18740   int count = ntohl (mp->mt_count);
18741   vl_api_fib_path2_t *fp;
18742   i32 i;
18743
18744   print (vam->ofp, "[%d]: sw_if_index %d via:",
18745          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
18746   fp = mp->mt_paths;
18747   for (i = 0; i < count; i++)
18748     {
18749       vl_api_mpls_fib_path_print (vam, fp);
18750       fp++;
18751     }
18752
18753   print (vam->ofp, "");
18754 }
18755
18756 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18757 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18758
18759 static void
18760 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18761 {
18762   vat_main_t *vam = &vat_main;
18763   vat_json_node_t *node = NULL;
18764   int count = ntohl (mp->mt_count);
18765   vl_api_fib_path2_t *fp;
18766   i32 i;
18767
18768   if (VAT_JSON_ARRAY != vam->json_tree.type)
18769     {
18770       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18771       vat_json_init_array (&vam->json_tree);
18772     }
18773   node = vat_json_array_add (&vam->json_tree);
18774
18775   vat_json_init_object (node);
18776   vat_json_object_add_uint (node, "tunnel_index",
18777                             ntohl (mp->mt_tunnel_index));
18778   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
18779
18780   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
18781
18782   fp = mp->mt_paths;
18783   for (i = 0; i < count; i++)
18784     {
18785       vl_api_mpls_fib_path_json_print (node, fp);
18786       fp++;
18787     }
18788 }
18789
18790 static int
18791 api_mpls_tunnel_dump (vat_main_t * vam)
18792 {
18793   vl_api_mpls_tunnel_dump_t *mp;
18794   vl_api_control_ping_t *mp_ping;
18795   i32 index = -1;
18796   int ret;
18797
18798   /* Parse args required to build the message */
18799   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
18800     {
18801       if (!unformat (vam->input, "tunnel_index %d", &index))
18802         {
18803           index = -1;
18804           break;
18805         }
18806     }
18807
18808   print (vam->ofp, "  tunnel_index %d", index);
18809
18810   M (MPLS_TUNNEL_DUMP, mp);
18811   mp->tunnel_index = htonl (index);
18812   S (mp);
18813
18814   /* Use a control ping for synchronization */
18815   MPING (CONTROL_PING, mp_ping);
18816   S (mp_ping);
18817
18818   W (ret);
18819   return ret;
18820 }
18821
18822 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
18823 #define vl_api_mpls_fib_details_t_print vl_noop_handler
18824
18825
18826 static void
18827 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
18828 {
18829   vat_main_t *vam = &vat_main;
18830   int count = ntohl (mp->count);
18831   vl_api_fib_path2_t *fp;
18832   int i;
18833
18834   print (vam->ofp,
18835          "table-id %d, label %u, ess_bit %u",
18836          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
18837   fp = mp->path;
18838   for (i = 0; i < count; i++)
18839     {
18840       vl_api_mpls_fib_path_print (vam, fp);
18841       fp++;
18842     }
18843 }
18844
18845 static void vl_api_mpls_fib_details_t_handler_json
18846   (vl_api_mpls_fib_details_t * mp)
18847 {
18848   vat_main_t *vam = &vat_main;
18849   int count = ntohl (mp->count);
18850   vat_json_node_t *node = NULL;
18851   vl_api_fib_path2_t *fp;
18852   int i;
18853
18854   if (VAT_JSON_ARRAY != vam->json_tree.type)
18855     {
18856       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18857       vat_json_init_array (&vam->json_tree);
18858     }
18859   node = vat_json_array_add (&vam->json_tree);
18860
18861   vat_json_init_object (node);
18862   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
18863   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
18864   vat_json_object_add_uint (node, "label", ntohl (mp->label));
18865   vat_json_object_add_uint (node, "path_count", count);
18866   fp = mp->path;
18867   for (i = 0; i < count; i++)
18868     {
18869       vl_api_mpls_fib_path_json_print (node, fp);
18870       fp++;
18871     }
18872 }
18873
18874 static int
18875 api_mpls_fib_dump (vat_main_t * vam)
18876 {
18877   vl_api_mpls_fib_dump_t *mp;
18878   vl_api_control_ping_t *mp_ping;
18879   int ret;
18880
18881   M (MPLS_FIB_DUMP, mp);
18882   S (mp);
18883
18884   /* Use a control ping for synchronization */
18885   MPING (CONTROL_PING, mp_ping);
18886   S (mp_ping);
18887
18888   W (ret);
18889   return ret;
18890 }
18891
18892 #define vl_api_ip_fib_details_t_endian vl_noop_handler
18893 #define vl_api_ip_fib_details_t_print vl_noop_handler
18894
18895 static void
18896 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
18897 {
18898   vat_main_t *vam = &vat_main;
18899   int count = ntohl (mp->count);
18900   vl_api_fib_path_t *fp;
18901   int i;
18902
18903   print (vam->ofp,
18904          "table-id %d, prefix %U/%d",
18905          ntohl (mp->table_id), format_ip4_address, mp->address,
18906          mp->address_length);
18907   fp = mp->path;
18908   for (i = 0; i < count; i++)
18909     {
18910       if (fp->afi == IP46_TYPE_IP6)
18911         print (vam->ofp,
18912                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18913                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18914                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18915                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18916                format_ip6_address, fp->next_hop);
18917       else if (fp->afi == IP46_TYPE_IP4)
18918         print (vam->ofp,
18919                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18920                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18921                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18922                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18923                format_ip4_address, fp->next_hop);
18924       fp++;
18925     }
18926 }
18927
18928 static void vl_api_ip_fib_details_t_handler_json
18929   (vl_api_ip_fib_details_t * mp)
18930 {
18931   vat_main_t *vam = &vat_main;
18932   int count = ntohl (mp->count);
18933   vat_json_node_t *node = NULL;
18934   struct in_addr ip4;
18935   struct in6_addr ip6;
18936   vl_api_fib_path_t *fp;
18937   int i;
18938
18939   if (VAT_JSON_ARRAY != vam->json_tree.type)
18940     {
18941       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18942       vat_json_init_array (&vam->json_tree);
18943     }
18944   node = vat_json_array_add (&vam->json_tree);
18945
18946   vat_json_init_object (node);
18947   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
18948   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
18949   vat_json_object_add_ip4 (node, "prefix", ip4);
18950   vat_json_object_add_uint (node, "mask_length", mp->address_length);
18951   vat_json_object_add_uint (node, "path_count", count);
18952   fp = mp->path;
18953   for (i = 0; i < count; i++)
18954     {
18955       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18956       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18957       vat_json_object_add_uint (node, "is_local", fp->is_local);
18958       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
18959       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
18960       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
18961       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
18962       if (fp->afi == IP46_TYPE_IP4)
18963         {
18964           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
18965           vat_json_object_add_ip4 (node, "next_hop", ip4);
18966         }
18967       else if (fp->afi == IP46_TYPE_IP6)
18968         {
18969           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
18970           vat_json_object_add_ip6 (node, "next_hop", ip6);
18971         }
18972     }
18973 }
18974
18975 static int
18976 api_ip_fib_dump (vat_main_t * vam)
18977 {
18978   vl_api_ip_fib_dump_t *mp;
18979   vl_api_control_ping_t *mp_ping;
18980   int ret;
18981
18982   M (IP_FIB_DUMP, mp);
18983   S (mp);
18984
18985   /* Use a control ping for synchronization */
18986   MPING (CONTROL_PING, mp_ping);
18987   S (mp_ping);
18988
18989   W (ret);
18990   return ret;
18991 }
18992
18993 static int
18994 api_ip_mfib_dump (vat_main_t * vam)
18995 {
18996   vl_api_ip_mfib_dump_t *mp;
18997   vl_api_control_ping_t *mp_ping;
18998   int ret;
18999
19000   M (IP_MFIB_DUMP, mp);
19001   S (mp);
19002
19003   /* Use a control ping for synchronization */
19004   MPING (CONTROL_PING, mp_ping);
19005   S (mp_ping);
19006
19007   W (ret);
19008   return ret;
19009 }
19010
19011 static void vl_api_ip_neighbor_details_t_handler
19012   (vl_api_ip_neighbor_details_t * mp)
19013 {
19014   vat_main_t *vam = &vat_main;
19015
19016   print (vam->ofp, "%c %U %U",
19017          (mp->is_static) ? 'S' : 'D',
19018          format_ethernet_address, &mp->mac_address,
19019          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
19020          &mp->ip_address);
19021 }
19022
19023 static void vl_api_ip_neighbor_details_t_handler_json
19024   (vl_api_ip_neighbor_details_t * mp)
19025 {
19026
19027   vat_main_t *vam = &vat_main;
19028   vat_json_node_t *node;
19029   struct in_addr ip4;
19030   struct in6_addr ip6;
19031
19032   if (VAT_JSON_ARRAY != vam->json_tree.type)
19033     {
19034       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19035       vat_json_init_array (&vam->json_tree);
19036     }
19037   node = vat_json_array_add (&vam->json_tree);
19038
19039   vat_json_init_object (node);
19040   vat_json_object_add_string_copy (node, "flag",
19041                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
19042                                    "dynamic");
19043
19044   vat_json_object_add_string_copy (node, "link_layer",
19045                                    format (0, "%U", format_ethernet_address,
19046                                            &mp->mac_address));
19047
19048   if (mp->is_ipv6)
19049     {
19050       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
19051       vat_json_object_add_ip6 (node, "ip_address", ip6);
19052     }
19053   else
19054     {
19055       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
19056       vat_json_object_add_ip4 (node, "ip_address", ip4);
19057     }
19058 }
19059
19060 static int
19061 api_ip_neighbor_dump (vat_main_t * vam)
19062 {
19063   unformat_input_t *i = vam->input;
19064   vl_api_ip_neighbor_dump_t *mp;
19065   vl_api_control_ping_t *mp_ping;
19066   u8 is_ipv6 = 0;
19067   u32 sw_if_index = ~0;
19068   int ret;
19069
19070   /* Parse args required to build the message */
19071   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19072     {
19073       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19074         ;
19075       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19076         ;
19077       else if (unformat (i, "ip6"))
19078         is_ipv6 = 1;
19079       else
19080         break;
19081     }
19082
19083   if (sw_if_index == ~0)
19084     {
19085       errmsg ("missing interface name or sw_if_index");
19086       return -99;
19087     }
19088
19089   M (IP_NEIGHBOR_DUMP, mp);
19090   mp->is_ipv6 = (u8) is_ipv6;
19091   mp->sw_if_index = ntohl (sw_if_index);
19092   S (mp);
19093
19094   /* Use a control ping for synchronization */
19095   MPING (CONTROL_PING, mp_ping);
19096   S (mp_ping);
19097
19098   W (ret);
19099   return ret;
19100 }
19101
19102 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
19103 #define vl_api_ip6_fib_details_t_print vl_noop_handler
19104
19105 static void
19106 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
19107 {
19108   vat_main_t *vam = &vat_main;
19109   int count = ntohl (mp->count);
19110   vl_api_fib_path_t *fp;
19111   int i;
19112
19113   print (vam->ofp,
19114          "table-id %d, prefix %U/%d",
19115          ntohl (mp->table_id), format_ip6_address, mp->address,
19116          mp->address_length);
19117   fp = mp->path;
19118   for (i = 0; i < count; i++)
19119     {
19120       if (fp->afi == IP46_TYPE_IP6)
19121         print (vam->ofp,
19122                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19123                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19124                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19125                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19126                format_ip6_address, fp->next_hop);
19127       else if (fp->afi == IP46_TYPE_IP4)
19128         print (vam->ofp,
19129                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19130                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19131                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19132                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19133                format_ip4_address, fp->next_hop);
19134       fp++;
19135     }
19136 }
19137
19138 static void vl_api_ip6_fib_details_t_handler_json
19139   (vl_api_ip6_fib_details_t * mp)
19140 {
19141   vat_main_t *vam = &vat_main;
19142   int count = ntohl (mp->count);
19143   vat_json_node_t *node = NULL;
19144   struct in_addr ip4;
19145   struct in6_addr ip6;
19146   vl_api_fib_path_t *fp;
19147   int i;
19148
19149   if (VAT_JSON_ARRAY != vam->json_tree.type)
19150     {
19151       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19152       vat_json_init_array (&vam->json_tree);
19153     }
19154   node = vat_json_array_add (&vam->json_tree);
19155
19156   vat_json_init_object (node);
19157   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19158   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
19159   vat_json_object_add_ip6 (node, "prefix", ip6);
19160   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19161   vat_json_object_add_uint (node, "path_count", count);
19162   fp = mp->path;
19163   for (i = 0; i < count; i++)
19164     {
19165       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19166       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19167       vat_json_object_add_uint (node, "is_local", fp->is_local);
19168       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19169       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19170       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19171       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19172       if (fp->afi == IP46_TYPE_IP4)
19173         {
19174           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19175           vat_json_object_add_ip4 (node, "next_hop", ip4);
19176         }
19177       else if (fp->afi == IP46_TYPE_IP6)
19178         {
19179           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19180           vat_json_object_add_ip6 (node, "next_hop", ip6);
19181         }
19182     }
19183 }
19184
19185 static int
19186 api_ip6_fib_dump (vat_main_t * vam)
19187 {
19188   vl_api_ip6_fib_dump_t *mp;
19189   vl_api_control_ping_t *mp_ping;
19190   int ret;
19191
19192   M (IP6_FIB_DUMP, mp);
19193   S (mp);
19194
19195   /* Use a control ping for synchronization */
19196   MPING (CONTROL_PING, mp_ping);
19197   S (mp_ping);
19198
19199   W (ret);
19200   return ret;
19201 }
19202
19203 static int
19204 api_ip6_mfib_dump (vat_main_t * vam)
19205 {
19206   vl_api_ip6_mfib_dump_t *mp;
19207   vl_api_control_ping_t *mp_ping;
19208   int ret;
19209
19210   M (IP6_MFIB_DUMP, mp);
19211   S (mp);
19212
19213   /* Use a control ping for synchronization */
19214   MPING (CONTROL_PING, mp_ping);
19215   S (mp_ping);
19216
19217   W (ret);
19218   return ret;
19219 }
19220
19221 int
19222 api_classify_table_ids (vat_main_t * vam)
19223 {
19224   vl_api_classify_table_ids_t *mp;
19225   int ret;
19226
19227   /* Construct the API message */
19228   M (CLASSIFY_TABLE_IDS, mp);
19229   mp->context = 0;
19230
19231   S (mp);
19232   W (ret);
19233   return ret;
19234 }
19235
19236 int
19237 api_classify_table_by_interface (vat_main_t * vam)
19238 {
19239   unformat_input_t *input = vam->input;
19240   vl_api_classify_table_by_interface_t *mp;
19241
19242   u32 sw_if_index = ~0;
19243   int ret;
19244   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19245     {
19246       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19247         ;
19248       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19249         ;
19250       else
19251         break;
19252     }
19253   if (sw_if_index == ~0)
19254     {
19255       errmsg ("missing interface name or sw_if_index");
19256       return -99;
19257     }
19258
19259   /* Construct the API message */
19260   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19261   mp->context = 0;
19262   mp->sw_if_index = ntohl (sw_if_index);
19263
19264   S (mp);
19265   W (ret);
19266   return ret;
19267 }
19268
19269 int
19270 api_classify_table_info (vat_main_t * vam)
19271 {
19272   unformat_input_t *input = vam->input;
19273   vl_api_classify_table_info_t *mp;
19274
19275   u32 table_id = ~0;
19276   int ret;
19277   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19278     {
19279       if (unformat (input, "table_id %d", &table_id))
19280         ;
19281       else
19282         break;
19283     }
19284   if (table_id == ~0)
19285     {
19286       errmsg ("missing table id");
19287       return -99;
19288     }
19289
19290   /* Construct the API message */
19291   M (CLASSIFY_TABLE_INFO, mp);
19292   mp->context = 0;
19293   mp->table_id = ntohl (table_id);
19294
19295   S (mp);
19296   W (ret);
19297   return ret;
19298 }
19299
19300 int
19301 api_classify_session_dump (vat_main_t * vam)
19302 {
19303   unformat_input_t *input = vam->input;
19304   vl_api_classify_session_dump_t *mp;
19305   vl_api_control_ping_t *mp_ping;
19306
19307   u32 table_id = ~0;
19308   int ret;
19309   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19310     {
19311       if (unformat (input, "table_id %d", &table_id))
19312         ;
19313       else
19314         break;
19315     }
19316   if (table_id == ~0)
19317     {
19318       errmsg ("missing table id");
19319       return -99;
19320     }
19321
19322   /* Construct the API message */
19323   M (CLASSIFY_SESSION_DUMP, mp);
19324   mp->context = 0;
19325   mp->table_id = ntohl (table_id);
19326   S (mp);
19327
19328   /* Use a control ping for synchronization */
19329   MPING (CONTROL_PING, mp_ping);
19330   S (mp_ping);
19331
19332   W (ret);
19333   return ret;
19334 }
19335
19336 static void
19337 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19338 {
19339   vat_main_t *vam = &vat_main;
19340
19341   print (vam->ofp, "collector_address %U, collector_port %d, "
19342          "src_address %U, vrf_id %d, path_mtu %u, "
19343          "template_interval %u, udp_checksum %d",
19344          format_ip4_address, mp->collector_address,
19345          ntohs (mp->collector_port),
19346          format_ip4_address, mp->src_address,
19347          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19348          ntohl (mp->template_interval), mp->udp_checksum);
19349
19350   vam->retval = 0;
19351   vam->result_ready = 1;
19352 }
19353
19354 static void
19355   vl_api_ipfix_exporter_details_t_handler_json
19356   (vl_api_ipfix_exporter_details_t * mp)
19357 {
19358   vat_main_t *vam = &vat_main;
19359   vat_json_node_t node;
19360   struct in_addr collector_address;
19361   struct in_addr src_address;
19362
19363   vat_json_init_object (&node);
19364   clib_memcpy (&collector_address, &mp->collector_address,
19365                sizeof (collector_address));
19366   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19367   vat_json_object_add_uint (&node, "collector_port",
19368                             ntohs (mp->collector_port));
19369   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19370   vat_json_object_add_ip4 (&node, "src_address", src_address);
19371   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19372   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19373   vat_json_object_add_uint (&node, "template_interval",
19374                             ntohl (mp->template_interval));
19375   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19376
19377   vat_json_print (vam->ofp, &node);
19378   vat_json_free (&node);
19379   vam->retval = 0;
19380   vam->result_ready = 1;
19381 }
19382
19383 int
19384 api_ipfix_exporter_dump (vat_main_t * vam)
19385 {
19386   vl_api_ipfix_exporter_dump_t *mp;
19387   int ret;
19388
19389   /* Construct the API message */
19390   M (IPFIX_EXPORTER_DUMP, mp);
19391   mp->context = 0;
19392
19393   S (mp);
19394   W (ret);
19395   return ret;
19396 }
19397
19398 static int
19399 api_ipfix_classify_stream_dump (vat_main_t * vam)
19400 {
19401   vl_api_ipfix_classify_stream_dump_t *mp;
19402   int ret;
19403
19404   /* Construct the API message */
19405   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19406   mp->context = 0;
19407
19408   S (mp);
19409   W (ret);
19410   return ret;
19411   /* NOTREACHED */
19412   return 0;
19413 }
19414
19415 static void
19416   vl_api_ipfix_classify_stream_details_t_handler
19417   (vl_api_ipfix_classify_stream_details_t * mp)
19418 {
19419   vat_main_t *vam = &vat_main;
19420   print (vam->ofp, "domain_id %d, src_port %d",
19421          ntohl (mp->domain_id), ntohs (mp->src_port));
19422   vam->retval = 0;
19423   vam->result_ready = 1;
19424 }
19425
19426 static void
19427   vl_api_ipfix_classify_stream_details_t_handler_json
19428   (vl_api_ipfix_classify_stream_details_t * mp)
19429 {
19430   vat_main_t *vam = &vat_main;
19431   vat_json_node_t node;
19432
19433   vat_json_init_object (&node);
19434   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19435   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19436
19437   vat_json_print (vam->ofp, &node);
19438   vat_json_free (&node);
19439   vam->retval = 0;
19440   vam->result_ready = 1;
19441 }
19442
19443 static int
19444 api_ipfix_classify_table_dump (vat_main_t * vam)
19445 {
19446   vl_api_ipfix_classify_table_dump_t *mp;
19447   vl_api_control_ping_t *mp_ping;
19448   int ret;
19449
19450   if (!vam->json_output)
19451     {
19452       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19453              "transport_protocol");
19454     }
19455
19456   /* Construct the API message */
19457   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19458
19459   /* send it... */
19460   S (mp);
19461
19462   /* Use a control ping for synchronization */
19463   MPING (CONTROL_PING, mp_ping);
19464   S (mp_ping);
19465
19466   W (ret);
19467   return ret;
19468 }
19469
19470 static void
19471   vl_api_ipfix_classify_table_details_t_handler
19472   (vl_api_ipfix_classify_table_details_t * mp)
19473 {
19474   vat_main_t *vam = &vat_main;
19475   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19476          mp->transport_protocol);
19477 }
19478
19479 static void
19480   vl_api_ipfix_classify_table_details_t_handler_json
19481   (vl_api_ipfix_classify_table_details_t * mp)
19482 {
19483   vat_json_node_t *node = NULL;
19484   vat_main_t *vam = &vat_main;
19485
19486   if (VAT_JSON_ARRAY != vam->json_tree.type)
19487     {
19488       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19489       vat_json_init_array (&vam->json_tree);
19490     }
19491
19492   node = vat_json_array_add (&vam->json_tree);
19493   vat_json_init_object (node);
19494
19495   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19496   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19497   vat_json_object_add_uint (node, "transport_protocol",
19498                             mp->transport_protocol);
19499 }
19500
19501 static int
19502 api_sw_interface_span_enable_disable (vat_main_t * vam)
19503 {
19504   unformat_input_t *i = vam->input;
19505   vl_api_sw_interface_span_enable_disable_t *mp;
19506   u32 src_sw_if_index = ~0;
19507   u32 dst_sw_if_index = ~0;
19508   u8 state = 3;
19509   int ret;
19510   u8 is_l2 = 0;
19511
19512   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19513     {
19514       if (unformat
19515           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19516         ;
19517       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19518         ;
19519       else
19520         if (unformat
19521             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19522         ;
19523       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19524         ;
19525       else if (unformat (i, "disable"))
19526         state = 0;
19527       else if (unformat (i, "rx"))
19528         state = 1;
19529       else if (unformat (i, "tx"))
19530         state = 2;
19531       else if (unformat (i, "both"))
19532         state = 3;
19533       else if (unformat (i, "l2"))
19534         is_l2 = 1;
19535       else
19536         break;
19537     }
19538
19539   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19540
19541   mp->sw_if_index_from = htonl (src_sw_if_index);
19542   mp->sw_if_index_to = htonl (dst_sw_if_index);
19543   mp->state = state;
19544   mp->is_l2 = is_l2;
19545
19546   S (mp);
19547   W (ret);
19548   return ret;
19549 }
19550
19551 static void
19552 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19553                                             * mp)
19554 {
19555   vat_main_t *vam = &vat_main;
19556   u8 *sw_if_from_name = 0;
19557   u8 *sw_if_to_name = 0;
19558   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19559   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19560   char *states[] = { "none", "rx", "tx", "both" };
19561   hash_pair_t *p;
19562
19563   /* *INDENT-OFF* */
19564   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19565   ({
19566     if ((u32) p->value[0] == sw_if_index_from)
19567       {
19568         sw_if_from_name = (u8 *)(p->key);
19569         if (sw_if_to_name)
19570           break;
19571       }
19572     if ((u32) p->value[0] == sw_if_index_to)
19573       {
19574         sw_if_to_name = (u8 *)(p->key);
19575         if (sw_if_from_name)
19576           break;
19577       }
19578   }));
19579   /* *INDENT-ON* */
19580   print (vam->ofp, "%20s => %20s (%s)",
19581          sw_if_from_name, sw_if_to_name, states[mp->state]);
19582 }
19583
19584 static void
19585   vl_api_sw_interface_span_details_t_handler_json
19586   (vl_api_sw_interface_span_details_t * mp)
19587 {
19588   vat_main_t *vam = &vat_main;
19589   vat_json_node_t *node = NULL;
19590   u8 *sw_if_from_name = 0;
19591   u8 *sw_if_to_name = 0;
19592   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19593   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19594   hash_pair_t *p;
19595
19596   /* *INDENT-OFF* */
19597   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19598   ({
19599     if ((u32) p->value[0] == sw_if_index_from)
19600       {
19601         sw_if_from_name = (u8 *)(p->key);
19602         if (sw_if_to_name)
19603           break;
19604       }
19605     if ((u32) p->value[0] == sw_if_index_to)
19606       {
19607         sw_if_to_name = (u8 *)(p->key);
19608         if (sw_if_from_name)
19609           break;
19610       }
19611   }));
19612   /* *INDENT-ON* */
19613
19614   if (VAT_JSON_ARRAY != vam->json_tree.type)
19615     {
19616       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19617       vat_json_init_array (&vam->json_tree);
19618     }
19619   node = vat_json_array_add (&vam->json_tree);
19620
19621   vat_json_init_object (node);
19622   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19623   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19624   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19625   if (0 != sw_if_to_name)
19626     {
19627       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19628     }
19629   vat_json_object_add_uint (node, "state", mp->state);
19630 }
19631
19632 static int
19633 api_sw_interface_span_dump (vat_main_t * vam)
19634 {
19635   unformat_input_t *input = vam->input;
19636   vl_api_sw_interface_span_dump_t *mp;
19637   vl_api_control_ping_t *mp_ping;
19638   u8 is_l2 = 0;
19639   int ret;
19640
19641   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19642     {
19643       if (unformat (input, "l2"))
19644         is_l2 = 1;
19645       else
19646         break;
19647     }
19648
19649   M (SW_INTERFACE_SPAN_DUMP, mp);
19650   mp->is_l2 = is_l2;
19651   S (mp);
19652
19653   /* Use a control ping for synchronization */
19654   MPING (CONTROL_PING, mp_ping);
19655   S (mp_ping);
19656
19657   W (ret);
19658   return ret;
19659 }
19660
19661 int
19662 api_pg_create_interface (vat_main_t * vam)
19663 {
19664   unformat_input_t *input = vam->input;
19665   vl_api_pg_create_interface_t *mp;
19666
19667   u32 if_id = ~0;
19668   int ret;
19669   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19670     {
19671       if (unformat (input, "if_id %d", &if_id))
19672         ;
19673       else
19674         break;
19675     }
19676   if (if_id == ~0)
19677     {
19678       errmsg ("missing pg interface index");
19679       return -99;
19680     }
19681
19682   /* Construct the API message */
19683   M (PG_CREATE_INTERFACE, mp);
19684   mp->context = 0;
19685   mp->interface_id = ntohl (if_id);
19686
19687   S (mp);
19688   W (ret);
19689   return ret;
19690 }
19691
19692 int
19693 api_pg_capture (vat_main_t * vam)
19694 {
19695   unformat_input_t *input = vam->input;
19696   vl_api_pg_capture_t *mp;
19697
19698   u32 if_id = ~0;
19699   u8 enable = 1;
19700   u32 count = 1;
19701   u8 pcap_file_set = 0;
19702   u8 *pcap_file = 0;
19703   int ret;
19704   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19705     {
19706       if (unformat (input, "if_id %d", &if_id))
19707         ;
19708       else if (unformat (input, "pcap %s", &pcap_file))
19709         pcap_file_set = 1;
19710       else if (unformat (input, "count %d", &count))
19711         ;
19712       else if (unformat (input, "disable"))
19713         enable = 0;
19714       else
19715         break;
19716     }
19717   if (if_id == ~0)
19718     {
19719       errmsg ("missing pg interface index");
19720       return -99;
19721     }
19722   if (pcap_file_set > 0)
19723     {
19724       if (vec_len (pcap_file) > 255)
19725         {
19726           errmsg ("pcap file name is too long");
19727           return -99;
19728         }
19729     }
19730
19731   u32 name_len = vec_len (pcap_file);
19732   /* Construct the API message */
19733   M (PG_CAPTURE, mp);
19734   mp->context = 0;
19735   mp->interface_id = ntohl (if_id);
19736   mp->is_enabled = enable;
19737   mp->count = ntohl (count);
19738   mp->pcap_name_length = ntohl (name_len);
19739   if (pcap_file_set != 0)
19740     {
19741       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19742     }
19743   vec_free (pcap_file);
19744
19745   S (mp);
19746   W (ret);
19747   return ret;
19748 }
19749
19750 int
19751 api_pg_enable_disable (vat_main_t * vam)
19752 {
19753   unformat_input_t *input = vam->input;
19754   vl_api_pg_enable_disable_t *mp;
19755
19756   u8 enable = 1;
19757   u8 stream_name_set = 0;
19758   u8 *stream_name = 0;
19759   int ret;
19760   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19761     {
19762       if (unformat (input, "stream %s", &stream_name))
19763         stream_name_set = 1;
19764       else if (unformat (input, "disable"))
19765         enable = 0;
19766       else
19767         break;
19768     }
19769
19770   if (stream_name_set > 0)
19771     {
19772       if (vec_len (stream_name) > 255)
19773         {
19774           errmsg ("stream name too long");
19775           return -99;
19776         }
19777     }
19778
19779   u32 name_len = vec_len (stream_name);
19780   /* Construct the API message */
19781   M (PG_ENABLE_DISABLE, mp);
19782   mp->context = 0;
19783   mp->is_enabled = enable;
19784   if (stream_name_set != 0)
19785     {
19786       mp->stream_name_length = ntohl (name_len);
19787       clib_memcpy (mp->stream_name, stream_name, name_len);
19788     }
19789   vec_free (stream_name);
19790
19791   S (mp);
19792   W (ret);
19793   return ret;
19794 }
19795
19796 int
19797 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19798 {
19799   unformat_input_t *input = vam->input;
19800   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19801
19802   u16 *low_ports = 0;
19803   u16 *high_ports = 0;
19804   u16 this_low;
19805   u16 this_hi;
19806   ip4_address_t ip4_addr;
19807   ip6_address_t ip6_addr;
19808   u32 length;
19809   u32 tmp, tmp2;
19810   u8 prefix_set = 0;
19811   u32 vrf_id = ~0;
19812   u8 is_add = 1;
19813   u8 is_ipv6 = 0;
19814   int ret;
19815
19816   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19817     {
19818       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
19819         {
19820           prefix_set = 1;
19821         }
19822       else
19823         if (unformat
19824             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
19825         {
19826           prefix_set = 1;
19827           is_ipv6 = 1;
19828         }
19829       else if (unformat (input, "vrf %d", &vrf_id))
19830         ;
19831       else if (unformat (input, "del"))
19832         is_add = 0;
19833       else if (unformat (input, "port %d", &tmp))
19834         {
19835           if (tmp == 0 || tmp > 65535)
19836             {
19837               errmsg ("port %d out of range", tmp);
19838               return -99;
19839             }
19840           this_low = tmp;
19841           this_hi = this_low + 1;
19842           vec_add1 (low_ports, this_low);
19843           vec_add1 (high_ports, this_hi);
19844         }
19845       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19846         {
19847           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19848             {
19849               errmsg ("incorrect range parameters");
19850               return -99;
19851             }
19852           this_low = tmp;
19853           /* Note: in debug CLI +1 is added to high before
19854              passing to real fn that does "the work"
19855              (ip_source_and_port_range_check_add_del).
19856              This fn is a wrapper around the binary API fn a
19857              control plane will call, which expects this increment
19858              to have occurred. Hence letting the binary API control
19859              plane fn do the increment for consistency between VAT
19860              and other control planes.
19861            */
19862           this_hi = tmp2;
19863           vec_add1 (low_ports, this_low);
19864           vec_add1 (high_ports, this_hi);
19865         }
19866       else
19867         break;
19868     }
19869
19870   if (prefix_set == 0)
19871     {
19872       errmsg ("<address>/<mask> not specified");
19873       return -99;
19874     }
19875
19876   if (vrf_id == ~0)
19877     {
19878       errmsg ("VRF ID required, not specified");
19879       return -99;
19880     }
19881
19882   if (vrf_id == 0)
19883     {
19884       errmsg
19885         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19886       return -99;
19887     }
19888
19889   if (vec_len (low_ports) == 0)
19890     {
19891       errmsg ("At least one port or port range required");
19892       return -99;
19893     }
19894
19895   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19896
19897   mp->is_add = is_add;
19898
19899   if (is_ipv6)
19900     {
19901       mp->is_ipv6 = 1;
19902       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
19903     }
19904   else
19905     {
19906       mp->is_ipv6 = 0;
19907       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
19908     }
19909
19910   mp->mask_length = length;
19911   mp->number_of_ranges = vec_len (low_ports);
19912
19913   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
19914   vec_free (low_ports);
19915
19916   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
19917   vec_free (high_ports);
19918
19919   mp->vrf_id = ntohl (vrf_id);
19920
19921   S (mp);
19922   W (ret);
19923   return ret;
19924 }
19925
19926 int
19927 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
19928 {
19929   unformat_input_t *input = vam->input;
19930   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
19931   u32 sw_if_index = ~0;
19932   int vrf_set = 0;
19933   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
19934   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
19935   u8 is_add = 1;
19936   int ret;
19937
19938   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19939     {
19940       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19941         ;
19942       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19943         ;
19944       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
19945         vrf_set = 1;
19946       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
19947         vrf_set = 1;
19948       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
19949         vrf_set = 1;
19950       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
19951         vrf_set = 1;
19952       else if (unformat (input, "del"))
19953         is_add = 0;
19954       else
19955         break;
19956     }
19957
19958   if (sw_if_index == ~0)
19959     {
19960       errmsg ("Interface required but not specified");
19961       return -99;
19962     }
19963
19964   if (vrf_set == 0)
19965     {
19966       errmsg ("VRF ID required but not specified");
19967       return -99;
19968     }
19969
19970   if (tcp_out_vrf_id == 0
19971       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
19972     {
19973       errmsg
19974         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19975       return -99;
19976     }
19977
19978   /* Construct the API message */
19979   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
19980
19981   mp->sw_if_index = ntohl (sw_if_index);
19982   mp->is_add = is_add;
19983   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
19984   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
19985   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
19986   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
19987
19988   /* send it... */
19989   S (mp);
19990
19991   /* Wait for a reply... */
19992   W (ret);
19993   return ret;
19994 }
19995
19996 static int
19997 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
19998 {
19999   unformat_input_t *i = vam->input;
20000   vl_api_ipsec_gre_add_del_tunnel_t *mp;
20001   u32 local_sa_id = 0;
20002   u32 remote_sa_id = 0;
20003   ip4_address_t src_address;
20004   ip4_address_t dst_address;
20005   u8 is_add = 1;
20006   int ret;
20007
20008   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20009     {
20010       if (unformat (i, "local_sa %d", &local_sa_id))
20011         ;
20012       else if (unformat (i, "remote_sa %d", &remote_sa_id))
20013         ;
20014       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
20015         ;
20016       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
20017         ;
20018       else if (unformat (i, "del"))
20019         is_add = 0;
20020       else
20021         {
20022           clib_warning ("parse error '%U'", format_unformat_error, i);
20023           return -99;
20024         }
20025     }
20026
20027   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
20028
20029   mp->local_sa_id = ntohl (local_sa_id);
20030   mp->remote_sa_id = ntohl (remote_sa_id);
20031   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
20032   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
20033   mp->is_add = is_add;
20034
20035   S (mp);
20036   W (ret);
20037   return ret;
20038 }
20039
20040 static int
20041 api_punt (vat_main_t * vam)
20042 {
20043   unformat_input_t *i = vam->input;
20044   vl_api_punt_t *mp;
20045   u32 ipv = ~0;
20046   u32 protocol = ~0;
20047   u32 port = ~0;
20048   int is_add = 1;
20049   int ret;
20050
20051   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20052     {
20053       if (unformat (i, "ip %d", &ipv))
20054         ;
20055       else if (unformat (i, "protocol %d", &protocol))
20056         ;
20057       else if (unformat (i, "port %d", &port))
20058         ;
20059       else if (unformat (i, "del"))
20060         is_add = 0;
20061       else
20062         {
20063           clib_warning ("parse error '%U'", format_unformat_error, i);
20064           return -99;
20065         }
20066     }
20067
20068   M (PUNT, mp);
20069
20070   mp->is_add = (u8) is_add;
20071   mp->ipv = (u8) ipv;
20072   mp->l4_protocol = (u8) protocol;
20073   mp->l4_port = htons ((u16) port);
20074
20075   S (mp);
20076   W (ret);
20077   return ret;
20078 }
20079
20080 static void vl_api_ipsec_gre_tunnel_details_t_handler
20081   (vl_api_ipsec_gre_tunnel_details_t * mp)
20082 {
20083   vat_main_t *vam = &vat_main;
20084
20085   print (vam->ofp, "%11d%15U%15U%14d%14d",
20086          ntohl (mp->sw_if_index),
20087          format_ip4_address, &mp->src_address,
20088          format_ip4_address, &mp->dst_address,
20089          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
20090 }
20091
20092 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
20093   (vl_api_ipsec_gre_tunnel_details_t * mp)
20094 {
20095   vat_main_t *vam = &vat_main;
20096   vat_json_node_t *node = NULL;
20097   struct in_addr ip4;
20098
20099   if (VAT_JSON_ARRAY != vam->json_tree.type)
20100     {
20101       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20102       vat_json_init_array (&vam->json_tree);
20103     }
20104   node = vat_json_array_add (&vam->json_tree);
20105
20106   vat_json_init_object (node);
20107   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
20108   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
20109   vat_json_object_add_ip4 (node, "src_address", ip4);
20110   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
20111   vat_json_object_add_ip4 (node, "dst_address", ip4);
20112   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
20113   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
20114 }
20115
20116 static int
20117 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
20118 {
20119   unformat_input_t *i = vam->input;
20120   vl_api_ipsec_gre_tunnel_dump_t *mp;
20121   vl_api_control_ping_t *mp_ping;
20122   u32 sw_if_index;
20123   u8 sw_if_index_set = 0;
20124   int ret;
20125
20126   /* Parse args required to build the message */
20127   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20128     {
20129       if (unformat (i, "sw_if_index %d", &sw_if_index))
20130         sw_if_index_set = 1;
20131       else
20132         break;
20133     }
20134
20135   if (sw_if_index_set == 0)
20136     {
20137       sw_if_index = ~0;
20138     }
20139
20140   if (!vam->json_output)
20141     {
20142       print (vam->ofp, "%11s%15s%15s%14s%14s",
20143              "sw_if_index", "src_address", "dst_address",
20144              "local_sa_id", "remote_sa_id");
20145     }
20146
20147   /* Get list of gre-tunnel interfaces */
20148   M (IPSEC_GRE_TUNNEL_DUMP, mp);
20149
20150   mp->sw_if_index = htonl (sw_if_index);
20151
20152   S (mp);
20153
20154   /* Use a control ping for synchronization */
20155   MPING (CONTROL_PING, mp_ping);
20156   S (mp_ping);
20157
20158   W (ret);
20159   return ret;
20160 }
20161
20162 static int
20163 api_delete_subif (vat_main_t * vam)
20164 {
20165   unformat_input_t *i = vam->input;
20166   vl_api_delete_subif_t *mp;
20167   u32 sw_if_index = ~0;
20168   int ret;
20169
20170   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20171     {
20172       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20173         ;
20174       if (unformat (i, "sw_if_index %d", &sw_if_index))
20175         ;
20176       else
20177         break;
20178     }
20179
20180   if (sw_if_index == ~0)
20181     {
20182       errmsg ("missing sw_if_index");
20183       return -99;
20184     }
20185
20186   /* Construct the API message */
20187   M (DELETE_SUBIF, mp);
20188   mp->sw_if_index = ntohl (sw_if_index);
20189
20190   S (mp);
20191   W (ret);
20192   return ret;
20193 }
20194
20195 #define foreach_pbb_vtr_op      \
20196 _("disable",  L2_VTR_DISABLED)  \
20197 _("pop",  L2_VTR_POP_2)         \
20198 _("push",  L2_VTR_PUSH_2)
20199
20200 static int
20201 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20202 {
20203   unformat_input_t *i = vam->input;
20204   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20205   u32 sw_if_index = ~0, vtr_op = ~0;
20206   u16 outer_tag = ~0;
20207   u8 dmac[6], smac[6];
20208   u8 dmac_set = 0, smac_set = 0;
20209   u16 vlanid = 0;
20210   u32 sid = ~0;
20211   u32 tmp;
20212   int ret;
20213
20214   /* Shut up coverity */
20215   memset (dmac, 0, sizeof (dmac));
20216   memset (smac, 0, sizeof (smac));
20217
20218   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20219     {
20220       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20221         ;
20222       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20223         ;
20224       else if (unformat (i, "vtr_op %d", &vtr_op))
20225         ;
20226 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20227       foreach_pbb_vtr_op
20228 #undef _
20229         else if (unformat (i, "translate_pbb_stag"))
20230         {
20231           if (unformat (i, "%d", &tmp))
20232             {
20233               vtr_op = L2_VTR_TRANSLATE_2_1;
20234               outer_tag = tmp;
20235             }
20236           else
20237             {
20238               errmsg
20239                 ("translate_pbb_stag operation requires outer tag definition");
20240               return -99;
20241             }
20242         }
20243       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20244         dmac_set++;
20245       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20246         smac_set++;
20247       else if (unformat (i, "sid %d", &sid))
20248         ;
20249       else if (unformat (i, "vlanid %d", &tmp))
20250         vlanid = tmp;
20251       else
20252         {
20253           clib_warning ("parse error '%U'", format_unformat_error, i);
20254           return -99;
20255         }
20256     }
20257
20258   if ((sw_if_index == ~0) || (vtr_op == ~0))
20259     {
20260       errmsg ("missing sw_if_index or vtr operation");
20261       return -99;
20262     }
20263   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20264       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20265     {
20266       errmsg
20267         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20268       return -99;
20269     }
20270
20271   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20272   mp->sw_if_index = ntohl (sw_if_index);
20273   mp->vtr_op = ntohl (vtr_op);
20274   mp->outer_tag = ntohs (outer_tag);
20275   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20276   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20277   mp->b_vlanid = ntohs (vlanid);
20278   mp->i_sid = ntohl (sid);
20279
20280   S (mp);
20281   W (ret);
20282   return ret;
20283 }
20284
20285 static int
20286 api_flow_classify_set_interface (vat_main_t * vam)
20287 {
20288   unformat_input_t *i = vam->input;
20289   vl_api_flow_classify_set_interface_t *mp;
20290   u32 sw_if_index;
20291   int sw_if_index_set;
20292   u32 ip4_table_index = ~0;
20293   u32 ip6_table_index = ~0;
20294   u8 is_add = 1;
20295   int ret;
20296
20297   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20298     {
20299       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20300         sw_if_index_set = 1;
20301       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20302         sw_if_index_set = 1;
20303       else if (unformat (i, "del"))
20304         is_add = 0;
20305       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20306         ;
20307       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20308         ;
20309       else
20310         {
20311           clib_warning ("parse error '%U'", format_unformat_error, i);
20312           return -99;
20313         }
20314     }
20315
20316   if (sw_if_index_set == 0)
20317     {
20318       errmsg ("missing interface name or sw_if_index");
20319       return -99;
20320     }
20321
20322   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20323
20324   mp->sw_if_index = ntohl (sw_if_index);
20325   mp->ip4_table_index = ntohl (ip4_table_index);
20326   mp->ip6_table_index = ntohl (ip6_table_index);
20327   mp->is_add = is_add;
20328
20329   S (mp);
20330   W (ret);
20331   return ret;
20332 }
20333
20334 static int
20335 api_flow_classify_dump (vat_main_t * vam)
20336 {
20337   unformat_input_t *i = vam->input;
20338   vl_api_flow_classify_dump_t *mp;
20339   vl_api_control_ping_t *mp_ping;
20340   u8 type = FLOW_CLASSIFY_N_TABLES;
20341   int ret;
20342
20343   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20344     ;
20345   else
20346     {
20347       errmsg ("classify table type must be specified");
20348       return -99;
20349     }
20350
20351   if (!vam->json_output)
20352     {
20353       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20354     }
20355
20356   M (FLOW_CLASSIFY_DUMP, mp);
20357   mp->type = type;
20358   /* send it... */
20359   S (mp);
20360
20361   /* Use a control ping for synchronization */
20362   MPING (CONTROL_PING, mp_ping);
20363   S (mp_ping);
20364
20365   /* Wait for a reply... */
20366   W (ret);
20367   return ret;
20368 }
20369
20370 static int
20371 api_feature_enable_disable (vat_main_t * vam)
20372 {
20373   unformat_input_t *i = vam->input;
20374   vl_api_feature_enable_disable_t *mp;
20375   u8 *arc_name = 0;
20376   u8 *feature_name = 0;
20377   u32 sw_if_index = ~0;
20378   u8 enable = 1;
20379   int ret;
20380
20381   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20382     {
20383       if (unformat (i, "arc_name %s", &arc_name))
20384         ;
20385       else if (unformat (i, "feature_name %s", &feature_name))
20386         ;
20387       else
20388         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20389         ;
20390       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20391         ;
20392       else if (unformat (i, "disable"))
20393         enable = 0;
20394       else
20395         break;
20396     }
20397
20398   if (arc_name == 0)
20399     {
20400       errmsg ("missing arc name");
20401       return -99;
20402     }
20403   if (vec_len (arc_name) > 63)
20404     {
20405       errmsg ("arc name too long");
20406     }
20407
20408   if (feature_name == 0)
20409     {
20410       errmsg ("missing feature name");
20411       return -99;
20412     }
20413   if (vec_len (feature_name) > 63)
20414     {
20415       errmsg ("feature name too long");
20416     }
20417
20418   if (sw_if_index == ~0)
20419     {
20420       errmsg ("missing interface name or sw_if_index");
20421       return -99;
20422     }
20423
20424   /* Construct the API message */
20425   M (FEATURE_ENABLE_DISABLE, mp);
20426   mp->sw_if_index = ntohl (sw_if_index);
20427   mp->enable = enable;
20428   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20429   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20430   vec_free (arc_name);
20431   vec_free (feature_name);
20432
20433   S (mp);
20434   W (ret);
20435   return ret;
20436 }
20437
20438 static int
20439 api_sw_interface_tag_add_del (vat_main_t * vam)
20440 {
20441   unformat_input_t *i = vam->input;
20442   vl_api_sw_interface_tag_add_del_t *mp;
20443   u32 sw_if_index = ~0;
20444   u8 *tag = 0;
20445   u8 enable = 1;
20446   int ret;
20447
20448   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20449     {
20450       if (unformat (i, "tag %s", &tag))
20451         ;
20452       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20453         ;
20454       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20455         ;
20456       else if (unformat (i, "del"))
20457         enable = 0;
20458       else
20459         break;
20460     }
20461
20462   if (sw_if_index == ~0)
20463     {
20464       errmsg ("missing interface name or sw_if_index");
20465       return -99;
20466     }
20467
20468   if (enable && (tag == 0))
20469     {
20470       errmsg ("no tag specified");
20471       return -99;
20472     }
20473
20474   /* Construct the API message */
20475   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20476   mp->sw_if_index = ntohl (sw_if_index);
20477   mp->is_add = enable;
20478   if (enable)
20479     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20480   vec_free (tag);
20481
20482   S (mp);
20483   W (ret);
20484   return ret;
20485 }
20486
20487 static void vl_api_l2_xconnect_details_t_handler
20488   (vl_api_l2_xconnect_details_t * mp)
20489 {
20490   vat_main_t *vam = &vat_main;
20491
20492   print (vam->ofp, "%15d%15d",
20493          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20494 }
20495
20496 static void vl_api_l2_xconnect_details_t_handler_json
20497   (vl_api_l2_xconnect_details_t * mp)
20498 {
20499   vat_main_t *vam = &vat_main;
20500   vat_json_node_t *node = NULL;
20501
20502   if (VAT_JSON_ARRAY != vam->json_tree.type)
20503     {
20504       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20505       vat_json_init_array (&vam->json_tree);
20506     }
20507   node = vat_json_array_add (&vam->json_tree);
20508
20509   vat_json_init_object (node);
20510   vat_json_object_add_uint (node, "rx_sw_if_index",
20511                             ntohl (mp->rx_sw_if_index));
20512   vat_json_object_add_uint (node, "tx_sw_if_index",
20513                             ntohl (mp->tx_sw_if_index));
20514 }
20515
20516 static int
20517 api_l2_xconnect_dump (vat_main_t * vam)
20518 {
20519   vl_api_l2_xconnect_dump_t *mp;
20520   vl_api_control_ping_t *mp_ping;
20521   int ret;
20522
20523   if (!vam->json_output)
20524     {
20525       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20526     }
20527
20528   M (L2_XCONNECT_DUMP, mp);
20529
20530   S (mp);
20531
20532   /* Use a control ping for synchronization */
20533   MPING (CONTROL_PING, mp_ping);
20534   S (mp_ping);
20535
20536   W (ret);
20537   return ret;
20538 }
20539
20540 static int
20541 api_sw_interface_set_mtu (vat_main_t * vam)
20542 {
20543   unformat_input_t *i = vam->input;
20544   vl_api_sw_interface_set_mtu_t *mp;
20545   u32 sw_if_index = ~0;
20546   u32 mtu = 0;
20547   int ret;
20548
20549   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20550     {
20551       if (unformat (i, "mtu %d", &mtu))
20552         ;
20553       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20554         ;
20555       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20556         ;
20557       else
20558         break;
20559     }
20560
20561   if (sw_if_index == ~0)
20562     {
20563       errmsg ("missing interface name or sw_if_index");
20564       return -99;
20565     }
20566
20567   if (mtu == 0)
20568     {
20569       errmsg ("no mtu specified");
20570       return -99;
20571     }
20572
20573   /* Construct the API message */
20574   M (SW_INTERFACE_SET_MTU, mp);
20575   mp->sw_if_index = ntohl (sw_if_index);
20576   mp->mtu = ntohs ((u16) mtu);
20577
20578   S (mp);
20579   W (ret);
20580   return ret;
20581 }
20582
20583 static int
20584 api_p2p_ethernet_add (vat_main_t * vam)
20585 {
20586   unformat_input_t *i = vam->input;
20587   vl_api_p2p_ethernet_add_t *mp;
20588   u32 parent_if_index = ~0;
20589   u32 sub_id = ~0;
20590   u8 remote_mac[6];
20591   u8 mac_set = 0;
20592   int ret;
20593
20594   memset (remote_mac, 0, sizeof (remote_mac));
20595   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20596     {
20597       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20598         ;
20599       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20600         ;
20601       else
20602         if (unformat
20603             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20604         mac_set++;
20605       else if (unformat (i, "sub_id %d", &sub_id))
20606         ;
20607       else
20608         {
20609           clib_warning ("parse error '%U'", format_unformat_error, i);
20610           return -99;
20611         }
20612     }
20613
20614   if (parent_if_index == ~0)
20615     {
20616       errmsg ("missing interface name or sw_if_index");
20617       return -99;
20618     }
20619   if (mac_set == 0)
20620     {
20621       errmsg ("missing remote mac address");
20622       return -99;
20623     }
20624   if (sub_id == ~0)
20625     {
20626       errmsg ("missing sub-interface id");
20627       return -99;
20628     }
20629
20630   M (P2P_ETHERNET_ADD, mp);
20631   mp->parent_if_index = ntohl (parent_if_index);
20632   mp->subif_id = ntohl (sub_id);
20633   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20634
20635   S (mp);
20636   W (ret);
20637   return ret;
20638 }
20639
20640 static int
20641 api_p2p_ethernet_del (vat_main_t * vam)
20642 {
20643   unformat_input_t *i = vam->input;
20644   vl_api_p2p_ethernet_del_t *mp;
20645   u32 parent_if_index = ~0;
20646   u8 remote_mac[6];
20647   u8 mac_set = 0;
20648   int ret;
20649
20650   memset (remote_mac, 0, sizeof (remote_mac));
20651   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20652     {
20653       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20654         ;
20655       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20656         ;
20657       else
20658         if (unformat
20659             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20660         mac_set++;
20661       else
20662         {
20663           clib_warning ("parse error '%U'", format_unformat_error, i);
20664           return -99;
20665         }
20666     }
20667
20668   if (parent_if_index == ~0)
20669     {
20670       errmsg ("missing interface name or sw_if_index");
20671       return -99;
20672     }
20673   if (mac_set == 0)
20674     {
20675       errmsg ("missing remote mac address");
20676       return -99;
20677     }
20678
20679   M (P2P_ETHERNET_DEL, mp);
20680   mp->parent_if_index = ntohl (parent_if_index);
20681   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20682
20683   S (mp);
20684   W (ret);
20685   return ret;
20686 }
20687
20688 static int
20689 api_lldp_config (vat_main_t * vam)
20690 {
20691   unformat_input_t *i = vam->input;
20692   vl_api_lldp_config_t *mp;
20693   int tx_hold = 0;
20694   int tx_interval = 0;
20695   u8 *sys_name = NULL;
20696   int ret;
20697
20698   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20699     {
20700       if (unformat (i, "system-name %s", &sys_name))
20701         ;
20702       else if (unformat (i, "tx-hold %d", &tx_hold))
20703         ;
20704       else if (unformat (i, "tx-interval %d", &tx_interval))
20705         ;
20706       else
20707         {
20708           clib_warning ("parse error '%U'", format_unformat_error, i);
20709           return -99;
20710         }
20711     }
20712
20713   vec_add1 (sys_name, 0);
20714
20715   M (LLDP_CONFIG, mp);
20716   mp->tx_hold = htonl (tx_hold);
20717   mp->tx_interval = htonl (tx_interval);
20718   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20719   vec_free (sys_name);
20720
20721   S (mp);
20722   W (ret);
20723   return ret;
20724 }
20725
20726 static int
20727 api_sw_interface_set_lldp (vat_main_t * vam)
20728 {
20729   unformat_input_t *i = vam->input;
20730   vl_api_sw_interface_set_lldp_t *mp;
20731   u32 sw_if_index = ~0;
20732   u32 enable = 1;
20733   u8 *port_desc = NULL, *mgmt_oid = NULL;
20734   ip4_address_t ip4_addr;
20735   ip6_address_t ip6_addr;
20736   int ret;
20737
20738   memset (&ip4_addr, 0, sizeof (ip4_addr));
20739   memset (&ip6_addr, 0, sizeof (ip6_addr));
20740
20741   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20742     {
20743       if (unformat (i, "disable"))
20744         enable = 0;
20745       else
20746         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20747         ;
20748       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20749         ;
20750       else if (unformat (i, "port-desc %s", &port_desc))
20751         ;
20752       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20753         ;
20754       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20755         ;
20756       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20757         ;
20758       else
20759         break;
20760     }
20761
20762   if (sw_if_index == ~0)
20763     {
20764       errmsg ("missing interface name or sw_if_index");
20765       return -99;
20766     }
20767
20768   /* Construct the API message */
20769   vec_add1 (port_desc, 0);
20770   vec_add1 (mgmt_oid, 0);
20771   M (SW_INTERFACE_SET_LLDP, mp);
20772   mp->sw_if_index = ntohl (sw_if_index);
20773   mp->enable = enable;
20774   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20775   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20776   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20777   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20778   vec_free (port_desc);
20779   vec_free (mgmt_oid);
20780
20781   S (mp);
20782   W (ret);
20783   return ret;
20784 }
20785
20786 static int
20787 api_tcp_configure_src_addresses (vat_main_t * vam)
20788 {
20789   vl_api_tcp_configure_src_addresses_t *mp;
20790   unformat_input_t *i = vam->input;
20791   ip4_address_t v4first, v4last;
20792   ip6_address_t v6first, v6last;
20793   u8 range_set = 0;
20794   u32 vrf_id = 0;
20795   int ret;
20796
20797   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20798     {
20799       if (unformat (i, "%U - %U",
20800                     unformat_ip4_address, &v4first,
20801                     unformat_ip4_address, &v4last))
20802         {
20803           if (range_set)
20804             {
20805               errmsg ("one range per message (range already set)");
20806               return -99;
20807             }
20808           range_set = 1;
20809         }
20810       else if (unformat (i, "%U - %U",
20811                          unformat_ip6_address, &v6first,
20812                          unformat_ip6_address, &v6last))
20813         {
20814           if (range_set)
20815             {
20816               errmsg ("one range per message (range already set)");
20817               return -99;
20818             }
20819           range_set = 2;
20820         }
20821       else if (unformat (i, "vrf %d", &vrf_id))
20822         ;
20823       else
20824         break;
20825     }
20826
20827   if (range_set == 0)
20828     {
20829       errmsg ("address range not set");
20830       return -99;
20831     }
20832
20833   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20834   mp->vrf_id = ntohl (vrf_id);
20835   /* ipv6? */
20836   if (range_set == 2)
20837     {
20838       mp->is_ipv6 = 1;
20839       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20840       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20841     }
20842   else
20843     {
20844       mp->is_ipv6 = 0;
20845       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20846       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20847     }
20848   S (mp);
20849   W (ret);
20850   return ret;
20851 }
20852
20853 static int
20854 api_app_namespace_add_del (vat_main_t * vam)
20855 {
20856   vl_api_app_namespace_add_del_t *mp;
20857   unformat_input_t *i = vam->input;
20858   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
20859   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
20860   u64 secret;
20861   int ret;
20862
20863   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20864     {
20865       if (unformat (i, "id %_%v%_", &ns_id))
20866         ;
20867       else if (unformat (i, "secret %lu", &secret))
20868         secret_set = 1;
20869       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20870         sw_if_index_set = 1;
20871       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
20872         ;
20873       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
20874         ;
20875       else
20876         break;
20877     }
20878   if (!ns_id || !secret_set || !sw_if_index_set)
20879     {
20880       errmsg ("namespace id, secret and sw_if_index must be set");
20881       return -99;
20882     }
20883   if (vec_len (ns_id) > 64)
20884     {
20885       errmsg ("namespace id too long");
20886       return -99;
20887     }
20888   M (APP_NAMESPACE_ADD_DEL, mp);
20889
20890   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
20891   mp->namespace_id_len = vec_len (ns_id);
20892   mp->secret = secret;
20893   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20894   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
20895   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
20896   vec_free (ns_id);
20897   S (mp);
20898   W (ret);
20899   return ret;
20900 }
20901
20902 static int
20903 api_memfd_segment_create (vat_main_t * vam)
20904 {
20905   unformat_input_t *i = vam->input;
20906   vl_api_memfd_segment_create_t *mp;
20907   u64 size = 64 << 20;
20908   int ret;
20909
20910 #if VPP_API_TEST_BUILTIN == 1
20911   errmsg ("memfd_segment_create (builtin) not supported");
20912   return -99;
20913 #endif
20914
20915   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20916     {
20917       if (unformat (i, "size %U", unformat_memory_size, &size))
20918         ;
20919       else
20920         break;
20921     }
20922
20923   M (MEMFD_SEGMENT_CREATE, mp);
20924   mp->requested_size = size;
20925   S (mp);
20926   W (ret);
20927   return ret;
20928 }
20929
20930 static int
20931 api_dns_enable_disable (vat_main_t * vam)
20932 {
20933   unformat_input_t *line_input = vam->input;
20934   vl_api_dns_enable_disable_t *mp;
20935   u8 enable_disable = 1;
20936   int ret;
20937
20938   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20939     {
20940       if (unformat (line_input, "disable"))
20941         enable_disable = 0;
20942       if (unformat (line_input, "enable"))
20943         enable_disable = 1;
20944       else
20945         break;
20946     }
20947
20948   /* Construct the API message */
20949   M (DNS_ENABLE_DISABLE, mp);
20950   mp->enable = enable_disable;
20951
20952   /* send it... */
20953   S (mp);
20954   /* Wait for the reply */
20955   W (ret);
20956   return ret;
20957 }
20958
20959 static int
20960 api_dns_resolve_name (vat_main_t * vam)
20961 {
20962   unformat_input_t *line_input = vam->input;
20963   vl_api_dns_resolve_name_t *mp;
20964   u8 *name = 0;
20965   int ret;
20966
20967   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20968     {
20969       if (unformat (line_input, "%s", &name))
20970         ;
20971       else
20972         break;
20973     }
20974
20975   if (vec_len (name) > 127)
20976     {
20977       errmsg ("name too long");
20978       return -99;
20979     }
20980
20981   /* Construct the API message */
20982   M (DNS_RESOLVE_NAME, mp);
20983   memcpy (mp->name, name, vec_len (name));
20984   vec_free (name);
20985
20986   /* send it... */
20987   S (mp);
20988   /* Wait for the reply */
20989   W (ret);
20990   return ret;
20991 }
20992
20993 static int
20994 api_dns_name_server_add_del (vat_main_t * vam)
20995 {
20996   unformat_input_t *i = vam->input;
20997   vl_api_dns_name_server_add_del_t *mp;
20998   u8 is_add = 1;
20999   ip6_address_t ip6_server;
21000   ip4_address_t ip4_server;
21001   int ip6_set = 0;
21002   int ip4_set = 0;
21003   int ret = 0;
21004
21005   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
21006     {
21007       if (unformat (i, "%U", unformat_ip6_address, &ip6_server))
21008         ip6_set = 1;
21009       else if (unformat (i, "%U", unformat_ip4_address, &ip4_server))
21010         ip4_set = 1;
21011       else if (unformat (i, "del"))
21012         is_add = 0;
21013       else
21014         {
21015           clib_warning ("parse error '%U'", format_unformat_error, i);
21016           return -99;
21017         }
21018     }
21019
21020   if (ip4_set && ip6_set)
21021     {
21022       errmsg ("Only one server address allowed per message");
21023       return -99;
21024     }
21025   if ((ip4_set + ip6_set) == 0)
21026     {
21027       errmsg ("Server address required");
21028       return -99;
21029     }
21030
21031   /* Construct the API message */
21032   M (DNS_NAME_SERVER_ADD_DEL, mp);
21033
21034   if (ip6_set)
21035     {
21036       memcpy (mp->server_address, &ip6_server, sizeof (ip6_address_t));
21037       mp->is_ip6 = 1;
21038     }
21039   else
21040     {
21041       memcpy (mp->server_address, &ip4_server, sizeof (ip4_address_t));
21042       mp->is_ip6 = 0;
21043     }
21044
21045   mp->is_add = is_add;
21046
21047   /* send it... */
21048   S (mp);
21049
21050   /* Wait for a reply, return good/bad news  */
21051   W (ret);
21052   return ret;
21053 }
21054
21055
21056 static int
21057 q_or_quit (vat_main_t * vam)
21058 {
21059 #if VPP_API_TEST_BUILTIN == 0
21060   longjmp (vam->jump_buf, 1);
21061 #endif
21062   return 0;                     /* not so much */
21063 }
21064
21065 static int
21066 q (vat_main_t * vam)
21067 {
21068   return q_or_quit (vam);
21069 }
21070
21071 static int
21072 quit (vat_main_t * vam)
21073 {
21074   return q_or_quit (vam);
21075 }
21076
21077 static int
21078 comment (vat_main_t * vam)
21079 {
21080   return 0;
21081 }
21082
21083 static int
21084 cmd_cmp (void *a1, void *a2)
21085 {
21086   u8 **c1 = a1;
21087   u8 **c2 = a2;
21088
21089   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21090 }
21091
21092 static int
21093 help (vat_main_t * vam)
21094 {
21095   u8 **cmds = 0;
21096   u8 *name = 0;
21097   hash_pair_t *p;
21098   unformat_input_t *i = vam->input;
21099   int j;
21100
21101   if (unformat (i, "%s", &name))
21102     {
21103       uword *hs;
21104
21105       vec_add1 (name, 0);
21106
21107       hs = hash_get_mem (vam->help_by_name, name);
21108       if (hs)
21109         print (vam->ofp, "usage: %s %s", name, hs[0]);
21110       else
21111         print (vam->ofp, "No such msg / command '%s'", name);
21112       vec_free (name);
21113       return 0;
21114     }
21115
21116   print (vam->ofp, "Help is available for the following:");
21117
21118     /* *INDENT-OFF* */
21119     hash_foreach_pair (p, vam->function_by_name,
21120     ({
21121       vec_add1 (cmds, (u8 *)(p->key));
21122     }));
21123     /* *INDENT-ON* */
21124
21125   vec_sort_with_function (cmds, cmd_cmp);
21126
21127   for (j = 0; j < vec_len (cmds); j++)
21128     print (vam->ofp, "%s", cmds[j]);
21129
21130   vec_free (cmds);
21131   return 0;
21132 }
21133
21134 static int
21135 set (vat_main_t * vam)
21136 {
21137   u8 *name = 0, *value = 0;
21138   unformat_input_t *i = vam->input;
21139
21140   if (unformat (i, "%s", &name))
21141     {
21142       /* The input buffer is a vector, not a string. */
21143       value = vec_dup (i->buffer);
21144       vec_delete (value, i->index, 0);
21145       /* Almost certainly has a trailing newline */
21146       if (value[vec_len (value) - 1] == '\n')
21147         value[vec_len (value) - 1] = 0;
21148       /* Make sure it's a proper string, one way or the other */
21149       vec_add1 (value, 0);
21150       (void) clib_macro_set_value (&vam->macro_main,
21151                                    (char *) name, (char *) value);
21152     }
21153   else
21154     errmsg ("usage: set <name> <value>");
21155
21156   vec_free (name);
21157   vec_free (value);
21158   return 0;
21159 }
21160
21161 static int
21162 unset (vat_main_t * vam)
21163 {
21164   u8 *name = 0;
21165
21166   if (unformat (vam->input, "%s", &name))
21167     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21168       errmsg ("unset: %s wasn't set", name);
21169   vec_free (name);
21170   return 0;
21171 }
21172
21173 typedef struct
21174 {
21175   u8 *name;
21176   u8 *value;
21177 } macro_sort_t;
21178
21179
21180 static int
21181 macro_sort_cmp (void *a1, void *a2)
21182 {
21183   macro_sort_t *s1 = a1;
21184   macro_sort_t *s2 = a2;
21185
21186   return strcmp ((char *) (s1->name), (char *) (s2->name));
21187 }
21188
21189 static int
21190 dump_macro_table (vat_main_t * vam)
21191 {
21192   macro_sort_t *sort_me = 0, *sm;
21193   int i;
21194   hash_pair_t *p;
21195
21196     /* *INDENT-OFF* */
21197     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21198     ({
21199       vec_add2 (sort_me, sm, 1);
21200       sm->name = (u8 *)(p->key);
21201       sm->value = (u8 *) (p->value[0]);
21202     }));
21203     /* *INDENT-ON* */
21204
21205   vec_sort_with_function (sort_me, macro_sort_cmp);
21206
21207   if (vec_len (sort_me))
21208     print (vam->ofp, "%-15s%s", "Name", "Value");
21209   else
21210     print (vam->ofp, "The macro table is empty...");
21211
21212   for (i = 0; i < vec_len (sort_me); i++)
21213     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21214   return 0;
21215 }
21216
21217 static int
21218 dump_node_table (vat_main_t * vam)
21219 {
21220   int i, j;
21221   vlib_node_t *node, *next_node;
21222
21223   if (vec_len (vam->graph_nodes) == 0)
21224     {
21225       print (vam->ofp, "Node table empty, issue get_node_graph...");
21226       return 0;
21227     }
21228
21229   for (i = 0; i < vec_len (vam->graph_nodes); i++)
21230     {
21231       node = vam->graph_nodes[i];
21232       print (vam->ofp, "[%d] %s", i, node->name);
21233       for (j = 0; j < vec_len (node->next_nodes); j++)
21234         {
21235           if (node->next_nodes[j] != ~0)
21236             {
21237               next_node = vam->graph_nodes[node->next_nodes[j]];
21238               print (vam->ofp, "  [%d] %s", j, next_node->name);
21239             }
21240         }
21241     }
21242   return 0;
21243 }
21244
21245 static int
21246 value_sort_cmp (void *a1, void *a2)
21247 {
21248   name_sort_t *n1 = a1;
21249   name_sort_t *n2 = a2;
21250
21251   if (n1->value < n2->value)
21252     return -1;
21253   if (n1->value > n2->value)
21254     return 1;
21255   return 0;
21256 }
21257
21258
21259 static int
21260 dump_msg_api_table (vat_main_t * vam)
21261 {
21262   api_main_t *am = &api_main;
21263   name_sort_t *nses = 0, *ns;
21264   hash_pair_t *hp;
21265   int i;
21266
21267   /* *INDENT-OFF* */
21268   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21269   ({
21270     vec_add2 (nses, ns, 1);
21271     ns->name = (u8 *)(hp->key);
21272     ns->value = (u32) hp->value[0];
21273   }));
21274   /* *INDENT-ON* */
21275
21276   vec_sort_with_function (nses, value_sort_cmp);
21277
21278   for (i = 0; i < vec_len (nses); i++)
21279     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21280   vec_free (nses);
21281   return 0;
21282 }
21283
21284 static int
21285 get_msg_id (vat_main_t * vam)
21286 {
21287   u8 *name_and_crc;
21288   u32 message_index;
21289
21290   if (unformat (vam->input, "%s", &name_and_crc))
21291     {
21292       message_index = vl_api_get_msg_index (name_and_crc);
21293       if (message_index == ~0)
21294         {
21295           print (vam->ofp, " '%s' not found", name_and_crc);
21296           return 0;
21297         }
21298       print (vam->ofp, " '%s' has message index %d",
21299              name_and_crc, message_index);
21300       return 0;
21301     }
21302   errmsg ("name_and_crc required...");
21303   return 0;
21304 }
21305
21306 static int
21307 search_node_table (vat_main_t * vam)
21308 {
21309   unformat_input_t *line_input = vam->input;
21310   u8 *node_to_find;
21311   int j;
21312   vlib_node_t *node, *next_node;
21313   uword *p;
21314
21315   if (vam->graph_node_index_by_name == 0)
21316     {
21317       print (vam->ofp, "Node table empty, issue get_node_graph...");
21318       return 0;
21319     }
21320
21321   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21322     {
21323       if (unformat (line_input, "%s", &node_to_find))
21324         {
21325           vec_add1 (node_to_find, 0);
21326           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21327           if (p == 0)
21328             {
21329               print (vam->ofp, "%s not found...", node_to_find);
21330               goto out;
21331             }
21332           node = vam->graph_nodes[p[0]];
21333           print (vam->ofp, "[%d] %s", p[0], node->name);
21334           for (j = 0; j < vec_len (node->next_nodes); j++)
21335             {
21336               if (node->next_nodes[j] != ~0)
21337                 {
21338                   next_node = vam->graph_nodes[node->next_nodes[j]];
21339                   print (vam->ofp, "  [%d] %s", j, next_node->name);
21340                 }
21341             }
21342         }
21343
21344       else
21345         {
21346           clib_warning ("parse error '%U'", format_unformat_error,
21347                         line_input);
21348           return -99;
21349         }
21350
21351     out:
21352       vec_free (node_to_find);
21353
21354     }
21355
21356   return 0;
21357 }
21358
21359
21360 static int
21361 script (vat_main_t * vam)
21362 {
21363 #if (VPP_API_TEST_BUILTIN==0)
21364   u8 *s = 0;
21365   char *save_current_file;
21366   unformat_input_t save_input;
21367   jmp_buf save_jump_buf;
21368   u32 save_line_number;
21369
21370   FILE *new_fp, *save_ifp;
21371
21372   if (unformat (vam->input, "%s", &s))
21373     {
21374       new_fp = fopen ((char *) s, "r");
21375       if (new_fp == 0)
21376         {
21377           errmsg ("Couldn't open script file %s", s);
21378           vec_free (s);
21379           return -99;
21380         }
21381     }
21382   else
21383     {
21384       errmsg ("Missing script name");
21385       return -99;
21386     }
21387
21388   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
21389   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
21390   save_ifp = vam->ifp;
21391   save_line_number = vam->input_line_number;
21392   save_current_file = (char *) vam->current_file;
21393
21394   vam->input_line_number = 0;
21395   vam->ifp = new_fp;
21396   vam->current_file = s;
21397   do_one_file (vam);
21398
21399   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
21400   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
21401   vam->ifp = save_ifp;
21402   vam->input_line_number = save_line_number;
21403   vam->current_file = (u8 *) save_current_file;
21404   vec_free (s);
21405
21406   return 0;
21407 #else
21408   clib_warning ("use the exec command...");
21409   return -99;
21410 #endif
21411 }
21412
21413 static int
21414 echo (vat_main_t * vam)
21415 {
21416   print (vam->ofp, "%v", vam->input->buffer);
21417   return 0;
21418 }
21419
21420 /* List of API message constructors, CLI names map to api_xxx */
21421 #define foreach_vpe_api_msg                                             \
21422 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
21423 _(sw_interface_dump,"")                                                 \
21424 _(sw_interface_set_flags,                                               \
21425   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
21426 _(sw_interface_add_del_address,                                         \
21427   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
21428 _(sw_interface_set_table,                                               \
21429   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
21430 _(sw_interface_set_mpls_enable,                                         \
21431   "<intfc> | sw_if_index [disable | dis]")                              \
21432 _(sw_interface_set_vpath,                                               \
21433   "<intfc> | sw_if_index <id> enable | disable")                        \
21434 _(sw_interface_set_vxlan_bypass,                                        \
21435   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21436 _(sw_interface_set_geneve_bypass,                                       \
21437   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21438 _(sw_interface_set_l2_xconnect,                                         \
21439   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21440   "enable | disable")                                                   \
21441 _(sw_interface_set_l2_bridge,                                           \
21442   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
21443   "[shg <split-horizon-group>] [bvi]\n"                                 \
21444   "enable | disable")                                                   \
21445 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
21446 _(bridge_domain_add_del,                                                \
21447   "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") \
21448 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
21449 _(l2fib_add_del,                                                        \
21450   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
21451 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
21452 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
21453 _(l2_flags,                                                             \
21454   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21455 _(bridge_flags,                                                         \
21456   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21457 _(tap_connect,                                                          \
21458   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
21459 _(tap_modify,                                                           \
21460   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
21461 _(tap_delete,                                                           \
21462   "<vpp-if-name> | sw_if_index <id>")                                   \
21463 _(sw_interface_tap_dump, "")                                            \
21464 _(ip_table_add_del,                                                     \
21465   "table-id <n> [ipv6]\n")                                              \
21466 _(ip_add_del_route,                                                     \
21467   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
21468   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
21469   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
21470   "[multipath] [count <n>]")                                            \
21471 _(ip_mroute_add_del,                                                    \
21472   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
21473   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
21474 _(mpls_table_add_del,                                                   \
21475   "table-id <n>\n")                                                     \
21476 _(mpls_route_add_del,                                                   \
21477   "<label> <eos> via <addr> [table-id <n>]\n"                           \
21478   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
21479   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
21480   "[multipath] [count <n>]")                                            \
21481 _(mpls_ip_bind_unbind,                                                  \
21482   "<label> <addr/len>")                                                 \
21483 _(mpls_tunnel_add_del,                                                  \
21484   " via <addr> [table-id <n>]\n"                                        \
21485   "sw_if_index <id>] [l2]  [del]")                                      \
21486 _(proxy_arp_add_del,                                                    \
21487   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
21488 _(proxy_arp_intfc_enable_disable,                                       \
21489   "<intfc> | sw_if_index <id> enable | disable")                        \
21490 _(sw_interface_set_unnumbered,                                          \
21491   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
21492 _(ip_neighbor_add_del,                                                  \
21493   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
21494   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
21495 _(reset_vrf, "vrf <id> [ipv6]")                                         \
21496 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
21497 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
21498   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
21499   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
21500   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
21501 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
21502 _(reset_fib, "vrf <n> [ipv6]")                                          \
21503 _(dhcp_proxy_config,                                                    \
21504   "svr <v46-address> src <v46-address>\n"                               \
21505    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
21506 _(dhcp_proxy_set_vss,                                                   \
21507   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
21508 _(dhcp_proxy_dump, "ip6")                                               \
21509 _(dhcp_client_config,                                                   \
21510   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
21511 _(set_ip_flow_hash,                                                     \
21512   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
21513 _(sw_interface_ip6_enable_disable,                                      \
21514   "<intfc> | sw_if_index <id> enable | disable")                        \
21515 _(sw_interface_ip6_set_link_local_address,                              \
21516   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
21517 _(ip6nd_proxy_add_del,                                                  \
21518   "<intfc> | sw_if_index <id> <ip6-address>")                           \
21519 _(ip6nd_proxy_dump, "")                                                 \
21520 _(sw_interface_ip6nd_ra_prefix,                                         \
21521   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
21522   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
21523   "[nolink] [isno]")                                                    \
21524 _(sw_interface_ip6nd_ra_config,                                         \
21525   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
21526   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
21527   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
21528 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
21529 _(l2_patch_add_del,                                                     \
21530   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21531   "enable | disable")                                                   \
21532 _(sr_localsid_add_del,                                                  \
21533   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
21534   "fib-table <num> (end.psp) sw_if_index <num>")                        \
21535 _(classify_add_del_table,                                               \
21536   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
21537   " [del] [del-chain] mask <mask-value>\n"                              \
21538   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
21539   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
21540 _(classify_add_del_session,                                             \
21541   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
21542   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
21543   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
21544   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
21545 _(classify_set_interface_ip_table,                                      \
21546   "<intfc> | sw_if_index <nn> table <nn>")                              \
21547 _(classify_set_interface_l2_tables,                                     \
21548   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21549   "  [other-table <nn>]")                                               \
21550 _(get_node_index, "node <node-name")                                    \
21551 _(add_node_next, "node <node-name> next <next-node-name>")              \
21552 _(l2tpv3_create_tunnel,                                                 \
21553   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
21554   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
21555   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
21556 _(l2tpv3_set_tunnel_cookies,                                            \
21557   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
21558   "[new_remote_cookie <nn>]\n")                                         \
21559 _(l2tpv3_interface_enable_disable,                                      \
21560   "<intfc> | sw_if_index <nn> enable | disable")                        \
21561 _(l2tpv3_set_lookup_key,                                                \
21562   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
21563 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
21564 _(vxlan_add_del_tunnel,                                                 \
21565   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21566   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21567   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21568 _(geneve_add_del_tunnel,                                                \
21569   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21570   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21571   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21572 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
21573 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
21574 _(gre_add_del_tunnel,                                                   \
21575   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
21576 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
21577 _(l2_fib_clear_table, "")                                               \
21578 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
21579 _(l2_interface_vlan_tag_rewrite,                                        \
21580   "<intfc> | sw_if_index <nn> \n"                                       \
21581   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
21582   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
21583 _(create_vhost_user_if,                                                 \
21584         "socket <filename> [server] [renumber <dev_instance>] "         \
21585         "[mac <mac_address>]")                                          \
21586 _(modify_vhost_user_if,                                                 \
21587         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
21588         "[server] [renumber <dev_instance>]")                           \
21589 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
21590 _(sw_interface_vhost_user_dump, "")                                     \
21591 _(show_version, "")                                                     \
21592 _(vxlan_gpe_add_del_tunnel,                                             \
21593   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
21594   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21595   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
21596   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
21597 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
21598 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
21599 _(interface_name_renumber,                                              \
21600   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
21601 _(input_acl_set_interface,                                              \
21602   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21603   "  [l2-table <nn>] [del]")                                            \
21604 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
21605 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
21606 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
21607 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
21608 _(ip_dump, "ipv4 | ipv6")                                               \
21609 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
21610 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
21611   "  spid_id <n> ")                                                     \
21612 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
21613   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
21614   "  integ_alg <alg> integ_key <hex>")                                  \
21615 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
21616   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
21617   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
21618   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
21619 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
21620 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
21621   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
21622   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
21623   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
21624 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
21625 _(ipsec_tunnel_if_set_key, "<intfc> <local|remote> <crypto|integ>\n"    \
21626   "  <alg> <hex>\n")                                                    \
21627 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
21628 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
21629   "(auth_data 0x<data> | auth_data <data>)")                            \
21630 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
21631   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
21632 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
21633   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
21634   "(local|remote)")                                                     \
21635 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
21636 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
21637 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
21638 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
21639 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
21640 _(ikev2_initiate_sa_init, "<profile_name>")                             \
21641 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
21642 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
21643 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
21644 _(delete_loopback,"sw_if_index <nn>")                                   \
21645 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
21646 _(map_add_domain,                                                       \
21647   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
21648   "ip6-src <ip6addr> "                                                  \
21649   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
21650 _(map_del_domain, "index <n>")                                          \
21651 _(map_add_del_rule,                                                     \
21652   "index <n> psid <n> dst <ip6addr> [del]")                             \
21653 _(map_domain_dump, "")                                                  \
21654 _(map_rule_dump, "index <map-domain>")                                  \
21655 _(want_interface_events,  "enable|disable")                             \
21656 _(want_stats,"enable|disable")                                          \
21657 _(get_first_msg_id, "client <name>")                                    \
21658 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
21659 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
21660   "fib-id <nn> [ip4][ip6][default]")                                    \
21661 _(get_node_graph, " ")                                                  \
21662 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
21663 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
21664 _(ioam_disable, "")                                                     \
21665 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
21666                             " sw_if_index <sw_if_index> p <priority> "  \
21667                             "w <weight>] [del]")                        \
21668 _(one_add_del_locator, "locator-set <locator_name> "                    \
21669                         "iface <intf> | sw_if_index <sw_if_index> "     \
21670                         "p <priority> w <weight> [del]")                \
21671 _(one_add_del_local_eid,"vni <vni> eid "                                \
21672                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21673                          "locator-set <locator_name> [del]"             \
21674                          "[key-id sha1|sha256 secret-key <secret-key>]")\
21675 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
21676 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
21677 _(one_enable_disable, "enable|disable")                                 \
21678 _(one_map_register_enable_disable, "enable|disable")                    \
21679 _(one_map_register_fallback_threshold, "<value>")                       \
21680 _(one_rloc_probe_enable_disable, "enable|disable")                      \
21681 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
21682                                "[seid <seid>] "                         \
21683                                "rloc <locator> p <prio> "               \
21684                                "w <weight> [rloc <loc> ... ] "          \
21685                                "action <action> [del-all]")             \
21686 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
21687                           "<local-eid>")                                \
21688 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
21689 _(one_use_petr, "ip-address> | disable")                                \
21690 _(one_map_request_mode, "src-dst|dst-only")                             \
21691 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
21692 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
21693 _(one_locator_set_dump, "[local | remote]")                             \
21694 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
21695 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
21696                        "[local] | [remote]")                            \
21697 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
21698 _(one_ndp_bd_get, "")                                                   \
21699 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
21700 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
21701 _(one_l2_arp_bd_get, "")                                                \
21702 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
21703 _(one_stats_enable_disable, "enable|disalbe")                           \
21704 _(show_one_stats_enable_disable, "")                                    \
21705 _(one_eid_table_vni_dump, "")                                           \
21706 _(one_eid_table_map_dump, "l2|l3")                                      \
21707 _(one_map_resolver_dump, "")                                            \
21708 _(one_map_server_dump, "")                                              \
21709 _(one_adjacencies_get, "vni <vni>")                                     \
21710 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
21711 _(show_one_rloc_probe_state, "")                                        \
21712 _(show_one_map_register_state, "")                                      \
21713 _(show_one_status, "")                                                  \
21714 _(one_stats_dump, "")                                                   \
21715 _(one_stats_flush, "")                                                  \
21716 _(one_get_map_request_itr_rlocs, "")                                    \
21717 _(one_map_register_set_ttl, "<ttl>")                                    \
21718 _(one_set_transport_protocol, "udp|api")                                \
21719 _(one_get_transport_protocol, "")                                       \
21720 _(show_one_nsh_mapping, "")                                             \
21721 _(show_one_pitr, "")                                                    \
21722 _(show_one_use_petr, "")                                                \
21723 _(show_one_map_request_mode, "")                                        \
21724 _(show_one_map_register_ttl, "")                                        \
21725 _(show_one_map_register_fallback_threshold, "")                         \
21726 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
21727                             " sw_if_index <sw_if_index> p <priority> "  \
21728                             "w <weight>] [del]")                        \
21729 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
21730                         "iface <intf> | sw_if_index <sw_if_index> "     \
21731                         "p <priority> w <weight> [del]")                \
21732 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
21733                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21734                          "locator-set <locator_name> [del]"             \
21735                          "[key-id sha1|sha256 secret-key <secret-key>]") \
21736 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
21737 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
21738 _(lisp_enable_disable, "enable|disable")                                \
21739 _(lisp_map_register_enable_disable, "enable|disable")                   \
21740 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
21741 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
21742                                "[seid <seid>] "                         \
21743                                "rloc <locator> p <prio> "               \
21744                                "w <weight> [rloc <loc> ... ] "          \
21745                                "action <action> [del-all]")             \
21746 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
21747                           "<local-eid>")                                \
21748 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
21749 _(lisp_use_petr, "<ip-address> | disable")                              \
21750 _(lisp_map_request_mode, "src-dst|dst-only")                            \
21751 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
21752 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
21753 _(lisp_locator_set_dump, "[local | remote]")                            \
21754 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
21755 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
21756                        "[local] | [remote]")                            \
21757 _(lisp_eid_table_vni_dump, "")                                          \
21758 _(lisp_eid_table_map_dump, "l2|l3")                                     \
21759 _(lisp_map_resolver_dump, "")                                           \
21760 _(lisp_map_server_dump, "")                                             \
21761 _(lisp_adjacencies_get, "vni <vni>")                                    \
21762 _(gpe_fwd_entry_vnis_get, "")                                           \
21763 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
21764 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
21765                                 "[table <table-id>]")                   \
21766 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
21767 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
21768 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
21769 _(gpe_get_encap_mode, "")                                               \
21770 _(lisp_gpe_add_del_iface, "up|down")                                    \
21771 _(lisp_gpe_enable_disable, "enable|disable")                            \
21772 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
21773   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
21774 _(show_lisp_rloc_probe_state, "")                                       \
21775 _(show_lisp_map_register_state, "")                                     \
21776 _(show_lisp_status, "")                                                 \
21777 _(lisp_get_map_request_itr_rlocs, "")                                   \
21778 _(show_lisp_pitr, "")                                                   \
21779 _(show_lisp_use_petr, "")                                               \
21780 _(show_lisp_map_request_mode, "")                                       \
21781 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
21782 _(af_packet_delete, "name <host interface name>")                       \
21783 _(policer_add_del, "name <policer name> <params> [del]")                \
21784 _(policer_dump, "[name <policer name>]")                                \
21785 _(policer_classify_set_interface,                                       \
21786   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21787   "  [l2-table <nn>] [del]")                                            \
21788 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
21789 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
21790     "[master|slave]")                                                   \
21791 _(netmap_delete, "name <interface name>")                               \
21792 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
21793 _(mpls_fib_dump, "")                                                    \
21794 _(classify_table_ids, "")                                               \
21795 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
21796 _(classify_table_info, "table_id <nn>")                                 \
21797 _(classify_session_dump, "table_id <nn>")                               \
21798 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
21799     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
21800     "[template_interval <nn>] [udp_checksum]")                          \
21801 _(ipfix_exporter_dump, "")                                              \
21802 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
21803 _(ipfix_classify_stream_dump, "")                                       \
21804 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
21805 _(ipfix_classify_table_dump, "")                                        \
21806 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
21807 _(sw_interface_span_dump, "[l2]")                                           \
21808 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
21809 _(pg_create_interface, "if_id <nn>")                                    \
21810 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
21811 _(pg_enable_disable, "[stream <id>] disable")                           \
21812 _(ip_source_and_port_range_check_add_del,                               \
21813   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
21814 _(ip_source_and_port_range_check_interface_add_del,                     \
21815   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
21816   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
21817 _(ipsec_gre_add_del_tunnel,                                             \
21818   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
21819 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
21820 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
21821 _(l2_interface_pbb_tag_rewrite,                                         \
21822   "<intfc> | sw_if_index <nn> \n"                                       \
21823   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
21824   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
21825 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
21826 _(flow_classify_set_interface,                                          \
21827   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
21828 _(flow_classify_dump, "type [ip4|ip6]")                                 \
21829 _(ip_fib_dump, "")                                                      \
21830 _(ip_mfib_dump, "")                                                     \
21831 _(ip6_fib_dump, "")                                                     \
21832 _(ip6_mfib_dump, "")                                                    \
21833 _(feature_enable_disable, "arc_name <arc_name> "                        \
21834   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
21835 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
21836 "[disable]")                                                            \
21837 _(l2_xconnect_dump, "")                                                 \
21838 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
21839 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
21840 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
21841 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
21842 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
21843 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
21844 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
21845   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
21846 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
21847 _(memfd_segment_create,"size <nnn>")                                    \
21848 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
21849 _(dns_enable_disable, "[enable][disable]")                              \
21850 _(dns_name_server_add_del, "<ip-address> [del]")                        \
21851 _(dns_resolve_name, "<hostname>")
21852
21853 /* List of command functions, CLI names map directly to functions */
21854 #define foreach_cli_function                                    \
21855 _(comment, "usage: comment <ignore-rest-of-line>")              \
21856 _(dump_interface_table, "usage: dump_interface_table")          \
21857 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21858 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21859 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21860 _(dump_stats_table, "usage: dump_stats_table")                  \
21861 _(dump_macro_table, "usage: dump_macro_table ")                 \
21862 _(dump_node_table, "usage: dump_node_table")                    \
21863 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21864 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21865 _(echo, "usage: echo <message>")                                \
21866 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21867 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21868 _(help, "usage: help")                                          \
21869 _(q, "usage: quit")                                             \
21870 _(quit, "usage: quit")                                          \
21871 _(search_node_table, "usage: search_node_table <name>...")      \
21872 _(set, "usage: set <variable-name> <value>")                    \
21873 _(script, "usage: script <file-name>")                          \
21874 _(unset, "usage: unset <variable-name>")
21875 #define _(N,n)                                  \
21876     static void vl_api_##n##_t_handler_uni      \
21877     (vl_api_##n##_t * mp)                       \
21878     {                                           \
21879         vat_main_t * vam = &vat_main;           \
21880         if (vam->json_output) {                 \
21881             vl_api_##n##_t_handler_json(mp);    \
21882         } else {                                \
21883             vl_api_##n##_t_handler(mp);         \
21884         }                                       \
21885     }
21886 foreach_vpe_api_reply_msg;
21887 #if VPP_API_TEST_BUILTIN == 0
21888 foreach_standalone_reply_msg;
21889 #endif
21890 #undef _
21891
21892 void
21893 vat_api_hookup (vat_main_t * vam)
21894 {
21895 #define _(N,n)                                                  \
21896     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21897                            vl_api_##n##_t_handler_uni,          \
21898                            vl_noop_handler,                     \
21899                            vl_api_##n##_t_endian,               \
21900                            vl_api_##n##_t_print,                \
21901                            sizeof(vl_api_##n##_t), 1);
21902   foreach_vpe_api_reply_msg;
21903 #if VPP_API_TEST_BUILTIN == 0
21904   foreach_standalone_reply_msg;
21905 #endif
21906 #undef _
21907
21908 #if (VPP_API_TEST_BUILTIN==0)
21909   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
21910
21911   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
21912
21913   vam->function_by_name = hash_create_string (0, sizeof (uword));
21914
21915   vam->help_by_name = hash_create_string (0, sizeof (uword));
21916 #endif
21917
21918   /* API messages we can send */
21919 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
21920   foreach_vpe_api_msg;
21921 #undef _
21922
21923   /* Help strings */
21924 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21925   foreach_vpe_api_msg;
21926 #undef _
21927
21928   /* CLI functions */
21929 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
21930   foreach_cli_function;
21931 #undef _
21932
21933   /* Help strings */
21934 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21935   foreach_cli_function;
21936 #undef _
21937 }
21938
21939 #if VPP_API_TEST_BUILTIN
21940 static clib_error_t *
21941 vat_api_hookup_shim (vlib_main_t * vm)
21942 {
21943   vat_api_hookup (&vat_main);
21944   return 0;
21945 }
21946
21947 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
21948 #endif
21949
21950 /*
21951  * fd.io coding-style-patch-verification: ON
21952  *
21953  * Local Variables:
21954  * eval: (c-set-style "gnu")
21955  * End:
21956  */