Bug Summary

File:build-scan/../src/network/networkd-manager.c
Warning:line 1383, column 25
Potential leak of memory pointed to by 'm'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name networkd-manager.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -menable-no-infs -menable-no-nans -menable-unsafe-fp-math -fno-signed-zeros -mreassociate -freciprocal-math -fdenormal-fp-math=preserve-sign,preserve-sign -ffp-contract=fast -fno-rounding-math -ffast-math -ffinite-math-only -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -include config.h -I src/network/libnetworkd-core.a.p -I src/network -I ../src/network -I src/basic -I ../src/basic -I src/shared -I ../src/shared -I src/systemd -I ../src/systemd -I src/journal -I ../src/journal -I src/journal-remote -I ../src/journal-remote -I src/nspawn -I ../src/nspawn -I src/resolve -I ../src/resolve -I src/timesync -I ../src/timesync -I ../src/time-wait-sync -I src/login -I ../src/login -I src/udev -I ../src/udev -I src/libudev -I ../src/libudev -I src/core -I ../src/core -I ../src/libsystemd/sd-bus -I ../src/libsystemd/sd-device -I ../src/libsystemd/sd-hwdb -I ../src/libsystemd/sd-id128 -I ../src/libsystemd/sd-netlink -I ../src/libsystemd/sd-network -I src/libsystemd-network -I ../src/libsystemd-network -I . -I .. -D _FILE_OFFSET_BITS=64 -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wwrite-strings -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unused-result -Wno-format-signedness -Wno-error=nonnull -std=gnu99 -fconst-strings -fdebug-compilation-dir /home/mrc0mmand/repos/@redhat-plumbers/systemd-rhel8/build-scan -ferror-limit 19 -fvisibility hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -analyzer-output=html -faddrsig -o /tmp/scan-build-2021-07-16-221226-1465241-1 -x c ../src/network/networkd-manager.c
1/* SPDX-License-Identifier: LGPL-2.1+ */
2
3#include <sys/socket.h>
4#include <linux1/if.h>
5#include <linux1/fib_rules.h>
6#include <stdio_ext.h>
7
8#include "sd-daemon.h"
9#include "sd-netlink.h"
10
11#include "alloc-util.h"
12#include "bus-util.h"
13#include "conf-parser.h"
14#include "def.h"
15#include "dns-domain.h"
16#include "fd-util.h"
17#include "fileio.h"
18#include "libudev-private.h"
19#include "local-addresses.h"
20#include "netlink-util.h"
21#include "networkd-manager.h"
22#include "ordered-set.h"
23#include "path-util.h"
24#include "set.h"
25#include "udev-util.h"
26#include "virt.h"
27
28/* use 8 MB for receive socket kernel queue. */
29#define RCVBUF_SIZE(8*1024*1024) (8*1024*1024)
30
31const char* const network_dirs[] = {
32 "/etc/systemd/network",
33 "/run/systemd/network",
34 "/usr/lib/systemd/network",
35#if HAVE_SPLIT_USR0
36 "/lib/systemd/network",
37#endif
38 NULL((void*)0)};
39
40static int setup_default_address_pool(Manager *m) {
41 AddressPool *p;
42 int r;
43
44 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/network/networkd-manager.c"
, 44, __PRETTY_FUNCTION__); } while (0)
;
45
46 /* Add in the well-known private address ranges. */
47
48 r = address_pool_new_from_string(m, &p, AF_INET610, "fc00::", 7);
49 if (r < 0)
50 return r;
51
52 r = address_pool_new_from_string(m, &p, AF_INET2, "192.168.0.0", 16);
53 if (r < 0)
54 return r;
55
56 r = address_pool_new_from_string(m, &p, AF_INET2, "172.16.0.0", 12);
57 if (r < 0)
58 return r;
59
60 r = address_pool_new_from_string(m, &p, AF_INET2, "10.0.0.0", 8);
61 if (r < 0)
62 return r;
63
64 return 0;
65}
66
67static int manager_reset_all(Manager *m) {
68 Link *link;
69 Iterator i;
70 int r;
71
72 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/network/networkd-manager.c"
, 72, __PRETTY_FUNCTION__); } while (0)
;
73
74 HASHMAP_FOREACH(link, m->links, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .
next_key = ((void*)0) }); hashmap_iterate((m->links), &
(i), (void**)&(link), ((void*)0)); )
{
75 r = link_carrier_reset(link);
76 if (r < 0)
77 log_link_warning_errno(link, r, "Could not reset carrier: %m")({ const Link *_l = (link); _l ? log_object_internal(4, r, "../src/network/networkd-manager.c"
, 77, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void
*)0), "Could not reset carrier: %m") : log_internal_realm(((LOG_REALM_SYSTEMD
) << 10 | ((4))), r, "../src/network/networkd-manager.c"
, 77, __func__, "Could not reset carrier: %m"); })
;
78 }
79
80 return 0;
81}
82
83static int match_prepare_for_sleep(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
84 Manager *m = userdata;
85 int b, r;
86
87 assert(message)do { if ((__builtin_expect(!!(!(message)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("message"), "../src/network/networkd-manager.c"
, 87, __PRETTY_FUNCTION__); } while (0)
;
88 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/network/networkd-manager.c"
, 88, __PRETTY_FUNCTION__); } while (0)
;
89
90 r = sd_bus_message_read(message, "b", &b);
91 if (r < 0) {
92 log_debug_errno(r, "Failed to parse PrepareForSleep signal: %m")({ int _level = ((7)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 92, __func__, "Failed to parse PrepareForSleep signal: %m"
) : -abs(_e); })
;
93 return 0;
94 }
95
96 if (b)
97 return 0;
98
99 log_debug("Coming back from suspend, resetting all connections...")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 99, __func__, "Coming back from suspend, resetting all connections..."
) : -abs(_e); })
;
100
101 (void) manager_reset_all(m);
102
103 return 0;
104}
105
106static int on_connected(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
107 Manager *m = userdata;
108
109 assert(message)do { if ((__builtin_expect(!!(!(message)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("message"), "../src/network/networkd-manager.c"
, 109, __PRETTY_FUNCTION__); } while (0)
;
110 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/network/networkd-manager.c"
, 110, __PRETTY_FUNCTION__); } while (0)
;
111
112 /* Did we get a timezone or transient hostname from DHCP while D-Bus wasn't up yet? */
113 if (m->dynamic_hostname)
114 (void) manager_set_hostname(m, m->dynamic_hostname);
115 if (m->dynamic_timezone)
116 (void) manager_set_timezone(m, m->dynamic_timezone);
117
118 return 0;
119}
120
121int manager_connect_bus(Manager *m) {
122 int r;
123
124 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/network/networkd-manager.c"
, 124, __PRETTY_FUNCTION__); } while (0)
;
125
126 if (m->bus)
127 return 0;
128
129 r = bus_open_system_watch_bind_with_description(&m->bus, "bus-api-network");
130 if (r < 0)
131 return log_error_errno(r, "Failed to connect to bus: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 131, __func__, "Failed to connect to bus: %m"
) : -abs(_e); })
;
132
133 r = sd_bus_add_object_vtable(m->bus, NULL((void*)0), "/org/freedesktop/network1", "org.freedesktop.network1.Manager", manager_vtable, m);
134 if (r < 0)
135 return log_error_errno(r, "Failed to add manager object vtable: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 135, __func__, "Failed to add manager object vtable: %m"
) : -abs(_e); })
;
136
137 r = sd_bus_add_fallback_vtable(m->bus, NULL((void*)0), "/org/freedesktop/network1/link", "org.freedesktop.network1.Link", link_vtable, link_object_find, m);
138 if (r < 0)
139 return log_error_errno(r, "Failed to add link object vtable: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 139, __func__, "Failed to add link object vtable: %m"
) : -abs(_e); })
;
140
141 r = sd_bus_add_node_enumerator(m->bus, NULL((void*)0), "/org/freedesktop/network1/link", link_node_enumerator, m);
142 if (r < 0)
143 return log_error_errno(r, "Failed to add link enumerator: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 143, __func__, "Failed to add link enumerator: %m"
) : -abs(_e); })
;
144
145 r = sd_bus_add_fallback_vtable(m->bus, NULL((void*)0), "/org/freedesktop/network1/network", "org.freedesktop.network1.Network", network_vtable, network_object_find, m);
146 if (r < 0)
147 return log_error_errno(r, "Failed to add network object vtable: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 147, __func__, "Failed to add network object vtable: %m"
) : -abs(_e); })
;
148
149 r = sd_bus_add_node_enumerator(m->bus, NULL((void*)0), "/org/freedesktop/network1/network", network_node_enumerator, m);
150 if (r < 0)
151 return log_error_errno(r, "Failed to add network enumerator: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 151, __func__, "Failed to add network enumerator: %m"
) : -abs(_e); })
;
152
153 r = bus_request_name_async_may_reload_dbus(m->bus, NULL((void*)0), "org.freedesktop.network1", 0, NULL((void*)0));
154 if (r < 0)
155 return log_error_errno(r, "Failed to request name: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 155, __func__, "Failed to request name: %m"
) : -abs(_e); })
;
156
157 r = sd_bus_attach_event(m->bus, m->event, 0);
158 if (r < 0)
159 return log_error_errno(r, "Failed to attach bus to event loop: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 159, __func__, "Failed to attach bus to event loop: %m"
) : -abs(_e); })
;
160
161 r = sd_bus_match_signal_async(
162 m->bus,
163 &m->connected_slot,
164 "org.freedesktop.DBus.Local",
165 NULL((void*)0),
166 "org.freedesktop.DBus.Local",
167 "Connected",
168 on_connected, NULL((void*)0), m);
169 if (r < 0)
170 return log_error_errno(r, "Failed to request match on Connected signal: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 170, __func__, "Failed to request match on Connected signal: %m"
) : -abs(_e); })
;
171
172 r = sd_bus_match_signal_async(
173 m->bus,
174 &m->prepare_for_sleep_slot,
175 "org.freedesktop.login1",
176 "/org/freedesktop/login1",
177 "org.freedesktop.login1.Manager",
178 "PrepareForSleep",
179 match_prepare_for_sleep, NULL((void*)0), m);
180 if (r < 0)
181 log_warning_errno(r, "Failed to request match for PrepareForSleep, ignoring: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 181, __func__, "Failed to request match for PrepareForSleep, ignoring: %m"
) : -abs(_e); })
;
182
183 return 0;
184}
185
186static int manager_udev_process_link(Manager *m, struct udev_device *device) {
187 Link *link = NULL((void*)0);
188 int r, ifindex;
189
190 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/network/networkd-manager.c"
, 190, __PRETTY_FUNCTION__); } while (0)
;
191 assert(device)do { if ((__builtin_expect(!!(!(device)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("device"), "../src/network/networkd-manager.c"
, 191, __PRETTY_FUNCTION__); } while (0)
;
192
193 if (!streq_ptr(udev_device_get_action(device), "add"))
194 return 0;
195
196 ifindex = udev_device_get_ifindex(device);
197 if (ifindex <= 0) {
198 log_debug("Ignoring udev ADD event for device with invalid ifindex")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 198, __func__, "Ignoring udev ADD event for device with invalid ifindex"
) : -abs(_e); })
;
199 return 0;
200 }
201
202 r = link_get(m, ifindex, &link);
203 if (r == -ENODEV19)
204 return 0;
205 else if (r < 0)
206 return r;
207
208 r = link_initialized(link, device);
209 if (r < 0)
210 return r;
211
212 return 0;
213}
214
215static int manager_dispatch_link_udev(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
216 Manager *m = userdata;
217 struct udev_monitor *monitor = m->udev_monitor;
218 _cleanup_(udev_device_unrefp)__attribute__((cleanup(udev_device_unrefp))) struct udev_device *device = NULL((void*)0);
219
220 device = udev_monitor_receive_device(monitor);
221 if (!device)
222 return -ENOMEM12;
223
224 (void) manager_udev_process_link(m, device);
225
226 return 0;
227}
228
229static int manager_connect_udev(Manager *m) {
230 int r;
231
232 /* udev does not initialize devices inside containers,
233 * so we rely on them being already initialized before
234 * entering the container */
235 if (detect_container() > 0)
236 return 0;
237
238 m->udev = udev_new();
239 if (!m->udev)
240 return -ENOMEM12;
241
242 m->udev_monitor = udev_monitor_new_from_netlink(m->udev, "udev");
243 if (!m->udev_monitor)
244 return -ENOMEM12;
245
246 r = udev_monitor_filter_add_match_subsystem_devtype(m->udev_monitor, "net", NULL((void*)0));
247 if (r < 0)
248 return log_error_errno(r, "Could not add udev monitor filter: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 248, __func__, "Could not add udev monitor filter: %m"
) : -abs(_e); })
;
249
250 r = udev_monitor_enable_receiving(m->udev_monitor);
251 if (r < 0) {
252 log_error("Could not enable udev monitor")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 252, __func__, "Could not enable udev monitor"
) : -abs(_e); })
;
253 return r;
254 }
255
256 r = sd_event_add_io(m->event,
257 &m->udev_event_source,
258 udev_monitor_get_fd(m->udev_monitor),
259 EPOLLINEPOLLIN, manager_dispatch_link_udev,
260 m);
261 if (r < 0)
262 return r;
263
264 r = sd_event_source_set_description(m->udev_event_source, "networkd-udev");
265 if (r < 0)
266 return r;
267
268 return 0;
269}
270
271int manager_rtnl_process_route(sd_netlink *rtnl, sd_netlink_message *message, void *userdata) {
272 Manager *m = userdata;
273 Link *link = NULL((void*)0);
274 uint16_t type;
275 uint32_t ifindex, priority = 0;
276 unsigned char protocol, scope, tos, table, rt_type;
277 int family;
278 unsigned char dst_prefixlen, src_prefixlen;
279 union in_addr_union dst = {}, gw = {}, src = {}, prefsrc = {};
280 Route *route = NULL((void*)0);
281 int r;
282
283 assert(rtnl)do { if ((__builtin_expect(!!(!(rtnl)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("rtnl"), "../src/network/networkd-manager.c"
, 283, __PRETTY_FUNCTION__); } while (0)
;
284 assert(message)do { if ((__builtin_expect(!!(!(message)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("message"), "../src/network/networkd-manager.c"
, 284, __PRETTY_FUNCTION__); } while (0)
;
285 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/network/networkd-manager.c"
, 285, __PRETTY_FUNCTION__); } while (0)
;
286
287 if (sd_netlink_message_is_error(message)) {
288 r = sd_netlink_message_get_errno(message);
289 if (r < 0)
290 log_warning_errno(r, "rtnl: failed to receive route, ignoring: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 290, __func__, "rtnl: failed to receive route, ignoring: %m"
) : -abs(_e); })
;
291
292 return 0;
293 }
294
295 r = sd_netlink_message_get_type(message, &type);
296 if (r < 0) {
297 log_warning_errno(r, "rtnl: could not get message type, ignoring: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 297, __func__, "rtnl: could not get message type, ignoring: %m"
) : -abs(_e); })
;
298 return 0;
299 } else if (!IN_SET(type, RTM_NEWROUTE, RTM_DELROUTE)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){RTM_NEWROUTE, RTM_DELROUTE})/sizeof(int)
]; switch(type) { case RTM_NEWROUTE: case RTM_DELROUTE: _found
= 1; break; default: break; } _found; })
) {
300 log_warning("rtnl: received unexpected message type when processing route, ignoring")({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 300, __func__, "rtnl: received unexpected message type when processing route, ignoring"
) : -abs(_e); })
;
301 return 0;
302 }
303
304 r = sd_netlink_message_read_u32(message, RTA_OIF, &ifindex);
305 if (r == -ENODATA61) {
306 log_debug("rtnl: received route without ifindex, ignoring")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 306, __func__, "rtnl: received route without ifindex, ignoring"
) : -abs(_e); })
;
307 return 0;
308 } else if (r < 0) {
309 log_warning_errno(r, "rtnl: could not get ifindex from route, ignoring: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 309, __func__, "rtnl: could not get ifindex from route, ignoring: %m"
) : -abs(_e); })
;
310 return 0;
311 } else if (ifindex <= 0) {
312 log_warning("rtnl: received route message with invalid ifindex, ignoring: %d", ifindex)({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 312, __func__, "rtnl: received route message with invalid ifindex, ignoring: %d"
, ifindex) : -abs(_e); })
;
313 return 0;
314 } else {
315 r = link_get(m, ifindex, &link);
316 if (r < 0 || !link) {
317 /* when enumerating we might be out of sync, but we will
318 * get the route again, so just ignore it */
319 if (!m->enumerating)
320 log_warning("rtnl: received route for nonexistent link (%d), ignoring", ifindex)({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 320, __func__, "rtnl: received route for nonexistent link (%d), ignoring"
, ifindex) : -abs(_e); })
;
321 return 0;
322 }
323 }
324
325 r = sd_rtnl_message_route_get_family(message, &family);
326 if (r < 0 || !IN_SET(family, AF_INET, AF_INET6)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){2, 10})/sizeof(int)]; switch(family) { case
2: case 10: _found = 1; break; default: break; } _found; })
) {
327 log_link_warning(link, "rtnl: received address with invalid family, ignoring")({ const Link *_l = (link); _l ? log_object_internal(4, 0, "../src/network/networkd-manager.c"
, 327, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void
*)0), "rtnl: received address with invalid family, ignoring")
: log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4)
)), 0, "../src/network/networkd-manager.c", 327, __func__, "rtnl: received address with invalid family, ignoring"
); })
;
328 return 0;
329 }
330
331 r = sd_rtnl_message_route_get_protocol(message, &protocol);
332 if (r < 0) {
333 log_warning_errno(r, "rtnl: could not get route protocol: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 333, __func__, "rtnl: could not get route protocol: %m"
) : -abs(_e); })
;
334 return 0;
335 }
336
337 switch (family) {
338 case AF_INET2:
339 r = sd_netlink_message_read_in_addr(message, RTA_DST, &dst.in);
340 if (r < 0 && r != -ENODATA61) {
341 log_link_warning_errno(link, r, "rtnl: received route without valid destination, ignoring: %m")({ const Link *_l = (link); _l ? log_object_internal(4, r, "../src/network/networkd-manager.c"
, 341, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void
*)0), "rtnl: received route without valid destination, ignoring: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), r, "../src/network/networkd-manager.c", 341, __func__, "rtnl: received route without valid destination, ignoring: %m"
); })
;
342 return 0;
343 }
344
345 r = sd_netlink_message_read_in_addr(message, RTA_GATEWAY, &gw.in);
346 if (r < 0 && r != -ENODATA61) {
347 log_link_warning_errno(link, r, "rtnl: received route with invalid gateway, ignoring: %m")({ const Link *_l = (link); _l ? log_object_internal(4, r, "../src/network/networkd-manager.c"
, 347, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void
*)0), "rtnl: received route with invalid gateway, ignoring: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), r, "../src/network/networkd-manager.c", 347, __func__, "rtnl: received route with invalid gateway, ignoring: %m"
); })
;
348 return 0;
349 }
350
351 r = sd_netlink_message_read_in_addr(message, RTA_SRC, &src.in);
352 if (r < 0 && r != -ENODATA61) {
353 log_link_warning_errno(link, r, "rtnl: received route with invalid source, ignoring: %m")({ const Link *_l = (link); _l ? log_object_internal(4, r, "../src/network/networkd-manager.c"
, 353, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void
*)0), "rtnl: received route with invalid source, ignoring: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), r, "../src/network/networkd-manager.c", 353, __func__, "rtnl: received route with invalid source, ignoring: %m"
); })
;
354 return 0;
355 }
356
357 r = sd_netlink_message_read_in_addr(message, RTA_PREFSRC, &prefsrc.in);
358 if (r < 0 && r != -ENODATA61) {
359 log_link_warning_errno(link, r, "rtnl: received route with invalid preferred source, ignoring: %m")({ const Link *_l = (link); _l ? log_object_internal(4, r, "../src/network/networkd-manager.c"
, 359, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void
*)0), "rtnl: received route with invalid preferred source, ignoring: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), r, "../src/network/networkd-manager.c", 359, __func__, "rtnl: received route with invalid preferred source, ignoring: %m"
); })
;
360 return 0;
361 }
362
363 break;
364
365 case AF_INET610:
366 r = sd_netlink_message_read_in6_addr(message, RTA_DST, &dst.in6);
367 if (r < 0 && r != -ENODATA61) {
368 log_link_warning_errno(link, r, "rtnl: received route without valid destination, ignoring: %m")({ const Link *_l = (link); _l ? log_object_internal(4, r, "../src/network/networkd-manager.c"
, 368, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void
*)0), "rtnl: received route without valid destination, ignoring: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), r, "../src/network/networkd-manager.c", 368, __func__, "rtnl: received route without valid destination, ignoring: %m"
); })
;
369 return 0;
370 }
371
372 r = sd_netlink_message_read_in6_addr(message, RTA_GATEWAY, &gw.in6);
373 if (r < 0 && r != -ENODATA61) {
374 log_link_warning_errno(link, r, "rtnl: received route with invalid gateway, ignoring: %m")({ const Link *_l = (link); _l ? log_object_internal(4, r, "../src/network/networkd-manager.c"
, 374, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void
*)0), "rtnl: received route with invalid gateway, ignoring: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), r, "../src/network/networkd-manager.c", 374, __func__, "rtnl: received route with invalid gateway, ignoring: %m"
); })
;
375 return 0;
376 }
377
378 r = sd_netlink_message_read_in6_addr(message, RTA_SRC, &src.in6);
379 if (r < 0 && r != -ENODATA61) {
380 log_link_warning_errno(link, r, "rtnl: received route with invalid source, ignoring: %m")({ const Link *_l = (link); _l ? log_object_internal(4, r, "../src/network/networkd-manager.c"
, 380, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void
*)0), "rtnl: received route with invalid source, ignoring: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), r, "../src/network/networkd-manager.c", 380, __func__, "rtnl: received route with invalid source, ignoring: %m"
); })
;
381 return 0;
382 }
383
384 r = sd_netlink_message_read_in6_addr(message, RTA_PREFSRC, &prefsrc.in6);
385 if (r < 0 && r != -ENODATA61) {
386 log_link_warning_errno(link, r, "rtnl: received route with invalid preferred source, ignoring: %m")({ const Link *_l = (link); _l ? log_object_internal(4, r, "../src/network/networkd-manager.c"
, 386, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void
*)0), "rtnl: received route with invalid preferred source, ignoring: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), r, "../src/network/networkd-manager.c", 386, __func__, "rtnl: received route with invalid preferred source, ignoring: %m"
); })
;
387 return 0;
388 }
389
390 break;
391
392 default:
393 assert_not_reached("Received unsupported address family")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, (
"Received unsupported address family"), "../src/network/networkd-manager.c"
, 393, __PRETTY_FUNCTION__); } while (0)
;
394 return 0;
395 }
396
397 r = sd_rtnl_message_route_get_dst_prefixlen(message, &dst_prefixlen);
398 if (r < 0) {
399 log_link_warning_errno(link, r, "rtnl: received route with invalid destination prefixlen, ignoring: %m")({ const Link *_l = (link); _l ? log_object_internal(4, r, "../src/network/networkd-manager.c"
, 399, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void
*)0), "rtnl: received route with invalid destination prefixlen, ignoring: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), r, "../src/network/networkd-manager.c", 399, __func__, "rtnl: received route with invalid destination prefixlen, ignoring: %m"
); })
;
400 return 0;
401 }
402
403 r = sd_rtnl_message_route_get_src_prefixlen(message, &src_prefixlen);
404 if (r < 0) {
405 log_link_warning_errno(link, r, "rtnl: received route with invalid source prefixlen, ignoring: %m")({ const Link *_l = (link); _l ? log_object_internal(4, r, "../src/network/networkd-manager.c"
, 405, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void
*)0), "rtnl: received route with invalid source prefixlen, ignoring: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), r, "../src/network/networkd-manager.c", 405, __func__, "rtnl: received route with invalid source prefixlen, ignoring: %m"
); })
;
406 return 0;
407 }
408
409 r = sd_rtnl_message_route_get_scope(message, &scope);
410 if (r < 0) {
411 log_link_warning_errno(link, r, "rtnl: received route with invalid scope, ignoring: %m")({ const Link *_l = (link); _l ? log_object_internal(4, r, "../src/network/networkd-manager.c"
, 411, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void
*)0), "rtnl: received route with invalid scope, ignoring: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), r, "../src/network/networkd-manager.c", 411, __func__, "rtnl: received route with invalid scope, ignoring: %m"
); })
;
412 return 0;
413 }
414
415 r = sd_rtnl_message_route_get_tos(message, &tos);
416 if (r < 0) {
417 log_link_warning_errno(link, r, "rtnl: received route with invalid tos, ignoring: %m")({ const Link *_l = (link); _l ? log_object_internal(4, r, "../src/network/networkd-manager.c"
, 417, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void
*)0), "rtnl: received route with invalid tos, ignoring: %m") :
log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4)))
, r, "../src/network/networkd-manager.c", 417, __func__, "rtnl: received route with invalid tos, ignoring: %m"
); })
;
418 return 0;
419 }
420
421 r = sd_rtnl_message_route_get_type(message, &rt_type);
422 if (r < 0) {
423 log_link_warning_errno(link, r, "rtnl: received route with invalid type, ignoring: %m")({ const Link *_l = (link); _l ? log_object_internal(4, r, "../src/network/networkd-manager.c"
, 423, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void
*)0), "rtnl: received route with invalid type, ignoring: %m")
: log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4)
)), r, "../src/network/networkd-manager.c", 423, __func__, "rtnl: received route with invalid type, ignoring: %m"
); })
;
424 return 0;
425 }
426
427 r = sd_rtnl_message_route_get_table(message, &table);
428 if (r < 0) {
429 log_link_warning_errno(link, r, "rtnl: received route with invalid table, ignoring: %m")({ const Link *_l = (link); _l ? log_object_internal(4, r, "../src/network/networkd-manager.c"
, 429, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void
*)0), "rtnl: received route with invalid table, ignoring: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), r, "../src/network/networkd-manager.c", 429, __func__, "rtnl: received route with invalid table, ignoring: %m"
); })
;
430 return 0;
431 }
432
433 r = sd_netlink_message_read_u32(message, RTA_PRIORITY, &priority);
434 if (r < 0 && r != -ENODATA61) {
435 log_link_warning_errno(link, r, "rtnl: received route with invalid priority, ignoring: %m")({ const Link *_l = (link); _l ? log_object_internal(4, r, "../src/network/networkd-manager.c"
, 435, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void
*)0), "rtnl: received route with invalid priority, ignoring: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), r, "../src/network/networkd-manager.c", 435, __func__, "rtnl: received route with invalid priority, ignoring: %m"
); })
;
436 return 0;
437 }
438
439 (void) route_get(link, family, &dst, dst_prefixlen, tos, priority, table, &route);
440
441 switch (type) {
442 case RTM_NEWROUTERTM_NEWROUTE:
443 if (!route) {
444 /* A route appeared that we did not request */
445 r = route_add_foreign(link, family, &dst, dst_prefixlen, tos, priority, table, &route);
446 if (r < 0) {
447 log_link_warning_errno(link, r, "Failed to add route, ignoring: %m")({ const Link *_l = (link); _l ? log_object_internal(4, r, "../src/network/networkd-manager.c"
, 447, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void
*)0), "Failed to add route, ignoring: %m") : log_internal_realm
(((LOG_REALM_SYSTEMD) << 10 | ((4))), r, "../src/network/networkd-manager.c"
, 447, __func__, "Failed to add route, ignoring: %m"); })
;
448 return 0;
449 }
450 }
451
452 route_update(route, &src, src_prefixlen, &gw, &prefsrc, scope, protocol, rt_type);
453
454 break;
455
456 case RTM_DELROUTERTM_DELROUTE:
457 route_free(route);
458 break;
459
460 default:
461 assert_not_reached("Received invalid RTNL message type")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, (
"Received invalid RTNL message type"), "../src/network/networkd-manager.c"
, 461, __PRETTY_FUNCTION__); } while (0)
;
462 }
463
464 return 1;
465}
466
467int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, void *userdata) {
468 Manager *m = userdata;
469 Link *link = NULL((void*)0);
470 uint16_t type;
471 unsigned char flags;
472 int family;
473 unsigned char prefixlen;
474 unsigned char scope;
475 union in_addr_union in_addr;
476 struct ifa_cacheinfo cinfo;
477 Address *address = NULL((void*)0);
478 char buf[INET6_ADDRSTRLEN46], valid_buf[FORMAT_TIMESPAN_MAX64];
479 const char *valid_str = NULL((void*)0);
480 int r, ifindex;
481
482 assert(rtnl)do { if ((__builtin_expect(!!(!(rtnl)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("rtnl"), "../src/network/networkd-manager.c"
, 482, __PRETTY_FUNCTION__); } while (0)
;
483 assert(message)do { if ((__builtin_expect(!!(!(message)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("message"), "../src/network/networkd-manager.c"
, 483, __PRETTY_FUNCTION__); } while (0)
;
484 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/network/networkd-manager.c"
, 484, __PRETTY_FUNCTION__); } while (0)
;
485
486 if (sd_netlink_message_is_error(message)) {
487 r = sd_netlink_message_get_errno(message);
488 if (r < 0)
489 log_warning_errno(r, "rtnl: failed to receive address, ignoring: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 489, __func__, "rtnl: failed to receive address, ignoring: %m"
) : -abs(_e); })
;
490
491 return 0;
492 }
493
494 r = sd_netlink_message_get_type(message, &type);
495 if (r < 0) {
496 log_warning_errno(r, "rtnl: could not get message type, ignoring: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 496, __func__, "rtnl: could not get message type, ignoring: %m"
) : -abs(_e); })
;
497 return 0;
498 } else if (!IN_SET(type, RTM_NEWADDR, RTM_DELADDR)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){RTM_NEWADDR, RTM_DELADDR})/sizeof(int)];
switch(type) { case RTM_NEWADDR: case RTM_DELADDR: _found = 1
; break; default: break; } _found; })
) {
499 log_warning("rtnl: received unexpected message type when processing address, ignoring")({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 499, __func__, "rtnl: received unexpected message type when processing address, ignoring"
) : -abs(_e); })
;
500 return 0;
501 }
502
503 r = sd_rtnl_message_addr_get_ifindex(message, &ifindex);
504 if (r < 0) {
505 log_warning_errno(r, "rtnl: could not get ifindex from address, ignoring: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 505, __func__, "rtnl: could not get ifindex from address, ignoring: %m"
) : -abs(_e); })
;
506 return 0;
507 } else if (ifindex <= 0) {
508 log_warning("rtnl: received address message with invalid ifindex, ignoring: %d", ifindex)({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 508, __func__, "rtnl: received address message with invalid ifindex, ignoring: %d"
, ifindex) : -abs(_e); })
;
509 return 0;
510 } else {
511 r = link_get(m, ifindex, &link);
512 if (r < 0 || !link) {
513 /* when enumerating we might be out of sync, but we will
514 * get the address again, so just ignore it */
515 if (!m->enumerating)
516 log_warning("rtnl: received address for nonexistent link (%d), ignoring", ifindex)({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 516, __func__, "rtnl: received address for nonexistent link (%d), ignoring"
, ifindex) : -abs(_e); })
;
517 return 0;
518 }
519 }
520
521 r = sd_rtnl_message_addr_get_family(message, &family);
522 if (r < 0 || !IN_SET(family, AF_INET, AF_INET6)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){2, 10})/sizeof(int)]; switch(family) { case
2: case 10: _found = 1; break; default: break; } _found; })
) {
523 log_link_warning(link, "rtnl: received address with invalid family, ignoring")({ const Link *_l = (link); _l ? log_object_internal(4, 0, "../src/network/networkd-manager.c"
, 523, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void
*)0), "rtnl: received address with invalid family, ignoring")
: log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4)
)), 0, "../src/network/networkd-manager.c", 523, __func__, "rtnl: received address with invalid family, ignoring"
); })
;
524 return 0;
525 }
526
527 r = sd_rtnl_message_addr_get_prefixlen(message, &prefixlen);
528 if (r < 0) {
529 log_link_warning_errno(link, r, "rtnl: received address with invalid prefixlen, ignoring: %m")({ const Link *_l = (link); _l ? log_object_internal(4, r, "../src/network/networkd-manager.c"
, 529, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void
*)0), "rtnl: received address with invalid prefixlen, ignoring: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), r, "../src/network/networkd-manager.c", 529, __func__, "rtnl: received address with invalid prefixlen, ignoring: %m"
); })
;
530 return 0;
531 }
532
533 r = sd_rtnl_message_addr_get_scope(message, &scope);
534 if (r < 0) {
535 log_link_warning_errno(link, r, "rtnl: received address with invalid scope, ignoring: %m")({ const Link *_l = (link); _l ? log_object_internal(4, r, "../src/network/networkd-manager.c"
, 535, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void
*)0), "rtnl: received address with invalid scope, ignoring: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), r, "../src/network/networkd-manager.c", 535, __func__, "rtnl: received address with invalid scope, ignoring: %m"
); })
;
536 return 0;
537 }
538
539 r = sd_rtnl_message_addr_get_flags(message, &flags);
540 if (r < 0) {
541 log_link_warning_errno(link, r, "rtnl: received address with invalid flags, ignoring: %m")({ const Link *_l = (link); _l ? log_object_internal(4, r, "../src/network/networkd-manager.c"
, 541, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void
*)0), "rtnl: received address with invalid flags, ignoring: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), r, "../src/network/networkd-manager.c", 541, __func__, "rtnl: received address with invalid flags, ignoring: %m"
); })
;
542 return 0;
543 }
544
545 switch (family) {
546 case AF_INET2:
547 r = sd_netlink_message_read_in_addr(message, IFA_LOCAL, &in_addr.in);
548 if (r < 0) {
549 log_link_warning_errno(link, r, "rtnl: received address without valid address, ignoring: %m")({ const Link *_l = (link); _l ? log_object_internal(4, r, "../src/network/networkd-manager.c"
, 549, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void
*)0), "rtnl: received address without valid address, ignoring: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), r, "../src/network/networkd-manager.c", 549, __func__, "rtnl: received address without valid address, ignoring: %m"
); })
;
550 return 0;
551 }
552
553 break;
554
555 case AF_INET610:
556 r = sd_netlink_message_read_in6_addr(message, IFA_ADDRESS, &in_addr.in6);
557 if (r < 0) {
558 log_link_warning_errno(link, r, "rtnl: received address without valid address, ignoring: %m")({ const Link *_l = (link); _l ? log_object_internal(4, r, "../src/network/networkd-manager.c"
, 558, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void
*)0), "rtnl: received address without valid address, ignoring: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), r, "../src/network/networkd-manager.c", 558, __func__, "rtnl: received address without valid address, ignoring: %m"
); })
;
559 return 0;
560 }
561
562 break;
563
564 default:
565 assert_not_reached("Received unsupported address family")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, (
"Received unsupported address family"), "../src/network/networkd-manager.c"
, 565, __PRETTY_FUNCTION__); } while (0)
;
566 }
567
568 if (!inet_ntop(family, &in_addr, buf, INET6_ADDRSTRLEN46)) {
569 log_link_warning(link, "Could not print address, ignoring")({ const Link *_l = (link); _l ? log_object_internal(4, 0, "../src/network/networkd-manager.c"
, 569, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void
*)0), "Could not print address, ignoring") : log_internal_realm
(((LOG_REALM_SYSTEMD) << 10 | ((4))), 0, "../src/network/networkd-manager.c"
, 569, __func__, "Could not print address, ignoring"); })
;
570 return 0;
571 }
572
573 r = sd_netlink_message_read_cache_info(message, IFA_CACHEINFO, &cinfo);
574 if (r < 0 && r != -ENODATA61) {
575 log_link_warning_errno(link, r, "rtnl: cannot get IFA_CACHEINFO attribute, ignoring: %m")({ const Link *_l = (link); _l ? log_object_internal(4, r, "../src/network/networkd-manager.c"
, 575, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void
*)0), "rtnl: cannot get IFA_CACHEINFO attribute, ignoring: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), r, "../src/network/networkd-manager.c", 575, __func__, "rtnl: cannot get IFA_CACHEINFO attribute, ignoring: %m"
); })
;
576 return 0;
577 } else if (r >= 0) {
578 if (cinfo.ifa_valid != CACHE_INFO_INFINITY_LIFE_TIME0xFFFFFFFFU)
579 valid_str = format_timespan(valid_buf, FORMAT_TIMESPAN_MAX64,
580 cinfo.ifa_valid * USEC_PER_SEC((usec_t) 1000000ULL),
581 USEC_PER_SEC((usec_t) 1000000ULL));
582 }
583
584 (void) address_get(link, family, &in_addr, prefixlen, &address);
585
586 switch (type) {
587 case RTM_NEWADDRRTM_NEWADDR:
588 if (address)
589 log_link_debug(link, "Updating address: %s/%u (valid %s%s)", buf, prefixlen,({ const Link *_l = (link); _l ? log_object_internal(7, 0, "../src/network/networkd-manager.c"
, 590, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void
*)0), "Updating address: %s/%u (valid %s%s)", buf, prefixlen,
valid_str ? "for " : "forever", strempty(valid_str)) : log_internal_realm
(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/network/networkd-manager.c"
, 590, __func__, "Updating address: %s/%u (valid %s%s)", buf,
prefixlen, valid_str ? "for " : "forever", strempty(valid_str
)); })
590 valid_str ? "for " : "forever", strempty(valid_str))({ const Link *_l = (link); _l ? log_object_internal(7, 0, "../src/network/networkd-manager.c"
, 590, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void
*)0), "Updating address: %s/%u (valid %s%s)", buf, prefixlen,
valid_str ? "for " : "forever", strempty(valid_str)) : log_internal_realm
(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/network/networkd-manager.c"
, 590, __func__, "Updating address: %s/%u (valid %s%s)", buf,
prefixlen, valid_str ? "for " : "forever", strempty(valid_str
)); })
;
591 else {
592 /* An address appeared that we did not request */
593 r = address_add_foreign(link, family, &in_addr, prefixlen, &address);
594 if (r < 0) {
595 log_link_warning_errno(link, r, "Failed to add address %s/%u, ignoring: %m", buf, prefixlen)({ const Link *_l = (link); _l ? log_object_internal(4, r, "../src/network/networkd-manager.c"
, 595, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void
*)0), "Failed to add address %s/%u, ignoring: %m", buf, prefixlen
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), r, "../src/network/networkd-manager.c", 595, __func__, "Failed to add address %s/%u, ignoring: %m"
, buf, prefixlen); })
;
596 return 0;
597 } else
598 log_link_debug(link, "Adding address: %s/%u (valid %s%s)", buf, prefixlen,({ const Link *_l = (link); _l ? log_object_internal(7, 0, "../src/network/networkd-manager.c"
, 599, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void
*)0), "Adding address: %s/%u (valid %s%s)", buf, prefixlen, valid_str
? "for " : "forever", strempty(valid_str)) : log_internal_realm
(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/network/networkd-manager.c"
, 599, __func__, "Adding address: %s/%u (valid %s%s)", buf, prefixlen
, valid_str ? "for " : "forever", strempty(valid_str)); })
599 valid_str ? "for " : "forever", strempty(valid_str))({ const Link *_l = (link); _l ? log_object_internal(7, 0, "../src/network/networkd-manager.c"
, 599, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void
*)0), "Adding address: %s/%u (valid %s%s)", buf, prefixlen, valid_str
? "for " : "forever", strempty(valid_str)) : log_internal_realm
(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/network/networkd-manager.c"
, 599, __func__, "Adding address: %s/%u (valid %s%s)", buf, prefixlen
, valid_str ? "for " : "forever", strempty(valid_str)); })
;
600 }
601
602 r = address_update(address, flags, scope, &cinfo);
603 if (r < 0) {
604 log_link_warning_errno(link, r, "Failed to update address %s/%u, ignoring: %m", buf, prefixlen)({ const Link *_l = (link); _l ? log_object_internal(4, r, "../src/network/networkd-manager.c"
, 604, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void
*)0), "Failed to update address %s/%u, ignoring: %m", buf, prefixlen
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), r, "../src/network/networkd-manager.c", 604, __func__, "Failed to update address %s/%u, ignoring: %m"
, buf, prefixlen); })
;
605 return 0;
606 }
607
608 break;
609
610 case RTM_DELADDRRTM_DELADDR:
611
612 if (address) {
613 log_link_debug(link, "Removing address: %s/%u (valid %s%s)", buf, prefixlen,({ const Link *_l = (link); _l ? log_object_internal(7, 0, "../src/network/networkd-manager.c"
, 614, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void
*)0), "Removing address: %s/%u (valid %s%s)", buf, prefixlen,
valid_str ? "for " : "forever", strempty(valid_str)) : log_internal_realm
(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/network/networkd-manager.c"
, 614, __func__, "Removing address: %s/%u (valid %s%s)", buf,
prefixlen, valid_str ? "for " : "forever", strempty(valid_str
)); })
614 valid_str ? "for " : "forever", strempty(valid_str))({ const Link *_l = (link); _l ? log_object_internal(7, 0, "../src/network/networkd-manager.c"
, 614, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void
*)0), "Removing address: %s/%u (valid %s%s)", buf, prefixlen,
valid_str ? "for " : "forever", strempty(valid_str)) : log_internal_realm
(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/network/networkd-manager.c"
, 614, __func__, "Removing address: %s/%u (valid %s%s)", buf,
prefixlen, valid_str ? "for " : "forever", strempty(valid_str
)); })
;
615 (void) address_drop(address);
616 } else
617 log_link_warning(link, "Removing non-existent address: %s/%u (valid %s%s), ignoring", buf, prefixlen,({ const Link *_l = (link); _l ? log_object_internal(4, 0, "../src/network/networkd-manager.c"
, 618, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void
*)0), "Removing non-existent address: %s/%u (valid %s%s), ignoring"
, buf, prefixlen, valid_str ? "for " : "forever", strempty(valid_str
)) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((
4))), 0, "../src/network/networkd-manager.c", 618, __func__, "Removing non-existent address: %s/%u (valid %s%s), ignoring"
, buf, prefixlen, valid_str ? "for " : "forever", strempty(valid_str
)); })
618 valid_str ? "for " : "forever", strempty(valid_str))({ const Link *_l = (link); _l ? log_object_internal(4, 0, "../src/network/networkd-manager.c"
, 618, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((void
*)0), "Removing non-existent address: %s/%u (valid %s%s), ignoring"
, buf, prefixlen, valid_str ? "for " : "forever", strempty(valid_str
)) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((
4))), 0, "../src/network/networkd-manager.c", 618, __func__, "Removing non-existent address: %s/%u (valid %s%s), ignoring"
, buf, prefixlen, valid_str ? "for " : "forever", strempty(valid_str
)); })
;
619
620 break;
621 default:
622 assert_not_reached("Received invalid RTNL message type")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, (
"Received invalid RTNL message type"), "../src/network/networkd-manager.c"
, 622, __PRETTY_FUNCTION__); } while (0)
;
623 }
624
625 return 1;
626}
627
628static int manager_rtnl_process_link(sd_netlink *rtnl, sd_netlink_message *message, void *userdata) {
629 Manager *m = userdata;
630 Link *link = NULL((void*)0);
631 NetDev *netdev = NULL((void*)0);
632 uint16_t type;
633 const char *name;
634 int r, ifindex;
635
636 assert(rtnl)do { if ((__builtin_expect(!!(!(rtnl)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("rtnl"), "../src/network/networkd-manager.c"
, 636, __PRETTY_FUNCTION__); } while (0)
;
637 assert(message)do { if ((__builtin_expect(!!(!(message)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("message"), "../src/network/networkd-manager.c"
, 637, __PRETTY_FUNCTION__); } while (0)
;
638 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/network/networkd-manager.c"
, 638, __PRETTY_FUNCTION__); } while (0)
;
639
640 if (sd_netlink_message_is_error(message)) {
641 r = sd_netlink_message_get_errno(message);
642 if (r < 0)
643 log_warning_errno(r, "rtnl: Could not receive link, ignoring: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 643, __func__, "rtnl: Could not receive link, ignoring: %m"
) : -abs(_e); })
;
644
645 return 0;
646 }
647
648 r = sd_netlink_message_get_type(message, &type);
649 if (r < 0) {
650 log_warning_errno(r, "rtnl: Could not get message type, ignoring: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 650, __func__, "rtnl: Could not get message type, ignoring: %m"
) : -abs(_e); })
;
651 return 0;
652 } else if (!IN_SET(type, RTM_NEWLINK, RTM_DELLINK)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){RTM_NEWLINK, RTM_DELLINK})/sizeof(int)];
switch(type) { case RTM_NEWLINK: case RTM_DELLINK: _found = 1
; break; default: break; } _found; })
) {
653 log_warning("rtnl: Received unexpected message type when processing link, ignoring")({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 653, __func__, "rtnl: Received unexpected message type when processing link, ignoring"
) : -abs(_e); })
;
654 return 0;
655 }
656
657 r = sd_rtnl_message_link_get_ifindex(message, &ifindex);
658 if (r < 0) {
659 log_warning_errno(r, "rtnl: Could not get ifindex from link, ignoring: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 659, __func__, "rtnl: Could not get ifindex from link, ignoring: %m"
) : -abs(_e); })
;
660 return 0;
661 } else if (ifindex <= 0) {
662 log_warning("rtnl: received link message with invalid ifindex %d, ignoring", ifindex)({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 662, __func__, "rtnl: received link message with invalid ifindex %d, ignoring"
, ifindex) : -abs(_e); })
;
663 return 0;
664 }
665
666 r = sd_netlink_message_read_string(message, IFLA_IFNAME, &name);
667 if (r < 0) {
668 log_warning_errno(r, "rtnl: Received link message without ifname, ignoring: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 668, __func__, "rtnl: Received link message without ifname, ignoring: %m"
) : -abs(_e); })
;
669 return 0;
670 }
671
672 (void) link_get(m, ifindex, &link);
673 (void) netdev_get(m, name, &netdev);
674
675 switch (type) {
676 case RTM_NEWLINKRTM_NEWLINK:
677 if (!link) {
678 /* link is new, so add it */
679 r = link_add(m, message, &link);
680 if (r < 0) {
681 log_warning_errno(r, "Could not add new link, ignoring: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 681, __func__, "Could not add new link, ignoring: %m"
) : -abs(_e); })
;
682 return 0;
683 }
684 }
685
686 if (netdev) {
687 /* netdev exists, so make sure the ifindex matches */
688 r = netdev_set_ifindex(netdev, message);
689 if (r < 0) {
690 log_warning_errno(r, "Could not set ifindex on netdev, ignoring: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 690, __func__, "Could not set ifindex on netdev, ignoring: %m"
) : -abs(_e); })
;
691 return 0;
692 }
693 }
694
695 r = link_update(link, message);
696 if (r < 0) {
697 log_warning_errno(r, "Could not update link, ignoring: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 697, __func__, "Could not update link, ignoring: %m"
) : -abs(_e); })
;
698 return 0;
699 }
700
701 break;
702
703 case RTM_DELLINKRTM_DELLINK:
704 link_drop(link);
705 netdev_drop(netdev);
706
707 break;
708
709 default:
710 assert_not_reached("Received invalid RTNL message type.")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, (
"Received invalid RTNL message type."), "../src/network/networkd-manager.c"
, 710, __PRETTY_FUNCTION__); } while (0)
;
711 }
712
713 return 1;
714}
715
716int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, void *userdata) {
717 uint8_t tos = 0, to_prefixlen = 0, from_prefixlen = 0;
718 union in_addr_union to = {}, from = {};
719 RoutingPolicyRule *rule = NULL((void*)0);
720 uint32_t fwmark = 0, table = 0;
721 char *iif = NULL((void*)0), *oif = NULL((void*)0);
722 Manager *m = userdata;
723 uint16_t type;
724 int family;
725 int r;
726
727 assert(rtnl)do { if ((__builtin_expect(!!(!(rtnl)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("rtnl"), "../src/network/networkd-manager.c"
, 727, __PRETTY_FUNCTION__); } while (0)
;
728 assert(message)do { if ((__builtin_expect(!!(!(message)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("message"), "../src/network/networkd-manager.c"
, 728, __PRETTY_FUNCTION__); } while (0)
;
729 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/network/networkd-manager.c"
, 729, __PRETTY_FUNCTION__); } while (0)
;
730
731 if (sd_netlink_message_is_error(message)) {
732 r = sd_netlink_message_get_errno(message);
733 if (r < 0)
734 log_warning_errno(r, "rtnl: failed to receive rule, ignoring: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 734, __func__, "rtnl: failed to receive rule, ignoring: %m"
) : -abs(_e); })
;
735
736 return 0;
737 }
738
739 r = sd_netlink_message_get_type(message, &type);
740 if (r < 0) {
741 log_warning_errno(r, "rtnl: could not get message type, ignoring: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 741, __func__, "rtnl: could not get message type, ignoring: %m"
) : -abs(_e); })
;
742 return 0;
743 } else if (!IN_SET(type, RTM_NEWRULE, RTM_DELRULE)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){RTM_NEWRULE, RTM_DELRULE})/sizeof(int)];
switch(type) { case RTM_NEWRULE: case RTM_DELRULE: _found = 1
; break; default: break; } _found; })
) {
744 log_warning("rtnl: received unexpected message type '%u' when processing rule, ignoring", type)({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 744, __func__, "rtnl: received unexpected message type '%u' when processing rule, ignoring"
, type) : -abs(_e); })
;
745 return 0;
746 }
747
748 r = sd_rtnl_message_get_family(message, &family);
749 if (r < 0) {
750 log_warning_errno(r, "rtnl: could not get rule family, ignoring: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 750, __func__, "rtnl: could not get rule family, ignoring: %m"
) : -abs(_e); })
;
751 return 0;
752 } else if (!IN_SET(family, AF_INET, AF_INET6)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){2, 10})/sizeof(int)]; switch(family) { case
2: case 10: _found = 1; break; default: break; } _found; })
) {
753 log_debug("rtnl: received address with invalid family %u, ignoring", family)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 753, __func__, "rtnl: received address with invalid family %u, ignoring"
, family) : -abs(_e); })
;
754 return 0;
755 }
756
757 switch (family) {
758 case AF_INET2:
759 r = sd_netlink_message_read_in_addr(message, FRA_SRC, &from.in);
760 if (r < 0 && r != -ENODATA61) {
761 log_warning_errno(r, "rtnl: could not get FRA_SRC attribute, ignoring: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 761, __func__, "rtnl: could not get FRA_SRC attribute, ignoring: %m"
) : -abs(_e); })
;
762 return 0;
763 } else if (r >= 0) {
764 r = sd_rtnl_message_routing_policy_rule_get_rtm_src_prefixlen(message, &from_prefixlen);
765 if (r < 0) {
766 log_warning_errno(r, "rtnl: failed to retrieve rule from prefix length, ignoring: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 766, __func__, "rtnl: failed to retrieve rule from prefix length, ignoring: %m"
) : -abs(_e); })
;
767 return 0;
768 }
769 }
770
771 r = sd_netlink_message_read_in_addr(message, FRA_DST, &to.in);
772 if (r < 0 && r != -ENODATA61) {
773 log_warning_errno(r, "rtnl: could not get FRA_DST attribute, ignoring: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 773, __func__, "rtnl: could not get FRA_DST attribute, ignoring: %m"
) : -abs(_e); })
;
774 return 0;
775 } else if (r >= 0) {
776 r = sd_rtnl_message_routing_policy_rule_get_rtm_dst_prefixlen(message, &to_prefixlen);
777 if (r < 0) {
778 log_warning_errno(r, "rtnl: failed to retrieve rule to prefix length, ignoring: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 778, __func__, "rtnl: failed to retrieve rule to prefix length, ignoring: %m"
) : -abs(_e); })
;
779 return 0;
780 }
781 }
782
783 break;
784
785 case AF_INET610:
786 r = sd_netlink_message_read_in6_addr(message, FRA_SRC, &from.in6);
787 if (r < 0 && r != -ENODATA61) {
788 log_warning_errno(r, "rtnl: could not get FRA_SRC attribute, ignoring: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 788, __func__, "rtnl: could not get FRA_SRC attribute, ignoring: %m"
) : -abs(_e); })
;
789 return 0;
790 } else if (r >= 0) {
791 r = sd_rtnl_message_routing_policy_rule_get_rtm_src_prefixlen(message, &from_prefixlen);
792 if (r < 0) {
793 log_warning_errno(r, "rtnl: failed to retrieve rule from prefix length, ignoring: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 793, __func__, "rtnl: failed to retrieve rule from prefix length, ignoring: %m"
) : -abs(_e); })
;
794 return 0;
795 }
796 }
797
798 r = sd_netlink_message_read_in6_addr(message, FRA_DST, &to.in6);
799 if (r < 0 && r != -ENODATA61) {
800 log_warning_errno(r, "rtnl: could not get FRA_DST attribute, ignoring: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 800, __func__, "rtnl: could not get FRA_DST attribute, ignoring: %m"
) : -abs(_e); })
;
801 return 0;
802 } else if (r >= 0) {
803 r = sd_rtnl_message_routing_policy_rule_get_rtm_dst_prefixlen(message, &to_prefixlen);
804 if (r < 0) {
805 log_warning_errno(r, "rtnl: failed to retrieve rule to prefix length, ignoring: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 805, __func__, "rtnl: failed to retrieve rule to prefix length, ignoring: %m"
) : -abs(_e); })
;
806 return 0;
807 }
808 }
809
810 break;
811
812 default:
813 assert_not_reached("Received unsupported address family")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, (
"Received unsupported address family"), "../src/network/networkd-manager.c"
, 813, __PRETTY_FUNCTION__); } while (0)
;
814 }
815
816 if (from_prefixlen == 0 && to_prefixlen == 0)
817 return 0;
818
819 r = sd_netlink_message_read_u32(message, FRA_FWMARK, &fwmark);
820 if (r < 0 && r != -ENODATA61) {
821 log_warning_errno(r, "rtnl: could not get FRA_FWMARK attribute, ignoring: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 821, __func__, "rtnl: could not get FRA_FWMARK attribute, ignoring: %m"
) : -abs(_e); })
;
822 return 0;
823 }
824
825 r = sd_netlink_message_read_u32(message, FRA_TABLE, &table);
826 if (r < 0 && r != -ENODATA61) {
827 log_warning_errno(r, "rtnl: could not get FRA_TABLE attribute, ignoring: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 827, __func__, "rtnl: could not get FRA_TABLE attribute, ignoring: %m"
) : -abs(_e); })
;
828 return 0;
829 }
830
831 r = sd_rtnl_message_routing_policy_rule_get_tos(message, &tos);
832 if (r < 0 && r != -ENODATA61) {
833 log_warning_errno(r, "rtnl: could not get ip rule TOS, ignoring: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 833, __func__, "rtnl: could not get ip rule TOS, ignoring: %m"
) : -abs(_e); })
;
834 return 0;
835 }
836
837 r = sd_netlink_message_read_string(message, FRA_IIFNAME, (const char **) &iif);
838 if (r < 0 && r != -ENODATA61) {
839 log_warning_errno(r, "rtnl: could not get FRA_IIFNAME attribute, ignoring: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 839, __func__, "rtnl: could not get FRA_IIFNAME attribute, ignoring: %m"
) : -abs(_e); })
;
840 return 0;
841 }
842
843 r = sd_netlink_message_read_string(message, FRA_OIFNAME, (const char **) &oif);
844 if (r < 0 && r != -ENODATA61) {
845 log_warning_errno(r, "rtnl: could not get FRA_OIFNAME attribute, ignoring: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 845, __func__, "rtnl: could not get FRA_OIFNAME attribute, ignoring: %m"
) : -abs(_e); })
;
846 return 0;
847 }
848
849 (void) routing_policy_rule_get(m, family, &from, from_prefixlen, &to, to_prefixlen, tos, fwmark, table, iif, oif, &rule);
850
851 switch (type) {
852 case RTM_NEWRULERTM_NEWRULE:
853 if (!rule) {
854 r = routing_policy_rule_add_foreign(m, family, &from, from_prefixlen, &to, to_prefixlen, tos, fwmark, table, iif, oif, &rule);
855 if (r < 0) {
856 log_warning_errno(r, "Could not add rule, ignoring: %m")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 856, __func__, "Could not add rule, ignoring: %m"
) : -abs(_e); })
;
857 return 0;
858 }
859 }
860 break;
861 case RTM_DELRULERTM_DELRULE:
862 routing_policy_rule_free(rule);
863
864 break;
865
866 default:
867 assert_not_reached("Received invalid RTNL message type")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, (
"Received invalid RTNL message type"), "../src/network/networkd-manager.c"
, 867, __PRETTY_FUNCTION__); } while (0)
;
868 }
869
870 return 1;
871}
872
873static int systemd_netlink_fd(void) {
874 int n, fd, rtnl_fd = -EINVAL22;
875
876 n = sd_listen_fds(true1);
877 if (n <= 0)
878 return -EINVAL22;
879
880 for (fd = SD_LISTEN_FDS_START3; fd < SD_LISTEN_FDS_START3 + n; fd ++) {
881 if (sd_is_socket(fd, AF_NETLINK16, SOCK_RAWSOCK_RAW, -1) > 0) {
882 if (rtnl_fd >= 0)
883 return -EINVAL22;
884
885 rtnl_fd = fd;
886 }
887 }
888
889 return rtnl_fd;
890}
891
892static int manager_connect_genl(Manager *m) {
893 int r;
894
895 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/network/networkd-manager.c"
, 895, __PRETTY_FUNCTION__); } while (0)
;
896
897 r = sd_genl_socket_open(&m->genl);
898 if (r < 0)
899 return r;
900
901 r = sd_netlink_inc_rcvbuf(m->genl, RCVBUF_SIZE(8*1024*1024));
902 if (r < 0)
903 return r;
904
905 r = sd_netlink_attach_event(m->genl, m->event, 0);
906 if (r < 0)
907 return r;
908
909 return 0;
910}
911
912static int manager_connect_rtnl(Manager *m) {
913 int fd, r;
914
915 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/network/networkd-manager.c"
, 915, __PRETTY_FUNCTION__); } while (0)
;
916
917 fd = systemd_netlink_fd();
918 if (fd < 0)
919 r = sd_netlink_open(&m->rtnl);
920 else
921 r = sd_netlink_open_fd(&m->rtnl, fd);
922 if (r < 0)
923 return r;
924
925 r = sd_netlink_inc_rcvbuf(m->rtnl, RCVBUF_SIZE(8*1024*1024));
926 if (r < 0)
927 return r;
928
929 r = sd_netlink_attach_event(m->rtnl, m->event, 0);
930 if (r < 0)
931 return r;
932
933 r = sd_netlink_add_match(m->rtnl, RTM_NEWLINKRTM_NEWLINK, &manager_rtnl_process_link, m);
934 if (r < 0)
935 return r;
936
937 r = sd_netlink_add_match(m->rtnl, RTM_DELLINKRTM_DELLINK, &manager_rtnl_process_link, m);
938 if (r < 0)
939 return r;
940
941 r = sd_netlink_add_match(m->rtnl, RTM_NEWADDRRTM_NEWADDR, &manager_rtnl_process_address, m);
942 if (r < 0)
943 return r;
944
945 r = sd_netlink_add_match(m->rtnl, RTM_DELADDRRTM_DELADDR, &manager_rtnl_process_address, m);
946 if (r < 0)
947 return r;
948
949 r = sd_netlink_add_match(m->rtnl, RTM_NEWROUTERTM_NEWROUTE, &manager_rtnl_process_route, m);
950 if (r < 0)
951 return r;
952
953 r = sd_netlink_add_match(m->rtnl, RTM_DELROUTERTM_DELROUTE, &manager_rtnl_process_route, m);
954 if (r < 0)
955 return r;
956
957 r = sd_netlink_add_match(m->rtnl, RTM_NEWRULERTM_NEWRULE, &manager_rtnl_process_rule, m);
958 if (r < 0)
959 return r;
960
961 r = sd_netlink_add_match(m->rtnl, RTM_DELRULERTM_DELRULE, &manager_rtnl_process_rule, m);
962 if (r < 0)
963 return r;
964
965 return 0;
966}
967
968static int ordered_set_put_in_addr_data(OrderedSet *s, const struct in_addr_data *address) {
969 char *p;
970 int r;
971
972 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/network/networkd-manager.c"
, 972, __PRETTY_FUNCTION__); } while (0)
;
973 assert(address)do { if ((__builtin_expect(!!(!(address)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("address"), "../src/network/networkd-manager.c"
, 973, __PRETTY_FUNCTION__); } while (0)
;
974
975 r = in_addr_to_string(address->family, &address->address, &p);
976 if (r < 0)
977 return r;
978
979 r = ordered_set_consume(s, p);
980 if (r == -EEXIST17)
981 return 0;
982
983 return r;
984}
985
986static int ordered_set_put_in_addr_datav(OrderedSet *s, const struct in_addr_data *addresses, unsigned n) {
987 int r, c = 0;
988 unsigned i;
989
990 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/network/networkd-manager.c"
, 990, __PRETTY_FUNCTION__); } while (0)
;
991 assert(addresses || n == 0)do { if ((__builtin_expect(!!(!(addresses || n == 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("addresses || n == 0"), "../src/network/networkd-manager.c"
, 991, __PRETTY_FUNCTION__); } while (0)
;
992
993 for (i = 0; i < n; i++) {
994 r = ordered_set_put_in_addr_data(s, addresses+i);
995 if (r < 0)
996 return r;
997
998 c += r;
999 }
1000
1001 return c;
1002}
1003
1004static int ordered_set_put_in4_addr(OrderedSet *s, const struct in_addr *address) {
1005 char *p;
1006 int r;
1007
1008 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/network/networkd-manager.c"
, 1008, __PRETTY_FUNCTION__); } while (0)
;
1009 assert(address)do { if ((__builtin_expect(!!(!(address)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("address"), "../src/network/networkd-manager.c"
, 1009, __PRETTY_FUNCTION__); } while (0)
;
1010
1011 r = in_addr_to_string(AF_INET2, (const union in_addr_union*) address, &p);
1012 if (r < 0)
1013 return r;
1014
1015 r = ordered_set_consume(s, p);
1016 if (r == -EEXIST17)
1017 return 0;
1018
1019 return r;
1020}
1021
1022static int ordered_set_put_in4_addrv(OrderedSet *s, const struct in_addr *addresses, unsigned n) {
1023 int r, c = 0;
1024 unsigned i;
1025
1026 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/network/networkd-manager.c"
, 1026, __PRETTY_FUNCTION__); } while (0)
;
1027 assert(n == 0 || addresses)do { if ((__builtin_expect(!!(!(n == 0 || addresses)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("n == 0 || addresses"), "../src/network/networkd-manager.c"
, 1027, __PRETTY_FUNCTION__); } while (0)
;
1028
1029 for (i = 0; i < n; i++) {
1030 r = ordered_set_put_in4_addr(s, addresses+i);
1031 if (r < 0)
1032 return r;
1033
1034 c += r;
1035 }
1036
1037 return c;
1038}
1039
1040static void print_string_set(FILE *f, const char *field, OrderedSet *s) {
1041 bool_Bool space = false0;
1042 Iterator i;
1043 char *p;
1044
1045 if (ordered_set_isempty(s))
1046 return;
1047
1048 fputs(field, f);
1049
1050 ORDERED_SET_FOREACH(p, s, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .
next_key = ((void*)0) }); ordered_set_iterate((s), &(i), (
void**)&(p)); )
1051 fputs_with_space(f, p, NULL((void*)0), &space);
1052
1053 fputc('\n', f);
1054}
1055
1056static int manager_save(Manager *m) {
1057 _cleanup_ordered_set_free_free___attribute__((cleanup(ordered_set_free_freep))) OrderedSet *dns = NULL((void*)0), *ntp = NULL((void*)0), *search_domains = NULL((void*)0), *route_domains = NULL((void*)0);
1058 Link *link;
1059 Iterator i;
1060 _cleanup_free___attribute__((cleanup(freep))) char *temp_path = NULL((void*)0);
1061 _cleanup_fclose___attribute__((cleanup(fclosep))) FILE *f = NULL((void*)0);
1062 LinkOperationalState operstate = LINK_OPERSTATE_OFF;
1063 const char *operstate_str;
1064 int r;
1065
1066 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/network/networkd-manager.c"
, 1066, __PRETTY_FUNCTION__); } while (0)
;
1067 assert(m->state_file)do { if ((__builtin_expect(!!(!(m->state_file)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m->state_file"), "../src/network/networkd-manager.c"
, 1067, __PRETTY_FUNCTION__); } while (0)
;
1068
1069 /* We add all NTP and DNS server to a set, to filter out duplicates */
1070 dns = ordered_set_new(&string_hash_ops);
1071 if (!dns)
1072 return -ENOMEM12;
1073
1074 ntp = ordered_set_new(&string_hash_ops);
1075 if (!ntp)
1076 return -ENOMEM12;
1077
1078 search_domains = ordered_set_new(&dns_name_hash_ops);
1079 if (!search_domains)
1080 return -ENOMEM12;
1081
1082 route_domains = ordered_set_new(&dns_name_hash_ops);
1083 if (!route_domains)
1084 return -ENOMEM12;
1085
1086 HASHMAP_FOREACH(link, m->links, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .
next_key = ((void*)0) }); hashmap_iterate((m->links), &
(i), (void**)&(link), ((void*)0)); )
{
1087 if (link->flags & IFF_LOOPBACKIFF_LOOPBACK)
1088 continue;
1089
1090 if (link->operstate > operstate)
1091 operstate = link->operstate;
1092
1093 if (!link->network)
1094 continue;
1095
1096 /* First add the static configured entries */
1097 r = ordered_set_put_in_addr_datav(dns, link->network->dns, link->network->n_dns);
1098 if (r < 0)
1099 return r;
1100
1101 r = ordered_set_put_strdupv(ntp, link->network->ntp);
1102 if (r < 0)
1103 return r;
1104
1105 r = ordered_set_put_strdupv(search_domains, link->network->search_domains);
1106 if (r < 0)
1107 return r;
1108
1109 r = ordered_set_put_strdupv(route_domains, link->network->route_domains);
1110 if (r < 0)
1111 return r;
1112
1113 if (!link->dhcp_lease)
1114 continue;
1115
1116 /* Secondly, add the entries acquired via DHCP */
1117 if (link->network->dhcp_use_dns) {
1118 const struct in_addr *addresses;
1119
1120 r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
1121 if (r > 0) {
1122 r = ordered_set_put_in4_addrv(dns, addresses, r);
1123 if (r < 0)
1124 return r;
1125 } else if (r < 0 && r != -ENODATA61)
1126 return r;
1127 }
1128
1129 if (link->network->dhcp_use_ntp) {
1130 const struct in_addr *addresses;
1131
1132 r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
1133 if (r > 0) {
1134 r = ordered_set_put_in4_addrv(ntp, addresses, r);
1135 if (r < 0)
1136 return r;
1137 } else if (r < 0 && r != -ENODATA61)
1138 return r;
1139 }
1140
1141 if (link->network->dhcp_use_domains != DHCP_USE_DOMAINS_NO) {
1142 const char *domainname;
1143 char **domains = NULL((void*)0);
1144
1145 OrderedSet *target_domains = (link->network->dhcp_use_domains == DHCP_USE_DOMAINS_YES) ? search_domains : route_domains;
1146 r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
1147 if (r >= 0) {
1148 r = ordered_set_put_strdup(target_domains, domainname);
1149 if (r < 0)
1150 return r;
1151 } else if (r != -ENODATA61)
1152 return r;
1153
1154 r = sd_dhcp_lease_get_search_domains(link->dhcp_lease, &domains);
1155 if (r >= 0) {
1156 r = ordered_set_put_strdupv(target_domains, domains);
1157 if (r < 0)
1158 return r;
1159 } else if (r != -ENODATA61)
1160 return r;
1161 }
1162 }
1163
1164 operstate_str = link_operstate_to_string(operstate);
1165 assert(operstate_str)do { if ((__builtin_expect(!!(!(operstate_str)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("operstate_str"), "../src/network/networkd-manager.c"
, 1165, __PRETTY_FUNCTION__); } while (0)
;
1166
1167 r = fopen_temporary(m->state_file, &f, &temp_path);
1168 if (r < 0)
1169 return r;
1170
1171 (void) __fsetlocking(f, FSETLOCKING_BYCALLERFSETLOCKING_BYCALLER);
1172 (void) fchmod(fileno(f), 0644);
1173
1174 fprintf(f,
1175 "# This is private data. Do not parse.\n"
1176 "OPER_STATE=%s\n", operstate_str);
1177
1178 print_string_set(f, "DNS=", dns);
1179 print_string_set(f, "NTP=", ntp);
1180 print_string_set(f, "DOMAINS=", search_domains);
1181 print_string_set(f, "ROUTE_DOMAINS=", route_domains);
1182
1183 r = routing_policy_serialize_rules(m->rules, f);
1184 if (r < 0)
1185 goto fail;
1186
1187 r = fflush_and_check(f);
1188 if (r < 0)
1189 goto fail;
1190
1191 if (rename(temp_path, m->state_file) < 0) {
1192 r = -errno(*__errno_location ());
1193 goto fail;
1194 }
1195
1196 if (m->operational_state != operstate) {
1197 m->operational_state = operstate;
1198 r = manager_send_changed(m, "OperationalState", NULL((void*)0));
1199 if (r < 0)
1200 log_error_errno(r, "Could not emit changed OperationalState: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 1200, __func__, "Could not emit changed OperationalState: %m"
) : -abs(_e); })
;
1201 }
1202
1203 m->dirty = false0;
1204
1205 return 0;
1206
1207fail:
1208 (void) unlink(m->state_file);
1209 (void) unlink(temp_path);
1210
1211 return log_error_errno(r, "Failed to save network state to %s: %m", m->state_file)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 1211, __func__, "Failed to save network state to %s: %m"
, m->state_file) : -abs(_e); })
;
1212}
1213
1214static int manager_dirty_handler(sd_event_source *s, void *userdata) {
1215 Manager *m = userdata;
1216 Link *link;
1217 Iterator i;
1218 int r;
1219
1220 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/network/networkd-manager.c"
, 1220, __PRETTY_FUNCTION__); } while (0)
;
1221
1222 if (m->dirty)
1223 manager_save(m);
1224
1225 SET_FOREACH(link, m->dirty_links, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .
next_key = ((void*)0) }); set_iterate((m->dirty_links), &
(i), (void**)&(link)); )
{
1226 r = link_save(link);
1227 if (r >= 0)
1228 link_clean(link);
1229 }
1230
1231 return 1;
1232}
1233
1234Link *manager_dhcp6_prefix_get(Manager *m, struct in6_addr *addr) {
1235 assert_return(m, NULL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/network/networkd-manager.c"
, 1235, __PRETTY_FUNCTION__), 0))) return (((void*)0)); } while
(0)
;
1236 assert_return(m->dhcp6_prefixes, NULL)do { if (!(((__builtin_expect(!!(m->dhcp6_prefixes),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("m->dhcp6_prefixes"
), "../src/network/networkd-manager.c", 1236, __PRETTY_FUNCTION__
), 0))) return (((void*)0)); } while (0)
;
1237 assert_return(addr, NULL)do { if (!(((__builtin_expect(!!(addr),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("addr"), "../src/network/networkd-manager.c"
, 1237, __PRETTY_FUNCTION__), 0))) return (((void*)0)); } while
(0)
;
1238
1239 return hashmap_get(m->dhcp6_prefixes, addr);
1240}
1241
1242static int dhcp6_route_add_callback(sd_netlink *nl, sd_netlink_message *m,
1243 void *userdata) {
1244 Link *l = userdata;
1245 int r;
1246 union in_addr_union prefix;
1247 _cleanup_free___attribute__((cleanup(freep))) char *buf = NULL((void*)0);
1248
1249 r = sd_netlink_message_get_errno(m);
1250 if (r != 0) {
1251 log_link_debug_errno(l, r, "Received error adding DHCPv6 Prefix Delegation route: %m")({ const Link *_l = (l); _l ? log_object_internal(7, r, "../src/network/networkd-manager.c"
, 1251, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((
void*)0), "Received error adding DHCPv6 Prefix Delegation route: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7
))), r, "../src/network/networkd-manager.c", 1251, __func__, "Received error adding DHCPv6 Prefix Delegation route: %m"
); })
;
1252 return 0;
1253 }
1254
1255 r = sd_netlink_message_read_in6_addr(m, RTA_DST, &prefix.in6);
1256 if (r < 0) {
1257 log_link_debug_errno(l, r, "Could not read IPv6 address from DHCPv6 Prefix Delegation while adding route: %m")({ const Link *_l = (l); _l ? log_object_internal(7, r, "../src/network/networkd-manager.c"
, 1257, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((
void*)0), "Could not read IPv6 address from DHCPv6 Prefix Delegation while adding route: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7
))), r, "../src/network/networkd-manager.c", 1257, __func__, "Could not read IPv6 address from DHCPv6 Prefix Delegation while adding route: %m"
); })
;
1258 return 0;
1259 }
1260
1261 (void) in_addr_to_string(AF_INET610, &prefix, &buf);
1262 log_link_debug(l, "Added DHCPv6 Prefix Deleagtion route %s/64",({ const Link *_l = (l); _l ? log_object_internal(7, 0, "../src/network/networkd-manager.c"
, 1263, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((
void*)0), "Added DHCPv6 Prefix Deleagtion route %s/64", strnull
(buf)) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 |
((7))), 0, "../src/network/networkd-manager.c", 1263, __func__
, "Added DHCPv6 Prefix Deleagtion route %s/64", strnull(buf))
; })
1263 strnull(buf))({ const Link *_l = (l); _l ? log_object_internal(7, 0, "../src/network/networkd-manager.c"
, 1263, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((
void*)0), "Added DHCPv6 Prefix Deleagtion route %s/64", strnull
(buf)) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 |
((7))), 0, "../src/network/networkd-manager.c", 1263, __func__
, "Added DHCPv6 Prefix Deleagtion route %s/64", strnull(buf))
; })
;
1264
1265 return 0;
1266}
1267
1268int manager_dhcp6_prefix_add(Manager *m, struct in6_addr *addr, Link *link) {
1269 int r;
1270 Route *route;
1271
1272 assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/network/networkd-manager.c"
, 1272, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1273 assert_return(m->dhcp6_prefixes, -ENODATA)do { if (!(((__builtin_expect(!!(m->dhcp6_prefixes),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("m->dhcp6_prefixes"
), "../src/network/networkd-manager.c", 1273, __PRETTY_FUNCTION__
), 0))) return (-61); } while (0)
;
1274 assert_return(addr, -EINVAL)do { if (!(((__builtin_expect(!!(addr),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("addr"), "../src/network/networkd-manager.c"
, 1274, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1275
1276 r = route_add(link, AF_INET610, (union in_addr_union *) addr, 64,
1277 0, 0, 0, &route);
1278 if (r < 0)
1279 return r;
1280
1281 r = route_configure(route, link, dhcp6_route_add_callback);
1282 if (r < 0)
1283 return r;
1284
1285 return hashmap_put(m->dhcp6_prefixes, addr, link);
1286}
1287
1288static int dhcp6_route_remove_callback(sd_netlink *nl, sd_netlink_message *m,
1289 void *userdata) {
1290 Link *l = userdata;
1291 int r;
1292 union in_addr_union prefix;
1293 _cleanup_free___attribute__((cleanup(freep))) char *buf = NULL((void*)0);
1294
1295 r = sd_netlink_message_get_errno(m);
1296 if (r != 0) {
1297 log_link_debug_errno(l, r, "Received error on DHCPv6 Prefix Delegation route removal: %m")({ const Link *_l = (l); _l ? log_object_internal(7, r, "../src/network/networkd-manager.c"
, 1297, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((
void*)0), "Received error on DHCPv6 Prefix Delegation route removal: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7
))), r, "../src/network/networkd-manager.c", 1297, __func__, "Received error on DHCPv6 Prefix Delegation route removal: %m"
); })
;
1298 return 0;
1299 }
1300
1301 r = sd_netlink_message_read_in6_addr(m, RTA_DST, &prefix.in6);
1302 if (r < 0) {
1303 log_link_debug_errno(l, r, "Could not read IPv6 address from DHCPv6 Prefix Delegation while removing route: %m")({ const Link *_l = (l); _l ? log_object_internal(7, r, "../src/network/networkd-manager.c"
, 1303, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((
void*)0), "Could not read IPv6 address from DHCPv6 Prefix Delegation while removing route: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7
))), r, "../src/network/networkd-manager.c", 1303, __func__, "Could not read IPv6 address from DHCPv6 Prefix Delegation while removing route: %m"
); })
;
1304 return 0;
1305 }
1306
1307 (void) in_addr_to_string(AF_INET610, &prefix, &buf);
1308 log_link_debug(l, "Removed DHCPv6 Prefix Delegation route %s/64",({ const Link *_l = (l); _l ? log_object_internal(7, 0, "../src/network/networkd-manager.c"
, 1309, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((
void*)0), "Removed DHCPv6 Prefix Delegation route %s/64", strnull
(buf)) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 |
((7))), 0, "../src/network/networkd-manager.c", 1309, __func__
, "Removed DHCPv6 Prefix Delegation route %s/64", strnull(buf
)); })
1309 strnull(buf))({ const Link *_l = (l); _l ? log_object_internal(7, 0, "../src/network/networkd-manager.c"
, 1309, __func__, "INTERFACE=", _l->ifname, ((void*)0), ((
void*)0), "Removed DHCPv6 Prefix Delegation route %s/64", strnull
(buf)) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 |
((7))), 0, "../src/network/networkd-manager.c", 1309, __func__
, "Removed DHCPv6 Prefix Delegation route %s/64", strnull(buf
)); })
;
1310
1311 return 0;
1312}
1313
1314int manager_dhcp6_prefix_remove(Manager *m, struct in6_addr *addr) {
1315 Link *l;
1316 int r;
1317 Route *route;
1318
1319 assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/network/networkd-manager.c"
, 1319, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1320 assert_return(m->dhcp6_prefixes, -ENODATA)do { if (!(((__builtin_expect(!!(m->dhcp6_prefixes),1))) ?
(1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("m->dhcp6_prefixes"
), "../src/network/networkd-manager.c", 1320, __PRETTY_FUNCTION__
), 0))) return (-61); } while (0)
;
1321 assert_return(addr, -EINVAL)do { if (!(((__builtin_expect(!!(addr),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("addr"), "../src/network/networkd-manager.c"
, 1321, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1322
1323 l = hashmap_remove(m->dhcp6_prefixes, addr);
1324 if (!l)
1325 return -EINVAL22;
1326
1327 (void) sd_radv_remove_prefix(l->radv, addr, 64);
1328 r = route_get(l, AF_INET610, (union in_addr_union *) addr, 64,
1329 0, 0, 0, &route);
1330 if (r >= 0)
1331 (void) route_remove(route, l, dhcp6_route_remove_callback);
1332
1333 return 0;
1334}
1335
1336int manager_dhcp6_prefix_remove_all(Manager *m, Link *link) {
1337 Iterator i;
1338 Link *l;
1339 struct in6_addr *addr;
1340
1341 assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/network/networkd-manager.c"
, 1341, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1342 assert_return(link, -EINVAL)do { if (!(((__builtin_expect(!!(link),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("link"), "../src/network/networkd-manager.c"
, 1342, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1343
1344 HASHMAP_FOREACH_KEY(l, addr, m->dhcp6_prefixes, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .
next_key = ((void*)0) }); hashmap_iterate((m->dhcp6_prefixes
), &(i), (void**)&(l), (const void**) &(addr)); )
{
1345 if (l != link)
1346 continue;
1347
1348 (void) manager_dhcp6_prefix_remove(m, addr);
1349 }
1350
1351 return 0;
1352}
1353
1354static void dhcp6_prefixes_hash_func(const void *p, struct siphash *state) {
1355 const struct in6_addr *addr = p;
1356
1357 assert(p)do { if ((__builtin_expect(!!(!(p)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("p"), "../src/network/networkd-manager.c"
, 1357, __PRETTY_FUNCTION__); } while (0)
;
1358
1359 siphash24_compress(addr, sizeof(*addr), state);
1360}
1361
1362static int dhcp6_prefixes_compare_func(const void *_a, const void *_b) {
1363 const struct in6_addr *a = _a, *b = _b;
1364
1365 return memcmp(a, b, sizeof(*a));
1366}
1367
1368static const struct hash_ops dhcp6_prefixes_hash_ops = {
1369 .hash = dhcp6_prefixes_hash_func,
1370 .compare = dhcp6_prefixes_compare_func,
1371};
1372
1373int manager_new(Manager **ret, sd_event *event) {
1374 _cleanup_(manager_freep)__attribute__((cleanup(manager_freep))) Manager *m = NULL((void*)0);
1375 int r;
1376
1377 m = new0(Manager, 1)((Manager*) calloc((1), sizeof(Manager)));
1
Memory is allocated
1378 if (!m)
2
Assuming 'm' is non-null
3
Taking false branch
1379 return -ENOMEM12;
1380
1381 m->state_file = strdup("/run/systemd/netif/state");
1382 if (!m->state_file)
4
Assuming field 'state_file' is null
5
Taking true branch
1383 return -ENOMEM12;
6
Potential leak of memory pointed to by 'm'
1384
1385 m->event = sd_event_ref(event);
1386
1387 r = sd_event_add_post(m->event, NULL((void*)0), manager_dirty_handler, m);
1388 if (r < 0)
1389 return r;
1390
1391 r = manager_connect_rtnl(m);
1392 if (r < 0)
1393 return r;
1394
1395 r = manager_connect_genl(m);
1396 if (r < 0)
1397 return r;
1398
1399 r = manager_connect_udev(m);
1400 if (r < 0)
1401 return r;
1402
1403 m->netdevs = hashmap_new(&string_hash_ops)internal_hashmap_new(&string_hash_ops );
1404 if (!m->netdevs)
1405 return -ENOMEM12;
1406
1407 LIST_HEAD_INIT(m->networks)do { (m->networks) = ((void*)0); } while (0);
1408
1409 r = sd_resolve_default(&m->resolve);
1410 if (r < 0)
1411 return r;
1412
1413 r = sd_resolve_attach_event(m->resolve, m->event, 0);
1414 if (r < 0)
1415 return r;
1416
1417 r = setup_default_address_pool(m);
1418 if (r < 0)
1419 return r;
1420
1421 m->dhcp6_prefixes = hashmap_new(&dhcp6_prefixes_hash_ops)internal_hashmap_new(&dhcp6_prefixes_hash_ops );
1422 if (!m->dhcp6_prefixes)
1423 return -ENOMEM12;
1424
1425 m->duid.type = DUID_TYPE_EN;
1426
1427 (void) routing_policy_load_rules(m->state_file, &m->rules_saved);
1428
1429 *ret = TAKE_PTR(m)({ typeof(m) _ptr_ = (m); (m) = ((void*)0); _ptr_; });
1430
1431 return 0;
1432}
1433
1434void manager_free(Manager *m) {
1435 Network *network;
1436 NetDev *netdev;
1437 Link *link;
1438 AddressPool *pool;
1439
1440 if (!m)
1441 return;
1442
1443 free(m->state_file);
1444
1445 while ((network = m->networks))
1446 network_free(network);
1447
1448 while ((link = hashmap_first(m->dhcp6_prefixes)))
1449 link_unref(link);
1450 hashmap_free(m->dhcp6_prefixes);
1451
1452 while ((link = hashmap_first(m->links)))
1453 link_unref(link);
1454 hashmap_free(m->links);
1455
1456 hashmap_free(m->networks_by_name);
1457
1458 while ((netdev = hashmap_first(m->netdevs)))
1459 netdev_unref(netdev);
1460 hashmap_free(m->netdevs);
1461
1462 while ((pool = m->address_pools))
1463 address_pool_free(pool);
1464
1465 set_free(m->rules);
1466 set_free(m->rules_foreign);
1467
1468 set_free_with_destructor(m->rules_saved, routing_policy_rule_free)({ ({ void *_item; while ((_item = set_steal_first(m->rules_saved
))) routing_policy_rule_free(_item); }); set_free(m->rules_saved
); })
;
1469
1470 sd_netlink_unref(m->rtnl);
1471 sd_event_unref(m->event);
1472
1473 sd_resolve_unref(m->resolve);
1474
1475 sd_event_source_unref(m->udev_event_source);
1476 udev_monitor_unref(m->udev_monitor);
1477 udev_unref(m->udev);
1478
1479 sd_bus_unref(m->bus);
1480 sd_bus_slot_unref(m->prepare_for_sleep_slot);
1481 sd_bus_slot_unref(m->connected_slot);
1482
1483 free(m->dynamic_timezone);
1484 free(m->dynamic_hostname);
1485
1486 free(m);
1487}
1488
1489int manager_start(Manager *m) {
1490 Link *link;
1491 Iterator i;
1492
1493 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/network/networkd-manager.c"
, 1493, __PRETTY_FUNCTION__); } while (0)
;
1494
1495 /* The dirty handler will deal with future serialization, but the first one
1496 must be done explicitly. */
1497
1498 manager_save(m);
1499
1500 HASHMAP_FOREACH(link, m->links, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .
next_key = ((void*)0) }); hashmap_iterate((m->links), &
(i), (void**)&(link), ((void*)0)); )
1501 link_save(link);
1502
1503 return 0;
1504}
1505
1506int manager_load_config(Manager *m) {
1507 int r;
1508
1509 /* update timestamp */
1510 paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, true1);
1511
1512 r = netdev_load(m);
1513 if (r < 0)
1514 return r;
1515
1516 r = network_load(m);
1517 if (r < 0)
1518 return r;
1519
1520 return 0;
1521}
1522
1523bool_Bool manager_should_reload(Manager *m) {
1524 return paths_check_timestamp(network_dirs, &m->network_dirs_ts_usec, false0);
1525}
1526
1527int manager_rtnl_enumerate_links(Manager *m) {
1528 _cleanup_(sd_netlink_message_unrefp)__attribute__((cleanup(sd_netlink_message_unrefp))) sd_netlink_message *req = NULL((void*)0), *reply = NULL((void*)0);
1529 sd_netlink_message *link;
1530 int r;
1531
1532 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/network/networkd-manager.c"
, 1532, __PRETTY_FUNCTION__); } while (0)
;
1533 assert(m->rtnl)do { if ((__builtin_expect(!!(!(m->rtnl)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m->rtnl"), "../src/network/networkd-manager.c"
, 1533, __PRETTY_FUNCTION__); } while (0)
;
1534
1535 r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINKRTM_GETLINK, 0);
1536 if (r < 0)
1537 return r;
1538
1539 r = sd_netlink_message_request_dump(req, true1);
1540 if (r < 0)
1541 return r;
1542
1543 r = sd_netlink_call(m->rtnl, req, 0, &reply);
1544 if (r < 0)
1545 return r;
1546
1547 for (link = reply; link; link = sd_netlink_message_next(link)) {
1548 int k;
1549
1550 m->enumerating = true1;
1551
1552 k = manager_rtnl_process_link(m->rtnl, link, m);
1553 if (k < 0)
1554 r = k;
1555
1556 m->enumerating = false0;
1557 }
1558
1559 return r;
1560}
1561
1562int manager_rtnl_enumerate_addresses(Manager *m) {
1563 _cleanup_(sd_netlink_message_unrefp)__attribute__((cleanup(sd_netlink_message_unrefp))) sd_netlink_message *req = NULL((void*)0), *reply = NULL((void*)0);
1564 sd_netlink_message *addr;
1565 int r;
1566
1567 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/network/networkd-manager.c"
, 1567, __PRETTY_FUNCTION__); } while (0)
;
1568 assert(m->rtnl)do { if ((__builtin_expect(!!(!(m->rtnl)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m->rtnl"), "../src/network/networkd-manager.c"
, 1568, __PRETTY_FUNCTION__); } while (0)
;
1569
1570 r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDRRTM_GETADDR, 0, 0);
1571 if (r < 0)
1572 return r;
1573
1574 r = sd_netlink_message_request_dump(req, true1);
1575 if (r < 0)
1576 return r;
1577
1578 r = sd_netlink_call(m->rtnl, req, 0, &reply);
1579 if (r < 0)
1580 return r;
1581
1582 for (addr = reply; addr; addr = sd_netlink_message_next(addr)) {
1583 int k;
1584
1585 m->enumerating = true1;
1586
1587 k = manager_rtnl_process_address(m->rtnl, addr, m);
1588 if (k < 0)
1589 r = k;
1590
1591 m->enumerating = false0;
1592 }
1593
1594 return r;
1595}
1596
1597int manager_rtnl_enumerate_routes(Manager *m) {
1598 _cleanup_(sd_netlink_message_unrefp)__attribute__((cleanup(sd_netlink_message_unrefp))) sd_netlink_message *req = NULL((void*)0), *reply = NULL((void*)0);
1599 sd_netlink_message *route;
1600 int r;
1601
1602 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/network/networkd-manager.c"
, 1602, __PRETTY_FUNCTION__); } while (0)
;
1603 assert(m->rtnl)do { if ((__builtin_expect(!!(!(m->rtnl)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m->rtnl"), "../src/network/networkd-manager.c"
, 1603, __PRETTY_FUNCTION__); } while (0)
;
1604
1605 r = sd_rtnl_message_new_route(m->rtnl, &req, RTM_GETROUTERTM_GETROUTE, 0, 0);
1606 if (r < 0)
1607 return r;
1608
1609 r = sd_netlink_message_request_dump(req, true1);
1610 if (r < 0)
1611 return r;
1612
1613 r = sd_netlink_call(m->rtnl, req, 0, &reply);
1614 if (r < 0)
1615 return r;
1616
1617 for (route = reply; route; route = sd_netlink_message_next(route)) {
1618 int k;
1619
1620 m->enumerating = true1;
1621
1622 k = manager_rtnl_process_route(m->rtnl, route, m);
1623 if (k < 0)
1624 r = k;
1625
1626 m->enumerating = false0;
1627 }
1628
1629 return r;
1630}
1631
1632int manager_rtnl_enumerate_rules(Manager *m) {
1633 _cleanup_(sd_netlink_message_unrefp)__attribute__((cleanup(sd_netlink_message_unrefp))) sd_netlink_message *req = NULL((void*)0), *reply = NULL((void*)0);
1634 sd_netlink_message *rule;
1635 int r;
1636
1637 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/network/networkd-manager.c"
, 1637, __PRETTY_FUNCTION__); } while (0)
;
1638 assert(m->rtnl)do { if ((__builtin_expect(!!(!(m->rtnl)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m->rtnl"), "../src/network/networkd-manager.c"
, 1638, __PRETTY_FUNCTION__); } while (0)
;
1639
1640 r = sd_rtnl_message_new_routing_policy_rule(m->rtnl, &req, RTM_GETRULERTM_GETRULE, 0);
1641 if (r < 0)
1642 return r;
1643
1644 r = sd_netlink_message_request_dump(req, true1);
1645 if (r < 0)
1646 return r;
1647
1648 r = sd_netlink_call(m->rtnl, req, 0, &reply);
1649 if (r < 0) {
1650 if (r == -EOPNOTSUPP95) {
1651 log_debug("FIB Rules are not supported by the kernel. Ignoring.")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 1651, __func__, "FIB Rules are not supported by the kernel. Ignoring."
) : -abs(_e); })
;
1652 return 0;
1653 }
1654
1655 return r;
1656 }
1657
1658 for (rule = reply; rule; rule = sd_netlink_message_next(rule)) {
1659 int k;
1660
1661 m->enumerating = true1;
1662
1663 k = manager_rtnl_process_rule(m->rtnl, rule, m);
1664 if (k < 0)
1665 r = k;
1666
1667 m->enumerating = false0;
1668 }
1669
1670 return r;
1671}
1672
1673int manager_address_pool_acquire(Manager *m, int family, unsigned prefixlen, union in_addr_union *found) {
1674 AddressPool *p;
1675 int r;
1676
1677 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/network/networkd-manager.c"
, 1677, __PRETTY_FUNCTION__); } while (0)
;
1678 assert(prefixlen > 0)do { if ((__builtin_expect(!!(!(prefixlen > 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("prefixlen > 0"), "../src/network/networkd-manager.c"
, 1678, __PRETTY_FUNCTION__); } while (0)
;
1679 assert(found)do { if ((__builtin_expect(!!(!(found)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("found"), "../src/network/networkd-manager.c"
, 1679, __PRETTY_FUNCTION__); } while (0)
;
1680
1681 LIST_FOREACH(address_pools, p, m->address_pools)for ((p) = (m->address_pools); (p); (p) = (p)->address_pools_next
)
{
1682 if (p->family != family)
1683 continue;
1684
1685 r = address_pool_acquire(p, prefixlen, found);
1686 if (r != 0)
1687 return r;
1688 }
1689
1690 return 0;
1691}
1692
1693Link* manager_find_uplink(Manager *m, Link *exclude) {
1694 _cleanup_free___attribute__((cleanup(freep))) struct local_address *gateways = NULL((void*)0);
1695 int n, i;
1696
1697 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/network/networkd-manager.c"
, 1697, __PRETTY_FUNCTION__); } while (0)
;
1698
1699 /* Looks for a suitable "uplink", via black magic: an
1700 * interface that is up and where the default route with the
1701 * highest priority points to. */
1702
1703 n = local_gateways(m->rtnl, 0, AF_UNSPEC0, &gateways);
1704 if (n < 0) {
1705 log_warning_errno(n, "Failed to determine list of default gateways: %m")({ int _level = ((4)), _e = ((n)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 1705, __func__, "Failed to determine list of default gateways: %m"
) : -abs(_e); })
;
1706 return NULL((void*)0);
1707 }
1708
1709 for (i = 0; i < n; i++) {
1710 Link *link;
1711
1712 link = hashmap_get(m->links, INT_TO_PTR(gateways[i].ifindex)((void *) ((intptr_t) (gateways[i].ifindex))));
1713 if (!link) {
1714 log_debug("Weird, found a gateway for a link we don't know. Ignoring.")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 1714, __func__, "Weird, found a gateway for a link we don't know. Ignoring."
) : -abs(_e); })
;
1715 continue;
1716 }
1717
1718 if (link == exclude)
1719 continue;
1720
1721 if (link->operstate < LINK_OPERSTATE_ROUTABLE)
1722 continue;
1723
1724 return link;
1725 }
1726
1727 return NULL((void*)0);
1728}
1729
1730void manager_dirty(Manager *manager) {
1731 assert(manager)do { if ((__builtin_expect(!!(!(manager)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("manager"), "../src/network/networkd-manager.c"
, 1731, __PRETTY_FUNCTION__); } while (0)
;
1732
1733 /* the serialized state in /run is no longer up-to-date */
1734 manager->dirty = true1;
1735}
1736
1737static int set_hostname_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
1738 Manager *manager = userdata;
1739 const sd_bus_error *e;
1740
1741 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/network/networkd-manager.c"
, 1741, __PRETTY_FUNCTION__); } while (0)
;
1742 assert(manager)do { if ((__builtin_expect(!!(!(manager)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("manager"), "../src/network/networkd-manager.c"
, 1742, __PRETTY_FUNCTION__); } while (0)
;
1743
1744 e = sd_bus_message_get_error(m);
1745 if (e)
1746 log_warning_errno(sd_bus_error_get_errno(e), "Could not set hostname: %s", e->message)({ int _level = ((4)), _e = ((sd_bus_error_get_errno(e))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/network/networkd-manager.c", 1746
, __func__, "Could not set hostname: %s", e->message) : -abs
(_e); })
;
1747
1748 return 1;
1749}
1750
1751int manager_set_hostname(Manager *m, const char *hostname) {
1752 int r;
1753
1754 log_debug("Setting transient hostname: '%s'", strna(hostname))({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 1754, __func__, "Setting transient hostname: '%s'"
, strna(hostname)) : -abs(_e); })
;
1755
1756 if (free_and_strdup(&m->dynamic_hostname, hostname) < 0)
1757 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/network/networkd-manager.c"
, 1757, __func__)
;
1758
1759 if (!m->bus || sd_bus_is_ready(m->bus) <= 0) {
1760 log_info("Not connected to system bus, not setting hostname.")({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 1760, __func__, "Not connected to system bus, not setting hostname."
) : -abs(_e); })
;
1761 return 0;
1762 }
1763
1764 r = sd_bus_call_method_async(
1765 m->bus,
1766 NULL((void*)0),
1767 "org.freedesktop.hostname1",
1768 "/org/freedesktop/hostname1",
1769 "org.freedesktop.hostname1",
1770 "SetHostname",
1771 set_hostname_handler,
1772 m,
1773 "sb",
1774 hostname,
1775 false0);
1776
1777 if (r < 0)
1778 return log_error_errno(r, "Could not set transient hostname: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 1778, __func__, "Could not set transient hostname: %m"
) : -abs(_e); })
;
1779
1780 return 0;
1781}
1782
1783static int set_timezone_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
1784 Manager *manager = userdata;
1785 const sd_bus_error *e;
1786
1787 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/network/networkd-manager.c"
, 1787, __PRETTY_FUNCTION__); } while (0)
;
1788 assert(manager)do { if ((__builtin_expect(!!(!(manager)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("manager"), "../src/network/networkd-manager.c"
, 1788, __PRETTY_FUNCTION__); } while (0)
;
1789
1790 e = sd_bus_message_get_error(m);
1791 if (e)
1792 log_warning_errno(sd_bus_error_get_errno(e), "Could not set timezone: %s", e->message)({ int _level = ((4)), _e = ((sd_bus_error_get_errno(e))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/network/networkd-manager.c", 1792
, __func__, "Could not set timezone: %s", e->message) : -abs
(_e); })
;
1793
1794 return 1;
1795}
1796
1797int manager_set_timezone(Manager *m, const char *tz) {
1798 int r;
1799
1800 assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/network/networkd-manager.c"
, 1800, __PRETTY_FUNCTION__); } while (0)
;
1801 assert(tz)do { if ((__builtin_expect(!!(!(tz)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("tz"), "../src/network/networkd-manager.c"
, 1801, __PRETTY_FUNCTION__); } while (0)
;
1802
1803 log_debug("Setting system timezone: '%s'", tz)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 1803, __func__, "Setting system timezone: '%s'"
, tz) : -abs(_e); })
;
1804 if (free_and_strdup(&m->dynamic_timezone, tz) < 0)
1805 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/network/networkd-manager.c"
, 1805, __func__)
;
1806
1807 if (!m->bus || sd_bus_is_ready(m->bus) <= 0) {
1808 log_info("Not connected to system bus, not setting timezone.")({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 1808, __func__, "Not connected to system bus, not setting timezone."
) : -abs(_e); })
;
1809 return 0;
1810 }
1811
1812 r = sd_bus_call_method_async(
1813 m->bus,
1814 NULL((void*)0),
1815 "org.freedesktop.timedate1",
1816 "/org/freedesktop/timedate1",
1817 "org.freedesktop.timedate1",
1818 "SetTimezone",
1819 set_timezone_handler,
1820 m,
1821 "sb",
1822 tz,
1823 false0);
1824 if (r < 0)
1825 return log_error_errno(r, "Could not set timezone: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/network/networkd-manager.c", 1825, __func__, "Could not set timezone: %m"
) : -abs(_e); })
;
1826
1827 return 0;
1828}