]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/network/networkd-manager.c
sd-netlink: allow to dump qdisc and tclass
[thirdparty/systemd.git] / src / network / networkd-manager.c
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
f579559b 2
9aa5d8ba 3#include <netinet/in.h>
091a364c 4#include <sys/socket.h>
9aa5d8ba 5#include <unistd.h>
bbf7c048 6#include <linux/if.h>
bce67bbe 7#include <linux/fib_rules.h>
c16c7808 8#include <linux/nexthop.h>
96f5f9ef 9#include <linux/nl80211.h>
3bef724f 10
fc2f9534 11#include "sd-daemon.h"
07630cea 12#include "sd-netlink.h"
fc2f9534 13
b5efdb8a 14#include "alloc-util.h"
f63e09ef 15#include "bus-error.h"
ac9f55ed 16#include "bus-log-control-api.h"
269e4d2d 17#include "bus-polkit.h"
a97dcc12 18#include "bus-util.h"
07630cea 19#include "conf-parser.h"
a97dcc12 20#include "def.h"
482d1aeb 21#include "dns-domain.h"
3ffd4af2 22#include "fd-util.h"
0d39fa9c 23#include "fileio.h"
761cf19d 24#include "firewall-util.h"
af664001 25#include "fs-util.h"
4f5f911e 26#include "local-addresses.h"
07630cea 27#include "netlink-util.h"
dc0d4078 28#include "network-internal.h"
bfbf150e 29#include "networkd-address-pool.h"
3b6a3bde 30#include "networkd-address.h"
cf72a786 31#include "networkd-dhcp-server-bus.h"
ca5ad760 32#include "networkd-dhcp6.h"
6a1af3d4 33#include "networkd-link-bus.h"
79a59fa5 34#include "networkd-manager-bus.h"
23f53b99 35#include "networkd-manager.h"
1939ebeb 36#include "networkd-neighbor.h"
ceac2c2b 37#include "networkd-network-bus.h"
75156ccb 38#include "networkd-nexthop.h"
19d9a5ad 39#include "networkd-queue.h"
3b6a3bde 40#include "networkd-route.h"
ca183bf8 41#include "networkd-routing-policy-rule.h"
a879e1a4 42#include "networkd-speed-meter.h"
3b5a4fc6 43#include "networkd-state-file.h"
96f5f9ef 44#include "networkd-wifi.h"
00616955 45#include "ordered-set.h"
b0c82192 46#include "path-lookup.h"
07630cea 47#include "path-util.h"
92b555aa 48#include "selinux-util.h"
07630cea 49#include "set.h"
ab76be55 50#include "signal-util.h"
d31f33e3 51#include "stat-util.h"
21486d9e 52#include "strv.h"
4b600505 53#include "sysctl-util.h"
e4de7287 54#include "tmpfile-util.h"
505f8da7 55
48d0248e
YW
56/* use 128 MB for receive socket kernel queue. */
57#define RCVBUF_SIZE (128*1024*1024)
be660c37 58
9c0a72f9
TG
59static int manager_reset_all(Manager *m) {
60 Link *link;
9c0a72f9
TG
61 int r;
62
63 assert(m);
64
6eab614d 65 HASHMAP_FOREACH(link, m->links_by_index) {
d09a179e 66 r = link_reconfigure_after_sleep(link);
f0269653 67 if (r < 0) {
d09a179e 68 log_link_warning_errno(link, r, "Failed to reconfigure interface: %m");
f0269653
YW
69 link_enter_failed(link);
70 }
9c0a72f9
TG
71 }
72
73 return 0;
74}
75
19070062 76static int match_prepare_for_sleep(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
9c0a72f9
TG
77 Manager *m = userdata;
78 int b, r;
79
19070062 80 assert(message);
d7afd945 81 assert(m);
9c0a72f9
TG
82
83 r = sd_bus_message_read(message, "b", &b);
84 if (r < 0) {
d67b1d18 85 bus_log_parse_error(r);
9c0a72f9
TG
86 return 0;
87 }
88
89 if (b)
90 return 0;
91
92 log_debug("Coming back from suspend, resetting all connections...");
93
e1694a75 94 (void) manager_reset_all(m);
9c0a72f9
TG
95
96 return 0;
97}
98
d7afd945
LP
99static int on_connected(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
100 Manager *m = userdata;
9c0a72f9 101
d7afd945 102 assert(message);
9c0a72f9
TG
103 assert(m);
104
d7afd945
LP
105 /* Did we get a timezone or transient hostname from DHCP while D-Bus wasn't up yet? */
106 if (m->dynamic_hostname)
107 (void) manager_set_hostname(m, m->dynamic_hostname);
108 if (m->dynamic_timezone)
109 (void) manager_set_timezone(m, m->dynamic_timezone);
ccffa166 110 if (m->product_uuid_requested)
4e26a5ba 111 (void) manager_request_product_uuid(m);
9c0a72f9 112
d7afd945
LP
113 return 0;
114}
9c0a72f9 115
96243149 116static int manager_connect_bus(Manager *m) {
d7afd945
LP
117 int r;
118
119 assert(m);
96243149 120 assert(!m->bus);
7d6884b6 121
621e4509 122 r = bus_open_system_watch_bind_with_description(&m->bus, "bus-api-network");
9c0a72f9 123 if (r < 0)
d7afd945 124 return log_error_errno(r, "Failed to connect to bus: %m");
9c0a72f9 125
6e194652 126 r = bus_add_implementation(m->bus, &manager_object, m);
e331e246 127 if (r < 0)
6e194652 128 return r;
e331e246 129
ac9f55ed
LP
130 r = bus_log_control_api_register(m->bus);
131 if (r < 0)
132 return r;
133
696fc836 134 r = sd_bus_request_name_async(m->bus, NULL, "org.freedesktop.network1", 0, NULL, NULL);
e331e246 135 if (r < 0)
0c0b9306 136 return log_error_errno(r, "Failed to request name: %m");
e331e246
TG
137
138 r = sd_bus_attach_event(m->bus, m->event, 0);
139 if (r < 0)
140 return log_error_errno(r, "Failed to attach bus to event loop: %m");
141
d7afd945
LP
142 r = sd_bus_match_signal_async(
143 m->bus,
cad43595 144 NULL,
d7afd945
LP
145 "org.freedesktop.DBus.Local",
146 NULL,
147 "org.freedesktop.DBus.Local",
148 "Connected",
149 on_connected, NULL, m);
150 if (r < 0)
151 return log_error_errno(r, "Failed to request match on Connected signal: %m");
152
153 r = sd_bus_match_signal_async(
154 m->bus,
cad43595 155 NULL,
d7afd945
LP
156 "org.freedesktop.login1",
157 "/org/freedesktop/login1",
158 "org.freedesktop.login1.Manager",
159 "PrepareForSleep",
160 match_prepare_for_sleep, NULL, m);
161 if (r < 0)
162 log_warning_errno(r, "Failed to request match for PrepareForSleep, ignoring: %m");
7901cea1 163
9c0a72f9
TG
164 return 0;
165}
166
5fae368b
TG
167static int manager_connect_udev(Manager *m) {
168 int r;
f579559b 169
d31f33e3
YW
170 /* udev does not initialize devices inside containers, so we rely on them being already
171 * initialized before entering the container. */
172 if (path_is_read_only_fs("/sys") > 0)
5fae368b 173 return 0;
f579559b 174
d2ebf952 175 r = sd_device_monitor_new(&m->device_monitor);
02b59d57 176 if (r < 0)
d2ebf952 177 return log_error_errno(r, "Failed to initialize device monitor: %m");
02b59d57 178
a725efb0
YW
179 r = sd_device_monitor_set_receive_buffer_size(m->device_monitor, RCVBUF_SIZE);
180 if (r < 0)
181 log_warning_errno(r, "Failed to increase buffer size for device monitor, ignoring: %m");
182
d2ebf952
YW
183 r = sd_device_monitor_filter_add_match_subsystem_devtype(m->device_monitor, "net", NULL);
184 if (r < 0)
185 return log_error_errno(r, "Could not add device monitor filter: %m");
505f8da7 186
deb2b734 187 r = sd_device_monitor_attach_event(m->device_monitor, m->event);
5fae368b 188 if (r < 0)
d2ebf952 189 return log_error_errno(r, "Failed to attach event to device monitor: %m");
505f8da7 190
deb2b734 191 r = sd_device_monitor_start(m->device_monitor, manager_udev_process_link, m);
505f8da7 192 if (r < 0)
d2ebf952 193 return log_error_errno(r, "Failed to start device monitor: %m");
11a7f229 194
505f8da7
TG
195 return 0;
196}
f579559b 197
5fae368b
TG
198static int systemd_netlink_fd(void) {
199 int n, fd, rtnl_fd = -EINVAL;
200
201 n = sd_listen_fds(true);
202 if (n <= 0)
203 return -EINVAL;
204
24e3ed84 205 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd ++)
5fae368b
TG
206 if (sd_is_socket(fd, AF_NETLINK, SOCK_RAW, -1) > 0) {
207 if (rtnl_fd >= 0)
208 return -EINVAL;
209
210 rtnl_fd = fd;
211 }
5fae368b
TG
212
213 return rtnl_fd;
214}
215
05d0c2e3
JT
216static int manager_connect_genl(Manager *m) {
217 int r;
218
219 assert(m);
220
221 r = sd_genl_socket_open(&m->genl);
222 if (r < 0)
223 return r;
224
225 r = sd_netlink_inc_rcvbuf(m->genl, RCVBUF_SIZE);
226 if (r < 0)
8c63924c 227 log_warning_errno(r, "Failed to increase receive buffer size for general netlink socket, ignoring: %m");
05d0c2e3
JT
228
229 r = sd_netlink_attach_event(m->genl, m->event, 0);
230 if (r < 0)
231 return r;
232
96f5f9ef
YW
233 r = genl_add_match(m->genl, NULL, NL80211_GENL_NAME, NL80211_MULTICAST_GROUP_CONFIG, 0,
234 &manager_genl_process_nl80211_config, NULL, m, "network-genl_process_nl80211_config");
235 if (r < 0 && r != -EOPNOTSUPP)
236 return r;
237
238 r = genl_add_match(m->genl, NULL, NL80211_GENL_NAME, NL80211_MULTICAST_GROUP_MLME, 0,
239 &manager_genl_process_nl80211_mlme, NULL, m, "network-genl_process_nl80211_mlme");
240 if (r < 0 && r != -EOPNOTSUPP)
241 return r;
242
05d0c2e3
JT
243 return 0;
244}
245
26a8be48
YW
246static int manager_setup_rtnl_filter(Manager *manager) {
247 struct sock_filter filter[] = {
248 /* Check the packet length. */
249 BPF_STMT(BPF_LD + BPF_W + BPF_LEN, 0), /* A <- packet length */
250 BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, sizeof(struct nlmsghdr), 1, 0), /* A (packet length) >= sizeof(struct nlmsghdr) ? */
251 BPF_STMT(BPF_RET + BPF_K, 0), /* reject */
252 /* Always accept multipart message. */
253 BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(struct nlmsghdr, nlmsg_flags)), /* A <- message flags */
254 BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, htobe16(NLM_F_MULTI), 0, 1), /* message flags has NLM_F_MULTI ? */
255 BPF_STMT(BPF_RET + BPF_K, UINT32_MAX), /* accept */
256 /* Accept all message types except for RTM_NEWNEIGH or RTM_DELNEIGH. */
257 BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(struct nlmsghdr, nlmsg_type)), /* A <- message type */
258 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, htobe16(RTM_NEWNEIGH), 2, 0), /* message type == RTM_NEWNEIGH ? */
259 BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, htobe16(RTM_DELNEIGH), 1, 0), /* message type == RTM_DELNEIGH ? */
260 BPF_STMT(BPF_RET + BPF_K, UINT32_MAX), /* accept */
261 /* Check the packet length. */
262 BPF_STMT(BPF_LD + BPF_W + BPF_LEN, 0), /* A <- packet length */
263 BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, sizeof(struct nlmsghdr) + sizeof(struct ndmsg), 1, 0),
264 /* packet length >= sizeof(struct nlmsghdr) + sizeof(struct ndmsg) ? */
265 BPF_STMT(BPF_RET + BPF_K, 0), /* reject */
266 /* Reject the message when the neighbor state does not have NUD_PERMANENT flag. */
267 BPF_STMT(BPF_LD + BPF_H + BPF_ABS, sizeof(struct nlmsghdr) + offsetof(struct ndmsg, ndm_state)),
268 /* A <- neighbor state */
269 BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, htobe16(NUD_PERMANENT), 1, 0), /* neighbor state has NUD_PERMANENT ? */
270 BPF_STMT(BPF_RET + BPF_K, 0), /* reject */
271 BPF_STMT(BPF_RET + BPF_K, UINT32_MAX), /* accept */
272 };
273
274 assert(manager);
275 assert(manager->rtnl);
276
277 return sd_netlink_attach_filter(manager->rtnl, ELEMENTSOF(filter), filter);
278}
279
5fae368b
TG
280static int manager_connect_rtnl(Manager *m) {
281 int fd, r;
505f8da7
TG
282
283 assert(m);
505f8da7 284
5fae368b
TG
285 fd = systemd_netlink_fd();
286 if (fd < 0)
1c4baffc 287 r = sd_netlink_open(&m->rtnl);
5fae368b 288 else
1c4baffc 289 r = sd_netlink_open_fd(&m->rtnl, fd);
505f8da7
TG
290 if (r < 0)
291 return r;
292
e13af7bd
YW
293 /* Bump receiver buffer, but only if we are not called via socket activation, as in that
294 * case systemd sets the receive buffer size for us, and the value in the .socket unit
295 * should take full effect. */
296 if (fd < 0) {
297 r = sd_netlink_inc_rcvbuf(m->rtnl, RCVBUF_SIZE);
298 if (r < 0)
299 log_warning_errno(r, "Failed to increase receive buffer size for rtnl socket, ignoring: %m");
300 }
f579559b 301
1c4baffc 302 r = sd_netlink_attach_event(m->rtnl, m->event, 0);
505f8da7
TG
303 if (r < 0)
304 return r;
f579559b 305
8dfed23d 306 r = netlink_add_match(m->rtnl, NULL, RTM_NEWLINK, &manager_rtnl_process_link, NULL, m, "network-rtnl_process_link");
5fae368b
TG
307 if (r < 0)
308 return r;
505f8da7 309
8dfed23d 310 r = netlink_add_match(m->rtnl, NULL, RTM_DELLINK, &manager_rtnl_process_link, NULL, m, "network-rtnl_process_link");
5fae368b
TG
311 if (r < 0)
312 return r;
45af44d4 313
8dfed23d 314 r = netlink_add_match(m->rtnl, NULL, RTM_NEWADDR, &manager_rtnl_process_address, NULL, m, "network-rtnl_process_address");
5fae368b
TG
315 if (r < 0)
316 return r;
317
8dfed23d 318 r = netlink_add_match(m->rtnl, NULL, RTM_DELADDR, &manager_rtnl_process_address, NULL, m, "network-rtnl_process_address");
5fae368b
TG
319 if (r < 0)
320 return r;
321
8dfed23d 322 r = netlink_add_match(m->rtnl, NULL, RTM_NEWNEIGH, &manager_rtnl_process_neighbor, NULL, m, "network-rtnl_process_neighbor");
d1bdafd2
WKI
323 if (r < 0)
324 return r;
325
8dfed23d 326 r = netlink_add_match(m->rtnl, NULL, RTM_DELNEIGH, &manager_rtnl_process_neighbor, NULL, m, "network-rtnl_process_neighbor");
d1bdafd2
WKI
327 if (r < 0)
328 return r;
329
8dfed23d 330 r = netlink_add_match(m->rtnl, NULL, RTM_NEWROUTE, &manager_rtnl_process_route, NULL, m, "network-rtnl_process_route");
1c8e710c
TG
331 if (r < 0)
332 return r;
333
8dfed23d 334 r = netlink_add_match(m->rtnl, NULL, RTM_DELROUTE, &manager_rtnl_process_route, NULL, m, "network-rtnl_process_route");
1c8e710c
TG
335 if (r < 0)
336 return r;
337
8dfed23d 338 r = netlink_add_match(m->rtnl, NULL, RTM_NEWRULE, &manager_rtnl_process_rule, NULL, m, "network-rtnl_process_rule");
bce67bbe
SS
339 if (r < 0)
340 return r;
341
8dfed23d 342 r = netlink_add_match(m->rtnl, NULL, RTM_DELRULE, &manager_rtnl_process_rule, NULL, m, "network-rtnl_process_rule");
bce67bbe
SS
343 if (r < 0)
344 return r;
345
8dfed23d 346 r = netlink_add_match(m->rtnl, NULL, RTM_NEWNEXTHOP, &manager_rtnl_process_nexthop, NULL, m, "network-rtnl_process_nexthop");
c16c7808
SS
347 if (r < 0)
348 return r;
349
8dfed23d 350 r = netlink_add_match(m->rtnl, NULL, RTM_DELNEXTHOP, &manager_rtnl_process_nexthop, NULL, m, "network-rtnl_process_nexthop");
c16c7808
SS
351 if (r < 0)
352 return r;
353
26a8be48 354 return manager_setup_rtnl_filter(m);
45af44d4 355}
505f8da7 356
84de38c5
TG
357static int manager_dirty_handler(sd_event_source *s, void *userdata) {
358 Manager *m = userdata;
359 Link *link;
d23a66f2 360 int r;
84de38c5
TG
361
362 assert(m);
363
d23a66f2
YW
364 if (m->dirty) {
365 r = manager_save(m);
366 if (r < 0)
367 log_warning_errno(r, "Failed to update state file %s, ignoring: %m", m->state_file);
368 }
84de38c5 369
d23a66f2
YW
370 SET_FOREACH(link, m->dirty_links) {
371 r = link_save_and_clean(link);
372 if (r < 0)
373 log_link_warning_errno(link, r, "Failed to update link state file %s, ignoring: %m", link->state_file);
374 }
84de38c5
TG
375
376 return 1;
377}
378
ab76be55
ZJS
379static int signal_terminate_callback(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
380 Manager *m = userdata;
381
382 assert(m);
383 m->restarting = false;
384
385 log_debug("Terminate operation initiated.");
386
387 return sd_event_exit(sd_event_source_get_event(s), 0);
388}
389
390static int signal_restart_callback(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
391 Manager *m = userdata;
392
393 assert(m);
394 m->restarting = true;
395
396 log_debug("Restart operation initiated.");
397
398 return sd_event_exit(sd_event_source_get_event(s), 0);
399}
400
ea853de5
YW
401static int manager_set_keep_configuration(Manager *m) {
402 int r;
403
404 assert(m);
405
406 if (in_initrd()) {
407 log_debug("Running in initrd, keep DHCPv4 addresses on stopping networkd by default.");
408 m->keep_configuration = KEEP_CONFIGURATION_DHCP_ON_STOP;
409 return 0;
410 }
411
412 r = path_is_network_fs("/");
413 if (r < 0)
414 return log_error_errno(r, "Failed to detect if root is network filesystem: %m");
415 if (r == 0) {
416 m->keep_configuration = _KEEP_CONFIGURATION_INVALID;
417 return 0;
418 }
419
420 log_debug("Running on network filesystem, enabling KeepConfiguration= by default.");
421 m->keep_configuration = KEEP_CONFIGURATION_YES;
422 return 0;
423}
424
4c78dc17 425int manager_setup(Manager *m) {
45af44d4 426 int r;
f579559b 427
96243149 428 assert(m);
5fae368b 429
3534a043
YW
430 r = sd_event_default(&m->event);
431 if (r < 0)
432 return r;
433
ab76be55
ZJS
434 assert_se(sigprocmask_many(SIG_SETMASK, NULL, SIGINT, SIGTERM, SIGUSR2, -1) >= 0);
435
05e21627 436 (void) sd_event_set_watchdog(m->event, true);
ab76be55
ZJS
437 (void) sd_event_add_signal(m->event, NULL, SIGTERM, signal_terminate_callback, m);
438 (void) sd_event_add_signal(m->event, NULL, SIGINT, signal_terminate_callback, m);
439 (void) sd_event_add_signal(m->event, NULL, SIGUSR2, signal_restart_callback, m);
5fae368b 440
84de38c5
TG
441 r = sd_event_add_post(m->event, NULL, manager_dirty_handler, m);
442 if (r < 0)
443 return r;
444
19d9a5ad
YW
445 r = sd_event_add_post(m->event, NULL, manager_process_requests, m);
446 if (r < 0)
447 return r;
448
5fae368b 449 r = manager_connect_rtnl(m);
45af44d4
TG
450 if (r < 0)
451 return r;
452
05d0c2e3
JT
453 r = manager_connect_genl(m);
454 if (r < 0)
455 return r;
456
4c78dc17 457 if (m->test_mode)
96243149
YW
458 return 0;
459
460 r = manager_connect_bus(m);
461 if (r < 0)
462 return r;
463
5fae368b
TG
464 r = manager_connect_udev(m);
465 if (r < 0)
466 return r;
45af44d4 467
05d0c2e3
JT
468 r = sd_resolve_default(&m->resolve);
469 if (r < 0)
470 return r;
471
472 r = sd_resolve_attach_event(m->resolve, m->event, 0);
473 if (r < 0)
474 return r;
475
ed76f585 476 r = address_pool_setup_default(m);
5fae368b
TG
477 if (r < 0)
478 return r;
f579559b 479
ea853de5
YW
480 r = manager_set_keep_configuration(m);
481 if (r < 0)
482 return r;
483
96243149
YW
484 m->state_file = strdup("/run/systemd/netif/state");
485 if (!m->state_file)
486 return -ENOMEM;
487
488 return 0;
489}
490
4c78dc17 491int manager_new(Manager **ret, bool test_mode) {
96243149 492 _cleanup_(manager_freep) Manager *m = NULL;
f579559b 493
96243149
YW
494 m = new(Manager, 1);
495 if (!m)
496 return -ENOMEM;
497
498 *m = (Manager) {
ea853de5 499 .keep_configuration = _KEEP_CONFIGURATION_INVALID,
4c78dc17 500 .test_mode = test_mode,
96243149
YW
501 .speed_meter_interval_usec = SPEED_METER_DEFAULT_TIME_INTERVAL,
502 .online_state = _LINK_ONLINE_STATE_INVALID,
503 .manage_foreign_routes = true,
504 .manage_foreign_rules = true,
505 .ethtool_fd = -1,
506 .dhcp_duid.type = DUID_TYPE_EN,
507 .dhcp6_duid.type = DUID_TYPE_EN,
508 .duid_product_uuid.type = DUID_TYPE_UUID,
509 };
510
511 *ret = TAKE_PTR(m);
f579559b
TG
512 return 0;
513}
514
75db809a 515Manager* manager_free(Manager *m) {
5fae368b 516 Link *link;
f579559b 517
5fae368b 518 if (!m)
75db809a 519 return NULL;
505f8da7 520
5fae368b 521 free(m->state_file);
505f8da7 522
6eab614d 523 HASHMAP_FOREACH(link, m->links_by_index)
2a99eed0 524 (void) link_stop_engines(link, true);
946f8e14 525
40b12fa2 526 m->request_queue = ordered_set_free(m->request_queue);
19d9a5ad 527
c4397d94 528 m->dirty_links = set_free_with_destructor(m->dirty_links, link_unref);
0b54c870 529 m->links_by_name = hashmap_free(m->links_by_name);
fe321d45 530 m->links_by_hw_addr = hashmap_free(m->links_by_hw_addr);
a27588d4 531 m->links_by_dhcp_pd_subnet_prefix = hashmap_free(m->links_by_dhcp_pd_subnet_prefix);
6eab614d 532 m->links_by_index = hashmap_free_with_destructor(m->links_by_index, link_unref);
27dfc982 533
a27588d4 534 m->dhcp_pd_subnet_ids = set_free(m->dhcp_pd_subnet_ids);
715d398e 535 m->networks = ordered_hashmap_free_with_destructor(m->networks, network_unref);
dbffab87 536
c4397d94 537 m->netdevs = hashmap_free_with_destructor(m->netdevs, netdev_unref);
5fae368b 538
bfbf150e 539 ordered_set_free_free(m->address_pools);
5fae368b 540
552b90a2
YW
541 hashmap_free(m->route_table_names_by_number);
542 hashmap_free(m->route_table_numbers_by_name);
c038ce46 543
eb72fa3a 544 set_free(m->rules);
bce67bbe 545
d4df6326
SS
546 sd_netlink_unref(m->rtnl);
547 sd_netlink_unref(m->genl);
548 sd_resolve_unref(m->resolve);
549
450fa34b
YW
550 /* reject (e.g. unreachable) type routes are managed by Manager, but may be referenced by a
551 * link. E.g., DHCP6 with prefix delegation creates unreachable routes, and they are referenced
552 * by the upstream link. And the links may be referenced by netlink slots. Hence, two
553 * set_free() must be called after the above sd_netlink_unref(). */
554 m->routes = set_free(m->routes);
555 m->routes_foreign = set_free(m->routes_foreign);
556
30f10837 557 m->nexthops = set_free(m->nexthops);
69e244e3
YW
558 m->nexthops_by_id = hashmap_free(m->nexthops_by_id);
559
a879e1a4 560 sd_event_source_unref(m->speed_meter_event_source);
2f5b4a77 561 sd_event_unref(m->event);
5fae368b 562
d2ebf952 563 sd_device_monitor_unref(m->device_monitor);
7d20d375 564
15761549 565 bus_verify_polkit_async_registry_free(m->polkit_registry);
92e31da1 566 sd_bus_flush_close_unref(m->bus);
7d20d375 567
7901cea1
MP
568 free(m->dynamic_timezone);
569 free(m->dynamic_hostname);
570
c643bda5
YW
571 safe_close(m->ethtool_fd);
572
761cf19d
FW
573 m->fw_ctx = fw_ctx_free(m->fw_ctx);
574
75db809a 575 return mfree(m);
5fae368b
TG
576}
577
b76d99d9 578int manager_start(Manager *m) {
84de38c5 579 Link *link;
a879e1a4 580 int r;
84de38c5 581
a97dcc12
TG
582 assert(m);
583
a879e1a4
YW
584 r = manager_start_speed_meter(m);
585 if (r < 0)
586 return log_error_errno(r, "Failed to initialize speed meter: %m");
587
84de38c5
TG
588 /* The dirty handler will deal with future serialization, but the first one
589 must be done explicitly. */
590
d23a66f2
YW
591 r = manager_save(m);
592 if (r < 0)
593 log_warning_errno(r, "Failed to update state file %s, ignoring: %m", m->state_file);
84de38c5 594
6eab614d 595 HASHMAP_FOREACH(link, m->links_by_index) {
d23a66f2
YW
596 r = link_save(link);
597 if (r < 0)
598 log_link_warning_errno(link, r, "Failed to update link state file %s, ignoring: %m", link->state_file);
599 }
84de38c5 600
b76d99d9 601 return 0;
a97dcc12
TG
602}
603
5fae368b
TG
604int manager_load_config(Manager *m) {
605 int r;
606
607 /* update timestamp */
dc0d4078 608 paths_check_timestamp(NETWORK_DIRS, &m->network_dirs_ts_usec, true);
5fae368b 609
e272b621 610 r = netdev_load(m, false);
f579559b
TG
611 if (r < 0)
612 return r;
613
7f06b3e1 614 r = network_load(m, &m->networks);
9021bb9f
TG
615 if (r < 0)
616 return r;
617
a27588d4 618 return manager_build_dhcp_pd_subnet_ids(m);
f579559b 619}
f882c247 620
5fae368b 621bool manager_should_reload(Manager *m) {
dc0d4078 622 return paths_check_timestamp(NETWORK_DIRS, &m->network_dirs_ts_usec, false);
5fae368b
TG
623}
624
446aaaf3
YW
625static int manager_enumerate_internal(
626 Manager *m,
bdcd4ab2 627 sd_netlink *nl,
446aaaf3 628 sd_netlink_message *req,
f12629ae 629 int (*process)(sd_netlink *, sd_netlink_message *, Manager *)) {
446aaaf3
YW
630
631 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *reply = NULL;
bdcd4ab2 632 int k, r;
f882c247 633
5da8149f 634 assert(m);
bdcd4ab2 635 assert(nl);
446aaaf3
YW
636 assert(req);
637 assert(process);
f882c247 638
1c4baffc 639 r = sd_netlink_message_request_dump(req, true);
dd3efc09
TG
640 if (r < 0)
641 return r;
642
bdcd4ab2 643 r = sd_netlink_call(nl, req, 0, &reply);
f12629ae 644 if (r < 0)
f2236469
TG
645 return r;
646
446aaaf3 647 for (sd_netlink_message *reply_one = reply; reply_one; reply_one = sd_netlink_message_next(reply_one)) {
6a24f148
TG
648 m->enumerating = true;
649
bdcd4ab2 650 k = process(nl, reply_one, m);
446aaaf3 651 if (k < 0 && r >= 0)
5fae368b 652 r = k;
6a24f148
TG
653
654 m->enumerating = false;
5fae368b 655 }
2e9f08ea 656
5fae368b 657 return r;
f882c247 658}
3bef724f 659
446aaaf3
YW
660static int manager_enumerate_links(Manager *m) {
661 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
1346b1f0
TG
662 int r;
663
5fae368b
TG
664 assert(m);
665 assert(m->rtnl);
bcbca829 666
446aaaf3 667 r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
5fae368b
TG
668 if (r < 0)
669 return r;
670
f12629ae 671 return manager_enumerate_internal(m, m->rtnl, req, manager_rtnl_process_link);
446aaaf3 672}
5fae368b 673
446aaaf3
YW
674static int manager_enumerate_addresses(Manager *m) {
675 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
676 int r;
6a24f148 677
446aaaf3
YW
678 assert(m);
679 assert(m->rtnl);
6a24f148 680
446aaaf3
YW
681 r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, 0, 0);
682 if (r < 0)
683 return r;
5fae368b 684
f12629ae 685 return manager_enumerate_internal(m, m->rtnl, req, manager_rtnl_process_address);
1346b1f0 686}
d1bdafd2 687
446aaaf3
YW
688static int manager_enumerate_neighbors(Manager *m) {
689 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
d1bdafd2
WKI
690 int r;
691
692 assert(m);
693 assert(m->rtnl);
694
695 r = sd_rtnl_message_new_neigh(m->rtnl, &req, RTM_GETNEIGH, 0, AF_UNSPEC);
696 if (r < 0)
697 return r;
698
f12629ae 699 return manager_enumerate_internal(m, m->rtnl, req, manager_rtnl_process_neighbor);
d1bdafd2 700}
1346b1f0 701
446aaaf3
YW
702static int manager_enumerate_routes(Manager *m) {
703 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
1c8e710c
TG
704 int r;
705
706 assert(m);
707 assert(m->rtnl);
708
5ff1ef31
YW
709 if (!m->manage_foreign_routes)
710 return 0;
711
1c8e710c
TG
712 r = sd_rtnl_message_new_route(m->rtnl, &req, RTM_GETROUTE, 0, 0);
713 if (r < 0)
714 return r;
715
f12629ae 716 return manager_enumerate_internal(m, m->rtnl, req, manager_rtnl_process_route);
1c8e710c
TG
717}
718
446aaaf3
YW
719static int manager_enumerate_rules(Manager *m) {
720 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
bce67bbe
SS
721 int r;
722
723 assert(m);
724 assert(m->rtnl);
725
d94dfe70
YW
726 if (!m->manage_foreign_rules)
727 return 0;
728
bce67bbe
SS
729 r = sd_rtnl_message_new_routing_policy_rule(m->rtnl, &req, RTM_GETRULE, 0);
730 if (r < 0)
731 return r;
732
f12629ae 733 return manager_enumerate_internal(m, m->rtnl, req, manager_rtnl_process_rule);
bce67bbe
SS
734}
735
446aaaf3
YW
736static int manager_enumerate_nexthop(Manager *m) {
737 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
c16c7808
SS
738 int r;
739
740 assert(m);
741 assert(m->rtnl);
742
743 r = sd_rtnl_message_new_nexthop(m->rtnl, &req, RTM_GETNEXTHOP, 0, 0);
744 if (r < 0)
745 return r;
746
f12629ae 747 return manager_enumerate_internal(m, m->rtnl, req, manager_rtnl_process_nexthop);
446aaaf3 748}
c16c7808 749
96f5f9ef
YW
750static int manager_enumerate_nl80211_config(Manager *m) {
751 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
752 int r;
753
754 assert(m);
755 assert(m->genl);
756
757 r = sd_genl_message_new(m->genl, NL80211_GENL_NAME, NL80211_CMD_GET_INTERFACE, &req);
758 if (r < 0)
759 return r;
760
761 return manager_enumerate_internal(m, m->genl, req, manager_genl_process_nl80211_config);
762}
763
764static int manager_enumerate_nl80211_mlme(Manager *m) {
765 Link *link;
766 int r;
767
768 assert(m);
769 assert(m->genl);
770
771 HASHMAP_FOREACH(link, m->links_by_index) {
772 _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
773
774 if (link->wlan_iftype != NL80211_IFTYPE_STATION)
775 continue;
776
777 r = sd_genl_message_new(m->genl, NL80211_GENL_NAME, NL80211_CMD_GET_STATION, &req);
778 if (r < 0)
779 return r;
780
781 r = sd_netlink_message_append_u32(req, NL80211_ATTR_IFINDEX, link->ifindex);
782 if (r < 0)
783 return r;
784
785 r = manager_enumerate_internal(m, m->genl, req, manager_genl_process_nl80211_mlme);
786 if (r < 0)
787 return r;
788 }
789
790 return 0;
791}
792
446aaaf3
YW
793int manager_enumerate(Manager *m) {
794 int r;
c16c7808 795
446aaaf3
YW
796 r = manager_enumerate_links(m);
797 if (r < 0)
798 return log_error_errno(r, "Could not enumerate links: %m");
c16c7808 799
446aaaf3
YW
800 r = manager_enumerate_addresses(m);
801 if (r < 0)
802 return log_error_errno(r, "Could not enumerate addresses: %m");
c16c7808 803
446aaaf3
YW
804 r = manager_enumerate_neighbors(m);
805 if (r < 0)
806 return log_error_errno(r, "Could not enumerate neighbors: %m");
c16c7808 807
f12629ae
YW
808 /* NextHop support is added in kernel v5.3 (65ee00a9409f751188a8cdc0988167858eb4a536),
809 * and older kernels return -EOPNOTSUPP, or -EINVAL if SELinux is enabled. */
0c0585ca 810 r = manager_enumerate_nexthop(m);
f12629ae
YW
811 if (r == -EOPNOTSUPP || (r == -EINVAL && mac_selinux_enforcing()))
812 log_debug_errno(r, "Could not enumerate nexthops, ignoring: %m");
813 else if (r < 0)
814 return log_error_errno(r, "Could not enumerate nexthops: %m");
0c0585ca 815
446aaaf3
YW
816 r = manager_enumerate_routes(m);
817 if (r < 0)
818 return log_error_errno(r, "Could not enumerate routes: %m");
c16c7808 819
f12629ae 820 /* If kernel is built with CONFIG_FIB_RULES=n, it returns -EOPNOTSUPP. */
446aaaf3 821 r = manager_enumerate_rules(m);
f12629ae
YW
822 if (r == -EOPNOTSUPP)
823 log_debug_errno(r, "Could not enumerate routing policy rules, ignoring: %m");
824 else if (r < 0)
446aaaf3 825 return log_error_errno(r, "Could not enumerate routing policy rules: %m");
c16c7808 826
96f5f9ef
YW
827 r = manager_enumerate_nl80211_config(m);
828 if (r == -EOPNOTSUPP)
829 log_debug_errno(r, "Could not enumerate wireless LAN interfaces, ignoring: %m");
830 else if (r < 0)
831 return log_error_errno(r, "Could not enumerate wireless LAN interfaces: %m");
832
833 r = manager_enumerate_nl80211_mlme(m);
834 if (r == -EOPNOTSUPP)
835 log_debug_errno(r, "Could not enumerate wireless LAN stations, ignoring: %m");
836 else if (r < 0)
837 return log_error_errno(r, "Could not enumerate wireless LAN stations: %m");
838
446aaaf3 839 return 0;
c16c7808
SS
840}
841
59eb33e0 842static int set_hostname_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
59eb33e0 843 const sd_bus_error *e;
f63e09ef 844 int r;
59eb33e0
MP
845
846 assert(m);
59eb33e0
MP
847
848 e = sd_bus_message_get_error(m);
f63e09ef
YW
849 if (e) {
850 r = sd_bus_error_get_errno(e);
851 log_warning_errno(r, "Could not set hostname: %s", bus_error_message(e, r));
852 }
59eb33e0
MP
853
854 return 1;
855}
856
857int manager_set_hostname(Manager *m, const char *hostname) {
858 int r;
859
860 log_debug("Setting transient hostname: '%s'", strna(hostname));
d7afd945 861
b3f9c17a
YW
862 r = free_and_strdup_warn(&m->dynamic_hostname, hostname);
863 if (r < 0)
864 return r;
59eb33e0 865
5dbec9bd
ZJS
866 if (sd_bus_is_ready(m->bus) <= 0) {
867 log_debug("Not connected to system bus, setting system hostname later.");
59eb33e0
MP
868 return 0;
869 }
870
871 r = sd_bus_call_method_async(
872 m->bus,
873 NULL,
874 "org.freedesktop.hostname1",
875 "/org/freedesktop/hostname1",
876 "org.freedesktop.hostname1",
877 "SetHostname",
878 set_hostname_handler,
879 m,
880 "sb",
881 hostname,
882 false);
59eb33e0
MP
883 if (r < 0)
884 return log_error_errno(r, "Could not set transient hostname: %m");
885
886 return 0;
887}
888
889static int set_timezone_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
59eb33e0 890 const sd_bus_error *e;
f63e09ef 891 int r;
59eb33e0
MP
892
893 assert(m);
59eb33e0
MP
894
895 e = sd_bus_message_get_error(m);
f63e09ef
YW
896 if (e) {
897 r = sd_bus_error_get_errno(e);
898 log_warning_errno(r, "Could not set timezone: %s", bus_error_message(e, r));
899 }
59eb33e0
MP
900
901 return 1;
902}
903
904int manager_set_timezone(Manager *m, const char *tz) {
905 int r;
906
907 assert(m);
908 assert(tz);
909
910 log_debug("Setting system timezone: '%s'", tz);
b3f9c17a
YW
911 r = free_and_strdup_warn(&m->dynamic_timezone, tz);
912 if (r < 0)
913 return r;
59eb33e0 914
5dbec9bd
ZJS
915 if (sd_bus_is_ready(m->bus) <= 0) {
916 log_debug("Not connected to system bus, setting system timezone later.");
59eb33e0
MP
917 return 0;
918 }
919
920 r = sd_bus_call_method_async(
921 m->bus,
922 NULL,
923 "org.freedesktop.timedate1",
924 "/org/freedesktop/timedate1",
925 "org.freedesktop.timedate1",
926 "SetTimezone",
927 set_timezone_handler,
928 m,
929 "sb",
930 tz,
931 false);
932 if (r < 0)
933 return log_error_errno(r, "Could not set timezone: %m");
934
935 return 0;
936}