Initial GENEVE TUNNEL implementation and tests.
[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
2183 static void vl_api_ip_address_details_t_handler
2184   (vl_api_ip_address_details_t * mp)
2185 {
2186   vat_main_t *vam = &vat_main;
2187   static ip_address_details_t empty_ip_address_details = { {0} };
2188   ip_address_details_t *address = NULL;
2189   ip_details_t *current_ip_details = NULL;
2190   ip_details_t *details = NULL;
2191
2192   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2193
2194   if (!details || vam->current_sw_if_index >= vec_len (details)
2195       || !details[vam->current_sw_if_index].present)
2196     {
2197       errmsg ("ip address details arrived but not stored");
2198       errmsg ("ip_dump should be called first");
2199       return;
2200     }
2201
2202   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2203
2204 #define addresses (current_ip_details->addr)
2205
2206   vec_validate_init_empty (addresses, vec_len (addresses),
2207                            empty_ip_address_details);
2208
2209   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2210
2211   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
2212   address->prefix_length = mp->prefix_length;
2213 #undef addresses
2214 }
2215
2216 static void vl_api_ip_address_details_t_handler_json
2217   (vl_api_ip_address_details_t * mp)
2218 {
2219   vat_main_t *vam = &vat_main;
2220   vat_json_node_t *node = NULL;
2221   struct in6_addr ip6;
2222   struct in_addr ip4;
2223
2224   if (VAT_JSON_ARRAY != vam->json_tree.type)
2225     {
2226       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2227       vat_json_init_array (&vam->json_tree);
2228     }
2229   node = vat_json_array_add (&vam->json_tree);
2230
2231   vat_json_init_object (node);
2232   if (vam->is_ipv6)
2233     {
2234       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
2235       vat_json_object_add_ip6 (node, "ip", ip6);
2236     }
2237   else
2238     {
2239       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
2240       vat_json_object_add_ip4 (node, "ip", ip4);
2241     }
2242   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
2243 }
2244
2245 static void
2246 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2247 {
2248   vat_main_t *vam = &vat_main;
2249   static ip_details_t empty_ip_details = { 0 };
2250   ip_details_t *ip = NULL;
2251   u32 sw_if_index = ~0;
2252
2253   sw_if_index = ntohl (mp->sw_if_index);
2254
2255   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2256                            sw_if_index, empty_ip_details);
2257
2258   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2259                          sw_if_index);
2260
2261   ip->present = 1;
2262 }
2263
2264 static void
2265 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2266 {
2267   vat_main_t *vam = &vat_main;
2268
2269   if (VAT_JSON_ARRAY != vam->json_tree.type)
2270     {
2271       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2272       vat_json_init_array (&vam->json_tree);
2273     }
2274   vat_json_array_add_uint (&vam->json_tree,
2275                            clib_net_to_host_u32 (mp->sw_if_index));
2276 }
2277
2278 static void vl_api_map_domain_details_t_handler_json
2279   (vl_api_map_domain_details_t * mp)
2280 {
2281   vat_json_node_t *node = NULL;
2282   vat_main_t *vam = &vat_main;
2283   struct in6_addr ip6;
2284   struct in_addr ip4;
2285
2286   if (VAT_JSON_ARRAY != vam->json_tree.type)
2287     {
2288       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2289       vat_json_init_array (&vam->json_tree);
2290     }
2291
2292   node = vat_json_array_add (&vam->json_tree);
2293   vat_json_init_object (node);
2294
2295   vat_json_object_add_uint (node, "domain_index",
2296                             clib_net_to_host_u32 (mp->domain_index));
2297   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
2298   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
2299   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
2300   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
2301   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
2302   vat_json_object_add_ip6 (node, "ip6_src", ip6);
2303   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
2304   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
2305   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
2306   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
2307   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
2308   vat_json_object_add_int (node, "psid_length", mp->psid_length);
2309   vat_json_object_add_uint (node, "flags", mp->flags);
2310   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
2311   vat_json_object_add_int (node, "is_translation", mp->is_translation);
2312 }
2313
2314 static void vl_api_map_domain_details_t_handler
2315   (vl_api_map_domain_details_t * mp)
2316 {
2317   vat_main_t *vam = &vat_main;
2318
2319   if (mp->is_translation)
2320     {
2321       print (vam->ofp,
2322              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
2323              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2324              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2325              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
2326              clib_net_to_host_u32 (mp->domain_index));
2327     }
2328   else
2329     {
2330       print (vam->ofp,
2331              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
2332              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
2333              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
2334              format_ip6_address, mp->ip6_src,
2335              clib_net_to_host_u32 (mp->domain_index));
2336     }
2337   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
2338          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
2339          mp->is_translation ? "map-t" : "");
2340 }
2341
2342 static void vl_api_map_rule_details_t_handler_json
2343   (vl_api_map_rule_details_t * mp)
2344 {
2345   struct in6_addr ip6;
2346   vat_json_node_t *node = NULL;
2347   vat_main_t *vam = &vat_main;
2348
2349   if (VAT_JSON_ARRAY != vam->json_tree.type)
2350     {
2351       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2352       vat_json_init_array (&vam->json_tree);
2353     }
2354
2355   node = vat_json_array_add (&vam->json_tree);
2356   vat_json_init_object (node);
2357
2358   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
2359   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
2360   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
2361 }
2362
2363 static void
2364 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
2365 {
2366   vat_main_t *vam = &vat_main;
2367   print (vam->ofp, " %d (psid) %U (ip6-dst)",
2368          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
2369 }
2370
2371 static void
2372 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
2373 {
2374   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
2375           "router_addr %U host_mac %U",
2376           ntohl (mp->pid), mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
2377           format_ip4_address, &mp->host_address,
2378           format_ip4_address, &mp->router_address,
2379           format_ethernet_address, mp->host_mac);
2380 }
2381
2382 static void vl_api_dhcp_compl_event_t_handler_json
2383   (vl_api_dhcp_compl_event_t * mp)
2384 {
2385   /* JSON output not supported */
2386 }
2387
2388 static void
2389 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2390                               u32 counter)
2391 {
2392   vat_main_t *vam = &vat_main;
2393   static u64 default_counter = 0;
2394
2395   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
2396                            NULL);
2397   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
2398                            sw_if_index, default_counter);
2399   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
2400 }
2401
2402 static void
2403 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
2404                                 interface_counter_t counter)
2405 {
2406   vat_main_t *vam = &vat_main;
2407   static interface_counter_t default_counter = { 0, };
2408
2409   vec_validate_init_empty (vam->combined_interface_counters,
2410                            vnet_counter_type, NULL);
2411   vec_validate_init_empty (vam->combined_interface_counters
2412                            [vnet_counter_type], sw_if_index, default_counter);
2413   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
2414 }
2415
2416 static void vl_api_vnet_interface_simple_counters_t_handler
2417   (vl_api_vnet_interface_simple_counters_t * mp)
2418 {
2419   /* not supported */
2420 }
2421
2422 static void vl_api_vnet_interface_combined_counters_t_handler
2423   (vl_api_vnet_interface_combined_counters_t * mp)
2424 {
2425   /* not supported */
2426 }
2427
2428 static void vl_api_vnet_interface_simple_counters_t_handler_json
2429   (vl_api_vnet_interface_simple_counters_t * mp)
2430 {
2431   u64 *v_packets;
2432   u64 packets;
2433   u32 count;
2434   u32 first_sw_if_index;
2435   int i;
2436
2437   count = ntohl (mp->count);
2438   first_sw_if_index = ntohl (mp->first_sw_if_index);
2439
2440   v_packets = (u64 *) & mp->data;
2441   for (i = 0; i < count; i++)
2442     {
2443       packets = clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
2444       set_simple_interface_counter (mp->vnet_counter_type,
2445                                     first_sw_if_index + i, packets);
2446       v_packets++;
2447     }
2448 }
2449
2450 static void vl_api_vnet_interface_combined_counters_t_handler_json
2451   (vl_api_vnet_interface_combined_counters_t * mp)
2452 {
2453   interface_counter_t counter;
2454   vlib_counter_t *v;
2455   u32 first_sw_if_index;
2456   int i;
2457   u32 count;
2458
2459   count = ntohl (mp->count);
2460   first_sw_if_index = ntohl (mp->first_sw_if_index);
2461
2462   v = (vlib_counter_t *) & mp->data;
2463   for (i = 0; i < count; i++)
2464     {
2465       counter.packets =
2466         clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2467       counter.bytes =
2468         clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2469       set_combined_interface_counter (mp->vnet_counter_type,
2470                                       first_sw_if_index + i, counter);
2471       v++;
2472     }
2473 }
2474
2475 static u32
2476 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2477 {
2478   vat_main_t *vam = &vat_main;
2479   u32 i;
2480
2481   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2482     {
2483       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2484         {
2485           return i;
2486         }
2487     }
2488   return ~0;
2489 }
2490
2491 static u32
2492 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2493 {
2494   vat_main_t *vam = &vat_main;
2495   u32 i;
2496
2497   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2498     {
2499       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2500         {
2501           return i;
2502         }
2503     }
2504   return ~0;
2505 }
2506
2507 static void vl_api_vnet_ip4_fib_counters_t_handler
2508   (vl_api_vnet_ip4_fib_counters_t * mp)
2509 {
2510   /* not supported */
2511 }
2512
2513 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2514   (vl_api_vnet_ip4_fib_counters_t * mp)
2515 {
2516   vat_main_t *vam = &vat_main;
2517   vl_api_ip4_fib_counter_t *v;
2518   ip4_fib_counter_t *counter;
2519   struct in_addr ip4;
2520   u32 vrf_id;
2521   u32 vrf_index;
2522   u32 count;
2523   int i;
2524
2525   vrf_id = ntohl (mp->vrf_id);
2526   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2527   if (~0 == vrf_index)
2528     {
2529       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2530       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2531       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2532       vec_validate (vam->ip4_fib_counters, vrf_index);
2533       vam->ip4_fib_counters[vrf_index] = NULL;
2534     }
2535
2536   vec_free (vam->ip4_fib_counters[vrf_index]);
2537   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2538   count = ntohl (mp->count);
2539   for (i = 0; i < count; i++)
2540     {
2541       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2542       counter = &vam->ip4_fib_counters[vrf_index][i];
2543       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2544       counter->address = ip4;
2545       counter->address_length = v->address_length;
2546       counter->packets = clib_net_to_host_u64 (v->packets);
2547       counter->bytes = clib_net_to_host_u64 (v->bytes);
2548       v++;
2549     }
2550 }
2551
2552 static void vl_api_vnet_ip4_nbr_counters_t_handler
2553   (vl_api_vnet_ip4_nbr_counters_t * mp)
2554 {
2555   /* not supported */
2556 }
2557
2558 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2559   (vl_api_vnet_ip4_nbr_counters_t * mp)
2560 {
2561   vat_main_t *vam = &vat_main;
2562   vl_api_ip4_nbr_counter_t *v;
2563   ip4_nbr_counter_t *counter;
2564   u32 sw_if_index;
2565   u32 count;
2566   int i;
2567
2568   sw_if_index = ntohl (mp->sw_if_index);
2569   count = ntohl (mp->count);
2570   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2571
2572   if (mp->begin)
2573     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2574
2575   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2576   for (i = 0; i < count; i++)
2577     {
2578       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2579       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2580       counter->address.s_addr = v->address;
2581       counter->packets = clib_net_to_host_u64 (v->packets);
2582       counter->bytes = clib_net_to_host_u64 (v->bytes);
2583       counter->linkt = v->link_type;
2584       v++;
2585     }
2586 }
2587
2588 static void vl_api_vnet_ip6_fib_counters_t_handler
2589   (vl_api_vnet_ip6_fib_counters_t * mp)
2590 {
2591   /* not supported */
2592 }
2593
2594 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2595   (vl_api_vnet_ip6_fib_counters_t * mp)
2596 {
2597   vat_main_t *vam = &vat_main;
2598   vl_api_ip6_fib_counter_t *v;
2599   ip6_fib_counter_t *counter;
2600   struct in6_addr ip6;
2601   u32 vrf_id;
2602   u32 vrf_index;
2603   u32 count;
2604   int i;
2605
2606   vrf_id = ntohl (mp->vrf_id);
2607   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2608   if (~0 == vrf_index)
2609     {
2610       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2611       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2612       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2613       vec_validate (vam->ip6_fib_counters, vrf_index);
2614       vam->ip6_fib_counters[vrf_index] = NULL;
2615     }
2616
2617   vec_free (vam->ip6_fib_counters[vrf_index]);
2618   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2619   count = ntohl (mp->count);
2620   for (i = 0; i < count; i++)
2621     {
2622       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2623       counter = &vam->ip6_fib_counters[vrf_index][i];
2624       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2625       counter->address = ip6;
2626       counter->address_length = v->address_length;
2627       counter->packets = clib_net_to_host_u64 (v->packets);
2628       counter->bytes = clib_net_to_host_u64 (v->bytes);
2629       v++;
2630     }
2631 }
2632
2633 static void vl_api_vnet_ip6_nbr_counters_t_handler
2634   (vl_api_vnet_ip6_nbr_counters_t * mp)
2635 {
2636   /* not supported */
2637 }
2638
2639 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2640   (vl_api_vnet_ip6_nbr_counters_t * mp)
2641 {
2642   vat_main_t *vam = &vat_main;
2643   vl_api_ip6_nbr_counter_t *v;
2644   ip6_nbr_counter_t *counter;
2645   struct in6_addr ip6;
2646   u32 sw_if_index;
2647   u32 count;
2648   int i;
2649
2650   sw_if_index = ntohl (mp->sw_if_index);
2651   count = ntohl (mp->count);
2652   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2653
2654   if (mp->begin)
2655     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2656
2657   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2658   for (i = 0; i < count; i++)
2659     {
2660       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2661       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2662       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2663       counter->address = ip6;
2664       counter->packets = clib_net_to_host_u64 (v->packets);
2665       counter->bytes = clib_net_to_host_u64 (v->bytes);
2666       v++;
2667     }
2668 }
2669
2670 static void vl_api_get_first_msg_id_reply_t_handler
2671   (vl_api_get_first_msg_id_reply_t * mp)
2672 {
2673   vat_main_t *vam = &vat_main;
2674   i32 retval = ntohl (mp->retval);
2675
2676   if (vam->async_mode)
2677     {
2678       vam->async_errors += (retval < 0);
2679     }
2680   else
2681     {
2682       vam->retval = retval;
2683       vam->result_ready = 1;
2684     }
2685   if (retval >= 0)
2686     {
2687       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2688     }
2689 }
2690
2691 static void vl_api_get_first_msg_id_reply_t_handler_json
2692   (vl_api_get_first_msg_id_reply_t * mp)
2693 {
2694   vat_main_t *vam = &vat_main;
2695   vat_json_node_t node;
2696
2697   vat_json_init_object (&node);
2698   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2699   vat_json_object_add_uint (&node, "first_msg_id",
2700                             (uint) ntohs (mp->first_msg_id));
2701
2702   vat_json_print (vam->ofp, &node);
2703   vat_json_free (&node);
2704
2705   vam->retval = ntohl (mp->retval);
2706   vam->result_ready = 1;
2707 }
2708
2709 static void vl_api_get_node_graph_reply_t_handler
2710   (vl_api_get_node_graph_reply_t * mp)
2711 {
2712   vat_main_t *vam = &vat_main;
2713   api_main_t *am = &api_main;
2714   i32 retval = ntohl (mp->retval);
2715   u8 *pvt_copy, *reply;
2716   void *oldheap;
2717   vlib_node_t *node;
2718   int i;
2719
2720   if (vam->async_mode)
2721     {
2722       vam->async_errors += (retval < 0);
2723     }
2724   else
2725     {
2726       vam->retval = retval;
2727       vam->result_ready = 1;
2728     }
2729
2730   /* "Should never happen..." */
2731   if (retval != 0)
2732     return;
2733
2734   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2735   pvt_copy = vec_dup (reply);
2736
2737   /* Toss the shared-memory original... */
2738   pthread_mutex_lock (&am->vlib_rp->mutex);
2739   oldheap = svm_push_data_heap (am->vlib_rp);
2740
2741   vec_free (reply);
2742
2743   svm_pop_heap (oldheap);
2744   pthread_mutex_unlock (&am->vlib_rp->mutex);
2745
2746   if (vam->graph_nodes)
2747     {
2748       hash_free (vam->graph_node_index_by_name);
2749
2750       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2751         {
2752           node = vam->graph_nodes[i];
2753           vec_free (node->name);
2754           vec_free (node->next_nodes);
2755           vec_free (node);
2756         }
2757       vec_free (vam->graph_nodes);
2758     }
2759
2760   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2761   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2762   vec_free (pvt_copy);
2763
2764   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2765     {
2766       node = vam->graph_nodes[i];
2767       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2768     }
2769 }
2770
2771 static void vl_api_get_node_graph_reply_t_handler_json
2772   (vl_api_get_node_graph_reply_t * mp)
2773 {
2774   vat_main_t *vam = &vat_main;
2775   api_main_t *am = &api_main;
2776   void *oldheap;
2777   vat_json_node_t node;
2778   u8 *reply;
2779
2780   /* $$$$ make this real? */
2781   vat_json_init_object (&node);
2782   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2783   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2784
2785   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2786
2787   /* Toss the shared-memory original... */
2788   pthread_mutex_lock (&am->vlib_rp->mutex);
2789   oldheap = svm_push_data_heap (am->vlib_rp);
2790
2791   vec_free (reply);
2792
2793   svm_pop_heap (oldheap);
2794   pthread_mutex_unlock (&am->vlib_rp->mutex);
2795
2796   vat_json_print (vam->ofp, &node);
2797   vat_json_free (&node);
2798
2799   vam->retval = ntohl (mp->retval);
2800   vam->result_ready = 1;
2801 }
2802
2803 static void
2804 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2805 {
2806   vat_main_t *vam = &vat_main;
2807   u8 *s = 0;
2808
2809   if (mp->local)
2810     {
2811       s = format (s, "%=16d%=16d%=16d",
2812                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2813     }
2814   else
2815     {
2816       s = format (s, "%=16U%=16d%=16d",
2817                   mp->is_ipv6 ? format_ip6_address :
2818                   format_ip4_address,
2819                   mp->ip_address, mp->priority, mp->weight);
2820     }
2821
2822   print (vam->ofp, "%v", s);
2823   vec_free (s);
2824 }
2825
2826 static void
2827 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2828 {
2829   vat_main_t *vam = &vat_main;
2830   vat_json_node_t *node = NULL;
2831   struct in6_addr ip6;
2832   struct in_addr ip4;
2833
2834   if (VAT_JSON_ARRAY != vam->json_tree.type)
2835     {
2836       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2837       vat_json_init_array (&vam->json_tree);
2838     }
2839   node = vat_json_array_add (&vam->json_tree);
2840   vat_json_init_object (node);
2841
2842   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2843   vat_json_object_add_uint (node, "priority", mp->priority);
2844   vat_json_object_add_uint (node, "weight", mp->weight);
2845
2846   if (mp->local)
2847     vat_json_object_add_uint (node, "sw_if_index",
2848                               clib_net_to_host_u32 (mp->sw_if_index));
2849   else
2850     {
2851       if (mp->is_ipv6)
2852         {
2853           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2854           vat_json_object_add_ip6 (node, "address", ip6);
2855         }
2856       else
2857         {
2858           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2859           vat_json_object_add_ip4 (node, "address", ip4);
2860         }
2861     }
2862 }
2863
2864 static void
2865 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2866                                           mp)
2867 {
2868   vat_main_t *vam = &vat_main;
2869   u8 *ls_name = 0;
2870
2871   ls_name = format (0, "%s", mp->ls_name);
2872
2873   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2874          ls_name);
2875   vec_free (ls_name);
2876 }
2877
2878 static void
2879   vl_api_one_locator_set_details_t_handler_json
2880   (vl_api_one_locator_set_details_t * mp)
2881 {
2882   vat_main_t *vam = &vat_main;
2883   vat_json_node_t *node = 0;
2884   u8 *ls_name = 0;
2885
2886   ls_name = format (0, "%s", mp->ls_name);
2887   vec_add1 (ls_name, 0);
2888
2889   if (VAT_JSON_ARRAY != vam->json_tree.type)
2890     {
2891       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2892       vat_json_init_array (&vam->json_tree);
2893     }
2894   node = vat_json_array_add (&vam->json_tree);
2895
2896   vat_json_init_object (node);
2897   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2898   vat_json_object_add_uint (node, "ls_index",
2899                             clib_net_to_host_u32 (mp->ls_index));
2900   vec_free (ls_name);
2901 }
2902
2903 typedef struct
2904 {
2905   u32 spi;
2906   u8 si;
2907 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2908
2909 uword
2910 unformat_nsh_address (unformat_input_t * input, va_list * args)
2911 {
2912   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2913   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2914 }
2915
2916 u8 *
2917 format_nsh_address_vat (u8 * s, va_list * args)
2918 {
2919   nsh_t *a = va_arg (*args, nsh_t *);
2920   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2921 }
2922
2923 static u8 *
2924 format_lisp_flat_eid (u8 * s, va_list * args)
2925 {
2926   u32 type = va_arg (*args, u32);
2927   u8 *eid = va_arg (*args, u8 *);
2928   u32 eid_len = va_arg (*args, u32);
2929
2930   switch (type)
2931     {
2932     case 0:
2933       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2934     case 1:
2935       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2936     case 2:
2937       return format (s, "%U", format_ethernet_address, eid);
2938     case 3:
2939       return format (s, "%U", format_nsh_address_vat, eid);
2940     }
2941   return 0;
2942 }
2943
2944 static u8 *
2945 format_lisp_eid_vat (u8 * s, va_list * args)
2946 {
2947   u32 type = va_arg (*args, u32);
2948   u8 *eid = va_arg (*args, u8 *);
2949   u32 eid_len = va_arg (*args, u32);
2950   u8 *seid = va_arg (*args, u8 *);
2951   u32 seid_len = va_arg (*args, u32);
2952   u32 is_src_dst = va_arg (*args, u32);
2953
2954   if (is_src_dst)
2955     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2956
2957   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2958
2959   return s;
2960 }
2961
2962 static void
2963 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2964 {
2965   vat_main_t *vam = &vat_main;
2966   u8 *s = 0, *eid = 0;
2967
2968   if (~0 == mp->locator_set_index)
2969     s = format (0, "action: %d", mp->action);
2970   else
2971     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2972
2973   eid = format (0, "%U", format_lisp_eid_vat,
2974                 mp->eid_type,
2975                 mp->eid,
2976                 mp->eid_prefix_len,
2977                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2978   vec_add1 (eid, 0);
2979
2980   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2981          clib_net_to_host_u32 (mp->vni),
2982          eid,
2983          mp->is_local ? "local" : "remote",
2984          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2985          clib_net_to_host_u16 (mp->key_id), mp->key);
2986
2987   vec_free (s);
2988   vec_free (eid);
2989 }
2990
2991 static void
2992 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2993                                              * mp)
2994 {
2995   vat_main_t *vam = &vat_main;
2996   vat_json_node_t *node = 0;
2997   u8 *eid = 0;
2998
2999   if (VAT_JSON_ARRAY != vam->json_tree.type)
3000     {
3001       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3002       vat_json_init_array (&vam->json_tree);
3003     }
3004   node = vat_json_array_add (&vam->json_tree);
3005
3006   vat_json_init_object (node);
3007   if (~0 == mp->locator_set_index)
3008     vat_json_object_add_uint (node, "action", mp->action);
3009   else
3010     vat_json_object_add_uint (node, "locator_set_index",
3011                               clib_net_to_host_u32 (mp->locator_set_index));
3012
3013   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3014   if (mp->eid_type == 3)
3015     {
3016       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3017       vat_json_init_object (nsh_json);
3018       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3019       vat_json_object_add_uint (nsh_json, "spi",
3020                                 clib_net_to_host_u32 (nsh->spi));
3021       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3022     }
3023   else
3024     {
3025       eid = format (0, "%U", format_lisp_eid_vat,
3026                     mp->eid_type,
3027                     mp->eid,
3028                     mp->eid_prefix_len,
3029                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3030       vec_add1 (eid, 0);
3031       vat_json_object_add_string_copy (node, "eid", eid);
3032       vec_free (eid);
3033     }
3034   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3035   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3036   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3037
3038   if (mp->key_id)
3039     {
3040       vat_json_object_add_uint (node, "key_id",
3041                                 clib_net_to_host_u16 (mp->key_id));
3042       vat_json_object_add_string_copy (node, "key", mp->key);
3043     }
3044 }
3045
3046 static void
3047 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3048 {
3049   vat_main_t *vam = &vat_main;
3050   u8 *seid = 0, *deid = 0;
3051   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3052
3053   deid = format (0, "%U", format_lisp_eid_vat,
3054                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3055
3056   seid = format (0, "%U", format_lisp_eid_vat,
3057                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3058
3059   vec_add1 (deid, 0);
3060   vec_add1 (seid, 0);
3061
3062   if (mp->is_ip4)
3063     format_ip_address_fcn = format_ip4_address;
3064   else
3065     format_ip_address_fcn = format_ip6_address;
3066
3067
3068   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3069          clib_net_to_host_u32 (mp->vni),
3070          seid, deid,
3071          format_ip_address_fcn, mp->lloc,
3072          format_ip_address_fcn, mp->rloc,
3073          clib_net_to_host_u32 (mp->pkt_count),
3074          clib_net_to_host_u32 (mp->bytes));
3075
3076   vec_free (deid);
3077   vec_free (seid);
3078 }
3079
3080 static void
3081 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3082 {
3083   struct in6_addr ip6;
3084   struct in_addr ip4;
3085   vat_main_t *vam = &vat_main;
3086   vat_json_node_t *node = 0;
3087   u8 *deid = 0, *seid = 0;
3088
3089   if (VAT_JSON_ARRAY != vam->json_tree.type)
3090     {
3091       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3092       vat_json_init_array (&vam->json_tree);
3093     }
3094   node = vat_json_array_add (&vam->json_tree);
3095
3096   vat_json_init_object (node);
3097   deid = format (0, "%U", format_lisp_eid_vat,
3098                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3099
3100   seid = format (0, "%U", format_lisp_eid_vat,
3101                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3102
3103   vec_add1 (deid, 0);
3104   vec_add1 (seid, 0);
3105
3106   vat_json_object_add_string_copy (node, "seid", seid);
3107   vat_json_object_add_string_copy (node, "deid", deid);
3108   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3109
3110   if (mp->is_ip4)
3111     {
3112       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3113       vat_json_object_add_ip4 (node, "lloc", ip4);
3114       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3115       vat_json_object_add_ip4 (node, "rloc", ip4);
3116     }
3117   else
3118     {
3119       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3120       vat_json_object_add_ip6 (node, "lloc", ip6);
3121       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3122       vat_json_object_add_ip6 (node, "rloc", ip6);
3123     }
3124   vat_json_object_add_uint (node, "pkt_count",
3125                             clib_net_to_host_u32 (mp->pkt_count));
3126   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3127
3128   vec_free (deid);
3129   vec_free (seid);
3130 }
3131
3132 static void
3133   vl_api_one_eid_table_map_details_t_handler
3134   (vl_api_one_eid_table_map_details_t * mp)
3135 {
3136   vat_main_t *vam = &vat_main;
3137
3138   u8 *line = format (0, "%=10d%=10d",
3139                      clib_net_to_host_u32 (mp->vni),
3140                      clib_net_to_host_u32 (mp->dp_table));
3141   print (vam->ofp, "%v", line);
3142   vec_free (line);
3143 }
3144
3145 static void
3146   vl_api_one_eid_table_map_details_t_handler_json
3147   (vl_api_one_eid_table_map_details_t * mp)
3148 {
3149   vat_main_t *vam = &vat_main;
3150   vat_json_node_t *node = NULL;
3151
3152   if (VAT_JSON_ARRAY != vam->json_tree.type)
3153     {
3154       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3155       vat_json_init_array (&vam->json_tree);
3156     }
3157   node = vat_json_array_add (&vam->json_tree);
3158   vat_json_init_object (node);
3159   vat_json_object_add_uint (node, "dp_table",
3160                             clib_net_to_host_u32 (mp->dp_table));
3161   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3162 }
3163
3164 static void
3165   vl_api_one_eid_table_vni_details_t_handler
3166   (vl_api_one_eid_table_vni_details_t * mp)
3167 {
3168   vat_main_t *vam = &vat_main;
3169
3170   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3171   print (vam->ofp, "%v", line);
3172   vec_free (line);
3173 }
3174
3175 static void
3176   vl_api_one_eid_table_vni_details_t_handler_json
3177   (vl_api_one_eid_table_vni_details_t * mp)
3178 {
3179   vat_main_t *vam = &vat_main;
3180   vat_json_node_t *node = NULL;
3181
3182   if (VAT_JSON_ARRAY != vam->json_tree.type)
3183     {
3184       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3185       vat_json_init_array (&vam->json_tree);
3186     }
3187   node = vat_json_array_add (&vam->json_tree);
3188   vat_json_init_object (node);
3189   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3190 }
3191
3192 static void
3193   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3194   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3195 {
3196   vat_main_t *vam = &vat_main;
3197   int retval = clib_net_to_host_u32 (mp->retval);
3198
3199   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3200   print (vam->ofp, "fallback threshold value: %d", mp->value);
3201
3202   vam->retval = retval;
3203   vam->result_ready = 1;
3204 }
3205
3206 static void
3207   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3208   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3209 {
3210   vat_main_t *vam = &vat_main;
3211   vat_json_node_t _node, *node = &_node;
3212   int retval = clib_net_to_host_u32 (mp->retval);
3213
3214   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3215   vat_json_init_object (node);
3216   vat_json_object_add_uint (node, "value", mp->value);
3217
3218   vat_json_print (vam->ofp, node);
3219   vat_json_free (node);
3220
3221   vam->retval = retval;
3222   vam->result_ready = 1;
3223 }
3224
3225 static void
3226   vl_api_show_one_map_register_state_reply_t_handler
3227   (vl_api_show_one_map_register_state_reply_t * mp)
3228 {
3229   vat_main_t *vam = &vat_main;
3230   int retval = clib_net_to_host_u32 (mp->retval);
3231
3232   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3233
3234   vam->retval = retval;
3235   vam->result_ready = 1;
3236 }
3237
3238 static void
3239   vl_api_show_one_map_register_state_reply_t_handler_json
3240   (vl_api_show_one_map_register_state_reply_t * mp)
3241 {
3242   vat_main_t *vam = &vat_main;
3243   vat_json_node_t _node, *node = &_node;
3244   int retval = clib_net_to_host_u32 (mp->retval);
3245
3246   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3247
3248   vat_json_init_object (node);
3249   vat_json_object_add_string_copy (node, "state", s);
3250
3251   vat_json_print (vam->ofp, node);
3252   vat_json_free (node);
3253
3254   vam->retval = retval;
3255   vam->result_ready = 1;
3256   vec_free (s);
3257 }
3258
3259 static void
3260   vl_api_show_one_rloc_probe_state_reply_t_handler
3261   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3262 {
3263   vat_main_t *vam = &vat_main;
3264   int retval = clib_net_to_host_u32 (mp->retval);
3265
3266   if (retval)
3267     goto end;
3268
3269   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3270 end:
3271   vam->retval = retval;
3272   vam->result_ready = 1;
3273 }
3274
3275 static void
3276   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3277   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3278 {
3279   vat_main_t *vam = &vat_main;
3280   vat_json_node_t _node, *node = &_node;
3281   int retval = clib_net_to_host_u32 (mp->retval);
3282
3283   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3284   vat_json_init_object (node);
3285   vat_json_object_add_string_copy (node, "state", s);
3286
3287   vat_json_print (vam->ofp, node);
3288   vat_json_free (node);
3289
3290   vam->retval = retval;
3291   vam->result_ready = 1;
3292   vec_free (s);
3293 }
3294
3295 static void
3296   vl_api_show_one_stats_enable_disable_reply_t_handler
3297   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3298 {
3299   vat_main_t *vam = &vat_main;
3300   int retval = clib_net_to_host_u32 (mp->retval);
3301
3302   if (retval)
3303     goto end;
3304
3305   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3306 end:
3307   vam->retval = retval;
3308   vam->result_ready = 1;
3309 }
3310
3311 static void
3312   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3313   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3314 {
3315   vat_main_t *vam = &vat_main;
3316   vat_json_node_t _node, *node = &_node;
3317   int retval = clib_net_to_host_u32 (mp->retval);
3318
3319   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3320   vat_json_init_object (node);
3321   vat_json_object_add_string_copy (node, "state", s);
3322
3323   vat_json_print (vam->ofp, node);
3324   vat_json_free (node);
3325
3326   vam->retval = retval;
3327   vam->result_ready = 1;
3328   vec_free (s);
3329 }
3330
3331 static void
3332 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3333 {
3334   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3335   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3336   e->vni = clib_net_to_host_u32 (e->vni);
3337 }
3338
3339 static void
3340   gpe_fwd_entries_get_reply_t_net_to_host
3341   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3342 {
3343   u32 i;
3344
3345   mp->count = clib_net_to_host_u32 (mp->count);
3346   for (i = 0; i < mp->count; i++)
3347     {
3348       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3349     }
3350 }
3351
3352 static u8 *
3353 format_gpe_encap_mode (u8 * s, va_list * args)
3354 {
3355   u32 mode = va_arg (*args, u32);
3356
3357   switch (mode)
3358     {
3359     case 0:
3360       return format (s, "lisp");
3361     case 1:
3362       return format (s, "vxlan");
3363     }
3364   return 0;
3365 }
3366
3367 static void
3368   vl_api_gpe_get_encap_mode_reply_t_handler
3369   (vl_api_gpe_get_encap_mode_reply_t * mp)
3370 {
3371   vat_main_t *vam = &vat_main;
3372
3373   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3374   vam->retval = ntohl (mp->retval);
3375   vam->result_ready = 1;
3376 }
3377
3378 static void
3379   vl_api_gpe_get_encap_mode_reply_t_handler_json
3380   (vl_api_gpe_get_encap_mode_reply_t * mp)
3381 {
3382   vat_main_t *vam = &vat_main;
3383   vat_json_node_t node;
3384
3385   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3386   vec_add1 (encap_mode, 0);
3387
3388   vat_json_init_object (&node);
3389   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3390
3391   vec_free (encap_mode);
3392   vat_json_print (vam->ofp, &node);
3393   vat_json_free (&node);
3394
3395   vam->retval = ntohl (mp->retval);
3396   vam->result_ready = 1;
3397 }
3398
3399 static void
3400   vl_api_gpe_fwd_entry_path_details_t_handler
3401   (vl_api_gpe_fwd_entry_path_details_t * mp)
3402 {
3403   vat_main_t *vam = &vat_main;
3404   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3405
3406   if (mp->lcl_loc.is_ip4)
3407     format_ip_address_fcn = format_ip4_address;
3408   else
3409     format_ip_address_fcn = format_ip6_address;
3410
3411   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3412          format_ip_address_fcn, &mp->lcl_loc,
3413          format_ip_address_fcn, &mp->rmt_loc);
3414 }
3415
3416 static void
3417 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3418 {
3419   struct in6_addr ip6;
3420   struct in_addr ip4;
3421
3422   if (loc->is_ip4)
3423     {
3424       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3425       vat_json_object_add_ip4 (n, "address", ip4);
3426     }
3427   else
3428     {
3429       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3430       vat_json_object_add_ip6 (n, "address", ip6);
3431     }
3432   vat_json_object_add_uint (n, "weight", loc->weight);
3433 }
3434
3435 static void
3436   vl_api_gpe_fwd_entry_path_details_t_handler_json
3437   (vl_api_gpe_fwd_entry_path_details_t * mp)
3438 {
3439   vat_main_t *vam = &vat_main;
3440   vat_json_node_t *node = NULL;
3441   vat_json_node_t *loc_node;
3442
3443   if (VAT_JSON_ARRAY != vam->json_tree.type)
3444     {
3445       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3446       vat_json_init_array (&vam->json_tree);
3447     }
3448   node = vat_json_array_add (&vam->json_tree);
3449   vat_json_init_object (node);
3450
3451   loc_node = vat_json_object_add (node, "local_locator");
3452   vat_json_init_object (loc_node);
3453   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3454
3455   loc_node = vat_json_object_add (node, "remote_locator");
3456   vat_json_init_object (loc_node);
3457   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3458 }
3459
3460 static void
3461   vl_api_gpe_fwd_entries_get_reply_t_handler
3462   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3463 {
3464   vat_main_t *vam = &vat_main;
3465   u32 i;
3466   int retval = clib_net_to_host_u32 (mp->retval);
3467   vl_api_gpe_fwd_entry_t *e;
3468
3469   if (retval)
3470     goto end;
3471
3472   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3473
3474   for (i = 0; i < mp->count; i++)
3475     {
3476       e = &mp->entries[i];
3477       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3478              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3479              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3480     }
3481
3482 end:
3483   vam->retval = retval;
3484   vam->result_ready = 1;
3485 }
3486
3487 static void
3488   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3489   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3490 {
3491   u8 *s = 0;
3492   vat_main_t *vam = &vat_main;
3493   vat_json_node_t *e = 0, root;
3494   u32 i;
3495   int retval = clib_net_to_host_u32 (mp->retval);
3496   vl_api_gpe_fwd_entry_t *fwd;
3497
3498   if (retval)
3499     goto end;
3500
3501   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3502   vat_json_init_array (&root);
3503
3504   for (i = 0; i < mp->count; i++)
3505     {
3506       e = vat_json_array_add (&root);
3507       fwd = &mp->entries[i];
3508
3509       vat_json_init_object (e);
3510       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3511       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3512       vat_json_object_add_int (e, "vni", fwd->vni);
3513       vat_json_object_add_int (e, "action", fwd->action);
3514
3515       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3516                   fwd->leid_prefix_len);
3517       vec_add1 (s, 0);
3518       vat_json_object_add_string_copy (e, "leid", s);
3519       vec_free (s);
3520
3521       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3522                   fwd->reid_prefix_len);
3523       vec_add1 (s, 0);
3524       vat_json_object_add_string_copy (e, "reid", s);
3525       vec_free (s);
3526     }
3527
3528   vat_json_print (vam->ofp, &root);
3529   vat_json_free (&root);
3530
3531 end:
3532   vam->retval = retval;
3533   vam->result_ready = 1;
3534 }
3535
3536 static void
3537   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3538   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3539 {
3540   vat_main_t *vam = &vat_main;
3541   u32 i, n;
3542   int retval = clib_net_to_host_u32 (mp->retval);
3543   vl_api_gpe_native_fwd_rpath_t *r;
3544
3545   if (retval)
3546     goto end;
3547
3548   n = clib_net_to_host_u32 (mp->count);
3549
3550   for (i = 0; i < n; i++)
3551     {
3552       r = &mp->entries[i];
3553       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3554              clib_net_to_host_u32 (r->fib_index),
3555              clib_net_to_host_u32 (r->nh_sw_if_index),
3556              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3557     }
3558
3559 end:
3560   vam->retval = retval;
3561   vam->result_ready = 1;
3562 }
3563
3564 static void
3565   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3566   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3567 {
3568   vat_main_t *vam = &vat_main;
3569   vat_json_node_t root, *e;
3570   u32 i, n;
3571   int retval = clib_net_to_host_u32 (mp->retval);
3572   vl_api_gpe_native_fwd_rpath_t *r;
3573   u8 *s;
3574
3575   if (retval)
3576     goto end;
3577
3578   n = clib_net_to_host_u32 (mp->count);
3579   vat_json_init_array (&root);
3580
3581   for (i = 0; i < n; i++)
3582     {
3583       e = vat_json_array_add (&root);
3584       vat_json_init_object (e);
3585       r = &mp->entries[i];
3586       s =
3587         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3588                 r->nh_addr);
3589       vec_add1 (s, 0);
3590       vat_json_object_add_string_copy (e, "ip4", s);
3591       vec_free (s);
3592
3593       vat_json_object_add_uint (e, "fib_index",
3594                                 clib_net_to_host_u32 (r->fib_index));
3595       vat_json_object_add_uint (e, "nh_sw_if_index",
3596                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3597     }
3598
3599   vat_json_print (vam->ofp, &root);
3600   vat_json_free (&root);
3601
3602 end:
3603   vam->retval = retval;
3604   vam->result_ready = 1;
3605 }
3606
3607 static void
3608   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3609   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3610 {
3611   vat_main_t *vam = &vat_main;
3612   u32 i, n;
3613   int retval = clib_net_to_host_u32 (mp->retval);
3614
3615   if (retval)
3616     goto end;
3617
3618   n = clib_net_to_host_u32 (mp->count);
3619
3620   for (i = 0; i < n; i++)
3621     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3622
3623 end:
3624   vam->retval = retval;
3625   vam->result_ready = 1;
3626 }
3627
3628 static void
3629   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3630   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3631 {
3632   vat_main_t *vam = &vat_main;
3633   vat_json_node_t root;
3634   u32 i, n;
3635   int retval = clib_net_to_host_u32 (mp->retval);
3636
3637   if (retval)
3638     goto end;
3639
3640   n = clib_net_to_host_u32 (mp->count);
3641   vat_json_init_array (&root);
3642
3643   for (i = 0; i < n; i++)
3644     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3645
3646   vat_json_print (vam->ofp, &root);
3647   vat_json_free (&root);
3648
3649 end:
3650   vam->retval = retval;
3651   vam->result_ready = 1;
3652 }
3653
3654 static void
3655   vl_api_one_ndp_entries_get_reply_t_handler
3656   (vl_api_one_ndp_entries_get_reply_t * mp)
3657 {
3658   vat_main_t *vam = &vat_main;
3659   u32 i, n;
3660   int retval = clib_net_to_host_u32 (mp->retval);
3661
3662   if (retval)
3663     goto end;
3664
3665   n = clib_net_to_host_u32 (mp->count);
3666
3667   for (i = 0; i < n; i++)
3668     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3669            format_ethernet_address, mp->entries[i].mac);
3670
3671 end:
3672   vam->retval = retval;
3673   vam->result_ready = 1;
3674 }
3675
3676 static void
3677   vl_api_one_ndp_entries_get_reply_t_handler_json
3678   (vl_api_one_ndp_entries_get_reply_t * mp)
3679 {
3680   u8 *s = 0;
3681   vat_main_t *vam = &vat_main;
3682   vat_json_node_t *e = 0, root;
3683   u32 i, n;
3684   int retval = clib_net_to_host_u32 (mp->retval);
3685   vl_api_one_ndp_entry_t *arp_entry;
3686
3687   if (retval)
3688     goto end;
3689
3690   n = clib_net_to_host_u32 (mp->count);
3691   vat_json_init_array (&root);
3692
3693   for (i = 0; i < n; i++)
3694     {
3695       e = vat_json_array_add (&root);
3696       arp_entry = &mp->entries[i];
3697
3698       vat_json_init_object (e);
3699       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3700       vec_add1 (s, 0);
3701
3702       vat_json_object_add_string_copy (e, "mac", s);
3703       vec_free (s);
3704
3705       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3706       vec_add1 (s, 0);
3707       vat_json_object_add_string_copy (e, "ip6", s);
3708       vec_free (s);
3709     }
3710
3711   vat_json_print (vam->ofp, &root);
3712   vat_json_free (&root);
3713
3714 end:
3715   vam->retval = retval;
3716   vam->result_ready = 1;
3717 }
3718
3719 static void
3720   vl_api_one_l2_arp_entries_get_reply_t_handler
3721   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3722 {
3723   vat_main_t *vam = &vat_main;
3724   u32 i, n;
3725   int retval = clib_net_to_host_u32 (mp->retval);
3726
3727   if (retval)
3728     goto end;
3729
3730   n = clib_net_to_host_u32 (mp->count);
3731
3732   for (i = 0; i < n; i++)
3733     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3734            format_ethernet_address, mp->entries[i].mac);
3735
3736 end:
3737   vam->retval = retval;
3738   vam->result_ready = 1;
3739 }
3740
3741 static void
3742   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3743   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3744 {
3745   u8 *s = 0;
3746   vat_main_t *vam = &vat_main;
3747   vat_json_node_t *e = 0, root;
3748   u32 i, n;
3749   int retval = clib_net_to_host_u32 (mp->retval);
3750   vl_api_one_l2_arp_entry_t *arp_entry;
3751
3752   if (retval)
3753     goto end;
3754
3755   n = clib_net_to_host_u32 (mp->count);
3756   vat_json_init_array (&root);
3757
3758   for (i = 0; i < n; i++)
3759     {
3760       e = vat_json_array_add (&root);
3761       arp_entry = &mp->entries[i];
3762
3763       vat_json_init_object (e);
3764       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3765       vec_add1 (s, 0);
3766
3767       vat_json_object_add_string_copy (e, "mac", s);
3768       vec_free (s);
3769
3770       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3771       vec_add1 (s, 0);
3772       vat_json_object_add_string_copy (e, "ip4", s);
3773       vec_free (s);
3774     }
3775
3776   vat_json_print (vam->ofp, &root);
3777   vat_json_free (&root);
3778
3779 end:
3780   vam->retval = retval;
3781   vam->result_ready = 1;
3782 }
3783
3784 static void
3785 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3786 {
3787   vat_main_t *vam = &vat_main;
3788   u32 i, n;
3789   int retval = clib_net_to_host_u32 (mp->retval);
3790
3791   if (retval)
3792     goto end;
3793
3794   n = clib_net_to_host_u32 (mp->count);
3795
3796   for (i = 0; i < n; i++)
3797     {
3798       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3799     }
3800
3801 end:
3802   vam->retval = retval;
3803   vam->result_ready = 1;
3804 }
3805
3806 static void
3807   vl_api_one_ndp_bd_get_reply_t_handler_json
3808   (vl_api_one_ndp_bd_get_reply_t * mp)
3809 {
3810   vat_main_t *vam = &vat_main;
3811   vat_json_node_t root;
3812   u32 i, n;
3813   int retval = clib_net_to_host_u32 (mp->retval);
3814
3815   if (retval)
3816     goto end;
3817
3818   n = clib_net_to_host_u32 (mp->count);
3819   vat_json_init_array (&root);
3820
3821   for (i = 0; i < n; i++)
3822     {
3823       vat_json_array_add_uint (&root,
3824                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3825     }
3826
3827   vat_json_print (vam->ofp, &root);
3828   vat_json_free (&root);
3829
3830 end:
3831   vam->retval = retval;
3832   vam->result_ready = 1;
3833 }
3834
3835 static void
3836   vl_api_one_l2_arp_bd_get_reply_t_handler
3837   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3838 {
3839   vat_main_t *vam = &vat_main;
3840   u32 i, n;
3841   int retval = clib_net_to_host_u32 (mp->retval);
3842
3843   if (retval)
3844     goto end;
3845
3846   n = clib_net_to_host_u32 (mp->count);
3847
3848   for (i = 0; i < n; i++)
3849     {
3850       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3851     }
3852
3853 end:
3854   vam->retval = retval;
3855   vam->result_ready = 1;
3856 }
3857
3858 static void
3859   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3860   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3861 {
3862   vat_main_t *vam = &vat_main;
3863   vat_json_node_t root;
3864   u32 i, n;
3865   int retval = clib_net_to_host_u32 (mp->retval);
3866
3867   if (retval)
3868     goto end;
3869
3870   n = clib_net_to_host_u32 (mp->count);
3871   vat_json_init_array (&root);
3872
3873   for (i = 0; i < n; i++)
3874     {
3875       vat_json_array_add_uint (&root,
3876                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3877     }
3878
3879   vat_json_print (vam->ofp, &root);
3880   vat_json_free (&root);
3881
3882 end:
3883   vam->retval = retval;
3884   vam->result_ready = 1;
3885 }
3886
3887 static void
3888   vl_api_one_adjacencies_get_reply_t_handler
3889   (vl_api_one_adjacencies_get_reply_t * mp)
3890 {
3891   vat_main_t *vam = &vat_main;
3892   u32 i, n;
3893   int retval = clib_net_to_host_u32 (mp->retval);
3894   vl_api_one_adjacency_t *a;
3895
3896   if (retval)
3897     goto end;
3898
3899   n = clib_net_to_host_u32 (mp->count);
3900
3901   for (i = 0; i < n; i++)
3902     {
3903       a = &mp->adjacencies[i];
3904       print (vam->ofp, "%U %40U",
3905              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3906              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3907     }
3908
3909 end:
3910   vam->retval = retval;
3911   vam->result_ready = 1;
3912 }
3913
3914 static void
3915   vl_api_one_adjacencies_get_reply_t_handler_json
3916   (vl_api_one_adjacencies_get_reply_t * mp)
3917 {
3918   u8 *s = 0;
3919   vat_main_t *vam = &vat_main;
3920   vat_json_node_t *e = 0, root;
3921   u32 i, n;
3922   int retval = clib_net_to_host_u32 (mp->retval);
3923   vl_api_one_adjacency_t *a;
3924
3925   if (retval)
3926     goto end;
3927
3928   n = clib_net_to_host_u32 (mp->count);
3929   vat_json_init_array (&root);
3930
3931   for (i = 0; i < n; i++)
3932     {
3933       e = vat_json_array_add (&root);
3934       a = &mp->adjacencies[i];
3935
3936       vat_json_init_object (e);
3937       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3938                   a->leid_prefix_len);
3939       vec_add1 (s, 0);
3940       vat_json_object_add_string_copy (e, "leid", s);
3941       vec_free (s);
3942
3943       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3944                   a->reid_prefix_len);
3945       vec_add1 (s, 0);
3946       vat_json_object_add_string_copy (e, "reid", s);
3947       vec_free (s);
3948     }
3949
3950   vat_json_print (vam->ofp, &root);
3951   vat_json_free (&root);
3952
3953 end:
3954   vam->retval = retval;
3955   vam->result_ready = 1;
3956 }
3957
3958 static void
3959 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3960 {
3961   vat_main_t *vam = &vat_main;
3962
3963   print (vam->ofp, "%=20U",
3964          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3965          mp->ip_address);
3966 }
3967
3968 static void
3969   vl_api_one_map_server_details_t_handler_json
3970   (vl_api_one_map_server_details_t * mp)
3971 {
3972   vat_main_t *vam = &vat_main;
3973   vat_json_node_t *node = NULL;
3974   struct in6_addr ip6;
3975   struct in_addr ip4;
3976
3977   if (VAT_JSON_ARRAY != vam->json_tree.type)
3978     {
3979       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3980       vat_json_init_array (&vam->json_tree);
3981     }
3982   node = vat_json_array_add (&vam->json_tree);
3983
3984   vat_json_init_object (node);
3985   if (mp->is_ipv6)
3986     {
3987       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3988       vat_json_object_add_ip6 (node, "map-server", ip6);
3989     }
3990   else
3991     {
3992       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3993       vat_json_object_add_ip4 (node, "map-server", ip4);
3994     }
3995 }
3996
3997 static void
3998 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3999                                            * mp)
4000 {
4001   vat_main_t *vam = &vat_main;
4002
4003   print (vam->ofp, "%=20U",
4004          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4005          mp->ip_address);
4006 }
4007
4008 static void
4009   vl_api_one_map_resolver_details_t_handler_json
4010   (vl_api_one_map_resolver_details_t * mp)
4011 {
4012   vat_main_t *vam = &vat_main;
4013   vat_json_node_t *node = NULL;
4014   struct in6_addr ip6;
4015   struct in_addr ip4;
4016
4017   if (VAT_JSON_ARRAY != vam->json_tree.type)
4018     {
4019       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4020       vat_json_init_array (&vam->json_tree);
4021     }
4022   node = vat_json_array_add (&vam->json_tree);
4023
4024   vat_json_init_object (node);
4025   if (mp->is_ipv6)
4026     {
4027       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4028       vat_json_object_add_ip6 (node, "map resolver", ip6);
4029     }
4030   else
4031     {
4032       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4033       vat_json_object_add_ip4 (node, "map resolver", ip4);
4034     }
4035 }
4036
4037 static void
4038 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4039 {
4040   vat_main_t *vam = &vat_main;
4041   i32 retval = ntohl (mp->retval);
4042
4043   if (0 <= retval)
4044     {
4045       print (vam->ofp, "feature: %s\ngpe: %s",
4046              mp->feature_status ? "enabled" : "disabled",
4047              mp->gpe_status ? "enabled" : "disabled");
4048     }
4049
4050   vam->retval = retval;
4051   vam->result_ready = 1;
4052 }
4053
4054 static void
4055   vl_api_show_one_status_reply_t_handler_json
4056   (vl_api_show_one_status_reply_t * mp)
4057 {
4058   vat_main_t *vam = &vat_main;
4059   vat_json_node_t node;
4060   u8 *gpe_status = NULL;
4061   u8 *feature_status = NULL;
4062
4063   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4064   feature_status = format (0, "%s",
4065                            mp->feature_status ? "enabled" : "disabled");
4066   vec_add1 (gpe_status, 0);
4067   vec_add1 (feature_status, 0);
4068
4069   vat_json_init_object (&node);
4070   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4071   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4072
4073   vec_free (gpe_status);
4074   vec_free (feature_status);
4075
4076   vat_json_print (vam->ofp, &node);
4077   vat_json_free (&node);
4078
4079   vam->retval = ntohl (mp->retval);
4080   vam->result_ready = 1;
4081 }
4082
4083 static void
4084   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4085   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4086 {
4087   vat_main_t *vam = &vat_main;
4088   i32 retval = ntohl (mp->retval);
4089
4090   if (retval >= 0)
4091     {
4092       print (vam->ofp, "%=20s", mp->locator_set_name);
4093     }
4094
4095   vam->retval = retval;
4096   vam->result_ready = 1;
4097 }
4098
4099 static void
4100   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4101   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4102 {
4103   vat_main_t *vam = &vat_main;
4104   vat_json_node_t *node = NULL;
4105
4106   if (VAT_JSON_ARRAY != vam->json_tree.type)
4107     {
4108       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4109       vat_json_init_array (&vam->json_tree);
4110     }
4111   node = vat_json_array_add (&vam->json_tree);
4112
4113   vat_json_init_object (node);
4114   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4115
4116   vat_json_print (vam->ofp, node);
4117   vat_json_free (node);
4118
4119   vam->retval = ntohl (mp->retval);
4120   vam->result_ready = 1;
4121 }
4122
4123 static u8 *
4124 format_lisp_map_request_mode (u8 * s, va_list * args)
4125 {
4126   u32 mode = va_arg (*args, u32);
4127
4128   switch (mode)
4129     {
4130     case 0:
4131       return format (0, "dst-only");
4132     case 1:
4133       return format (0, "src-dst");
4134     }
4135   return 0;
4136 }
4137
4138 static void
4139   vl_api_show_one_map_request_mode_reply_t_handler
4140   (vl_api_show_one_map_request_mode_reply_t * mp)
4141 {
4142   vat_main_t *vam = &vat_main;
4143   i32 retval = ntohl (mp->retval);
4144
4145   if (0 <= retval)
4146     {
4147       u32 mode = mp->mode;
4148       print (vam->ofp, "map_request_mode: %U",
4149              format_lisp_map_request_mode, mode);
4150     }
4151
4152   vam->retval = retval;
4153   vam->result_ready = 1;
4154 }
4155
4156 static void
4157   vl_api_show_one_map_request_mode_reply_t_handler_json
4158   (vl_api_show_one_map_request_mode_reply_t * mp)
4159 {
4160   vat_main_t *vam = &vat_main;
4161   vat_json_node_t node;
4162   u8 *s = 0;
4163   u32 mode;
4164
4165   mode = mp->mode;
4166   s = format (0, "%U", format_lisp_map_request_mode, mode);
4167   vec_add1 (s, 0);
4168
4169   vat_json_init_object (&node);
4170   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4171   vat_json_print (vam->ofp, &node);
4172   vat_json_free (&node);
4173
4174   vec_free (s);
4175   vam->retval = ntohl (mp->retval);
4176   vam->result_ready = 1;
4177 }
4178
4179 static void
4180   vl_api_show_one_use_petr_reply_t_handler
4181   (vl_api_show_one_use_petr_reply_t * mp)
4182 {
4183   vat_main_t *vam = &vat_main;
4184   i32 retval = ntohl (mp->retval);
4185
4186   if (0 <= retval)
4187     {
4188       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4189       if (mp->status)
4190         {
4191           print (vam->ofp, "Proxy-ETR address; %U",
4192                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4193                  mp->address);
4194         }
4195     }
4196
4197   vam->retval = retval;
4198   vam->result_ready = 1;
4199 }
4200
4201 static void
4202   vl_api_show_one_use_petr_reply_t_handler_json
4203   (vl_api_show_one_use_petr_reply_t * mp)
4204 {
4205   vat_main_t *vam = &vat_main;
4206   vat_json_node_t node;
4207   u8 *status = 0;
4208   struct in_addr ip4;
4209   struct in6_addr ip6;
4210
4211   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4212   vec_add1 (status, 0);
4213
4214   vat_json_init_object (&node);
4215   vat_json_object_add_string_copy (&node, "status", status);
4216   if (mp->status)
4217     {
4218       if (mp->is_ip4)
4219         {
4220           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4221           vat_json_object_add_ip6 (&node, "address", ip6);
4222         }
4223       else
4224         {
4225           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4226           vat_json_object_add_ip4 (&node, "address", ip4);
4227         }
4228     }
4229
4230   vec_free (status);
4231
4232   vat_json_print (vam->ofp, &node);
4233   vat_json_free (&node);
4234
4235   vam->retval = ntohl (mp->retval);
4236   vam->result_ready = 1;
4237 }
4238
4239 static void
4240   vl_api_show_one_nsh_mapping_reply_t_handler
4241   (vl_api_show_one_nsh_mapping_reply_t * mp)
4242 {
4243   vat_main_t *vam = &vat_main;
4244   i32 retval = ntohl (mp->retval);
4245
4246   if (0 <= retval)
4247     {
4248       print (vam->ofp, "%-20s%-16s",
4249              mp->is_set ? "set" : "not-set",
4250              mp->is_set ? (char *) mp->locator_set_name : "");
4251     }
4252
4253   vam->retval = retval;
4254   vam->result_ready = 1;
4255 }
4256
4257 static void
4258   vl_api_show_one_nsh_mapping_reply_t_handler_json
4259   (vl_api_show_one_nsh_mapping_reply_t * mp)
4260 {
4261   vat_main_t *vam = &vat_main;
4262   vat_json_node_t node;
4263   u8 *status = 0;
4264
4265   status = format (0, "%s", mp->is_set ? "yes" : "no");
4266   vec_add1 (status, 0);
4267
4268   vat_json_init_object (&node);
4269   vat_json_object_add_string_copy (&node, "is_set", status);
4270   if (mp->is_set)
4271     {
4272       vat_json_object_add_string_copy (&node, "locator_set",
4273                                        mp->locator_set_name);
4274     }
4275
4276   vec_free (status);
4277
4278   vat_json_print (vam->ofp, &node);
4279   vat_json_free (&node);
4280
4281   vam->retval = ntohl (mp->retval);
4282   vam->result_ready = 1;
4283 }
4284
4285 static void
4286   vl_api_show_one_map_register_ttl_reply_t_handler
4287   (vl_api_show_one_map_register_ttl_reply_t * mp)
4288 {
4289   vat_main_t *vam = &vat_main;
4290   i32 retval = ntohl (mp->retval);
4291
4292   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4293
4294   if (0 <= retval)
4295     {
4296       print (vam->ofp, "ttl: %u", mp->ttl);
4297     }
4298
4299   vam->retval = retval;
4300   vam->result_ready = 1;
4301 }
4302
4303 static void
4304   vl_api_show_one_map_register_ttl_reply_t_handler_json
4305   (vl_api_show_one_map_register_ttl_reply_t * mp)
4306 {
4307   vat_main_t *vam = &vat_main;
4308   vat_json_node_t node;
4309
4310   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4311   vat_json_init_object (&node);
4312   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4313
4314   vat_json_print (vam->ofp, &node);
4315   vat_json_free (&node);
4316
4317   vam->retval = ntohl (mp->retval);
4318   vam->result_ready = 1;
4319 }
4320
4321 static void
4322 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4323 {
4324   vat_main_t *vam = &vat_main;
4325   i32 retval = ntohl (mp->retval);
4326
4327   if (0 <= retval)
4328     {
4329       print (vam->ofp, "%-20s%-16s",
4330              mp->status ? "enabled" : "disabled",
4331              mp->status ? (char *) mp->locator_set_name : "");
4332     }
4333
4334   vam->retval = retval;
4335   vam->result_ready = 1;
4336 }
4337
4338 static void
4339 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4340 {
4341   vat_main_t *vam = &vat_main;
4342   vat_json_node_t node;
4343   u8 *status = 0;
4344
4345   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4346   vec_add1 (status, 0);
4347
4348   vat_json_init_object (&node);
4349   vat_json_object_add_string_copy (&node, "status", status);
4350   if (mp->status)
4351     {
4352       vat_json_object_add_string_copy (&node, "locator_set",
4353                                        mp->locator_set_name);
4354     }
4355
4356   vec_free (status);
4357
4358   vat_json_print (vam->ofp, &node);
4359   vat_json_free (&node);
4360
4361   vam->retval = ntohl (mp->retval);
4362   vam->result_ready = 1;
4363 }
4364
4365 static u8 *
4366 format_policer_type (u8 * s, va_list * va)
4367 {
4368   u32 i = va_arg (*va, u32);
4369
4370   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4371     s = format (s, "1r2c");
4372   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4373     s = format (s, "1r3c");
4374   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4375     s = format (s, "2r3c-2698");
4376   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4377     s = format (s, "2r3c-4115");
4378   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4379     s = format (s, "2r3c-mef5cf1");
4380   else
4381     s = format (s, "ILLEGAL");
4382   return s;
4383 }
4384
4385 static u8 *
4386 format_policer_rate_type (u8 * s, va_list * va)
4387 {
4388   u32 i = va_arg (*va, u32);
4389
4390   if (i == SSE2_QOS_RATE_KBPS)
4391     s = format (s, "kbps");
4392   else if (i == SSE2_QOS_RATE_PPS)
4393     s = format (s, "pps");
4394   else
4395     s = format (s, "ILLEGAL");
4396   return s;
4397 }
4398
4399 static u8 *
4400 format_policer_round_type (u8 * s, va_list * va)
4401 {
4402   u32 i = va_arg (*va, u32);
4403
4404   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4405     s = format (s, "closest");
4406   else if (i == SSE2_QOS_ROUND_TO_UP)
4407     s = format (s, "up");
4408   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4409     s = format (s, "down");
4410   else
4411     s = format (s, "ILLEGAL");
4412   return s;
4413 }
4414
4415 static u8 *
4416 format_policer_action_type (u8 * s, va_list * va)
4417 {
4418   u32 i = va_arg (*va, u32);
4419
4420   if (i == SSE2_QOS_ACTION_DROP)
4421     s = format (s, "drop");
4422   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4423     s = format (s, "transmit");
4424   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4425     s = format (s, "mark-and-transmit");
4426   else
4427     s = format (s, "ILLEGAL");
4428   return s;
4429 }
4430
4431 static u8 *
4432 format_dscp (u8 * s, va_list * va)
4433 {
4434   u32 i = va_arg (*va, u32);
4435   char *t = 0;
4436
4437   switch (i)
4438     {
4439 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4440       foreach_vnet_dscp
4441 #undef _
4442     default:
4443       return format (s, "ILLEGAL");
4444     }
4445   s = format (s, "%s", t);
4446   return s;
4447 }
4448
4449 static void
4450 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4451 {
4452   vat_main_t *vam = &vat_main;
4453   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4454
4455   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4456     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4457   else
4458     conform_dscp_str = format (0, "");
4459
4460   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4461     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4462   else
4463     exceed_dscp_str = format (0, "");
4464
4465   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4466     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4467   else
4468     violate_dscp_str = format (0, "");
4469
4470   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4471          "rate type %U, round type %U, %s rate, %s color-aware, "
4472          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4473          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4474          "conform action %U%s, exceed action %U%s, violate action %U%s",
4475          mp->name,
4476          format_policer_type, mp->type,
4477          ntohl (mp->cir),
4478          ntohl (mp->eir),
4479          clib_net_to_host_u64 (mp->cb),
4480          clib_net_to_host_u64 (mp->eb),
4481          format_policer_rate_type, mp->rate_type,
4482          format_policer_round_type, mp->round_type,
4483          mp->single_rate ? "single" : "dual",
4484          mp->color_aware ? "is" : "not",
4485          ntohl (mp->cir_tokens_per_period),
4486          ntohl (mp->pir_tokens_per_period),
4487          ntohl (mp->scale),
4488          ntohl (mp->current_limit),
4489          ntohl (mp->current_bucket),
4490          ntohl (mp->extended_limit),
4491          ntohl (mp->extended_bucket),
4492          clib_net_to_host_u64 (mp->last_update_time),
4493          format_policer_action_type, mp->conform_action_type,
4494          conform_dscp_str,
4495          format_policer_action_type, mp->exceed_action_type,
4496          exceed_dscp_str,
4497          format_policer_action_type, mp->violate_action_type,
4498          violate_dscp_str);
4499
4500   vec_free (conform_dscp_str);
4501   vec_free (exceed_dscp_str);
4502   vec_free (violate_dscp_str);
4503 }
4504
4505 static void vl_api_policer_details_t_handler_json
4506   (vl_api_policer_details_t * mp)
4507 {
4508   vat_main_t *vam = &vat_main;
4509   vat_json_node_t *node;
4510   u8 *rate_type_str, *round_type_str, *type_str;
4511   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4512
4513   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4514   round_type_str =
4515     format (0, "%U", format_policer_round_type, mp->round_type);
4516   type_str = format (0, "%U", format_policer_type, mp->type);
4517   conform_action_str = format (0, "%U", format_policer_action_type,
4518                                mp->conform_action_type);
4519   exceed_action_str = format (0, "%U", format_policer_action_type,
4520                               mp->exceed_action_type);
4521   violate_action_str = format (0, "%U", format_policer_action_type,
4522                                mp->violate_action_type);
4523
4524   if (VAT_JSON_ARRAY != vam->json_tree.type)
4525     {
4526       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4527       vat_json_init_array (&vam->json_tree);
4528     }
4529   node = vat_json_array_add (&vam->json_tree);
4530
4531   vat_json_init_object (node);
4532   vat_json_object_add_string_copy (node, "name", mp->name);
4533   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4534   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4535   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4536   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4537   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4538   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4539   vat_json_object_add_string_copy (node, "type", type_str);
4540   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4541   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4542   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4543   vat_json_object_add_uint (node, "cir_tokens_per_period",
4544                             ntohl (mp->cir_tokens_per_period));
4545   vat_json_object_add_uint (node, "eir_tokens_per_period",
4546                             ntohl (mp->pir_tokens_per_period));
4547   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4548   vat_json_object_add_uint (node, "current_bucket",
4549                             ntohl (mp->current_bucket));
4550   vat_json_object_add_uint (node, "extended_limit",
4551                             ntohl (mp->extended_limit));
4552   vat_json_object_add_uint (node, "extended_bucket",
4553                             ntohl (mp->extended_bucket));
4554   vat_json_object_add_uint (node, "last_update_time",
4555                             ntohl (mp->last_update_time));
4556   vat_json_object_add_string_copy (node, "conform_action",
4557                                    conform_action_str);
4558   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4559     {
4560       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4561       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4562       vec_free (dscp_str);
4563     }
4564   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4565   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4566     {
4567       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4568       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4569       vec_free (dscp_str);
4570     }
4571   vat_json_object_add_string_copy (node, "violate_action",
4572                                    violate_action_str);
4573   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4574     {
4575       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4576       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4577       vec_free (dscp_str);
4578     }
4579
4580   vec_free (rate_type_str);
4581   vec_free (round_type_str);
4582   vec_free (type_str);
4583   vec_free (conform_action_str);
4584   vec_free (exceed_action_str);
4585   vec_free (violate_action_str);
4586 }
4587
4588 static void
4589 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4590                                            mp)
4591 {
4592   vat_main_t *vam = &vat_main;
4593   int i, count = ntohl (mp->count);
4594
4595   if (count > 0)
4596     print (vam->ofp, "classify table ids (%d) : ", count);
4597   for (i = 0; i < count; i++)
4598     {
4599       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4600       print (vam->ofp, (i < count - 1) ? "," : "");
4601     }
4602   vam->retval = ntohl (mp->retval);
4603   vam->result_ready = 1;
4604 }
4605
4606 static void
4607   vl_api_classify_table_ids_reply_t_handler_json
4608   (vl_api_classify_table_ids_reply_t * mp)
4609 {
4610   vat_main_t *vam = &vat_main;
4611   int i, count = ntohl (mp->count);
4612
4613   if (count > 0)
4614     {
4615       vat_json_node_t node;
4616
4617       vat_json_init_object (&node);
4618       for (i = 0; i < count; i++)
4619         {
4620           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4621         }
4622       vat_json_print (vam->ofp, &node);
4623       vat_json_free (&node);
4624     }
4625   vam->retval = ntohl (mp->retval);
4626   vam->result_ready = 1;
4627 }
4628
4629 static void
4630   vl_api_classify_table_by_interface_reply_t_handler
4631   (vl_api_classify_table_by_interface_reply_t * mp)
4632 {
4633   vat_main_t *vam = &vat_main;
4634   u32 table_id;
4635
4636   table_id = ntohl (mp->l2_table_id);
4637   if (table_id != ~0)
4638     print (vam->ofp, "l2 table id : %d", table_id);
4639   else
4640     print (vam->ofp, "l2 table id : No input ACL tables configured");
4641   table_id = ntohl (mp->ip4_table_id);
4642   if (table_id != ~0)
4643     print (vam->ofp, "ip4 table id : %d", table_id);
4644   else
4645     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4646   table_id = ntohl (mp->ip6_table_id);
4647   if (table_id != ~0)
4648     print (vam->ofp, "ip6 table id : %d", table_id);
4649   else
4650     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4651   vam->retval = ntohl (mp->retval);
4652   vam->result_ready = 1;
4653 }
4654
4655 static void
4656   vl_api_classify_table_by_interface_reply_t_handler_json
4657   (vl_api_classify_table_by_interface_reply_t * mp)
4658 {
4659   vat_main_t *vam = &vat_main;
4660   vat_json_node_t node;
4661
4662   vat_json_init_object (&node);
4663
4664   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4665   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4666   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4667
4668   vat_json_print (vam->ofp, &node);
4669   vat_json_free (&node);
4670
4671   vam->retval = ntohl (mp->retval);
4672   vam->result_ready = 1;
4673 }
4674
4675 static void vl_api_policer_add_del_reply_t_handler
4676   (vl_api_policer_add_del_reply_t * mp)
4677 {
4678   vat_main_t *vam = &vat_main;
4679   i32 retval = ntohl (mp->retval);
4680   if (vam->async_mode)
4681     {
4682       vam->async_errors += (retval < 0);
4683     }
4684   else
4685     {
4686       vam->retval = retval;
4687       vam->result_ready = 1;
4688       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4689         /*
4690          * Note: this is just barely thread-safe, depends on
4691          * the main thread spinning waiting for an answer...
4692          */
4693         errmsg ("policer index %d", ntohl (mp->policer_index));
4694     }
4695 }
4696
4697 static void vl_api_policer_add_del_reply_t_handler_json
4698   (vl_api_policer_add_del_reply_t * mp)
4699 {
4700   vat_main_t *vam = &vat_main;
4701   vat_json_node_t node;
4702
4703   vat_json_init_object (&node);
4704   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4705   vat_json_object_add_uint (&node, "policer_index",
4706                             ntohl (mp->policer_index));
4707
4708   vat_json_print (vam->ofp, &node);
4709   vat_json_free (&node);
4710
4711   vam->retval = ntohl (mp->retval);
4712   vam->result_ready = 1;
4713 }
4714
4715 /* Format hex dump. */
4716 u8 *
4717 format_hex_bytes (u8 * s, va_list * va)
4718 {
4719   u8 *bytes = va_arg (*va, u8 *);
4720   int n_bytes = va_arg (*va, int);
4721   uword i;
4722
4723   /* Print short or long form depending on byte count. */
4724   uword short_form = n_bytes <= 32;
4725   u32 indent = format_get_indent (s);
4726
4727   if (n_bytes == 0)
4728     return s;
4729
4730   for (i = 0; i < n_bytes; i++)
4731     {
4732       if (!short_form && (i % 32) == 0)
4733         s = format (s, "%08x: ", i);
4734       s = format (s, "%02x", bytes[i]);
4735       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4736         s = format (s, "\n%U", format_white_space, indent);
4737     }
4738
4739   return s;
4740 }
4741
4742 static void
4743 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4744                                             * mp)
4745 {
4746   vat_main_t *vam = &vat_main;
4747   i32 retval = ntohl (mp->retval);
4748   if (retval == 0)
4749     {
4750       print (vam->ofp, "classify table info :");
4751       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4752              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4753              ntohl (mp->miss_next_index));
4754       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4755              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4756              ntohl (mp->match_n_vectors));
4757       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4758              ntohl (mp->mask_length));
4759     }
4760   vam->retval = retval;
4761   vam->result_ready = 1;
4762 }
4763
4764 static void
4765   vl_api_classify_table_info_reply_t_handler_json
4766   (vl_api_classify_table_info_reply_t * mp)
4767 {
4768   vat_main_t *vam = &vat_main;
4769   vat_json_node_t node;
4770
4771   i32 retval = ntohl (mp->retval);
4772   if (retval == 0)
4773     {
4774       vat_json_init_object (&node);
4775
4776       vat_json_object_add_int (&node, "sessions",
4777                                ntohl (mp->active_sessions));
4778       vat_json_object_add_int (&node, "nexttbl",
4779                                ntohl (mp->next_table_index));
4780       vat_json_object_add_int (&node, "nextnode",
4781                                ntohl (mp->miss_next_index));
4782       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4783       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4784       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4785       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4786                       ntohl (mp->mask_length), 0);
4787       vat_json_object_add_string_copy (&node, "mask", s);
4788
4789       vat_json_print (vam->ofp, &node);
4790       vat_json_free (&node);
4791     }
4792   vam->retval = ntohl (mp->retval);
4793   vam->result_ready = 1;
4794 }
4795
4796 static void
4797 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4798                                            mp)
4799 {
4800   vat_main_t *vam = &vat_main;
4801
4802   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4803          ntohl (mp->hit_next_index), ntohl (mp->advance),
4804          ntohl (mp->opaque_index));
4805   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4806          ntohl (mp->match_length));
4807 }
4808
4809 static void
4810   vl_api_classify_session_details_t_handler_json
4811   (vl_api_classify_session_details_t * mp)
4812 {
4813   vat_main_t *vam = &vat_main;
4814   vat_json_node_t *node = NULL;
4815
4816   if (VAT_JSON_ARRAY != vam->json_tree.type)
4817     {
4818       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4819       vat_json_init_array (&vam->json_tree);
4820     }
4821   node = vat_json_array_add (&vam->json_tree);
4822
4823   vat_json_init_object (node);
4824   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4825   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4826   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4827   u8 *s =
4828     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4829             0);
4830   vat_json_object_add_string_copy (node, "match", s);
4831 }
4832
4833 static void vl_api_pg_create_interface_reply_t_handler
4834   (vl_api_pg_create_interface_reply_t * mp)
4835 {
4836   vat_main_t *vam = &vat_main;
4837
4838   vam->retval = ntohl (mp->retval);
4839   vam->result_ready = 1;
4840 }
4841
4842 static void vl_api_pg_create_interface_reply_t_handler_json
4843   (vl_api_pg_create_interface_reply_t * mp)
4844 {
4845   vat_main_t *vam = &vat_main;
4846   vat_json_node_t node;
4847
4848   i32 retval = ntohl (mp->retval);
4849   if (retval == 0)
4850     {
4851       vat_json_init_object (&node);
4852
4853       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4854
4855       vat_json_print (vam->ofp, &node);
4856       vat_json_free (&node);
4857     }
4858   vam->retval = ntohl (mp->retval);
4859   vam->result_ready = 1;
4860 }
4861
4862 static void vl_api_policer_classify_details_t_handler
4863   (vl_api_policer_classify_details_t * mp)
4864 {
4865   vat_main_t *vam = &vat_main;
4866
4867   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4868          ntohl (mp->table_index));
4869 }
4870
4871 static void vl_api_policer_classify_details_t_handler_json
4872   (vl_api_policer_classify_details_t * mp)
4873 {
4874   vat_main_t *vam = &vat_main;
4875   vat_json_node_t *node;
4876
4877   if (VAT_JSON_ARRAY != vam->json_tree.type)
4878     {
4879       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4880       vat_json_init_array (&vam->json_tree);
4881     }
4882   node = vat_json_array_add (&vam->json_tree);
4883
4884   vat_json_init_object (node);
4885   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4886   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4887 }
4888
4889 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
4890   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4891 {
4892   vat_main_t *vam = &vat_main;
4893   i32 retval = ntohl (mp->retval);
4894   if (vam->async_mode)
4895     {
4896       vam->async_errors += (retval < 0);
4897     }
4898   else
4899     {
4900       vam->retval = retval;
4901       vam->sw_if_index = ntohl (mp->sw_if_index);
4902       vam->result_ready = 1;
4903     }
4904 }
4905
4906 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
4907   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
4908 {
4909   vat_main_t *vam = &vat_main;
4910   vat_json_node_t node;
4911
4912   vat_json_init_object (&node);
4913   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4914   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
4915
4916   vat_json_print (vam->ofp, &node);
4917   vat_json_free (&node);
4918
4919   vam->retval = ntohl (mp->retval);
4920   vam->result_ready = 1;
4921 }
4922
4923 static void vl_api_flow_classify_details_t_handler
4924   (vl_api_flow_classify_details_t * mp)
4925 {
4926   vat_main_t *vam = &vat_main;
4927
4928   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4929          ntohl (mp->table_index));
4930 }
4931
4932 static void vl_api_flow_classify_details_t_handler_json
4933   (vl_api_flow_classify_details_t * mp)
4934 {
4935   vat_main_t *vam = &vat_main;
4936   vat_json_node_t *node;
4937
4938   if (VAT_JSON_ARRAY != vam->json_tree.type)
4939     {
4940       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4941       vat_json_init_array (&vam->json_tree);
4942     }
4943   node = vat_json_array_add (&vam->json_tree);
4944
4945   vat_json_init_object (node);
4946   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4947   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4948 }
4949
4950 #define vl_api_vnet_interface_simple_counters_t_endian vl_noop_handler
4951 #define vl_api_vnet_interface_simple_counters_t_print vl_noop_handler
4952 #define vl_api_vnet_interface_combined_counters_t_endian vl_noop_handler
4953 #define vl_api_vnet_interface_combined_counters_t_print vl_noop_handler
4954 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
4955 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
4956 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
4957 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
4958 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
4959 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
4960 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
4961 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
4962 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
4963 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
4964 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
4965 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
4966 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
4967 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
4968 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
4969 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
4970 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
4971 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
4972
4973 /*
4974  * Generate boilerplate reply handlers, which
4975  * dig the return value out of the xxx_reply_t API message,
4976  * stick it into vam->retval, and set vam->result_ready
4977  *
4978  * Could also do this by pointing N message decode slots at
4979  * a single function, but that could break in subtle ways.
4980  */
4981
4982 #define foreach_standard_reply_retval_handler           \
4983 _(sw_interface_set_flags_reply)                         \
4984 _(sw_interface_add_del_address_reply)                   \
4985 _(sw_interface_set_table_reply)                         \
4986 _(sw_interface_set_mpls_enable_reply)                   \
4987 _(sw_interface_set_vpath_reply)                         \
4988 _(sw_interface_set_vxlan_bypass_reply)                  \
4989 _(sw_interface_set_geneve_bypass_reply)                 \
4990 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
4991 _(sw_interface_set_l2_bridge_reply)                     \
4992 _(bridge_domain_add_del_reply)                          \
4993 _(sw_interface_set_l2_xconnect_reply)                   \
4994 _(l2fib_add_del_reply)                                  \
4995 _(l2fib_flush_int_reply)                                \
4996 _(l2fib_flush_bd_reply)                                 \
4997 _(ip_add_del_route_reply)                               \
4998 _(ip_table_add_del_reply)                               \
4999 _(ip_mroute_add_del_reply)                              \
5000 _(mpls_route_add_del_reply)                             \
5001 _(mpls_table_add_del_reply)                             \
5002 _(mpls_ip_bind_unbind_reply)                            \
5003 _(proxy_arp_add_del_reply)                              \
5004 _(proxy_arp_intfc_enable_disable_reply)                 \
5005 _(sw_interface_set_unnumbered_reply)                    \
5006 _(ip_neighbor_add_del_reply)                            \
5007 _(reset_vrf_reply)                                      \
5008 _(oam_add_del_reply)                                    \
5009 _(reset_fib_reply)                                      \
5010 _(dhcp_proxy_config_reply)                              \
5011 _(dhcp_proxy_set_vss_reply)                             \
5012 _(dhcp_client_config_reply)                             \
5013 _(set_ip_flow_hash_reply)                               \
5014 _(sw_interface_ip6_enable_disable_reply)                \
5015 _(sw_interface_ip6_set_link_local_address_reply)        \
5016 _(ip6nd_proxy_add_del_reply)                            \
5017 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5018 _(sw_interface_ip6nd_ra_config_reply)                   \
5019 _(set_arp_neighbor_limit_reply)                         \
5020 _(l2_patch_add_del_reply)                               \
5021 _(sr_policy_add_reply)                                  \
5022 _(sr_policy_mod_reply)                                  \
5023 _(sr_policy_del_reply)                                  \
5024 _(sr_localsid_add_del_reply)                            \
5025 _(sr_steering_add_del_reply)                            \
5026 _(classify_add_del_session_reply)                       \
5027 _(classify_set_interface_ip_table_reply)                \
5028 _(classify_set_interface_l2_tables_reply)               \
5029 _(l2tpv3_set_tunnel_cookies_reply)                      \
5030 _(l2tpv3_interface_enable_disable_reply)                \
5031 _(l2tpv3_set_lookup_key_reply)                          \
5032 _(l2_fib_clear_table_reply)                             \
5033 _(l2_interface_efp_filter_reply)                        \
5034 _(l2_interface_vlan_tag_rewrite_reply)                  \
5035 _(modify_vhost_user_if_reply)                           \
5036 _(delete_vhost_user_if_reply)                           \
5037 _(want_ip4_arp_events_reply)                            \
5038 _(want_ip6_nd_events_reply)                             \
5039 _(want_l2_macs_events_reply)                            \
5040 _(input_acl_set_interface_reply)                        \
5041 _(ipsec_spd_add_del_reply)                              \
5042 _(ipsec_interface_add_del_spd_reply)                    \
5043 _(ipsec_spd_add_del_entry_reply)                        \
5044 _(ipsec_sad_add_del_entry_reply)                        \
5045 _(ipsec_sa_set_key_reply)                               \
5046 _(ipsec_tunnel_if_add_del_reply)                        \
5047 _(ikev2_profile_add_del_reply)                          \
5048 _(ikev2_profile_set_auth_reply)                         \
5049 _(ikev2_profile_set_id_reply)                           \
5050 _(ikev2_profile_set_ts_reply)                           \
5051 _(ikev2_set_local_key_reply)                            \
5052 _(ikev2_set_responder_reply)                            \
5053 _(ikev2_set_ike_transforms_reply)                       \
5054 _(ikev2_set_esp_transforms_reply)                       \
5055 _(ikev2_set_sa_lifetime_reply)                          \
5056 _(ikev2_initiate_sa_init_reply)                         \
5057 _(ikev2_initiate_del_ike_sa_reply)                      \
5058 _(ikev2_initiate_del_child_sa_reply)                    \
5059 _(ikev2_initiate_rekey_child_sa_reply)                  \
5060 _(delete_loopback_reply)                                \
5061 _(bd_ip_mac_add_del_reply)                              \
5062 _(map_del_domain_reply)                                 \
5063 _(map_add_del_rule_reply)                               \
5064 _(want_interface_events_reply)                          \
5065 _(want_stats_reply)                                     \
5066 _(cop_interface_enable_disable_reply)                   \
5067 _(cop_whitelist_enable_disable_reply)                   \
5068 _(sw_interface_clear_stats_reply)                       \
5069 _(ioam_enable_reply)                              \
5070 _(ioam_disable_reply)                              \
5071 _(one_add_del_locator_reply)                            \
5072 _(one_add_del_local_eid_reply)                          \
5073 _(one_add_del_remote_mapping_reply)                     \
5074 _(one_add_del_adjacency_reply)                          \
5075 _(one_add_del_map_resolver_reply)                       \
5076 _(one_add_del_map_server_reply)                         \
5077 _(one_enable_disable_reply)                             \
5078 _(one_rloc_probe_enable_disable_reply)                  \
5079 _(one_map_register_enable_disable_reply)                \
5080 _(one_map_register_set_ttl_reply)                       \
5081 _(one_set_transport_protocol_reply)                     \
5082 _(one_map_register_fallback_threshold_reply)            \
5083 _(one_pitr_set_locator_set_reply)                       \
5084 _(one_map_request_mode_reply)                           \
5085 _(one_add_del_map_request_itr_rlocs_reply)              \
5086 _(one_eid_table_add_del_map_reply)                      \
5087 _(one_use_petr_reply)                                   \
5088 _(one_stats_enable_disable_reply)                       \
5089 _(one_add_del_l2_arp_entry_reply)                       \
5090 _(one_add_del_ndp_entry_reply)                          \
5091 _(one_stats_flush_reply)                                \
5092 _(gpe_enable_disable_reply)                             \
5093 _(gpe_set_encap_mode_reply)                             \
5094 _(gpe_add_del_iface_reply)                              \
5095 _(gpe_add_del_native_fwd_rpath_reply)                   \
5096 _(af_packet_delete_reply)                               \
5097 _(policer_classify_set_interface_reply)                 \
5098 _(netmap_create_reply)                                  \
5099 _(netmap_delete_reply)                                  \
5100 _(set_ipfix_exporter_reply)                             \
5101 _(set_ipfix_classify_stream_reply)                      \
5102 _(ipfix_classify_table_add_del_reply)                   \
5103 _(flow_classify_set_interface_reply)                    \
5104 _(sw_interface_span_enable_disable_reply)               \
5105 _(pg_capture_reply)                                     \
5106 _(pg_enable_disable_reply)                              \
5107 _(ip_source_and_port_range_check_add_del_reply)         \
5108 _(ip_source_and_port_range_check_interface_add_del_reply)\
5109 _(delete_subif_reply)                                   \
5110 _(l2_interface_pbb_tag_rewrite_reply)                   \
5111 _(punt_reply)                                           \
5112 _(feature_enable_disable_reply)                         \
5113 _(sw_interface_tag_add_del_reply)                       \
5114 _(sw_interface_set_mtu_reply)                           \
5115 _(p2p_ethernet_add_reply)                               \
5116 _(p2p_ethernet_del_reply)                               \
5117 _(lldp_config_reply)                                    \
5118 _(sw_interface_set_lldp_reply)                          \
5119 _(tcp_configure_src_addresses_reply)
5120
5121 #define _(n)                                    \
5122     static void vl_api_##n##_t_handler          \
5123     (vl_api_##n##_t * mp)                       \
5124     {                                           \
5125         vat_main_t * vam = &vat_main;           \
5126         i32 retval = ntohl(mp->retval);         \
5127         if (vam->async_mode) {                  \
5128             vam->async_errors += (retval < 0);  \
5129         } else {                                \
5130             vam->retval = retval;               \
5131             vam->result_ready = 1;              \
5132         }                                       \
5133     }
5134 foreach_standard_reply_retval_handler;
5135 #undef _
5136
5137 #define _(n)                                    \
5138     static void vl_api_##n##_t_handler_json     \
5139     (vl_api_##n##_t * mp)                       \
5140     {                                           \
5141         vat_main_t * vam = &vat_main;           \
5142         vat_json_node_t node;                   \
5143         vat_json_init_object(&node);            \
5144         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5145         vat_json_print(vam->ofp, &node);        \
5146         vam->retval = ntohl(mp->retval);        \
5147         vam->result_ready = 1;                  \
5148     }
5149 foreach_standard_reply_retval_handler;
5150 #undef _
5151
5152 /*
5153  * Table of message reply handlers, must include boilerplate handlers
5154  * we just generated
5155  */
5156
5157 #define foreach_vpe_api_reply_msg                                       \
5158 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5159 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5160 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5161 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5162 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5163 _(CLI_REPLY, cli_reply)                                                 \
5164 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5165 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5166   sw_interface_add_del_address_reply)                                   \
5167 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5168 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5169 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5170 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5171 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5172 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5173 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5174   sw_interface_set_l2_xconnect_reply)                                   \
5175 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5176   sw_interface_set_l2_bridge_reply)                                     \
5177 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5178 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5179 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5180 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5181 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5182 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5183 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5184 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5185 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5186 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5187 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5188 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5189 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5190 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5191 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5192 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5193 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5194 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5195 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5196 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5197   proxy_arp_intfc_enable_disable_reply)                                 \
5198 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5199 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5200   sw_interface_set_unnumbered_reply)                                    \
5201 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5202 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
5203 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5204 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5205 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5206 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5207 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5208 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5209 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5210 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5211 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5212 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5213   sw_interface_ip6_enable_disable_reply)                                \
5214 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5215   sw_interface_ip6_set_link_local_address_reply)                        \
5216 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5217 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5218 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5219   sw_interface_ip6nd_ra_prefix_reply)                                   \
5220 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5221   sw_interface_ip6nd_ra_config_reply)                                   \
5222 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5223 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5224 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5225 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5226 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5227 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5228 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5229 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5230 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5231 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5232 classify_set_interface_ip_table_reply)                                  \
5233 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5234   classify_set_interface_l2_tables_reply)                               \
5235 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5236 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5237 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5238 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5239 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5240   l2tpv3_interface_enable_disable_reply)                                \
5241 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5242 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5243 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5244 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5245 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5246 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5247 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5248 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5249 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5250 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5251 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5252 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5253 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5254 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5255 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5256 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5257 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5258 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
5259 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5260 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5261 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5262 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5263 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5264 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5265 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5266 _(L2_MACS_EVENT, l2_macs_event)                                         \
5267 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5268 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5269 _(IP_DETAILS, ip_details)                                               \
5270 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5271 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5272 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5273 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5274 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5275 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5276 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5277 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5278 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5279 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5280 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5281 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5282 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5283 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5284 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5285 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5286 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5287 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5288 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5289 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5290 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5291 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5292 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5293 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5294 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5295 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5296 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5297 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5298 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5299 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5300 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5301 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5302 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5303 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5304 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5305 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5306 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5307 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5308 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5309 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5310 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5311 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5312 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5313 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5314 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5315 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5316   one_map_register_enable_disable_reply)                                \
5317 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5318 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5319 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5320 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5321   one_map_register_fallback_threshold_reply)                            \
5322 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5323   one_rloc_probe_enable_disable_reply)                                  \
5324 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5325 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5326 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5327 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5328 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5329 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5330 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5331 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5332 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5333 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5334 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5335 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5336 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5337 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5338 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5339 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5340   show_one_stats_enable_disable_reply)                                  \
5341 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5342 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5343 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5344 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5345 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5346 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5347 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5348 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5349 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5350 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5351 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5352 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5353 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5354 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5355 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5356   gpe_add_del_native_fwd_rpath_reply)                                   \
5357 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5358   gpe_fwd_entry_path_details)                                           \
5359 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5360 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5361   one_add_del_map_request_itr_rlocs_reply)                              \
5362 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5363   one_get_map_request_itr_rlocs_reply)                                  \
5364 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5365 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5366 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5367 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5368 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5369 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5370   show_one_map_register_state_reply)                                    \
5371 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5372 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5373   show_one_map_register_fallback_threshold_reply)                       \
5374 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5375 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5376 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5377 _(POLICER_DETAILS, policer_details)                                     \
5378 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5379 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5380 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5381 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5382 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5383 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5384 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5385 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5386 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5387 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5388 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5389 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5390 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5391 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5392 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5393 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5394 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5395 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5396 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5397 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5398 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5399 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5400 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5401 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5402 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5403  ip_source_and_port_range_check_add_del_reply)                          \
5404 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5405  ip_source_and_port_range_check_interface_add_del_reply)                \
5406 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5407 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5408 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5409 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5410 _(PUNT_REPLY, punt_reply)                                               \
5411 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5412 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5413 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5414 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5415 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5416 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5417 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5418 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5419 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5420 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5421 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5422 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5423 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply)
5424
5425 #define foreach_standalone_reply_msg                                    \
5426 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5427 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5428 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5429 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5430 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5431 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5432 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
5433 _(MEMFD_SEGMENT_CREATE_REPLY, memfd_segment_create_reply)
5434
5435 typedef struct
5436 {
5437   u8 *name;
5438   u32 value;
5439 } name_sort_t;
5440
5441
5442 #define STR_VTR_OP_CASE(op)     \
5443     case L2_VTR_ ## op:         \
5444         return "" # op;
5445
5446 static const char *
5447 str_vtr_op (u32 vtr_op)
5448 {
5449   switch (vtr_op)
5450     {
5451       STR_VTR_OP_CASE (DISABLED);
5452       STR_VTR_OP_CASE (PUSH_1);
5453       STR_VTR_OP_CASE (PUSH_2);
5454       STR_VTR_OP_CASE (POP_1);
5455       STR_VTR_OP_CASE (POP_2);
5456       STR_VTR_OP_CASE (TRANSLATE_1_1);
5457       STR_VTR_OP_CASE (TRANSLATE_1_2);
5458       STR_VTR_OP_CASE (TRANSLATE_2_1);
5459       STR_VTR_OP_CASE (TRANSLATE_2_2);
5460     }
5461
5462   return "UNKNOWN";
5463 }
5464
5465 static int
5466 dump_sub_interface_table (vat_main_t * vam)
5467 {
5468   const sw_interface_subif_t *sub = NULL;
5469
5470   if (vam->json_output)
5471     {
5472       clib_warning
5473         ("JSON output supported only for VPE API calls and dump_stats_table");
5474       return -99;
5475     }
5476
5477   print (vam->ofp,
5478          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5479          "Interface", "sw_if_index",
5480          "sub id", "dot1ad", "tags", "outer id",
5481          "inner id", "exact", "default", "outer any", "inner any");
5482
5483   vec_foreach (sub, vam->sw_if_subif_table)
5484   {
5485     print (vam->ofp,
5486            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5487            sub->interface_name,
5488            sub->sw_if_index,
5489            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5490            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5491            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5492            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5493     if (sub->vtr_op != L2_VTR_DISABLED)
5494       {
5495         print (vam->ofp,
5496                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5497                "tag1: %d tag2: %d ]",
5498                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5499                sub->vtr_tag1, sub->vtr_tag2);
5500       }
5501   }
5502
5503   return 0;
5504 }
5505
5506 static int
5507 name_sort_cmp (void *a1, void *a2)
5508 {
5509   name_sort_t *n1 = a1;
5510   name_sort_t *n2 = a2;
5511
5512   return strcmp ((char *) n1->name, (char *) n2->name);
5513 }
5514
5515 static int
5516 dump_interface_table (vat_main_t * vam)
5517 {
5518   hash_pair_t *p;
5519   name_sort_t *nses = 0, *ns;
5520
5521   if (vam->json_output)
5522     {
5523       clib_warning
5524         ("JSON output supported only for VPE API calls and dump_stats_table");
5525       return -99;
5526     }
5527
5528   /* *INDENT-OFF* */
5529   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5530   ({
5531     vec_add2 (nses, ns, 1);
5532     ns->name = (u8 *)(p->key);
5533     ns->value = (u32) p->value[0];
5534   }));
5535   /* *INDENT-ON* */
5536
5537   vec_sort_with_function (nses, name_sort_cmp);
5538
5539   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5540   vec_foreach (ns, nses)
5541   {
5542     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5543   }
5544   vec_free (nses);
5545   return 0;
5546 }
5547
5548 static int
5549 dump_ip_table (vat_main_t * vam, int is_ipv6)
5550 {
5551   const ip_details_t *det = NULL;
5552   const ip_address_details_t *address = NULL;
5553   u32 i = ~0;
5554
5555   print (vam->ofp, "%-12s", "sw_if_index");
5556
5557   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5558   {
5559     i++;
5560     if (!det->present)
5561       {
5562         continue;
5563       }
5564     print (vam->ofp, "%-12d", i);
5565     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5566     if (!det->addr)
5567       {
5568         continue;
5569       }
5570     vec_foreach (address, det->addr)
5571     {
5572       print (vam->ofp,
5573              "            %-30U%-13d",
5574              is_ipv6 ? format_ip6_address : format_ip4_address,
5575              address->ip, address->prefix_length);
5576     }
5577   }
5578
5579   return 0;
5580 }
5581
5582 static int
5583 dump_ipv4_table (vat_main_t * vam)
5584 {
5585   if (vam->json_output)
5586     {
5587       clib_warning
5588         ("JSON output supported only for VPE API calls and dump_stats_table");
5589       return -99;
5590     }
5591
5592   return dump_ip_table (vam, 0);
5593 }
5594
5595 static int
5596 dump_ipv6_table (vat_main_t * vam)
5597 {
5598   if (vam->json_output)
5599     {
5600       clib_warning
5601         ("JSON output supported only for VPE API calls and dump_stats_table");
5602       return -99;
5603     }
5604
5605   return dump_ip_table (vam, 1);
5606 }
5607
5608 static char *
5609 counter_type_to_str (u8 counter_type, u8 is_combined)
5610 {
5611   if (!is_combined)
5612     {
5613       switch (counter_type)
5614         {
5615         case VNET_INTERFACE_COUNTER_DROP:
5616           return "drop";
5617         case VNET_INTERFACE_COUNTER_PUNT:
5618           return "punt";
5619         case VNET_INTERFACE_COUNTER_IP4:
5620           return "ip4";
5621         case VNET_INTERFACE_COUNTER_IP6:
5622           return "ip6";
5623         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5624           return "rx-no-buf";
5625         case VNET_INTERFACE_COUNTER_RX_MISS:
5626           return "rx-miss";
5627         case VNET_INTERFACE_COUNTER_RX_ERROR:
5628           return "rx-error";
5629         case VNET_INTERFACE_COUNTER_TX_ERROR:
5630           return "tx-error";
5631         default:
5632           return "INVALID-COUNTER-TYPE";
5633         }
5634     }
5635   else
5636     {
5637       switch (counter_type)
5638         {
5639         case VNET_INTERFACE_COUNTER_RX:
5640           return "rx";
5641         case VNET_INTERFACE_COUNTER_TX:
5642           return "tx";
5643         default:
5644           return "INVALID-COUNTER-TYPE";
5645         }
5646     }
5647 }
5648
5649 static int
5650 dump_stats_table (vat_main_t * vam)
5651 {
5652   vat_json_node_t node;
5653   vat_json_node_t *msg_array;
5654   vat_json_node_t *msg;
5655   vat_json_node_t *counter_array;
5656   vat_json_node_t *counter;
5657   interface_counter_t c;
5658   u64 packets;
5659   ip4_fib_counter_t *c4;
5660   ip6_fib_counter_t *c6;
5661   ip4_nbr_counter_t *n4;
5662   ip6_nbr_counter_t *n6;
5663   int i, j;
5664
5665   if (!vam->json_output)
5666     {
5667       clib_warning ("dump_stats_table supported only in JSON format");
5668       return -99;
5669     }
5670
5671   vat_json_init_object (&node);
5672
5673   /* interface counters */
5674   msg_array = vat_json_object_add (&node, "interface_counters");
5675   vat_json_init_array (msg_array);
5676   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5677     {
5678       msg = vat_json_array_add (msg_array);
5679       vat_json_init_object (msg);
5680       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5681                                        (u8 *) counter_type_to_str (i, 0));
5682       vat_json_object_add_int (msg, "is_combined", 0);
5683       counter_array = vat_json_object_add (msg, "data");
5684       vat_json_init_array (counter_array);
5685       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5686         {
5687           packets = vam->simple_interface_counters[i][j];
5688           vat_json_array_add_uint (counter_array, packets);
5689         }
5690     }
5691   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5692     {
5693       msg = vat_json_array_add (msg_array);
5694       vat_json_init_object (msg);
5695       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5696                                        (u8 *) counter_type_to_str (i, 1));
5697       vat_json_object_add_int (msg, "is_combined", 1);
5698       counter_array = vat_json_object_add (msg, "data");
5699       vat_json_init_array (counter_array);
5700       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5701         {
5702           c = vam->combined_interface_counters[i][j];
5703           counter = vat_json_array_add (counter_array);
5704           vat_json_init_object (counter);
5705           vat_json_object_add_uint (counter, "packets", c.packets);
5706           vat_json_object_add_uint (counter, "bytes", c.bytes);
5707         }
5708     }
5709
5710   /* ip4 fib counters */
5711   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
5712   vat_json_init_array (msg_array);
5713   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
5714     {
5715       msg = vat_json_array_add (msg_array);
5716       vat_json_init_object (msg);
5717       vat_json_object_add_uint (msg, "vrf_id",
5718                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
5719       counter_array = vat_json_object_add (msg, "c");
5720       vat_json_init_array (counter_array);
5721       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
5722         {
5723           counter = vat_json_array_add (counter_array);
5724           vat_json_init_object (counter);
5725           c4 = &vam->ip4_fib_counters[i][j];
5726           vat_json_object_add_ip4 (counter, "address", c4->address);
5727           vat_json_object_add_uint (counter, "address_length",
5728                                     c4->address_length);
5729           vat_json_object_add_uint (counter, "packets", c4->packets);
5730           vat_json_object_add_uint (counter, "bytes", c4->bytes);
5731         }
5732     }
5733
5734   /* ip6 fib counters */
5735   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
5736   vat_json_init_array (msg_array);
5737   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
5738     {
5739       msg = vat_json_array_add (msg_array);
5740       vat_json_init_object (msg);
5741       vat_json_object_add_uint (msg, "vrf_id",
5742                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
5743       counter_array = vat_json_object_add (msg, "c");
5744       vat_json_init_array (counter_array);
5745       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
5746         {
5747           counter = vat_json_array_add (counter_array);
5748           vat_json_init_object (counter);
5749           c6 = &vam->ip6_fib_counters[i][j];
5750           vat_json_object_add_ip6 (counter, "address", c6->address);
5751           vat_json_object_add_uint (counter, "address_length",
5752                                     c6->address_length);
5753           vat_json_object_add_uint (counter, "packets", c6->packets);
5754           vat_json_object_add_uint (counter, "bytes", c6->bytes);
5755         }
5756     }
5757
5758   /* ip4 nbr counters */
5759   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
5760   vat_json_init_array (msg_array);
5761   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
5762     {
5763       msg = vat_json_array_add (msg_array);
5764       vat_json_init_object (msg);
5765       vat_json_object_add_uint (msg, "sw_if_index", i);
5766       counter_array = vat_json_object_add (msg, "c");
5767       vat_json_init_array (counter_array);
5768       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
5769         {
5770           counter = vat_json_array_add (counter_array);
5771           vat_json_init_object (counter);
5772           n4 = &vam->ip4_nbr_counters[i][j];
5773           vat_json_object_add_ip4 (counter, "address", n4->address);
5774           vat_json_object_add_uint (counter, "link-type", n4->linkt);
5775           vat_json_object_add_uint (counter, "packets", n4->packets);
5776           vat_json_object_add_uint (counter, "bytes", n4->bytes);
5777         }
5778     }
5779
5780   /* ip6 nbr counters */
5781   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
5782   vat_json_init_array (msg_array);
5783   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
5784     {
5785       msg = vat_json_array_add (msg_array);
5786       vat_json_init_object (msg);
5787       vat_json_object_add_uint (msg, "sw_if_index", i);
5788       counter_array = vat_json_object_add (msg, "c");
5789       vat_json_init_array (counter_array);
5790       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
5791         {
5792           counter = vat_json_array_add (counter_array);
5793           vat_json_init_object (counter);
5794           n6 = &vam->ip6_nbr_counters[i][j];
5795           vat_json_object_add_ip6 (counter, "address", n6->address);
5796           vat_json_object_add_uint (counter, "packets", n6->packets);
5797           vat_json_object_add_uint (counter, "bytes", n6->bytes);
5798         }
5799     }
5800
5801   vat_json_print (vam->ofp, &node);
5802   vat_json_free (&node);
5803
5804   return 0;
5805 }
5806
5807 /*
5808  * Pass CLI buffers directly in the CLI_INBAND API message,
5809  * instead of an additional shared memory area.
5810  */
5811 static int
5812 exec_inband (vat_main_t * vam)
5813 {
5814   vl_api_cli_inband_t *mp;
5815   unformat_input_t *i = vam->input;
5816   int ret;
5817
5818   if (vec_len (i->buffer) == 0)
5819     return -1;
5820
5821   if (vam->exec_mode == 0 && unformat (i, "mode"))
5822     {
5823       vam->exec_mode = 1;
5824       return 0;
5825     }
5826   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5827     {
5828       vam->exec_mode = 0;
5829       return 0;
5830     }
5831
5832   /*
5833    * In order for the CLI command to work, it
5834    * must be a vector ending in \n, not a C-string ending
5835    * in \n\0.
5836    */
5837   u32 len = vec_len (vam->input->buffer);
5838   M2 (CLI_INBAND, mp, len);
5839   clib_memcpy (mp->cmd, vam->input->buffer, len);
5840   mp->length = htonl (len);
5841
5842   S (mp);
5843   W (ret);
5844   /* json responses may or may not include a useful reply... */
5845   if (vec_len (vam->cmd_reply))
5846     print (vam->ofp, (char *) (vam->cmd_reply));
5847   return ret;
5848 }
5849
5850 int
5851 exec (vat_main_t * vam)
5852 {
5853   return exec_inband (vam);
5854 }
5855
5856 static int
5857 api_create_loopback (vat_main_t * vam)
5858 {
5859   unformat_input_t *i = vam->input;
5860   vl_api_create_loopback_t *mp;
5861   vl_api_create_loopback_instance_t *mp_lbi;
5862   u8 mac_address[6];
5863   u8 mac_set = 0;
5864   u8 is_specified = 0;
5865   u32 user_instance = 0;
5866   int ret;
5867
5868   memset (mac_address, 0, sizeof (mac_address));
5869
5870   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5871     {
5872       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5873         mac_set = 1;
5874       if (unformat (i, "instance %d", &user_instance))
5875         is_specified = 1;
5876       else
5877         break;
5878     }
5879
5880   if (is_specified)
5881     {
5882       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5883       mp_lbi->is_specified = is_specified;
5884       if (is_specified)
5885         mp_lbi->user_instance = htonl (user_instance);
5886       if (mac_set)
5887         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5888       S (mp_lbi);
5889     }
5890   else
5891     {
5892       /* Construct the API message */
5893       M (CREATE_LOOPBACK, mp);
5894       if (mac_set)
5895         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5896       S (mp);
5897     }
5898
5899   W (ret);
5900   return ret;
5901 }
5902
5903 static int
5904 api_delete_loopback (vat_main_t * vam)
5905 {
5906   unformat_input_t *i = vam->input;
5907   vl_api_delete_loopback_t *mp;
5908   u32 sw_if_index = ~0;
5909   int ret;
5910
5911   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5912     {
5913       if (unformat (i, "sw_if_index %d", &sw_if_index))
5914         ;
5915       else
5916         break;
5917     }
5918
5919   if (sw_if_index == ~0)
5920     {
5921       errmsg ("missing sw_if_index");
5922       return -99;
5923     }
5924
5925   /* Construct the API message */
5926   M (DELETE_LOOPBACK, mp);
5927   mp->sw_if_index = ntohl (sw_if_index);
5928
5929   S (mp);
5930   W (ret);
5931   return ret;
5932 }
5933
5934 static int
5935 api_want_stats (vat_main_t * vam)
5936 {
5937   unformat_input_t *i = vam->input;
5938   vl_api_want_stats_t *mp;
5939   int enable = -1;
5940   int ret;
5941
5942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5943     {
5944       if (unformat (i, "enable"))
5945         enable = 1;
5946       else if (unformat (i, "disable"))
5947         enable = 0;
5948       else
5949         break;
5950     }
5951
5952   if (enable == -1)
5953     {
5954       errmsg ("missing enable|disable");
5955       return -99;
5956     }
5957
5958   M (WANT_STATS, mp);
5959   mp->enable_disable = enable;
5960
5961   S (mp);
5962   W (ret);
5963   return ret;
5964 }
5965
5966 static int
5967 api_want_interface_events (vat_main_t * vam)
5968 {
5969   unformat_input_t *i = vam->input;
5970   vl_api_want_interface_events_t *mp;
5971   int enable = -1;
5972   int ret;
5973
5974   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5975     {
5976       if (unformat (i, "enable"))
5977         enable = 1;
5978       else if (unformat (i, "disable"))
5979         enable = 0;
5980       else
5981         break;
5982     }
5983
5984   if (enable == -1)
5985     {
5986       errmsg ("missing enable|disable");
5987       return -99;
5988     }
5989
5990   M (WANT_INTERFACE_EVENTS, mp);
5991   mp->enable_disable = enable;
5992
5993   vam->interface_event_display = enable;
5994
5995   S (mp);
5996   W (ret);
5997   return ret;
5998 }
5999
6000
6001 /* Note: non-static, called once to set up the initial intfc table */
6002 int
6003 api_sw_interface_dump (vat_main_t * vam)
6004 {
6005   vl_api_sw_interface_dump_t *mp;
6006   vl_api_control_ping_t *mp_ping;
6007   hash_pair_t *p;
6008   name_sort_t *nses = 0, *ns;
6009   sw_interface_subif_t *sub = NULL;
6010   int ret;
6011
6012   /* Toss the old name table */
6013   /* *INDENT-OFF* */
6014   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6015   ({
6016     vec_add2 (nses, ns, 1);
6017     ns->name = (u8 *)(p->key);
6018     ns->value = (u32) p->value[0];
6019   }));
6020   /* *INDENT-ON* */
6021
6022   hash_free (vam->sw_if_index_by_interface_name);
6023
6024   vec_foreach (ns, nses) vec_free (ns->name);
6025
6026   vec_free (nses);
6027
6028   vec_foreach (sub, vam->sw_if_subif_table)
6029   {
6030     vec_free (sub->interface_name);
6031   }
6032   vec_free (vam->sw_if_subif_table);
6033
6034   /* recreate the interface name hash table */
6035   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6036
6037   /* Get list of ethernets */
6038   M (SW_INTERFACE_DUMP, mp);
6039   mp->name_filter_valid = 1;
6040   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
6041   S (mp);
6042
6043   /* and local / loopback interfaces */
6044   M (SW_INTERFACE_DUMP, mp);
6045   mp->name_filter_valid = 1;
6046   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
6047   S (mp);
6048
6049   /* and packet-generator interfaces */
6050   M (SW_INTERFACE_DUMP, mp);
6051   mp->name_filter_valid = 1;
6052   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
6053   S (mp);
6054
6055   /* and vxlan-gpe tunnel interfaces */
6056   M (SW_INTERFACE_DUMP, mp);
6057   mp->name_filter_valid = 1;
6058   strncpy ((char *) mp->name_filter, "vxlan_gpe",
6059            sizeof (mp->name_filter) - 1);
6060   S (mp);
6061
6062   /* and vxlan tunnel interfaces */
6063   M (SW_INTERFACE_DUMP, mp);
6064   mp->name_filter_valid = 1;
6065   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
6066   S (mp);
6067
6068   /* and geneve tunnel interfaces */
6069   M (SW_INTERFACE_DUMP, mp);
6070   mp->name_filter_valid = 1;
6071   strncpy ((char *) mp->name_filter, "geneve", sizeof (mp->name_filter) - 1);
6072   S (mp);
6073
6074   /* and host (af_packet) interfaces */
6075   M (SW_INTERFACE_DUMP, mp);
6076   mp->name_filter_valid = 1;
6077   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
6078   S (mp);
6079
6080   /* and l2tpv3 tunnel interfaces */
6081   M (SW_INTERFACE_DUMP, mp);
6082   mp->name_filter_valid = 1;
6083   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
6084            sizeof (mp->name_filter) - 1);
6085   S (mp);
6086
6087   /* and GRE tunnel interfaces */
6088   M (SW_INTERFACE_DUMP, mp);
6089   mp->name_filter_valid = 1;
6090   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
6091   S (mp);
6092
6093   /* and LISP-GPE interfaces */
6094   M (SW_INTERFACE_DUMP, mp);
6095   mp->name_filter_valid = 1;
6096   strncpy ((char *) mp->name_filter, "lisp_gpe",
6097            sizeof (mp->name_filter) - 1);
6098   S (mp);
6099
6100   /* and IPSEC tunnel interfaces */
6101   M (SW_INTERFACE_DUMP, mp);
6102   mp->name_filter_valid = 1;
6103   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
6104   S (mp);
6105
6106   /* Use a control ping for synchronization */
6107   MPING (CONTROL_PING, mp_ping);
6108   S (mp_ping);
6109
6110   W (ret);
6111   return ret;
6112 }
6113
6114 static int
6115 api_sw_interface_set_flags (vat_main_t * vam)
6116 {
6117   unformat_input_t *i = vam->input;
6118   vl_api_sw_interface_set_flags_t *mp;
6119   u32 sw_if_index;
6120   u8 sw_if_index_set = 0;
6121   u8 admin_up = 0;
6122   int ret;
6123
6124   /* Parse args required to build the message */
6125   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6126     {
6127       if (unformat (i, "admin-up"))
6128         admin_up = 1;
6129       else if (unformat (i, "admin-down"))
6130         admin_up = 0;
6131       else
6132         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6133         sw_if_index_set = 1;
6134       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6135         sw_if_index_set = 1;
6136       else
6137         break;
6138     }
6139
6140   if (sw_if_index_set == 0)
6141     {
6142       errmsg ("missing interface name or sw_if_index");
6143       return -99;
6144     }
6145
6146   /* Construct the API message */
6147   M (SW_INTERFACE_SET_FLAGS, mp);
6148   mp->sw_if_index = ntohl (sw_if_index);
6149   mp->admin_up_down = admin_up;
6150
6151   /* send it... */
6152   S (mp);
6153
6154   /* Wait for a reply, return the good/bad news... */
6155   W (ret);
6156   return ret;
6157 }
6158
6159 static int
6160 api_sw_interface_clear_stats (vat_main_t * vam)
6161 {
6162   unformat_input_t *i = vam->input;
6163   vl_api_sw_interface_clear_stats_t *mp;
6164   u32 sw_if_index;
6165   u8 sw_if_index_set = 0;
6166   int ret;
6167
6168   /* Parse args required to build the message */
6169   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6170     {
6171       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6172         sw_if_index_set = 1;
6173       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6174         sw_if_index_set = 1;
6175       else
6176         break;
6177     }
6178
6179   /* Construct the API message */
6180   M (SW_INTERFACE_CLEAR_STATS, mp);
6181
6182   if (sw_if_index_set == 1)
6183     mp->sw_if_index = ntohl (sw_if_index);
6184   else
6185     mp->sw_if_index = ~0;
6186
6187   /* send it... */
6188   S (mp);
6189
6190   /* Wait for a reply, return the good/bad news... */
6191   W (ret);
6192   return ret;
6193 }
6194
6195 static int
6196 api_sw_interface_add_del_address (vat_main_t * vam)
6197 {
6198   unformat_input_t *i = vam->input;
6199   vl_api_sw_interface_add_del_address_t *mp;
6200   u32 sw_if_index;
6201   u8 sw_if_index_set = 0;
6202   u8 is_add = 1, del_all = 0;
6203   u32 address_length = 0;
6204   u8 v4_address_set = 0;
6205   u8 v6_address_set = 0;
6206   ip4_address_t v4address;
6207   ip6_address_t v6address;
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, "del-all"))
6214         del_all = 1;
6215       else if (unformat (i, "del"))
6216         is_add = 0;
6217       else
6218         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6219         sw_if_index_set = 1;
6220       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6221         sw_if_index_set = 1;
6222       else if (unformat (i, "%U/%d",
6223                          unformat_ip4_address, &v4address, &address_length))
6224         v4_address_set = 1;
6225       else if (unformat (i, "%U/%d",
6226                          unformat_ip6_address, &v6address, &address_length))
6227         v6_address_set = 1;
6228       else
6229         break;
6230     }
6231
6232   if (sw_if_index_set == 0)
6233     {
6234       errmsg ("missing interface name or sw_if_index");
6235       return -99;
6236     }
6237   if (v4_address_set && v6_address_set)
6238     {
6239       errmsg ("both v4 and v6 addresses set");
6240       return -99;
6241     }
6242   if (!v4_address_set && !v6_address_set && !del_all)
6243     {
6244       errmsg ("no addresses set");
6245       return -99;
6246     }
6247
6248   /* Construct the API message */
6249   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6250
6251   mp->sw_if_index = ntohl (sw_if_index);
6252   mp->is_add = is_add;
6253   mp->del_all = del_all;
6254   if (v6_address_set)
6255     {
6256       mp->is_ipv6 = 1;
6257       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6258     }
6259   else
6260     {
6261       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6262     }
6263   mp->address_length = address_length;
6264
6265   /* send it... */
6266   S (mp);
6267
6268   /* Wait for a reply, return good/bad news  */
6269   W (ret);
6270   return ret;
6271 }
6272
6273 static int
6274 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6275 {
6276   unformat_input_t *i = vam->input;
6277   vl_api_sw_interface_set_mpls_enable_t *mp;
6278   u32 sw_if_index;
6279   u8 sw_if_index_set = 0;
6280   u8 enable = 1;
6281   int ret;
6282
6283   /* Parse args required to build the message */
6284   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6285     {
6286       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6287         sw_if_index_set = 1;
6288       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6289         sw_if_index_set = 1;
6290       else if (unformat (i, "disable"))
6291         enable = 0;
6292       else if (unformat (i, "dis"))
6293         enable = 0;
6294       else
6295         break;
6296     }
6297
6298   if (sw_if_index_set == 0)
6299     {
6300       errmsg ("missing interface name or sw_if_index");
6301       return -99;
6302     }
6303
6304   /* Construct the API message */
6305   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6306
6307   mp->sw_if_index = ntohl (sw_if_index);
6308   mp->enable = enable;
6309
6310   /* send it... */
6311   S (mp);
6312
6313   /* Wait for a reply... */
6314   W (ret);
6315   return ret;
6316 }
6317
6318 static int
6319 api_sw_interface_set_table (vat_main_t * vam)
6320 {
6321   unformat_input_t *i = vam->input;
6322   vl_api_sw_interface_set_table_t *mp;
6323   u32 sw_if_index, vrf_id = 0;
6324   u8 sw_if_index_set = 0;
6325   u8 is_ipv6 = 0;
6326   int ret;
6327
6328   /* Parse args required to build the message */
6329   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6330     {
6331       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6332         sw_if_index_set = 1;
6333       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6334         sw_if_index_set = 1;
6335       else if (unformat (i, "vrf %d", &vrf_id))
6336         ;
6337       else if (unformat (i, "ipv6"))
6338         is_ipv6 = 1;
6339       else
6340         break;
6341     }
6342
6343   if (sw_if_index_set == 0)
6344     {
6345       errmsg ("missing interface name or sw_if_index");
6346       return -99;
6347     }
6348
6349   /* Construct the API message */
6350   M (SW_INTERFACE_SET_TABLE, mp);
6351
6352   mp->sw_if_index = ntohl (sw_if_index);
6353   mp->is_ipv6 = is_ipv6;
6354   mp->vrf_id = ntohl (vrf_id);
6355
6356   /* send it... */
6357   S (mp);
6358
6359   /* Wait for a reply... */
6360   W (ret);
6361   return ret;
6362 }
6363
6364 static void vl_api_sw_interface_get_table_reply_t_handler
6365   (vl_api_sw_interface_get_table_reply_t * mp)
6366 {
6367   vat_main_t *vam = &vat_main;
6368
6369   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6370
6371   vam->retval = ntohl (mp->retval);
6372   vam->result_ready = 1;
6373
6374 }
6375
6376 static void vl_api_sw_interface_get_table_reply_t_handler_json
6377   (vl_api_sw_interface_get_table_reply_t * mp)
6378 {
6379   vat_main_t *vam = &vat_main;
6380   vat_json_node_t node;
6381
6382   vat_json_init_object (&node);
6383   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6384   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6385
6386   vat_json_print (vam->ofp, &node);
6387   vat_json_free (&node);
6388
6389   vam->retval = ntohl (mp->retval);
6390   vam->result_ready = 1;
6391 }
6392
6393 static int
6394 api_sw_interface_get_table (vat_main_t * vam)
6395 {
6396   unformat_input_t *i = vam->input;
6397   vl_api_sw_interface_get_table_t *mp;
6398   u32 sw_if_index;
6399   u8 sw_if_index_set = 0;
6400   u8 is_ipv6 = 0;
6401   int ret;
6402
6403   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6404     {
6405       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6406         sw_if_index_set = 1;
6407       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6408         sw_if_index_set = 1;
6409       else if (unformat (i, "ipv6"))
6410         is_ipv6 = 1;
6411       else
6412         break;
6413     }
6414
6415   if (sw_if_index_set == 0)
6416     {
6417       errmsg ("missing interface name or sw_if_index");
6418       return -99;
6419     }
6420
6421   M (SW_INTERFACE_GET_TABLE, mp);
6422   mp->sw_if_index = htonl (sw_if_index);
6423   mp->is_ipv6 = is_ipv6;
6424
6425   S (mp);
6426   W (ret);
6427   return ret;
6428 }
6429
6430 static int
6431 api_sw_interface_set_vpath (vat_main_t * vam)
6432 {
6433   unformat_input_t *i = vam->input;
6434   vl_api_sw_interface_set_vpath_t *mp;
6435   u32 sw_if_index = 0;
6436   u8 sw_if_index_set = 0;
6437   u8 is_enable = 0;
6438   int ret;
6439
6440   /* Parse args required to build the message */
6441   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6442     {
6443       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6444         sw_if_index_set = 1;
6445       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6446         sw_if_index_set = 1;
6447       else if (unformat (i, "enable"))
6448         is_enable = 1;
6449       else if (unformat (i, "disable"))
6450         is_enable = 0;
6451       else
6452         break;
6453     }
6454
6455   if (sw_if_index_set == 0)
6456     {
6457       errmsg ("missing interface name or sw_if_index");
6458       return -99;
6459     }
6460
6461   /* Construct the API message */
6462   M (SW_INTERFACE_SET_VPATH, mp);
6463
6464   mp->sw_if_index = ntohl (sw_if_index);
6465   mp->enable = is_enable;
6466
6467   /* send it... */
6468   S (mp);
6469
6470   /* Wait for a reply... */
6471   W (ret);
6472   return ret;
6473 }
6474
6475 static int
6476 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6477 {
6478   unformat_input_t *i = vam->input;
6479   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6480   u32 sw_if_index = 0;
6481   u8 sw_if_index_set = 0;
6482   u8 is_enable = 1;
6483   u8 is_ipv6 = 0;
6484   int ret;
6485
6486   /* Parse args required to build the message */
6487   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6488     {
6489       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6490         sw_if_index_set = 1;
6491       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6492         sw_if_index_set = 1;
6493       else if (unformat (i, "enable"))
6494         is_enable = 1;
6495       else if (unformat (i, "disable"))
6496         is_enable = 0;
6497       else if (unformat (i, "ip4"))
6498         is_ipv6 = 0;
6499       else if (unformat (i, "ip6"))
6500         is_ipv6 = 1;
6501       else
6502         break;
6503     }
6504
6505   if (sw_if_index_set == 0)
6506     {
6507       errmsg ("missing interface name or sw_if_index");
6508       return -99;
6509     }
6510
6511   /* Construct the API message */
6512   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6513
6514   mp->sw_if_index = ntohl (sw_if_index);
6515   mp->enable = is_enable;
6516   mp->is_ipv6 = is_ipv6;
6517
6518   /* send it... */
6519   S (mp);
6520
6521   /* Wait for a reply... */
6522   W (ret);
6523   return ret;
6524 }
6525
6526 static int
6527 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6528 {
6529   unformat_input_t *i = vam->input;
6530   vl_api_sw_interface_set_geneve_bypass_t *mp;
6531   u32 sw_if_index = 0;
6532   u8 sw_if_index_set = 0;
6533   u8 is_enable = 1;
6534   u8 is_ipv6 = 0;
6535   int ret;
6536
6537   /* Parse args required to build the message */
6538   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6539     {
6540       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6541         sw_if_index_set = 1;
6542       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6543         sw_if_index_set = 1;
6544       else if (unformat (i, "enable"))
6545         is_enable = 1;
6546       else if (unformat (i, "disable"))
6547         is_enable = 0;
6548       else if (unformat (i, "ip4"))
6549         is_ipv6 = 0;
6550       else if (unformat (i, "ip6"))
6551         is_ipv6 = 1;
6552       else
6553         break;
6554     }
6555
6556   if (sw_if_index_set == 0)
6557     {
6558       errmsg ("missing interface name or sw_if_index");
6559       return -99;
6560     }
6561
6562   /* Construct the API message */
6563   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6564
6565   mp->sw_if_index = ntohl (sw_if_index);
6566   mp->enable = is_enable;
6567   mp->is_ipv6 = is_ipv6;
6568
6569   /* send it... */
6570   S (mp);
6571
6572   /* Wait for a reply... */
6573   W (ret);
6574   return ret;
6575 }
6576
6577 static int
6578 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6579 {
6580   unformat_input_t *i = vam->input;
6581   vl_api_sw_interface_set_l2_xconnect_t *mp;
6582   u32 rx_sw_if_index;
6583   u8 rx_sw_if_index_set = 0;
6584   u32 tx_sw_if_index;
6585   u8 tx_sw_if_index_set = 0;
6586   u8 enable = 1;
6587   int ret;
6588
6589   /* Parse args required to build the message */
6590   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6591     {
6592       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6593         rx_sw_if_index_set = 1;
6594       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6595         tx_sw_if_index_set = 1;
6596       else if (unformat (i, "rx"))
6597         {
6598           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6599             {
6600               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6601                             &rx_sw_if_index))
6602                 rx_sw_if_index_set = 1;
6603             }
6604           else
6605             break;
6606         }
6607       else if (unformat (i, "tx"))
6608         {
6609           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6610             {
6611               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6612                             &tx_sw_if_index))
6613                 tx_sw_if_index_set = 1;
6614             }
6615           else
6616             break;
6617         }
6618       else if (unformat (i, "enable"))
6619         enable = 1;
6620       else if (unformat (i, "disable"))
6621         enable = 0;
6622       else
6623         break;
6624     }
6625
6626   if (rx_sw_if_index_set == 0)
6627     {
6628       errmsg ("missing rx interface name or rx_sw_if_index");
6629       return -99;
6630     }
6631
6632   if (enable && (tx_sw_if_index_set == 0))
6633     {
6634       errmsg ("missing tx interface name or tx_sw_if_index");
6635       return -99;
6636     }
6637
6638   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6639
6640   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6641   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6642   mp->enable = enable;
6643
6644   S (mp);
6645   W (ret);
6646   return ret;
6647 }
6648
6649 static int
6650 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6651 {
6652   unformat_input_t *i = vam->input;
6653   vl_api_sw_interface_set_l2_bridge_t *mp;
6654   u32 rx_sw_if_index;
6655   u8 rx_sw_if_index_set = 0;
6656   u32 bd_id;
6657   u8 bd_id_set = 0;
6658   u8 bvi = 0;
6659   u32 shg = 0;
6660   u8 enable = 1;
6661   int ret;
6662
6663   /* Parse args required to build the message */
6664   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6665     {
6666       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6667         rx_sw_if_index_set = 1;
6668       else if (unformat (i, "bd_id %d", &bd_id))
6669         bd_id_set = 1;
6670       else
6671         if (unformat
6672             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6673         rx_sw_if_index_set = 1;
6674       else if (unformat (i, "shg %d", &shg))
6675         ;
6676       else if (unformat (i, "bvi"))
6677         bvi = 1;
6678       else if (unformat (i, "enable"))
6679         enable = 1;
6680       else if (unformat (i, "disable"))
6681         enable = 0;
6682       else
6683         break;
6684     }
6685
6686   if (rx_sw_if_index_set == 0)
6687     {
6688       errmsg ("missing rx interface name or sw_if_index");
6689       return -99;
6690     }
6691
6692   if (enable && (bd_id_set == 0))
6693     {
6694       errmsg ("missing bridge domain");
6695       return -99;
6696     }
6697
6698   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6699
6700   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6701   mp->bd_id = ntohl (bd_id);
6702   mp->shg = (u8) shg;
6703   mp->bvi = bvi;
6704   mp->enable = enable;
6705
6706   S (mp);
6707   W (ret);
6708   return ret;
6709 }
6710
6711 static int
6712 api_bridge_domain_dump (vat_main_t * vam)
6713 {
6714   unformat_input_t *i = vam->input;
6715   vl_api_bridge_domain_dump_t *mp;
6716   vl_api_control_ping_t *mp_ping;
6717   u32 bd_id = ~0;
6718   int ret;
6719
6720   /* Parse args required to build the message */
6721   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6722     {
6723       if (unformat (i, "bd_id %d", &bd_id))
6724         ;
6725       else
6726         break;
6727     }
6728
6729   M (BRIDGE_DOMAIN_DUMP, mp);
6730   mp->bd_id = ntohl (bd_id);
6731   S (mp);
6732
6733   /* Use a control ping for synchronization */
6734   MPING (CONTROL_PING, mp_ping);
6735   S (mp_ping);
6736
6737   W (ret);
6738   return ret;
6739 }
6740
6741 static int
6742 api_bridge_domain_add_del (vat_main_t * vam)
6743 {
6744   unformat_input_t *i = vam->input;
6745   vl_api_bridge_domain_add_del_t *mp;
6746   u32 bd_id = ~0;
6747   u8 is_add = 1;
6748   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6749   u8 *bd_tag = NULL;
6750   u32 mac_age = 0;
6751   int ret;
6752
6753   /* Parse args required to build the message */
6754   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6755     {
6756       if (unformat (i, "bd_id %d", &bd_id))
6757         ;
6758       else if (unformat (i, "flood %d", &flood))
6759         ;
6760       else if (unformat (i, "uu-flood %d", &uu_flood))
6761         ;
6762       else if (unformat (i, "forward %d", &forward))
6763         ;
6764       else if (unformat (i, "learn %d", &learn))
6765         ;
6766       else if (unformat (i, "arp-term %d", &arp_term))
6767         ;
6768       else if (unformat (i, "mac-age %d", &mac_age))
6769         ;
6770       else if (unformat (i, "bd-tag %s", &bd_tag))
6771         ;
6772       else if (unformat (i, "del"))
6773         {
6774           is_add = 0;
6775           flood = uu_flood = forward = learn = 0;
6776         }
6777       else
6778         break;
6779     }
6780
6781   if (bd_id == ~0)
6782     {
6783       errmsg ("missing bridge domain");
6784       ret = -99;
6785       goto done;
6786     }
6787
6788   if (mac_age > 255)
6789     {
6790       errmsg ("mac age must be less than 256 ");
6791       ret = -99;
6792       goto done;
6793     }
6794
6795   if ((bd_tag) && (strlen ((char *) bd_tag) > 63))
6796     {
6797       errmsg ("bd-tag cannot be longer than 63");
6798       ret = -99;
6799       goto done;
6800     }
6801
6802   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6803
6804   mp->bd_id = ntohl (bd_id);
6805   mp->flood = flood;
6806   mp->uu_flood = uu_flood;
6807   mp->forward = forward;
6808   mp->learn = learn;
6809   mp->arp_term = arp_term;
6810   mp->is_add = is_add;
6811   mp->mac_age = (u8) mac_age;
6812   if (bd_tag)
6813     strcpy ((char *) mp->bd_tag, (char *) bd_tag);
6814
6815   S (mp);
6816   W (ret);
6817
6818 done:
6819   vec_free (bd_tag);
6820   return ret;
6821 }
6822
6823 static int
6824 api_l2fib_flush_bd (vat_main_t * vam)
6825 {
6826   unformat_input_t *i = vam->input;
6827   vl_api_l2fib_flush_bd_t *mp;
6828   u32 bd_id = ~0;
6829   int ret;
6830
6831   /* Parse args required to build the message */
6832   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6833     {
6834       if (unformat (i, "bd_id %d", &bd_id));
6835       else
6836         break;
6837     }
6838
6839   if (bd_id == ~0)
6840     {
6841       errmsg ("missing bridge domain");
6842       return -99;
6843     }
6844
6845   M (L2FIB_FLUSH_BD, mp);
6846
6847   mp->bd_id = htonl (bd_id);
6848
6849   S (mp);
6850   W (ret);
6851   return ret;
6852 }
6853
6854 static int
6855 api_l2fib_flush_int (vat_main_t * vam)
6856 {
6857   unformat_input_t *i = vam->input;
6858   vl_api_l2fib_flush_int_t *mp;
6859   u32 sw_if_index = ~0;
6860   int ret;
6861
6862   /* Parse args required to build the message */
6863   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6864     {
6865       if (unformat (i, "sw_if_index %d", &sw_if_index));
6866       else
6867         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6868       else
6869         break;
6870     }
6871
6872   if (sw_if_index == ~0)
6873     {
6874       errmsg ("missing interface name or sw_if_index");
6875       return -99;
6876     }
6877
6878   M (L2FIB_FLUSH_INT, mp);
6879
6880   mp->sw_if_index = ntohl (sw_if_index);
6881
6882   S (mp);
6883   W (ret);
6884   return ret;
6885 }
6886
6887 static int
6888 api_l2fib_add_del (vat_main_t * vam)
6889 {
6890   unformat_input_t *i = vam->input;
6891   vl_api_l2fib_add_del_t *mp;
6892   f64 timeout;
6893   u64 mac = 0;
6894   u8 mac_set = 0;
6895   u32 bd_id;
6896   u8 bd_id_set = 0;
6897   u32 sw_if_index = ~0;
6898   u8 sw_if_index_set = 0;
6899   u8 is_add = 1;
6900   u8 static_mac = 0;
6901   u8 filter_mac = 0;
6902   u8 bvi_mac = 0;
6903   int count = 1;
6904   f64 before = 0;
6905   int j;
6906
6907   /* Parse args required to build the message */
6908   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6909     {
6910       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
6911         mac_set = 1;
6912       else if (unformat (i, "bd_id %d", &bd_id))
6913         bd_id_set = 1;
6914       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6915         sw_if_index_set = 1;
6916       else if (unformat (i, "sw_if"))
6917         {
6918           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6919             {
6920               if (unformat
6921                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6922                 sw_if_index_set = 1;
6923             }
6924           else
6925             break;
6926         }
6927       else if (unformat (i, "static"))
6928         static_mac = 1;
6929       else if (unformat (i, "filter"))
6930         {
6931           filter_mac = 1;
6932           static_mac = 1;
6933         }
6934       else if (unformat (i, "bvi"))
6935         {
6936           bvi_mac = 1;
6937           static_mac = 1;
6938         }
6939       else if (unformat (i, "del"))
6940         is_add = 0;
6941       else if (unformat (i, "count %d", &count))
6942         ;
6943       else
6944         break;
6945     }
6946
6947   if (mac_set == 0)
6948     {
6949       errmsg ("missing mac address");
6950       return -99;
6951     }
6952
6953   if (bd_id_set == 0)
6954     {
6955       errmsg ("missing bridge domain");
6956       return -99;
6957     }
6958
6959   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6960     {
6961       errmsg ("missing interface name or sw_if_index");
6962       return -99;
6963     }
6964
6965   if (count > 1)
6966     {
6967       /* Turn on async mode */
6968       vam->async_mode = 1;
6969       vam->async_errors = 0;
6970       before = vat_time_now (vam);
6971     }
6972
6973   for (j = 0; j < count; j++)
6974     {
6975       M (L2FIB_ADD_DEL, mp);
6976
6977       mp->mac = mac;
6978       mp->bd_id = ntohl (bd_id);
6979       mp->is_add = is_add;
6980
6981       if (is_add)
6982         {
6983           mp->sw_if_index = ntohl (sw_if_index);
6984           mp->static_mac = static_mac;
6985           mp->filter_mac = filter_mac;
6986           mp->bvi_mac = bvi_mac;
6987         }
6988       increment_mac_address (&mac);
6989       /* send it... */
6990       S (mp);
6991     }
6992
6993   if (count > 1)
6994     {
6995       vl_api_control_ping_t *mp_ping;
6996       f64 after;
6997
6998       /* Shut off async mode */
6999       vam->async_mode = 0;
7000
7001       MPING (CONTROL_PING, mp_ping);
7002       S (mp_ping);
7003
7004       timeout = vat_time_now (vam) + 1.0;
7005       while (vat_time_now (vam) < timeout)
7006         if (vam->result_ready == 1)
7007           goto out;
7008       vam->retval = -99;
7009
7010     out:
7011       if (vam->retval == -99)
7012         errmsg ("timeout");
7013
7014       if (vam->async_errors > 0)
7015         {
7016           errmsg ("%d asynchronous errors", vam->async_errors);
7017           vam->retval = -98;
7018         }
7019       vam->async_errors = 0;
7020       after = vat_time_now (vam);
7021
7022       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7023              count, after - before, count / (after - before));
7024     }
7025   else
7026     {
7027       int ret;
7028
7029       /* Wait for a reply... */
7030       W (ret);
7031       return ret;
7032     }
7033   /* Return the good/bad news */
7034   return (vam->retval);
7035 }
7036
7037 static int
7038 api_bridge_domain_set_mac_age (vat_main_t * vam)
7039 {
7040   unformat_input_t *i = vam->input;
7041   vl_api_bridge_domain_set_mac_age_t *mp;
7042   u32 bd_id = ~0;
7043   u32 mac_age = 0;
7044   int ret;
7045
7046   /* Parse args required to build the message */
7047   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7048     {
7049       if (unformat (i, "bd_id %d", &bd_id));
7050       else if (unformat (i, "mac-age %d", &mac_age));
7051       else
7052         break;
7053     }
7054
7055   if (bd_id == ~0)
7056     {
7057       errmsg ("missing bridge domain");
7058       return -99;
7059     }
7060
7061   if (mac_age > 255)
7062     {
7063       errmsg ("mac age must be less than 256 ");
7064       return -99;
7065     }
7066
7067   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7068
7069   mp->bd_id = htonl (bd_id);
7070   mp->mac_age = (u8) mac_age;
7071
7072   S (mp);
7073   W (ret);
7074   return ret;
7075 }
7076
7077 static int
7078 api_l2_flags (vat_main_t * vam)
7079 {
7080   unformat_input_t *i = vam->input;
7081   vl_api_l2_flags_t *mp;
7082   u32 sw_if_index;
7083   u32 flags = 0;
7084   u8 sw_if_index_set = 0;
7085   u8 is_set = 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, "sw_if_index %d", &sw_if_index))
7092         sw_if_index_set = 1;
7093       else if (unformat (i, "sw_if"))
7094         {
7095           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7096             {
7097               if (unformat
7098                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7099                 sw_if_index_set = 1;
7100             }
7101           else
7102             break;
7103         }
7104       else if (unformat (i, "learn"))
7105         flags |= L2_LEARN;
7106       else if (unformat (i, "forward"))
7107         flags |= L2_FWD;
7108       else if (unformat (i, "flood"))
7109         flags |= L2_FLOOD;
7110       else if (unformat (i, "uu-flood"))
7111         flags |= L2_UU_FLOOD;
7112       else if (unformat (i, "arp-term"))
7113         flags |= L2_ARP_TERM;
7114       else if (unformat (i, "off"))
7115         is_set = 0;
7116       else if (unformat (i, "disable"))
7117         is_set = 0;
7118       else
7119         break;
7120     }
7121
7122   if (sw_if_index_set == 0)
7123     {
7124       errmsg ("missing interface name or sw_if_index");
7125       return -99;
7126     }
7127
7128   M (L2_FLAGS, mp);
7129
7130   mp->sw_if_index = ntohl (sw_if_index);
7131   mp->feature_bitmap = ntohl (flags);
7132   mp->is_set = is_set;
7133
7134   S (mp);
7135   W (ret);
7136   return ret;
7137 }
7138
7139 static int
7140 api_bridge_flags (vat_main_t * vam)
7141 {
7142   unformat_input_t *i = vam->input;
7143   vl_api_bridge_flags_t *mp;
7144   u32 bd_id;
7145   u8 bd_id_set = 0;
7146   u8 is_set = 1;
7147   u32 flags = 0;
7148   int ret;
7149
7150   /* Parse args required to build the message */
7151   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7152     {
7153       if (unformat (i, "bd_id %d", &bd_id))
7154         bd_id_set = 1;
7155       else if (unformat (i, "learn"))
7156         flags |= L2_LEARN;
7157       else if (unformat (i, "forward"))
7158         flags |= L2_FWD;
7159       else if (unformat (i, "flood"))
7160         flags |= L2_FLOOD;
7161       else if (unformat (i, "uu-flood"))
7162         flags |= L2_UU_FLOOD;
7163       else if (unformat (i, "arp-term"))
7164         flags |= L2_ARP_TERM;
7165       else if (unformat (i, "off"))
7166         is_set = 0;
7167       else if (unformat (i, "disable"))
7168         is_set = 0;
7169       else
7170         break;
7171     }
7172
7173   if (bd_id_set == 0)
7174     {
7175       errmsg ("missing bridge domain");
7176       return -99;
7177     }
7178
7179   M (BRIDGE_FLAGS, mp);
7180
7181   mp->bd_id = ntohl (bd_id);
7182   mp->feature_bitmap = ntohl (flags);
7183   mp->is_set = is_set;
7184
7185   S (mp);
7186   W (ret);
7187   return ret;
7188 }
7189
7190 static int
7191 api_bd_ip_mac_add_del (vat_main_t * vam)
7192 {
7193   unformat_input_t *i = vam->input;
7194   vl_api_bd_ip_mac_add_del_t *mp;
7195   u32 bd_id;
7196   u8 is_ipv6 = 0;
7197   u8 is_add = 1;
7198   u8 bd_id_set = 0;
7199   u8 ip_set = 0;
7200   u8 mac_set = 0;
7201   ip4_address_t v4addr;
7202   ip6_address_t v6addr;
7203   u8 macaddr[6];
7204   int ret;
7205
7206
7207   /* Parse args required to build the message */
7208   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7209     {
7210       if (unformat (i, "bd_id %d", &bd_id))
7211         {
7212           bd_id_set++;
7213         }
7214       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7215         {
7216           ip_set++;
7217         }
7218       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7219         {
7220           ip_set++;
7221           is_ipv6++;
7222         }
7223       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7224         {
7225           mac_set++;
7226         }
7227       else if (unformat (i, "del"))
7228         is_add = 0;
7229       else
7230         break;
7231     }
7232
7233   if (bd_id_set == 0)
7234     {
7235       errmsg ("missing bridge domain");
7236       return -99;
7237     }
7238   else if (ip_set == 0)
7239     {
7240       errmsg ("missing IP address");
7241       return -99;
7242     }
7243   else if (mac_set == 0)
7244     {
7245       errmsg ("missing MAC address");
7246       return -99;
7247     }
7248
7249   M (BD_IP_MAC_ADD_DEL, mp);
7250
7251   mp->bd_id = ntohl (bd_id);
7252   mp->is_ipv6 = is_ipv6;
7253   mp->is_add = is_add;
7254   if (is_ipv6)
7255     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7256   else
7257     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7258   clib_memcpy (mp->mac_address, macaddr, 6);
7259   S (mp);
7260   W (ret);
7261   return ret;
7262 }
7263
7264 static int
7265 api_tap_connect (vat_main_t * vam)
7266 {
7267   unformat_input_t *i = vam->input;
7268   vl_api_tap_connect_t *mp;
7269   u8 mac_address[6];
7270   u8 random_mac = 1;
7271   u8 name_set = 0;
7272   u8 *tap_name;
7273   u8 *tag = 0;
7274   ip4_address_t ip4_address;
7275   u32 ip4_mask_width;
7276   int ip4_address_set = 0;
7277   ip6_address_t ip6_address;
7278   u32 ip6_mask_width;
7279   int ip6_address_set = 0;
7280   int ret;
7281
7282   memset (mac_address, 0, sizeof (mac_address));
7283
7284   /* Parse args required to build the message */
7285   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7286     {
7287       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7288         {
7289           random_mac = 0;
7290         }
7291       else if (unformat (i, "random-mac"))
7292         random_mac = 1;
7293       else if (unformat (i, "tapname %s", &tap_name))
7294         name_set = 1;
7295       else if (unformat (i, "tag %s", &tag))
7296         ;
7297       else if (unformat (i, "address %U/%d",
7298                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7299         ip4_address_set = 1;
7300       else if (unformat (i, "address %U/%d",
7301                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7302         ip6_address_set = 1;
7303       else
7304         break;
7305     }
7306
7307   if (name_set == 0)
7308     {
7309       errmsg ("missing tap name");
7310       return -99;
7311     }
7312   if (vec_len (tap_name) > 63)
7313     {
7314       errmsg ("tap name too long");
7315       return -99;
7316     }
7317   vec_add1 (tap_name, 0);
7318
7319   if (vec_len (tag) > 63)
7320     {
7321       errmsg ("tag too long");
7322       return -99;
7323     }
7324
7325   /* Construct the API message */
7326   M (TAP_CONNECT, mp);
7327
7328   mp->use_random_mac = random_mac;
7329   clib_memcpy (mp->mac_address, mac_address, 6);
7330   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7331   if (tag)
7332     clib_memcpy (mp->tag, tag, vec_len (tag));
7333
7334   if (ip4_address_set)
7335     {
7336       mp->ip4_address_set = 1;
7337       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7338       mp->ip4_mask_width = ip4_mask_width;
7339     }
7340   if (ip6_address_set)
7341     {
7342       mp->ip6_address_set = 1;
7343       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7344       mp->ip6_mask_width = ip6_mask_width;
7345     }
7346
7347   vec_free (tap_name);
7348   vec_free (tag);
7349
7350   /* send it... */
7351   S (mp);
7352
7353   /* Wait for a reply... */
7354   W (ret);
7355   return ret;
7356 }
7357
7358 static int
7359 api_tap_modify (vat_main_t * vam)
7360 {
7361   unformat_input_t *i = vam->input;
7362   vl_api_tap_modify_t *mp;
7363   u8 mac_address[6];
7364   u8 random_mac = 1;
7365   u8 name_set = 0;
7366   u8 *tap_name;
7367   u32 sw_if_index = ~0;
7368   u8 sw_if_index_set = 0;
7369   int ret;
7370
7371   memset (mac_address, 0, sizeof (mac_address));
7372
7373   /* Parse args required to build the message */
7374   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7375     {
7376       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7377         sw_if_index_set = 1;
7378       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7379         sw_if_index_set = 1;
7380       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7381         {
7382           random_mac = 0;
7383         }
7384       else if (unformat (i, "random-mac"))
7385         random_mac = 1;
7386       else if (unformat (i, "tapname %s", &tap_name))
7387         name_set = 1;
7388       else
7389         break;
7390     }
7391
7392   if (sw_if_index_set == 0)
7393     {
7394       errmsg ("missing vpp interface name");
7395       return -99;
7396     }
7397   if (name_set == 0)
7398     {
7399       errmsg ("missing tap name");
7400       return -99;
7401     }
7402   if (vec_len (tap_name) > 63)
7403     {
7404       errmsg ("tap name too long");
7405     }
7406   vec_add1 (tap_name, 0);
7407
7408   /* Construct the API message */
7409   M (TAP_MODIFY, mp);
7410
7411   mp->use_random_mac = random_mac;
7412   mp->sw_if_index = ntohl (sw_if_index);
7413   clib_memcpy (mp->mac_address, mac_address, 6);
7414   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7415   vec_free (tap_name);
7416
7417   /* send it... */
7418   S (mp);
7419
7420   /* Wait for a reply... */
7421   W (ret);
7422   return ret;
7423 }
7424
7425 static int
7426 api_tap_delete (vat_main_t * vam)
7427 {
7428   unformat_input_t *i = vam->input;
7429   vl_api_tap_delete_t *mp;
7430   u32 sw_if_index = ~0;
7431   u8 sw_if_index_set = 0;
7432   int ret;
7433
7434   /* Parse args required to build the message */
7435   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7436     {
7437       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7438         sw_if_index_set = 1;
7439       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7440         sw_if_index_set = 1;
7441       else
7442         break;
7443     }
7444
7445   if (sw_if_index_set == 0)
7446     {
7447       errmsg ("missing vpp interface name");
7448       return -99;
7449     }
7450
7451   /* Construct the API message */
7452   M (TAP_DELETE, mp);
7453
7454   mp->sw_if_index = ntohl (sw_if_index);
7455
7456   /* send it... */
7457   S (mp);
7458
7459   /* Wait for a reply... */
7460   W (ret);
7461   return ret;
7462 }
7463
7464 static int
7465 api_ip_table_add_del (vat_main_t * vam)
7466 {
7467   unformat_input_t *i = vam->input;
7468   vl_api_ip_table_add_del_t *mp;
7469   u32 table_id = ~0;
7470   u8 is_ipv6 = 0;
7471   u8 is_add = 1;
7472   int ret = 0;
7473
7474   /* Parse args required to build the message */
7475   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7476     {
7477       if (unformat (i, "ipv6"))
7478         is_ipv6 = 1;
7479       else if (unformat (i, "del"))
7480         is_add = 0;
7481       else if (unformat (i, "add"))
7482         is_add = 1;
7483       else if (unformat (i, "table %d", &table_id))
7484         ;
7485       else
7486         {
7487           clib_warning ("parse error '%U'", format_unformat_error, i);
7488           return -99;
7489         }
7490     }
7491
7492   if (~0 == table_id)
7493     {
7494       errmsg ("missing table-ID");
7495       return -99;
7496     }
7497
7498   /* Construct the API message */
7499   M (IP_TABLE_ADD_DEL, mp);
7500
7501   mp->table_id = ntohl (table_id);
7502   mp->is_ipv6 = is_ipv6;
7503   mp->is_add = is_add;
7504
7505   /* send it... */
7506   S (mp);
7507
7508   /* Wait for a reply... */
7509   W (ret);
7510
7511   return ret;
7512 }
7513
7514 static int
7515 api_ip_add_del_route (vat_main_t * vam)
7516 {
7517   unformat_input_t *i = vam->input;
7518   vl_api_ip_add_del_route_t *mp;
7519   u32 sw_if_index = ~0, vrf_id = 0;
7520   u8 is_ipv6 = 0;
7521   u8 is_local = 0, is_drop = 0;
7522   u8 is_unreach = 0, is_prohibit = 0;
7523   u8 create_vrf_if_needed = 0;
7524   u8 is_add = 1;
7525   u32 next_hop_weight = 1;
7526   u8 not_last = 0;
7527   u8 is_multipath = 0;
7528   u8 address_set = 0;
7529   u8 address_length_set = 0;
7530   u32 next_hop_table_id = 0;
7531   u32 resolve_attempts = 0;
7532   u32 dst_address_length = 0;
7533   u8 next_hop_set = 0;
7534   ip4_address_t v4_dst_address, v4_next_hop_address;
7535   ip6_address_t v6_dst_address, v6_next_hop_address;
7536   int count = 1;
7537   int j;
7538   f64 before = 0;
7539   u32 random_add_del = 0;
7540   u32 *random_vector = 0;
7541   uword *random_hash;
7542   u32 random_seed = 0xdeaddabe;
7543   u32 classify_table_index = ~0;
7544   u8 is_classify = 0;
7545   u8 resolve_host = 0, resolve_attached = 0;
7546   mpls_label_t *next_hop_out_label_stack = NULL;
7547   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7548   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7549
7550   /* Parse args required to build the message */
7551   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7552     {
7553       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7554         ;
7555       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7556         ;
7557       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
7558         {
7559           address_set = 1;
7560           is_ipv6 = 0;
7561         }
7562       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
7563         {
7564           address_set = 1;
7565           is_ipv6 = 1;
7566         }
7567       else if (unformat (i, "/%d", &dst_address_length))
7568         {
7569           address_length_set = 1;
7570         }
7571
7572       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
7573                                          &v4_next_hop_address))
7574         {
7575           next_hop_set = 1;
7576         }
7577       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
7578                                          &v6_next_hop_address))
7579         {
7580           next_hop_set = 1;
7581         }
7582       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
7583         ;
7584       else if (unformat (i, "weight %d", &next_hop_weight))
7585         ;
7586       else if (unformat (i, "drop"))
7587         {
7588           is_drop = 1;
7589         }
7590       else if (unformat (i, "null-send-unreach"))
7591         {
7592           is_unreach = 1;
7593         }
7594       else if (unformat (i, "null-send-prohibit"))
7595         {
7596           is_prohibit = 1;
7597         }
7598       else if (unformat (i, "local"))
7599         {
7600           is_local = 1;
7601         }
7602       else if (unformat (i, "classify %d", &classify_table_index))
7603         {
7604           is_classify = 1;
7605         }
7606       else if (unformat (i, "del"))
7607         is_add = 0;
7608       else if (unformat (i, "add"))
7609         is_add = 1;
7610       else if (unformat (i, "not-last"))
7611         not_last = 1;
7612       else if (unformat (i, "resolve-via-host"))
7613         resolve_host = 1;
7614       else if (unformat (i, "resolve-via-attached"))
7615         resolve_attached = 1;
7616       else if (unformat (i, "multipath"))
7617         is_multipath = 1;
7618       else if (unformat (i, "vrf %d", &vrf_id))
7619         ;
7620       else if (unformat (i, "create-vrf"))
7621         create_vrf_if_needed = 1;
7622       else if (unformat (i, "count %d", &count))
7623         ;
7624       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
7625         ;
7626       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7627         ;
7628       else if (unformat (i, "out-label %d", &next_hop_out_label))
7629         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7630       else if (unformat (i, "via-label %d", &next_hop_via_label))
7631         ;
7632       else if (unformat (i, "random"))
7633         random_add_del = 1;
7634       else if (unformat (i, "seed %d", &random_seed))
7635         ;
7636       else
7637         {
7638           clib_warning ("parse error '%U'", format_unformat_error, i);
7639           return -99;
7640         }
7641     }
7642
7643   if (!next_hop_set && !is_drop && !is_local &&
7644       !is_classify && !is_unreach && !is_prohibit &&
7645       MPLS_LABEL_INVALID == next_hop_via_label)
7646     {
7647       errmsg
7648         ("next hop / local / drop / unreach / prohibit / classify not set");
7649       return -99;
7650     }
7651
7652   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
7653     {
7654       errmsg ("next hop and next-hop via label set");
7655       return -99;
7656     }
7657   if (address_set == 0)
7658     {
7659       errmsg ("missing addresses");
7660       return -99;
7661     }
7662
7663   if (address_length_set == 0)
7664     {
7665       errmsg ("missing address length");
7666       return -99;
7667     }
7668
7669   /* Generate a pile of unique, random routes */
7670   if (random_add_del)
7671     {
7672       u32 this_random_address;
7673       random_hash = hash_create (count, sizeof (uword));
7674
7675       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
7676       for (j = 0; j <= count; j++)
7677         {
7678           do
7679             {
7680               this_random_address = random_u32 (&random_seed);
7681               this_random_address =
7682                 clib_host_to_net_u32 (this_random_address);
7683             }
7684           while (hash_get (random_hash, this_random_address));
7685           vec_add1 (random_vector, this_random_address);
7686           hash_set (random_hash, this_random_address, 1);
7687         }
7688       hash_free (random_hash);
7689       v4_dst_address.as_u32 = random_vector[0];
7690     }
7691
7692   if (count > 1)
7693     {
7694       /* Turn on async mode */
7695       vam->async_mode = 1;
7696       vam->async_errors = 0;
7697       before = vat_time_now (vam);
7698     }
7699
7700   for (j = 0; j < count; j++)
7701     {
7702       /* Construct the API message */
7703       M2 (IP_ADD_DEL_ROUTE, mp,
7704           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7705
7706       mp->next_hop_sw_if_index = ntohl (sw_if_index);
7707       mp->table_id = ntohl (vrf_id);
7708       mp->create_vrf_if_needed = create_vrf_if_needed;
7709
7710       mp->is_add = is_add;
7711       mp->is_drop = is_drop;
7712       mp->is_unreach = is_unreach;
7713       mp->is_prohibit = is_prohibit;
7714       mp->is_ipv6 = is_ipv6;
7715       mp->is_local = is_local;
7716       mp->is_classify = is_classify;
7717       mp->is_multipath = is_multipath;
7718       mp->is_resolve_host = resolve_host;
7719       mp->is_resolve_attached = resolve_attached;
7720       mp->not_last = not_last;
7721       mp->next_hop_weight = next_hop_weight;
7722       mp->dst_address_length = dst_address_length;
7723       mp->next_hop_table_id = ntohl (next_hop_table_id);
7724       mp->classify_table_index = ntohl (classify_table_index);
7725       mp->next_hop_via_label = ntohl (next_hop_via_label);
7726       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7727       if (0 != mp->next_hop_n_out_labels)
7728         {
7729           memcpy (mp->next_hop_out_label_stack,
7730                   next_hop_out_label_stack,
7731                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7732           vec_free (next_hop_out_label_stack);
7733         }
7734
7735       if (is_ipv6)
7736         {
7737           clib_memcpy (mp->dst_address, &v6_dst_address,
7738                        sizeof (v6_dst_address));
7739           if (next_hop_set)
7740             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
7741                          sizeof (v6_next_hop_address));
7742           increment_v6_address (&v6_dst_address);
7743         }
7744       else
7745         {
7746           clib_memcpy (mp->dst_address, &v4_dst_address,
7747                        sizeof (v4_dst_address));
7748           if (next_hop_set)
7749             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
7750                          sizeof (v4_next_hop_address));
7751           if (random_add_del)
7752             v4_dst_address.as_u32 = random_vector[j + 1];
7753           else
7754             increment_v4_address (&v4_dst_address);
7755         }
7756       /* send it... */
7757       S (mp);
7758       /* If we receive SIGTERM, stop now... */
7759       if (vam->do_exit)
7760         break;
7761     }
7762
7763   /* When testing multiple add/del ops, use a control-ping to sync */
7764   if (count > 1)
7765     {
7766       vl_api_control_ping_t *mp_ping;
7767       f64 after;
7768       f64 timeout;
7769
7770       /* Shut off async mode */
7771       vam->async_mode = 0;
7772
7773       MPING (CONTROL_PING, mp_ping);
7774       S (mp_ping);
7775
7776       timeout = vat_time_now (vam) + 1.0;
7777       while (vat_time_now (vam) < timeout)
7778         if (vam->result_ready == 1)
7779           goto out;
7780       vam->retval = -99;
7781
7782     out:
7783       if (vam->retval == -99)
7784         errmsg ("timeout");
7785
7786       if (vam->async_errors > 0)
7787         {
7788           errmsg ("%d asynchronous errors", vam->async_errors);
7789           vam->retval = -98;
7790         }
7791       vam->async_errors = 0;
7792       after = vat_time_now (vam);
7793
7794       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7795       if (j > 0)
7796         count = j;
7797
7798       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7799              count, after - before, count / (after - before));
7800     }
7801   else
7802     {
7803       int ret;
7804
7805       /* Wait for a reply... */
7806       W (ret);
7807       return ret;
7808     }
7809
7810   /* Return the good/bad news */
7811   return (vam->retval);
7812 }
7813
7814 static int
7815 api_ip_mroute_add_del (vat_main_t * vam)
7816 {
7817   unformat_input_t *i = vam->input;
7818   vl_api_ip_mroute_add_del_t *mp;
7819   u32 sw_if_index = ~0, vrf_id = 0;
7820   u8 is_ipv6 = 0;
7821   u8 is_local = 0;
7822   u8 create_vrf_if_needed = 0;
7823   u8 is_add = 1;
7824   u8 address_set = 0;
7825   u32 grp_address_length = 0;
7826   ip4_address_t v4_grp_address, v4_src_address;
7827   ip6_address_t v6_grp_address, v6_src_address;
7828   mfib_itf_flags_t iflags = 0;
7829   mfib_entry_flags_t eflags = 0;
7830   int ret;
7831
7832   /* Parse args required to build the message */
7833   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7834     {
7835       if (unformat (i, "sw_if_index %d", &sw_if_index))
7836         ;
7837       else if (unformat (i, "%U %U",
7838                          unformat_ip4_address, &v4_src_address,
7839                          unformat_ip4_address, &v4_grp_address))
7840         {
7841           grp_address_length = 64;
7842           address_set = 1;
7843           is_ipv6 = 0;
7844         }
7845       else if (unformat (i, "%U %U",
7846                          unformat_ip6_address, &v6_src_address,
7847                          unformat_ip6_address, &v6_grp_address))
7848         {
7849           grp_address_length = 256;
7850           address_set = 1;
7851           is_ipv6 = 1;
7852         }
7853       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
7854         {
7855           memset (&v4_src_address, 0, sizeof (v4_src_address));
7856           grp_address_length = 32;
7857           address_set = 1;
7858           is_ipv6 = 0;
7859         }
7860       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
7861         {
7862           memset (&v6_src_address, 0, sizeof (v6_src_address));
7863           grp_address_length = 128;
7864           address_set = 1;
7865           is_ipv6 = 1;
7866         }
7867       else if (unformat (i, "/%d", &grp_address_length))
7868         ;
7869       else if (unformat (i, "local"))
7870         {
7871           is_local = 1;
7872         }
7873       else if (unformat (i, "del"))
7874         is_add = 0;
7875       else if (unformat (i, "add"))
7876         is_add = 1;
7877       else if (unformat (i, "vrf %d", &vrf_id))
7878         ;
7879       else if (unformat (i, "create-vrf"))
7880         create_vrf_if_needed = 1;
7881       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
7882         ;
7883       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
7884         ;
7885       else
7886         {
7887           clib_warning ("parse error '%U'", format_unformat_error, i);
7888           return -99;
7889         }
7890     }
7891
7892   if (address_set == 0)
7893     {
7894       errmsg ("missing addresses\n");
7895       return -99;
7896     }
7897
7898   /* Construct the API message */
7899   M (IP_MROUTE_ADD_DEL, mp);
7900
7901   mp->next_hop_sw_if_index = ntohl (sw_if_index);
7902   mp->table_id = ntohl (vrf_id);
7903   mp->create_vrf_if_needed = create_vrf_if_needed;
7904
7905   mp->is_add = is_add;
7906   mp->is_ipv6 = is_ipv6;
7907   mp->is_local = is_local;
7908   mp->itf_flags = ntohl (iflags);
7909   mp->entry_flags = ntohl (eflags);
7910   mp->grp_address_length = grp_address_length;
7911   mp->grp_address_length = ntohs (mp->grp_address_length);
7912
7913   if (is_ipv6)
7914     {
7915       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
7916       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
7917     }
7918   else
7919     {
7920       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
7921       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
7922
7923     }
7924
7925   /* send it... */
7926   S (mp);
7927   /* Wait for a reply... */
7928   W (ret);
7929   return ret;
7930 }
7931
7932 static int
7933 api_mpls_table_add_del (vat_main_t * vam)
7934 {
7935   unformat_input_t *i = vam->input;
7936   vl_api_mpls_table_add_del_t *mp;
7937   u32 table_id = ~0;
7938   u8 is_add = 1;
7939   int ret = 0;
7940
7941   /* Parse args required to build the message */
7942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7943     {
7944       if (unformat (i, "table %d", &table_id))
7945         ;
7946       else if (unformat (i, "del"))
7947         is_add = 0;
7948       else if (unformat (i, "add"))
7949         is_add = 1;
7950       else
7951         {
7952           clib_warning ("parse error '%U'", format_unformat_error, i);
7953           return -99;
7954         }
7955     }
7956
7957   if (~0 == table_id)
7958     {
7959       errmsg ("missing table-ID");
7960       return -99;
7961     }
7962
7963   /* Construct the API message */
7964   M (MPLS_TABLE_ADD_DEL, mp);
7965
7966   mp->mt_table_id = ntohl (table_id);
7967   mp->mt_is_add = is_add;
7968
7969   /* send it... */
7970   S (mp);
7971
7972   /* Wait for a reply... */
7973   W (ret);
7974
7975   return ret;
7976 }
7977
7978 static int
7979 api_mpls_route_add_del (vat_main_t * vam)
7980 {
7981   unformat_input_t *i = vam->input;
7982   vl_api_mpls_route_add_del_t *mp;
7983   u32 sw_if_index = ~0, table_id = 0;
7984   u8 create_table_if_needed = 0;
7985   u8 is_add = 1;
7986   u32 next_hop_weight = 1;
7987   u8 is_multipath = 0;
7988   u32 next_hop_table_id = 0;
7989   u8 next_hop_set = 0;
7990   ip4_address_t v4_next_hop_address = {
7991     .as_u32 = 0,
7992   };
7993   ip6_address_t v6_next_hop_address = { {0} };
7994   int count = 1;
7995   int j;
7996   f64 before = 0;
7997   u32 classify_table_index = ~0;
7998   u8 is_classify = 0;
7999   u8 resolve_host = 0, resolve_attached = 0;
8000   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8001   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8002   mpls_label_t *next_hop_out_label_stack = NULL;
8003   mpls_label_t local_label = MPLS_LABEL_INVALID;
8004   u8 is_eos = 0;
8005   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8006
8007   /* Parse args required to build the message */
8008   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8009     {
8010       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8011         ;
8012       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8013         ;
8014       else if (unformat (i, "%d", &local_label))
8015         ;
8016       else if (unformat (i, "eos"))
8017         is_eos = 1;
8018       else if (unformat (i, "non-eos"))
8019         is_eos = 0;
8020       else if (unformat (i, "via %U", unformat_ip4_address,
8021                          &v4_next_hop_address))
8022         {
8023           next_hop_set = 1;
8024           next_hop_proto = DPO_PROTO_IP4;
8025         }
8026       else if (unformat (i, "via %U", unformat_ip6_address,
8027                          &v6_next_hop_address))
8028         {
8029           next_hop_set = 1;
8030           next_hop_proto = DPO_PROTO_IP6;
8031         }
8032       else if (unformat (i, "weight %d", &next_hop_weight))
8033         ;
8034       else if (unformat (i, "create-table"))
8035         create_table_if_needed = 1;
8036       else if (unformat (i, "classify %d", &classify_table_index))
8037         {
8038           is_classify = 1;
8039         }
8040       else if (unformat (i, "del"))
8041         is_add = 0;
8042       else if (unformat (i, "add"))
8043         is_add = 1;
8044       else if (unformat (i, "resolve-via-host"))
8045         resolve_host = 1;
8046       else if (unformat (i, "resolve-via-attached"))
8047         resolve_attached = 1;
8048       else if (unformat (i, "multipath"))
8049         is_multipath = 1;
8050       else if (unformat (i, "count %d", &count))
8051         ;
8052       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8053         {
8054           next_hop_set = 1;
8055           next_hop_proto = DPO_PROTO_IP4;
8056         }
8057       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8058         {
8059           next_hop_set = 1;
8060           next_hop_proto = DPO_PROTO_IP6;
8061         }
8062       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8063         ;
8064       else if (unformat (i, "via-label %d", &next_hop_via_label))
8065         ;
8066       else if (unformat (i, "out-label %d", &next_hop_out_label))
8067         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8068       else
8069         {
8070           clib_warning ("parse error '%U'", format_unformat_error, i);
8071           return -99;
8072         }
8073     }
8074
8075   if (!next_hop_set && !is_classify)
8076     {
8077       errmsg ("next hop / classify not set");
8078       return -99;
8079     }
8080
8081   if (MPLS_LABEL_INVALID == local_label)
8082     {
8083       errmsg ("missing label");
8084       return -99;
8085     }
8086
8087   if (count > 1)
8088     {
8089       /* Turn on async mode */
8090       vam->async_mode = 1;
8091       vam->async_errors = 0;
8092       before = vat_time_now (vam);
8093     }
8094
8095   for (j = 0; j < count; j++)
8096     {
8097       /* Construct the API message */
8098       M2 (MPLS_ROUTE_ADD_DEL, mp,
8099           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8100
8101       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8102       mp->mr_table_id = ntohl (table_id);
8103       mp->mr_create_table_if_needed = create_table_if_needed;
8104
8105       mp->mr_is_add = is_add;
8106       mp->mr_next_hop_proto = next_hop_proto;
8107       mp->mr_is_classify = is_classify;
8108       mp->mr_is_multipath = is_multipath;
8109       mp->mr_is_resolve_host = resolve_host;
8110       mp->mr_is_resolve_attached = resolve_attached;
8111       mp->mr_next_hop_weight = next_hop_weight;
8112       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8113       mp->mr_classify_table_index = ntohl (classify_table_index);
8114       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8115       mp->mr_label = ntohl (local_label);
8116       mp->mr_eos = is_eos;
8117
8118       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8119       if (0 != mp->mr_next_hop_n_out_labels)
8120         {
8121           memcpy (mp->mr_next_hop_out_label_stack,
8122                   next_hop_out_label_stack,
8123                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8124           vec_free (next_hop_out_label_stack);
8125         }
8126
8127       if (next_hop_set)
8128         {
8129           if (DPO_PROTO_IP4 == next_hop_proto)
8130             {
8131               clib_memcpy (mp->mr_next_hop,
8132                            &v4_next_hop_address,
8133                            sizeof (v4_next_hop_address));
8134             }
8135           else if (DPO_PROTO_IP6 == next_hop_proto)
8136
8137             {
8138               clib_memcpy (mp->mr_next_hop,
8139                            &v6_next_hop_address,
8140                            sizeof (v6_next_hop_address));
8141             }
8142         }
8143       local_label++;
8144
8145       /* send it... */
8146       S (mp);
8147       /* If we receive SIGTERM, stop now... */
8148       if (vam->do_exit)
8149         break;
8150     }
8151
8152   /* When testing multiple add/del ops, use a control-ping to sync */
8153   if (count > 1)
8154     {
8155       vl_api_control_ping_t *mp_ping;
8156       f64 after;
8157       f64 timeout;
8158
8159       /* Shut off async mode */
8160       vam->async_mode = 0;
8161
8162       MPING (CONTROL_PING, mp_ping);
8163       S (mp_ping);
8164
8165       timeout = vat_time_now (vam) + 1.0;
8166       while (vat_time_now (vam) < timeout)
8167         if (vam->result_ready == 1)
8168           goto out;
8169       vam->retval = -99;
8170
8171     out:
8172       if (vam->retval == -99)
8173         errmsg ("timeout");
8174
8175       if (vam->async_errors > 0)
8176         {
8177           errmsg ("%d asynchronous errors", vam->async_errors);
8178           vam->retval = -98;
8179         }
8180       vam->async_errors = 0;
8181       after = vat_time_now (vam);
8182
8183       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8184       if (j > 0)
8185         count = j;
8186
8187       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8188              count, after - before, count / (after - before));
8189     }
8190   else
8191     {
8192       int ret;
8193
8194       /* Wait for a reply... */
8195       W (ret);
8196       return ret;
8197     }
8198
8199   /* Return the good/bad news */
8200   return (vam->retval);
8201 }
8202
8203 static int
8204 api_mpls_ip_bind_unbind (vat_main_t * vam)
8205 {
8206   unformat_input_t *i = vam->input;
8207   vl_api_mpls_ip_bind_unbind_t *mp;
8208   u32 ip_table_id = 0;
8209   u8 create_table_if_needed = 0;
8210   u8 is_bind = 1;
8211   u8 is_ip4 = 1;
8212   ip4_address_t v4_address;
8213   ip6_address_t v6_address;
8214   u32 address_length;
8215   u8 address_set = 0;
8216   mpls_label_t local_label = MPLS_LABEL_INVALID;
8217   int ret;
8218
8219   /* Parse args required to build the message */
8220   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8221     {
8222       if (unformat (i, "%U/%d", unformat_ip4_address,
8223                     &v4_address, &address_length))
8224         {
8225           is_ip4 = 1;
8226           address_set = 1;
8227         }
8228       else if (unformat (i, "%U/%d", unformat_ip6_address,
8229                          &v6_address, &address_length))
8230         {
8231           is_ip4 = 0;
8232           address_set = 1;
8233         }
8234       else if (unformat (i, "%d", &local_label))
8235         ;
8236       else if (unformat (i, "create-table"))
8237         create_table_if_needed = 1;
8238       else if (unformat (i, "table-id %d", &ip_table_id))
8239         ;
8240       else if (unformat (i, "unbind"))
8241         is_bind = 0;
8242       else if (unformat (i, "bind"))
8243         is_bind = 1;
8244       else
8245         {
8246           clib_warning ("parse error '%U'", format_unformat_error, i);
8247           return -99;
8248         }
8249     }
8250
8251   if (!address_set)
8252     {
8253       errmsg ("IP addres not set");
8254       return -99;
8255     }
8256
8257   if (MPLS_LABEL_INVALID == local_label)
8258     {
8259       errmsg ("missing label");
8260       return -99;
8261     }
8262
8263   /* Construct the API message */
8264   M (MPLS_IP_BIND_UNBIND, mp);
8265
8266   mp->mb_create_table_if_needed = create_table_if_needed;
8267   mp->mb_is_bind = is_bind;
8268   mp->mb_is_ip4 = is_ip4;
8269   mp->mb_ip_table_id = ntohl (ip_table_id);
8270   mp->mb_mpls_table_id = 0;
8271   mp->mb_label = ntohl (local_label);
8272   mp->mb_address_length = address_length;
8273
8274   if (is_ip4)
8275     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8276   else
8277     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8278
8279   /* send it... */
8280   S (mp);
8281
8282   /* Wait for a reply... */
8283   W (ret);
8284   return ret;
8285 }
8286
8287 static int
8288 api_proxy_arp_add_del (vat_main_t * vam)
8289 {
8290   unformat_input_t *i = vam->input;
8291   vl_api_proxy_arp_add_del_t *mp;
8292   u32 vrf_id = 0;
8293   u8 is_add = 1;
8294   ip4_address_t lo, hi;
8295   u8 range_set = 0;
8296   int ret;
8297
8298   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8299     {
8300       if (unformat (i, "vrf %d", &vrf_id))
8301         ;
8302       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
8303                          unformat_ip4_address, &hi))
8304         range_set = 1;
8305       else if (unformat (i, "del"))
8306         is_add = 0;
8307       else
8308         {
8309           clib_warning ("parse error '%U'", format_unformat_error, i);
8310           return -99;
8311         }
8312     }
8313
8314   if (range_set == 0)
8315     {
8316       errmsg ("address range not set");
8317       return -99;
8318     }
8319
8320   M (PROXY_ARP_ADD_DEL, mp);
8321
8322   mp->vrf_id = ntohl (vrf_id);
8323   mp->is_add = is_add;
8324   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
8325   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
8326
8327   S (mp);
8328   W (ret);
8329   return ret;
8330 }
8331
8332 static int
8333 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8334 {
8335   unformat_input_t *i = vam->input;
8336   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8337   u32 sw_if_index;
8338   u8 enable = 1;
8339   u8 sw_if_index_set = 0;
8340   int ret;
8341
8342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8343     {
8344       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8345         sw_if_index_set = 1;
8346       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8347         sw_if_index_set = 1;
8348       else if (unformat (i, "enable"))
8349         enable = 1;
8350       else if (unformat (i, "disable"))
8351         enable = 0;
8352       else
8353         {
8354           clib_warning ("parse error '%U'", format_unformat_error, i);
8355           return -99;
8356         }
8357     }
8358
8359   if (sw_if_index_set == 0)
8360     {
8361       errmsg ("missing interface name or sw_if_index");
8362       return -99;
8363     }
8364
8365   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8366
8367   mp->sw_if_index = ntohl (sw_if_index);
8368   mp->enable_disable = enable;
8369
8370   S (mp);
8371   W (ret);
8372   return ret;
8373 }
8374
8375 static int
8376 api_mpls_tunnel_add_del (vat_main_t * vam)
8377 {
8378   unformat_input_t *i = vam->input;
8379   vl_api_mpls_tunnel_add_del_t *mp;
8380
8381   u8 is_add = 1;
8382   u8 l2_only = 0;
8383   u32 sw_if_index = ~0;
8384   u32 next_hop_sw_if_index = ~0;
8385   u32 next_hop_proto_is_ip4 = 1;
8386
8387   u32 next_hop_table_id = 0;
8388   ip4_address_t v4_next_hop_address = {
8389     .as_u32 = 0,
8390   };
8391   ip6_address_t v6_next_hop_address = { {0} };
8392   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
8393   int ret;
8394
8395   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8396     {
8397       if (unformat (i, "add"))
8398         is_add = 1;
8399       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8400         is_add = 0;
8401       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
8402         ;
8403       else if (unformat (i, "via %U",
8404                          unformat_ip4_address, &v4_next_hop_address))
8405         {
8406           next_hop_proto_is_ip4 = 1;
8407         }
8408       else if (unformat (i, "via %U",
8409                          unformat_ip6_address, &v6_next_hop_address))
8410         {
8411           next_hop_proto_is_ip4 = 0;
8412         }
8413       else if (unformat (i, "l2-only"))
8414         l2_only = 1;
8415       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8416         ;
8417       else if (unformat (i, "out-label %d", &next_hop_out_label))
8418         vec_add1 (labels, ntohl (next_hop_out_label));
8419       else
8420         {
8421           clib_warning ("parse error '%U'", format_unformat_error, i);
8422           return -99;
8423         }
8424     }
8425
8426   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
8427
8428   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
8429   mp->mt_sw_if_index = ntohl (sw_if_index);
8430   mp->mt_is_add = is_add;
8431   mp->mt_l2_only = l2_only;
8432   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
8433   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
8434
8435   mp->mt_next_hop_n_out_labels = vec_len (labels);
8436
8437   if (0 != mp->mt_next_hop_n_out_labels)
8438     {
8439       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
8440                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
8441       vec_free (labels);
8442     }
8443
8444   if (next_hop_proto_is_ip4)
8445     {
8446       clib_memcpy (mp->mt_next_hop,
8447                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8448     }
8449   else
8450     {
8451       clib_memcpy (mp->mt_next_hop,
8452                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8453     }
8454
8455   S (mp);
8456   W (ret);
8457   return ret;
8458 }
8459
8460 static int
8461 api_sw_interface_set_unnumbered (vat_main_t * vam)
8462 {
8463   unformat_input_t *i = vam->input;
8464   vl_api_sw_interface_set_unnumbered_t *mp;
8465   u32 sw_if_index;
8466   u32 unnum_sw_index = ~0;
8467   u8 is_add = 1;
8468   u8 sw_if_index_set = 0;
8469   int ret;
8470
8471   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8472     {
8473       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8474         sw_if_index_set = 1;
8475       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8476         sw_if_index_set = 1;
8477       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8478         ;
8479       else if (unformat (i, "del"))
8480         is_add = 0;
8481       else
8482         {
8483           clib_warning ("parse error '%U'", format_unformat_error, i);
8484           return -99;
8485         }
8486     }
8487
8488   if (sw_if_index_set == 0)
8489     {
8490       errmsg ("missing interface name or sw_if_index");
8491       return -99;
8492     }
8493
8494   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8495
8496   mp->sw_if_index = ntohl (sw_if_index);
8497   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8498   mp->is_add = is_add;
8499
8500   S (mp);
8501   W (ret);
8502   return ret;
8503 }
8504
8505 static int
8506 api_ip_neighbor_add_del (vat_main_t * vam)
8507 {
8508   unformat_input_t *i = vam->input;
8509   vl_api_ip_neighbor_add_del_t *mp;
8510   u32 sw_if_index;
8511   u8 sw_if_index_set = 0;
8512   u8 is_add = 1;
8513   u8 is_static = 0;
8514   u8 is_no_fib_entry = 0;
8515   u8 mac_address[6];
8516   u8 mac_set = 0;
8517   u8 v4_address_set = 0;
8518   u8 v6_address_set = 0;
8519   ip4_address_t v4address;
8520   ip6_address_t v6address;
8521   int ret;
8522
8523   memset (mac_address, 0, sizeof (mac_address));
8524
8525   /* Parse args required to build the message */
8526   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8527     {
8528       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8529         {
8530           mac_set = 1;
8531         }
8532       else if (unformat (i, "del"))
8533         is_add = 0;
8534       else
8535         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8536         sw_if_index_set = 1;
8537       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8538         sw_if_index_set = 1;
8539       else if (unformat (i, "is_static"))
8540         is_static = 1;
8541       else if (unformat (i, "no-fib-entry"))
8542         is_no_fib_entry = 1;
8543       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
8544         v4_address_set = 1;
8545       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
8546         v6_address_set = 1;
8547       else
8548         {
8549           clib_warning ("parse error '%U'", format_unformat_error, i);
8550           return -99;
8551         }
8552     }
8553
8554   if (sw_if_index_set == 0)
8555     {
8556       errmsg ("missing interface name or sw_if_index");
8557       return -99;
8558     }
8559   if (v4_address_set && v6_address_set)
8560     {
8561       errmsg ("both v4 and v6 addresses set");
8562       return -99;
8563     }
8564   if (!v4_address_set && !v6_address_set)
8565     {
8566       errmsg ("no address set");
8567       return -99;
8568     }
8569
8570   /* Construct the API message */
8571   M (IP_NEIGHBOR_ADD_DEL, mp);
8572
8573   mp->sw_if_index = ntohl (sw_if_index);
8574   mp->is_add = is_add;
8575   mp->is_static = is_static;
8576   mp->is_no_adj_fib = is_no_fib_entry;
8577   if (mac_set)
8578     clib_memcpy (mp->mac_address, mac_address, 6);
8579   if (v6_address_set)
8580     {
8581       mp->is_ipv6 = 1;
8582       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
8583     }
8584   else
8585     {
8586       /* mp->is_ipv6 = 0; via memset in M macro above */
8587       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
8588     }
8589
8590   /* send it... */
8591   S (mp);
8592
8593   /* Wait for a reply, return good/bad news  */
8594   W (ret);
8595   return ret;
8596 }
8597
8598 static int
8599 api_reset_vrf (vat_main_t * vam)
8600 {
8601   unformat_input_t *i = vam->input;
8602   vl_api_reset_vrf_t *mp;
8603   u32 vrf_id = 0;
8604   u8 is_ipv6 = 0;
8605   u8 vrf_id_set = 0;
8606   int ret;
8607
8608   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8609     {
8610       if (unformat (i, "vrf %d", &vrf_id))
8611         vrf_id_set = 1;
8612       else if (unformat (i, "ipv6"))
8613         is_ipv6 = 1;
8614       else
8615         {
8616           clib_warning ("parse error '%U'", format_unformat_error, i);
8617           return -99;
8618         }
8619     }
8620
8621   if (vrf_id_set == 0)
8622     {
8623       errmsg ("missing vrf id");
8624       return -99;
8625     }
8626
8627   M (RESET_VRF, mp);
8628
8629   mp->vrf_id = ntohl (vrf_id);
8630   mp->is_ipv6 = is_ipv6;
8631
8632   S (mp);
8633   W (ret);
8634   return ret;
8635 }
8636
8637 static int
8638 api_create_vlan_subif (vat_main_t * vam)
8639 {
8640   unformat_input_t *i = vam->input;
8641   vl_api_create_vlan_subif_t *mp;
8642   u32 sw_if_index;
8643   u8 sw_if_index_set = 0;
8644   u32 vlan_id;
8645   u8 vlan_id_set = 0;
8646   int ret;
8647
8648   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8649     {
8650       if (unformat (i, "sw_if_index %d", &sw_if_index))
8651         sw_if_index_set = 1;
8652       else
8653         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8654         sw_if_index_set = 1;
8655       else if (unformat (i, "vlan %d", &vlan_id))
8656         vlan_id_set = 1;
8657       else
8658         {
8659           clib_warning ("parse error '%U'", format_unformat_error, i);
8660           return -99;
8661         }
8662     }
8663
8664   if (sw_if_index_set == 0)
8665     {
8666       errmsg ("missing interface name or sw_if_index");
8667       return -99;
8668     }
8669
8670   if (vlan_id_set == 0)
8671     {
8672       errmsg ("missing vlan_id");
8673       return -99;
8674     }
8675   M (CREATE_VLAN_SUBIF, mp);
8676
8677   mp->sw_if_index = ntohl (sw_if_index);
8678   mp->vlan_id = ntohl (vlan_id);
8679
8680   S (mp);
8681   W (ret);
8682   return ret;
8683 }
8684
8685 #define foreach_create_subif_bit                \
8686 _(no_tags)                                      \
8687 _(one_tag)                                      \
8688 _(two_tags)                                     \
8689 _(dot1ad)                                       \
8690 _(exact_match)                                  \
8691 _(default_sub)                                  \
8692 _(outer_vlan_id_any)                            \
8693 _(inner_vlan_id_any)
8694
8695 static int
8696 api_create_subif (vat_main_t * vam)
8697 {
8698   unformat_input_t *i = vam->input;
8699   vl_api_create_subif_t *mp;
8700   u32 sw_if_index;
8701   u8 sw_if_index_set = 0;
8702   u32 sub_id;
8703   u8 sub_id_set = 0;
8704   u32 no_tags = 0;
8705   u32 one_tag = 0;
8706   u32 two_tags = 0;
8707   u32 dot1ad = 0;
8708   u32 exact_match = 0;
8709   u32 default_sub = 0;
8710   u32 outer_vlan_id_any = 0;
8711   u32 inner_vlan_id_any = 0;
8712   u32 tmp;
8713   u16 outer_vlan_id = 0;
8714   u16 inner_vlan_id = 0;
8715   int ret;
8716
8717   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8718     {
8719       if (unformat (i, "sw_if_index %d", &sw_if_index))
8720         sw_if_index_set = 1;
8721       else
8722         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8723         sw_if_index_set = 1;
8724       else if (unformat (i, "sub_id %d", &sub_id))
8725         sub_id_set = 1;
8726       else if (unformat (i, "outer_vlan_id %d", &tmp))
8727         outer_vlan_id = tmp;
8728       else if (unformat (i, "inner_vlan_id %d", &tmp))
8729         inner_vlan_id = tmp;
8730
8731 #define _(a) else if (unformat (i, #a)) a = 1 ;
8732       foreach_create_subif_bit
8733 #undef _
8734         else
8735         {
8736           clib_warning ("parse error '%U'", format_unformat_error, i);
8737           return -99;
8738         }
8739     }
8740
8741   if (sw_if_index_set == 0)
8742     {
8743       errmsg ("missing interface name or sw_if_index");
8744       return -99;
8745     }
8746
8747   if (sub_id_set == 0)
8748     {
8749       errmsg ("missing sub_id");
8750       return -99;
8751     }
8752   M (CREATE_SUBIF, mp);
8753
8754   mp->sw_if_index = ntohl (sw_if_index);
8755   mp->sub_id = ntohl (sub_id);
8756
8757 #define _(a) mp->a = a;
8758   foreach_create_subif_bit;
8759 #undef _
8760
8761   mp->outer_vlan_id = ntohs (outer_vlan_id);
8762   mp->inner_vlan_id = ntohs (inner_vlan_id);
8763
8764   S (mp);
8765   W (ret);
8766   return ret;
8767 }
8768
8769 static int
8770 api_oam_add_del (vat_main_t * vam)
8771 {
8772   unformat_input_t *i = vam->input;
8773   vl_api_oam_add_del_t *mp;
8774   u32 vrf_id = 0;
8775   u8 is_add = 1;
8776   ip4_address_t src, dst;
8777   u8 src_set = 0;
8778   u8 dst_set = 0;
8779   int ret;
8780
8781   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8782     {
8783       if (unformat (i, "vrf %d", &vrf_id))
8784         ;
8785       else if (unformat (i, "src %U", unformat_ip4_address, &src))
8786         src_set = 1;
8787       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
8788         dst_set = 1;
8789       else if (unformat (i, "del"))
8790         is_add = 0;
8791       else
8792         {
8793           clib_warning ("parse error '%U'", format_unformat_error, i);
8794           return -99;
8795         }
8796     }
8797
8798   if (src_set == 0)
8799     {
8800       errmsg ("missing src addr");
8801       return -99;
8802     }
8803
8804   if (dst_set == 0)
8805     {
8806       errmsg ("missing dst addr");
8807       return -99;
8808     }
8809
8810   M (OAM_ADD_DEL, mp);
8811
8812   mp->vrf_id = ntohl (vrf_id);
8813   mp->is_add = is_add;
8814   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
8815   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
8816
8817   S (mp);
8818   W (ret);
8819   return ret;
8820 }
8821
8822 static int
8823 api_reset_fib (vat_main_t * vam)
8824 {
8825   unformat_input_t *i = vam->input;
8826   vl_api_reset_fib_t *mp;
8827   u32 vrf_id = 0;
8828   u8 is_ipv6 = 0;
8829   u8 vrf_id_set = 0;
8830
8831   int ret;
8832   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8833     {
8834       if (unformat (i, "vrf %d", &vrf_id))
8835         vrf_id_set = 1;
8836       else if (unformat (i, "ipv6"))
8837         is_ipv6 = 1;
8838       else
8839         {
8840           clib_warning ("parse error '%U'", format_unformat_error, i);
8841           return -99;
8842         }
8843     }
8844
8845   if (vrf_id_set == 0)
8846     {
8847       errmsg ("missing vrf id");
8848       return -99;
8849     }
8850
8851   M (RESET_FIB, mp);
8852
8853   mp->vrf_id = ntohl (vrf_id);
8854   mp->is_ipv6 = is_ipv6;
8855
8856   S (mp);
8857   W (ret);
8858   return ret;
8859 }
8860
8861 static int
8862 api_dhcp_proxy_config (vat_main_t * vam)
8863 {
8864   unformat_input_t *i = vam->input;
8865   vl_api_dhcp_proxy_config_t *mp;
8866   u32 rx_vrf_id = 0;
8867   u32 server_vrf_id = 0;
8868   u8 is_add = 1;
8869   u8 v4_address_set = 0;
8870   u8 v6_address_set = 0;
8871   ip4_address_t v4address;
8872   ip6_address_t v6address;
8873   u8 v4_src_address_set = 0;
8874   u8 v6_src_address_set = 0;
8875   ip4_address_t v4srcaddress;
8876   ip6_address_t v6srcaddress;
8877   int ret;
8878
8879   /* Parse args required to build the message */
8880   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8881     {
8882       if (unformat (i, "del"))
8883         is_add = 0;
8884       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
8885         ;
8886       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
8887         ;
8888       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
8889         v4_address_set = 1;
8890       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
8891         v6_address_set = 1;
8892       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
8893         v4_src_address_set = 1;
8894       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
8895         v6_src_address_set = 1;
8896       else
8897         break;
8898     }
8899
8900   if (v4_address_set && v6_address_set)
8901     {
8902       errmsg ("both v4 and v6 server addresses set");
8903       return -99;
8904     }
8905   if (!v4_address_set && !v6_address_set)
8906     {
8907       errmsg ("no server addresses set");
8908       return -99;
8909     }
8910
8911   if (v4_src_address_set && v6_src_address_set)
8912     {
8913       errmsg ("both v4 and v6  src addresses set");
8914       return -99;
8915     }
8916   if (!v4_src_address_set && !v6_src_address_set)
8917     {
8918       errmsg ("no src addresses set");
8919       return -99;
8920     }
8921
8922   if (!(v4_src_address_set && v4_address_set) &&
8923       !(v6_src_address_set && v6_address_set))
8924     {
8925       errmsg ("no matching server and src addresses set");
8926       return -99;
8927     }
8928
8929   /* Construct the API message */
8930   M (DHCP_PROXY_CONFIG, mp);
8931
8932   mp->is_add = is_add;
8933   mp->rx_vrf_id = ntohl (rx_vrf_id);
8934   mp->server_vrf_id = ntohl (server_vrf_id);
8935   if (v6_address_set)
8936     {
8937       mp->is_ipv6 = 1;
8938       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
8939       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
8940     }
8941   else
8942     {
8943       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
8944       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
8945     }
8946
8947   /* send it... */
8948   S (mp);
8949
8950   /* Wait for a reply, return good/bad news  */
8951   W (ret);
8952   return ret;
8953 }
8954
8955 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
8956 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
8957
8958 static void
8959 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
8960 {
8961   vat_main_t *vam = &vat_main;
8962   u32 i, count = mp->count;
8963   vl_api_dhcp_server_t *s;
8964
8965   if (mp->is_ipv6)
8966     print (vam->ofp,
8967            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8968            ntohl (mp->rx_vrf_id),
8969            format_ip6_address, mp->dhcp_src_address,
8970            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8971   else
8972     print (vam->ofp,
8973            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8974            ntohl (mp->rx_vrf_id),
8975            format_ip4_address, mp->dhcp_src_address,
8976            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8977
8978   for (i = 0; i < count; i++)
8979     {
8980       s = &mp->servers[i];
8981
8982       if (mp->is_ipv6)
8983         print (vam->ofp,
8984                " Server Table-ID %d, Server Address %U",
8985                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
8986       else
8987         print (vam->ofp,
8988                " Server Table-ID %d, Server Address %U",
8989                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
8990     }
8991 }
8992
8993 static void vl_api_dhcp_proxy_details_t_handler_json
8994   (vl_api_dhcp_proxy_details_t * mp)
8995 {
8996   vat_main_t *vam = &vat_main;
8997   vat_json_node_t *node = NULL;
8998   u32 i, count = mp->count;
8999   struct in_addr ip4;
9000   struct in6_addr ip6;
9001   vl_api_dhcp_server_t *s;
9002
9003   if (VAT_JSON_ARRAY != vam->json_tree.type)
9004     {
9005       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9006       vat_json_init_array (&vam->json_tree);
9007     }
9008   node = vat_json_array_add (&vam->json_tree);
9009
9010   vat_json_init_object (node);
9011   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9012   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9013   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9014
9015   if (mp->is_ipv6)
9016     {
9017       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9018       vat_json_object_add_ip6 (node, "src_address", ip6);
9019     }
9020   else
9021     {
9022       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9023       vat_json_object_add_ip4 (node, "src_address", ip4);
9024     }
9025
9026   for (i = 0; i < count; i++)
9027     {
9028       s = &mp->servers[i];
9029
9030       vat_json_object_add_uint (node, "server-table-id",
9031                                 ntohl (s->server_vrf_id));
9032
9033       if (mp->is_ipv6)
9034         {
9035           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9036           vat_json_object_add_ip4 (node, "src_address", ip4);
9037         }
9038       else
9039         {
9040           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9041           vat_json_object_add_ip6 (node, "server_address", ip6);
9042         }
9043     }
9044 }
9045
9046 static int
9047 api_dhcp_proxy_dump (vat_main_t * vam)
9048 {
9049   unformat_input_t *i = vam->input;
9050   vl_api_control_ping_t *mp_ping;
9051   vl_api_dhcp_proxy_dump_t *mp;
9052   u8 is_ipv6 = 0;
9053   int ret;
9054
9055   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9056     {
9057       if (unformat (i, "ipv6"))
9058         is_ipv6 = 1;
9059       else
9060         {
9061           clib_warning ("parse error '%U'", format_unformat_error, i);
9062           return -99;
9063         }
9064     }
9065
9066   M (DHCP_PROXY_DUMP, mp);
9067
9068   mp->is_ip6 = is_ipv6;
9069   S (mp);
9070
9071   /* Use a control ping for synchronization */
9072   MPING (CONTROL_PING, mp_ping);
9073   S (mp_ping);
9074
9075   W (ret);
9076   return ret;
9077 }
9078
9079 static int
9080 api_dhcp_proxy_set_vss (vat_main_t * vam)
9081 {
9082   unformat_input_t *i = vam->input;
9083   vl_api_dhcp_proxy_set_vss_t *mp;
9084   u8 is_ipv6 = 0;
9085   u8 is_add = 1;
9086   u32 tbl_id;
9087   u8 tbl_id_set = 0;
9088   u32 oui;
9089   u8 oui_set = 0;
9090   u32 fib_id;
9091   u8 fib_id_set = 0;
9092   int ret;
9093
9094   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9095     {
9096       if (unformat (i, "tbl_id %d", &tbl_id))
9097         tbl_id_set = 1;
9098       if (unformat (i, "fib_id %d", &fib_id))
9099         fib_id_set = 1;
9100       if (unformat (i, "oui %d", &oui))
9101         oui_set = 1;
9102       else if (unformat (i, "ipv6"))
9103         is_ipv6 = 1;
9104       else if (unformat (i, "del"))
9105         is_add = 0;
9106       else
9107         {
9108           clib_warning ("parse error '%U'", format_unformat_error, i);
9109           return -99;
9110         }
9111     }
9112
9113   if (tbl_id_set == 0)
9114     {
9115       errmsg ("missing tbl id");
9116       return -99;
9117     }
9118
9119   if (fib_id_set == 0)
9120     {
9121       errmsg ("missing fib id");
9122       return -99;
9123     }
9124   if (oui_set == 0)
9125     {
9126       errmsg ("missing oui");
9127       return -99;
9128     }
9129
9130   M (DHCP_PROXY_SET_VSS, mp);
9131   mp->tbl_id = ntohl (tbl_id);
9132   mp->fib_id = ntohl (fib_id);
9133   mp->oui = ntohl (oui);
9134   mp->is_ipv6 = is_ipv6;
9135   mp->is_add = is_add;
9136
9137   S (mp);
9138   W (ret);
9139   return ret;
9140 }
9141
9142 static int
9143 api_dhcp_client_config (vat_main_t * vam)
9144 {
9145   unformat_input_t *i = vam->input;
9146   vl_api_dhcp_client_config_t *mp;
9147   u32 sw_if_index;
9148   u8 sw_if_index_set = 0;
9149   u8 is_add = 1;
9150   u8 *hostname = 0;
9151   u8 disable_event = 0;
9152   int ret;
9153
9154   /* Parse args required to build the message */
9155   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9156     {
9157       if (unformat (i, "del"))
9158         is_add = 0;
9159       else
9160         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9161         sw_if_index_set = 1;
9162       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9163         sw_if_index_set = 1;
9164       else if (unformat (i, "hostname %s", &hostname))
9165         ;
9166       else if (unformat (i, "disable_event"))
9167         disable_event = 1;
9168       else
9169         break;
9170     }
9171
9172   if (sw_if_index_set == 0)
9173     {
9174       errmsg ("missing interface name or sw_if_index");
9175       return -99;
9176     }
9177
9178   if (vec_len (hostname) > 63)
9179     {
9180       errmsg ("hostname too long");
9181     }
9182   vec_add1 (hostname, 0);
9183
9184   /* Construct the API message */
9185   M (DHCP_CLIENT_CONFIG, mp);
9186
9187   mp->sw_if_index = htonl (sw_if_index);
9188   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
9189   vec_free (hostname);
9190   mp->is_add = is_add;
9191   mp->want_dhcp_event = disable_event ? 0 : 1;
9192   mp->pid = htonl (getpid ());
9193
9194   /* send it... */
9195   S (mp);
9196
9197   /* Wait for a reply, return good/bad news  */
9198   W (ret);
9199   return ret;
9200 }
9201
9202 static int
9203 api_set_ip_flow_hash (vat_main_t * vam)
9204 {
9205   unformat_input_t *i = vam->input;
9206   vl_api_set_ip_flow_hash_t *mp;
9207   u32 vrf_id = 0;
9208   u8 is_ipv6 = 0;
9209   u8 vrf_id_set = 0;
9210   u8 src = 0;
9211   u8 dst = 0;
9212   u8 sport = 0;
9213   u8 dport = 0;
9214   u8 proto = 0;
9215   u8 reverse = 0;
9216   int ret;
9217
9218   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9219     {
9220       if (unformat (i, "vrf %d", &vrf_id))
9221         vrf_id_set = 1;
9222       else if (unformat (i, "ipv6"))
9223         is_ipv6 = 1;
9224       else if (unformat (i, "src"))
9225         src = 1;
9226       else if (unformat (i, "dst"))
9227         dst = 1;
9228       else if (unformat (i, "sport"))
9229         sport = 1;
9230       else if (unformat (i, "dport"))
9231         dport = 1;
9232       else if (unformat (i, "proto"))
9233         proto = 1;
9234       else if (unformat (i, "reverse"))
9235         reverse = 1;
9236
9237       else
9238         {
9239           clib_warning ("parse error '%U'", format_unformat_error, i);
9240           return -99;
9241         }
9242     }
9243
9244   if (vrf_id_set == 0)
9245     {
9246       errmsg ("missing vrf id");
9247       return -99;
9248     }
9249
9250   M (SET_IP_FLOW_HASH, mp);
9251   mp->src = src;
9252   mp->dst = dst;
9253   mp->sport = sport;
9254   mp->dport = dport;
9255   mp->proto = proto;
9256   mp->reverse = reverse;
9257   mp->vrf_id = ntohl (vrf_id);
9258   mp->is_ipv6 = is_ipv6;
9259
9260   S (mp);
9261   W (ret);
9262   return ret;
9263 }
9264
9265 static int
9266 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9267 {
9268   unformat_input_t *i = vam->input;
9269   vl_api_sw_interface_ip6_enable_disable_t *mp;
9270   u32 sw_if_index;
9271   u8 sw_if_index_set = 0;
9272   u8 enable = 0;
9273   int ret;
9274
9275   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9276     {
9277       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9278         sw_if_index_set = 1;
9279       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9280         sw_if_index_set = 1;
9281       else if (unformat (i, "enable"))
9282         enable = 1;
9283       else if (unformat (i, "disable"))
9284         enable = 0;
9285       else
9286         {
9287           clib_warning ("parse error '%U'", format_unformat_error, i);
9288           return -99;
9289         }
9290     }
9291
9292   if (sw_if_index_set == 0)
9293     {
9294       errmsg ("missing interface name or sw_if_index");
9295       return -99;
9296     }
9297
9298   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9299
9300   mp->sw_if_index = ntohl (sw_if_index);
9301   mp->enable = enable;
9302
9303   S (mp);
9304   W (ret);
9305   return ret;
9306 }
9307
9308 static int
9309 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
9310 {
9311   unformat_input_t *i = vam->input;
9312   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
9313   u32 sw_if_index;
9314   u8 sw_if_index_set = 0;
9315   u8 v6_address_set = 0;
9316   ip6_address_t v6address;
9317   int ret;
9318
9319   /* Parse args required to build the message */
9320   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9321     {
9322       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9323         sw_if_index_set = 1;
9324       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9325         sw_if_index_set = 1;
9326       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9327         v6_address_set = 1;
9328       else
9329         break;
9330     }
9331
9332   if (sw_if_index_set == 0)
9333     {
9334       errmsg ("missing interface name or sw_if_index");
9335       return -99;
9336     }
9337   if (!v6_address_set)
9338     {
9339       errmsg ("no address set");
9340       return -99;
9341     }
9342
9343   /* Construct the API message */
9344   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
9345
9346   mp->sw_if_index = ntohl (sw_if_index);
9347   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9348
9349   /* send it... */
9350   S (mp);
9351
9352   /* Wait for a reply, return good/bad news  */
9353   W (ret);
9354   return ret;
9355 }
9356
9357 static int
9358 api_ip6nd_proxy_add_del (vat_main_t * vam)
9359 {
9360   unformat_input_t *i = vam->input;
9361   vl_api_ip6nd_proxy_add_del_t *mp;
9362   u32 sw_if_index = ~0;
9363   u8 v6_address_set = 0;
9364   ip6_address_t v6address;
9365   u8 is_del = 0;
9366   int ret;
9367
9368   /* Parse args required to build the message */
9369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9370     {
9371       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9372         ;
9373       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9374         ;
9375       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9376         v6_address_set = 1;
9377       if (unformat (i, "del"))
9378         is_del = 1;
9379       else
9380         {
9381           clib_warning ("parse error '%U'", format_unformat_error, i);
9382           return -99;
9383         }
9384     }
9385
9386   if (sw_if_index == ~0)
9387     {
9388       errmsg ("missing interface name or sw_if_index");
9389       return -99;
9390     }
9391   if (!v6_address_set)
9392     {
9393       errmsg ("no address set");
9394       return -99;
9395     }
9396
9397   /* Construct the API message */
9398   M (IP6ND_PROXY_ADD_DEL, mp);
9399
9400   mp->is_del = is_del;
9401   mp->sw_if_index = ntohl (sw_if_index);
9402   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9403
9404   /* send it... */
9405   S (mp);
9406
9407   /* Wait for a reply, return good/bad news  */
9408   W (ret);
9409   return ret;
9410 }
9411
9412 static int
9413 api_ip6nd_proxy_dump (vat_main_t * vam)
9414 {
9415   vl_api_ip6nd_proxy_dump_t *mp;
9416   vl_api_control_ping_t *mp_ping;
9417   int ret;
9418
9419   M (IP6ND_PROXY_DUMP, mp);
9420
9421   S (mp);
9422
9423   /* Use a control ping for synchronization */
9424   MPING (CONTROL_PING, mp_ping);
9425   S (mp_ping);
9426
9427   W (ret);
9428   return ret;
9429 }
9430
9431 static void vl_api_ip6nd_proxy_details_t_handler
9432   (vl_api_ip6nd_proxy_details_t * mp)
9433 {
9434   vat_main_t *vam = &vat_main;
9435
9436   print (vam->ofp, "host %U sw_if_index %d",
9437          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
9438 }
9439
9440 static void vl_api_ip6nd_proxy_details_t_handler_json
9441   (vl_api_ip6nd_proxy_details_t * mp)
9442 {
9443   vat_main_t *vam = &vat_main;
9444   struct in6_addr ip6;
9445   vat_json_node_t *node = NULL;
9446
9447   if (VAT_JSON_ARRAY != vam->json_tree.type)
9448     {
9449       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9450       vat_json_init_array (&vam->json_tree);
9451     }
9452   node = vat_json_array_add (&vam->json_tree);
9453
9454   vat_json_init_object (node);
9455   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9456
9457   clib_memcpy (&ip6, mp->address, sizeof (ip6));
9458   vat_json_object_add_ip6 (node, "host", ip6);
9459 }
9460
9461 static int
9462 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9463 {
9464   unformat_input_t *i = vam->input;
9465   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9466   u32 sw_if_index;
9467   u8 sw_if_index_set = 0;
9468   u32 address_length = 0;
9469   u8 v6_address_set = 0;
9470   ip6_address_t v6address;
9471   u8 use_default = 0;
9472   u8 no_advertise = 0;
9473   u8 off_link = 0;
9474   u8 no_autoconfig = 0;
9475   u8 no_onlink = 0;
9476   u8 is_no = 0;
9477   u32 val_lifetime = 0;
9478   u32 pref_lifetime = 0;
9479   int ret;
9480
9481   /* Parse args required to build the message */
9482   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9483     {
9484       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9485         sw_if_index_set = 1;
9486       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9487         sw_if_index_set = 1;
9488       else if (unformat (i, "%U/%d",
9489                          unformat_ip6_address, &v6address, &address_length))
9490         v6_address_set = 1;
9491       else if (unformat (i, "val_life %d", &val_lifetime))
9492         ;
9493       else if (unformat (i, "pref_life %d", &pref_lifetime))
9494         ;
9495       else if (unformat (i, "def"))
9496         use_default = 1;
9497       else if (unformat (i, "noadv"))
9498         no_advertise = 1;
9499       else if (unformat (i, "offl"))
9500         off_link = 1;
9501       else if (unformat (i, "noauto"))
9502         no_autoconfig = 1;
9503       else if (unformat (i, "nolink"))
9504         no_onlink = 1;
9505       else if (unformat (i, "isno"))
9506         is_no = 1;
9507       else
9508         {
9509           clib_warning ("parse error '%U'", format_unformat_error, i);
9510           return -99;
9511         }
9512     }
9513
9514   if (sw_if_index_set == 0)
9515     {
9516       errmsg ("missing interface name or sw_if_index");
9517       return -99;
9518     }
9519   if (!v6_address_set)
9520     {
9521       errmsg ("no address set");
9522       return -99;
9523     }
9524
9525   /* Construct the API message */
9526   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9527
9528   mp->sw_if_index = ntohl (sw_if_index);
9529   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9530   mp->address_length = address_length;
9531   mp->use_default = use_default;
9532   mp->no_advertise = no_advertise;
9533   mp->off_link = off_link;
9534   mp->no_autoconfig = no_autoconfig;
9535   mp->no_onlink = no_onlink;
9536   mp->is_no = is_no;
9537   mp->val_lifetime = ntohl (val_lifetime);
9538   mp->pref_lifetime = ntohl (pref_lifetime);
9539
9540   /* send it... */
9541   S (mp);
9542
9543   /* Wait for a reply, return good/bad news  */
9544   W (ret);
9545   return ret;
9546 }
9547
9548 static int
9549 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9550 {
9551   unformat_input_t *i = vam->input;
9552   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9553   u32 sw_if_index;
9554   u8 sw_if_index_set = 0;
9555   u8 suppress = 0;
9556   u8 managed = 0;
9557   u8 other = 0;
9558   u8 ll_option = 0;
9559   u8 send_unicast = 0;
9560   u8 cease = 0;
9561   u8 is_no = 0;
9562   u8 default_router = 0;
9563   u32 max_interval = 0;
9564   u32 min_interval = 0;
9565   u32 lifetime = 0;
9566   u32 initial_count = 0;
9567   u32 initial_interval = 0;
9568   int ret;
9569
9570
9571   /* Parse args required to build the message */
9572   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9573     {
9574       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9575         sw_if_index_set = 1;
9576       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9577         sw_if_index_set = 1;
9578       else if (unformat (i, "maxint %d", &max_interval))
9579         ;
9580       else if (unformat (i, "minint %d", &min_interval))
9581         ;
9582       else if (unformat (i, "life %d", &lifetime))
9583         ;
9584       else if (unformat (i, "count %d", &initial_count))
9585         ;
9586       else if (unformat (i, "interval %d", &initial_interval))
9587         ;
9588       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9589         suppress = 1;
9590       else if (unformat (i, "managed"))
9591         managed = 1;
9592       else if (unformat (i, "other"))
9593         other = 1;
9594       else if (unformat (i, "ll"))
9595         ll_option = 1;
9596       else if (unformat (i, "send"))
9597         send_unicast = 1;
9598       else if (unformat (i, "cease"))
9599         cease = 1;
9600       else if (unformat (i, "isno"))
9601         is_no = 1;
9602       else if (unformat (i, "def"))
9603         default_router = 1;
9604       else
9605         {
9606           clib_warning ("parse error '%U'", format_unformat_error, i);
9607           return -99;
9608         }
9609     }
9610
9611   if (sw_if_index_set == 0)
9612     {
9613       errmsg ("missing interface name or sw_if_index");
9614       return -99;
9615     }
9616
9617   /* Construct the API message */
9618   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9619
9620   mp->sw_if_index = ntohl (sw_if_index);
9621   mp->max_interval = ntohl (max_interval);
9622   mp->min_interval = ntohl (min_interval);
9623   mp->lifetime = ntohl (lifetime);
9624   mp->initial_count = ntohl (initial_count);
9625   mp->initial_interval = ntohl (initial_interval);
9626   mp->suppress = suppress;
9627   mp->managed = managed;
9628   mp->other = other;
9629   mp->ll_option = ll_option;
9630   mp->send_unicast = send_unicast;
9631   mp->cease = cease;
9632   mp->is_no = is_no;
9633   mp->default_router = default_router;
9634
9635   /* send it... */
9636   S (mp);
9637
9638   /* Wait for a reply, return good/bad news  */
9639   W (ret);
9640   return ret;
9641 }
9642
9643 static int
9644 api_set_arp_neighbor_limit (vat_main_t * vam)
9645 {
9646   unformat_input_t *i = vam->input;
9647   vl_api_set_arp_neighbor_limit_t *mp;
9648   u32 arp_nbr_limit;
9649   u8 limit_set = 0;
9650   u8 is_ipv6 = 0;
9651   int ret;
9652
9653   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9654     {
9655       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
9656         limit_set = 1;
9657       else if (unformat (i, "ipv6"))
9658         is_ipv6 = 1;
9659       else
9660         {
9661           clib_warning ("parse error '%U'", format_unformat_error, i);
9662           return -99;
9663         }
9664     }
9665
9666   if (limit_set == 0)
9667     {
9668       errmsg ("missing limit value");
9669       return -99;
9670     }
9671
9672   M (SET_ARP_NEIGHBOR_LIMIT, mp);
9673
9674   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
9675   mp->is_ipv6 = is_ipv6;
9676
9677   S (mp);
9678   W (ret);
9679   return ret;
9680 }
9681
9682 static int
9683 api_l2_patch_add_del (vat_main_t * vam)
9684 {
9685   unformat_input_t *i = vam->input;
9686   vl_api_l2_patch_add_del_t *mp;
9687   u32 rx_sw_if_index;
9688   u8 rx_sw_if_index_set = 0;
9689   u32 tx_sw_if_index;
9690   u8 tx_sw_if_index_set = 0;
9691   u8 is_add = 1;
9692   int ret;
9693
9694   /* Parse args required to build the message */
9695   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9696     {
9697       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9698         rx_sw_if_index_set = 1;
9699       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9700         tx_sw_if_index_set = 1;
9701       else if (unformat (i, "rx"))
9702         {
9703           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9704             {
9705               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9706                             &rx_sw_if_index))
9707                 rx_sw_if_index_set = 1;
9708             }
9709           else
9710             break;
9711         }
9712       else if (unformat (i, "tx"))
9713         {
9714           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9715             {
9716               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9717                             &tx_sw_if_index))
9718                 tx_sw_if_index_set = 1;
9719             }
9720           else
9721             break;
9722         }
9723       else if (unformat (i, "del"))
9724         is_add = 0;
9725       else
9726         break;
9727     }
9728
9729   if (rx_sw_if_index_set == 0)
9730     {
9731       errmsg ("missing rx interface name or rx_sw_if_index");
9732       return -99;
9733     }
9734
9735   if (tx_sw_if_index_set == 0)
9736     {
9737       errmsg ("missing tx interface name or tx_sw_if_index");
9738       return -99;
9739     }
9740
9741   M (L2_PATCH_ADD_DEL, mp);
9742
9743   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9744   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9745   mp->is_add = is_add;
9746
9747   S (mp);
9748   W (ret);
9749   return ret;
9750 }
9751
9752 u8 is_del;
9753 u8 localsid_addr[16];
9754 u8 end_psp;
9755 u8 behavior;
9756 u32 sw_if_index;
9757 u32 vlan_index;
9758 u32 fib_table;
9759 u8 nh_addr[16];
9760
9761 static int
9762 api_sr_localsid_add_del (vat_main_t * vam)
9763 {
9764   unformat_input_t *i = vam->input;
9765   vl_api_sr_localsid_add_del_t *mp;
9766
9767   u8 is_del;
9768   ip6_address_t localsid;
9769   u8 end_psp = 0;
9770   u8 behavior = ~0;
9771   u32 sw_if_index;
9772   u32 fib_table = ~(u32) 0;
9773   ip6_address_t next_hop;
9774
9775   bool nexthop_set = 0;
9776
9777   int ret;
9778
9779   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9780     {
9781       if (unformat (i, "del"))
9782         is_del = 1;
9783       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9784       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
9785         nexthop_set = 1;
9786       else if (unformat (i, "behavior %u", &behavior));
9787       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9788       else if (unformat (i, "fib-table %u", &fib_table));
9789       else if (unformat (i, "end.psp %u", &behavior));
9790       else
9791         break;
9792     }
9793
9794   M (SR_LOCALSID_ADD_DEL, mp);
9795
9796   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
9797   if (nexthop_set)
9798     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
9799   mp->behavior = behavior;
9800   mp->sw_if_index = ntohl (sw_if_index);
9801   mp->fib_table = ntohl (fib_table);
9802   mp->end_psp = end_psp;
9803   mp->is_del = is_del;
9804
9805   S (mp);
9806   W (ret);
9807   return ret;
9808 }
9809
9810 static int
9811 api_ioam_enable (vat_main_t * vam)
9812 {
9813   unformat_input_t *input = vam->input;
9814   vl_api_ioam_enable_t *mp;
9815   u32 id = 0;
9816   int has_trace_option = 0;
9817   int has_pot_option = 0;
9818   int has_seqno_option = 0;
9819   int has_analyse_option = 0;
9820   int ret;
9821
9822   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9823     {
9824       if (unformat (input, "trace"))
9825         has_trace_option = 1;
9826       else if (unformat (input, "pot"))
9827         has_pot_option = 1;
9828       else if (unformat (input, "seqno"))
9829         has_seqno_option = 1;
9830       else if (unformat (input, "analyse"))
9831         has_analyse_option = 1;
9832       else
9833         break;
9834     }
9835   M (IOAM_ENABLE, mp);
9836   mp->id = htons (id);
9837   mp->seqno = has_seqno_option;
9838   mp->analyse = has_analyse_option;
9839   mp->pot_enable = has_pot_option;
9840   mp->trace_enable = has_trace_option;
9841
9842   S (mp);
9843   W (ret);
9844   return ret;
9845 }
9846
9847
9848 static int
9849 api_ioam_disable (vat_main_t * vam)
9850 {
9851   vl_api_ioam_disable_t *mp;
9852   int ret;
9853
9854   M (IOAM_DISABLE, mp);
9855   S (mp);
9856   W (ret);
9857   return ret;
9858 }
9859
9860 #define foreach_tcp_proto_field                 \
9861 _(src_port)                                     \
9862 _(dst_port)
9863
9864 #define foreach_udp_proto_field                 \
9865 _(src_port)                                     \
9866 _(dst_port)
9867
9868 #define foreach_ip4_proto_field                 \
9869 _(src_address)                                  \
9870 _(dst_address)                                  \
9871 _(tos)                                          \
9872 _(length)                                       \
9873 _(fragment_id)                                  \
9874 _(ttl)                                          \
9875 _(protocol)                                     \
9876 _(checksum)
9877
9878 typedef struct
9879 {
9880   u16 src_port, dst_port;
9881 } tcpudp_header_t;
9882
9883 #if VPP_API_TEST_BUILTIN == 0
9884 uword
9885 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9886 {
9887   u8 **maskp = va_arg (*args, u8 **);
9888   u8 *mask = 0;
9889   u8 found_something = 0;
9890   tcp_header_t *tcp;
9891
9892 #define _(a) u8 a=0;
9893   foreach_tcp_proto_field;
9894 #undef _
9895
9896   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9897     {
9898       if (0);
9899 #define _(a) else if (unformat (input, #a)) a=1;
9900       foreach_tcp_proto_field
9901 #undef _
9902         else
9903         break;
9904     }
9905
9906 #define _(a) found_something += a;
9907   foreach_tcp_proto_field;
9908 #undef _
9909
9910   if (found_something == 0)
9911     return 0;
9912
9913   vec_validate (mask, sizeof (*tcp) - 1);
9914
9915   tcp = (tcp_header_t *) mask;
9916
9917 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
9918   foreach_tcp_proto_field;
9919 #undef _
9920
9921   *maskp = mask;
9922   return 1;
9923 }
9924
9925 uword
9926 unformat_udp_mask (unformat_input_t * input, va_list * args)
9927 {
9928   u8 **maskp = va_arg (*args, u8 **);
9929   u8 *mask = 0;
9930   u8 found_something = 0;
9931   udp_header_t *udp;
9932
9933 #define _(a) u8 a=0;
9934   foreach_udp_proto_field;
9935 #undef _
9936
9937   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9938     {
9939       if (0);
9940 #define _(a) else if (unformat (input, #a)) a=1;
9941       foreach_udp_proto_field
9942 #undef _
9943         else
9944         break;
9945     }
9946
9947 #define _(a) found_something += a;
9948   foreach_udp_proto_field;
9949 #undef _
9950
9951   if (found_something == 0)
9952     return 0;
9953
9954   vec_validate (mask, sizeof (*udp) - 1);
9955
9956   udp = (udp_header_t *) mask;
9957
9958 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
9959   foreach_udp_proto_field;
9960 #undef _
9961
9962   *maskp = mask;
9963   return 1;
9964 }
9965
9966 uword
9967 unformat_l4_mask (unformat_input_t * input, va_list * args)
9968 {
9969   u8 **maskp = va_arg (*args, u8 **);
9970   u16 src_port = 0, dst_port = 0;
9971   tcpudp_header_t *tcpudp;
9972
9973   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9974     {
9975       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9976         return 1;
9977       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9978         return 1;
9979       else if (unformat (input, "src_port"))
9980         src_port = 0xFFFF;
9981       else if (unformat (input, "dst_port"))
9982         dst_port = 0xFFFF;
9983       else
9984         return 0;
9985     }
9986
9987   if (!src_port && !dst_port)
9988     return 0;
9989
9990   u8 *mask = 0;
9991   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9992
9993   tcpudp = (tcpudp_header_t *) mask;
9994   tcpudp->src_port = src_port;
9995   tcpudp->dst_port = dst_port;
9996
9997   *maskp = mask;
9998
9999   return 1;
10000 }
10001
10002 uword
10003 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10004 {
10005   u8 **maskp = va_arg (*args, u8 **);
10006   u8 *mask = 0;
10007   u8 found_something = 0;
10008   ip4_header_t *ip;
10009
10010 #define _(a) u8 a=0;
10011   foreach_ip4_proto_field;
10012 #undef _
10013   u8 version = 0;
10014   u8 hdr_length = 0;
10015
10016
10017   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10018     {
10019       if (unformat (input, "version"))
10020         version = 1;
10021       else if (unformat (input, "hdr_length"))
10022         hdr_length = 1;
10023       else if (unformat (input, "src"))
10024         src_address = 1;
10025       else if (unformat (input, "dst"))
10026         dst_address = 1;
10027       else if (unformat (input, "proto"))
10028         protocol = 1;
10029
10030 #define _(a) else if (unformat (input, #a)) a=1;
10031       foreach_ip4_proto_field
10032 #undef _
10033         else
10034         break;
10035     }
10036
10037 #define _(a) found_something += a;
10038   foreach_ip4_proto_field;
10039 #undef _
10040
10041   if (found_something == 0)
10042     return 0;
10043
10044   vec_validate (mask, sizeof (*ip) - 1);
10045
10046   ip = (ip4_header_t *) mask;
10047
10048 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10049   foreach_ip4_proto_field;
10050 #undef _
10051
10052   ip->ip_version_and_header_length = 0;
10053
10054   if (version)
10055     ip->ip_version_and_header_length |= 0xF0;
10056
10057   if (hdr_length)
10058     ip->ip_version_and_header_length |= 0x0F;
10059
10060   *maskp = mask;
10061   return 1;
10062 }
10063
10064 #define foreach_ip6_proto_field                 \
10065 _(src_address)                                  \
10066 _(dst_address)                                  \
10067 _(payload_length)                               \
10068 _(hop_limit)                                    \
10069 _(protocol)
10070
10071 uword
10072 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10073 {
10074   u8 **maskp = va_arg (*args, u8 **);
10075   u8 *mask = 0;
10076   u8 found_something = 0;
10077   ip6_header_t *ip;
10078   u32 ip_version_traffic_class_and_flow_label;
10079
10080 #define _(a) u8 a=0;
10081   foreach_ip6_proto_field;
10082 #undef _
10083   u8 version = 0;
10084   u8 traffic_class = 0;
10085   u8 flow_label = 0;
10086
10087   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10088     {
10089       if (unformat (input, "version"))
10090         version = 1;
10091       else if (unformat (input, "traffic-class"))
10092         traffic_class = 1;
10093       else if (unformat (input, "flow-label"))
10094         flow_label = 1;
10095       else if (unformat (input, "src"))
10096         src_address = 1;
10097       else if (unformat (input, "dst"))
10098         dst_address = 1;
10099       else if (unformat (input, "proto"))
10100         protocol = 1;
10101
10102 #define _(a) else if (unformat (input, #a)) a=1;
10103       foreach_ip6_proto_field
10104 #undef _
10105         else
10106         break;
10107     }
10108
10109 #define _(a) found_something += a;
10110   foreach_ip6_proto_field;
10111 #undef _
10112
10113   if (found_something == 0)
10114     return 0;
10115
10116   vec_validate (mask, sizeof (*ip) - 1);
10117
10118   ip = (ip6_header_t *) mask;
10119
10120 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10121   foreach_ip6_proto_field;
10122 #undef _
10123
10124   ip_version_traffic_class_and_flow_label = 0;
10125
10126   if (version)
10127     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10128
10129   if (traffic_class)
10130     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10131
10132   if (flow_label)
10133     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10134
10135   ip->ip_version_traffic_class_and_flow_label =
10136     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10137
10138   *maskp = mask;
10139   return 1;
10140 }
10141
10142 uword
10143 unformat_l3_mask (unformat_input_t * input, va_list * args)
10144 {
10145   u8 **maskp = va_arg (*args, u8 **);
10146
10147   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10148     {
10149       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10150         return 1;
10151       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10152         return 1;
10153       else
10154         break;
10155     }
10156   return 0;
10157 }
10158
10159 uword
10160 unformat_l2_mask (unformat_input_t * input, va_list * args)
10161 {
10162   u8 **maskp = va_arg (*args, u8 **);
10163   u8 *mask = 0;
10164   u8 src = 0;
10165   u8 dst = 0;
10166   u8 proto = 0;
10167   u8 tag1 = 0;
10168   u8 tag2 = 0;
10169   u8 ignore_tag1 = 0;
10170   u8 ignore_tag2 = 0;
10171   u8 cos1 = 0;
10172   u8 cos2 = 0;
10173   u8 dot1q = 0;
10174   u8 dot1ad = 0;
10175   int len = 14;
10176
10177   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10178     {
10179       if (unformat (input, "src"))
10180         src = 1;
10181       else if (unformat (input, "dst"))
10182         dst = 1;
10183       else if (unformat (input, "proto"))
10184         proto = 1;
10185       else if (unformat (input, "tag1"))
10186         tag1 = 1;
10187       else if (unformat (input, "tag2"))
10188         tag2 = 1;
10189       else if (unformat (input, "ignore-tag1"))
10190         ignore_tag1 = 1;
10191       else if (unformat (input, "ignore-tag2"))
10192         ignore_tag2 = 1;
10193       else if (unformat (input, "cos1"))
10194         cos1 = 1;
10195       else if (unformat (input, "cos2"))
10196         cos2 = 1;
10197       else if (unformat (input, "dot1q"))
10198         dot1q = 1;
10199       else if (unformat (input, "dot1ad"))
10200         dot1ad = 1;
10201       else
10202         break;
10203     }
10204   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10205        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10206     return 0;
10207
10208   if (tag1 || ignore_tag1 || cos1 || dot1q)
10209     len = 18;
10210   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10211     len = 22;
10212
10213   vec_validate (mask, len - 1);
10214
10215   if (dst)
10216     memset (mask, 0xff, 6);
10217
10218   if (src)
10219     memset (mask + 6, 0xff, 6);
10220
10221   if (tag2 || dot1ad)
10222     {
10223       /* inner vlan tag */
10224       if (tag2)
10225         {
10226           mask[19] = 0xff;
10227           mask[18] = 0x0f;
10228         }
10229       if (cos2)
10230         mask[18] |= 0xe0;
10231       if (proto)
10232         mask[21] = mask[20] = 0xff;
10233       if (tag1)
10234         {
10235           mask[15] = 0xff;
10236           mask[14] = 0x0f;
10237         }
10238       if (cos1)
10239         mask[14] |= 0xe0;
10240       *maskp = mask;
10241       return 1;
10242     }
10243   if (tag1 | dot1q)
10244     {
10245       if (tag1)
10246         {
10247           mask[15] = 0xff;
10248           mask[14] = 0x0f;
10249         }
10250       if (cos1)
10251         mask[14] |= 0xe0;
10252       if (proto)
10253         mask[16] = mask[17] = 0xff;
10254
10255       *maskp = mask;
10256       return 1;
10257     }
10258   if (cos2)
10259     mask[18] |= 0xe0;
10260   if (cos1)
10261     mask[14] |= 0xe0;
10262   if (proto)
10263     mask[12] = mask[13] = 0xff;
10264
10265   *maskp = mask;
10266   return 1;
10267 }
10268
10269 uword
10270 unformat_classify_mask (unformat_input_t * input, va_list * args)
10271 {
10272   u8 **maskp = va_arg (*args, u8 **);
10273   u32 *skipp = va_arg (*args, u32 *);
10274   u32 *matchp = va_arg (*args, u32 *);
10275   u32 match;
10276   u8 *mask = 0;
10277   u8 *l2 = 0;
10278   u8 *l3 = 0;
10279   u8 *l4 = 0;
10280   int i;
10281
10282   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10283     {
10284       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10285         ;
10286       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10287         ;
10288       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10289         ;
10290       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10291         ;
10292       else
10293         break;
10294     }
10295
10296   if (l4 && !l3)
10297     {
10298       vec_free (mask);
10299       vec_free (l2);
10300       vec_free (l4);
10301       return 0;
10302     }
10303
10304   if (mask || l2 || l3 || l4)
10305     {
10306       if (l2 || l3 || l4)
10307         {
10308           /* "With a free Ethernet header in every package" */
10309           if (l2 == 0)
10310             vec_validate (l2, 13);
10311           mask = l2;
10312           if (vec_len (l3))
10313             {
10314               vec_append (mask, l3);
10315               vec_free (l3);
10316             }
10317           if (vec_len (l4))
10318             {
10319               vec_append (mask, l4);
10320               vec_free (l4);
10321             }
10322         }
10323
10324       /* Scan forward looking for the first significant mask octet */
10325       for (i = 0; i < vec_len (mask); i++)
10326         if (mask[i])
10327           break;
10328
10329       /* compute (skip, match) params */
10330       *skipp = i / sizeof (u32x4);
10331       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10332
10333       /* Pad mask to an even multiple of the vector size */
10334       while (vec_len (mask) % sizeof (u32x4))
10335         vec_add1 (mask, 0);
10336
10337       match = vec_len (mask) / sizeof (u32x4);
10338
10339       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10340         {
10341           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10342           if (*tmp || *(tmp + 1))
10343             break;
10344           match--;
10345         }
10346       if (match == 0)
10347         clib_warning ("BUG: match 0");
10348
10349       _vec_len (mask) = match * sizeof (u32x4);
10350
10351       *matchp = match;
10352       *maskp = mask;
10353
10354       return 1;
10355     }
10356
10357   return 0;
10358 }
10359 #endif /* VPP_API_TEST_BUILTIN */
10360
10361 #define foreach_l2_next                         \
10362 _(drop, DROP)                                   \
10363 _(ethernet, ETHERNET_INPUT)                     \
10364 _(ip4, IP4_INPUT)                               \
10365 _(ip6, IP6_INPUT)
10366
10367 uword
10368 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10369 {
10370   u32 *miss_next_indexp = va_arg (*args, u32 *);
10371   u32 next_index = 0;
10372   u32 tmp;
10373
10374 #define _(n,N) \
10375   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10376   foreach_l2_next;
10377 #undef _
10378
10379   if (unformat (input, "%d", &tmp))
10380     {
10381       next_index = tmp;
10382       goto out;
10383     }
10384
10385   return 0;
10386
10387 out:
10388   *miss_next_indexp = next_index;
10389   return 1;
10390 }
10391
10392 #define foreach_ip_next                         \
10393 _(drop, DROP)                                   \
10394 _(local, LOCAL)                                 \
10395 _(rewrite, REWRITE)
10396
10397 uword
10398 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10399 {
10400   u32 *miss_next_indexp = va_arg (*args, u32 *);
10401   u32 next_index = 0;
10402   u32 tmp;
10403
10404 #define _(n,N) \
10405   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10406   foreach_ip_next;
10407 #undef _
10408
10409   if (unformat (input, "%d", &tmp))
10410     {
10411       next_index = tmp;
10412       goto out;
10413     }
10414
10415   return 0;
10416
10417 out:
10418   *miss_next_indexp = next_index;
10419   return 1;
10420 }
10421
10422 #define foreach_acl_next                        \
10423 _(deny, DENY)
10424
10425 uword
10426 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10427 {
10428   u32 *miss_next_indexp = va_arg (*args, u32 *);
10429   u32 next_index = 0;
10430   u32 tmp;
10431
10432 #define _(n,N) \
10433   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10434   foreach_acl_next;
10435 #undef _
10436
10437   if (unformat (input, "permit"))
10438     {
10439       next_index = ~0;
10440       goto out;
10441     }
10442   else if (unformat (input, "%d", &tmp))
10443     {
10444       next_index = tmp;
10445       goto out;
10446     }
10447
10448   return 0;
10449
10450 out:
10451   *miss_next_indexp = next_index;
10452   return 1;
10453 }
10454
10455 uword
10456 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10457 {
10458   u32 *r = va_arg (*args, u32 *);
10459
10460   if (unformat (input, "conform-color"))
10461     *r = POLICE_CONFORM;
10462   else if (unformat (input, "exceed-color"))
10463     *r = POLICE_EXCEED;
10464   else
10465     return 0;
10466
10467   return 1;
10468 }
10469
10470 static int
10471 api_classify_add_del_table (vat_main_t * vam)
10472 {
10473   unformat_input_t *i = vam->input;
10474   vl_api_classify_add_del_table_t *mp;
10475
10476   u32 nbuckets = 2;
10477   u32 skip = ~0;
10478   u32 match = ~0;
10479   int is_add = 1;
10480   int del_chain = 0;
10481   u32 table_index = ~0;
10482   u32 next_table_index = ~0;
10483   u32 miss_next_index = ~0;
10484   u32 memory_size = 32 << 20;
10485   u8 *mask = 0;
10486   u32 current_data_flag = 0;
10487   int current_data_offset = 0;
10488   int ret;
10489
10490   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10491     {
10492       if (unformat (i, "del"))
10493         is_add = 0;
10494       else if (unformat (i, "del-chain"))
10495         {
10496           is_add = 0;
10497           del_chain = 1;
10498         }
10499       else if (unformat (i, "buckets %d", &nbuckets))
10500         ;
10501       else if (unformat (i, "memory_size %d", &memory_size))
10502         ;
10503       else if (unformat (i, "skip %d", &skip))
10504         ;
10505       else if (unformat (i, "match %d", &match))
10506         ;
10507       else if (unformat (i, "table %d", &table_index))
10508         ;
10509       else if (unformat (i, "mask %U", unformat_classify_mask,
10510                          &mask, &skip, &match))
10511         ;
10512       else if (unformat (i, "next-table %d", &next_table_index))
10513         ;
10514       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10515                          &miss_next_index))
10516         ;
10517       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10518                          &miss_next_index))
10519         ;
10520       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10521                          &miss_next_index))
10522         ;
10523       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10524         ;
10525       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10526         ;
10527       else
10528         break;
10529     }
10530
10531   if (is_add && mask == 0)
10532     {
10533       errmsg ("Mask required");
10534       return -99;
10535     }
10536
10537   if (is_add && skip == ~0)
10538     {
10539       errmsg ("skip count required");
10540       return -99;
10541     }
10542
10543   if (is_add && match == ~0)
10544     {
10545       errmsg ("match count required");
10546       return -99;
10547     }
10548
10549   if (!is_add && table_index == ~0)
10550     {
10551       errmsg ("table index required for delete");
10552       return -99;
10553     }
10554
10555   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10556
10557   mp->is_add = is_add;
10558   mp->del_chain = del_chain;
10559   mp->table_index = ntohl (table_index);
10560   mp->nbuckets = ntohl (nbuckets);
10561   mp->memory_size = ntohl (memory_size);
10562   mp->skip_n_vectors = ntohl (skip);
10563   mp->match_n_vectors = ntohl (match);
10564   mp->next_table_index = ntohl (next_table_index);
10565   mp->miss_next_index = ntohl (miss_next_index);
10566   mp->current_data_flag = ntohl (current_data_flag);
10567   mp->current_data_offset = ntohl (current_data_offset);
10568   clib_memcpy (mp->mask, mask, vec_len (mask));
10569
10570   vec_free (mask);
10571
10572   S (mp);
10573   W (ret);
10574   return ret;
10575 }
10576
10577 #if VPP_API_TEST_BUILTIN == 0
10578 uword
10579 unformat_l4_match (unformat_input_t * input, va_list * args)
10580 {
10581   u8 **matchp = va_arg (*args, u8 **);
10582
10583   u8 *proto_header = 0;
10584   int src_port = 0;
10585   int dst_port = 0;
10586
10587   tcpudp_header_t h;
10588
10589   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10590     {
10591       if (unformat (input, "src_port %d", &src_port))
10592         ;
10593       else if (unformat (input, "dst_port %d", &dst_port))
10594         ;
10595       else
10596         return 0;
10597     }
10598
10599   h.src_port = clib_host_to_net_u16 (src_port);
10600   h.dst_port = clib_host_to_net_u16 (dst_port);
10601   vec_validate (proto_header, sizeof (h) - 1);
10602   memcpy (proto_header, &h, sizeof (h));
10603
10604   *matchp = proto_header;
10605
10606   return 1;
10607 }
10608
10609 uword
10610 unformat_ip4_match (unformat_input_t * input, va_list * args)
10611 {
10612   u8 **matchp = va_arg (*args, u8 **);
10613   u8 *match = 0;
10614   ip4_header_t *ip;
10615   int version = 0;
10616   u32 version_val;
10617   int hdr_length = 0;
10618   u32 hdr_length_val;
10619   int src = 0, dst = 0;
10620   ip4_address_t src_val, dst_val;
10621   int proto = 0;
10622   u32 proto_val;
10623   int tos = 0;
10624   u32 tos_val;
10625   int length = 0;
10626   u32 length_val;
10627   int fragment_id = 0;
10628   u32 fragment_id_val;
10629   int ttl = 0;
10630   int ttl_val;
10631   int checksum = 0;
10632   u32 checksum_val;
10633
10634   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10635     {
10636       if (unformat (input, "version %d", &version_val))
10637         version = 1;
10638       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10639         hdr_length = 1;
10640       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10641         src = 1;
10642       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10643         dst = 1;
10644       else if (unformat (input, "proto %d", &proto_val))
10645         proto = 1;
10646       else if (unformat (input, "tos %d", &tos_val))
10647         tos = 1;
10648       else if (unformat (input, "length %d", &length_val))
10649         length = 1;
10650       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10651         fragment_id = 1;
10652       else if (unformat (input, "ttl %d", &ttl_val))
10653         ttl = 1;
10654       else if (unformat (input, "checksum %d", &checksum_val))
10655         checksum = 1;
10656       else
10657         break;
10658     }
10659
10660   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10661       + ttl + checksum == 0)
10662     return 0;
10663
10664   /*
10665    * Aligned because we use the real comparison functions
10666    */
10667   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10668
10669   ip = (ip4_header_t *) match;
10670
10671   /* These are realistically matched in practice */
10672   if (src)
10673     ip->src_address.as_u32 = src_val.as_u32;
10674
10675   if (dst)
10676     ip->dst_address.as_u32 = dst_val.as_u32;
10677
10678   if (proto)
10679     ip->protocol = proto_val;
10680
10681
10682   /* These are not, but they're included for completeness */
10683   if (version)
10684     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10685
10686   if (hdr_length)
10687     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10688
10689   if (tos)
10690     ip->tos = tos_val;
10691
10692   if (length)
10693     ip->length = clib_host_to_net_u16 (length_val);
10694
10695   if (ttl)
10696     ip->ttl = ttl_val;
10697
10698   if (checksum)
10699     ip->checksum = clib_host_to_net_u16 (checksum_val);
10700
10701   *matchp = match;
10702   return 1;
10703 }
10704
10705 uword
10706 unformat_ip6_match (unformat_input_t * input, va_list * args)
10707 {
10708   u8 **matchp = va_arg (*args, u8 **);
10709   u8 *match = 0;
10710   ip6_header_t *ip;
10711   int version = 0;
10712   u32 version_val;
10713   u8 traffic_class = 0;
10714   u32 traffic_class_val = 0;
10715   u8 flow_label = 0;
10716   u8 flow_label_val;
10717   int src = 0, dst = 0;
10718   ip6_address_t src_val, dst_val;
10719   int proto = 0;
10720   u32 proto_val;
10721   int payload_length = 0;
10722   u32 payload_length_val;
10723   int hop_limit = 0;
10724   int hop_limit_val;
10725   u32 ip_version_traffic_class_and_flow_label;
10726
10727   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10728     {
10729       if (unformat (input, "version %d", &version_val))
10730         version = 1;
10731       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10732         traffic_class = 1;
10733       else if (unformat (input, "flow_label %d", &flow_label_val))
10734         flow_label = 1;
10735       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10736         src = 1;
10737       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10738         dst = 1;
10739       else if (unformat (input, "proto %d", &proto_val))
10740         proto = 1;
10741       else if (unformat (input, "payload_length %d", &payload_length_val))
10742         payload_length = 1;
10743       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10744         hop_limit = 1;
10745       else
10746         break;
10747     }
10748
10749   if (version + traffic_class + flow_label + src + dst + proto +
10750       payload_length + hop_limit == 0)
10751     return 0;
10752
10753   /*
10754    * Aligned because we use the real comparison functions
10755    */
10756   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10757
10758   ip = (ip6_header_t *) match;
10759
10760   if (src)
10761     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10762
10763   if (dst)
10764     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10765
10766   if (proto)
10767     ip->protocol = proto_val;
10768
10769   ip_version_traffic_class_and_flow_label = 0;
10770
10771   if (version)
10772     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10773
10774   if (traffic_class)
10775     ip_version_traffic_class_and_flow_label |=
10776       (traffic_class_val & 0xFF) << 20;
10777
10778   if (flow_label)
10779     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10780
10781   ip->ip_version_traffic_class_and_flow_label =
10782     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10783
10784   if (payload_length)
10785     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10786
10787   if (hop_limit)
10788     ip->hop_limit = hop_limit_val;
10789
10790   *matchp = match;
10791   return 1;
10792 }
10793
10794 uword
10795 unformat_l3_match (unformat_input_t * input, va_list * args)
10796 {
10797   u8 **matchp = va_arg (*args, u8 **);
10798
10799   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10800     {
10801       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10802         return 1;
10803       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10804         return 1;
10805       else
10806         break;
10807     }
10808   return 0;
10809 }
10810
10811 uword
10812 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10813 {
10814   u8 *tagp = va_arg (*args, u8 *);
10815   u32 tag;
10816
10817   if (unformat (input, "%d", &tag))
10818     {
10819       tagp[0] = (tag >> 8) & 0x0F;
10820       tagp[1] = tag & 0xFF;
10821       return 1;
10822     }
10823
10824   return 0;
10825 }
10826
10827 uword
10828 unformat_l2_match (unformat_input_t * input, va_list * args)
10829 {
10830   u8 **matchp = va_arg (*args, u8 **);
10831   u8 *match = 0;
10832   u8 src = 0;
10833   u8 src_val[6];
10834   u8 dst = 0;
10835   u8 dst_val[6];
10836   u8 proto = 0;
10837   u16 proto_val;
10838   u8 tag1 = 0;
10839   u8 tag1_val[2];
10840   u8 tag2 = 0;
10841   u8 tag2_val[2];
10842   int len = 14;
10843   u8 ignore_tag1 = 0;
10844   u8 ignore_tag2 = 0;
10845   u8 cos1 = 0;
10846   u8 cos2 = 0;
10847   u32 cos1_val = 0;
10848   u32 cos2_val = 0;
10849
10850   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10851     {
10852       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10853         src = 1;
10854       else
10855         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10856         dst = 1;
10857       else if (unformat (input, "proto %U",
10858                          unformat_ethernet_type_host_byte_order, &proto_val))
10859         proto = 1;
10860       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10861         tag1 = 1;
10862       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10863         tag2 = 1;
10864       else if (unformat (input, "ignore-tag1"))
10865         ignore_tag1 = 1;
10866       else if (unformat (input, "ignore-tag2"))
10867         ignore_tag2 = 1;
10868       else if (unformat (input, "cos1 %d", &cos1_val))
10869         cos1 = 1;
10870       else if (unformat (input, "cos2 %d", &cos2_val))
10871         cos2 = 1;
10872       else
10873         break;
10874     }
10875   if ((src + dst + proto + tag1 + tag2 +
10876        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10877     return 0;
10878
10879   if (tag1 || ignore_tag1 || cos1)
10880     len = 18;
10881   if (tag2 || ignore_tag2 || cos2)
10882     len = 22;
10883
10884   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10885
10886   if (dst)
10887     clib_memcpy (match, dst_val, 6);
10888
10889   if (src)
10890     clib_memcpy (match + 6, src_val, 6);
10891
10892   if (tag2)
10893     {
10894       /* inner vlan tag */
10895       match[19] = tag2_val[1];
10896       match[18] = tag2_val[0];
10897       if (cos2)
10898         match[18] |= (cos2_val & 0x7) << 5;
10899       if (proto)
10900         {
10901           match[21] = proto_val & 0xff;
10902           match[20] = proto_val >> 8;
10903         }
10904       if (tag1)
10905         {
10906           match[15] = tag1_val[1];
10907           match[14] = tag1_val[0];
10908         }
10909       if (cos1)
10910         match[14] |= (cos1_val & 0x7) << 5;
10911       *matchp = match;
10912       return 1;
10913     }
10914   if (tag1)
10915     {
10916       match[15] = tag1_val[1];
10917       match[14] = tag1_val[0];
10918       if (proto)
10919         {
10920           match[17] = proto_val & 0xff;
10921           match[16] = proto_val >> 8;
10922         }
10923       if (cos1)
10924         match[14] |= (cos1_val & 0x7) << 5;
10925
10926       *matchp = match;
10927       return 1;
10928     }
10929   if (cos2)
10930     match[18] |= (cos2_val & 0x7) << 5;
10931   if (cos1)
10932     match[14] |= (cos1_val & 0x7) << 5;
10933   if (proto)
10934     {
10935       match[13] = proto_val & 0xff;
10936       match[12] = proto_val >> 8;
10937     }
10938
10939   *matchp = match;
10940   return 1;
10941 }
10942 #endif
10943
10944 uword
10945 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10946 {
10947   u8 **matchp = va_arg (*args, u8 **);
10948   u32 skip_n_vectors = va_arg (*args, u32);
10949   u32 match_n_vectors = va_arg (*args, u32);
10950
10951   u8 *match = 0;
10952   u8 *l2 = 0;
10953   u8 *l3 = 0;
10954   u8 *l4 = 0;
10955
10956   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10957     {
10958       if (unformat (input, "hex %U", unformat_hex_string, &match))
10959         ;
10960       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10961         ;
10962       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10963         ;
10964       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10965         ;
10966       else
10967         break;
10968     }
10969
10970   if (l4 && !l3)
10971     {
10972       vec_free (match);
10973       vec_free (l2);
10974       vec_free (l4);
10975       return 0;
10976     }
10977
10978   if (match || l2 || l3 || l4)
10979     {
10980       if (l2 || l3 || l4)
10981         {
10982           /* "Win a free Ethernet header in every packet" */
10983           if (l2 == 0)
10984             vec_validate_aligned (l2, 13, sizeof (u32x4));
10985           match = l2;
10986           if (vec_len (l3))
10987             {
10988               vec_append_aligned (match, l3, sizeof (u32x4));
10989               vec_free (l3);
10990             }
10991           if (vec_len (l4))
10992             {
10993               vec_append_aligned (match, l4, sizeof (u32x4));
10994               vec_free (l4);
10995             }
10996         }
10997
10998       /* Make sure the vector is big enough even if key is all 0's */
10999       vec_validate_aligned
11000         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11001          sizeof (u32x4));
11002
11003       /* Set size, include skipped vectors */
11004       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11005
11006       *matchp = match;
11007
11008       return 1;
11009     }
11010
11011   return 0;
11012 }
11013
11014 static int
11015 api_classify_add_del_session (vat_main_t * vam)
11016 {
11017   unformat_input_t *i = vam->input;
11018   vl_api_classify_add_del_session_t *mp;
11019   int is_add = 1;
11020   u32 table_index = ~0;
11021   u32 hit_next_index = ~0;
11022   u32 opaque_index = ~0;
11023   u8 *match = 0;
11024   i32 advance = 0;
11025   u32 skip_n_vectors = 0;
11026   u32 match_n_vectors = 0;
11027   u32 action = 0;
11028   u32 metadata = 0;
11029   int ret;
11030
11031   /*
11032    * Warning: you have to supply skip_n and match_n
11033    * because the API client cant simply look at the classify
11034    * table object.
11035    */
11036
11037   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11038     {
11039       if (unformat (i, "del"))
11040         is_add = 0;
11041       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11042                          &hit_next_index))
11043         ;
11044       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11045                          &hit_next_index))
11046         ;
11047       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11048                          &hit_next_index))
11049         ;
11050       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11051         ;
11052       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11053         ;
11054       else if (unformat (i, "opaque-index %d", &opaque_index))
11055         ;
11056       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11057         ;
11058       else if (unformat (i, "match_n %d", &match_n_vectors))
11059         ;
11060       else if (unformat (i, "match %U", api_unformat_classify_match,
11061                          &match, skip_n_vectors, match_n_vectors))
11062         ;
11063       else if (unformat (i, "advance %d", &advance))
11064         ;
11065       else if (unformat (i, "table-index %d", &table_index))
11066         ;
11067       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11068         action = 1;
11069       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11070         action = 2;
11071       else if (unformat (i, "action %d", &action))
11072         ;
11073       else if (unformat (i, "metadata %d", &metadata))
11074         ;
11075       else
11076         break;
11077     }
11078
11079   if (table_index == ~0)
11080     {
11081       errmsg ("Table index required");
11082       return -99;
11083     }
11084
11085   if (is_add && match == 0)
11086     {
11087       errmsg ("Match value required");
11088       return -99;
11089     }
11090
11091   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11092
11093   mp->is_add = is_add;
11094   mp->table_index = ntohl (table_index);
11095   mp->hit_next_index = ntohl (hit_next_index);
11096   mp->opaque_index = ntohl (opaque_index);
11097   mp->advance = ntohl (advance);
11098   mp->action = action;
11099   mp->metadata = ntohl (metadata);
11100   clib_memcpy (mp->match, match, vec_len (match));
11101   vec_free (match);
11102
11103   S (mp);
11104   W (ret);
11105   return ret;
11106 }
11107
11108 static int
11109 api_classify_set_interface_ip_table (vat_main_t * vam)
11110 {
11111   unformat_input_t *i = vam->input;
11112   vl_api_classify_set_interface_ip_table_t *mp;
11113   u32 sw_if_index;
11114   int sw_if_index_set;
11115   u32 table_index = ~0;
11116   u8 is_ipv6 = 0;
11117   int ret;
11118
11119   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11120     {
11121       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11122         sw_if_index_set = 1;
11123       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11124         sw_if_index_set = 1;
11125       else if (unformat (i, "table %d", &table_index))
11126         ;
11127       else
11128         {
11129           clib_warning ("parse error '%U'", format_unformat_error, i);
11130           return -99;
11131         }
11132     }
11133
11134   if (sw_if_index_set == 0)
11135     {
11136       errmsg ("missing interface name or sw_if_index");
11137       return -99;
11138     }
11139
11140
11141   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11142
11143   mp->sw_if_index = ntohl (sw_if_index);
11144   mp->table_index = ntohl (table_index);
11145   mp->is_ipv6 = is_ipv6;
11146
11147   S (mp);
11148   W (ret);
11149   return ret;
11150 }
11151
11152 static int
11153 api_classify_set_interface_l2_tables (vat_main_t * vam)
11154 {
11155   unformat_input_t *i = vam->input;
11156   vl_api_classify_set_interface_l2_tables_t *mp;
11157   u32 sw_if_index;
11158   int sw_if_index_set;
11159   u32 ip4_table_index = ~0;
11160   u32 ip6_table_index = ~0;
11161   u32 other_table_index = ~0;
11162   u32 is_input = 1;
11163   int ret;
11164
11165   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11166     {
11167       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11168         sw_if_index_set = 1;
11169       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11170         sw_if_index_set = 1;
11171       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11172         ;
11173       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11174         ;
11175       else if (unformat (i, "other-table %d", &other_table_index))
11176         ;
11177       else if (unformat (i, "is-input %d", &is_input))
11178         ;
11179       else
11180         {
11181           clib_warning ("parse error '%U'", format_unformat_error, i);
11182           return -99;
11183         }
11184     }
11185
11186   if (sw_if_index_set == 0)
11187     {
11188       errmsg ("missing interface name or sw_if_index");
11189       return -99;
11190     }
11191
11192
11193   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11194
11195   mp->sw_if_index = ntohl (sw_if_index);
11196   mp->ip4_table_index = ntohl (ip4_table_index);
11197   mp->ip6_table_index = ntohl (ip6_table_index);
11198   mp->other_table_index = ntohl (other_table_index);
11199   mp->is_input = (u8) is_input;
11200
11201   S (mp);
11202   W (ret);
11203   return ret;
11204 }
11205
11206 static int
11207 api_set_ipfix_exporter (vat_main_t * vam)
11208 {
11209   unformat_input_t *i = vam->input;
11210   vl_api_set_ipfix_exporter_t *mp;
11211   ip4_address_t collector_address;
11212   u8 collector_address_set = 0;
11213   u32 collector_port = ~0;
11214   ip4_address_t src_address;
11215   u8 src_address_set = 0;
11216   u32 vrf_id = ~0;
11217   u32 path_mtu = ~0;
11218   u32 template_interval = ~0;
11219   u8 udp_checksum = 0;
11220   int ret;
11221
11222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11223     {
11224       if (unformat (i, "collector_address %U", unformat_ip4_address,
11225                     &collector_address))
11226         collector_address_set = 1;
11227       else if (unformat (i, "collector_port %d", &collector_port))
11228         ;
11229       else if (unformat (i, "src_address %U", unformat_ip4_address,
11230                          &src_address))
11231         src_address_set = 1;
11232       else if (unformat (i, "vrf_id %d", &vrf_id))
11233         ;
11234       else if (unformat (i, "path_mtu %d", &path_mtu))
11235         ;
11236       else if (unformat (i, "template_interval %d", &template_interval))
11237         ;
11238       else if (unformat (i, "udp_checksum"))
11239         udp_checksum = 1;
11240       else
11241         break;
11242     }
11243
11244   if (collector_address_set == 0)
11245     {
11246       errmsg ("collector_address required");
11247       return -99;
11248     }
11249
11250   if (src_address_set == 0)
11251     {
11252       errmsg ("src_address required");
11253       return -99;
11254     }
11255
11256   M (SET_IPFIX_EXPORTER, mp);
11257
11258   memcpy (mp->collector_address, collector_address.data,
11259           sizeof (collector_address.data));
11260   mp->collector_port = htons ((u16) collector_port);
11261   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11262   mp->vrf_id = htonl (vrf_id);
11263   mp->path_mtu = htonl (path_mtu);
11264   mp->template_interval = htonl (template_interval);
11265   mp->udp_checksum = udp_checksum;
11266
11267   S (mp);
11268   W (ret);
11269   return ret;
11270 }
11271
11272 static int
11273 api_set_ipfix_classify_stream (vat_main_t * vam)
11274 {
11275   unformat_input_t *i = vam->input;
11276   vl_api_set_ipfix_classify_stream_t *mp;
11277   u32 domain_id = 0;
11278   u32 src_port = UDP_DST_PORT_ipfix;
11279   int ret;
11280
11281   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11282     {
11283       if (unformat (i, "domain %d", &domain_id))
11284         ;
11285       else if (unformat (i, "src_port %d", &src_port))
11286         ;
11287       else
11288         {
11289           errmsg ("unknown input `%U'", format_unformat_error, i);
11290           return -99;
11291         }
11292     }
11293
11294   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11295
11296   mp->domain_id = htonl (domain_id);
11297   mp->src_port = htons ((u16) src_port);
11298
11299   S (mp);
11300   W (ret);
11301   return ret;
11302 }
11303
11304 static int
11305 api_ipfix_classify_table_add_del (vat_main_t * vam)
11306 {
11307   unformat_input_t *i = vam->input;
11308   vl_api_ipfix_classify_table_add_del_t *mp;
11309   int is_add = -1;
11310   u32 classify_table_index = ~0;
11311   u8 ip_version = 0;
11312   u8 transport_protocol = 255;
11313   int ret;
11314
11315   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11316     {
11317       if (unformat (i, "add"))
11318         is_add = 1;
11319       else if (unformat (i, "del"))
11320         is_add = 0;
11321       else if (unformat (i, "table %d", &classify_table_index))
11322         ;
11323       else if (unformat (i, "ip4"))
11324         ip_version = 4;
11325       else if (unformat (i, "ip6"))
11326         ip_version = 6;
11327       else if (unformat (i, "tcp"))
11328         transport_protocol = 6;
11329       else if (unformat (i, "udp"))
11330         transport_protocol = 17;
11331       else
11332         {
11333           errmsg ("unknown input `%U'", format_unformat_error, i);
11334           return -99;
11335         }
11336     }
11337
11338   if (is_add == -1)
11339     {
11340       errmsg ("expecting: add|del");
11341       return -99;
11342     }
11343   if (classify_table_index == ~0)
11344     {
11345       errmsg ("classifier table not specified");
11346       return -99;
11347     }
11348   if (ip_version == 0)
11349     {
11350       errmsg ("IP version not specified");
11351       return -99;
11352     }
11353
11354   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11355
11356   mp->is_add = is_add;
11357   mp->table_id = htonl (classify_table_index);
11358   mp->ip_version = ip_version;
11359   mp->transport_protocol = transport_protocol;
11360
11361   S (mp);
11362   W (ret);
11363   return ret;
11364 }
11365
11366 static int
11367 api_get_node_index (vat_main_t * vam)
11368 {
11369   unformat_input_t *i = vam->input;
11370   vl_api_get_node_index_t *mp;
11371   u8 *name = 0;
11372   int ret;
11373
11374   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11375     {
11376       if (unformat (i, "node %s", &name))
11377         ;
11378       else
11379         break;
11380     }
11381   if (name == 0)
11382     {
11383       errmsg ("node name required");
11384       return -99;
11385     }
11386   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11387     {
11388       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11389       return -99;
11390     }
11391
11392   M (GET_NODE_INDEX, mp);
11393   clib_memcpy (mp->node_name, name, vec_len (name));
11394   vec_free (name);
11395
11396   S (mp);
11397   W (ret);
11398   return ret;
11399 }
11400
11401 static int
11402 api_get_next_index (vat_main_t * vam)
11403 {
11404   unformat_input_t *i = vam->input;
11405   vl_api_get_next_index_t *mp;
11406   u8 *node_name = 0, *next_node_name = 0;
11407   int ret;
11408
11409   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11410     {
11411       if (unformat (i, "node-name %s", &node_name))
11412         ;
11413       else if (unformat (i, "next-node-name %s", &next_node_name))
11414         break;
11415     }
11416
11417   if (node_name == 0)
11418     {
11419       errmsg ("node name required");
11420       return -99;
11421     }
11422   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11423     {
11424       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11425       return -99;
11426     }
11427
11428   if (next_node_name == 0)
11429     {
11430       errmsg ("next node name required");
11431       return -99;
11432     }
11433   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11434     {
11435       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11436       return -99;
11437     }
11438
11439   M (GET_NEXT_INDEX, mp);
11440   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11441   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11442   vec_free (node_name);
11443   vec_free (next_node_name);
11444
11445   S (mp);
11446   W (ret);
11447   return ret;
11448 }
11449
11450 static int
11451 api_add_node_next (vat_main_t * vam)
11452 {
11453   unformat_input_t *i = vam->input;
11454   vl_api_add_node_next_t *mp;
11455   u8 *name = 0;
11456   u8 *next = 0;
11457   int ret;
11458
11459   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11460     {
11461       if (unformat (i, "node %s", &name))
11462         ;
11463       else if (unformat (i, "next %s", &next))
11464         ;
11465       else
11466         break;
11467     }
11468   if (name == 0)
11469     {
11470       errmsg ("node name required");
11471       return -99;
11472     }
11473   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11474     {
11475       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11476       return -99;
11477     }
11478   if (next == 0)
11479     {
11480       errmsg ("next node required");
11481       return -99;
11482     }
11483   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11484     {
11485       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11486       return -99;
11487     }
11488
11489   M (ADD_NODE_NEXT, mp);
11490   clib_memcpy (mp->node_name, name, vec_len (name));
11491   clib_memcpy (mp->next_name, next, vec_len (next));
11492   vec_free (name);
11493   vec_free (next);
11494
11495   S (mp);
11496   W (ret);
11497   return ret;
11498 }
11499
11500 static int
11501 api_l2tpv3_create_tunnel (vat_main_t * vam)
11502 {
11503   unformat_input_t *i = vam->input;
11504   ip6_address_t client_address, our_address;
11505   int client_address_set = 0;
11506   int our_address_set = 0;
11507   u32 local_session_id = 0;
11508   u32 remote_session_id = 0;
11509   u64 local_cookie = 0;
11510   u64 remote_cookie = 0;
11511   u8 l2_sublayer_present = 0;
11512   vl_api_l2tpv3_create_tunnel_t *mp;
11513   int ret;
11514
11515   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11516     {
11517       if (unformat (i, "client_address %U", unformat_ip6_address,
11518                     &client_address))
11519         client_address_set = 1;
11520       else if (unformat (i, "our_address %U", unformat_ip6_address,
11521                          &our_address))
11522         our_address_set = 1;
11523       else if (unformat (i, "local_session_id %d", &local_session_id))
11524         ;
11525       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11526         ;
11527       else if (unformat (i, "local_cookie %lld", &local_cookie))
11528         ;
11529       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11530         ;
11531       else if (unformat (i, "l2-sublayer-present"))
11532         l2_sublayer_present = 1;
11533       else
11534         break;
11535     }
11536
11537   if (client_address_set == 0)
11538     {
11539       errmsg ("client_address required");
11540       return -99;
11541     }
11542
11543   if (our_address_set == 0)
11544     {
11545       errmsg ("our_address required");
11546       return -99;
11547     }
11548
11549   M (L2TPV3_CREATE_TUNNEL, mp);
11550
11551   clib_memcpy (mp->client_address, client_address.as_u8,
11552                sizeof (mp->client_address));
11553
11554   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11555
11556   mp->local_session_id = ntohl (local_session_id);
11557   mp->remote_session_id = ntohl (remote_session_id);
11558   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11559   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11560   mp->l2_sublayer_present = l2_sublayer_present;
11561   mp->is_ipv6 = 1;
11562
11563   S (mp);
11564   W (ret);
11565   return ret;
11566 }
11567
11568 static int
11569 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11570 {
11571   unformat_input_t *i = vam->input;
11572   u32 sw_if_index;
11573   u8 sw_if_index_set = 0;
11574   u64 new_local_cookie = 0;
11575   u64 new_remote_cookie = 0;
11576   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11577   int ret;
11578
11579   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11580     {
11581       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11582         sw_if_index_set = 1;
11583       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11584         sw_if_index_set = 1;
11585       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11586         ;
11587       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11588         ;
11589       else
11590         break;
11591     }
11592
11593   if (sw_if_index_set == 0)
11594     {
11595       errmsg ("missing interface name or sw_if_index");
11596       return -99;
11597     }
11598
11599   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11600
11601   mp->sw_if_index = ntohl (sw_if_index);
11602   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11603   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11604
11605   S (mp);
11606   W (ret);
11607   return ret;
11608 }
11609
11610 static int
11611 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11612 {
11613   unformat_input_t *i = vam->input;
11614   vl_api_l2tpv3_interface_enable_disable_t *mp;
11615   u32 sw_if_index;
11616   u8 sw_if_index_set = 0;
11617   u8 enable_disable = 1;
11618   int ret;
11619
11620   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11621     {
11622       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11623         sw_if_index_set = 1;
11624       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11625         sw_if_index_set = 1;
11626       else if (unformat (i, "enable"))
11627         enable_disable = 1;
11628       else if (unformat (i, "disable"))
11629         enable_disable = 0;
11630       else
11631         break;
11632     }
11633
11634   if (sw_if_index_set == 0)
11635     {
11636       errmsg ("missing interface name or sw_if_index");
11637       return -99;
11638     }
11639
11640   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11641
11642   mp->sw_if_index = ntohl (sw_if_index);
11643   mp->enable_disable = enable_disable;
11644
11645   S (mp);
11646   W (ret);
11647   return ret;
11648 }
11649
11650 static int
11651 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11652 {
11653   unformat_input_t *i = vam->input;
11654   vl_api_l2tpv3_set_lookup_key_t *mp;
11655   u8 key = ~0;
11656   int ret;
11657
11658   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11659     {
11660       if (unformat (i, "lookup_v6_src"))
11661         key = L2T_LOOKUP_SRC_ADDRESS;
11662       else if (unformat (i, "lookup_v6_dst"))
11663         key = L2T_LOOKUP_DST_ADDRESS;
11664       else if (unformat (i, "lookup_session_id"))
11665         key = L2T_LOOKUP_SESSION_ID;
11666       else
11667         break;
11668     }
11669
11670   if (key == (u8) ~ 0)
11671     {
11672       errmsg ("l2tp session lookup key unset");
11673       return -99;
11674     }
11675
11676   M (L2TPV3_SET_LOOKUP_KEY, mp);
11677
11678   mp->key = key;
11679
11680   S (mp);
11681   W (ret);
11682   return ret;
11683 }
11684
11685 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11686   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11687 {
11688   vat_main_t *vam = &vat_main;
11689
11690   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11691          format_ip6_address, mp->our_address,
11692          format_ip6_address, mp->client_address,
11693          clib_net_to_host_u32 (mp->sw_if_index));
11694
11695   print (vam->ofp,
11696          "   local cookies %016llx %016llx remote cookie %016llx",
11697          clib_net_to_host_u64 (mp->local_cookie[0]),
11698          clib_net_to_host_u64 (mp->local_cookie[1]),
11699          clib_net_to_host_u64 (mp->remote_cookie));
11700
11701   print (vam->ofp, "   local session-id %d remote session-id %d",
11702          clib_net_to_host_u32 (mp->local_session_id),
11703          clib_net_to_host_u32 (mp->remote_session_id));
11704
11705   print (vam->ofp, "   l2 specific sublayer %s\n",
11706          mp->l2_sublayer_present ? "preset" : "absent");
11707
11708 }
11709
11710 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11711   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11712 {
11713   vat_main_t *vam = &vat_main;
11714   vat_json_node_t *node = NULL;
11715   struct in6_addr addr;
11716
11717   if (VAT_JSON_ARRAY != vam->json_tree.type)
11718     {
11719       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11720       vat_json_init_array (&vam->json_tree);
11721     }
11722   node = vat_json_array_add (&vam->json_tree);
11723
11724   vat_json_init_object (node);
11725
11726   clib_memcpy (&addr, mp->our_address, sizeof (addr));
11727   vat_json_object_add_ip6 (node, "our_address", addr);
11728   clib_memcpy (&addr, mp->client_address, sizeof (addr));
11729   vat_json_object_add_ip6 (node, "client_address", addr);
11730
11731   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11732   vat_json_init_array (lc);
11733   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11734   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11735   vat_json_object_add_uint (node, "remote_cookie",
11736                             clib_net_to_host_u64 (mp->remote_cookie));
11737
11738   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11739   vat_json_object_add_uint (node, "local_session_id",
11740                             clib_net_to_host_u32 (mp->local_session_id));
11741   vat_json_object_add_uint (node, "remote_session_id",
11742                             clib_net_to_host_u32 (mp->remote_session_id));
11743   vat_json_object_add_string_copy (node, "l2_sublayer",
11744                                    mp->l2_sublayer_present ? (u8 *) "present"
11745                                    : (u8 *) "absent");
11746 }
11747
11748 static int
11749 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11750 {
11751   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11752   vl_api_control_ping_t *mp_ping;
11753   int ret;
11754
11755   /* Get list of l2tpv3-tunnel interfaces */
11756   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11757   S (mp);
11758
11759   /* Use a control ping for synchronization */
11760   MPING (CONTROL_PING, mp_ping);
11761   S (mp_ping);
11762
11763   W (ret);
11764   return ret;
11765 }
11766
11767
11768 static void vl_api_sw_interface_tap_details_t_handler
11769   (vl_api_sw_interface_tap_details_t * mp)
11770 {
11771   vat_main_t *vam = &vat_main;
11772
11773   print (vam->ofp, "%-16s %d",
11774          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
11775 }
11776
11777 static void vl_api_sw_interface_tap_details_t_handler_json
11778   (vl_api_sw_interface_tap_details_t * mp)
11779 {
11780   vat_main_t *vam = &vat_main;
11781   vat_json_node_t *node = NULL;
11782
11783   if (VAT_JSON_ARRAY != vam->json_tree.type)
11784     {
11785       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11786       vat_json_init_array (&vam->json_tree);
11787     }
11788   node = vat_json_array_add (&vam->json_tree);
11789
11790   vat_json_init_object (node);
11791   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11792   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11793 }
11794
11795 static int
11796 api_sw_interface_tap_dump (vat_main_t * vam)
11797 {
11798   vl_api_sw_interface_tap_dump_t *mp;
11799   vl_api_control_ping_t *mp_ping;
11800   int ret;
11801
11802   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
11803   /* Get list of tap interfaces */
11804   M (SW_INTERFACE_TAP_DUMP, mp);
11805   S (mp);
11806
11807   /* Use a control ping for synchronization */
11808   MPING (CONTROL_PING, mp_ping);
11809   S (mp_ping);
11810
11811   W (ret);
11812   return ret;
11813 }
11814
11815 static uword unformat_vxlan_decap_next
11816   (unformat_input_t * input, va_list * args)
11817 {
11818   u32 *result = va_arg (*args, u32 *);
11819   u32 tmp;
11820
11821   if (unformat (input, "l2"))
11822     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11823   else if (unformat (input, "%d", &tmp))
11824     *result = tmp;
11825   else
11826     return 0;
11827   return 1;
11828 }
11829
11830 static int
11831 api_vxlan_add_del_tunnel (vat_main_t * vam)
11832 {
11833   unformat_input_t *line_input = vam->input;
11834   vl_api_vxlan_add_del_tunnel_t *mp;
11835   ip46_address_t src, dst;
11836   u8 is_add = 1;
11837   u8 ipv4_set = 0, ipv6_set = 0;
11838   u8 src_set = 0;
11839   u8 dst_set = 0;
11840   u8 grp_set = 0;
11841   u32 mcast_sw_if_index = ~0;
11842   u32 encap_vrf_id = 0;
11843   u32 decap_next_index = ~0;
11844   u32 vni = 0;
11845   int ret;
11846
11847   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11848   memset (&src, 0, sizeof src);
11849   memset (&dst, 0, sizeof dst);
11850
11851   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11852     {
11853       if (unformat (line_input, "del"))
11854         is_add = 0;
11855       else
11856         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11857         {
11858           ipv4_set = 1;
11859           src_set = 1;
11860         }
11861       else
11862         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11863         {
11864           ipv4_set = 1;
11865           dst_set = 1;
11866         }
11867       else
11868         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11869         {
11870           ipv6_set = 1;
11871           src_set = 1;
11872         }
11873       else
11874         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11875         {
11876           ipv6_set = 1;
11877           dst_set = 1;
11878         }
11879       else if (unformat (line_input, "group %U %U",
11880                          unformat_ip4_address, &dst.ip4,
11881                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11882         {
11883           grp_set = dst_set = 1;
11884           ipv4_set = 1;
11885         }
11886       else if (unformat (line_input, "group %U",
11887                          unformat_ip4_address, &dst.ip4))
11888         {
11889           grp_set = dst_set = 1;
11890           ipv4_set = 1;
11891         }
11892       else if (unformat (line_input, "group %U %U",
11893                          unformat_ip6_address, &dst.ip6,
11894                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11895         {
11896           grp_set = dst_set = 1;
11897           ipv6_set = 1;
11898         }
11899       else if (unformat (line_input, "group %U",
11900                          unformat_ip6_address, &dst.ip6))
11901         {
11902           grp_set = dst_set = 1;
11903           ipv6_set = 1;
11904         }
11905       else
11906         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11907         ;
11908       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11909         ;
11910       else if (unformat (line_input, "decap-next %U",
11911                          unformat_vxlan_decap_next, &decap_next_index))
11912         ;
11913       else if (unformat (line_input, "vni %d", &vni))
11914         ;
11915       else
11916         {
11917           errmsg ("parse error '%U'", format_unformat_error, line_input);
11918           return -99;
11919         }
11920     }
11921
11922   if (src_set == 0)
11923     {
11924       errmsg ("tunnel src address not specified");
11925       return -99;
11926     }
11927   if (dst_set == 0)
11928     {
11929       errmsg ("tunnel dst address not specified");
11930       return -99;
11931     }
11932
11933   if (grp_set && !ip46_address_is_multicast (&dst))
11934     {
11935       errmsg ("tunnel group address not multicast");
11936       return -99;
11937     }
11938   if (grp_set && mcast_sw_if_index == ~0)
11939     {
11940       errmsg ("tunnel nonexistent multicast device");
11941       return -99;
11942     }
11943   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11944     {
11945       errmsg ("tunnel dst address must be unicast");
11946       return -99;
11947     }
11948
11949
11950   if (ipv4_set && ipv6_set)
11951     {
11952       errmsg ("both IPv4 and IPv6 addresses specified");
11953       return -99;
11954     }
11955
11956   if ((vni == 0) || (vni >> 24))
11957     {
11958       errmsg ("vni not specified or out of range");
11959       return -99;
11960     }
11961
11962   M (VXLAN_ADD_DEL_TUNNEL, mp);
11963
11964   if (ipv6_set)
11965     {
11966       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
11967       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
11968     }
11969   else
11970     {
11971       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
11972       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
11973     }
11974   mp->encap_vrf_id = ntohl (encap_vrf_id);
11975   mp->decap_next_index = ntohl (decap_next_index);
11976   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11977   mp->vni = ntohl (vni);
11978   mp->is_add = is_add;
11979   mp->is_ipv6 = ipv6_set;
11980
11981   S (mp);
11982   W (ret);
11983   return ret;
11984 }
11985
11986 static void vl_api_vxlan_tunnel_details_t_handler
11987   (vl_api_vxlan_tunnel_details_t * mp)
11988 {
11989   vat_main_t *vam = &vat_main;
11990   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
11991   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
11992
11993   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
11994          ntohl (mp->sw_if_index),
11995          format_ip46_address, &src, IP46_TYPE_ANY,
11996          format_ip46_address, &dst, IP46_TYPE_ANY,
11997          ntohl (mp->encap_vrf_id),
11998          ntohl (mp->decap_next_index), ntohl (mp->vni),
11999          ntohl (mp->mcast_sw_if_index));
12000 }
12001
12002 static void vl_api_vxlan_tunnel_details_t_handler_json
12003   (vl_api_vxlan_tunnel_details_t * mp)
12004 {
12005   vat_main_t *vam = &vat_main;
12006   vat_json_node_t *node = NULL;
12007
12008   if (VAT_JSON_ARRAY != vam->json_tree.type)
12009     {
12010       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12011       vat_json_init_array (&vam->json_tree);
12012     }
12013   node = vat_json_array_add (&vam->json_tree);
12014
12015   vat_json_init_object (node);
12016   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12017   if (mp->is_ipv6)
12018     {
12019       struct in6_addr ip6;
12020
12021       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12022       vat_json_object_add_ip6 (node, "src_address", ip6);
12023       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12024       vat_json_object_add_ip6 (node, "dst_address", ip6);
12025     }
12026   else
12027     {
12028       struct in_addr ip4;
12029
12030       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12031       vat_json_object_add_ip4 (node, "src_address", ip4);
12032       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12033       vat_json_object_add_ip4 (node, "dst_address", ip4);
12034     }
12035   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12036   vat_json_object_add_uint (node, "decap_next_index",
12037                             ntohl (mp->decap_next_index));
12038   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12039   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12040   vat_json_object_add_uint (node, "mcast_sw_if_index",
12041                             ntohl (mp->mcast_sw_if_index));
12042 }
12043
12044 static int
12045 api_vxlan_tunnel_dump (vat_main_t * vam)
12046 {
12047   unformat_input_t *i = vam->input;
12048   vl_api_vxlan_tunnel_dump_t *mp;
12049   vl_api_control_ping_t *mp_ping;
12050   u32 sw_if_index;
12051   u8 sw_if_index_set = 0;
12052   int ret;
12053
12054   /* Parse args required to build the message */
12055   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12056     {
12057       if (unformat (i, "sw_if_index %d", &sw_if_index))
12058         sw_if_index_set = 1;
12059       else
12060         break;
12061     }
12062
12063   if (sw_if_index_set == 0)
12064     {
12065       sw_if_index = ~0;
12066     }
12067
12068   if (!vam->json_output)
12069     {
12070       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12071              "sw_if_index", "src_address", "dst_address",
12072              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12073     }
12074
12075   /* Get list of vxlan-tunnel interfaces */
12076   M (VXLAN_TUNNEL_DUMP, mp);
12077
12078   mp->sw_if_index = htonl (sw_if_index);
12079
12080   S (mp);
12081
12082   /* Use a control ping for synchronization */
12083   MPING (CONTROL_PING, mp_ping);
12084   S (mp_ping);
12085
12086   W (ret);
12087   return ret;
12088 }
12089
12090 static uword unformat_geneve_decap_next
12091   (unformat_input_t * input, va_list * args)
12092 {
12093   u32 *result = va_arg (*args, u32 *);
12094   u32 tmp;
12095
12096   if (unformat (input, "l2"))
12097     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12098   else if (unformat (input, "%d", &tmp))
12099     *result = tmp;
12100   else
12101     return 0;
12102   return 1;
12103 }
12104
12105 static int
12106 api_geneve_add_del_tunnel (vat_main_t * vam)
12107 {
12108   unformat_input_t *line_input = vam->input;
12109   vl_api_geneve_add_del_tunnel_t *mp;
12110   ip46_address_t src, dst;
12111   u8 is_add = 1;
12112   u8 ipv4_set = 0, ipv6_set = 0;
12113   u8 src_set = 0;
12114   u8 dst_set = 0;
12115   u8 grp_set = 0;
12116   u32 mcast_sw_if_index = ~0;
12117   u32 encap_vrf_id = 0;
12118   u32 decap_next_index = ~0;
12119   u32 vni = 0;
12120   int ret;
12121
12122   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12123   memset (&src, 0, sizeof src);
12124   memset (&dst, 0, sizeof dst);
12125
12126   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12127     {
12128       if (unformat (line_input, "del"))
12129         is_add = 0;
12130       else
12131         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12132         {
12133           ipv4_set = 1;
12134           src_set = 1;
12135         }
12136       else
12137         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12138         {
12139           ipv4_set = 1;
12140           dst_set = 1;
12141         }
12142       else
12143         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12144         {
12145           ipv6_set = 1;
12146           src_set = 1;
12147         }
12148       else
12149         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12150         {
12151           ipv6_set = 1;
12152           dst_set = 1;
12153         }
12154       else if (unformat (line_input, "group %U %U",
12155                          unformat_ip4_address, &dst.ip4,
12156                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12157         {
12158           grp_set = dst_set = 1;
12159           ipv4_set = 1;
12160         }
12161       else if (unformat (line_input, "group %U",
12162                          unformat_ip4_address, &dst.ip4))
12163         {
12164           grp_set = dst_set = 1;
12165           ipv4_set = 1;
12166         }
12167       else if (unformat (line_input, "group %U %U",
12168                          unformat_ip6_address, &dst.ip6,
12169                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12170         {
12171           grp_set = dst_set = 1;
12172           ipv6_set = 1;
12173         }
12174       else if (unformat (line_input, "group %U",
12175                          unformat_ip6_address, &dst.ip6))
12176         {
12177           grp_set = dst_set = 1;
12178           ipv6_set = 1;
12179         }
12180       else
12181         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12182         ;
12183       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12184         ;
12185       else if (unformat (line_input, "decap-next %U",
12186                          unformat_geneve_decap_next, &decap_next_index))
12187         ;
12188       else if (unformat (line_input, "vni %d", &vni))
12189         ;
12190       else
12191         {
12192           errmsg ("parse error '%U'", format_unformat_error, line_input);
12193           return -99;
12194         }
12195     }
12196
12197   if (src_set == 0)
12198     {
12199       errmsg ("tunnel src address not specified");
12200       return -99;
12201     }
12202   if (dst_set == 0)
12203     {
12204       errmsg ("tunnel dst address not specified");
12205       return -99;
12206     }
12207
12208   if (grp_set && !ip46_address_is_multicast (&dst))
12209     {
12210       errmsg ("tunnel group address not multicast");
12211       return -99;
12212     }
12213   if (grp_set && mcast_sw_if_index == ~0)
12214     {
12215       errmsg ("tunnel nonexistent multicast device");
12216       return -99;
12217     }
12218   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12219     {
12220       errmsg ("tunnel dst address must be unicast");
12221       return -99;
12222     }
12223
12224
12225   if (ipv4_set && ipv6_set)
12226     {
12227       errmsg ("both IPv4 and IPv6 addresses specified");
12228       return -99;
12229     }
12230
12231   if ((vni == 0) || (vni >> 24))
12232     {
12233       errmsg ("vni not specified or out of range");
12234       return -99;
12235     }
12236
12237   M (GENEVE_ADD_DEL_TUNNEL, mp);
12238
12239   if (ipv6_set)
12240     {
12241       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12242       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12243     }
12244   else
12245     {
12246       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12247       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12248     }
12249   mp->encap_vrf_id = ntohl (encap_vrf_id);
12250   mp->decap_next_index = ntohl (decap_next_index);
12251   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12252   mp->vni = ntohl (vni);
12253   mp->is_add = is_add;
12254   mp->is_ipv6 = ipv6_set;
12255
12256   S (mp);
12257   W (ret);
12258   return ret;
12259 }
12260
12261 static void vl_api_geneve_tunnel_details_t_handler
12262   (vl_api_geneve_tunnel_details_t * mp)
12263 {
12264   vat_main_t *vam = &vat_main;
12265   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12266   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12267
12268   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12269          ntohl (mp->sw_if_index),
12270          format_ip46_address, &src, IP46_TYPE_ANY,
12271          format_ip46_address, &dst, IP46_TYPE_ANY,
12272          ntohl (mp->encap_vrf_id),
12273          ntohl (mp->decap_next_index), ntohl (mp->vni),
12274          ntohl (mp->mcast_sw_if_index));
12275 }
12276
12277 static void vl_api_geneve_tunnel_details_t_handler_json
12278   (vl_api_geneve_tunnel_details_t * mp)
12279 {
12280   vat_main_t *vam = &vat_main;
12281   vat_json_node_t *node = NULL;
12282
12283   if (VAT_JSON_ARRAY != vam->json_tree.type)
12284     {
12285       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12286       vat_json_init_array (&vam->json_tree);
12287     }
12288   node = vat_json_array_add (&vam->json_tree);
12289
12290   vat_json_init_object (node);
12291   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12292   if (mp->is_ipv6)
12293     {
12294       struct in6_addr ip6;
12295
12296       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12297       vat_json_object_add_ip6 (node, "src_address", ip6);
12298       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12299       vat_json_object_add_ip6 (node, "dst_address", ip6);
12300     }
12301   else
12302     {
12303       struct in_addr ip4;
12304
12305       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12306       vat_json_object_add_ip4 (node, "src_address", ip4);
12307       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12308       vat_json_object_add_ip4 (node, "dst_address", ip4);
12309     }
12310   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12311   vat_json_object_add_uint (node, "decap_next_index",
12312                             ntohl (mp->decap_next_index));
12313   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12314   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12315   vat_json_object_add_uint (node, "mcast_sw_if_index",
12316                             ntohl (mp->mcast_sw_if_index));
12317 }
12318
12319 static int
12320 api_geneve_tunnel_dump (vat_main_t * vam)
12321 {
12322   unformat_input_t *i = vam->input;
12323   vl_api_geneve_tunnel_dump_t *mp;
12324   vl_api_control_ping_t *mp_ping;
12325   u32 sw_if_index;
12326   u8 sw_if_index_set = 0;
12327   int ret;
12328
12329   /* Parse args required to build the message */
12330   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12331     {
12332       if (unformat (i, "sw_if_index %d", &sw_if_index))
12333         sw_if_index_set = 1;
12334       else
12335         break;
12336     }
12337
12338   if (sw_if_index_set == 0)
12339     {
12340       sw_if_index = ~0;
12341     }
12342
12343   if (!vam->json_output)
12344     {
12345       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12346              "sw_if_index", "local_address", "remote_address",
12347              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12348     }
12349
12350   /* Get list of geneve-tunnel interfaces */
12351   M (GENEVE_TUNNEL_DUMP, mp);
12352
12353   mp->sw_if_index = htonl (sw_if_index);
12354
12355   S (mp);
12356
12357   /* Use a control ping for synchronization */
12358   M (CONTROL_PING, mp_ping);
12359   S (mp_ping);
12360
12361   W (ret);
12362   return ret;
12363 }
12364
12365 static int
12366 api_gre_add_del_tunnel (vat_main_t * vam)
12367 {
12368   unformat_input_t *line_input = vam->input;
12369   vl_api_gre_add_del_tunnel_t *mp;
12370   ip4_address_t src4, dst4;
12371   ip6_address_t src6, dst6;
12372   u8 is_add = 1;
12373   u8 ipv4_set = 0;
12374   u8 ipv6_set = 0;
12375   u8 teb = 0;
12376   u8 src_set = 0;
12377   u8 dst_set = 0;
12378   u32 outer_fib_id = 0;
12379   int ret;
12380
12381   memset (&src4, 0, sizeof src4);
12382   memset (&dst4, 0, sizeof dst4);
12383   memset (&src6, 0, sizeof src6);
12384   memset (&dst6, 0, sizeof dst6);
12385
12386   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12387     {
12388       if (unformat (line_input, "del"))
12389         is_add = 0;
12390       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
12391         {
12392           src_set = 1;
12393           ipv4_set = 1;
12394         }
12395       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
12396         {
12397           dst_set = 1;
12398           ipv4_set = 1;
12399         }
12400       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
12401         {
12402           src_set = 1;
12403           ipv6_set = 1;
12404         }
12405       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
12406         {
12407           dst_set = 1;
12408           ipv6_set = 1;
12409         }
12410       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
12411         ;
12412       else if (unformat (line_input, "teb"))
12413         teb = 1;
12414       else
12415         {
12416           errmsg ("parse error '%U'", format_unformat_error, line_input);
12417           return -99;
12418         }
12419     }
12420
12421   if (src_set == 0)
12422     {
12423       errmsg ("tunnel src address not specified");
12424       return -99;
12425     }
12426   if (dst_set == 0)
12427     {
12428       errmsg ("tunnel dst address not specified");
12429       return -99;
12430     }
12431   if (ipv4_set && ipv6_set)
12432     {
12433       errmsg ("both IPv4 and IPv6 addresses specified");
12434       return -99;
12435     }
12436
12437
12438   M (GRE_ADD_DEL_TUNNEL, mp);
12439
12440   if (ipv4_set)
12441     {
12442       clib_memcpy (&mp->src_address, &src4, 4);
12443       clib_memcpy (&mp->dst_address, &dst4, 4);
12444     }
12445   else
12446     {
12447       clib_memcpy (&mp->src_address, &src6, 16);
12448       clib_memcpy (&mp->dst_address, &dst6, 16);
12449     }
12450   mp->outer_fib_id = ntohl (outer_fib_id);
12451   mp->is_add = is_add;
12452   mp->teb = teb;
12453   mp->is_ipv6 = ipv6_set;
12454
12455   S (mp);
12456   W (ret);
12457   return ret;
12458 }
12459
12460 static void vl_api_gre_tunnel_details_t_handler
12461   (vl_api_gre_tunnel_details_t * mp)
12462 {
12463   vat_main_t *vam = &vat_main;
12464   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
12465   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
12466
12467   print (vam->ofp, "%11d%24U%24U%6d%14d",
12468          ntohl (mp->sw_if_index),
12469          format_ip46_address, &src, IP46_TYPE_ANY,
12470          format_ip46_address, &dst, IP46_TYPE_ANY,
12471          mp->teb, ntohl (mp->outer_fib_id));
12472 }
12473
12474 static void vl_api_gre_tunnel_details_t_handler_json
12475   (vl_api_gre_tunnel_details_t * mp)
12476 {
12477   vat_main_t *vam = &vat_main;
12478   vat_json_node_t *node = NULL;
12479   struct in_addr ip4;
12480   struct in6_addr ip6;
12481
12482   if (VAT_JSON_ARRAY != vam->json_tree.type)
12483     {
12484       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12485       vat_json_init_array (&vam->json_tree);
12486     }
12487   node = vat_json_array_add (&vam->json_tree);
12488
12489   vat_json_init_object (node);
12490   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12491   if (!mp->is_ipv6)
12492     {
12493       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
12494       vat_json_object_add_ip4 (node, "src_address", ip4);
12495       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
12496       vat_json_object_add_ip4 (node, "dst_address", ip4);
12497     }
12498   else
12499     {
12500       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
12501       vat_json_object_add_ip6 (node, "src_address", ip6);
12502       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
12503       vat_json_object_add_ip6 (node, "dst_address", ip6);
12504     }
12505   vat_json_object_add_uint (node, "teb", mp->teb);
12506   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
12507   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
12508 }
12509
12510 static int
12511 api_gre_tunnel_dump (vat_main_t * vam)
12512 {
12513   unformat_input_t *i = vam->input;
12514   vl_api_gre_tunnel_dump_t *mp;
12515   vl_api_control_ping_t *mp_ping;
12516   u32 sw_if_index;
12517   u8 sw_if_index_set = 0;
12518   int ret;
12519
12520   /* Parse args required to build the message */
12521   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12522     {
12523       if (unformat (i, "sw_if_index %d", &sw_if_index))
12524         sw_if_index_set = 1;
12525       else
12526         break;
12527     }
12528
12529   if (sw_if_index_set == 0)
12530     {
12531       sw_if_index = ~0;
12532     }
12533
12534   if (!vam->json_output)
12535     {
12536       print (vam->ofp, "%11s%24s%24s%6s%14s",
12537              "sw_if_index", "src_address", "dst_address", "teb",
12538              "outer_fib_id");
12539     }
12540
12541   /* Get list of gre-tunnel interfaces */
12542   M (GRE_TUNNEL_DUMP, mp);
12543
12544   mp->sw_if_index = htonl (sw_if_index);
12545
12546   S (mp);
12547
12548   /* Use a control ping for synchronization */
12549   MPING (CONTROL_PING, mp_ping);
12550   S (mp_ping);
12551
12552   W (ret);
12553   return ret;
12554 }
12555
12556 static int
12557 api_l2_fib_clear_table (vat_main_t * vam)
12558 {
12559 //  unformat_input_t * i = vam->input;
12560   vl_api_l2_fib_clear_table_t *mp;
12561   int ret;
12562
12563   M (L2_FIB_CLEAR_TABLE, mp);
12564
12565   S (mp);
12566   W (ret);
12567   return ret;
12568 }
12569
12570 static int
12571 api_l2_interface_efp_filter (vat_main_t * vam)
12572 {
12573   unformat_input_t *i = vam->input;
12574   vl_api_l2_interface_efp_filter_t *mp;
12575   u32 sw_if_index;
12576   u8 enable = 1;
12577   u8 sw_if_index_set = 0;
12578   int ret;
12579
12580   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12581     {
12582       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12583         sw_if_index_set = 1;
12584       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12585         sw_if_index_set = 1;
12586       else if (unformat (i, "enable"))
12587         enable = 1;
12588       else if (unformat (i, "disable"))
12589         enable = 0;
12590       else
12591         {
12592           clib_warning ("parse error '%U'", format_unformat_error, i);
12593           return -99;
12594         }
12595     }
12596
12597   if (sw_if_index_set == 0)
12598     {
12599       errmsg ("missing sw_if_index");
12600       return -99;
12601     }
12602
12603   M (L2_INTERFACE_EFP_FILTER, mp);
12604
12605   mp->sw_if_index = ntohl (sw_if_index);
12606   mp->enable_disable = enable;
12607
12608   S (mp);
12609   W (ret);
12610   return ret;
12611 }
12612
12613 #define foreach_vtr_op                          \
12614 _("disable",  L2_VTR_DISABLED)                  \
12615 _("push-1",  L2_VTR_PUSH_1)                     \
12616 _("push-2",  L2_VTR_PUSH_2)                     \
12617 _("pop-1",  L2_VTR_POP_1)                       \
12618 _("pop-2",  L2_VTR_POP_2)                       \
12619 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12620 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12621 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12622 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12623
12624 static int
12625 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12626 {
12627   unformat_input_t *i = vam->input;
12628   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12629   u32 sw_if_index;
12630   u8 sw_if_index_set = 0;
12631   u8 vtr_op_set = 0;
12632   u32 vtr_op = 0;
12633   u32 push_dot1q = 1;
12634   u32 tag1 = ~0;
12635   u32 tag2 = ~0;
12636   int ret;
12637
12638   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12639     {
12640       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12641         sw_if_index_set = 1;
12642       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12643         sw_if_index_set = 1;
12644       else if (unformat (i, "vtr_op %d", &vtr_op))
12645         vtr_op_set = 1;
12646 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12647       foreach_vtr_op
12648 #undef _
12649         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12650         ;
12651       else if (unformat (i, "tag1 %d", &tag1))
12652         ;
12653       else if (unformat (i, "tag2 %d", &tag2))
12654         ;
12655       else
12656         {
12657           clib_warning ("parse error '%U'", format_unformat_error, i);
12658           return -99;
12659         }
12660     }
12661
12662   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12663     {
12664       errmsg ("missing vtr operation or sw_if_index");
12665       return -99;
12666     }
12667
12668   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12669   mp->sw_if_index = ntohl (sw_if_index);
12670   mp->vtr_op = ntohl (vtr_op);
12671   mp->push_dot1q = ntohl (push_dot1q);
12672   mp->tag1 = ntohl (tag1);
12673   mp->tag2 = ntohl (tag2);
12674
12675   S (mp);
12676   W (ret);
12677   return ret;
12678 }
12679
12680 static int
12681 api_create_vhost_user_if (vat_main_t * vam)
12682 {
12683   unformat_input_t *i = vam->input;
12684   vl_api_create_vhost_user_if_t *mp;
12685   u8 *file_name;
12686   u8 is_server = 0;
12687   u8 file_name_set = 0;
12688   u32 custom_dev_instance = ~0;
12689   u8 hwaddr[6];
12690   u8 use_custom_mac = 0;
12691   u8 *tag = 0;
12692   int ret;
12693
12694   /* Shut up coverity */
12695   memset (hwaddr, 0, sizeof (hwaddr));
12696
12697   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12698     {
12699       if (unformat (i, "socket %s", &file_name))
12700         {
12701           file_name_set = 1;
12702         }
12703       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12704         ;
12705       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12706         use_custom_mac = 1;
12707       else if (unformat (i, "server"))
12708         is_server = 1;
12709       else if (unformat (i, "tag %s", &tag))
12710         ;
12711       else
12712         break;
12713     }
12714
12715   if (file_name_set == 0)
12716     {
12717       errmsg ("missing socket file name");
12718       return -99;
12719     }
12720
12721   if (vec_len (file_name) > 255)
12722     {
12723       errmsg ("socket file name too long");
12724       return -99;
12725     }
12726   vec_add1 (file_name, 0);
12727
12728   M (CREATE_VHOST_USER_IF, mp);
12729
12730   mp->is_server = is_server;
12731   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12732   vec_free (file_name);
12733   if (custom_dev_instance != ~0)
12734     {
12735       mp->renumber = 1;
12736       mp->custom_dev_instance = ntohl (custom_dev_instance);
12737     }
12738   mp->use_custom_mac = use_custom_mac;
12739   clib_memcpy (mp->mac_address, hwaddr, 6);
12740   if (tag)
12741     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12742   vec_free (tag);
12743
12744   S (mp);
12745   W (ret);
12746   return ret;
12747 }
12748
12749 static int
12750 api_modify_vhost_user_if (vat_main_t * vam)
12751 {
12752   unformat_input_t *i = vam->input;
12753   vl_api_modify_vhost_user_if_t *mp;
12754   u8 *file_name;
12755   u8 is_server = 0;
12756   u8 file_name_set = 0;
12757   u32 custom_dev_instance = ~0;
12758   u8 sw_if_index_set = 0;
12759   u32 sw_if_index = (u32) ~ 0;
12760   int ret;
12761
12762   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12763     {
12764       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12765         sw_if_index_set = 1;
12766       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12767         sw_if_index_set = 1;
12768       else if (unformat (i, "socket %s", &file_name))
12769         {
12770           file_name_set = 1;
12771         }
12772       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12773         ;
12774       else if (unformat (i, "server"))
12775         is_server = 1;
12776       else
12777         break;
12778     }
12779
12780   if (sw_if_index_set == 0)
12781     {
12782       errmsg ("missing sw_if_index or interface name");
12783       return -99;
12784     }
12785
12786   if (file_name_set == 0)
12787     {
12788       errmsg ("missing socket file name");
12789       return -99;
12790     }
12791
12792   if (vec_len (file_name) > 255)
12793     {
12794       errmsg ("socket file name too long");
12795       return -99;
12796     }
12797   vec_add1 (file_name, 0);
12798
12799   M (MODIFY_VHOST_USER_IF, mp);
12800
12801   mp->sw_if_index = ntohl (sw_if_index);
12802   mp->is_server = is_server;
12803   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12804   vec_free (file_name);
12805   if (custom_dev_instance != ~0)
12806     {
12807       mp->renumber = 1;
12808       mp->custom_dev_instance = ntohl (custom_dev_instance);
12809     }
12810
12811   S (mp);
12812   W (ret);
12813   return ret;
12814 }
12815
12816 static int
12817 api_delete_vhost_user_if (vat_main_t * vam)
12818 {
12819   unformat_input_t *i = vam->input;
12820   vl_api_delete_vhost_user_if_t *mp;
12821   u32 sw_if_index = ~0;
12822   u8 sw_if_index_set = 0;
12823   int ret;
12824
12825   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12826     {
12827       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12828         sw_if_index_set = 1;
12829       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12830         sw_if_index_set = 1;
12831       else
12832         break;
12833     }
12834
12835   if (sw_if_index_set == 0)
12836     {
12837       errmsg ("missing sw_if_index or interface name");
12838       return -99;
12839     }
12840
12841
12842   M (DELETE_VHOST_USER_IF, mp);
12843
12844   mp->sw_if_index = ntohl (sw_if_index);
12845
12846   S (mp);
12847   W (ret);
12848   return ret;
12849 }
12850
12851 static void vl_api_sw_interface_vhost_user_details_t_handler
12852   (vl_api_sw_interface_vhost_user_details_t * mp)
12853 {
12854   vat_main_t *vam = &vat_main;
12855
12856   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12857          (char *) mp->interface_name,
12858          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12859          clib_net_to_host_u64 (mp->features), mp->is_server,
12860          ntohl (mp->num_regions), (char *) mp->sock_filename);
12861   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12862 }
12863
12864 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12865   (vl_api_sw_interface_vhost_user_details_t * mp)
12866 {
12867   vat_main_t *vam = &vat_main;
12868   vat_json_node_t *node = NULL;
12869
12870   if (VAT_JSON_ARRAY != vam->json_tree.type)
12871     {
12872       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12873       vat_json_init_array (&vam->json_tree);
12874     }
12875   node = vat_json_array_add (&vam->json_tree);
12876
12877   vat_json_init_object (node);
12878   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12879   vat_json_object_add_string_copy (node, "interface_name",
12880                                    mp->interface_name);
12881   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12882                             ntohl (mp->virtio_net_hdr_sz));
12883   vat_json_object_add_uint (node, "features",
12884                             clib_net_to_host_u64 (mp->features));
12885   vat_json_object_add_uint (node, "is_server", mp->is_server);
12886   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12887   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12888   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12889 }
12890
12891 static int
12892 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12893 {
12894   vl_api_sw_interface_vhost_user_dump_t *mp;
12895   vl_api_control_ping_t *mp_ping;
12896   int ret;
12897   print (vam->ofp,
12898          "Interface name            idx hdr_sz features server regions filename");
12899
12900   /* Get list of vhost-user interfaces */
12901   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12902   S (mp);
12903
12904   /* Use a control ping for synchronization */
12905   MPING (CONTROL_PING, mp_ping);
12906   S (mp_ping);
12907
12908   W (ret);
12909   return ret;
12910 }
12911
12912 static int
12913 api_show_version (vat_main_t * vam)
12914 {
12915   vl_api_show_version_t *mp;
12916   int ret;
12917
12918   M (SHOW_VERSION, mp);
12919
12920   S (mp);
12921   W (ret);
12922   return ret;
12923 }
12924
12925
12926 static int
12927 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12928 {
12929   unformat_input_t *line_input = vam->input;
12930   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12931   ip4_address_t local4, remote4;
12932   ip6_address_t local6, remote6;
12933   u8 is_add = 1;
12934   u8 ipv4_set = 0, ipv6_set = 0;
12935   u8 local_set = 0;
12936   u8 remote_set = 0;
12937   u8 grp_set = 0;
12938   u32 mcast_sw_if_index = ~0;
12939   u32 encap_vrf_id = 0;
12940   u32 decap_vrf_id = 0;
12941   u8 protocol = ~0;
12942   u32 vni;
12943   u8 vni_set = 0;
12944   int ret;
12945
12946   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12947   memset (&local4, 0, sizeof local4);
12948   memset (&remote4, 0, sizeof remote4);
12949   memset (&local6, 0, sizeof local6);
12950   memset (&remote6, 0, sizeof remote6);
12951
12952   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12953     {
12954       if (unformat (line_input, "del"))
12955         is_add = 0;
12956       else if (unformat (line_input, "local %U",
12957                          unformat_ip4_address, &local4))
12958         {
12959           local_set = 1;
12960           ipv4_set = 1;
12961         }
12962       else if (unformat (line_input, "remote %U",
12963                          unformat_ip4_address, &remote4))
12964         {
12965           remote_set = 1;
12966           ipv4_set = 1;
12967         }
12968       else if (unformat (line_input, "local %U",
12969                          unformat_ip6_address, &local6))
12970         {
12971           local_set = 1;
12972           ipv6_set = 1;
12973         }
12974       else if (unformat (line_input, "remote %U",
12975                          unformat_ip6_address, &remote6))
12976         {
12977           remote_set = 1;
12978           ipv6_set = 1;
12979         }
12980       else if (unformat (line_input, "group %U %U",
12981                          unformat_ip4_address, &remote4,
12982                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12983         {
12984           grp_set = remote_set = 1;
12985           ipv4_set = 1;
12986         }
12987       else if (unformat (line_input, "group %U",
12988                          unformat_ip4_address, &remote4))
12989         {
12990           grp_set = remote_set = 1;
12991           ipv4_set = 1;
12992         }
12993       else if (unformat (line_input, "group %U %U",
12994                          unformat_ip6_address, &remote6,
12995                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12996         {
12997           grp_set = remote_set = 1;
12998           ipv6_set = 1;
12999         }
13000       else if (unformat (line_input, "group %U",
13001                          unformat_ip6_address, &remote6))
13002         {
13003           grp_set = remote_set = 1;
13004           ipv6_set = 1;
13005         }
13006       else
13007         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13008         ;
13009       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13010         ;
13011       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13012         ;
13013       else if (unformat (line_input, "vni %d", &vni))
13014         vni_set = 1;
13015       else if (unformat (line_input, "next-ip4"))
13016         protocol = 1;
13017       else if (unformat (line_input, "next-ip6"))
13018         protocol = 2;
13019       else if (unformat (line_input, "next-ethernet"))
13020         protocol = 3;
13021       else if (unformat (line_input, "next-nsh"))
13022         protocol = 4;
13023       else
13024         {
13025           errmsg ("parse error '%U'", format_unformat_error, line_input);
13026           return -99;
13027         }
13028     }
13029
13030   if (local_set == 0)
13031     {
13032       errmsg ("tunnel local address not specified");
13033       return -99;
13034     }
13035   if (remote_set == 0)
13036     {
13037       errmsg ("tunnel remote address not specified");
13038       return -99;
13039     }
13040   if (grp_set && mcast_sw_if_index == ~0)
13041     {
13042       errmsg ("tunnel nonexistent multicast device");
13043       return -99;
13044     }
13045   if (ipv4_set && ipv6_set)
13046     {
13047       errmsg ("both IPv4 and IPv6 addresses specified");
13048       return -99;
13049     }
13050
13051   if (vni_set == 0)
13052     {
13053       errmsg ("vni not specified");
13054       return -99;
13055     }
13056
13057   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13058
13059
13060   if (ipv6_set)
13061     {
13062       clib_memcpy (&mp->local, &local6, sizeof (local6));
13063       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13064     }
13065   else
13066     {
13067       clib_memcpy (&mp->local, &local4, sizeof (local4));
13068       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13069     }
13070
13071   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13072   mp->encap_vrf_id = ntohl (encap_vrf_id);
13073   mp->decap_vrf_id = ntohl (decap_vrf_id);
13074   mp->protocol = protocol;
13075   mp->vni = ntohl (vni);
13076   mp->is_add = is_add;
13077   mp->is_ipv6 = ipv6_set;
13078
13079   S (mp);
13080   W (ret);
13081   return ret;
13082 }
13083
13084 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13085   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13086 {
13087   vat_main_t *vam = &vat_main;
13088   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13089   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13090
13091   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13092          ntohl (mp->sw_if_index),
13093          format_ip46_address, &local, IP46_TYPE_ANY,
13094          format_ip46_address, &remote, IP46_TYPE_ANY,
13095          ntohl (mp->vni), mp->protocol,
13096          ntohl (mp->mcast_sw_if_index),
13097          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13098 }
13099
13100
13101 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13102   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13103 {
13104   vat_main_t *vam = &vat_main;
13105   vat_json_node_t *node = NULL;
13106   struct in_addr ip4;
13107   struct in6_addr ip6;
13108
13109   if (VAT_JSON_ARRAY != vam->json_tree.type)
13110     {
13111       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13112       vat_json_init_array (&vam->json_tree);
13113     }
13114   node = vat_json_array_add (&vam->json_tree);
13115
13116   vat_json_init_object (node);
13117   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13118   if (mp->is_ipv6)
13119     {
13120       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13121       vat_json_object_add_ip6 (node, "local", ip6);
13122       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13123       vat_json_object_add_ip6 (node, "remote", ip6);
13124     }
13125   else
13126     {
13127       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13128       vat_json_object_add_ip4 (node, "local", ip4);
13129       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13130       vat_json_object_add_ip4 (node, "remote", ip4);
13131     }
13132   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13133   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13134   vat_json_object_add_uint (node, "mcast_sw_if_index",
13135                             ntohl (mp->mcast_sw_if_index));
13136   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13137   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13138   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13139 }
13140
13141 static int
13142 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13143 {
13144   unformat_input_t *i = vam->input;
13145   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13146   vl_api_control_ping_t *mp_ping;
13147   u32 sw_if_index;
13148   u8 sw_if_index_set = 0;
13149   int ret;
13150
13151   /* Parse args required to build the message */
13152   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13153     {
13154       if (unformat (i, "sw_if_index %d", &sw_if_index))
13155         sw_if_index_set = 1;
13156       else
13157         break;
13158     }
13159
13160   if (sw_if_index_set == 0)
13161     {
13162       sw_if_index = ~0;
13163     }
13164
13165   if (!vam->json_output)
13166     {
13167       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13168              "sw_if_index", "local", "remote", "vni",
13169              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13170     }
13171
13172   /* Get list of vxlan-tunnel interfaces */
13173   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13174
13175   mp->sw_if_index = htonl (sw_if_index);
13176
13177   S (mp);
13178
13179   /* Use a control ping for synchronization */
13180   MPING (CONTROL_PING, mp_ping);
13181   S (mp_ping);
13182
13183   W (ret);
13184   return ret;
13185 }
13186
13187
13188 u8 *
13189 format_l2_fib_mac_address (u8 * s, va_list * args)
13190 {
13191   u8 *a = va_arg (*args, u8 *);
13192
13193   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
13194                  a[2], a[3], a[4], a[5], a[6], a[7]);
13195 }
13196
13197 static void vl_api_l2_fib_table_details_t_handler
13198   (vl_api_l2_fib_table_details_t * mp)
13199 {
13200   vat_main_t *vam = &vat_main;
13201
13202   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13203          "       %d       %d     %d",
13204          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
13205          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13206          mp->bvi_mac);
13207 }
13208
13209 static void vl_api_l2_fib_table_details_t_handler_json
13210   (vl_api_l2_fib_table_details_t * mp)
13211 {
13212   vat_main_t *vam = &vat_main;
13213   vat_json_node_t *node = NULL;
13214
13215   if (VAT_JSON_ARRAY != vam->json_tree.type)
13216     {
13217       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13218       vat_json_init_array (&vam->json_tree);
13219     }
13220   node = vat_json_array_add (&vam->json_tree);
13221
13222   vat_json_init_object (node);
13223   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13224   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
13225   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13226   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13227   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13228   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13229 }
13230
13231 static int
13232 api_l2_fib_table_dump (vat_main_t * vam)
13233 {
13234   unformat_input_t *i = vam->input;
13235   vl_api_l2_fib_table_dump_t *mp;
13236   vl_api_control_ping_t *mp_ping;
13237   u32 bd_id;
13238   u8 bd_id_set = 0;
13239   int ret;
13240
13241   /* Parse args required to build the message */
13242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13243     {
13244       if (unformat (i, "bd_id %d", &bd_id))
13245         bd_id_set = 1;
13246       else
13247         break;
13248     }
13249
13250   if (bd_id_set == 0)
13251     {
13252       errmsg ("missing bridge domain");
13253       return -99;
13254     }
13255
13256   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13257
13258   /* Get list of l2 fib entries */
13259   M (L2_FIB_TABLE_DUMP, mp);
13260
13261   mp->bd_id = ntohl (bd_id);
13262   S (mp);
13263
13264   /* Use a control ping for synchronization */
13265   MPING (CONTROL_PING, mp_ping);
13266   S (mp_ping);
13267
13268   W (ret);
13269   return ret;
13270 }
13271
13272
13273 static int
13274 api_interface_name_renumber (vat_main_t * vam)
13275 {
13276   unformat_input_t *line_input = vam->input;
13277   vl_api_interface_name_renumber_t *mp;
13278   u32 sw_if_index = ~0;
13279   u32 new_show_dev_instance = ~0;
13280   int ret;
13281
13282   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13283     {
13284       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13285                     &sw_if_index))
13286         ;
13287       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13288         ;
13289       else if (unformat (line_input, "new_show_dev_instance %d",
13290                          &new_show_dev_instance))
13291         ;
13292       else
13293         break;
13294     }
13295
13296   if (sw_if_index == ~0)
13297     {
13298       errmsg ("missing interface name or sw_if_index");
13299       return -99;
13300     }
13301
13302   if (new_show_dev_instance == ~0)
13303     {
13304       errmsg ("missing new_show_dev_instance");
13305       return -99;
13306     }
13307
13308   M (INTERFACE_NAME_RENUMBER, mp);
13309
13310   mp->sw_if_index = ntohl (sw_if_index);
13311   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13312
13313   S (mp);
13314   W (ret);
13315   return ret;
13316 }
13317
13318 static int
13319 api_want_ip4_arp_events (vat_main_t * vam)
13320 {
13321   unformat_input_t *line_input = vam->input;
13322   vl_api_want_ip4_arp_events_t *mp;
13323   ip4_address_t address;
13324   int address_set = 0;
13325   u32 enable_disable = 1;
13326   int ret;
13327
13328   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13329     {
13330       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
13331         address_set = 1;
13332       else if (unformat (line_input, "del"))
13333         enable_disable = 0;
13334       else
13335         break;
13336     }
13337
13338   if (address_set == 0)
13339     {
13340       errmsg ("missing addresses");
13341       return -99;
13342     }
13343
13344   M (WANT_IP4_ARP_EVENTS, mp);
13345   mp->enable_disable = enable_disable;
13346   mp->pid = htonl (getpid ());
13347   mp->address = address.as_u32;
13348
13349   S (mp);
13350   W (ret);
13351   return ret;
13352 }
13353
13354 static int
13355 api_want_ip6_nd_events (vat_main_t * vam)
13356 {
13357   unformat_input_t *line_input = vam->input;
13358   vl_api_want_ip6_nd_events_t *mp;
13359   ip6_address_t address;
13360   int address_set = 0;
13361   u32 enable_disable = 1;
13362   int ret;
13363
13364   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13365     {
13366       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
13367         address_set = 1;
13368       else if (unformat (line_input, "del"))
13369         enable_disable = 0;
13370       else
13371         break;
13372     }
13373
13374   if (address_set == 0)
13375     {
13376       errmsg ("missing addresses");
13377       return -99;
13378     }
13379
13380   M (WANT_IP6_ND_EVENTS, mp);
13381   mp->enable_disable = enable_disable;
13382   mp->pid = htonl (getpid ());
13383   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
13384
13385   S (mp);
13386   W (ret);
13387   return ret;
13388 }
13389
13390 static int
13391 api_want_l2_macs_events (vat_main_t * vam)
13392 {
13393   unformat_input_t *line_input = vam->input;
13394   vl_api_want_l2_macs_events_t *mp;
13395   u8 enable_disable = 1;
13396   u32 scan_delay = 0;
13397   u32 max_macs_in_event = 0;
13398   u32 learn_limit = 0;
13399   int ret;
13400
13401   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13402     {
13403       if (unformat (line_input, "learn-limit %d", &learn_limit))
13404         ;
13405       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13406         ;
13407       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13408         ;
13409       else if (unformat (line_input, "disable"))
13410         enable_disable = 0;
13411       else
13412         break;
13413     }
13414
13415   M (WANT_L2_MACS_EVENTS, mp);
13416   mp->enable_disable = enable_disable;
13417   mp->pid = htonl (getpid ());
13418   mp->learn_limit = htonl (learn_limit);
13419   mp->scan_delay = (u8) scan_delay;
13420   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13421   S (mp);
13422   W (ret);
13423   return ret;
13424 }
13425
13426 static int
13427 api_input_acl_set_interface (vat_main_t * vam)
13428 {
13429   unformat_input_t *i = vam->input;
13430   vl_api_input_acl_set_interface_t *mp;
13431   u32 sw_if_index;
13432   int sw_if_index_set;
13433   u32 ip4_table_index = ~0;
13434   u32 ip6_table_index = ~0;
13435   u32 l2_table_index = ~0;
13436   u8 is_add = 1;
13437   int ret;
13438
13439   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13440     {
13441       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13442         sw_if_index_set = 1;
13443       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13444         sw_if_index_set = 1;
13445       else if (unformat (i, "del"))
13446         is_add = 0;
13447       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13448         ;
13449       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13450         ;
13451       else if (unformat (i, "l2-table %d", &l2_table_index))
13452         ;
13453       else
13454         {
13455           clib_warning ("parse error '%U'", format_unformat_error, i);
13456           return -99;
13457         }
13458     }
13459
13460   if (sw_if_index_set == 0)
13461     {
13462       errmsg ("missing interface name or sw_if_index");
13463       return -99;
13464     }
13465
13466   M (INPUT_ACL_SET_INTERFACE, mp);
13467
13468   mp->sw_if_index = ntohl (sw_if_index);
13469   mp->ip4_table_index = ntohl (ip4_table_index);
13470   mp->ip6_table_index = ntohl (ip6_table_index);
13471   mp->l2_table_index = ntohl (l2_table_index);
13472   mp->is_add = is_add;
13473
13474   S (mp);
13475   W (ret);
13476   return ret;
13477 }
13478
13479 static int
13480 api_ip_address_dump (vat_main_t * vam)
13481 {
13482   unformat_input_t *i = vam->input;
13483   vl_api_ip_address_dump_t *mp;
13484   vl_api_control_ping_t *mp_ping;
13485   u32 sw_if_index = ~0;
13486   u8 sw_if_index_set = 0;
13487   u8 ipv4_set = 0;
13488   u8 ipv6_set = 0;
13489   int ret;
13490
13491   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13492     {
13493       if (unformat (i, "sw_if_index %d", &sw_if_index))
13494         sw_if_index_set = 1;
13495       else
13496         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13497         sw_if_index_set = 1;
13498       else if (unformat (i, "ipv4"))
13499         ipv4_set = 1;
13500       else if (unformat (i, "ipv6"))
13501         ipv6_set = 1;
13502       else
13503         break;
13504     }
13505
13506   if (ipv4_set && ipv6_set)
13507     {
13508       errmsg ("ipv4 and ipv6 flags cannot be both set");
13509       return -99;
13510     }
13511
13512   if ((!ipv4_set) && (!ipv6_set))
13513     {
13514       errmsg ("no ipv4 nor ipv6 flag set");
13515       return -99;
13516     }
13517
13518   if (sw_if_index_set == 0)
13519     {
13520       errmsg ("missing interface name or sw_if_index");
13521       return -99;
13522     }
13523
13524   vam->current_sw_if_index = sw_if_index;
13525   vam->is_ipv6 = ipv6_set;
13526
13527   M (IP_ADDRESS_DUMP, mp);
13528   mp->sw_if_index = ntohl (sw_if_index);
13529   mp->is_ipv6 = ipv6_set;
13530   S (mp);
13531
13532   /* Use a control ping for synchronization */
13533   MPING (CONTROL_PING, mp_ping);
13534   S (mp_ping);
13535
13536   W (ret);
13537   return ret;
13538 }
13539
13540 static int
13541 api_ip_dump (vat_main_t * vam)
13542 {
13543   vl_api_ip_dump_t *mp;
13544   vl_api_control_ping_t *mp_ping;
13545   unformat_input_t *in = vam->input;
13546   int ipv4_set = 0;
13547   int ipv6_set = 0;
13548   int is_ipv6;
13549   int i;
13550   int ret;
13551
13552   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13553     {
13554       if (unformat (in, "ipv4"))
13555         ipv4_set = 1;
13556       else if (unformat (in, "ipv6"))
13557         ipv6_set = 1;
13558       else
13559         break;
13560     }
13561
13562   if (ipv4_set && ipv6_set)
13563     {
13564       errmsg ("ipv4 and ipv6 flags cannot be both set");
13565       return -99;
13566     }
13567
13568   if ((!ipv4_set) && (!ipv6_set))
13569     {
13570       errmsg ("no ipv4 nor ipv6 flag set");
13571       return -99;
13572     }
13573
13574   is_ipv6 = ipv6_set;
13575   vam->is_ipv6 = is_ipv6;
13576
13577   /* free old data */
13578   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13579     {
13580       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13581     }
13582   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13583
13584   M (IP_DUMP, mp);
13585   mp->is_ipv6 = ipv6_set;
13586   S (mp);
13587
13588   /* Use a control ping for synchronization */
13589   MPING (CONTROL_PING, mp_ping);
13590   S (mp_ping);
13591
13592   W (ret);
13593   return ret;
13594 }
13595
13596 static int
13597 api_ipsec_spd_add_del (vat_main_t * vam)
13598 {
13599   unformat_input_t *i = vam->input;
13600   vl_api_ipsec_spd_add_del_t *mp;
13601   u32 spd_id = ~0;
13602   u8 is_add = 1;
13603   int ret;
13604
13605   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13606     {
13607       if (unformat (i, "spd_id %d", &spd_id))
13608         ;
13609       else if (unformat (i, "del"))
13610         is_add = 0;
13611       else
13612         {
13613           clib_warning ("parse error '%U'", format_unformat_error, i);
13614           return -99;
13615         }
13616     }
13617   if (spd_id == ~0)
13618     {
13619       errmsg ("spd_id must be set");
13620       return -99;
13621     }
13622
13623   M (IPSEC_SPD_ADD_DEL, mp);
13624
13625   mp->spd_id = ntohl (spd_id);
13626   mp->is_add = is_add;
13627
13628   S (mp);
13629   W (ret);
13630   return ret;
13631 }
13632
13633 static int
13634 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13635 {
13636   unformat_input_t *i = vam->input;
13637   vl_api_ipsec_interface_add_del_spd_t *mp;
13638   u32 sw_if_index;
13639   u8 sw_if_index_set = 0;
13640   u32 spd_id = (u32) ~ 0;
13641   u8 is_add = 1;
13642   int ret;
13643
13644   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13645     {
13646       if (unformat (i, "del"))
13647         is_add = 0;
13648       else if (unformat (i, "spd_id %d", &spd_id))
13649         ;
13650       else
13651         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13652         sw_if_index_set = 1;
13653       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13654         sw_if_index_set = 1;
13655       else
13656         {
13657           clib_warning ("parse error '%U'", format_unformat_error, i);
13658           return -99;
13659         }
13660
13661     }
13662
13663   if (spd_id == (u32) ~ 0)
13664     {
13665       errmsg ("spd_id must be set");
13666       return -99;
13667     }
13668
13669   if (sw_if_index_set == 0)
13670     {
13671       errmsg ("missing interface name or sw_if_index");
13672       return -99;
13673     }
13674
13675   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13676
13677   mp->spd_id = ntohl (spd_id);
13678   mp->sw_if_index = ntohl (sw_if_index);
13679   mp->is_add = is_add;
13680
13681   S (mp);
13682   W (ret);
13683   return ret;
13684 }
13685
13686 static int
13687 api_ipsec_spd_add_del_entry (vat_main_t * vam)
13688 {
13689   unformat_input_t *i = vam->input;
13690   vl_api_ipsec_spd_add_del_entry_t *mp;
13691   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
13692   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13693   i32 priority = 0;
13694   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13695   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13696   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
13697   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
13698   int ret;
13699
13700   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
13701   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
13702   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
13703   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
13704   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
13705   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
13706
13707   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13708     {
13709       if (unformat (i, "del"))
13710         is_add = 0;
13711       if (unformat (i, "outbound"))
13712         is_outbound = 1;
13713       if (unformat (i, "inbound"))
13714         is_outbound = 0;
13715       else if (unformat (i, "spd_id %d", &spd_id))
13716         ;
13717       else if (unformat (i, "sa_id %d", &sa_id))
13718         ;
13719       else if (unformat (i, "priority %d", &priority))
13720         ;
13721       else if (unformat (i, "protocol %d", &protocol))
13722         ;
13723       else if (unformat (i, "lport_start %d", &lport_start))
13724         ;
13725       else if (unformat (i, "lport_stop %d", &lport_stop))
13726         ;
13727       else if (unformat (i, "rport_start %d", &rport_start))
13728         ;
13729       else if (unformat (i, "rport_stop %d", &rport_stop))
13730         ;
13731       else
13732         if (unformat
13733             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
13734         {
13735           is_ipv6 = 0;
13736           is_ip_any = 0;
13737         }
13738       else
13739         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
13740         {
13741           is_ipv6 = 0;
13742           is_ip_any = 0;
13743         }
13744       else
13745         if (unformat
13746             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
13747         {
13748           is_ipv6 = 0;
13749           is_ip_any = 0;
13750         }
13751       else
13752         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
13753         {
13754           is_ipv6 = 0;
13755           is_ip_any = 0;
13756         }
13757       else
13758         if (unformat
13759             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
13760         {
13761           is_ipv6 = 1;
13762           is_ip_any = 0;
13763         }
13764       else
13765         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
13766         {
13767           is_ipv6 = 1;
13768           is_ip_any = 0;
13769         }
13770       else
13771         if (unformat
13772             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
13773         {
13774           is_ipv6 = 1;
13775           is_ip_any = 0;
13776         }
13777       else
13778         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
13779         {
13780           is_ipv6 = 1;
13781           is_ip_any = 0;
13782         }
13783       else
13784         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13785         {
13786           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13787             {
13788               clib_warning ("unsupported action: 'resolve'");
13789               return -99;
13790             }
13791         }
13792       else
13793         {
13794           clib_warning ("parse error '%U'", format_unformat_error, i);
13795           return -99;
13796         }
13797
13798     }
13799
13800   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
13801
13802   mp->spd_id = ntohl (spd_id);
13803   mp->priority = ntohl (priority);
13804   mp->is_outbound = is_outbound;
13805
13806   mp->is_ipv6 = is_ipv6;
13807   if (is_ipv6 || is_ip_any)
13808     {
13809       clib_memcpy (mp->remote_address_start, &raddr6_start,
13810                    sizeof (ip6_address_t));
13811       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
13812                    sizeof (ip6_address_t));
13813       clib_memcpy (mp->local_address_start, &laddr6_start,
13814                    sizeof (ip6_address_t));
13815       clib_memcpy (mp->local_address_stop, &laddr6_stop,
13816                    sizeof (ip6_address_t));
13817     }
13818   else
13819     {
13820       clib_memcpy (mp->remote_address_start, &raddr4_start,
13821                    sizeof (ip4_address_t));
13822       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
13823                    sizeof (ip4_address_t));
13824       clib_memcpy (mp->local_address_start, &laddr4_start,
13825                    sizeof (ip4_address_t));
13826       clib_memcpy (mp->local_address_stop, &laddr4_stop,
13827                    sizeof (ip4_address_t));
13828     }
13829   mp->protocol = (u8) protocol;
13830   mp->local_port_start = ntohs ((u16) lport_start);
13831   mp->local_port_stop = ntohs ((u16) lport_stop);
13832   mp->remote_port_start = ntohs ((u16) rport_start);
13833   mp->remote_port_stop = ntohs ((u16) rport_stop);
13834   mp->policy = (u8) policy;
13835   mp->sa_id = ntohl (sa_id);
13836   mp->is_add = is_add;
13837   mp->is_ip_any = is_ip_any;
13838   S (mp);
13839   W (ret);
13840   return ret;
13841 }
13842
13843 static int
13844 api_ipsec_sad_add_del_entry (vat_main_t * vam)
13845 {
13846   unformat_input_t *i = vam->input;
13847   vl_api_ipsec_sad_add_del_entry_t *mp;
13848   u32 sad_id = 0, spi = 0;
13849   u8 *ck = 0, *ik = 0;
13850   u8 is_add = 1;
13851
13852   u8 protocol = IPSEC_PROTOCOL_AH;
13853   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
13854   u32 crypto_alg = 0, integ_alg = 0;
13855   ip4_address_t tun_src4;
13856   ip4_address_t tun_dst4;
13857   ip6_address_t tun_src6;
13858   ip6_address_t tun_dst6;
13859   int ret;
13860
13861   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13862     {
13863       if (unformat (i, "del"))
13864         is_add = 0;
13865       else if (unformat (i, "sad_id %d", &sad_id))
13866         ;
13867       else if (unformat (i, "spi %d", &spi))
13868         ;
13869       else if (unformat (i, "esp"))
13870         protocol = IPSEC_PROTOCOL_ESP;
13871       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
13872         {
13873           is_tunnel = 1;
13874           is_tunnel_ipv6 = 0;
13875         }
13876       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
13877         {
13878           is_tunnel = 1;
13879           is_tunnel_ipv6 = 0;
13880         }
13881       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
13882         {
13883           is_tunnel = 1;
13884           is_tunnel_ipv6 = 1;
13885         }
13886       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
13887         {
13888           is_tunnel = 1;
13889           is_tunnel_ipv6 = 1;
13890         }
13891       else
13892         if (unformat
13893             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
13894         {
13895           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
13896               crypto_alg >= IPSEC_CRYPTO_N_ALG)
13897             {
13898               clib_warning ("unsupported crypto-alg: '%U'",
13899                             format_ipsec_crypto_alg, crypto_alg);
13900               return -99;
13901             }
13902         }
13903       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13904         ;
13905       else
13906         if (unformat
13907             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
13908         {
13909           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
13910               integ_alg >= IPSEC_INTEG_N_ALG)
13911             {
13912               clib_warning ("unsupported integ-alg: '%U'",
13913                             format_ipsec_integ_alg, integ_alg);
13914               return -99;
13915             }
13916         }
13917       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13918         ;
13919       else
13920         {
13921           clib_warning ("parse error '%U'", format_unformat_error, i);
13922           return -99;
13923         }
13924
13925     }
13926
13927   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
13928
13929   mp->sad_id = ntohl (sad_id);
13930   mp->is_add = is_add;
13931   mp->protocol = protocol;
13932   mp->spi = ntohl (spi);
13933   mp->is_tunnel = is_tunnel;
13934   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
13935   mp->crypto_algorithm = crypto_alg;
13936   mp->integrity_algorithm = integ_alg;
13937   mp->crypto_key_length = vec_len (ck);
13938   mp->integrity_key_length = vec_len (ik);
13939
13940   if (mp->crypto_key_length > sizeof (mp->crypto_key))
13941     mp->crypto_key_length = sizeof (mp->crypto_key);
13942
13943   if (mp->integrity_key_length > sizeof (mp->integrity_key))
13944     mp->integrity_key_length = sizeof (mp->integrity_key);
13945
13946   if (ck)
13947     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
13948   if (ik)
13949     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
13950
13951   if (is_tunnel)
13952     {
13953       if (is_tunnel_ipv6)
13954         {
13955           clib_memcpy (mp->tunnel_src_address, &tun_src6,
13956                        sizeof (ip6_address_t));
13957           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
13958                        sizeof (ip6_address_t));
13959         }
13960       else
13961         {
13962           clib_memcpy (mp->tunnel_src_address, &tun_src4,
13963                        sizeof (ip4_address_t));
13964           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
13965                        sizeof (ip4_address_t));
13966         }
13967     }
13968
13969   S (mp);
13970   W (ret);
13971   return ret;
13972 }
13973
13974 static int
13975 api_ipsec_sa_set_key (vat_main_t * vam)
13976 {
13977   unformat_input_t *i = vam->input;
13978   vl_api_ipsec_sa_set_key_t *mp;
13979   u32 sa_id;
13980   u8 *ck = 0, *ik = 0;
13981   int ret;
13982
13983   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13984     {
13985       if (unformat (i, "sa_id %d", &sa_id))
13986         ;
13987       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13988         ;
13989       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13990         ;
13991       else
13992         {
13993           clib_warning ("parse error '%U'", format_unformat_error, i);
13994           return -99;
13995         }
13996     }
13997
13998   M (IPSEC_SA_SET_KEY, mp);
13999
14000   mp->sa_id = ntohl (sa_id);
14001   mp->crypto_key_length = vec_len (ck);
14002   mp->integrity_key_length = vec_len (ik);
14003
14004   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14005     mp->crypto_key_length = sizeof (mp->crypto_key);
14006
14007   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14008     mp->integrity_key_length = sizeof (mp->integrity_key);
14009
14010   if (ck)
14011     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14012   if (ik)
14013     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14014
14015   S (mp);
14016   W (ret);
14017   return ret;
14018 }
14019
14020 static int
14021 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14022 {
14023   unformat_input_t *i = vam->input;
14024   vl_api_ipsec_tunnel_if_add_del_t *mp;
14025   u32 local_spi = 0, remote_spi = 0;
14026   u32 crypto_alg = 0, integ_alg = 0;
14027   u8 *lck = NULL, *rck = NULL;
14028   u8 *lik = NULL, *rik = NULL;
14029   ip4_address_t local_ip = { {0} };
14030   ip4_address_t remote_ip = { {0} };
14031   u8 is_add = 1;
14032   u8 esn = 0;
14033   u8 anti_replay = 0;
14034   int ret;
14035
14036   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14037     {
14038       if (unformat (i, "del"))
14039         is_add = 0;
14040       else if (unformat (i, "esn"))
14041         esn = 1;
14042       else if (unformat (i, "anti_replay"))
14043         anti_replay = 1;
14044       else if (unformat (i, "local_spi %d", &local_spi))
14045         ;
14046       else if (unformat (i, "remote_spi %d", &remote_spi))
14047         ;
14048       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
14049         ;
14050       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
14051         ;
14052       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14053         ;
14054       else
14055         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14056         ;
14057       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14058         ;
14059       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14060         ;
14061       else
14062         if (unformat
14063             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14064         {
14065           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14066               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14067             {
14068               errmsg ("unsupported crypto-alg: '%U'\n",
14069                       format_ipsec_crypto_alg, crypto_alg);
14070               return -99;
14071             }
14072         }
14073       else
14074         if (unformat
14075             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14076         {
14077           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14078               integ_alg >= IPSEC_INTEG_N_ALG)
14079             {
14080               errmsg ("unsupported integ-alg: '%U'\n",
14081                       format_ipsec_integ_alg, integ_alg);
14082               return -99;
14083             }
14084         }
14085       else
14086         {
14087           errmsg ("parse error '%U'\n", format_unformat_error, i);
14088           return -99;
14089         }
14090     }
14091
14092   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14093
14094   mp->is_add = is_add;
14095   mp->esn = esn;
14096   mp->anti_replay = anti_replay;
14097
14098   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
14099   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
14100
14101   mp->local_spi = htonl (local_spi);
14102   mp->remote_spi = htonl (remote_spi);
14103   mp->crypto_alg = (u8) crypto_alg;
14104
14105   mp->local_crypto_key_len = 0;
14106   if (lck)
14107     {
14108       mp->local_crypto_key_len = vec_len (lck);
14109       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14110         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14111       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14112     }
14113
14114   mp->remote_crypto_key_len = 0;
14115   if (rck)
14116     {
14117       mp->remote_crypto_key_len = vec_len (rck);
14118       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14119         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14120       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14121     }
14122
14123   mp->integ_alg = (u8) integ_alg;
14124
14125   mp->local_integ_key_len = 0;
14126   if (lik)
14127     {
14128       mp->local_integ_key_len = vec_len (lik);
14129       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14130         mp->local_integ_key_len = sizeof (mp->local_integ_key);
14131       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14132     }
14133
14134   mp->remote_integ_key_len = 0;
14135   if (rik)
14136     {
14137       mp->remote_integ_key_len = vec_len (rik);
14138       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14139         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14140       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14141     }
14142
14143   S (mp);
14144   W (ret);
14145   return ret;
14146 }
14147
14148 static void
14149 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14150 {
14151   vat_main_t *vam = &vat_main;
14152
14153   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14154          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
14155          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
14156          "tunnel_src_addr %U tunnel_dst_addr %U "
14157          "salt %u seq_outbound %lu last_seq_inbound %lu "
14158          "replay_window %lu total_data_size %lu\n",
14159          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
14160          mp->protocol,
14161          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
14162          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
14163          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
14164          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14165          mp->tunnel_src_addr,
14166          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14167          mp->tunnel_dst_addr,
14168          ntohl (mp->salt),
14169          clib_net_to_host_u64 (mp->seq_outbound),
14170          clib_net_to_host_u64 (mp->last_seq_inbound),
14171          clib_net_to_host_u64 (mp->replay_window),
14172          clib_net_to_host_u64 (mp->total_data_size));
14173 }
14174
14175 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14176 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14177
14178 static void vl_api_ipsec_sa_details_t_handler_json
14179   (vl_api_ipsec_sa_details_t * mp)
14180 {
14181   vat_main_t *vam = &vat_main;
14182   vat_json_node_t *node = NULL;
14183   struct in_addr src_ip4, dst_ip4;
14184   struct in6_addr src_ip6, dst_ip6;
14185
14186   if (VAT_JSON_ARRAY != vam->json_tree.type)
14187     {
14188       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14189       vat_json_init_array (&vam->json_tree);
14190     }
14191   node = vat_json_array_add (&vam->json_tree);
14192
14193   vat_json_init_object (node);
14194   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
14195   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14196   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
14197   vat_json_object_add_uint (node, "proto", mp->protocol);
14198   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
14199   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
14200   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
14201   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
14202   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
14203   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
14204   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
14205                              mp->crypto_key_len);
14206   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
14207                              mp->integ_key_len);
14208   if (mp->is_tunnel_ip6)
14209     {
14210       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
14211       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
14212       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
14213       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
14214     }
14215   else
14216     {
14217       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
14218       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
14219       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
14220       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
14221     }
14222   vat_json_object_add_uint (node, "replay_window",
14223                             clib_net_to_host_u64 (mp->replay_window));
14224   vat_json_object_add_uint (node, "total_data_size",
14225                             clib_net_to_host_u64 (mp->total_data_size));
14226
14227 }
14228
14229 static int
14230 api_ipsec_sa_dump (vat_main_t * vam)
14231 {
14232   unformat_input_t *i = vam->input;
14233   vl_api_ipsec_sa_dump_t *mp;
14234   vl_api_control_ping_t *mp_ping;
14235   u32 sa_id = ~0;
14236   int ret;
14237
14238   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14239     {
14240       if (unformat (i, "sa_id %d", &sa_id))
14241         ;
14242       else
14243         {
14244           clib_warning ("parse error '%U'", format_unformat_error, i);
14245           return -99;
14246         }
14247     }
14248
14249   M (IPSEC_SA_DUMP, mp);
14250
14251   mp->sa_id = ntohl (sa_id);
14252
14253   S (mp);
14254
14255   /* Use a control ping for synchronization */
14256   M (CONTROL_PING, mp_ping);
14257   S (mp_ping);
14258
14259   W (ret);
14260   return ret;
14261 }
14262
14263 static int
14264 api_ikev2_profile_add_del (vat_main_t * vam)
14265 {
14266   unformat_input_t *i = vam->input;
14267   vl_api_ikev2_profile_add_del_t *mp;
14268   u8 is_add = 1;
14269   u8 *name = 0;
14270   int ret;
14271
14272   const char *valid_chars = "a-zA-Z0-9_";
14273
14274   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14275     {
14276       if (unformat (i, "del"))
14277         is_add = 0;
14278       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14279         vec_add1 (name, 0);
14280       else
14281         {
14282           errmsg ("parse error '%U'", format_unformat_error, i);
14283           return -99;
14284         }
14285     }
14286
14287   if (!vec_len (name))
14288     {
14289       errmsg ("profile name must be specified");
14290       return -99;
14291     }
14292
14293   if (vec_len (name) > 64)
14294     {
14295       errmsg ("profile name too long");
14296       return -99;
14297     }
14298
14299   M (IKEV2_PROFILE_ADD_DEL, mp);
14300
14301   clib_memcpy (mp->name, name, vec_len (name));
14302   mp->is_add = is_add;
14303   vec_free (name);
14304
14305   S (mp);
14306   W (ret);
14307   return ret;
14308 }
14309
14310 static int
14311 api_ikev2_profile_set_auth (vat_main_t * vam)
14312 {
14313   unformat_input_t *i = vam->input;
14314   vl_api_ikev2_profile_set_auth_t *mp;
14315   u8 *name = 0;
14316   u8 *data = 0;
14317   u32 auth_method = 0;
14318   u8 is_hex = 0;
14319   int ret;
14320
14321   const char *valid_chars = "a-zA-Z0-9_";
14322
14323   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14324     {
14325       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14326         vec_add1 (name, 0);
14327       else if (unformat (i, "auth_method %U",
14328                          unformat_ikev2_auth_method, &auth_method))
14329         ;
14330       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
14331         is_hex = 1;
14332       else if (unformat (i, "auth_data %v", &data))
14333         ;
14334       else
14335         {
14336           errmsg ("parse error '%U'", format_unformat_error, i);
14337           return -99;
14338         }
14339     }
14340
14341   if (!vec_len (name))
14342     {
14343       errmsg ("profile name must be specified");
14344       return -99;
14345     }
14346
14347   if (vec_len (name) > 64)
14348     {
14349       errmsg ("profile name too long");
14350       return -99;
14351     }
14352
14353   if (!vec_len (data))
14354     {
14355       errmsg ("auth_data must be specified");
14356       return -99;
14357     }
14358
14359   if (!auth_method)
14360     {
14361       errmsg ("auth_method must be specified");
14362       return -99;
14363     }
14364
14365   M (IKEV2_PROFILE_SET_AUTH, mp);
14366
14367   mp->is_hex = is_hex;
14368   mp->auth_method = (u8) auth_method;
14369   mp->data_len = vec_len (data);
14370   clib_memcpy (mp->name, name, vec_len (name));
14371   clib_memcpy (mp->data, data, vec_len (data));
14372   vec_free (name);
14373   vec_free (data);
14374
14375   S (mp);
14376   W (ret);
14377   return ret;
14378 }
14379
14380 static int
14381 api_ikev2_profile_set_id (vat_main_t * vam)
14382 {
14383   unformat_input_t *i = vam->input;
14384   vl_api_ikev2_profile_set_id_t *mp;
14385   u8 *name = 0;
14386   u8 *data = 0;
14387   u8 is_local = 0;
14388   u32 id_type = 0;
14389   ip4_address_t ip4;
14390   int ret;
14391
14392   const char *valid_chars = "a-zA-Z0-9_";
14393
14394   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14395     {
14396       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14397         vec_add1 (name, 0);
14398       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
14399         ;
14400       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
14401         {
14402           data = vec_new (u8, 4);
14403           clib_memcpy (data, ip4.as_u8, 4);
14404         }
14405       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
14406         ;
14407       else if (unformat (i, "id_data %v", &data))
14408         ;
14409       else if (unformat (i, "local"))
14410         is_local = 1;
14411       else if (unformat (i, "remote"))
14412         is_local = 0;
14413       else
14414         {
14415           errmsg ("parse error '%U'", format_unformat_error, i);
14416           return -99;
14417         }
14418     }
14419
14420   if (!vec_len (name))
14421     {
14422       errmsg ("profile name must be specified");
14423       return -99;
14424     }
14425
14426   if (vec_len (name) > 64)
14427     {
14428       errmsg ("profile name too long");
14429       return -99;
14430     }
14431
14432   if (!vec_len (data))
14433     {
14434       errmsg ("id_data must be specified");
14435       return -99;
14436     }
14437
14438   if (!id_type)
14439     {
14440       errmsg ("id_type must be specified");
14441       return -99;
14442     }
14443
14444   M (IKEV2_PROFILE_SET_ID, mp);
14445
14446   mp->is_local = is_local;
14447   mp->id_type = (u8) id_type;
14448   mp->data_len = vec_len (data);
14449   clib_memcpy (mp->name, name, vec_len (name));
14450   clib_memcpy (mp->data, data, vec_len (data));
14451   vec_free (name);
14452   vec_free (data);
14453
14454   S (mp);
14455   W (ret);
14456   return ret;
14457 }
14458
14459 static int
14460 api_ikev2_profile_set_ts (vat_main_t * vam)
14461 {
14462   unformat_input_t *i = vam->input;
14463   vl_api_ikev2_profile_set_ts_t *mp;
14464   u8 *name = 0;
14465   u8 is_local = 0;
14466   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
14467   ip4_address_t start_addr, end_addr;
14468
14469   const char *valid_chars = "a-zA-Z0-9_";
14470   int ret;
14471
14472   start_addr.as_u32 = 0;
14473   end_addr.as_u32 = (u32) ~ 0;
14474
14475   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14476     {
14477       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14478         vec_add1 (name, 0);
14479       else if (unformat (i, "protocol %d", &proto))
14480         ;
14481       else if (unformat (i, "start_port %d", &start_port))
14482         ;
14483       else if (unformat (i, "end_port %d", &end_port))
14484         ;
14485       else
14486         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
14487         ;
14488       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
14489         ;
14490       else if (unformat (i, "local"))
14491         is_local = 1;
14492       else if (unformat (i, "remote"))
14493         is_local = 0;
14494       else
14495         {
14496           errmsg ("parse error '%U'", format_unformat_error, i);
14497           return -99;
14498         }
14499     }
14500
14501   if (!vec_len (name))
14502     {
14503       errmsg ("profile name must be specified");
14504       return -99;
14505     }
14506
14507   if (vec_len (name) > 64)
14508     {
14509       errmsg ("profile name too long");
14510       return -99;
14511     }
14512
14513   M (IKEV2_PROFILE_SET_TS, mp);
14514
14515   mp->is_local = is_local;
14516   mp->proto = (u8) proto;
14517   mp->start_port = (u16) start_port;
14518   mp->end_port = (u16) end_port;
14519   mp->start_addr = start_addr.as_u32;
14520   mp->end_addr = end_addr.as_u32;
14521   clib_memcpy (mp->name, name, vec_len (name));
14522   vec_free (name);
14523
14524   S (mp);
14525   W (ret);
14526   return ret;
14527 }
14528
14529 static int
14530 api_ikev2_set_local_key (vat_main_t * vam)
14531 {
14532   unformat_input_t *i = vam->input;
14533   vl_api_ikev2_set_local_key_t *mp;
14534   u8 *file = 0;
14535   int ret;
14536
14537   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14538     {
14539       if (unformat (i, "file %v", &file))
14540         vec_add1 (file, 0);
14541       else
14542         {
14543           errmsg ("parse error '%U'", format_unformat_error, i);
14544           return -99;
14545         }
14546     }
14547
14548   if (!vec_len (file))
14549     {
14550       errmsg ("RSA key file must be specified");
14551       return -99;
14552     }
14553
14554   if (vec_len (file) > 256)
14555     {
14556       errmsg ("file name too long");
14557       return -99;
14558     }
14559
14560   M (IKEV2_SET_LOCAL_KEY, mp);
14561
14562   clib_memcpy (mp->key_file, file, vec_len (file));
14563   vec_free (file);
14564
14565   S (mp);
14566   W (ret);
14567   return ret;
14568 }
14569
14570 static int
14571 api_ikev2_set_responder (vat_main_t * vam)
14572 {
14573   unformat_input_t *i = vam->input;
14574   vl_api_ikev2_set_responder_t *mp;
14575   int ret;
14576   u8 *name = 0;
14577   u32 sw_if_index = ~0;
14578   ip4_address_t address;
14579
14580   const char *valid_chars = "a-zA-Z0-9_";
14581
14582   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14583     {
14584       if (unformat
14585           (i, "%U interface %d address %U", unformat_token, valid_chars,
14586            &name, &sw_if_index, unformat_ip4_address, &address))
14587         vec_add1 (name, 0);
14588       else
14589         {
14590           errmsg ("parse error '%U'", format_unformat_error, i);
14591           return -99;
14592         }
14593     }
14594
14595   if (!vec_len (name))
14596     {
14597       errmsg ("profile name must be specified");
14598       return -99;
14599     }
14600
14601   if (vec_len (name) > 64)
14602     {
14603       errmsg ("profile name too long");
14604       return -99;
14605     }
14606
14607   M (IKEV2_SET_RESPONDER, mp);
14608
14609   clib_memcpy (mp->name, name, vec_len (name));
14610   vec_free (name);
14611
14612   mp->sw_if_index = sw_if_index;
14613   clib_memcpy (mp->address, &address, sizeof (address));
14614
14615   S (mp);
14616   W (ret);
14617   return ret;
14618 }
14619
14620 static int
14621 api_ikev2_set_ike_transforms (vat_main_t * vam)
14622 {
14623   unformat_input_t *i = vam->input;
14624   vl_api_ikev2_set_ike_transforms_t *mp;
14625   int ret;
14626   u8 *name = 0;
14627   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
14628
14629   const char *valid_chars = "a-zA-Z0-9_";
14630
14631   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14632     {
14633       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
14634                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
14635         vec_add1 (name, 0);
14636       else
14637         {
14638           errmsg ("parse error '%U'", format_unformat_error, i);
14639           return -99;
14640         }
14641     }
14642
14643   if (!vec_len (name))
14644     {
14645       errmsg ("profile name must be specified");
14646       return -99;
14647     }
14648
14649   if (vec_len (name) > 64)
14650     {
14651       errmsg ("profile name too long");
14652       return -99;
14653     }
14654
14655   M (IKEV2_SET_IKE_TRANSFORMS, mp);
14656
14657   clib_memcpy (mp->name, name, vec_len (name));
14658   vec_free (name);
14659   mp->crypto_alg = crypto_alg;
14660   mp->crypto_key_size = crypto_key_size;
14661   mp->integ_alg = integ_alg;
14662   mp->dh_group = dh_group;
14663
14664   S (mp);
14665   W (ret);
14666   return ret;
14667 }
14668
14669
14670 static int
14671 api_ikev2_set_esp_transforms (vat_main_t * vam)
14672 {
14673   unformat_input_t *i = vam->input;
14674   vl_api_ikev2_set_esp_transforms_t *mp;
14675   int ret;
14676   u8 *name = 0;
14677   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
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 (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
14684                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
14685         vec_add1 (name, 0);
14686       else
14687         {
14688           errmsg ("parse error '%U'", format_unformat_error, i);
14689           return -99;
14690         }
14691     }
14692
14693   if (!vec_len (name))
14694     {
14695       errmsg ("profile name must be specified");
14696       return -99;
14697     }
14698
14699   if (vec_len (name) > 64)
14700     {
14701       errmsg ("profile name too long");
14702       return -99;
14703     }
14704
14705   M (IKEV2_SET_ESP_TRANSFORMS, mp);
14706
14707   clib_memcpy (mp->name, name, vec_len (name));
14708   vec_free (name);
14709   mp->crypto_alg = crypto_alg;
14710   mp->crypto_key_size = crypto_key_size;
14711   mp->integ_alg = integ_alg;
14712   mp->dh_group = dh_group;
14713
14714   S (mp);
14715   W (ret);
14716   return ret;
14717 }
14718
14719 static int
14720 api_ikev2_set_sa_lifetime (vat_main_t * vam)
14721 {
14722   unformat_input_t *i = vam->input;
14723   vl_api_ikev2_set_sa_lifetime_t *mp;
14724   int ret;
14725   u8 *name = 0;
14726   u64 lifetime, lifetime_maxdata;
14727   u32 lifetime_jitter, handover;
14728
14729   const char *valid_chars = "a-zA-Z0-9_";
14730
14731   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14732     {
14733       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
14734                     &lifetime, &lifetime_jitter, &handover,
14735                     &lifetime_maxdata))
14736         vec_add1 (name, 0);
14737       else
14738         {
14739           errmsg ("parse error '%U'", format_unformat_error, i);
14740           return -99;
14741         }
14742     }
14743
14744   if (!vec_len (name))
14745     {
14746       errmsg ("profile name must be specified");
14747       return -99;
14748     }
14749
14750   if (vec_len (name) > 64)
14751     {
14752       errmsg ("profile name too long");
14753       return -99;
14754     }
14755
14756   M (IKEV2_SET_SA_LIFETIME, mp);
14757
14758   clib_memcpy (mp->name, name, vec_len (name));
14759   vec_free (name);
14760   mp->lifetime = lifetime;
14761   mp->lifetime_jitter = lifetime_jitter;
14762   mp->handover = handover;
14763   mp->lifetime_maxdata = lifetime_maxdata;
14764
14765   S (mp);
14766   W (ret);
14767   return ret;
14768 }
14769
14770 static int
14771 api_ikev2_initiate_sa_init (vat_main_t * vam)
14772 {
14773   unformat_input_t *i = vam->input;
14774   vl_api_ikev2_initiate_sa_init_t *mp;
14775   int ret;
14776   u8 *name = 0;
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", unformat_token, valid_chars, &name))
14783         vec_add1 (name, 0);
14784       else
14785         {
14786           errmsg ("parse error '%U'", format_unformat_error, i);
14787           return -99;
14788         }
14789     }
14790
14791   if (!vec_len (name))
14792     {
14793       errmsg ("profile name must be specified");
14794       return -99;
14795     }
14796
14797   if (vec_len (name) > 64)
14798     {
14799       errmsg ("profile name too long");
14800       return -99;
14801     }
14802
14803   M (IKEV2_INITIATE_SA_INIT, mp);
14804
14805   clib_memcpy (mp->name, name, vec_len (name));
14806   vec_free (name);
14807
14808   S (mp);
14809   W (ret);
14810   return ret;
14811 }
14812
14813 static int
14814 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
14815 {
14816   unformat_input_t *i = vam->input;
14817   vl_api_ikev2_initiate_del_ike_sa_t *mp;
14818   int ret;
14819   u64 ispi;
14820
14821
14822   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14823     {
14824       if (unformat (i, "%lx", &ispi))
14825         ;
14826       else
14827         {
14828           errmsg ("parse error '%U'", format_unformat_error, i);
14829           return -99;
14830         }
14831     }
14832
14833   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
14834
14835   mp->ispi = ispi;
14836
14837   S (mp);
14838   W (ret);
14839   return ret;
14840 }
14841
14842 static int
14843 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
14844 {
14845   unformat_input_t *i = vam->input;
14846   vl_api_ikev2_initiate_del_child_sa_t *mp;
14847   int ret;
14848   u32 ispi;
14849
14850
14851   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14852     {
14853       if (unformat (i, "%x", &ispi))
14854         ;
14855       else
14856         {
14857           errmsg ("parse error '%U'", format_unformat_error, i);
14858           return -99;
14859         }
14860     }
14861
14862   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
14863
14864   mp->ispi = ispi;
14865
14866   S (mp);
14867   W (ret);
14868   return ret;
14869 }
14870
14871 static int
14872 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
14873 {
14874   unformat_input_t *i = vam->input;
14875   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
14876   int ret;
14877   u32 ispi;
14878
14879
14880   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14881     {
14882       if (unformat (i, "%x", &ispi))
14883         ;
14884       else
14885         {
14886           errmsg ("parse error '%U'", format_unformat_error, i);
14887           return -99;
14888         }
14889     }
14890
14891   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
14892
14893   mp->ispi = ispi;
14894
14895   S (mp);
14896   W (ret);
14897   return ret;
14898 }
14899
14900 /*
14901  * MAP
14902  */
14903 static int
14904 api_map_add_domain (vat_main_t * vam)
14905 {
14906   unformat_input_t *i = vam->input;
14907   vl_api_map_add_domain_t *mp;
14908
14909   ip4_address_t ip4_prefix;
14910   ip6_address_t ip6_prefix;
14911   ip6_address_t ip6_src;
14912   u32 num_m_args = 0;
14913   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
14914     0, psid_length = 0;
14915   u8 is_translation = 0;
14916   u32 mtu = 0;
14917   u32 ip6_src_len = 128;
14918   int ret;
14919
14920   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14921     {
14922       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
14923                     &ip4_prefix, &ip4_prefix_len))
14924         num_m_args++;
14925       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
14926                          &ip6_prefix, &ip6_prefix_len))
14927         num_m_args++;
14928       else
14929         if (unformat
14930             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
14931              &ip6_src_len))
14932         num_m_args++;
14933       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
14934         num_m_args++;
14935       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
14936         num_m_args++;
14937       else if (unformat (i, "psid-offset %d", &psid_offset))
14938         num_m_args++;
14939       else if (unformat (i, "psid-len %d", &psid_length))
14940         num_m_args++;
14941       else if (unformat (i, "mtu %d", &mtu))
14942         num_m_args++;
14943       else if (unformat (i, "map-t"))
14944         is_translation = 1;
14945       else
14946         {
14947           clib_warning ("parse error '%U'", format_unformat_error, i);
14948           return -99;
14949         }
14950     }
14951
14952   if (num_m_args < 3)
14953     {
14954       errmsg ("mandatory argument(s) missing");
14955       return -99;
14956     }
14957
14958   /* Construct the API message */
14959   M (MAP_ADD_DOMAIN, mp);
14960
14961   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
14962   mp->ip4_prefix_len = ip4_prefix_len;
14963
14964   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
14965   mp->ip6_prefix_len = ip6_prefix_len;
14966
14967   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
14968   mp->ip6_src_prefix_len = ip6_src_len;
14969
14970   mp->ea_bits_len = ea_bits_len;
14971   mp->psid_offset = psid_offset;
14972   mp->psid_length = psid_length;
14973   mp->is_translation = is_translation;
14974   mp->mtu = htons (mtu);
14975
14976   /* send it... */
14977   S (mp);
14978
14979   /* Wait for a reply, return good/bad news  */
14980   W (ret);
14981   return ret;
14982 }
14983
14984 static int
14985 api_map_del_domain (vat_main_t * vam)
14986 {
14987   unformat_input_t *i = vam->input;
14988   vl_api_map_del_domain_t *mp;
14989
14990   u32 num_m_args = 0;
14991   u32 index;
14992   int ret;
14993
14994   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14995     {
14996       if (unformat (i, "index %d", &index))
14997         num_m_args++;
14998       else
14999         {
15000           clib_warning ("parse error '%U'", format_unformat_error, i);
15001           return -99;
15002         }
15003     }
15004
15005   if (num_m_args != 1)
15006     {
15007       errmsg ("mandatory argument(s) missing");
15008       return -99;
15009     }
15010
15011   /* Construct the API message */
15012   M (MAP_DEL_DOMAIN, mp);
15013
15014   mp->index = ntohl (index);
15015
15016   /* send it... */
15017   S (mp);
15018
15019   /* Wait for a reply, return good/bad news  */
15020   W (ret);
15021   return ret;
15022 }
15023
15024 static int
15025 api_map_add_del_rule (vat_main_t * vam)
15026 {
15027   unformat_input_t *i = vam->input;
15028   vl_api_map_add_del_rule_t *mp;
15029   u8 is_add = 1;
15030   ip6_address_t ip6_dst;
15031   u32 num_m_args = 0, index, psid = 0;
15032   int ret;
15033
15034   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15035     {
15036       if (unformat (i, "index %d", &index))
15037         num_m_args++;
15038       else if (unformat (i, "psid %d", &psid))
15039         num_m_args++;
15040       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
15041         num_m_args++;
15042       else if (unformat (i, "del"))
15043         {
15044           is_add = 0;
15045         }
15046       else
15047         {
15048           clib_warning ("parse error '%U'", format_unformat_error, i);
15049           return -99;
15050         }
15051     }
15052
15053   /* Construct the API message */
15054   M (MAP_ADD_DEL_RULE, mp);
15055
15056   mp->index = ntohl (index);
15057   mp->is_add = is_add;
15058   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
15059   mp->psid = ntohs (psid);
15060
15061   /* send it... */
15062   S (mp);
15063
15064   /* Wait for a reply, return good/bad news  */
15065   W (ret);
15066   return ret;
15067 }
15068
15069 static int
15070 api_map_domain_dump (vat_main_t * vam)
15071 {
15072   vl_api_map_domain_dump_t *mp;
15073   vl_api_control_ping_t *mp_ping;
15074   int ret;
15075
15076   /* Construct the API message */
15077   M (MAP_DOMAIN_DUMP, mp);
15078
15079   /* send it... */
15080   S (mp);
15081
15082   /* Use a control ping for synchronization */
15083   MPING (CONTROL_PING, mp_ping);
15084   S (mp_ping);
15085
15086   W (ret);
15087   return ret;
15088 }
15089
15090 static int
15091 api_map_rule_dump (vat_main_t * vam)
15092 {
15093   unformat_input_t *i = vam->input;
15094   vl_api_map_rule_dump_t *mp;
15095   vl_api_control_ping_t *mp_ping;
15096   u32 domain_index = ~0;
15097   int ret;
15098
15099   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15100     {
15101       if (unformat (i, "index %u", &domain_index))
15102         ;
15103       else
15104         break;
15105     }
15106
15107   if (domain_index == ~0)
15108     {
15109       clib_warning ("parse error: domain index expected");
15110       return -99;
15111     }
15112
15113   /* Construct the API message */
15114   M (MAP_RULE_DUMP, mp);
15115
15116   mp->domain_index = htonl (domain_index);
15117
15118   /* send it... */
15119   S (mp);
15120
15121   /* Use a control ping for synchronization */
15122   MPING (CONTROL_PING, mp_ping);
15123   S (mp_ping);
15124
15125   W (ret);
15126   return ret;
15127 }
15128
15129 static void vl_api_map_add_domain_reply_t_handler
15130   (vl_api_map_add_domain_reply_t * mp)
15131 {
15132   vat_main_t *vam = &vat_main;
15133   i32 retval = ntohl (mp->retval);
15134
15135   if (vam->async_mode)
15136     {
15137       vam->async_errors += (retval < 0);
15138     }
15139   else
15140     {
15141       vam->retval = retval;
15142       vam->result_ready = 1;
15143     }
15144 }
15145
15146 static void vl_api_map_add_domain_reply_t_handler_json
15147   (vl_api_map_add_domain_reply_t * mp)
15148 {
15149   vat_main_t *vam = &vat_main;
15150   vat_json_node_t node;
15151
15152   vat_json_init_object (&node);
15153   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
15154   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
15155
15156   vat_json_print (vam->ofp, &node);
15157   vat_json_free (&node);
15158
15159   vam->retval = ntohl (mp->retval);
15160   vam->result_ready = 1;
15161 }
15162
15163 static int
15164 api_get_first_msg_id (vat_main_t * vam)
15165 {
15166   vl_api_get_first_msg_id_t *mp;
15167   unformat_input_t *i = vam->input;
15168   u8 *name;
15169   u8 name_set = 0;
15170   int ret;
15171
15172   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15173     {
15174       if (unformat (i, "client %s", &name))
15175         name_set = 1;
15176       else
15177         break;
15178     }
15179
15180   if (name_set == 0)
15181     {
15182       errmsg ("missing client name");
15183       return -99;
15184     }
15185   vec_add1 (name, 0);
15186
15187   if (vec_len (name) > 63)
15188     {
15189       errmsg ("client name too long");
15190       return -99;
15191     }
15192
15193   M (GET_FIRST_MSG_ID, mp);
15194   clib_memcpy (mp->name, name, vec_len (name));
15195   S (mp);
15196   W (ret);
15197   return ret;
15198 }
15199
15200 static int
15201 api_cop_interface_enable_disable (vat_main_t * vam)
15202 {
15203   unformat_input_t *line_input = vam->input;
15204   vl_api_cop_interface_enable_disable_t *mp;
15205   u32 sw_if_index = ~0;
15206   u8 enable_disable = 1;
15207   int ret;
15208
15209   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15210     {
15211       if (unformat (line_input, "disable"))
15212         enable_disable = 0;
15213       if (unformat (line_input, "enable"))
15214         enable_disable = 1;
15215       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15216                          vam, &sw_if_index))
15217         ;
15218       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15219         ;
15220       else
15221         break;
15222     }
15223
15224   if (sw_if_index == ~0)
15225     {
15226       errmsg ("missing interface name or sw_if_index");
15227       return -99;
15228     }
15229
15230   /* Construct the API message */
15231   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15232   mp->sw_if_index = ntohl (sw_if_index);
15233   mp->enable_disable = enable_disable;
15234
15235   /* send it... */
15236   S (mp);
15237   /* Wait for the reply */
15238   W (ret);
15239   return ret;
15240 }
15241
15242 static int
15243 api_cop_whitelist_enable_disable (vat_main_t * vam)
15244 {
15245   unformat_input_t *line_input = vam->input;
15246   vl_api_cop_whitelist_enable_disable_t *mp;
15247   u32 sw_if_index = ~0;
15248   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15249   u32 fib_id = 0;
15250   int ret;
15251
15252   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15253     {
15254       if (unformat (line_input, "ip4"))
15255         ip4 = 1;
15256       else if (unformat (line_input, "ip6"))
15257         ip6 = 1;
15258       else if (unformat (line_input, "default"))
15259         default_cop = 1;
15260       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15261                          vam, &sw_if_index))
15262         ;
15263       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15264         ;
15265       else if (unformat (line_input, "fib-id %d", &fib_id))
15266         ;
15267       else
15268         break;
15269     }
15270
15271   if (sw_if_index == ~0)
15272     {
15273       errmsg ("missing interface name or sw_if_index");
15274       return -99;
15275     }
15276
15277   /* Construct the API message */
15278   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15279   mp->sw_if_index = ntohl (sw_if_index);
15280   mp->fib_id = ntohl (fib_id);
15281   mp->ip4 = ip4;
15282   mp->ip6 = ip6;
15283   mp->default_cop = default_cop;
15284
15285   /* send it... */
15286   S (mp);
15287   /* Wait for the reply */
15288   W (ret);
15289   return ret;
15290 }
15291
15292 static int
15293 api_get_node_graph (vat_main_t * vam)
15294 {
15295   vl_api_get_node_graph_t *mp;
15296   int ret;
15297
15298   M (GET_NODE_GRAPH, mp);
15299
15300   /* send it... */
15301   S (mp);
15302   /* Wait for the reply */
15303   W (ret);
15304   return ret;
15305 }
15306
15307 /* *INDENT-OFF* */
15308 /** Used for parsing LISP eids */
15309 typedef CLIB_PACKED(struct{
15310   u8 addr[16];   /**< eid address */
15311   u32 len;       /**< prefix length if IP */
15312   u8 type;      /**< type of eid */
15313 }) lisp_eid_vat_t;
15314 /* *INDENT-ON* */
15315
15316 static uword
15317 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15318 {
15319   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15320
15321   memset (a, 0, sizeof (a[0]));
15322
15323   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15324     {
15325       a->type = 0;              /* ipv4 type */
15326     }
15327   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15328     {
15329       a->type = 1;              /* ipv6 type */
15330     }
15331   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15332     {
15333       a->type = 2;              /* mac type */
15334     }
15335   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15336     {
15337       a->type = 3;              /* NSH type */
15338       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15339       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15340     }
15341   else
15342     {
15343       return 0;
15344     }
15345
15346   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15347     {
15348       return 0;
15349     }
15350
15351   return 1;
15352 }
15353
15354 static int
15355 lisp_eid_size_vat (u8 type)
15356 {
15357   switch (type)
15358     {
15359     case 0:
15360       return 4;
15361     case 1:
15362       return 16;
15363     case 2:
15364       return 6;
15365     case 3:
15366       return 5;
15367     }
15368   return 0;
15369 }
15370
15371 static void
15372 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15373 {
15374   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15375 }
15376
15377 static int
15378 api_one_add_del_locator_set (vat_main_t * vam)
15379 {
15380   unformat_input_t *input = vam->input;
15381   vl_api_one_add_del_locator_set_t *mp;
15382   u8 is_add = 1;
15383   u8 *locator_set_name = NULL;
15384   u8 locator_set_name_set = 0;
15385   vl_api_local_locator_t locator, *locators = 0;
15386   u32 sw_if_index, priority, weight;
15387   u32 data_len = 0;
15388
15389   int ret;
15390   /* Parse args required to build the message */
15391   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15392     {
15393       if (unformat (input, "del"))
15394         {
15395           is_add = 0;
15396         }
15397       else if (unformat (input, "locator-set %s", &locator_set_name))
15398         {
15399           locator_set_name_set = 1;
15400         }
15401       else if (unformat (input, "sw_if_index %u p %u w %u",
15402                          &sw_if_index, &priority, &weight))
15403         {
15404           locator.sw_if_index = htonl (sw_if_index);
15405           locator.priority = priority;
15406           locator.weight = weight;
15407           vec_add1 (locators, locator);
15408         }
15409       else
15410         if (unformat
15411             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15412              &sw_if_index, &priority, &weight))
15413         {
15414           locator.sw_if_index = htonl (sw_if_index);
15415           locator.priority = priority;
15416           locator.weight = weight;
15417           vec_add1 (locators, locator);
15418         }
15419       else
15420         break;
15421     }
15422
15423   if (locator_set_name_set == 0)
15424     {
15425       errmsg ("missing locator-set name");
15426       vec_free (locators);
15427       return -99;
15428     }
15429
15430   if (vec_len (locator_set_name) > 64)
15431     {
15432       errmsg ("locator-set name too long");
15433       vec_free (locator_set_name);
15434       vec_free (locators);
15435       return -99;
15436     }
15437   vec_add1 (locator_set_name, 0);
15438
15439   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15440
15441   /* Construct the API message */
15442   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15443
15444   mp->is_add = is_add;
15445   clib_memcpy (mp->locator_set_name, locator_set_name,
15446                vec_len (locator_set_name));
15447   vec_free (locator_set_name);
15448
15449   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15450   if (locators)
15451     clib_memcpy (mp->locators, locators, data_len);
15452   vec_free (locators);
15453
15454   /* send it... */
15455   S (mp);
15456
15457   /* Wait for a reply... */
15458   W (ret);
15459   return ret;
15460 }
15461
15462 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15463
15464 static int
15465 api_one_add_del_locator (vat_main_t * vam)
15466 {
15467   unformat_input_t *input = vam->input;
15468   vl_api_one_add_del_locator_t *mp;
15469   u32 tmp_if_index = ~0;
15470   u32 sw_if_index = ~0;
15471   u8 sw_if_index_set = 0;
15472   u8 sw_if_index_if_name_set = 0;
15473   u32 priority = ~0;
15474   u8 priority_set = 0;
15475   u32 weight = ~0;
15476   u8 weight_set = 0;
15477   u8 is_add = 1;
15478   u8 *locator_set_name = NULL;
15479   u8 locator_set_name_set = 0;
15480   int ret;
15481
15482   /* Parse args required to build the message */
15483   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15484     {
15485       if (unformat (input, "del"))
15486         {
15487           is_add = 0;
15488         }
15489       else if (unformat (input, "locator-set %s", &locator_set_name))
15490         {
15491           locator_set_name_set = 1;
15492         }
15493       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15494                          &tmp_if_index))
15495         {
15496           sw_if_index_if_name_set = 1;
15497           sw_if_index = tmp_if_index;
15498         }
15499       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15500         {
15501           sw_if_index_set = 1;
15502           sw_if_index = tmp_if_index;
15503         }
15504       else if (unformat (input, "p %d", &priority))
15505         {
15506           priority_set = 1;
15507         }
15508       else if (unformat (input, "w %d", &weight))
15509         {
15510           weight_set = 1;
15511         }
15512       else
15513         break;
15514     }
15515
15516   if (locator_set_name_set == 0)
15517     {
15518       errmsg ("missing locator-set name");
15519       return -99;
15520     }
15521
15522   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15523     {
15524       errmsg ("missing sw_if_index");
15525       vec_free (locator_set_name);
15526       return -99;
15527     }
15528
15529   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15530     {
15531       errmsg ("cannot use both params interface name and sw_if_index");
15532       vec_free (locator_set_name);
15533       return -99;
15534     }
15535
15536   if (priority_set == 0)
15537     {
15538       errmsg ("missing locator-set priority");
15539       vec_free (locator_set_name);
15540       return -99;
15541     }
15542
15543   if (weight_set == 0)
15544     {
15545       errmsg ("missing locator-set weight");
15546       vec_free (locator_set_name);
15547       return -99;
15548     }
15549
15550   if (vec_len (locator_set_name) > 64)
15551     {
15552       errmsg ("locator-set name too long");
15553       vec_free (locator_set_name);
15554       return -99;
15555     }
15556   vec_add1 (locator_set_name, 0);
15557
15558   /* Construct the API message */
15559   M (ONE_ADD_DEL_LOCATOR, mp);
15560
15561   mp->is_add = is_add;
15562   mp->sw_if_index = ntohl (sw_if_index);
15563   mp->priority = priority;
15564   mp->weight = weight;
15565   clib_memcpy (mp->locator_set_name, locator_set_name,
15566                vec_len (locator_set_name));
15567   vec_free (locator_set_name);
15568
15569   /* send it... */
15570   S (mp);
15571
15572   /* Wait for a reply... */
15573   W (ret);
15574   return ret;
15575 }
15576
15577 #define api_lisp_add_del_locator api_one_add_del_locator
15578
15579 uword
15580 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15581 {
15582   u32 *key_id = va_arg (*args, u32 *);
15583   u8 *s = 0;
15584
15585   if (unformat (input, "%s", &s))
15586     {
15587       if (!strcmp ((char *) s, "sha1"))
15588         key_id[0] = HMAC_SHA_1_96;
15589       else if (!strcmp ((char *) s, "sha256"))
15590         key_id[0] = HMAC_SHA_256_128;
15591       else
15592         {
15593           clib_warning ("invalid key_id: '%s'", s);
15594           key_id[0] = HMAC_NO_KEY;
15595         }
15596     }
15597   else
15598     return 0;
15599
15600   vec_free (s);
15601   return 1;
15602 }
15603
15604 static int
15605 api_one_add_del_local_eid (vat_main_t * vam)
15606 {
15607   unformat_input_t *input = vam->input;
15608   vl_api_one_add_del_local_eid_t *mp;
15609   u8 is_add = 1;
15610   u8 eid_set = 0;
15611   lisp_eid_vat_t _eid, *eid = &_eid;
15612   u8 *locator_set_name = 0;
15613   u8 locator_set_name_set = 0;
15614   u32 vni = 0;
15615   u16 key_id = 0;
15616   u8 *key = 0;
15617   int ret;
15618
15619   /* Parse args required to build the message */
15620   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15621     {
15622       if (unformat (input, "del"))
15623         {
15624           is_add = 0;
15625         }
15626       else if (unformat (input, "vni %d", &vni))
15627         {
15628           ;
15629         }
15630       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15631         {
15632           eid_set = 1;
15633         }
15634       else if (unformat (input, "locator-set %s", &locator_set_name))
15635         {
15636           locator_set_name_set = 1;
15637         }
15638       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15639         ;
15640       else if (unformat (input, "secret-key %_%v%_", &key))
15641         ;
15642       else
15643         break;
15644     }
15645
15646   if (locator_set_name_set == 0)
15647     {
15648       errmsg ("missing locator-set name");
15649       return -99;
15650     }
15651
15652   if (0 == eid_set)
15653     {
15654       errmsg ("EID address not set!");
15655       vec_free (locator_set_name);
15656       return -99;
15657     }
15658
15659   if (key && (0 == key_id))
15660     {
15661       errmsg ("invalid key_id!");
15662       return -99;
15663     }
15664
15665   if (vec_len (key) > 64)
15666     {
15667       errmsg ("key too long");
15668       vec_free (key);
15669       return -99;
15670     }
15671
15672   if (vec_len (locator_set_name) > 64)
15673     {
15674       errmsg ("locator-set name too long");
15675       vec_free (locator_set_name);
15676       return -99;
15677     }
15678   vec_add1 (locator_set_name, 0);
15679
15680   /* Construct the API message */
15681   M (ONE_ADD_DEL_LOCAL_EID, mp);
15682
15683   mp->is_add = is_add;
15684   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15685   mp->eid_type = eid->type;
15686   mp->prefix_len = eid->len;
15687   mp->vni = clib_host_to_net_u32 (vni);
15688   mp->key_id = clib_host_to_net_u16 (key_id);
15689   clib_memcpy (mp->locator_set_name, locator_set_name,
15690                vec_len (locator_set_name));
15691   clib_memcpy (mp->key, key, vec_len (key));
15692
15693   vec_free (locator_set_name);
15694   vec_free (key);
15695
15696   /* send it... */
15697   S (mp);
15698
15699   /* Wait for a reply... */
15700   W (ret);
15701   return ret;
15702 }
15703
15704 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15705
15706 static int
15707 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15708 {
15709   u32 dp_table = 0, vni = 0;;
15710   unformat_input_t *input = vam->input;
15711   vl_api_gpe_add_del_fwd_entry_t *mp;
15712   u8 is_add = 1;
15713   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15714   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15715   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15716   u32 action = ~0, w;
15717   ip4_address_t rmt_rloc4, lcl_rloc4;
15718   ip6_address_t rmt_rloc6, lcl_rloc6;
15719   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15720   int ret;
15721
15722   memset (&rloc, 0, sizeof (rloc));
15723
15724   /* Parse args required to build the message */
15725   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15726     {
15727       if (unformat (input, "del"))
15728         is_add = 0;
15729       else if (unformat (input, "add"))
15730         is_add = 1;
15731       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15732         {
15733           rmt_eid_set = 1;
15734         }
15735       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15736         {
15737           lcl_eid_set = 1;
15738         }
15739       else if (unformat (input, "vrf %d", &dp_table))
15740         ;
15741       else if (unformat (input, "bd %d", &dp_table))
15742         ;
15743       else if (unformat (input, "vni %d", &vni))
15744         ;
15745       else if (unformat (input, "w %d", &w))
15746         {
15747           if (!curr_rloc)
15748             {
15749               errmsg ("No RLOC configured for setting priority/weight!");
15750               return -99;
15751             }
15752           curr_rloc->weight = w;
15753         }
15754       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15755                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15756         {
15757           rloc.is_ip4 = 1;
15758
15759           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15760           rloc.weight = 0;
15761           vec_add1 (lcl_locs, rloc);
15762
15763           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15764           vec_add1 (rmt_locs, rloc);
15765           /* weight saved in rmt loc */
15766           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15767         }
15768       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15769                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15770         {
15771           rloc.is_ip4 = 0;
15772           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15773           rloc.weight = 0;
15774           vec_add1 (lcl_locs, rloc);
15775
15776           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15777           vec_add1 (rmt_locs, rloc);
15778           /* weight saved in rmt loc */
15779           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15780         }
15781       else if (unformat (input, "action %d", &action))
15782         {
15783           ;
15784         }
15785       else
15786         {
15787           clib_warning ("parse error '%U'", format_unformat_error, input);
15788           return -99;
15789         }
15790     }
15791
15792   if (!rmt_eid_set)
15793     {
15794       errmsg ("remote eid addresses not set");
15795       return -99;
15796     }
15797
15798   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15799     {
15800       errmsg ("eid types don't match");
15801       return -99;
15802     }
15803
15804   if (0 == rmt_locs && (u32) ~ 0 == action)
15805     {
15806       errmsg ("action not set for negative mapping");
15807       return -99;
15808     }
15809
15810   /* Construct the API message */
15811   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15812       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15813
15814   mp->is_add = is_add;
15815   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15816   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15817   mp->eid_type = rmt_eid->type;
15818   mp->dp_table = clib_host_to_net_u32 (dp_table);
15819   mp->vni = clib_host_to_net_u32 (vni);
15820   mp->rmt_len = rmt_eid->len;
15821   mp->lcl_len = lcl_eid->len;
15822   mp->action = action;
15823
15824   if (0 != rmt_locs && 0 != lcl_locs)
15825     {
15826       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15827       clib_memcpy (mp->locs, lcl_locs,
15828                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15829
15830       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15831       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15832                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15833     }
15834   vec_free (lcl_locs);
15835   vec_free (rmt_locs);
15836
15837   /* send it... */
15838   S (mp);
15839
15840   /* Wait for a reply... */
15841   W (ret);
15842   return ret;
15843 }
15844
15845 static int
15846 api_one_add_del_map_server (vat_main_t * vam)
15847 {
15848   unformat_input_t *input = vam->input;
15849   vl_api_one_add_del_map_server_t *mp;
15850   u8 is_add = 1;
15851   u8 ipv4_set = 0;
15852   u8 ipv6_set = 0;
15853   ip4_address_t ipv4;
15854   ip6_address_t ipv6;
15855   int ret;
15856
15857   /* Parse args required to build the message */
15858   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15859     {
15860       if (unformat (input, "del"))
15861         {
15862           is_add = 0;
15863         }
15864       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15865         {
15866           ipv4_set = 1;
15867         }
15868       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15869         {
15870           ipv6_set = 1;
15871         }
15872       else
15873         break;
15874     }
15875
15876   if (ipv4_set && ipv6_set)
15877     {
15878       errmsg ("both eid v4 and v6 addresses set");
15879       return -99;
15880     }
15881
15882   if (!ipv4_set && !ipv6_set)
15883     {
15884       errmsg ("eid addresses not set");
15885       return -99;
15886     }
15887
15888   /* Construct the API message */
15889   M (ONE_ADD_DEL_MAP_SERVER, mp);
15890
15891   mp->is_add = is_add;
15892   if (ipv6_set)
15893     {
15894       mp->is_ipv6 = 1;
15895       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15896     }
15897   else
15898     {
15899       mp->is_ipv6 = 0;
15900       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15901     }
15902
15903   /* send it... */
15904   S (mp);
15905
15906   /* Wait for a reply... */
15907   W (ret);
15908   return ret;
15909 }
15910
15911 #define api_lisp_add_del_map_server api_one_add_del_map_server
15912
15913 static int
15914 api_one_add_del_map_resolver (vat_main_t * vam)
15915 {
15916   unformat_input_t *input = vam->input;
15917   vl_api_one_add_del_map_resolver_t *mp;
15918   u8 is_add = 1;
15919   u8 ipv4_set = 0;
15920   u8 ipv6_set = 0;
15921   ip4_address_t ipv4;
15922   ip6_address_t ipv6;
15923   int ret;
15924
15925   /* Parse args required to build the message */
15926   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15927     {
15928       if (unformat (input, "del"))
15929         {
15930           is_add = 0;
15931         }
15932       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15933         {
15934           ipv4_set = 1;
15935         }
15936       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15937         {
15938           ipv6_set = 1;
15939         }
15940       else
15941         break;
15942     }
15943
15944   if (ipv4_set && ipv6_set)
15945     {
15946       errmsg ("both eid v4 and v6 addresses set");
15947       return -99;
15948     }
15949
15950   if (!ipv4_set && !ipv6_set)
15951     {
15952       errmsg ("eid addresses not set");
15953       return -99;
15954     }
15955
15956   /* Construct the API message */
15957   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
15958
15959   mp->is_add = is_add;
15960   if (ipv6_set)
15961     {
15962       mp->is_ipv6 = 1;
15963       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15964     }
15965   else
15966     {
15967       mp->is_ipv6 = 0;
15968       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15969     }
15970
15971   /* send it... */
15972   S (mp);
15973
15974   /* Wait for a reply... */
15975   W (ret);
15976   return ret;
15977 }
15978
15979 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
15980
15981 static int
15982 api_lisp_gpe_enable_disable (vat_main_t * vam)
15983 {
15984   unformat_input_t *input = vam->input;
15985   vl_api_gpe_enable_disable_t *mp;
15986   u8 is_set = 0;
15987   u8 is_en = 1;
15988   int ret;
15989
15990   /* Parse args required to build the message */
15991   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15992     {
15993       if (unformat (input, "enable"))
15994         {
15995           is_set = 1;
15996           is_en = 1;
15997         }
15998       else if (unformat (input, "disable"))
15999         {
16000           is_set = 1;
16001           is_en = 0;
16002         }
16003       else
16004         break;
16005     }
16006
16007   if (is_set == 0)
16008     {
16009       errmsg ("Value not set");
16010       return -99;
16011     }
16012
16013   /* Construct the API message */
16014   M (GPE_ENABLE_DISABLE, mp);
16015
16016   mp->is_en = is_en;
16017
16018   /* send it... */
16019   S (mp);
16020
16021   /* Wait for a reply... */
16022   W (ret);
16023   return ret;
16024 }
16025
16026 static int
16027 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16028 {
16029   unformat_input_t *input = vam->input;
16030   vl_api_one_rloc_probe_enable_disable_t *mp;
16031   u8 is_set = 0;
16032   u8 is_en = 0;
16033   int ret;
16034
16035   /* Parse args required to build the message */
16036   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16037     {
16038       if (unformat (input, "enable"))
16039         {
16040           is_set = 1;
16041           is_en = 1;
16042         }
16043       else if (unformat (input, "disable"))
16044         is_set = 1;
16045       else
16046         break;
16047     }
16048
16049   if (!is_set)
16050     {
16051       errmsg ("Value not set");
16052       return -99;
16053     }
16054
16055   /* Construct the API message */
16056   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16057
16058   mp->is_enabled = is_en;
16059
16060   /* send it... */
16061   S (mp);
16062
16063   /* Wait for a reply... */
16064   W (ret);
16065   return ret;
16066 }
16067
16068 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16069
16070 static int
16071 api_one_map_register_enable_disable (vat_main_t * vam)
16072 {
16073   unformat_input_t *input = vam->input;
16074   vl_api_one_map_register_enable_disable_t *mp;
16075   u8 is_set = 0;
16076   u8 is_en = 0;
16077   int ret;
16078
16079   /* Parse args required to build the message */
16080   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16081     {
16082       if (unformat (input, "enable"))
16083         {
16084           is_set = 1;
16085           is_en = 1;
16086         }
16087       else if (unformat (input, "disable"))
16088         is_set = 1;
16089       else
16090         break;
16091     }
16092
16093   if (!is_set)
16094     {
16095       errmsg ("Value not set");
16096       return -99;
16097     }
16098
16099   /* Construct the API message */
16100   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16101
16102   mp->is_enabled = is_en;
16103
16104   /* send it... */
16105   S (mp);
16106
16107   /* Wait for a reply... */
16108   W (ret);
16109   return ret;
16110 }
16111
16112 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16113
16114 static int
16115 api_one_enable_disable (vat_main_t * vam)
16116 {
16117   unformat_input_t *input = vam->input;
16118   vl_api_one_enable_disable_t *mp;
16119   u8 is_set = 0;
16120   u8 is_en = 0;
16121   int ret;
16122
16123   /* Parse args required to build the message */
16124   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16125     {
16126       if (unformat (input, "enable"))
16127         {
16128           is_set = 1;
16129           is_en = 1;
16130         }
16131       else if (unformat (input, "disable"))
16132         {
16133           is_set = 1;
16134         }
16135       else
16136         break;
16137     }
16138
16139   if (!is_set)
16140     {
16141       errmsg ("Value not set");
16142       return -99;
16143     }
16144
16145   /* Construct the API message */
16146   M (ONE_ENABLE_DISABLE, mp);
16147
16148   mp->is_en = is_en;
16149
16150   /* send it... */
16151   S (mp);
16152
16153   /* Wait for a reply... */
16154   W (ret);
16155   return ret;
16156 }
16157
16158 #define api_lisp_enable_disable api_one_enable_disable
16159
16160 static int
16161 api_show_one_map_register_state (vat_main_t * vam)
16162 {
16163   vl_api_show_one_map_register_state_t *mp;
16164   int ret;
16165
16166   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16167
16168   /* send */
16169   S (mp);
16170
16171   /* wait for reply */
16172   W (ret);
16173   return ret;
16174 }
16175
16176 #define api_show_lisp_map_register_state api_show_one_map_register_state
16177
16178 static int
16179 api_show_one_rloc_probe_state (vat_main_t * vam)
16180 {
16181   vl_api_show_one_rloc_probe_state_t *mp;
16182   int ret;
16183
16184   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16185
16186   /* send */
16187   S (mp);
16188
16189   /* wait for reply */
16190   W (ret);
16191   return ret;
16192 }
16193
16194 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16195
16196 static int
16197 api_one_add_del_ndp_entry (vat_main_t * vam)
16198 {
16199   vl_api_one_add_del_ndp_entry_t *mp;
16200   unformat_input_t *input = vam->input;
16201   u8 is_add = 1;
16202   u8 mac_set = 0;
16203   u8 bd_set = 0;
16204   u8 ip_set = 0;
16205   u8 mac[6] = { 0, };
16206   u8 ip6[16] = { 0, };
16207   u32 bd = ~0;
16208   int ret;
16209
16210   /* Parse args required to build the message */
16211   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16212     {
16213       if (unformat (input, "del"))
16214         is_add = 0;
16215       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16216         mac_set = 1;
16217       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16218         ip_set = 1;
16219       else if (unformat (input, "bd %d", &bd))
16220         bd_set = 1;
16221       else
16222         {
16223           errmsg ("parse error '%U'", format_unformat_error, input);
16224           return -99;
16225         }
16226     }
16227
16228   if (!bd_set || !ip_set || (!mac_set && is_add))
16229     {
16230       errmsg ("Missing BD, IP or MAC!");
16231       return -99;
16232     }
16233
16234   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16235   mp->is_add = is_add;
16236   clib_memcpy (mp->mac, mac, 6);
16237   mp->bd = clib_host_to_net_u32 (bd);
16238   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16239
16240   /* send */
16241   S (mp);
16242
16243   /* wait for reply */
16244   W (ret);
16245   return ret;
16246 }
16247
16248 static int
16249 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16250 {
16251   vl_api_one_add_del_l2_arp_entry_t *mp;
16252   unformat_input_t *input = vam->input;
16253   u8 is_add = 1;
16254   u8 mac_set = 0;
16255   u8 bd_set = 0;
16256   u8 ip_set = 0;
16257   u8 mac[6] = { 0, };
16258   u32 ip4 = 0, bd = ~0;
16259   int ret;
16260
16261   /* Parse args required to build the message */
16262   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16263     {
16264       if (unformat (input, "del"))
16265         is_add = 0;
16266       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16267         mac_set = 1;
16268       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16269         ip_set = 1;
16270       else if (unformat (input, "bd %d", &bd))
16271         bd_set = 1;
16272       else
16273         {
16274           errmsg ("parse error '%U'", format_unformat_error, input);
16275           return -99;
16276         }
16277     }
16278
16279   if (!bd_set || !ip_set || (!mac_set && is_add))
16280     {
16281       errmsg ("Missing BD, IP or MAC!");
16282       return -99;
16283     }
16284
16285   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16286   mp->is_add = is_add;
16287   clib_memcpy (mp->mac, mac, 6);
16288   mp->bd = clib_host_to_net_u32 (bd);
16289   mp->ip4 = ip4;
16290
16291   /* send */
16292   S (mp);
16293
16294   /* wait for reply */
16295   W (ret);
16296   return ret;
16297 }
16298
16299 static int
16300 api_one_ndp_bd_get (vat_main_t * vam)
16301 {
16302   vl_api_one_ndp_bd_get_t *mp;
16303   int ret;
16304
16305   M (ONE_NDP_BD_GET, mp);
16306
16307   /* send */
16308   S (mp);
16309
16310   /* wait for reply */
16311   W (ret);
16312   return ret;
16313 }
16314
16315 static int
16316 api_one_ndp_entries_get (vat_main_t * vam)
16317 {
16318   vl_api_one_ndp_entries_get_t *mp;
16319   unformat_input_t *input = vam->input;
16320   u8 bd_set = 0;
16321   u32 bd = ~0;
16322   int ret;
16323
16324   /* Parse args required to build the message */
16325   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16326     {
16327       if (unformat (input, "bd %d", &bd))
16328         bd_set = 1;
16329       else
16330         {
16331           errmsg ("parse error '%U'", format_unformat_error, input);
16332           return -99;
16333         }
16334     }
16335
16336   if (!bd_set)
16337     {
16338       errmsg ("Expected bridge domain!");
16339       return -99;
16340     }
16341
16342   M (ONE_NDP_ENTRIES_GET, mp);
16343   mp->bd = clib_host_to_net_u32 (bd);
16344
16345   /* send */
16346   S (mp);
16347
16348   /* wait for reply */
16349   W (ret);
16350   return ret;
16351 }
16352
16353 static int
16354 api_one_l2_arp_bd_get (vat_main_t * vam)
16355 {
16356   vl_api_one_l2_arp_bd_get_t *mp;
16357   int ret;
16358
16359   M (ONE_L2_ARP_BD_GET, mp);
16360
16361   /* send */
16362   S (mp);
16363
16364   /* wait for reply */
16365   W (ret);
16366   return ret;
16367 }
16368
16369 static int
16370 api_one_l2_arp_entries_get (vat_main_t * vam)
16371 {
16372   vl_api_one_l2_arp_entries_get_t *mp;
16373   unformat_input_t *input = vam->input;
16374   u8 bd_set = 0;
16375   u32 bd = ~0;
16376   int ret;
16377
16378   /* Parse args required to build the message */
16379   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16380     {
16381       if (unformat (input, "bd %d", &bd))
16382         bd_set = 1;
16383       else
16384         {
16385           errmsg ("parse error '%U'", format_unformat_error, input);
16386           return -99;
16387         }
16388     }
16389
16390   if (!bd_set)
16391     {
16392       errmsg ("Expected bridge domain!");
16393       return -99;
16394     }
16395
16396   M (ONE_L2_ARP_ENTRIES_GET, mp);
16397   mp->bd = clib_host_to_net_u32 (bd);
16398
16399   /* send */
16400   S (mp);
16401
16402   /* wait for reply */
16403   W (ret);
16404   return ret;
16405 }
16406
16407 static int
16408 api_one_stats_enable_disable (vat_main_t * vam)
16409 {
16410   vl_api_one_stats_enable_disable_t *mp;
16411   unformat_input_t *input = vam->input;
16412   u8 is_set = 0;
16413   u8 is_en = 0;
16414   int ret;
16415
16416   /* Parse args required to build the message */
16417   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16418     {
16419       if (unformat (input, "enable"))
16420         {
16421           is_set = 1;
16422           is_en = 1;
16423         }
16424       else if (unformat (input, "disable"))
16425         {
16426           is_set = 1;
16427         }
16428       else
16429         break;
16430     }
16431
16432   if (!is_set)
16433     {
16434       errmsg ("Value not set");
16435       return -99;
16436     }
16437
16438   M (ONE_STATS_ENABLE_DISABLE, mp);
16439   mp->is_en = is_en;
16440
16441   /* send */
16442   S (mp);
16443
16444   /* wait for reply */
16445   W (ret);
16446   return ret;
16447 }
16448
16449 static int
16450 api_show_one_stats_enable_disable (vat_main_t * vam)
16451 {
16452   vl_api_show_one_stats_enable_disable_t *mp;
16453   int ret;
16454
16455   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16456
16457   /* send */
16458   S (mp);
16459
16460   /* wait for reply */
16461   W (ret);
16462   return ret;
16463 }
16464
16465 static int
16466 api_show_one_map_request_mode (vat_main_t * vam)
16467 {
16468   vl_api_show_one_map_request_mode_t *mp;
16469   int ret;
16470
16471   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16472
16473   /* send */
16474   S (mp);
16475
16476   /* wait for reply */
16477   W (ret);
16478   return ret;
16479 }
16480
16481 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16482
16483 static int
16484 api_one_map_request_mode (vat_main_t * vam)
16485 {
16486   unformat_input_t *input = vam->input;
16487   vl_api_one_map_request_mode_t *mp;
16488   u8 mode = 0;
16489   int ret;
16490
16491   /* Parse args required to build the message */
16492   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16493     {
16494       if (unformat (input, "dst-only"))
16495         mode = 0;
16496       else if (unformat (input, "src-dst"))
16497         mode = 1;
16498       else
16499         {
16500           errmsg ("parse error '%U'", format_unformat_error, input);
16501           return -99;
16502         }
16503     }
16504
16505   M (ONE_MAP_REQUEST_MODE, mp);
16506
16507   mp->mode = mode;
16508
16509   /* send */
16510   S (mp);
16511
16512   /* wait for reply */
16513   W (ret);
16514   return ret;
16515 }
16516
16517 #define api_lisp_map_request_mode api_one_map_request_mode
16518
16519 /**
16520  * Enable/disable ONE proxy ITR.
16521  *
16522  * @param vam vpp API test context
16523  * @return return code
16524  */
16525 static int
16526 api_one_pitr_set_locator_set (vat_main_t * vam)
16527 {
16528   u8 ls_name_set = 0;
16529   unformat_input_t *input = vam->input;
16530   vl_api_one_pitr_set_locator_set_t *mp;
16531   u8 is_add = 1;
16532   u8 *ls_name = 0;
16533   int ret;
16534
16535   /* Parse args required to build the message */
16536   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16537     {
16538       if (unformat (input, "del"))
16539         is_add = 0;
16540       else if (unformat (input, "locator-set %s", &ls_name))
16541         ls_name_set = 1;
16542       else
16543         {
16544           errmsg ("parse error '%U'", format_unformat_error, input);
16545           return -99;
16546         }
16547     }
16548
16549   if (!ls_name_set)
16550     {
16551       errmsg ("locator-set name not set!");
16552       return -99;
16553     }
16554
16555   M (ONE_PITR_SET_LOCATOR_SET, mp);
16556
16557   mp->is_add = is_add;
16558   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16559   vec_free (ls_name);
16560
16561   /* send */
16562   S (mp);
16563
16564   /* wait for reply */
16565   W (ret);
16566   return ret;
16567 }
16568
16569 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16570
16571 static int
16572 api_one_nsh_set_locator_set (vat_main_t * vam)
16573 {
16574   u8 ls_name_set = 0;
16575   unformat_input_t *input = vam->input;
16576   vl_api_one_nsh_set_locator_set_t *mp;
16577   u8 is_add = 1;
16578   u8 *ls_name = 0;
16579   int ret;
16580
16581   /* Parse args required to build the message */
16582   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16583     {
16584       if (unformat (input, "del"))
16585         is_add = 0;
16586       else if (unformat (input, "ls %s", &ls_name))
16587         ls_name_set = 1;
16588       else
16589         {
16590           errmsg ("parse error '%U'", format_unformat_error, input);
16591           return -99;
16592         }
16593     }
16594
16595   if (!ls_name_set && is_add)
16596     {
16597       errmsg ("locator-set name not set!");
16598       return -99;
16599     }
16600
16601   M (ONE_NSH_SET_LOCATOR_SET, mp);
16602
16603   mp->is_add = is_add;
16604   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16605   vec_free (ls_name);
16606
16607   /* send */
16608   S (mp);
16609
16610   /* wait for reply */
16611   W (ret);
16612   return ret;
16613 }
16614
16615 static int
16616 api_show_one_pitr (vat_main_t * vam)
16617 {
16618   vl_api_show_one_pitr_t *mp;
16619   int ret;
16620
16621   if (!vam->json_output)
16622     {
16623       print (vam->ofp, "%=20s", "lisp status:");
16624     }
16625
16626   M (SHOW_ONE_PITR, mp);
16627   /* send it... */
16628   S (mp);
16629
16630   /* Wait for a reply... */
16631   W (ret);
16632   return ret;
16633 }
16634
16635 #define api_show_lisp_pitr api_show_one_pitr
16636
16637 static int
16638 api_one_use_petr (vat_main_t * vam)
16639 {
16640   unformat_input_t *input = vam->input;
16641   vl_api_one_use_petr_t *mp;
16642   u8 is_add = 0;
16643   ip_address_t ip;
16644   int ret;
16645
16646   memset (&ip, 0, sizeof (ip));
16647
16648   /* Parse args required to build the message */
16649   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16650     {
16651       if (unformat (input, "disable"))
16652         is_add = 0;
16653       else
16654         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16655         {
16656           is_add = 1;
16657           ip_addr_version (&ip) = IP4;
16658         }
16659       else
16660         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16661         {
16662           is_add = 1;
16663           ip_addr_version (&ip) = IP6;
16664         }
16665       else
16666         {
16667           errmsg ("parse error '%U'", format_unformat_error, input);
16668           return -99;
16669         }
16670     }
16671
16672   M (ONE_USE_PETR, mp);
16673
16674   mp->is_add = is_add;
16675   if (is_add)
16676     {
16677       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16678       if (mp->is_ip4)
16679         clib_memcpy (mp->address, &ip, 4);
16680       else
16681         clib_memcpy (mp->address, &ip, 16);
16682     }
16683
16684   /* send */
16685   S (mp);
16686
16687   /* wait for reply */
16688   W (ret);
16689   return ret;
16690 }
16691
16692 #define api_lisp_use_petr api_one_use_petr
16693
16694 static int
16695 api_show_one_nsh_mapping (vat_main_t * vam)
16696 {
16697   vl_api_show_one_use_petr_t *mp;
16698   int ret;
16699
16700   if (!vam->json_output)
16701     {
16702       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16703     }
16704
16705   M (SHOW_ONE_NSH_MAPPING, mp);
16706   /* send it... */
16707   S (mp);
16708
16709   /* Wait for a reply... */
16710   W (ret);
16711   return ret;
16712 }
16713
16714 static int
16715 api_show_one_use_petr (vat_main_t * vam)
16716 {
16717   vl_api_show_one_use_petr_t *mp;
16718   int ret;
16719
16720   if (!vam->json_output)
16721     {
16722       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16723     }
16724
16725   M (SHOW_ONE_USE_PETR, 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_use_petr api_show_one_use_petr
16735
16736 /**
16737  * Add/delete mapping between vni and vrf
16738  */
16739 static int
16740 api_one_eid_table_add_del_map (vat_main_t * vam)
16741 {
16742   unformat_input_t *input = vam->input;
16743   vl_api_one_eid_table_add_del_map_t *mp;
16744   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16745   u32 vni, vrf, bd_index;
16746   int ret;
16747
16748   /* Parse args required to build the message */
16749   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16750     {
16751       if (unformat (input, "del"))
16752         is_add = 0;
16753       else if (unformat (input, "vrf %d", &vrf))
16754         vrf_set = 1;
16755       else if (unformat (input, "bd_index %d", &bd_index))
16756         bd_index_set = 1;
16757       else if (unformat (input, "vni %d", &vni))
16758         vni_set = 1;
16759       else
16760         break;
16761     }
16762
16763   if (!vni_set || (!vrf_set && !bd_index_set))
16764     {
16765       errmsg ("missing arguments!");
16766       return -99;
16767     }
16768
16769   if (vrf_set && bd_index_set)
16770     {
16771       errmsg ("error: both vrf and bd entered!");
16772       return -99;
16773     }
16774
16775   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16776
16777   mp->is_add = is_add;
16778   mp->vni = htonl (vni);
16779   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16780   mp->is_l2 = bd_index_set;
16781
16782   /* send */
16783   S (mp);
16784
16785   /* wait for reply */
16786   W (ret);
16787   return ret;
16788 }
16789
16790 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16791
16792 uword
16793 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16794 {
16795   u32 *action = va_arg (*args, u32 *);
16796   u8 *s = 0;
16797
16798   if (unformat (input, "%s", &s))
16799     {
16800       if (!strcmp ((char *) s, "no-action"))
16801         action[0] = 0;
16802       else if (!strcmp ((char *) s, "natively-forward"))
16803         action[0] = 1;
16804       else if (!strcmp ((char *) s, "send-map-request"))
16805         action[0] = 2;
16806       else if (!strcmp ((char *) s, "drop"))
16807         action[0] = 3;
16808       else
16809         {
16810           clib_warning ("invalid action: '%s'", s);
16811           action[0] = 3;
16812         }
16813     }
16814   else
16815     return 0;
16816
16817   vec_free (s);
16818   return 1;
16819 }
16820
16821 /**
16822  * Add/del remote mapping to/from ONE control plane
16823  *
16824  * @param vam vpp API test context
16825  * @return return code
16826  */
16827 static int
16828 api_one_add_del_remote_mapping (vat_main_t * vam)
16829 {
16830   unformat_input_t *input = vam->input;
16831   vl_api_one_add_del_remote_mapping_t *mp;
16832   u32 vni = 0;
16833   lisp_eid_vat_t _eid, *eid = &_eid;
16834   lisp_eid_vat_t _seid, *seid = &_seid;
16835   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
16836   u32 action = ~0, p, w, data_len;
16837   ip4_address_t rloc4;
16838   ip6_address_t rloc6;
16839   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
16840   int ret;
16841
16842   memset (&rloc, 0, sizeof (rloc));
16843
16844   /* Parse args required to build the message */
16845   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16846     {
16847       if (unformat (input, "del-all"))
16848         {
16849           del_all = 1;
16850         }
16851       else if (unformat (input, "del"))
16852         {
16853           is_add = 0;
16854         }
16855       else if (unformat (input, "add"))
16856         {
16857           is_add = 1;
16858         }
16859       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16860         {
16861           eid_set = 1;
16862         }
16863       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
16864         {
16865           seid_set = 1;
16866         }
16867       else if (unformat (input, "vni %d", &vni))
16868         {
16869           ;
16870         }
16871       else if (unformat (input, "p %d w %d", &p, &w))
16872         {
16873           if (!curr_rloc)
16874             {
16875               errmsg ("No RLOC configured for setting priority/weight!");
16876               return -99;
16877             }
16878           curr_rloc->priority = p;
16879           curr_rloc->weight = w;
16880         }
16881       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
16882         {
16883           rloc.is_ip4 = 1;
16884           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
16885           vec_add1 (rlocs, rloc);
16886           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16887         }
16888       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
16889         {
16890           rloc.is_ip4 = 0;
16891           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
16892           vec_add1 (rlocs, rloc);
16893           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16894         }
16895       else if (unformat (input, "action %U",
16896                          unformat_negative_mapping_action, &action))
16897         {
16898           ;
16899         }
16900       else
16901         {
16902           clib_warning ("parse error '%U'", format_unformat_error, input);
16903           return -99;
16904         }
16905     }
16906
16907   if (0 == eid_set)
16908     {
16909       errmsg ("missing params!");
16910       return -99;
16911     }
16912
16913   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
16914     {
16915       errmsg ("no action set for negative map-reply!");
16916       return -99;
16917     }
16918
16919   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
16920
16921   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
16922   mp->is_add = is_add;
16923   mp->vni = htonl (vni);
16924   mp->action = (u8) action;
16925   mp->is_src_dst = seid_set;
16926   mp->eid_len = eid->len;
16927   mp->seid_len = seid->len;
16928   mp->del_all = del_all;
16929   mp->eid_type = eid->type;
16930   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16931   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
16932
16933   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
16934   clib_memcpy (mp->rlocs, rlocs, data_len);
16935   vec_free (rlocs);
16936
16937   /* send it... */
16938   S (mp);
16939
16940   /* Wait for a reply... */
16941   W (ret);
16942   return ret;
16943 }
16944
16945 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
16946
16947 /**
16948  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
16949  * forwarding entries in data-plane accordingly.
16950  *
16951  * @param vam vpp API test context
16952  * @return return code
16953  */
16954 static int
16955 api_one_add_del_adjacency (vat_main_t * vam)
16956 {
16957   unformat_input_t *input = vam->input;
16958   vl_api_one_add_del_adjacency_t *mp;
16959   u32 vni = 0;
16960   ip4_address_t leid4, reid4;
16961   ip6_address_t leid6, reid6;
16962   u8 reid_mac[6] = { 0 };
16963   u8 leid_mac[6] = { 0 };
16964   u8 reid_type, leid_type;
16965   u32 leid_len = 0, reid_len = 0, len;
16966   u8 is_add = 1;
16967   int ret;
16968
16969   leid_type = reid_type = (u8) ~ 0;
16970
16971   /* Parse args required to build the message */
16972   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16973     {
16974       if (unformat (input, "del"))
16975         {
16976           is_add = 0;
16977         }
16978       else if (unformat (input, "add"))
16979         {
16980           is_add = 1;
16981         }
16982       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
16983                          &reid4, &len))
16984         {
16985           reid_type = 0;        /* ipv4 */
16986           reid_len = len;
16987         }
16988       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
16989                          &reid6, &len))
16990         {
16991           reid_type = 1;        /* ipv6 */
16992           reid_len = len;
16993         }
16994       else if (unformat (input, "reid %U", unformat_ethernet_address,
16995                          reid_mac))
16996         {
16997           reid_type = 2;        /* mac */
16998         }
16999       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17000                          &leid4, &len))
17001         {
17002           leid_type = 0;        /* ipv4 */
17003           leid_len = len;
17004         }
17005       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17006                          &leid6, &len))
17007         {
17008           leid_type = 1;        /* ipv6 */
17009           leid_len = len;
17010         }
17011       else if (unformat (input, "leid %U", unformat_ethernet_address,
17012                          leid_mac))
17013         {
17014           leid_type = 2;        /* mac */
17015         }
17016       else if (unformat (input, "vni %d", &vni))
17017         {
17018           ;
17019         }
17020       else
17021         {
17022           errmsg ("parse error '%U'", format_unformat_error, input);
17023           return -99;
17024         }
17025     }
17026
17027   if ((u8) ~ 0 == reid_type)
17028     {
17029       errmsg ("missing params!");
17030       return -99;
17031     }
17032
17033   if (leid_type != reid_type)
17034     {
17035       errmsg ("remote and local EIDs are of different types!");
17036       return -99;
17037     }
17038
17039   M (ONE_ADD_DEL_ADJACENCY, mp);
17040   mp->is_add = is_add;
17041   mp->vni = htonl (vni);
17042   mp->leid_len = leid_len;
17043   mp->reid_len = reid_len;
17044   mp->eid_type = reid_type;
17045
17046   switch (mp->eid_type)
17047     {
17048     case 0:
17049       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17050       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17051       break;
17052     case 1:
17053       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17054       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17055       break;
17056     case 2:
17057       clib_memcpy (mp->leid, leid_mac, 6);
17058       clib_memcpy (mp->reid, reid_mac, 6);
17059       break;
17060     default:
17061       errmsg ("unknown EID type %d!", mp->eid_type);
17062       return 0;
17063     }
17064
17065   /* send it... */
17066   S (mp);
17067
17068   /* Wait for a reply... */
17069   W (ret);
17070   return ret;
17071 }
17072
17073 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17074
17075 uword
17076 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17077 {
17078   u32 *mode = va_arg (*args, u32 *);
17079
17080   if (unformat (input, "lisp"))
17081     *mode = 0;
17082   else if (unformat (input, "vxlan"))
17083     *mode = 1;
17084   else
17085     return 0;
17086
17087   return 1;
17088 }
17089
17090 static int
17091 api_gpe_get_encap_mode (vat_main_t * vam)
17092 {
17093   vl_api_gpe_get_encap_mode_t *mp;
17094   int ret;
17095
17096   /* Construct the API message */
17097   M (GPE_GET_ENCAP_MODE, mp);
17098
17099   /* send it... */
17100   S (mp);
17101
17102   /* Wait for a reply... */
17103   W (ret);
17104   return ret;
17105 }
17106
17107 static int
17108 api_gpe_set_encap_mode (vat_main_t * vam)
17109 {
17110   unformat_input_t *input = vam->input;
17111   vl_api_gpe_set_encap_mode_t *mp;
17112   int ret;
17113   u32 mode = 0;
17114
17115   /* Parse args required to build the message */
17116   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17117     {
17118       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17119         ;
17120       else
17121         break;
17122     }
17123
17124   /* Construct the API message */
17125   M (GPE_SET_ENCAP_MODE, mp);
17126
17127   mp->mode = mode;
17128
17129   /* send it... */
17130   S (mp);
17131
17132   /* Wait for a reply... */
17133   W (ret);
17134   return ret;
17135 }
17136
17137 static int
17138 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17139 {
17140   unformat_input_t *input = vam->input;
17141   vl_api_gpe_add_del_iface_t *mp;
17142   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17143   u32 dp_table = 0, vni = 0;
17144   int ret;
17145
17146   /* Parse args required to build the message */
17147   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17148     {
17149       if (unformat (input, "up"))
17150         {
17151           action_set = 1;
17152           is_add = 1;
17153         }
17154       else if (unformat (input, "down"))
17155         {
17156           action_set = 1;
17157           is_add = 0;
17158         }
17159       else if (unformat (input, "table_id %d", &dp_table))
17160         {
17161           dp_table_set = 1;
17162         }
17163       else if (unformat (input, "bd_id %d", &dp_table))
17164         {
17165           dp_table_set = 1;
17166           is_l2 = 1;
17167         }
17168       else if (unformat (input, "vni %d", &vni))
17169         {
17170           vni_set = 1;
17171         }
17172       else
17173         break;
17174     }
17175
17176   if (action_set == 0)
17177     {
17178       errmsg ("Action not set");
17179       return -99;
17180     }
17181   if (dp_table_set == 0 || vni_set == 0)
17182     {
17183       errmsg ("vni and dp_table must be set");
17184       return -99;
17185     }
17186
17187   /* Construct the API message */
17188   M (GPE_ADD_DEL_IFACE, mp);
17189
17190   mp->is_add = is_add;
17191   mp->dp_table = clib_host_to_net_u32 (dp_table);
17192   mp->is_l2 = is_l2;
17193   mp->vni = clib_host_to_net_u32 (vni);
17194
17195   /* send it... */
17196   S (mp);
17197
17198   /* Wait for a reply... */
17199   W (ret);
17200   return ret;
17201 }
17202
17203 static int
17204 api_one_map_register_fallback_threshold (vat_main_t * vam)
17205 {
17206   unformat_input_t *input = vam->input;
17207   vl_api_one_map_register_fallback_threshold_t *mp;
17208   u32 value = 0;
17209   u8 is_set = 0;
17210   int ret;
17211
17212   /* Parse args required to build the message */
17213   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17214     {
17215       if (unformat (input, "%u", &value))
17216         is_set = 1;
17217       else
17218         {
17219           clib_warning ("parse error '%U'", format_unformat_error, input);
17220           return -99;
17221         }
17222     }
17223
17224   if (!is_set)
17225     {
17226       errmsg ("fallback threshold value is missing!");
17227       return -99;
17228     }
17229
17230   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17231   mp->value = clib_host_to_net_u32 (value);
17232
17233   /* send it... */
17234   S (mp);
17235
17236   /* Wait for a reply... */
17237   W (ret);
17238   return ret;
17239 }
17240
17241 static int
17242 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17243 {
17244   vl_api_show_one_map_register_fallback_threshold_t *mp;
17245   int ret;
17246
17247   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17248
17249   /* send it... */
17250   S (mp);
17251
17252   /* Wait for a reply... */
17253   W (ret);
17254   return ret;
17255 }
17256
17257 uword
17258 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17259 {
17260   u32 *proto = va_arg (*args, u32 *);
17261
17262   if (unformat (input, "udp"))
17263     *proto = 1;
17264   else if (unformat (input, "api"))
17265     *proto = 2;
17266   else
17267     return 0;
17268
17269   return 1;
17270 }
17271
17272 static int
17273 api_one_set_transport_protocol (vat_main_t * vam)
17274 {
17275   unformat_input_t *input = vam->input;
17276   vl_api_one_set_transport_protocol_t *mp;
17277   u8 is_set = 0;
17278   u32 protocol = 0;
17279   int ret;
17280
17281   /* Parse args required to build the message */
17282   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17283     {
17284       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17285         is_set = 1;
17286       else
17287         {
17288           clib_warning ("parse error '%U'", format_unformat_error, input);
17289           return -99;
17290         }
17291     }
17292
17293   if (!is_set)
17294     {
17295       errmsg ("Transport protocol missing!");
17296       return -99;
17297     }
17298
17299   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17300   mp->protocol = (u8) protocol;
17301
17302   /* send it... */
17303   S (mp);
17304
17305   /* Wait for a reply... */
17306   W (ret);
17307   return ret;
17308 }
17309
17310 static int
17311 api_one_get_transport_protocol (vat_main_t * vam)
17312 {
17313   vl_api_one_get_transport_protocol_t *mp;
17314   int ret;
17315
17316   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17317
17318   /* send it... */
17319   S (mp);
17320
17321   /* Wait for a reply... */
17322   W (ret);
17323   return ret;
17324 }
17325
17326 static int
17327 api_one_map_register_set_ttl (vat_main_t * vam)
17328 {
17329   unformat_input_t *input = vam->input;
17330   vl_api_one_map_register_set_ttl_t *mp;
17331   u32 ttl = 0;
17332   u8 is_set = 0;
17333   int ret;
17334
17335   /* Parse args required to build the message */
17336   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17337     {
17338       if (unformat (input, "%u", &ttl))
17339         is_set = 1;
17340       else
17341         {
17342           clib_warning ("parse error '%U'", format_unformat_error, input);
17343           return -99;
17344         }
17345     }
17346
17347   if (!is_set)
17348     {
17349       errmsg ("TTL value missing!");
17350       return -99;
17351     }
17352
17353   M (ONE_MAP_REGISTER_SET_TTL, mp);
17354   mp->ttl = clib_host_to_net_u32 (ttl);
17355
17356   /* send it... */
17357   S (mp);
17358
17359   /* Wait for a reply... */
17360   W (ret);
17361   return ret;
17362 }
17363
17364 static int
17365 api_show_one_map_register_ttl (vat_main_t * vam)
17366 {
17367   vl_api_show_one_map_register_ttl_t *mp;
17368   int ret;
17369
17370   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17371
17372   /* send it... */
17373   S (mp);
17374
17375   /* Wait for a reply... */
17376   W (ret);
17377   return ret;
17378 }
17379
17380 /**
17381  * Add/del map request itr rlocs from ONE control plane and updates
17382  *
17383  * @param vam vpp API test context
17384  * @return return code
17385  */
17386 static int
17387 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17388 {
17389   unformat_input_t *input = vam->input;
17390   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17391   u8 *locator_set_name = 0;
17392   u8 locator_set_name_set = 0;
17393   u8 is_add = 1;
17394   int ret;
17395
17396   /* Parse args required to build the message */
17397   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17398     {
17399       if (unformat (input, "del"))
17400         {
17401           is_add = 0;
17402         }
17403       else if (unformat (input, "%_%v%_", &locator_set_name))
17404         {
17405           locator_set_name_set = 1;
17406         }
17407       else
17408         {
17409           clib_warning ("parse error '%U'", format_unformat_error, input);
17410           return -99;
17411         }
17412     }
17413
17414   if (is_add && !locator_set_name_set)
17415     {
17416       errmsg ("itr-rloc is not set!");
17417       return -99;
17418     }
17419
17420   if (is_add && vec_len (locator_set_name) > 64)
17421     {
17422       errmsg ("itr-rloc locator-set name too long");
17423       vec_free (locator_set_name);
17424       return -99;
17425     }
17426
17427   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17428   mp->is_add = is_add;
17429   if (is_add)
17430     {
17431       clib_memcpy (mp->locator_set_name, locator_set_name,
17432                    vec_len (locator_set_name));
17433     }
17434   else
17435     {
17436       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17437     }
17438   vec_free (locator_set_name);
17439
17440   /* send it... */
17441   S (mp);
17442
17443   /* Wait for a reply... */
17444   W (ret);
17445   return ret;
17446 }
17447
17448 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17449
17450 static int
17451 api_one_locator_dump (vat_main_t * vam)
17452 {
17453   unformat_input_t *input = vam->input;
17454   vl_api_one_locator_dump_t *mp;
17455   vl_api_control_ping_t *mp_ping;
17456   u8 is_index_set = 0, is_name_set = 0;
17457   u8 *ls_name = 0;
17458   u32 ls_index = ~0;
17459   int ret;
17460
17461   /* Parse args required to build the message */
17462   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17463     {
17464       if (unformat (input, "ls_name %_%v%_", &ls_name))
17465         {
17466           is_name_set = 1;
17467         }
17468       else if (unformat (input, "ls_index %d", &ls_index))
17469         {
17470           is_index_set = 1;
17471         }
17472       else
17473         {
17474           errmsg ("parse error '%U'", format_unformat_error, input);
17475           return -99;
17476         }
17477     }
17478
17479   if (!is_index_set && !is_name_set)
17480     {
17481       errmsg ("error: expected one of index or name!");
17482       return -99;
17483     }
17484
17485   if (is_index_set && is_name_set)
17486     {
17487       errmsg ("error: only one param expected!");
17488       return -99;
17489     }
17490
17491   if (vec_len (ls_name) > 62)
17492     {
17493       errmsg ("error: locator set name too long!");
17494       return -99;
17495     }
17496
17497   if (!vam->json_output)
17498     {
17499       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17500     }
17501
17502   M (ONE_LOCATOR_DUMP, mp);
17503   mp->is_index_set = is_index_set;
17504
17505   if (is_index_set)
17506     mp->ls_index = clib_host_to_net_u32 (ls_index);
17507   else
17508     {
17509       vec_add1 (ls_name, 0);
17510       strncpy ((char *) mp->ls_name, (char *) ls_name,
17511                sizeof (mp->ls_name) - 1);
17512     }
17513
17514   /* send it... */
17515   S (mp);
17516
17517   /* Use a control ping for synchronization */
17518   MPING (CONTROL_PING, mp_ping);
17519   S (mp_ping);
17520
17521   /* Wait for a reply... */
17522   W (ret);
17523   return ret;
17524 }
17525
17526 #define api_lisp_locator_dump api_one_locator_dump
17527
17528 static int
17529 api_one_locator_set_dump (vat_main_t * vam)
17530 {
17531   vl_api_one_locator_set_dump_t *mp;
17532   vl_api_control_ping_t *mp_ping;
17533   unformat_input_t *input = vam->input;
17534   u8 filter = 0;
17535   int ret;
17536
17537   /* Parse args required to build the message */
17538   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17539     {
17540       if (unformat (input, "local"))
17541         {
17542           filter = 1;
17543         }
17544       else if (unformat (input, "remote"))
17545         {
17546           filter = 2;
17547         }
17548       else
17549         {
17550           errmsg ("parse error '%U'", format_unformat_error, input);
17551           return -99;
17552         }
17553     }
17554
17555   if (!vam->json_output)
17556     {
17557       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17558     }
17559
17560   M (ONE_LOCATOR_SET_DUMP, mp);
17561
17562   mp->filter = filter;
17563
17564   /* send it... */
17565   S (mp);
17566
17567   /* Use a control ping for synchronization */
17568   MPING (CONTROL_PING, mp_ping);
17569   S (mp_ping);
17570
17571   /* Wait for a reply... */
17572   W (ret);
17573   return ret;
17574 }
17575
17576 #define api_lisp_locator_set_dump api_one_locator_set_dump
17577
17578 static int
17579 api_one_eid_table_map_dump (vat_main_t * vam)
17580 {
17581   u8 is_l2 = 0;
17582   u8 mode_set = 0;
17583   unformat_input_t *input = vam->input;
17584   vl_api_one_eid_table_map_dump_t *mp;
17585   vl_api_control_ping_t *mp_ping;
17586   int ret;
17587
17588   /* Parse args required to build the message */
17589   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17590     {
17591       if (unformat (input, "l2"))
17592         {
17593           is_l2 = 1;
17594           mode_set = 1;
17595         }
17596       else if (unformat (input, "l3"))
17597         {
17598           is_l2 = 0;
17599           mode_set = 1;
17600         }
17601       else
17602         {
17603           errmsg ("parse error '%U'", format_unformat_error, input);
17604           return -99;
17605         }
17606     }
17607
17608   if (!mode_set)
17609     {
17610       errmsg ("expected one of 'l2' or 'l3' parameter!");
17611       return -99;
17612     }
17613
17614   if (!vam->json_output)
17615     {
17616       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17617     }
17618
17619   M (ONE_EID_TABLE_MAP_DUMP, mp);
17620   mp->is_l2 = is_l2;
17621
17622   /* send it... */
17623   S (mp);
17624
17625   /* Use a control ping for synchronization */
17626   MPING (CONTROL_PING, mp_ping);
17627   S (mp_ping);
17628
17629   /* Wait for a reply... */
17630   W (ret);
17631   return ret;
17632 }
17633
17634 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17635
17636 static int
17637 api_one_eid_table_vni_dump (vat_main_t * vam)
17638 {
17639   vl_api_one_eid_table_vni_dump_t *mp;
17640   vl_api_control_ping_t *mp_ping;
17641   int ret;
17642
17643   if (!vam->json_output)
17644     {
17645       print (vam->ofp, "VNI");
17646     }
17647
17648   M (ONE_EID_TABLE_VNI_DUMP, mp);
17649
17650   /* send it... */
17651   S (mp);
17652
17653   /* Use a control ping for synchronization */
17654   MPING (CONTROL_PING, mp_ping);
17655   S (mp_ping);
17656
17657   /* Wait for a reply... */
17658   W (ret);
17659   return ret;
17660 }
17661
17662 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17663
17664 static int
17665 api_one_eid_table_dump (vat_main_t * vam)
17666 {
17667   unformat_input_t *i = vam->input;
17668   vl_api_one_eid_table_dump_t *mp;
17669   vl_api_control_ping_t *mp_ping;
17670   struct in_addr ip4;
17671   struct in6_addr ip6;
17672   u8 mac[6];
17673   u8 eid_type = ~0, eid_set = 0;
17674   u32 prefix_length = ~0, t, vni = 0;
17675   u8 filter = 0;
17676   int ret;
17677   lisp_nsh_api_t nsh;
17678
17679   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17680     {
17681       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17682         {
17683           eid_set = 1;
17684           eid_type = 0;
17685           prefix_length = t;
17686         }
17687       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17688         {
17689           eid_set = 1;
17690           eid_type = 1;
17691           prefix_length = t;
17692         }
17693       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17694         {
17695           eid_set = 1;
17696           eid_type = 2;
17697         }
17698       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17699         {
17700           eid_set = 1;
17701           eid_type = 3;
17702         }
17703       else if (unformat (i, "vni %d", &t))
17704         {
17705           vni = t;
17706         }
17707       else if (unformat (i, "local"))
17708         {
17709           filter = 1;
17710         }
17711       else if (unformat (i, "remote"))
17712         {
17713           filter = 2;
17714         }
17715       else
17716         {
17717           errmsg ("parse error '%U'", format_unformat_error, i);
17718           return -99;
17719         }
17720     }
17721
17722   if (!vam->json_output)
17723     {
17724       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17725              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17726     }
17727
17728   M (ONE_EID_TABLE_DUMP, mp);
17729
17730   mp->filter = filter;
17731   if (eid_set)
17732     {
17733       mp->eid_set = 1;
17734       mp->vni = htonl (vni);
17735       mp->eid_type = eid_type;
17736       switch (eid_type)
17737         {
17738         case 0:
17739           mp->prefix_length = prefix_length;
17740           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17741           break;
17742         case 1:
17743           mp->prefix_length = prefix_length;
17744           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17745           break;
17746         case 2:
17747           clib_memcpy (mp->eid, mac, sizeof (mac));
17748           break;
17749         case 3:
17750           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17751           break;
17752         default:
17753           errmsg ("unknown EID type %d!", eid_type);
17754           return -99;
17755         }
17756     }
17757
17758   /* send it... */
17759   S (mp);
17760
17761   /* Use a control ping for synchronization */
17762   MPING (CONTROL_PING, mp_ping);
17763   S (mp_ping);
17764
17765   /* Wait for a reply... */
17766   W (ret);
17767   return ret;
17768 }
17769
17770 #define api_lisp_eid_table_dump api_one_eid_table_dump
17771
17772 static int
17773 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17774 {
17775   unformat_input_t *i = vam->input;
17776   vl_api_gpe_fwd_entries_get_t *mp;
17777   u8 vni_set = 0;
17778   u32 vni = ~0;
17779   int ret;
17780
17781   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17782     {
17783       if (unformat (i, "vni %d", &vni))
17784         {
17785           vni_set = 1;
17786         }
17787       else
17788         {
17789           errmsg ("parse error '%U'", format_unformat_error, i);
17790           return -99;
17791         }
17792     }
17793
17794   if (!vni_set)
17795     {
17796       errmsg ("vni not set!");
17797       return -99;
17798     }
17799
17800   if (!vam->json_output)
17801     {
17802       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17803              "leid", "reid");
17804     }
17805
17806   M (GPE_FWD_ENTRIES_GET, mp);
17807   mp->vni = clib_host_to_net_u32 (vni);
17808
17809   /* send it... */
17810   S (mp);
17811
17812   /* Wait for a reply... */
17813   W (ret);
17814   return ret;
17815 }
17816
17817 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
17818 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
17819 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
17820 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
17821 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
17822 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
17823 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
17824 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
17825
17826 static int
17827 api_one_adjacencies_get (vat_main_t * vam)
17828 {
17829   unformat_input_t *i = vam->input;
17830   vl_api_one_adjacencies_get_t *mp;
17831   u8 vni_set = 0;
17832   u32 vni = ~0;
17833   int ret;
17834
17835   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17836     {
17837       if (unformat (i, "vni %d", &vni))
17838         {
17839           vni_set = 1;
17840         }
17841       else
17842         {
17843           errmsg ("parse error '%U'", format_unformat_error, i);
17844           return -99;
17845         }
17846     }
17847
17848   if (!vni_set)
17849     {
17850       errmsg ("vni not set!");
17851       return -99;
17852     }
17853
17854   if (!vam->json_output)
17855     {
17856       print (vam->ofp, "%s %40s", "leid", "reid");
17857     }
17858
17859   M (ONE_ADJACENCIES_GET, mp);
17860   mp->vni = clib_host_to_net_u32 (vni);
17861
17862   /* send it... */
17863   S (mp);
17864
17865   /* Wait for a reply... */
17866   W (ret);
17867   return ret;
17868 }
17869
17870 #define api_lisp_adjacencies_get api_one_adjacencies_get
17871
17872 static int
17873 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
17874 {
17875   unformat_input_t *i = vam->input;
17876   vl_api_gpe_native_fwd_rpaths_get_t *mp;
17877   int ret;
17878   u8 ip_family_set = 0, is_ip4 = 1;
17879
17880   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17881     {
17882       if (unformat (i, "ip4"))
17883         {
17884           ip_family_set = 1;
17885           is_ip4 = 1;
17886         }
17887       else if (unformat (i, "ip6"))
17888         {
17889           ip_family_set = 1;
17890           is_ip4 = 0;
17891         }
17892       else
17893         {
17894           errmsg ("parse error '%U'", format_unformat_error, i);
17895           return -99;
17896         }
17897     }
17898
17899   if (!ip_family_set)
17900     {
17901       errmsg ("ip family not set!");
17902       return -99;
17903     }
17904
17905   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
17906   mp->is_ip4 = is_ip4;
17907
17908   /* send it... */
17909   S (mp);
17910
17911   /* Wait for a reply... */
17912   W (ret);
17913   return ret;
17914 }
17915
17916 static int
17917 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
17918 {
17919   vl_api_gpe_fwd_entry_vnis_get_t *mp;
17920   int ret;
17921
17922   if (!vam->json_output)
17923     {
17924       print (vam->ofp, "VNIs");
17925     }
17926
17927   M (GPE_FWD_ENTRY_VNIS_GET, mp);
17928
17929   /* send it... */
17930   S (mp);
17931
17932   /* Wait for a reply... */
17933   W (ret);
17934   return ret;
17935 }
17936
17937 static int
17938 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
17939 {
17940   unformat_input_t *i = vam->input;
17941   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
17942   int ret = 0;
17943   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
17944   struct in_addr ip4;
17945   struct in6_addr ip6;
17946   u32 table_id = 0, nh_sw_if_index = ~0;
17947
17948   memset (&ip4, 0, sizeof (ip4));
17949   memset (&ip6, 0, sizeof (ip6));
17950
17951   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17952     {
17953       if (unformat (i, "del"))
17954         is_add = 0;
17955       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
17956                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17957         {
17958           ip_set = 1;
17959           is_ip4 = 1;
17960         }
17961       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
17962                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17963         {
17964           ip_set = 1;
17965           is_ip4 = 0;
17966         }
17967       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
17968         {
17969           ip_set = 1;
17970           is_ip4 = 1;
17971           nh_sw_if_index = ~0;
17972         }
17973       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
17974         {
17975           ip_set = 1;
17976           is_ip4 = 0;
17977           nh_sw_if_index = ~0;
17978         }
17979       else if (unformat (i, "table %d", &table_id))
17980         ;
17981       else
17982         {
17983           errmsg ("parse error '%U'", format_unformat_error, i);
17984           return -99;
17985         }
17986     }
17987
17988   if (!ip_set)
17989     {
17990       errmsg ("nh addr not set!");
17991       return -99;
17992     }
17993
17994   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
17995   mp->is_add = is_add;
17996   mp->table_id = clib_host_to_net_u32 (table_id);
17997   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
17998   mp->is_ip4 = is_ip4;
17999   if (is_ip4)
18000     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18001   else
18002     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18003
18004   /* send it... */
18005   S (mp);
18006
18007   /* Wait for a reply... */
18008   W (ret);
18009   return ret;
18010 }
18011
18012 static int
18013 api_one_map_server_dump (vat_main_t * vam)
18014 {
18015   vl_api_one_map_server_dump_t *mp;
18016   vl_api_control_ping_t *mp_ping;
18017   int ret;
18018
18019   if (!vam->json_output)
18020     {
18021       print (vam->ofp, "%=20s", "Map server");
18022     }
18023
18024   M (ONE_MAP_SERVER_DUMP, mp);
18025   /* send it... */
18026   S (mp);
18027
18028   /* Use a control ping for synchronization */
18029   MPING (CONTROL_PING, mp_ping);
18030   S (mp_ping);
18031
18032   /* Wait for a reply... */
18033   W (ret);
18034   return ret;
18035 }
18036
18037 #define api_lisp_map_server_dump api_one_map_server_dump
18038
18039 static int
18040 api_one_map_resolver_dump (vat_main_t * vam)
18041 {
18042   vl_api_one_map_resolver_dump_t *mp;
18043   vl_api_control_ping_t *mp_ping;
18044   int ret;
18045
18046   if (!vam->json_output)
18047     {
18048       print (vam->ofp, "%=20s", "Map resolver");
18049     }
18050
18051   M (ONE_MAP_RESOLVER_DUMP, mp);
18052   /* send it... */
18053   S (mp);
18054
18055   /* Use a control ping for synchronization */
18056   MPING (CONTROL_PING, mp_ping);
18057   S (mp_ping);
18058
18059   /* Wait for a reply... */
18060   W (ret);
18061   return ret;
18062 }
18063
18064 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18065
18066 static int
18067 api_one_stats_flush (vat_main_t * vam)
18068 {
18069   vl_api_one_stats_flush_t *mp;
18070   int ret = 0;
18071
18072   M (ONE_STATS_FLUSH, mp);
18073   S (mp);
18074   W (ret);
18075   return ret;
18076 }
18077
18078 static int
18079 api_one_stats_dump (vat_main_t * vam)
18080 {
18081   vl_api_one_stats_dump_t *mp;
18082   vl_api_control_ping_t *mp_ping;
18083   int ret;
18084
18085   M (ONE_STATS_DUMP, mp);
18086   /* send it... */
18087   S (mp);
18088
18089   /* Use a control ping for synchronization */
18090   MPING (CONTROL_PING, mp_ping);
18091   S (mp_ping);
18092
18093   /* Wait for a reply... */
18094   W (ret);
18095   return ret;
18096 }
18097
18098 static int
18099 api_show_one_status (vat_main_t * vam)
18100 {
18101   vl_api_show_one_status_t *mp;
18102   int ret;
18103
18104   if (!vam->json_output)
18105     {
18106       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18107     }
18108
18109   M (SHOW_ONE_STATUS, mp);
18110   /* send it... */
18111   S (mp);
18112   /* Wait for a reply... */
18113   W (ret);
18114   return ret;
18115 }
18116
18117 #define api_show_lisp_status api_show_one_status
18118
18119 static int
18120 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18121 {
18122   vl_api_gpe_fwd_entry_path_dump_t *mp;
18123   vl_api_control_ping_t *mp_ping;
18124   unformat_input_t *i = vam->input;
18125   u32 fwd_entry_index = ~0;
18126   int ret;
18127
18128   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18129     {
18130       if (unformat (i, "index %d", &fwd_entry_index))
18131         ;
18132       else
18133         break;
18134     }
18135
18136   if (~0 == fwd_entry_index)
18137     {
18138       errmsg ("no index specified!");
18139       return -99;
18140     }
18141
18142   if (!vam->json_output)
18143     {
18144       print (vam->ofp, "first line");
18145     }
18146
18147   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18148
18149   /* send it... */
18150   S (mp);
18151   /* Use a control ping for synchronization */
18152   MPING (CONTROL_PING, mp_ping);
18153   S (mp_ping);
18154
18155   /* Wait for a reply... */
18156   W (ret);
18157   return ret;
18158 }
18159
18160 static int
18161 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18162 {
18163   vl_api_one_get_map_request_itr_rlocs_t *mp;
18164   int ret;
18165
18166   if (!vam->json_output)
18167     {
18168       print (vam->ofp, "%=20s", "itr-rlocs:");
18169     }
18170
18171   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18172   /* send it... */
18173   S (mp);
18174   /* Wait for a reply... */
18175   W (ret);
18176   return ret;
18177 }
18178
18179 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18180
18181 static int
18182 api_af_packet_create (vat_main_t * vam)
18183 {
18184   unformat_input_t *i = vam->input;
18185   vl_api_af_packet_create_t *mp;
18186   u8 *host_if_name = 0;
18187   u8 hw_addr[6];
18188   u8 random_hw_addr = 1;
18189   int ret;
18190
18191   memset (hw_addr, 0, sizeof (hw_addr));
18192
18193   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18194     {
18195       if (unformat (i, "name %s", &host_if_name))
18196         vec_add1 (host_if_name, 0);
18197       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18198         random_hw_addr = 0;
18199       else
18200         break;
18201     }
18202
18203   if (!vec_len (host_if_name))
18204     {
18205       errmsg ("host-interface name must be specified");
18206       return -99;
18207     }
18208
18209   if (vec_len (host_if_name) > 64)
18210     {
18211       errmsg ("host-interface name too long");
18212       return -99;
18213     }
18214
18215   M (AF_PACKET_CREATE, mp);
18216
18217   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18218   clib_memcpy (mp->hw_addr, hw_addr, 6);
18219   mp->use_random_hw_addr = random_hw_addr;
18220   vec_free (host_if_name);
18221
18222   S (mp);
18223
18224   /* *INDENT-OFF* */
18225   W2 (ret,
18226       ({
18227         if (ret == 0)
18228           fprintf (vam->ofp ? vam->ofp : stderr,
18229                    " new sw_if_index = %d\n", vam->sw_if_index);
18230       }));
18231   /* *INDENT-ON* */
18232   return ret;
18233 }
18234
18235 static int
18236 api_af_packet_delete (vat_main_t * vam)
18237 {
18238   unformat_input_t *i = vam->input;
18239   vl_api_af_packet_delete_t *mp;
18240   u8 *host_if_name = 0;
18241   int ret;
18242
18243   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18244     {
18245       if (unformat (i, "name %s", &host_if_name))
18246         vec_add1 (host_if_name, 0);
18247       else
18248         break;
18249     }
18250
18251   if (!vec_len (host_if_name))
18252     {
18253       errmsg ("host-interface name must be specified");
18254       return -99;
18255     }
18256
18257   if (vec_len (host_if_name) > 64)
18258     {
18259       errmsg ("host-interface name too long");
18260       return -99;
18261     }
18262
18263   M (AF_PACKET_DELETE, mp);
18264
18265   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18266   vec_free (host_if_name);
18267
18268   S (mp);
18269   W (ret);
18270   return ret;
18271 }
18272
18273 static int
18274 api_policer_add_del (vat_main_t * vam)
18275 {
18276   unformat_input_t *i = vam->input;
18277   vl_api_policer_add_del_t *mp;
18278   u8 is_add = 1;
18279   u8 *name = 0;
18280   u32 cir = 0;
18281   u32 eir = 0;
18282   u64 cb = 0;
18283   u64 eb = 0;
18284   u8 rate_type = 0;
18285   u8 round_type = 0;
18286   u8 type = 0;
18287   u8 color_aware = 0;
18288   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18289   int ret;
18290
18291   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18292   conform_action.dscp = 0;
18293   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18294   exceed_action.dscp = 0;
18295   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18296   violate_action.dscp = 0;
18297
18298   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18299     {
18300       if (unformat (i, "del"))
18301         is_add = 0;
18302       else if (unformat (i, "name %s", &name))
18303         vec_add1 (name, 0);
18304       else if (unformat (i, "cir %u", &cir))
18305         ;
18306       else if (unformat (i, "eir %u", &eir))
18307         ;
18308       else if (unformat (i, "cb %u", &cb))
18309         ;
18310       else if (unformat (i, "eb %u", &eb))
18311         ;
18312       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18313                          &rate_type))
18314         ;
18315       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18316                          &round_type))
18317         ;
18318       else if (unformat (i, "type %U", unformat_policer_type, &type))
18319         ;
18320       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18321                          &conform_action))
18322         ;
18323       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18324                          &exceed_action))
18325         ;
18326       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18327                          &violate_action))
18328         ;
18329       else if (unformat (i, "color-aware"))
18330         color_aware = 1;
18331       else
18332         break;
18333     }
18334
18335   if (!vec_len (name))
18336     {
18337       errmsg ("policer name must be specified");
18338       return -99;
18339     }
18340
18341   if (vec_len (name) > 64)
18342     {
18343       errmsg ("policer name too long");
18344       return -99;
18345     }
18346
18347   M (POLICER_ADD_DEL, mp);
18348
18349   clib_memcpy (mp->name, name, vec_len (name));
18350   vec_free (name);
18351   mp->is_add = is_add;
18352   mp->cir = cir;
18353   mp->eir = eir;
18354   mp->cb = cb;
18355   mp->eb = eb;
18356   mp->rate_type = rate_type;
18357   mp->round_type = round_type;
18358   mp->type = type;
18359   mp->conform_action_type = conform_action.action_type;
18360   mp->conform_dscp = conform_action.dscp;
18361   mp->exceed_action_type = exceed_action.action_type;
18362   mp->exceed_dscp = exceed_action.dscp;
18363   mp->violate_action_type = violate_action.action_type;
18364   mp->violate_dscp = violate_action.dscp;
18365   mp->color_aware = color_aware;
18366
18367   S (mp);
18368   W (ret);
18369   return ret;
18370 }
18371
18372 static int
18373 api_policer_dump (vat_main_t * vam)
18374 {
18375   unformat_input_t *i = vam->input;
18376   vl_api_policer_dump_t *mp;
18377   vl_api_control_ping_t *mp_ping;
18378   u8 *match_name = 0;
18379   u8 match_name_valid = 0;
18380   int ret;
18381
18382   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18383     {
18384       if (unformat (i, "name %s", &match_name))
18385         {
18386           vec_add1 (match_name, 0);
18387           match_name_valid = 1;
18388         }
18389       else
18390         break;
18391     }
18392
18393   M (POLICER_DUMP, mp);
18394   mp->match_name_valid = match_name_valid;
18395   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18396   vec_free (match_name);
18397   /* send it... */
18398   S (mp);
18399
18400   /* Use a control ping for synchronization */
18401   MPING (CONTROL_PING, mp_ping);
18402   S (mp_ping);
18403
18404   /* Wait for a reply... */
18405   W (ret);
18406   return ret;
18407 }
18408
18409 static int
18410 api_policer_classify_set_interface (vat_main_t * vam)
18411 {
18412   unformat_input_t *i = vam->input;
18413   vl_api_policer_classify_set_interface_t *mp;
18414   u32 sw_if_index;
18415   int sw_if_index_set;
18416   u32 ip4_table_index = ~0;
18417   u32 ip6_table_index = ~0;
18418   u32 l2_table_index = ~0;
18419   u8 is_add = 1;
18420   int ret;
18421
18422   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18423     {
18424       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18425         sw_if_index_set = 1;
18426       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18427         sw_if_index_set = 1;
18428       else if (unformat (i, "del"))
18429         is_add = 0;
18430       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18431         ;
18432       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18433         ;
18434       else if (unformat (i, "l2-table %d", &l2_table_index))
18435         ;
18436       else
18437         {
18438           clib_warning ("parse error '%U'", format_unformat_error, i);
18439           return -99;
18440         }
18441     }
18442
18443   if (sw_if_index_set == 0)
18444     {
18445       errmsg ("missing interface name or sw_if_index");
18446       return -99;
18447     }
18448
18449   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18450
18451   mp->sw_if_index = ntohl (sw_if_index);
18452   mp->ip4_table_index = ntohl (ip4_table_index);
18453   mp->ip6_table_index = ntohl (ip6_table_index);
18454   mp->l2_table_index = ntohl (l2_table_index);
18455   mp->is_add = is_add;
18456
18457   S (mp);
18458   W (ret);
18459   return ret;
18460 }
18461
18462 static int
18463 api_policer_classify_dump (vat_main_t * vam)
18464 {
18465   unformat_input_t *i = vam->input;
18466   vl_api_policer_classify_dump_t *mp;
18467   vl_api_control_ping_t *mp_ping;
18468   u8 type = POLICER_CLASSIFY_N_TABLES;
18469   int ret;
18470
18471   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18472     ;
18473   else
18474     {
18475       errmsg ("classify table type must be specified");
18476       return -99;
18477     }
18478
18479   if (!vam->json_output)
18480     {
18481       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18482     }
18483
18484   M (POLICER_CLASSIFY_DUMP, mp);
18485   mp->type = type;
18486   /* send it... */
18487   S (mp);
18488
18489   /* Use a control ping for synchronization */
18490   MPING (CONTROL_PING, mp_ping);
18491   S (mp_ping);
18492
18493   /* Wait for a reply... */
18494   W (ret);
18495   return ret;
18496 }
18497
18498 static int
18499 api_netmap_create (vat_main_t * vam)
18500 {
18501   unformat_input_t *i = vam->input;
18502   vl_api_netmap_create_t *mp;
18503   u8 *if_name = 0;
18504   u8 hw_addr[6];
18505   u8 random_hw_addr = 1;
18506   u8 is_pipe = 0;
18507   u8 is_master = 0;
18508   int ret;
18509
18510   memset (hw_addr, 0, sizeof (hw_addr));
18511
18512   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18513     {
18514       if (unformat (i, "name %s", &if_name))
18515         vec_add1 (if_name, 0);
18516       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18517         random_hw_addr = 0;
18518       else if (unformat (i, "pipe"))
18519         is_pipe = 1;
18520       else if (unformat (i, "master"))
18521         is_master = 1;
18522       else if (unformat (i, "slave"))
18523         is_master = 0;
18524       else
18525         break;
18526     }
18527
18528   if (!vec_len (if_name))
18529     {
18530       errmsg ("interface name must be specified");
18531       return -99;
18532     }
18533
18534   if (vec_len (if_name) > 64)
18535     {
18536       errmsg ("interface name too long");
18537       return -99;
18538     }
18539
18540   M (NETMAP_CREATE, mp);
18541
18542   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18543   clib_memcpy (mp->hw_addr, hw_addr, 6);
18544   mp->use_random_hw_addr = random_hw_addr;
18545   mp->is_pipe = is_pipe;
18546   mp->is_master = is_master;
18547   vec_free (if_name);
18548
18549   S (mp);
18550   W (ret);
18551   return ret;
18552 }
18553
18554 static int
18555 api_netmap_delete (vat_main_t * vam)
18556 {
18557   unformat_input_t *i = vam->input;
18558   vl_api_netmap_delete_t *mp;
18559   u8 *if_name = 0;
18560   int ret;
18561
18562   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18563     {
18564       if (unformat (i, "name %s", &if_name))
18565         vec_add1 (if_name, 0);
18566       else
18567         break;
18568     }
18569
18570   if (!vec_len (if_name))
18571     {
18572       errmsg ("interface name must be specified");
18573       return -99;
18574     }
18575
18576   if (vec_len (if_name) > 64)
18577     {
18578       errmsg ("interface name too long");
18579       return -99;
18580     }
18581
18582   M (NETMAP_DELETE, mp);
18583
18584   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18585   vec_free (if_name);
18586
18587   S (mp);
18588   W (ret);
18589   return ret;
18590 }
18591
18592 static void
18593 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
18594 {
18595   if (fp->afi == IP46_TYPE_IP6)
18596     print (vam->ofp,
18597            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18598            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18599            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18600            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18601            format_ip6_address, fp->next_hop);
18602   else if (fp->afi == IP46_TYPE_IP4)
18603     print (vam->ofp,
18604            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18605            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18606            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18607            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18608            format_ip4_address, fp->next_hop);
18609 }
18610
18611 static void
18612 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18613                                  vl_api_fib_path2_t * fp)
18614 {
18615   struct in_addr ip4;
18616   struct in6_addr ip6;
18617
18618   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18619   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18620   vat_json_object_add_uint (node, "is_local", fp->is_local);
18621   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
18622   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
18623   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
18624   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
18625   if (fp->afi == IP46_TYPE_IP4)
18626     {
18627       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
18628       vat_json_object_add_ip4 (node, "next_hop", ip4);
18629     }
18630   else if (fp->afi == IP46_TYPE_IP6)
18631     {
18632       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
18633       vat_json_object_add_ip6 (node, "next_hop", ip6);
18634     }
18635 }
18636
18637 static void
18638 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18639 {
18640   vat_main_t *vam = &vat_main;
18641   int count = ntohl (mp->mt_count);
18642   vl_api_fib_path2_t *fp;
18643   i32 i;
18644
18645   print (vam->ofp, "[%d]: sw_if_index %d via:",
18646          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
18647   fp = mp->mt_paths;
18648   for (i = 0; i < count; i++)
18649     {
18650       vl_api_mpls_fib_path_print (vam, fp);
18651       fp++;
18652     }
18653
18654   print (vam->ofp, "");
18655 }
18656
18657 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18658 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18659
18660 static void
18661 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18662 {
18663   vat_main_t *vam = &vat_main;
18664   vat_json_node_t *node = NULL;
18665   int count = ntohl (mp->mt_count);
18666   vl_api_fib_path2_t *fp;
18667   i32 i;
18668
18669   if (VAT_JSON_ARRAY != vam->json_tree.type)
18670     {
18671       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18672       vat_json_init_array (&vam->json_tree);
18673     }
18674   node = vat_json_array_add (&vam->json_tree);
18675
18676   vat_json_init_object (node);
18677   vat_json_object_add_uint (node, "tunnel_index",
18678                             ntohl (mp->mt_tunnel_index));
18679   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
18680
18681   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
18682
18683   fp = mp->mt_paths;
18684   for (i = 0; i < count; i++)
18685     {
18686       vl_api_mpls_fib_path_json_print (node, fp);
18687       fp++;
18688     }
18689 }
18690
18691 static int
18692 api_mpls_tunnel_dump (vat_main_t * vam)
18693 {
18694   vl_api_mpls_tunnel_dump_t *mp;
18695   vl_api_control_ping_t *mp_ping;
18696   i32 index = -1;
18697   int ret;
18698
18699   /* Parse args required to build the message */
18700   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
18701     {
18702       if (!unformat (vam->input, "tunnel_index %d", &index))
18703         {
18704           index = -1;
18705           break;
18706         }
18707     }
18708
18709   print (vam->ofp, "  tunnel_index %d", index);
18710
18711   M (MPLS_TUNNEL_DUMP, mp);
18712   mp->tunnel_index = htonl (index);
18713   S (mp);
18714
18715   /* Use a control ping for synchronization */
18716   MPING (CONTROL_PING, mp_ping);
18717   S (mp_ping);
18718
18719   W (ret);
18720   return ret;
18721 }
18722
18723 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
18724 #define vl_api_mpls_fib_details_t_print vl_noop_handler
18725
18726
18727 static void
18728 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
18729 {
18730   vat_main_t *vam = &vat_main;
18731   int count = ntohl (mp->count);
18732   vl_api_fib_path2_t *fp;
18733   int i;
18734
18735   print (vam->ofp,
18736          "table-id %d, label %u, ess_bit %u",
18737          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
18738   fp = mp->path;
18739   for (i = 0; i < count; i++)
18740     {
18741       vl_api_mpls_fib_path_print (vam, fp);
18742       fp++;
18743     }
18744 }
18745
18746 static void vl_api_mpls_fib_details_t_handler_json
18747   (vl_api_mpls_fib_details_t * mp)
18748 {
18749   vat_main_t *vam = &vat_main;
18750   int count = ntohl (mp->count);
18751   vat_json_node_t *node = NULL;
18752   vl_api_fib_path2_t *fp;
18753   int i;
18754
18755   if (VAT_JSON_ARRAY != vam->json_tree.type)
18756     {
18757       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18758       vat_json_init_array (&vam->json_tree);
18759     }
18760   node = vat_json_array_add (&vam->json_tree);
18761
18762   vat_json_init_object (node);
18763   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
18764   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
18765   vat_json_object_add_uint (node, "label", ntohl (mp->label));
18766   vat_json_object_add_uint (node, "path_count", count);
18767   fp = mp->path;
18768   for (i = 0; i < count; i++)
18769     {
18770       vl_api_mpls_fib_path_json_print (node, fp);
18771       fp++;
18772     }
18773 }
18774
18775 static int
18776 api_mpls_fib_dump (vat_main_t * vam)
18777 {
18778   vl_api_mpls_fib_dump_t *mp;
18779   vl_api_control_ping_t *mp_ping;
18780   int ret;
18781
18782   M (MPLS_FIB_DUMP, mp);
18783   S (mp);
18784
18785   /* Use a control ping for synchronization */
18786   MPING (CONTROL_PING, mp_ping);
18787   S (mp_ping);
18788
18789   W (ret);
18790   return ret;
18791 }
18792
18793 #define vl_api_ip_fib_details_t_endian vl_noop_handler
18794 #define vl_api_ip_fib_details_t_print vl_noop_handler
18795
18796 static void
18797 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
18798 {
18799   vat_main_t *vam = &vat_main;
18800   int count = ntohl (mp->count);
18801   vl_api_fib_path_t *fp;
18802   int i;
18803
18804   print (vam->ofp,
18805          "table-id %d, prefix %U/%d",
18806          ntohl (mp->table_id), format_ip4_address, mp->address,
18807          mp->address_length);
18808   fp = mp->path;
18809   for (i = 0; i < count; i++)
18810     {
18811       if (fp->afi == IP46_TYPE_IP6)
18812         print (vam->ofp,
18813                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18814                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18815                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18816                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18817                format_ip6_address, fp->next_hop);
18818       else if (fp->afi == IP46_TYPE_IP4)
18819         print (vam->ofp,
18820                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18821                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18822                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18823                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18824                format_ip4_address, fp->next_hop);
18825       fp++;
18826     }
18827 }
18828
18829 static void vl_api_ip_fib_details_t_handler_json
18830   (vl_api_ip_fib_details_t * mp)
18831 {
18832   vat_main_t *vam = &vat_main;
18833   int count = ntohl (mp->count);
18834   vat_json_node_t *node = NULL;
18835   struct in_addr ip4;
18836   struct in6_addr ip6;
18837   vl_api_fib_path_t *fp;
18838   int i;
18839
18840   if (VAT_JSON_ARRAY != vam->json_tree.type)
18841     {
18842       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18843       vat_json_init_array (&vam->json_tree);
18844     }
18845   node = vat_json_array_add (&vam->json_tree);
18846
18847   vat_json_init_object (node);
18848   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
18849   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
18850   vat_json_object_add_ip4 (node, "prefix", ip4);
18851   vat_json_object_add_uint (node, "mask_length", mp->address_length);
18852   vat_json_object_add_uint (node, "path_count", count);
18853   fp = mp->path;
18854   for (i = 0; i < count; i++)
18855     {
18856       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18857       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18858       vat_json_object_add_uint (node, "is_local", fp->is_local);
18859       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
18860       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
18861       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
18862       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
18863       if (fp->afi == IP46_TYPE_IP4)
18864         {
18865           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
18866           vat_json_object_add_ip4 (node, "next_hop", ip4);
18867         }
18868       else if (fp->afi == IP46_TYPE_IP6)
18869         {
18870           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
18871           vat_json_object_add_ip6 (node, "next_hop", ip6);
18872         }
18873     }
18874 }
18875
18876 static int
18877 api_ip_fib_dump (vat_main_t * vam)
18878 {
18879   vl_api_ip_fib_dump_t *mp;
18880   vl_api_control_ping_t *mp_ping;
18881   int ret;
18882
18883   M (IP_FIB_DUMP, mp);
18884   S (mp);
18885
18886   /* Use a control ping for synchronization */
18887   MPING (CONTROL_PING, mp_ping);
18888   S (mp_ping);
18889
18890   W (ret);
18891   return ret;
18892 }
18893
18894 static int
18895 api_ip_mfib_dump (vat_main_t * vam)
18896 {
18897   vl_api_ip_mfib_dump_t *mp;
18898   vl_api_control_ping_t *mp_ping;
18899   int ret;
18900
18901   M (IP_MFIB_DUMP, mp);
18902   S (mp);
18903
18904   /* Use a control ping for synchronization */
18905   MPING (CONTROL_PING, mp_ping);
18906   S (mp_ping);
18907
18908   W (ret);
18909   return ret;
18910 }
18911
18912 static void vl_api_ip_neighbor_details_t_handler
18913   (vl_api_ip_neighbor_details_t * mp)
18914 {
18915   vat_main_t *vam = &vat_main;
18916
18917   print (vam->ofp, "%c %U %U",
18918          (mp->is_static) ? 'S' : 'D',
18919          format_ethernet_address, &mp->mac_address,
18920          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
18921          &mp->ip_address);
18922 }
18923
18924 static void vl_api_ip_neighbor_details_t_handler_json
18925   (vl_api_ip_neighbor_details_t * mp)
18926 {
18927
18928   vat_main_t *vam = &vat_main;
18929   vat_json_node_t *node;
18930   struct in_addr ip4;
18931   struct in6_addr ip6;
18932
18933   if (VAT_JSON_ARRAY != vam->json_tree.type)
18934     {
18935       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18936       vat_json_init_array (&vam->json_tree);
18937     }
18938   node = vat_json_array_add (&vam->json_tree);
18939
18940   vat_json_init_object (node);
18941   vat_json_object_add_string_copy (node, "flag",
18942                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
18943                                    "dynamic");
18944
18945   vat_json_object_add_string_copy (node, "link_layer",
18946                                    format (0, "%U", format_ethernet_address,
18947                                            &mp->mac_address));
18948
18949   if (mp->is_ipv6)
18950     {
18951       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
18952       vat_json_object_add_ip6 (node, "ip_address", ip6);
18953     }
18954   else
18955     {
18956       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
18957       vat_json_object_add_ip4 (node, "ip_address", ip4);
18958     }
18959 }
18960
18961 static int
18962 api_ip_neighbor_dump (vat_main_t * vam)
18963 {
18964   unformat_input_t *i = vam->input;
18965   vl_api_ip_neighbor_dump_t *mp;
18966   vl_api_control_ping_t *mp_ping;
18967   u8 is_ipv6 = 0;
18968   u32 sw_if_index = ~0;
18969   int ret;
18970
18971   /* Parse args required to build the message */
18972   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18973     {
18974       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18975         ;
18976       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18977         ;
18978       else if (unformat (i, "ip6"))
18979         is_ipv6 = 1;
18980       else
18981         break;
18982     }
18983
18984   if (sw_if_index == ~0)
18985     {
18986       errmsg ("missing interface name or sw_if_index");
18987       return -99;
18988     }
18989
18990   M (IP_NEIGHBOR_DUMP, mp);
18991   mp->is_ipv6 = (u8) is_ipv6;
18992   mp->sw_if_index = ntohl (sw_if_index);
18993   S (mp);
18994
18995   /* Use a control ping for synchronization */
18996   MPING (CONTROL_PING, mp_ping);
18997   S (mp_ping);
18998
18999   W (ret);
19000   return ret;
19001 }
19002
19003 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
19004 #define vl_api_ip6_fib_details_t_print vl_noop_handler
19005
19006 static void
19007 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
19008 {
19009   vat_main_t *vam = &vat_main;
19010   int count = ntohl (mp->count);
19011   vl_api_fib_path_t *fp;
19012   int i;
19013
19014   print (vam->ofp,
19015          "table-id %d, prefix %U/%d",
19016          ntohl (mp->table_id), format_ip6_address, mp->address,
19017          mp->address_length);
19018   fp = mp->path;
19019   for (i = 0; i < count; i++)
19020     {
19021       if (fp->afi == IP46_TYPE_IP6)
19022         print (vam->ofp,
19023                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19024                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19025                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19026                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19027                format_ip6_address, fp->next_hop);
19028       else if (fp->afi == IP46_TYPE_IP4)
19029         print (vam->ofp,
19030                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19031                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19032                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19033                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19034                format_ip4_address, fp->next_hop);
19035       fp++;
19036     }
19037 }
19038
19039 static void vl_api_ip6_fib_details_t_handler_json
19040   (vl_api_ip6_fib_details_t * mp)
19041 {
19042   vat_main_t *vam = &vat_main;
19043   int count = ntohl (mp->count);
19044   vat_json_node_t *node = NULL;
19045   struct in_addr ip4;
19046   struct in6_addr ip6;
19047   vl_api_fib_path_t *fp;
19048   int i;
19049
19050   if (VAT_JSON_ARRAY != vam->json_tree.type)
19051     {
19052       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19053       vat_json_init_array (&vam->json_tree);
19054     }
19055   node = vat_json_array_add (&vam->json_tree);
19056
19057   vat_json_init_object (node);
19058   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19059   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
19060   vat_json_object_add_ip6 (node, "prefix", ip6);
19061   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19062   vat_json_object_add_uint (node, "path_count", count);
19063   fp = mp->path;
19064   for (i = 0; i < count; i++)
19065     {
19066       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19067       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19068       vat_json_object_add_uint (node, "is_local", fp->is_local);
19069       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19070       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19071       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19072       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19073       if (fp->afi == IP46_TYPE_IP4)
19074         {
19075           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19076           vat_json_object_add_ip4 (node, "next_hop", ip4);
19077         }
19078       else if (fp->afi == IP46_TYPE_IP6)
19079         {
19080           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19081           vat_json_object_add_ip6 (node, "next_hop", ip6);
19082         }
19083     }
19084 }
19085
19086 static int
19087 api_ip6_fib_dump (vat_main_t * vam)
19088 {
19089   vl_api_ip6_fib_dump_t *mp;
19090   vl_api_control_ping_t *mp_ping;
19091   int ret;
19092
19093   M (IP6_FIB_DUMP, mp);
19094   S (mp);
19095
19096   /* Use a control ping for synchronization */
19097   MPING (CONTROL_PING, mp_ping);
19098   S (mp_ping);
19099
19100   W (ret);
19101   return ret;
19102 }
19103
19104 static int
19105 api_ip6_mfib_dump (vat_main_t * vam)
19106 {
19107   vl_api_ip6_mfib_dump_t *mp;
19108   vl_api_control_ping_t *mp_ping;
19109   int ret;
19110
19111   M (IP6_MFIB_DUMP, mp);
19112   S (mp);
19113
19114   /* Use a control ping for synchronization */
19115   MPING (CONTROL_PING, mp_ping);
19116   S (mp_ping);
19117
19118   W (ret);
19119   return ret;
19120 }
19121
19122 int
19123 api_classify_table_ids (vat_main_t * vam)
19124 {
19125   vl_api_classify_table_ids_t *mp;
19126   int ret;
19127
19128   /* Construct the API message */
19129   M (CLASSIFY_TABLE_IDS, mp);
19130   mp->context = 0;
19131
19132   S (mp);
19133   W (ret);
19134   return ret;
19135 }
19136
19137 int
19138 api_classify_table_by_interface (vat_main_t * vam)
19139 {
19140   unformat_input_t *input = vam->input;
19141   vl_api_classify_table_by_interface_t *mp;
19142
19143   u32 sw_if_index = ~0;
19144   int ret;
19145   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19146     {
19147       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19148         ;
19149       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19150         ;
19151       else
19152         break;
19153     }
19154   if (sw_if_index == ~0)
19155     {
19156       errmsg ("missing interface name or sw_if_index");
19157       return -99;
19158     }
19159
19160   /* Construct the API message */
19161   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19162   mp->context = 0;
19163   mp->sw_if_index = ntohl (sw_if_index);
19164
19165   S (mp);
19166   W (ret);
19167   return ret;
19168 }
19169
19170 int
19171 api_classify_table_info (vat_main_t * vam)
19172 {
19173   unformat_input_t *input = vam->input;
19174   vl_api_classify_table_info_t *mp;
19175
19176   u32 table_id = ~0;
19177   int ret;
19178   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19179     {
19180       if (unformat (input, "table_id %d", &table_id))
19181         ;
19182       else
19183         break;
19184     }
19185   if (table_id == ~0)
19186     {
19187       errmsg ("missing table id");
19188       return -99;
19189     }
19190
19191   /* Construct the API message */
19192   M (CLASSIFY_TABLE_INFO, mp);
19193   mp->context = 0;
19194   mp->table_id = ntohl (table_id);
19195
19196   S (mp);
19197   W (ret);
19198   return ret;
19199 }
19200
19201 int
19202 api_classify_session_dump (vat_main_t * vam)
19203 {
19204   unformat_input_t *input = vam->input;
19205   vl_api_classify_session_dump_t *mp;
19206   vl_api_control_ping_t *mp_ping;
19207
19208   u32 table_id = ~0;
19209   int ret;
19210   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19211     {
19212       if (unformat (input, "table_id %d", &table_id))
19213         ;
19214       else
19215         break;
19216     }
19217   if (table_id == ~0)
19218     {
19219       errmsg ("missing table id");
19220       return -99;
19221     }
19222
19223   /* Construct the API message */
19224   M (CLASSIFY_SESSION_DUMP, mp);
19225   mp->context = 0;
19226   mp->table_id = ntohl (table_id);
19227   S (mp);
19228
19229   /* Use a control ping for synchronization */
19230   MPING (CONTROL_PING, mp_ping);
19231   S (mp_ping);
19232
19233   W (ret);
19234   return ret;
19235 }
19236
19237 static void
19238 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19239 {
19240   vat_main_t *vam = &vat_main;
19241
19242   print (vam->ofp, "collector_address %U, collector_port %d, "
19243          "src_address %U, vrf_id %d, path_mtu %u, "
19244          "template_interval %u, udp_checksum %d",
19245          format_ip4_address, mp->collector_address,
19246          ntohs (mp->collector_port),
19247          format_ip4_address, mp->src_address,
19248          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19249          ntohl (mp->template_interval), mp->udp_checksum);
19250
19251   vam->retval = 0;
19252   vam->result_ready = 1;
19253 }
19254
19255 static void
19256   vl_api_ipfix_exporter_details_t_handler_json
19257   (vl_api_ipfix_exporter_details_t * mp)
19258 {
19259   vat_main_t *vam = &vat_main;
19260   vat_json_node_t node;
19261   struct in_addr collector_address;
19262   struct in_addr src_address;
19263
19264   vat_json_init_object (&node);
19265   clib_memcpy (&collector_address, &mp->collector_address,
19266                sizeof (collector_address));
19267   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19268   vat_json_object_add_uint (&node, "collector_port",
19269                             ntohs (mp->collector_port));
19270   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19271   vat_json_object_add_ip4 (&node, "src_address", src_address);
19272   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19273   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19274   vat_json_object_add_uint (&node, "template_interval",
19275                             ntohl (mp->template_interval));
19276   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19277
19278   vat_json_print (vam->ofp, &node);
19279   vat_json_free (&node);
19280   vam->retval = 0;
19281   vam->result_ready = 1;
19282 }
19283
19284 int
19285 api_ipfix_exporter_dump (vat_main_t * vam)
19286 {
19287   vl_api_ipfix_exporter_dump_t *mp;
19288   int ret;
19289
19290   /* Construct the API message */
19291   M (IPFIX_EXPORTER_DUMP, mp);
19292   mp->context = 0;
19293
19294   S (mp);
19295   W (ret);
19296   return ret;
19297 }
19298
19299 static int
19300 api_ipfix_classify_stream_dump (vat_main_t * vam)
19301 {
19302   vl_api_ipfix_classify_stream_dump_t *mp;
19303   int ret;
19304
19305   /* Construct the API message */
19306   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19307   mp->context = 0;
19308
19309   S (mp);
19310   W (ret);
19311   return ret;
19312   /* NOTREACHED */
19313   return 0;
19314 }
19315
19316 static void
19317   vl_api_ipfix_classify_stream_details_t_handler
19318   (vl_api_ipfix_classify_stream_details_t * mp)
19319 {
19320   vat_main_t *vam = &vat_main;
19321   print (vam->ofp, "domain_id %d, src_port %d",
19322          ntohl (mp->domain_id), ntohs (mp->src_port));
19323   vam->retval = 0;
19324   vam->result_ready = 1;
19325 }
19326
19327 static void
19328   vl_api_ipfix_classify_stream_details_t_handler_json
19329   (vl_api_ipfix_classify_stream_details_t * mp)
19330 {
19331   vat_main_t *vam = &vat_main;
19332   vat_json_node_t node;
19333
19334   vat_json_init_object (&node);
19335   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19336   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19337
19338   vat_json_print (vam->ofp, &node);
19339   vat_json_free (&node);
19340   vam->retval = 0;
19341   vam->result_ready = 1;
19342 }
19343
19344 static int
19345 api_ipfix_classify_table_dump (vat_main_t * vam)
19346 {
19347   vl_api_ipfix_classify_table_dump_t *mp;
19348   vl_api_control_ping_t *mp_ping;
19349   int ret;
19350
19351   if (!vam->json_output)
19352     {
19353       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19354              "transport_protocol");
19355     }
19356
19357   /* Construct the API message */
19358   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19359
19360   /* send it... */
19361   S (mp);
19362
19363   /* Use a control ping for synchronization */
19364   MPING (CONTROL_PING, mp_ping);
19365   S (mp_ping);
19366
19367   W (ret);
19368   return ret;
19369 }
19370
19371 static void
19372   vl_api_ipfix_classify_table_details_t_handler
19373   (vl_api_ipfix_classify_table_details_t * mp)
19374 {
19375   vat_main_t *vam = &vat_main;
19376   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19377          mp->transport_protocol);
19378 }
19379
19380 static void
19381   vl_api_ipfix_classify_table_details_t_handler_json
19382   (vl_api_ipfix_classify_table_details_t * mp)
19383 {
19384   vat_json_node_t *node = NULL;
19385   vat_main_t *vam = &vat_main;
19386
19387   if (VAT_JSON_ARRAY != vam->json_tree.type)
19388     {
19389       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19390       vat_json_init_array (&vam->json_tree);
19391     }
19392
19393   node = vat_json_array_add (&vam->json_tree);
19394   vat_json_init_object (node);
19395
19396   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19397   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19398   vat_json_object_add_uint (node, "transport_protocol",
19399                             mp->transport_protocol);
19400 }
19401
19402 static int
19403 api_sw_interface_span_enable_disable (vat_main_t * vam)
19404 {
19405   unformat_input_t *i = vam->input;
19406   vl_api_sw_interface_span_enable_disable_t *mp;
19407   u32 src_sw_if_index = ~0;
19408   u32 dst_sw_if_index = ~0;
19409   u8 state = 3;
19410   int ret;
19411   u8 is_l2 = 0;
19412
19413   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19414     {
19415       if (unformat
19416           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19417         ;
19418       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19419         ;
19420       else
19421         if (unformat
19422             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19423         ;
19424       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19425         ;
19426       else if (unformat (i, "disable"))
19427         state = 0;
19428       else if (unformat (i, "rx"))
19429         state = 1;
19430       else if (unformat (i, "tx"))
19431         state = 2;
19432       else if (unformat (i, "both"))
19433         state = 3;
19434       else if (unformat (i, "l2"))
19435         is_l2 = 1;
19436       else
19437         break;
19438     }
19439
19440   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19441
19442   mp->sw_if_index_from = htonl (src_sw_if_index);
19443   mp->sw_if_index_to = htonl (dst_sw_if_index);
19444   mp->state = state;
19445   mp->is_l2 = is_l2;
19446
19447   S (mp);
19448   W (ret);
19449   return ret;
19450 }
19451
19452 static void
19453 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19454                                             * mp)
19455 {
19456   vat_main_t *vam = &vat_main;
19457   u8 *sw_if_from_name = 0;
19458   u8 *sw_if_to_name = 0;
19459   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19460   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19461   char *states[] = { "none", "rx", "tx", "both" };
19462   hash_pair_t *p;
19463
19464   /* *INDENT-OFF* */
19465   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19466   ({
19467     if ((u32) p->value[0] == sw_if_index_from)
19468       {
19469         sw_if_from_name = (u8 *)(p->key);
19470         if (sw_if_to_name)
19471           break;
19472       }
19473     if ((u32) p->value[0] == sw_if_index_to)
19474       {
19475         sw_if_to_name = (u8 *)(p->key);
19476         if (sw_if_from_name)
19477           break;
19478       }
19479   }));
19480   /* *INDENT-ON* */
19481   print (vam->ofp, "%20s => %20s (%s)",
19482          sw_if_from_name, sw_if_to_name, states[mp->state]);
19483 }
19484
19485 static void
19486   vl_api_sw_interface_span_details_t_handler_json
19487   (vl_api_sw_interface_span_details_t * mp)
19488 {
19489   vat_main_t *vam = &vat_main;
19490   vat_json_node_t *node = NULL;
19491   u8 *sw_if_from_name = 0;
19492   u8 *sw_if_to_name = 0;
19493   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19494   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19495   hash_pair_t *p;
19496
19497   /* *INDENT-OFF* */
19498   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19499   ({
19500     if ((u32) p->value[0] == sw_if_index_from)
19501       {
19502         sw_if_from_name = (u8 *)(p->key);
19503         if (sw_if_to_name)
19504           break;
19505       }
19506     if ((u32) p->value[0] == sw_if_index_to)
19507       {
19508         sw_if_to_name = (u8 *)(p->key);
19509         if (sw_if_from_name)
19510           break;
19511       }
19512   }));
19513   /* *INDENT-ON* */
19514
19515   if (VAT_JSON_ARRAY != vam->json_tree.type)
19516     {
19517       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19518       vat_json_init_array (&vam->json_tree);
19519     }
19520   node = vat_json_array_add (&vam->json_tree);
19521
19522   vat_json_init_object (node);
19523   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19524   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19525   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19526   if (0 != sw_if_to_name)
19527     {
19528       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19529     }
19530   vat_json_object_add_uint (node, "state", mp->state);
19531 }
19532
19533 static int
19534 api_sw_interface_span_dump (vat_main_t * vam)
19535 {
19536   unformat_input_t *input = vam->input;
19537   vl_api_sw_interface_span_dump_t *mp;
19538   vl_api_control_ping_t *mp_ping;
19539   u8 is_l2 = 0;
19540   int ret;
19541
19542   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19543     {
19544       if (unformat (input, "l2"))
19545         is_l2 = 1;
19546       else
19547         break;
19548     }
19549
19550   M (SW_INTERFACE_SPAN_DUMP, mp);
19551   mp->is_l2 = is_l2;
19552   S (mp);
19553
19554   /* Use a control ping for synchronization */
19555   MPING (CONTROL_PING, mp_ping);
19556   S (mp_ping);
19557
19558   W (ret);
19559   return ret;
19560 }
19561
19562 int
19563 api_pg_create_interface (vat_main_t * vam)
19564 {
19565   unformat_input_t *input = vam->input;
19566   vl_api_pg_create_interface_t *mp;
19567
19568   u32 if_id = ~0;
19569   int ret;
19570   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19571     {
19572       if (unformat (input, "if_id %d", &if_id))
19573         ;
19574       else
19575         break;
19576     }
19577   if (if_id == ~0)
19578     {
19579       errmsg ("missing pg interface index");
19580       return -99;
19581     }
19582
19583   /* Construct the API message */
19584   M (PG_CREATE_INTERFACE, mp);
19585   mp->context = 0;
19586   mp->interface_id = ntohl (if_id);
19587
19588   S (mp);
19589   W (ret);
19590   return ret;
19591 }
19592
19593 int
19594 api_pg_capture (vat_main_t * vam)
19595 {
19596   unformat_input_t *input = vam->input;
19597   vl_api_pg_capture_t *mp;
19598
19599   u32 if_id = ~0;
19600   u8 enable = 1;
19601   u32 count = 1;
19602   u8 pcap_file_set = 0;
19603   u8 *pcap_file = 0;
19604   int ret;
19605   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19606     {
19607       if (unformat (input, "if_id %d", &if_id))
19608         ;
19609       else if (unformat (input, "pcap %s", &pcap_file))
19610         pcap_file_set = 1;
19611       else if (unformat (input, "count %d", &count))
19612         ;
19613       else if (unformat (input, "disable"))
19614         enable = 0;
19615       else
19616         break;
19617     }
19618   if (if_id == ~0)
19619     {
19620       errmsg ("missing pg interface index");
19621       return -99;
19622     }
19623   if (pcap_file_set > 0)
19624     {
19625       if (vec_len (pcap_file) > 255)
19626         {
19627           errmsg ("pcap file name is too long");
19628           return -99;
19629         }
19630     }
19631
19632   u32 name_len = vec_len (pcap_file);
19633   /* Construct the API message */
19634   M (PG_CAPTURE, mp);
19635   mp->context = 0;
19636   mp->interface_id = ntohl (if_id);
19637   mp->is_enabled = enable;
19638   mp->count = ntohl (count);
19639   mp->pcap_name_length = ntohl (name_len);
19640   if (pcap_file_set != 0)
19641     {
19642       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19643     }
19644   vec_free (pcap_file);
19645
19646   S (mp);
19647   W (ret);
19648   return ret;
19649 }
19650
19651 int
19652 api_pg_enable_disable (vat_main_t * vam)
19653 {
19654   unformat_input_t *input = vam->input;
19655   vl_api_pg_enable_disable_t *mp;
19656
19657   u8 enable = 1;
19658   u8 stream_name_set = 0;
19659   u8 *stream_name = 0;
19660   int ret;
19661   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19662     {
19663       if (unformat (input, "stream %s", &stream_name))
19664         stream_name_set = 1;
19665       else if (unformat (input, "disable"))
19666         enable = 0;
19667       else
19668         break;
19669     }
19670
19671   if (stream_name_set > 0)
19672     {
19673       if (vec_len (stream_name) > 255)
19674         {
19675           errmsg ("stream name too long");
19676           return -99;
19677         }
19678     }
19679
19680   u32 name_len = vec_len (stream_name);
19681   /* Construct the API message */
19682   M (PG_ENABLE_DISABLE, mp);
19683   mp->context = 0;
19684   mp->is_enabled = enable;
19685   if (stream_name_set != 0)
19686     {
19687       mp->stream_name_length = ntohl (name_len);
19688       clib_memcpy (mp->stream_name, stream_name, name_len);
19689     }
19690   vec_free (stream_name);
19691
19692   S (mp);
19693   W (ret);
19694   return ret;
19695 }
19696
19697 int
19698 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19699 {
19700   unformat_input_t *input = vam->input;
19701   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19702
19703   u16 *low_ports = 0;
19704   u16 *high_ports = 0;
19705   u16 this_low;
19706   u16 this_hi;
19707   ip4_address_t ip4_addr;
19708   ip6_address_t ip6_addr;
19709   u32 length;
19710   u32 tmp, tmp2;
19711   u8 prefix_set = 0;
19712   u32 vrf_id = ~0;
19713   u8 is_add = 1;
19714   u8 is_ipv6 = 0;
19715   int ret;
19716
19717   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19718     {
19719       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
19720         {
19721           prefix_set = 1;
19722         }
19723       else
19724         if (unformat
19725             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
19726         {
19727           prefix_set = 1;
19728           is_ipv6 = 1;
19729         }
19730       else if (unformat (input, "vrf %d", &vrf_id))
19731         ;
19732       else if (unformat (input, "del"))
19733         is_add = 0;
19734       else if (unformat (input, "port %d", &tmp))
19735         {
19736           if (tmp == 0 || tmp > 65535)
19737             {
19738               errmsg ("port %d out of range", tmp);
19739               return -99;
19740             }
19741           this_low = tmp;
19742           this_hi = this_low + 1;
19743           vec_add1 (low_ports, this_low);
19744           vec_add1 (high_ports, this_hi);
19745         }
19746       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19747         {
19748           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19749             {
19750               errmsg ("incorrect range parameters");
19751               return -99;
19752             }
19753           this_low = tmp;
19754           /* Note: in debug CLI +1 is added to high before
19755              passing to real fn that does "the work"
19756              (ip_source_and_port_range_check_add_del).
19757              This fn is a wrapper around the binary API fn a
19758              control plane will call, which expects this increment
19759              to have occurred. Hence letting the binary API control
19760              plane fn do the increment for consistency between VAT
19761              and other control planes.
19762            */
19763           this_hi = tmp2;
19764           vec_add1 (low_ports, this_low);
19765           vec_add1 (high_ports, this_hi);
19766         }
19767       else
19768         break;
19769     }
19770
19771   if (prefix_set == 0)
19772     {
19773       errmsg ("<address>/<mask> not specified");
19774       return -99;
19775     }
19776
19777   if (vrf_id == ~0)
19778     {
19779       errmsg ("VRF ID required, not specified");
19780       return -99;
19781     }
19782
19783   if (vrf_id == 0)
19784     {
19785       errmsg
19786         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19787       return -99;
19788     }
19789
19790   if (vec_len (low_ports) == 0)
19791     {
19792       errmsg ("At least one port or port range required");
19793       return -99;
19794     }
19795
19796   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19797
19798   mp->is_add = is_add;
19799
19800   if (is_ipv6)
19801     {
19802       mp->is_ipv6 = 1;
19803       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
19804     }
19805   else
19806     {
19807       mp->is_ipv6 = 0;
19808       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
19809     }
19810
19811   mp->mask_length = length;
19812   mp->number_of_ranges = vec_len (low_ports);
19813
19814   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
19815   vec_free (low_ports);
19816
19817   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
19818   vec_free (high_ports);
19819
19820   mp->vrf_id = ntohl (vrf_id);
19821
19822   S (mp);
19823   W (ret);
19824   return ret;
19825 }
19826
19827 int
19828 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
19829 {
19830   unformat_input_t *input = vam->input;
19831   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
19832   u32 sw_if_index = ~0;
19833   int vrf_set = 0;
19834   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
19835   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
19836   u8 is_add = 1;
19837   int ret;
19838
19839   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19840     {
19841       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19842         ;
19843       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19844         ;
19845       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
19846         vrf_set = 1;
19847       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
19848         vrf_set = 1;
19849       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
19850         vrf_set = 1;
19851       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
19852         vrf_set = 1;
19853       else if (unformat (input, "del"))
19854         is_add = 0;
19855       else
19856         break;
19857     }
19858
19859   if (sw_if_index == ~0)
19860     {
19861       errmsg ("Interface required but not specified");
19862       return -99;
19863     }
19864
19865   if (vrf_set == 0)
19866     {
19867       errmsg ("VRF ID required but not specified");
19868       return -99;
19869     }
19870
19871   if (tcp_out_vrf_id == 0
19872       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
19873     {
19874       errmsg
19875         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19876       return -99;
19877     }
19878
19879   /* Construct the API message */
19880   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
19881
19882   mp->sw_if_index = ntohl (sw_if_index);
19883   mp->is_add = is_add;
19884   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
19885   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
19886   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
19887   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
19888
19889   /* send it... */
19890   S (mp);
19891
19892   /* Wait for a reply... */
19893   W (ret);
19894   return ret;
19895 }
19896
19897 static int
19898 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
19899 {
19900   unformat_input_t *i = vam->input;
19901   vl_api_ipsec_gre_add_del_tunnel_t *mp;
19902   u32 local_sa_id = 0;
19903   u32 remote_sa_id = 0;
19904   ip4_address_t src_address;
19905   ip4_address_t dst_address;
19906   u8 is_add = 1;
19907   int ret;
19908
19909   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19910     {
19911       if (unformat (i, "local_sa %d", &local_sa_id))
19912         ;
19913       else if (unformat (i, "remote_sa %d", &remote_sa_id))
19914         ;
19915       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
19916         ;
19917       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
19918         ;
19919       else if (unformat (i, "del"))
19920         is_add = 0;
19921       else
19922         {
19923           clib_warning ("parse error '%U'", format_unformat_error, i);
19924           return -99;
19925         }
19926     }
19927
19928   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
19929
19930   mp->local_sa_id = ntohl (local_sa_id);
19931   mp->remote_sa_id = ntohl (remote_sa_id);
19932   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
19933   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
19934   mp->is_add = is_add;
19935
19936   S (mp);
19937   W (ret);
19938   return ret;
19939 }
19940
19941 static int
19942 api_punt (vat_main_t * vam)
19943 {
19944   unformat_input_t *i = vam->input;
19945   vl_api_punt_t *mp;
19946   u32 ipv = ~0;
19947   u32 protocol = ~0;
19948   u32 port = ~0;
19949   int is_add = 1;
19950   int ret;
19951
19952   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19953     {
19954       if (unformat (i, "ip %d", &ipv))
19955         ;
19956       else if (unformat (i, "protocol %d", &protocol))
19957         ;
19958       else if (unformat (i, "port %d", &port))
19959         ;
19960       else if (unformat (i, "del"))
19961         is_add = 0;
19962       else
19963         {
19964           clib_warning ("parse error '%U'", format_unformat_error, i);
19965           return -99;
19966         }
19967     }
19968
19969   M (PUNT, mp);
19970
19971   mp->is_add = (u8) is_add;
19972   mp->ipv = (u8) ipv;
19973   mp->l4_protocol = (u8) protocol;
19974   mp->l4_port = htons ((u16) port);
19975
19976   S (mp);
19977   W (ret);
19978   return ret;
19979 }
19980
19981 static void vl_api_ipsec_gre_tunnel_details_t_handler
19982   (vl_api_ipsec_gre_tunnel_details_t * mp)
19983 {
19984   vat_main_t *vam = &vat_main;
19985
19986   print (vam->ofp, "%11d%15U%15U%14d%14d",
19987          ntohl (mp->sw_if_index),
19988          format_ip4_address, &mp->src_address,
19989          format_ip4_address, &mp->dst_address,
19990          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
19991 }
19992
19993 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
19994   (vl_api_ipsec_gre_tunnel_details_t * mp)
19995 {
19996   vat_main_t *vam = &vat_main;
19997   vat_json_node_t *node = NULL;
19998   struct in_addr ip4;
19999
20000   if (VAT_JSON_ARRAY != vam->json_tree.type)
20001     {
20002       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20003       vat_json_init_array (&vam->json_tree);
20004     }
20005   node = vat_json_array_add (&vam->json_tree);
20006
20007   vat_json_init_object (node);
20008   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
20009   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
20010   vat_json_object_add_ip4 (node, "src_address", ip4);
20011   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
20012   vat_json_object_add_ip4 (node, "dst_address", ip4);
20013   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
20014   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
20015 }
20016
20017 static int
20018 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
20019 {
20020   unformat_input_t *i = vam->input;
20021   vl_api_ipsec_gre_tunnel_dump_t *mp;
20022   vl_api_control_ping_t *mp_ping;
20023   u32 sw_if_index;
20024   u8 sw_if_index_set = 0;
20025   int ret;
20026
20027   /* Parse args required to build the message */
20028   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20029     {
20030       if (unformat (i, "sw_if_index %d", &sw_if_index))
20031         sw_if_index_set = 1;
20032       else
20033         break;
20034     }
20035
20036   if (sw_if_index_set == 0)
20037     {
20038       sw_if_index = ~0;
20039     }
20040
20041   if (!vam->json_output)
20042     {
20043       print (vam->ofp, "%11s%15s%15s%14s%14s",
20044              "sw_if_index", "src_address", "dst_address",
20045              "local_sa_id", "remote_sa_id");
20046     }
20047
20048   /* Get list of gre-tunnel interfaces */
20049   M (IPSEC_GRE_TUNNEL_DUMP, mp);
20050
20051   mp->sw_if_index = htonl (sw_if_index);
20052
20053   S (mp);
20054
20055   /* Use a control ping for synchronization */
20056   MPING (CONTROL_PING, mp_ping);
20057   S (mp_ping);
20058
20059   W (ret);
20060   return ret;
20061 }
20062
20063 static int
20064 api_delete_subif (vat_main_t * vam)
20065 {
20066   unformat_input_t *i = vam->input;
20067   vl_api_delete_subif_t *mp;
20068   u32 sw_if_index = ~0;
20069   int ret;
20070
20071   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20072     {
20073       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20074         ;
20075       if (unformat (i, "sw_if_index %d", &sw_if_index))
20076         ;
20077       else
20078         break;
20079     }
20080
20081   if (sw_if_index == ~0)
20082     {
20083       errmsg ("missing sw_if_index");
20084       return -99;
20085     }
20086
20087   /* Construct the API message */
20088   M (DELETE_SUBIF, mp);
20089   mp->sw_if_index = ntohl (sw_if_index);
20090
20091   S (mp);
20092   W (ret);
20093   return ret;
20094 }
20095
20096 #define foreach_pbb_vtr_op      \
20097 _("disable",  L2_VTR_DISABLED)  \
20098 _("pop",  L2_VTR_POP_2)         \
20099 _("push",  L2_VTR_PUSH_2)
20100
20101 static int
20102 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20103 {
20104   unformat_input_t *i = vam->input;
20105   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20106   u32 sw_if_index = ~0, vtr_op = ~0;
20107   u16 outer_tag = ~0;
20108   u8 dmac[6], smac[6];
20109   u8 dmac_set = 0, smac_set = 0;
20110   u16 vlanid = 0;
20111   u32 sid = ~0;
20112   u32 tmp;
20113   int ret;
20114
20115   /* Shut up coverity */
20116   memset (dmac, 0, sizeof (dmac));
20117   memset (smac, 0, sizeof (smac));
20118
20119   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20120     {
20121       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20122         ;
20123       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20124         ;
20125       else if (unformat (i, "vtr_op %d", &vtr_op))
20126         ;
20127 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20128       foreach_pbb_vtr_op
20129 #undef _
20130         else if (unformat (i, "translate_pbb_stag"))
20131         {
20132           if (unformat (i, "%d", &tmp))
20133             {
20134               vtr_op = L2_VTR_TRANSLATE_2_1;
20135               outer_tag = tmp;
20136             }
20137           else
20138             {
20139               errmsg
20140                 ("translate_pbb_stag operation requires outer tag definition");
20141               return -99;
20142             }
20143         }
20144       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20145         dmac_set++;
20146       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20147         smac_set++;
20148       else if (unformat (i, "sid %d", &sid))
20149         ;
20150       else if (unformat (i, "vlanid %d", &tmp))
20151         vlanid = tmp;
20152       else
20153         {
20154           clib_warning ("parse error '%U'", format_unformat_error, i);
20155           return -99;
20156         }
20157     }
20158
20159   if ((sw_if_index == ~0) || (vtr_op == ~0))
20160     {
20161       errmsg ("missing sw_if_index or vtr operation");
20162       return -99;
20163     }
20164   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20165       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20166     {
20167       errmsg
20168         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20169       return -99;
20170     }
20171
20172   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20173   mp->sw_if_index = ntohl (sw_if_index);
20174   mp->vtr_op = ntohl (vtr_op);
20175   mp->outer_tag = ntohs (outer_tag);
20176   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20177   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20178   mp->b_vlanid = ntohs (vlanid);
20179   mp->i_sid = ntohl (sid);
20180
20181   S (mp);
20182   W (ret);
20183   return ret;
20184 }
20185
20186 static int
20187 api_flow_classify_set_interface (vat_main_t * vam)
20188 {
20189   unformat_input_t *i = vam->input;
20190   vl_api_flow_classify_set_interface_t *mp;
20191   u32 sw_if_index;
20192   int sw_if_index_set;
20193   u32 ip4_table_index = ~0;
20194   u32 ip6_table_index = ~0;
20195   u8 is_add = 1;
20196   int ret;
20197
20198   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20199     {
20200       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20201         sw_if_index_set = 1;
20202       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20203         sw_if_index_set = 1;
20204       else if (unformat (i, "del"))
20205         is_add = 0;
20206       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20207         ;
20208       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20209         ;
20210       else
20211         {
20212           clib_warning ("parse error '%U'", format_unformat_error, i);
20213           return -99;
20214         }
20215     }
20216
20217   if (sw_if_index_set == 0)
20218     {
20219       errmsg ("missing interface name or sw_if_index");
20220       return -99;
20221     }
20222
20223   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20224
20225   mp->sw_if_index = ntohl (sw_if_index);
20226   mp->ip4_table_index = ntohl (ip4_table_index);
20227   mp->ip6_table_index = ntohl (ip6_table_index);
20228   mp->is_add = is_add;
20229
20230   S (mp);
20231   W (ret);
20232   return ret;
20233 }
20234
20235 static int
20236 api_flow_classify_dump (vat_main_t * vam)
20237 {
20238   unformat_input_t *i = vam->input;
20239   vl_api_flow_classify_dump_t *mp;
20240   vl_api_control_ping_t *mp_ping;
20241   u8 type = FLOW_CLASSIFY_N_TABLES;
20242   int ret;
20243
20244   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20245     ;
20246   else
20247     {
20248       errmsg ("classify table type must be specified");
20249       return -99;
20250     }
20251
20252   if (!vam->json_output)
20253     {
20254       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20255     }
20256
20257   M (FLOW_CLASSIFY_DUMP, mp);
20258   mp->type = type;
20259   /* send it... */
20260   S (mp);
20261
20262   /* Use a control ping for synchronization */
20263   MPING (CONTROL_PING, mp_ping);
20264   S (mp_ping);
20265
20266   /* Wait for a reply... */
20267   W (ret);
20268   return ret;
20269 }
20270
20271 static int
20272 api_feature_enable_disable (vat_main_t * vam)
20273 {
20274   unformat_input_t *i = vam->input;
20275   vl_api_feature_enable_disable_t *mp;
20276   u8 *arc_name = 0;
20277   u8 *feature_name = 0;
20278   u32 sw_if_index = ~0;
20279   u8 enable = 1;
20280   int ret;
20281
20282   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20283     {
20284       if (unformat (i, "arc_name %s", &arc_name))
20285         ;
20286       else if (unformat (i, "feature_name %s", &feature_name))
20287         ;
20288       else
20289         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20290         ;
20291       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20292         ;
20293       else if (unformat (i, "disable"))
20294         enable = 0;
20295       else
20296         break;
20297     }
20298
20299   if (arc_name == 0)
20300     {
20301       errmsg ("missing arc name");
20302       return -99;
20303     }
20304   if (vec_len (arc_name) > 63)
20305     {
20306       errmsg ("arc name too long");
20307     }
20308
20309   if (feature_name == 0)
20310     {
20311       errmsg ("missing feature name");
20312       return -99;
20313     }
20314   if (vec_len (feature_name) > 63)
20315     {
20316       errmsg ("feature name too long");
20317     }
20318
20319   if (sw_if_index == ~0)
20320     {
20321       errmsg ("missing interface name or sw_if_index");
20322       return -99;
20323     }
20324
20325   /* Construct the API message */
20326   M (FEATURE_ENABLE_DISABLE, mp);
20327   mp->sw_if_index = ntohl (sw_if_index);
20328   mp->enable = enable;
20329   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20330   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20331   vec_free (arc_name);
20332   vec_free (feature_name);
20333
20334   S (mp);
20335   W (ret);
20336   return ret;
20337 }
20338
20339 static int
20340 api_sw_interface_tag_add_del (vat_main_t * vam)
20341 {
20342   unformat_input_t *i = vam->input;
20343   vl_api_sw_interface_tag_add_del_t *mp;
20344   u32 sw_if_index = ~0;
20345   u8 *tag = 0;
20346   u8 enable = 1;
20347   int ret;
20348
20349   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20350     {
20351       if (unformat (i, "tag %s", &tag))
20352         ;
20353       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20354         ;
20355       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20356         ;
20357       else if (unformat (i, "del"))
20358         enable = 0;
20359       else
20360         break;
20361     }
20362
20363   if (sw_if_index == ~0)
20364     {
20365       errmsg ("missing interface name or sw_if_index");
20366       return -99;
20367     }
20368
20369   if (enable && (tag == 0))
20370     {
20371       errmsg ("no tag specified");
20372       return -99;
20373     }
20374
20375   /* Construct the API message */
20376   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20377   mp->sw_if_index = ntohl (sw_if_index);
20378   mp->is_add = enable;
20379   if (enable)
20380     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20381   vec_free (tag);
20382
20383   S (mp);
20384   W (ret);
20385   return ret;
20386 }
20387
20388 static void vl_api_l2_xconnect_details_t_handler
20389   (vl_api_l2_xconnect_details_t * mp)
20390 {
20391   vat_main_t *vam = &vat_main;
20392
20393   print (vam->ofp, "%15d%15d",
20394          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20395 }
20396
20397 static void vl_api_l2_xconnect_details_t_handler_json
20398   (vl_api_l2_xconnect_details_t * mp)
20399 {
20400   vat_main_t *vam = &vat_main;
20401   vat_json_node_t *node = NULL;
20402
20403   if (VAT_JSON_ARRAY != vam->json_tree.type)
20404     {
20405       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20406       vat_json_init_array (&vam->json_tree);
20407     }
20408   node = vat_json_array_add (&vam->json_tree);
20409
20410   vat_json_init_object (node);
20411   vat_json_object_add_uint (node, "rx_sw_if_index",
20412                             ntohl (mp->rx_sw_if_index));
20413   vat_json_object_add_uint (node, "tx_sw_if_index",
20414                             ntohl (mp->tx_sw_if_index));
20415 }
20416
20417 static int
20418 api_l2_xconnect_dump (vat_main_t * vam)
20419 {
20420   vl_api_l2_xconnect_dump_t *mp;
20421   vl_api_control_ping_t *mp_ping;
20422   int ret;
20423
20424   if (!vam->json_output)
20425     {
20426       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20427     }
20428
20429   M (L2_XCONNECT_DUMP, mp);
20430
20431   S (mp);
20432
20433   /* Use a control ping for synchronization */
20434   MPING (CONTROL_PING, mp_ping);
20435   S (mp_ping);
20436
20437   W (ret);
20438   return ret;
20439 }
20440
20441 static int
20442 api_sw_interface_set_mtu (vat_main_t * vam)
20443 {
20444   unformat_input_t *i = vam->input;
20445   vl_api_sw_interface_set_mtu_t *mp;
20446   u32 sw_if_index = ~0;
20447   u32 mtu = 0;
20448   int ret;
20449
20450   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20451     {
20452       if (unformat (i, "mtu %d", &mtu))
20453         ;
20454       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20455         ;
20456       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20457         ;
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 (mtu == 0)
20469     {
20470       errmsg ("no mtu specified");
20471       return -99;
20472     }
20473
20474   /* Construct the API message */
20475   M (SW_INTERFACE_SET_MTU, mp);
20476   mp->sw_if_index = ntohl (sw_if_index);
20477   mp->mtu = ntohs ((u16) mtu);
20478
20479   S (mp);
20480   W (ret);
20481   return ret;
20482 }
20483
20484 static int
20485 api_p2p_ethernet_add (vat_main_t * vam)
20486 {
20487   unformat_input_t *i = vam->input;
20488   vl_api_p2p_ethernet_add_t *mp;
20489   u32 parent_if_index = ~0;
20490   u32 sub_id = ~0;
20491   u8 remote_mac[6];
20492   u8 mac_set = 0;
20493   int ret;
20494
20495   memset (remote_mac, 0, sizeof (remote_mac));
20496   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20497     {
20498       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20499         ;
20500       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20501         ;
20502       else
20503         if (unformat
20504             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20505         mac_set++;
20506       else if (unformat (i, "sub_id %d", &sub_id))
20507         ;
20508       else
20509         {
20510           clib_warning ("parse error '%U'", format_unformat_error, i);
20511           return -99;
20512         }
20513     }
20514
20515   if (parent_if_index == ~0)
20516     {
20517       errmsg ("missing interface name or sw_if_index");
20518       return -99;
20519     }
20520   if (mac_set == 0)
20521     {
20522       errmsg ("missing remote mac address");
20523       return -99;
20524     }
20525   if (sub_id == ~0)
20526     {
20527       errmsg ("missing sub-interface id");
20528       return -99;
20529     }
20530
20531   M (P2P_ETHERNET_ADD, mp);
20532   mp->parent_if_index = ntohl (parent_if_index);
20533   mp->subif_id = ntohl (sub_id);
20534   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20535
20536   S (mp);
20537   W (ret);
20538   return ret;
20539 }
20540
20541 static int
20542 api_p2p_ethernet_del (vat_main_t * vam)
20543 {
20544   unformat_input_t *i = vam->input;
20545   vl_api_p2p_ethernet_del_t *mp;
20546   u32 parent_if_index = ~0;
20547   u8 remote_mac[6];
20548   u8 mac_set = 0;
20549   int ret;
20550
20551   memset (remote_mac, 0, sizeof (remote_mac));
20552   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20553     {
20554       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20555         ;
20556       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20557         ;
20558       else
20559         if (unformat
20560             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20561         mac_set++;
20562       else
20563         {
20564           clib_warning ("parse error '%U'", format_unformat_error, i);
20565           return -99;
20566         }
20567     }
20568
20569   if (parent_if_index == ~0)
20570     {
20571       errmsg ("missing interface name or sw_if_index");
20572       return -99;
20573     }
20574   if (mac_set == 0)
20575     {
20576       errmsg ("missing remote mac address");
20577       return -99;
20578     }
20579
20580   M (P2P_ETHERNET_DEL, mp);
20581   mp->parent_if_index = ntohl (parent_if_index);
20582   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20583
20584   S (mp);
20585   W (ret);
20586   return ret;
20587 }
20588
20589 static int
20590 api_lldp_config (vat_main_t * vam)
20591 {
20592   unformat_input_t *i = vam->input;
20593   vl_api_lldp_config_t *mp;
20594   int tx_hold = 0;
20595   int tx_interval = 0;
20596   u8 *sys_name = NULL;
20597   int ret;
20598
20599   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20600     {
20601       if (unformat (i, "system-name %s", &sys_name))
20602         ;
20603       else if (unformat (i, "tx-hold %d", &tx_hold))
20604         ;
20605       else if (unformat (i, "tx-interval %d", &tx_interval))
20606         ;
20607       else
20608         {
20609           clib_warning ("parse error '%U'", format_unformat_error, i);
20610           return -99;
20611         }
20612     }
20613
20614   vec_add1 (sys_name, 0);
20615
20616   M (LLDP_CONFIG, mp);
20617   mp->tx_hold = htonl (tx_hold);
20618   mp->tx_interval = htonl (tx_interval);
20619   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20620   vec_free (sys_name);
20621
20622   S (mp);
20623   W (ret);
20624   return ret;
20625 }
20626
20627 static int
20628 api_sw_interface_set_lldp (vat_main_t * vam)
20629 {
20630   unformat_input_t *i = vam->input;
20631   vl_api_sw_interface_set_lldp_t *mp;
20632   u32 sw_if_index = ~0;
20633   u32 enable = 1;
20634   u8 *port_desc = NULL;
20635   int ret;
20636
20637   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20638     {
20639       if (unformat (i, "disable"))
20640         enable = 0;
20641       else
20642         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20643         ;
20644       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20645         ;
20646       else if (unformat (i, "port-desc %s", &port_desc))
20647         ;
20648       else
20649         break;
20650     }
20651
20652   if (sw_if_index == ~0)
20653     {
20654       errmsg ("missing interface name or sw_if_index");
20655       return -99;
20656     }
20657
20658   /* Construct the API message */
20659   vec_add1 (port_desc, 0);
20660   M (SW_INTERFACE_SET_LLDP, mp);
20661   mp->sw_if_index = ntohl (sw_if_index);
20662   mp->enable = enable;
20663   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20664   vec_free (port_desc);
20665
20666   S (mp);
20667   W (ret);
20668   return ret;
20669 }
20670
20671 static int
20672 api_tcp_configure_src_addresses (vat_main_t * vam)
20673 {
20674   vl_api_tcp_configure_src_addresses_t *mp;
20675   unformat_input_t *i = vam->input;
20676   ip4_address_t v4first, v4last;
20677   ip6_address_t v6first, v6last;
20678   u8 range_set = 0;
20679   u32 vrf_id = 0;
20680   int ret;
20681
20682   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20683     {
20684       if (unformat (i, "%U - %U",
20685                     unformat_ip4_address, &v4first,
20686                     unformat_ip4_address, &v4last))
20687         {
20688           if (range_set)
20689             {
20690               errmsg ("one range per message (range already set)");
20691               return -99;
20692             }
20693           range_set = 1;
20694         }
20695       else if (unformat (i, "%U - %U",
20696                          unformat_ip6_address, &v6first,
20697                          unformat_ip6_address, &v6last))
20698         {
20699           if (range_set)
20700             {
20701               errmsg ("one range per message (range already set)");
20702               return -99;
20703             }
20704           range_set = 2;
20705         }
20706       else if (unformat (i, "vrf %d", &vrf_id))
20707         ;
20708       else
20709         break;
20710     }
20711
20712   if (range_set == 0)
20713     {
20714       errmsg ("address range not set");
20715       return -99;
20716     }
20717
20718   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20719   mp->vrf_id = ntohl (vrf_id);
20720   /* ipv6? */
20721   if (range_set == 2)
20722     {
20723       mp->is_ipv6 = 1;
20724       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20725       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20726     }
20727   else
20728     {
20729       mp->is_ipv6 = 0;
20730       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20731       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20732     }
20733   S (mp);
20734   W (ret);
20735   return ret;
20736 }
20737
20738 static int
20739 api_memfd_segment_create (vat_main_t * vam)
20740 {
20741   unformat_input_t *i = vam->input;
20742   vl_api_memfd_segment_create_t *mp;
20743   u64 size = 64 << 20;
20744   int ret;
20745
20746 #if VPP_API_TEST_BUILTIN == 1
20747   errmsg ("memfd_segment_create (builtin) not supported");
20748   return -99;
20749 #endif
20750
20751   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20752     {
20753       if (unformat (i, "size %U", unformat_memory_size, &size))
20754         ;
20755       else
20756         break;
20757     }
20758
20759   M (MEMFD_SEGMENT_CREATE, mp);
20760   mp->requested_size = size;
20761   S (mp);
20762   W (ret);
20763   return ret;
20764 }
20765
20766 static int
20767 q_or_quit (vat_main_t * vam)
20768 {
20769 #if VPP_API_TEST_BUILTIN == 0
20770   longjmp (vam->jump_buf, 1);
20771 #endif
20772   return 0;                     /* not so much */
20773 }
20774
20775 static int
20776 q (vat_main_t * vam)
20777 {
20778   return q_or_quit (vam);
20779 }
20780
20781 static int
20782 quit (vat_main_t * vam)
20783 {
20784   return q_or_quit (vam);
20785 }
20786
20787 static int
20788 comment (vat_main_t * vam)
20789 {
20790   return 0;
20791 }
20792
20793 static int
20794 cmd_cmp (void *a1, void *a2)
20795 {
20796   u8 **c1 = a1;
20797   u8 **c2 = a2;
20798
20799   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
20800 }
20801
20802 static int
20803 help (vat_main_t * vam)
20804 {
20805   u8 **cmds = 0;
20806   u8 *name = 0;
20807   hash_pair_t *p;
20808   unformat_input_t *i = vam->input;
20809   int j;
20810
20811   if (unformat (i, "%s", &name))
20812     {
20813       uword *hs;
20814
20815       vec_add1 (name, 0);
20816
20817       hs = hash_get_mem (vam->help_by_name, name);
20818       if (hs)
20819         print (vam->ofp, "usage: %s %s", name, hs[0]);
20820       else
20821         print (vam->ofp, "No such msg / command '%s'", name);
20822       vec_free (name);
20823       return 0;
20824     }
20825
20826   print (vam->ofp, "Help is available for the following:");
20827
20828     /* *INDENT-OFF* */
20829     hash_foreach_pair (p, vam->function_by_name,
20830     ({
20831       vec_add1 (cmds, (u8 *)(p->key));
20832     }));
20833     /* *INDENT-ON* */
20834
20835   vec_sort_with_function (cmds, cmd_cmp);
20836
20837   for (j = 0; j < vec_len (cmds); j++)
20838     print (vam->ofp, "%s", cmds[j]);
20839
20840   vec_free (cmds);
20841   return 0;
20842 }
20843
20844 static int
20845 set (vat_main_t * vam)
20846 {
20847   u8 *name = 0, *value = 0;
20848   unformat_input_t *i = vam->input;
20849
20850   if (unformat (i, "%s", &name))
20851     {
20852       /* The input buffer is a vector, not a string. */
20853       value = vec_dup (i->buffer);
20854       vec_delete (value, i->index, 0);
20855       /* Almost certainly has a trailing newline */
20856       if (value[vec_len (value) - 1] == '\n')
20857         value[vec_len (value) - 1] = 0;
20858       /* Make sure it's a proper string, one way or the other */
20859       vec_add1 (value, 0);
20860       (void) clib_macro_set_value (&vam->macro_main,
20861                                    (char *) name, (char *) value);
20862     }
20863   else
20864     errmsg ("usage: set <name> <value>");
20865
20866   vec_free (name);
20867   vec_free (value);
20868   return 0;
20869 }
20870
20871 static int
20872 unset (vat_main_t * vam)
20873 {
20874   u8 *name = 0;
20875
20876   if (unformat (vam->input, "%s", &name))
20877     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
20878       errmsg ("unset: %s wasn't set", name);
20879   vec_free (name);
20880   return 0;
20881 }
20882
20883 typedef struct
20884 {
20885   u8 *name;
20886   u8 *value;
20887 } macro_sort_t;
20888
20889
20890 static int
20891 macro_sort_cmp (void *a1, void *a2)
20892 {
20893   macro_sort_t *s1 = a1;
20894   macro_sort_t *s2 = a2;
20895
20896   return strcmp ((char *) (s1->name), (char *) (s2->name));
20897 }
20898
20899 static int
20900 dump_macro_table (vat_main_t * vam)
20901 {
20902   macro_sort_t *sort_me = 0, *sm;
20903   int i;
20904   hash_pair_t *p;
20905
20906     /* *INDENT-OFF* */
20907     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
20908     ({
20909       vec_add2 (sort_me, sm, 1);
20910       sm->name = (u8 *)(p->key);
20911       sm->value = (u8 *) (p->value[0]);
20912     }));
20913     /* *INDENT-ON* */
20914
20915   vec_sort_with_function (sort_me, macro_sort_cmp);
20916
20917   if (vec_len (sort_me))
20918     print (vam->ofp, "%-15s%s", "Name", "Value");
20919   else
20920     print (vam->ofp, "The macro table is empty...");
20921
20922   for (i = 0; i < vec_len (sort_me); i++)
20923     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
20924   return 0;
20925 }
20926
20927 static int
20928 dump_node_table (vat_main_t * vam)
20929 {
20930   int i, j;
20931   vlib_node_t *node, *next_node;
20932
20933   if (vec_len (vam->graph_nodes) == 0)
20934     {
20935       print (vam->ofp, "Node table empty, issue get_node_graph...");
20936       return 0;
20937     }
20938
20939   for (i = 0; i < vec_len (vam->graph_nodes); i++)
20940     {
20941       node = vam->graph_nodes[i];
20942       print (vam->ofp, "[%d] %s", i, node->name);
20943       for (j = 0; j < vec_len (node->next_nodes); j++)
20944         {
20945           if (node->next_nodes[j] != ~0)
20946             {
20947               next_node = vam->graph_nodes[node->next_nodes[j]];
20948               print (vam->ofp, "  [%d] %s", j, next_node->name);
20949             }
20950         }
20951     }
20952   return 0;
20953 }
20954
20955 static int
20956 value_sort_cmp (void *a1, void *a2)
20957 {
20958   name_sort_t *n1 = a1;
20959   name_sort_t *n2 = a2;
20960
20961   if (n1->value < n2->value)
20962     return -1;
20963   if (n1->value > n2->value)
20964     return 1;
20965   return 0;
20966 }
20967
20968
20969 static int
20970 dump_msg_api_table (vat_main_t * vam)
20971 {
20972   api_main_t *am = &api_main;
20973   name_sort_t *nses = 0, *ns;
20974   hash_pair_t *hp;
20975   int i;
20976
20977   /* *INDENT-OFF* */
20978   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
20979   ({
20980     vec_add2 (nses, ns, 1);
20981     ns->name = (u8 *)(hp->key);
20982     ns->value = (u32) hp->value[0];
20983   }));
20984   /* *INDENT-ON* */
20985
20986   vec_sort_with_function (nses, value_sort_cmp);
20987
20988   for (i = 0; i < vec_len (nses); i++)
20989     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
20990   vec_free (nses);
20991   return 0;
20992 }
20993
20994 static int
20995 get_msg_id (vat_main_t * vam)
20996 {
20997   u8 *name_and_crc;
20998   u32 message_index;
20999
21000   if (unformat (vam->input, "%s", &name_and_crc))
21001     {
21002       message_index = vl_api_get_msg_index (name_and_crc);
21003       if (message_index == ~0)
21004         {
21005           print (vam->ofp, " '%s' not found", name_and_crc);
21006           return 0;
21007         }
21008       print (vam->ofp, " '%s' has message index %d",
21009              name_and_crc, message_index);
21010       return 0;
21011     }
21012   errmsg ("name_and_crc required...");
21013   return 0;
21014 }
21015
21016 static int
21017 search_node_table (vat_main_t * vam)
21018 {
21019   unformat_input_t *line_input = vam->input;
21020   u8 *node_to_find;
21021   int j;
21022   vlib_node_t *node, *next_node;
21023   uword *p;
21024
21025   if (vam->graph_node_index_by_name == 0)
21026     {
21027       print (vam->ofp, "Node table empty, issue get_node_graph...");
21028       return 0;
21029     }
21030
21031   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21032     {
21033       if (unformat (line_input, "%s", &node_to_find))
21034         {
21035           vec_add1 (node_to_find, 0);
21036           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21037           if (p == 0)
21038             {
21039               print (vam->ofp, "%s not found...", node_to_find);
21040               goto out;
21041             }
21042           node = vam->graph_nodes[p[0]];
21043           print (vam->ofp, "[%d] %s", p[0], node->name);
21044           for (j = 0; j < vec_len (node->next_nodes); j++)
21045             {
21046               if (node->next_nodes[j] != ~0)
21047                 {
21048                   next_node = vam->graph_nodes[node->next_nodes[j]];
21049                   print (vam->ofp, "  [%d] %s", j, next_node->name);
21050                 }
21051             }
21052         }
21053
21054       else
21055         {
21056           clib_warning ("parse error '%U'", format_unformat_error,
21057                         line_input);
21058           return -99;
21059         }
21060
21061     out:
21062       vec_free (node_to_find);
21063
21064     }
21065
21066   return 0;
21067 }
21068
21069
21070 static int
21071 script (vat_main_t * vam)
21072 {
21073 #if (VPP_API_TEST_BUILTIN==0)
21074   u8 *s = 0;
21075   char *save_current_file;
21076   unformat_input_t save_input;
21077   jmp_buf save_jump_buf;
21078   u32 save_line_number;
21079
21080   FILE *new_fp, *save_ifp;
21081
21082   if (unformat (vam->input, "%s", &s))
21083     {
21084       new_fp = fopen ((char *) s, "r");
21085       if (new_fp == 0)
21086         {
21087           errmsg ("Couldn't open script file %s", s);
21088           vec_free (s);
21089           return -99;
21090         }
21091     }
21092   else
21093     {
21094       errmsg ("Missing script name");
21095       return -99;
21096     }
21097
21098   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
21099   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
21100   save_ifp = vam->ifp;
21101   save_line_number = vam->input_line_number;
21102   save_current_file = (char *) vam->current_file;
21103
21104   vam->input_line_number = 0;
21105   vam->ifp = new_fp;
21106   vam->current_file = s;
21107   do_one_file (vam);
21108
21109   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
21110   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
21111   vam->ifp = save_ifp;
21112   vam->input_line_number = save_line_number;
21113   vam->current_file = (u8 *) save_current_file;
21114   vec_free (s);
21115
21116   return 0;
21117 #else
21118   clib_warning ("use the exec command...");
21119   return -99;
21120 #endif
21121 }
21122
21123 static int
21124 echo (vat_main_t * vam)
21125 {
21126   print (vam->ofp, "%v", vam->input->buffer);
21127   return 0;
21128 }
21129
21130 /* List of API message constructors, CLI names map to api_xxx */
21131 #define foreach_vpe_api_msg                                             \
21132 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
21133 _(sw_interface_dump,"")                                                 \
21134 _(sw_interface_set_flags,                                               \
21135   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
21136 _(sw_interface_add_del_address,                                         \
21137   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
21138 _(sw_interface_set_table,                                               \
21139   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
21140 _(sw_interface_set_mpls_enable,                                         \
21141   "<intfc> | sw_if_index [disable | dis]")                              \
21142 _(sw_interface_set_vpath,                                               \
21143   "<intfc> | sw_if_index <id> enable | disable")                        \
21144 _(sw_interface_set_vxlan_bypass,                                        \
21145   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21146 _(sw_interface_set_geneve_bypass,                                       \
21147   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21148 _(sw_interface_set_l2_xconnect,                                         \
21149   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21150   "enable | disable")                                                   \
21151 _(sw_interface_set_l2_bridge,                                           \
21152   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
21153   "[shg <split-horizon-group>] [bvi]\n"                                 \
21154   "enable | disable")                                                   \
21155 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
21156 _(bridge_domain_add_del,                                                \
21157   "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") \
21158 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
21159 _(l2fib_add_del,                                                        \
21160   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
21161 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
21162 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
21163 _(l2_flags,                                                             \
21164   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21165 _(bridge_flags,                                                         \
21166   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21167 _(tap_connect,                                                          \
21168   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
21169 _(tap_modify,                                                           \
21170   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
21171 _(tap_delete,                                                           \
21172   "<vpp-if-name> | sw_if_index <id>")                                   \
21173 _(sw_interface_tap_dump, "")                                            \
21174 _(ip_table_add_del,                                                     \
21175   "table-id <n> [ipv6]\n")                                              \
21176 _(ip_add_del_route,                                                     \
21177   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
21178   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
21179   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
21180   "[multipath] [count <n>]")                                            \
21181 _(ip_mroute_add_del,                                                    \
21182   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
21183   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
21184 _(mpls_table_add_del,                                                   \
21185   "table-id <n>\n")                                                     \
21186 _(mpls_route_add_del,                                                   \
21187   "<label> <eos> via <addr> [table-id <n>]\n"                           \
21188   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
21189   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
21190   "[multipath] [count <n>]")                                            \
21191 _(mpls_ip_bind_unbind,                                                  \
21192   "<label> <addr/len>")                                                 \
21193 _(mpls_tunnel_add_del,                                                  \
21194   " via <addr> [table-id <n>]\n"                                        \
21195   "sw_if_index <id>] [l2]  [del]")                                      \
21196 _(proxy_arp_add_del,                                                    \
21197   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
21198 _(proxy_arp_intfc_enable_disable,                                       \
21199   "<intfc> | sw_if_index <id> enable | disable")                        \
21200 _(sw_interface_set_unnumbered,                                          \
21201   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
21202 _(ip_neighbor_add_del,                                                  \
21203   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
21204   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
21205 _(reset_vrf, "vrf <id> [ipv6]")                                         \
21206 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
21207 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
21208   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
21209   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
21210   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
21211 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
21212 _(reset_fib, "vrf <n> [ipv6]")                                          \
21213 _(dhcp_proxy_config,                                                    \
21214   "svr <v46-address> src <v46-address>\n"                               \
21215    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
21216 _(dhcp_proxy_set_vss,                                                   \
21217   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
21218 _(dhcp_proxy_dump, "ip6")                                               \
21219 _(dhcp_client_config,                                                   \
21220   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
21221 _(set_ip_flow_hash,                                                     \
21222   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
21223 _(sw_interface_ip6_enable_disable,                                      \
21224   "<intfc> | sw_if_index <id> enable | disable")                        \
21225 _(sw_interface_ip6_set_link_local_address,                              \
21226   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
21227 _(ip6nd_proxy_add_del,                                                  \
21228   "<intfc> | sw_if_index <id> <ip6-address>")                           \
21229 _(ip6nd_proxy_dump, "")                                                 \
21230 _(sw_interface_ip6nd_ra_prefix,                                         \
21231   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
21232   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
21233   "[nolink] [isno]")                                                    \
21234 _(sw_interface_ip6nd_ra_config,                                         \
21235   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
21236   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
21237   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
21238 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
21239 _(l2_patch_add_del,                                                     \
21240   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21241   "enable | disable")                                                   \
21242 _(sr_localsid_add_del,                                                  \
21243   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
21244   "fib-table <num> (end.psp) sw_if_index <num>")                        \
21245 _(classify_add_del_table,                                               \
21246   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
21247   " [del] [del-chain] mask <mask-value>\n"                              \
21248   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
21249   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
21250 _(classify_add_del_session,                                             \
21251   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
21252   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
21253   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
21254   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
21255 _(classify_set_interface_ip_table,                                      \
21256   "<intfc> | sw_if_index <nn> table <nn>")                              \
21257 _(classify_set_interface_l2_tables,                                     \
21258   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21259   "  [other-table <nn>]")                                               \
21260 _(get_node_index, "node <node-name")                                    \
21261 _(add_node_next, "node <node-name> next <next-node-name>")              \
21262 _(l2tpv3_create_tunnel,                                                 \
21263   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
21264   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
21265   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
21266 _(l2tpv3_set_tunnel_cookies,                                            \
21267   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
21268   "[new_remote_cookie <nn>]\n")                                         \
21269 _(l2tpv3_interface_enable_disable,                                      \
21270   "<intfc> | sw_if_index <nn> enable | disable")                        \
21271 _(l2tpv3_set_lookup_key,                                                \
21272   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
21273 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
21274 _(vxlan_add_del_tunnel,                                                 \
21275   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21276   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21277   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21278 _(geneve_add_del_tunnel,                                                \
21279   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21280   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21281   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21282 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
21283 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
21284 _(gre_add_del_tunnel,                                                   \
21285   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
21286 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
21287 _(l2_fib_clear_table, "")                                               \
21288 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
21289 _(l2_interface_vlan_tag_rewrite,                                        \
21290   "<intfc> | sw_if_index <nn> \n"                                       \
21291   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
21292   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
21293 _(create_vhost_user_if,                                                 \
21294         "socket <filename> [server] [renumber <dev_instance>] "         \
21295         "[mac <mac_address>]")                                          \
21296 _(modify_vhost_user_if,                                                 \
21297         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
21298         "[server] [renumber <dev_instance>]")                           \
21299 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
21300 _(sw_interface_vhost_user_dump, "")                                     \
21301 _(show_version, "")                                                     \
21302 _(vxlan_gpe_add_del_tunnel,                                             \
21303   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
21304   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21305   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
21306   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
21307 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
21308 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
21309 _(interface_name_renumber,                                              \
21310   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
21311 _(input_acl_set_interface,                                              \
21312   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21313   "  [l2-table <nn>] [del]")                                            \
21314 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
21315 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
21316 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
21317 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
21318 _(ip_dump, "ipv4 | ipv6")                                               \
21319 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
21320 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
21321   "  spid_id <n> ")                                                     \
21322 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
21323   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
21324   "  integ_alg <alg> integ_key <hex>")                                  \
21325 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
21326   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
21327   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
21328   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
21329 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
21330 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
21331   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
21332   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
21333   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
21334 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
21335 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
21336 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
21337   "(auth_data 0x<data> | auth_data <data>)")                            \
21338 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
21339   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
21340 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
21341   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
21342   "(local|remote)")                                                     \
21343 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
21344 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
21345 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
21346 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
21347 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
21348 _(ikev2_initiate_sa_init, "<profile_name>")                             \
21349 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
21350 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
21351 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
21352 _(delete_loopback,"sw_if_index <nn>")                                   \
21353 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
21354 _(map_add_domain,                                                       \
21355   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
21356   "ip6-src <ip6addr> "                                                  \
21357   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
21358 _(map_del_domain, "index <n>")                                          \
21359 _(map_add_del_rule,                                                     \
21360   "index <n> psid <n> dst <ip6addr> [del]")                             \
21361 _(map_domain_dump, "")                                                  \
21362 _(map_rule_dump, "index <map-domain>")                                  \
21363 _(want_interface_events,  "enable|disable")                             \
21364 _(want_stats,"enable|disable")                                          \
21365 _(get_first_msg_id, "client <name>")                                    \
21366 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
21367 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
21368   "fib-id <nn> [ip4][ip6][default]")                                    \
21369 _(get_node_graph, " ")                                                  \
21370 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
21371 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
21372 _(ioam_disable, "")                                                     \
21373 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
21374                             " sw_if_index <sw_if_index> p <priority> "  \
21375                             "w <weight>] [del]")                        \
21376 _(one_add_del_locator, "locator-set <locator_name> "                    \
21377                         "iface <intf> | sw_if_index <sw_if_index> "     \
21378                         "p <priority> w <weight> [del]")                \
21379 _(one_add_del_local_eid,"vni <vni> eid "                                \
21380                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21381                          "locator-set <locator_name> [del]"             \
21382                          "[key-id sha1|sha256 secret-key <secret-key>]")\
21383 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
21384 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
21385 _(one_enable_disable, "enable|disable")                                 \
21386 _(one_map_register_enable_disable, "enable|disable")                    \
21387 _(one_map_register_fallback_threshold, "<value>")                       \
21388 _(one_rloc_probe_enable_disable, "enable|disable")                      \
21389 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
21390                                "[seid <seid>] "                         \
21391                                "rloc <locator> p <prio> "               \
21392                                "w <weight> [rloc <loc> ... ] "          \
21393                                "action <action> [del-all]")             \
21394 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
21395                           "<local-eid>")                                \
21396 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
21397 _(one_use_petr, "ip-address> | disable")                                \
21398 _(one_map_request_mode, "src-dst|dst-only")                             \
21399 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
21400 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
21401 _(one_locator_set_dump, "[local | remote]")                             \
21402 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
21403 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
21404                        "[local] | [remote]")                            \
21405 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
21406 _(one_ndp_bd_get, "")                                                   \
21407 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
21408 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
21409 _(one_l2_arp_bd_get, "")                                                \
21410 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
21411 _(one_stats_enable_disable, "enable|disalbe")                           \
21412 _(show_one_stats_enable_disable, "")                                    \
21413 _(one_eid_table_vni_dump, "")                                           \
21414 _(one_eid_table_map_dump, "l2|l3")                                      \
21415 _(one_map_resolver_dump, "")                                            \
21416 _(one_map_server_dump, "")                                              \
21417 _(one_adjacencies_get, "vni <vni>")                                     \
21418 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
21419 _(show_one_rloc_probe_state, "")                                        \
21420 _(show_one_map_register_state, "")                                      \
21421 _(show_one_status, "")                                                  \
21422 _(one_stats_dump, "")                                                   \
21423 _(one_stats_flush, "")                                                  \
21424 _(one_get_map_request_itr_rlocs, "")                                    \
21425 _(one_map_register_set_ttl, "<ttl>")                                    \
21426 _(one_set_transport_protocol, "udp|api")                                \
21427 _(one_get_transport_protocol, "")                                       \
21428 _(show_one_nsh_mapping, "")                                             \
21429 _(show_one_pitr, "")                                                    \
21430 _(show_one_use_petr, "")                                                \
21431 _(show_one_map_request_mode, "")                                        \
21432 _(show_one_map_register_ttl, "")                                        \
21433 _(show_one_map_register_fallback_threshold, "")                         \
21434 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
21435                             " sw_if_index <sw_if_index> p <priority> "  \
21436                             "w <weight>] [del]")                        \
21437 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
21438                         "iface <intf> | sw_if_index <sw_if_index> "     \
21439                         "p <priority> w <weight> [del]")                \
21440 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
21441                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21442                          "locator-set <locator_name> [del]"             \
21443                          "[key-id sha1|sha256 secret-key <secret-key>]") \
21444 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
21445 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
21446 _(lisp_enable_disable, "enable|disable")                                \
21447 _(lisp_map_register_enable_disable, "enable|disable")                   \
21448 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
21449 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
21450                                "[seid <seid>] "                         \
21451                                "rloc <locator> p <prio> "               \
21452                                "w <weight> [rloc <loc> ... ] "          \
21453                                "action <action> [del-all]")             \
21454 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
21455                           "<local-eid>")                                \
21456 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
21457 _(lisp_use_petr, "<ip-address> | disable")                              \
21458 _(lisp_map_request_mode, "src-dst|dst-only")                            \
21459 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
21460 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
21461 _(lisp_locator_set_dump, "[local | remote]")                            \
21462 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
21463 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
21464                        "[local] | [remote]")                            \
21465 _(lisp_eid_table_vni_dump, "")                                          \
21466 _(lisp_eid_table_map_dump, "l2|l3")                                     \
21467 _(lisp_map_resolver_dump, "")                                           \
21468 _(lisp_map_server_dump, "")                                             \
21469 _(lisp_adjacencies_get, "vni <vni>")                                    \
21470 _(gpe_fwd_entry_vnis_get, "")                                           \
21471 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
21472 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
21473                                 "[table <table-id>]")                   \
21474 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
21475 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
21476 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
21477 _(gpe_get_encap_mode, "")                                               \
21478 _(lisp_gpe_add_del_iface, "up|down")                                    \
21479 _(lisp_gpe_enable_disable, "enable|disable")                            \
21480 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
21481   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
21482 _(show_lisp_rloc_probe_state, "")                                       \
21483 _(show_lisp_map_register_state, "")                                     \
21484 _(show_lisp_status, "")                                                 \
21485 _(lisp_get_map_request_itr_rlocs, "")                                   \
21486 _(show_lisp_pitr, "")                                                   \
21487 _(show_lisp_use_petr, "")                                               \
21488 _(show_lisp_map_request_mode, "")                                       \
21489 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
21490 _(af_packet_delete, "name <host interface name>")                       \
21491 _(policer_add_del, "name <policer name> <params> [del]")                \
21492 _(policer_dump, "[name <policer name>]")                                \
21493 _(policer_classify_set_interface,                                       \
21494   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21495   "  [l2-table <nn>] [del]")                                            \
21496 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
21497 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
21498     "[master|slave]")                                                   \
21499 _(netmap_delete, "name <interface name>")                               \
21500 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
21501 _(mpls_fib_dump, "")                                                    \
21502 _(classify_table_ids, "")                                               \
21503 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
21504 _(classify_table_info, "table_id <nn>")                                 \
21505 _(classify_session_dump, "table_id <nn>")                               \
21506 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
21507     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
21508     "[template_interval <nn>] [udp_checksum]")                          \
21509 _(ipfix_exporter_dump, "")                                              \
21510 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
21511 _(ipfix_classify_stream_dump, "")                                       \
21512 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
21513 _(ipfix_classify_table_dump, "")                                        \
21514 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
21515 _(sw_interface_span_dump, "[l2]")                                           \
21516 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
21517 _(pg_create_interface, "if_id <nn>")                                    \
21518 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
21519 _(pg_enable_disable, "[stream <id>] disable")                           \
21520 _(ip_source_and_port_range_check_add_del,                               \
21521   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
21522 _(ip_source_and_port_range_check_interface_add_del,                     \
21523   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
21524   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
21525 _(ipsec_gre_add_del_tunnel,                                             \
21526   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
21527 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
21528 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
21529 _(l2_interface_pbb_tag_rewrite,                                         \
21530   "<intfc> | sw_if_index <nn> \n"                                       \
21531   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
21532   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
21533 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
21534 _(flow_classify_set_interface,                                          \
21535   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
21536 _(flow_classify_dump, "type [ip4|ip6]")                                 \
21537 _(ip_fib_dump, "")                                                      \
21538 _(ip_mfib_dump, "")                                                     \
21539 _(ip6_fib_dump, "")                                                     \
21540 _(ip6_mfib_dump, "")                                                    \
21541 _(feature_enable_disable, "arc_name <arc_name> "                        \
21542   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
21543 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
21544 "[disable]")                                                            \
21545 _(l2_xconnect_dump, "")                                                 \
21546 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
21547 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
21548 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
21549 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
21550 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
21551 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
21552 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>] [disable]") \
21553 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
21554 _(memfd_segment_create,"size <nnn>")
21555
21556 /* List of command functions, CLI names map directly to functions */
21557 #define foreach_cli_function                                    \
21558 _(comment, "usage: comment <ignore-rest-of-line>")              \
21559 _(dump_interface_table, "usage: dump_interface_table")          \
21560 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21561 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21562 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21563 _(dump_stats_table, "usage: dump_stats_table")                  \
21564 _(dump_macro_table, "usage: dump_macro_table ")                 \
21565 _(dump_node_table, "usage: dump_node_table")                    \
21566 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21567 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21568 _(echo, "usage: echo <message>")                                \
21569 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21570 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21571 _(help, "usage: help")                                          \
21572 _(q, "usage: quit")                                             \
21573 _(quit, "usage: quit")                                          \
21574 _(search_node_table, "usage: search_node_table <name>...")      \
21575 _(set, "usage: set <variable-name> <value>")                    \
21576 _(script, "usage: script <file-name>")                          \
21577 _(unset, "usage: unset <variable-name>")
21578 #define _(N,n)                                  \
21579     static void vl_api_##n##_t_handler_uni      \
21580     (vl_api_##n##_t * mp)                       \
21581     {                                           \
21582         vat_main_t * vam = &vat_main;           \
21583         if (vam->json_output) {                 \
21584             vl_api_##n##_t_handler_json(mp);    \
21585         } else {                                \
21586             vl_api_##n##_t_handler(mp);         \
21587         }                                       \
21588     }
21589 foreach_vpe_api_reply_msg;
21590 #if VPP_API_TEST_BUILTIN == 0
21591 foreach_standalone_reply_msg;
21592 #endif
21593 #undef _
21594
21595 void
21596 vat_api_hookup (vat_main_t * vam)
21597 {
21598 #define _(N,n)                                                  \
21599     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21600                            vl_api_##n##_t_handler_uni,          \
21601                            vl_noop_handler,                     \
21602                            vl_api_##n##_t_endian,               \
21603                            vl_api_##n##_t_print,                \
21604                            sizeof(vl_api_##n##_t), 1);
21605   foreach_vpe_api_reply_msg;
21606 #if VPP_API_TEST_BUILTIN == 0
21607   foreach_standalone_reply_msg;
21608 #endif
21609 #undef _
21610
21611 #if (VPP_API_TEST_BUILTIN==0)
21612   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
21613
21614   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
21615
21616   vam->function_by_name = hash_create_string (0, sizeof (uword));
21617
21618   vam->help_by_name = hash_create_string (0, sizeof (uword));
21619 #endif
21620
21621   /* API messages we can send */
21622 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
21623   foreach_vpe_api_msg;
21624 #undef _
21625
21626   /* Help strings */
21627 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21628   foreach_vpe_api_msg;
21629 #undef _
21630
21631   /* CLI functions */
21632 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
21633   foreach_cli_function;
21634 #undef _
21635
21636   /* Help strings */
21637 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21638   foreach_cli_function;
21639 #undef _
21640 }
21641
21642 #if VPP_API_TEST_BUILTIN
21643 static clib_error_t *
21644 vat_api_hookup_shim (vlib_main_t * vm)
21645 {
21646   vat_api_hookup (&vat_main);
21647   return 0;
21648 }
21649
21650 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
21651 #endif
21652
21653 /*
21654  * fd.io coding-style-patch-verification: ON
21655  *
21656  * Local Variables:
21657  * eval: (c-set-style "gnu")
21658  * End:
21659  */