chiark / gitweb /
test: always use assert_se in tests
[elogind.git] / src / libsystemd / sd-rtnl / test-rtnl.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2013 Tom Gundersen <teg@jklm.no>
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <netinet/ether.h>
23
24 #include "util.h"
25 #include "macro.h"
26 #include "sd-rtnl.h"
27 #include "socket-util.h"
28 #include "rtnl-util.h"
29 #include "event-util.h"
30 #include "missing.h"
31
32 static void test_link_configure(sd_rtnl *rtnl, int ifindex) {
33         _cleanup_rtnl_message_unref_ sd_rtnl_message *message;
34         uint16_t type;
35         const char *mac = "98:fe:94:3f:c6:18", *name = "test";
36         unsigned int mtu = 1450;
37         void *data;
38
39         /* we'd really like to test NEWLINK, but let's not mess with the running kernel */
40         assert_se(sd_rtnl_message_new_link(rtnl, &message, RTM_GETLINK, ifindex) >= 0);
41         assert_se(sd_rtnl_message_append_string(message, IFLA_IFNAME, name) >= 0);
42         assert_se(sd_rtnl_message_append_ether_addr(message, IFLA_ADDRESS, ether_aton(mac)) >= 0);
43         assert_se(sd_rtnl_message_append_u32(message, IFLA_MTU, mtu) >= 0);
44
45         assert_se(sd_rtnl_call(rtnl, message, 0, NULL) == 1);
46
47         assert_se(sd_rtnl_message_read(message, &type, &data) > 0);
48         assert_se(type == IFLA_IFNAME);
49         assert_se(streq(name, (char *) data));
50
51         assert_se(sd_rtnl_message_read(message, &type, &data) > 0);
52         assert_se(type == IFLA_ADDRESS);
53         assert_se(streq(mac, ether_ntoa(data)));
54
55         assert_se(sd_rtnl_message_read(message, &type, &data) > 0);
56         assert_se(type == IFLA_MTU);
57         assert_se(mtu == *(unsigned int *) data);
58 }
59
60 static void test_link_get(sd_rtnl *rtnl, int ifindex) {
61         sd_rtnl_message *m;
62         sd_rtnl_message *r;
63         unsigned int mtu = 1500;
64         unsigned int *mtu_reply;
65         void *data;
66         uint16_t type;
67
68         assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0);
69         assert_se(m);
70
71         /* u8 test cases  */
72         assert_se(sd_rtnl_message_append_u8(m, IFLA_CARRIER, 0) >= 0);
73         assert_se(sd_rtnl_message_append_u8(m, IFLA_OPERSTATE, 0) >= 0);
74         assert_se(sd_rtnl_message_append_u8(m, IFLA_LINKMODE, 0) >= 0);
75
76         /* u32 test cases */
77         assert_se(sd_rtnl_message_append_u32(m, IFLA_MTU, mtu) >= 0);
78         assert_se(sd_rtnl_message_append_u32(m, IFLA_GROUP, 0) >= 0);
79         assert_se(sd_rtnl_message_append_u32(m, IFLA_TXQLEN, 0) >= 0);
80         assert_se(sd_rtnl_message_append_u32(m, IFLA_NUM_TX_QUEUES, 0) >= 0);
81         assert_se(sd_rtnl_message_append_u32(m, IFLA_NUM_RX_QUEUES, 0) >= 0);
82
83         assert_se(sd_rtnl_call(rtnl, m, -1, &r) == 1);
84
85         /* u8 read back */
86         assert_se(sd_rtnl_message_read(m, &type, &data) == 1);
87         assert_se(type == IFLA_CARRIER);
88
89         assert_se(sd_rtnl_message_read(m, &type, &data) == 1);
90         assert_se(type == IFLA_OPERSTATE);
91
92         assert_se(sd_rtnl_message_read(m, &type, &data) == 1);
93         assert_se(type == IFLA_LINKMODE);
94
95         /* u32 read back */
96         assert_se(sd_rtnl_message_read(m, &type, (void **) &mtu_reply) == 1);
97         assert_se(type == IFLA_MTU);
98         assert_se(*mtu_reply == mtu);
99
100         assert_se(sd_rtnl_message_read(m, &type, &data) == 1);
101         assert_se(type == IFLA_GROUP);
102
103         assert_se(sd_rtnl_message_read(m, &type, &data) == 1);
104         assert_se(type == IFLA_TXQLEN);
105
106         assert_se(sd_rtnl_message_read(m, &type, &data) == 1);
107         assert_se(type == IFLA_NUM_TX_QUEUES);
108
109         assert_se(sd_rtnl_message_read(m, &type, &data) == 1);
110         assert_se(type == IFLA_NUM_RX_QUEUES);
111
112         while (sd_rtnl_message_read(r, &type, &data) > 0) {
113                 switch (type) {
114 //                        case IFLA_MTU:
115 //                                assert_se(*(unsigned int *) data == 65536);
116 //                                break;
117 //                        case IFLA_QDISC:
118 //                                assert_se(streq((char *) data, "noqueue"));
119 //                                break;
120                         case IFLA_IFNAME:
121                                 assert_se(streq((char *) data, "lo"));
122                                 break;
123                 }
124         }
125
126         assert_se(sd_rtnl_flush(rtnl) >= 0);
127         assert_se((m = sd_rtnl_message_unref(m)) == NULL);
128
129 }
130
131 static void test_route(void) {
132         _cleanup_rtnl_message_unref_ sd_rtnl_message *req;
133         struct in_addr addr;
134         uint32_t index = 2;
135         uint16_t type;
136         void *data;
137         int r;
138
139         r = sd_rtnl_message_new_route(NULL, &req, RTM_NEWROUTE, AF_INET);
140         if (r < 0) {
141                 log_error("Could not create RTM_NEWROUTE message: %s", strerror(-r));
142                 return;
143         }
144
145         addr.s_addr = htonl(INADDR_LOOPBACK);
146
147         r = sd_rtnl_message_append_in_addr(req, RTA_GATEWAY, &addr);
148         if (r < 0) {
149                 log_error("Could not append RTA_GATEWAY attribute: %s", strerror(-r));
150                 return;
151         }
152
153         r = sd_rtnl_message_append_u32(req, RTA_OIF, index);
154         if (r < 0) {
155                 log_error("Could not append RTA_OIF attribute: %s", strerror(-r));
156                 return;
157         }
158
159         assert_se(rtnl_message_seal(NULL, req) >= 0);
160
161         assert_se(sd_rtnl_message_read(req, &type, &data) > 0);
162         assert_se(type == RTA_GATEWAY);
163         assert_se(((struct in_addr *)data)->s_addr == addr.s_addr);
164
165         assert_se(sd_rtnl_message_read(req, &type, &data) > 0);
166         assert_se(type == RTA_OIF);
167         assert_se(*(uint32_t *) data == index);
168 }
169
170 static void test_multiple(void) {
171         sd_rtnl *rtnl1, *rtnl2;
172
173         assert_se(sd_rtnl_open(&rtnl1, 0) >= 0);
174         assert_se(sd_rtnl_open(&rtnl2, 0) >= 0);
175
176         rtnl1 = sd_rtnl_unref(rtnl1);
177         rtnl2 = sd_rtnl_unref(rtnl2);
178 }
179
180 static int link_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
181         void *data;
182         uint16_t type;
183         char *ifname = userdata;
184
185         assert_se(rtnl);
186         assert_se(m);
187
188         log_info("got link info about %s", ifname);
189         free(ifname);
190
191         while (sd_rtnl_message_read(m, &type, &data) > 0) {
192                 switch (type) {
193 //                        case IFLA_MTU:
194 //                                assert_se(*(unsigned int *) data == 65536);
195 //                                break;
196 //                        case IFLA_QDISC:
197 //                                assert_se(streq((char *) data, "noqueue"));
198 //                                break;
199                         case IFLA_IFNAME:
200                                 assert_se(streq((char *) data, "lo"));
201                                 break;
202                 }
203         }
204
205         return 1;
206 }
207
208 static void test_event_loop(int ifindex) {
209         _cleanup_event_unref_ sd_event *event = NULL;
210         _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
211         _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
212         char *ifname;
213
214         ifname = strdup("lo2");
215         assert_se(ifname);
216
217         assert_se(sd_rtnl_open(&rtnl, 0) >= 0);
218         assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0);
219
220         assert_se(sd_rtnl_call_async(rtnl, m, &link_handler, ifname, 0, NULL) >= 0);
221
222         assert_se(sd_event_default(&event) >= 0);
223
224         assert_se(sd_rtnl_attach_event(rtnl, event, 0) >= 0);
225
226         assert_se(sd_event_run(event, 0) >= 0);
227
228         assert_se(sd_rtnl_detach_event(rtnl) >= 0);
229 }
230
231 static int pipe_handler(sd_rtnl *rtnl, sd_rtnl_message *m, void *userdata) {
232         int *counter = userdata;
233
234         (*counter) --;
235
236         log_info("got reply, %d left in pipe", *counter);
237
238         return sd_rtnl_message_get_errno(m);
239 }
240
241 static void test_async(int ifindex) {
242         _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
243         _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL, *r = NULL;
244         uint32_t serial;
245         char *ifname;
246
247         ifname = strdup("lo");
248         assert_se(ifname);
249
250         assert_se(sd_rtnl_open(&rtnl, 0) >= 0);
251
252         assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0);
253
254         assert_se(sd_rtnl_call_async(rtnl, m, &link_handler, ifname, 0, &serial) >= 0);
255
256         assert_se(sd_rtnl_wait(rtnl, 0) >= 0);
257         assert_se(sd_rtnl_process(rtnl, &r) >= 0);
258 }
259
260 static void test_pipe(int ifindex) {
261         _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
262         _cleanup_rtnl_message_unref_ sd_rtnl_message *m1 = NULL, *m2 = NULL;
263         int counter = 0;
264
265         assert_se(sd_rtnl_open(&rtnl, 0) >= 0);
266
267         assert_se(sd_rtnl_message_new_link(rtnl, &m1, RTM_GETLINK, ifindex) >= 0);
268         assert_se(sd_rtnl_message_new_link(rtnl, &m2, RTM_GETLINK, ifindex) >= 0);
269
270         counter ++;
271         assert_se(sd_rtnl_call_async(rtnl, m1, &pipe_handler, &counter, 0, NULL) >= 0);
272
273         counter ++;
274         assert_se(sd_rtnl_call_async(rtnl, m2, &pipe_handler, &counter, 0, NULL) >= 0);
275
276         while (counter > 0) {
277                 assert_se(sd_rtnl_wait(rtnl, 0) >= 0);
278                 assert_se(sd_rtnl_process(rtnl, NULL) >= 0);
279         }
280 }
281
282 static void test_container(void) {
283         _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
284         uint16_t type;
285         void *data;
286
287         assert_se(sd_rtnl_message_new_link(NULL, &m, RTM_NEWLINK, 0) >= 0);
288
289         assert_se(sd_rtnl_message_open_container(m, IFLA_LINKINFO) >= 0);
290         assert_se(sd_rtnl_message_open_container(m, IFLA_LINKINFO) == -ENOTSUP);
291         assert_se(sd_rtnl_message_append_string(m, IFLA_INFO_KIND, "kind") >= 0);
292         assert_se(sd_rtnl_message_open_container(m, IFLA_INFO_DATA) >= 0);
293         assert_se(sd_rtnl_message_open_container(m, IFLA_INFO_DATA) == -ENOTSUP);
294         assert_se(sd_rtnl_message_append_u16(m, IFLA_VLAN_ID, 100) >= 0);
295         assert_se(sd_rtnl_message_close_container(m) >= 0);
296         assert_se(sd_rtnl_message_append_string(m, IFLA_INFO_KIND, "kind") >= 0);
297         assert_se(sd_rtnl_message_close_container(m) >= 0);
298         assert_se(sd_rtnl_message_close_container(m) == -EINVAL);
299
300         assert_se(rtnl_message_seal(NULL, m) >= 0);
301
302         assert_se(sd_rtnl_message_read(m, &type, &data) >= 0);
303         assert_se(type == IFLA_LINKINFO);
304         assert_se(data == NULL);
305         assert_se(sd_rtnl_message_read(m, &type, &data) >= 0);
306         assert_se(type == IFLA_INFO_KIND);
307         assert_se(streq("kind", (char *)data));
308         assert_se(sd_rtnl_message_read(m, &type, &data) >= 0);
309         assert_se(type == IFLA_INFO_DATA);
310         assert_se(data == NULL);
311         assert_se(sd_rtnl_message_read(m, &type, &data) >= 0);
312         assert_se(type == IFLA_VLAN_ID);
313         assert_se(*(uint16_t *)data == 100);
314         assert_se(sd_rtnl_message_read(m, &type, &data) == 0);
315         assert_se(sd_rtnl_message_exit_container(m) >= 0);
316         assert_se(sd_rtnl_message_read(m, &type, &data) >= 0);
317         assert_se(type == IFLA_INFO_KIND);
318         assert_se(streq("kind", (char *)data));
319         assert_se(sd_rtnl_message_read(m, &type, &data) == 0);
320         assert_se(sd_rtnl_message_exit_container(m) >= 0);
321         assert_se(sd_rtnl_message_exit_container(m) == -EINVAL);
322 }
323
324 static void test_match(void) {
325         _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
326
327         assert_se(sd_rtnl_open(&rtnl, 0) >= 0);
328
329         assert_se(sd_rtnl_add_match(rtnl, RTM_NEWLINK, &link_handler, NULL) >= 0);
330         assert_se(sd_rtnl_add_match(rtnl, RTM_NEWLINK, &link_handler, NULL) >= 0);
331
332         assert_se(sd_rtnl_remove_match(rtnl, RTM_NEWLINK, &link_handler, NULL) == 1);
333         assert_se(sd_rtnl_remove_match(rtnl, RTM_NEWLINK, &link_handler, NULL) == 1);
334         assert_se(sd_rtnl_remove_match(rtnl, RTM_NEWLINK, &link_handler, NULL) == 0);
335 }
336
337 int main(void) {
338         sd_rtnl *rtnl;
339         sd_rtnl_message *m;
340         sd_rtnl_message *r;
341         void *data;
342         int if_loopback;
343         uint16_t type;
344
345         test_match();
346
347         test_multiple();
348
349         test_route();
350
351         test_container();
352
353         assert_se(sd_rtnl_open(&rtnl, 0) >= 0);
354         assert_se(rtnl);
355
356         if_loopback = (int) if_nametoindex("lo");
357         assert_se(if_loopback > 0);
358
359         test_async(if_loopback);
360
361         test_pipe(if_loopback);
362
363         test_event_loop(if_loopback);
364
365         test_link_configure(rtnl, if_loopback);
366
367         assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, if_loopback) >= 0);
368         assert_se(m);
369
370         assert_se(sd_rtnl_message_get_type(m, &type) >= 0);
371         assert_se(type == RTM_GETLINK);
372
373         assert_se(sd_rtnl_message_read(m, &type, &data) == -EPERM);
374
375         assert_se(sd_rtnl_call(rtnl, m, 0, &r) == 1);
376         assert_se(sd_rtnl_message_get_type(r, &type) >= 0);
377         assert_se(type == RTM_NEWLINK);
378
379         assert_se(sd_rtnl_message_read(m, &type, &data) == 0);
380         assert_se((r = sd_rtnl_message_unref(r)) == NULL);
381
382         assert_se(sd_rtnl_call(rtnl, m, -1, &r) == -EPERM);
383         assert_se((m = sd_rtnl_message_unref(m)) == NULL);
384         assert_se((r = sd_rtnl_message_unref(r)) == NULL);
385
386         test_link_get(rtnl, if_loopback);
387
388         assert_se(sd_rtnl_flush(rtnl) >= 0);
389         assert_se((m = sd_rtnl_message_unref(m)) == NULL);
390         assert_se((r = sd_rtnl_message_unref(r)) == NULL);
391         assert_se((rtnl = sd_rtnl_unref(rtnl)) == NULL);
392
393         return EXIT_SUCCESS;
394 }