1
0
mirror of https://github.com/systemd/systemd.git synced 2025-03-25 18:50:18 +03:00

network: drop old kernel support (#36402)

This commit is contained in:
Luca Boccassi 2025-02-18 22:39:36 +00:00 committed by GitHub
commit 7b0403bef9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 26 additions and 70 deletions

6
README
View File

@ -39,10 +39,12 @@ REQUIREMENTS:
≥ 4.11 for nsfs NS_GET_NSTYPE
≥ 4.13 for TIOCGPTPEER
≥ 4.15 for cgroup-bpf device hook and cpu controller in cgroup v2
≥ 4.17 for cgroup-bpf socket address hooks and /sys/power/resume_offset
≥ 4.17 for cgroup-bpf socket address hooks, /sys/power/resume_offset,
and FRA_PROTOCOL attribute for fib rules
≥ 4.20 for PSI (used by systemd-oomd)
≥ 5.2 for cgroup freezer and new mount API
≥ 5.3 for bounded loops in BPF program and keyring namespacing
≥ 5.3 for bounded loops in BPF program, keyring namespacing,
and nexthop support
≥ 5.4 for pidfd and signed Verity images
⛔ Kernel versions below 5.4 ("minimum baseline") are not supported at all,

View File

@ -1148,7 +1148,6 @@ static void address_forget(Link *link, Address *address, bool removed_by_us, con
}
static int address_set_netlink_message(const Address *address, sd_netlink_message *m, Link *link) {
uint32_t flags;
int r;
assert(address);
@ -1163,12 +1162,8 @@ static int address_set_netlink_message(const Address *address, sd_netlink_messag
* flags except tentative flag here unconditionally. Without setting the flag, the template
* addresses generated by kernel will not be removed automatically when the main address is
* removed. */
flags = address->flags & ~IFA_F_TENTATIVE;
r = sd_rtnl_message_addr_set_flags(m, flags & 0xff);
if (r < 0)
return r;
if ((flags & ~0xff) != 0) {
uint32_t flags = address->flags & ~IFA_F_TENTATIVE;
if (flags != 0) {
r = sd_netlink_message_append_u32(m, IFA_FLAGS, flags);
if (r < 0)
return r;
@ -1339,12 +1334,12 @@ int link_drop_ipv6ll_addresses(Link *link) {
for (sd_netlink_message *addr = reply; addr; addr = sd_netlink_message_next(addr)) {
_cleanup_(address_unrefp) Address *a = NULL;
unsigned char flags, prefixlen;
unsigned char prefixlen;
struct in6_addr address;
int ifindex;
/* NETLINK_GET_STRICT_CHK socket option is supported since kernel 4.20. To support
* older kernels, we need to check ifindex here. */
/* We set ifindex in the request, and NETLINK_GET_STRICT_CHK socket option is set. Hence the
* check below is redundant, but let's do that for safety. */
r = sd_rtnl_message_addr_get_ifindex(addr, &ifindex);
if (r < 0) {
log_link_debug_errno(link, r, "rtnl: received address message without valid ifindex, ignoring: %m");
@ -1352,9 +1347,10 @@ int link_drop_ipv6ll_addresses(Link *link) {
} else if (link->ifindex != ifindex)
continue;
r = sd_rtnl_message_addr_get_flags(addr, &flags);
uint32_t flags;
r = sd_netlink_message_read_u32(addr, IFA_FLAGS, &flags);
if (r < 0) {
log_link_debug_errno(link, r, "rtnl: received address message without valid flags, ignoring: %m");
log_link_debug_errno(link, r, "rtnl: Failed to read IFA_FLAGS attribute, ignoring: %m");
continue;
}
@ -1971,14 +1967,7 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message,
}
r = sd_netlink_message_read_u32(message, IFA_FLAGS, &address->flags);
if (r == -ENODATA) {
unsigned char flags;
/* For old kernels. */
r = sd_rtnl_message_addr_get_flags(message, &flags);
if (r >= 0)
address->flags = flags;
} else if (r < 0)
if (r < 0)
log_link_debug_errno(link, r, "rtnl: failed to read IFA_FLAGS attribute, ignoring: %m");
struct ifa_cacheinfo cinfo;

View File

@ -90,13 +90,7 @@ static int bridge_mdb_configure_handler(sd_netlink *rtnl, sd_netlink_message *m,
assert(link);
r = sd_netlink_message_get_errno(m);
if (r == -EINVAL && streq_ptr(link->kind, "bridge") && link->master_ifindex <= 0) {
/* To configure bridge MDB entries on bridge master, 1bc844ee0faa1b92e3ede00bdd948021c78d7088 (v5.4) is required. */
if (!link->manager->bridge_mdb_on_master_not_supported) {
log_link_warning_errno(link, r, "Kernel seems not to support bridge MDB entries on bridge master, ignoring: %m");
link->manager->bridge_mdb_on_master_not_supported = true;
}
} else if (r < 0 && r != -EEXIST) {
if (r < 0 && r != -EEXIST) {
log_link_message_warning_errno(link, m, r, "Could not add MDB entry");
link_enter_failed(link);
return 1;

View File

@ -2321,7 +2321,7 @@ static int link_update_permanent_hardware_address(Link *link, sd_netlink_message
if (r != -ENODATA)
return log_link_debug_errno(link, r, "Failed to read IFLA_PERM_ADDRESS attribute: %m");
/* Fallback to ethtool for older kernels. */
/* Fallback to ethtool for kernels older than v5.6 (f74877a5457d34d604dba6dbbb13c4c05bac8b93). */
r = link_update_permanent_hardware_address_from_ethtool(link, message);
if (r < 0)
return r;

View File

@ -277,6 +277,7 @@ static int manager_connect_genl(Manager *m) {
if (r < 0)
return r;
/* If the kernel is built without CONFIG_WIRELESS, the belows will fail with -EOPNOTSUPP. */
r = genl_add_match(m->genl, NULL, NL80211_GENL_NAME, NL80211_MULTICAST_GROUP_CONFIG, 0,
&manager_genl_process_nl80211_config, NULL, m, "network-genl_process_nl80211_config");
if (r < 0 && r != -EOPNOTSUPP)
@ -1049,12 +1050,14 @@ int manager_enumerate(Manager *m) {
if (r < 0)
return log_error_errno(r, "Could not enumerate links: %m");
/* If the kernel is built without CONFIG_NET_SCHED, the below will fail with -EOPNOTSUPP. */
r = manager_enumerate_qdisc(m);
if (r == -EOPNOTSUPP)
log_debug_errno(r, "Could not enumerate QDiscs, ignoring: %m");
else if (r < 0)
return log_error_errno(r, "Could not enumerate QDisc: %m");
/* If the kernel is built without CONFIG_NET_CLS, the below will fail with -EOPNOTSUPP. */
r = manager_enumerate_tclass(m);
if (r == -EOPNOTSUPP)
log_debug_errno(r, "Could not enumerate TClasses, ignoring: %m");
@ -1069,25 +1072,22 @@ int manager_enumerate(Manager *m) {
if (r < 0)
return log_error_errno(r, "Could not enumerate neighbors: %m");
/* NextHop support is added in kernel v5.3 (65ee00a9409f751188a8cdc0988167858eb4a536),
* and older kernels return -EOPNOTSUPP, or -EINVAL if SELinux is enabled. */
r = manager_enumerate_nexthop(m);
if (r == -EOPNOTSUPP || (r == -EINVAL && mac_selinux_enforcing()))
log_debug_errno(r, "Could not enumerate nexthops, ignoring: %m");
else if (r < 0)
if (r < 0)
return log_error_errno(r, "Could not enumerate nexthops: %m");
r = manager_enumerate_routes(m);
if (r < 0)
return log_error_errno(r, "Could not enumerate routes: %m");
/* If kernel is built with CONFIG_FIB_RULES=n, it returns -EOPNOTSUPP. */
/* If the kernel is built without CONFIG_FIB_RULES, the below will fail with -EOPNOTSUPP. */
r = manager_enumerate_rules(m);
if (r == -EOPNOTSUPP)
log_debug_errno(r, "Could not enumerate routing policy rules, ignoring: %m");
else if (r < 0)
return log_error_errno(r, "Could not enumerate routing policy rules: %m");
/* If the kernel is built without CONFIG_WIRELESS, the belows will fail with -EOPNOTSUPP. */
r = manager_enumerate_nl80211_wiphy(m);
if (r == -EOPNOTSUPP)
log_debug_errno(r, "Could not enumerate wireless LAN phy, ignoring: %m");

View File

@ -118,8 +118,6 @@ struct Manager {
usec_t speed_meter_usec_new;
usec_t speed_meter_usec_old;
bool bridge_mdb_on_master_not_supported;
FirewallContext *fw_ctx;
bool request_queued;

View File

@ -1050,26 +1050,6 @@ int link_request_static_routing_policy_rules(Link *link) {
return 0;
}
static const RoutingPolicyRule kernel_rules[] = {
{ .family = AF_INET, .priority_set = true, .priority = 0, .table = RT_TABLE_LOCAL, .action = FR_ACT_TO_TBL, .uid_range.start = UID_INVALID, .uid_range.end = UID_INVALID, .suppress_prefixlen = -1, .suppress_ifgroup = -1, },
{ .family = AF_INET, .priority_set = true, .priority = 1000, .table = RT_TABLE_UNSPEC, .action = FR_ACT_TO_TBL, .uid_range.start = UID_INVALID, .uid_range.end = UID_INVALID, .suppress_prefixlen = -1, .suppress_ifgroup = -1, .l3mdev = true },
{ .family = AF_INET, .priority_set = true, .priority = 32766, .table = RT_TABLE_MAIN, .action = FR_ACT_TO_TBL, .uid_range.start = UID_INVALID, .uid_range.end = UID_INVALID, .suppress_prefixlen = -1, .suppress_ifgroup = -1, },
{ .family = AF_INET, .priority_set = true, .priority = 32767, .table = RT_TABLE_DEFAULT, .action = FR_ACT_TO_TBL, .uid_range.start = UID_INVALID, .uid_range.end = UID_INVALID, .suppress_prefixlen = -1, .suppress_ifgroup = -1, },
{ .family = AF_INET6, .priority_set = true, .priority = 0, .table = RT_TABLE_LOCAL, .action = FR_ACT_TO_TBL, .uid_range.start = UID_INVALID, .uid_range.end = UID_INVALID, .suppress_prefixlen = -1, .suppress_ifgroup = -1, },
{ .family = AF_INET6, .priority_set = true, .priority = 1000, .table = RT_TABLE_UNSPEC, .action = FR_ACT_TO_TBL, .uid_range.start = UID_INVALID, .uid_range.end = UID_INVALID, .suppress_prefixlen = -1, .suppress_ifgroup = -1, .l3mdev = true },
{ .family = AF_INET6, .priority_set = true, .priority = 32766, .table = RT_TABLE_MAIN, .action = FR_ACT_TO_TBL, .uid_range.start = UID_INVALID, .uid_range.end = UID_INVALID, .suppress_prefixlen = -1, .suppress_ifgroup = -1, },
};
static bool routing_policy_rule_is_created_by_kernel(const RoutingPolicyRule *rule) {
assert(rule);
FOREACH_ELEMENT(i, kernel_rules)
if (routing_policy_rule_equal(rule, i, i->family, i->priority))
return true;
return false;
}
int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) {
int r;
@ -1249,16 +1229,10 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, Man
return 0;
}
/* If FRA_PROTOCOL is supported by kernel, then the attribute is always appended. If the received
* message does not have FRA_PROTOCOL, then we need to adjust the protocol of the rule. That requires
* all properties compared in the routing_policy_rule_compare_func(), hence it must be done after
* reading them. */
/* The kernel always sets the FRA_PROTOCOL attribute, and it is necessary for comparing rules.
* Hence, -ENODATA here is critical. */
r = sd_netlink_message_read_u8(message, FRA_PROTOCOL, &tmp->protocol);
if (r == -ENODATA)
/* As .network files does not have setting to specify protocol, we can assume the
* protocol of the received rule is RTPROT_KERNEL or RTPROT_STATIC. */
tmp->protocol = routing_policy_rule_is_created_by_kernel(tmp) ? RTPROT_KERNEL : RTPROT_STATIC;
else if (r < 0) {
if (r < 0) {
log_warning_errno(r, "rtnl: could not get FRA_PROTOCOL attribute, ignoring: %m");
return 0;
}

View File

@ -70,9 +70,8 @@ static int run(int argc, char *argv[]) {
return log_error_errno(r, "Failed to drop privileges: %m");
}
/* Always create the directories people can create inotify watches in.
* It is necessary to create the following subdirectories after drop_privileges()
* to support old kernels not supporting AmbientCapabilities=. */
/* Always create the directories people can create inotify watches in. It is necessary to create the
* following subdirectories after drop_privileges() to make them owned by systemd-network. */
FOREACH_STRING(p,
"/run/systemd/netif/links/",
"/run/systemd/netif/leases/") {