• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

systemd / systemd / 15057632786

15 May 2025 09:01PM UTC coverage: 72.267% (+0.02%) from 72.244%
15057632786

push

github

bluca
man: document how to hook stuff into system wakeup

Fixes: #6364

298523 of 413084 relevant lines covered (72.27%)

738132.88 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

79.94
/src/network/networkd-manager.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#include <linux/fib_rules.h>
4
#include <linux/if.h>
5
#include <linux/nexthop.h>
6
#include <linux/nl80211.h>
7
#include <netinet/in.h>
8
#include <sys/socket.h>
9
#include <unistd.h>
10

11
#include "sd-netlink.h"
12

13
#include "alloc-util.h"
14
#include "bus-error.h"
15
#include "bus-locator.h"
16
#include "bus-log-control-api.h"
17
#include "bus-polkit.h"
18
#include "bus-util.h"
19
#include "capability-util.h"
20
#include "common-signal.h"
21
#include "conf-parser.h"
22
#include "constants.h"
23
#include "daemon-util.h"
24
#include "device-private.h"
25
#include "device-util.h"
26
#include "dns-domain.h"
27
#include "env-util.h"
28
#include "fd-util.h"
29
#include "fileio.h"
30
#include "firewall-util.h"
31
#include "fs-util.h"
32
#include "initrd-util.h"
33
#include "local-addresses.h"
34
#include "mount-util.h"
35
#include "netlink-util.h"
36
#include "network-internal.h"
37
#include "networkd-address.h"
38
#include "networkd-address-label.h"
39
#include "networkd-address-pool.h"
40
#include "networkd-dhcp-server-bus.h"
41
#include "networkd-dhcp6.h"
42
#include "networkd-link-bus.h"
43
#include "networkd-manager.h"
44
#include "networkd-manager-bus.h"
45
#include "networkd-manager-varlink.h"
46
#include "networkd-neighbor.h"
47
#include "networkd-network-bus.h"
48
#include "networkd-nexthop.h"
49
#include "networkd-queue.h"
50
#include "networkd-route.h"
51
#include "networkd-routing-policy-rule.h"
52
#include "networkd-serialize.h"
53
#include "networkd-speed-meter.h"
54
#include "networkd-state-file.h"
55
#include "networkd-wifi.h"
56
#include "networkd-wiphy.h"
57
#include "ordered-set.h"
58
#include "path-lookup.h"
59
#include "path-util.h"
60
#include "qdisc.h"
61
#include "selinux-util.h"
62
#include "set.h"
63
#include "signal-util.h"
64
#include "strv.h"
65
#include "sysctl-util.h"
66
#include "tclass.h"
67
#include "tuntap.h"
68
#include "udev-util.h"
69

70
/* use 128 MB for receive socket kernel queue. */
71
#define RCVBUF_SIZE    (128*1024*1024)
72

73
static int match_prepare_for_sleep(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
×
74
        Manager *m = ASSERT_PTR(userdata);
×
75
        Link *link;
×
76
        int b, r;
×
77

78
        assert(message);
×
79

80
        r = sd_bus_message_read(message, "b", &b);
×
81
        if (r < 0) {
×
82
                bus_log_parse_error(r);
×
83
                return 0;
×
84
        }
85

86
        if (b)
×
87
                return 0;
88

89
        log_debug("Coming back from suspend, reconfiguring all connections...");
×
90

91
        HASHMAP_FOREACH(link, m->links_by_index)
×
92
                (void) link_reconfigure(link, LINK_RECONFIGURE_UNCONDITIONALLY);
×
93

94
        return 0;
×
95
}
96

97
static int on_connected(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
417✔
98
        Manager *m = ASSERT_PTR(userdata);
417✔
99

100
        assert(message);
417✔
101

102
        /* Did we get a timezone or transient hostname from DHCP while D-Bus wasn't up yet? */
103
        if (m->dynamic_hostname)
417✔
104
                (void) manager_set_hostname(m, m->dynamic_hostname);
×
105
        if (m->dynamic_timezone)
417✔
106
                (void) manager_set_timezone(m, m->dynamic_timezone);
×
107
        if (m->product_uuid_requested)
417✔
108
                (void) manager_request_product_uuid(m);
×
109

110
        return 0;
417✔
111
}
112

113
static int manager_connect_bus(Manager *m) {
417✔
114
        int r;
417✔
115

116
        assert(m);
417✔
117
        assert(!m->bus);
417✔
118

119
        r = bus_open_system_watch_bind_with_description(&m->bus, "bus-api-network");
417✔
120
        if (r < 0)
417✔
121
                return log_error_errno(r, "Failed to connect to bus: %m");
×
122

123
        r = bus_add_implementation(m->bus, &manager_object, m);
417✔
124
        if (r < 0)
417✔
125
                return r;
126

127
        r = bus_log_control_api_register(m->bus);
417✔
128
        if (r < 0)
417✔
129
                return r;
130

131
        r = sd_bus_request_name_async(m->bus, NULL, "org.freedesktop.network1", 0, NULL, NULL);
417✔
132
        if (r < 0)
417✔
133
                return log_error_errno(r, "Failed to request name: %m");
×
134

135
        r = sd_bus_attach_event(m->bus, m->event, 0);
417✔
136
        if (r < 0)
417✔
137
                return log_error_errno(r, "Failed to attach bus to event loop: %m");
×
138

139
        r = sd_bus_match_signal_async(
417✔
140
                        m->bus,
141
                        NULL,
142
                        "org.freedesktop.DBus.Local",
143
                        NULL,
144
                        "org.freedesktop.DBus.Local",
145
                        "Connected",
146
                        on_connected, NULL, m);
147
        if (r < 0)
417✔
148
                return log_error_errno(r, "Failed to request match on Connected signal: %m");
×
149

150
        r = bus_match_signal_async(
417✔
151
                        m->bus,
152
                        NULL,
153
                        bus_login_mgr,
154
                        "PrepareForSleep",
155
                        match_prepare_for_sleep, NULL, m);
156
        if (r < 0)
417✔
157
                log_warning_errno(r, "Failed to request match for PrepareForSleep, ignoring: %m");
×
158

159
        return 0;
160
}
161

162
static int manager_process_uevent(sd_device_monitor *monitor, sd_device *device, void *userdata) {
1,828✔
163
        Manager *m = ASSERT_PTR(userdata);
1,828✔
164
        sd_device_action_t action;
1,828✔
165
        int r;
1,828✔
166

167
        assert(device);
1,828✔
168

169
        r = sd_device_get_action(device, &action);
1,828✔
170
        if (r < 0)
1,828✔
171
                return log_device_warning_errno(device, r, "Failed to get udev action, ignoring: %m");
×
172

173
        if (device_in_subsystem(device, "net") > 0)
1,828✔
174
                r = manager_udev_process_link(m, device, action);
1,828✔
175
        else if (device_in_subsystem(device, "ieee80211") > 0)
×
176
                r = manager_udev_process_wiphy(m, device, action);
×
177
        else if (device_in_subsystem(device, "rfkill") > 0)
×
178
                r = manager_udev_process_rfkill(m, device, action);
×
179
        if (r < 0)
1,828✔
180
                log_device_warning_errno(device, r, "Failed to process \"%s\" uevent, ignoring: %m",
×
181
                                         device_action_to_string(action));
182

183
        return 0;
184
}
185

186
static int manager_connect_udev(Manager *m) {
417✔
187
        int r;
417✔
188

189
        /* udev does not initialize devices inside containers, so we rely on them being already
190
         * initialized before entering the container. */
191
        if (!udev_available())
417✔
192
                return 0;
193

194
        r = sd_device_monitor_new(&m->device_monitor);
361✔
195
        if (r < 0)
361✔
196
                return log_error_errno(r, "Failed to initialize device monitor: %m");
×
197

198
        r = sd_device_monitor_filter_add_match_subsystem_devtype(m->device_monitor, "net", NULL);
361✔
199
        if (r < 0)
361✔
200
                return log_error_errno(r, "Could not add device monitor filter for net subsystem: %m");
×
201

202
        r = sd_device_monitor_filter_add_match_subsystem_devtype(m->device_monitor, "ieee80211", NULL);
361✔
203
        if (r < 0)
361✔
204
                return log_error_errno(r, "Could not add device monitor filter for ieee80211 subsystem: %m");
×
205

206
        r = sd_device_monitor_filter_add_match_subsystem_devtype(m->device_monitor, "rfkill", NULL);
361✔
207
        if (r < 0)
361✔
208
                return log_error_errno(r, "Could not add device monitor filter for rfkill subsystem: %m");
×
209

210
        r = sd_device_monitor_attach_event(m->device_monitor, m->event);
361✔
211
        if (r < 0)
361✔
212
                return log_error_errno(r, "Failed to attach event to device monitor: %m");
×
213

214
        r = sd_device_monitor_start(m->device_monitor, manager_process_uevent, m);
361✔
215
        if (r < 0)
361✔
216
                return log_error_errno(r, "Failed to start device monitor: %m");
×
217

218
        return 0;
219
}
220

221
static int manager_listen_fds(Manager *m, int *ret_rtnl_fd) {
418✔
222
        _cleanup_strv_free_ char **names = NULL;
418✔
223
        int n, rtnl_fd = -EBADF;
418✔
224

225
        assert(m);
418✔
226
        assert(ret_rtnl_fd);
418✔
227

228
        n = sd_listen_fds_with_names(/* unset_environment = */ true, &names);
418✔
229
        if (n < 0)
418✔
230
                return n;
231

232
        for (int i = 0; i < n; i++) {
865✔
233
                int fd = i + SD_LISTEN_FDS_START;
447✔
234

235
                if (sd_is_socket(fd, AF_NETLINK, SOCK_RAW, -1) > 0) {
447✔
236
                        if (rtnl_fd >= 0) {
417✔
237
                                log_debug("Received multiple netlink socket, ignoring.");
×
238
                                goto unused;
×
239
                        }
240

241
                        rtnl_fd = fd;
417✔
242
                        continue;
417✔
243
                }
244

245
                if (manager_set_serialization_fd(m, fd, names[i]) >= 0)
30✔
246
                        continue;
26✔
247

248
                if (manager_add_tuntap_fd(m, fd, names[i]) >= 0)
4✔
249
                        continue;
4✔
250

251
        unused:
×
252
                if (m->test_mode)
×
253
                        safe_close(fd);
×
254
                else
255
                        close_and_notify_warn(fd, names[i]);
×
256
        }
257

258
        *ret_rtnl_fd = rtnl_fd;
418✔
259
        return 0;
418✔
260
}
261

262
static int manager_connect_genl(Manager *m) {
418✔
263
        int r;
418✔
264

265
        assert(m);
418✔
266

267
        r = sd_genl_socket_open(&m->genl);
418✔
268
        if (r < 0)
418✔
269
                return r;
270

271
        r = sd_netlink_increase_rxbuf(m->genl, RCVBUF_SIZE);
418✔
272
        if (r < 0)
418✔
273
                log_warning_errno(r, "Failed to increase receive buffer size for general netlink socket, ignoring: %m");
×
274

275
        r = sd_netlink_attach_event(m->genl, m->event, 0);
418✔
276
        if (r < 0)
418✔
277
                return r;
278

279
        /* If the kernel is built without CONFIG_WIRELESS, the below will fail with -EOPNOTSUPP. */
280
        r = genl_add_match(m->genl, NULL, NL80211_GENL_NAME, NL80211_MULTICAST_GROUP_CONFIG, 0,
418✔
281
                           &manager_genl_process_nl80211_config, NULL, m, "network-genl_process_nl80211_config");
282
        if (r < 0 && r != -EOPNOTSUPP)
418✔
283
                return r;
284

285
        r = genl_add_match(m->genl, NULL, NL80211_GENL_NAME, NL80211_MULTICAST_GROUP_MLME, 0,
418✔
286
                           &manager_genl_process_nl80211_mlme, NULL, m, "network-genl_process_nl80211_mlme");
287
        if (r < 0 && r != -EOPNOTSUPP)
418✔
288
                return r;
×
289

290
        return 0;
291
}
292

293
static int manager_setup_rtnl_filter(Manager *manager) {
418✔
294
        struct sock_filter filter[] = {
418✔
295
                /* Check the packet length. */
296
                BPF_STMT(BPF_LD + BPF_W + BPF_LEN, 0),                                      /* A <- packet length */
297
                BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, sizeof(struct nlmsghdr), 1, 0),         /* A (packet length) >= sizeof(struct nlmsghdr) ? */
298
                BPF_STMT(BPF_RET + BPF_K, 0),                                               /* reject */
299
                /* Always accept multipart message. */
300
                BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(struct nlmsghdr, nlmsg_flags)), /* A <- message flags */
301
                BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, htobe16(NLM_F_MULTI), 0, 1),           /* message flags has NLM_F_MULTI ? */
418✔
302
                BPF_STMT(BPF_RET + BPF_K, UINT32_MAX),                                      /* accept */
303
                /* Accept all message types except for RTM_NEWNEIGH or RTM_DELNEIGH. */
304
                BPF_STMT(BPF_LD + BPF_H + BPF_ABS, offsetof(struct nlmsghdr, nlmsg_type)),  /* A <- message type */
305
                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, htobe16(RTM_NEWNEIGH), 2, 0),           /* message type == RTM_NEWNEIGH ? */
418✔
306
                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, htobe16(RTM_DELNEIGH), 1, 0),           /* message type == RTM_DELNEIGH ? */
418✔
307
                BPF_STMT(BPF_RET + BPF_K, UINT32_MAX),                                      /* accept */
308
                /* Check the packet length. */
309
                BPF_STMT(BPF_LD + BPF_W + BPF_LEN, 0),                                      /* A <- packet length */
310
                BPF_JUMP(BPF_JMP + BPF_JGE + BPF_K, sizeof(struct nlmsghdr) + sizeof(struct ndmsg), 1, 0),
311
                                                                                            /* packet length >= sizeof(struct nlmsghdr) + sizeof(struct ndmsg) ? */
312
                BPF_STMT(BPF_RET + BPF_K, 0),                                               /* reject */
313
                /* Reject the message when the neighbor state does not have NUD_PERMANENT flag. */
314
                BPF_STMT(BPF_LD + BPF_H + BPF_ABS, sizeof(struct nlmsghdr) + offsetof(struct ndmsg, ndm_state)),
315
                                                                                            /* A <- neighbor state */
316
                BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, htobe16(NUD_PERMANENT), 1, 0),         /* neighbor state has NUD_PERMANENT ? */
418✔
317
                BPF_STMT(BPF_RET + BPF_K, 0),                                               /* reject */
318
                BPF_STMT(BPF_RET + BPF_K, UINT32_MAX),                                      /* accept */
319
        };
320

321
        assert(manager);
418✔
322
        assert(manager->rtnl);
418✔
323

324
        return sd_netlink_attach_filter(manager->rtnl, ELEMENTSOF(filter), filter);
418✔
325
}
326

327
static int manager_connect_rtnl(Manager *m, int fd) {
418✔
328
        _unused_ _cleanup_close_ int fd_close = fd;
418✔
329
        int r;
418✔
330

331
        assert(m);
418✔
332

333
        /* This takes input fd. */
334

335
        if (fd < 0)
418✔
336
                r = sd_netlink_open(&m->rtnl);
1✔
337
        else
338
                r = sd_netlink_open_fd(&m->rtnl, fd);
417✔
339
        if (r < 0)
418✔
340
                return r;
341
        TAKE_FD(fd_close);
418✔
342

343
        /* Bump receiver buffer, but only if we are not called via socket activation, as in that
344
         * case systemd sets the receive buffer size for us, and the value in the .socket unit
345
         * should take full effect. */
346
        if (fd < 0) {
418✔
347
                r = sd_netlink_increase_rxbuf(m->rtnl, RCVBUF_SIZE);
1✔
348
                if (r < 0)
1✔
349
                        log_warning_errno(r, "Failed to increase receive buffer size for rtnl socket, ignoring: %m");
×
350
        }
351

352
        r = sd_netlink_attach_event(m->rtnl, m->event, 0);
418✔
353
        if (r < 0)
418✔
354
                return r;
355

356
        r = netlink_add_match(m->rtnl, NULL, RTM_NEWLINK, &manager_rtnl_process_link, NULL, m, "network-rtnl_process_link");
418✔
357
        if (r < 0)
418✔
358
                return r;
359

360
        r = netlink_add_match(m->rtnl, NULL, RTM_DELLINK, &manager_rtnl_process_link, NULL, m, "network-rtnl_process_link");
418✔
361
        if (r < 0)
418✔
362
                return r;
363

364
        r = netlink_add_match(m->rtnl, NULL, RTM_NEWQDISC, &manager_rtnl_process_qdisc, NULL, m, "network-rtnl_process_qdisc");
418✔
365
        if (r < 0)
418✔
366
                return r;
367

368
        r = netlink_add_match(m->rtnl, NULL, RTM_DELQDISC, &manager_rtnl_process_qdisc, NULL, m, "network-rtnl_process_qdisc");
418✔
369
        if (r < 0)
418✔
370
                return r;
371

372
        r = netlink_add_match(m->rtnl, NULL, RTM_NEWTCLASS, &manager_rtnl_process_tclass, NULL, m, "network-rtnl_process_tclass");
418✔
373
        if (r < 0)
418✔
374
                return r;
375

376
        r = netlink_add_match(m->rtnl, NULL, RTM_DELTCLASS, &manager_rtnl_process_tclass, NULL, m, "network-rtnl_process_tclass");
418✔
377
        if (r < 0)
418✔
378
                return r;
379

380
        r = netlink_add_match(m->rtnl, NULL, RTM_NEWADDR, &manager_rtnl_process_address, NULL, m, "network-rtnl_process_address");
418✔
381
        if (r < 0)
418✔
382
                return r;
383

384
        r = netlink_add_match(m->rtnl, NULL, RTM_DELADDR, &manager_rtnl_process_address, NULL, m, "network-rtnl_process_address");
418✔
385
        if (r < 0)
418✔
386
                return r;
387

388
        r = netlink_add_match(m->rtnl, NULL, RTM_NEWNEIGH, &manager_rtnl_process_neighbor, NULL, m, "network-rtnl_process_neighbor");
418✔
389
        if (r < 0)
418✔
390
                return r;
391

392
        r = netlink_add_match(m->rtnl, NULL, RTM_DELNEIGH, &manager_rtnl_process_neighbor, NULL, m, "network-rtnl_process_neighbor");
418✔
393
        if (r < 0)
418✔
394
                return r;
395

396
        r = netlink_add_match(m->rtnl, NULL, RTM_NEWROUTE, &manager_rtnl_process_route, NULL, m, "network-rtnl_process_route");
418✔
397
        if (r < 0)
418✔
398
                return r;
399

400
        r = netlink_add_match(m->rtnl, NULL, RTM_DELROUTE, &manager_rtnl_process_route, NULL, m, "network-rtnl_process_route");
418✔
401
        if (r < 0)
418✔
402
                return r;
403

404
        r = netlink_add_match(m->rtnl, NULL, RTM_NEWRULE, &manager_rtnl_process_rule, NULL, m, "network-rtnl_process_rule");
418✔
405
        if (r < 0)
418✔
406
                return r;
407

408
        r = netlink_add_match(m->rtnl, NULL, RTM_DELRULE, &manager_rtnl_process_rule, NULL, m, "network-rtnl_process_rule");
418✔
409
        if (r < 0)
418✔
410
                return r;
411

412
        r = netlink_add_match(m->rtnl, NULL, RTM_NEWNEXTHOP, &manager_rtnl_process_nexthop, NULL, m, "network-rtnl_process_nexthop");
418✔
413
        if (r < 0)
418✔
414
                return r;
415

416
        r = netlink_add_match(m->rtnl, NULL, RTM_DELNEXTHOP, &manager_rtnl_process_nexthop, NULL, m, "network-rtnl_process_nexthop");
418✔
417
        if (r < 0)
418✔
418
                return r;
419

420
        return manager_setup_rtnl_filter(m);
418✔
421
}
422

423
static int manager_post_handler(sd_event_source *s, void *userdata) {
56,448✔
424
        Manager *manager = ASSERT_PTR(userdata);
56,448✔
425

426
        /* To release dynamic leases, we need to process queued remove requests before stopping networkd.
427
         * This is especially important when KeepConfiguration=no. See issue #34837. */
428
        (void) manager_process_remove_requests(manager);
56,448✔
429

430
        switch (manager->state) {
56,448✔
431
        case MANAGER_RUNNING:
56,010✔
432
                (void) manager_process_requests(manager);
56,010✔
433
                (void) manager_clean_all(manager);
56,010✔
434
                return 0;
56,010✔
435

436
        case MANAGER_TERMINATING:
438✔
437
        case MANAGER_RESTARTING:
438
                if (!ordered_set_isempty(manager->remove_request_queue))
438✔
439
                        return 0; /* There are some unissued remove requests. */
440

441
                if (netlink_get_reply_callback_count(manager->rtnl) > 0 ||
855✔
442
                    netlink_get_reply_callback_count(manager->genl) > 0 ||
834✔
443
                    fw_ctx_get_reply_callback_count(manager->fw_ctx) > 0)
417✔
444
                        return 0; /* There are some message calls waiting for their replies. */
21✔
445

446
                (void) manager_serialize(manager);
417✔
447
                manager->state = MANAGER_STOPPED;
417✔
448
                return sd_event_exit(sd_event_source_get_event(s), 0);
417✔
449

450
        default:
×
451
                assert_not_reached();
×
452
        }
453

454
        return 0;
455
}
456

457
static int manager_stop(Manager *manager, ManagerState state) {
417✔
458
        assert(manager);
417✔
459
        assert(IN_SET(state, MANAGER_TERMINATING, MANAGER_RESTARTING));
417✔
460

461
        if (manager->state != MANAGER_RUNNING) {
417✔
462
                log_debug("Already terminating or restarting systemd-networkd, refusing further operation request.");
×
463
                return 0;
×
464
        }
465

466
        switch (state) {
417✔
467
        case MANAGER_TERMINATING:
468
                log_debug("Terminate operation initiated.");
387✔
469
                break;
470
        case MANAGER_RESTARTING:
471
                log_debug("Restart operation initiated.");
30✔
472
                break;
473
        default:
×
474
                assert_not_reached();
×
475
        }
476

477
        manager->state = state;
417✔
478

479
        Link *link;
417✔
480
        HASHMAP_FOREACH(link, manager->links_by_index)
2,216✔
481
                (void) link_stop_engines(link, /* may_keep_dynamic = */ true);
1,799✔
482

483
        return 0;
417✔
484
}
485

486
static int signal_terminate_callback(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
387✔
487
        return manager_stop(userdata, MANAGER_TERMINATING);
387✔
488
}
489

490
static int signal_restart_callback(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
30✔
491
        return manager_stop(userdata, MANAGER_RESTARTING);
30✔
492
}
493

494
static int signal_reload_callback(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
×
495
        Manager *m = ASSERT_PTR(userdata);
×
496

497
        (void) manager_reload(m, /* message = */ NULL);
×
498

499
        return 0;
×
500
}
501

502
static int manager_set_keep_configuration(Manager *m) {
417✔
503
        int r;
417✔
504

505
        assert(m);
417✔
506

507
        if (in_initrd()) {
417✔
508
                log_debug("Running in initrd, keep dynamically assigned configurations on stopping networkd by default.");
×
509
                m->keep_configuration = KEEP_CONFIGURATION_DYNAMIC_ON_STOP;
×
510
                return 0;
×
511
        }
512

513
        r = path_is_network_fs_harder("/");
417✔
514
        if (r < 0) {
417✔
515
                log_warning_errno(r, "Failed to detect if root is network filesystem, assuming not: %m");
×
516
                return 0;
×
517
        }
518
        if (r == 0) {
417✔
519
                m->keep_configuration = _KEEP_CONFIGURATION_INVALID;
417✔
520
                return 0;
417✔
521
        }
522

523
        log_debug("Running on network filesystem, enabling KeepConfiguration= by default.");
×
524
        m->keep_configuration = KEEP_CONFIGURATION_YES;
×
525
        return 0;
×
526
}
527

528
int manager_setup(Manager *m) {
418✔
529
        _cleanup_close_ int rtnl_fd = -EBADF;
418✔
530
        int r;
418✔
531

532
        assert(m);
418✔
533

534
        r = sd_event_default(&m->event);
418✔
535
        if (r < 0)
418✔
536
                return r;
537

538
        (void) sd_event_set_watchdog(m->event, true);
418✔
539
        (void) sd_event_add_signal(m->event, NULL, SIGTERM | SD_EVENT_SIGNAL_PROCMASK, signal_terminate_callback, m);
418✔
540
        (void) sd_event_add_signal(m->event, NULL, SIGINT | SD_EVENT_SIGNAL_PROCMASK, signal_terminate_callback, m);
418✔
541
        (void) sd_event_add_signal(m->event, NULL, SIGUSR2 | SD_EVENT_SIGNAL_PROCMASK, signal_restart_callback, m);
418✔
542
        (void) sd_event_add_signal(m->event, NULL, SIGHUP | SD_EVENT_SIGNAL_PROCMASK, signal_reload_callback, m);
418✔
543
        (void) sd_event_add_signal(m->event, NULL, (SIGRTMIN+18) | SD_EVENT_SIGNAL_PROCMASK, sigrtmin18_handler, NULL);
418✔
544

545
        r = sd_event_add_memory_pressure(m->event, NULL, NULL, NULL);
418✔
546
        if (r < 0)
418✔
547
                log_debug_errno(r, "Failed allocate memory pressure event source, ignoring: %m");
×
548

549
        r = sd_event_add_post(m->event, NULL, manager_post_handler, m);
418✔
550
        if (r < 0)
418✔
551
                return r;
552

553
        r = manager_listen_fds(m, &rtnl_fd);
418✔
554
        if (r < 0)
418✔
555
                return r;
556

557
        r = manager_connect_rtnl(m, TAKE_FD(rtnl_fd));
418✔
558
        if (r < 0)
418✔
559
                return r;
560

561
        r = manager_connect_genl(m);
418✔
562
        if (r < 0)
418✔
563
                return r;
564

565
        if (m->test_mode)
418✔
566
                return 0;
567

568
        r = manager_connect_varlink(m);
417✔
569
        if (r < 0)
417✔
570
                return r;
571

572
        r = manager_connect_bus(m);
417✔
573
        if (r < 0)
417✔
574
                return r;
575

576
        r = manager_connect_udev(m);
417✔
577
        if (r < 0)
417✔
578
                return r;
579

580
        r = sd_resolve_default(&m->resolve);
417✔
581
        if (r < 0)
417✔
582
                return r;
583

584
        r = sd_resolve_attach_event(m->resolve, m->event, 0);
417✔
585
        if (r < 0)
417✔
586
                return r;
587

588
        r = address_pool_setup_default(m);
417✔
589
        if (r < 0)
417✔
590
                return r;
591

592
        r = manager_set_keep_configuration(m);
417✔
593
        if (r < 0)
417✔
594
                return r;
595

596
        m->state_file = strdup("/run/systemd/netif/state");
417✔
597
        if (!m->state_file)
417✔
598
                return -ENOMEM;
×
599

600
        return 0;
601
}
602

603
static int persistent_storage_open(void) {
441✔
604
        _cleanup_close_ int fd = -EBADF;
441✔
605
        int r;
441✔
606

607
        r = getenv_bool("SYSTEMD_NETWORK_PERSISTENT_STORAGE_READY");
441✔
608
        if (r < 0 && r != -ENXIO)
441✔
609
                return log_debug_errno(r, "Failed to parse $SYSTEMD_NETWORK_PERSISTENT_STORAGE_READY environment variable, ignoring: %m");
×
610
        if (r <= 0)
441✔
611
                return -EBADF;
612

613
        fd = open("/var/lib/systemd/network/", O_CLOEXEC | O_DIRECTORY);
×
614
        if (fd < 0)
×
615
                return log_debug_errno(errno, "Failed to open /var/lib/systemd/network/, ignoring: %m");
×
616

617
        r = fd_is_read_only_fs(fd);
×
618
        if (r < 0)
×
619
                return log_debug_errno(r, "Failed to check if /var/lib/systemd/network/ is writable: %m");
×
620
        if (r > 0)
×
621
                return log_debug_errno(SYNTHETIC_ERRNO(EROFS), "The directory /var/lib/systemd/network/ is on read-only filesystem.");
×
622

623
        return TAKE_FD(fd);
624
}
625

626
int manager_new(Manager **ret, bool test_mode) {
441✔
627
        _cleanup_(manager_freep) Manager *m = NULL;
441✔
628

629
        m = new(Manager, 1);
441✔
630
        if (!m)
441✔
631
                return -ENOMEM;
632

633
        *m = (Manager) {
882✔
634
                .keep_configuration = _KEEP_CONFIGURATION_INVALID,
635
                .ipv6_privacy_extensions = IPV6_PRIVACY_EXTENSIONS_NO,
636
                .test_mode = test_mode,
637
                .speed_meter_interval_usec = SPEED_METER_DEFAULT_TIME_INTERVAL,
638
                .online_state = _LINK_ONLINE_STATE_INVALID,
639
                .manage_foreign_routes = true,
640
                .manage_foreign_rules = true,
641
                .manage_foreign_nexthops = true,
642
                .ethtool_fd = -EBADF,
643
                .persistent_storage_fd = persistent_storage_open(),
441✔
644
                .dhcp_use_domains = _USE_DOMAINS_INVALID,
645
                .dhcp6_use_domains = _USE_DOMAINS_INVALID,
646
                .ndisc_use_domains = _USE_DOMAINS_INVALID,
647
                .dhcp_client_identifier = DHCP_CLIENT_ID_DUID,
648
                .dhcp_duid.type = DUID_TYPE_EN,
649
                .dhcp6_duid.type = DUID_TYPE_EN,
650
                .duid_product_uuid.type = DUID_TYPE_UUID,
651
                .dhcp_server_persist_leases = true,
652
                .serialization_fd = -EBADF,
653
                .ip_forwarding = { -1, -1, },
654
#if HAVE_VMLINUX_H
655
                .cgroup_fd = -EBADF,
656
#endif
657
        };
658

659
        *ret = TAKE_PTR(m);
441✔
660
        return 0;
441✔
661
}
662

663
Manager* manager_free(Manager *m) {
441✔
664
        if (!m)
441✔
665
                return NULL;
666

667
        manager_remove_sysctl_monitor(m);
441✔
668

669
        free(m->state_file);
441✔
670

671
        m->request_queue = ordered_set_free(m->request_queue);
441✔
672
        m->remove_request_queue = ordered_set_free(m->remove_request_queue);
441✔
673

674
        m->new_wlan_ifindices = set_free(m->new_wlan_ifindices);
441✔
675

676
        m->dirty_links = set_free(m->dirty_links);
441✔
677
        m->links_by_name = hashmap_free(m->links_by_name);
441✔
678
        m->links_by_hw_addr = hashmap_free(m->links_by_hw_addr);
441✔
679
        m->links_by_dhcp_pd_subnet_prefix = hashmap_free(m->links_by_dhcp_pd_subnet_prefix);
441✔
680
        m->links_by_index = hashmap_free(m->links_by_index);
441✔
681

682
        m->dhcp_pd_subnet_ids = set_free(m->dhcp_pd_subnet_ids);
441✔
683
        m->networks = ordered_hashmap_free(m->networks);
441✔
684

685
        /* The same object may be registered with multiple names, and netdev_detach() may drop multiple entries. */
686
        for (NetDev *n; (n = hashmap_first(m->netdevs)); )
559✔
687
                netdev_detach(n);
118✔
688
        m->netdevs = hashmap_free(m->netdevs);
441✔
689

690
        m->tuntap_fds_by_name = hashmap_free(m->tuntap_fds_by_name);
441✔
691

692
        m->wiphy_by_name = hashmap_free(m->wiphy_by_name);
441✔
693
        m->wiphy_by_index = hashmap_free(m->wiphy_by_index);
441✔
694

695
        ordered_set_free(m->address_pools);
441✔
696

697
        hashmap_free(m->route_table_names_by_number);
441✔
698
        hashmap_free(m->route_table_numbers_by_name);
441✔
699

700
        set_free(m->rules);
441✔
701

702
        sd_netlink_unref(m->rtnl);
441✔
703
        sd_netlink_unref(m->genl);
441✔
704
        sd_resolve_unref(m->resolve);
441✔
705

706
        m->routes = set_free(m->routes);
441✔
707

708
        m->nexthops_by_id = hashmap_free(m->nexthops_by_id);
441✔
709
        m->nexthop_ids = set_free(m->nexthop_ids);
441✔
710

711
        m->address_labels_by_section = hashmap_free(m->address_labels_by_section);
441✔
712

713
        sd_event_source_unref(m->speed_meter_event_source);
441✔
714
        sd_event_unref(m->event);
441✔
715

716
        sd_device_monitor_unref(m->device_monitor);
441✔
717

718
        manager_varlink_done(m);
441✔
719
        hashmap_free(m->polkit_registry);
441✔
720
        sd_bus_flush_close_unref(m->bus);
441✔
721

722
        free(m->dynamic_timezone);
441✔
723
        free(m->dynamic_hostname);
441✔
724

725
        safe_close(m->ethtool_fd);
441✔
726
        safe_close(m->persistent_storage_fd);
441✔
727

728
        m->fw_ctx = fw_ctx_free(m->fw_ctx);
441✔
729

730
        m->serialization_fd = safe_close(m->serialization_fd);
441✔
731

732
        return mfree(m);
441✔
733
}
734

735
int manager_start(Manager *m) {
417✔
736
        Link *link;
417✔
737
        int r;
417✔
738

739
        assert(m);
417✔
740

741
        log_debug("Starting...");
417✔
742

743
        (void) manager_install_sysctl_monitor(m);
417✔
744

745
        /* Loading BPF programs requires CAP_SYS_ADMIN and CAP_BPF.
746
         * Drop the capabilities here, regardless if the load succeeds or not. */
747
        r = drop_capability(CAP_SYS_ADMIN);
417✔
748
        if (r < 0)
417✔
749
                log_warning_errno(r, "Failed to drop CAP_SYS_ADMIN, ignoring: %m.");
×
750

751
        r = drop_capability(CAP_BPF);
417✔
752
        if (r < 0)
417✔
753
                log_warning_errno(r, "Failed to drop CAP_BPF, ignoring: %m.");
×
754

755
        manager_set_sysctl(m);
417✔
756

757
        r = manager_request_static_address_labels(m);
417✔
758
        if (r < 0)
417✔
759
                return r;
417✔
760

761
        r = manager_start_speed_meter(m);
417✔
762
        if (r < 0)
417✔
763
                return log_error_errno(r, "Failed to initialize speed meter: %m");
×
764

765
        HASHMAP_FOREACH(link, m->links_by_index) {
2,150✔
766
                if (link->state != LINK_STATE_PENDING)
1,733✔
767
                        continue;
×
768

769
                r = link_check_initialized(link);
1,733✔
770
                if (r < 0) {
1,733✔
771
                        log_link_warning_errno(link, r, "Failed to check if link is initialized: %m");
×
772
                        link_enter_failed(link);
×
773
                }
774
        }
775

776
        /* The dirty handler will deal with future serialization, but the first one
777
           must be done explicitly. */
778

779
        r = manager_save(m);
417✔
780
        if (r < 0)
417✔
781
                log_warning_errno(r, "Failed to update state file %s, ignoring: %m", m->state_file);
×
782

783
        HASHMAP_FOREACH(link, m->links_by_index) {
2,567✔
784
                r = link_save_and_clean(link);
1,733✔
785
                if (r < 0)
1,733✔
786
                        log_link_warning_errno(link, r, "Failed to update link state file %s, ignoring: %m", link->state_file);
×
787
        }
788

789
        log_debug("Started.");
417✔
790
        return 0;
791
}
792

793
int manager_load_config(Manager *m) {
418✔
794
        int r;
418✔
795

796
        log_debug("Loading...");
418✔
797

798
        r = netdev_load(m);
418✔
799
        if (r < 0)
418✔
800
                return log_debug_errno(r, "Failed to load .netdev files: %m");
×
801

802
        manager_clear_unmanaged_tuntap_fds(m);
418✔
803

804
        r = network_load(m, &m->networks);
418✔
805
        if (r < 0)
418✔
806
                return log_debug_errno(r, "Failed to load .network files: %m");
×
807

808
        r = manager_build_dhcp_pd_subnet_ids(m);
418✔
809
        if (r < 0)
418✔
810
                return log_debug_errno(r, "Failed to build DHCP-PD subnet ID map: %m");
×
811

812
        r = manager_build_nexthop_ids(m);
418✔
813
        if (r < 0)
418✔
814
                return log_debug_errno(r, "Failed to build nexthop ID map: %m");
×
815

816
        log_debug("Loaded.");
418✔
817
        return 0;
818
}
819

820
int manager_enumerate_internal(
5,906✔
821
                Manager *m,
822
                sd_netlink *nl,
823
                sd_netlink_message *req,
824
                int (*process)(sd_netlink *, sd_netlink_message *, Manager *)) {
825

826
        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *reply = NULL;
5,906✔
827
        int r;
5,906✔
828

829
        assert(m);
5,906✔
830
        assert(nl);
5,906✔
831
        assert(req);
5,906✔
832
        assert(process);
5,906✔
833

834
        r = sd_netlink_message_set_request_dump(req, true);
5,906✔
835
        if (r < 0)
5,906✔
836
                return r;
837

838
        r = sd_netlink_call(nl, req, 0, &reply);
5,906✔
839
        if (r < 0)
5,906✔
840
                return r;
841

842
        m->enumerating = true;
5,906✔
843
        for (sd_netlink_message *reply_one = reply; reply_one; reply_one = sd_netlink_message_next(reply_one))
16,197✔
844
                RET_GATHER(r, process(nl, reply_one, m));
10,291✔
845
        m->enumerating = false;
5,906✔
846

847
        return r;
5,906✔
848
}
849

850
static int manager_enumerate_links(Manager *m) {
418✔
851
        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
418✔
852
        int r;
418✔
853

854
        assert(m);
418✔
855
        assert(m->rtnl);
418✔
856

857
        r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
418✔
858
        if (r < 0)
418✔
859
                return r;
860

861
        r = manager_enumerate_internal(m, m->rtnl, req, manager_rtnl_process_link);
418✔
862
        if (r < 0)
418✔
863
                return r;
864

865
        req = sd_netlink_message_unref(req);
418✔
866

867
        r = sd_rtnl_message_new_link(m->rtnl, &req, RTM_GETLINK, 0);
418✔
868
        if (r < 0)
418✔
869
                return r;
870

871
        r = sd_rtnl_message_link_set_family(req, AF_BRIDGE);
418✔
872
        if (r < 0)
418✔
873
                return r;
874

875
        return manager_enumerate_internal(m, m->rtnl, req, manager_rtnl_process_link);
418✔
876
}
877

878
static int manager_enumerate_qdisc(Manager *m) {
418✔
879
        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
418✔
880
        int r;
418✔
881

882
        assert(m);
418✔
883
        assert(m->rtnl);
418✔
884

885
        r = sd_rtnl_message_new_traffic_control(m->rtnl, &req, RTM_GETQDISC, 0, 0, 0);
418✔
886
        if (r < 0)
418✔
887
                return r;
888

889
        return manager_enumerate_internal(m, m->rtnl, req, manager_rtnl_process_qdisc);
418✔
890
}
891

892
static int manager_enumerate_tclass(Manager *m) {
418✔
893
        Link *link;
418✔
894
        int r = 0;
418✔
895

896
        assert(m);
418✔
897
        assert(m->rtnl);
418✔
898

899
        /* TC class can be enumerated only per link. See tc_dump_tclass() in net/sched/sched_api.c. */
900

901
        HASHMAP_FOREACH(link, m->links_by_index)
2,152✔
902
                RET_GATHER(r, link_enumerate_tclass(link, 0));
1,734✔
903

904
        return r;
418✔
905
}
906

907
static int manager_enumerate_addresses(Manager *m) {
418✔
908
        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
418✔
909
        int r;
418✔
910

911
        assert(m);
418✔
912
        assert(m->rtnl);
418✔
913

914
        r = sd_rtnl_message_new_addr(m->rtnl, &req, RTM_GETADDR, 0, 0);
418✔
915
        if (r < 0)
418✔
916
                return r;
917

918
        return manager_enumerate_internal(m, m->rtnl, req, manager_rtnl_process_address);
418✔
919
}
920

921
static int manager_enumerate_neighbors(Manager *m) {
418✔
922
        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
418✔
923
        int r;
418✔
924

925
        assert(m);
418✔
926
        assert(m->rtnl);
418✔
927

928
        r = sd_rtnl_message_new_neigh(m->rtnl, &req, RTM_GETNEIGH, 0, AF_UNSPEC);
418✔
929
        if (r < 0)
418✔
930
                return r;
931

932
        return manager_enumerate_internal(m, m->rtnl, req, manager_rtnl_process_neighbor);
418✔
933
}
934

935
static int manager_enumerate_routes(Manager *m) {
418✔
936
        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
418✔
937
        int r;
418✔
938

939
        assert(m);
418✔
940
        assert(m->rtnl);
418✔
941

942
        if (!m->manage_foreign_routes)
418✔
943
                return 0;
944

945
        r = sd_rtnl_message_new_route(m->rtnl, &req, RTM_GETROUTE, 0, 0);
417✔
946
        if (r < 0)
417✔
947
                return r;
948

949
        return manager_enumerate_internal(m, m->rtnl, req, manager_rtnl_process_route);
417✔
950
}
951

952
static int manager_enumerate_rules(Manager *m) {
418✔
953
        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
418✔
954
        int r;
418✔
955

956
        assert(m);
418✔
957
        assert(m->rtnl);
418✔
958

959
        if (!m->manage_foreign_rules)
418✔
960
                return 0;
961

962
        r = sd_rtnl_message_new_routing_policy_rule(m->rtnl, &req, RTM_GETRULE, 0);
417✔
963
        if (r < 0)
417✔
964
                return r;
965

966
        return manager_enumerate_internal(m, m->rtnl, req, manager_rtnl_process_rule);
417✔
967
}
968

969
static int manager_enumerate_nexthop(Manager *m) {
418✔
970
        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
418✔
971
        int r;
418✔
972

973
        assert(m);
418✔
974
        assert(m->rtnl);
418✔
975

976
        if (!m->manage_foreign_nexthops)
418✔
977
                return 0;
978

979
        r = sd_rtnl_message_new_nexthop(m->rtnl, &req, RTM_GETNEXTHOP, 0, 0);
416✔
980
        if (r < 0)
416✔
981
                return r;
982

983
        return manager_enumerate_internal(m, m->rtnl, req, manager_rtnl_process_nexthop);
416✔
984
}
985

986
static int manager_enumerate_nl80211_wiphy(Manager *m) {
418✔
987
        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
418✔
988
        int r;
418✔
989

990
        assert(m);
418✔
991
        assert(m->genl);
418✔
992

993
        r = sd_genl_message_new(m->genl, NL80211_GENL_NAME, NL80211_CMD_GET_WIPHY, &req);
418✔
994
        if (r < 0)
418✔
995
                return r;
996

997
        return manager_enumerate_internal(m, m->genl, req, manager_genl_process_nl80211_wiphy);
361✔
998
}
999

1000
static int manager_enumerate_nl80211_config(Manager *m) {
418✔
1001
        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
418✔
1002
        int r;
418✔
1003

1004
        assert(m);
418✔
1005
        assert(m->genl);
418✔
1006

1007
        r = sd_genl_message_new(m->genl, NL80211_GENL_NAME, NL80211_CMD_GET_INTERFACE, &req);
418✔
1008
        if (r < 0)
418✔
1009
                return r;
1010

1011
        return manager_enumerate_internal(m, m->genl, req, manager_genl_process_nl80211_config);
361✔
1012
}
1013

1014
static int manager_enumerate_nl80211_mlme(Manager *m) {
418✔
1015
        Link *link;
418✔
1016
        int r;
418✔
1017

1018
        assert(m);
418✔
1019
        assert(m->genl);
418✔
1020

1021
        HASHMAP_FOREACH(link, m->links_by_index) {
2,152✔
1022
                _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
×
1023

1024
                if (link->wlan_iftype != NL80211_IFTYPE_STATION)
1,734✔
1025
                        continue;
1,734✔
1026

1027
                r = sd_genl_message_new(m->genl, NL80211_GENL_NAME, NL80211_CMD_GET_STATION, &req);
×
1028
                if (r < 0)
×
1029
                        return r;
1030

1031
                r = sd_netlink_message_append_u32(req, NL80211_ATTR_IFINDEX, link->ifindex);
×
1032
                if (r < 0)
×
1033
                        return r;
1034

1035
                r = manager_enumerate_internal(m, m->genl, req, manager_genl_process_nl80211_mlme);
×
1036
                if (r < 0)
×
1037
                        return r;
1038
        }
1039

1040
        return 0;
418✔
1041
}
1042

1043
int manager_enumerate(Manager *m) {
418✔
1044
        int r;
418✔
1045

1046
        log_debug("Enumerating...");
418✔
1047

1048
        r = manager_enumerate_links(m);
418✔
1049
        if (r < 0)
418✔
1050
                return log_error_errno(r, "Could not enumerate links: %m");
×
1051

1052
        /* If the kernel is built without CONFIG_NET_SCHED, the below will fail with -EOPNOTSUPP. */
1053
        r = manager_enumerate_qdisc(m);
418✔
1054
        if (r == -EOPNOTSUPP)
418✔
1055
                log_debug_errno(r, "Could not enumerate QDiscs, ignoring: %m");
×
1056
        else if (r < 0)
418✔
1057
                return log_error_errno(r, "Could not enumerate QDisc: %m");
×
1058

1059
        /* If the kernel is built without CONFIG_NET_CLS, the below will fail with -EOPNOTSUPP. */
1060
        r = manager_enumerate_tclass(m);
418✔
1061
        if (r == -EOPNOTSUPP)
418✔
1062
                log_debug_errno(r, "Could not enumerate TClasses, ignoring: %m");
×
1063
        else if (r < 0)
418✔
1064
                return log_error_errno(r, "Could not enumerate TClass: %m");
×
1065

1066
        r = manager_enumerate_addresses(m);
418✔
1067
        if (r < 0)
418✔
1068
                return log_error_errno(r, "Could not enumerate addresses: %m");
×
1069

1070
        r = manager_enumerate_neighbors(m);
418✔
1071
        if (r < 0)
418✔
1072
                return log_error_errno(r, "Could not enumerate neighbors: %m");
×
1073

1074
        r = manager_enumerate_nexthop(m);
418✔
1075
        if (r < 0)
418✔
1076
                return log_error_errno(r, "Could not enumerate nexthops: %m");
×
1077

1078
        r = manager_enumerate_routes(m);
418✔
1079
        if (r < 0)
418✔
1080
                return log_error_errno(r, "Could not enumerate routes: %m");
×
1081

1082
        /* If the kernel is built without CONFIG_FIB_RULES, the below will fail with -EOPNOTSUPP. */
1083
        r = manager_enumerate_rules(m);
418✔
1084
        if (r == -EOPNOTSUPP)
418✔
1085
                log_debug_errno(r, "Could not enumerate routing policy rules, ignoring: %m");
×
1086
        else if (r < 0)
418✔
1087
                return log_error_errno(r, "Could not enumerate routing policy rules: %m");
×
1088

1089
        /* If the kernel is built without CONFIG_WIRELESS, the below will fail with -EOPNOTSUPP. */
1090
        r = manager_enumerate_nl80211_wiphy(m);
418✔
1091
        if (r == -EOPNOTSUPP)
418✔
1092
                log_debug_errno(r, "Could not enumerate wireless LAN phy, ignoring: %m");
57✔
1093
        else if (r < 0)
361✔
1094
                return log_error_errno(r, "Could not enumerate wireless LAN phy: %m");
×
1095

1096
        r = manager_enumerate_nl80211_config(m);
418✔
1097
        if (r == -EOPNOTSUPP)
418✔
1098
                log_debug_errno(r, "Could not enumerate wireless LAN interfaces, ignoring: %m");
57✔
1099
        else if (r < 0)
361✔
1100
                return log_error_errno(r, "Could not enumerate wireless LAN interfaces: %m");
×
1101

1102
        r = manager_enumerate_nl80211_mlme(m);
418✔
1103
        if (r == -EOPNOTSUPP)
418✔
1104
                log_debug_errno(r, "Could not enumerate wireless LAN stations, ignoring: %m");
×
1105
        else if (r < 0)
418✔
1106
                return log_error_errno(r, "Could not enumerate wireless LAN stations: %m");
×
1107

1108
        log_debug("Enumeration completed.");
418✔
1109
        return 0;
1110
}
1111

1112
static int set_hostname_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
102✔
1113
        const sd_bus_error *e;
102✔
1114
        int r;
102✔
1115

1116
        assert(m);
102✔
1117

1118
        e = sd_bus_message_get_error(m);
102✔
1119
        if (e) {
102✔
1120
                r = sd_bus_error_get_errno(e);
×
1121
                log_warning_errno(r, "Could not set hostname: %s", bus_error_message(e, r));
×
1122
        }
1123

1124
        return 1;
102✔
1125
}
1126

1127
int manager_set_hostname(Manager *m, const char *hostname) {
103✔
1128
        int r;
103✔
1129

1130
        log_debug("Setting transient hostname: '%s'", strna(hostname));
206✔
1131

1132
        r = free_and_strdup_warn(&m->dynamic_hostname, hostname);
103✔
1133
        if (r < 0)
103✔
1134
                return r;
1135

1136
        if (sd_bus_is_ready(m->bus) <= 0) {
103✔
1137
                log_debug("Not connected to system bus, setting system hostname later.");
×
1138
                return 0;
×
1139
        }
1140

1141
        r = bus_call_method_async(
103✔
1142
                        m->bus,
1143
                        NULL,
1144
                        bus_hostname,
1145
                        "SetHostname",
1146
                        set_hostname_handler,
1147
                        m,
1148
                        "sb",
1149
                        hostname,
1150
                        false);
1151
        if (r < 0)
103✔
1152
                return log_error_errno(r, "Could not set transient hostname: %m");
×
1153

1154
        return 0;
1155
}
1156

1157
static int set_timezone_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
×
1158
        const sd_bus_error *e;
×
1159
        int r;
×
1160

1161
        assert(m);
×
1162

1163
        e = sd_bus_message_get_error(m);
×
1164
        if (e) {
×
1165
                r = sd_bus_error_get_errno(e);
×
1166
                log_warning_errno(r, "Could not set timezone: %s", bus_error_message(e, r));
×
1167
        }
1168

1169
        return 1;
×
1170
}
1171

1172
int manager_set_timezone(Manager *m, const char *tz) {
1✔
1173
        int r;
1✔
1174

1175
        assert(m);
1✔
1176
        assert(tz);
1✔
1177

1178
        log_debug("Setting system timezone: '%s'", tz);
1✔
1179
        r = free_and_strdup_warn(&m->dynamic_timezone, tz);
1✔
1180
        if (r < 0)
1✔
1181
                return r;
1182

1183
        if (sd_bus_is_ready(m->bus) <= 0) {
1✔
1184
                log_debug("Not connected to system bus, setting system timezone later.");
×
1185
                return 0;
×
1186
        }
1187

1188
        r = bus_call_method_async(
1✔
1189
                        m->bus,
1190
                        NULL,
1191
                        bus_timedate,
1192
                        "SetTimezone",
1193
                        set_timezone_handler,
1194
                        m,
1195
                        "sb",
1196
                        tz,
1197
                        false);
1198
        if (r < 0)
1✔
1199
                return log_error_errno(r, "Could not set timezone: %m");
×
1200

1201
        return 0;
1202
}
1203

1204
int manager_reload(Manager *m, sd_bus_message *message) {
136✔
1205
        Link *link;
136✔
1206
        int r;
136✔
1207

1208
        assert(m);
136✔
1209

1210
        log_debug("Reloading...");
136✔
1211
        (void) notify_reloading();
136✔
1212

1213
        r = netdev_reload(m);
136✔
1214
        if (r < 0) {
136✔
1215
                log_debug_errno(r, "Failed to reload .netdev files: %m");
×
1216
                goto finish;
×
1217
        }
1218

1219
        r = network_reload(m);
136✔
1220
        if (r < 0) {
136✔
1221
                log_debug_errno(r, "Failed to reload .network files: %m");
×
1222
                goto finish;
×
1223
        }
1224

1225
        HASHMAP_FOREACH(link, m->links_by_index)
1,190✔
1226
                (void) link_reconfigure_full(link, /* flags = */ 0, message,
1,054✔
1227
                                             /* counter = */ message ? &m->reloading : NULL);
1228

1229
        log_debug("Reloaded.");
136✔
1230
        r = 0;
1231
finish:
136✔
1232
        (void) sd_notify(/* unset_environment= */ false, NOTIFY_READY_MESSAGE);
136✔
1233
        return r;
136✔
1234
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc