2 This file is part of systemd.
4 Copyright 2013 Tom Gundersen <teg@jklm.no>
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
21 #include <netinet/ether.h>
23 #include "sd-netlink.h"
25 #include "ether-addr-util.h"
28 #include "netlink-util.h"
29 #include "socket-util.h"
30 #include "string-util.h"
33 static void test_message_link_bridge(sd_netlink
*rtnl
) {
34 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*message
= NULL
;
37 assert_se(sd_rtnl_message_new_link(rtnl
, &message
, RTM_NEWLINK
, 1) >= 0);
38 assert_se(sd_rtnl_message_link_set_family(message
, PF_BRIDGE
) >= 0);
39 assert_se(sd_netlink_message_open_container(message
, IFLA_PROTINFO
) >= 0);
40 assert_se(sd_netlink_message_append_u32(message
, IFLA_BRPORT_COST
, 10) >= 0);
41 assert_se(sd_netlink_message_close_container(message
) >= 0);
43 assert_se(sd_netlink_message_rewind(message
) >= 0);
45 assert_se(sd_netlink_message_enter_container(message
, IFLA_PROTINFO
) >= 0);
46 assert_se(sd_netlink_message_read_u32(message
, IFLA_BRPORT_COST
, &cost
) >= 0);
47 assert_se(cost
== 10);
48 assert_se(sd_netlink_message_exit_container(message
) >= 0);
51 static void test_link_configure(sd_netlink
*rtnl
, int ifindex
) {
52 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*message
= NULL
;
53 const char *mac
= "98:fe:94:3f:c6:18", *name
= "test";
54 char buffer
[ETHER_ADDR_TO_STRING_MAX
];
55 unsigned int mtu
= 1450, mtu_out
;
57 struct ether_addr mac_out
;
59 /* we'd really like to test NEWLINK, but let's not mess with the running kernel */
60 assert_se(sd_rtnl_message_new_link(rtnl
, &message
, RTM_GETLINK
, ifindex
) >= 0);
61 assert_se(sd_netlink_message_append_string(message
, IFLA_IFNAME
, name
) >= 0);
62 assert_se(sd_netlink_message_append_ether_addr(message
, IFLA_ADDRESS
, ether_aton(mac
)) >= 0);
63 assert_se(sd_netlink_message_append_u32(message
, IFLA_MTU
, mtu
) >= 0);
65 assert_se(sd_netlink_call(rtnl
, message
, 0, NULL
) == 1);
66 assert_se(sd_netlink_message_rewind(message
) >= 0);
68 assert_se(sd_netlink_message_read_string(message
, IFLA_IFNAME
, &name_out
) >= 0);
69 assert_se(streq(name
, name_out
));
71 assert_se(sd_netlink_message_read_ether_addr(message
, IFLA_ADDRESS
, &mac_out
) >= 0);
72 assert_se(streq(mac
, ether_addr_to_string(&mac_out
, buffer
)));
74 assert_se(sd_netlink_message_read_u32(message
, IFLA_MTU
, &mtu_out
) >= 0);
75 assert_se(mtu
== mtu_out
);
78 static void test_link_get(sd_netlink
*rtnl
, int ifindex
) {
79 sd_netlink_message
*m
;
80 sd_netlink_message
*r
;
81 unsigned int mtu
= 1500;
85 struct ether_addr eth_data
;
87 assert_se(sd_rtnl_message_new_link(rtnl
, &m
, RTM_GETLINK
, ifindex
) >= 0);
91 assert_se(sd_netlink_message_append_u8(m
, IFLA_CARRIER
, 0) >= 0);
92 assert_se(sd_netlink_message_append_u8(m
, IFLA_OPERSTATE
, 0) >= 0);
93 assert_se(sd_netlink_message_append_u8(m
, IFLA_LINKMODE
, 0) >= 0);
96 assert_se(sd_netlink_message_append_u32(m
, IFLA_MTU
, mtu
) >= 0);
97 assert_se(sd_netlink_message_append_u32(m
, IFLA_GROUP
, 0) >= 0);
98 assert_se(sd_netlink_message_append_u32(m
, IFLA_TXQLEN
, 0) >= 0);
99 assert_se(sd_netlink_message_append_u32(m
, IFLA_NUM_TX_QUEUES
, 0) >= 0);
100 assert_se(sd_netlink_message_append_u32(m
, IFLA_NUM_RX_QUEUES
, 0) >= 0);
102 assert_se(sd_netlink_call(rtnl
, m
, -1, &r
) == 1);
104 assert_se(sd_netlink_message_read_string(r
, IFLA_IFNAME
, &str_data
) == 0);
106 assert_se(sd_netlink_message_read_u8(r
, IFLA_CARRIER
, &u8_data
) == 0);
107 assert_se(sd_netlink_message_read_u8(r
, IFLA_OPERSTATE
, &u8_data
) == 0);
108 assert_se(sd_netlink_message_read_u8(r
, IFLA_LINKMODE
, &u8_data
) == 0);
110 assert_se(sd_netlink_message_read_u32(r
, IFLA_MTU
, &u32_data
) == 0);
111 assert_se(sd_netlink_message_read_u32(r
, IFLA_GROUP
, &u32_data
) == 0);
112 assert_se(sd_netlink_message_read_u32(r
, IFLA_TXQLEN
, &u32_data
) == 0);
113 assert_se(sd_netlink_message_read_u32(r
, IFLA_NUM_TX_QUEUES
, &u32_data
) == 0);
114 assert_se(sd_netlink_message_read_u32(r
, IFLA_NUM_RX_QUEUES
, &u32_data
) == 0);
116 assert_se(sd_netlink_message_read_ether_addr(r
, IFLA_ADDRESS
, ð_data
) == 0);
118 assert_se((m
= sd_netlink_message_unref(m
)) == NULL
);
119 assert_se((r
= sd_netlink_message_unref(r
)) == NULL
);
123 static void test_address_get(sd_netlink
*rtnl
, int ifindex
) {
124 sd_netlink_message
*m
;
125 sd_netlink_message
*r
;
126 struct in_addr in_data
;
127 struct ifa_cacheinfo cache
;
130 assert_se(sd_rtnl_message_new_addr(rtnl
, &m
, RTM_GETADDR
, ifindex
, AF_INET
) >= 0);
133 assert_se(sd_netlink_call(rtnl
, m
, -1, &r
) == 1);
135 assert_se(sd_netlink_message_read_in_addr(r
, IFA_LOCAL
, &in_data
) == 0);
136 assert_se(sd_netlink_message_read_in_addr(r
, IFA_ADDRESS
, &in_data
) == 0);
137 assert_se(sd_netlink_message_read_string(r
, IFA_LABEL
, &label
) == 0);
138 assert_se(sd_netlink_message_read_cache_info(r
, IFA_CACHEINFO
, &cache
) == 0);
140 assert_se((m
= sd_netlink_message_unref(m
)) == NULL
);
141 assert_se((r
= sd_netlink_message_unref(r
)) == NULL
);
145 static void test_route(void) {
146 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*req
;
147 struct in_addr addr
, addr_data
;
148 uint32_t index
= 2, u32_data
;
151 r
= sd_rtnl_message_new_route(NULL
, &req
, RTM_NEWROUTE
, AF_INET
, RTPROT_STATIC
);
153 log_error_errno(r
, "Could not create RTM_NEWROUTE message: %m");
157 addr
.s_addr
= htonl(INADDR_LOOPBACK
);
159 r
= sd_netlink_message_append_in_addr(req
, RTA_GATEWAY
, &addr
);
161 log_error_errno(r
, "Could not append RTA_GATEWAY attribute: %m");
165 r
= sd_netlink_message_append_u32(req
, RTA_OIF
, index
);
167 log_error_errno(r
, "Could not append RTA_OIF attribute: %m");
171 assert_se(sd_netlink_message_rewind(req
) >= 0);
173 assert_se(sd_netlink_message_read_in_addr(req
, RTA_GATEWAY
, &addr_data
) >= 0);
174 assert_se(addr_data
.s_addr
== addr
.s_addr
);
176 assert_se(sd_netlink_message_read_u32(req
, RTA_OIF
, &u32_data
) >= 0);
177 assert_se(u32_data
== index
);
179 assert_se((req
= sd_netlink_message_unref(req
)) == NULL
);
182 static void test_multiple(void) {
183 sd_netlink
*rtnl1
, *rtnl2
;
185 assert_se(sd_netlink_open(&rtnl1
) >= 0);
186 assert_se(sd_netlink_open(&rtnl2
) >= 0);
188 rtnl1
= sd_netlink_unref(rtnl1
);
189 rtnl2
= sd_netlink_unref(rtnl2
);
192 static int link_handler(sd_netlink
*rtnl
, sd_netlink_message
*m
, void *userdata
) {
193 char *ifname
= userdata
;
199 log_info("got link info about %s", ifname
);
202 assert_se(sd_netlink_message_read_string(m
, IFLA_IFNAME
, &data
) >= 0);
203 assert_se(streq(data
, "lo"));
208 static void test_event_loop(int ifindex
) {
209 _cleanup_(sd_event_unrefp
) sd_event
*event
= NULL
;
210 _cleanup_(sd_netlink_unrefp
) sd_netlink
*rtnl
= NULL
;
211 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*m
= NULL
;
214 ifname
= strdup("lo2");
217 assert_se(sd_netlink_open(&rtnl
) >= 0);
218 assert_se(sd_rtnl_message_new_link(rtnl
, &m
, RTM_GETLINK
, ifindex
) >= 0);
220 assert_se(sd_netlink_call_async(rtnl
, m
, &link_handler
, ifname
, 0, NULL
) >= 0);
222 assert_se(sd_event_default(&event
) >= 0);
224 assert_se(sd_netlink_attach_event(rtnl
, event
, 0) >= 0);
226 assert_se(sd_event_run(event
, 0) >= 0);
228 assert_se(sd_netlink_detach_event(rtnl
) >= 0);
230 assert_se((rtnl
= sd_netlink_unref(rtnl
)) == NULL
);
233 static int pipe_handler(sd_netlink
*rtnl
, sd_netlink_message
*m
, void *userdata
) {
234 int *counter
= userdata
;
239 r
= sd_netlink_message_get_errno(m
);
241 log_info_errno(r
, "%d left in pipe. got reply: %m", *counter
);
248 static void test_async(int ifindex
) {
249 _cleanup_(sd_netlink_unrefp
) sd_netlink
*rtnl
= NULL
;
250 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*m
= NULL
, *r
= NULL
;
254 ifname
= strdup("lo");
257 assert_se(sd_netlink_open(&rtnl
) >= 0);
259 assert_se(sd_rtnl_message_new_link(rtnl
, &m
, RTM_GETLINK
, ifindex
) >= 0);
261 assert_se(sd_netlink_call_async(rtnl
, m
, &link_handler
, ifname
, 0, &serial
) >= 0);
263 assert_se(sd_netlink_wait(rtnl
, 0) >= 0);
264 assert_se(sd_netlink_process(rtnl
, &r
) >= 0);
266 assert_se((rtnl
= sd_netlink_unref(rtnl
)) == NULL
);
269 static void test_pipe(int ifindex
) {
270 _cleanup_(sd_netlink_unrefp
) sd_netlink
*rtnl
= NULL
;
271 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*m1
= NULL
, *m2
= NULL
;
274 assert_se(sd_netlink_open(&rtnl
) >= 0);
276 assert_se(sd_rtnl_message_new_link(rtnl
, &m1
, RTM_GETLINK
, ifindex
) >= 0);
277 assert_se(sd_rtnl_message_new_link(rtnl
, &m2
, RTM_GETLINK
, ifindex
) >= 0);
280 assert_se(sd_netlink_call_async(rtnl
, m1
, &pipe_handler
, &counter
, 0, NULL
) >= 0);
283 assert_se(sd_netlink_call_async(rtnl
, m2
, &pipe_handler
, &counter
, 0, NULL
) >= 0);
285 while (counter
> 0) {
286 assert_se(sd_netlink_wait(rtnl
, 0) >= 0);
287 assert_se(sd_netlink_process(rtnl
, NULL
) >= 0);
290 assert_se((rtnl
= sd_netlink_unref(rtnl
)) == NULL
);
293 static void test_container(void) {
294 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*m
= NULL
;
297 const char *string_data
;
299 assert_se(sd_rtnl_message_new_link(NULL
, &m
, RTM_NEWLINK
, 0) >= 0);
301 assert_se(sd_netlink_message_open_container(m
, IFLA_LINKINFO
) >= 0);
302 assert_se(sd_netlink_message_open_container_union(m
, IFLA_INFO_DATA
, "vlan") >= 0);
303 assert_se(sd_netlink_message_append_u16(m
, IFLA_VLAN_ID
, 100) >= 0);
304 assert_se(sd_netlink_message_close_container(m
) >= 0);
305 assert_se(sd_netlink_message_append_string(m
, IFLA_INFO_KIND
, "vlan") >= 0);
306 assert_se(sd_netlink_message_close_container(m
) >= 0);
307 assert_se(sd_netlink_message_close_container(m
) == -EINVAL
);
309 assert_se(sd_netlink_message_rewind(m
) >= 0);
311 assert_se(sd_netlink_message_enter_container(m
, IFLA_LINKINFO
) >= 0);
312 assert_se(sd_netlink_message_read_string(m
, IFLA_INFO_KIND
, &string_data
) >= 0);
313 assert_se(streq("vlan", string_data
));
315 assert_se(sd_netlink_message_enter_container(m
, IFLA_INFO_DATA
) >= 0);
316 assert_se(sd_netlink_message_read_u16(m
, IFLA_VLAN_ID
, &u16_data
) >= 0);
317 assert_se(sd_netlink_message_exit_container(m
) >= 0);
319 assert_se(sd_netlink_message_read_string(m
, IFLA_INFO_KIND
, &string_data
) >= 0);
320 assert_se(streq("vlan", string_data
));
321 assert_se(sd_netlink_message_exit_container(m
) >= 0);
323 assert_se(sd_netlink_message_read_u32(m
, IFLA_LINKINFO
, &u32_data
) < 0);
325 assert_se(sd_netlink_message_exit_container(m
) == -EINVAL
);
328 static void test_match(void) {
329 _cleanup_(sd_netlink_unrefp
) sd_netlink
*rtnl
= NULL
;
331 assert_se(sd_netlink_open(&rtnl
) >= 0);
333 assert_se(sd_netlink_add_match(rtnl
, RTM_NEWLINK
, &link_handler
, NULL
) >= 0);
334 assert_se(sd_netlink_add_match(rtnl
, RTM_NEWLINK
, &link_handler
, NULL
) >= 0);
336 assert_se(sd_netlink_remove_match(rtnl
, RTM_NEWLINK
, &link_handler
, NULL
) == 1);
337 assert_se(sd_netlink_remove_match(rtnl
, RTM_NEWLINK
, &link_handler
, NULL
) == 1);
338 assert_se(sd_netlink_remove_match(rtnl
, RTM_NEWLINK
, &link_handler
, NULL
) == 0);
340 assert_se((rtnl
= sd_netlink_unref(rtnl
)) == NULL
);
343 static void test_get_addresses(sd_netlink
*rtnl
) {
344 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*req
= NULL
, *reply
= NULL
;
345 sd_netlink_message
*m
;
347 assert_se(sd_rtnl_message_new_addr(rtnl
, &req
, RTM_GETADDR
, 0, AF_UNSPEC
) >= 0);
349 assert_se(sd_netlink_call(rtnl
, req
, 0, &reply
) >= 0);
351 for (m
= reply
; m
; m
= sd_netlink_message_next(m
)) {
353 unsigned char scope
, flags
;
356 assert_se(sd_netlink_message_get_type(m
, &type
) >= 0);
357 assert_se(type
== RTM_NEWADDR
);
359 assert_se(sd_rtnl_message_addr_get_ifindex(m
, &ifindex
) >= 0);
360 assert_se(sd_rtnl_message_addr_get_family(m
, &family
) >= 0);
361 assert_se(sd_rtnl_message_addr_get_scope(m
, &scope
) >= 0);
362 assert_se(sd_rtnl_message_addr_get_flags(m
, &flags
) >= 0);
364 assert_se(ifindex
> 0);
365 assert_se(family
== AF_INET
|| family
== AF_INET6
);
367 log_info("got IPv%u address on ifindex %i", family
== AF_INET
? 4: 6, ifindex
);
371 static void test_message(void) {
372 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*m
= NULL
;
374 assert_se(rtnl_message_new_synthetic_error(-ETIMEDOUT
, 1, &m
) >= 0);
375 assert_se(sd_netlink_message_get_errno(m
) == -ETIMEDOUT
);
380 sd_netlink_message
*m
;
381 sd_netlink_message
*r
;
382 const char *string_data
;
396 assert_se(sd_netlink_open(&rtnl
) >= 0);
399 if_loopback
= (int) if_nametoindex("lo");
400 assert_se(if_loopback
> 0);
402 test_async(if_loopback
);
404 test_pipe(if_loopback
);
406 test_event_loop(if_loopback
);
408 test_link_configure(rtnl
, if_loopback
);
410 test_get_addresses(rtnl
);
412 test_message_link_bridge(rtnl
);
414 assert_se(sd_rtnl_message_new_link(rtnl
, &m
, RTM_GETLINK
, if_loopback
) >= 0);
417 assert_se(sd_netlink_message_get_type(m
, &type
) >= 0);
418 assert_se(type
== RTM_GETLINK
);
420 assert_se(sd_netlink_message_read_string(m
, IFLA_IFNAME
, &string_data
) == -EPERM
);
422 assert_se(sd_netlink_call(rtnl
, m
, 0, &r
) == 1);
423 assert_se(sd_netlink_message_get_type(r
, &type
) >= 0);
424 assert_se(type
== RTM_NEWLINK
);
426 assert_se((r
= sd_netlink_message_unref(r
)) == NULL
);
428 assert_se(sd_netlink_call(rtnl
, m
, -1, &r
) == -EPERM
);
429 assert_se((m
= sd_netlink_message_unref(m
)) == NULL
);
430 assert_se((r
= sd_netlink_message_unref(r
)) == NULL
);
432 test_link_get(rtnl
, if_loopback
);
433 test_address_get(rtnl
, if_loopback
);
435 assert_se((m
= sd_netlink_message_unref(m
)) == NULL
);
436 assert_se((r
= sd_netlink_message_unref(r
)) == NULL
);
437 assert_se((rtnl
= sd_netlink_unref(rtnl
)) == NULL
);