session: add support for application namespacing
[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 _(app_namespace_add_del_reply)
5121
5122 #define _(n)                                    \
5123     static void vl_api_##n##_t_handler          \
5124     (vl_api_##n##_t * mp)                       \
5125     {                                           \
5126         vat_main_t * vam = &vat_main;           \
5127         i32 retval = ntohl(mp->retval);         \
5128         if (vam->async_mode) {                  \
5129             vam->async_errors += (retval < 0);  \
5130         } else {                                \
5131             vam->retval = retval;               \
5132             vam->result_ready = 1;              \
5133         }                                       \
5134     }
5135 foreach_standard_reply_retval_handler;
5136 #undef _
5137
5138 #define _(n)                                    \
5139     static void vl_api_##n##_t_handler_json     \
5140     (vl_api_##n##_t * mp)                       \
5141     {                                           \
5142         vat_main_t * vam = &vat_main;           \
5143         vat_json_node_t node;                   \
5144         vat_json_init_object(&node);            \
5145         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5146         vat_json_print(vam->ofp, &node);        \
5147         vam->retval = ntohl(mp->retval);        \
5148         vam->result_ready = 1;                  \
5149     }
5150 foreach_standard_reply_retval_handler;
5151 #undef _
5152
5153 /*
5154  * Table of message reply handlers, must include boilerplate handlers
5155  * we just generated
5156  */
5157
5158 #define foreach_vpe_api_reply_msg                                       \
5159 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5160 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5161 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5162 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5163 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5164 _(CLI_REPLY, cli_reply)                                                 \
5165 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5166 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5167   sw_interface_add_del_address_reply)                                   \
5168 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5169 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5170 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5171 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5172 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5173 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5174 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5175   sw_interface_set_l2_xconnect_reply)                                   \
5176 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5177   sw_interface_set_l2_bridge_reply)                                     \
5178 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5179 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5180 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5181 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5182 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5183 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5184 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5185 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5186 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
5187 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
5188 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
5189 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
5190 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
5191 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5192 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5193 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5194 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5195 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5196 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5197 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5198   proxy_arp_intfc_enable_disable_reply)                                 \
5199 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5200 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5201   sw_interface_set_unnumbered_reply)                                    \
5202 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5203 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
5204 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5205 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5206 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
5207 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5208 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
5209 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
5210 _(DHCP_PROXY_DETAILS, dhcp_proxy_details)                               \
5211 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
5212 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5213 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5214   sw_interface_ip6_enable_disable_reply)                                \
5215 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
5216   sw_interface_ip6_set_link_local_address_reply)                        \
5217 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5218 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5219 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5220   sw_interface_ip6nd_ra_prefix_reply)                                   \
5221 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5222   sw_interface_ip6nd_ra_config_reply)                                   \
5223 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5224 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5225 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5226 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5227 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5228 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5229 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5230 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5231 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5232 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5233 classify_set_interface_ip_table_reply)                                  \
5234 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5235   classify_set_interface_l2_tables_reply)                               \
5236 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5237 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5238 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5239 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5240 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5241   l2tpv3_interface_enable_disable_reply)                                \
5242 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5243 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5244 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5245 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5246 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5247 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5248 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
5249 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5250 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5251 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5252 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5253 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5254 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5255 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5256 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5257 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5258 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5259 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
5260 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5261 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5262 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5263 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5264 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5265 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5266 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5267 _(L2_MACS_EVENT, l2_macs_event)                                         \
5268 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5269 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5270 _(IP_DETAILS, ip_details)                                               \
5271 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5272 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5273 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
5274 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
5275 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5276 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
5277 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5278 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
5279 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
5280 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
5281 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
5282 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
5283 _(IKEV2_SET_RESPONDER_REPLY, ikev2_set_responder_reply)                 \
5284 _(IKEV2_SET_IKE_TRANSFORMS_REPLY, ikev2_set_ike_transforms_reply)       \
5285 _(IKEV2_SET_ESP_TRANSFORMS_REPLY, ikev2_set_esp_transforms_reply)       \
5286 _(IKEV2_SET_SA_LIFETIME_REPLY, ikev2_set_sa_lifetime_reply)             \
5287 _(IKEV2_INITIATE_SA_INIT_REPLY, ikev2_initiate_sa_init_reply)           \
5288 _(IKEV2_INITIATE_DEL_IKE_SA_REPLY, ikev2_initiate_del_ike_sa_reply)     \
5289 _(IKEV2_INITIATE_DEL_CHILD_SA_REPLY, ikev2_initiate_del_child_sa_reply) \
5290 _(IKEV2_INITIATE_REKEY_CHILD_SA_REPLY, ikev2_initiate_rekey_child_sa_reply) \
5291 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5292 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5293 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
5294 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
5295 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
5296 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
5297 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
5298 _(MAP_RULE_DETAILS, map_rule_details)                                   \
5299 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5300 _(WANT_STATS_REPLY, want_stats_reply)                                   \
5301 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5302 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5303 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5304 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5305 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5306 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5307 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5308 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5309 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5310 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5311 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5312 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5313 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5314 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5315 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5316 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5317   one_map_register_enable_disable_reply)                                \
5318 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5319 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5320 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5321 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5322   one_map_register_fallback_threshold_reply)                            \
5323 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5324   one_rloc_probe_enable_disable_reply)                                  \
5325 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5326 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5327 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5328 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5329 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5330 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5331 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5332 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5333 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5334 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5335 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5336 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5337 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5338 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5339 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5340 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5341   show_one_stats_enable_disable_reply)                                  \
5342 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5343 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5344 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5345 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5346 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5347 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5348 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5349 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5350 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5351 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5352 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5353 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5354 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5355 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5356 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5357   gpe_add_del_native_fwd_rpath_reply)                                   \
5358 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5359   gpe_fwd_entry_path_details)                                           \
5360 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5361 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5362   one_add_del_map_request_itr_rlocs_reply)                              \
5363 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5364   one_get_map_request_itr_rlocs_reply)                                  \
5365 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5366 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5367 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5368 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5369 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5370 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5371   show_one_map_register_state_reply)                                    \
5372 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5373 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5374   show_one_map_register_fallback_threshold_reply)                       \
5375 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5376 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5377 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5378 _(POLICER_DETAILS, policer_details)                                     \
5379 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5380 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5381 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5382 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5383 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5384 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
5385 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5386 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5387 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5388 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5389 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5390 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5391 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5392 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5393 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5394 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5395 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5396 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5397 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5398 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5399 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5400 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5401 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5402 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5403 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5404  ip_source_and_port_range_check_add_del_reply)                          \
5405 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5406  ip_source_and_port_range_check_interface_add_del_reply)                \
5407 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
5408 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
5409 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5410 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5411 _(PUNT_REPLY, punt_reply)                                               \
5412 _(IP_FIB_DETAILS, ip_fib_details)                                       \
5413 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
5414 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5415 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5416 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5417 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
5418 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5419 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5420 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5421 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5422 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5423 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5424 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5425 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)
5426
5427 #define foreach_standalone_reply_msg                                    \
5428 _(SW_INTERFACE_EVENT, sw_interface_event)                               \
5429 _(VNET_INTERFACE_SIMPLE_COUNTERS, vnet_interface_simple_counters)       \
5430 _(VNET_INTERFACE_COMBINED_COUNTERS, vnet_interface_combined_counters)   \
5431 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
5432 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
5433 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
5434 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
5435 _(MEMFD_SEGMENT_CREATE_REPLY, memfd_segment_create_reply)
5436
5437 typedef struct
5438 {
5439   u8 *name;
5440   u32 value;
5441 } name_sort_t;
5442
5443
5444 #define STR_VTR_OP_CASE(op)     \
5445     case L2_VTR_ ## op:         \
5446         return "" # op;
5447
5448 static const char *
5449 str_vtr_op (u32 vtr_op)
5450 {
5451   switch (vtr_op)
5452     {
5453       STR_VTR_OP_CASE (DISABLED);
5454       STR_VTR_OP_CASE (PUSH_1);
5455       STR_VTR_OP_CASE (PUSH_2);
5456       STR_VTR_OP_CASE (POP_1);
5457       STR_VTR_OP_CASE (POP_2);
5458       STR_VTR_OP_CASE (TRANSLATE_1_1);
5459       STR_VTR_OP_CASE (TRANSLATE_1_2);
5460       STR_VTR_OP_CASE (TRANSLATE_2_1);
5461       STR_VTR_OP_CASE (TRANSLATE_2_2);
5462     }
5463
5464   return "UNKNOWN";
5465 }
5466
5467 static int
5468 dump_sub_interface_table (vat_main_t * vam)
5469 {
5470   const sw_interface_subif_t *sub = NULL;
5471
5472   if (vam->json_output)
5473     {
5474       clib_warning
5475         ("JSON output supported only for VPE API calls and dump_stats_table");
5476       return -99;
5477     }
5478
5479   print (vam->ofp,
5480          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5481          "Interface", "sw_if_index",
5482          "sub id", "dot1ad", "tags", "outer id",
5483          "inner id", "exact", "default", "outer any", "inner any");
5484
5485   vec_foreach (sub, vam->sw_if_subif_table)
5486   {
5487     print (vam->ofp,
5488            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5489            sub->interface_name,
5490            sub->sw_if_index,
5491            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5492            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5493            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5494            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5495     if (sub->vtr_op != L2_VTR_DISABLED)
5496       {
5497         print (vam->ofp,
5498                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5499                "tag1: %d tag2: %d ]",
5500                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5501                sub->vtr_tag1, sub->vtr_tag2);
5502       }
5503   }
5504
5505   return 0;
5506 }
5507
5508 static int
5509 name_sort_cmp (void *a1, void *a2)
5510 {
5511   name_sort_t *n1 = a1;
5512   name_sort_t *n2 = a2;
5513
5514   return strcmp ((char *) n1->name, (char *) n2->name);
5515 }
5516
5517 static int
5518 dump_interface_table (vat_main_t * vam)
5519 {
5520   hash_pair_t *p;
5521   name_sort_t *nses = 0, *ns;
5522
5523   if (vam->json_output)
5524     {
5525       clib_warning
5526         ("JSON output supported only for VPE API calls and dump_stats_table");
5527       return -99;
5528     }
5529
5530   /* *INDENT-OFF* */
5531   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5532   ({
5533     vec_add2 (nses, ns, 1);
5534     ns->name = (u8 *)(p->key);
5535     ns->value = (u32) p->value[0];
5536   }));
5537   /* *INDENT-ON* */
5538
5539   vec_sort_with_function (nses, name_sort_cmp);
5540
5541   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5542   vec_foreach (ns, nses)
5543   {
5544     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5545   }
5546   vec_free (nses);
5547   return 0;
5548 }
5549
5550 static int
5551 dump_ip_table (vat_main_t * vam, int is_ipv6)
5552 {
5553   const ip_details_t *det = NULL;
5554   const ip_address_details_t *address = NULL;
5555   u32 i = ~0;
5556
5557   print (vam->ofp, "%-12s", "sw_if_index");
5558
5559   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5560   {
5561     i++;
5562     if (!det->present)
5563       {
5564         continue;
5565       }
5566     print (vam->ofp, "%-12d", i);
5567     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5568     if (!det->addr)
5569       {
5570         continue;
5571       }
5572     vec_foreach (address, det->addr)
5573     {
5574       print (vam->ofp,
5575              "            %-30U%-13d",
5576              is_ipv6 ? format_ip6_address : format_ip4_address,
5577              address->ip, address->prefix_length);
5578     }
5579   }
5580
5581   return 0;
5582 }
5583
5584 static int
5585 dump_ipv4_table (vat_main_t * vam)
5586 {
5587   if (vam->json_output)
5588     {
5589       clib_warning
5590         ("JSON output supported only for VPE API calls and dump_stats_table");
5591       return -99;
5592     }
5593
5594   return dump_ip_table (vam, 0);
5595 }
5596
5597 static int
5598 dump_ipv6_table (vat_main_t * vam)
5599 {
5600   if (vam->json_output)
5601     {
5602       clib_warning
5603         ("JSON output supported only for VPE API calls and dump_stats_table");
5604       return -99;
5605     }
5606
5607   return dump_ip_table (vam, 1);
5608 }
5609
5610 static char *
5611 counter_type_to_str (u8 counter_type, u8 is_combined)
5612 {
5613   if (!is_combined)
5614     {
5615       switch (counter_type)
5616         {
5617         case VNET_INTERFACE_COUNTER_DROP:
5618           return "drop";
5619         case VNET_INTERFACE_COUNTER_PUNT:
5620           return "punt";
5621         case VNET_INTERFACE_COUNTER_IP4:
5622           return "ip4";
5623         case VNET_INTERFACE_COUNTER_IP6:
5624           return "ip6";
5625         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
5626           return "rx-no-buf";
5627         case VNET_INTERFACE_COUNTER_RX_MISS:
5628           return "rx-miss";
5629         case VNET_INTERFACE_COUNTER_RX_ERROR:
5630           return "rx-error";
5631         case VNET_INTERFACE_COUNTER_TX_ERROR:
5632           return "tx-error";
5633         default:
5634           return "INVALID-COUNTER-TYPE";
5635         }
5636     }
5637   else
5638     {
5639       switch (counter_type)
5640         {
5641         case VNET_INTERFACE_COUNTER_RX:
5642           return "rx";
5643         case VNET_INTERFACE_COUNTER_TX:
5644           return "tx";
5645         default:
5646           return "INVALID-COUNTER-TYPE";
5647         }
5648     }
5649 }
5650
5651 static int
5652 dump_stats_table (vat_main_t * vam)
5653 {
5654   vat_json_node_t node;
5655   vat_json_node_t *msg_array;
5656   vat_json_node_t *msg;
5657   vat_json_node_t *counter_array;
5658   vat_json_node_t *counter;
5659   interface_counter_t c;
5660   u64 packets;
5661   ip4_fib_counter_t *c4;
5662   ip6_fib_counter_t *c6;
5663   ip4_nbr_counter_t *n4;
5664   ip6_nbr_counter_t *n6;
5665   int i, j;
5666
5667   if (!vam->json_output)
5668     {
5669       clib_warning ("dump_stats_table supported only in JSON format");
5670       return -99;
5671     }
5672
5673   vat_json_init_object (&node);
5674
5675   /* interface counters */
5676   msg_array = vat_json_object_add (&node, "interface_counters");
5677   vat_json_init_array (msg_array);
5678   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
5679     {
5680       msg = vat_json_array_add (msg_array);
5681       vat_json_init_object (msg);
5682       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5683                                        (u8 *) counter_type_to_str (i, 0));
5684       vat_json_object_add_int (msg, "is_combined", 0);
5685       counter_array = vat_json_object_add (msg, "data");
5686       vat_json_init_array (counter_array);
5687       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
5688         {
5689           packets = vam->simple_interface_counters[i][j];
5690           vat_json_array_add_uint (counter_array, packets);
5691         }
5692     }
5693   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
5694     {
5695       msg = vat_json_array_add (msg_array);
5696       vat_json_init_object (msg);
5697       vat_json_object_add_string_copy (msg, "vnet_counter_type",
5698                                        (u8 *) counter_type_to_str (i, 1));
5699       vat_json_object_add_int (msg, "is_combined", 1);
5700       counter_array = vat_json_object_add (msg, "data");
5701       vat_json_init_array (counter_array);
5702       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
5703         {
5704           c = vam->combined_interface_counters[i][j];
5705           counter = vat_json_array_add (counter_array);
5706           vat_json_init_object (counter);
5707           vat_json_object_add_uint (counter, "packets", c.packets);
5708           vat_json_object_add_uint (counter, "bytes", c.bytes);
5709         }
5710     }
5711
5712   /* ip4 fib counters */
5713   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
5714   vat_json_init_array (msg_array);
5715   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
5716     {
5717       msg = vat_json_array_add (msg_array);
5718       vat_json_init_object (msg);
5719       vat_json_object_add_uint (msg, "vrf_id",
5720                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
5721       counter_array = vat_json_object_add (msg, "c");
5722       vat_json_init_array (counter_array);
5723       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
5724         {
5725           counter = vat_json_array_add (counter_array);
5726           vat_json_init_object (counter);
5727           c4 = &vam->ip4_fib_counters[i][j];
5728           vat_json_object_add_ip4 (counter, "address", c4->address);
5729           vat_json_object_add_uint (counter, "address_length",
5730                                     c4->address_length);
5731           vat_json_object_add_uint (counter, "packets", c4->packets);
5732           vat_json_object_add_uint (counter, "bytes", c4->bytes);
5733         }
5734     }
5735
5736   /* ip6 fib counters */
5737   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
5738   vat_json_init_array (msg_array);
5739   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
5740     {
5741       msg = vat_json_array_add (msg_array);
5742       vat_json_init_object (msg);
5743       vat_json_object_add_uint (msg, "vrf_id",
5744                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
5745       counter_array = vat_json_object_add (msg, "c");
5746       vat_json_init_array (counter_array);
5747       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
5748         {
5749           counter = vat_json_array_add (counter_array);
5750           vat_json_init_object (counter);
5751           c6 = &vam->ip6_fib_counters[i][j];
5752           vat_json_object_add_ip6 (counter, "address", c6->address);
5753           vat_json_object_add_uint (counter, "address_length",
5754                                     c6->address_length);
5755           vat_json_object_add_uint (counter, "packets", c6->packets);
5756           vat_json_object_add_uint (counter, "bytes", c6->bytes);
5757         }
5758     }
5759
5760   /* ip4 nbr counters */
5761   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
5762   vat_json_init_array (msg_array);
5763   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
5764     {
5765       msg = vat_json_array_add (msg_array);
5766       vat_json_init_object (msg);
5767       vat_json_object_add_uint (msg, "sw_if_index", i);
5768       counter_array = vat_json_object_add (msg, "c");
5769       vat_json_init_array (counter_array);
5770       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
5771         {
5772           counter = vat_json_array_add (counter_array);
5773           vat_json_init_object (counter);
5774           n4 = &vam->ip4_nbr_counters[i][j];
5775           vat_json_object_add_ip4 (counter, "address", n4->address);
5776           vat_json_object_add_uint (counter, "link-type", n4->linkt);
5777           vat_json_object_add_uint (counter, "packets", n4->packets);
5778           vat_json_object_add_uint (counter, "bytes", n4->bytes);
5779         }
5780     }
5781
5782   /* ip6 nbr counters */
5783   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
5784   vat_json_init_array (msg_array);
5785   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
5786     {
5787       msg = vat_json_array_add (msg_array);
5788       vat_json_init_object (msg);
5789       vat_json_object_add_uint (msg, "sw_if_index", i);
5790       counter_array = vat_json_object_add (msg, "c");
5791       vat_json_init_array (counter_array);
5792       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
5793         {
5794           counter = vat_json_array_add (counter_array);
5795           vat_json_init_object (counter);
5796           n6 = &vam->ip6_nbr_counters[i][j];
5797           vat_json_object_add_ip6 (counter, "address", n6->address);
5798           vat_json_object_add_uint (counter, "packets", n6->packets);
5799           vat_json_object_add_uint (counter, "bytes", n6->bytes);
5800         }
5801     }
5802
5803   vat_json_print (vam->ofp, &node);
5804   vat_json_free (&node);
5805
5806   return 0;
5807 }
5808
5809 /*
5810  * Pass CLI buffers directly in the CLI_INBAND API message,
5811  * instead of an additional shared memory area.
5812  */
5813 static int
5814 exec_inband (vat_main_t * vam)
5815 {
5816   vl_api_cli_inband_t *mp;
5817   unformat_input_t *i = vam->input;
5818   int ret;
5819
5820   if (vec_len (i->buffer) == 0)
5821     return -1;
5822
5823   if (vam->exec_mode == 0 && unformat (i, "mode"))
5824     {
5825       vam->exec_mode = 1;
5826       return 0;
5827     }
5828   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5829     {
5830       vam->exec_mode = 0;
5831       return 0;
5832     }
5833
5834   /*
5835    * In order for the CLI command to work, it
5836    * must be a vector ending in \n, not a C-string ending
5837    * in \n\0.
5838    */
5839   u32 len = vec_len (vam->input->buffer);
5840   M2 (CLI_INBAND, mp, len);
5841   clib_memcpy (mp->cmd, vam->input->buffer, len);
5842   mp->length = htonl (len);
5843
5844   S (mp);
5845   W (ret);
5846   /* json responses may or may not include a useful reply... */
5847   if (vec_len (vam->cmd_reply))
5848     print (vam->ofp, (char *) (vam->cmd_reply));
5849   return ret;
5850 }
5851
5852 int
5853 exec (vat_main_t * vam)
5854 {
5855   return exec_inband (vam);
5856 }
5857
5858 static int
5859 api_create_loopback (vat_main_t * vam)
5860 {
5861   unformat_input_t *i = vam->input;
5862   vl_api_create_loopback_t *mp;
5863   vl_api_create_loopback_instance_t *mp_lbi;
5864   u8 mac_address[6];
5865   u8 mac_set = 0;
5866   u8 is_specified = 0;
5867   u32 user_instance = 0;
5868   int ret;
5869
5870   memset (mac_address, 0, sizeof (mac_address));
5871
5872   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5873     {
5874       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5875         mac_set = 1;
5876       if (unformat (i, "instance %d", &user_instance))
5877         is_specified = 1;
5878       else
5879         break;
5880     }
5881
5882   if (is_specified)
5883     {
5884       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5885       mp_lbi->is_specified = is_specified;
5886       if (is_specified)
5887         mp_lbi->user_instance = htonl (user_instance);
5888       if (mac_set)
5889         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5890       S (mp_lbi);
5891     }
5892   else
5893     {
5894       /* Construct the API message */
5895       M (CREATE_LOOPBACK, mp);
5896       if (mac_set)
5897         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5898       S (mp);
5899     }
5900
5901   W (ret);
5902   return ret;
5903 }
5904
5905 static int
5906 api_delete_loopback (vat_main_t * vam)
5907 {
5908   unformat_input_t *i = vam->input;
5909   vl_api_delete_loopback_t *mp;
5910   u32 sw_if_index = ~0;
5911   int ret;
5912
5913   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5914     {
5915       if (unformat (i, "sw_if_index %d", &sw_if_index))
5916         ;
5917       else
5918         break;
5919     }
5920
5921   if (sw_if_index == ~0)
5922     {
5923       errmsg ("missing sw_if_index");
5924       return -99;
5925     }
5926
5927   /* Construct the API message */
5928   M (DELETE_LOOPBACK, mp);
5929   mp->sw_if_index = ntohl (sw_if_index);
5930
5931   S (mp);
5932   W (ret);
5933   return ret;
5934 }
5935
5936 static int
5937 api_want_stats (vat_main_t * vam)
5938 {
5939   unformat_input_t *i = vam->input;
5940   vl_api_want_stats_t *mp;
5941   int enable = -1;
5942   int ret;
5943
5944   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5945     {
5946       if (unformat (i, "enable"))
5947         enable = 1;
5948       else if (unformat (i, "disable"))
5949         enable = 0;
5950       else
5951         break;
5952     }
5953
5954   if (enable == -1)
5955     {
5956       errmsg ("missing enable|disable");
5957       return -99;
5958     }
5959
5960   M (WANT_STATS, mp);
5961   mp->enable_disable = enable;
5962
5963   S (mp);
5964   W (ret);
5965   return ret;
5966 }
5967
5968 static int
5969 api_want_interface_events (vat_main_t * vam)
5970 {
5971   unformat_input_t *i = vam->input;
5972   vl_api_want_interface_events_t *mp;
5973   int enable = -1;
5974   int ret;
5975
5976   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5977     {
5978       if (unformat (i, "enable"))
5979         enable = 1;
5980       else if (unformat (i, "disable"))
5981         enable = 0;
5982       else
5983         break;
5984     }
5985
5986   if (enable == -1)
5987     {
5988       errmsg ("missing enable|disable");
5989       return -99;
5990     }
5991
5992   M (WANT_INTERFACE_EVENTS, mp);
5993   mp->enable_disable = enable;
5994
5995   vam->interface_event_display = enable;
5996
5997   S (mp);
5998   W (ret);
5999   return ret;
6000 }
6001
6002
6003 /* Note: non-static, called once to set up the initial intfc table */
6004 int
6005 api_sw_interface_dump (vat_main_t * vam)
6006 {
6007   vl_api_sw_interface_dump_t *mp;
6008   vl_api_control_ping_t *mp_ping;
6009   hash_pair_t *p;
6010   name_sort_t *nses = 0, *ns;
6011   sw_interface_subif_t *sub = NULL;
6012   int ret;
6013
6014   /* Toss the old name table */
6015   /* *INDENT-OFF* */
6016   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
6017   ({
6018     vec_add2 (nses, ns, 1);
6019     ns->name = (u8 *)(p->key);
6020     ns->value = (u32) p->value[0];
6021   }));
6022   /* *INDENT-ON* */
6023
6024   hash_free (vam->sw_if_index_by_interface_name);
6025
6026   vec_foreach (ns, nses) vec_free (ns->name);
6027
6028   vec_free (nses);
6029
6030   vec_foreach (sub, vam->sw_if_subif_table)
6031   {
6032     vec_free (sub->interface_name);
6033   }
6034   vec_free (vam->sw_if_subif_table);
6035
6036   /* recreate the interface name hash table */
6037   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
6038
6039   /* Get list of ethernets */
6040   M (SW_INTERFACE_DUMP, mp);
6041   mp->name_filter_valid = 1;
6042   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
6043   S (mp);
6044
6045   /* and local / loopback interfaces */
6046   M (SW_INTERFACE_DUMP, mp);
6047   mp->name_filter_valid = 1;
6048   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
6049   S (mp);
6050
6051   /* and packet-generator interfaces */
6052   M (SW_INTERFACE_DUMP, mp);
6053   mp->name_filter_valid = 1;
6054   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
6055   S (mp);
6056
6057   /* and vxlan-gpe tunnel interfaces */
6058   M (SW_INTERFACE_DUMP, mp);
6059   mp->name_filter_valid = 1;
6060   strncpy ((char *) mp->name_filter, "vxlan_gpe",
6061            sizeof (mp->name_filter) - 1);
6062   S (mp);
6063
6064   /* and vxlan tunnel interfaces */
6065   M (SW_INTERFACE_DUMP, mp);
6066   mp->name_filter_valid = 1;
6067   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
6068   S (mp);
6069
6070   /* and geneve tunnel interfaces */
6071   M (SW_INTERFACE_DUMP, mp);
6072   mp->name_filter_valid = 1;
6073   strncpy ((char *) mp->name_filter, "geneve", sizeof (mp->name_filter) - 1);
6074   S (mp);
6075
6076   /* and host (af_packet) interfaces */
6077   M (SW_INTERFACE_DUMP, mp);
6078   mp->name_filter_valid = 1;
6079   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
6080   S (mp);
6081
6082   /* and l2tpv3 tunnel interfaces */
6083   M (SW_INTERFACE_DUMP, mp);
6084   mp->name_filter_valid = 1;
6085   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
6086            sizeof (mp->name_filter) - 1);
6087   S (mp);
6088
6089   /* and GRE tunnel interfaces */
6090   M (SW_INTERFACE_DUMP, mp);
6091   mp->name_filter_valid = 1;
6092   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
6093   S (mp);
6094
6095   /* and LISP-GPE interfaces */
6096   M (SW_INTERFACE_DUMP, mp);
6097   mp->name_filter_valid = 1;
6098   strncpy ((char *) mp->name_filter, "lisp_gpe",
6099            sizeof (mp->name_filter) - 1);
6100   S (mp);
6101
6102   /* and IPSEC tunnel interfaces */
6103   M (SW_INTERFACE_DUMP, mp);
6104   mp->name_filter_valid = 1;
6105   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
6106   S (mp);
6107
6108   /* Use a control ping for synchronization */
6109   MPING (CONTROL_PING, mp_ping);
6110   S (mp_ping);
6111
6112   W (ret);
6113   return ret;
6114 }
6115
6116 static int
6117 api_sw_interface_set_flags (vat_main_t * vam)
6118 {
6119   unformat_input_t *i = vam->input;
6120   vl_api_sw_interface_set_flags_t *mp;
6121   u32 sw_if_index;
6122   u8 sw_if_index_set = 0;
6123   u8 admin_up = 0;
6124   int ret;
6125
6126   /* Parse args required to build the message */
6127   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6128     {
6129       if (unformat (i, "admin-up"))
6130         admin_up = 1;
6131       else if (unformat (i, "admin-down"))
6132         admin_up = 0;
6133       else
6134         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6135         sw_if_index_set = 1;
6136       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6137         sw_if_index_set = 1;
6138       else
6139         break;
6140     }
6141
6142   if (sw_if_index_set == 0)
6143     {
6144       errmsg ("missing interface name or sw_if_index");
6145       return -99;
6146     }
6147
6148   /* Construct the API message */
6149   M (SW_INTERFACE_SET_FLAGS, mp);
6150   mp->sw_if_index = ntohl (sw_if_index);
6151   mp->admin_up_down = admin_up;
6152
6153   /* send it... */
6154   S (mp);
6155
6156   /* Wait for a reply, return the good/bad news... */
6157   W (ret);
6158   return ret;
6159 }
6160
6161 static int
6162 api_sw_interface_clear_stats (vat_main_t * vam)
6163 {
6164   unformat_input_t *i = vam->input;
6165   vl_api_sw_interface_clear_stats_t *mp;
6166   u32 sw_if_index;
6167   u8 sw_if_index_set = 0;
6168   int ret;
6169
6170   /* Parse args required to build the message */
6171   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6172     {
6173       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6174         sw_if_index_set = 1;
6175       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6176         sw_if_index_set = 1;
6177       else
6178         break;
6179     }
6180
6181   /* Construct the API message */
6182   M (SW_INTERFACE_CLEAR_STATS, mp);
6183
6184   if (sw_if_index_set == 1)
6185     mp->sw_if_index = ntohl (sw_if_index);
6186   else
6187     mp->sw_if_index = ~0;
6188
6189   /* send it... */
6190   S (mp);
6191
6192   /* Wait for a reply, return the good/bad news... */
6193   W (ret);
6194   return ret;
6195 }
6196
6197 static int
6198 api_sw_interface_add_del_address (vat_main_t * vam)
6199 {
6200   unformat_input_t *i = vam->input;
6201   vl_api_sw_interface_add_del_address_t *mp;
6202   u32 sw_if_index;
6203   u8 sw_if_index_set = 0;
6204   u8 is_add = 1, del_all = 0;
6205   u32 address_length = 0;
6206   u8 v4_address_set = 0;
6207   u8 v6_address_set = 0;
6208   ip4_address_t v4address;
6209   ip6_address_t v6address;
6210   int ret;
6211
6212   /* Parse args required to build the message */
6213   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6214     {
6215       if (unformat (i, "del-all"))
6216         del_all = 1;
6217       else if (unformat (i, "del"))
6218         is_add = 0;
6219       else
6220         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6221         sw_if_index_set = 1;
6222       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6223         sw_if_index_set = 1;
6224       else if (unformat (i, "%U/%d",
6225                          unformat_ip4_address, &v4address, &address_length))
6226         v4_address_set = 1;
6227       else if (unformat (i, "%U/%d",
6228                          unformat_ip6_address, &v6address, &address_length))
6229         v6_address_set = 1;
6230       else
6231         break;
6232     }
6233
6234   if (sw_if_index_set == 0)
6235     {
6236       errmsg ("missing interface name or sw_if_index");
6237       return -99;
6238     }
6239   if (v4_address_set && v6_address_set)
6240     {
6241       errmsg ("both v4 and v6 addresses set");
6242       return -99;
6243     }
6244   if (!v4_address_set && !v6_address_set && !del_all)
6245     {
6246       errmsg ("no addresses set");
6247       return -99;
6248     }
6249
6250   /* Construct the API message */
6251   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6252
6253   mp->sw_if_index = ntohl (sw_if_index);
6254   mp->is_add = is_add;
6255   mp->del_all = del_all;
6256   if (v6_address_set)
6257     {
6258       mp->is_ipv6 = 1;
6259       clib_memcpy (mp->address, &v6address, sizeof (v6address));
6260     }
6261   else
6262     {
6263       clib_memcpy (mp->address, &v4address, sizeof (v4address));
6264     }
6265   mp->address_length = address_length;
6266
6267   /* send it... */
6268   S (mp);
6269
6270   /* Wait for a reply, return good/bad news  */
6271   W (ret);
6272   return ret;
6273 }
6274
6275 static int
6276 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6277 {
6278   unformat_input_t *i = vam->input;
6279   vl_api_sw_interface_set_mpls_enable_t *mp;
6280   u32 sw_if_index;
6281   u8 sw_if_index_set = 0;
6282   u8 enable = 1;
6283   int ret;
6284
6285   /* Parse args required to build the message */
6286   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6287     {
6288       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6289         sw_if_index_set = 1;
6290       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6291         sw_if_index_set = 1;
6292       else if (unformat (i, "disable"))
6293         enable = 0;
6294       else if (unformat (i, "dis"))
6295         enable = 0;
6296       else
6297         break;
6298     }
6299
6300   if (sw_if_index_set == 0)
6301     {
6302       errmsg ("missing interface name or sw_if_index");
6303       return -99;
6304     }
6305
6306   /* Construct the API message */
6307   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6308
6309   mp->sw_if_index = ntohl (sw_if_index);
6310   mp->enable = enable;
6311
6312   /* send it... */
6313   S (mp);
6314
6315   /* Wait for a reply... */
6316   W (ret);
6317   return ret;
6318 }
6319
6320 static int
6321 api_sw_interface_set_table (vat_main_t * vam)
6322 {
6323   unformat_input_t *i = vam->input;
6324   vl_api_sw_interface_set_table_t *mp;
6325   u32 sw_if_index, vrf_id = 0;
6326   u8 sw_if_index_set = 0;
6327   u8 is_ipv6 = 0;
6328   int ret;
6329
6330   /* Parse args required to build the message */
6331   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6332     {
6333       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6334         sw_if_index_set = 1;
6335       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6336         sw_if_index_set = 1;
6337       else if (unformat (i, "vrf %d", &vrf_id))
6338         ;
6339       else if (unformat (i, "ipv6"))
6340         is_ipv6 = 1;
6341       else
6342         break;
6343     }
6344
6345   if (sw_if_index_set == 0)
6346     {
6347       errmsg ("missing interface name or sw_if_index");
6348       return -99;
6349     }
6350
6351   /* Construct the API message */
6352   M (SW_INTERFACE_SET_TABLE, mp);
6353
6354   mp->sw_if_index = ntohl (sw_if_index);
6355   mp->is_ipv6 = is_ipv6;
6356   mp->vrf_id = ntohl (vrf_id);
6357
6358   /* send it... */
6359   S (mp);
6360
6361   /* Wait for a reply... */
6362   W (ret);
6363   return ret;
6364 }
6365
6366 static void vl_api_sw_interface_get_table_reply_t_handler
6367   (vl_api_sw_interface_get_table_reply_t * mp)
6368 {
6369   vat_main_t *vam = &vat_main;
6370
6371   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6372
6373   vam->retval = ntohl (mp->retval);
6374   vam->result_ready = 1;
6375
6376 }
6377
6378 static void vl_api_sw_interface_get_table_reply_t_handler_json
6379   (vl_api_sw_interface_get_table_reply_t * mp)
6380 {
6381   vat_main_t *vam = &vat_main;
6382   vat_json_node_t node;
6383
6384   vat_json_init_object (&node);
6385   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6386   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6387
6388   vat_json_print (vam->ofp, &node);
6389   vat_json_free (&node);
6390
6391   vam->retval = ntohl (mp->retval);
6392   vam->result_ready = 1;
6393 }
6394
6395 static int
6396 api_sw_interface_get_table (vat_main_t * vam)
6397 {
6398   unformat_input_t *i = vam->input;
6399   vl_api_sw_interface_get_table_t *mp;
6400   u32 sw_if_index;
6401   u8 sw_if_index_set = 0;
6402   u8 is_ipv6 = 0;
6403   int ret;
6404
6405   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6406     {
6407       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6408         sw_if_index_set = 1;
6409       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6410         sw_if_index_set = 1;
6411       else if (unformat (i, "ipv6"))
6412         is_ipv6 = 1;
6413       else
6414         break;
6415     }
6416
6417   if (sw_if_index_set == 0)
6418     {
6419       errmsg ("missing interface name or sw_if_index");
6420       return -99;
6421     }
6422
6423   M (SW_INTERFACE_GET_TABLE, mp);
6424   mp->sw_if_index = htonl (sw_if_index);
6425   mp->is_ipv6 = is_ipv6;
6426
6427   S (mp);
6428   W (ret);
6429   return ret;
6430 }
6431
6432 static int
6433 api_sw_interface_set_vpath (vat_main_t * vam)
6434 {
6435   unformat_input_t *i = vam->input;
6436   vl_api_sw_interface_set_vpath_t *mp;
6437   u32 sw_if_index = 0;
6438   u8 sw_if_index_set = 0;
6439   u8 is_enable = 0;
6440   int ret;
6441
6442   /* Parse args required to build the message */
6443   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6444     {
6445       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6446         sw_if_index_set = 1;
6447       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6448         sw_if_index_set = 1;
6449       else if (unformat (i, "enable"))
6450         is_enable = 1;
6451       else if (unformat (i, "disable"))
6452         is_enable = 0;
6453       else
6454         break;
6455     }
6456
6457   if (sw_if_index_set == 0)
6458     {
6459       errmsg ("missing interface name or sw_if_index");
6460       return -99;
6461     }
6462
6463   /* Construct the API message */
6464   M (SW_INTERFACE_SET_VPATH, mp);
6465
6466   mp->sw_if_index = ntohl (sw_if_index);
6467   mp->enable = is_enable;
6468
6469   /* send it... */
6470   S (mp);
6471
6472   /* Wait for a reply... */
6473   W (ret);
6474   return ret;
6475 }
6476
6477 static int
6478 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6479 {
6480   unformat_input_t *i = vam->input;
6481   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6482   u32 sw_if_index = 0;
6483   u8 sw_if_index_set = 0;
6484   u8 is_enable = 1;
6485   u8 is_ipv6 = 0;
6486   int ret;
6487
6488   /* Parse args required to build the message */
6489   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6490     {
6491       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6492         sw_if_index_set = 1;
6493       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6494         sw_if_index_set = 1;
6495       else if (unformat (i, "enable"))
6496         is_enable = 1;
6497       else if (unformat (i, "disable"))
6498         is_enable = 0;
6499       else if (unformat (i, "ip4"))
6500         is_ipv6 = 0;
6501       else if (unformat (i, "ip6"))
6502         is_ipv6 = 1;
6503       else
6504         break;
6505     }
6506
6507   if (sw_if_index_set == 0)
6508     {
6509       errmsg ("missing interface name or sw_if_index");
6510       return -99;
6511     }
6512
6513   /* Construct the API message */
6514   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6515
6516   mp->sw_if_index = ntohl (sw_if_index);
6517   mp->enable = is_enable;
6518   mp->is_ipv6 = is_ipv6;
6519
6520   /* send it... */
6521   S (mp);
6522
6523   /* Wait for a reply... */
6524   W (ret);
6525   return ret;
6526 }
6527
6528 static int
6529 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6530 {
6531   unformat_input_t *i = vam->input;
6532   vl_api_sw_interface_set_geneve_bypass_t *mp;
6533   u32 sw_if_index = 0;
6534   u8 sw_if_index_set = 0;
6535   u8 is_enable = 1;
6536   u8 is_ipv6 = 0;
6537   int ret;
6538
6539   /* Parse args required to build the message */
6540   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6541     {
6542       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6543         sw_if_index_set = 1;
6544       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6545         sw_if_index_set = 1;
6546       else if (unformat (i, "enable"))
6547         is_enable = 1;
6548       else if (unformat (i, "disable"))
6549         is_enable = 0;
6550       else if (unformat (i, "ip4"))
6551         is_ipv6 = 0;
6552       else if (unformat (i, "ip6"))
6553         is_ipv6 = 1;
6554       else
6555         break;
6556     }
6557
6558   if (sw_if_index_set == 0)
6559     {
6560       errmsg ("missing interface name or sw_if_index");
6561       return -99;
6562     }
6563
6564   /* Construct the API message */
6565   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6566
6567   mp->sw_if_index = ntohl (sw_if_index);
6568   mp->enable = is_enable;
6569   mp->is_ipv6 = is_ipv6;
6570
6571   /* send it... */
6572   S (mp);
6573
6574   /* Wait for a reply... */
6575   W (ret);
6576   return ret;
6577 }
6578
6579 static int
6580 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6581 {
6582   unformat_input_t *i = vam->input;
6583   vl_api_sw_interface_set_l2_xconnect_t *mp;
6584   u32 rx_sw_if_index;
6585   u8 rx_sw_if_index_set = 0;
6586   u32 tx_sw_if_index;
6587   u8 tx_sw_if_index_set = 0;
6588   u8 enable = 1;
6589   int ret;
6590
6591   /* Parse args required to build the message */
6592   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6593     {
6594       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6595         rx_sw_if_index_set = 1;
6596       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6597         tx_sw_if_index_set = 1;
6598       else if (unformat (i, "rx"))
6599         {
6600           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6601             {
6602               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6603                             &rx_sw_if_index))
6604                 rx_sw_if_index_set = 1;
6605             }
6606           else
6607             break;
6608         }
6609       else if (unformat (i, "tx"))
6610         {
6611           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6612             {
6613               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6614                             &tx_sw_if_index))
6615                 tx_sw_if_index_set = 1;
6616             }
6617           else
6618             break;
6619         }
6620       else if (unformat (i, "enable"))
6621         enable = 1;
6622       else if (unformat (i, "disable"))
6623         enable = 0;
6624       else
6625         break;
6626     }
6627
6628   if (rx_sw_if_index_set == 0)
6629     {
6630       errmsg ("missing rx interface name or rx_sw_if_index");
6631       return -99;
6632     }
6633
6634   if (enable && (tx_sw_if_index_set == 0))
6635     {
6636       errmsg ("missing tx interface name or tx_sw_if_index");
6637       return -99;
6638     }
6639
6640   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6641
6642   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6643   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6644   mp->enable = enable;
6645
6646   S (mp);
6647   W (ret);
6648   return ret;
6649 }
6650
6651 static int
6652 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6653 {
6654   unformat_input_t *i = vam->input;
6655   vl_api_sw_interface_set_l2_bridge_t *mp;
6656   u32 rx_sw_if_index;
6657   u8 rx_sw_if_index_set = 0;
6658   u32 bd_id;
6659   u8 bd_id_set = 0;
6660   u8 bvi = 0;
6661   u32 shg = 0;
6662   u8 enable = 1;
6663   int ret;
6664
6665   /* Parse args required to build the message */
6666   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6667     {
6668       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6669         rx_sw_if_index_set = 1;
6670       else if (unformat (i, "bd_id %d", &bd_id))
6671         bd_id_set = 1;
6672       else
6673         if (unformat
6674             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6675         rx_sw_if_index_set = 1;
6676       else if (unformat (i, "shg %d", &shg))
6677         ;
6678       else if (unformat (i, "bvi"))
6679         bvi = 1;
6680       else if (unformat (i, "enable"))
6681         enable = 1;
6682       else if (unformat (i, "disable"))
6683         enable = 0;
6684       else
6685         break;
6686     }
6687
6688   if (rx_sw_if_index_set == 0)
6689     {
6690       errmsg ("missing rx interface name or sw_if_index");
6691       return -99;
6692     }
6693
6694   if (enable && (bd_id_set == 0))
6695     {
6696       errmsg ("missing bridge domain");
6697       return -99;
6698     }
6699
6700   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6701
6702   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6703   mp->bd_id = ntohl (bd_id);
6704   mp->shg = (u8) shg;
6705   mp->bvi = bvi;
6706   mp->enable = enable;
6707
6708   S (mp);
6709   W (ret);
6710   return ret;
6711 }
6712
6713 static int
6714 api_bridge_domain_dump (vat_main_t * vam)
6715 {
6716   unformat_input_t *i = vam->input;
6717   vl_api_bridge_domain_dump_t *mp;
6718   vl_api_control_ping_t *mp_ping;
6719   u32 bd_id = ~0;
6720   int ret;
6721
6722   /* Parse args required to build the message */
6723   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6724     {
6725       if (unformat (i, "bd_id %d", &bd_id))
6726         ;
6727       else
6728         break;
6729     }
6730
6731   M (BRIDGE_DOMAIN_DUMP, mp);
6732   mp->bd_id = ntohl (bd_id);
6733   S (mp);
6734
6735   /* Use a control ping for synchronization */
6736   MPING (CONTROL_PING, mp_ping);
6737   S (mp_ping);
6738
6739   W (ret);
6740   return ret;
6741 }
6742
6743 static int
6744 api_bridge_domain_add_del (vat_main_t * vam)
6745 {
6746   unformat_input_t *i = vam->input;
6747   vl_api_bridge_domain_add_del_t *mp;
6748   u32 bd_id = ~0;
6749   u8 is_add = 1;
6750   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6751   u8 *bd_tag = NULL;
6752   u32 mac_age = 0;
6753   int ret;
6754
6755   /* Parse args required to build the message */
6756   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6757     {
6758       if (unformat (i, "bd_id %d", &bd_id))
6759         ;
6760       else if (unformat (i, "flood %d", &flood))
6761         ;
6762       else if (unformat (i, "uu-flood %d", &uu_flood))
6763         ;
6764       else if (unformat (i, "forward %d", &forward))
6765         ;
6766       else if (unformat (i, "learn %d", &learn))
6767         ;
6768       else if (unformat (i, "arp-term %d", &arp_term))
6769         ;
6770       else if (unformat (i, "mac-age %d", &mac_age))
6771         ;
6772       else if (unformat (i, "bd-tag %s", &bd_tag))
6773         ;
6774       else if (unformat (i, "del"))
6775         {
6776           is_add = 0;
6777           flood = uu_flood = forward = learn = 0;
6778         }
6779       else
6780         break;
6781     }
6782
6783   if (bd_id == ~0)
6784     {
6785       errmsg ("missing bridge domain");
6786       ret = -99;
6787       goto done;
6788     }
6789
6790   if (mac_age > 255)
6791     {
6792       errmsg ("mac age must be less than 256 ");
6793       ret = -99;
6794       goto done;
6795     }
6796
6797   if ((bd_tag) && (strlen ((char *) bd_tag) > 63))
6798     {
6799       errmsg ("bd-tag cannot be longer than 63");
6800       ret = -99;
6801       goto done;
6802     }
6803
6804   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6805
6806   mp->bd_id = ntohl (bd_id);
6807   mp->flood = flood;
6808   mp->uu_flood = uu_flood;
6809   mp->forward = forward;
6810   mp->learn = learn;
6811   mp->arp_term = arp_term;
6812   mp->is_add = is_add;
6813   mp->mac_age = (u8) mac_age;
6814   if (bd_tag)
6815     strcpy ((char *) mp->bd_tag, (char *) bd_tag);
6816
6817   S (mp);
6818   W (ret);
6819
6820 done:
6821   vec_free (bd_tag);
6822   return ret;
6823 }
6824
6825 static int
6826 api_l2fib_flush_bd (vat_main_t * vam)
6827 {
6828   unformat_input_t *i = vam->input;
6829   vl_api_l2fib_flush_bd_t *mp;
6830   u32 bd_id = ~0;
6831   int ret;
6832
6833   /* Parse args required to build the message */
6834   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6835     {
6836       if (unformat (i, "bd_id %d", &bd_id));
6837       else
6838         break;
6839     }
6840
6841   if (bd_id == ~0)
6842     {
6843       errmsg ("missing bridge domain");
6844       return -99;
6845     }
6846
6847   M (L2FIB_FLUSH_BD, mp);
6848
6849   mp->bd_id = htonl (bd_id);
6850
6851   S (mp);
6852   W (ret);
6853   return ret;
6854 }
6855
6856 static int
6857 api_l2fib_flush_int (vat_main_t * vam)
6858 {
6859   unformat_input_t *i = vam->input;
6860   vl_api_l2fib_flush_int_t *mp;
6861   u32 sw_if_index = ~0;
6862   int ret;
6863
6864   /* Parse args required to build the message */
6865   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6866     {
6867       if (unformat (i, "sw_if_index %d", &sw_if_index));
6868       else
6869         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6870       else
6871         break;
6872     }
6873
6874   if (sw_if_index == ~0)
6875     {
6876       errmsg ("missing interface name or sw_if_index");
6877       return -99;
6878     }
6879
6880   M (L2FIB_FLUSH_INT, mp);
6881
6882   mp->sw_if_index = ntohl (sw_if_index);
6883
6884   S (mp);
6885   W (ret);
6886   return ret;
6887 }
6888
6889 static int
6890 api_l2fib_add_del (vat_main_t * vam)
6891 {
6892   unformat_input_t *i = vam->input;
6893   vl_api_l2fib_add_del_t *mp;
6894   f64 timeout;
6895   u64 mac = 0;
6896   u8 mac_set = 0;
6897   u32 bd_id;
6898   u8 bd_id_set = 0;
6899   u32 sw_if_index = ~0;
6900   u8 sw_if_index_set = 0;
6901   u8 is_add = 1;
6902   u8 static_mac = 0;
6903   u8 filter_mac = 0;
6904   u8 bvi_mac = 0;
6905   int count = 1;
6906   f64 before = 0;
6907   int j;
6908
6909   /* Parse args required to build the message */
6910   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6911     {
6912       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
6913         mac_set = 1;
6914       else if (unformat (i, "bd_id %d", &bd_id))
6915         bd_id_set = 1;
6916       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6917         sw_if_index_set = 1;
6918       else if (unformat (i, "sw_if"))
6919         {
6920           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6921             {
6922               if (unformat
6923                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6924                 sw_if_index_set = 1;
6925             }
6926           else
6927             break;
6928         }
6929       else if (unformat (i, "static"))
6930         static_mac = 1;
6931       else if (unformat (i, "filter"))
6932         {
6933           filter_mac = 1;
6934           static_mac = 1;
6935         }
6936       else if (unformat (i, "bvi"))
6937         {
6938           bvi_mac = 1;
6939           static_mac = 1;
6940         }
6941       else if (unformat (i, "del"))
6942         is_add = 0;
6943       else if (unformat (i, "count %d", &count))
6944         ;
6945       else
6946         break;
6947     }
6948
6949   if (mac_set == 0)
6950     {
6951       errmsg ("missing mac address");
6952       return -99;
6953     }
6954
6955   if (bd_id_set == 0)
6956     {
6957       errmsg ("missing bridge domain");
6958       return -99;
6959     }
6960
6961   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6962     {
6963       errmsg ("missing interface name or sw_if_index");
6964       return -99;
6965     }
6966
6967   if (count > 1)
6968     {
6969       /* Turn on async mode */
6970       vam->async_mode = 1;
6971       vam->async_errors = 0;
6972       before = vat_time_now (vam);
6973     }
6974
6975   for (j = 0; j < count; j++)
6976     {
6977       M (L2FIB_ADD_DEL, mp);
6978
6979       mp->mac = mac;
6980       mp->bd_id = ntohl (bd_id);
6981       mp->is_add = is_add;
6982
6983       if (is_add)
6984         {
6985           mp->sw_if_index = ntohl (sw_if_index);
6986           mp->static_mac = static_mac;
6987           mp->filter_mac = filter_mac;
6988           mp->bvi_mac = bvi_mac;
6989         }
6990       increment_mac_address (&mac);
6991       /* send it... */
6992       S (mp);
6993     }
6994
6995   if (count > 1)
6996     {
6997       vl_api_control_ping_t *mp_ping;
6998       f64 after;
6999
7000       /* Shut off async mode */
7001       vam->async_mode = 0;
7002
7003       MPING (CONTROL_PING, mp_ping);
7004       S (mp_ping);
7005
7006       timeout = vat_time_now (vam) + 1.0;
7007       while (vat_time_now (vam) < timeout)
7008         if (vam->result_ready == 1)
7009           goto out;
7010       vam->retval = -99;
7011
7012     out:
7013       if (vam->retval == -99)
7014         errmsg ("timeout");
7015
7016       if (vam->async_errors > 0)
7017         {
7018           errmsg ("%d asynchronous errors", vam->async_errors);
7019           vam->retval = -98;
7020         }
7021       vam->async_errors = 0;
7022       after = vat_time_now (vam);
7023
7024       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7025              count, after - before, count / (after - before));
7026     }
7027   else
7028     {
7029       int ret;
7030
7031       /* Wait for a reply... */
7032       W (ret);
7033       return ret;
7034     }
7035   /* Return the good/bad news */
7036   return (vam->retval);
7037 }
7038
7039 static int
7040 api_bridge_domain_set_mac_age (vat_main_t * vam)
7041 {
7042   unformat_input_t *i = vam->input;
7043   vl_api_bridge_domain_set_mac_age_t *mp;
7044   u32 bd_id = ~0;
7045   u32 mac_age = 0;
7046   int ret;
7047
7048   /* Parse args required to build the message */
7049   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7050     {
7051       if (unformat (i, "bd_id %d", &bd_id));
7052       else if (unformat (i, "mac-age %d", &mac_age));
7053       else
7054         break;
7055     }
7056
7057   if (bd_id == ~0)
7058     {
7059       errmsg ("missing bridge domain");
7060       return -99;
7061     }
7062
7063   if (mac_age > 255)
7064     {
7065       errmsg ("mac age must be less than 256 ");
7066       return -99;
7067     }
7068
7069   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7070
7071   mp->bd_id = htonl (bd_id);
7072   mp->mac_age = (u8) mac_age;
7073
7074   S (mp);
7075   W (ret);
7076   return ret;
7077 }
7078
7079 static int
7080 api_l2_flags (vat_main_t * vam)
7081 {
7082   unformat_input_t *i = vam->input;
7083   vl_api_l2_flags_t *mp;
7084   u32 sw_if_index;
7085   u32 flags = 0;
7086   u8 sw_if_index_set = 0;
7087   u8 is_set = 0;
7088   int ret;
7089
7090   /* Parse args required to build the message */
7091   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7092     {
7093       if (unformat (i, "sw_if_index %d", &sw_if_index))
7094         sw_if_index_set = 1;
7095       else if (unformat (i, "sw_if"))
7096         {
7097           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7098             {
7099               if (unformat
7100                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7101                 sw_if_index_set = 1;
7102             }
7103           else
7104             break;
7105         }
7106       else if (unformat (i, "learn"))
7107         flags |= L2_LEARN;
7108       else if (unformat (i, "forward"))
7109         flags |= L2_FWD;
7110       else if (unformat (i, "flood"))
7111         flags |= L2_FLOOD;
7112       else if (unformat (i, "uu-flood"))
7113         flags |= L2_UU_FLOOD;
7114       else if (unformat (i, "arp-term"))
7115         flags |= L2_ARP_TERM;
7116       else if (unformat (i, "off"))
7117         is_set = 0;
7118       else if (unformat (i, "disable"))
7119         is_set = 0;
7120       else
7121         break;
7122     }
7123
7124   if (sw_if_index_set == 0)
7125     {
7126       errmsg ("missing interface name or sw_if_index");
7127       return -99;
7128     }
7129
7130   M (L2_FLAGS, mp);
7131
7132   mp->sw_if_index = ntohl (sw_if_index);
7133   mp->feature_bitmap = ntohl (flags);
7134   mp->is_set = is_set;
7135
7136   S (mp);
7137   W (ret);
7138   return ret;
7139 }
7140
7141 static int
7142 api_bridge_flags (vat_main_t * vam)
7143 {
7144   unformat_input_t *i = vam->input;
7145   vl_api_bridge_flags_t *mp;
7146   u32 bd_id;
7147   u8 bd_id_set = 0;
7148   u8 is_set = 1;
7149   u32 flags = 0;
7150   int ret;
7151
7152   /* Parse args required to build the message */
7153   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7154     {
7155       if (unformat (i, "bd_id %d", &bd_id))
7156         bd_id_set = 1;
7157       else if (unformat (i, "learn"))
7158         flags |= L2_LEARN;
7159       else if (unformat (i, "forward"))
7160         flags |= L2_FWD;
7161       else if (unformat (i, "flood"))
7162         flags |= L2_FLOOD;
7163       else if (unformat (i, "uu-flood"))
7164         flags |= L2_UU_FLOOD;
7165       else if (unformat (i, "arp-term"))
7166         flags |= L2_ARP_TERM;
7167       else if (unformat (i, "off"))
7168         is_set = 0;
7169       else if (unformat (i, "disable"))
7170         is_set = 0;
7171       else
7172         break;
7173     }
7174
7175   if (bd_id_set == 0)
7176     {
7177       errmsg ("missing bridge domain");
7178       return -99;
7179     }
7180
7181   M (BRIDGE_FLAGS, mp);
7182
7183   mp->bd_id = ntohl (bd_id);
7184   mp->feature_bitmap = ntohl (flags);
7185   mp->is_set = is_set;
7186
7187   S (mp);
7188   W (ret);
7189   return ret;
7190 }
7191
7192 static int
7193 api_bd_ip_mac_add_del (vat_main_t * vam)
7194 {
7195   unformat_input_t *i = vam->input;
7196   vl_api_bd_ip_mac_add_del_t *mp;
7197   u32 bd_id;
7198   u8 is_ipv6 = 0;
7199   u8 is_add = 1;
7200   u8 bd_id_set = 0;
7201   u8 ip_set = 0;
7202   u8 mac_set = 0;
7203   ip4_address_t v4addr;
7204   ip6_address_t v6addr;
7205   u8 macaddr[6];
7206   int ret;
7207
7208
7209   /* Parse args required to build the message */
7210   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7211     {
7212       if (unformat (i, "bd_id %d", &bd_id))
7213         {
7214           bd_id_set++;
7215         }
7216       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
7217         {
7218           ip_set++;
7219         }
7220       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
7221         {
7222           ip_set++;
7223           is_ipv6++;
7224         }
7225       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
7226         {
7227           mac_set++;
7228         }
7229       else if (unformat (i, "del"))
7230         is_add = 0;
7231       else
7232         break;
7233     }
7234
7235   if (bd_id_set == 0)
7236     {
7237       errmsg ("missing bridge domain");
7238       return -99;
7239     }
7240   else if (ip_set == 0)
7241     {
7242       errmsg ("missing IP address");
7243       return -99;
7244     }
7245   else if (mac_set == 0)
7246     {
7247       errmsg ("missing MAC address");
7248       return -99;
7249     }
7250
7251   M (BD_IP_MAC_ADD_DEL, mp);
7252
7253   mp->bd_id = ntohl (bd_id);
7254   mp->is_ipv6 = is_ipv6;
7255   mp->is_add = is_add;
7256   if (is_ipv6)
7257     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
7258   else
7259     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
7260   clib_memcpy (mp->mac_address, macaddr, 6);
7261   S (mp);
7262   W (ret);
7263   return ret;
7264 }
7265
7266 static int
7267 api_tap_connect (vat_main_t * vam)
7268 {
7269   unformat_input_t *i = vam->input;
7270   vl_api_tap_connect_t *mp;
7271   u8 mac_address[6];
7272   u8 random_mac = 1;
7273   u8 name_set = 0;
7274   u8 *tap_name;
7275   u8 *tag = 0;
7276   ip4_address_t ip4_address;
7277   u32 ip4_mask_width;
7278   int ip4_address_set = 0;
7279   ip6_address_t ip6_address;
7280   u32 ip6_mask_width;
7281   int ip6_address_set = 0;
7282   int ret;
7283
7284   memset (mac_address, 0, sizeof (mac_address));
7285
7286   /* Parse args required to build the message */
7287   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7288     {
7289       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7290         {
7291           random_mac = 0;
7292         }
7293       else if (unformat (i, "random-mac"))
7294         random_mac = 1;
7295       else if (unformat (i, "tapname %s", &tap_name))
7296         name_set = 1;
7297       else if (unformat (i, "tag %s", &tag))
7298         ;
7299       else if (unformat (i, "address %U/%d",
7300                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
7301         ip4_address_set = 1;
7302       else if (unformat (i, "address %U/%d",
7303                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
7304         ip6_address_set = 1;
7305       else
7306         break;
7307     }
7308
7309   if (name_set == 0)
7310     {
7311       errmsg ("missing tap name");
7312       return -99;
7313     }
7314   if (vec_len (tap_name) > 63)
7315     {
7316       errmsg ("tap name too long");
7317       return -99;
7318     }
7319   vec_add1 (tap_name, 0);
7320
7321   if (vec_len (tag) > 63)
7322     {
7323       errmsg ("tag too long");
7324       return -99;
7325     }
7326
7327   /* Construct the API message */
7328   M (TAP_CONNECT, mp);
7329
7330   mp->use_random_mac = random_mac;
7331   clib_memcpy (mp->mac_address, mac_address, 6);
7332   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7333   if (tag)
7334     clib_memcpy (mp->tag, tag, vec_len (tag));
7335
7336   if (ip4_address_set)
7337     {
7338       mp->ip4_address_set = 1;
7339       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
7340       mp->ip4_mask_width = ip4_mask_width;
7341     }
7342   if (ip6_address_set)
7343     {
7344       mp->ip6_address_set = 1;
7345       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
7346       mp->ip6_mask_width = ip6_mask_width;
7347     }
7348
7349   vec_free (tap_name);
7350   vec_free (tag);
7351
7352   /* send it... */
7353   S (mp);
7354
7355   /* Wait for a reply... */
7356   W (ret);
7357   return ret;
7358 }
7359
7360 static int
7361 api_tap_modify (vat_main_t * vam)
7362 {
7363   unformat_input_t *i = vam->input;
7364   vl_api_tap_modify_t *mp;
7365   u8 mac_address[6];
7366   u8 random_mac = 1;
7367   u8 name_set = 0;
7368   u8 *tap_name;
7369   u32 sw_if_index = ~0;
7370   u8 sw_if_index_set = 0;
7371   int ret;
7372
7373   memset (mac_address, 0, sizeof (mac_address));
7374
7375   /* Parse args required to build the message */
7376   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7377     {
7378       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7379         sw_if_index_set = 1;
7380       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7381         sw_if_index_set = 1;
7382       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
7383         {
7384           random_mac = 0;
7385         }
7386       else if (unformat (i, "random-mac"))
7387         random_mac = 1;
7388       else if (unformat (i, "tapname %s", &tap_name))
7389         name_set = 1;
7390       else
7391         break;
7392     }
7393
7394   if (sw_if_index_set == 0)
7395     {
7396       errmsg ("missing vpp interface name");
7397       return -99;
7398     }
7399   if (name_set == 0)
7400     {
7401       errmsg ("missing tap name");
7402       return -99;
7403     }
7404   if (vec_len (tap_name) > 63)
7405     {
7406       errmsg ("tap name too long");
7407     }
7408   vec_add1 (tap_name, 0);
7409
7410   /* Construct the API message */
7411   M (TAP_MODIFY, mp);
7412
7413   mp->use_random_mac = random_mac;
7414   mp->sw_if_index = ntohl (sw_if_index);
7415   clib_memcpy (mp->mac_address, mac_address, 6);
7416   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
7417   vec_free (tap_name);
7418
7419   /* send it... */
7420   S (mp);
7421
7422   /* Wait for a reply... */
7423   W (ret);
7424   return ret;
7425 }
7426
7427 static int
7428 api_tap_delete (vat_main_t * vam)
7429 {
7430   unformat_input_t *i = vam->input;
7431   vl_api_tap_delete_t *mp;
7432   u32 sw_if_index = ~0;
7433   u8 sw_if_index_set = 0;
7434   int ret;
7435
7436   /* Parse args required to build the message */
7437   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7438     {
7439       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7440         sw_if_index_set = 1;
7441       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7442         sw_if_index_set = 1;
7443       else
7444         break;
7445     }
7446
7447   if (sw_if_index_set == 0)
7448     {
7449       errmsg ("missing vpp interface name");
7450       return -99;
7451     }
7452
7453   /* Construct the API message */
7454   M (TAP_DELETE, mp);
7455
7456   mp->sw_if_index = ntohl (sw_if_index);
7457
7458   /* send it... */
7459   S (mp);
7460
7461   /* Wait for a reply... */
7462   W (ret);
7463   return ret;
7464 }
7465
7466 static int
7467 api_ip_table_add_del (vat_main_t * vam)
7468 {
7469   unformat_input_t *i = vam->input;
7470   vl_api_ip_table_add_del_t *mp;
7471   u32 table_id = ~0;
7472   u8 is_ipv6 = 0;
7473   u8 is_add = 1;
7474   int ret = 0;
7475
7476   /* Parse args required to build the message */
7477   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7478     {
7479       if (unformat (i, "ipv6"))
7480         is_ipv6 = 1;
7481       else if (unformat (i, "del"))
7482         is_add = 0;
7483       else if (unformat (i, "add"))
7484         is_add = 1;
7485       else if (unformat (i, "table %d", &table_id))
7486         ;
7487       else
7488         {
7489           clib_warning ("parse error '%U'", format_unformat_error, i);
7490           return -99;
7491         }
7492     }
7493
7494   if (~0 == table_id)
7495     {
7496       errmsg ("missing table-ID");
7497       return -99;
7498     }
7499
7500   /* Construct the API message */
7501   M (IP_TABLE_ADD_DEL, mp);
7502
7503   mp->table_id = ntohl (table_id);
7504   mp->is_ipv6 = is_ipv6;
7505   mp->is_add = is_add;
7506
7507   /* send it... */
7508   S (mp);
7509
7510   /* Wait for a reply... */
7511   W (ret);
7512
7513   return ret;
7514 }
7515
7516 static int
7517 api_ip_add_del_route (vat_main_t * vam)
7518 {
7519   unformat_input_t *i = vam->input;
7520   vl_api_ip_add_del_route_t *mp;
7521   u32 sw_if_index = ~0, vrf_id = 0;
7522   u8 is_ipv6 = 0;
7523   u8 is_local = 0, is_drop = 0;
7524   u8 is_unreach = 0, is_prohibit = 0;
7525   u8 create_vrf_if_needed = 0;
7526   u8 is_add = 1;
7527   u32 next_hop_weight = 1;
7528   u8 not_last = 0;
7529   u8 is_multipath = 0;
7530   u8 address_set = 0;
7531   u8 address_length_set = 0;
7532   u32 next_hop_table_id = 0;
7533   u32 resolve_attempts = 0;
7534   u32 dst_address_length = 0;
7535   u8 next_hop_set = 0;
7536   ip4_address_t v4_dst_address, v4_next_hop_address;
7537   ip6_address_t v6_dst_address, v6_next_hop_address;
7538   int count = 1;
7539   int j;
7540   f64 before = 0;
7541   u32 random_add_del = 0;
7542   u32 *random_vector = 0;
7543   uword *random_hash;
7544   u32 random_seed = 0xdeaddabe;
7545   u32 classify_table_index = ~0;
7546   u8 is_classify = 0;
7547   u8 resolve_host = 0, resolve_attached = 0;
7548   mpls_label_t *next_hop_out_label_stack = NULL;
7549   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
7550   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
7551
7552   /* Parse args required to build the message */
7553   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7554     {
7555       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7556         ;
7557       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7558         ;
7559       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
7560         {
7561           address_set = 1;
7562           is_ipv6 = 0;
7563         }
7564       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
7565         {
7566           address_set = 1;
7567           is_ipv6 = 1;
7568         }
7569       else if (unformat (i, "/%d", &dst_address_length))
7570         {
7571           address_length_set = 1;
7572         }
7573
7574       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
7575                                          &v4_next_hop_address))
7576         {
7577           next_hop_set = 1;
7578         }
7579       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
7580                                          &v6_next_hop_address))
7581         {
7582           next_hop_set = 1;
7583         }
7584       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
7585         ;
7586       else if (unformat (i, "weight %d", &next_hop_weight))
7587         ;
7588       else if (unformat (i, "drop"))
7589         {
7590           is_drop = 1;
7591         }
7592       else if (unformat (i, "null-send-unreach"))
7593         {
7594           is_unreach = 1;
7595         }
7596       else if (unformat (i, "null-send-prohibit"))
7597         {
7598           is_prohibit = 1;
7599         }
7600       else if (unformat (i, "local"))
7601         {
7602           is_local = 1;
7603         }
7604       else if (unformat (i, "classify %d", &classify_table_index))
7605         {
7606           is_classify = 1;
7607         }
7608       else if (unformat (i, "del"))
7609         is_add = 0;
7610       else if (unformat (i, "add"))
7611         is_add = 1;
7612       else if (unformat (i, "not-last"))
7613         not_last = 1;
7614       else if (unformat (i, "resolve-via-host"))
7615         resolve_host = 1;
7616       else if (unformat (i, "resolve-via-attached"))
7617         resolve_attached = 1;
7618       else if (unformat (i, "multipath"))
7619         is_multipath = 1;
7620       else if (unformat (i, "vrf %d", &vrf_id))
7621         ;
7622       else if (unformat (i, "create-vrf"))
7623         create_vrf_if_needed = 1;
7624       else if (unformat (i, "count %d", &count))
7625         ;
7626       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
7627         ;
7628       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
7629         ;
7630       else if (unformat (i, "out-label %d", &next_hop_out_label))
7631         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
7632       else if (unformat (i, "via-label %d", &next_hop_via_label))
7633         ;
7634       else if (unformat (i, "random"))
7635         random_add_del = 1;
7636       else if (unformat (i, "seed %d", &random_seed))
7637         ;
7638       else
7639         {
7640           clib_warning ("parse error '%U'", format_unformat_error, i);
7641           return -99;
7642         }
7643     }
7644
7645   if (!next_hop_set && !is_drop && !is_local &&
7646       !is_classify && !is_unreach && !is_prohibit &&
7647       MPLS_LABEL_INVALID == next_hop_via_label)
7648     {
7649       errmsg
7650         ("next hop / local / drop / unreach / prohibit / classify not set");
7651       return -99;
7652     }
7653
7654   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
7655     {
7656       errmsg ("next hop and next-hop via label set");
7657       return -99;
7658     }
7659   if (address_set == 0)
7660     {
7661       errmsg ("missing addresses");
7662       return -99;
7663     }
7664
7665   if (address_length_set == 0)
7666     {
7667       errmsg ("missing address length");
7668       return -99;
7669     }
7670
7671   /* Generate a pile of unique, random routes */
7672   if (random_add_del)
7673     {
7674       u32 this_random_address;
7675       random_hash = hash_create (count, sizeof (uword));
7676
7677       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
7678       for (j = 0; j <= count; j++)
7679         {
7680           do
7681             {
7682               this_random_address = random_u32 (&random_seed);
7683               this_random_address =
7684                 clib_host_to_net_u32 (this_random_address);
7685             }
7686           while (hash_get (random_hash, this_random_address));
7687           vec_add1 (random_vector, this_random_address);
7688           hash_set (random_hash, this_random_address, 1);
7689         }
7690       hash_free (random_hash);
7691       v4_dst_address.as_u32 = random_vector[0];
7692     }
7693
7694   if (count > 1)
7695     {
7696       /* Turn on async mode */
7697       vam->async_mode = 1;
7698       vam->async_errors = 0;
7699       before = vat_time_now (vam);
7700     }
7701
7702   for (j = 0; j < count; j++)
7703     {
7704       /* Construct the API message */
7705       M2 (IP_ADD_DEL_ROUTE, mp,
7706           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
7707
7708       mp->next_hop_sw_if_index = ntohl (sw_if_index);
7709       mp->table_id = ntohl (vrf_id);
7710       mp->create_vrf_if_needed = create_vrf_if_needed;
7711
7712       mp->is_add = is_add;
7713       mp->is_drop = is_drop;
7714       mp->is_unreach = is_unreach;
7715       mp->is_prohibit = is_prohibit;
7716       mp->is_ipv6 = is_ipv6;
7717       mp->is_local = is_local;
7718       mp->is_classify = is_classify;
7719       mp->is_multipath = is_multipath;
7720       mp->is_resolve_host = resolve_host;
7721       mp->is_resolve_attached = resolve_attached;
7722       mp->not_last = not_last;
7723       mp->next_hop_weight = next_hop_weight;
7724       mp->dst_address_length = dst_address_length;
7725       mp->next_hop_table_id = ntohl (next_hop_table_id);
7726       mp->classify_table_index = ntohl (classify_table_index);
7727       mp->next_hop_via_label = ntohl (next_hop_via_label);
7728       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
7729       if (0 != mp->next_hop_n_out_labels)
7730         {
7731           memcpy (mp->next_hop_out_label_stack,
7732                   next_hop_out_label_stack,
7733                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
7734           vec_free (next_hop_out_label_stack);
7735         }
7736
7737       if (is_ipv6)
7738         {
7739           clib_memcpy (mp->dst_address, &v6_dst_address,
7740                        sizeof (v6_dst_address));
7741           if (next_hop_set)
7742             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
7743                          sizeof (v6_next_hop_address));
7744           increment_v6_address (&v6_dst_address);
7745         }
7746       else
7747         {
7748           clib_memcpy (mp->dst_address, &v4_dst_address,
7749                        sizeof (v4_dst_address));
7750           if (next_hop_set)
7751             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
7752                          sizeof (v4_next_hop_address));
7753           if (random_add_del)
7754             v4_dst_address.as_u32 = random_vector[j + 1];
7755           else
7756             increment_v4_address (&v4_dst_address);
7757         }
7758       /* send it... */
7759       S (mp);
7760       /* If we receive SIGTERM, stop now... */
7761       if (vam->do_exit)
7762         break;
7763     }
7764
7765   /* When testing multiple add/del ops, use a control-ping to sync */
7766   if (count > 1)
7767     {
7768       vl_api_control_ping_t *mp_ping;
7769       f64 after;
7770       f64 timeout;
7771
7772       /* Shut off async mode */
7773       vam->async_mode = 0;
7774
7775       MPING (CONTROL_PING, mp_ping);
7776       S (mp_ping);
7777
7778       timeout = vat_time_now (vam) + 1.0;
7779       while (vat_time_now (vam) < timeout)
7780         if (vam->result_ready == 1)
7781           goto out;
7782       vam->retval = -99;
7783
7784     out:
7785       if (vam->retval == -99)
7786         errmsg ("timeout");
7787
7788       if (vam->async_errors > 0)
7789         {
7790           errmsg ("%d asynchronous errors", vam->async_errors);
7791           vam->retval = -98;
7792         }
7793       vam->async_errors = 0;
7794       after = vat_time_now (vam);
7795
7796       /* slim chance, but we might have eaten SIGTERM on the first iteration */
7797       if (j > 0)
7798         count = j;
7799
7800       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
7801              count, after - before, count / (after - before));
7802     }
7803   else
7804     {
7805       int ret;
7806
7807       /* Wait for a reply... */
7808       W (ret);
7809       return ret;
7810     }
7811
7812   /* Return the good/bad news */
7813   return (vam->retval);
7814 }
7815
7816 static int
7817 api_ip_mroute_add_del (vat_main_t * vam)
7818 {
7819   unformat_input_t *i = vam->input;
7820   vl_api_ip_mroute_add_del_t *mp;
7821   u32 sw_if_index = ~0, vrf_id = 0;
7822   u8 is_ipv6 = 0;
7823   u8 is_local = 0;
7824   u8 create_vrf_if_needed = 0;
7825   u8 is_add = 1;
7826   u8 address_set = 0;
7827   u32 grp_address_length = 0;
7828   ip4_address_t v4_grp_address, v4_src_address;
7829   ip6_address_t v6_grp_address, v6_src_address;
7830   mfib_itf_flags_t iflags = 0;
7831   mfib_entry_flags_t eflags = 0;
7832   int ret;
7833
7834   /* Parse args required to build the message */
7835   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7836     {
7837       if (unformat (i, "sw_if_index %d", &sw_if_index))
7838         ;
7839       else if (unformat (i, "%U %U",
7840                          unformat_ip4_address, &v4_src_address,
7841                          unformat_ip4_address, &v4_grp_address))
7842         {
7843           grp_address_length = 64;
7844           address_set = 1;
7845           is_ipv6 = 0;
7846         }
7847       else if (unformat (i, "%U %U",
7848                          unformat_ip6_address, &v6_src_address,
7849                          unformat_ip6_address, &v6_grp_address))
7850         {
7851           grp_address_length = 256;
7852           address_set = 1;
7853           is_ipv6 = 1;
7854         }
7855       else if (unformat (i, "%U", unformat_ip4_address, &v4_grp_address))
7856         {
7857           memset (&v4_src_address, 0, sizeof (v4_src_address));
7858           grp_address_length = 32;
7859           address_set = 1;
7860           is_ipv6 = 0;
7861         }
7862       else if (unformat (i, "%U", unformat_ip6_address, &v6_grp_address))
7863         {
7864           memset (&v6_src_address, 0, sizeof (v6_src_address));
7865           grp_address_length = 128;
7866           address_set = 1;
7867           is_ipv6 = 1;
7868         }
7869       else if (unformat (i, "/%d", &grp_address_length))
7870         ;
7871       else if (unformat (i, "local"))
7872         {
7873           is_local = 1;
7874         }
7875       else if (unformat (i, "del"))
7876         is_add = 0;
7877       else if (unformat (i, "add"))
7878         is_add = 1;
7879       else if (unformat (i, "vrf %d", &vrf_id))
7880         ;
7881       else if (unformat (i, "create-vrf"))
7882         create_vrf_if_needed = 1;
7883       else if (unformat (i, "%U", unformat_mfib_itf_flags, &iflags))
7884         ;
7885       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
7886         ;
7887       else
7888         {
7889           clib_warning ("parse error '%U'", format_unformat_error, i);
7890           return -99;
7891         }
7892     }
7893
7894   if (address_set == 0)
7895     {
7896       errmsg ("missing addresses\n");
7897       return -99;
7898     }
7899
7900   /* Construct the API message */
7901   M (IP_MROUTE_ADD_DEL, mp);
7902
7903   mp->next_hop_sw_if_index = ntohl (sw_if_index);
7904   mp->table_id = ntohl (vrf_id);
7905   mp->create_vrf_if_needed = create_vrf_if_needed;
7906
7907   mp->is_add = is_add;
7908   mp->is_ipv6 = is_ipv6;
7909   mp->is_local = is_local;
7910   mp->itf_flags = ntohl (iflags);
7911   mp->entry_flags = ntohl (eflags);
7912   mp->grp_address_length = grp_address_length;
7913   mp->grp_address_length = ntohs (mp->grp_address_length);
7914
7915   if (is_ipv6)
7916     {
7917       clib_memcpy (mp->grp_address, &v6_grp_address, sizeof (v6_grp_address));
7918       clib_memcpy (mp->src_address, &v6_src_address, sizeof (v6_src_address));
7919     }
7920   else
7921     {
7922       clib_memcpy (mp->grp_address, &v4_grp_address, sizeof (v4_grp_address));
7923       clib_memcpy (mp->src_address, &v4_src_address, sizeof (v4_src_address));
7924
7925     }
7926
7927   /* send it... */
7928   S (mp);
7929   /* Wait for a reply... */
7930   W (ret);
7931   return ret;
7932 }
7933
7934 static int
7935 api_mpls_table_add_del (vat_main_t * vam)
7936 {
7937   unformat_input_t *i = vam->input;
7938   vl_api_mpls_table_add_del_t *mp;
7939   u32 table_id = ~0;
7940   u8 is_add = 1;
7941   int ret = 0;
7942
7943   /* Parse args required to build the message */
7944   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7945     {
7946       if (unformat (i, "table %d", &table_id))
7947         ;
7948       else if (unformat (i, "del"))
7949         is_add = 0;
7950       else if (unformat (i, "add"))
7951         is_add = 1;
7952       else
7953         {
7954           clib_warning ("parse error '%U'", format_unformat_error, i);
7955           return -99;
7956         }
7957     }
7958
7959   if (~0 == table_id)
7960     {
7961       errmsg ("missing table-ID");
7962       return -99;
7963     }
7964
7965   /* Construct the API message */
7966   M (MPLS_TABLE_ADD_DEL, mp);
7967
7968   mp->mt_table_id = ntohl (table_id);
7969   mp->mt_is_add = is_add;
7970
7971   /* send it... */
7972   S (mp);
7973
7974   /* Wait for a reply... */
7975   W (ret);
7976
7977   return ret;
7978 }
7979
7980 static int
7981 api_mpls_route_add_del (vat_main_t * vam)
7982 {
7983   unformat_input_t *i = vam->input;
7984   vl_api_mpls_route_add_del_t *mp;
7985   u32 sw_if_index = ~0, table_id = 0;
7986   u8 create_table_if_needed = 0;
7987   u8 is_add = 1;
7988   u32 next_hop_weight = 1;
7989   u8 is_multipath = 0;
7990   u32 next_hop_table_id = 0;
7991   u8 next_hop_set = 0;
7992   ip4_address_t v4_next_hop_address = {
7993     .as_u32 = 0,
7994   };
7995   ip6_address_t v6_next_hop_address = { {0} };
7996   int count = 1;
7997   int j;
7998   f64 before = 0;
7999   u32 classify_table_index = ~0;
8000   u8 is_classify = 0;
8001   u8 resolve_host = 0, resolve_attached = 0;
8002   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
8003   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8004   mpls_label_t *next_hop_out_label_stack = NULL;
8005   mpls_label_t local_label = MPLS_LABEL_INVALID;
8006   u8 is_eos = 0;
8007   dpo_proto_t next_hop_proto = DPO_PROTO_IP4;
8008
8009   /* Parse args required to build the message */
8010   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8011     {
8012       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8013         ;
8014       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8015         ;
8016       else if (unformat (i, "%d", &local_label))
8017         ;
8018       else if (unformat (i, "eos"))
8019         is_eos = 1;
8020       else if (unformat (i, "non-eos"))
8021         is_eos = 0;
8022       else if (unformat (i, "via %U", unformat_ip4_address,
8023                          &v4_next_hop_address))
8024         {
8025           next_hop_set = 1;
8026           next_hop_proto = DPO_PROTO_IP4;
8027         }
8028       else if (unformat (i, "via %U", unformat_ip6_address,
8029                          &v6_next_hop_address))
8030         {
8031           next_hop_set = 1;
8032           next_hop_proto = DPO_PROTO_IP6;
8033         }
8034       else if (unformat (i, "weight %d", &next_hop_weight))
8035         ;
8036       else if (unformat (i, "create-table"))
8037         create_table_if_needed = 1;
8038       else if (unformat (i, "classify %d", &classify_table_index))
8039         {
8040           is_classify = 1;
8041         }
8042       else if (unformat (i, "del"))
8043         is_add = 0;
8044       else if (unformat (i, "add"))
8045         is_add = 1;
8046       else if (unformat (i, "resolve-via-host"))
8047         resolve_host = 1;
8048       else if (unformat (i, "resolve-via-attached"))
8049         resolve_attached = 1;
8050       else if (unformat (i, "multipath"))
8051         is_multipath = 1;
8052       else if (unformat (i, "count %d", &count))
8053         ;
8054       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
8055         {
8056           next_hop_set = 1;
8057           next_hop_proto = DPO_PROTO_IP4;
8058         }
8059       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
8060         {
8061           next_hop_set = 1;
8062           next_hop_proto = DPO_PROTO_IP6;
8063         }
8064       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8065         ;
8066       else if (unformat (i, "via-label %d", &next_hop_via_label))
8067         ;
8068       else if (unformat (i, "out-label %d", &next_hop_out_label))
8069         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
8070       else
8071         {
8072           clib_warning ("parse error '%U'", format_unformat_error, i);
8073           return -99;
8074         }
8075     }
8076
8077   if (!next_hop_set && !is_classify)
8078     {
8079       errmsg ("next hop / classify not set");
8080       return -99;
8081     }
8082
8083   if (MPLS_LABEL_INVALID == local_label)
8084     {
8085       errmsg ("missing label");
8086       return -99;
8087     }
8088
8089   if (count > 1)
8090     {
8091       /* Turn on async mode */
8092       vam->async_mode = 1;
8093       vam->async_errors = 0;
8094       before = vat_time_now (vam);
8095     }
8096
8097   for (j = 0; j < count; j++)
8098     {
8099       /* Construct the API message */
8100       M2 (MPLS_ROUTE_ADD_DEL, mp,
8101           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
8102
8103       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
8104       mp->mr_table_id = ntohl (table_id);
8105       mp->mr_create_table_if_needed = create_table_if_needed;
8106
8107       mp->mr_is_add = is_add;
8108       mp->mr_next_hop_proto = next_hop_proto;
8109       mp->mr_is_classify = is_classify;
8110       mp->mr_is_multipath = is_multipath;
8111       mp->mr_is_resolve_host = resolve_host;
8112       mp->mr_is_resolve_attached = resolve_attached;
8113       mp->mr_next_hop_weight = next_hop_weight;
8114       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
8115       mp->mr_classify_table_index = ntohl (classify_table_index);
8116       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
8117       mp->mr_label = ntohl (local_label);
8118       mp->mr_eos = is_eos;
8119
8120       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
8121       if (0 != mp->mr_next_hop_n_out_labels)
8122         {
8123           memcpy (mp->mr_next_hop_out_label_stack,
8124                   next_hop_out_label_stack,
8125                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
8126           vec_free (next_hop_out_label_stack);
8127         }
8128
8129       if (next_hop_set)
8130         {
8131           if (DPO_PROTO_IP4 == next_hop_proto)
8132             {
8133               clib_memcpy (mp->mr_next_hop,
8134                            &v4_next_hop_address,
8135                            sizeof (v4_next_hop_address));
8136             }
8137           else if (DPO_PROTO_IP6 == next_hop_proto)
8138
8139             {
8140               clib_memcpy (mp->mr_next_hop,
8141                            &v6_next_hop_address,
8142                            sizeof (v6_next_hop_address));
8143             }
8144         }
8145       local_label++;
8146
8147       /* send it... */
8148       S (mp);
8149       /* If we receive SIGTERM, stop now... */
8150       if (vam->do_exit)
8151         break;
8152     }
8153
8154   /* When testing multiple add/del ops, use a control-ping to sync */
8155   if (count > 1)
8156     {
8157       vl_api_control_ping_t *mp_ping;
8158       f64 after;
8159       f64 timeout;
8160
8161       /* Shut off async mode */
8162       vam->async_mode = 0;
8163
8164       MPING (CONTROL_PING, mp_ping);
8165       S (mp_ping);
8166
8167       timeout = vat_time_now (vam) + 1.0;
8168       while (vat_time_now (vam) < timeout)
8169         if (vam->result_ready == 1)
8170           goto out;
8171       vam->retval = -99;
8172
8173     out:
8174       if (vam->retval == -99)
8175         errmsg ("timeout");
8176
8177       if (vam->async_errors > 0)
8178         {
8179           errmsg ("%d asynchronous errors", vam->async_errors);
8180           vam->retval = -98;
8181         }
8182       vam->async_errors = 0;
8183       after = vat_time_now (vam);
8184
8185       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8186       if (j > 0)
8187         count = j;
8188
8189       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8190              count, after - before, count / (after - before));
8191     }
8192   else
8193     {
8194       int ret;
8195
8196       /* Wait for a reply... */
8197       W (ret);
8198       return ret;
8199     }
8200
8201   /* Return the good/bad news */
8202   return (vam->retval);
8203 }
8204
8205 static int
8206 api_mpls_ip_bind_unbind (vat_main_t * vam)
8207 {
8208   unformat_input_t *i = vam->input;
8209   vl_api_mpls_ip_bind_unbind_t *mp;
8210   u32 ip_table_id = 0;
8211   u8 create_table_if_needed = 0;
8212   u8 is_bind = 1;
8213   u8 is_ip4 = 1;
8214   ip4_address_t v4_address;
8215   ip6_address_t v6_address;
8216   u32 address_length;
8217   u8 address_set = 0;
8218   mpls_label_t local_label = MPLS_LABEL_INVALID;
8219   int ret;
8220
8221   /* Parse args required to build the message */
8222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8223     {
8224       if (unformat (i, "%U/%d", unformat_ip4_address,
8225                     &v4_address, &address_length))
8226         {
8227           is_ip4 = 1;
8228           address_set = 1;
8229         }
8230       else if (unformat (i, "%U/%d", unformat_ip6_address,
8231                          &v6_address, &address_length))
8232         {
8233           is_ip4 = 0;
8234           address_set = 1;
8235         }
8236       else if (unformat (i, "%d", &local_label))
8237         ;
8238       else if (unformat (i, "create-table"))
8239         create_table_if_needed = 1;
8240       else if (unformat (i, "table-id %d", &ip_table_id))
8241         ;
8242       else if (unformat (i, "unbind"))
8243         is_bind = 0;
8244       else if (unformat (i, "bind"))
8245         is_bind = 1;
8246       else
8247         {
8248           clib_warning ("parse error '%U'", format_unformat_error, i);
8249           return -99;
8250         }
8251     }
8252
8253   if (!address_set)
8254     {
8255       errmsg ("IP addres not set");
8256       return -99;
8257     }
8258
8259   if (MPLS_LABEL_INVALID == local_label)
8260     {
8261       errmsg ("missing label");
8262       return -99;
8263     }
8264
8265   /* Construct the API message */
8266   M (MPLS_IP_BIND_UNBIND, mp);
8267
8268   mp->mb_create_table_if_needed = create_table_if_needed;
8269   mp->mb_is_bind = is_bind;
8270   mp->mb_is_ip4 = is_ip4;
8271   mp->mb_ip_table_id = ntohl (ip_table_id);
8272   mp->mb_mpls_table_id = 0;
8273   mp->mb_label = ntohl (local_label);
8274   mp->mb_address_length = address_length;
8275
8276   if (is_ip4)
8277     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
8278   else
8279     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
8280
8281   /* send it... */
8282   S (mp);
8283
8284   /* Wait for a reply... */
8285   W (ret);
8286   return ret;
8287 }
8288
8289 static int
8290 api_proxy_arp_add_del (vat_main_t * vam)
8291 {
8292   unformat_input_t *i = vam->input;
8293   vl_api_proxy_arp_add_del_t *mp;
8294   u32 vrf_id = 0;
8295   u8 is_add = 1;
8296   ip4_address_t lo, hi;
8297   u8 range_set = 0;
8298   int ret;
8299
8300   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8301     {
8302       if (unformat (i, "vrf %d", &vrf_id))
8303         ;
8304       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
8305                          unformat_ip4_address, &hi))
8306         range_set = 1;
8307       else if (unformat (i, "del"))
8308         is_add = 0;
8309       else
8310         {
8311           clib_warning ("parse error '%U'", format_unformat_error, i);
8312           return -99;
8313         }
8314     }
8315
8316   if (range_set == 0)
8317     {
8318       errmsg ("address range not set");
8319       return -99;
8320     }
8321
8322   M (PROXY_ARP_ADD_DEL, mp);
8323
8324   mp->vrf_id = ntohl (vrf_id);
8325   mp->is_add = is_add;
8326   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
8327   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
8328
8329   S (mp);
8330   W (ret);
8331   return ret;
8332 }
8333
8334 static int
8335 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8336 {
8337   unformat_input_t *i = vam->input;
8338   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8339   u32 sw_if_index;
8340   u8 enable = 1;
8341   u8 sw_if_index_set = 0;
8342   int ret;
8343
8344   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8345     {
8346       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8347         sw_if_index_set = 1;
8348       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8349         sw_if_index_set = 1;
8350       else if (unformat (i, "enable"))
8351         enable = 1;
8352       else if (unformat (i, "disable"))
8353         enable = 0;
8354       else
8355         {
8356           clib_warning ("parse error '%U'", format_unformat_error, i);
8357           return -99;
8358         }
8359     }
8360
8361   if (sw_if_index_set == 0)
8362     {
8363       errmsg ("missing interface name or sw_if_index");
8364       return -99;
8365     }
8366
8367   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8368
8369   mp->sw_if_index = ntohl (sw_if_index);
8370   mp->enable_disable = enable;
8371
8372   S (mp);
8373   W (ret);
8374   return ret;
8375 }
8376
8377 static int
8378 api_mpls_tunnel_add_del (vat_main_t * vam)
8379 {
8380   unformat_input_t *i = vam->input;
8381   vl_api_mpls_tunnel_add_del_t *mp;
8382
8383   u8 is_add = 1;
8384   u8 l2_only = 0;
8385   u32 sw_if_index = ~0;
8386   u32 next_hop_sw_if_index = ~0;
8387   u32 next_hop_proto_is_ip4 = 1;
8388
8389   u32 next_hop_table_id = 0;
8390   ip4_address_t v4_next_hop_address = {
8391     .as_u32 = 0,
8392   };
8393   ip6_address_t v6_next_hop_address = { {0} };
8394   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
8395   int ret;
8396
8397   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8398     {
8399       if (unformat (i, "add"))
8400         is_add = 1;
8401       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8402         is_add = 0;
8403       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
8404         ;
8405       else if (unformat (i, "via %U",
8406                          unformat_ip4_address, &v4_next_hop_address))
8407         {
8408           next_hop_proto_is_ip4 = 1;
8409         }
8410       else if (unformat (i, "via %U",
8411                          unformat_ip6_address, &v6_next_hop_address))
8412         {
8413           next_hop_proto_is_ip4 = 0;
8414         }
8415       else if (unformat (i, "l2-only"))
8416         l2_only = 1;
8417       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
8418         ;
8419       else if (unformat (i, "out-label %d", &next_hop_out_label))
8420         vec_add1 (labels, ntohl (next_hop_out_label));
8421       else
8422         {
8423           clib_warning ("parse error '%U'", format_unformat_error, i);
8424           return -99;
8425         }
8426     }
8427
8428   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (mpls_label_t) * vec_len (labels));
8429
8430   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
8431   mp->mt_sw_if_index = ntohl (sw_if_index);
8432   mp->mt_is_add = is_add;
8433   mp->mt_l2_only = l2_only;
8434   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
8435   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
8436
8437   mp->mt_next_hop_n_out_labels = vec_len (labels);
8438
8439   if (0 != mp->mt_next_hop_n_out_labels)
8440     {
8441       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
8442                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
8443       vec_free (labels);
8444     }
8445
8446   if (next_hop_proto_is_ip4)
8447     {
8448       clib_memcpy (mp->mt_next_hop,
8449                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8450     }
8451   else
8452     {
8453       clib_memcpy (mp->mt_next_hop,
8454                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8455     }
8456
8457   S (mp);
8458   W (ret);
8459   return ret;
8460 }
8461
8462 static int
8463 api_sw_interface_set_unnumbered (vat_main_t * vam)
8464 {
8465   unformat_input_t *i = vam->input;
8466   vl_api_sw_interface_set_unnumbered_t *mp;
8467   u32 sw_if_index;
8468   u32 unnum_sw_index = ~0;
8469   u8 is_add = 1;
8470   u8 sw_if_index_set = 0;
8471   int ret;
8472
8473   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8474     {
8475       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8476         sw_if_index_set = 1;
8477       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8478         sw_if_index_set = 1;
8479       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8480         ;
8481       else if (unformat (i, "del"))
8482         is_add = 0;
8483       else
8484         {
8485           clib_warning ("parse error '%U'", format_unformat_error, i);
8486           return -99;
8487         }
8488     }
8489
8490   if (sw_if_index_set == 0)
8491     {
8492       errmsg ("missing interface name or sw_if_index");
8493       return -99;
8494     }
8495
8496   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8497
8498   mp->sw_if_index = ntohl (sw_if_index);
8499   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8500   mp->is_add = is_add;
8501
8502   S (mp);
8503   W (ret);
8504   return ret;
8505 }
8506
8507 static int
8508 api_ip_neighbor_add_del (vat_main_t * vam)
8509 {
8510   unformat_input_t *i = vam->input;
8511   vl_api_ip_neighbor_add_del_t *mp;
8512   u32 sw_if_index;
8513   u8 sw_if_index_set = 0;
8514   u8 is_add = 1;
8515   u8 is_static = 0;
8516   u8 is_no_fib_entry = 0;
8517   u8 mac_address[6];
8518   u8 mac_set = 0;
8519   u8 v4_address_set = 0;
8520   u8 v6_address_set = 0;
8521   ip4_address_t v4address;
8522   ip6_address_t v6address;
8523   int ret;
8524
8525   memset (mac_address, 0, sizeof (mac_address));
8526
8527   /* Parse args required to build the message */
8528   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8529     {
8530       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
8531         {
8532           mac_set = 1;
8533         }
8534       else if (unformat (i, "del"))
8535         is_add = 0;
8536       else
8537         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8538         sw_if_index_set = 1;
8539       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8540         sw_if_index_set = 1;
8541       else if (unformat (i, "is_static"))
8542         is_static = 1;
8543       else if (unformat (i, "no-fib-entry"))
8544         is_no_fib_entry = 1;
8545       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
8546         v4_address_set = 1;
8547       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
8548         v6_address_set = 1;
8549       else
8550         {
8551           clib_warning ("parse error '%U'", format_unformat_error, i);
8552           return -99;
8553         }
8554     }
8555
8556   if (sw_if_index_set == 0)
8557     {
8558       errmsg ("missing interface name or sw_if_index");
8559       return -99;
8560     }
8561   if (v4_address_set && v6_address_set)
8562     {
8563       errmsg ("both v4 and v6 addresses set");
8564       return -99;
8565     }
8566   if (!v4_address_set && !v6_address_set)
8567     {
8568       errmsg ("no address set");
8569       return -99;
8570     }
8571
8572   /* Construct the API message */
8573   M (IP_NEIGHBOR_ADD_DEL, mp);
8574
8575   mp->sw_if_index = ntohl (sw_if_index);
8576   mp->is_add = is_add;
8577   mp->is_static = is_static;
8578   mp->is_no_adj_fib = is_no_fib_entry;
8579   if (mac_set)
8580     clib_memcpy (mp->mac_address, mac_address, 6);
8581   if (v6_address_set)
8582     {
8583       mp->is_ipv6 = 1;
8584       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
8585     }
8586   else
8587     {
8588       /* mp->is_ipv6 = 0; via memset in M macro above */
8589       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
8590     }
8591
8592   /* send it... */
8593   S (mp);
8594
8595   /* Wait for a reply, return good/bad news  */
8596   W (ret);
8597   return ret;
8598 }
8599
8600 static int
8601 api_reset_vrf (vat_main_t * vam)
8602 {
8603   unformat_input_t *i = vam->input;
8604   vl_api_reset_vrf_t *mp;
8605   u32 vrf_id = 0;
8606   u8 is_ipv6 = 0;
8607   u8 vrf_id_set = 0;
8608   int ret;
8609
8610   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8611     {
8612       if (unformat (i, "vrf %d", &vrf_id))
8613         vrf_id_set = 1;
8614       else if (unformat (i, "ipv6"))
8615         is_ipv6 = 1;
8616       else
8617         {
8618           clib_warning ("parse error '%U'", format_unformat_error, i);
8619           return -99;
8620         }
8621     }
8622
8623   if (vrf_id_set == 0)
8624     {
8625       errmsg ("missing vrf id");
8626       return -99;
8627     }
8628
8629   M (RESET_VRF, mp);
8630
8631   mp->vrf_id = ntohl (vrf_id);
8632   mp->is_ipv6 = is_ipv6;
8633
8634   S (mp);
8635   W (ret);
8636   return ret;
8637 }
8638
8639 static int
8640 api_create_vlan_subif (vat_main_t * vam)
8641 {
8642   unformat_input_t *i = vam->input;
8643   vl_api_create_vlan_subif_t *mp;
8644   u32 sw_if_index;
8645   u8 sw_if_index_set = 0;
8646   u32 vlan_id;
8647   u8 vlan_id_set = 0;
8648   int ret;
8649
8650   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8651     {
8652       if (unformat (i, "sw_if_index %d", &sw_if_index))
8653         sw_if_index_set = 1;
8654       else
8655         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8656         sw_if_index_set = 1;
8657       else if (unformat (i, "vlan %d", &vlan_id))
8658         vlan_id_set = 1;
8659       else
8660         {
8661           clib_warning ("parse error '%U'", format_unformat_error, i);
8662           return -99;
8663         }
8664     }
8665
8666   if (sw_if_index_set == 0)
8667     {
8668       errmsg ("missing interface name or sw_if_index");
8669       return -99;
8670     }
8671
8672   if (vlan_id_set == 0)
8673     {
8674       errmsg ("missing vlan_id");
8675       return -99;
8676     }
8677   M (CREATE_VLAN_SUBIF, mp);
8678
8679   mp->sw_if_index = ntohl (sw_if_index);
8680   mp->vlan_id = ntohl (vlan_id);
8681
8682   S (mp);
8683   W (ret);
8684   return ret;
8685 }
8686
8687 #define foreach_create_subif_bit                \
8688 _(no_tags)                                      \
8689 _(one_tag)                                      \
8690 _(two_tags)                                     \
8691 _(dot1ad)                                       \
8692 _(exact_match)                                  \
8693 _(default_sub)                                  \
8694 _(outer_vlan_id_any)                            \
8695 _(inner_vlan_id_any)
8696
8697 static int
8698 api_create_subif (vat_main_t * vam)
8699 {
8700   unformat_input_t *i = vam->input;
8701   vl_api_create_subif_t *mp;
8702   u32 sw_if_index;
8703   u8 sw_if_index_set = 0;
8704   u32 sub_id;
8705   u8 sub_id_set = 0;
8706   u32 no_tags = 0;
8707   u32 one_tag = 0;
8708   u32 two_tags = 0;
8709   u32 dot1ad = 0;
8710   u32 exact_match = 0;
8711   u32 default_sub = 0;
8712   u32 outer_vlan_id_any = 0;
8713   u32 inner_vlan_id_any = 0;
8714   u32 tmp;
8715   u16 outer_vlan_id = 0;
8716   u16 inner_vlan_id = 0;
8717   int ret;
8718
8719   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8720     {
8721       if (unformat (i, "sw_if_index %d", &sw_if_index))
8722         sw_if_index_set = 1;
8723       else
8724         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8725         sw_if_index_set = 1;
8726       else if (unformat (i, "sub_id %d", &sub_id))
8727         sub_id_set = 1;
8728       else if (unformat (i, "outer_vlan_id %d", &tmp))
8729         outer_vlan_id = tmp;
8730       else if (unformat (i, "inner_vlan_id %d", &tmp))
8731         inner_vlan_id = tmp;
8732
8733 #define _(a) else if (unformat (i, #a)) a = 1 ;
8734       foreach_create_subif_bit
8735 #undef _
8736         else
8737         {
8738           clib_warning ("parse error '%U'", format_unformat_error, i);
8739           return -99;
8740         }
8741     }
8742
8743   if (sw_if_index_set == 0)
8744     {
8745       errmsg ("missing interface name or sw_if_index");
8746       return -99;
8747     }
8748
8749   if (sub_id_set == 0)
8750     {
8751       errmsg ("missing sub_id");
8752       return -99;
8753     }
8754   M (CREATE_SUBIF, mp);
8755
8756   mp->sw_if_index = ntohl (sw_if_index);
8757   mp->sub_id = ntohl (sub_id);
8758
8759 #define _(a) mp->a = a;
8760   foreach_create_subif_bit;
8761 #undef _
8762
8763   mp->outer_vlan_id = ntohs (outer_vlan_id);
8764   mp->inner_vlan_id = ntohs (inner_vlan_id);
8765
8766   S (mp);
8767   W (ret);
8768   return ret;
8769 }
8770
8771 static int
8772 api_oam_add_del (vat_main_t * vam)
8773 {
8774   unformat_input_t *i = vam->input;
8775   vl_api_oam_add_del_t *mp;
8776   u32 vrf_id = 0;
8777   u8 is_add = 1;
8778   ip4_address_t src, dst;
8779   u8 src_set = 0;
8780   u8 dst_set = 0;
8781   int ret;
8782
8783   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8784     {
8785       if (unformat (i, "vrf %d", &vrf_id))
8786         ;
8787       else if (unformat (i, "src %U", unformat_ip4_address, &src))
8788         src_set = 1;
8789       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
8790         dst_set = 1;
8791       else if (unformat (i, "del"))
8792         is_add = 0;
8793       else
8794         {
8795           clib_warning ("parse error '%U'", format_unformat_error, i);
8796           return -99;
8797         }
8798     }
8799
8800   if (src_set == 0)
8801     {
8802       errmsg ("missing src addr");
8803       return -99;
8804     }
8805
8806   if (dst_set == 0)
8807     {
8808       errmsg ("missing dst addr");
8809       return -99;
8810     }
8811
8812   M (OAM_ADD_DEL, mp);
8813
8814   mp->vrf_id = ntohl (vrf_id);
8815   mp->is_add = is_add;
8816   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
8817   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
8818
8819   S (mp);
8820   W (ret);
8821   return ret;
8822 }
8823
8824 static int
8825 api_reset_fib (vat_main_t * vam)
8826 {
8827   unformat_input_t *i = vam->input;
8828   vl_api_reset_fib_t *mp;
8829   u32 vrf_id = 0;
8830   u8 is_ipv6 = 0;
8831   u8 vrf_id_set = 0;
8832
8833   int ret;
8834   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8835     {
8836       if (unformat (i, "vrf %d", &vrf_id))
8837         vrf_id_set = 1;
8838       else if (unformat (i, "ipv6"))
8839         is_ipv6 = 1;
8840       else
8841         {
8842           clib_warning ("parse error '%U'", format_unformat_error, i);
8843           return -99;
8844         }
8845     }
8846
8847   if (vrf_id_set == 0)
8848     {
8849       errmsg ("missing vrf id");
8850       return -99;
8851     }
8852
8853   M (RESET_FIB, mp);
8854
8855   mp->vrf_id = ntohl (vrf_id);
8856   mp->is_ipv6 = is_ipv6;
8857
8858   S (mp);
8859   W (ret);
8860   return ret;
8861 }
8862
8863 static int
8864 api_dhcp_proxy_config (vat_main_t * vam)
8865 {
8866   unformat_input_t *i = vam->input;
8867   vl_api_dhcp_proxy_config_t *mp;
8868   u32 rx_vrf_id = 0;
8869   u32 server_vrf_id = 0;
8870   u8 is_add = 1;
8871   u8 v4_address_set = 0;
8872   u8 v6_address_set = 0;
8873   ip4_address_t v4address;
8874   ip6_address_t v6address;
8875   u8 v4_src_address_set = 0;
8876   u8 v6_src_address_set = 0;
8877   ip4_address_t v4srcaddress;
8878   ip6_address_t v6srcaddress;
8879   int ret;
8880
8881   /* Parse args required to build the message */
8882   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8883     {
8884       if (unformat (i, "del"))
8885         is_add = 0;
8886       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
8887         ;
8888       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
8889         ;
8890       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
8891         v4_address_set = 1;
8892       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
8893         v6_address_set = 1;
8894       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
8895         v4_src_address_set = 1;
8896       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
8897         v6_src_address_set = 1;
8898       else
8899         break;
8900     }
8901
8902   if (v4_address_set && v6_address_set)
8903     {
8904       errmsg ("both v4 and v6 server addresses set");
8905       return -99;
8906     }
8907   if (!v4_address_set && !v6_address_set)
8908     {
8909       errmsg ("no server addresses set");
8910       return -99;
8911     }
8912
8913   if (v4_src_address_set && v6_src_address_set)
8914     {
8915       errmsg ("both v4 and v6  src addresses set");
8916       return -99;
8917     }
8918   if (!v4_src_address_set && !v6_src_address_set)
8919     {
8920       errmsg ("no src addresses set");
8921       return -99;
8922     }
8923
8924   if (!(v4_src_address_set && v4_address_set) &&
8925       !(v6_src_address_set && v6_address_set))
8926     {
8927       errmsg ("no matching server and src addresses set");
8928       return -99;
8929     }
8930
8931   /* Construct the API message */
8932   M (DHCP_PROXY_CONFIG, mp);
8933
8934   mp->is_add = is_add;
8935   mp->rx_vrf_id = ntohl (rx_vrf_id);
8936   mp->server_vrf_id = ntohl (server_vrf_id);
8937   if (v6_address_set)
8938     {
8939       mp->is_ipv6 = 1;
8940       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
8941       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
8942     }
8943   else
8944     {
8945       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
8946       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
8947     }
8948
8949   /* send it... */
8950   S (mp);
8951
8952   /* Wait for a reply, return good/bad news  */
8953   W (ret);
8954   return ret;
8955 }
8956
8957 #define vl_api_dhcp_proxy_details_t_endian vl_noop_handler
8958 #define vl_api_dhcp_proxy_details_t_print vl_noop_handler
8959
8960 static void
8961 vl_api_dhcp_proxy_details_t_handler (vl_api_dhcp_proxy_details_t * mp)
8962 {
8963   vat_main_t *vam = &vat_main;
8964   u32 i, count = mp->count;
8965   vl_api_dhcp_server_t *s;
8966
8967   if (mp->is_ipv6)
8968     print (vam->ofp,
8969            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8970            ntohl (mp->rx_vrf_id),
8971            format_ip6_address, mp->dhcp_src_address,
8972            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8973   else
8974     print (vam->ofp,
8975            "RX Table-ID %d, Source Address %U, VSS FIB-ID %d, VSS OUI %d",
8976            ntohl (mp->rx_vrf_id),
8977            format_ip4_address, mp->dhcp_src_address,
8978            ntohl (mp->vss_oui), ntohl (mp->vss_fib_id));
8979
8980   for (i = 0; i < count; i++)
8981     {
8982       s = &mp->servers[i];
8983
8984       if (mp->is_ipv6)
8985         print (vam->ofp,
8986                " Server Table-ID %d, Server Address %U",
8987                ntohl (s->server_vrf_id), format_ip6_address, s->dhcp_server);
8988       else
8989         print (vam->ofp,
8990                " Server Table-ID %d, Server Address %U",
8991                ntohl (s->server_vrf_id), format_ip4_address, s->dhcp_server);
8992     }
8993 }
8994
8995 static void vl_api_dhcp_proxy_details_t_handler_json
8996   (vl_api_dhcp_proxy_details_t * mp)
8997 {
8998   vat_main_t *vam = &vat_main;
8999   vat_json_node_t *node = NULL;
9000   u32 i, count = mp->count;
9001   struct in_addr ip4;
9002   struct in6_addr ip6;
9003   vl_api_dhcp_server_t *s;
9004
9005   if (VAT_JSON_ARRAY != vam->json_tree.type)
9006     {
9007       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9008       vat_json_init_array (&vam->json_tree);
9009     }
9010   node = vat_json_array_add (&vam->json_tree);
9011
9012   vat_json_init_object (node);
9013   vat_json_object_add_uint (node, "rx-table-id", ntohl (mp->rx_vrf_id));
9014   vat_json_object_add_uint (node, "vss-fib-id", ntohl (mp->vss_fib_id));
9015   vat_json_object_add_uint (node, "vss-oui", ntohl (mp->vss_oui));
9016
9017   if (mp->is_ipv6)
9018     {
9019       clib_memcpy (&ip6, &mp->dhcp_src_address, sizeof (ip6));
9020       vat_json_object_add_ip6 (node, "src_address", ip6);
9021     }
9022   else
9023     {
9024       clib_memcpy (&ip4, &mp->dhcp_src_address, sizeof (ip4));
9025       vat_json_object_add_ip4 (node, "src_address", ip4);
9026     }
9027
9028   for (i = 0; i < count; i++)
9029     {
9030       s = &mp->servers[i];
9031
9032       vat_json_object_add_uint (node, "server-table-id",
9033                                 ntohl (s->server_vrf_id));
9034
9035       if (mp->is_ipv6)
9036         {
9037           clib_memcpy (&ip4, &s->dhcp_server, sizeof (ip4));
9038           vat_json_object_add_ip4 (node, "src_address", ip4);
9039         }
9040       else
9041         {
9042           clib_memcpy (&ip6, &s->dhcp_server, sizeof (ip6));
9043           vat_json_object_add_ip6 (node, "server_address", ip6);
9044         }
9045     }
9046 }
9047
9048 static int
9049 api_dhcp_proxy_dump (vat_main_t * vam)
9050 {
9051   unformat_input_t *i = vam->input;
9052   vl_api_control_ping_t *mp_ping;
9053   vl_api_dhcp_proxy_dump_t *mp;
9054   u8 is_ipv6 = 0;
9055   int ret;
9056
9057   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9058     {
9059       if (unformat (i, "ipv6"))
9060         is_ipv6 = 1;
9061       else
9062         {
9063           clib_warning ("parse error '%U'", format_unformat_error, i);
9064           return -99;
9065         }
9066     }
9067
9068   M (DHCP_PROXY_DUMP, mp);
9069
9070   mp->is_ip6 = is_ipv6;
9071   S (mp);
9072
9073   /* Use a control ping for synchronization */
9074   MPING (CONTROL_PING, mp_ping);
9075   S (mp_ping);
9076
9077   W (ret);
9078   return ret;
9079 }
9080
9081 static int
9082 api_dhcp_proxy_set_vss (vat_main_t * vam)
9083 {
9084   unformat_input_t *i = vam->input;
9085   vl_api_dhcp_proxy_set_vss_t *mp;
9086   u8 is_ipv6 = 0;
9087   u8 is_add = 1;
9088   u32 tbl_id;
9089   u8 tbl_id_set = 0;
9090   u32 oui;
9091   u8 oui_set = 0;
9092   u32 fib_id;
9093   u8 fib_id_set = 0;
9094   int ret;
9095
9096   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9097     {
9098       if (unformat (i, "tbl_id %d", &tbl_id))
9099         tbl_id_set = 1;
9100       if (unformat (i, "fib_id %d", &fib_id))
9101         fib_id_set = 1;
9102       if (unformat (i, "oui %d", &oui))
9103         oui_set = 1;
9104       else if (unformat (i, "ipv6"))
9105         is_ipv6 = 1;
9106       else if (unformat (i, "del"))
9107         is_add = 0;
9108       else
9109         {
9110           clib_warning ("parse error '%U'", format_unformat_error, i);
9111           return -99;
9112         }
9113     }
9114
9115   if (tbl_id_set == 0)
9116     {
9117       errmsg ("missing tbl id");
9118       return -99;
9119     }
9120
9121   if (fib_id_set == 0)
9122     {
9123       errmsg ("missing fib id");
9124       return -99;
9125     }
9126   if (oui_set == 0)
9127     {
9128       errmsg ("missing oui");
9129       return -99;
9130     }
9131
9132   M (DHCP_PROXY_SET_VSS, mp);
9133   mp->tbl_id = ntohl (tbl_id);
9134   mp->fib_id = ntohl (fib_id);
9135   mp->oui = ntohl (oui);
9136   mp->is_ipv6 = is_ipv6;
9137   mp->is_add = is_add;
9138
9139   S (mp);
9140   W (ret);
9141   return ret;
9142 }
9143
9144 static int
9145 api_dhcp_client_config (vat_main_t * vam)
9146 {
9147   unformat_input_t *i = vam->input;
9148   vl_api_dhcp_client_config_t *mp;
9149   u32 sw_if_index;
9150   u8 sw_if_index_set = 0;
9151   u8 is_add = 1;
9152   u8 *hostname = 0;
9153   u8 disable_event = 0;
9154   int ret;
9155
9156   /* Parse args required to build the message */
9157   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9158     {
9159       if (unformat (i, "del"))
9160         is_add = 0;
9161       else
9162         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9163         sw_if_index_set = 1;
9164       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9165         sw_if_index_set = 1;
9166       else if (unformat (i, "hostname %s", &hostname))
9167         ;
9168       else if (unformat (i, "disable_event"))
9169         disable_event = 1;
9170       else
9171         break;
9172     }
9173
9174   if (sw_if_index_set == 0)
9175     {
9176       errmsg ("missing interface name or sw_if_index");
9177       return -99;
9178     }
9179
9180   if (vec_len (hostname) > 63)
9181     {
9182       errmsg ("hostname too long");
9183     }
9184   vec_add1 (hostname, 0);
9185
9186   /* Construct the API message */
9187   M (DHCP_CLIENT_CONFIG, mp);
9188
9189   mp->sw_if_index = htonl (sw_if_index);
9190   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
9191   vec_free (hostname);
9192   mp->is_add = is_add;
9193   mp->want_dhcp_event = disable_event ? 0 : 1;
9194   mp->pid = htonl (getpid ());
9195
9196   /* send it... */
9197   S (mp);
9198
9199   /* Wait for a reply, return good/bad news  */
9200   W (ret);
9201   return ret;
9202 }
9203
9204 static int
9205 api_set_ip_flow_hash (vat_main_t * vam)
9206 {
9207   unformat_input_t *i = vam->input;
9208   vl_api_set_ip_flow_hash_t *mp;
9209   u32 vrf_id = 0;
9210   u8 is_ipv6 = 0;
9211   u8 vrf_id_set = 0;
9212   u8 src = 0;
9213   u8 dst = 0;
9214   u8 sport = 0;
9215   u8 dport = 0;
9216   u8 proto = 0;
9217   u8 reverse = 0;
9218   int ret;
9219
9220   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9221     {
9222       if (unformat (i, "vrf %d", &vrf_id))
9223         vrf_id_set = 1;
9224       else if (unformat (i, "ipv6"))
9225         is_ipv6 = 1;
9226       else if (unformat (i, "src"))
9227         src = 1;
9228       else if (unformat (i, "dst"))
9229         dst = 1;
9230       else if (unformat (i, "sport"))
9231         sport = 1;
9232       else if (unformat (i, "dport"))
9233         dport = 1;
9234       else if (unformat (i, "proto"))
9235         proto = 1;
9236       else if (unformat (i, "reverse"))
9237         reverse = 1;
9238
9239       else
9240         {
9241           clib_warning ("parse error '%U'", format_unformat_error, i);
9242           return -99;
9243         }
9244     }
9245
9246   if (vrf_id_set == 0)
9247     {
9248       errmsg ("missing vrf id");
9249       return -99;
9250     }
9251
9252   M (SET_IP_FLOW_HASH, mp);
9253   mp->src = src;
9254   mp->dst = dst;
9255   mp->sport = sport;
9256   mp->dport = dport;
9257   mp->proto = proto;
9258   mp->reverse = reverse;
9259   mp->vrf_id = ntohl (vrf_id);
9260   mp->is_ipv6 = is_ipv6;
9261
9262   S (mp);
9263   W (ret);
9264   return ret;
9265 }
9266
9267 static int
9268 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9269 {
9270   unformat_input_t *i = vam->input;
9271   vl_api_sw_interface_ip6_enable_disable_t *mp;
9272   u32 sw_if_index;
9273   u8 sw_if_index_set = 0;
9274   u8 enable = 0;
9275   int ret;
9276
9277   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9278     {
9279       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9280         sw_if_index_set = 1;
9281       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9282         sw_if_index_set = 1;
9283       else if (unformat (i, "enable"))
9284         enable = 1;
9285       else if (unformat (i, "disable"))
9286         enable = 0;
9287       else
9288         {
9289           clib_warning ("parse error '%U'", format_unformat_error, i);
9290           return -99;
9291         }
9292     }
9293
9294   if (sw_if_index_set == 0)
9295     {
9296       errmsg ("missing interface name or sw_if_index");
9297       return -99;
9298     }
9299
9300   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9301
9302   mp->sw_if_index = ntohl (sw_if_index);
9303   mp->enable = enable;
9304
9305   S (mp);
9306   W (ret);
9307   return ret;
9308 }
9309
9310 static int
9311 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
9312 {
9313   unformat_input_t *i = vam->input;
9314   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
9315   u32 sw_if_index;
9316   u8 sw_if_index_set = 0;
9317   u8 v6_address_set = 0;
9318   ip6_address_t v6address;
9319   int ret;
9320
9321   /* Parse args required to build the message */
9322   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9323     {
9324       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9325         sw_if_index_set = 1;
9326       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9327         sw_if_index_set = 1;
9328       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9329         v6_address_set = 1;
9330       else
9331         break;
9332     }
9333
9334   if (sw_if_index_set == 0)
9335     {
9336       errmsg ("missing interface name or sw_if_index");
9337       return -99;
9338     }
9339   if (!v6_address_set)
9340     {
9341       errmsg ("no address set");
9342       return -99;
9343     }
9344
9345   /* Construct the API message */
9346   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, mp);
9347
9348   mp->sw_if_index = ntohl (sw_if_index);
9349   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9350
9351   /* send it... */
9352   S (mp);
9353
9354   /* Wait for a reply, return good/bad news  */
9355   W (ret);
9356   return ret;
9357 }
9358
9359 static int
9360 api_ip6nd_proxy_add_del (vat_main_t * vam)
9361 {
9362   unformat_input_t *i = vam->input;
9363   vl_api_ip6nd_proxy_add_del_t *mp;
9364   u32 sw_if_index = ~0;
9365   u8 v6_address_set = 0;
9366   ip6_address_t v6address;
9367   u8 is_del = 0;
9368   int ret;
9369
9370   /* Parse args required to build the message */
9371   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9372     {
9373       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9374         ;
9375       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9376         ;
9377       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
9378         v6_address_set = 1;
9379       if (unformat (i, "del"))
9380         is_del = 1;
9381       else
9382         {
9383           clib_warning ("parse error '%U'", format_unformat_error, i);
9384           return -99;
9385         }
9386     }
9387
9388   if (sw_if_index == ~0)
9389     {
9390       errmsg ("missing interface name or sw_if_index");
9391       return -99;
9392     }
9393   if (!v6_address_set)
9394     {
9395       errmsg ("no address set");
9396       return -99;
9397     }
9398
9399   /* Construct the API message */
9400   M (IP6ND_PROXY_ADD_DEL, mp);
9401
9402   mp->is_del = is_del;
9403   mp->sw_if_index = ntohl (sw_if_index);
9404   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9405
9406   /* send it... */
9407   S (mp);
9408
9409   /* Wait for a reply, return good/bad news  */
9410   W (ret);
9411   return ret;
9412 }
9413
9414 static int
9415 api_ip6nd_proxy_dump (vat_main_t * vam)
9416 {
9417   vl_api_ip6nd_proxy_dump_t *mp;
9418   vl_api_control_ping_t *mp_ping;
9419   int ret;
9420
9421   M (IP6ND_PROXY_DUMP, mp);
9422
9423   S (mp);
9424
9425   /* Use a control ping for synchronization */
9426   MPING (CONTROL_PING, mp_ping);
9427   S (mp_ping);
9428
9429   W (ret);
9430   return ret;
9431 }
9432
9433 static void vl_api_ip6nd_proxy_details_t_handler
9434   (vl_api_ip6nd_proxy_details_t * mp)
9435 {
9436   vat_main_t *vam = &vat_main;
9437
9438   print (vam->ofp, "host %U sw_if_index %d",
9439          format_ip6_address, mp->address, ntohl (mp->sw_if_index));
9440 }
9441
9442 static void vl_api_ip6nd_proxy_details_t_handler_json
9443   (vl_api_ip6nd_proxy_details_t * mp)
9444 {
9445   vat_main_t *vam = &vat_main;
9446   struct in6_addr ip6;
9447   vat_json_node_t *node = NULL;
9448
9449   if (VAT_JSON_ARRAY != vam->json_tree.type)
9450     {
9451       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9452       vat_json_init_array (&vam->json_tree);
9453     }
9454   node = vat_json_array_add (&vam->json_tree);
9455
9456   vat_json_init_object (node);
9457   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9458
9459   clib_memcpy (&ip6, mp->address, sizeof (ip6));
9460   vat_json_object_add_ip6 (node, "host", ip6);
9461 }
9462
9463 static int
9464 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9465 {
9466   unformat_input_t *i = vam->input;
9467   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9468   u32 sw_if_index;
9469   u8 sw_if_index_set = 0;
9470   u32 address_length = 0;
9471   u8 v6_address_set = 0;
9472   ip6_address_t v6address;
9473   u8 use_default = 0;
9474   u8 no_advertise = 0;
9475   u8 off_link = 0;
9476   u8 no_autoconfig = 0;
9477   u8 no_onlink = 0;
9478   u8 is_no = 0;
9479   u32 val_lifetime = 0;
9480   u32 pref_lifetime = 0;
9481   int ret;
9482
9483   /* Parse args required to build the message */
9484   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9485     {
9486       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9487         sw_if_index_set = 1;
9488       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9489         sw_if_index_set = 1;
9490       else if (unformat (i, "%U/%d",
9491                          unformat_ip6_address, &v6address, &address_length))
9492         v6_address_set = 1;
9493       else if (unformat (i, "val_life %d", &val_lifetime))
9494         ;
9495       else if (unformat (i, "pref_life %d", &pref_lifetime))
9496         ;
9497       else if (unformat (i, "def"))
9498         use_default = 1;
9499       else if (unformat (i, "noadv"))
9500         no_advertise = 1;
9501       else if (unformat (i, "offl"))
9502         off_link = 1;
9503       else if (unformat (i, "noauto"))
9504         no_autoconfig = 1;
9505       else if (unformat (i, "nolink"))
9506         no_onlink = 1;
9507       else if (unformat (i, "isno"))
9508         is_no = 1;
9509       else
9510         {
9511           clib_warning ("parse error '%U'", format_unformat_error, i);
9512           return -99;
9513         }
9514     }
9515
9516   if (sw_if_index_set == 0)
9517     {
9518       errmsg ("missing interface name or sw_if_index");
9519       return -99;
9520     }
9521   if (!v6_address_set)
9522     {
9523       errmsg ("no address set");
9524       return -99;
9525     }
9526
9527   /* Construct the API message */
9528   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9529
9530   mp->sw_if_index = ntohl (sw_if_index);
9531   clib_memcpy (mp->address, &v6address, sizeof (v6address));
9532   mp->address_length = address_length;
9533   mp->use_default = use_default;
9534   mp->no_advertise = no_advertise;
9535   mp->off_link = off_link;
9536   mp->no_autoconfig = no_autoconfig;
9537   mp->no_onlink = no_onlink;
9538   mp->is_no = is_no;
9539   mp->val_lifetime = ntohl (val_lifetime);
9540   mp->pref_lifetime = ntohl (pref_lifetime);
9541
9542   /* send it... */
9543   S (mp);
9544
9545   /* Wait for a reply, return good/bad news  */
9546   W (ret);
9547   return ret;
9548 }
9549
9550 static int
9551 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9552 {
9553   unformat_input_t *i = vam->input;
9554   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9555   u32 sw_if_index;
9556   u8 sw_if_index_set = 0;
9557   u8 suppress = 0;
9558   u8 managed = 0;
9559   u8 other = 0;
9560   u8 ll_option = 0;
9561   u8 send_unicast = 0;
9562   u8 cease = 0;
9563   u8 is_no = 0;
9564   u8 default_router = 0;
9565   u32 max_interval = 0;
9566   u32 min_interval = 0;
9567   u32 lifetime = 0;
9568   u32 initial_count = 0;
9569   u32 initial_interval = 0;
9570   int ret;
9571
9572
9573   /* Parse args required to build the message */
9574   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9575     {
9576       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9577         sw_if_index_set = 1;
9578       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9579         sw_if_index_set = 1;
9580       else if (unformat (i, "maxint %d", &max_interval))
9581         ;
9582       else if (unformat (i, "minint %d", &min_interval))
9583         ;
9584       else if (unformat (i, "life %d", &lifetime))
9585         ;
9586       else if (unformat (i, "count %d", &initial_count))
9587         ;
9588       else if (unformat (i, "interval %d", &initial_interval))
9589         ;
9590       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9591         suppress = 1;
9592       else if (unformat (i, "managed"))
9593         managed = 1;
9594       else if (unformat (i, "other"))
9595         other = 1;
9596       else if (unformat (i, "ll"))
9597         ll_option = 1;
9598       else if (unformat (i, "send"))
9599         send_unicast = 1;
9600       else if (unformat (i, "cease"))
9601         cease = 1;
9602       else if (unformat (i, "isno"))
9603         is_no = 1;
9604       else if (unformat (i, "def"))
9605         default_router = 1;
9606       else
9607         {
9608           clib_warning ("parse error '%U'", format_unformat_error, i);
9609           return -99;
9610         }
9611     }
9612
9613   if (sw_if_index_set == 0)
9614     {
9615       errmsg ("missing interface name or sw_if_index");
9616       return -99;
9617     }
9618
9619   /* Construct the API message */
9620   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9621
9622   mp->sw_if_index = ntohl (sw_if_index);
9623   mp->max_interval = ntohl (max_interval);
9624   mp->min_interval = ntohl (min_interval);
9625   mp->lifetime = ntohl (lifetime);
9626   mp->initial_count = ntohl (initial_count);
9627   mp->initial_interval = ntohl (initial_interval);
9628   mp->suppress = suppress;
9629   mp->managed = managed;
9630   mp->other = other;
9631   mp->ll_option = ll_option;
9632   mp->send_unicast = send_unicast;
9633   mp->cease = cease;
9634   mp->is_no = is_no;
9635   mp->default_router = default_router;
9636
9637   /* send it... */
9638   S (mp);
9639
9640   /* Wait for a reply, return good/bad news  */
9641   W (ret);
9642   return ret;
9643 }
9644
9645 static int
9646 api_set_arp_neighbor_limit (vat_main_t * vam)
9647 {
9648   unformat_input_t *i = vam->input;
9649   vl_api_set_arp_neighbor_limit_t *mp;
9650   u32 arp_nbr_limit;
9651   u8 limit_set = 0;
9652   u8 is_ipv6 = 0;
9653   int ret;
9654
9655   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9656     {
9657       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
9658         limit_set = 1;
9659       else if (unformat (i, "ipv6"))
9660         is_ipv6 = 1;
9661       else
9662         {
9663           clib_warning ("parse error '%U'", format_unformat_error, i);
9664           return -99;
9665         }
9666     }
9667
9668   if (limit_set == 0)
9669     {
9670       errmsg ("missing limit value");
9671       return -99;
9672     }
9673
9674   M (SET_ARP_NEIGHBOR_LIMIT, mp);
9675
9676   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
9677   mp->is_ipv6 = is_ipv6;
9678
9679   S (mp);
9680   W (ret);
9681   return ret;
9682 }
9683
9684 static int
9685 api_l2_patch_add_del (vat_main_t * vam)
9686 {
9687   unformat_input_t *i = vam->input;
9688   vl_api_l2_patch_add_del_t *mp;
9689   u32 rx_sw_if_index;
9690   u8 rx_sw_if_index_set = 0;
9691   u32 tx_sw_if_index;
9692   u8 tx_sw_if_index_set = 0;
9693   u8 is_add = 1;
9694   int ret;
9695
9696   /* Parse args required to build the message */
9697   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9698     {
9699       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9700         rx_sw_if_index_set = 1;
9701       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9702         tx_sw_if_index_set = 1;
9703       else if (unformat (i, "rx"))
9704         {
9705           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9706             {
9707               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9708                             &rx_sw_if_index))
9709                 rx_sw_if_index_set = 1;
9710             }
9711           else
9712             break;
9713         }
9714       else if (unformat (i, "tx"))
9715         {
9716           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9717             {
9718               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9719                             &tx_sw_if_index))
9720                 tx_sw_if_index_set = 1;
9721             }
9722           else
9723             break;
9724         }
9725       else if (unformat (i, "del"))
9726         is_add = 0;
9727       else
9728         break;
9729     }
9730
9731   if (rx_sw_if_index_set == 0)
9732     {
9733       errmsg ("missing rx interface name or rx_sw_if_index");
9734       return -99;
9735     }
9736
9737   if (tx_sw_if_index_set == 0)
9738     {
9739       errmsg ("missing tx interface name or tx_sw_if_index");
9740       return -99;
9741     }
9742
9743   M (L2_PATCH_ADD_DEL, mp);
9744
9745   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9746   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9747   mp->is_add = is_add;
9748
9749   S (mp);
9750   W (ret);
9751   return ret;
9752 }
9753
9754 u8 is_del;
9755 u8 localsid_addr[16];
9756 u8 end_psp;
9757 u8 behavior;
9758 u32 sw_if_index;
9759 u32 vlan_index;
9760 u32 fib_table;
9761 u8 nh_addr[16];
9762
9763 static int
9764 api_sr_localsid_add_del (vat_main_t * vam)
9765 {
9766   unformat_input_t *i = vam->input;
9767   vl_api_sr_localsid_add_del_t *mp;
9768
9769   u8 is_del;
9770   ip6_address_t localsid;
9771   u8 end_psp = 0;
9772   u8 behavior = ~0;
9773   u32 sw_if_index;
9774   u32 fib_table = ~(u32) 0;
9775   ip6_address_t next_hop;
9776
9777   bool nexthop_set = 0;
9778
9779   int ret;
9780
9781   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9782     {
9783       if (unformat (i, "del"))
9784         is_del = 1;
9785       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9786       else if (unformat (i, "next-hop %U", unformat_ip6_address, &next_hop))
9787         nexthop_set = 1;
9788       else if (unformat (i, "behavior %u", &behavior));
9789       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9790       else if (unformat (i, "fib-table %u", &fib_table));
9791       else if (unformat (i, "end.psp %u", &behavior));
9792       else
9793         break;
9794     }
9795
9796   M (SR_LOCALSID_ADD_DEL, mp);
9797
9798   clib_memcpy (mp->localsid_addr, &localsid, sizeof (mp->localsid_addr));
9799   if (nexthop_set)
9800     clib_memcpy (mp->nh_addr, &next_hop, sizeof (mp->nh_addr));
9801   mp->behavior = behavior;
9802   mp->sw_if_index = ntohl (sw_if_index);
9803   mp->fib_table = ntohl (fib_table);
9804   mp->end_psp = end_psp;
9805   mp->is_del = is_del;
9806
9807   S (mp);
9808   W (ret);
9809   return ret;
9810 }
9811
9812 static int
9813 api_ioam_enable (vat_main_t * vam)
9814 {
9815   unformat_input_t *input = vam->input;
9816   vl_api_ioam_enable_t *mp;
9817   u32 id = 0;
9818   int has_trace_option = 0;
9819   int has_pot_option = 0;
9820   int has_seqno_option = 0;
9821   int has_analyse_option = 0;
9822   int ret;
9823
9824   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9825     {
9826       if (unformat (input, "trace"))
9827         has_trace_option = 1;
9828       else if (unformat (input, "pot"))
9829         has_pot_option = 1;
9830       else if (unformat (input, "seqno"))
9831         has_seqno_option = 1;
9832       else if (unformat (input, "analyse"))
9833         has_analyse_option = 1;
9834       else
9835         break;
9836     }
9837   M (IOAM_ENABLE, mp);
9838   mp->id = htons (id);
9839   mp->seqno = has_seqno_option;
9840   mp->analyse = has_analyse_option;
9841   mp->pot_enable = has_pot_option;
9842   mp->trace_enable = has_trace_option;
9843
9844   S (mp);
9845   W (ret);
9846   return ret;
9847 }
9848
9849
9850 static int
9851 api_ioam_disable (vat_main_t * vam)
9852 {
9853   vl_api_ioam_disable_t *mp;
9854   int ret;
9855
9856   M (IOAM_DISABLE, mp);
9857   S (mp);
9858   W (ret);
9859   return ret;
9860 }
9861
9862 #define foreach_tcp_proto_field                 \
9863 _(src_port)                                     \
9864 _(dst_port)
9865
9866 #define foreach_udp_proto_field                 \
9867 _(src_port)                                     \
9868 _(dst_port)
9869
9870 #define foreach_ip4_proto_field                 \
9871 _(src_address)                                  \
9872 _(dst_address)                                  \
9873 _(tos)                                          \
9874 _(length)                                       \
9875 _(fragment_id)                                  \
9876 _(ttl)                                          \
9877 _(protocol)                                     \
9878 _(checksum)
9879
9880 typedef struct
9881 {
9882   u16 src_port, dst_port;
9883 } tcpudp_header_t;
9884
9885 #if VPP_API_TEST_BUILTIN == 0
9886 uword
9887 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9888 {
9889   u8 **maskp = va_arg (*args, u8 **);
9890   u8 *mask = 0;
9891   u8 found_something = 0;
9892   tcp_header_t *tcp;
9893
9894 #define _(a) u8 a=0;
9895   foreach_tcp_proto_field;
9896 #undef _
9897
9898   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9899     {
9900       if (0);
9901 #define _(a) else if (unformat (input, #a)) a=1;
9902       foreach_tcp_proto_field
9903 #undef _
9904         else
9905         break;
9906     }
9907
9908 #define _(a) found_something += a;
9909   foreach_tcp_proto_field;
9910 #undef _
9911
9912   if (found_something == 0)
9913     return 0;
9914
9915   vec_validate (mask, sizeof (*tcp) - 1);
9916
9917   tcp = (tcp_header_t *) mask;
9918
9919 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
9920   foreach_tcp_proto_field;
9921 #undef _
9922
9923   *maskp = mask;
9924   return 1;
9925 }
9926
9927 uword
9928 unformat_udp_mask (unformat_input_t * input, va_list * args)
9929 {
9930   u8 **maskp = va_arg (*args, u8 **);
9931   u8 *mask = 0;
9932   u8 found_something = 0;
9933   udp_header_t *udp;
9934
9935 #define _(a) u8 a=0;
9936   foreach_udp_proto_field;
9937 #undef _
9938
9939   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9940     {
9941       if (0);
9942 #define _(a) else if (unformat (input, #a)) a=1;
9943       foreach_udp_proto_field
9944 #undef _
9945         else
9946         break;
9947     }
9948
9949 #define _(a) found_something += a;
9950   foreach_udp_proto_field;
9951 #undef _
9952
9953   if (found_something == 0)
9954     return 0;
9955
9956   vec_validate (mask, sizeof (*udp) - 1);
9957
9958   udp = (udp_header_t *) mask;
9959
9960 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
9961   foreach_udp_proto_field;
9962 #undef _
9963
9964   *maskp = mask;
9965   return 1;
9966 }
9967
9968 uword
9969 unformat_l4_mask (unformat_input_t * input, va_list * args)
9970 {
9971   u8 **maskp = va_arg (*args, u8 **);
9972   u16 src_port = 0, dst_port = 0;
9973   tcpudp_header_t *tcpudp;
9974
9975   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9976     {
9977       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9978         return 1;
9979       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9980         return 1;
9981       else if (unformat (input, "src_port"))
9982         src_port = 0xFFFF;
9983       else if (unformat (input, "dst_port"))
9984         dst_port = 0xFFFF;
9985       else
9986         return 0;
9987     }
9988
9989   if (!src_port && !dst_port)
9990     return 0;
9991
9992   u8 *mask = 0;
9993   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9994
9995   tcpudp = (tcpudp_header_t *) mask;
9996   tcpudp->src_port = src_port;
9997   tcpudp->dst_port = dst_port;
9998
9999   *maskp = mask;
10000
10001   return 1;
10002 }
10003
10004 uword
10005 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10006 {
10007   u8 **maskp = va_arg (*args, u8 **);
10008   u8 *mask = 0;
10009   u8 found_something = 0;
10010   ip4_header_t *ip;
10011
10012 #define _(a) u8 a=0;
10013   foreach_ip4_proto_field;
10014 #undef _
10015   u8 version = 0;
10016   u8 hdr_length = 0;
10017
10018
10019   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10020     {
10021       if (unformat (input, "version"))
10022         version = 1;
10023       else if (unformat (input, "hdr_length"))
10024         hdr_length = 1;
10025       else if (unformat (input, "src"))
10026         src_address = 1;
10027       else if (unformat (input, "dst"))
10028         dst_address = 1;
10029       else if (unformat (input, "proto"))
10030         protocol = 1;
10031
10032 #define _(a) else if (unformat (input, #a)) a=1;
10033       foreach_ip4_proto_field
10034 #undef _
10035         else
10036         break;
10037     }
10038
10039 #define _(a) found_something += a;
10040   foreach_ip4_proto_field;
10041 #undef _
10042
10043   if (found_something == 0)
10044     return 0;
10045
10046   vec_validate (mask, sizeof (*ip) - 1);
10047
10048   ip = (ip4_header_t *) mask;
10049
10050 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10051   foreach_ip4_proto_field;
10052 #undef _
10053
10054   ip->ip_version_and_header_length = 0;
10055
10056   if (version)
10057     ip->ip_version_and_header_length |= 0xF0;
10058
10059   if (hdr_length)
10060     ip->ip_version_and_header_length |= 0x0F;
10061
10062   *maskp = mask;
10063   return 1;
10064 }
10065
10066 #define foreach_ip6_proto_field                 \
10067 _(src_address)                                  \
10068 _(dst_address)                                  \
10069 _(payload_length)                               \
10070 _(hop_limit)                                    \
10071 _(protocol)
10072
10073 uword
10074 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10075 {
10076   u8 **maskp = va_arg (*args, u8 **);
10077   u8 *mask = 0;
10078   u8 found_something = 0;
10079   ip6_header_t *ip;
10080   u32 ip_version_traffic_class_and_flow_label;
10081
10082 #define _(a) u8 a=0;
10083   foreach_ip6_proto_field;
10084 #undef _
10085   u8 version = 0;
10086   u8 traffic_class = 0;
10087   u8 flow_label = 0;
10088
10089   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10090     {
10091       if (unformat (input, "version"))
10092         version = 1;
10093       else if (unformat (input, "traffic-class"))
10094         traffic_class = 1;
10095       else if (unformat (input, "flow-label"))
10096         flow_label = 1;
10097       else if (unformat (input, "src"))
10098         src_address = 1;
10099       else if (unformat (input, "dst"))
10100         dst_address = 1;
10101       else if (unformat (input, "proto"))
10102         protocol = 1;
10103
10104 #define _(a) else if (unformat (input, #a)) a=1;
10105       foreach_ip6_proto_field
10106 #undef _
10107         else
10108         break;
10109     }
10110
10111 #define _(a) found_something += a;
10112   foreach_ip6_proto_field;
10113 #undef _
10114
10115   if (found_something == 0)
10116     return 0;
10117
10118   vec_validate (mask, sizeof (*ip) - 1);
10119
10120   ip = (ip6_header_t *) mask;
10121
10122 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
10123   foreach_ip6_proto_field;
10124 #undef _
10125
10126   ip_version_traffic_class_and_flow_label = 0;
10127
10128   if (version)
10129     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10130
10131   if (traffic_class)
10132     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10133
10134   if (flow_label)
10135     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10136
10137   ip->ip_version_traffic_class_and_flow_label =
10138     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10139
10140   *maskp = mask;
10141   return 1;
10142 }
10143
10144 uword
10145 unformat_l3_mask (unformat_input_t * input, va_list * args)
10146 {
10147   u8 **maskp = va_arg (*args, u8 **);
10148
10149   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10150     {
10151       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10152         return 1;
10153       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10154         return 1;
10155       else
10156         break;
10157     }
10158   return 0;
10159 }
10160
10161 uword
10162 unformat_l2_mask (unformat_input_t * input, va_list * args)
10163 {
10164   u8 **maskp = va_arg (*args, u8 **);
10165   u8 *mask = 0;
10166   u8 src = 0;
10167   u8 dst = 0;
10168   u8 proto = 0;
10169   u8 tag1 = 0;
10170   u8 tag2 = 0;
10171   u8 ignore_tag1 = 0;
10172   u8 ignore_tag2 = 0;
10173   u8 cos1 = 0;
10174   u8 cos2 = 0;
10175   u8 dot1q = 0;
10176   u8 dot1ad = 0;
10177   int len = 14;
10178
10179   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10180     {
10181       if (unformat (input, "src"))
10182         src = 1;
10183       else if (unformat (input, "dst"))
10184         dst = 1;
10185       else if (unformat (input, "proto"))
10186         proto = 1;
10187       else if (unformat (input, "tag1"))
10188         tag1 = 1;
10189       else if (unformat (input, "tag2"))
10190         tag2 = 1;
10191       else if (unformat (input, "ignore-tag1"))
10192         ignore_tag1 = 1;
10193       else if (unformat (input, "ignore-tag2"))
10194         ignore_tag2 = 1;
10195       else if (unformat (input, "cos1"))
10196         cos1 = 1;
10197       else if (unformat (input, "cos2"))
10198         cos2 = 1;
10199       else if (unformat (input, "dot1q"))
10200         dot1q = 1;
10201       else if (unformat (input, "dot1ad"))
10202         dot1ad = 1;
10203       else
10204         break;
10205     }
10206   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10207        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10208     return 0;
10209
10210   if (tag1 || ignore_tag1 || cos1 || dot1q)
10211     len = 18;
10212   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10213     len = 22;
10214
10215   vec_validate (mask, len - 1);
10216
10217   if (dst)
10218     memset (mask, 0xff, 6);
10219
10220   if (src)
10221     memset (mask + 6, 0xff, 6);
10222
10223   if (tag2 || dot1ad)
10224     {
10225       /* inner vlan tag */
10226       if (tag2)
10227         {
10228           mask[19] = 0xff;
10229           mask[18] = 0x0f;
10230         }
10231       if (cos2)
10232         mask[18] |= 0xe0;
10233       if (proto)
10234         mask[21] = mask[20] = 0xff;
10235       if (tag1)
10236         {
10237           mask[15] = 0xff;
10238           mask[14] = 0x0f;
10239         }
10240       if (cos1)
10241         mask[14] |= 0xe0;
10242       *maskp = mask;
10243       return 1;
10244     }
10245   if (tag1 | dot1q)
10246     {
10247       if (tag1)
10248         {
10249           mask[15] = 0xff;
10250           mask[14] = 0x0f;
10251         }
10252       if (cos1)
10253         mask[14] |= 0xe0;
10254       if (proto)
10255         mask[16] = mask[17] = 0xff;
10256
10257       *maskp = mask;
10258       return 1;
10259     }
10260   if (cos2)
10261     mask[18] |= 0xe0;
10262   if (cos1)
10263     mask[14] |= 0xe0;
10264   if (proto)
10265     mask[12] = mask[13] = 0xff;
10266
10267   *maskp = mask;
10268   return 1;
10269 }
10270
10271 uword
10272 unformat_classify_mask (unformat_input_t * input, va_list * args)
10273 {
10274   u8 **maskp = va_arg (*args, u8 **);
10275   u32 *skipp = va_arg (*args, u32 *);
10276   u32 *matchp = va_arg (*args, u32 *);
10277   u32 match;
10278   u8 *mask = 0;
10279   u8 *l2 = 0;
10280   u8 *l3 = 0;
10281   u8 *l4 = 0;
10282   int i;
10283
10284   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10285     {
10286       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10287         ;
10288       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10289         ;
10290       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10291         ;
10292       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10293         ;
10294       else
10295         break;
10296     }
10297
10298   if (l4 && !l3)
10299     {
10300       vec_free (mask);
10301       vec_free (l2);
10302       vec_free (l4);
10303       return 0;
10304     }
10305
10306   if (mask || l2 || l3 || l4)
10307     {
10308       if (l2 || l3 || l4)
10309         {
10310           /* "With a free Ethernet header in every package" */
10311           if (l2 == 0)
10312             vec_validate (l2, 13);
10313           mask = l2;
10314           if (vec_len (l3))
10315             {
10316               vec_append (mask, l3);
10317               vec_free (l3);
10318             }
10319           if (vec_len (l4))
10320             {
10321               vec_append (mask, l4);
10322               vec_free (l4);
10323             }
10324         }
10325
10326       /* Scan forward looking for the first significant mask octet */
10327       for (i = 0; i < vec_len (mask); i++)
10328         if (mask[i])
10329           break;
10330
10331       /* compute (skip, match) params */
10332       *skipp = i / sizeof (u32x4);
10333       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10334
10335       /* Pad mask to an even multiple of the vector size */
10336       while (vec_len (mask) % sizeof (u32x4))
10337         vec_add1 (mask, 0);
10338
10339       match = vec_len (mask) / sizeof (u32x4);
10340
10341       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10342         {
10343           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10344           if (*tmp || *(tmp + 1))
10345             break;
10346           match--;
10347         }
10348       if (match == 0)
10349         clib_warning ("BUG: match 0");
10350
10351       _vec_len (mask) = match * sizeof (u32x4);
10352
10353       *matchp = match;
10354       *maskp = mask;
10355
10356       return 1;
10357     }
10358
10359   return 0;
10360 }
10361 #endif /* VPP_API_TEST_BUILTIN */
10362
10363 #define foreach_l2_next                         \
10364 _(drop, DROP)                                   \
10365 _(ethernet, ETHERNET_INPUT)                     \
10366 _(ip4, IP4_INPUT)                               \
10367 _(ip6, IP6_INPUT)
10368
10369 uword
10370 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10371 {
10372   u32 *miss_next_indexp = va_arg (*args, u32 *);
10373   u32 next_index = 0;
10374   u32 tmp;
10375
10376 #define _(n,N) \
10377   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10378   foreach_l2_next;
10379 #undef _
10380
10381   if (unformat (input, "%d", &tmp))
10382     {
10383       next_index = tmp;
10384       goto out;
10385     }
10386
10387   return 0;
10388
10389 out:
10390   *miss_next_indexp = next_index;
10391   return 1;
10392 }
10393
10394 #define foreach_ip_next                         \
10395 _(drop, DROP)                                   \
10396 _(local, LOCAL)                                 \
10397 _(rewrite, REWRITE)
10398
10399 uword
10400 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10401 {
10402   u32 *miss_next_indexp = va_arg (*args, u32 *);
10403   u32 next_index = 0;
10404   u32 tmp;
10405
10406 #define _(n,N) \
10407   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10408   foreach_ip_next;
10409 #undef _
10410
10411   if (unformat (input, "%d", &tmp))
10412     {
10413       next_index = tmp;
10414       goto out;
10415     }
10416
10417   return 0;
10418
10419 out:
10420   *miss_next_indexp = next_index;
10421   return 1;
10422 }
10423
10424 #define foreach_acl_next                        \
10425 _(deny, DENY)
10426
10427 uword
10428 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10429 {
10430   u32 *miss_next_indexp = va_arg (*args, u32 *);
10431   u32 next_index = 0;
10432   u32 tmp;
10433
10434 #define _(n,N) \
10435   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10436   foreach_acl_next;
10437 #undef _
10438
10439   if (unformat (input, "permit"))
10440     {
10441       next_index = ~0;
10442       goto out;
10443     }
10444   else if (unformat (input, "%d", &tmp))
10445     {
10446       next_index = tmp;
10447       goto out;
10448     }
10449
10450   return 0;
10451
10452 out:
10453   *miss_next_indexp = next_index;
10454   return 1;
10455 }
10456
10457 uword
10458 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10459 {
10460   u32 *r = va_arg (*args, u32 *);
10461
10462   if (unformat (input, "conform-color"))
10463     *r = POLICE_CONFORM;
10464   else if (unformat (input, "exceed-color"))
10465     *r = POLICE_EXCEED;
10466   else
10467     return 0;
10468
10469   return 1;
10470 }
10471
10472 static int
10473 api_classify_add_del_table (vat_main_t * vam)
10474 {
10475   unformat_input_t *i = vam->input;
10476   vl_api_classify_add_del_table_t *mp;
10477
10478   u32 nbuckets = 2;
10479   u32 skip = ~0;
10480   u32 match = ~0;
10481   int is_add = 1;
10482   int del_chain = 0;
10483   u32 table_index = ~0;
10484   u32 next_table_index = ~0;
10485   u32 miss_next_index = ~0;
10486   u32 memory_size = 32 << 20;
10487   u8 *mask = 0;
10488   u32 current_data_flag = 0;
10489   int current_data_offset = 0;
10490   int ret;
10491
10492   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10493     {
10494       if (unformat (i, "del"))
10495         is_add = 0;
10496       else if (unformat (i, "del-chain"))
10497         {
10498           is_add = 0;
10499           del_chain = 1;
10500         }
10501       else if (unformat (i, "buckets %d", &nbuckets))
10502         ;
10503       else if (unformat (i, "memory_size %d", &memory_size))
10504         ;
10505       else if (unformat (i, "skip %d", &skip))
10506         ;
10507       else if (unformat (i, "match %d", &match))
10508         ;
10509       else if (unformat (i, "table %d", &table_index))
10510         ;
10511       else if (unformat (i, "mask %U", unformat_classify_mask,
10512                          &mask, &skip, &match))
10513         ;
10514       else if (unformat (i, "next-table %d", &next_table_index))
10515         ;
10516       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10517                          &miss_next_index))
10518         ;
10519       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10520                          &miss_next_index))
10521         ;
10522       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10523                          &miss_next_index))
10524         ;
10525       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10526         ;
10527       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10528         ;
10529       else
10530         break;
10531     }
10532
10533   if (is_add && mask == 0)
10534     {
10535       errmsg ("Mask required");
10536       return -99;
10537     }
10538
10539   if (is_add && skip == ~0)
10540     {
10541       errmsg ("skip count required");
10542       return -99;
10543     }
10544
10545   if (is_add && match == ~0)
10546     {
10547       errmsg ("match count required");
10548       return -99;
10549     }
10550
10551   if (!is_add && table_index == ~0)
10552     {
10553       errmsg ("table index required for delete");
10554       return -99;
10555     }
10556
10557   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10558
10559   mp->is_add = is_add;
10560   mp->del_chain = del_chain;
10561   mp->table_index = ntohl (table_index);
10562   mp->nbuckets = ntohl (nbuckets);
10563   mp->memory_size = ntohl (memory_size);
10564   mp->skip_n_vectors = ntohl (skip);
10565   mp->match_n_vectors = ntohl (match);
10566   mp->next_table_index = ntohl (next_table_index);
10567   mp->miss_next_index = ntohl (miss_next_index);
10568   mp->current_data_flag = ntohl (current_data_flag);
10569   mp->current_data_offset = ntohl (current_data_offset);
10570   clib_memcpy (mp->mask, mask, vec_len (mask));
10571
10572   vec_free (mask);
10573
10574   S (mp);
10575   W (ret);
10576   return ret;
10577 }
10578
10579 #if VPP_API_TEST_BUILTIN == 0
10580 uword
10581 unformat_l4_match (unformat_input_t * input, va_list * args)
10582 {
10583   u8 **matchp = va_arg (*args, u8 **);
10584
10585   u8 *proto_header = 0;
10586   int src_port = 0;
10587   int dst_port = 0;
10588
10589   tcpudp_header_t h;
10590
10591   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10592     {
10593       if (unformat (input, "src_port %d", &src_port))
10594         ;
10595       else if (unformat (input, "dst_port %d", &dst_port))
10596         ;
10597       else
10598         return 0;
10599     }
10600
10601   h.src_port = clib_host_to_net_u16 (src_port);
10602   h.dst_port = clib_host_to_net_u16 (dst_port);
10603   vec_validate (proto_header, sizeof (h) - 1);
10604   memcpy (proto_header, &h, sizeof (h));
10605
10606   *matchp = proto_header;
10607
10608   return 1;
10609 }
10610
10611 uword
10612 unformat_ip4_match (unformat_input_t * input, va_list * args)
10613 {
10614   u8 **matchp = va_arg (*args, u8 **);
10615   u8 *match = 0;
10616   ip4_header_t *ip;
10617   int version = 0;
10618   u32 version_val;
10619   int hdr_length = 0;
10620   u32 hdr_length_val;
10621   int src = 0, dst = 0;
10622   ip4_address_t src_val, dst_val;
10623   int proto = 0;
10624   u32 proto_val;
10625   int tos = 0;
10626   u32 tos_val;
10627   int length = 0;
10628   u32 length_val;
10629   int fragment_id = 0;
10630   u32 fragment_id_val;
10631   int ttl = 0;
10632   int ttl_val;
10633   int checksum = 0;
10634   u32 checksum_val;
10635
10636   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10637     {
10638       if (unformat (input, "version %d", &version_val))
10639         version = 1;
10640       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10641         hdr_length = 1;
10642       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10643         src = 1;
10644       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10645         dst = 1;
10646       else if (unformat (input, "proto %d", &proto_val))
10647         proto = 1;
10648       else if (unformat (input, "tos %d", &tos_val))
10649         tos = 1;
10650       else if (unformat (input, "length %d", &length_val))
10651         length = 1;
10652       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10653         fragment_id = 1;
10654       else if (unformat (input, "ttl %d", &ttl_val))
10655         ttl = 1;
10656       else if (unformat (input, "checksum %d", &checksum_val))
10657         checksum = 1;
10658       else
10659         break;
10660     }
10661
10662   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10663       + ttl + checksum == 0)
10664     return 0;
10665
10666   /*
10667    * Aligned because we use the real comparison functions
10668    */
10669   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10670
10671   ip = (ip4_header_t *) match;
10672
10673   /* These are realistically matched in practice */
10674   if (src)
10675     ip->src_address.as_u32 = src_val.as_u32;
10676
10677   if (dst)
10678     ip->dst_address.as_u32 = dst_val.as_u32;
10679
10680   if (proto)
10681     ip->protocol = proto_val;
10682
10683
10684   /* These are not, but they're included for completeness */
10685   if (version)
10686     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10687
10688   if (hdr_length)
10689     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10690
10691   if (tos)
10692     ip->tos = tos_val;
10693
10694   if (length)
10695     ip->length = clib_host_to_net_u16 (length_val);
10696
10697   if (ttl)
10698     ip->ttl = ttl_val;
10699
10700   if (checksum)
10701     ip->checksum = clib_host_to_net_u16 (checksum_val);
10702
10703   *matchp = match;
10704   return 1;
10705 }
10706
10707 uword
10708 unformat_ip6_match (unformat_input_t * input, va_list * args)
10709 {
10710   u8 **matchp = va_arg (*args, u8 **);
10711   u8 *match = 0;
10712   ip6_header_t *ip;
10713   int version = 0;
10714   u32 version_val;
10715   u8 traffic_class = 0;
10716   u32 traffic_class_val = 0;
10717   u8 flow_label = 0;
10718   u8 flow_label_val;
10719   int src = 0, dst = 0;
10720   ip6_address_t src_val, dst_val;
10721   int proto = 0;
10722   u32 proto_val;
10723   int payload_length = 0;
10724   u32 payload_length_val;
10725   int hop_limit = 0;
10726   int hop_limit_val;
10727   u32 ip_version_traffic_class_and_flow_label;
10728
10729   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10730     {
10731       if (unformat (input, "version %d", &version_val))
10732         version = 1;
10733       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10734         traffic_class = 1;
10735       else if (unformat (input, "flow_label %d", &flow_label_val))
10736         flow_label = 1;
10737       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10738         src = 1;
10739       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10740         dst = 1;
10741       else if (unformat (input, "proto %d", &proto_val))
10742         proto = 1;
10743       else if (unformat (input, "payload_length %d", &payload_length_val))
10744         payload_length = 1;
10745       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10746         hop_limit = 1;
10747       else
10748         break;
10749     }
10750
10751   if (version + traffic_class + flow_label + src + dst + proto +
10752       payload_length + hop_limit == 0)
10753     return 0;
10754
10755   /*
10756    * Aligned because we use the real comparison functions
10757    */
10758   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10759
10760   ip = (ip6_header_t *) match;
10761
10762   if (src)
10763     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10764
10765   if (dst)
10766     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10767
10768   if (proto)
10769     ip->protocol = proto_val;
10770
10771   ip_version_traffic_class_and_flow_label = 0;
10772
10773   if (version)
10774     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10775
10776   if (traffic_class)
10777     ip_version_traffic_class_and_flow_label |=
10778       (traffic_class_val & 0xFF) << 20;
10779
10780   if (flow_label)
10781     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10782
10783   ip->ip_version_traffic_class_and_flow_label =
10784     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10785
10786   if (payload_length)
10787     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10788
10789   if (hop_limit)
10790     ip->hop_limit = hop_limit_val;
10791
10792   *matchp = match;
10793   return 1;
10794 }
10795
10796 uword
10797 unformat_l3_match (unformat_input_t * input, va_list * args)
10798 {
10799   u8 **matchp = va_arg (*args, u8 **);
10800
10801   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10802     {
10803       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10804         return 1;
10805       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10806         return 1;
10807       else
10808         break;
10809     }
10810   return 0;
10811 }
10812
10813 uword
10814 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10815 {
10816   u8 *tagp = va_arg (*args, u8 *);
10817   u32 tag;
10818
10819   if (unformat (input, "%d", &tag))
10820     {
10821       tagp[0] = (tag >> 8) & 0x0F;
10822       tagp[1] = tag & 0xFF;
10823       return 1;
10824     }
10825
10826   return 0;
10827 }
10828
10829 uword
10830 unformat_l2_match (unformat_input_t * input, va_list * args)
10831 {
10832   u8 **matchp = va_arg (*args, u8 **);
10833   u8 *match = 0;
10834   u8 src = 0;
10835   u8 src_val[6];
10836   u8 dst = 0;
10837   u8 dst_val[6];
10838   u8 proto = 0;
10839   u16 proto_val;
10840   u8 tag1 = 0;
10841   u8 tag1_val[2];
10842   u8 tag2 = 0;
10843   u8 tag2_val[2];
10844   int len = 14;
10845   u8 ignore_tag1 = 0;
10846   u8 ignore_tag2 = 0;
10847   u8 cos1 = 0;
10848   u8 cos2 = 0;
10849   u32 cos1_val = 0;
10850   u32 cos2_val = 0;
10851
10852   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10853     {
10854       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10855         src = 1;
10856       else
10857         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10858         dst = 1;
10859       else if (unformat (input, "proto %U",
10860                          unformat_ethernet_type_host_byte_order, &proto_val))
10861         proto = 1;
10862       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10863         tag1 = 1;
10864       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10865         tag2 = 1;
10866       else if (unformat (input, "ignore-tag1"))
10867         ignore_tag1 = 1;
10868       else if (unformat (input, "ignore-tag2"))
10869         ignore_tag2 = 1;
10870       else if (unformat (input, "cos1 %d", &cos1_val))
10871         cos1 = 1;
10872       else if (unformat (input, "cos2 %d", &cos2_val))
10873         cos2 = 1;
10874       else
10875         break;
10876     }
10877   if ((src + dst + proto + tag1 + tag2 +
10878        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10879     return 0;
10880
10881   if (tag1 || ignore_tag1 || cos1)
10882     len = 18;
10883   if (tag2 || ignore_tag2 || cos2)
10884     len = 22;
10885
10886   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10887
10888   if (dst)
10889     clib_memcpy (match, dst_val, 6);
10890
10891   if (src)
10892     clib_memcpy (match + 6, src_val, 6);
10893
10894   if (tag2)
10895     {
10896       /* inner vlan tag */
10897       match[19] = tag2_val[1];
10898       match[18] = tag2_val[0];
10899       if (cos2)
10900         match[18] |= (cos2_val & 0x7) << 5;
10901       if (proto)
10902         {
10903           match[21] = proto_val & 0xff;
10904           match[20] = proto_val >> 8;
10905         }
10906       if (tag1)
10907         {
10908           match[15] = tag1_val[1];
10909           match[14] = tag1_val[0];
10910         }
10911       if (cos1)
10912         match[14] |= (cos1_val & 0x7) << 5;
10913       *matchp = match;
10914       return 1;
10915     }
10916   if (tag1)
10917     {
10918       match[15] = tag1_val[1];
10919       match[14] = tag1_val[0];
10920       if (proto)
10921         {
10922           match[17] = proto_val & 0xff;
10923           match[16] = proto_val >> 8;
10924         }
10925       if (cos1)
10926         match[14] |= (cos1_val & 0x7) << 5;
10927
10928       *matchp = match;
10929       return 1;
10930     }
10931   if (cos2)
10932     match[18] |= (cos2_val & 0x7) << 5;
10933   if (cos1)
10934     match[14] |= (cos1_val & 0x7) << 5;
10935   if (proto)
10936     {
10937       match[13] = proto_val & 0xff;
10938       match[12] = proto_val >> 8;
10939     }
10940
10941   *matchp = match;
10942   return 1;
10943 }
10944 #endif
10945
10946 uword
10947 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10948 {
10949   u8 **matchp = va_arg (*args, u8 **);
10950   u32 skip_n_vectors = va_arg (*args, u32);
10951   u32 match_n_vectors = va_arg (*args, u32);
10952
10953   u8 *match = 0;
10954   u8 *l2 = 0;
10955   u8 *l3 = 0;
10956   u8 *l4 = 0;
10957
10958   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10959     {
10960       if (unformat (input, "hex %U", unformat_hex_string, &match))
10961         ;
10962       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10963         ;
10964       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10965         ;
10966       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10967         ;
10968       else
10969         break;
10970     }
10971
10972   if (l4 && !l3)
10973     {
10974       vec_free (match);
10975       vec_free (l2);
10976       vec_free (l4);
10977       return 0;
10978     }
10979
10980   if (match || l2 || l3 || l4)
10981     {
10982       if (l2 || l3 || l4)
10983         {
10984           /* "Win a free Ethernet header in every packet" */
10985           if (l2 == 0)
10986             vec_validate_aligned (l2, 13, sizeof (u32x4));
10987           match = l2;
10988           if (vec_len (l3))
10989             {
10990               vec_append_aligned (match, l3, sizeof (u32x4));
10991               vec_free (l3);
10992             }
10993           if (vec_len (l4))
10994             {
10995               vec_append_aligned (match, l4, sizeof (u32x4));
10996               vec_free (l4);
10997             }
10998         }
10999
11000       /* Make sure the vector is big enough even if key is all 0's */
11001       vec_validate_aligned
11002         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11003          sizeof (u32x4));
11004
11005       /* Set size, include skipped vectors */
11006       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11007
11008       *matchp = match;
11009
11010       return 1;
11011     }
11012
11013   return 0;
11014 }
11015
11016 static int
11017 api_classify_add_del_session (vat_main_t * vam)
11018 {
11019   unformat_input_t *i = vam->input;
11020   vl_api_classify_add_del_session_t *mp;
11021   int is_add = 1;
11022   u32 table_index = ~0;
11023   u32 hit_next_index = ~0;
11024   u32 opaque_index = ~0;
11025   u8 *match = 0;
11026   i32 advance = 0;
11027   u32 skip_n_vectors = 0;
11028   u32 match_n_vectors = 0;
11029   u32 action = 0;
11030   u32 metadata = 0;
11031   int ret;
11032
11033   /*
11034    * Warning: you have to supply skip_n and match_n
11035    * because the API client cant simply look at the classify
11036    * table object.
11037    */
11038
11039   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11040     {
11041       if (unformat (i, "del"))
11042         is_add = 0;
11043       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11044                          &hit_next_index))
11045         ;
11046       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11047                          &hit_next_index))
11048         ;
11049       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11050                          &hit_next_index))
11051         ;
11052       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11053         ;
11054       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11055         ;
11056       else if (unformat (i, "opaque-index %d", &opaque_index))
11057         ;
11058       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11059         ;
11060       else if (unformat (i, "match_n %d", &match_n_vectors))
11061         ;
11062       else if (unformat (i, "match %U", api_unformat_classify_match,
11063                          &match, skip_n_vectors, match_n_vectors))
11064         ;
11065       else if (unformat (i, "advance %d", &advance))
11066         ;
11067       else if (unformat (i, "table-index %d", &table_index))
11068         ;
11069       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11070         action = 1;
11071       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11072         action = 2;
11073       else if (unformat (i, "action %d", &action))
11074         ;
11075       else if (unformat (i, "metadata %d", &metadata))
11076         ;
11077       else
11078         break;
11079     }
11080
11081   if (table_index == ~0)
11082     {
11083       errmsg ("Table index required");
11084       return -99;
11085     }
11086
11087   if (is_add && match == 0)
11088     {
11089       errmsg ("Match value required");
11090       return -99;
11091     }
11092
11093   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11094
11095   mp->is_add = is_add;
11096   mp->table_index = ntohl (table_index);
11097   mp->hit_next_index = ntohl (hit_next_index);
11098   mp->opaque_index = ntohl (opaque_index);
11099   mp->advance = ntohl (advance);
11100   mp->action = action;
11101   mp->metadata = ntohl (metadata);
11102   clib_memcpy (mp->match, match, vec_len (match));
11103   vec_free (match);
11104
11105   S (mp);
11106   W (ret);
11107   return ret;
11108 }
11109
11110 static int
11111 api_classify_set_interface_ip_table (vat_main_t * vam)
11112 {
11113   unformat_input_t *i = vam->input;
11114   vl_api_classify_set_interface_ip_table_t *mp;
11115   u32 sw_if_index;
11116   int sw_if_index_set;
11117   u32 table_index = ~0;
11118   u8 is_ipv6 = 0;
11119   int ret;
11120
11121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11122     {
11123       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11124         sw_if_index_set = 1;
11125       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11126         sw_if_index_set = 1;
11127       else if (unformat (i, "table %d", &table_index))
11128         ;
11129       else
11130         {
11131           clib_warning ("parse error '%U'", format_unformat_error, i);
11132           return -99;
11133         }
11134     }
11135
11136   if (sw_if_index_set == 0)
11137     {
11138       errmsg ("missing interface name or sw_if_index");
11139       return -99;
11140     }
11141
11142
11143   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11144
11145   mp->sw_if_index = ntohl (sw_if_index);
11146   mp->table_index = ntohl (table_index);
11147   mp->is_ipv6 = is_ipv6;
11148
11149   S (mp);
11150   W (ret);
11151   return ret;
11152 }
11153
11154 static int
11155 api_classify_set_interface_l2_tables (vat_main_t * vam)
11156 {
11157   unformat_input_t *i = vam->input;
11158   vl_api_classify_set_interface_l2_tables_t *mp;
11159   u32 sw_if_index;
11160   int sw_if_index_set;
11161   u32 ip4_table_index = ~0;
11162   u32 ip6_table_index = ~0;
11163   u32 other_table_index = ~0;
11164   u32 is_input = 1;
11165   int ret;
11166
11167   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11168     {
11169       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11170         sw_if_index_set = 1;
11171       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11172         sw_if_index_set = 1;
11173       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11174         ;
11175       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11176         ;
11177       else if (unformat (i, "other-table %d", &other_table_index))
11178         ;
11179       else if (unformat (i, "is-input %d", &is_input))
11180         ;
11181       else
11182         {
11183           clib_warning ("parse error '%U'", format_unformat_error, i);
11184           return -99;
11185         }
11186     }
11187
11188   if (sw_if_index_set == 0)
11189     {
11190       errmsg ("missing interface name or sw_if_index");
11191       return -99;
11192     }
11193
11194
11195   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11196
11197   mp->sw_if_index = ntohl (sw_if_index);
11198   mp->ip4_table_index = ntohl (ip4_table_index);
11199   mp->ip6_table_index = ntohl (ip6_table_index);
11200   mp->other_table_index = ntohl (other_table_index);
11201   mp->is_input = (u8) is_input;
11202
11203   S (mp);
11204   W (ret);
11205   return ret;
11206 }
11207
11208 static int
11209 api_set_ipfix_exporter (vat_main_t * vam)
11210 {
11211   unformat_input_t *i = vam->input;
11212   vl_api_set_ipfix_exporter_t *mp;
11213   ip4_address_t collector_address;
11214   u8 collector_address_set = 0;
11215   u32 collector_port = ~0;
11216   ip4_address_t src_address;
11217   u8 src_address_set = 0;
11218   u32 vrf_id = ~0;
11219   u32 path_mtu = ~0;
11220   u32 template_interval = ~0;
11221   u8 udp_checksum = 0;
11222   int ret;
11223
11224   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11225     {
11226       if (unformat (i, "collector_address %U", unformat_ip4_address,
11227                     &collector_address))
11228         collector_address_set = 1;
11229       else if (unformat (i, "collector_port %d", &collector_port))
11230         ;
11231       else if (unformat (i, "src_address %U", unformat_ip4_address,
11232                          &src_address))
11233         src_address_set = 1;
11234       else if (unformat (i, "vrf_id %d", &vrf_id))
11235         ;
11236       else if (unformat (i, "path_mtu %d", &path_mtu))
11237         ;
11238       else if (unformat (i, "template_interval %d", &template_interval))
11239         ;
11240       else if (unformat (i, "udp_checksum"))
11241         udp_checksum = 1;
11242       else
11243         break;
11244     }
11245
11246   if (collector_address_set == 0)
11247     {
11248       errmsg ("collector_address required");
11249       return -99;
11250     }
11251
11252   if (src_address_set == 0)
11253     {
11254       errmsg ("src_address required");
11255       return -99;
11256     }
11257
11258   M (SET_IPFIX_EXPORTER, mp);
11259
11260   memcpy (mp->collector_address, collector_address.data,
11261           sizeof (collector_address.data));
11262   mp->collector_port = htons ((u16) collector_port);
11263   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11264   mp->vrf_id = htonl (vrf_id);
11265   mp->path_mtu = htonl (path_mtu);
11266   mp->template_interval = htonl (template_interval);
11267   mp->udp_checksum = udp_checksum;
11268
11269   S (mp);
11270   W (ret);
11271   return ret;
11272 }
11273
11274 static int
11275 api_set_ipfix_classify_stream (vat_main_t * vam)
11276 {
11277   unformat_input_t *i = vam->input;
11278   vl_api_set_ipfix_classify_stream_t *mp;
11279   u32 domain_id = 0;
11280   u32 src_port = UDP_DST_PORT_ipfix;
11281   int ret;
11282
11283   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11284     {
11285       if (unformat (i, "domain %d", &domain_id))
11286         ;
11287       else if (unformat (i, "src_port %d", &src_port))
11288         ;
11289       else
11290         {
11291           errmsg ("unknown input `%U'", format_unformat_error, i);
11292           return -99;
11293         }
11294     }
11295
11296   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11297
11298   mp->domain_id = htonl (domain_id);
11299   mp->src_port = htons ((u16) src_port);
11300
11301   S (mp);
11302   W (ret);
11303   return ret;
11304 }
11305
11306 static int
11307 api_ipfix_classify_table_add_del (vat_main_t * vam)
11308 {
11309   unformat_input_t *i = vam->input;
11310   vl_api_ipfix_classify_table_add_del_t *mp;
11311   int is_add = -1;
11312   u32 classify_table_index = ~0;
11313   u8 ip_version = 0;
11314   u8 transport_protocol = 255;
11315   int ret;
11316
11317   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11318     {
11319       if (unformat (i, "add"))
11320         is_add = 1;
11321       else if (unformat (i, "del"))
11322         is_add = 0;
11323       else if (unformat (i, "table %d", &classify_table_index))
11324         ;
11325       else if (unformat (i, "ip4"))
11326         ip_version = 4;
11327       else if (unformat (i, "ip6"))
11328         ip_version = 6;
11329       else if (unformat (i, "tcp"))
11330         transport_protocol = 6;
11331       else if (unformat (i, "udp"))
11332         transport_protocol = 17;
11333       else
11334         {
11335           errmsg ("unknown input `%U'", format_unformat_error, i);
11336           return -99;
11337         }
11338     }
11339
11340   if (is_add == -1)
11341     {
11342       errmsg ("expecting: add|del");
11343       return -99;
11344     }
11345   if (classify_table_index == ~0)
11346     {
11347       errmsg ("classifier table not specified");
11348       return -99;
11349     }
11350   if (ip_version == 0)
11351     {
11352       errmsg ("IP version not specified");
11353       return -99;
11354     }
11355
11356   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11357
11358   mp->is_add = is_add;
11359   mp->table_id = htonl (classify_table_index);
11360   mp->ip_version = ip_version;
11361   mp->transport_protocol = transport_protocol;
11362
11363   S (mp);
11364   W (ret);
11365   return ret;
11366 }
11367
11368 static int
11369 api_get_node_index (vat_main_t * vam)
11370 {
11371   unformat_input_t *i = vam->input;
11372   vl_api_get_node_index_t *mp;
11373   u8 *name = 0;
11374   int ret;
11375
11376   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11377     {
11378       if (unformat (i, "node %s", &name))
11379         ;
11380       else
11381         break;
11382     }
11383   if (name == 0)
11384     {
11385       errmsg ("node name required");
11386       return -99;
11387     }
11388   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11389     {
11390       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11391       return -99;
11392     }
11393
11394   M (GET_NODE_INDEX, mp);
11395   clib_memcpy (mp->node_name, name, vec_len (name));
11396   vec_free (name);
11397
11398   S (mp);
11399   W (ret);
11400   return ret;
11401 }
11402
11403 static int
11404 api_get_next_index (vat_main_t * vam)
11405 {
11406   unformat_input_t *i = vam->input;
11407   vl_api_get_next_index_t *mp;
11408   u8 *node_name = 0, *next_node_name = 0;
11409   int ret;
11410
11411   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11412     {
11413       if (unformat (i, "node-name %s", &node_name))
11414         ;
11415       else if (unformat (i, "next-node-name %s", &next_node_name))
11416         break;
11417     }
11418
11419   if (node_name == 0)
11420     {
11421       errmsg ("node name required");
11422       return -99;
11423     }
11424   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11425     {
11426       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11427       return -99;
11428     }
11429
11430   if (next_node_name == 0)
11431     {
11432       errmsg ("next node name required");
11433       return -99;
11434     }
11435   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11436     {
11437       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11438       return -99;
11439     }
11440
11441   M (GET_NEXT_INDEX, mp);
11442   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11443   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11444   vec_free (node_name);
11445   vec_free (next_node_name);
11446
11447   S (mp);
11448   W (ret);
11449   return ret;
11450 }
11451
11452 static int
11453 api_add_node_next (vat_main_t * vam)
11454 {
11455   unformat_input_t *i = vam->input;
11456   vl_api_add_node_next_t *mp;
11457   u8 *name = 0;
11458   u8 *next = 0;
11459   int ret;
11460
11461   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11462     {
11463       if (unformat (i, "node %s", &name))
11464         ;
11465       else if (unformat (i, "next %s", &next))
11466         ;
11467       else
11468         break;
11469     }
11470   if (name == 0)
11471     {
11472       errmsg ("node name required");
11473       return -99;
11474     }
11475   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11476     {
11477       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11478       return -99;
11479     }
11480   if (next == 0)
11481     {
11482       errmsg ("next node required");
11483       return -99;
11484     }
11485   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11486     {
11487       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11488       return -99;
11489     }
11490
11491   M (ADD_NODE_NEXT, mp);
11492   clib_memcpy (mp->node_name, name, vec_len (name));
11493   clib_memcpy (mp->next_name, next, vec_len (next));
11494   vec_free (name);
11495   vec_free (next);
11496
11497   S (mp);
11498   W (ret);
11499   return ret;
11500 }
11501
11502 static int
11503 api_l2tpv3_create_tunnel (vat_main_t * vam)
11504 {
11505   unformat_input_t *i = vam->input;
11506   ip6_address_t client_address, our_address;
11507   int client_address_set = 0;
11508   int our_address_set = 0;
11509   u32 local_session_id = 0;
11510   u32 remote_session_id = 0;
11511   u64 local_cookie = 0;
11512   u64 remote_cookie = 0;
11513   u8 l2_sublayer_present = 0;
11514   vl_api_l2tpv3_create_tunnel_t *mp;
11515   int ret;
11516
11517   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11518     {
11519       if (unformat (i, "client_address %U", unformat_ip6_address,
11520                     &client_address))
11521         client_address_set = 1;
11522       else if (unformat (i, "our_address %U", unformat_ip6_address,
11523                          &our_address))
11524         our_address_set = 1;
11525       else if (unformat (i, "local_session_id %d", &local_session_id))
11526         ;
11527       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11528         ;
11529       else if (unformat (i, "local_cookie %lld", &local_cookie))
11530         ;
11531       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11532         ;
11533       else if (unformat (i, "l2-sublayer-present"))
11534         l2_sublayer_present = 1;
11535       else
11536         break;
11537     }
11538
11539   if (client_address_set == 0)
11540     {
11541       errmsg ("client_address required");
11542       return -99;
11543     }
11544
11545   if (our_address_set == 0)
11546     {
11547       errmsg ("our_address required");
11548       return -99;
11549     }
11550
11551   M (L2TPV3_CREATE_TUNNEL, mp);
11552
11553   clib_memcpy (mp->client_address, client_address.as_u8,
11554                sizeof (mp->client_address));
11555
11556   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11557
11558   mp->local_session_id = ntohl (local_session_id);
11559   mp->remote_session_id = ntohl (remote_session_id);
11560   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11561   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11562   mp->l2_sublayer_present = l2_sublayer_present;
11563   mp->is_ipv6 = 1;
11564
11565   S (mp);
11566   W (ret);
11567   return ret;
11568 }
11569
11570 static int
11571 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11572 {
11573   unformat_input_t *i = vam->input;
11574   u32 sw_if_index;
11575   u8 sw_if_index_set = 0;
11576   u64 new_local_cookie = 0;
11577   u64 new_remote_cookie = 0;
11578   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11579   int ret;
11580
11581   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11582     {
11583       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11584         sw_if_index_set = 1;
11585       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11586         sw_if_index_set = 1;
11587       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11588         ;
11589       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11590         ;
11591       else
11592         break;
11593     }
11594
11595   if (sw_if_index_set == 0)
11596     {
11597       errmsg ("missing interface name or sw_if_index");
11598       return -99;
11599     }
11600
11601   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11602
11603   mp->sw_if_index = ntohl (sw_if_index);
11604   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11605   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11606
11607   S (mp);
11608   W (ret);
11609   return ret;
11610 }
11611
11612 static int
11613 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11614 {
11615   unformat_input_t *i = vam->input;
11616   vl_api_l2tpv3_interface_enable_disable_t *mp;
11617   u32 sw_if_index;
11618   u8 sw_if_index_set = 0;
11619   u8 enable_disable = 1;
11620   int ret;
11621
11622   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11623     {
11624       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11625         sw_if_index_set = 1;
11626       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11627         sw_if_index_set = 1;
11628       else if (unformat (i, "enable"))
11629         enable_disable = 1;
11630       else if (unformat (i, "disable"))
11631         enable_disable = 0;
11632       else
11633         break;
11634     }
11635
11636   if (sw_if_index_set == 0)
11637     {
11638       errmsg ("missing interface name or sw_if_index");
11639       return -99;
11640     }
11641
11642   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11643
11644   mp->sw_if_index = ntohl (sw_if_index);
11645   mp->enable_disable = enable_disable;
11646
11647   S (mp);
11648   W (ret);
11649   return ret;
11650 }
11651
11652 static int
11653 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11654 {
11655   unformat_input_t *i = vam->input;
11656   vl_api_l2tpv3_set_lookup_key_t *mp;
11657   u8 key = ~0;
11658   int ret;
11659
11660   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11661     {
11662       if (unformat (i, "lookup_v6_src"))
11663         key = L2T_LOOKUP_SRC_ADDRESS;
11664       else if (unformat (i, "lookup_v6_dst"))
11665         key = L2T_LOOKUP_DST_ADDRESS;
11666       else if (unformat (i, "lookup_session_id"))
11667         key = L2T_LOOKUP_SESSION_ID;
11668       else
11669         break;
11670     }
11671
11672   if (key == (u8) ~ 0)
11673     {
11674       errmsg ("l2tp session lookup key unset");
11675       return -99;
11676     }
11677
11678   M (L2TPV3_SET_LOOKUP_KEY, mp);
11679
11680   mp->key = key;
11681
11682   S (mp);
11683   W (ret);
11684   return ret;
11685 }
11686
11687 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11688   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11689 {
11690   vat_main_t *vam = &vat_main;
11691
11692   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11693          format_ip6_address, mp->our_address,
11694          format_ip6_address, mp->client_address,
11695          clib_net_to_host_u32 (mp->sw_if_index));
11696
11697   print (vam->ofp,
11698          "   local cookies %016llx %016llx remote cookie %016llx",
11699          clib_net_to_host_u64 (mp->local_cookie[0]),
11700          clib_net_to_host_u64 (mp->local_cookie[1]),
11701          clib_net_to_host_u64 (mp->remote_cookie));
11702
11703   print (vam->ofp, "   local session-id %d remote session-id %d",
11704          clib_net_to_host_u32 (mp->local_session_id),
11705          clib_net_to_host_u32 (mp->remote_session_id));
11706
11707   print (vam->ofp, "   l2 specific sublayer %s\n",
11708          mp->l2_sublayer_present ? "preset" : "absent");
11709
11710 }
11711
11712 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11713   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11714 {
11715   vat_main_t *vam = &vat_main;
11716   vat_json_node_t *node = NULL;
11717   struct in6_addr addr;
11718
11719   if (VAT_JSON_ARRAY != vam->json_tree.type)
11720     {
11721       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11722       vat_json_init_array (&vam->json_tree);
11723     }
11724   node = vat_json_array_add (&vam->json_tree);
11725
11726   vat_json_init_object (node);
11727
11728   clib_memcpy (&addr, mp->our_address, sizeof (addr));
11729   vat_json_object_add_ip6 (node, "our_address", addr);
11730   clib_memcpy (&addr, mp->client_address, sizeof (addr));
11731   vat_json_object_add_ip6 (node, "client_address", addr);
11732
11733   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11734   vat_json_init_array (lc);
11735   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11736   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11737   vat_json_object_add_uint (node, "remote_cookie",
11738                             clib_net_to_host_u64 (mp->remote_cookie));
11739
11740   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11741   vat_json_object_add_uint (node, "local_session_id",
11742                             clib_net_to_host_u32 (mp->local_session_id));
11743   vat_json_object_add_uint (node, "remote_session_id",
11744                             clib_net_to_host_u32 (mp->remote_session_id));
11745   vat_json_object_add_string_copy (node, "l2_sublayer",
11746                                    mp->l2_sublayer_present ? (u8 *) "present"
11747                                    : (u8 *) "absent");
11748 }
11749
11750 static int
11751 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11752 {
11753   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11754   vl_api_control_ping_t *mp_ping;
11755   int ret;
11756
11757   /* Get list of l2tpv3-tunnel interfaces */
11758   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11759   S (mp);
11760
11761   /* Use a control ping for synchronization */
11762   MPING (CONTROL_PING, mp_ping);
11763   S (mp_ping);
11764
11765   W (ret);
11766   return ret;
11767 }
11768
11769
11770 static void vl_api_sw_interface_tap_details_t_handler
11771   (vl_api_sw_interface_tap_details_t * mp)
11772 {
11773   vat_main_t *vam = &vat_main;
11774
11775   print (vam->ofp, "%-16s %d",
11776          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
11777 }
11778
11779 static void vl_api_sw_interface_tap_details_t_handler_json
11780   (vl_api_sw_interface_tap_details_t * mp)
11781 {
11782   vat_main_t *vam = &vat_main;
11783   vat_json_node_t *node = NULL;
11784
11785   if (VAT_JSON_ARRAY != vam->json_tree.type)
11786     {
11787       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11788       vat_json_init_array (&vam->json_tree);
11789     }
11790   node = vat_json_array_add (&vam->json_tree);
11791
11792   vat_json_init_object (node);
11793   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11794   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11795 }
11796
11797 static int
11798 api_sw_interface_tap_dump (vat_main_t * vam)
11799 {
11800   vl_api_sw_interface_tap_dump_t *mp;
11801   vl_api_control_ping_t *mp_ping;
11802   int ret;
11803
11804   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
11805   /* Get list of tap interfaces */
11806   M (SW_INTERFACE_TAP_DUMP, mp);
11807   S (mp);
11808
11809   /* Use a control ping for synchronization */
11810   MPING (CONTROL_PING, mp_ping);
11811   S (mp_ping);
11812
11813   W (ret);
11814   return ret;
11815 }
11816
11817 static uword unformat_vxlan_decap_next
11818   (unformat_input_t * input, va_list * args)
11819 {
11820   u32 *result = va_arg (*args, u32 *);
11821   u32 tmp;
11822
11823   if (unformat (input, "l2"))
11824     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11825   else if (unformat (input, "%d", &tmp))
11826     *result = tmp;
11827   else
11828     return 0;
11829   return 1;
11830 }
11831
11832 static int
11833 api_vxlan_add_del_tunnel (vat_main_t * vam)
11834 {
11835   unformat_input_t *line_input = vam->input;
11836   vl_api_vxlan_add_del_tunnel_t *mp;
11837   ip46_address_t src, dst;
11838   u8 is_add = 1;
11839   u8 ipv4_set = 0, ipv6_set = 0;
11840   u8 src_set = 0;
11841   u8 dst_set = 0;
11842   u8 grp_set = 0;
11843   u32 mcast_sw_if_index = ~0;
11844   u32 encap_vrf_id = 0;
11845   u32 decap_next_index = ~0;
11846   u32 vni = 0;
11847   int ret;
11848
11849   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11850   memset (&src, 0, sizeof src);
11851   memset (&dst, 0, sizeof dst);
11852
11853   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11854     {
11855       if (unformat (line_input, "del"))
11856         is_add = 0;
11857       else
11858         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11859         {
11860           ipv4_set = 1;
11861           src_set = 1;
11862         }
11863       else
11864         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11865         {
11866           ipv4_set = 1;
11867           dst_set = 1;
11868         }
11869       else
11870         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11871         {
11872           ipv6_set = 1;
11873           src_set = 1;
11874         }
11875       else
11876         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11877         {
11878           ipv6_set = 1;
11879           dst_set = 1;
11880         }
11881       else if (unformat (line_input, "group %U %U",
11882                          unformat_ip4_address, &dst.ip4,
11883                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11884         {
11885           grp_set = dst_set = 1;
11886           ipv4_set = 1;
11887         }
11888       else if (unformat (line_input, "group %U",
11889                          unformat_ip4_address, &dst.ip4))
11890         {
11891           grp_set = dst_set = 1;
11892           ipv4_set = 1;
11893         }
11894       else if (unformat (line_input, "group %U %U",
11895                          unformat_ip6_address, &dst.ip6,
11896                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11897         {
11898           grp_set = dst_set = 1;
11899           ipv6_set = 1;
11900         }
11901       else if (unformat (line_input, "group %U",
11902                          unformat_ip6_address, &dst.ip6))
11903         {
11904           grp_set = dst_set = 1;
11905           ipv6_set = 1;
11906         }
11907       else
11908         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11909         ;
11910       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11911         ;
11912       else if (unformat (line_input, "decap-next %U",
11913                          unformat_vxlan_decap_next, &decap_next_index))
11914         ;
11915       else if (unformat (line_input, "vni %d", &vni))
11916         ;
11917       else
11918         {
11919           errmsg ("parse error '%U'", format_unformat_error, line_input);
11920           return -99;
11921         }
11922     }
11923
11924   if (src_set == 0)
11925     {
11926       errmsg ("tunnel src address not specified");
11927       return -99;
11928     }
11929   if (dst_set == 0)
11930     {
11931       errmsg ("tunnel dst address not specified");
11932       return -99;
11933     }
11934
11935   if (grp_set && !ip46_address_is_multicast (&dst))
11936     {
11937       errmsg ("tunnel group address not multicast");
11938       return -99;
11939     }
11940   if (grp_set && mcast_sw_if_index == ~0)
11941     {
11942       errmsg ("tunnel nonexistent multicast device");
11943       return -99;
11944     }
11945   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11946     {
11947       errmsg ("tunnel dst address must be unicast");
11948       return -99;
11949     }
11950
11951
11952   if (ipv4_set && ipv6_set)
11953     {
11954       errmsg ("both IPv4 and IPv6 addresses specified");
11955       return -99;
11956     }
11957
11958   if ((vni == 0) || (vni >> 24))
11959     {
11960       errmsg ("vni not specified or out of range");
11961       return -99;
11962     }
11963
11964   M (VXLAN_ADD_DEL_TUNNEL, mp);
11965
11966   if (ipv6_set)
11967     {
11968       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
11969       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
11970     }
11971   else
11972     {
11973       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
11974       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
11975     }
11976   mp->encap_vrf_id = ntohl (encap_vrf_id);
11977   mp->decap_next_index = ntohl (decap_next_index);
11978   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11979   mp->vni = ntohl (vni);
11980   mp->is_add = is_add;
11981   mp->is_ipv6 = ipv6_set;
11982
11983   S (mp);
11984   W (ret);
11985   return ret;
11986 }
11987
11988 static void vl_api_vxlan_tunnel_details_t_handler
11989   (vl_api_vxlan_tunnel_details_t * mp)
11990 {
11991   vat_main_t *vam = &vat_main;
11992   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
11993   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
11994
11995   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
11996          ntohl (mp->sw_if_index),
11997          format_ip46_address, &src, IP46_TYPE_ANY,
11998          format_ip46_address, &dst, IP46_TYPE_ANY,
11999          ntohl (mp->encap_vrf_id),
12000          ntohl (mp->decap_next_index), ntohl (mp->vni),
12001          ntohl (mp->mcast_sw_if_index));
12002 }
12003
12004 static void vl_api_vxlan_tunnel_details_t_handler_json
12005   (vl_api_vxlan_tunnel_details_t * mp)
12006 {
12007   vat_main_t *vam = &vat_main;
12008   vat_json_node_t *node = NULL;
12009
12010   if (VAT_JSON_ARRAY != vam->json_tree.type)
12011     {
12012       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12013       vat_json_init_array (&vam->json_tree);
12014     }
12015   node = vat_json_array_add (&vam->json_tree);
12016
12017   vat_json_init_object (node);
12018   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12019   if (mp->is_ipv6)
12020     {
12021       struct in6_addr ip6;
12022
12023       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12024       vat_json_object_add_ip6 (node, "src_address", ip6);
12025       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12026       vat_json_object_add_ip6 (node, "dst_address", ip6);
12027     }
12028   else
12029     {
12030       struct in_addr ip4;
12031
12032       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12033       vat_json_object_add_ip4 (node, "src_address", ip4);
12034       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12035       vat_json_object_add_ip4 (node, "dst_address", ip4);
12036     }
12037   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12038   vat_json_object_add_uint (node, "decap_next_index",
12039                             ntohl (mp->decap_next_index));
12040   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12041   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12042   vat_json_object_add_uint (node, "mcast_sw_if_index",
12043                             ntohl (mp->mcast_sw_if_index));
12044 }
12045
12046 static int
12047 api_vxlan_tunnel_dump (vat_main_t * vam)
12048 {
12049   unformat_input_t *i = vam->input;
12050   vl_api_vxlan_tunnel_dump_t *mp;
12051   vl_api_control_ping_t *mp_ping;
12052   u32 sw_if_index;
12053   u8 sw_if_index_set = 0;
12054   int ret;
12055
12056   /* Parse args required to build the message */
12057   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12058     {
12059       if (unformat (i, "sw_if_index %d", &sw_if_index))
12060         sw_if_index_set = 1;
12061       else
12062         break;
12063     }
12064
12065   if (sw_if_index_set == 0)
12066     {
12067       sw_if_index = ~0;
12068     }
12069
12070   if (!vam->json_output)
12071     {
12072       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12073              "sw_if_index", "src_address", "dst_address",
12074              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12075     }
12076
12077   /* Get list of vxlan-tunnel interfaces */
12078   M (VXLAN_TUNNEL_DUMP, mp);
12079
12080   mp->sw_if_index = htonl (sw_if_index);
12081
12082   S (mp);
12083
12084   /* Use a control ping for synchronization */
12085   MPING (CONTROL_PING, mp_ping);
12086   S (mp_ping);
12087
12088   W (ret);
12089   return ret;
12090 }
12091
12092 static uword unformat_geneve_decap_next
12093   (unformat_input_t * input, va_list * args)
12094 {
12095   u32 *result = va_arg (*args, u32 *);
12096   u32 tmp;
12097
12098   if (unformat (input, "l2"))
12099     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12100   else if (unformat (input, "%d", &tmp))
12101     *result = tmp;
12102   else
12103     return 0;
12104   return 1;
12105 }
12106
12107 static int
12108 api_geneve_add_del_tunnel (vat_main_t * vam)
12109 {
12110   unformat_input_t *line_input = vam->input;
12111   vl_api_geneve_add_del_tunnel_t *mp;
12112   ip46_address_t src, dst;
12113   u8 is_add = 1;
12114   u8 ipv4_set = 0, ipv6_set = 0;
12115   u8 src_set = 0;
12116   u8 dst_set = 0;
12117   u8 grp_set = 0;
12118   u32 mcast_sw_if_index = ~0;
12119   u32 encap_vrf_id = 0;
12120   u32 decap_next_index = ~0;
12121   u32 vni = 0;
12122   int ret;
12123
12124   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12125   memset (&src, 0, sizeof src);
12126   memset (&dst, 0, sizeof dst);
12127
12128   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12129     {
12130       if (unformat (line_input, "del"))
12131         is_add = 0;
12132       else
12133         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12134         {
12135           ipv4_set = 1;
12136           src_set = 1;
12137         }
12138       else
12139         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12140         {
12141           ipv4_set = 1;
12142           dst_set = 1;
12143         }
12144       else
12145         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12146         {
12147           ipv6_set = 1;
12148           src_set = 1;
12149         }
12150       else
12151         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12152         {
12153           ipv6_set = 1;
12154           dst_set = 1;
12155         }
12156       else if (unformat (line_input, "group %U %U",
12157                          unformat_ip4_address, &dst.ip4,
12158                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12159         {
12160           grp_set = dst_set = 1;
12161           ipv4_set = 1;
12162         }
12163       else if (unformat (line_input, "group %U",
12164                          unformat_ip4_address, &dst.ip4))
12165         {
12166           grp_set = dst_set = 1;
12167           ipv4_set = 1;
12168         }
12169       else if (unformat (line_input, "group %U %U",
12170                          unformat_ip6_address, &dst.ip6,
12171                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12172         {
12173           grp_set = dst_set = 1;
12174           ipv6_set = 1;
12175         }
12176       else if (unformat (line_input, "group %U",
12177                          unformat_ip6_address, &dst.ip6))
12178         {
12179           grp_set = dst_set = 1;
12180           ipv6_set = 1;
12181         }
12182       else
12183         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12184         ;
12185       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12186         ;
12187       else if (unformat (line_input, "decap-next %U",
12188                          unformat_geneve_decap_next, &decap_next_index))
12189         ;
12190       else if (unformat (line_input, "vni %d", &vni))
12191         ;
12192       else
12193         {
12194           errmsg ("parse error '%U'", format_unformat_error, line_input);
12195           return -99;
12196         }
12197     }
12198
12199   if (src_set == 0)
12200     {
12201       errmsg ("tunnel src address not specified");
12202       return -99;
12203     }
12204   if (dst_set == 0)
12205     {
12206       errmsg ("tunnel dst address not specified");
12207       return -99;
12208     }
12209
12210   if (grp_set && !ip46_address_is_multicast (&dst))
12211     {
12212       errmsg ("tunnel group address not multicast");
12213       return -99;
12214     }
12215   if (grp_set && mcast_sw_if_index == ~0)
12216     {
12217       errmsg ("tunnel nonexistent multicast device");
12218       return -99;
12219     }
12220   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12221     {
12222       errmsg ("tunnel dst address must be unicast");
12223       return -99;
12224     }
12225
12226
12227   if (ipv4_set && ipv6_set)
12228     {
12229       errmsg ("both IPv4 and IPv6 addresses specified");
12230       return -99;
12231     }
12232
12233   if ((vni == 0) || (vni >> 24))
12234     {
12235       errmsg ("vni not specified or out of range");
12236       return -99;
12237     }
12238
12239   M (GENEVE_ADD_DEL_TUNNEL, mp);
12240
12241   if (ipv6_set)
12242     {
12243       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12244       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12245     }
12246   else
12247     {
12248       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12249       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12250     }
12251   mp->encap_vrf_id = ntohl (encap_vrf_id);
12252   mp->decap_next_index = ntohl (decap_next_index);
12253   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12254   mp->vni = ntohl (vni);
12255   mp->is_add = is_add;
12256   mp->is_ipv6 = ipv6_set;
12257
12258   S (mp);
12259   W (ret);
12260   return ret;
12261 }
12262
12263 static void vl_api_geneve_tunnel_details_t_handler
12264   (vl_api_geneve_tunnel_details_t * mp)
12265 {
12266   vat_main_t *vam = &vat_main;
12267   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12268   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12269
12270   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12271          ntohl (mp->sw_if_index),
12272          format_ip46_address, &src, IP46_TYPE_ANY,
12273          format_ip46_address, &dst, IP46_TYPE_ANY,
12274          ntohl (mp->encap_vrf_id),
12275          ntohl (mp->decap_next_index), ntohl (mp->vni),
12276          ntohl (mp->mcast_sw_if_index));
12277 }
12278
12279 static void vl_api_geneve_tunnel_details_t_handler_json
12280   (vl_api_geneve_tunnel_details_t * mp)
12281 {
12282   vat_main_t *vam = &vat_main;
12283   vat_json_node_t *node = NULL;
12284
12285   if (VAT_JSON_ARRAY != vam->json_tree.type)
12286     {
12287       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12288       vat_json_init_array (&vam->json_tree);
12289     }
12290   node = vat_json_array_add (&vam->json_tree);
12291
12292   vat_json_init_object (node);
12293   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12294   if (mp->is_ipv6)
12295     {
12296       struct in6_addr ip6;
12297
12298       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12299       vat_json_object_add_ip6 (node, "src_address", ip6);
12300       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12301       vat_json_object_add_ip6 (node, "dst_address", ip6);
12302     }
12303   else
12304     {
12305       struct in_addr ip4;
12306
12307       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12308       vat_json_object_add_ip4 (node, "src_address", ip4);
12309       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12310       vat_json_object_add_ip4 (node, "dst_address", ip4);
12311     }
12312   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12313   vat_json_object_add_uint (node, "decap_next_index",
12314                             ntohl (mp->decap_next_index));
12315   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12316   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12317   vat_json_object_add_uint (node, "mcast_sw_if_index",
12318                             ntohl (mp->mcast_sw_if_index));
12319 }
12320
12321 static int
12322 api_geneve_tunnel_dump (vat_main_t * vam)
12323 {
12324   unformat_input_t *i = vam->input;
12325   vl_api_geneve_tunnel_dump_t *mp;
12326   vl_api_control_ping_t *mp_ping;
12327   u32 sw_if_index;
12328   u8 sw_if_index_set = 0;
12329   int ret;
12330
12331   /* Parse args required to build the message */
12332   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12333     {
12334       if (unformat (i, "sw_if_index %d", &sw_if_index))
12335         sw_if_index_set = 1;
12336       else
12337         break;
12338     }
12339
12340   if (sw_if_index_set == 0)
12341     {
12342       sw_if_index = ~0;
12343     }
12344
12345   if (!vam->json_output)
12346     {
12347       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12348              "sw_if_index", "local_address", "remote_address",
12349              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12350     }
12351
12352   /* Get list of geneve-tunnel interfaces */
12353   M (GENEVE_TUNNEL_DUMP, mp);
12354
12355   mp->sw_if_index = htonl (sw_if_index);
12356
12357   S (mp);
12358
12359   /* Use a control ping for synchronization */
12360   M (CONTROL_PING, mp_ping);
12361   S (mp_ping);
12362
12363   W (ret);
12364   return ret;
12365 }
12366
12367 static int
12368 api_gre_add_del_tunnel (vat_main_t * vam)
12369 {
12370   unformat_input_t *line_input = vam->input;
12371   vl_api_gre_add_del_tunnel_t *mp;
12372   ip4_address_t src4, dst4;
12373   ip6_address_t src6, dst6;
12374   u8 is_add = 1;
12375   u8 ipv4_set = 0;
12376   u8 ipv6_set = 0;
12377   u8 teb = 0;
12378   u8 src_set = 0;
12379   u8 dst_set = 0;
12380   u32 outer_fib_id = 0;
12381   int ret;
12382
12383   memset (&src4, 0, sizeof src4);
12384   memset (&dst4, 0, sizeof dst4);
12385   memset (&src6, 0, sizeof src6);
12386   memset (&dst6, 0, sizeof dst6);
12387
12388   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12389     {
12390       if (unformat (line_input, "del"))
12391         is_add = 0;
12392       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
12393         {
12394           src_set = 1;
12395           ipv4_set = 1;
12396         }
12397       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
12398         {
12399           dst_set = 1;
12400           ipv4_set = 1;
12401         }
12402       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
12403         {
12404           src_set = 1;
12405           ipv6_set = 1;
12406         }
12407       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
12408         {
12409           dst_set = 1;
12410           ipv6_set = 1;
12411         }
12412       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
12413         ;
12414       else if (unformat (line_input, "teb"))
12415         teb = 1;
12416       else
12417         {
12418           errmsg ("parse error '%U'", format_unformat_error, line_input);
12419           return -99;
12420         }
12421     }
12422
12423   if (src_set == 0)
12424     {
12425       errmsg ("tunnel src address not specified");
12426       return -99;
12427     }
12428   if (dst_set == 0)
12429     {
12430       errmsg ("tunnel dst address not specified");
12431       return -99;
12432     }
12433   if (ipv4_set && ipv6_set)
12434     {
12435       errmsg ("both IPv4 and IPv6 addresses specified");
12436       return -99;
12437     }
12438
12439
12440   M (GRE_ADD_DEL_TUNNEL, mp);
12441
12442   if (ipv4_set)
12443     {
12444       clib_memcpy (&mp->src_address, &src4, 4);
12445       clib_memcpy (&mp->dst_address, &dst4, 4);
12446     }
12447   else
12448     {
12449       clib_memcpy (&mp->src_address, &src6, 16);
12450       clib_memcpy (&mp->dst_address, &dst6, 16);
12451     }
12452   mp->outer_fib_id = ntohl (outer_fib_id);
12453   mp->is_add = is_add;
12454   mp->teb = teb;
12455   mp->is_ipv6 = ipv6_set;
12456
12457   S (mp);
12458   W (ret);
12459   return ret;
12460 }
12461
12462 static void vl_api_gre_tunnel_details_t_handler
12463   (vl_api_gre_tunnel_details_t * mp)
12464 {
12465   vat_main_t *vam = &vat_main;
12466   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->src_address);
12467   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->dst_address);
12468
12469   print (vam->ofp, "%11d%24U%24U%6d%14d",
12470          ntohl (mp->sw_if_index),
12471          format_ip46_address, &src, IP46_TYPE_ANY,
12472          format_ip46_address, &dst, IP46_TYPE_ANY,
12473          mp->teb, ntohl (mp->outer_fib_id));
12474 }
12475
12476 static void vl_api_gre_tunnel_details_t_handler_json
12477   (vl_api_gre_tunnel_details_t * mp)
12478 {
12479   vat_main_t *vam = &vat_main;
12480   vat_json_node_t *node = NULL;
12481   struct in_addr ip4;
12482   struct in6_addr ip6;
12483
12484   if (VAT_JSON_ARRAY != vam->json_tree.type)
12485     {
12486       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12487       vat_json_init_array (&vam->json_tree);
12488     }
12489   node = vat_json_array_add (&vam->json_tree);
12490
12491   vat_json_init_object (node);
12492   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12493   if (!mp->is_ipv6)
12494     {
12495       clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
12496       vat_json_object_add_ip4 (node, "src_address", ip4);
12497       clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
12498       vat_json_object_add_ip4 (node, "dst_address", ip4);
12499     }
12500   else
12501     {
12502       clib_memcpy (&ip6, &mp->src_address, sizeof (ip6));
12503       vat_json_object_add_ip6 (node, "src_address", ip6);
12504       clib_memcpy (&ip6, &mp->dst_address, sizeof (ip6));
12505       vat_json_object_add_ip6 (node, "dst_address", ip6);
12506     }
12507   vat_json_object_add_uint (node, "teb", mp->teb);
12508   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
12509   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6);
12510 }
12511
12512 static int
12513 api_gre_tunnel_dump (vat_main_t * vam)
12514 {
12515   unformat_input_t *i = vam->input;
12516   vl_api_gre_tunnel_dump_t *mp;
12517   vl_api_control_ping_t *mp_ping;
12518   u32 sw_if_index;
12519   u8 sw_if_index_set = 0;
12520   int ret;
12521
12522   /* Parse args required to build the message */
12523   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12524     {
12525       if (unformat (i, "sw_if_index %d", &sw_if_index))
12526         sw_if_index_set = 1;
12527       else
12528         break;
12529     }
12530
12531   if (sw_if_index_set == 0)
12532     {
12533       sw_if_index = ~0;
12534     }
12535
12536   if (!vam->json_output)
12537     {
12538       print (vam->ofp, "%11s%24s%24s%6s%14s",
12539              "sw_if_index", "src_address", "dst_address", "teb",
12540              "outer_fib_id");
12541     }
12542
12543   /* Get list of gre-tunnel interfaces */
12544   M (GRE_TUNNEL_DUMP, mp);
12545
12546   mp->sw_if_index = htonl (sw_if_index);
12547
12548   S (mp);
12549
12550   /* Use a control ping for synchronization */
12551   MPING (CONTROL_PING, mp_ping);
12552   S (mp_ping);
12553
12554   W (ret);
12555   return ret;
12556 }
12557
12558 static int
12559 api_l2_fib_clear_table (vat_main_t * vam)
12560 {
12561 //  unformat_input_t * i = vam->input;
12562   vl_api_l2_fib_clear_table_t *mp;
12563   int ret;
12564
12565   M (L2_FIB_CLEAR_TABLE, mp);
12566
12567   S (mp);
12568   W (ret);
12569   return ret;
12570 }
12571
12572 static int
12573 api_l2_interface_efp_filter (vat_main_t * vam)
12574 {
12575   unformat_input_t *i = vam->input;
12576   vl_api_l2_interface_efp_filter_t *mp;
12577   u32 sw_if_index;
12578   u8 enable = 1;
12579   u8 sw_if_index_set = 0;
12580   int ret;
12581
12582   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12583     {
12584       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12585         sw_if_index_set = 1;
12586       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12587         sw_if_index_set = 1;
12588       else if (unformat (i, "enable"))
12589         enable = 1;
12590       else if (unformat (i, "disable"))
12591         enable = 0;
12592       else
12593         {
12594           clib_warning ("parse error '%U'", format_unformat_error, i);
12595           return -99;
12596         }
12597     }
12598
12599   if (sw_if_index_set == 0)
12600     {
12601       errmsg ("missing sw_if_index");
12602       return -99;
12603     }
12604
12605   M (L2_INTERFACE_EFP_FILTER, mp);
12606
12607   mp->sw_if_index = ntohl (sw_if_index);
12608   mp->enable_disable = enable;
12609
12610   S (mp);
12611   W (ret);
12612   return ret;
12613 }
12614
12615 #define foreach_vtr_op                          \
12616 _("disable",  L2_VTR_DISABLED)                  \
12617 _("push-1",  L2_VTR_PUSH_1)                     \
12618 _("push-2",  L2_VTR_PUSH_2)                     \
12619 _("pop-1",  L2_VTR_POP_1)                       \
12620 _("pop-2",  L2_VTR_POP_2)                       \
12621 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12622 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12623 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12624 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12625
12626 static int
12627 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12628 {
12629   unformat_input_t *i = vam->input;
12630   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12631   u32 sw_if_index;
12632   u8 sw_if_index_set = 0;
12633   u8 vtr_op_set = 0;
12634   u32 vtr_op = 0;
12635   u32 push_dot1q = 1;
12636   u32 tag1 = ~0;
12637   u32 tag2 = ~0;
12638   int ret;
12639
12640   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12641     {
12642       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12643         sw_if_index_set = 1;
12644       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12645         sw_if_index_set = 1;
12646       else if (unformat (i, "vtr_op %d", &vtr_op))
12647         vtr_op_set = 1;
12648 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12649       foreach_vtr_op
12650 #undef _
12651         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12652         ;
12653       else if (unformat (i, "tag1 %d", &tag1))
12654         ;
12655       else if (unformat (i, "tag2 %d", &tag2))
12656         ;
12657       else
12658         {
12659           clib_warning ("parse error '%U'", format_unformat_error, i);
12660           return -99;
12661         }
12662     }
12663
12664   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12665     {
12666       errmsg ("missing vtr operation or sw_if_index");
12667       return -99;
12668     }
12669
12670   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12671   mp->sw_if_index = ntohl (sw_if_index);
12672   mp->vtr_op = ntohl (vtr_op);
12673   mp->push_dot1q = ntohl (push_dot1q);
12674   mp->tag1 = ntohl (tag1);
12675   mp->tag2 = ntohl (tag2);
12676
12677   S (mp);
12678   W (ret);
12679   return ret;
12680 }
12681
12682 static int
12683 api_create_vhost_user_if (vat_main_t * vam)
12684 {
12685   unformat_input_t *i = vam->input;
12686   vl_api_create_vhost_user_if_t *mp;
12687   u8 *file_name;
12688   u8 is_server = 0;
12689   u8 file_name_set = 0;
12690   u32 custom_dev_instance = ~0;
12691   u8 hwaddr[6];
12692   u8 use_custom_mac = 0;
12693   u8 *tag = 0;
12694   int ret;
12695
12696   /* Shut up coverity */
12697   memset (hwaddr, 0, sizeof (hwaddr));
12698
12699   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12700     {
12701       if (unformat (i, "socket %s", &file_name))
12702         {
12703           file_name_set = 1;
12704         }
12705       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12706         ;
12707       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12708         use_custom_mac = 1;
12709       else if (unformat (i, "server"))
12710         is_server = 1;
12711       else if (unformat (i, "tag %s", &tag))
12712         ;
12713       else
12714         break;
12715     }
12716
12717   if (file_name_set == 0)
12718     {
12719       errmsg ("missing socket file name");
12720       return -99;
12721     }
12722
12723   if (vec_len (file_name) > 255)
12724     {
12725       errmsg ("socket file name too long");
12726       return -99;
12727     }
12728   vec_add1 (file_name, 0);
12729
12730   M (CREATE_VHOST_USER_IF, mp);
12731
12732   mp->is_server = is_server;
12733   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12734   vec_free (file_name);
12735   if (custom_dev_instance != ~0)
12736     {
12737       mp->renumber = 1;
12738       mp->custom_dev_instance = ntohl (custom_dev_instance);
12739     }
12740   mp->use_custom_mac = use_custom_mac;
12741   clib_memcpy (mp->mac_address, hwaddr, 6);
12742   if (tag)
12743     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12744   vec_free (tag);
12745
12746   S (mp);
12747   W (ret);
12748   return ret;
12749 }
12750
12751 static int
12752 api_modify_vhost_user_if (vat_main_t * vam)
12753 {
12754   unformat_input_t *i = vam->input;
12755   vl_api_modify_vhost_user_if_t *mp;
12756   u8 *file_name;
12757   u8 is_server = 0;
12758   u8 file_name_set = 0;
12759   u32 custom_dev_instance = ~0;
12760   u8 sw_if_index_set = 0;
12761   u32 sw_if_index = (u32) ~ 0;
12762   int ret;
12763
12764   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12765     {
12766       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12767         sw_if_index_set = 1;
12768       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12769         sw_if_index_set = 1;
12770       else if (unformat (i, "socket %s", &file_name))
12771         {
12772           file_name_set = 1;
12773         }
12774       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12775         ;
12776       else if (unformat (i, "server"))
12777         is_server = 1;
12778       else
12779         break;
12780     }
12781
12782   if (sw_if_index_set == 0)
12783     {
12784       errmsg ("missing sw_if_index or interface name");
12785       return -99;
12786     }
12787
12788   if (file_name_set == 0)
12789     {
12790       errmsg ("missing socket file name");
12791       return -99;
12792     }
12793
12794   if (vec_len (file_name) > 255)
12795     {
12796       errmsg ("socket file name too long");
12797       return -99;
12798     }
12799   vec_add1 (file_name, 0);
12800
12801   M (MODIFY_VHOST_USER_IF, mp);
12802
12803   mp->sw_if_index = ntohl (sw_if_index);
12804   mp->is_server = is_server;
12805   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12806   vec_free (file_name);
12807   if (custom_dev_instance != ~0)
12808     {
12809       mp->renumber = 1;
12810       mp->custom_dev_instance = ntohl (custom_dev_instance);
12811     }
12812
12813   S (mp);
12814   W (ret);
12815   return ret;
12816 }
12817
12818 static int
12819 api_delete_vhost_user_if (vat_main_t * vam)
12820 {
12821   unformat_input_t *i = vam->input;
12822   vl_api_delete_vhost_user_if_t *mp;
12823   u32 sw_if_index = ~0;
12824   u8 sw_if_index_set = 0;
12825   int ret;
12826
12827   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12828     {
12829       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12830         sw_if_index_set = 1;
12831       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12832         sw_if_index_set = 1;
12833       else
12834         break;
12835     }
12836
12837   if (sw_if_index_set == 0)
12838     {
12839       errmsg ("missing sw_if_index or interface name");
12840       return -99;
12841     }
12842
12843
12844   M (DELETE_VHOST_USER_IF, mp);
12845
12846   mp->sw_if_index = ntohl (sw_if_index);
12847
12848   S (mp);
12849   W (ret);
12850   return ret;
12851 }
12852
12853 static void vl_api_sw_interface_vhost_user_details_t_handler
12854   (vl_api_sw_interface_vhost_user_details_t * mp)
12855 {
12856   vat_main_t *vam = &vat_main;
12857
12858   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12859          (char *) mp->interface_name,
12860          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12861          clib_net_to_host_u64 (mp->features), mp->is_server,
12862          ntohl (mp->num_regions), (char *) mp->sock_filename);
12863   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12864 }
12865
12866 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12867   (vl_api_sw_interface_vhost_user_details_t * mp)
12868 {
12869   vat_main_t *vam = &vat_main;
12870   vat_json_node_t *node = NULL;
12871
12872   if (VAT_JSON_ARRAY != vam->json_tree.type)
12873     {
12874       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12875       vat_json_init_array (&vam->json_tree);
12876     }
12877   node = vat_json_array_add (&vam->json_tree);
12878
12879   vat_json_init_object (node);
12880   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12881   vat_json_object_add_string_copy (node, "interface_name",
12882                                    mp->interface_name);
12883   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12884                             ntohl (mp->virtio_net_hdr_sz));
12885   vat_json_object_add_uint (node, "features",
12886                             clib_net_to_host_u64 (mp->features));
12887   vat_json_object_add_uint (node, "is_server", mp->is_server);
12888   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12889   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12890   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12891 }
12892
12893 static int
12894 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12895 {
12896   vl_api_sw_interface_vhost_user_dump_t *mp;
12897   vl_api_control_ping_t *mp_ping;
12898   int ret;
12899   print (vam->ofp,
12900          "Interface name            idx hdr_sz features server regions filename");
12901
12902   /* Get list of vhost-user interfaces */
12903   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12904   S (mp);
12905
12906   /* Use a control ping for synchronization */
12907   MPING (CONTROL_PING, mp_ping);
12908   S (mp_ping);
12909
12910   W (ret);
12911   return ret;
12912 }
12913
12914 static int
12915 api_show_version (vat_main_t * vam)
12916 {
12917   vl_api_show_version_t *mp;
12918   int ret;
12919
12920   M (SHOW_VERSION, mp);
12921
12922   S (mp);
12923   W (ret);
12924   return ret;
12925 }
12926
12927
12928 static int
12929 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12930 {
12931   unformat_input_t *line_input = vam->input;
12932   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12933   ip4_address_t local4, remote4;
12934   ip6_address_t local6, remote6;
12935   u8 is_add = 1;
12936   u8 ipv4_set = 0, ipv6_set = 0;
12937   u8 local_set = 0;
12938   u8 remote_set = 0;
12939   u8 grp_set = 0;
12940   u32 mcast_sw_if_index = ~0;
12941   u32 encap_vrf_id = 0;
12942   u32 decap_vrf_id = 0;
12943   u8 protocol = ~0;
12944   u32 vni;
12945   u8 vni_set = 0;
12946   int ret;
12947
12948   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12949   memset (&local4, 0, sizeof local4);
12950   memset (&remote4, 0, sizeof remote4);
12951   memset (&local6, 0, sizeof local6);
12952   memset (&remote6, 0, sizeof remote6);
12953
12954   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12955     {
12956       if (unformat (line_input, "del"))
12957         is_add = 0;
12958       else if (unformat (line_input, "local %U",
12959                          unformat_ip4_address, &local4))
12960         {
12961           local_set = 1;
12962           ipv4_set = 1;
12963         }
12964       else if (unformat (line_input, "remote %U",
12965                          unformat_ip4_address, &remote4))
12966         {
12967           remote_set = 1;
12968           ipv4_set = 1;
12969         }
12970       else if (unformat (line_input, "local %U",
12971                          unformat_ip6_address, &local6))
12972         {
12973           local_set = 1;
12974           ipv6_set = 1;
12975         }
12976       else if (unformat (line_input, "remote %U",
12977                          unformat_ip6_address, &remote6))
12978         {
12979           remote_set = 1;
12980           ipv6_set = 1;
12981         }
12982       else if (unformat (line_input, "group %U %U",
12983                          unformat_ip4_address, &remote4,
12984                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12985         {
12986           grp_set = remote_set = 1;
12987           ipv4_set = 1;
12988         }
12989       else if (unformat (line_input, "group %U",
12990                          unformat_ip4_address, &remote4))
12991         {
12992           grp_set = remote_set = 1;
12993           ipv4_set = 1;
12994         }
12995       else if (unformat (line_input, "group %U %U",
12996                          unformat_ip6_address, &remote6,
12997                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12998         {
12999           grp_set = remote_set = 1;
13000           ipv6_set = 1;
13001         }
13002       else if (unformat (line_input, "group %U",
13003                          unformat_ip6_address, &remote6))
13004         {
13005           grp_set = remote_set = 1;
13006           ipv6_set = 1;
13007         }
13008       else
13009         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13010         ;
13011       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13012         ;
13013       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13014         ;
13015       else if (unformat (line_input, "vni %d", &vni))
13016         vni_set = 1;
13017       else if (unformat (line_input, "next-ip4"))
13018         protocol = 1;
13019       else if (unformat (line_input, "next-ip6"))
13020         protocol = 2;
13021       else if (unformat (line_input, "next-ethernet"))
13022         protocol = 3;
13023       else if (unformat (line_input, "next-nsh"))
13024         protocol = 4;
13025       else
13026         {
13027           errmsg ("parse error '%U'", format_unformat_error, line_input);
13028           return -99;
13029         }
13030     }
13031
13032   if (local_set == 0)
13033     {
13034       errmsg ("tunnel local address not specified");
13035       return -99;
13036     }
13037   if (remote_set == 0)
13038     {
13039       errmsg ("tunnel remote address not specified");
13040       return -99;
13041     }
13042   if (grp_set && mcast_sw_if_index == ~0)
13043     {
13044       errmsg ("tunnel nonexistent multicast device");
13045       return -99;
13046     }
13047   if (ipv4_set && ipv6_set)
13048     {
13049       errmsg ("both IPv4 and IPv6 addresses specified");
13050       return -99;
13051     }
13052
13053   if (vni_set == 0)
13054     {
13055       errmsg ("vni not specified");
13056       return -99;
13057     }
13058
13059   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13060
13061
13062   if (ipv6_set)
13063     {
13064       clib_memcpy (&mp->local, &local6, sizeof (local6));
13065       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13066     }
13067   else
13068     {
13069       clib_memcpy (&mp->local, &local4, sizeof (local4));
13070       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13071     }
13072
13073   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13074   mp->encap_vrf_id = ntohl (encap_vrf_id);
13075   mp->decap_vrf_id = ntohl (decap_vrf_id);
13076   mp->protocol = protocol;
13077   mp->vni = ntohl (vni);
13078   mp->is_add = is_add;
13079   mp->is_ipv6 = ipv6_set;
13080
13081   S (mp);
13082   W (ret);
13083   return ret;
13084 }
13085
13086 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13087   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13088 {
13089   vat_main_t *vam = &vat_main;
13090   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13091   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13092
13093   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13094          ntohl (mp->sw_if_index),
13095          format_ip46_address, &local, IP46_TYPE_ANY,
13096          format_ip46_address, &remote, IP46_TYPE_ANY,
13097          ntohl (mp->vni), mp->protocol,
13098          ntohl (mp->mcast_sw_if_index),
13099          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13100 }
13101
13102
13103 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13104   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13105 {
13106   vat_main_t *vam = &vat_main;
13107   vat_json_node_t *node = NULL;
13108   struct in_addr ip4;
13109   struct in6_addr ip6;
13110
13111   if (VAT_JSON_ARRAY != vam->json_tree.type)
13112     {
13113       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13114       vat_json_init_array (&vam->json_tree);
13115     }
13116   node = vat_json_array_add (&vam->json_tree);
13117
13118   vat_json_init_object (node);
13119   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13120   if (mp->is_ipv6)
13121     {
13122       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13123       vat_json_object_add_ip6 (node, "local", ip6);
13124       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13125       vat_json_object_add_ip6 (node, "remote", ip6);
13126     }
13127   else
13128     {
13129       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13130       vat_json_object_add_ip4 (node, "local", ip4);
13131       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13132       vat_json_object_add_ip4 (node, "remote", ip4);
13133     }
13134   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13135   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13136   vat_json_object_add_uint (node, "mcast_sw_if_index",
13137                             ntohl (mp->mcast_sw_if_index));
13138   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13139   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13140   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13141 }
13142
13143 static int
13144 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13145 {
13146   unformat_input_t *i = vam->input;
13147   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13148   vl_api_control_ping_t *mp_ping;
13149   u32 sw_if_index;
13150   u8 sw_if_index_set = 0;
13151   int ret;
13152
13153   /* Parse args required to build the message */
13154   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13155     {
13156       if (unformat (i, "sw_if_index %d", &sw_if_index))
13157         sw_if_index_set = 1;
13158       else
13159         break;
13160     }
13161
13162   if (sw_if_index_set == 0)
13163     {
13164       sw_if_index = ~0;
13165     }
13166
13167   if (!vam->json_output)
13168     {
13169       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13170              "sw_if_index", "local", "remote", "vni",
13171              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13172     }
13173
13174   /* Get list of vxlan-tunnel interfaces */
13175   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13176
13177   mp->sw_if_index = htonl (sw_if_index);
13178
13179   S (mp);
13180
13181   /* Use a control ping for synchronization */
13182   MPING (CONTROL_PING, mp_ping);
13183   S (mp_ping);
13184
13185   W (ret);
13186   return ret;
13187 }
13188
13189
13190 u8 *
13191 format_l2_fib_mac_address (u8 * s, va_list * args)
13192 {
13193   u8 *a = va_arg (*args, u8 *);
13194
13195   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
13196                  a[2], a[3], a[4], a[5], a[6], a[7]);
13197 }
13198
13199 static void vl_api_l2_fib_table_details_t_handler
13200   (vl_api_l2_fib_table_details_t * mp)
13201 {
13202   vat_main_t *vam = &vat_main;
13203
13204   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13205          "       %d       %d     %d",
13206          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
13207          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13208          mp->bvi_mac);
13209 }
13210
13211 static void vl_api_l2_fib_table_details_t_handler_json
13212   (vl_api_l2_fib_table_details_t * mp)
13213 {
13214   vat_main_t *vam = &vat_main;
13215   vat_json_node_t *node = NULL;
13216
13217   if (VAT_JSON_ARRAY != vam->json_tree.type)
13218     {
13219       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13220       vat_json_init_array (&vam->json_tree);
13221     }
13222   node = vat_json_array_add (&vam->json_tree);
13223
13224   vat_json_init_object (node);
13225   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13226   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
13227   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13228   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13229   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13230   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13231 }
13232
13233 static int
13234 api_l2_fib_table_dump (vat_main_t * vam)
13235 {
13236   unformat_input_t *i = vam->input;
13237   vl_api_l2_fib_table_dump_t *mp;
13238   vl_api_control_ping_t *mp_ping;
13239   u32 bd_id;
13240   u8 bd_id_set = 0;
13241   int ret;
13242
13243   /* Parse args required to build the message */
13244   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13245     {
13246       if (unformat (i, "bd_id %d", &bd_id))
13247         bd_id_set = 1;
13248       else
13249         break;
13250     }
13251
13252   if (bd_id_set == 0)
13253     {
13254       errmsg ("missing bridge domain");
13255       return -99;
13256     }
13257
13258   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13259
13260   /* Get list of l2 fib entries */
13261   M (L2_FIB_TABLE_DUMP, mp);
13262
13263   mp->bd_id = ntohl (bd_id);
13264   S (mp);
13265
13266   /* Use a control ping for synchronization */
13267   MPING (CONTROL_PING, mp_ping);
13268   S (mp_ping);
13269
13270   W (ret);
13271   return ret;
13272 }
13273
13274
13275 static int
13276 api_interface_name_renumber (vat_main_t * vam)
13277 {
13278   unformat_input_t *line_input = vam->input;
13279   vl_api_interface_name_renumber_t *mp;
13280   u32 sw_if_index = ~0;
13281   u32 new_show_dev_instance = ~0;
13282   int ret;
13283
13284   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13285     {
13286       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13287                     &sw_if_index))
13288         ;
13289       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13290         ;
13291       else if (unformat (line_input, "new_show_dev_instance %d",
13292                          &new_show_dev_instance))
13293         ;
13294       else
13295         break;
13296     }
13297
13298   if (sw_if_index == ~0)
13299     {
13300       errmsg ("missing interface name or sw_if_index");
13301       return -99;
13302     }
13303
13304   if (new_show_dev_instance == ~0)
13305     {
13306       errmsg ("missing new_show_dev_instance");
13307       return -99;
13308     }
13309
13310   M (INTERFACE_NAME_RENUMBER, mp);
13311
13312   mp->sw_if_index = ntohl (sw_if_index);
13313   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13314
13315   S (mp);
13316   W (ret);
13317   return ret;
13318 }
13319
13320 static int
13321 api_want_ip4_arp_events (vat_main_t * vam)
13322 {
13323   unformat_input_t *line_input = vam->input;
13324   vl_api_want_ip4_arp_events_t *mp;
13325   ip4_address_t address;
13326   int address_set = 0;
13327   u32 enable_disable = 1;
13328   int ret;
13329
13330   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13331     {
13332       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
13333         address_set = 1;
13334       else if (unformat (line_input, "del"))
13335         enable_disable = 0;
13336       else
13337         break;
13338     }
13339
13340   if (address_set == 0)
13341     {
13342       errmsg ("missing addresses");
13343       return -99;
13344     }
13345
13346   M (WANT_IP4_ARP_EVENTS, mp);
13347   mp->enable_disable = enable_disable;
13348   mp->pid = htonl (getpid ());
13349   mp->address = address.as_u32;
13350
13351   S (mp);
13352   W (ret);
13353   return ret;
13354 }
13355
13356 static int
13357 api_want_ip6_nd_events (vat_main_t * vam)
13358 {
13359   unformat_input_t *line_input = vam->input;
13360   vl_api_want_ip6_nd_events_t *mp;
13361   ip6_address_t address;
13362   int address_set = 0;
13363   u32 enable_disable = 1;
13364   int ret;
13365
13366   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13367     {
13368       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
13369         address_set = 1;
13370       else if (unformat (line_input, "del"))
13371         enable_disable = 0;
13372       else
13373         break;
13374     }
13375
13376   if (address_set == 0)
13377     {
13378       errmsg ("missing addresses");
13379       return -99;
13380     }
13381
13382   M (WANT_IP6_ND_EVENTS, mp);
13383   mp->enable_disable = enable_disable;
13384   mp->pid = htonl (getpid ());
13385   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
13386
13387   S (mp);
13388   W (ret);
13389   return ret;
13390 }
13391
13392 static int
13393 api_want_l2_macs_events (vat_main_t * vam)
13394 {
13395   unformat_input_t *line_input = vam->input;
13396   vl_api_want_l2_macs_events_t *mp;
13397   u8 enable_disable = 1;
13398   u32 scan_delay = 0;
13399   u32 max_macs_in_event = 0;
13400   u32 learn_limit = 0;
13401   int ret;
13402
13403   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13404     {
13405       if (unformat (line_input, "learn-limit %d", &learn_limit))
13406         ;
13407       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13408         ;
13409       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13410         ;
13411       else if (unformat (line_input, "disable"))
13412         enable_disable = 0;
13413       else
13414         break;
13415     }
13416
13417   M (WANT_L2_MACS_EVENTS, mp);
13418   mp->enable_disable = enable_disable;
13419   mp->pid = htonl (getpid ());
13420   mp->learn_limit = htonl (learn_limit);
13421   mp->scan_delay = (u8) scan_delay;
13422   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13423   S (mp);
13424   W (ret);
13425   return ret;
13426 }
13427
13428 static int
13429 api_input_acl_set_interface (vat_main_t * vam)
13430 {
13431   unformat_input_t *i = vam->input;
13432   vl_api_input_acl_set_interface_t *mp;
13433   u32 sw_if_index;
13434   int sw_if_index_set;
13435   u32 ip4_table_index = ~0;
13436   u32 ip6_table_index = ~0;
13437   u32 l2_table_index = ~0;
13438   u8 is_add = 1;
13439   int ret;
13440
13441   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13442     {
13443       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13444         sw_if_index_set = 1;
13445       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13446         sw_if_index_set = 1;
13447       else if (unformat (i, "del"))
13448         is_add = 0;
13449       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13450         ;
13451       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13452         ;
13453       else if (unformat (i, "l2-table %d", &l2_table_index))
13454         ;
13455       else
13456         {
13457           clib_warning ("parse error '%U'", format_unformat_error, i);
13458           return -99;
13459         }
13460     }
13461
13462   if (sw_if_index_set == 0)
13463     {
13464       errmsg ("missing interface name or sw_if_index");
13465       return -99;
13466     }
13467
13468   M (INPUT_ACL_SET_INTERFACE, mp);
13469
13470   mp->sw_if_index = ntohl (sw_if_index);
13471   mp->ip4_table_index = ntohl (ip4_table_index);
13472   mp->ip6_table_index = ntohl (ip6_table_index);
13473   mp->l2_table_index = ntohl (l2_table_index);
13474   mp->is_add = is_add;
13475
13476   S (mp);
13477   W (ret);
13478   return ret;
13479 }
13480
13481 static int
13482 api_ip_address_dump (vat_main_t * vam)
13483 {
13484   unformat_input_t *i = vam->input;
13485   vl_api_ip_address_dump_t *mp;
13486   vl_api_control_ping_t *mp_ping;
13487   u32 sw_if_index = ~0;
13488   u8 sw_if_index_set = 0;
13489   u8 ipv4_set = 0;
13490   u8 ipv6_set = 0;
13491   int ret;
13492
13493   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13494     {
13495       if (unformat (i, "sw_if_index %d", &sw_if_index))
13496         sw_if_index_set = 1;
13497       else
13498         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13499         sw_if_index_set = 1;
13500       else if (unformat (i, "ipv4"))
13501         ipv4_set = 1;
13502       else if (unformat (i, "ipv6"))
13503         ipv6_set = 1;
13504       else
13505         break;
13506     }
13507
13508   if (ipv4_set && ipv6_set)
13509     {
13510       errmsg ("ipv4 and ipv6 flags cannot be both set");
13511       return -99;
13512     }
13513
13514   if ((!ipv4_set) && (!ipv6_set))
13515     {
13516       errmsg ("no ipv4 nor ipv6 flag set");
13517       return -99;
13518     }
13519
13520   if (sw_if_index_set == 0)
13521     {
13522       errmsg ("missing interface name or sw_if_index");
13523       return -99;
13524     }
13525
13526   vam->current_sw_if_index = sw_if_index;
13527   vam->is_ipv6 = ipv6_set;
13528
13529   M (IP_ADDRESS_DUMP, mp);
13530   mp->sw_if_index = ntohl (sw_if_index);
13531   mp->is_ipv6 = ipv6_set;
13532   S (mp);
13533
13534   /* Use a control ping for synchronization */
13535   MPING (CONTROL_PING, mp_ping);
13536   S (mp_ping);
13537
13538   W (ret);
13539   return ret;
13540 }
13541
13542 static int
13543 api_ip_dump (vat_main_t * vam)
13544 {
13545   vl_api_ip_dump_t *mp;
13546   vl_api_control_ping_t *mp_ping;
13547   unformat_input_t *in = vam->input;
13548   int ipv4_set = 0;
13549   int ipv6_set = 0;
13550   int is_ipv6;
13551   int i;
13552   int ret;
13553
13554   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13555     {
13556       if (unformat (in, "ipv4"))
13557         ipv4_set = 1;
13558       else if (unformat (in, "ipv6"))
13559         ipv6_set = 1;
13560       else
13561         break;
13562     }
13563
13564   if (ipv4_set && ipv6_set)
13565     {
13566       errmsg ("ipv4 and ipv6 flags cannot be both set");
13567       return -99;
13568     }
13569
13570   if ((!ipv4_set) && (!ipv6_set))
13571     {
13572       errmsg ("no ipv4 nor ipv6 flag set");
13573       return -99;
13574     }
13575
13576   is_ipv6 = ipv6_set;
13577   vam->is_ipv6 = is_ipv6;
13578
13579   /* free old data */
13580   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13581     {
13582       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13583     }
13584   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13585
13586   M (IP_DUMP, mp);
13587   mp->is_ipv6 = ipv6_set;
13588   S (mp);
13589
13590   /* Use a control ping for synchronization */
13591   MPING (CONTROL_PING, mp_ping);
13592   S (mp_ping);
13593
13594   W (ret);
13595   return ret;
13596 }
13597
13598 static int
13599 api_ipsec_spd_add_del (vat_main_t * vam)
13600 {
13601   unformat_input_t *i = vam->input;
13602   vl_api_ipsec_spd_add_del_t *mp;
13603   u32 spd_id = ~0;
13604   u8 is_add = 1;
13605   int ret;
13606
13607   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13608     {
13609       if (unformat (i, "spd_id %d", &spd_id))
13610         ;
13611       else if (unformat (i, "del"))
13612         is_add = 0;
13613       else
13614         {
13615           clib_warning ("parse error '%U'", format_unformat_error, i);
13616           return -99;
13617         }
13618     }
13619   if (spd_id == ~0)
13620     {
13621       errmsg ("spd_id must be set");
13622       return -99;
13623     }
13624
13625   M (IPSEC_SPD_ADD_DEL, mp);
13626
13627   mp->spd_id = ntohl (spd_id);
13628   mp->is_add = is_add;
13629
13630   S (mp);
13631   W (ret);
13632   return ret;
13633 }
13634
13635 static int
13636 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13637 {
13638   unformat_input_t *i = vam->input;
13639   vl_api_ipsec_interface_add_del_spd_t *mp;
13640   u32 sw_if_index;
13641   u8 sw_if_index_set = 0;
13642   u32 spd_id = (u32) ~ 0;
13643   u8 is_add = 1;
13644   int ret;
13645
13646   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13647     {
13648       if (unformat (i, "del"))
13649         is_add = 0;
13650       else if (unformat (i, "spd_id %d", &spd_id))
13651         ;
13652       else
13653         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13654         sw_if_index_set = 1;
13655       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13656         sw_if_index_set = 1;
13657       else
13658         {
13659           clib_warning ("parse error '%U'", format_unformat_error, i);
13660           return -99;
13661         }
13662
13663     }
13664
13665   if (spd_id == (u32) ~ 0)
13666     {
13667       errmsg ("spd_id must be set");
13668       return -99;
13669     }
13670
13671   if (sw_if_index_set == 0)
13672     {
13673       errmsg ("missing interface name or sw_if_index");
13674       return -99;
13675     }
13676
13677   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13678
13679   mp->spd_id = ntohl (spd_id);
13680   mp->sw_if_index = ntohl (sw_if_index);
13681   mp->is_add = is_add;
13682
13683   S (mp);
13684   W (ret);
13685   return ret;
13686 }
13687
13688 static int
13689 api_ipsec_spd_add_del_entry (vat_main_t * vam)
13690 {
13691   unformat_input_t *i = vam->input;
13692   vl_api_ipsec_spd_add_del_entry_t *mp;
13693   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
13694   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13695   i32 priority = 0;
13696   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13697   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13698   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
13699   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
13700   int ret;
13701
13702   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
13703   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
13704   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
13705   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
13706   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
13707   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
13708
13709   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13710     {
13711       if (unformat (i, "del"))
13712         is_add = 0;
13713       if (unformat (i, "outbound"))
13714         is_outbound = 1;
13715       if (unformat (i, "inbound"))
13716         is_outbound = 0;
13717       else if (unformat (i, "spd_id %d", &spd_id))
13718         ;
13719       else if (unformat (i, "sa_id %d", &sa_id))
13720         ;
13721       else if (unformat (i, "priority %d", &priority))
13722         ;
13723       else if (unformat (i, "protocol %d", &protocol))
13724         ;
13725       else if (unformat (i, "lport_start %d", &lport_start))
13726         ;
13727       else if (unformat (i, "lport_stop %d", &lport_stop))
13728         ;
13729       else if (unformat (i, "rport_start %d", &rport_start))
13730         ;
13731       else if (unformat (i, "rport_stop %d", &rport_stop))
13732         ;
13733       else
13734         if (unformat
13735             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
13736         {
13737           is_ipv6 = 0;
13738           is_ip_any = 0;
13739         }
13740       else
13741         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
13742         {
13743           is_ipv6 = 0;
13744           is_ip_any = 0;
13745         }
13746       else
13747         if (unformat
13748             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
13749         {
13750           is_ipv6 = 0;
13751           is_ip_any = 0;
13752         }
13753       else
13754         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
13755         {
13756           is_ipv6 = 0;
13757           is_ip_any = 0;
13758         }
13759       else
13760         if (unformat
13761             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
13762         {
13763           is_ipv6 = 1;
13764           is_ip_any = 0;
13765         }
13766       else
13767         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
13768         {
13769           is_ipv6 = 1;
13770           is_ip_any = 0;
13771         }
13772       else
13773         if (unformat
13774             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
13775         {
13776           is_ipv6 = 1;
13777           is_ip_any = 0;
13778         }
13779       else
13780         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
13781         {
13782           is_ipv6 = 1;
13783           is_ip_any = 0;
13784         }
13785       else
13786         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13787         {
13788           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13789             {
13790               clib_warning ("unsupported action: 'resolve'");
13791               return -99;
13792             }
13793         }
13794       else
13795         {
13796           clib_warning ("parse error '%U'", format_unformat_error, i);
13797           return -99;
13798         }
13799
13800     }
13801
13802   M (IPSEC_SPD_ADD_DEL_ENTRY, mp);
13803
13804   mp->spd_id = ntohl (spd_id);
13805   mp->priority = ntohl (priority);
13806   mp->is_outbound = is_outbound;
13807
13808   mp->is_ipv6 = is_ipv6;
13809   if (is_ipv6 || is_ip_any)
13810     {
13811       clib_memcpy (mp->remote_address_start, &raddr6_start,
13812                    sizeof (ip6_address_t));
13813       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
13814                    sizeof (ip6_address_t));
13815       clib_memcpy (mp->local_address_start, &laddr6_start,
13816                    sizeof (ip6_address_t));
13817       clib_memcpy (mp->local_address_stop, &laddr6_stop,
13818                    sizeof (ip6_address_t));
13819     }
13820   else
13821     {
13822       clib_memcpy (mp->remote_address_start, &raddr4_start,
13823                    sizeof (ip4_address_t));
13824       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
13825                    sizeof (ip4_address_t));
13826       clib_memcpy (mp->local_address_start, &laddr4_start,
13827                    sizeof (ip4_address_t));
13828       clib_memcpy (mp->local_address_stop, &laddr4_stop,
13829                    sizeof (ip4_address_t));
13830     }
13831   mp->protocol = (u8) protocol;
13832   mp->local_port_start = ntohs ((u16) lport_start);
13833   mp->local_port_stop = ntohs ((u16) lport_stop);
13834   mp->remote_port_start = ntohs ((u16) rport_start);
13835   mp->remote_port_stop = ntohs ((u16) rport_stop);
13836   mp->policy = (u8) policy;
13837   mp->sa_id = ntohl (sa_id);
13838   mp->is_add = is_add;
13839   mp->is_ip_any = is_ip_any;
13840   S (mp);
13841   W (ret);
13842   return ret;
13843 }
13844
13845 static int
13846 api_ipsec_sad_add_del_entry (vat_main_t * vam)
13847 {
13848   unformat_input_t *i = vam->input;
13849   vl_api_ipsec_sad_add_del_entry_t *mp;
13850   u32 sad_id = 0, spi = 0;
13851   u8 *ck = 0, *ik = 0;
13852   u8 is_add = 1;
13853
13854   u8 protocol = IPSEC_PROTOCOL_AH;
13855   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
13856   u32 crypto_alg = 0, integ_alg = 0;
13857   ip4_address_t tun_src4;
13858   ip4_address_t tun_dst4;
13859   ip6_address_t tun_src6;
13860   ip6_address_t tun_dst6;
13861   int ret;
13862
13863   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13864     {
13865       if (unformat (i, "del"))
13866         is_add = 0;
13867       else if (unformat (i, "sad_id %d", &sad_id))
13868         ;
13869       else if (unformat (i, "spi %d", &spi))
13870         ;
13871       else if (unformat (i, "esp"))
13872         protocol = IPSEC_PROTOCOL_ESP;
13873       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
13874         {
13875           is_tunnel = 1;
13876           is_tunnel_ipv6 = 0;
13877         }
13878       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
13879         {
13880           is_tunnel = 1;
13881           is_tunnel_ipv6 = 0;
13882         }
13883       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
13884         {
13885           is_tunnel = 1;
13886           is_tunnel_ipv6 = 1;
13887         }
13888       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
13889         {
13890           is_tunnel = 1;
13891           is_tunnel_ipv6 = 1;
13892         }
13893       else
13894         if (unformat
13895             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
13896         {
13897           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
13898               crypto_alg >= IPSEC_CRYPTO_N_ALG)
13899             {
13900               clib_warning ("unsupported crypto-alg: '%U'",
13901                             format_ipsec_crypto_alg, crypto_alg);
13902               return -99;
13903             }
13904         }
13905       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13906         ;
13907       else
13908         if (unformat
13909             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
13910         {
13911           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
13912               integ_alg >= IPSEC_INTEG_N_ALG)
13913             {
13914               clib_warning ("unsupported integ-alg: '%U'",
13915                             format_ipsec_integ_alg, integ_alg);
13916               return -99;
13917             }
13918         }
13919       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13920         ;
13921       else
13922         {
13923           clib_warning ("parse error '%U'", format_unformat_error, i);
13924           return -99;
13925         }
13926
13927     }
13928
13929   M (IPSEC_SAD_ADD_DEL_ENTRY, mp);
13930
13931   mp->sad_id = ntohl (sad_id);
13932   mp->is_add = is_add;
13933   mp->protocol = protocol;
13934   mp->spi = ntohl (spi);
13935   mp->is_tunnel = is_tunnel;
13936   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
13937   mp->crypto_algorithm = crypto_alg;
13938   mp->integrity_algorithm = integ_alg;
13939   mp->crypto_key_length = vec_len (ck);
13940   mp->integrity_key_length = vec_len (ik);
13941
13942   if (mp->crypto_key_length > sizeof (mp->crypto_key))
13943     mp->crypto_key_length = sizeof (mp->crypto_key);
13944
13945   if (mp->integrity_key_length > sizeof (mp->integrity_key))
13946     mp->integrity_key_length = sizeof (mp->integrity_key);
13947
13948   if (ck)
13949     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
13950   if (ik)
13951     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
13952
13953   if (is_tunnel)
13954     {
13955       if (is_tunnel_ipv6)
13956         {
13957           clib_memcpy (mp->tunnel_src_address, &tun_src6,
13958                        sizeof (ip6_address_t));
13959           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
13960                        sizeof (ip6_address_t));
13961         }
13962       else
13963         {
13964           clib_memcpy (mp->tunnel_src_address, &tun_src4,
13965                        sizeof (ip4_address_t));
13966           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
13967                        sizeof (ip4_address_t));
13968         }
13969     }
13970
13971   S (mp);
13972   W (ret);
13973   return ret;
13974 }
13975
13976 static int
13977 api_ipsec_sa_set_key (vat_main_t * vam)
13978 {
13979   unformat_input_t *i = vam->input;
13980   vl_api_ipsec_sa_set_key_t *mp;
13981   u32 sa_id;
13982   u8 *ck = 0, *ik = 0;
13983   int ret;
13984
13985   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13986     {
13987       if (unformat (i, "sa_id %d", &sa_id))
13988         ;
13989       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13990         ;
13991       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13992         ;
13993       else
13994         {
13995           clib_warning ("parse error '%U'", format_unformat_error, i);
13996           return -99;
13997         }
13998     }
13999
14000   M (IPSEC_SA_SET_KEY, mp);
14001
14002   mp->sa_id = ntohl (sa_id);
14003   mp->crypto_key_length = vec_len (ck);
14004   mp->integrity_key_length = vec_len (ik);
14005
14006   if (mp->crypto_key_length > sizeof (mp->crypto_key))
14007     mp->crypto_key_length = sizeof (mp->crypto_key);
14008
14009   if (mp->integrity_key_length > sizeof (mp->integrity_key))
14010     mp->integrity_key_length = sizeof (mp->integrity_key);
14011
14012   if (ck)
14013     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
14014   if (ik)
14015     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
14016
14017   S (mp);
14018   W (ret);
14019   return ret;
14020 }
14021
14022 static int
14023 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14024 {
14025   unformat_input_t *i = vam->input;
14026   vl_api_ipsec_tunnel_if_add_del_t *mp;
14027   u32 local_spi = 0, remote_spi = 0;
14028   u32 crypto_alg = 0, integ_alg = 0;
14029   u8 *lck = NULL, *rck = NULL;
14030   u8 *lik = NULL, *rik = NULL;
14031   ip4_address_t local_ip = { {0} };
14032   ip4_address_t remote_ip = { {0} };
14033   u8 is_add = 1;
14034   u8 esn = 0;
14035   u8 anti_replay = 0;
14036   int ret;
14037
14038   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14039     {
14040       if (unformat (i, "del"))
14041         is_add = 0;
14042       else if (unformat (i, "esn"))
14043         esn = 1;
14044       else if (unformat (i, "anti_replay"))
14045         anti_replay = 1;
14046       else if (unformat (i, "local_spi %d", &local_spi))
14047         ;
14048       else if (unformat (i, "remote_spi %d", &remote_spi))
14049         ;
14050       else if (unformat (i, "local_ip %U", unformat_ip4_address, &local_ip))
14051         ;
14052       else if (unformat (i, "remote_ip %U", unformat_ip4_address, &remote_ip))
14053         ;
14054       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14055         ;
14056       else
14057         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14058         ;
14059       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14060         ;
14061       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14062         ;
14063       else
14064         if (unformat
14065             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
14066         {
14067           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
14068               crypto_alg >= IPSEC_CRYPTO_N_ALG)
14069             {
14070               errmsg ("unsupported crypto-alg: '%U'\n",
14071                       format_ipsec_crypto_alg, crypto_alg);
14072               return -99;
14073             }
14074         }
14075       else
14076         if (unformat
14077             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
14078         {
14079           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
14080               integ_alg >= IPSEC_INTEG_N_ALG)
14081             {
14082               errmsg ("unsupported integ-alg: '%U'\n",
14083                       format_ipsec_integ_alg, integ_alg);
14084               return -99;
14085             }
14086         }
14087       else
14088         {
14089           errmsg ("parse error '%U'\n", format_unformat_error, i);
14090           return -99;
14091         }
14092     }
14093
14094   M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14095
14096   mp->is_add = is_add;
14097   mp->esn = esn;
14098   mp->anti_replay = anti_replay;
14099
14100   clib_memcpy (mp->local_ip, &local_ip, sizeof (ip4_address_t));
14101   clib_memcpy (mp->remote_ip, &remote_ip, sizeof (ip4_address_t));
14102
14103   mp->local_spi = htonl (local_spi);
14104   mp->remote_spi = htonl (remote_spi);
14105   mp->crypto_alg = (u8) crypto_alg;
14106
14107   mp->local_crypto_key_len = 0;
14108   if (lck)
14109     {
14110       mp->local_crypto_key_len = vec_len (lck);
14111       if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14112         mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14113       clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14114     }
14115
14116   mp->remote_crypto_key_len = 0;
14117   if (rck)
14118     {
14119       mp->remote_crypto_key_len = vec_len (rck);
14120       if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14121         mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14122       clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14123     }
14124
14125   mp->integ_alg = (u8) integ_alg;
14126
14127   mp->local_integ_key_len = 0;
14128   if (lik)
14129     {
14130       mp->local_integ_key_len = vec_len (lik);
14131       if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14132         mp->local_integ_key_len = sizeof (mp->local_integ_key);
14133       clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14134     }
14135
14136   mp->remote_integ_key_len = 0;
14137   if (rik)
14138     {
14139       mp->remote_integ_key_len = vec_len (rik);
14140       if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14141         mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14142       clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14143     }
14144
14145   S (mp);
14146   W (ret);
14147   return ret;
14148 }
14149
14150 static void
14151 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14152 {
14153   vat_main_t *vam = &vat_main;
14154
14155   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14156          "crypto_key %U integ_alg %u integ_key %U use_esn %u "
14157          "use_anti_replay %u is_tunnel %u is_tunnel_ip6 %u "
14158          "tunnel_src_addr %U tunnel_dst_addr %U "
14159          "salt %u seq_outbound %lu last_seq_inbound %lu "
14160          "replay_window %lu total_data_size %lu\n",
14161          ntohl (mp->sa_id), ntohl (mp->sw_if_index), ntohl (mp->spi),
14162          mp->protocol,
14163          mp->crypto_alg, format_hex_bytes, mp->crypto_key, mp->crypto_key_len,
14164          mp->integ_alg, format_hex_bytes, mp->integ_key, mp->integ_key_len,
14165          mp->use_esn, mp->use_anti_replay, mp->is_tunnel, mp->is_tunnel_ip6,
14166          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14167          mp->tunnel_src_addr,
14168          (mp->is_tunnel_ip6) ? format_ip6_address : format_ip4_address,
14169          mp->tunnel_dst_addr,
14170          ntohl (mp->salt),
14171          clib_net_to_host_u64 (mp->seq_outbound),
14172          clib_net_to_host_u64 (mp->last_seq_inbound),
14173          clib_net_to_host_u64 (mp->replay_window),
14174          clib_net_to_host_u64 (mp->total_data_size));
14175 }
14176
14177 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14178 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14179
14180 static void vl_api_ipsec_sa_details_t_handler_json
14181   (vl_api_ipsec_sa_details_t * mp)
14182 {
14183   vat_main_t *vam = &vat_main;
14184   vat_json_node_t *node = NULL;
14185   struct in_addr src_ip4, dst_ip4;
14186   struct in6_addr src_ip6, dst_ip6;
14187
14188   if (VAT_JSON_ARRAY != vam->json_tree.type)
14189     {
14190       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14191       vat_json_init_array (&vam->json_tree);
14192     }
14193   node = vat_json_array_add (&vam->json_tree);
14194
14195   vat_json_init_object (node);
14196   vat_json_object_add_uint (node, "sa_id", ntohl (mp->sa_id));
14197   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14198   vat_json_object_add_uint (node, "spi", ntohl (mp->spi));
14199   vat_json_object_add_uint (node, "proto", mp->protocol);
14200   vat_json_object_add_uint (node, "crypto_alg", mp->crypto_alg);
14201   vat_json_object_add_uint (node, "integ_alg", mp->integ_alg);
14202   vat_json_object_add_uint (node, "use_esn", mp->use_esn);
14203   vat_json_object_add_uint (node, "use_anti_replay", mp->use_anti_replay);
14204   vat_json_object_add_uint (node, "is_tunnel", mp->is_tunnel);
14205   vat_json_object_add_uint (node, "is_tunnel_ip6", mp->is_tunnel_ip6);
14206   vat_json_object_add_bytes (node, "crypto_key", mp->crypto_key,
14207                              mp->crypto_key_len);
14208   vat_json_object_add_bytes (node, "integ_key", mp->integ_key,
14209                              mp->integ_key_len);
14210   if (mp->is_tunnel_ip6)
14211     {
14212       clib_memcpy (&src_ip6, mp->tunnel_src_addr, sizeof (src_ip6));
14213       vat_json_object_add_ip6 (node, "tunnel_src_addr", src_ip6);
14214       clib_memcpy (&dst_ip6, mp->tunnel_dst_addr, sizeof (dst_ip6));
14215       vat_json_object_add_ip6 (node, "tunnel_dst_addr", dst_ip6);
14216     }
14217   else
14218     {
14219       clib_memcpy (&src_ip4, mp->tunnel_src_addr, sizeof (src_ip4));
14220       vat_json_object_add_ip4 (node, "tunnel_src_addr", src_ip4);
14221       clib_memcpy (&dst_ip4, mp->tunnel_dst_addr, sizeof (dst_ip4));
14222       vat_json_object_add_ip4 (node, "tunnel_dst_addr", dst_ip4);
14223     }
14224   vat_json_object_add_uint (node, "replay_window",
14225                             clib_net_to_host_u64 (mp->replay_window));
14226   vat_json_object_add_uint (node, "total_data_size",
14227                             clib_net_to_host_u64 (mp->total_data_size));
14228
14229 }
14230
14231 static int
14232 api_ipsec_sa_dump (vat_main_t * vam)
14233 {
14234   unformat_input_t *i = vam->input;
14235   vl_api_ipsec_sa_dump_t *mp;
14236   vl_api_control_ping_t *mp_ping;
14237   u32 sa_id = ~0;
14238   int ret;
14239
14240   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14241     {
14242       if (unformat (i, "sa_id %d", &sa_id))
14243         ;
14244       else
14245         {
14246           clib_warning ("parse error '%U'", format_unformat_error, i);
14247           return -99;
14248         }
14249     }
14250
14251   M (IPSEC_SA_DUMP, mp);
14252
14253   mp->sa_id = ntohl (sa_id);
14254
14255   S (mp);
14256
14257   /* Use a control ping for synchronization */
14258   M (CONTROL_PING, mp_ping);
14259   S (mp_ping);
14260
14261   W (ret);
14262   return ret;
14263 }
14264
14265 static int
14266 api_ikev2_profile_add_del (vat_main_t * vam)
14267 {
14268   unformat_input_t *i = vam->input;
14269   vl_api_ikev2_profile_add_del_t *mp;
14270   u8 is_add = 1;
14271   u8 *name = 0;
14272   int ret;
14273
14274   const char *valid_chars = "a-zA-Z0-9_";
14275
14276   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14277     {
14278       if (unformat (i, "del"))
14279         is_add = 0;
14280       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14281         vec_add1 (name, 0);
14282       else
14283         {
14284           errmsg ("parse error '%U'", format_unformat_error, i);
14285           return -99;
14286         }
14287     }
14288
14289   if (!vec_len (name))
14290     {
14291       errmsg ("profile name must be specified");
14292       return -99;
14293     }
14294
14295   if (vec_len (name) > 64)
14296     {
14297       errmsg ("profile name too long");
14298       return -99;
14299     }
14300
14301   M (IKEV2_PROFILE_ADD_DEL, mp);
14302
14303   clib_memcpy (mp->name, name, vec_len (name));
14304   mp->is_add = is_add;
14305   vec_free (name);
14306
14307   S (mp);
14308   W (ret);
14309   return ret;
14310 }
14311
14312 static int
14313 api_ikev2_profile_set_auth (vat_main_t * vam)
14314 {
14315   unformat_input_t *i = vam->input;
14316   vl_api_ikev2_profile_set_auth_t *mp;
14317   u8 *name = 0;
14318   u8 *data = 0;
14319   u32 auth_method = 0;
14320   u8 is_hex = 0;
14321   int ret;
14322
14323   const char *valid_chars = "a-zA-Z0-9_";
14324
14325   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14326     {
14327       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14328         vec_add1 (name, 0);
14329       else if (unformat (i, "auth_method %U",
14330                          unformat_ikev2_auth_method, &auth_method))
14331         ;
14332       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
14333         is_hex = 1;
14334       else if (unformat (i, "auth_data %v", &data))
14335         ;
14336       else
14337         {
14338           errmsg ("parse error '%U'", format_unformat_error, i);
14339           return -99;
14340         }
14341     }
14342
14343   if (!vec_len (name))
14344     {
14345       errmsg ("profile name must be specified");
14346       return -99;
14347     }
14348
14349   if (vec_len (name) > 64)
14350     {
14351       errmsg ("profile name too long");
14352       return -99;
14353     }
14354
14355   if (!vec_len (data))
14356     {
14357       errmsg ("auth_data must be specified");
14358       return -99;
14359     }
14360
14361   if (!auth_method)
14362     {
14363       errmsg ("auth_method must be specified");
14364       return -99;
14365     }
14366
14367   M (IKEV2_PROFILE_SET_AUTH, mp);
14368
14369   mp->is_hex = is_hex;
14370   mp->auth_method = (u8) auth_method;
14371   mp->data_len = vec_len (data);
14372   clib_memcpy (mp->name, name, vec_len (name));
14373   clib_memcpy (mp->data, data, vec_len (data));
14374   vec_free (name);
14375   vec_free (data);
14376
14377   S (mp);
14378   W (ret);
14379   return ret;
14380 }
14381
14382 static int
14383 api_ikev2_profile_set_id (vat_main_t * vam)
14384 {
14385   unformat_input_t *i = vam->input;
14386   vl_api_ikev2_profile_set_id_t *mp;
14387   u8 *name = 0;
14388   u8 *data = 0;
14389   u8 is_local = 0;
14390   u32 id_type = 0;
14391   ip4_address_t ip4;
14392   int ret;
14393
14394   const char *valid_chars = "a-zA-Z0-9_";
14395
14396   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14397     {
14398       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14399         vec_add1 (name, 0);
14400       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
14401         ;
14402       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
14403         {
14404           data = vec_new (u8, 4);
14405           clib_memcpy (data, ip4.as_u8, 4);
14406         }
14407       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
14408         ;
14409       else if (unformat (i, "id_data %v", &data))
14410         ;
14411       else if (unformat (i, "local"))
14412         is_local = 1;
14413       else if (unformat (i, "remote"))
14414         is_local = 0;
14415       else
14416         {
14417           errmsg ("parse error '%U'", format_unformat_error, i);
14418           return -99;
14419         }
14420     }
14421
14422   if (!vec_len (name))
14423     {
14424       errmsg ("profile name must be specified");
14425       return -99;
14426     }
14427
14428   if (vec_len (name) > 64)
14429     {
14430       errmsg ("profile name too long");
14431       return -99;
14432     }
14433
14434   if (!vec_len (data))
14435     {
14436       errmsg ("id_data must be specified");
14437       return -99;
14438     }
14439
14440   if (!id_type)
14441     {
14442       errmsg ("id_type must be specified");
14443       return -99;
14444     }
14445
14446   M (IKEV2_PROFILE_SET_ID, mp);
14447
14448   mp->is_local = is_local;
14449   mp->id_type = (u8) id_type;
14450   mp->data_len = vec_len (data);
14451   clib_memcpy (mp->name, name, vec_len (name));
14452   clib_memcpy (mp->data, data, vec_len (data));
14453   vec_free (name);
14454   vec_free (data);
14455
14456   S (mp);
14457   W (ret);
14458   return ret;
14459 }
14460
14461 static int
14462 api_ikev2_profile_set_ts (vat_main_t * vam)
14463 {
14464   unformat_input_t *i = vam->input;
14465   vl_api_ikev2_profile_set_ts_t *mp;
14466   u8 *name = 0;
14467   u8 is_local = 0;
14468   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
14469   ip4_address_t start_addr, end_addr;
14470
14471   const char *valid_chars = "a-zA-Z0-9_";
14472   int ret;
14473
14474   start_addr.as_u32 = 0;
14475   end_addr.as_u32 = (u32) ~ 0;
14476
14477   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14478     {
14479       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
14480         vec_add1 (name, 0);
14481       else if (unformat (i, "protocol %d", &proto))
14482         ;
14483       else if (unformat (i, "start_port %d", &start_port))
14484         ;
14485       else if (unformat (i, "end_port %d", &end_port))
14486         ;
14487       else
14488         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
14489         ;
14490       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
14491         ;
14492       else if (unformat (i, "local"))
14493         is_local = 1;
14494       else if (unformat (i, "remote"))
14495         is_local = 0;
14496       else
14497         {
14498           errmsg ("parse error '%U'", format_unformat_error, i);
14499           return -99;
14500         }
14501     }
14502
14503   if (!vec_len (name))
14504     {
14505       errmsg ("profile name must be specified");
14506       return -99;
14507     }
14508
14509   if (vec_len (name) > 64)
14510     {
14511       errmsg ("profile name too long");
14512       return -99;
14513     }
14514
14515   M (IKEV2_PROFILE_SET_TS, mp);
14516
14517   mp->is_local = is_local;
14518   mp->proto = (u8) proto;
14519   mp->start_port = (u16) start_port;
14520   mp->end_port = (u16) end_port;
14521   mp->start_addr = start_addr.as_u32;
14522   mp->end_addr = end_addr.as_u32;
14523   clib_memcpy (mp->name, name, vec_len (name));
14524   vec_free (name);
14525
14526   S (mp);
14527   W (ret);
14528   return ret;
14529 }
14530
14531 static int
14532 api_ikev2_set_local_key (vat_main_t * vam)
14533 {
14534   unformat_input_t *i = vam->input;
14535   vl_api_ikev2_set_local_key_t *mp;
14536   u8 *file = 0;
14537   int ret;
14538
14539   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14540     {
14541       if (unformat (i, "file %v", &file))
14542         vec_add1 (file, 0);
14543       else
14544         {
14545           errmsg ("parse error '%U'", format_unformat_error, i);
14546           return -99;
14547         }
14548     }
14549
14550   if (!vec_len (file))
14551     {
14552       errmsg ("RSA key file must be specified");
14553       return -99;
14554     }
14555
14556   if (vec_len (file) > 256)
14557     {
14558       errmsg ("file name too long");
14559       return -99;
14560     }
14561
14562   M (IKEV2_SET_LOCAL_KEY, mp);
14563
14564   clib_memcpy (mp->key_file, file, vec_len (file));
14565   vec_free (file);
14566
14567   S (mp);
14568   W (ret);
14569   return ret;
14570 }
14571
14572 static int
14573 api_ikev2_set_responder (vat_main_t * vam)
14574 {
14575   unformat_input_t *i = vam->input;
14576   vl_api_ikev2_set_responder_t *mp;
14577   int ret;
14578   u8 *name = 0;
14579   u32 sw_if_index = ~0;
14580   ip4_address_t address;
14581
14582   const char *valid_chars = "a-zA-Z0-9_";
14583
14584   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14585     {
14586       if (unformat
14587           (i, "%U interface %d address %U", unformat_token, valid_chars,
14588            &name, &sw_if_index, unformat_ip4_address, &address))
14589         vec_add1 (name, 0);
14590       else
14591         {
14592           errmsg ("parse error '%U'", format_unformat_error, i);
14593           return -99;
14594         }
14595     }
14596
14597   if (!vec_len (name))
14598     {
14599       errmsg ("profile name must be specified");
14600       return -99;
14601     }
14602
14603   if (vec_len (name) > 64)
14604     {
14605       errmsg ("profile name too long");
14606       return -99;
14607     }
14608
14609   M (IKEV2_SET_RESPONDER, mp);
14610
14611   clib_memcpy (mp->name, name, vec_len (name));
14612   vec_free (name);
14613
14614   mp->sw_if_index = sw_if_index;
14615   clib_memcpy (mp->address, &address, sizeof (address));
14616
14617   S (mp);
14618   W (ret);
14619   return ret;
14620 }
14621
14622 static int
14623 api_ikev2_set_ike_transforms (vat_main_t * vam)
14624 {
14625   unformat_input_t *i = vam->input;
14626   vl_api_ikev2_set_ike_transforms_t *mp;
14627   int ret;
14628   u8 *name = 0;
14629   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
14630
14631   const char *valid_chars = "a-zA-Z0-9_";
14632
14633   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14634     {
14635       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
14636                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
14637         vec_add1 (name, 0);
14638       else
14639         {
14640           errmsg ("parse error '%U'", format_unformat_error, i);
14641           return -99;
14642         }
14643     }
14644
14645   if (!vec_len (name))
14646     {
14647       errmsg ("profile name must be specified");
14648       return -99;
14649     }
14650
14651   if (vec_len (name) > 64)
14652     {
14653       errmsg ("profile name too long");
14654       return -99;
14655     }
14656
14657   M (IKEV2_SET_IKE_TRANSFORMS, mp);
14658
14659   clib_memcpy (mp->name, name, vec_len (name));
14660   vec_free (name);
14661   mp->crypto_alg = crypto_alg;
14662   mp->crypto_key_size = crypto_key_size;
14663   mp->integ_alg = integ_alg;
14664   mp->dh_group = dh_group;
14665
14666   S (mp);
14667   W (ret);
14668   return ret;
14669 }
14670
14671
14672 static int
14673 api_ikev2_set_esp_transforms (vat_main_t * vam)
14674 {
14675   unformat_input_t *i = vam->input;
14676   vl_api_ikev2_set_esp_transforms_t *mp;
14677   int ret;
14678   u8 *name = 0;
14679   u32 crypto_alg, crypto_key_size, integ_alg, dh_group;
14680
14681   const char *valid_chars = "a-zA-Z0-9_";
14682
14683   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14684     {
14685       if (unformat (i, "%U %d %d %d %d", unformat_token, valid_chars, &name,
14686                     &crypto_alg, &crypto_key_size, &integ_alg, &dh_group))
14687         vec_add1 (name, 0);
14688       else
14689         {
14690           errmsg ("parse error '%U'", format_unformat_error, i);
14691           return -99;
14692         }
14693     }
14694
14695   if (!vec_len (name))
14696     {
14697       errmsg ("profile name must be specified");
14698       return -99;
14699     }
14700
14701   if (vec_len (name) > 64)
14702     {
14703       errmsg ("profile name too long");
14704       return -99;
14705     }
14706
14707   M (IKEV2_SET_ESP_TRANSFORMS, mp);
14708
14709   clib_memcpy (mp->name, name, vec_len (name));
14710   vec_free (name);
14711   mp->crypto_alg = crypto_alg;
14712   mp->crypto_key_size = crypto_key_size;
14713   mp->integ_alg = integ_alg;
14714   mp->dh_group = dh_group;
14715
14716   S (mp);
14717   W (ret);
14718   return ret;
14719 }
14720
14721 static int
14722 api_ikev2_set_sa_lifetime (vat_main_t * vam)
14723 {
14724   unformat_input_t *i = vam->input;
14725   vl_api_ikev2_set_sa_lifetime_t *mp;
14726   int ret;
14727   u8 *name = 0;
14728   u64 lifetime, lifetime_maxdata;
14729   u32 lifetime_jitter, handover;
14730
14731   const char *valid_chars = "a-zA-Z0-9_";
14732
14733   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14734     {
14735       if (unformat (i, "%U %lu %u %u %lu", unformat_token, valid_chars, &name,
14736                     &lifetime, &lifetime_jitter, &handover,
14737                     &lifetime_maxdata))
14738         vec_add1 (name, 0);
14739       else
14740         {
14741           errmsg ("parse error '%U'", format_unformat_error, i);
14742           return -99;
14743         }
14744     }
14745
14746   if (!vec_len (name))
14747     {
14748       errmsg ("profile name must be specified");
14749       return -99;
14750     }
14751
14752   if (vec_len (name) > 64)
14753     {
14754       errmsg ("profile name too long");
14755       return -99;
14756     }
14757
14758   M (IKEV2_SET_SA_LIFETIME, mp);
14759
14760   clib_memcpy (mp->name, name, vec_len (name));
14761   vec_free (name);
14762   mp->lifetime = lifetime;
14763   mp->lifetime_jitter = lifetime_jitter;
14764   mp->handover = handover;
14765   mp->lifetime_maxdata = lifetime_maxdata;
14766
14767   S (mp);
14768   W (ret);
14769   return ret;
14770 }
14771
14772 static int
14773 api_ikev2_initiate_sa_init (vat_main_t * vam)
14774 {
14775   unformat_input_t *i = vam->input;
14776   vl_api_ikev2_initiate_sa_init_t *mp;
14777   int ret;
14778   u8 *name = 0;
14779
14780   const char *valid_chars = "a-zA-Z0-9_";
14781
14782   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14783     {
14784       if (unformat (i, "%U", unformat_token, valid_chars, &name))
14785         vec_add1 (name, 0);
14786       else
14787         {
14788           errmsg ("parse error '%U'", format_unformat_error, i);
14789           return -99;
14790         }
14791     }
14792
14793   if (!vec_len (name))
14794     {
14795       errmsg ("profile name must be specified");
14796       return -99;
14797     }
14798
14799   if (vec_len (name) > 64)
14800     {
14801       errmsg ("profile name too long");
14802       return -99;
14803     }
14804
14805   M (IKEV2_INITIATE_SA_INIT, mp);
14806
14807   clib_memcpy (mp->name, name, vec_len (name));
14808   vec_free (name);
14809
14810   S (mp);
14811   W (ret);
14812   return ret;
14813 }
14814
14815 static int
14816 api_ikev2_initiate_del_ike_sa (vat_main_t * vam)
14817 {
14818   unformat_input_t *i = vam->input;
14819   vl_api_ikev2_initiate_del_ike_sa_t *mp;
14820   int ret;
14821   u64 ispi;
14822
14823
14824   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14825     {
14826       if (unformat (i, "%lx", &ispi))
14827         ;
14828       else
14829         {
14830           errmsg ("parse error '%U'", format_unformat_error, i);
14831           return -99;
14832         }
14833     }
14834
14835   M (IKEV2_INITIATE_DEL_IKE_SA, mp);
14836
14837   mp->ispi = ispi;
14838
14839   S (mp);
14840   W (ret);
14841   return ret;
14842 }
14843
14844 static int
14845 api_ikev2_initiate_del_child_sa (vat_main_t * vam)
14846 {
14847   unformat_input_t *i = vam->input;
14848   vl_api_ikev2_initiate_del_child_sa_t *mp;
14849   int ret;
14850   u32 ispi;
14851
14852
14853   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14854     {
14855       if (unformat (i, "%x", &ispi))
14856         ;
14857       else
14858         {
14859           errmsg ("parse error '%U'", format_unformat_error, i);
14860           return -99;
14861         }
14862     }
14863
14864   M (IKEV2_INITIATE_DEL_CHILD_SA, mp);
14865
14866   mp->ispi = ispi;
14867
14868   S (mp);
14869   W (ret);
14870   return ret;
14871 }
14872
14873 static int
14874 api_ikev2_initiate_rekey_child_sa (vat_main_t * vam)
14875 {
14876   unformat_input_t *i = vam->input;
14877   vl_api_ikev2_initiate_rekey_child_sa_t *mp;
14878   int ret;
14879   u32 ispi;
14880
14881
14882   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14883     {
14884       if (unformat (i, "%x", &ispi))
14885         ;
14886       else
14887         {
14888           errmsg ("parse error '%U'", format_unformat_error, i);
14889           return -99;
14890         }
14891     }
14892
14893   M (IKEV2_INITIATE_REKEY_CHILD_SA, mp);
14894
14895   mp->ispi = ispi;
14896
14897   S (mp);
14898   W (ret);
14899   return ret;
14900 }
14901
14902 /*
14903  * MAP
14904  */
14905 static int
14906 api_map_add_domain (vat_main_t * vam)
14907 {
14908   unformat_input_t *i = vam->input;
14909   vl_api_map_add_domain_t *mp;
14910
14911   ip4_address_t ip4_prefix;
14912   ip6_address_t ip6_prefix;
14913   ip6_address_t ip6_src;
14914   u32 num_m_args = 0;
14915   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
14916     0, psid_length = 0;
14917   u8 is_translation = 0;
14918   u32 mtu = 0;
14919   u32 ip6_src_len = 128;
14920   int ret;
14921
14922   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14923     {
14924       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
14925                     &ip4_prefix, &ip4_prefix_len))
14926         num_m_args++;
14927       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
14928                          &ip6_prefix, &ip6_prefix_len))
14929         num_m_args++;
14930       else
14931         if (unformat
14932             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
14933              &ip6_src_len))
14934         num_m_args++;
14935       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
14936         num_m_args++;
14937       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
14938         num_m_args++;
14939       else if (unformat (i, "psid-offset %d", &psid_offset))
14940         num_m_args++;
14941       else if (unformat (i, "psid-len %d", &psid_length))
14942         num_m_args++;
14943       else if (unformat (i, "mtu %d", &mtu))
14944         num_m_args++;
14945       else if (unformat (i, "map-t"))
14946         is_translation = 1;
14947       else
14948         {
14949           clib_warning ("parse error '%U'", format_unformat_error, i);
14950           return -99;
14951         }
14952     }
14953
14954   if (num_m_args < 3)
14955     {
14956       errmsg ("mandatory argument(s) missing");
14957       return -99;
14958     }
14959
14960   /* Construct the API message */
14961   M (MAP_ADD_DOMAIN, mp);
14962
14963   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
14964   mp->ip4_prefix_len = ip4_prefix_len;
14965
14966   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
14967   mp->ip6_prefix_len = ip6_prefix_len;
14968
14969   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
14970   mp->ip6_src_prefix_len = ip6_src_len;
14971
14972   mp->ea_bits_len = ea_bits_len;
14973   mp->psid_offset = psid_offset;
14974   mp->psid_length = psid_length;
14975   mp->is_translation = is_translation;
14976   mp->mtu = htons (mtu);
14977
14978   /* send it... */
14979   S (mp);
14980
14981   /* Wait for a reply, return good/bad news  */
14982   W (ret);
14983   return ret;
14984 }
14985
14986 static int
14987 api_map_del_domain (vat_main_t * vam)
14988 {
14989   unformat_input_t *i = vam->input;
14990   vl_api_map_del_domain_t *mp;
14991
14992   u32 num_m_args = 0;
14993   u32 index;
14994   int ret;
14995
14996   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14997     {
14998       if (unformat (i, "index %d", &index))
14999         num_m_args++;
15000       else
15001         {
15002           clib_warning ("parse error '%U'", format_unformat_error, i);
15003           return -99;
15004         }
15005     }
15006
15007   if (num_m_args != 1)
15008     {
15009       errmsg ("mandatory argument(s) missing");
15010       return -99;
15011     }
15012
15013   /* Construct the API message */
15014   M (MAP_DEL_DOMAIN, mp);
15015
15016   mp->index = ntohl (index);
15017
15018   /* send it... */
15019   S (mp);
15020
15021   /* Wait for a reply, return good/bad news  */
15022   W (ret);
15023   return ret;
15024 }
15025
15026 static int
15027 api_map_add_del_rule (vat_main_t * vam)
15028 {
15029   unformat_input_t *i = vam->input;
15030   vl_api_map_add_del_rule_t *mp;
15031   u8 is_add = 1;
15032   ip6_address_t ip6_dst;
15033   u32 num_m_args = 0, index, psid = 0;
15034   int ret;
15035
15036   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15037     {
15038       if (unformat (i, "index %d", &index))
15039         num_m_args++;
15040       else if (unformat (i, "psid %d", &psid))
15041         num_m_args++;
15042       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
15043         num_m_args++;
15044       else if (unformat (i, "del"))
15045         {
15046           is_add = 0;
15047         }
15048       else
15049         {
15050           clib_warning ("parse error '%U'", format_unformat_error, i);
15051           return -99;
15052         }
15053     }
15054
15055   /* Construct the API message */
15056   M (MAP_ADD_DEL_RULE, mp);
15057
15058   mp->index = ntohl (index);
15059   mp->is_add = is_add;
15060   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
15061   mp->psid = ntohs (psid);
15062
15063   /* send it... */
15064   S (mp);
15065
15066   /* Wait for a reply, return good/bad news  */
15067   W (ret);
15068   return ret;
15069 }
15070
15071 static int
15072 api_map_domain_dump (vat_main_t * vam)
15073 {
15074   vl_api_map_domain_dump_t *mp;
15075   vl_api_control_ping_t *mp_ping;
15076   int ret;
15077
15078   /* Construct the API message */
15079   M (MAP_DOMAIN_DUMP, mp);
15080
15081   /* send it... */
15082   S (mp);
15083
15084   /* Use a control ping for synchronization */
15085   MPING (CONTROL_PING, mp_ping);
15086   S (mp_ping);
15087
15088   W (ret);
15089   return ret;
15090 }
15091
15092 static int
15093 api_map_rule_dump (vat_main_t * vam)
15094 {
15095   unformat_input_t *i = vam->input;
15096   vl_api_map_rule_dump_t *mp;
15097   vl_api_control_ping_t *mp_ping;
15098   u32 domain_index = ~0;
15099   int ret;
15100
15101   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15102     {
15103       if (unformat (i, "index %u", &domain_index))
15104         ;
15105       else
15106         break;
15107     }
15108
15109   if (domain_index == ~0)
15110     {
15111       clib_warning ("parse error: domain index expected");
15112       return -99;
15113     }
15114
15115   /* Construct the API message */
15116   M (MAP_RULE_DUMP, mp);
15117
15118   mp->domain_index = htonl (domain_index);
15119
15120   /* send it... */
15121   S (mp);
15122
15123   /* Use a control ping for synchronization */
15124   MPING (CONTROL_PING, mp_ping);
15125   S (mp_ping);
15126
15127   W (ret);
15128   return ret;
15129 }
15130
15131 static void vl_api_map_add_domain_reply_t_handler
15132   (vl_api_map_add_domain_reply_t * mp)
15133 {
15134   vat_main_t *vam = &vat_main;
15135   i32 retval = ntohl (mp->retval);
15136
15137   if (vam->async_mode)
15138     {
15139       vam->async_errors += (retval < 0);
15140     }
15141   else
15142     {
15143       vam->retval = retval;
15144       vam->result_ready = 1;
15145     }
15146 }
15147
15148 static void vl_api_map_add_domain_reply_t_handler_json
15149   (vl_api_map_add_domain_reply_t * mp)
15150 {
15151   vat_main_t *vam = &vat_main;
15152   vat_json_node_t node;
15153
15154   vat_json_init_object (&node);
15155   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
15156   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
15157
15158   vat_json_print (vam->ofp, &node);
15159   vat_json_free (&node);
15160
15161   vam->retval = ntohl (mp->retval);
15162   vam->result_ready = 1;
15163 }
15164
15165 static int
15166 api_get_first_msg_id (vat_main_t * vam)
15167 {
15168   vl_api_get_first_msg_id_t *mp;
15169   unformat_input_t *i = vam->input;
15170   u8 *name;
15171   u8 name_set = 0;
15172   int ret;
15173
15174   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15175     {
15176       if (unformat (i, "client %s", &name))
15177         name_set = 1;
15178       else
15179         break;
15180     }
15181
15182   if (name_set == 0)
15183     {
15184       errmsg ("missing client name");
15185       return -99;
15186     }
15187   vec_add1 (name, 0);
15188
15189   if (vec_len (name) > 63)
15190     {
15191       errmsg ("client name too long");
15192       return -99;
15193     }
15194
15195   M (GET_FIRST_MSG_ID, mp);
15196   clib_memcpy (mp->name, name, vec_len (name));
15197   S (mp);
15198   W (ret);
15199   return ret;
15200 }
15201
15202 static int
15203 api_cop_interface_enable_disable (vat_main_t * vam)
15204 {
15205   unformat_input_t *line_input = vam->input;
15206   vl_api_cop_interface_enable_disable_t *mp;
15207   u32 sw_if_index = ~0;
15208   u8 enable_disable = 1;
15209   int ret;
15210
15211   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15212     {
15213       if (unformat (line_input, "disable"))
15214         enable_disable = 0;
15215       if (unformat (line_input, "enable"))
15216         enable_disable = 1;
15217       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15218                          vam, &sw_if_index))
15219         ;
15220       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15221         ;
15222       else
15223         break;
15224     }
15225
15226   if (sw_if_index == ~0)
15227     {
15228       errmsg ("missing interface name or sw_if_index");
15229       return -99;
15230     }
15231
15232   /* Construct the API message */
15233   M (COP_INTERFACE_ENABLE_DISABLE, mp);
15234   mp->sw_if_index = ntohl (sw_if_index);
15235   mp->enable_disable = enable_disable;
15236
15237   /* send it... */
15238   S (mp);
15239   /* Wait for the reply */
15240   W (ret);
15241   return ret;
15242 }
15243
15244 static int
15245 api_cop_whitelist_enable_disable (vat_main_t * vam)
15246 {
15247   unformat_input_t *line_input = vam->input;
15248   vl_api_cop_whitelist_enable_disable_t *mp;
15249   u32 sw_if_index = ~0;
15250   u8 ip4 = 0, ip6 = 0, default_cop = 0;
15251   u32 fib_id = 0;
15252   int ret;
15253
15254   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15255     {
15256       if (unformat (line_input, "ip4"))
15257         ip4 = 1;
15258       else if (unformat (line_input, "ip6"))
15259         ip6 = 1;
15260       else if (unformat (line_input, "default"))
15261         default_cop = 1;
15262       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
15263                          vam, &sw_if_index))
15264         ;
15265       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
15266         ;
15267       else if (unformat (line_input, "fib-id %d", &fib_id))
15268         ;
15269       else
15270         break;
15271     }
15272
15273   if (sw_if_index == ~0)
15274     {
15275       errmsg ("missing interface name or sw_if_index");
15276       return -99;
15277     }
15278
15279   /* Construct the API message */
15280   M (COP_WHITELIST_ENABLE_DISABLE, mp);
15281   mp->sw_if_index = ntohl (sw_if_index);
15282   mp->fib_id = ntohl (fib_id);
15283   mp->ip4 = ip4;
15284   mp->ip6 = ip6;
15285   mp->default_cop = default_cop;
15286
15287   /* send it... */
15288   S (mp);
15289   /* Wait for the reply */
15290   W (ret);
15291   return ret;
15292 }
15293
15294 static int
15295 api_get_node_graph (vat_main_t * vam)
15296 {
15297   vl_api_get_node_graph_t *mp;
15298   int ret;
15299
15300   M (GET_NODE_GRAPH, mp);
15301
15302   /* send it... */
15303   S (mp);
15304   /* Wait for the reply */
15305   W (ret);
15306   return ret;
15307 }
15308
15309 /* *INDENT-OFF* */
15310 /** Used for parsing LISP eids */
15311 typedef CLIB_PACKED(struct{
15312   u8 addr[16];   /**< eid address */
15313   u32 len;       /**< prefix length if IP */
15314   u8 type;      /**< type of eid */
15315 }) lisp_eid_vat_t;
15316 /* *INDENT-ON* */
15317
15318 static uword
15319 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
15320 {
15321   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
15322
15323   memset (a, 0, sizeof (a[0]));
15324
15325   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
15326     {
15327       a->type = 0;              /* ipv4 type */
15328     }
15329   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
15330     {
15331       a->type = 1;              /* ipv6 type */
15332     }
15333   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
15334     {
15335       a->type = 2;              /* mac type */
15336     }
15337   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
15338     {
15339       a->type = 3;              /* NSH type */
15340       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
15341       nsh->spi = clib_host_to_net_u32 (nsh->spi);
15342     }
15343   else
15344     {
15345       return 0;
15346     }
15347
15348   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
15349     {
15350       return 0;
15351     }
15352
15353   return 1;
15354 }
15355
15356 static int
15357 lisp_eid_size_vat (u8 type)
15358 {
15359   switch (type)
15360     {
15361     case 0:
15362       return 4;
15363     case 1:
15364       return 16;
15365     case 2:
15366       return 6;
15367     case 3:
15368       return 5;
15369     }
15370   return 0;
15371 }
15372
15373 static void
15374 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
15375 {
15376   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
15377 }
15378
15379 static int
15380 api_one_add_del_locator_set (vat_main_t * vam)
15381 {
15382   unformat_input_t *input = vam->input;
15383   vl_api_one_add_del_locator_set_t *mp;
15384   u8 is_add = 1;
15385   u8 *locator_set_name = NULL;
15386   u8 locator_set_name_set = 0;
15387   vl_api_local_locator_t locator, *locators = 0;
15388   u32 sw_if_index, priority, weight;
15389   u32 data_len = 0;
15390
15391   int ret;
15392   /* Parse args required to build the message */
15393   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15394     {
15395       if (unformat (input, "del"))
15396         {
15397           is_add = 0;
15398         }
15399       else if (unformat (input, "locator-set %s", &locator_set_name))
15400         {
15401           locator_set_name_set = 1;
15402         }
15403       else if (unformat (input, "sw_if_index %u p %u w %u",
15404                          &sw_if_index, &priority, &weight))
15405         {
15406           locator.sw_if_index = htonl (sw_if_index);
15407           locator.priority = priority;
15408           locator.weight = weight;
15409           vec_add1 (locators, locator);
15410         }
15411       else
15412         if (unformat
15413             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
15414              &sw_if_index, &priority, &weight))
15415         {
15416           locator.sw_if_index = htonl (sw_if_index);
15417           locator.priority = priority;
15418           locator.weight = weight;
15419           vec_add1 (locators, locator);
15420         }
15421       else
15422         break;
15423     }
15424
15425   if (locator_set_name_set == 0)
15426     {
15427       errmsg ("missing locator-set name");
15428       vec_free (locators);
15429       return -99;
15430     }
15431
15432   if (vec_len (locator_set_name) > 64)
15433     {
15434       errmsg ("locator-set name too long");
15435       vec_free (locator_set_name);
15436       vec_free (locators);
15437       return -99;
15438     }
15439   vec_add1 (locator_set_name, 0);
15440
15441   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
15442
15443   /* Construct the API message */
15444   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
15445
15446   mp->is_add = is_add;
15447   clib_memcpy (mp->locator_set_name, locator_set_name,
15448                vec_len (locator_set_name));
15449   vec_free (locator_set_name);
15450
15451   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
15452   if (locators)
15453     clib_memcpy (mp->locators, locators, data_len);
15454   vec_free (locators);
15455
15456   /* send it... */
15457   S (mp);
15458
15459   /* Wait for a reply... */
15460   W (ret);
15461   return ret;
15462 }
15463
15464 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
15465
15466 static int
15467 api_one_add_del_locator (vat_main_t * vam)
15468 {
15469   unformat_input_t *input = vam->input;
15470   vl_api_one_add_del_locator_t *mp;
15471   u32 tmp_if_index = ~0;
15472   u32 sw_if_index = ~0;
15473   u8 sw_if_index_set = 0;
15474   u8 sw_if_index_if_name_set = 0;
15475   u32 priority = ~0;
15476   u8 priority_set = 0;
15477   u32 weight = ~0;
15478   u8 weight_set = 0;
15479   u8 is_add = 1;
15480   u8 *locator_set_name = NULL;
15481   u8 locator_set_name_set = 0;
15482   int ret;
15483
15484   /* Parse args required to build the message */
15485   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15486     {
15487       if (unformat (input, "del"))
15488         {
15489           is_add = 0;
15490         }
15491       else if (unformat (input, "locator-set %s", &locator_set_name))
15492         {
15493           locator_set_name_set = 1;
15494         }
15495       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15496                          &tmp_if_index))
15497         {
15498           sw_if_index_if_name_set = 1;
15499           sw_if_index = tmp_if_index;
15500         }
15501       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15502         {
15503           sw_if_index_set = 1;
15504           sw_if_index = tmp_if_index;
15505         }
15506       else if (unformat (input, "p %d", &priority))
15507         {
15508           priority_set = 1;
15509         }
15510       else if (unformat (input, "w %d", &weight))
15511         {
15512           weight_set = 1;
15513         }
15514       else
15515         break;
15516     }
15517
15518   if (locator_set_name_set == 0)
15519     {
15520       errmsg ("missing locator-set name");
15521       return -99;
15522     }
15523
15524   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15525     {
15526       errmsg ("missing sw_if_index");
15527       vec_free (locator_set_name);
15528       return -99;
15529     }
15530
15531   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15532     {
15533       errmsg ("cannot use both params interface name and sw_if_index");
15534       vec_free (locator_set_name);
15535       return -99;
15536     }
15537
15538   if (priority_set == 0)
15539     {
15540       errmsg ("missing locator-set priority");
15541       vec_free (locator_set_name);
15542       return -99;
15543     }
15544
15545   if (weight_set == 0)
15546     {
15547       errmsg ("missing locator-set weight");
15548       vec_free (locator_set_name);
15549       return -99;
15550     }
15551
15552   if (vec_len (locator_set_name) > 64)
15553     {
15554       errmsg ("locator-set name too long");
15555       vec_free (locator_set_name);
15556       return -99;
15557     }
15558   vec_add1 (locator_set_name, 0);
15559
15560   /* Construct the API message */
15561   M (ONE_ADD_DEL_LOCATOR, mp);
15562
15563   mp->is_add = is_add;
15564   mp->sw_if_index = ntohl (sw_if_index);
15565   mp->priority = priority;
15566   mp->weight = weight;
15567   clib_memcpy (mp->locator_set_name, locator_set_name,
15568                vec_len (locator_set_name));
15569   vec_free (locator_set_name);
15570
15571   /* send it... */
15572   S (mp);
15573
15574   /* Wait for a reply... */
15575   W (ret);
15576   return ret;
15577 }
15578
15579 #define api_lisp_add_del_locator api_one_add_del_locator
15580
15581 uword
15582 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15583 {
15584   u32 *key_id = va_arg (*args, u32 *);
15585   u8 *s = 0;
15586
15587   if (unformat (input, "%s", &s))
15588     {
15589       if (!strcmp ((char *) s, "sha1"))
15590         key_id[0] = HMAC_SHA_1_96;
15591       else if (!strcmp ((char *) s, "sha256"))
15592         key_id[0] = HMAC_SHA_256_128;
15593       else
15594         {
15595           clib_warning ("invalid key_id: '%s'", s);
15596           key_id[0] = HMAC_NO_KEY;
15597         }
15598     }
15599   else
15600     return 0;
15601
15602   vec_free (s);
15603   return 1;
15604 }
15605
15606 static int
15607 api_one_add_del_local_eid (vat_main_t * vam)
15608 {
15609   unformat_input_t *input = vam->input;
15610   vl_api_one_add_del_local_eid_t *mp;
15611   u8 is_add = 1;
15612   u8 eid_set = 0;
15613   lisp_eid_vat_t _eid, *eid = &_eid;
15614   u8 *locator_set_name = 0;
15615   u8 locator_set_name_set = 0;
15616   u32 vni = 0;
15617   u16 key_id = 0;
15618   u8 *key = 0;
15619   int ret;
15620
15621   /* Parse args required to build the message */
15622   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15623     {
15624       if (unformat (input, "del"))
15625         {
15626           is_add = 0;
15627         }
15628       else if (unformat (input, "vni %d", &vni))
15629         {
15630           ;
15631         }
15632       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15633         {
15634           eid_set = 1;
15635         }
15636       else if (unformat (input, "locator-set %s", &locator_set_name))
15637         {
15638           locator_set_name_set = 1;
15639         }
15640       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15641         ;
15642       else if (unformat (input, "secret-key %_%v%_", &key))
15643         ;
15644       else
15645         break;
15646     }
15647
15648   if (locator_set_name_set == 0)
15649     {
15650       errmsg ("missing locator-set name");
15651       return -99;
15652     }
15653
15654   if (0 == eid_set)
15655     {
15656       errmsg ("EID address not set!");
15657       vec_free (locator_set_name);
15658       return -99;
15659     }
15660
15661   if (key && (0 == key_id))
15662     {
15663       errmsg ("invalid key_id!");
15664       return -99;
15665     }
15666
15667   if (vec_len (key) > 64)
15668     {
15669       errmsg ("key too long");
15670       vec_free (key);
15671       return -99;
15672     }
15673
15674   if (vec_len (locator_set_name) > 64)
15675     {
15676       errmsg ("locator-set name too long");
15677       vec_free (locator_set_name);
15678       return -99;
15679     }
15680   vec_add1 (locator_set_name, 0);
15681
15682   /* Construct the API message */
15683   M (ONE_ADD_DEL_LOCAL_EID, mp);
15684
15685   mp->is_add = is_add;
15686   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15687   mp->eid_type = eid->type;
15688   mp->prefix_len = eid->len;
15689   mp->vni = clib_host_to_net_u32 (vni);
15690   mp->key_id = clib_host_to_net_u16 (key_id);
15691   clib_memcpy (mp->locator_set_name, locator_set_name,
15692                vec_len (locator_set_name));
15693   clib_memcpy (mp->key, key, vec_len (key));
15694
15695   vec_free (locator_set_name);
15696   vec_free (key);
15697
15698   /* send it... */
15699   S (mp);
15700
15701   /* Wait for a reply... */
15702   W (ret);
15703   return ret;
15704 }
15705
15706 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15707
15708 static int
15709 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15710 {
15711   u32 dp_table = 0, vni = 0;;
15712   unformat_input_t *input = vam->input;
15713   vl_api_gpe_add_del_fwd_entry_t *mp;
15714   u8 is_add = 1;
15715   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15716   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15717   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15718   u32 action = ~0, w;
15719   ip4_address_t rmt_rloc4, lcl_rloc4;
15720   ip6_address_t rmt_rloc6, lcl_rloc6;
15721   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15722   int ret;
15723
15724   memset (&rloc, 0, sizeof (rloc));
15725
15726   /* Parse args required to build the message */
15727   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15728     {
15729       if (unformat (input, "del"))
15730         is_add = 0;
15731       else if (unformat (input, "add"))
15732         is_add = 1;
15733       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15734         {
15735           rmt_eid_set = 1;
15736         }
15737       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15738         {
15739           lcl_eid_set = 1;
15740         }
15741       else if (unformat (input, "vrf %d", &dp_table))
15742         ;
15743       else if (unformat (input, "bd %d", &dp_table))
15744         ;
15745       else if (unformat (input, "vni %d", &vni))
15746         ;
15747       else if (unformat (input, "w %d", &w))
15748         {
15749           if (!curr_rloc)
15750             {
15751               errmsg ("No RLOC configured for setting priority/weight!");
15752               return -99;
15753             }
15754           curr_rloc->weight = w;
15755         }
15756       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15757                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15758         {
15759           rloc.is_ip4 = 1;
15760
15761           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15762           rloc.weight = 0;
15763           vec_add1 (lcl_locs, rloc);
15764
15765           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15766           vec_add1 (rmt_locs, rloc);
15767           /* weight saved in rmt loc */
15768           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15769         }
15770       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15771                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15772         {
15773           rloc.is_ip4 = 0;
15774           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15775           rloc.weight = 0;
15776           vec_add1 (lcl_locs, rloc);
15777
15778           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15779           vec_add1 (rmt_locs, rloc);
15780           /* weight saved in rmt loc */
15781           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15782         }
15783       else if (unformat (input, "action %d", &action))
15784         {
15785           ;
15786         }
15787       else
15788         {
15789           clib_warning ("parse error '%U'", format_unformat_error, input);
15790           return -99;
15791         }
15792     }
15793
15794   if (!rmt_eid_set)
15795     {
15796       errmsg ("remote eid addresses not set");
15797       return -99;
15798     }
15799
15800   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15801     {
15802       errmsg ("eid types don't match");
15803       return -99;
15804     }
15805
15806   if (0 == rmt_locs && (u32) ~ 0 == action)
15807     {
15808       errmsg ("action not set for negative mapping");
15809       return -99;
15810     }
15811
15812   /* Construct the API message */
15813   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15814       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15815
15816   mp->is_add = is_add;
15817   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15818   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15819   mp->eid_type = rmt_eid->type;
15820   mp->dp_table = clib_host_to_net_u32 (dp_table);
15821   mp->vni = clib_host_to_net_u32 (vni);
15822   mp->rmt_len = rmt_eid->len;
15823   mp->lcl_len = lcl_eid->len;
15824   mp->action = action;
15825
15826   if (0 != rmt_locs && 0 != lcl_locs)
15827     {
15828       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15829       clib_memcpy (mp->locs, lcl_locs,
15830                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15831
15832       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15833       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15834                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15835     }
15836   vec_free (lcl_locs);
15837   vec_free (rmt_locs);
15838
15839   /* send it... */
15840   S (mp);
15841
15842   /* Wait for a reply... */
15843   W (ret);
15844   return ret;
15845 }
15846
15847 static int
15848 api_one_add_del_map_server (vat_main_t * vam)
15849 {
15850   unformat_input_t *input = vam->input;
15851   vl_api_one_add_del_map_server_t *mp;
15852   u8 is_add = 1;
15853   u8 ipv4_set = 0;
15854   u8 ipv6_set = 0;
15855   ip4_address_t ipv4;
15856   ip6_address_t ipv6;
15857   int ret;
15858
15859   /* Parse args required to build the message */
15860   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15861     {
15862       if (unformat (input, "del"))
15863         {
15864           is_add = 0;
15865         }
15866       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15867         {
15868           ipv4_set = 1;
15869         }
15870       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15871         {
15872           ipv6_set = 1;
15873         }
15874       else
15875         break;
15876     }
15877
15878   if (ipv4_set && ipv6_set)
15879     {
15880       errmsg ("both eid v4 and v6 addresses set");
15881       return -99;
15882     }
15883
15884   if (!ipv4_set && !ipv6_set)
15885     {
15886       errmsg ("eid addresses not set");
15887       return -99;
15888     }
15889
15890   /* Construct the API message */
15891   M (ONE_ADD_DEL_MAP_SERVER, mp);
15892
15893   mp->is_add = is_add;
15894   if (ipv6_set)
15895     {
15896       mp->is_ipv6 = 1;
15897       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15898     }
15899   else
15900     {
15901       mp->is_ipv6 = 0;
15902       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15903     }
15904
15905   /* send it... */
15906   S (mp);
15907
15908   /* Wait for a reply... */
15909   W (ret);
15910   return ret;
15911 }
15912
15913 #define api_lisp_add_del_map_server api_one_add_del_map_server
15914
15915 static int
15916 api_one_add_del_map_resolver (vat_main_t * vam)
15917 {
15918   unformat_input_t *input = vam->input;
15919   vl_api_one_add_del_map_resolver_t *mp;
15920   u8 is_add = 1;
15921   u8 ipv4_set = 0;
15922   u8 ipv6_set = 0;
15923   ip4_address_t ipv4;
15924   ip6_address_t ipv6;
15925   int ret;
15926
15927   /* Parse args required to build the message */
15928   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15929     {
15930       if (unformat (input, "del"))
15931         {
15932           is_add = 0;
15933         }
15934       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15935         {
15936           ipv4_set = 1;
15937         }
15938       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15939         {
15940           ipv6_set = 1;
15941         }
15942       else
15943         break;
15944     }
15945
15946   if (ipv4_set && ipv6_set)
15947     {
15948       errmsg ("both eid v4 and v6 addresses set");
15949       return -99;
15950     }
15951
15952   if (!ipv4_set && !ipv6_set)
15953     {
15954       errmsg ("eid addresses not set");
15955       return -99;
15956     }
15957
15958   /* Construct the API message */
15959   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
15960
15961   mp->is_add = is_add;
15962   if (ipv6_set)
15963     {
15964       mp->is_ipv6 = 1;
15965       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15966     }
15967   else
15968     {
15969       mp->is_ipv6 = 0;
15970       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15971     }
15972
15973   /* send it... */
15974   S (mp);
15975
15976   /* Wait for a reply... */
15977   W (ret);
15978   return ret;
15979 }
15980
15981 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
15982
15983 static int
15984 api_lisp_gpe_enable_disable (vat_main_t * vam)
15985 {
15986   unformat_input_t *input = vam->input;
15987   vl_api_gpe_enable_disable_t *mp;
15988   u8 is_set = 0;
15989   u8 is_en = 1;
15990   int ret;
15991
15992   /* Parse args required to build the message */
15993   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15994     {
15995       if (unformat (input, "enable"))
15996         {
15997           is_set = 1;
15998           is_en = 1;
15999         }
16000       else if (unformat (input, "disable"))
16001         {
16002           is_set = 1;
16003           is_en = 0;
16004         }
16005       else
16006         break;
16007     }
16008
16009   if (is_set == 0)
16010     {
16011       errmsg ("Value not set");
16012       return -99;
16013     }
16014
16015   /* Construct the API message */
16016   M (GPE_ENABLE_DISABLE, mp);
16017
16018   mp->is_en = is_en;
16019
16020   /* send it... */
16021   S (mp);
16022
16023   /* Wait for a reply... */
16024   W (ret);
16025   return ret;
16026 }
16027
16028 static int
16029 api_one_rloc_probe_enable_disable (vat_main_t * vam)
16030 {
16031   unformat_input_t *input = vam->input;
16032   vl_api_one_rloc_probe_enable_disable_t *mp;
16033   u8 is_set = 0;
16034   u8 is_en = 0;
16035   int ret;
16036
16037   /* Parse args required to build the message */
16038   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16039     {
16040       if (unformat (input, "enable"))
16041         {
16042           is_set = 1;
16043           is_en = 1;
16044         }
16045       else if (unformat (input, "disable"))
16046         is_set = 1;
16047       else
16048         break;
16049     }
16050
16051   if (!is_set)
16052     {
16053       errmsg ("Value not set");
16054       return -99;
16055     }
16056
16057   /* Construct the API message */
16058   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
16059
16060   mp->is_enabled = is_en;
16061
16062   /* send it... */
16063   S (mp);
16064
16065   /* Wait for a reply... */
16066   W (ret);
16067   return ret;
16068 }
16069
16070 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
16071
16072 static int
16073 api_one_map_register_enable_disable (vat_main_t * vam)
16074 {
16075   unformat_input_t *input = vam->input;
16076   vl_api_one_map_register_enable_disable_t *mp;
16077   u8 is_set = 0;
16078   u8 is_en = 0;
16079   int ret;
16080
16081   /* Parse args required to build the message */
16082   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16083     {
16084       if (unformat (input, "enable"))
16085         {
16086           is_set = 1;
16087           is_en = 1;
16088         }
16089       else if (unformat (input, "disable"))
16090         is_set = 1;
16091       else
16092         break;
16093     }
16094
16095   if (!is_set)
16096     {
16097       errmsg ("Value not set");
16098       return -99;
16099     }
16100
16101   /* Construct the API message */
16102   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
16103
16104   mp->is_enabled = is_en;
16105
16106   /* send it... */
16107   S (mp);
16108
16109   /* Wait for a reply... */
16110   W (ret);
16111   return ret;
16112 }
16113
16114 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
16115
16116 static int
16117 api_one_enable_disable (vat_main_t * vam)
16118 {
16119   unformat_input_t *input = vam->input;
16120   vl_api_one_enable_disable_t *mp;
16121   u8 is_set = 0;
16122   u8 is_en = 0;
16123   int ret;
16124
16125   /* Parse args required to build the message */
16126   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16127     {
16128       if (unformat (input, "enable"))
16129         {
16130           is_set = 1;
16131           is_en = 1;
16132         }
16133       else if (unformat (input, "disable"))
16134         {
16135           is_set = 1;
16136         }
16137       else
16138         break;
16139     }
16140
16141   if (!is_set)
16142     {
16143       errmsg ("Value not set");
16144       return -99;
16145     }
16146
16147   /* Construct the API message */
16148   M (ONE_ENABLE_DISABLE, mp);
16149
16150   mp->is_en = is_en;
16151
16152   /* send it... */
16153   S (mp);
16154
16155   /* Wait for a reply... */
16156   W (ret);
16157   return ret;
16158 }
16159
16160 #define api_lisp_enable_disable api_one_enable_disable
16161
16162 static int
16163 api_show_one_map_register_state (vat_main_t * vam)
16164 {
16165   vl_api_show_one_map_register_state_t *mp;
16166   int ret;
16167
16168   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
16169
16170   /* send */
16171   S (mp);
16172
16173   /* wait for reply */
16174   W (ret);
16175   return ret;
16176 }
16177
16178 #define api_show_lisp_map_register_state api_show_one_map_register_state
16179
16180 static int
16181 api_show_one_rloc_probe_state (vat_main_t * vam)
16182 {
16183   vl_api_show_one_rloc_probe_state_t *mp;
16184   int ret;
16185
16186   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
16187
16188   /* send */
16189   S (mp);
16190
16191   /* wait for reply */
16192   W (ret);
16193   return ret;
16194 }
16195
16196 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
16197
16198 static int
16199 api_one_add_del_ndp_entry (vat_main_t * vam)
16200 {
16201   vl_api_one_add_del_ndp_entry_t *mp;
16202   unformat_input_t *input = vam->input;
16203   u8 is_add = 1;
16204   u8 mac_set = 0;
16205   u8 bd_set = 0;
16206   u8 ip_set = 0;
16207   u8 mac[6] = { 0, };
16208   u8 ip6[16] = { 0, };
16209   u32 bd = ~0;
16210   int ret;
16211
16212   /* Parse args required to build the message */
16213   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16214     {
16215       if (unformat (input, "del"))
16216         is_add = 0;
16217       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16218         mac_set = 1;
16219       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
16220         ip_set = 1;
16221       else if (unformat (input, "bd %d", &bd))
16222         bd_set = 1;
16223       else
16224         {
16225           errmsg ("parse error '%U'", format_unformat_error, input);
16226           return -99;
16227         }
16228     }
16229
16230   if (!bd_set || !ip_set || (!mac_set && is_add))
16231     {
16232       errmsg ("Missing BD, IP or MAC!");
16233       return -99;
16234     }
16235
16236   M (ONE_ADD_DEL_NDP_ENTRY, mp);
16237   mp->is_add = is_add;
16238   clib_memcpy (mp->mac, mac, 6);
16239   mp->bd = clib_host_to_net_u32 (bd);
16240   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
16241
16242   /* send */
16243   S (mp);
16244
16245   /* wait for reply */
16246   W (ret);
16247   return ret;
16248 }
16249
16250 static int
16251 api_one_add_del_l2_arp_entry (vat_main_t * vam)
16252 {
16253   vl_api_one_add_del_l2_arp_entry_t *mp;
16254   unformat_input_t *input = vam->input;
16255   u8 is_add = 1;
16256   u8 mac_set = 0;
16257   u8 bd_set = 0;
16258   u8 ip_set = 0;
16259   u8 mac[6] = { 0, };
16260   u32 ip4 = 0, bd = ~0;
16261   int ret;
16262
16263   /* Parse args required to build the message */
16264   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16265     {
16266       if (unformat (input, "del"))
16267         is_add = 0;
16268       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
16269         mac_set = 1;
16270       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
16271         ip_set = 1;
16272       else if (unformat (input, "bd %d", &bd))
16273         bd_set = 1;
16274       else
16275         {
16276           errmsg ("parse error '%U'", format_unformat_error, input);
16277           return -99;
16278         }
16279     }
16280
16281   if (!bd_set || !ip_set || (!mac_set && is_add))
16282     {
16283       errmsg ("Missing BD, IP or MAC!");
16284       return -99;
16285     }
16286
16287   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
16288   mp->is_add = is_add;
16289   clib_memcpy (mp->mac, mac, 6);
16290   mp->bd = clib_host_to_net_u32 (bd);
16291   mp->ip4 = ip4;
16292
16293   /* send */
16294   S (mp);
16295
16296   /* wait for reply */
16297   W (ret);
16298   return ret;
16299 }
16300
16301 static int
16302 api_one_ndp_bd_get (vat_main_t * vam)
16303 {
16304   vl_api_one_ndp_bd_get_t *mp;
16305   int ret;
16306
16307   M (ONE_NDP_BD_GET, mp);
16308
16309   /* send */
16310   S (mp);
16311
16312   /* wait for reply */
16313   W (ret);
16314   return ret;
16315 }
16316
16317 static int
16318 api_one_ndp_entries_get (vat_main_t * vam)
16319 {
16320   vl_api_one_ndp_entries_get_t *mp;
16321   unformat_input_t *input = vam->input;
16322   u8 bd_set = 0;
16323   u32 bd = ~0;
16324   int ret;
16325
16326   /* Parse args required to build the message */
16327   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16328     {
16329       if (unformat (input, "bd %d", &bd))
16330         bd_set = 1;
16331       else
16332         {
16333           errmsg ("parse error '%U'", format_unformat_error, input);
16334           return -99;
16335         }
16336     }
16337
16338   if (!bd_set)
16339     {
16340       errmsg ("Expected bridge domain!");
16341       return -99;
16342     }
16343
16344   M (ONE_NDP_ENTRIES_GET, mp);
16345   mp->bd = clib_host_to_net_u32 (bd);
16346
16347   /* send */
16348   S (mp);
16349
16350   /* wait for reply */
16351   W (ret);
16352   return ret;
16353 }
16354
16355 static int
16356 api_one_l2_arp_bd_get (vat_main_t * vam)
16357 {
16358   vl_api_one_l2_arp_bd_get_t *mp;
16359   int ret;
16360
16361   M (ONE_L2_ARP_BD_GET, mp);
16362
16363   /* send */
16364   S (mp);
16365
16366   /* wait for reply */
16367   W (ret);
16368   return ret;
16369 }
16370
16371 static int
16372 api_one_l2_arp_entries_get (vat_main_t * vam)
16373 {
16374   vl_api_one_l2_arp_entries_get_t *mp;
16375   unformat_input_t *input = vam->input;
16376   u8 bd_set = 0;
16377   u32 bd = ~0;
16378   int ret;
16379
16380   /* Parse args required to build the message */
16381   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16382     {
16383       if (unformat (input, "bd %d", &bd))
16384         bd_set = 1;
16385       else
16386         {
16387           errmsg ("parse error '%U'", format_unformat_error, input);
16388           return -99;
16389         }
16390     }
16391
16392   if (!bd_set)
16393     {
16394       errmsg ("Expected bridge domain!");
16395       return -99;
16396     }
16397
16398   M (ONE_L2_ARP_ENTRIES_GET, mp);
16399   mp->bd = clib_host_to_net_u32 (bd);
16400
16401   /* send */
16402   S (mp);
16403
16404   /* wait for reply */
16405   W (ret);
16406   return ret;
16407 }
16408
16409 static int
16410 api_one_stats_enable_disable (vat_main_t * vam)
16411 {
16412   vl_api_one_stats_enable_disable_t *mp;
16413   unformat_input_t *input = vam->input;
16414   u8 is_set = 0;
16415   u8 is_en = 0;
16416   int ret;
16417
16418   /* Parse args required to build the message */
16419   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16420     {
16421       if (unformat (input, "enable"))
16422         {
16423           is_set = 1;
16424           is_en = 1;
16425         }
16426       else if (unformat (input, "disable"))
16427         {
16428           is_set = 1;
16429         }
16430       else
16431         break;
16432     }
16433
16434   if (!is_set)
16435     {
16436       errmsg ("Value not set");
16437       return -99;
16438     }
16439
16440   M (ONE_STATS_ENABLE_DISABLE, mp);
16441   mp->is_en = is_en;
16442
16443   /* send */
16444   S (mp);
16445
16446   /* wait for reply */
16447   W (ret);
16448   return ret;
16449 }
16450
16451 static int
16452 api_show_one_stats_enable_disable (vat_main_t * vam)
16453 {
16454   vl_api_show_one_stats_enable_disable_t *mp;
16455   int ret;
16456
16457   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16458
16459   /* send */
16460   S (mp);
16461
16462   /* wait for reply */
16463   W (ret);
16464   return ret;
16465 }
16466
16467 static int
16468 api_show_one_map_request_mode (vat_main_t * vam)
16469 {
16470   vl_api_show_one_map_request_mode_t *mp;
16471   int ret;
16472
16473   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16474
16475   /* send */
16476   S (mp);
16477
16478   /* wait for reply */
16479   W (ret);
16480   return ret;
16481 }
16482
16483 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16484
16485 static int
16486 api_one_map_request_mode (vat_main_t * vam)
16487 {
16488   unformat_input_t *input = vam->input;
16489   vl_api_one_map_request_mode_t *mp;
16490   u8 mode = 0;
16491   int ret;
16492
16493   /* Parse args required to build the message */
16494   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16495     {
16496       if (unformat (input, "dst-only"))
16497         mode = 0;
16498       else if (unformat (input, "src-dst"))
16499         mode = 1;
16500       else
16501         {
16502           errmsg ("parse error '%U'", format_unformat_error, input);
16503           return -99;
16504         }
16505     }
16506
16507   M (ONE_MAP_REQUEST_MODE, mp);
16508
16509   mp->mode = mode;
16510
16511   /* send */
16512   S (mp);
16513
16514   /* wait for reply */
16515   W (ret);
16516   return ret;
16517 }
16518
16519 #define api_lisp_map_request_mode api_one_map_request_mode
16520
16521 /**
16522  * Enable/disable ONE proxy ITR.
16523  *
16524  * @param vam vpp API test context
16525  * @return return code
16526  */
16527 static int
16528 api_one_pitr_set_locator_set (vat_main_t * vam)
16529 {
16530   u8 ls_name_set = 0;
16531   unformat_input_t *input = vam->input;
16532   vl_api_one_pitr_set_locator_set_t *mp;
16533   u8 is_add = 1;
16534   u8 *ls_name = 0;
16535   int ret;
16536
16537   /* Parse args required to build the message */
16538   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16539     {
16540       if (unformat (input, "del"))
16541         is_add = 0;
16542       else if (unformat (input, "locator-set %s", &ls_name))
16543         ls_name_set = 1;
16544       else
16545         {
16546           errmsg ("parse error '%U'", format_unformat_error, input);
16547           return -99;
16548         }
16549     }
16550
16551   if (!ls_name_set)
16552     {
16553       errmsg ("locator-set name not set!");
16554       return -99;
16555     }
16556
16557   M (ONE_PITR_SET_LOCATOR_SET, mp);
16558
16559   mp->is_add = is_add;
16560   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16561   vec_free (ls_name);
16562
16563   /* send */
16564   S (mp);
16565
16566   /* wait for reply */
16567   W (ret);
16568   return ret;
16569 }
16570
16571 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16572
16573 static int
16574 api_one_nsh_set_locator_set (vat_main_t * vam)
16575 {
16576   u8 ls_name_set = 0;
16577   unformat_input_t *input = vam->input;
16578   vl_api_one_nsh_set_locator_set_t *mp;
16579   u8 is_add = 1;
16580   u8 *ls_name = 0;
16581   int ret;
16582
16583   /* Parse args required to build the message */
16584   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16585     {
16586       if (unformat (input, "del"))
16587         is_add = 0;
16588       else if (unformat (input, "ls %s", &ls_name))
16589         ls_name_set = 1;
16590       else
16591         {
16592           errmsg ("parse error '%U'", format_unformat_error, input);
16593           return -99;
16594         }
16595     }
16596
16597   if (!ls_name_set && is_add)
16598     {
16599       errmsg ("locator-set name not set!");
16600       return -99;
16601     }
16602
16603   M (ONE_NSH_SET_LOCATOR_SET, mp);
16604
16605   mp->is_add = is_add;
16606   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16607   vec_free (ls_name);
16608
16609   /* send */
16610   S (mp);
16611
16612   /* wait for reply */
16613   W (ret);
16614   return ret;
16615 }
16616
16617 static int
16618 api_show_one_pitr (vat_main_t * vam)
16619 {
16620   vl_api_show_one_pitr_t *mp;
16621   int ret;
16622
16623   if (!vam->json_output)
16624     {
16625       print (vam->ofp, "%=20s", "lisp status:");
16626     }
16627
16628   M (SHOW_ONE_PITR, mp);
16629   /* send it... */
16630   S (mp);
16631
16632   /* Wait for a reply... */
16633   W (ret);
16634   return ret;
16635 }
16636
16637 #define api_show_lisp_pitr api_show_one_pitr
16638
16639 static int
16640 api_one_use_petr (vat_main_t * vam)
16641 {
16642   unformat_input_t *input = vam->input;
16643   vl_api_one_use_petr_t *mp;
16644   u8 is_add = 0;
16645   ip_address_t ip;
16646   int ret;
16647
16648   memset (&ip, 0, sizeof (ip));
16649
16650   /* Parse args required to build the message */
16651   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16652     {
16653       if (unformat (input, "disable"))
16654         is_add = 0;
16655       else
16656         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16657         {
16658           is_add = 1;
16659           ip_addr_version (&ip) = IP4;
16660         }
16661       else
16662         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16663         {
16664           is_add = 1;
16665           ip_addr_version (&ip) = IP6;
16666         }
16667       else
16668         {
16669           errmsg ("parse error '%U'", format_unformat_error, input);
16670           return -99;
16671         }
16672     }
16673
16674   M (ONE_USE_PETR, mp);
16675
16676   mp->is_add = is_add;
16677   if (is_add)
16678     {
16679       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16680       if (mp->is_ip4)
16681         clib_memcpy (mp->address, &ip, 4);
16682       else
16683         clib_memcpy (mp->address, &ip, 16);
16684     }
16685
16686   /* send */
16687   S (mp);
16688
16689   /* wait for reply */
16690   W (ret);
16691   return ret;
16692 }
16693
16694 #define api_lisp_use_petr api_one_use_petr
16695
16696 static int
16697 api_show_one_nsh_mapping (vat_main_t * vam)
16698 {
16699   vl_api_show_one_use_petr_t *mp;
16700   int ret;
16701
16702   if (!vam->json_output)
16703     {
16704       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16705     }
16706
16707   M (SHOW_ONE_NSH_MAPPING, mp);
16708   /* send it... */
16709   S (mp);
16710
16711   /* Wait for a reply... */
16712   W (ret);
16713   return ret;
16714 }
16715
16716 static int
16717 api_show_one_use_petr (vat_main_t * vam)
16718 {
16719   vl_api_show_one_use_petr_t *mp;
16720   int ret;
16721
16722   if (!vam->json_output)
16723     {
16724       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16725     }
16726
16727   M (SHOW_ONE_USE_PETR, mp);
16728   /* send it... */
16729   S (mp);
16730
16731   /* Wait for a reply... */
16732   W (ret);
16733   return ret;
16734 }
16735
16736 #define api_show_lisp_use_petr api_show_one_use_petr
16737
16738 /**
16739  * Add/delete mapping between vni and vrf
16740  */
16741 static int
16742 api_one_eid_table_add_del_map (vat_main_t * vam)
16743 {
16744   unformat_input_t *input = vam->input;
16745   vl_api_one_eid_table_add_del_map_t *mp;
16746   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16747   u32 vni, vrf, bd_index;
16748   int ret;
16749
16750   /* Parse args required to build the message */
16751   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16752     {
16753       if (unformat (input, "del"))
16754         is_add = 0;
16755       else if (unformat (input, "vrf %d", &vrf))
16756         vrf_set = 1;
16757       else if (unformat (input, "bd_index %d", &bd_index))
16758         bd_index_set = 1;
16759       else if (unformat (input, "vni %d", &vni))
16760         vni_set = 1;
16761       else
16762         break;
16763     }
16764
16765   if (!vni_set || (!vrf_set && !bd_index_set))
16766     {
16767       errmsg ("missing arguments!");
16768       return -99;
16769     }
16770
16771   if (vrf_set && bd_index_set)
16772     {
16773       errmsg ("error: both vrf and bd entered!");
16774       return -99;
16775     }
16776
16777   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16778
16779   mp->is_add = is_add;
16780   mp->vni = htonl (vni);
16781   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16782   mp->is_l2 = bd_index_set;
16783
16784   /* send */
16785   S (mp);
16786
16787   /* wait for reply */
16788   W (ret);
16789   return ret;
16790 }
16791
16792 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16793
16794 uword
16795 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16796 {
16797   u32 *action = va_arg (*args, u32 *);
16798   u8 *s = 0;
16799
16800   if (unformat (input, "%s", &s))
16801     {
16802       if (!strcmp ((char *) s, "no-action"))
16803         action[0] = 0;
16804       else if (!strcmp ((char *) s, "natively-forward"))
16805         action[0] = 1;
16806       else if (!strcmp ((char *) s, "send-map-request"))
16807         action[0] = 2;
16808       else if (!strcmp ((char *) s, "drop"))
16809         action[0] = 3;
16810       else
16811         {
16812           clib_warning ("invalid action: '%s'", s);
16813           action[0] = 3;
16814         }
16815     }
16816   else
16817     return 0;
16818
16819   vec_free (s);
16820   return 1;
16821 }
16822
16823 /**
16824  * Add/del remote mapping to/from ONE control plane
16825  *
16826  * @param vam vpp API test context
16827  * @return return code
16828  */
16829 static int
16830 api_one_add_del_remote_mapping (vat_main_t * vam)
16831 {
16832   unformat_input_t *input = vam->input;
16833   vl_api_one_add_del_remote_mapping_t *mp;
16834   u32 vni = 0;
16835   lisp_eid_vat_t _eid, *eid = &_eid;
16836   lisp_eid_vat_t _seid, *seid = &_seid;
16837   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
16838   u32 action = ~0, p, w, data_len;
16839   ip4_address_t rloc4;
16840   ip6_address_t rloc6;
16841   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
16842   int ret;
16843
16844   memset (&rloc, 0, sizeof (rloc));
16845
16846   /* Parse args required to build the message */
16847   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16848     {
16849       if (unformat (input, "del-all"))
16850         {
16851           del_all = 1;
16852         }
16853       else if (unformat (input, "del"))
16854         {
16855           is_add = 0;
16856         }
16857       else if (unformat (input, "add"))
16858         {
16859           is_add = 1;
16860         }
16861       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16862         {
16863           eid_set = 1;
16864         }
16865       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
16866         {
16867           seid_set = 1;
16868         }
16869       else if (unformat (input, "vni %d", &vni))
16870         {
16871           ;
16872         }
16873       else if (unformat (input, "p %d w %d", &p, &w))
16874         {
16875           if (!curr_rloc)
16876             {
16877               errmsg ("No RLOC configured for setting priority/weight!");
16878               return -99;
16879             }
16880           curr_rloc->priority = p;
16881           curr_rloc->weight = w;
16882         }
16883       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
16884         {
16885           rloc.is_ip4 = 1;
16886           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
16887           vec_add1 (rlocs, rloc);
16888           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16889         }
16890       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
16891         {
16892           rloc.is_ip4 = 0;
16893           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
16894           vec_add1 (rlocs, rloc);
16895           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16896         }
16897       else if (unformat (input, "action %U",
16898                          unformat_negative_mapping_action, &action))
16899         {
16900           ;
16901         }
16902       else
16903         {
16904           clib_warning ("parse error '%U'", format_unformat_error, input);
16905           return -99;
16906         }
16907     }
16908
16909   if (0 == eid_set)
16910     {
16911       errmsg ("missing params!");
16912       return -99;
16913     }
16914
16915   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
16916     {
16917       errmsg ("no action set for negative map-reply!");
16918       return -99;
16919     }
16920
16921   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
16922
16923   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
16924   mp->is_add = is_add;
16925   mp->vni = htonl (vni);
16926   mp->action = (u8) action;
16927   mp->is_src_dst = seid_set;
16928   mp->eid_len = eid->len;
16929   mp->seid_len = seid->len;
16930   mp->del_all = del_all;
16931   mp->eid_type = eid->type;
16932   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16933   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
16934
16935   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
16936   clib_memcpy (mp->rlocs, rlocs, data_len);
16937   vec_free (rlocs);
16938
16939   /* send it... */
16940   S (mp);
16941
16942   /* Wait for a reply... */
16943   W (ret);
16944   return ret;
16945 }
16946
16947 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
16948
16949 /**
16950  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
16951  * forwarding entries in data-plane accordingly.
16952  *
16953  * @param vam vpp API test context
16954  * @return return code
16955  */
16956 static int
16957 api_one_add_del_adjacency (vat_main_t * vam)
16958 {
16959   unformat_input_t *input = vam->input;
16960   vl_api_one_add_del_adjacency_t *mp;
16961   u32 vni = 0;
16962   ip4_address_t leid4, reid4;
16963   ip6_address_t leid6, reid6;
16964   u8 reid_mac[6] = { 0 };
16965   u8 leid_mac[6] = { 0 };
16966   u8 reid_type, leid_type;
16967   u32 leid_len = 0, reid_len = 0, len;
16968   u8 is_add = 1;
16969   int ret;
16970
16971   leid_type = reid_type = (u8) ~ 0;
16972
16973   /* Parse args required to build the message */
16974   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16975     {
16976       if (unformat (input, "del"))
16977         {
16978           is_add = 0;
16979         }
16980       else if (unformat (input, "add"))
16981         {
16982           is_add = 1;
16983         }
16984       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
16985                          &reid4, &len))
16986         {
16987           reid_type = 0;        /* ipv4 */
16988           reid_len = len;
16989         }
16990       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
16991                          &reid6, &len))
16992         {
16993           reid_type = 1;        /* ipv6 */
16994           reid_len = len;
16995         }
16996       else if (unformat (input, "reid %U", unformat_ethernet_address,
16997                          reid_mac))
16998         {
16999           reid_type = 2;        /* mac */
17000         }
17001       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
17002                          &leid4, &len))
17003         {
17004           leid_type = 0;        /* ipv4 */
17005           leid_len = len;
17006         }
17007       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
17008                          &leid6, &len))
17009         {
17010           leid_type = 1;        /* ipv6 */
17011           leid_len = len;
17012         }
17013       else if (unformat (input, "leid %U", unformat_ethernet_address,
17014                          leid_mac))
17015         {
17016           leid_type = 2;        /* mac */
17017         }
17018       else if (unformat (input, "vni %d", &vni))
17019         {
17020           ;
17021         }
17022       else
17023         {
17024           errmsg ("parse error '%U'", format_unformat_error, input);
17025           return -99;
17026         }
17027     }
17028
17029   if ((u8) ~ 0 == reid_type)
17030     {
17031       errmsg ("missing params!");
17032       return -99;
17033     }
17034
17035   if (leid_type != reid_type)
17036     {
17037       errmsg ("remote and local EIDs are of different types!");
17038       return -99;
17039     }
17040
17041   M (ONE_ADD_DEL_ADJACENCY, mp);
17042   mp->is_add = is_add;
17043   mp->vni = htonl (vni);
17044   mp->leid_len = leid_len;
17045   mp->reid_len = reid_len;
17046   mp->eid_type = reid_type;
17047
17048   switch (mp->eid_type)
17049     {
17050     case 0:
17051       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
17052       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
17053       break;
17054     case 1:
17055       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
17056       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
17057       break;
17058     case 2:
17059       clib_memcpy (mp->leid, leid_mac, 6);
17060       clib_memcpy (mp->reid, reid_mac, 6);
17061       break;
17062     default:
17063       errmsg ("unknown EID type %d!", mp->eid_type);
17064       return 0;
17065     }
17066
17067   /* send it... */
17068   S (mp);
17069
17070   /* Wait for a reply... */
17071   W (ret);
17072   return ret;
17073 }
17074
17075 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
17076
17077 uword
17078 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
17079 {
17080   u32 *mode = va_arg (*args, u32 *);
17081
17082   if (unformat (input, "lisp"))
17083     *mode = 0;
17084   else if (unformat (input, "vxlan"))
17085     *mode = 1;
17086   else
17087     return 0;
17088
17089   return 1;
17090 }
17091
17092 static int
17093 api_gpe_get_encap_mode (vat_main_t * vam)
17094 {
17095   vl_api_gpe_get_encap_mode_t *mp;
17096   int ret;
17097
17098   /* Construct the API message */
17099   M (GPE_GET_ENCAP_MODE, mp);
17100
17101   /* send it... */
17102   S (mp);
17103
17104   /* Wait for a reply... */
17105   W (ret);
17106   return ret;
17107 }
17108
17109 static int
17110 api_gpe_set_encap_mode (vat_main_t * vam)
17111 {
17112   unformat_input_t *input = vam->input;
17113   vl_api_gpe_set_encap_mode_t *mp;
17114   int ret;
17115   u32 mode = 0;
17116
17117   /* Parse args required to build the message */
17118   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17119     {
17120       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
17121         ;
17122       else
17123         break;
17124     }
17125
17126   /* Construct the API message */
17127   M (GPE_SET_ENCAP_MODE, mp);
17128
17129   mp->mode = mode;
17130
17131   /* send it... */
17132   S (mp);
17133
17134   /* Wait for a reply... */
17135   W (ret);
17136   return ret;
17137 }
17138
17139 static int
17140 api_lisp_gpe_add_del_iface (vat_main_t * vam)
17141 {
17142   unformat_input_t *input = vam->input;
17143   vl_api_gpe_add_del_iface_t *mp;
17144   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
17145   u32 dp_table = 0, vni = 0;
17146   int ret;
17147
17148   /* Parse args required to build the message */
17149   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17150     {
17151       if (unformat (input, "up"))
17152         {
17153           action_set = 1;
17154           is_add = 1;
17155         }
17156       else if (unformat (input, "down"))
17157         {
17158           action_set = 1;
17159           is_add = 0;
17160         }
17161       else if (unformat (input, "table_id %d", &dp_table))
17162         {
17163           dp_table_set = 1;
17164         }
17165       else if (unformat (input, "bd_id %d", &dp_table))
17166         {
17167           dp_table_set = 1;
17168           is_l2 = 1;
17169         }
17170       else if (unformat (input, "vni %d", &vni))
17171         {
17172           vni_set = 1;
17173         }
17174       else
17175         break;
17176     }
17177
17178   if (action_set == 0)
17179     {
17180       errmsg ("Action not set");
17181       return -99;
17182     }
17183   if (dp_table_set == 0 || vni_set == 0)
17184     {
17185       errmsg ("vni and dp_table must be set");
17186       return -99;
17187     }
17188
17189   /* Construct the API message */
17190   M (GPE_ADD_DEL_IFACE, mp);
17191
17192   mp->is_add = is_add;
17193   mp->dp_table = clib_host_to_net_u32 (dp_table);
17194   mp->is_l2 = is_l2;
17195   mp->vni = clib_host_to_net_u32 (vni);
17196
17197   /* send it... */
17198   S (mp);
17199
17200   /* Wait for a reply... */
17201   W (ret);
17202   return ret;
17203 }
17204
17205 static int
17206 api_one_map_register_fallback_threshold (vat_main_t * vam)
17207 {
17208   unformat_input_t *input = vam->input;
17209   vl_api_one_map_register_fallback_threshold_t *mp;
17210   u32 value = 0;
17211   u8 is_set = 0;
17212   int ret;
17213
17214   /* Parse args required to build the message */
17215   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17216     {
17217       if (unformat (input, "%u", &value))
17218         is_set = 1;
17219       else
17220         {
17221           clib_warning ("parse error '%U'", format_unformat_error, input);
17222           return -99;
17223         }
17224     }
17225
17226   if (!is_set)
17227     {
17228       errmsg ("fallback threshold value is missing!");
17229       return -99;
17230     }
17231
17232   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17233   mp->value = clib_host_to_net_u32 (value);
17234
17235   /* send it... */
17236   S (mp);
17237
17238   /* Wait for a reply... */
17239   W (ret);
17240   return ret;
17241 }
17242
17243 static int
17244 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
17245 {
17246   vl_api_show_one_map_register_fallback_threshold_t *mp;
17247   int ret;
17248
17249   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
17250
17251   /* send it... */
17252   S (mp);
17253
17254   /* Wait for a reply... */
17255   W (ret);
17256   return ret;
17257 }
17258
17259 uword
17260 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
17261 {
17262   u32 *proto = va_arg (*args, u32 *);
17263
17264   if (unformat (input, "udp"))
17265     *proto = 1;
17266   else if (unformat (input, "api"))
17267     *proto = 2;
17268   else
17269     return 0;
17270
17271   return 1;
17272 }
17273
17274 static int
17275 api_one_set_transport_protocol (vat_main_t * vam)
17276 {
17277   unformat_input_t *input = vam->input;
17278   vl_api_one_set_transport_protocol_t *mp;
17279   u8 is_set = 0;
17280   u32 protocol = 0;
17281   int ret;
17282
17283   /* Parse args required to build the message */
17284   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17285     {
17286       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
17287         is_set = 1;
17288       else
17289         {
17290           clib_warning ("parse error '%U'", format_unformat_error, input);
17291           return -99;
17292         }
17293     }
17294
17295   if (!is_set)
17296     {
17297       errmsg ("Transport protocol missing!");
17298       return -99;
17299     }
17300
17301   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
17302   mp->protocol = (u8) protocol;
17303
17304   /* send it... */
17305   S (mp);
17306
17307   /* Wait for a reply... */
17308   W (ret);
17309   return ret;
17310 }
17311
17312 static int
17313 api_one_get_transport_protocol (vat_main_t * vam)
17314 {
17315   vl_api_one_get_transport_protocol_t *mp;
17316   int ret;
17317
17318   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17319
17320   /* send it... */
17321   S (mp);
17322
17323   /* Wait for a reply... */
17324   W (ret);
17325   return ret;
17326 }
17327
17328 static int
17329 api_one_map_register_set_ttl (vat_main_t * vam)
17330 {
17331   unformat_input_t *input = vam->input;
17332   vl_api_one_map_register_set_ttl_t *mp;
17333   u32 ttl = 0;
17334   u8 is_set = 0;
17335   int ret;
17336
17337   /* Parse args required to build the message */
17338   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17339     {
17340       if (unformat (input, "%u", &ttl))
17341         is_set = 1;
17342       else
17343         {
17344           clib_warning ("parse error '%U'", format_unformat_error, input);
17345           return -99;
17346         }
17347     }
17348
17349   if (!is_set)
17350     {
17351       errmsg ("TTL value missing!");
17352       return -99;
17353     }
17354
17355   M (ONE_MAP_REGISTER_SET_TTL, mp);
17356   mp->ttl = clib_host_to_net_u32 (ttl);
17357
17358   /* send it... */
17359   S (mp);
17360
17361   /* Wait for a reply... */
17362   W (ret);
17363   return ret;
17364 }
17365
17366 static int
17367 api_show_one_map_register_ttl (vat_main_t * vam)
17368 {
17369   vl_api_show_one_map_register_ttl_t *mp;
17370   int ret;
17371
17372   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17373
17374   /* send it... */
17375   S (mp);
17376
17377   /* Wait for a reply... */
17378   W (ret);
17379   return ret;
17380 }
17381
17382 /**
17383  * Add/del map request itr rlocs from ONE control plane and updates
17384  *
17385  * @param vam vpp API test context
17386  * @return return code
17387  */
17388 static int
17389 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17390 {
17391   unformat_input_t *input = vam->input;
17392   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17393   u8 *locator_set_name = 0;
17394   u8 locator_set_name_set = 0;
17395   u8 is_add = 1;
17396   int ret;
17397
17398   /* Parse args required to build the message */
17399   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17400     {
17401       if (unformat (input, "del"))
17402         {
17403           is_add = 0;
17404         }
17405       else if (unformat (input, "%_%v%_", &locator_set_name))
17406         {
17407           locator_set_name_set = 1;
17408         }
17409       else
17410         {
17411           clib_warning ("parse error '%U'", format_unformat_error, input);
17412           return -99;
17413         }
17414     }
17415
17416   if (is_add && !locator_set_name_set)
17417     {
17418       errmsg ("itr-rloc is not set!");
17419       return -99;
17420     }
17421
17422   if (is_add && vec_len (locator_set_name) > 64)
17423     {
17424       errmsg ("itr-rloc locator-set name too long");
17425       vec_free (locator_set_name);
17426       return -99;
17427     }
17428
17429   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17430   mp->is_add = is_add;
17431   if (is_add)
17432     {
17433       clib_memcpy (mp->locator_set_name, locator_set_name,
17434                    vec_len (locator_set_name));
17435     }
17436   else
17437     {
17438       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17439     }
17440   vec_free (locator_set_name);
17441
17442   /* send it... */
17443   S (mp);
17444
17445   /* Wait for a reply... */
17446   W (ret);
17447   return ret;
17448 }
17449
17450 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17451
17452 static int
17453 api_one_locator_dump (vat_main_t * vam)
17454 {
17455   unformat_input_t *input = vam->input;
17456   vl_api_one_locator_dump_t *mp;
17457   vl_api_control_ping_t *mp_ping;
17458   u8 is_index_set = 0, is_name_set = 0;
17459   u8 *ls_name = 0;
17460   u32 ls_index = ~0;
17461   int ret;
17462
17463   /* Parse args required to build the message */
17464   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17465     {
17466       if (unformat (input, "ls_name %_%v%_", &ls_name))
17467         {
17468           is_name_set = 1;
17469         }
17470       else if (unformat (input, "ls_index %d", &ls_index))
17471         {
17472           is_index_set = 1;
17473         }
17474       else
17475         {
17476           errmsg ("parse error '%U'", format_unformat_error, input);
17477           return -99;
17478         }
17479     }
17480
17481   if (!is_index_set && !is_name_set)
17482     {
17483       errmsg ("error: expected one of index or name!");
17484       return -99;
17485     }
17486
17487   if (is_index_set && is_name_set)
17488     {
17489       errmsg ("error: only one param expected!");
17490       return -99;
17491     }
17492
17493   if (vec_len (ls_name) > 62)
17494     {
17495       errmsg ("error: locator set name too long!");
17496       return -99;
17497     }
17498
17499   if (!vam->json_output)
17500     {
17501       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17502     }
17503
17504   M (ONE_LOCATOR_DUMP, mp);
17505   mp->is_index_set = is_index_set;
17506
17507   if (is_index_set)
17508     mp->ls_index = clib_host_to_net_u32 (ls_index);
17509   else
17510     {
17511       vec_add1 (ls_name, 0);
17512       strncpy ((char *) mp->ls_name, (char *) ls_name,
17513                sizeof (mp->ls_name) - 1);
17514     }
17515
17516   /* send it... */
17517   S (mp);
17518
17519   /* Use a control ping for synchronization */
17520   MPING (CONTROL_PING, mp_ping);
17521   S (mp_ping);
17522
17523   /* Wait for a reply... */
17524   W (ret);
17525   return ret;
17526 }
17527
17528 #define api_lisp_locator_dump api_one_locator_dump
17529
17530 static int
17531 api_one_locator_set_dump (vat_main_t * vam)
17532 {
17533   vl_api_one_locator_set_dump_t *mp;
17534   vl_api_control_ping_t *mp_ping;
17535   unformat_input_t *input = vam->input;
17536   u8 filter = 0;
17537   int ret;
17538
17539   /* Parse args required to build the message */
17540   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17541     {
17542       if (unformat (input, "local"))
17543         {
17544           filter = 1;
17545         }
17546       else if (unformat (input, "remote"))
17547         {
17548           filter = 2;
17549         }
17550       else
17551         {
17552           errmsg ("parse error '%U'", format_unformat_error, input);
17553           return -99;
17554         }
17555     }
17556
17557   if (!vam->json_output)
17558     {
17559       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17560     }
17561
17562   M (ONE_LOCATOR_SET_DUMP, mp);
17563
17564   mp->filter = filter;
17565
17566   /* send it... */
17567   S (mp);
17568
17569   /* Use a control ping for synchronization */
17570   MPING (CONTROL_PING, mp_ping);
17571   S (mp_ping);
17572
17573   /* Wait for a reply... */
17574   W (ret);
17575   return ret;
17576 }
17577
17578 #define api_lisp_locator_set_dump api_one_locator_set_dump
17579
17580 static int
17581 api_one_eid_table_map_dump (vat_main_t * vam)
17582 {
17583   u8 is_l2 = 0;
17584   u8 mode_set = 0;
17585   unformat_input_t *input = vam->input;
17586   vl_api_one_eid_table_map_dump_t *mp;
17587   vl_api_control_ping_t *mp_ping;
17588   int ret;
17589
17590   /* Parse args required to build the message */
17591   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17592     {
17593       if (unformat (input, "l2"))
17594         {
17595           is_l2 = 1;
17596           mode_set = 1;
17597         }
17598       else if (unformat (input, "l3"))
17599         {
17600           is_l2 = 0;
17601           mode_set = 1;
17602         }
17603       else
17604         {
17605           errmsg ("parse error '%U'", format_unformat_error, input);
17606           return -99;
17607         }
17608     }
17609
17610   if (!mode_set)
17611     {
17612       errmsg ("expected one of 'l2' or 'l3' parameter!");
17613       return -99;
17614     }
17615
17616   if (!vam->json_output)
17617     {
17618       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17619     }
17620
17621   M (ONE_EID_TABLE_MAP_DUMP, mp);
17622   mp->is_l2 = is_l2;
17623
17624   /* send it... */
17625   S (mp);
17626
17627   /* Use a control ping for synchronization */
17628   MPING (CONTROL_PING, mp_ping);
17629   S (mp_ping);
17630
17631   /* Wait for a reply... */
17632   W (ret);
17633   return ret;
17634 }
17635
17636 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17637
17638 static int
17639 api_one_eid_table_vni_dump (vat_main_t * vam)
17640 {
17641   vl_api_one_eid_table_vni_dump_t *mp;
17642   vl_api_control_ping_t *mp_ping;
17643   int ret;
17644
17645   if (!vam->json_output)
17646     {
17647       print (vam->ofp, "VNI");
17648     }
17649
17650   M (ONE_EID_TABLE_VNI_DUMP, mp);
17651
17652   /* send it... */
17653   S (mp);
17654
17655   /* Use a control ping for synchronization */
17656   MPING (CONTROL_PING, mp_ping);
17657   S (mp_ping);
17658
17659   /* Wait for a reply... */
17660   W (ret);
17661   return ret;
17662 }
17663
17664 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17665
17666 static int
17667 api_one_eid_table_dump (vat_main_t * vam)
17668 {
17669   unformat_input_t *i = vam->input;
17670   vl_api_one_eid_table_dump_t *mp;
17671   vl_api_control_ping_t *mp_ping;
17672   struct in_addr ip4;
17673   struct in6_addr ip6;
17674   u8 mac[6];
17675   u8 eid_type = ~0, eid_set = 0;
17676   u32 prefix_length = ~0, t, vni = 0;
17677   u8 filter = 0;
17678   int ret;
17679   lisp_nsh_api_t nsh;
17680
17681   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17682     {
17683       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17684         {
17685           eid_set = 1;
17686           eid_type = 0;
17687           prefix_length = t;
17688         }
17689       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17690         {
17691           eid_set = 1;
17692           eid_type = 1;
17693           prefix_length = t;
17694         }
17695       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17696         {
17697           eid_set = 1;
17698           eid_type = 2;
17699         }
17700       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17701         {
17702           eid_set = 1;
17703           eid_type = 3;
17704         }
17705       else if (unformat (i, "vni %d", &t))
17706         {
17707           vni = t;
17708         }
17709       else if (unformat (i, "local"))
17710         {
17711           filter = 1;
17712         }
17713       else if (unformat (i, "remote"))
17714         {
17715           filter = 2;
17716         }
17717       else
17718         {
17719           errmsg ("parse error '%U'", format_unformat_error, i);
17720           return -99;
17721         }
17722     }
17723
17724   if (!vam->json_output)
17725     {
17726       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17727              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17728     }
17729
17730   M (ONE_EID_TABLE_DUMP, mp);
17731
17732   mp->filter = filter;
17733   if (eid_set)
17734     {
17735       mp->eid_set = 1;
17736       mp->vni = htonl (vni);
17737       mp->eid_type = eid_type;
17738       switch (eid_type)
17739         {
17740         case 0:
17741           mp->prefix_length = prefix_length;
17742           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17743           break;
17744         case 1:
17745           mp->prefix_length = prefix_length;
17746           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17747           break;
17748         case 2:
17749           clib_memcpy (mp->eid, mac, sizeof (mac));
17750           break;
17751         case 3:
17752           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17753           break;
17754         default:
17755           errmsg ("unknown EID type %d!", eid_type);
17756           return -99;
17757         }
17758     }
17759
17760   /* send it... */
17761   S (mp);
17762
17763   /* Use a control ping for synchronization */
17764   MPING (CONTROL_PING, mp_ping);
17765   S (mp_ping);
17766
17767   /* Wait for a reply... */
17768   W (ret);
17769   return ret;
17770 }
17771
17772 #define api_lisp_eid_table_dump api_one_eid_table_dump
17773
17774 static int
17775 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17776 {
17777   unformat_input_t *i = vam->input;
17778   vl_api_gpe_fwd_entries_get_t *mp;
17779   u8 vni_set = 0;
17780   u32 vni = ~0;
17781   int ret;
17782
17783   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17784     {
17785       if (unformat (i, "vni %d", &vni))
17786         {
17787           vni_set = 1;
17788         }
17789       else
17790         {
17791           errmsg ("parse error '%U'", format_unformat_error, i);
17792           return -99;
17793         }
17794     }
17795
17796   if (!vni_set)
17797     {
17798       errmsg ("vni not set!");
17799       return -99;
17800     }
17801
17802   if (!vam->json_output)
17803     {
17804       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17805              "leid", "reid");
17806     }
17807
17808   M (GPE_FWD_ENTRIES_GET, mp);
17809   mp->vni = clib_host_to_net_u32 (vni);
17810
17811   /* send it... */
17812   S (mp);
17813
17814   /* Wait for a reply... */
17815   W (ret);
17816   return ret;
17817 }
17818
17819 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
17820 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
17821 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
17822 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
17823 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
17824 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
17825 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
17826 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
17827
17828 static int
17829 api_one_adjacencies_get (vat_main_t * vam)
17830 {
17831   unformat_input_t *i = vam->input;
17832   vl_api_one_adjacencies_get_t *mp;
17833   u8 vni_set = 0;
17834   u32 vni = ~0;
17835   int ret;
17836
17837   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17838     {
17839       if (unformat (i, "vni %d", &vni))
17840         {
17841           vni_set = 1;
17842         }
17843       else
17844         {
17845           errmsg ("parse error '%U'", format_unformat_error, i);
17846           return -99;
17847         }
17848     }
17849
17850   if (!vni_set)
17851     {
17852       errmsg ("vni not set!");
17853       return -99;
17854     }
17855
17856   if (!vam->json_output)
17857     {
17858       print (vam->ofp, "%s %40s", "leid", "reid");
17859     }
17860
17861   M (ONE_ADJACENCIES_GET, mp);
17862   mp->vni = clib_host_to_net_u32 (vni);
17863
17864   /* send it... */
17865   S (mp);
17866
17867   /* Wait for a reply... */
17868   W (ret);
17869   return ret;
17870 }
17871
17872 #define api_lisp_adjacencies_get api_one_adjacencies_get
17873
17874 static int
17875 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
17876 {
17877   unformat_input_t *i = vam->input;
17878   vl_api_gpe_native_fwd_rpaths_get_t *mp;
17879   int ret;
17880   u8 ip_family_set = 0, is_ip4 = 1;
17881
17882   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17883     {
17884       if (unformat (i, "ip4"))
17885         {
17886           ip_family_set = 1;
17887           is_ip4 = 1;
17888         }
17889       else if (unformat (i, "ip6"))
17890         {
17891           ip_family_set = 1;
17892           is_ip4 = 0;
17893         }
17894       else
17895         {
17896           errmsg ("parse error '%U'", format_unformat_error, i);
17897           return -99;
17898         }
17899     }
17900
17901   if (!ip_family_set)
17902     {
17903       errmsg ("ip family not set!");
17904       return -99;
17905     }
17906
17907   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
17908   mp->is_ip4 = is_ip4;
17909
17910   /* send it... */
17911   S (mp);
17912
17913   /* Wait for a reply... */
17914   W (ret);
17915   return ret;
17916 }
17917
17918 static int
17919 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
17920 {
17921   vl_api_gpe_fwd_entry_vnis_get_t *mp;
17922   int ret;
17923
17924   if (!vam->json_output)
17925     {
17926       print (vam->ofp, "VNIs");
17927     }
17928
17929   M (GPE_FWD_ENTRY_VNIS_GET, mp);
17930
17931   /* send it... */
17932   S (mp);
17933
17934   /* Wait for a reply... */
17935   W (ret);
17936   return ret;
17937 }
17938
17939 static int
17940 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
17941 {
17942   unformat_input_t *i = vam->input;
17943   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
17944   int ret = 0;
17945   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
17946   struct in_addr ip4;
17947   struct in6_addr ip6;
17948   u32 table_id = 0, nh_sw_if_index = ~0;
17949
17950   memset (&ip4, 0, sizeof (ip4));
17951   memset (&ip6, 0, sizeof (ip6));
17952
17953   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17954     {
17955       if (unformat (i, "del"))
17956         is_add = 0;
17957       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
17958                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17959         {
17960           ip_set = 1;
17961           is_ip4 = 1;
17962         }
17963       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
17964                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17965         {
17966           ip_set = 1;
17967           is_ip4 = 0;
17968         }
17969       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
17970         {
17971           ip_set = 1;
17972           is_ip4 = 1;
17973           nh_sw_if_index = ~0;
17974         }
17975       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
17976         {
17977           ip_set = 1;
17978           is_ip4 = 0;
17979           nh_sw_if_index = ~0;
17980         }
17981       else if (unformat (i, "table %d", &table_id))
17982         ;
17983       else
17984         {
17985           errmsg ("parse error '%U'", format_unformat_error, i);
17986           return -99;
17987         }
17988     }
17989
17990   if (!ip_set)
17991     {
17992       errmsg ("nh addr not set!");
17993       return -99;
17994     }
17995
17996   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
17997   mp->is_add = is_add;
17998   mp->table_id = clib_host_to_net_u32 (table_id);
17999   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
18000   mp->is_ip4 = is_ip4;
18001   if (is_ip4)
18002     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
18003   else
18004     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
18005
18006   /* send it... */
18007   S (mp);
18008
18009   /* Wait for a reply... */
18010   W (ret);
18011   return ret;
18012 }
18013
18014 static int
18015 api_one_map_server_dump (vat_main_t * vam)
18016 {
18017   vl_api_one_map_server_dump_t *mp;
18018   vl_api_control_ping_t *mp_ping;
18019   int ret;
18020
18021   if (!vam->json_output)
18022     {
18023       print (vam->ofp, "%=20s", "Map server");
18024     }
18025
18026   M (ONE_MAP_SERVER_DUMP, mp);
18027   /* send it... */
18028   S (mp);
18029
18030   /* Use a control ping for synchronization */
18031   MPING (CONTROL_PING, mp_ping);
18032   S (mp_ping);
18033
18034   /* Wait for a reply... */
18035   W (ret);
18036   return ret;
18037 }
18038
18039 #define api_lisp_map_server_dump api_one_map_server_dump
18040
18041 static int
18042 api_one_map_resolver_dump (vat_main_t * vam)
18043 {
18044   vl_api_one_map_resolver_dump_t *mp;
18045   vl_api_control_ping_t *mp_ping;
18046   int ret;
18047
18048   if (!vam->json_output)
18049     {
18050       print (vam->ofp, "%=20s", "Map resolver");
18051     }
18052
18053   M (ONE_MAP_RESOLVER_DUMP, mp);
18054   /* send it... */
18055   S (mp);
18056
18057   /* Use a control ping for synchronization */
18058   MPING (CONTROL_PING, mp_ping);
18059   S (mp_ping);
18060
18061   /* Wait for a reply... */
18062   W (ret);
18063   return ret;
18064 }
18065
18066 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
18067
18068 static int
18069 api_one_stats_flush (vat_main_t * vam)
18070 {
18071   vl_api_one_stats_flush_t *mp;
18072   int ret = 0;
18073
18074   M (ONE_STATS_FLUSH, mp);
18075   S (mp);
18076   W (ret);
18077   return ret;
18078 }
18079
18080 static int
18081 api_one_stats_dump (vat_main_t * vam)
18082 {
18083   vl_api_one_stats_dump_t *mp;
18084   vl_api_control_ping_t *mp_ping;
18085   int ret;
18086
18087   M (ONE_STATS_DUMP, mp);
18088   /* send it... */
18089   S (mp);
18090
18091   /* Use a control ping for synchronization */
18092   MPING (CONTROL_PING, mp_ping);
18093   S (mp_ping);
18094
18095   /* Wait for a reply... */
18096   W (ret);
18097   return ret;
18098 }
18099
18100 static int
18101 api_show_one_status (vat_main_t * vam)
18102 {
18103   vl_api_show_one_status_t *mp;
18104   int ret;
18105
18106   if (!vam->json_output)
18107     {
18108       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
18109     }
18110
18111   M (SHOW_ONE_STATUS, mp);
18112   /* send it... */
18113   S (mp);
18114   /* Wait for a reply... */
18115   W (ret);
18116   return ret;
18117 }
18118
18119 #define api_show_lisp_status api_show_one_status
18120
18121 static int
18122 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
18123 {
18124   vl_api_gpe_fwd_entry_path_dump_t *mp;
18125   vl_api_control_ping_t *mp_ping;
18126   unformat_input_t *i = vam->input;
18127   u32 fwd_entry_index = ~0;
18128   int ret;
18129
18130   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18131     {
18132       if (unformat (i, "index %d", &fwd_entry_index))
18133         ;
18134       else
18135         break;
18136     }
18137
18138   if (~0 == fwd_entry_index)
18139     {
18140       errmsg ("no index specified!");
18141       return -99;
18142     }
18143
18144   if (!vam->json_output)
18145     {
18146       print (vam->ofp, "first line");
18147     }
18148
18149   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
18150
18151   /* send it... */
18152   S (mp);
18153   /* Use a control ping for synchronization */
18154   MPING (CONTROL_PING, mp_ping);
18155   S (mp_ping);
18156
18157   /* Wait for a reply... */
18158   W (ret);
18159   return ret;
18160 }
18161
18162 static int
18163 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
18164 {
18165   vl_api_one_get_map_request_itr_rlocs_t *mp;
18166   int ret;
18167
18168   if (!vam->json_output)
18169     {
18170       print (vam->ofp, "%=20s", "itr-rlocs:");
18171     }
18172
18173   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
18174   /* send it... */
18175   S (mp);
18176   /* Wait for a reply... */
18177   W (ret);
18178   return ret;
18179 }
18180
18181 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
18182
18183 static int
18184 api_af_packet_create (vat_main_t * vam)
18185 {
18186   unformat_input_t *i = vam->input;
18187   vl_api_af_packet_create_t *mp;
18188   u8 *host_if_name = 0;
18189   u8 hw_addr[6];
18190   u8 random_hw_addr = 1;
18191   int ret;
18192
18193   memset (hw_addr, 0, sizeof (hw_addr));
18194
18195   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18196     {
18197       if (unformat (i, "name %s", &host_if_name))
18198         vec_add1 (host_if_name, 0);
18199       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18200         random_hw_addr = 0;
18201       else
18202         break;
18203     }
18204
18205   if (!vec_len (host_if_name))
18206     {
18207       errmsg ("host-interface name must be specified");
18208       return -99;
18209     }
18210
18211   if (vec_len (host_if_name) > 64)
18212     {
18213       errmsg ("host-interface name too long");
18214       return -99;
18215     }
18216
18217   M (AF_PACKET_CREATE, mp);
18218
18219   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18220   clib_memcpy (mp->hw_addr, hw_addr, 6);
18221   mp->use_random_hw_addr = random_hw_addr;
18222   vec_free (host_if_name);
18223
18224   S (mp);
18225
18226   /* *INDENT-OFF* */
18227   W2 (ret,
18228       ({
18229         if (ret == 0)
18230           fprintf (vam->ofp ? vam->ofp : stderr,
18231                    " new sw_if_index = %d\n", vam->sw_if_index);
18232       }));
18233   /* *INDENT-ON* */
18234   return ret;
18235 }
18236
18237 static int
18238 api_af_packet_delete (vat_main_t * vam)
18239 {
18240   unformat_input_t *i = vam->input;
18241   vl_api_af_packet_delete_t *mp;
18242   u8 *host_if_name = 0;
18243   int ret;
18244
18245   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18246     {
18247       if (unformat (i, "name %s", &host_if_name))
18248         vec_add1 (host_if_name, 0);
18249       else
18250         break;
18251     }
18252
18253   if (!vec_len (host_if_name))
18254     {
18255       errmsg ("host-interface name must be specified");
18256       return -99;
18257     }
18258
18259   if (vec_len (host_if_name) > 64)
18260     {
18261       errmsg ("host-interface name too long");
18262       return -99;
18263     }
18264
18265   M (AF_PACKET_DELETE, mp);
18266
18267   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
18268   vec_free (host_if_name);
18269
18270   S (mp);
18271   W (ret);
18272   return ret;
18273 }
18274
18275 static int
18276 api_policer_add_del (vat_main_t * vam)
18277 {
18278   unformat_input_t *i = vam->input;
18279   vl_api_policer_add_del_t *mp;
18280   u8 is_add = 1;
18281   u8 *name = 0;
18282   u32 cir = 0;
18283   u32 eir = 0;
18284   u64 cb = 0;
18285   u64 eb = 0;
18286   u8 rate_type = 0;
18287   u8 round_type = 0;
18288   u8 type = 0;
18289   u8 color_aware = 0;
18290   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18291   int ret;
18292
18293   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18294   conform_action.dscp = 0;
18295   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18296   exceed_action.dscp = 0;
18297   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18298   violate_action.dscp = 0;
18299
18300   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18301     {
18302       if (unformat (i, "del"))
18303         is_add = 0;
18304       else if (unformat (i, "name %s", &name))
18305         vec_add1 (name, 0);
18306       else if (unformat (i, "cir %u", &cir))
18307         ;
18308       else if (unformat (i, "eir %u", &eir))
18309         ;
18310       else if (unformat (i, "cb %u", &cb))
18311         ;
18312       else if (unformat (i, "eb %u", &eb))
18313         ;
18314       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18315                          &rate_type))
18316         ;
18317       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18318                          &round_type))
18319         ;
18320       else if (unformat (i, "type %U", unformat_policer_type, &type))
18321         ;
18322       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18323                          &conform_action))
18324         ;
18325       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18326                          &exceed_action))
18327         ;
18328       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18329                          &violate_action))
18330         ;
18331       else if (unformat (i, "color-aware"))
18332         color_aware = 1;
18333       else
18334         break;
18335     }
18336
18337   if (!vec_len (name))
18338     {
18339       errmsg ("policer name must be specified");
18340       return -99;
18341     }
18342
18343   if (vec_len (name) > 64)
18344     {
18345       errmsg ("policer name too long");
18346       return -99;
18347     }
18348
18349   M (POLICER_ADD_DEL, mp);
18350
18351   clib_memcpy (mp->name, name, vec_len (name));
18352   vec_free (name);
18353   mp->is_add = is_add;
18354   mp->cir = ntohl (cir);
18355   mp->eir = ntohl (eir);
18356   mp->cb = clib_net_to_host_u64 (cb);
18357   mp->eb = clib_net_to_host_u64 (eb);
18358   mp->rate_type = rate_type;
18359   mp->round_type = round_type;
18360   mp->type = type;
18361   mp->conform_action_type = conform_action.action_type;
18362   mp->conform_dscp = conform_action.dscp;
18363   mp->exceed_action_type = exceed_action.action_type;
18364   mp->exceed_dscp = exceed_action.dscp;
18365   mp->violate_action_type = violate_action.action_type;
18366   mp->violate_dscp = violate_action.dscp;
18367   mp->color_aware = color_aware;
18368
18369   S (mp);
18370   W (ret);
18371   return ret;
18372 }
18373
18374 static int
18375 api_policer_dump (vat_main_t * vam)
18376 {
18377   unformat_input_t *i = vam->input;
18378   vl_api_policer_dump_t *mp;
18379   vl_api_control_ping_t *mp_ping;
18380   u8 *match_name = 0;
18381   u8 match_name_valid = 0;
18382   int ret;
18383
18384   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18385     {
18386       if (unformat (i, "name %s", &match_name))
18387         {
18388           vec_add1 (match_name, 0);
18389           match_name_valid = 1;
18390         }
18391       else
18392         break;
18393     }
18394
18395   M (POLICER_DUMP, mp);
18396   mp->match_name_valid = match_name_valid;
18397   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18398   vec_free (match_name);
18399   /* send it... */
18400   S (mp);
18401
18402   /* Use a control ping for synchronization */
18403   MPING (CONTROL_PING, mp_ping);
18404   S (mp_ping);
18405
18406   /* Wait for a reply... */
18407   W (ret);
18408   return ret;
18409 }
18410
18411 static int
18412 api_policer_classify_set_interface (vat_main_t * vam)
18413 {
18414   unformat_input_t *i = vam->input;
18415   vl_api_policer_classify_set_interface_t *mp;
18416   u32 sw_if_index;
18417   int sw_if_index_set;
18418   u32 ip4_table_index = ~0;
18419   u32 ip6_table_index = ~0;
18420   u32 l2_table_index = ~0;
18421   u8 is_add = 1;
18422   int ret;
18423
18424   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18425     {
18426       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18427         sw_if_index_set = 1;
18428       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18429         sw_if_index_set = 1;
18430       else if (unformat (i, "del"))
18431         is_add = 0;
18432       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18433         ;
18434       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18435         ;
18436       else if (unformat (i, "l2-table %d", &l2_table_index))
18437         ;
18438       else
18439         {
18440           clib_warning ("parse error '%U'", format_unformat_error, i);
18441           return -99;
18442         }
18443     }
18444
18445   if (sw_if_index_set == 0)
18446     {
18447       errmsg ("missing interface name or sw_if_index");
18448       return -99;
18449     }
18450
18451   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18452
18453   mp->sw_if_index = ntohl (sw_if_index);
18454   mp->ip4_table_index = ntohl (ip4_table_index);
18455   mp->ip6_table_index = ntohl (ip6_table_index);
18456   mp->l2_table_index = ntohl (l2_table_index);
18457   mp->is_add = is_add;
18458
18459   S (mp);
18460   W (ret);
18461   return ret;
18462 }
18463
18464 static int
18465 api_policer_classify_dump (vat_main_t * vam)
18466 {
18467   unformat_input_t *i = vam->input;
18468   vl_api_policer_classify_dump_t *mp;
18469   vl_api_control_ping_t *mp_ping;
18470   u8 type = POLICER_CLASSIFY_N_TABLES;
18471   int ret;
18472
18473   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18474     ;
18475   else
18476     {
18477       errmsg ("classify table type must be specified");
18478       return -99;
18479     }
18480
18481   if (!vam->json_output)
18482     {
18483       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18484     }
18485
18486   M (POLICER_CLASSIFY_DUMP, mp);
18487   mp->type = type;
18488   /* send it... */
18489   S (mp);
18490
18491   /* Use a control ping for synchronization */
18492   MPING (CONTROL_PING, mp_ping);
18493   S (mp_ping);
18494
18495   /* Wait for a reply... */
18496   W (ret);
18497   return ret;
18498 }
18499
18500 static int
18501 api_netmap_create (vat_main_t * vam)
18502 {
18503   unformat_input_t *i = vam->input;
18504   vl_api_netmap_create_t *mp;
18505   u8 *if_name = 0;
18506   u8 hw_addr[6];
18507   u8 random_hw_addr = 1;
18508   u8 is_pipe = 0;
18509   u8 is_master = 0;
18510   int ret;
18511
18512   memset (hw_addr, 0, sizeof (hw_addr));
18513
18514   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18515     {
18516       if (unformat (i, "name %s", &if_name))
18517         vec_add1 (if_name, 0);
18518       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18519         random_hw_addr = 0;
18520       else if (unformat (i, "pipe"))
18521         is_pipe = 1;
18522       else if (unformat (i, "master"))
18523         is_master = 1;
18524       else if (unformat (i, "slave"))
18525         is_master = 0;
18526       else
18527         break;
18528     }
18529
18530   if (!vec_len (if_name))
18531     {
18532       errmsg ("interface name must be specified");
18533       return -99;
18534     }
18535
18536   if (vec_len (if_name) > 64)
18537     {
18538       errmsg ("interface name too long");
18539       return -99;
18540     }
18541
18542   M (NETMAP_CREATE, mp);
18543
18544   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18545   clib_memcpy (mp->hw_addr, hw_addr, 6);
18546   mp->use_random_hw_addr = random_hw_addr;
18547   mp->is_pipe = is_pipe;
18548   mp->is_master = is_master;
18549   vec_free (if_name);
18550
18551   S (mp);
18552   W (ret);
18553   return ret;
18554 }
18555
18556 static int
18557 api_netmap_delete (vat_main_t * vam)
18558 {
18559   unformat_input_t *i = vam->input;
18560   vl_api_netmap_delete_t *mp;
18561   u8 *if_name = 0;
18562   int ret;
18563
18564   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18565     {
18566       if (unformat (i, "name %s", &if_name))
18567         vec_add1 (if_name, 0);
18568       else
18569         break;
18570     }
18571
18572   if (!vec_len (if_name))
18573     {
18574       errmsg ("interface name must be specified");
18575       return -99;
18576     }
18577
18578   if (vec_len (if_name) > 64)
18579     {
18580       errmsg ("interface name too long");
18581       return -99;
18582     }
18583
18584   M (NETMAP_DELETE, mp);
18585
18586   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18587   vec_free (if_name);
18588
18589   S (mp);
18590   W (ret);
18591   return ret;
18592 }
18593
18594 static void
18595 vl_api_mpls_fib_path_print (vat_main_t * vam, vl_api_fib_path2_t * fp)
18596 {
18597   if (fp->afi == IP46_TYPE_IP6)
18598     print (vam->ofp,
18599            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18600            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18601            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18602            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18603            format_ip6_address, fp->next_hop);
18604   else if (fp->afi == IP46_TYPE_IP4)
18605     print (vam->ofp,
18606            "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18607            "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18608            ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18609            fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18610            format_ip4_address, fp->next_hop);
18611 }
18612
18613 static void
18614 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18615                                  vl_api_fib_path2_t * fp)
18616 {
18617   struct in_addr ip4;
18618   struct in6_addr ip6;
18619
18620   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18621   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18622   vat_json_object_add_uint (node, "is_local", fp->is_local);
18623   vat_json_object_add_uint (node, "is_drop", fp->is_drop);
18624   vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
18625   vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
18626   vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
18627   if (fp->afi == IP46_TYPE_IP4)
18628     {
18629       clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
18630       vat_json_object_add_ip4 (node, "next_hop", ip4);
18631     }
18632   else if (fp->afi == IP46_TYPE_IP6)
18633     {
18634       clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
18635       vat_json_object_add_ip6 (node, "next_hop", ip6);
18636     }
18637 }
18638
18639 static void
18640 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18641 {
18642   vat_main_t *vam = &vat_main;
18643   int count = ntohl (mp->mt_count);
18644   vl_api_fib_path2_t *fp;
18645   i32 i;
18646
18647   print (vam->ofp, "[%d]: sw_if_index %d via:",
18648          ntohl (mp->mt_tunnel_index), ntohl (mp->mt_sw_if_index));
18649   fp = mp->mt_paths;
18650   for (i = 0; i < count; i++)
18651     {
18652       vl_api_mpls_fib_path_print (vam, fp);
18653       fp++;
18654     }
18655
18656   print (vam->ofp, "");
18657 }
18658
18659 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18660 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18661
18662 static void
18663 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18664 {
18665   vat_main_t *vam = &vat_main;
18666   vat_json_node_t *node = NULL;
18667   int count = ntohl (mp->mt_count);
18668   vl_api_fib_path2_t *fp;
18669   i32 i;
18670
18671   if (VAT_JSON_ARRAY != vam->json_tree.type)
18672     {
18673       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18674       vat_json_init_array (&vam->json_tree);
18675     }
18676   node = vat_json_array_add (&vam->json_tree);
18677
18678   vat_json_init_object (node);
18679   vat_json_object_add_uint (node, "tunnel_index",
18680                             ntohl (mp->mt_tunnel_index));
18681   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->mt_sw_if_index));
18682
18683   vat_json_object_add_uint (node, "l2_only", mp->mt_l2_only);
18684
18685   fp = mp->mt_paths;
18686   for (i = 0; i < count; i++)
18687     {
18688       vl_api_mpls_fib_path_json_print (node, fp);
18689       fp++;
18690     }
18691 }
18692
18693 static int
18694 api_mpls_tunnel_dump (vat_main_t * vam)
18695 {
18696   vl_api_mpls_tunnel_dump_t *mp;
18697   vl_api_control_ping_t *mp_ping;
18698   i32 index = -1;
18699   int ret;
18700
18701   /* Parse args required to build the message */
18702   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
18703     {
18704       if (!unformat (vam->input, "tunnel_index %d", &index))
18705         {
18706           index = -1;
18707           break;
18708         }
18709     }
18710
18711   print (vam->ofp, "  tunnel_index %d", index);
18712
18713   M (MPLS_TUNNEL_DUMP, mp);
18714   mp->tunnel_index = htonl (index);
18715   S (mp);
18716
18717   /* Use a control ping for synchronization */
18718   MPING (CONTROL_PING, mp_ping);
18719   S (mp_ping);
18720
18721   W (ret);
18722   return ret;
18723 }
18724
18725 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
18726 #define vl_api_mpls_fib_details_t_print vl_noop_handler
18727
18728
18729 static void
18730 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
18731 {
18732   vat_main_t *vam = &vat_main;
18733   int count = ntohl (mp->count);
18734   vl_api_fib_path2_t *fp;
18735   int i;
18736
18737   print (vam->ofp,
18738          "table-id %d, label %u, ess_bit %u",
18739          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
18740   fp = mp->path;
18741   for (i = 0; i < count; i++)
18742     {
18743       vl_api_mpls_fib_path_print (vam, fp);
18744       fp++;
18745     }
18746 }
18747
18748 static void vl_api_mpls_fib_details_t_handler_json
18749   (vl_api_mpls_fib_details_t * mp)
18750 {
18751   vat_main_t *vam = &vat_main;
18752   int count = ntohl (mp->count);
18753   vat_json_node_t *node = NULL;
18754   vl_api_fib_path2_t *fp;
18755   int i;
18756
18757   if (VAT_JSON_ARRAY != vam->json_tree.type)
18758     {
18759       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18760       vat_json_init_array (&vam->json_tree);
18761     }
18762   node = vat_json_array_add (&vam->json_tree);
18763
18764   vat_json_init_object (node);
18765   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
18766   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
18767   vat_json_object_add_uint (node, "label", ntohl (mp->label));
18768   vat_json_object_add_uint (node, "path_count", count);
18769   fp = mp->path;
18770   for (i = 0; i < count; i++)
18771     {
18772       vl_api_mpls_fib_path_json_print (node, fp);
18773       fp++;
18774     }
18775 }
18776
18777 static int
18778 api_mpls_fib_dump (vat_main_t * vam)
18779 {
18780   vl_api_mpls_fib_dump_t *mp;
18781   vl_api_control_ping_t *mp_ping;
18782   int ret;
18783
18784   M (MPLS_FIB_DUMP, mp);
18785   S (mp);
18786
18787   /* Use a control ping for synchronization */
18788   MPING (CONTROL_PING, mp_ping);
18789   S (mp_ping);
18790
18791   W (ret);
18792   return ret;
18793 }
18794
18795 #define vl_api_ip_fib_details_t_endian vl_noop_handler
18796 #define vl_api_ip_fib_details_t_print vl_noop_handler
18797
18798 static void
18799 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
18800 {
18801   vat_main_t *vam = &vat_main;
18802   int count = ntohl (mp->count);
18803   vl_api_fib_path_t *fp;
18804   int i;
18805
18806   print (vam->ofp,
18807          "table-id %d, prefix %U/%d",
18808          ntohl (mp->table_id), format_ip4_address, mp->address,
18809          mp->address_length);
18810   fp = mp->path;
18811   for (i = 0; i < count; i++)
18812     {
18813       if (fp->afi == IP46_TYPE_IP6)
18814         print (vam->ofp,
18815                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18816                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18817                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18818                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18819                format_ip6_address, fp->next_hop);
18820       else if (fp->afi == IP46_TYPE_IP4)
18821         print (vam->ofp,
18822                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
18823                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
18824                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
18825                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
18826                format_ip4_address, fp->next_hop);
18827       fp++;
18828     }
18829 }
18830
18831 static void vl_api_ip_fib_details_t_handler_json
18832   (vl_api_ip_fib_details_t * mp)
18833 {
18834   vat_main_t *vam = &vat_main;
18835   int count = ntohl (mp->count);
18836   vat_json_node_t *node = NULL;
18837   struct in_addr ip4;
18838   struct in6_addr ip6;
18839   vl_api_fib_path_t *fp;
18840   int i;
18841
18842   if (VAT_JSON_ARRAY != vam->json_tree.type)
18843     {
18844       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18845       vat_json_init_array (&vam->json_tree);
18846     }
18847   node = vat_json_array_add (&vam->json_tree);
18848
18849   vat_json_init_object (node);
18850   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
18851   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
18852   vat_json_object_add_ip4 (node, "prefix", ip4);
18853   vat_json_object_add_uint (node, "mask_length", mp->address_length);
18854   vat_json_object_add_uint (node, "path_count", count);
18855   fp = mp->path;
18856   for (i = 0; i < count; i++)
18857     {
18858       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18859       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18860       vat_json_object_add_uint (node, "is_local", fp->is_local);
18861       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
18862       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
18863       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
18864       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
18865       if (fp->afi == IP46_TYPE_IP4)
18866         {
18867           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
18868           vat_json_object_add_ip4 (node, "next_hop", ip4);
18869         }
18870       else if (fp->afi == IP46_TYPE_IP6)
18871         {
18872           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
18873           vat_json_object_add_ip6 (node, "next_hop", ip6);
18874         }
18875     }
18876 }
18877
18878 static int
18879 api_ip_fib_dump (vat_main_t * vam)
18880 {
18881   vl_api_ip_fib_dump_t *mp;
18882   vl_api_control_ping_t *mp_ping;
18883   int ret;
18884
18885   M (IP_FIB_DUMP, mp);
18886   S (mp);
18887
18888   /* Use a control ping for synchronization */
18889   MPING (CONTROL_PING, mp_ping);
18890   S (mp_ping);
18891
18892   W (ret);
18893   return ret;
18894 }
18895
18896 static int
18897 api_ip_mfib_dump (vat_main_t * vam)
18898 {
18899   vl_api_ip_mfib_dump_t *mp;
18900   vl_api_control_ping_t *mp_ping;
18901   int ret;
18902
18903   M (IP_MFIB_DUMP, mp);
18904   S (mp);
18905
18906   /* Use a control ping for synchronization */
18907   MPING (CONTROL_PING, mp_ping);
18908   S (mp_ping);
18909
18910   W (ret);
18911   return ret;
18912 }
18913
18914 static void vl_api_ip_neighbor_details_t_handler
18915   (vl_api_ip_neighbor_details_t * mp)
18916 {
18917   vat_main_t *vam = &vat_main;
18918
18919   print (vam->ofp, "%c %U %U",
18920          (mp->is_static) ? 'S' : 'D',
18921          format_ethernet_address, &mp->mac_address,
18922          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
18923          &mp->ip_address);
18924 }
18925
18926 static void vl_api_ip_neighbor_details_t_handler_json
18927   (vl_api_ip_neighbor_details_t * mp)
18928 {
18929
18930   vat_main_t *vam = &vat_main;
18931   vat_json_node_t *node;
18932   struct in_addr ip4;
18933   struct in6_addr ip6;
18934
18935   if (VAT_JSON_ARRAY != vam->json_tree.type)
18936     {
18937       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18938       vat_json_init_array (&vam->json_tree);
18939     }
18940   node = vat_json_array_add (&vam->json_tree);
18941
18942   vat_json_init_object (node);
18943   vat_json_object_add_string_copy (node, "flag",
18944                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
18945                                    "dynamic");
18946
18947   vat_json_object_add_string_copy (node, "link_layer",
18948                                    format (0, "%U", format_ethernet_address,
18949                                            &mp->mac_address));
18950
18951   if (mp->is_ipv6)
18952     {
18953       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
18954       vat_json_object_add_ip6 (node, "ip_address", ip6);
18955     }
18956   else
18957     {
18958       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
18959       vat_json_object_add_ip4 (node, "ip_address", ip4);
18960     }
18961 }
18962
18963 static int
18964 api_ip_neighbor_dump (vat_main_t * vam)
18965 {
18966   unformat_input_t *i = vam->input;
18967   vl_api_ip_neighbor_dump_t *mp;
18968   vl_api_control_ping_t *mp_ping;
18969   u8 is_ipv6 = 0;
18970   u32 sw_if_index = ~0;
18971   int ret;
18972
18973   /* Parse args required to build the message */
18974   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18975     {
18976       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18977         ;
18978       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18979         ;
18980       else if (unformat (i, "ip6"))
18981         is_ipv6 = 1;
18982       else
18983         break;
18984     }
18985
18986   if (sw_if_index == ~0)
18987     {
18988       errmsg ("missing interface name or sw_if_index");
18989       return -99;
18990     }
18991
18992   M (IP_NEIGHBOR_DUMP, mp);
18993   mp->is_ipv6 = (u8) is_ipv6;
18994   mp->sw_if_index = ntohl (sw_if_index);
18995   S (mp);
18996
18997   /* Use a control ping for synchronization */
18998   MPING (CONTROL_PING, mp_ping);
18999   S (mp_ping);
19000
19001   W (ret);
19002   return ret;
19003 }
19004
19005 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
19006 #define vl_api_ip6_fib_details_t_print vl_noop_handler
19007
19008 static void
19009 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
19010 {
19011   vat_main_t *vam = &vat_main;
19012   int count = ntohl (mp->count);
19013   vl_api_fib_path_t *fp;
19014   int i;
19015
19016   print (vam->ofp,
19017          "table-id %d, prefix %U/%d",
19018          ntohl (mp->table_id), format_ip6_address, mp->address,
19019          mp->address_length);
19020   fp = mp->path;
19021   for (i = 0; i < count; i++)
19022     {
19023       if (fp->afi == IP46_TYPE_IP6)
19024         print (vam->ofp,
19025                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19026                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19027                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19028                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19029                format_ip6_address, fp->next_hop);
19030       else if (fp->afi == IP46_TYPE_IP4)
19031         print (vam->ofp,
19032                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
19033                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
19034                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
19035                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
19036                format_ip4_address, fp->next_hop);
19037       fp++;
19038     }
19039 }
19040
19041 static void vl_api_ip6_fib_details_t_handler_json
19042   (vl_api_ip6_fib_details_t * mp)
19043 {
19044   vat_main_t *vam = &vat_main;
19045   int count = ntohl (mp->count);
19046   vat_json_node_t *node = NULL;
19047   struct in_addr ip4;
19048   struct in6_addr ip6;
19049   vl_api_fib_path_t *fp;
19050   int i;
19051
19052   if (VAT_JSON_ARRAY != vam->json_tree.type)
19053     {
19054       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19055       vat_json_init_array (&vam->json_tree);
19056     }
19057   node = vat_json_array_add (&vam->json_tree);
19058
19059   vat_json_init_object (node);
19060   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
19061   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
19062   vat_json_object_add_ip6 (node, "prefix", ip6);
19063   vat_json_object_add_uint (node, "mask_length", mp->address_length);
19064   vat_json_object_add_uint (node, "path_count", count);
19065   fp = mp->path;
19066   for (i = 0; i < count; i++)
19067     {
19068       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
19069       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
19070       vat_json_object_add_uint (node, "is_local", fp->is_local);
19071       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
19072       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
19073       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
19074       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
19075       if (fp->afi == IP46_TYPE_IP4)
19076         {
19077           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
19078           vat_json_object_add_ip4 (node, "next_hop", ip4);
19079         }
19080       else if (fp->afi == IP46_TYPE_IP6)
19081         {
19082           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
19083           vat_json_object_add_ip6 (node, "next_hop", ip6);
19084         }
19085     }
19086 }
19087
19088 static int
19089 api_ip6_fib_dump (vat_main_t * vam)
19090 {
19091   vl_api_ip6_fib_dump_t *mp;
19092   vl_api_control_ping_t *mp_ping;
19093   int ret;
19094
19095   M (IP6_FIB_DUMP, mp);
19096   S (mp);
19097
19098   /* Use a control ping for synchronization */
19099   MPING (CONTROL_PING, mp_ping);
19100   S (mp_ping);
19101
19102   W (ret);
19103   return ret;
19104 }
19105
19106 static int
19107 api_ip6_mfib_dump (vat_main_t * vam)
19108 {
19109   vl_api_ip6_mfib_dump_t *mp;
19110   vl_api_control_ping_t *mp_ping;
19111   int ret;
19112
19113   M (IP6_MFIB_DUMP, mp);
19114   S (mp);
19115
19116   /* Use a control ping for synchronization */
19117   MPING (CONTROL_PING, mp_ping);
19118   S (mp_ping);
19119
19120   W (ret);
19121   return ret;
19122 }
19123
19124 int
19125 api_classify_table_ids (vat_main_t * vam)
19126 {
19127   vl_api_classify_table_ids_t *mp;
19128   int ret;
19129
19130   /* Construct the API message */
19131   M (CLASSIFY_TABLE_IDS, mp);
19132   mp->context = 0;
19133
19134   S (mp);
19135   W (ret);
19136   return ret;
19137 }
19138
19139 int
19140 api_classify_table_by_interface (vat_main_t * vam)
19141 {
19142   unformat_input_t *input = vam->input;
19143   vl_api_classify_table_by_interface_t *mp;
19144
19145   u32 sw_if_index = ~0;
19146   int ret;
19147   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19148     {
19149       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19150         ;
19151       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19152         ;
19153       else
19154         break;
19155     }
19156   if (sw_if_index == ~0)
19157     {
19158       errmsg ("missing interface name or sw_if_index");
19159       return -99;
19160     }
19161
19162   /* Construct the API message */
19163   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
19164   mp->context = 0;
19165   mp->sw_if_index = ntohl (sw_if_index);
19166
19167   S (mp);
19168   W (ret);
19169   return ret;
19170 }
19171
19172 int
19173 api_classify_table_info (vat_main_t * vam)
19174 {
19175   unformat_input_t *input = vam->input;
19176   vl_api_classify_table_info_t *mp;
19177
19178   u32 table_id = ~0;
19179   int ret;
19180   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19181     {
19182       if (unformat (input, "table_id %d", &table_id))
19183         ;
19184       else
19185         break;
19186     }
19187   if (table_id == ~0)
19188     {
19189       errmsg ("missing table id");
19190       return -99;
19191     }
19192
19193   /* Construct the API message */
19194   M (CLASSIFY_TABLE_INFO, mp);
19195   mp->context = 0;
19196   mp->table_id = ntohl (table_id);
19197
19198   S (mp);
19199   W (ret);
19200   return ret;
19201 }
19202
19203 int
19204 api_classify_session_dump (vat_main_t * vam)
19205 {
19206   unformat_input_t *input = vam->input;
19207   vl_api_classify_session_dump_t *mp;
19208   vl_api_control_ping_t *mp_ping;
19209
19210   u32 table_id = ~0;
19211   int ret;
19212   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19213     {
19214       if (unformat (input, "table_id %d", &table_id))
19215         ;
19216       else
19217         break;
19218     }
19219   if (table_id == ~0)
19220     {
19221       errmsg ("missing table id");
19222       return -99;
19223     }
19224
19225   /* Construct the API message */
19226   M (CLASSIFY_SESSION_DUMP, mp);
19227   mp->context = 0;
19228   mp->table_id = ntohl (table_id);
19229   S (mp);
19230
19231   /* Use a control ping for synchronization */
19232   MPING (CONTROL_PING, mp_ping);
19233   S (mp_ping);
19234
19235   W (ret);
19236   return ret;
19237 }
19238
19239 static void
19240 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19241 {
19242   vat_main_t *vam = &vat_main;
19243
19244   print (vam->ofp, "collector_address %U, collector_port %d, "
19245          "src_address %U, vrf_id %d, path_mtu %u, "
19246          "template_interval %u, udp_checksum %d",
19247          format_ip4_address, mp->collector_address,
19248          ntohs (mp->collector_port),
19249          format_ip4_address, mp->src_address,
19250          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19251          ntohl (mp->template_interval), mp->udp_checksum);
19252
19253   vam->retval = 0;
19254   vam->result_ready = 1;
19255 }
19256
19257 static void
19258   vl_api_ipfix_exporter_details_t_handler_json
19259   (vl_api_ipfix_exporter_details_t * mp)
19260 {
19261   vat_main_t *vam = &vat_main;
19262   vat_json_node_t node;
19263   struct in_addr collector_address;
19264   struct in_addr src_address;
19265
19266   vat_json_init_object (&node);
19267   clib_memcpy (&collector_address, &mp->collector_address,
19268                sizeof (collector_address));
19269   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19270   vat_json_object_add_uint (&node, "collector_port",
19271                             ntohs (mp->collector_port));
19272   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19273   vat_json_object_add_ip4 (&node, "src_address", src_address);
19274   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19275   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19276   vat_json_object_add_uint (&node, "template_interval",
19277                             ntohl (mp->template_interval));
19278   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19279
19280   vat_json_print (vam->ofp, &node);
19281   vat_json_free (&node);
19282   vam->retval = 0;
19283   vam->result_ready = 1;
19284 }
19285
19286 int
19287 api_ipfix_exporter_dump (vat_main_t * vam)
19288 {
19289   vl_api_ipfix_exporter_dump_t *mp;
19290   int ret;
19291
19292   /* Construct the API message */
19293   M (IPFIX_EXPORTER_DUMP, mp);
19294   mp->context = 0;
19295
19296   S (mp);
19297   W (ret);
19298   return ret;
19299 }
19300
19301 static int
19302 api_ipfix_classify_stream_dump (vat_main_t * vam)
19303 {
19304   vl_api_ipfix_classify_stream_dump_t *mp;
19305   int ret;
19306
19307   /* Construct the API message */
19308   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19309   mp->context = 0;
19310
19311   S (mp);
19312   W (ret);
19313   return ret;
19314   /* NOTREACHED */
19315   return 0;
19316 }
19317
19318 static void
19319   vl_api_ipfix_classify_stream_details_t_handler
19320   (vl_api_ipfix_classify_stream_details_t * mp)
19321 {
19322   vat_main_t *vam = &vat_main;
19323   print (vam->ofp, "domain_id %d, src_port %d",
19324          ntohl (mp->domain_id), ntohs (mp->src_port));
19325   vam->retval = 0;
19326   vam->result_ready = 1;
19327 }
19328
19329 static void
19330   vl_api_ipfix_classify_stream_details_t_handler_json
19331   (vl_api_ipfix_classify_stream_details_t * mp)
19332 {
19333   vat_main_t *vam = &vat_main;
19334   vat_json_node_t node;
19335
19336   vat_json_init_object (&node);
19337   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19338   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19339
19340   vat_json_print (vam->ofp, &node);
19341   vat_json_free (&node);
19342   vam->retval = 0;
19343   vam->result_ready = 1;
19344 }
19345
19346 static int
19347 api_ipfix_classify_table_dump (vat_main_t * vam)
19348 {
19349   vl_api_ipfix_classify_table_dump_t *mp;
19350   vl_api_control_ping_t *mp_ping;
19351   int ret;
19352
19353   if (!vam->json_output)
19354     {
19355       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19356              "transport_protocol");
19357     }
19358
19359   /* Construct the API message */
19360   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19361
19362   /* send it... */
19363   S (mp);
19364
19365   /* Use a control ping for synchronization */
19366   MPING (CONTROL_PING, mp_ping);
19367   S (mp_ping);
19368
19369   W (ret);
19370   return ret;
19371 }
19372
19373 static void
19374   vl_api_ipfix_classify_table_details_t_handler
19375   (vl_api_ipfix_classify_table_details_t * mp)
19376 {
19377   vat_main_t *vam = &vat_main;
19378   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19379          mp->transport_protocol);
19380 }
19381
19382 static void
19383   vl_api_ipfix_classify_table_details_t_handler_json
19384   (vl_api_ipfix_classify_table_details_t * mp)
19385 {
19386   vat_json_node_t *node = NULL;
19387   vat_main_t *vam = &vat_main;
19388
19389   if (VAT_JSON_ARRAY != vam->json_tree.type)
19390     {
19391       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19392       vat_json_init_array (&vam->json_tree);
19393     }
19394
19395   node = vat_json_array_add (&vam->json_tree);
19396   vat_json_init_object (node);
19397
19398   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19399   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19400   vat_json_object_add_uint (node, "transport_protocol",
19401                             mp->transport_protocol);
19402 }
19403
19404 static int
19405 api_sw_interface_span_enable_disable (vat_main_t * vam)
19406 {
19407   unformat_input_t *i = vam->input;
19408   vl_api_sw_interface_span_enable_disable_t *mp;
19409   u32 src_sw_if_index = ~0;
19410   u32 dst_sw_if_index = ~0;
19411   u8 state = 3;
19412   int ret;
19413   u8 is_l2 = 0;
19414
19415   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19416     {
19417       if (unformat
19418           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19419         ;
19420       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19421         ;
19422       else
19423         if (unformat
19424             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19425         ;
19426       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19427         ;
19428       else if (unformat (i, "disable"))
19429         state = 0;
19430       else if (unformat (i, "rx"))
19431         state = 1;
19432       else if (unformat (i, "tx"))
19433         state = 2;
19434       else if (unformat (i, "both"))
19435         state = 3;
19436       else if (unformat (i, "l2"))
19437         is_l2 = 1;
19438       else
19439         break;
19440     }
19441
19442   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19443
19444   mp->sw_if_index_from = htonl (src_sw_if_index);
19445   mp->sw_if_index_to = htonl (dst_sw_if_index);
19446   mp->state = state;
19447   mp->is_l2 = is_l2;
19448
19449   S (mp);
19450   W (ret);
19451   return ret;
19452 }
19453
19454 static void
19455 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19456                                             * mp)
19457 {
19458   vat_main_t *vam = &vat_main;
19459   u8 *sw_if_from_name = 0;
19460   u8 *sw_if_to_name = 0;
19461   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19462   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19463   char *states[] = { "none", "rx", "tx", "both" };
19464   hash_pair_t *p;
19465
19466   /* *INDENT-OFF* */
19467   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19468   ({
19469     if ((u32) p->value[0] == sw_if_index_from)
19470       {
19471         sw_if_from_name = (u8 *)(p->key);
19472         if (sw_if_to_name)
19473           break;
19474       }
19475     if ((u32) p->value[0] == sw_if_index_to)
19476       {
19477         sw_if_to_name = (u8 *)(p->key);
19478         if (sw_if_from_name)
19479           break;
19480       }
19481   }));
19482   /* *INDENT-ON* */
19483   print (vam->ofp, "%20s => %20s (%s)",
19484          sw_if_from_name, sw_if_to_name, states[mp->state]);
19485 }
19486
19487 static void
19488   vl_api_sw_interface_span_details_t_handler_json
19489   (vl_api_sw_interface_span_details_t * mp)
19490 {
19491   vat_main_t *vam = &vat_main;
19492   vat_json_node_t *node = NULL;
19493   u8 *sw_if_from_name = 0;
19494   u8 *sw_if_to_name = 0;
19495   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19496   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19497   hash_pair_t *p;
19498
19499   /* *INDENT-OFF* */
19500   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19501   ({
19502     if ((u32) p->value[0] == sw_if_index_from)
19503       {
19504         sw_if_from_name = (u8 *)(p->key);
19505         if (sw_if_to_name)
19506           break;
19507       }
19508     if ((u32) p->value[0] == sw_if_index_to)
19509       {
19510         sw_if_to_name = (u8 *)(p->key);
19511         if (sw_if_from_name)
19512           break;
19513       }
19514   }));
19515   /* *INDENT-ON* */
19516
19517   if (VAT_JSON_ARRAY != vam->json_tree.type)
19518     {
19519       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19520       vat_json_init_array (&vam->json_tree);
19521     }
19522   node = vat_json_array_add (&vam->json_tree);
19523
19524   vat_json_init_object (node);
19525   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19526   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19527   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19528   if (0 != sw_if_to_name)
19529     {
19530       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19531     }
19532   vat_json_object_add_uint (node, "state", mp->state);
19533 }
19534
19535 static int
19536 api_sw_interface_span_dump (vat_main_t * vam)
19537 {
19538   unformat_input_t *input = vam->input;
19539   vl_api_sw_interface_span_dump_t *mp;
19540   vl_api_control_ping_t *mp_ping;
19541   u8 is_l2 = 0;
19542   int ret;
19543
19544   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19545     {
19546       if (unformat (input, "l2"))
19547         is_l2 = 1;
19548       else
19549         break;
19550     }
19551
19552   M (SW_INTERFACE_SPAN_DUMP, mp);
19553   mp->is_l2 = is_l2;
19554   S (mp);
19555
19556   /* Use a control ping for synchronization */
19557   MPING (CONTROL_PING, mp_ping);
19558   S (mp_ping);
19559
19560   W (ret);
19561   return ret;
19562 }
19563
19564 int
19565 api_pg_create_interface (vat_main_t * vam)
19566 {
19567   unformat_input_t *input = vam->input;
19568   vl_api_pg_create_interface_t *mp;
19569
19570   u32 if_id = ~0;
19571   int ret;
19572   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19573     {
19574       if (unformat (input, "if_id %d", &if_id))
19575         ;
19576       else
19577         break;
19578     }
19579   if (if_id == ~0)
19580     {
19581       errmsg ("missing pg interface index");
19582       return -99;
19583     }
19584
19585   /* Construct the API message */
19586   M (PG_CREATE_INTERFACE, mp);
19587   mp->context = 0;
19588   mp->interface_id = ntohl (if_id);
19589
19590   S (mp);
19591   W (ret);
19592   return ret;
19593 }
19594
19595 int
19596 api_pg_capture (vat_main_t * vam)
19597 {
19598   unformat_input_t *input = vam->input;
19599   vl_api_pg_capture_t *mp;
19600
19601   u32 if_id = ~0;
19602   u8 enable = 1;
19603   u32 count = 1;
19604   u8 pcap_file_set = 0;
19605   u8 *pcap_file = 0;
19606   int ret;
19607   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19608     {
19609       if (unformat (input, "if_id %d", &if_id))
19610         ;
19611       else if (unformat (input, "pcap %s", &pcap_file))
19612         pcap_file_set = 1;
19613       else if (unformat (input, "count %d", &count))
19614         ;
19615       else if (unformat (input, "disable"))
19616         enable = 0;
19617       else
19618         break;
19619     }
19620   if (if_id == ~0)
19621     {
19622       errmsg ("missing pg interface index");
19623       return -99;
19624     }
19625   if (pcap_file_set > 0)
19626     {
19627       if (vec_len (pcap_file) > 255)
19628         {
19629           errmsg ("pcap file name is too long");
19630           return -99;
19631         }
19632     }
19633
19634   u32 name_len = vec_len (pcap_file);
19635   /* Construct the API message */
19636   M (PG_CAPTURE, mp);
19637   mp->context = 0;
19638   mp->interface_id = ntohl (if_id);
19639   mp->is_enabled = enable;
19640   mp->count = ntohl (count);
19641   mp->pcap_name_length = ntohl (name_len);
19642   if (pcap_file_set != 0)
19643     {
19644       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19645     }
19646   vec_free (pcap_file);
19647
19648   S (mp);
19649   W (ret);
19650   return ret;
19651 }
19652
19653 int
19654 api_pg_enable_disable (vat_main_t * vam)
19655 {
19656   unformat_input_t *input = vam->input;
19657   vl_api_pg_enable_disable_t *mp;
19658
19659   u8 enable = 1;
19660   u8 stream_name_set = 0;
19661   u8 *stream_name = 0;
19662   int ret;
19663   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19664     {
19665       if (unformat (input, "stream %s", &stream_name))
19666         stream_name_set = 1;
19667       else if (unformat (input, "disable"))
19668         enable = 0;
19669       else
19670         break;
19671     }
19672
19673   if (stream_name_set > 0)
19674     {
19675       if (vec_len (stream_name) > 255)
19676         {
19677           errmsg ("stream name too long");
19678           return -99;
19679         }
19680     }
19681
19682   u32 name_len = vec_len (stream_name);
19683   /* Construct the API message */
19684   M (PG_ENABLE_DISABLE, mp);
19685   mp->context = 0;
19686   mp->is_enabled = enable;
19687   if (stream_name_set != 0)
19688     {
19689       mp->stream_name_length = ntohl (name_len);
19690       clib_memcpy (mp->stream_name, stream_name, name_len);
19691     }
19692   vec_free (stream_name);
19693
19694   S (mp);
19695   W (ret);
19696   return ret;
19697 }
19698
19699 int
19700 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19701 {
19702   unformat_input_t *input = vam->input;
19703   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19704
19705   u16 *low_ports = 0;
19706   u16 *high_ports = 0;
19707   u16 this_low;
19708   u16 this_hi;
19709   ip4_address_t ip4_addr;
19710   ip6_address_t ip6_addr;
19711   u32 length;
19712   u32 tmp, tmp2;
19713   u8 prefix_set = 0;
19714   u32 vrf_id = ~0;
19715   u8 is_add = 1;
19716   u8 is_ipv6 = 0;
19717   int ret;
19718
19719   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19720     {
19721       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
19722         {
19723           prefix_set = 1;
19724         }
19725       else
19726         if (unformat
19727             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
19728         {
19729           prefix_set = 1;
19730           is_ipv6 = 1;
19731         }
19732       else if (unformat (input, "vrf %d", &vrf_id))
19733         ;
19734       else if (unformat (input, "del"))
19735         is_add = 0;
19736       else if (unformat (input, "port %d", &tmp))
19737         {
19738           if (tmp == 0 || tmp > 65535)
19739             {
19740               errmsg ("port %d out of range", tmp);
19741               return -99;
19742             }
19743           this_low = tmp;
19744           this_hi = this_low + 1;
19745           vec_add1 (low_ports, this_low);
19746           vec_add1 (high_ports, this_hi);
19747         }
19748       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19749         {
19750           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19751             {
19752               errmsg ("incorrect range parameters");
19753               return -99;
19754             }
19755           this_low = tmp;
19756           /* Note: in debug CLI +1 is added to high before
19757              passing to real fn that does "the work"
19758              (ip_source_and_port_range_check_add_del).
19759              This fn is a wrapper around the binary API fn a
19760              control plane will call, which expects this increment
19761              to have occurred. Hence letting the binary API control
19762              plane fn do the increment for consistency between VAT
19763              and other control planes.
19764            */
19765           this_hi = tmp2;
19766           vec_add1 (low_ports, this_low);
19767           vec_add1 (high_ports, this_hi);
19768         }
19769       else
19770         break;
19771     }
19772
19773   if (prefix_set == 0)
19774     {
19775       errmsg ("<address>/<mask> not specified");
19776       return -99;
19777     }
19778
19779   if (vrf_id == ~0)
19780     {
19781       errmsg ("VRF ID required, not specified");
19782       return -99;
19783     }
19784
19785   if (vrf_id == 0)
19786     {
19787       errmsg
19788         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19789       return -99;
19790     }
19791
19792   if (vec_len (low_ports) == 0)
19793     {
19794       errmsg ("At least one port or port range required");
19795       return -99;
19796     }
19797
19798   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19799
19800   mp->is_add = is_add;
19801
19802   if (is_ipv6)
19803     {
19804       mp->is_ipv6 = 1;
19805       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
19806     }
19807   else
19808     {
19809       mp->is_ipv6 = 0;
19810       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
19811     }
19812
19813   mp->mask_length = length;
19814   mp->number_of_ranges = vec_len (low_ports);
19815
19816   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
19817   vec_free (low_ports);
19818
19819   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
19820   vec_free (high_ports);
19821
19822   mp->vrf_id = ntohl (vrf_id);
19823
19824   S (mp);
19825   W (ret);
19826   return ret;
19827 }
19828
19829 int
19830 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
19831 {
19832   unformat_input_t *input = vam->input;
19833   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
19834   u32 sw_if_index = ~0;
19835   int vrf_set = 0;
19836   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
19837   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
19838   u8 is_add = 1;
19839   int ret;
19840
19841   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19842     {
19843       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19844         ;
19845       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19846         ;
19847       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
19848         vrf_set = 1;
19849       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
19850         vrf_set = 1;
19851       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
19852         vrf_set = 1;
19853       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
19854         vrf_set = 1;
19855       else if (unformat (input, "del"))
19856         is_add = 0;
19857       else
19858         break;
19859     }
19860
19861   if (sw_if_index == ~0)
19862     {
19863       errmsg ("Interface required but not specified");
19864       return -99;
19865     }
19866
19867   if (vrf_set == 0)
19868     {
19869       errmsg ("VRF ID required but not specified");
19870       return -99;
19871     }
19872
19873   if (tcp_out_vrf_id == 0
19874       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
19875     {
19876       errmsg
19877         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19878       return -99;
19879     }
19880
19881   /* Construct the API message */
19882   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
19883
19884   mp->sw_if_index = ntohl (sw_if_index);
19885   mp->is_add = is_add;
19886   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
19887   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
19888   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
19889   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
19890
19891   /* send it... */
19892   S (mp);
19893
19894   /* Wait for a reply... */
19895   W (ret);
19896   return ret;
19897 }
19898
19899 static int
19900 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
19901 {
19902   unformat_input_t *i = vam->input;
19903   vl_api_ipsec_gre_add_del_tunnel_t *mp;
19904   u32 local_sa_id = 0;
19905   u32 remote_sa_id = 0;
19906   ip4_address_t src_address;
19907   ip4_address_t dst_address;
19908   u8 is_add = 1;
19909   int ret;
19910
19911   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19912     {
19913       if (unformat (i, "local_sa %d", &local_sa_id))
19914         ;
19915       else if (unformat (i, "remote_sa %d", &remote_sa_id))
19916         ;
19917       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
19918         ;
19919       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
19920         ;
19921       else if (unformat (i, "del"))
19922         is_add = 0;
19923       else
19924         {
19925           clib_warning ("parse error '%U'", format_unformat_error, i);
19926           return -99;
19927         }
19928     }
19929
19930   M (IPSEC_GRE_ADD_DEL_TUNNEL, mp);
19931
19932   mp->local_sa_id = ntohl (local_sa_id);
19933   mp->remote_sa_id = ntohl (remote_sa_id);
19934   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
19935   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
19936   mp->is_add = is_add;
19937
19938   S (mp);
19939   W (ret);
19940   return ret;
19941 }
19942
19943 static int
19944 api_punt (vat_main_t * vam)
19945 {
19946   unformat_input_t *i = vam->input;
19947   vl_api_punt_t *mp;
19948   u32 ipv = ~0;
19949   u32 protocol = ~0;
19950   u32 port = ~0;
19951   int is_add = 1;
19952   int ret;
19953
19954   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19955     {
19956       if (unformat (i, "ip %d", &ipv))
19957         ;
19958       else if (unformat (i, "protocol %d", &protocol))
19959         ;
19960       else if (unformat (i, "port %d", &port))
19961         ;
19962       else if (unformat (i, "del"))
19963         is_add = 0;
19964       else
19965         {
19966           clib_warning ("parse error '%U'", format_unformat_error, i);
19967           return -99;
19968         }
19969     }
19970
19971   M (PUNT, mp);
19972
19973   mp->is_add = (u8) is_add;
19974   mp->ipv = (u8) ipv;
19975   mp->l4_protocol = (u8) protocol;
19976   mp->l4_port = htons ((u16) port);
19977
19978   S (mp);
19979   W (ret);
19980   return ret;
19981 }
19982
19983 static void vl_api_ipsec_gre_tunnel_details_t_handler
19984   (vl_api_ipsec_gre_tunnel_details_t * mp)
19985 {
19986   vat_main_t *vam = &vat_main;
19987
19988   print (vam->ofp, "%11d%15U%15U%14d%14d",
19989          ntohl (mp->sw_if_index),
19990          format_ip4_address, &mp->src_address,
19991          format_ip4_address, &mp->dst_address,
19992          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
19993 }
19994
19995 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
19996   (vl_api_ipsec_gre_tunnel_details_t * mp)
19997 {
19998   vat_main_t *vam = &vat_main;
19999   vat_json_node_t *node = NULL;
20000   struct in_addr ip4;
20001
20002   if (VAT_JSON_ARRAY != vam->json_tree.type)
20003     {
20004       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20005       vat_json_init_array (&vam->json_tree);
20006     }
20007   node = vat_json_array_add (&vam->json_tree);
20008
20009   vat_json_init_object (node);
20010   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
20011   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
20012   vat_json_object_add_ip4 (node, "src_address", ip4);
20013   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
20014   vat_json_object_add_ip4 (node, "dst_address", ip4);
20015   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
20016   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
20017 }
20018
20019 static int
20020 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
20021 {
20022   unformat_input_t *i = vam->input;
20023   vl_api_ipsec_gre_tunnel_dump_t *mp;
20024   vl_api_control_ping_t *mp_ping;
20025   u32 sw_if_index;
20026   u8 sw_if_index_set = 0;
20027   int ret;
20028
20029   /* Parse args required to build the message */
20030   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20031     {
20032       if (unformat (i, "sw_if_index %d", &sw_if_index))
20033         sw_if_index_set = 1;
20034       else
20035         break;
20036     }
20037
20038   if (sw_if_index_set == 0)
20039     {
20040       sw_if_index = ~0;
20041     }
20042
20043   if (!vam->json_output)
20044     {
20045       print (vam->ofp, "%11s%15s%15s%14s%14s",
20046              "sw_if_index", "src_address", "dst_address",
20047              "local_sa_id", "remote_sa_id");
20048     }
20049
20050   /* Get list of gre-tunnel interfaces */
20051   M (IPSEC_GRE_TUNNEL_DUMP, mp);
20052
20053   mp->sw_if_index = htonl (sw_if_index);
20054
20055   S (mp);
20056
20057   /* Use a control ping for synchronization */
20058   MPING (CONTROL_PING, mp_ping);
20059   S (mp_ping);
20060
20061   W (ret);
20062   return ret;
20063 }
20064
20065 static int
20066 api_delete_subif (vat_main_t * vam)
20067 {
20068   unformat_input_t *i = vam->input;
20069   vl_api_delete_subif_t *mp;
20070   u32 sw_if_index = ~0;
20071   int ret;
20072
20073   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20074     {
20075       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20076         ;
20077       if (unformat (i, "sw_if_index %d", &sw_if_index))
20078         ;
20079       else
20080         break;
20081     }
20082
20083   if (sw_if_index == ~0)
20084     {
20085       errmsg ("missing sw_if_index");
20086       return -99;
20087     }
20088
20089   /* Construct the API message */
20090   M (DELETE_SUBIF, mp);
20091   mp->sw_if_index = ntohl (sw_if_index);
20092
20093   S (mp);
20094   W (ret);
20095   return ret;
20096 }
20097
20098 #define foreach_pbb_vtr_op      \
20099 _("disable",  L2_VTR_DISABLED)  \
20100 _("pop",  L2_VTR_POP_2)         \
20101 _("push",  L2_VTR_PUSH_2)
20102
20103 static int
20104 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
20105 {
20106   unformat_input_t *i = vam->input;
20107   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
20108   u32 sw_if_index = ~0, vtr_op = ~0;
20109   u16 outer_tag = ~0;
20110   u8 dmac[6], smac[6];
20111   u8 dmac_set = 0, smac_set = 0;
20112   u16 vlanid = 0;
20113   u32 sid = ~0;
20114   u32 tmp;
20115   int ret;
20116
20117   /* Shut up coverity */
20118   memset (dmac, 0, sizeof (dmac));
20119   memset (smac, 0, sizeof (smac));
20120
20121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20122     {
20123       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20124         ;
20125       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20126         ;
20127       else if (unformat (i, "vtr_op %d", &vtr_op))
20128         ;
20129 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
20130       foreach_pbb_vtr_op
20131 #undef _
20132         else if (unformat (i, "translate_pbb_stag"))
20133         {
20134           if (unformat (i, "%d", &tmp))
20135             {
20136               vtr_op = L2_VTR_TRANSLATE_2_1;
20137               outer_tag = tmp;
20138             }
20139           else
20140             {
20141               errmsg
20142                 ("translate_pbb_stag operation requires outer tag definition");
20143               return -99;
20144             }
20145         }
20146       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
20147         dmac_set++;
20148       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
20149         smac_set++;
20150       else if (unformat (i, "sid %d", &sid))
20151         ;
20152       else if (unformat (i, "vlanid %d", &tmp))
20153         vlanid = tmp;
20154       else
20155         {
20156           clib_warning ("parse error '%U'", format_unformat_error, i);
20157           return -99;
20158         }
20159     }
20160
20161   if ((sw_if_index == ~0) || (vtr_op == ~0))
20162     {
20163       errmsg ("missing sw_if_index or vtr operation");
20164       return -99;
20165     }
20166   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
20167       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
20168     {
20169       errmsg
20170         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
20171       return -99;
20172     }
20173
20174   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
20175   mp->sw_if_index = ntohl (sw_if_index);
20176   mp->vtr_op = ntohl (vtr_op);
20177   mp->outer_tag = ntohs (outer_tag);
20178   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
20179   clib_memcpy (mp->b_smac, smac, sizeof (smac));
20180   mp->b_vlanid = ntohs (vlanid);
20181   mp->i_sid = ntohl (sid);
20182
20183   S (mp);
20184   W (ret);
20185   return ret;
20186 }
20187
20188 static int
20189 api_flow_classify_set_interface (vat_main_t * vam)
20190 {
20191   unformat_input_t *i = vam->input;
20192   vl_api_flow_classify_set_interface_t *mp;
20193   u32 sw_if_index;
20194   int sw_if_index_set;
20195   u32 ip4_table_index = ~0;
20196   u32 ip6_table_index = ~0;
20197   u8 is_add = 1;
20198   int ret;
20199
20200   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20201     {
20202       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20203         sw_if_index_set = 1;
20204       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20205         sw_if_index_set = 1;
20206       else if (unformat (i, "del"))
20207         is_add = 0;
20208       else if (unformat (i, "ip4-table %d", &ip4_table_index))
20209         ;
20210       else if (unformat (i, "ip6-table %d", &ip6_table_index))
20211         ;
20212       else
20213         {
20214           clib_warning ("parse error '%U'", format_unformat_error, i);
20215           return -99;
20216         }
20217     }
20218
20219   if (sw_if_index_set == 0)
20220     {
20221       errmsg ("missing interface name or sw_if_index");
20222       return -99;
20223     }
20224
20225   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
20226
20227   mp->sw_if_index = ntohl (sw_if_index);
20228   mp->ip4_table_index = ntohl (ip4_table_index);
20229   mp->ip6_table_index = ntohl (ip6_table_index);
20230   mp->is_add = is_add;
20231
20232   S (mp);
20233   W (ret);
20234   return ret;
20235 }
20236
20237 static int
20238 api_flow_classify_dump (vat_main_t * vam)
20239 {
20240   unformat_input_t *i = vam->input;
20241   vl_api_flow_classify_dump_t *mp;
20242   vl_api_control_ping_t *mp_ping;
20243   u8 type = FLOW_CLASSIFY_N_TABLES;
20244   int ret;
20245
20246   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
20247     ;
20248   else
20249     {
20250       errmsg ("classify table type must be specified");
20251       return -99;
20252     }
20253
20254   if (!vam->json_output)
20255     {
20256       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
20257     }
20258
20259   M (FLOW_CLASSIFY_DUMP, mp);
20260   mp->type = type;
20261   /* send it... */
20262   S (mp);
20263
20264   /* Use a control ping for synchronization */
20265   MPING (CONTROL_PING, mp_ping);
20266   S (mp_ping);
20267
20268   /* Wait for a reply... */
20269   W (ret);
20270   return ret;
20271 }
20272
20273 static int
20274 api_feature_enable_disable (vat_main_t * vam)
20275 {
20276   unformat_input_t *i = vam->input;
20277   vl_api_feature_enable_disable_t *mp;
20278   u8 *arc_name = 0;
20279   u8 *feature_name = 0;
20280   u32 sw_if_index = ~0;
20281   u8 enable = 1;
20282   int ret;
20283
20284   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20285     {
20286       if (unformat (i, "arc_name %s", &arc_name))
20287         ;
20288       else if (unformat (i, "feature_name %s", &feature_name))
20289         ;
20290       else
20291         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20292         ;
20293       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20294         ;
20295       else if (unformat (i, "disable"))
20296         enable = 0;
20297       else
20298         break;
20299     }
20300
20301   if (arc_name == 0)
20302     {
20303       errmsg ("missing arc name");
20304       return -99;
20305     }
20306   if (vec_len (arc_name) > 63)
20307     {
20308       errmsg ("arc name too long");
20309     }
20310
20311   if (feature_name == 0)
20312     {
20313       errmsg ("missing feature name");
20314       return -99;
20315     }
20316   if (vec_len (feature_name) > 63)
20317     {
20318       errmsg ("feature name too long");
20319     }
20320
20321   if (sw_if_index == ~0)
20322     {
20323       errmsg ("missing interface name or sw_if_index");
20324       return -99;
20325     }
20326
20327   /* Construct the API message */
20328   M (FEATURE_ENABLE_DISABLE, mp);
20329   mp->sw_if_index = ntohl (sw_if_index);
20330   mp->enable = enable;
20331   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20332   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20333   vec_free (arc_name);
20334   vec_free (feature_name);
20335
20336   S (mp);
20337   W (ret);
20338   return ret;
20339 }
20340
20341 static int
20342 api_sw_interface_tag_add_del (vat_main_t * vam)
20343 {
20344   unformat_input_t *i = vam->input;
20345   vl_api_sw_interface_tag_add_del_t *mp;
20346   u32 sw_if_index = ~0;
20347   u8 *tag = 0;
20348   u8 enable = 1;
20349   int ret;
20350
20351   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20352     {
20353       if (unformat (i, "tag %s", &tag))
20354         ;
20355       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20356         ;
20357       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20358         ;
20359       else if (unformat (i, "del"))
20360         enable = 0;
20361       else
20362         break;
20363     }
20364
20365   if (sw_if_index == ~0)
20366     {
20367       errmsg ("missing interface name or sw_if_index");
20368       return -99;
20369     }
20370
20371   if (enable && (tag == 0))
20372     {
20373       errmsg ("no tag specified");
20374       return -99;
20375     }
20376
20377   /* Construct the API message */
20378   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20379   mp->sw_if_index = ntohl (sw_if_index);
20380   mp->is_add = enable;
20381   if (enable)
20382     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20383   vec_free (tag);
20384
20385   S (mp);
20386   W (ret);
20387   return ret;
20388 }
20389
20390 static void vl_api_l2_xconnect_details_t_handler
20391   (vl_api_l2_xconnect_details_t * mp)
20392 {
20393   vat_main_t *vam = &vat_main;
20394
20395   print (vam->ofp, "%15d%15d",
20396          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20397 }
20398
20399 static void vl_api_l2_xconnect_details_t_handler_json
20400   (vl_api_l2_xconnect_details_t * mp)
20401 {
20402   vat_main_t *vam = &vat_main;
20403   vat_json_node_t *node = NULL;
20404
20405   if (VAT_JSON_ARRAY != vam->json_tree.type)
20406     {
20407       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20408       vat_json_init_array (&vam->json_tree);
20409     }
20410   node = vat_json_array_add (&vam->json_tree);
20411
20412   vat_json_init_object (node);
20413   vat_json_object_add_uint (node, "rx_sw_if_index",
20414                             ntohl (mp->rx_sw_if_index));
20415   vat_json_object_add_uint (node, "tx_sw_if_index",
20416                             ntohl (mp->tx_sw_if_index));
20417 }
20418
20419 static int
20420 api_l2_xconnect_dump (vat_main_t * vam)
20421 {
20422   vl_api_l2_xconnect_dump_t *mp;
20423   vl_api_control_ping_t *mp_ping;
20424   int ret;
20425
20426   if (!vam->json_output)
20427     {
20428       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20429     }
20430
20431   M (L2_XCONNECT_DUMP, mp);
20432
20433   S (mp);
20434
20435   /* Use a control ping for synchronization */
20436   MPING (CONTROL_PING, mp_ping);
20437   S (mp_ping);
20438
20439   W (ret);
20440   return ret;
20441 }
20442
20443 static int
20444 api_sw_interface_set_mtu (vat_main_t * vam)
20445 {
20446   unformat_input_t *i = vam->input;
20447   vl_api_sw_interface_set_mtu_t *mp;
20448   u32 sw_if_index = ~0;
20449   u32 mtu = 0;
20450   int ret;
20451
20452   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20453     {
20454       if (unformat (i, "mtu %d", &mtu))
20455         ;
20456       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20457         ;
20458       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20459         ;
20460       else
20461         break;
20462     }
20463
20464   if (sw_if_index == ~0)
20465     {
20466       errmsg ("missing interface name or sw_if_index");
20467       return -99;
20468     }
20469
20470   if (mtu == 0)
20471     {
20472       errmsg ("no mtu specified");
20473       return -99;
20474     }
20475
20476   /* Construct the API message */
20477   M (SW_INTERFACE_SET_MTU, mp);
20478   mp->sw_if_index = ntohl (sw_if_index);
20479   mp->mtu = ntohs ((u16) mtu);
20480
20481   S (mp);
20482   W (ret);
20483   return ret;
20484 }
20485
20486 static int
20487 api_p2p_ethernet_add (vat_main_t * vam)
20488 {
20489   unformat_input_t *i = vam->input;
20490   vl_api_p2p_ethernet_add_t *mp;
20491   u32 parent_if_index = ~0;
20492   u32 sub_id = ~0;
20493   u8 remote_mac[6];
20494   u8 mac_set = 0;
20495   int ret;
20496
20497   memset (remote_mac, 0, sizeof (remote_mac));
20498   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20499     {
20500       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20501         ;
20502       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20503         ;
20504       else
20505         if (unformat
20506             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20507         mac_set++;
20508       else if (unformat (i, "sub_id %d", &sub_id))
20509         ;
20510       else
20511         {
20512           clib_warning ("parse error '%U'", format_unformat_error, i);
20513           return -99;
20514         }
20515     }
20516
20517   if (parent_if_index == ~0)
20518     {
20519       errmsg ("missing interface name or sw_if_index");
20520       return -99;
20521     }
20522   if (mac_set == 0)
20523     {
20524       errmsg ("missing remote mac address");
20525       return -99;
20526     }
20527   if (sub_id == ~0)
20528     {
20529       errmsg ("missing sub-interface id");
20530       return -99;
20531     }
20532
20533   M (P2P_ETHERNET_ADD, mp);
20534   mp->parent_if_index = ntohl (parent_if_index);
20535   mp->subif_id = ntohl (sub_id);
20536   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20537
20538   S (mp);
20539   W (ret);
20540   return ret;
20541 }
20542
20543 static int
20544 api_p2p_ethernet_del (vat_main_t * vam)
20545 {
20546   unformat_input_t *i = vam->input;
20547   vl_api_p2p_ethernet_del_t *mp;
20548   u32 parent_if_index = ~0;
20549   u8 remote_mac[6];
20550   u8 mac_set = 0;
20551   int ret;
20552
20553   memset (remote_mac, 0, sizeof (remote_mac));
20554   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20555     {
20556       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20557         ;
20558       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20559         ;
20560       else
20561         if (unformat
20562             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20563         mac_set++;
20564       else
20565         {
20566           clib_warning ("parse error '%U'", format_unformat_error, i);
20567           return -99;
20568         }
20569     }
20570
20571   if (parent_if_index == ~0)
20572     {
20573       errmsg ("missing interface name or sw_if_index");
20574       return -99;
20575     }
20576   if (mac_set == 0)
20577     {
20578       errmsg ("missing remote mac address");
20579       return -99;
20580     }
20581
20582   M (P2P_ETHERNET_DEL, mp);
20583   mp->parent_if_index = ntohl (parent_if_index);
20584   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20585
20586   S (mp);
20587   W (ret);
20588   return ret;
20589 }
20590
20591 static int
20592 api_lldp_config (vat_main_t * vam)
20593 {
20594   unformat_input_t *i = vam->input;
20595   vl_api_lldp_config_t *mp;
20596   int tx_hold = 0;
20597   int tx_interval = 0;
20598   u8 *sys_name = NULL;
20599   int ret;
20600
20601   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20602     {
20603       if (unformat (i, "system-name %s", &sys_name))
20604         ;
20605       else if (unformat (i, "tx-hold %d", &tx_hold))
20606         ;
20607       else if (unformat (i, "tx-interval %d", &tx_interval))
20608         ;
20609       else
20610         {
20611           clib_warning ("parse error '%U'", format_unformat_error, i);
20612           return -99;
20613         }
20614     }
20615
20616   vec_add1 (sys_name, 0);
20617
20618   M (LLDP_CONFIG, mp);
20619   mp->tx_hold = htonl (tx_hold);
20620   mp->tx_interval = htonl (tx_interval);
20621   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20622   vec_free (sys_name);
20623
20624   S (mp);
20625   W (ret);
20626   return ret;
20627 }
20628
20629 static int
20630 api_sw_interface_set_lldp (vat_main_t * vam)
20631 {
20632   unformat_input_t *i = vam->input;
20633   vl_api_sw_interface_set_lldp_t *mp;
20634   u32 sw_if_index = ~0;
20635   u32 enable = 1;
20636   u8 *port_desc = NULL;
20637   int ret;
20638
20639   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20640     {
20641       if (unformat (i, "disable"))
20642         enable = 0;
20643       else
20644         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20645         ;
20646       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20647         ;
20648       else if (unformat (i, "port-desc %s", &port_desc))
20649         ;
20650       else
20651         break;
20652     }
20653
20654   if (sw_if_index == ~0)
20655     {
20656       errmsg ("missing interface name or sw_if_index");
20657       return -99;
20658     }
20659
20660   /* Construct the API message */
20661   vec_add1 (port_desc, 0);
20662   M (SW_INTERFACE_SET_LLDP, mp);
20663   mp->sw_if_index = ntohl (sw_if_index);
20664   mp->enable = enable;
20665   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20666   vec_free (port_desc);
20667
20668   S (mp);
20669   W (ret);
20670   return ret;
20671 }
20672
20673 static int
20674 api_tcp_configure_src_addresses (vat_main_t * vam)
20675 {
20676   vl_api_tcp_configure_src_addresses_t *mp;
20677   unformat_input_t *i = vam->input;
20678   ip4_address_t v4first, v4last;
20679   ip6_address_t v6first, v6last;
20680   u8 range_set = 0;
20681   u32 vrf_id = 0;
20682   int ret;
20683
20684   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20685     {
20686       if (unformat (i, "%U - %U",
20687                     unformat_ip4_address, &v4first,
20688                     unformat_ip4_address, &v4last))
20689         {
20690           if (range_set)
20691             {
20692               errmsg ("one range per message (range already set)");
20693               return -99;
20694             }
20695           range_set = 1;
20696         }
20697       else if (unformat (i, "%U - %U",
20698                          unformat_ip6_address, &v6first,
20699                          unformat_ip6_address, &v6last))
20700         {
20701           if (range_set)
20702             {
20703               errmsg ("one range per message (range already set)");
20704               return -99;
20705             }
20706           range_set = 2;
20707         }
20708       else if (unformat (i, "vrf %d", &vrf_id))
20709         ;
20710       else
20711         break;
20712     }
20713
20714   if (range_set == 0)
20715     {
20716       errmsg ("address range not set");
20717       return -99;
20718     }
20719
20720   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20721   mp->vrf_id = ntohl (vrf_id);
20722   /* ipv6? */
20723   if (range_set == 2)
20724     {
20725       mp->is_ipv6 = 1;
20726       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20727       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20728     }
20729   else
20730     {
20731       mp->is_ipv6 = 0;
20732       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20733       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20734     }
20735   S (mp);
20736   W (ret);
20737   return ret;
20738 }
20739
20740 static int
20741 api_app_namespace_add_del (vat_main_t * vam)
20742 {
20743   vl_api_app_namespace_add_del_t *mp;
20744   unformat_input_t *i = vam->input;
20745   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
20746   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
20747   u64 secret;
20748   int ret;
20749
20750   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20751     {
20752       if (unformat (i, "id %_%v%_", &ns_id))
20753         ;
20754       else if (unformat (i, "secret %lu", &secret))
20755         secret_set = 1;
20756       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20757         sw_if_index_set = 1;
20758       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
20759         ;
20760       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
20761         ;
20762       else
20763         break;
20764     }
20765   if (!ns_id || !secret_set || !sw_if_index_set)
20766     {
20767       errmsg ("namespace id, secret and sw_if_index must be set");
20768       return -99;
20769     }
20770   if (vec_len (ns_id) > 64)
20771     {
20772       errmsg ("namespace id too long");
20773       return -99;
20774     }
20775   M (APP_NAMESPACE_ADD_DEL, mp);
20776
20777   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
20778   mp->namespace_id_len = vec_len (ns_id);
20779   mp->secret = secret;
20780   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20781   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
20782   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
20783   vec_free (ns_id);
20784   S (mp);
20785   W (ret);
20786   return ret;
20787 }
20788
20789 static int
20790 api_memfd_segment_create (vat_main_t * vam)
20791 {
20792   unformat_input_t *i = vam->input;
20793   vl_api_memfd_segment_create_t *mp;
20794   u64 size = 64 << 20;
20795   int ret;
20796
20797 #if VPP_API_TEST_BUILTIN == 1
20798   errmsg ("memfd_segment_create (builtin) not supported");
20799   return -99;
20800 #endif
20801
20802   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20803     {
20804       if (unformat (i, "size %U", unformat_memory_size, &size))
20805         ;
20806       else
20807         break;
20808     }
20809
20810   M (MEMFD_SEGMENT_CREATE, mp);
20811   mp->requested_size = size;
20812   S (mp);
20813   W (ret);
20814   return ret;
20815 }
20816
20817 static int
20818 q_or_quit (vat_main_t * vam)
20819 {
20820 #if VPP_API_TEST_BUILTIN == 0
20821   longjmp (vam->jump_buf, 1);
20822 #endif
20823   return 0;                     /* not so much */
20824 }
20825
20826 static int
20827 q (vat_main_t * vam)
20828 {
20829   return q_or_quit (vam);
20830 }
20831
20832 static int
20833 quit (vat_main_t * vam)
20834 {
20835   return q_or_quit (vam);
20836 }
20837
20838 static int
20839 comment (vat_main_t * vam)
20840 {
20841   return 0;
20842 }
20843
20844 static int
20845 cmd_cmp (void *a1, void *a2)
20846 {
20847   u8 **c1 = a1;
20848   u8 **c2 = a2;
20849
20850   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
20851 }
20852
20853 static int
20854 help (vat_main_t * vam)
20855 {
20856   u8 **cmds = 0;
20857   u8 *name = 0;
20858   hash_pair_t *p;
20859   unformat_input_t *i = vam->input;
20860   int j;
20861
20862   if (unformat (i, "%s", &name))
20863     {
20864       uword *hs;
20865
20866       vec_add1 (name, 0);
20867
20868       hs = hash_get_mem (vam->help_by_name, name);
20869       if (hs)
20870         print (vam->ofp, "usage: %s %s", name, hs[0]);
20871       else
20872         print (vam->ofp, "No such msg / command '%s'", name);
20873       vec_free (name);
20874       return 0;
20875     }
20876
20877   print (vam->ofp, "Help is available for the following:");
20878
20879     /* *INDENT-OFF* */
20880     hash_foreach_pair (p, vam->function_by_name,
20881     ({
20882       vec_add1 (cmds, (u8 *)(p->key));
20883     }));
20884     /* *INDENT-ON* */
20885
20886   vec_sort_with_function (cmds, cmd_cmp);
20887
20888   for (j = 0; j < vec_len (cmds); j++)
20889     print (vam->ofp, "%s", cmds[j]);
20890
20891   vec_free (cmds);
20892   return 0;
20893 }
20894
20895 static int
20896 set (vat_main_t * vam)
20897 {
20898   u8 *name = 0, *value = 0;
20899   unformat_input_t *i = vam->input;
20900
20901   if (unformat (i, "%s", &name))
20902     {
20903       /* The input buffer is a vector, not a string. */
20904       value = vec_dup (i->buffer);
20905       vec_delete (value, i->index, 0);
20906       /* Almost certainly has a trailing newline */
20907       if (value[vec_len (value) - 1] == '\n')
20908         value[vec_len (value) - 1] = 0;
20909       /* Make sure it's a proper string, one way or the other */
20910       vec_add1 (value, 0);
20911       (void) clib_macro_set_value (&vam->macro_main,
20912                                    (char *) name, (char *) value);
20913     }
20914   else
20915     errmsg ("usage: set <name> <value>");
20916
20917   vec_free (name);
20918   vec_free (value);
20919   return 0;
20920 }
20921
20922 static int
20923 unset (vat_main_t * vam)
20924 {
20925   u8 *name = 0;
20926
20927   if (unformat (vam->input, "%s", &name))
20928     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
20929       errmsg ("unset: %s wasn't set", name);
20930   vec_free (name);
20931   return 0;
20932 }
20933
20934 typedef struct
20935 {
20936   u8 *name;
20937   u8 *value;
20938 } macro_sort_t;
20939
20940
20941 static int
20942 macro_sort_cmp (void *a1, void *a2)
20943 {
20944   macro_sort_t *s1 = a1;
20945   macro_sort_t *s2 = a2;
20946
20947   return strcmp ((char *) (s1->name), (char *) (s2->name));
20948 }
20949
20950 static int
20951 dump_macro_table (vat_main_t * vam)
20952 {
20953   macro_sort_t *sort_me = 0, *sm;
20954   int i;
20955   hash_pair_t *p;
20956
20957     /* *INDENT-OFF* */
20958     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
20959     ({
20960       vec_add2 (sort_me, sm, 1);
20961       sm->name = (u8 *)(p->key);
20962       sm->value = (u8 *) (p->value[0]);
20963     }));
20964     /* *INDENT-ON* */
20965
20966   vec_sort_with_function (sort_me, macro_sort_cmp);
20967
20968   if (vec_len (sort_me))
20969     print (vam->ofp, "%-15s%s", "Name", "Value");
20970   else
20971     print (vam->ofp, "The macro table is empty...");
20972
20973   for (i = 0; i < vec_len (sort_me); i++)
20974     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
20975   return 0;
20976 }
20977
20978 static int
20979 dump_node_table (vat_main_t * vam)
20980 {
20981   int i, j;
20982   vlib_node_t *node, *next_node;
20983
20984   if (vec_len (vam->graph_nodes) == 0)
20985     {
20986       print (vam->ofp, "Node table empty, issue get_node_graph...");
20987       return 0;
20988     }
20989
20990   for (i = 0; i < vec_len (vam->graph_nodes); i++)
20991     {
20992       node = vam->graph_nodes[i];
20993       print (vam->ofp, "[%d] %s", i, node->name);
20994       for (j = 0; j < vec_len (node->next_nodes); j++)
20995         {
20996           if (node->next_nodes[j] != ~0)
20997             {
20998               next_node = vam->graph_nodes[node->next_nodes[j]];
20999               print (vam->ofp, "  [%d] %s", j, next_node->name);
21000             }
21001         }
21002     }
21003   return 0;
21004 }
21005
21006 static int
21007 value_sort_cmp (void *a1, void *a2)
21008 {
21009   name_sort_t *n1 = a1;
21010   name_sort_t *n2 = a2;
21011
21012   if (n1->value < n2->value)
21013     return -1;
21014   if (n1->value > n2->value)
21015     return 1;
21016   return 0;
21017 }
21018
21019
21020 static int
21021 dump_msg_api_table (vat_main_t * vam)
21022 {
21023   api_main_t *am = &api_main;
21024   name_sort_t *nses = 0, *ns;
21025   hash_pair_t *hp;
21026   int i;
21027
21028   /* *INDENT-OFF* */
21029   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21030   ({
21031     vec_add2 (nses, ns, 1);
21032     ns->name = (u8 *)(hp->key);
21033     ns->value = (u32) hp->value[0];
21034   }));
21035   /* *INDENT-ON* */
21036
21037   vec_sort_with_function (nses, value_sort_cmp);
21038
21039   for (i = 0; i < vec_len (nses); i++)
21040     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21041   vec_free (nses);
21042   return 0;
21043 }
21044
21045 static int
21046 get_msg_id (vat_main_t * vam)
21047 {
21048   u8 *name_and_crc;
21049   u32 message_index;
21050
21051   if (unformat (vam->input, "%s", &name_and_crc))
21052     {
21053       message_index = vl_api_get_msg_index (name_and_crc);
21054       if (message_index == ~0)
21055         {
21056           print (vam->ofp, " '%s' not found", name_and_crc);
21057           return 0;
21058         }
21059       print (vam->ofp, " '%s' has message index %d",
21060              name_and_crc, message_index);
21061       return 0;
21062     }
21063   errmsg ("name_and_crc required...");
21064   return 0;
21065 }
21066
21067 static int
21068 search_node_table (vat_main_t * vam)
21069 {
21070   unformat_input_t *line_input = vam->input;
21071   u8 *node_to_find;
21072   int j;
21073   vlib_node_t *node, *next_node;
21074   uword *p;
21075
21076   if (vam->graph_node_index_by_name == 0)
21077     {
21078       print (vam->ofp, "Node table empty, issue get_node_graph...");
21079       return 0;
21080     }
21081
21082   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21083     {
21084       if (unformat (line_input, "%s", &node_to_find))
21085         {
21086           vec_add1 (node_to_find, 0);
21087           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21088           if (p == 0)
21089             {
21090               print (vam->ofp, "%s not found...", node_to_find);
21091               goto out;
21092             }
21093           node = vam->graph_nodes[p[0]];
21094           print (vam->ofp, "[%d] %s", p[0], node->name);
21095           for (j = 0; j < vec_len (node->next_nodes); j++)
21096             {
21097               if (node->next_nodes[j] != ~0)
21098                 {
21099                   next_node = vam->graph_nodes[node->next_nodes[j]];
21100                   print (vam->ofp, "  [%d] %s", j, next_node->name);
21101                 }
21102             }
21103         }
21104
21105       else
21106         {
21107           clib_warning ("parse error '%U'", format_unformat_error,
21108                         line_input);
21109           return -99;
21110         }
21111
21112     out:
21113       vec_free (node_to_find);
21114
21115     }
21116
21117   return 0;
21118 }
21119
21120
21121 static int
21122 script (vat_main_t * vam)
21123 {
21124 #if (VPP_API_TEST_BUILTIN==0)
21125   u8 *s = 0;
21126   char *save_current_file;
21127   unformat_input_t save_input;
21128   jmp_buf save_jump_buf;
21129   u32 save_line_number;
21130
21131   FILE *new_fp, *save_ifp;
21132
21133   if (unformat (vam->input, "%s", &s))
21134     {
21135       new_fp = fopen ((char *) s, "r");
21136       if (new_fp == 0)
21137         {
21138           errmsg ("Couldn't open script file %s", s);
21139           vec_free (s);
21140           return -99;
21141         }
21142     }
21143   else
21144     {
21145       errmsg ("Missing script name");
21146       return -99;
21147     }
21148
21149   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
21150   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
21151   save_ifp = vam->ifp;
21152   save_line_number = vam->input_line_number;
21153   save_current_file = (char *) vam->current_file;
21154
21155   vam->input_line_number = 0;
21156   vam->ifp = new_fp;
21157   vam->current_file = s;
21158   do_one_file (vam);
21159
21160   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
21161   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
21162   vam->ifp = save_ifp;
21163   vam->input_line_number = save_line_number;
21164   vam->current_file = (u8 *) save_current_file;
21165   vec_free (s);
21166
21167   return 0;
21168 #else
21169   clib_warning ("use the exec command...");
21170   return -99;
21171 #endif
21172 }
21173
21174 static int
21175 echo (vat_main_t * vam)
21176 {
21177   print (vam->ofp, "%v", vam->input->buffer);
21178   return 0;
21179 }
21180
21181 /* List of API message constructors, CLI names map to api_xxx */
21182 #define foreach_vpe_api_msg                                             \
21183 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
21184 _(sw_interface_dump,"")                                                 \
21185 _(sw_interface_set_flags,                                               \
21186   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
21187 _(sw_interface_add_del_address,                                         \
21188   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
21189 _(sw_interface_set_table,                                               \
21190   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
21191 _(sw_interface_set_mpls_enable,                                         \
21192   "<intfc> | sw_if_index [disable | dis]")                              \
21193 _(sw_interface_set_vpath,                                               \
21194   "<intfc> | sw_if_index <id> enable | disable")                        \
21195 _(sw_interface_set_vxlan_bypass,                                        \
21196   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21197 _(sw_interface_set_geneve_bypass,                                       \
21198   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21199 _(sw_interface_set_l2_xconnect,                                         \
21200   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21201   "enable | disable")                                                   \
21202 _(sw_interface_set_l2_bridge,                                           \
21203   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
21204   "[shg <split-horizon-group>] [bvi]\n"                                 \
21205   "enable | disable")                                                   \
21206 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
21207 _(bridge_domain_add_del,                                                \
21208   "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") \
21209 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
21210 _(l2fib_add_del,                                                        \
21211   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
21212 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
21213 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
21214 _(l2_flags,                                                             \
21215   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21216 _(bridge_flags,                                                         \
21217   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21218 _(tap_connect,                                                          \
21219   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
21220 _(tap_modify,                                                           \
21221   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
21222 _(tap_delete,                                                           \
21223   "<vpp-if-name> | sw_if_index <id>")                                   \
21224 _(sw_interface_tap_dump, "")                                            \
21225 _(ip_table_add_del,                                                     \
21226   "table-id <n> [ipv6]\n")                                              \
21227 _(ip_add_del_route,                                                     \
21228   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
21229   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
21230   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
21231   "[multipath] [count <n>]")                                            \
21232 _(ip_mroute_add_del,                                                    \
21233   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
21234   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
21235 _(mpls_table_add_del,                                                   \
21236   "table-id <n>\n")                                                     \
21237 _(mpls_route_add_del,                                                   \
21238   "<label> <eos> via <addr> [table-id <n>]\n"                           \
21239   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
21240   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
21241   "[multipath] [count <n>]")                                            \
21242 _(mpls_ip_bind_unbind,                                                  \
21243   "<label> <addr/len>")                                                 \
21244 _(mpls_tunnel_add_del,                                                  \
21245   " via <addr> [table-id <n>]\n"                                        \
21246   "sw_if_index <id>] [l2]  [del]")                                      \
21247 _(proxy_arp_add_del,                                                    \
21248   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
21249 _(proxy_arp_intfc_enable_disable,                                       \
21250   "<intfc> | sw_if_index <id> enable | disable")                        \
21251 _(sw_interface_set_unnumbered,                                          \
21252   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
21253 _(ip_neighbor_add_del,                                                  \
21254   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
21255   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
21256 _(reset_vrf, "vrf <id> [ipv6]")                                         \
21257 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
21258 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
21259   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
21260   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
21261   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
21262 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
21263 _(reset_fib, "vrf <n> [ipv6]")                                          \
21264 _(dhcp_proxy_config,                                                    \
21265   "svr <v46-address> src <v46-address>\n"                               \
21266    "rx_vrf_id <nn> server_vrf_id <nn>  [del]")                          \
21267 _(dhcp_proxy_set_vss,                                                   \
21268   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
21269 _(dhcp_proxy_dump, "ip6")                                               \
21270 _(dhcp_client_config,                                                   \
21271   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
21272 _(set_ip_flow_hash,                                                     \
21273   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
21274 _(sw_interface_ip6_enable_disable,                                      \
21275   "<intfc> | sw_if_index <id> enable | disable")                        \
21276 _(sw_interface_ip6_set_link_local_address,                              \
21277   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
21278 _(ip6nd_proxy_add_del,                                                  \
21279   "<intfc> | sw_if_index <id> <ip6-address>")                           \
21280 _(ip6nd_proxy_dump, "")                                                 \
21281 _(sw_interface_ip6nd_ra_prefix,                                         \
21282   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
21283   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
21284   "[nolink] [isno]")                                                    \
21285 _(sw_interface_ip6nd_ra_config,                                         \
21286   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
21287   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
21288   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
21289 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
21290 _(l2_patch_add_del,                                                     \
21291   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21292   "enable | disable")                                                   \
21293 _(sr_localsid_add_del,                                                  \
21294   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
21295   "fib-table <num> (end.psp) sw_if_index <num>")                        \
21296 _(classify_add_del_table,                                               \
21297   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
21298   " [del] [del-chain] mask <mask-value>\n"                              \
21299   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
21300   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
21301 _(classify_add_del_session,                                             \
21302   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
21303   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
21304   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
21305   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
21306 _(classify_set_interface_ip_table,                                      \
21307   "<intfc> | sw_if_index <nn> table <nn>")                              \
21308 _(classify_set_interface_l2_tables,                                     \
21309   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21310   "  [other-table <nn>]")                                               \
21311 _(get_node_index, "node <node-name")                                    \
21312 _(add_node_next, "node <node-name> next <next-node-name>")              \
21313 _(l2tpv3_create_tunnel,                                                 \
21314   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
21315   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
21316   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
21317 _(l2tpv3_set_tunnel_cookies,                                            \
21318   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
21319   "[new_remote_cookie <nn>]\n")                                         \
21320 _(l2tpv3_interface_enable_disable,                                      \
21321   "<intfc> | sw_if_index <nn> enable | disable")                        \
21322 _(l2tpv3_set_lookup_key,                                                \
21323   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
21324 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
21325 _(vxlan_add_del_tunnel,                                                 \
21326   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21327   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21328   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21329 _(geneve_add_del_tunnel,                                                \
21330   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21331   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21332   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21333 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
21334 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
21335 _(gre_add_del_tunnel,                                                   \
21336   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
21337 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
21338 _(l2_fib_clear_table, "")                                               \
21339 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
21340 _(l2_interface_vlan_tag_rewrite,                                        \
21341   "<intfc> | sw_if_index <nn> \n"                                       \
21342   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
21343   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
21344 _(create_vhost_user_if,                                                 \
21345         "socket <filename> [server] [renumber <dev_instance>] "         \
21346         "[mac <mac_address>]")                                          \
21347 _(modify_vhost_user_if,                                                 \
21348         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
21349         "[server] [renumber <dev_instance>]")                           \
21350 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
21351 _(sw_interface_vhost_user_dump, "")                                     \
21352 _(show_version, "")                                                     \
21353 _(vxlan_gpe_add_del_tunnel,                                             \
21354   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
21355   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21356   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
21357   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
21358 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
21359 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
21360 _(interface_name_renumber,                                              \
21361   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
21362 _(input_acl_set_interface,                                              \
21363   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21364   "  [l2-table <nn>] [del]")                                            \
21365 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
21366 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
21367 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
21368 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
21369 _(ip_dump, "ipv4 | ipv6")                                               \
21370 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
21371 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
21372   "  spid_id <n> ")                                                     \
21373 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
21374   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
21375   "  integ_alg <alg> integ_key <hex>")                                  \
21376 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
21377   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
21378   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
21379   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
21380 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
21381 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
21382   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
21383   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
21384   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n")     \
21385 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
21386 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
21387 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
21388   "(auth_data 0x<data> | auth_data <data>)")                            \
21389 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
21390   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
21391 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
21392   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
21393   "(local|remote)")                                                     \
21394 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
21395 _(ikev2_set_responder, "<profile_name> interface <interface> address <addr>") \
21396 _(ikev2_set_ike_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
21397 _(ikev2_set_esp_transforms, "<profile_name> <crypto alg> <key size> <integrity alg> <DH group>") \
21398 _(ikev2_set_sa_lifetime, "<profile_name> <seconds> <jitter> <handover> <max bytes>") \
21399 _(ikev2_initiate_sa_init, "<profile_name>")                             \
21400 _(ikev2_initiate_del_ike_sa, "<ispi>")                                  \
21401 _(ikev2_initiate_del_child_sa, "<ispi>")                                \
21402 _(ikev2_initiate_rekey_child_sa, "<ispi>")                              \
21403 _(delete_loopback,"sw_if_index <nn>")                                   \
21404 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
21405 _(map_add_domain,                                                       \
21406   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
21407   "ip6-src <ip6addr> "                                                  \
21408   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
21409 _(map_del_domain, "index <n>")                                          \
21410 _(map_add_del_rule,                                                     \
21411   "index <n> psid <n> dst <ip6addr> [del]")                             \
21412 _(map_domain_dump, "")                                                  \
21413 _(map_rule_dump, "index <map-domain>")                                  \
21414 _(want_interface_events,  "enable|disable")                             \
21415 _(want_stats,"enable|disable")                                          \
21416 _(get_first_msg_id, "client <name>")                                    \
21417 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
21418 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
21419   "fib-id <nn> [ip4][ip6][default]")                                    \
21420 _(get_node_graph, " ")                                                  \
21421 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
21422 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
21423 _(ioam_disable, "")                                                     \
21424 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
21425                             " sw_if_index <sw_if_index> p <priority> "  \
21426                             "w <weight>] [del]")                        \
21427 _(one_add_del_locator, "locator-set <locator_name> "                    \
21428                         "iface <intf> | sw_if_index <sw_if_index> "     \
21429                         "p <priority> w <weight> [del]")                \
21430 _(one_add_del_local_eid,"vni <vni> eid "                                \
21431                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21432                          "locator-set <locator_name> [del]"             \
21433                          "[key-id sha1|sha256 secret-key <secret-key>]")\
21434 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
21435 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
21436 _(one_enable_disable, "enable|disable")                                 \
21437 _(one_map_register_enable_disable, "enable|disable")                    \
21438 _(one_map_register_fallback_threshold, "<value>")                       \
21439 _(one_rloc_probe_enable_disable, "enable|disable")                      \
21440 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
21441                                "[seid <seid>] "                         \
21442                                "rloc <locator> p <prio> "               \
21443                                "w <weight> [rloc <loc> ... ] "          \
21444                                "action <action> [del-all]")             \
21445 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
21446                           "<local-eid>")                                \
21447 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
21448 _(one_use_petr, "ip-address> | disable")                                \
21449 _(one_map_request_mode, "src-dst|dst-only")                             \
21450 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
21451 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
21452 _(one_locator_set_dump, "[local | remote]")                             \
21453 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
21454 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
21455                        "[local] | [remote]")                            \
21456 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
21457 _(one_ndp_bd_get, "")                                                   \
21458 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
21459 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
21460 _(one_l2_arp_bd_get, "")                                                \
21461 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
21462 _(one_stats_enable_disable, "enable|disalbe")                           \
21463 _(show_one_stats_enable_disable, "")                                    \
21464 _(one_eid_table_vni_dump, "")                                           \
21465 _(one_eid_table_map_dump, "l2|l3")                                      \
21466 _(one_map_resolver_dump, "")                                            \
21467 _(one_map_server_dump, "")                                              \
21468 _(one_adjacencies_get, "vni <vni>")                                     \
21469 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
21470 _(show_one_rloc_probe_state, "")                                        \
21471 _(show_one_map_register_state, "")                                      \
21472 _(show_one_status, "")                                                  \
21473 _(one_stats_dump, "")                                                   \
21474 _(one_stats_flush, "")                                                  \
21475 _(one_get_map_request_itr_rlocs, "")                                    \
21476 _(one_map_register_set_ttl, "<ttl>")                                    \
21477 _(one_set_transport_protocol, "udp|api")                                \
21478 _(one_get_transport_protocol, "")                                       \
21479 _(show_one_nsh_mapping, "")                                             \
21480 _(show_one_pitr, "")                                                    \
21481 _(show_one_use_petr, "")                                                \
21482 _(show_one_map_request_mode, "")                                        \
21483 _(show_one_map_register_ttl, "")                                        \
21484 _(show_one_map_register_fallback_threshold, "")                         \
21485 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
21486                             " sw_if_index <sw_if_index> p <priority> "  \
21487                             "w <weight>] [del]")                        \
21488 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
21489                         "iface <intf> | sw_if_index <sw_if_index> "     \
21490                         "p <priority> w <weight> [del]")                \
21491 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
21492                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21493                          "locator-set <locator_name> [del]"             \
21494                          "[key-id sha1|sha256 secret-key <secret-key>]") \
21495 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
21496 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
21497 _(lisp_enable_disable, "enable|disable")                                \
21498 _(lisp_map_register_enable_disable, "enable|disable")                   \
21499 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
21500 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
21501                                "[seid <seid>] "                         \
21502                                "rloc <locator> p <prio> "               \
21503                                "w <weight> [rloc <loc> ... ] "          \
21504                                "action <action> [del-all]")             \
21505 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
21506                           "<local-eid>")                                \
21507 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
21508 _(lisp_use_petr, "<ip-address> | disable")                              \
21509 _(lisp_map_request_mode, "src-dst|dst-only")                            \
21510 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
21511 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
21512 _(lisp_locator_set_dump, "[local | remote]")                            \
21513 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
21514 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
21515                        "[local] | [remote]")                            \
21516 _(lisp_eid_table_vni_dump, "")                                          \
21517 _(lisp_eid_table_map_dump, "l2|l3")                                     \
21518 _(lisp_map_resolver_dump, "")                                           \
21519 _(lisp_map_server_dump, "")                                             \
21520 _(lisp_adjacencies_get, "vni <vni>")                                    \
21521 _(gpe_fwd_entry_vnis_get, "")                                           \
21522 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
21523 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
21524                                 "[table <table-id>]")                   \
21525 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
21526 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
21527 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
21528 _(gpe_get_encap_mode, "")                                               \
21529 _(lisp_gpe_add_del_iface, "up|down")                                    \
21530 _(lisp_gpe_enable_disable, "enable|disable")                            \
21531 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
21532   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
21533 _(show_lisp_rloc_probe_state, "")                                       \
21534 _(show_lisp_map_register_state, "")                                     \
21535 _(show_lisp_status, "")                                                 \
21536 _(lisp_get_map_request_itr_rlocs, "")                                   \
21537 _(show_lisp_pitr, "")                                                   \
21538 _(show_lisp_use_petr, "")                                               \
21539 _(show_lisp_map_request_mode, "")                                       \
21540 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
21541 _(af_packet_delete, "name <host interface name>")                       \
21542 _(policer_add_del, "name <policer name> <params> [del]")                \
21543 _(policer_dump, "[name <policer name>]")                                \
21544 _(policer_classify_set_interface,                                       \
21545   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21546   "  [l2-table <nn>] [del]")                                            \
21547 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
21548 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
21549     "[master|slave]")                                                   \
21550 _(netmap_delete, "name <interface name>")                               \
21551 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
21552 _(mpls_fib_dump, "")                                                    \
21553 _(classify_table_ids, "")                                               \
21554 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
21555 _(classify_table_info, "table_id <nn>")                                 \
21556 _(classify_session_dump, "table_id <nn>")                               \
21557 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
21558     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
21559     "[template_interval <nn>] [udp_checksum]")                          \
21560 _(ipfix_exporter_dump, "")                                              \
21561 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
21562 _(ipfix_classify_stream_dump, "")                                       \
21563 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
21564 _(ipfix_classify_table_dump, "")                                        \
21565 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
21566 _(sw_interface_span_dump, "[l2]")                                           \
21567 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
21568 _(pg_create_interface, "if_id <nn>")                                    \
21569 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
21570 _(pg_enable_disable, "[stream <id>] disable")                           \
21571 _(ip_source_and_port_range_check_add_del,                               \
21572   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
21573 _(ip_source_and_port_range_check_interface_add_del,                     \
21574   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
21575   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
21576 _(ipsec_gre_add_del_tunnel,                                             \
21577   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
21578 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
21579 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
21580 _(l2_interface_pbb_tag_rewrite,                                         \
21581   "<intfc> | sw_if_index <nn> \n"                                       \
21582   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
21583   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
21584 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
21585 _(flow_classify_set_interface,                                          \
21586   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
21587 _(flow_classify_dump, "type [ip4|ip6]")                                 \
21588 _(ip_fib_dump, "")                                                      \
21589 _(ip_mfib_dump, "")                                                     \
21590 _(ip6_fib_dump, "")                                                     \
21591 _(ip6_mfib_dump, "")                                                    \
21592 _(feature_enable_disable, "arc_name <arc_name> "                        \
21593   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
21594 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
21595 "[disable]")                                                            \
21596 _(l2_xconnect_dump, "")                                                 \
21597 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
21598 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
21599 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
21600 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
21601 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
21602 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
21603 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>] [disable]") \
21604 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
21605 _(memfd_segment_create,"size <nnn>")                                    \
21606 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
21607
21608 /* List of command functions, CLI names map directly to functions */
21609 #define foreach_cli_function                                    \
21610 _(comment, "usage: comment <ignore-rest-of-line>")              \
21611 _(dump_interface_table, "usage: dump_interface_table")          \
21612 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21613 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21614 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21615 _(dump_stats_table, "usage: dump_stats_table")                  \
21616 _(dump_macro_table, "usage: dump_macro_table ")                 \
21617 _(dump_node_table, "usage: dump_node_table")                    \
21618 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21619 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21620 _(echo, "usage: echo <message>")                                \
21621 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21622 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21623 _(help, "usage: help")                                          \
21624 _(q, "usage: quit")                                             \
21625 _(quit, "usage: quit")                                          \
21626 _(search_node_table, "usage: search_node_table <name>...")      \
21627 _(set, "usage: set <variable-name> <value>")                    \
21628 _(script, "usage: script <file-name>")                          \
21629 _(unset, "usage: unset <variable-name>")
21630 #define _(N,n)                                  \
21631     static void vl_api_##n##_t_handler_uni      \
21632     (vl_api_##n##_t * mp)                       \
21633     {                                           \
21634         vat_main_t * vam = &vat_main;           \
21635         if (vam->json_output) {                 \
21636             vl_api_##n##_t_handler_json(mp);    \
21637         } else {                                \
21638             vl_api_##n##_t_handler(mp);         \
21639         }                                       \
21640     }
21641 foreach_vpe_api_reply_msg;
21642 #if VPP_API_TEST_BUILTIN == 0
21643 foreach_standalone_reply_msg;
21644 #endif
21645 #undef _
21646
21647 void
21648 vat_api_hookup (vat_main_t * vam)
21649 {
21650 #define _(N,n)                                                  \
21651     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21652                            vl_api_##n##_t_handler_uni,          \
21653                            vl_noop_handler,                     \
21654                            vl_api_##n##_t_endian,               \
21655                            vl_api_##n##_t_print,                \
21656                            sizeof(vl_api_##n##_t), 1);
21657   foreach_vpe_api_reply_msg;
21658 #if VPP_API_TEST_BUILTIN == 0
21659   foreach_standalone_reply_msg;
21660 #endif
21661 #undef _
21662
21663 #if (VPP_API_TEST_BUILTIN==0)
21664   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
21665
21666   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
21667
21668   vam->function_by_name = hash_create_string (0, sizeof (uword));
21669
21670   vam->help_by_name = hash_create_string (0, sizeof (uword));
21671 #endif
21672
21673   /* API messages we can send */
21674 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
21675   foreach_vpe_api_msg;
21676 #undef _
21677
21678   /* Help strings */
21679 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21680   foreach_vpe_api_msg;
21681 #undef _
21682
21683   /* CLI functions */
21684 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
21685   foreach_cli_function;
21686 #undef _
21687
21688   /* Help strings */
21689 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21690   foreach_cli_function;
21691 #undef _
21692 }
21693
21694 #if VPP_API_TEST_BUILTIN
21695 static clib_error_t *
21696 vat_api_hookup_shim (vlib_main_t * vm)
21697 {
21698   vat_api_hookup (&vat_main);
21699   return 0;
21700 }
21701
21702 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
21703 #endif
21704
21705 /*
21706  * fd.io coding-style-patch-verification: ON
21707  *
21708  * Local Variables:
21709  * eval: (c-set-style "gnu")
21710  * End:
21711  */