]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd/sd-netlink/test-netlink.c
sd-netlink: make sd_netlink_slot take its description
[thirdparty/systemd.git] / src / libsystemd / sd-netlink / test-netlink.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
1c4baffc 2
1c4baffc 3#include <net/if.h>
07630cea 4#include <netinet/ether.h>
1c4baffc 5
1c4baffc 6#include "sd-netlink.h"
07630cea 7
0d0f02cd 8#include "alloc-util.h"
81a56d6f 9#include "ether-addr-util.h"
07630cea 10#include "macro.h"
1c4baffc 11#include "missing.h"
07630cea
LP
12#include "netlink-util.h"
13#include "socket-util.h"
14#include "string-util.h"
15#include "util.h"
1c4baffc
TG
16
17static void test_message_link_bridge(sd_netlink *rtnl) {
4afd3348 18 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL;
1c4baffc
TG
19 uint32_t cost;
20
21 assert_se(sd_rtnl_message_new_link(rtnl, &message, RTM_NEWLINK, 1) >= 0);
22 assert_se(sd_rtnl_message_link_set_family(message, PF_BRIDGE) >= 0);
23 assert_se(sd_netlink_message_open_container(message, IFLA_PROTINFO) >= 0);
24 assert_se(sd_netlink_message_append_u32(message, IFLA_BRPORT_COST, 10) >= 0);
25 assert_se(sd_netlink_message_close_container(message) >= 0);
26
27 assert_se(sd_netlink_message_rewind(message) >= 0);
28
29 assert_se(sd_netlink_message_enter_container(message, IFLA_PROTINFO) >= 0);
30 assert_se(sd_netlink_message_read_u32(message, IFLA_BRPORT_COST, &cost) >= 0);
31 assert_se(cost == 10);
32 assert_se(sd_netlink_message_exit_container(message) >= 0);
33}
34
35static void test_link_configure(sd_netlink *rtnl, int ifindex) {
4afd3348 36 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL;
1c4baffc
TG
37 const char *mac = "98:fe:94:3f:c6:18", *name = "test";
38 char buffer[ETHER_ADDR_TO_STRING_MAX];
4e964aa0 39 uint32_t mtu = 1450, mtu_out;
1c4baffc
TG
40 const char *name_out;
41 struct ether_addr mac_out;
42
43 /* we'd really like to test NEWLINK, but let's not mess with the running kernel */
44 assert_se(sd_rtnl_message_new_link(rtnl, &message, RTM_GETLINK, ifindex) >= 0);
45 assert_se(sd_netlink_message_append_string(message, IFLA_IFNAME, name) >= 0);
46 assert_se(sd_netlink_message_append_ether_addr(message, IFLA_ADDRESS, ether_aton(mac)) >= 0);
47 assert_se(sd_netlink_message_append_u32(message, IFLA_MTU, mtu) >= 0);
48
49 assert_se(sd_netlink_call(rtnl, message, 0, NULL) == 1);
50 assert_se(sd_netlink_message_rewind(message) >= 0);
51
52 assert_se(sd_netlink_message_read_string(message, IFLA_IFNAME, &name_out) >= 0);
53 assert_se(streq(name, name_out));
54
55 assert_se(sd_netlink_message_read_ether_addr(message, IFLA_ADDRESS, &mac_out) >= 0);
56 assert_se(streq(mac, ether_addr_to_string(&mac_out, buffer)));
57
58 assert_se(sd_netlink_message_read_u32(message, IFLA_MTU, &mtu_out) >= 0);
59 assert_se(mtu == mtu_out);
60}
61
62static void test_link_get(sd_netlink *rtnl, int ifindex) {
63 sd_netlink_message *m;
64 sd_netlink_message *r;
4e964aa0 65 uint32_t mtu = 1500;
1c4baffc
TG
66 const char *str_data;
67 uint8_t u8_data;
68 uint32_t u32_data;
69 struct ether_addr eth_data;
70
71 assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0);
72 assert_se(m);
73
74 /* u8 test cases */
75 assert_se(sd_netlink_message_append_u8(m, IFLA_CARRIER, 0) >= 0);
76 assert_se(sd_netlink_message_append_u8(m, IFLA_OPERSTATE, 0) >= 0);
77 assert_se(sd_netlink_message_append_u8(m, IFLA_LINKMODE, 0) >= 0);
78
79 /* u32 test cases */
80 assert_se(sd_netlink_message_append_u32(m, IFLA_MTU, mtu) >= 0);
81 assert_se(sd_netlink_message_append_u32(m, IFLA_GROUP, 0) >= 0);
82 assert_se(sd_netlink_message_append_u32(m, IFLA_TXQLEN, 0) >= 0);
83 assert_se(sd_netlink_message_append_u32(m, IFLA_NUM_TX_QUEUES, 0) >= 0);
84 assert_se(sd_netlink_message_append_u32(m, IFLA_NUM_RX_QUEUES, 0) >= 0);
85
86 assert_se(sd_netlink_call(rtnl, m, -1, &r) == 1);
87
88 assert_se(sd_netlink_message_read_string(r, IFLA_IFNAME, &str_data) == 0);
89
90 assert_se(sd_netlink_message_read_u8(r, IFLA_CARRIER, &u8_data) == 0);
91 assert_se(sd_netlink_message_read_u8(r, IFLA_OPERSTATE, &u8_data) == 0);
92 assert_se(sd_netlink_message_read_u8(r, IFLA_LINKMODE, &u8_data) == 0);
93
94 assert_se(sd_netlink_message_read_u32(r, IFLA_MTU, &u32_data) == 0);
95 assert_se(sd_netlink_message_read_u32(r, IFLA_GROUP, &u32_data) == 0);
96 assert_se(sd_netlink_message_read_u32(r, IFLA_TXQLEN, &u32_data) == 0);
97 assert_se(sd_netlink_message_read_u32(r, IFLA_NUM_TX_QUEUES, &u32_data) == 0);
98 assert_se(sd_netlink_message_read_u32(r, IFLA_NUM_RX_QUEUES, &u32_data) == 0);
99
100 assert_se(sd_netlink_message_read_ether_addr(r, IFLA_ADDRESS, &eth_data) == 0);
101
1c4baffc
TG
102 assert_se((m = sd_netlink_message_unref(m)) == NULL);
103 assert_se((r = sd_netlink_message_unref(r)) == NULL);
104}
105
1c4baffc
TG
106static void test_address_get(sd_netlink *rtnl, int ifindex) {
107 sd_netlink_message *m;
108 sd_netlink_message *r;
109 struct in_addr in_data;
110 struct ifa_cacheinfo cache;
111 const char *label;
112
113 assert_se(sd_rtnl_message_new_addr(rtnl, &m, RTM_GETADDR, ifindex, AF_INET) >= 0);
114 assert_se(m);
115
116 assert_se(sd_netlink_call(rtnl, m, -1, &r) == 1);
117
118 assert_se(sd_netlink_message_read_in_addr(r, IFA_LOCAL, &in_data) == 0);
119 assert_se(sd_netlink_message_read_in_addr(r, IFA_ADDRESS, &in_data) == 0);
120 assert_se(sd_netlink_message_read_string(r, IFA_LABEL, &label) == 0);
121 assert_se(sd_netlink_message_read_cache_info(r, IFA_CACHEINFO, &cache) == 0);
122
1c4baffc
TG
123 assert_se((m = sd_netlink_message_unref(m)) == NULL);
124 assert_se((r = sd_netlink_message_unref(r)) == NULL);
125
126}
127
05d0c2e3 128static void test_route(sd_netlink *rtnl) {
4afd3348 129 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req;
1c4baffc
TG
130 struct in_addr addr, addr_data;
131 uint32_t index = 2, u32_data;
132 int r;
133
05d0c2e3 134 r = sd_rtnl_message_new_route(rtnl, &req, RTM_NEWROUTE, AF_INET, RTPROT_STATIC);
1c4baffc
TG
135 if (r < 0) {
136 log_error_errno(r, "Could not create RTM_NEWROUTE message: %m");
137 return;
138 }
139
140 addr.s_addr = htonl(INADDR_LOOPBACK);
141
142 r = sd_netlink_message_append_in_addr(req, RTA_GATEWAY, &addr);
143 if (r < 0) {
144 log_error_errno(r, "Could not append RTA_GATEWAY attribute: %m");
145 return;
146 }
147
148 r = sd_netlink_message_append_u32(req, RTA_OIF, index);
149 if (r < 0) {
150 log_error_errno(r, "Could not append RTA_OIF attribute: %m");
151 return;
152 }
153
154 assert_se(sd_netlink_message_rewind(req) >= 0);
155
156 assert_se(sd_netlink_message_read_in_addr(req, RTA_GATEWAY, &addr_data) >= 0);
157 assert_se(addr_data.s_addr == addr.s_addr);
158
159 assert_se(sd_netlink_message_read_u32(req, RTA_OIF, &u32_data) >= 0);
160 assert_se(u32_data == index);
161
162 assert_se((req = sd_netlink_message_unref(req)) == NULL);
163}
164
165static void test_multiple(void) {
166 sd_netlink *rtnl1, *rtnl2;
167
168 assert_se(sd_netlink_open(&rtnl1) >= 0);
169 assert_se(sd_netlink_open(&rtnl2) >= 0);
170
171 rtnl1 = sd_netlink_unref(rtnl1);
172 rtnl2 = sd_netlink_unref(rtnl2);
173}
174
175static int link_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
176 char *ifname = userdata;
177 const char *data;
178
179 assert_se(rtnl);
180 assert_se(m);
0d0f02cd 181 assert_se(userdata);
1c4baffc 182
0d0f02cd 183 log_info("%s: got link info about %s", __func__, ifname);
1c4baffc
TG
184 free(ifname);
185
186 assert_se(sd_netlink_message_read_string(m, IFLA_IFNAME, &data) >= 0);
187 assert_se(streq(data, "lo"));
188
189 return 1;
190}
191
192static void test_event_loop(int ifindex) {
4afd3348
LP
193 _cleanup_(sd_event_unrefp) sd_event *event = NULL;
194 _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
195 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
1c4baffc
TG
196 char *ifname;
197
198 ifname = strdup("lo2");
199 assert_se(ifname);
200
201 assert_se(sd_netlink_open(&rtnl) >= 0);
202 assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0);
203
8190a388 204 assert_se(sd_netlink_call_async(rtnl, NULL, m, link_handler, NULL, ifname, 0, NULL) >= 0);
1c4baffc
TG
205
206 assert_se(sd_event_default(&event) >= 0);
207
208 assert_se(sd_netlink_attach_event(rtnl, event, 0) >= 0);
209
210 assert_se(sd_event_run(event, 0) >= 0);
211
212 assert_se(sd_netlink_detach_event(rtnl) >= 0);
213
214 assert_se((rtnl = sd_netlink_unref(rtnl)) == NULL);
215}
216
0d0f02cd
YW
217static void test_async(int ifindex) {
218 _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
219 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL, *r = NULL;
ee38400b 220 _cleanup_(sd_netlink_slot_unrefp) sd_netlink_slot *slot = NULL;
0d0f02cd 221 char *ifname;
1c4baffc 222
0d0f02cd
YW
223 ifname = strdup("lo");
224 assert_se(ifname);
1c4baffc 225
0d0f02cd 226 assert_se(sd_netlink_open(&rtnl) >= 0);
1c4baffc 227
0d0f02cd 228 assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0);
1c4baffc 229
8190a388 230 assert_se(sd_netlink_call_async(rtnl, &slot, m, link_handler, NULL, ifname, 0, NULL) >= 0);
0d0f02cd
YW
231
232 assert_se(sd_netlink_wait(rtnl, 0) >= 0);
233 assert_se(sd_netlink_process(rtnl, &r) >= 0);
234
235 assert_se((rtnl = sd_netlink_unref(rtnl)) == NULL);
236}
237
238struct test_async_object {
239 unsigned n_ref;
240 char *ifname;
241};
242
243static struct test_async_object *test_async_object_free(struct test_async_object *t) {
244 assert(t);
245
246 free(t->ifname);
247 return mfree(t);
248}
249
250DEFINE_PRIVATE_TRIVIAL_REF_UNREF_FUNC(struct test_async_object, test_async_object, test_async_object_free);
251DEFINE_TRIVIAL_CLEANUP_FUNC(struct test_async_object *, test_async_object_unref);
252
253static int link_handler2(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
254 struct test_async_object *t = userdata;
255 const char *data;
256
257 assert_se(rtnl);
258 assert_se(m);
259 assert_se(userdata);
260
261 log_info("%s: got link info about %s", __func__, t->ifname);
262
263 assert_se(sd_netlink_message_read_string(m, IFLA_IFNAME, &data) >= 0);
264 assert_se(streq(data, "lo"));
1c4baffc
TG
265
266 return 1;
267}
268
0d0f02cd
YW
269static void test_async_object_destroy(void *userdata) {
270 struct test_async_object *t = userdata;
271
272 assert(userdata);
273
274 log_info("%s: n_ref=%u", __func__, t->n_ref);
275 test_async_object_unref(t);
276}
277
278static void test_async_destroy_callback(int ifindex) {
4afd3348
LP
279 _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
280 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL, *r = NULL;
0d0f02cd 281 _cleanup_(test_async_object_unrefp) struct test_async_object *t = NULL;
ee38400b 282 _cleanup_(sd_netlink_slot_unrefp) sd_netlink_slot *slot = NULL;
1c4baffc
TG
283 char *ifname;
284
0d0f02cd
YW
285 assert_se(t = new(struct test_async_object, 1));
286 assert_se(ifname = strdup("lo"));
287 *t = (struct test_async_object) {
288 .n_ref = 1,
289 .ifname = ifname,
290 };
1c4baffc
TG
291
292 assert_se(sd_netlink_open(&rtnl) >= 0);
293
0d0f02cd 294 /* destroy callback is called after processing message */
1c4baffc 295 assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0);
8190a388 296 assert_se(sd_netlink_call_async(rtnl, NULL, m, link_handler2, test_async_object_destroy, t, 0, NULL) >= 0);
1c4baffc 297
0d0f02cd
YW
298 assert_se(t->n_ref == 1);
299 assert_se(test_async_object_ref(t));
300 assert_se(t->n_ref == 2);
1c4baffc
TG
301
302 assert_se(sd_netlink_wait(rtnl, 0) >= 0);
0d0f02cd
YW
303 assert_se(sd_netlink_process(rtnl, &r) == 1);
304 assert_se(t->n_ref == 1);
305
306 assert_se(!sd_netlink_message_unref(m));
307
ee38400b 308 /* destroy callback is called when asynchronous call is cancelled, that is, slot is freed. */
0d0f02cd 309 assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0);
8190a388 310 assert_se(sd_netlink_call_async(rtnl, &slot, m, link_handler2, test_async_object_destroy, t, 0, NULL) >= 0);
0d0f02cd
YW
311
312 assert_se(t->n_ref == 1);
313 assert_se(test_async_object_ref(t));
314 assert_se(t->n_ref == 2);
315
ee38400b 316 assert_se(!(slot = sd_netlink_slot_unref(slot)));
0d0f02cd
YW
317 assert_se(t->n_ref == 1);
318
319 assert_se(!sd_netlink_message_unref(m));
320
321 /* destroy callback is also called by sd_netlink_unref() */
322 assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, ifindex) >= 0);
8190a388 323 assert_se(sd_netlink_call_async(rtnl, NULL, m, link_handler2, test_async_object_destroy, t, 0, NULL) >= 0);
0d0f02cd
YW
324
325 assert_se(t->n_ref == 1);
326 assert_se(test_async_object_ref(t));
327 assert_se(t->n_ref == 2);
1c4baffc
TG
328
329 assert_se((rtnl = sd_netlink_unref(rtnl)) == NULL);
0d0f02cd
YW
330 assert_se(t->n_ref == 1);
331}
332
333static int pipe_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
334 int *counter = userdata;
335 int r;
336
337 (*counter)--;
338
339 r = sd_netlink_message_get_errno(m);
340
341 log_info_errno(r, "%d left in pipe. got reply: %m", *counter);
342
343 assert_se(r >= 0);
344
345 return 1;
1c4baffc
TG
346}
347
348static void test_pipe(int ifindex) {
4afd3348
LP
349 _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
350 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m1 = NULL, *m2 = NULL;
1c4baffc
TG
351 int counter = 0;
352
353 assert_se(sd_netlink_open(&rtnl) >= 0);
354
355 assert_se(sd_rtnl_message_new_link(rtnl, &m1, RTM_GETLINK, ifindex) >= 0);
356 assert_se(sd_rtnl_message_new_link(rtnl, &m2, RTM_GETLINK, ifindex) >= 0);
357
313cefa1 358 counter++;
8190a388 359 assert_se(sd_netlink_call_async(rtnl, NULL, m1, pipe_handler, NULL, &counter, 0, NULL) >= 0);
1c4baffc 360
313cefa1 361 counter++;
8190a388 362 assert_se(sd_netlink_call_async(rtnl, NULL, m2, pipe_handler, NULL, &counter, 0, NULL) >= 0);
1c4baffc
TG
363
364 while (counter > 0) {
365 assert_se(sd_netlink_wait(rtnl, 0) >= 0);
366 assert_se(sd_netlink_process(rtnl, NULL) >= 0);
367 }
368
369 assert_se((rtnl = sd_netlink_unref(rtnl)) == NULL);
370}
371
05d0c2e3 372static void test_container(sd_netlink *rtnl) {
4afd3348 373 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
1c4baffc
TG
374 uint16_t u16_data;
375 uint32_t u32_data;
376 const char *string_data;
377
05d0c2e3 378 assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_NEWLINK, 0) >= 0);
1c4baffc
TG
379
380 assert_se(sd_netlink_message_open_container(m, IFLA_LINKINFO) >= 0);
381 assert_se(sd_netlink_message_open_container_union(m, IFLA_INFO_DATA, "vlan") >= 0);
382 assert_se(sd_netlink_message_append_u16(m, IFLA_VLAN_ID, 100) >= 0);
383 assert_se(sd_netlink_message_close_container(m) >= 0);
384 assert_se(sd_netlink_message_append_string(m, IFLA_INFO_KIND, "vlan") >= 0);
385 assert_se(sd_netlink_message_close_container(m) >= 0);
386 assert_se(sd_netlink_message_close_container(m) == -EINVAL);
387
388 assert_se(sd_netlink_message_rewind(m) >= 0);
389
390 assert_se(sd_netlink_message_enter_container(m, IFLA_LINKINFO) >= 0);
391 assert_se(sd_netlink_message_read_string(m, IFLA_INFO_KIND, &string_data) >= 0);
392 assert_se(streq("vlan", string_data));
393
394 assert_se(sd_netlink_message_enter_container(m, IFLA_INFO_DATA) >= 0);
395 assert_se(sd_netlink_message_read_u16(m, IFLA_VLAN_ID, &u16_data) >= 0);
396 assert_se(sd_netlink_message_exit_container(m) >= 0);
397
398 assert_se(sd_netlink_message_read_string(m, IFLA_INFO_KIND, &string_data) >= 0);
399 assert_se(streq("vlan", string_data));
400 assert_se(sd_netlink_message_exit_container(m) >= 0);
401
402 assert_se(sd_netlink_message_read_u32(m, IFLA_LINKINFO, &u32_data) < 0);
403
404 assert_se(sd_netlink_message_exit_container(m) == -EINVAL);
405}
406
407static void test_match(void) {
ee38400b 408 _cleanup_(sd_netlink_slot_unrefp) sd_netlink_slot *s1 = NULL, *s2 = NULL;
4afd3348 409 _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
1c4baffc
TG
410
411 assert_se(sd_netlink_open(&rtnl) >= 0);
412
8190a388
YW
413 assert_se(sd_netlink_add_match(rtnl, &s1, RTM_NEWLINK, link_handler, NULL, NULL, NULL) >= 0);
414 assert_se(sd_netlink_add_match(rtnl, &s2, RTM_NEWLINK, link_handler, NULL, NULL, NULL) >= 0);
415 assert_se(sd_netlink_add_match(rtnl, NULL, RTM_NEWLINK, link_handler, NULL, NULL, NULL) >= 0);
1c4baffc 416
ee38400b
YW
417 assert_se(!(s1 = sd_netlink_slot_unref(s1)));
418 assert_se(!(s2 = sd_netlink_slot_unref(s2)));
1c4baffc
TG
419
420 assert_se((rtnl = sd_netlink_unref(rtnl)) == NULL);
421}
422
423static void test_get_addresses(sd_netlink *rtnl) {
4afd3348 424 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
1c4baffc
TG
425 sd_netlink_message *m;
426
427 assert_se(sd_rtnl_message_new_addr(rtnl, &req, RTM_GETADDR, 0, AF_UNSPEC) >= 0);
428
429 assert_se(sd_netlink_call(rtnl, req, 0, &reply) >= 0);
430
431 for (m = reply; m; m = sd_netlink_message_next(m)) {
432 uint16_t type;
433 unsigned char scope, flags;
434 int family, ifindex;
435
436 assert_se(sd_netlink_message_get_type(m, &type) >= 0);
437 assert_se(type == RTM_NEWADDR);
438
439 assert_se(sd_rtnl_message_addr_get_ifindex(m, &ifindex) >= 0);
440 assert_se(sd_rtnl_message_addr_get_family(m, &family) >= 0);
441 assert_se(sd_rtnl_message_addr_get_scope(m, &scope) >= 0);
442 assert_se(sd_rtnl_message_addr_get_flags(m, &flags) >= 0);
443
444 assert_se(ifindex > 0);
945c2931 445 assert_se(IN_SET(family, AF_INET, AF_INET6));
1c4baffc
TG
446
447 log_info("got IPv%u address on ifindex %i", family == AF_INET ? 4: 6, ifindex);
448 }
449}
450
05d0c2e3 451static void test_message(sd_netlink *rtnl) {
4afd3348 452 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
1c4baffc 453
05d0c2e3 454 assert_se(rtnl_message_new_synthetic_error(rtnl, -ETIMEDOUT, 1, &m) >= 0);
1c4baffc
TG
455 assert_se(sd_netlink_message_get_errno(m) == -ETIMEDOUT);
456}
457
458int main(void) {
459 sd_netlink *rtnl;
460 sd_netlink_message *m;
461 sd_netlink_message *r;
462 const char *string_data;
463 int if_loopback;
464 uint16_t type;
465
1c4baffc 466 test_match();
1c4baffc
TG
467 test_multiple();
468
1c4baffc
TG
469 assert_se(sd_netlink_open(&rtnl) >= 0);
470 assert_se(rtnl);
471
05d0c2e3 472 test_route(rtnl);
05d0c2e3 473 test_message(rtnl);
05d0c2e3
JT
474 test_container(rtnl);
475
1c4baffc
TG
476 if_loopback = (int) if_nametoindex("lo");
477 assert_se(if_loopback > 0);
478
479 test_async(if_loopback);
0d0f02cd 480 test_async_destroy_callback(if_loopback);
1c4baffc 481 test_pipe(if_loopback);
1c4baffc 482 test_event_loop(if_loopback);
1c4baffc
TG
483 test_link_configure(rtnl, if_loopback);
484
485 test_get_addresses(rtnl);
1c4baffc
TG
486 test_message_link_bridge(rtnl);
487
488 assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_GETLINK, if_loopback) >= 0);
489 assert_se(m);
490
491 assert_se(sd_netlink_message_get_type(m, &type) >= 0);
492 assert_se(type == RTM_GETLINK);
493
494 assert_se(sd_netlink_message_read_string(m, IFLA_IFNAME, &string_data) == -EPERM);
495
496 assert_se(sd_netlink_call(rtnl, m, 0, &r) == 1);
497 assert_se(sd_netlink_message_get_type(r, &type) >= 0);
498 assert_se(type == RTM_NEWLINK);
499
500 assert_se((r = sd_netlink_message_unref(r)) == NULL);
501
502 assert_se(sd_netlink_call(rtnl, m, -1, &r) == -EPERM);
503 assert_se((m = sd_netlink_message_unref(m)) == NULL);
504 assert_se((r = sd_netlink_message_unref(r)) == NULL);
505
506 test_link_get(rtnl, if_loopback);
507 test_address_get(rtnl, if_loopback);
508
1c4baffc
TG
509 assert_se((m = sd_netlink_message_unref(m)) == NULL);
510 assert_se((r = sd_netlink_message_unref(r)) == NULL);
511 assert_se((rtnl = sd_netlink_unref(rtnl)) == NULL);
512
513 return EXIT_SUCCESS;
514}