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

systemd / systemd / 13210122091

07 Feb 2025 10:56PM UTC coverage: 71.748% (-0.07%) from 71.813%
13210122091

push

github

web-flow
network: allow to configure routing policy rule even if requesting interface is not activated yet (#36257)

Fixes a regression caused by 4f8b153d9
(v257).
Fixes #36244.

16 of 16 new or added lines in 2 files covered. (100.0%)

3079 existing lines in 54 files now uncovered.

292917 of 408258 relevant lines covered (71.75%)

714241.77 hits per line

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

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

3
#include <netinet/in.h>
4
#include <sys/socket.h>
5
#include <unistd.h>
6
#include <linux/if.h>
7
#include <linux/fib_rules.h>
8
#include <linux/nexthop.h>
9
#include <linux/nl80211.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-label.h"
38
#include "networkd-address-pool.h"
39
#include "networkd-address.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 "tmpfile-util.h"
68
#include "tuntap.h"
69
#include "udev-util.h"
70

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

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

79
        assert(message);
×
80

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

87
        if (b)
×
88
                return 0;
89

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

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

95
        return 0;
×
96
}
97

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

101
        assert(message);
413✔
102

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

111
        return 0;
413✔
112
}
113

114
static int manager_connect_bus(Manager *m) {
413✔
115
        int r;
413✔
116

117
        assert(m);
413✔
118
        assert(!m->bus);
413✔
119

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

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

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

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

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

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

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

160
        return 0;
161
}
162

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

168
        assert(device);
1,735✔
169

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

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

184
        return 0;
185
}
186

187
static int manager_connect_udev(Manager *m) {
413✔
188
        int r;
413✔
189

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

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

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

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

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

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

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

219
        return 0;
220
}
221

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

226
        assert(m);
414✔
227
        assert(ret_rtnl_fd);
414✔
228

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

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

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

242
                        rtnl_fd = fd;
413✔
243
                        continue;
413✔
244
                }
245

246
                if (manager_set_serialization_fd(m, fd, names[i]) >= 0)
34✔
247
                        continue;
25✔
248

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

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

259
        *ret_rtnl_fd = rtnl_fd;
414✔
260
        return 0;
414✔
261
}
262

263
static int manager_connect_genl(Manager *m) {
414✔
264
        int r;
414✔
265

266
        assert(m);
414✔
267

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

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

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

280
        r = genl_add_match(m->genl, NULL, NL80211_GENL_NAME, NL80211_MULTICAST_GROUP_CONFIG, 0,
414✔
281
                           &manager_genl_process_nl80211_config, NULL, m, "network-genl_process_nl80211_config");
282
        if (r < 0 && r != -EOPNOTSUPP)
414✔
283
                return r;
284

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

290
        return 0;
291
}
292

293
static int manager_setup_rtnl_filter(Manager *manager) {
414✔
294
        struct sock_filter filter[] = {
414✔
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 ? */
414✔
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 ? */
414✔
306
                BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, htobe16(RTM_DELNEIGH), 1, 0),           /* message type == RTM_DELNEIGH ? */
414✔
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 ? */
414✔
317
                BPF_STMT(BPF_RET + BPF_K, 0),                                               /* reject */
318
                BPF_STMT(BPF_RET + BPF_K, UINT32_MAX),                                      /* accept */
319
        };
320

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

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

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

331
        assert(m);
414✔
332

333
        /* This takes input fd. */
334

335
        if (fd < 0)
414✔
336
                r = sd_netlink_open(&m->rtnl);
1✔
337
        else
338
                r = sd_netlink_open_fd(&m->rtnl, fd);
413✔
339
        if (r < 0)
414✔
340
                return r;
341
        TAKE_FD(fd_close);
414✔
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) {
414✔
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);
414✔
353
        if (r < 0)
414✔
354
                return r;
355

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

423
static int manager_post_handler(sd_event_source *s, void *userdata) {
55,515✔
424
        Manager *manager = ASSERT_PTR(userdata);
55,515✔
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);
55,515✔
429

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

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

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

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

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

454
        return 0;
455
}
456

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

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

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

477
        manager->state = state;
413✔
478

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

483
        return 0;
413✔
484
}
485

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

490
static int signal_restart_callback(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
29✔
491
        return manager_stop(userdata, MANAGER_RESTARTING);
29✔
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) {
413✔
503
        int r;
413✔
504

505
        assert(m);
413✔
506

507
        if (in_initrd()) {
413✔
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("/");
413✔
514
        if (r < 0) {
413✔
515
                log_warning_errno(r, "Failed to detect if root is network filesystem, assuming not: %m");
×
516
                return 0;
×
517
        }
518
        if (r == 0) {
413✔
519
                m->keep_configuration = _KEEP_CONFIGURATION_INVALID;
413✔
520
                return 0;
413✔
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) {
414✔
529
        _cleanup_close_ int rtnl_fd = -EBADF;
414✔
530
        int r;
414✔
531

532
        assert(m);
414✔
533

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

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

545
        r = sd_event_add_memory_pressure(m->event, NULL, NULL, NULL);
414✔
546
        if (r < 0)
414✔
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);
414✔
550
        if (r < 0)
414✔
551
                return r;
552

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

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

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

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

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

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

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

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

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

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

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

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

600
        return 0;
601
}
602

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

607
        r = getenv_bool("SYSTEMD_NETWORK_PERSISTENT_STORAGE_READY");
437✔
608
        if (r < 0 && r != -ENXIO)
437✔
609
                return log_debug_errno(r, "Failed to parse $SYSTEMD_NETWORK_PERSISTENT_STORAGE_READY environment variable, ignoring: %m");
×
610
        if (r <= 0)
437✔
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) {
437✔
627
        _cleanup_(manager_freep) Manager *m = NULL;
437✔
628

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

633
        *m = (Manager) {
874✔
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(),
437✔
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);
437✔
660
        return 0;
437✔
661
}
662

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

667
        manager_remove_sysctl_monitor(m);
437✔
668

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

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

674
        m->dirty_links = set_free_with_destructor(m->dirty_links, link_unref);
439✔
675
        m->new_wlan_ifindices = set_free(m->new_wlan_ifindices);
437✔
676
        m->links_by_name = hashmap_free(m->links_by_name);
437✔
677
        m->links_by_hw_addr = hashmap_free(m->links_by_hw_addr);
437✔
678
        m->links_by_dhcp_pd_subnet_prefix = hashmap_free(m->links_by_dhcp_pd_subnet_prefix);
437✔
679
        m->links_by_index = hashmap_free_with_destructor(m->links_by_index, link_unref);
2,212✔
680

681
        m->dhcp_pd_subnet_ids = set_free(m->dhcp_pd_subnet_ids);
437✔
682
        m->networks = ordered_hashmap_free_with_destructor(m->networks, network_unref);
4,408✔
683

684
        /* The same object may be registered with multiple names, and netdev_detach() may drop multiple
685
         * entries. Hence, hashmap_free_with_destructor() cannot be used. */
686
        for (NetDev *n; (n = hashmap_first(m->netdevs)); )
554✔
687
                netdev_detach(n);
117✔
688
        m->netdevs = hashmap_free(m->netdevs);
437✔
689

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

692
        m->wiphy_by_name = hashmap_free(m->wiphy_by_name);
437✔
693
        m->wiphy_by_index = hashmap_free_with_destructor(m->wiphy_by_index, wiphy_free);
437✔
694

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

739
        assert(m);
413✔
740

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

743
        (void) manager_install_sysctl_monitor(m);
413✔
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);
413✔
748
        if (r < 0)
413✔
749
                log_warning_errno(r, "Failed to drop CAP_SYS_ADMIN, ignoring: %m.");
×
750

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

755
        manager_set_sysctl(m);
413✔
756

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

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

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

769
                r = link_check_initialized(link);
1,706✔
770
                if (r < 0) {
1,706✔
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);
413✔
780
        if (r < 0)
413✔
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,532✔
784
                r = link_save_and_clean(link);
1,706✔
785
                if (r < 0)
1,706✔
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.");
413✔
790
        return 0;
791
}
792

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

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

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

802
        manager_clear_unmanaged_tuntap_fds(m);
414✔
803

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

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

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

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

820
int manager_enumerate_internal(
5,839✔
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,839✔
827
        int r;
5,839✔
828

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

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

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

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

847
        return r;
5,839✔
848
}
849

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

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

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

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

865
        req = sd_netlink_message_unref(req);
414✔
866

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

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

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

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

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

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

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

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

896
        assert(m);
414✔
897
        assert(m->rtnl);
414✔
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,121✔
902
                RET_GATHER(r, link_enumerate_tclass(link, 0));
1,707✔
903

904
        return r;
414✔
905
}
906

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1024
                if (link->wlan_iftype != NL80211_IFTYPE_STATION)
1,707✔
1025
                        continue;
1,707✔
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;
414✔
1041
}
1042

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

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

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

1052
        r = manager_enumerate_qdisc(m);
414✔
1053
        if (r == -EOPNOTSUPP)
414✔
1054
                log_debug_errno(r, "Could not enumerate QDiscs, ignoring: %m");
×
1055
        else if (r < 0)
414✔
1056
                return log_error_errno(r, "Could not enumerate QDisc: %m");
×
1057

1058
        r = manager_enumerate_tclass(m);
414✔
1059
        if (r == -EOPNOTSUPP)
414✔
1060
                log_debug_errno(r, "Could not enumerate TClasses, ignoring: %m");
×
1061
        else if (r < 0)
414✔
1062
                return log_error_errno(r, "Could not enumerate TClass: %m");
×
1063

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

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

1072
        /* NextHop support is added in kernel v5.3 (65ee00a9409f751188a8cdc0988167858eb4a536),
1073
         * and older kernels return -EOPNOTSUPP, or -EINVAL if SELinux is enabled. */
1074
        r = manager_enumerate_nexthop(m);
414✔
1075
        if (r == -EOPNOTSUPP || (r == -EINVAL && mac_selinux_enforcing()))
414✔
1076
                log_debug_errno(r, "Could not enumerate nexthops, ignoring: %m");
×
1077
        else if (r < 0)
414✔
1078
                return log_error_errno(r, "Could not enumerate nexthops: %m");
×
1079

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

1084
        /* If kernel is built with CONFIG_FIB_RULES=n, it returns -EOPNOTSUPP. */
1085
        r = manager_enumerate_rules(m);
414✔
1086
        if (r == -EOPNOTSUPP)
414✔
1087
                log_debug_errno(r, "Could not enumerate routing policy rules, ignoring: %m");
×
1088
        else if (r < 0)
414✔
1089
                return log_error_errno(r, "Could not enumerate routing policy rules: %m");
×
1090

1091
        r = manager_enumerate_nl80211_wiphy(m);
414✔
1092
        if (r == -EOPNOTSUPP)
414✔
1093
                log_debug_errno(r, "Could not enumerate wireless LAN phy, ignoring: %m");
57✔
1094
        else if (r < 0)
357✔
1095
                return log_error_errno(r, "Could not enumerate wireless LAN phy: %m");
×
1096

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

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

1109
        log_debug("Enumeration completed.");
414✔
1110
        return 0;
1111
}
1112

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

1117
        assert(m);
100✔
1118

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

1125
        return 1;
100✔
1126
}
1127

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

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

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

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

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

1155
        return 0;
1156
}
1157

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

UNCOV
1162
        assert(m);
×
1163

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

UNCOV
1170
        return 1;
×
1171
}
1172

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

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

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

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

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

1202
        return 0;
1203
}
1204

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

1209
        assert(m);
130✔
1210

1211
        log_debug("Reloading...");
130✔
1212
        (void) notify_reloading();
130✔
1213

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

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

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

1230
        log_debug("Reloaded.");
130✔
1231
        r = 0;
1232
finish:
130✔
1233
        (void) sd_notify(/* unset= */ false, NOTIFY_READY);
130✔
1234
        return r;
130✔
1235
}
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