1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
4 #include <linux/genetlink.h>
5 #include <linux/if_macsec.h>
6 #include <linux/l2tp.h>
7 #include <linux/nl80211.h>
8 #include <linux/unix_diag.h>
9 #include <net/ethernet.h>
11 #include <netinet/in.h>
16 #include "sd-netlink.h"
18 #include "alloc-util.h"
20 #include "missing_network.h"
21 #include "netlink-genl.h"
22 #include "netlink-internal.h"
23 #include "netlink-sock-diag.h"
24 #include "netlink-util.h"
25 #include "socket-util.h"
26 #include "stdio-util.h"
29 #include "time-util.h"
31 TEST(message_newlink_bridge
) {
32 _cleanup_(sd_netlink_unrefp
) sd_netlink
*rtnl
= NULL
;
33 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*message
= NULL
;
36 ASSERT_OK(sd_netlink_open(&rtnl
));
38 ASSERT_OK(sd_rtnl_message_new_link(rtnl
, &message
, RTM_NEWLINK
, 1));
39 ASSERT_OK(sd_rtnl_message_link_set_family(message
, AF_BRIDGE
));
40 ASSERT_OK(sd_netlink_message_open_container(message
, IFLA_PROTINFO
));
41 ASSERT_OK(sd_netlink_message_append_u32(message
, IFLA_BRPORT_COST
, 10));
42 ASSERT_OK(sd_netlink_message_close_container(message
));
44 ASSERT_OK(sd_netlink_message_rewind(message
, rtnl
));
46 ASSERT_OK(sd_netlink_message_enter_container(message
, IFLA_PROTINFO
));
47 ASSERT_OK(sd_netlink_message_read_u32(message
, IFLA_BRPORT_COST
, &cost
));
49 ASSERT_OK(sd_netlink_message_exit_container(message
));
52 TEST(message_getlink
) {
53 _cleanup_(sd_netlink_unrefp
) sd_netlink
*rtnl
= NULL
;
54 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*message
= NULL
, *reply
= NULL
;
60 struct ether_addr eth_data
;
62 ASSERT_OK(sd_netlink_open(&rtnl
));
63 ifindex
= (int) if_nametoindex("lo");
65 /* we'd really like to test NEWLINK, but let's not mess with the running kernel */
66 ASSERT_OK(sd_rtnl_message_new_link(rtnl
, &message
, RTM_GETLINK
, ifindex
));
67 ASSERT_OK_EQ(sd_netlink_call(rtnl
, message
, 0, &reply
), 1);
70 ASSERT_OK(sd_netlink_message_read_u8(reply
, IFLA_CARRIER
, &u8_data
));
71 ASSERT_OK(sd_netlink_message_read_u8(reply
, IFLA_OPERSTATE
, &u8_data
));
72 ASSERT_OK(sd_netlink_message_read_u8(reply
, IFLA_LINKMODE
, &u8_data
));
75 ASSERT_OK(sd_netlink_message_get_type(reply
, &u16_data
));
76 ASSERT_EQ(u16_data
, RTM_NEWLINK
);
79 ASSERT_OK(sd_netlink_message_read_u32(reply
, IFLA_MTU
, &u32_data
));
80 ASSERT_OK(sd_netlink_message_read_u32(reply
, IFLA_GROUP
, &u32_data
));
81 ASSERT_OK(sd_netlink_message_read_u32(reply
, IFLA_TXQLEN
, &u32_data
));
82 ASSERT_OK(sd_netlink_message_read_u32(reply
, IFLA_NUM_TX_QUEUES
, &u32_data
));
85 ASSERT_OK(sd_netlink_message_read_string(reply
, IFLA_IFNAME
, &str_data
));
88 ASSERT_OK(sd_netlink_message_read_ether_addr(reply
, IFLA_ADDRESS
, ð_data
));
91 TEST(message_address
) {
92 _cleanup_(sd_netlink_unrefp
) sd_netlink
*rtnl
= NULL
;
93 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*message
= NULL
, *reply
= NULL
;
95 struct in_addr in_data
;
96 struct ifa_cacheinfo cache
;
100 ASSERT_OK(sd_netlink_open(&rtnl
));
101 ifindex
= (int) if_nametoindex("lo");
103 ASSERT_OK(sd_rtnl_message_new_addr(rtnl
, &message
, RTM_GETADDR
, ifindex
, AF_INET
));
104 ASSERT_OK(sd_netlink_message_set_request_dump(message
, true));
106 ASSERT_OK(r
= sd_netlink_call(rtnl
, message
, 0, &reply
));
108 /* If the loopback device is down we won't get any results. */
110 ASSERT_OK(sd_netlink_message_read_in_addr(reply
, IFA_LOCAL
, &in_data
));
111 ASSERT_OK(sd_netlink_message_read_in_addr(reply
, IFA_ADDRESS
, &in_data
));
112 ASSERT_OK(sd_netlink_message_read_string(reply
, IFA_LABEL
, &label
));
113 ASSERT_OK(sd_netlink_message_read_cache_info(reply
, IFA_CACHEINFO
, &cache
));
117 TEST(message_route
) {
118 _cleanup_(sd_netlink_unrefp
) sd_netlink
*rtnl
= NULL
;
119 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*req
= NULL
;
120 struct in_addr addr
, addr_data
;
121 uint32_t index
= 2, u32_data
;
123 ASSERT_OK(sd_netlink_open(&rtnl
));
125 ASSERT_OK(sd_rtnl_message_new_route(rtnl
, &req
, RTM_NEWROUTE
, AF_INET
, RTPROT_STATIC
));
127 addr
.s_addr
= htobe32(INADDR_LOOPBACK
);
129 ASSERT_OK(sd_netlink_message_append_in_addr(req
, RTA_GATEWAY
, &addr
));
130 ASSERT_OK(sd_netlink_message_append_u32(req
, RTA_OIF
, index
));
132 ASSERT_OK(sd_netlink_message_rewind(req
, rtnl
));
134 ASSERT_OK(sd_netlink_message_read_in_addr(req
, RTA_GATEWAY
, &addr_data
));
135 ASSERT_EQ(addr_data
.s_addr
, addr
.s_addr
);
137 ASSERT_OK(sd_netlink_message_read_u32(req
, RTA_OIF
, &u32_data
));
138 ASSERT_EQ(u32_data
, index
);
140 ASSERT_NULL(req
= sd_netlink_message_unref(req
));
143 static int link_handler(sd_netlink
*rtnl
, sd_netlink_message
*m
, void *userdata
) {
146 ASSERT_NOT_NULL(rtnl
);
149 ASSERT_STREQ(userdata
, "foo");
151 ASSERT_OK(sd_netlink_message_read_string(m
, IFLA_IFNAME
, &data
));
152 ASSERT_STREQ(data
, "lo");
154 log_info("%s: got link info about %s", __func__
, data
);
158 TEST(netlink_event_loop
) {
159 _cleanup_(sd_event_unrefp
) sd_event
*event
= NULL
;
160 _cleanup_(sd_netlink_unrefp
) sd_netlink
*rtnl
= NULL
;
161 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*m
= NULL
;
162 _cleanup_free_
char *userdata
= NULL
;
165 ASSERT_OK(sd_netlink_open(&rtnl
));
166 ifindex
= (int) if_nametoindex("lo");
168 ASSERT_NOT_NULL((userdata
= strdup("foo")));
170 ASSERT_OK(sd_event_default(&event
));
171 ASSERT_OK(sd_netlink_attach_event(rtnl
, event
, 0));
173 ASSERT_OK(sd_rtnl_message_new_link(rtnl
, &m
, RTM_GETLINK
, ifindex
));
174 ASSERT_OK(sd_netlink_call_async(rtnl
, NULL
, m
, link_handler
, NULL
, userdata
, 0, NULL
));
176 ASSERT_OK(sd_event_run(event
, 0));
178 ASSERT_OK(sd_netlink_detach_event(rtnl
));
179 ASSERT_NULL(rtnl
= sd_netlink_unref(rtnl
));
182 static void test_async_destroy(void *userdata
) {
185 TEST(netlink_call_async
) {
186 _cleanup_(sd_netlink_unrefp
) sd_netlink
*rtnl
= NULL
;
187 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*m
= NULL
, *reply
= NULL
;
188 _cleanup_(sd_netlink_slot_unrefp
) sd_netlink_slot
*slot
= NULL
;
189 _cleanup_free_
char *userdata
= NULL
;
190 sd_netlink_destroy_t destroy_callback
;
191 const char *description
;
194 ASSERT_OK(sd_netlink_open(&rtnl
));
195 ifindex
= (int) if_nametoindex("lo");
197 ASSERT_NOT_NULL((userdata
= strdup("foo")));
199 ASSERT_OK(sd_rtnl_message_new_link(rtnl
, &m
, RTM_GETLINK
, ifindex
));
200 ASSERT_OK(sd_netlink_call_async(rtnl
, &slot
, m
, link_handler
, test_async_destroy
, userdata
, 0, "hogehoge"));
202 ASSERT_PTR_EQ(sd_netlink_slot_get_netlink(slot
), rtnl
);
204 ASSERT_PTR_EQ(sd_netlink_slot_get_userdata(slot
), userdata
);
205 ASSERT_PTR_EQ(sd_netlink_slot_set_userdata(slot
, NULL
), userdata
);
206 ASSERT_NULL(sd_netlink_slot_get_userdata(slot
));
207 ASSERT_NULL(sd_netlink_slot_set_userdata(slot
, userdata
));
208 ASSERT_PTR_EQ(sd_netlink_slot_get_userdata(slot
), userdata
);
210 ASSERT_OK_EQ(sd_netlink_slot_get_destroy_callback(slot
, &destroy_callback
), 1);
211 ASSERT_PTR_EQ(destroy_callback
, test_async_destroy
);
212 ASSERT_OK(sd_netlink_slot_set_destroy_callback(slot
, NULL
));
213 ASSERT_OK_ZERO(sd_netlink_slot_get_destroy_callback(slot
, &destroy_callback
));
214 ASSERT_NULL(destroy_callback
);
215 ASSERT_OK(sd_netlink_slot_set_destroy_callback(slot
, test_async_destroy
));
216 ASSERT_OK_EQ(sd_netlink_slot_get_destroy_callback(slot
, &destroy_callback
), 1);
217 ASSERT_PTR_EQ(destroy_callback
, test_async_destroy
);
219 ASSERT_OK_ZERO(sd_netlink_slot_get_floating(slot
));
220 ASSERT_OK_EQ(sd_netlink_slot_set_floating(slot
, 1), 1);
221 ASSERT_OK_EQ(sd_netlink_slot_get_floating(slot
), 1);
223 ASSERT_OK_EQ(sd_netlink_slot_get_description(slot
, &description
), 1);
224 ASSERT_STREQ(description
, "hogehoge");
225 ASSERT_OK(sd_netlink_slot_set_description(slot
, NULL
));
226 ASSERT_OK_ZERO(sd_netlink_slot_get_description(slot
, &description
));
227 ASSERT_NULL(description
);
229 ASSERT_OK(sd_netlink_wait(rtnl
, 0));
230 ASSERT_OK(sd_netlink_process(rtnl
, &reply
));
232 ASSERT_NULL(rtnl
= sd_netlink_unref(rtnl
));
235 struct test_async_object
{
240 static struct test_async_object
*test_async_object_free(struct test_async_object
*t
) {
247 DEFINE_PRIVATE_TRIVIAL_REF_UNREF_FUNC(struct test_async_object
, test_async_object
, test_async_object_free
);
248 DEFINE_TRIVIAL_CLEANUP_FUNC(struct test_async_object
*, test_async_object_unref
);
250 static int link_handler2(sd_netlink
*rtnl
, sd_netlink_message
*m
, void *userdata
) {
251 struct test_async_object
*t
= userdata
;
254 ASSERT_NOT_NULL(rtnl
);
256 ASSERT_NOT_NULL(userdata
);
258 log_info("%s: got link info about %s", __func__
, t
->ifname
);
260 ASSERT_OK(sd_netlink_message_read_string(m
, IFLA_IFNAME
, &data
));
261 ASSERT_STREQ(data
, "lo");
266 static void test_async_object_destroy(void *userdata
) {
267 struct test_async_object
*t
= userdata
;
269 ASSERT_NOT_NULL(userdata
);
271 log_info("%s: n_ref=%u", __func__
, t
->n_ref
);
272 test_async_object_unref(t
);
275 TEST(async_destroy_callback
) {
276 _cleanup_(sd_netlink_unrefp
) sd_netlink
*rtnl
= NULL
;
277 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*m
= NULL
, *reply
= NULL
;
278 _cleanup_(test_async_object_unrefp
) struct test_async_object
*t
= NULL
;
279 _cleanup_(sd_netlink_slot_unrefp
) sd_netlink_slot
*slot
= NULL
;
282 ASSERT_OK(sd_netlink_open(&rtnl
));
283 ifindex
= (int) if_nametoindex("lo");
285 ASSERT_NOT_NULL((t
= new(struct test_async_object
, 1)));
286 *t
= (struct test_async_object
) {
289 ASSERT_NOT_NULL((t
->ifname
= strdup("lo")));
291 /* destroy callback is called after processing message */
292 ASSERT_OK(sd_rtnl_message_new_link(rtnl
, &m
, RTM_GETLINK
, ifindex
));
293 ASSERT_OK(sd_netlink_call_async(rtnl
, NULL
, m
, link_handler2
, test_async_object_destroy
, t
, 0, NULL
));
295 ASSERT_EQ(t
->n_ref
, 1U);
296 ASSERT_PTR_EQ(test_async_object_ref(t
), t
);
297 ASSERT_EQ(t
->n_ref
, 2U);
299 ASSERT_OK(sd_netlink_wait(rtnl
, 0));
300 ASSERT_OK_EQ(sd_netlink_process(rtnl
, &reply
), 1);
301 ASSERT_EQ(t
->n_ref
, 1U);
303 ASSERT_NULL(sd_netlink_message_unref(m
));
305 /* destroy callback is called when asynchronous call is cancelled, that is, slot is freed. */
306 ASSERT_OK(sd_rtnl_message_new_link(rtnl
, &m
, RTM_GETLINK
, ifindex
));
307 ASSERT_OK(sd_netlink_call_async(rtnl
, &slot
, m
, link_handler2
, test_async_object_destroy
, t
, 0, NULL
));
309 ASSERT_EQ(t
->n_ref
, 1U);
310 ASSERT_PTR_EQ(test_async_object_ref(t
), t
);
311 ASSERT_EQ(t
->n_ref
, 2U);
313 ASSERT_NULL(slot
= sd_netlink_slot_unref(slot
));
314 ASSERT_EQ(t
->n_ref
, 1U);
316 ASSERT_NULL(sd_netlink_message_unref(m
));
318 /* destroy callback is also called by sd_netlink_unref() */
319 ASSERT_OK(sd_rtnl_message_new_link(rtnl
, &m
, RTM_GETLINK
, ifindex
));
320 ASSERT_OK(sd_netlink_call_async(rtnl
, NULL
, m
, link_handler2
, test_async_object_destroy
, t
, 0, NULL
));
322 ASSERT_EQ(t
->n_ref
, 1U);
323 ASSERT_PTR_EQ(test_async_object_ref(t
), t
);
324 ASSERT_EQ(t
->n_ref
, 2U);
326 ASSERT_NULL(rtnl
= sd_netlink_unref(rtnl
));
327 ASSERT_EQ(t
->n_ref
, 1U);
330 static int pipe_handler(sd_netlink
*rtnl
, sd_netlink_message
*m
, void *userdata
) {
331 int r
, *counter
= userdata
;
335 ASSERT_OK(r
= sd_netlink_message_get_errno(m
));
336 log_info_errno(r
, "%d left in pipe. got reply: %m", *counter
);
341 _cleanup_(sd_netlink_unrefp
) sd_netlink
*rtnl
= NULL
;
342 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*m1
= NULL
, *m2
= NULL
;
343 int ifindex
, counter
= 0;
345 ASSERT_OK(sd_netlink_open(&rtnl
));
346 ifindex
= (int) if_nametoindex("lo");
348 ASSERT_OK(sd_rtnl_message_new_link(rtnl
, &m1
, RTM_GETLINK
, ifindex
));
349 ASSERT_OK(sd_rtnl_message_new_link(rtnl
, &m2
, RTM_GETLINK
, ifindex
));
352 ASSERT_OK(sd_netlink_call_async(rtnl
, NULL
, m1
, pipe_handler
, NULL
, &counter
, 0, NULL
));
355 ASSERT_OK(sd_netlink_call_async(rtnl
, NULL
, m2
, pipe_handler
, NULL
, &counter
, 0, NULL
));
357 while (counter
> 0) {
358 ASSERT_OK(sd_netlink_wait(rtnl
, 0));
359 ASSERT_OK(sd_netlink_process(rtnl
, NULL
));
362 ASSERT_NULL(rtnl
= sd_netlink_unref(rtnl
));
365 TEST(message_container
) {
366 _cleanup_(sd_netlink_unrefp
) sd_netlink
*rtnl
= NULL
;
367 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*m
= NULL
;
370 const char *string_data
;
372 ASSERT_OK(sd_netlink_open(&rtnl
));
374 ASSERT_OK(sd_rtnl_message_new_link(rtnl
, &m
, RTM_NEWLINK
, 0));
376 ASSERT_OK(sd_netlink_message_open_container(m
, IFLA_LINKINFO
));
377 ASSERT_OK(sd_netlink_message_open_container_union(m
, IFLA_INFO_DATA
, "vlan"));
378 ASSERT_OK(sd_netlink_message_append_u16(m
, IFLA_VLAN_ID
, 100));
379 ASSERT_OK(sd_netlink_message_close_container(m
));
380 ASSERT_OK(sd_netlink_message_close_container(m
));
382 ASSERT_OK(sd_netlink_message_rewind(m
, rtnl
));
384 ASSERT_OK(sd_netlink_message_enter_container(m
, IFLA_LINKINFO
));
385 ASSERT_OK(sd_netlink_message_read_string(m
, IFLA_INFO_KIND
, &string_data
));
386 ASSERT_STREQ("vlan", string_data
);
388 ASSERT_OK(sd_netlink_message_enter_container(m
, IFLA_INFO_DATA
));
389 ASSERT_OK(sd_netlink_message_read_u16(m
, IFLA_VLAN_ID
, &u16_data
));
390 ASSERT_OK(sd_netlink_message_exit_container(m
));
392 ASSERT_OK(sd_netlink_message_read_string(m
, IFLA_INFO_KIND
, &string_data
));
393 ASSERT_STREQ("vlan", string_data
);
394 ASSERT_OK(sd_netlink_message_exit_container(m
));
396 ASSERT_FAIL(sd_netlink_message_read_u32(m
, IFLA_LINKINFO
, &u32_data
));
399 TEST(sd_netlink_add_match
) {
400 _cleanup_(sd_netlink_slot_unrefp
) sd_netlink_slot
*s1
= NULL
, *s2
= NULL
;
401 _cleanup_(sd_netlink_unrefp
) sd_netlink
*rtnl
= NULL
;
403 ASSERT_OK(sd_netlink_open(&rtnl
));
405 ASSERT_OK(sd_netlink_add_match(rtnl
, &s1
, RTM_NEWLINK
, link_handler
, NULL
, NULL
, NULL
));
406 ASSERT_OK(sd_netlink_add_match(rtnl
, &s2
, RTM_NEWLINK
, link_handler
, NULL
, NULL
, NULL
));
407 ASSERT_OK(sd_netlink_add_match(rtnl
, NULL
, RTM_NEWLINK
, link_handler
, NULL
, NULL
, NULL
));
409 ASSERT_NULL(s1
= sd_netlink_slot_unref(s1
));
410 ASSERT_NULL(s2
= sd_netlink_slot_unref(s2
));
412 ASSERT_NULL(rtnl
= sd_netlink_unref(rtnl
));
415 TEST(dump_addresses
) {
416 _cleanup_(sd_netlink_unrefp
) sd_netlink
*rtnl
= NULL
;
417 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*req
= NULL
, *reply
= NULL
;
419 ASSERT_OK(sd_netlink_open(&rtnl
));
421 ASSERT_OK(sd_rtnl_message_new_addr(rtnl
, &req
, RTM_GETADDR
, 0, AF_UNSPEC
));
422 ASSERT_OK(sd_netlink_message_set_request_dump(req
, true));
423 ASSERT_OK(sd_netlink_call(rtnl
, req
, 0, &reply
));
425 for (sd_netlink_message
*m
= reply
; m
; m
= sd_netlink_message_next(m
)) {
431 ASSERT_OK(sd_netlink_message_get_type(m
, &type
));
432 ASSERT_EQ(type
, RTM_NEWADDR
);
434 ASSERT_OK(sd_rtnl_message_addr_get_ifindex(m
, &ifindex
));
435 ASSERT_OK(sd_rtnl_message_addr_get_family(m
, &family
));
436 ASSERT_OK(sd_rtnl_message_addr_get_scope(m
, &scope
));
437 ASSERT_OK(sd_netlink_message_read_u32(m
, IFA_FLAGS
, &flags
));
439 ASSERT_GT(ifindex
, 0);
440 ASSERT_TRUE(IN_SET(family
, AF_INET
, AF_INET6
));
442 log_info("got IPv%i address on ifindex %i", family
== AF_INET
? 4 : 6, ifindex
);
446 TEST(sd_netlink_message_get_errno
) {
447 _cleanup_(sd_netlink_unrefp
) sd_netlink
*rtnl
= NULL
;
448 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*m
= NULL
;
450 ASSERT_OK(sd_netlink_open(&rtnl
));
452 ASSERT_OK(message_new_synthetic_error(rtnl
, -ETIMEDOUT
, 1, &m
));
453 ASSERT_ERROR(sd_netlink_message_get_errno(m
), ETIMEDOUT
);
456 TEST(message_array
) {
457 _cleanup_(sd_netlink_unrefp
) sd_netlink
*genl
= NULL
;
458 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*m
= NULL
;
460 ASSERT_OK(sd_genl_socket_open(&genl
));
461 ASSERT_OK(sd_genl_message_new(genl
, CTRL_GENL_NAME
, CTRL_CMD_GETFAMILY
, &m
));
463 ASSERT_OK(sd_netlink_message_open_container(m
, CTRL_ATTR_MCAST_GROUPS
));
464 for (unsigned i
= 0; i
< 10; i
++) {
465 char name
[STRLEN("hoge") + DECIMAL_STR_MAX(uint32_t)];
466 uint32_t id
= i
+ 1000;
468 xsprintf(name
, "hoge%" PRIu32
, id
);
469 ASSERT_OK(sd_netlink_message_open_array(m
, i
+ 1));
470 ASSERT_OK(sd_netlink_message_append_u32(m
, CTRL_ATTR_MCAST_GRP_ID
, id
));
471 ASSERT_OK(sd_netlink_message_append_string(m
, CTRL_ATTR_MCAST_GRP_NAME
, name
));
472 ASSERT_OK(sd_netlink_message_close_container(m
));
474 ASSERT_OK(sd_netlink_message_close_container(m
));
477 ASSERT_OK(sd_netlink_message_rewind(m
, genl
));
479 ASSERT_OK(sd_netlink_message_enter_container(m
, CTRL_ATTR_MCAST_GROUPS
));
480 for (unsigned i
= 0; i
< 10; i
++) {
481 char expected
[STRLEN("hoge") + DECIMAL_STR_MAX(uint32_t)];
485 ASSERT_OK(sd_netlink_message_enter_array(m
, i
+ 1));
486 ASSERT_OK(sd_netlink_message_read_u32(m
, CTRL_ATTR_MCAST_GRP_ID
, &id
));
487 ASSERT_OK(sd_netlink_message_read_string(m
, CTRL_ATTR_MCAST_GRP_NAME
, &name
));
488 ASSERT_OK(sd_netlink_message_exit_container(m
));
490 ASSERT_EQ(id
, i
+ 1000);
491 xsprintf(expected
, "hoge%" PRIu32
, id
);
492 ASSERT_STREQ(name
, expected
);
494 ASSERT_OK(sd_netlink_message_exit_container(m
));
498 _cleanup_(sd_netlink_unrefp
) sd_netlink
*rtnl
= NULL
;
499 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*m
= NULL
;
500 _cleanup_strv_free_
char **names_in
= NULL
, **names_out
;
503 ASSERT_OK(sd_netlink_open(&rtnl
));
505 ASSERT_OK(sd_rtnl_message_new_link(rtnl
, &m
, RTM_NEWLINKPROP
, 1));
507 for (unsigned i
= 0; i
< 10; i
++) {
508 char name
[STRLEN("hoge") + DECIMAL_STR_MAX(uint32_t)];
510 xsprintf(name
, "hoge%" PRIu32
, i
+ 1000);
511 ASSERT_OK(strv_extend(&names_in
, name
));
514 ASSERT_OK(sd_netlink_message_open_container(m
, IFLA_PROP_LIST
));
515 ASSERT_OK(sd_netlink_message_append_strv(m
, IFLA_ALT_IFNAME
, (const char**) names_in
));
516 ASSERT_OK(sd_netlink_message_close_container(m
));
519 ASSERT_OK(sd_netlink_message_rewind(m
, rtnl
));
521 ASSERT_OK(sd_netlink_message_read_strv(m
, IFLA_PROP_LIST
, IFLA_ALT_IFNAME
, &names_out
));
522 ASSERT_TRUE(strv_equal(names_in
, names_out
));
524 ASSERT_OK(sd_netlink_message_enter_container(m
, IFLA_PROP_LIST
));
525 ASSERT_OK(sd_netlink_message_read_string(m
, IFLA_ALT_IFNAME
, &p
));
526 ASSERT_STREQ(p
, "hoge1009");
527 ASSERT_OK(sd_netlink_message_exit_container(m
));
530 static int genl_ctrl_match_callback(sd_netlink
*genl
, sd_netlink_message
*m
, void *userdata
) {
535 ASSERT_NOT_NULL(genl
);
538 ASSERT_OK(sd_genl_message_get_family_name(genl
, m
, &name
));
539 ASSERT_STREQ(name
, CTRL_GENL_NAME
);
541 ASSERT_OK(sd_genl_message_get_command(genl
, m
, &cmd
));
544 case CTRL_CMD_NEWFAMILY
:
545 case CTRL_CMD_DELFAMILY
:
546 ASSERT_OK(sd_netlink_message_read_string(m
, CTRL_ATTR_FAMILY_NAME
, &name
));
547 ASSERT_OK(sd_netlink_message_read_u16(m
, CTRL_ATTR_FAMILY_ID
, &id
));
548 log_debug("%s: %s (id=%"PRIu16
") family is %s.",
549 __func__
, name
, id
, cmd
== CTRL_CMD_NEWFAMILY
? "added" : "removed");
551 case CTRL_CMD_NEWMCAST_GRP
:
552 case CTRL_CMD_DELMCAST_GRP
:
553 ASSERT_OK(sd_netlink_message_read_string(m
, CTRL_ATTR_FAMILY_NAME
, &name
));
554 ASSERT_OK(sd_netlink_message_read_u16(m
, CTRL_ATTR_FAMILY_ID
, &id
));
555 log_debug("%s: multicast group for %s (id=%"PRIu16
") family is %s.",
556 __func__
, name
, id
, cmd
== CTRL_CMD_NEWMCAST_GRP
? "added" : "removed");
559 log_debug("%s: received nlctrl message with unknown command '%"PRIu8
"'.", __func__
, cmd
);
566 _cleanup_(sd_event_unrefp
) sd_event
*event
= NULL
;
567 _cleanup_(sd_netlink_unrefp
) sd_netlink
*genl
= NULL
;
568 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*m
= NULL
;
573 ASSERT_OK(sd_genl_socket_open(&genl
));
574 ASSERT_OK(sd_event_default(&event
));
575 ASSERT_OK(sd_netlink_attach_event(genl
, event
, 0));
577 ASSERT_OK(sd_genl_message_new(genl
, CTRL_GENL_NAME
, CTRL_CMD_GETFAMILY
, &m
));
578 ASSERT_OK(sd_genl_message_get_family_name(genl
, m
, &name
));
579 ASSERT_STREQ(name
, CTRL_GENL_NAME
);
580 ASSERT_OK(sd_genl_message_get_command(genl
, m
, &cmd
));
581 ASSERT_EQ(cmd
, CTRL_CMD_GETFAMILY
);
583 ASSERT_OK(sd_genl_add_match(genl
, NULL
, CTRL_GENL_NAME
, "notify", 0, genl_ctrl_match_callback
, NULL
, NULL
, "genl-ctrl-notify"));
585 ASSERT_NULL(m
= sd_netlink_message_unref(m
));
586 ASSERT_FAIL(sd_genl_message_new(genl
, "should-not-exist", CTRL_CMD_GETFAMILY
, &m
));
587 ASSERT_ERROR(sd_genl_message_new(genl
, "should-not-exist", CTRL_CMD_GETFAMILY
, &m
), EOPNOTSUPP
);
589 /* These families may not be supported by kernel. Hence, ignore results. */
590 (void) sd_genl_message_new(genl
, FOU_GENL_NAME
, 0, &m
);
591 ASSERT_NULL(m
= sd_netlink_message_unref(m
));
592 (void) sd_genl_message_new(genl
, L2TP_GENL_NAME
, 0, &m
);
593 ASSERT_NULL(m
= sd_netlink_message_unref(m
));
594 (void) sd_genl_message_new(genl
, MACSEC_GENL_NAME
, 0, &m
);
595 ASSERT_NULL(m
= sd_netlink_message_unref(m
));
596 (void) sd_genl_message_new(genl
, NL80211_GENL_NAME
, 0, &m
);
597 ASSERT_NULL(m
= sd_netlink_message_unref(m
));
598 (void) sd_genl_message_new(genl
, NETLBL_NLTYPE_UNLABELED_NAME
, 0, &m
);
601 ASSERT_OK(r
= sd_event_run(event
, 500 * USEC_PER_MSEC
));
607 static void remove_dummy_interfacep(int *ifindex
) {
608 _cleanup_(sd_netlink_unrefp
) sd_netlink
*rtnl
= NULL
;
609 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*message
= NULL
;
611 if (!ifindex
|| *ifindex
<= 0)
614 ASSERT_OK(sd_netlink_open(&rtnl
));
616 ASSERT_OK(sd_rtnl_message_new_link(rtnl
, &message
, RTM_DELLINK
, *ifindex
));
617 ASSERT_OK_EQ(sd_netlink_call(rtnl
, message
, 0, NULL
), 1);
620 TEST(rtnl_set_link_name
) {
621 _cleanup_(sd_netlink_unrefp
) sd_netlink
*rtnl
= NULL
;
622 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*message
= NULL
, *reply
= NULL
;
623 _cleanup_(remove_dummy_interfacep
) int ifindex
= 0;
624 _cleanup_strv_free_
char **alternative_names
= NULL
;
628 return (void) log_tests_skipped("not root");
630 ASSERT_OK(sd_netlink_open(&rtnl
));
632 ASSERT_OK(sd_rtnl_message_new_link(rtnl
, &message
, RTM_NEWLINK
, 0));
633 ASSERT_OK(sd_netlink_message_append_string(message
, IFLA_IFNAME
, "test-netlink"));
634 ASSERT_OK(sd_netlink_message_open_container(message
, IFLA_LINKINFO
));
635 ASSERT_OK(sd_netlink_message_append_string(message
, IFLA_INFO_KIND
, "dummy"));
636 r
= sd_netlink_call(rtnl
, message
, 0, &reply
);
638 return (void) log_tests_skipped("missing required capabilities");
639 if (r
== -EOPNOTSUPP
)
640 return (void) log_tests_skipped("dummy network interface is not supported");
643 ASSERT_NULL(message
= sd_netlink_message_unref(message
));
644 ASSERT_NULL(reply
= sd_netlink_message_unref(reply
));
646 ASSERT_OK(sd_rtnl_message_new_link(rtnl
, &message
, RTM_GETLINK
, 0));
647 ASSERT_OK(sd_netlink_message_append_string(message
, IFLA_IFNAME
, "test-netlink"));
648 ASSERT_OK_EQ(sd_netlink_call(rtnl
, message
, 0, &reply
), 1);
650 ASSERT_OK(sd_rtnl_message_link_get_ifindex(reply
, &ifindex
));
651 ASSERT_GT(ifindex
, 0);
653 /* Test that the new name (which is currently an alternative name) is
654 * restored as an alternative name on error. Create an error by using
655 * an invalid device name, namely one that exceeds IFNAMSIZ
656 * (alternative names can exceed IFNAMSIZ, but not regular names). */
657 r
= rtnl_set_link_alternative_names(&rtnl
, ifindex
, STRV_MAKE("testlongalternativename", "test-shortname"));
659 return (void) log_tests_skipped("missing required capabilities");
660 if (r
== -EOPNOTSUPP
)
661 return (void) log_tests_skipped("alternative name is not supported");
664 ASSERT_OK(rtnl_get_link_alternative_names(&rtnl
, ifindex
, &alternative_names
));
665 ASSERT_TRUE(strv_contains(alternative_names
, "testlongalternativename"));
666 ASSERT_TRUE(strv_contains(alternative_names
, "test-shortname"));
668 ASSERT_ERROR(rtnl_set_link_name(&rtnl
, ifindex
, "testlongalternativename", NULL
), EINVAL
);
669 ASSERT_OK(rtnl_set_link_name(&rtnl
, ifindex
, "test-shortname", STRV_MAKE("testlongalternativename", "test-shortname", "test-additional-name")));
671 ASSERT_NULL(alternative_names
= strv_free(alternative_names
));
672 ASSERT_OK(rtnl_get_link_alternative_names(&rtnl
, ifindex
, &alternative_names
));
673 ASSERT_TRUE(strv_contains(alternative_names
, "testlongalternativename"));
674 ASSERT_TRUE(strv_contains(alternative_names
, "test-additional-name"));
675 ASSERT_FALSE(strv_contains(alternative_names
, "test-shortname"));
677 ASSERT_OK(rtnl_delete_link_alternative_names(&rtnl
, ifindex
, STRV_MAKE("testlongalternativename")));
679 ASSERT_NULL(alternative_names
= strv_free(alternative_names
));
680 ASSERT_OK_EQ(rtnl_get_link_alternative_names(&rtnl
, ifindex
, &alternative_names
), ifindex
);
681 ASSERT_FALSE(strv_contains(alternative_names
, "testlongalternativename"));
682 ASSERT_TRUE(strv_contains(alternative_names
, "test-additional-name"));
683 ASSERT_FALSE(strv_contains(alternative_names
, "test-shortname"));
685 _cleanup_free_
char *resolved
= NULL
;
686 ASSERT_OK_EQ(rtnl_resolve_link_alternative_name(&rtnl
, "test-additional-name", NULL
), ifindex
);
687 ASSERT_OK_EQ(rtnl_resolve_link_alternative_name(&rtnl
, "test-additional-name", &resolved
), ifindex
);
688 ASSERT_STREQ(resolved
, "test-shortname");
689 ASSERT_NULL(resolved
= mfree(resolved
));
691 ASSERT_OK(rtnl_rename_link(&rtnl
, "test-shortname", "test-shortname"));
692 ASSERT_OK(rtnl_rename_link(&rtnl
, "test-shortname", "test-shortname2"));
693 ASSERT_OK(rtnl_rename_link(NULL
, "test-shortname2", "test-shortname3"));
695 ASSERT_OK_EQ(rtnl_resolve_link_alternative_name(&rtnl
, "test-additional-name", NULL
), ifindex
);
696 ASSERT_OK_EQ(rtnl_resolve_link_alternative_name(&rtnl
, "test-additional-name", &resolved
), ifindex
);
697 ASSERT_STREQ(resolved
, "test-shortname3");
698 ASSERT_NULL(resolved
= mfree(resolved
));
700 ASSERT_OK_EQ(rtnl_resolve_link_alternative_name(&rtnl
, "test-shortname3", NULL
), ifindex
);
701 ASSERT_OK_EQ(rtnl_resolve_link_alternative_name(&rtnl
, "test-shortname3", &resolved
), ifindex
);
702 ASSERT_STREQ(resolved
, "test-shortname3");
703 ASSERT_NULL(resolved
= mfree(resolved
));
706 TEST(sock_diag_unix
) {
707 _cleanup_(sd_netlink_unrefp
) sd_netlink
*nl
= NULL
;
710 ASSERT_OK(sd_sock_diag_socket_open(&nl
));
712 _cleanup_close_
int unix_fd
= ASSERT_FD(socket(AF_UNIX
, SOCK_STREAM
|SOCK_CLOEXEC
, 0));
713 ASSERT_OK(socket_autobind(unix_fd
, /* ret_name= */ NULL
));
714 ASSERT_OK_ERRNO(listen(unix_fd
, 123));
717 ASSERT_OK_ERRNO(fstat(unix_fd
, &st
));
720 ASSERT_OK(socket_get_cookie(unix_fd
, &cookie
));
722 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*message
= NULL
;
723 ASSERT_OK(sd_sock_diag_message_new_unix(nl
, &message
, st
.st_ino
, cookie
, UDIAG_SHOW_RQLEN
));
725 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*reply
= NULL
;
726 r
= sd_netlink_call(nl
, message
, /* timeout= */ 0, &reply
);
728 return (void) log_tests_skipped("CONFIG_UNIX_DIAG disabled");
732 DEFINE_TEST_MAIN(LOG_DEBUG
);