ioam: remove api boilerplate
[vpp.git] / src / plugins / ioam / udp-ping / udp_ping_test.c
1 /*
2  * Copyright (c) 2017 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 /*
16  *------------------------------------------------------------------
17  * udp_ping_test.c - test harness for udp ping plugin
18  *------------------------------------------------------------------
19  */
20
21 #include <vat/vat.h>
22 #include <vlibapi/api.h>
23 #include <vlibmemory/api.h>
24
25 #include <vppinfra/error.h>
26 #include <vnet/ip/ip.h>
27
28 /* Declare message IDs */
29 #include <ioam/udp-ping/udp_ping.api_enum.h>
30 #include <ioam/udp-ping/udp_ping.api_types.h>
31
32 #define vl_endianfun            /* define message structures */
33 #define vl_printfun
34 #define vl_print(handle, ...)
35 #define vl_api_version(n,v) static u32 api_version=(v);
36 #include <ioam/udp-ping/udp_ping.api.h>
37 #undef vl_endianfun
38 #undef vl_printfun
39 #undef vl_api_version
40
41 typedef struct
42 {
43   /* API message ID base */
44   u16 msg_id_base;
45   vat_main_t *vat_main;
46 } udp_ping_test_main_t;
47
48 udp_ping_test_main_t udp_ping_test_main;
49
50 #define foreach_standard_reply_retval_handler     \
51 _(udp_ping_add_del_reply)                          \
52 _(udp_ping_export_reply)
53
54 #define _(n)                                            \
55     static void vl_api_##n##_t_handler                  \
56     (vl_api_##n##_t * mp)                               \
57     {                                                   \
58         vat_main_t * vam = udp_ping_test_main.vat_main;   \
59         i32 retval = ntohl(mp->retval);                 \
60         if (vam->async_mode) {                          \
61             vam->async_errors += (retval < 0);          \
62         } else {                                        \
63             vam->retval = retval;                       \
64             vam->result_ready = 1;                      \
65         }                                               \
66     }
67 foreach_standard_reply_retval_handler;
68 #undef _
69
70 /*
71  * Table of message reply handlers, must include boilerplate handlers
72  * we just generated
73  */
74 #define foreach_vpe_api_reply_msg                                       \
75 _(UDP_PING_ADD_DEL_REPLY, udp_ping_add_del_reply)                         \
76 _(UDP_PING_EXPORT_REPLY, udp_ping_export_reply)                         \
77
78
79 /* M: construct, but don't yet send a message */
80
81 #define M(T,t)                                                  \
82 do {                                                            \
83     vam->result_ready = 0;                                      \
84     mp = vl_msg_api_alloc(sizeof(*mp));                         \
85     clib_memset (mp, 0, sizeof (*mp));                               \
86     mp->_vl_msg_id = ntohs (VL_API_##T + sm->msg_id_base);      \
87     mp->client_index = vam->my_client_index;                    \
88 } while(0);
89
90 /* S: send a message */
91 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
92
93 /* W: wait for results, with timeout */
94 #define W                                       \
95 do {                                            \
96     timeout = vat_time_now (vam) + 5.0;         \
97                                                 \
98     while (vat_time_now (vam) < timeout) {      \
99         if (vam->result_ready == 1) {           \
100             return (vam->retval);               \
101         }                                       \
102     }                                           \
103     return -99;                                 \
104 } while(0);
105
106 static int
107 api_udp_ping_add_del (vat_main_t * vam)
108 {
109   udp_ping_test_main_t *sm = &udp_ping_test_main;
110   unformat_input_t *input = vam->input;
111   vl_api_udp_ping_add_del_t *mp;
112   int rv = 0;
113   ip6_address_t dst, src;
114   u32 start_src_port, end_src_port;
115   u32 start_dst_port, end_dst_port;
116   u32 interval;
117   u8 is_disable = 0;
118   f64 timeout;
119
120   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
121     {
122       if (unformat (input, "src %U", unformat_ip6_address, &src))
123         ;
124       else if (unformat (input, "start-src-port %d", &start_src_port))
125         ;
126       else if (unformat (input, "end-src-port %d", &end_src_port))
127         ;
128       else if (unformat (input, "start-dst-port %d", &start_dst_port))
129         ;
130       else if (unformat (input, "end-dst-port %d", &end_dst_port))
131         ;
132       else if (unformat (input, "dst %U", unformat_ip6_address, &dst))
133         ;
134       else if (unformat (input, "interval %d", &interval))
135         ;
136       else if (unformat (input, "disable"))
137         is_disable = 1;
138       else
139         break;
140     }
141
142   M (UDP_PING_ADD_DEL, udp_ping_add);
143
144   clib_memcpy (mp->src_ip_address, &src, 16);
145   clib_memcpy (mp->dst_ip_address, &dst, 16);
146   mp->start_src_port = (u16) start_src_port;
147   mp->end_src_port = (u16) end_src_port;
148   mp->start_dst_port = (u16) start_dst_port;
149   mp->end_dst_port = (u16) end_dst_port;
150   mp->interval = (u16) interval;
151   mp->is_ipv4 = 0;
152   mp->dis = is_disable;
153
154   S;
155   W;
156
157   return (rv);
158 }
159
160 static int
161 api_udp_ping_export (vat_main_t * vam)
162 {
163   udp_ping_test_main_t *sm = &udp_ping_test_main;
164   unformat_input_t *input = vam->input;
165   vl_api_udp_ping_export_t *mp;
166   int rv = 0;
167   int is_add = 1;
168   f64 timeout;
169
170   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
171     {
172       if (unformat (input, "export"))
173         is_add = 1;
174       else if (unformat (input, "disable"))
175         is_add = 0;
176       else
177         break;
178     }
179
180   M (UDP_PING_EXPORT, udp_ping_export);
181
182   mp->enable = is_add;
183
184   S;
185   W;
186
187   return (rv);
188 }
189
190 /*
191  * List of messages that the api test plugin sends,
192  * and that the data plane plugin processes
193  */
194 #define foreach_vpe_api_msg \
195 _(udp_ping_add_del, "src <local IPv6 address>  start-src-port <first local port> "\
196   "end-src-port <last local port> " \
197   "dst <remote IPv6 address> start-dst-port <first destination port> "\
198   "end-dst-port <last destination port> "\
199   "interval <time interval in sec for which ping packet will be sent> "\
200   "[disable]")                         \
201 _(udp_ping_export, "export [disable]")                                         \
202
203
204 static void
205 udp_ping_test_api_hookup (vat_main_t * vam)
206 {
207   udp_ping_test_main_t *sm = &udp_ping_test_main;
208   /* Hook up handlers for replies from the data plane plug-in */
209 #define _(N,n)                                                  \
210     vl_msg_api_set_handlers((VL_API_##N + sm->msg_id_base),     \
211                            #n,                                  \
212                            vl_api_##n##_t_handler,              \
213                            vl_noop_handler,                     \
214                            vl_api_##n##_t_endian,               \
215                            vl_api_##n##_t_print,                \
216                            sizeof(vl_api_##n##_t), 1);
217   foreach_vpe_api_reply_msg;
218 #undef _
219
220   /* API messages we can send */
221 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
222   foreach_vpe_api_msg;
223 #undef _
224
225   /* Help strings */
226 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
227   foreach_vpe_api_msg;
228 #undef _
229 }
230
231 clib_error_t *
232 udp_ping_vat_plugin_register (vat_main_t * vam)
233 {
234   udp_ping_test_main_t *sm = &udp_ping_test_main;
235   u8 *name;
236
237   sm->vat_main = vam;
238
239   name = format (0, "udp_ping_%08x%c", api_version, 0);
240   sm->msg_id_base = vl_client_get_first_plugin_msg_id ((char *) name);
241
242   if (sm->msg_id_base != (u16) ~ 0)
243     udp_ping_test_api_hookup (vam);
244
245   vec_free (name);
246
247   return 0;
248 }
249
250 /*
251  * fd.io coding-style-patch-verification: ON
252  *
253  * Local Variables:
254  * eval: (c-set-style "gnu")
255  * End:
256  */