mirror of
https://github.com/systemd/systemd.git
synced 2025-03-31 14:50:15 +03:00
Merge pull request #12741 from keszybz/bpf-firewall-warning
Silence BPF firewall warning when not useful
This commit is contained in:
commit
277cb7631e
@ -23,6 +23,7 @@
|
||||
#include "memory-util.h"
|
||||
#include "missing_syscall.h"
|
||||
#include "unit.h"
|
||||
#include "virt.h"
|
||||
|
||||
enum {
|
||||
MAP_KEY_PACKETS,
|
||||
@ -484,19 +485,17 @@ int bpf_firewall_compile(Unit *u) {
|
||||
supported = bpf_firewall_supported();
|
||||
if (supported < 0)
|
||||
return supported;
|
||||
if (supported == BPF_FIREWALL_UNSUPPORTED) {
|
||||
log_unit_debug(u, "BPF firewalling not supported on this manager, proceeding without.");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
if (supported != BPF_FIREWALL_SUPPORTED_WITH_MULTI && u->type == UNIT_SLICE) {
|
||||
if (supported == BPF_FIREWALL_UNSUPPORTED)
|
||||
return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||
"BPF firewalling not supported on this manager, proceeding without.");
|
||||
if (supported != BPF_FIREWALL_SUPPORTED_WITH_MULTI && u->type == UNIT_SLICE)
|
||||
/* If BPF_F_ALLOW_MULTI is not supported we don't support any BPF magic on inner nodes (i.e. on slice
|
||||
* units), since that would mean leaf nodes couldn't do any BPF anymore at all. Under the assumption
|
||||
* that BPF is more interesting on leaf nodes we hence avoid it on inner nodes in that case. This is
|
||||
* consistent with old systemd behaviour from before v238, where BPF wasn't supported in inner nodes at
|
||||
* all, either. */
|
||||
log_unit_debug(u, "BPF_F_ALLOW_MULTI is not supported on this manager, not doing BPF firewall on slice units.");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||
"BPF_F_ALLOW_MULTI is not supported on this manager, not doing BPF firewall on slice units.");
|
||||
|
||||
/* Note that when we compile a new firewall we first flush out the access maps and the BPF programs themselves,
|
||||
* but we reuse the the accounting maps. That way the firewall in effect always maps to the actual
|
||||
@ -645,6 +644,8 @@ int bpf_firewall_reset_accounting(int map_fd) {
|
||||
return bpf_map_update_element(map_fd, &key, &value);
|
||||
}
|
||||
|
||||
static int bpf_firewall_unsupported_reason = 0;
|
||||
|
||||
int bpf_firewall_supported(void) {
|
||||
struct bpf_insn trivial[] = {
|
||||
BPF_MOV64_IMM(BPF_REG_0, 1),
|
||||
@ -669,7 +670,9 @@ int bpf_firewall_supported(void) {
|
||||
return supported;
|
||||
|
||||
if (geteuid() != 0) {
|
||||
log_debug("Not enough privileges, BPF firewalling is not supported.");
|
||||
bpf_firewall_unsupported_reason =
|
||||
log_debug_errno(SYNTHETIC_ERRNO(EACCES),
|
||||
"Not enough privileges, BPF firewalling is not supported.");
|
||||
return supported = BPF_FIREWALL_UNSUPPORTED;
|
||||
}
|
||||
|
||||
@ -677,7 +680,9 @@ int bpf_firewall_supported(void) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Can't determine whether the unified hierarchy is used: %m");
|
||||
if (r == 0) {
|
||||
log_debug("Not running with unified cgroups, BPF firewalling is not supported.");
|
||||
bpf_firewall_unsupported_reason =
|
||||
log_debug_errno(SYNTHETIC_ERRNO(EUCLEAN),
|
||||
"Not running with unified cgroups, BPF firewalling is not supported.");
|
||||
return supported = BPF_FIREWALL_UNSUPPORTED;
|
||||
}
|
||||
|
||||
@ -687,7 +692,8 @@ int bpf_firewall_supported(void) {
|
||||
1,
|
||||
BPF_F_NO_PREALLOC);
|
||||
if (fd < 0) {
|
||||
log_debug_errno(fd, "Can't allocate BPF LPM TRIE map, BPF firewalling is not supported: %m");
|
||||
bpf_firewall_unsupported_reason =
|
||||
log_debug_errno(fd, "Can't allocate BPF LPM TRIE map, BPF firewalling is not supported: %m");
|
||||
return supported = BPF_FIREWALL_UNSUPPORTED;
|
||||
}
|
||||
|
||||
@ -695,19 +701,22 @@ int bpf_firewall_supported(void) {
|
||||
|
||||
r = bpf_program_new(BPF_PROG_TYPE_CGROUP_SKB, &program);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Can't allocate CGROUP SKB BPF program, BPF firewalling is not supported: %m");
|
||||
bpf_firewall_unsupported_reason =
|
||||
log_debug_errno(r, "Can't allocate CGROUP SKB BPF program, BPF firewalling is not supported: %m");
|
||||
return supported = BPF_FIREWALL_UNSUPPORTED;
|
||||
}
|
||||
|
||||
r = bpf_program_add_instructions(program, trivial, ELEMENTSOF(trivial));
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Can't add trivial instructions to CGROUP SKB BPF program, BPF firewalling is not supported: %m");
|
||||
bpf_firewall_unsupported_reason =
|
||||
log_debug_errno(r, "Can't add trivial instructions to CGROUP SKB BPF program, BPF firewalling is not supported: %m");
|
||||
return supported = BPF_FIREWALL_UNSUPPORTED;
|
||||
}
|
||||
|
||||
r = bpf_program_load_kernel(program, NULL, 0);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Can't load kernel CGROUP SKB BPF program, BPF firewalling is not supported: %m");
|
||||
bpf_firewall_unsupported_reason =
|
||||
log_debug_errno(r, "Can't load kernel CGROUP SKB BPF program, BPF firewalling is not supported: %m");
|
||||
return supported = BPF_FIREWALL_UNSUPPORTED;
|
||||
}
|
||||
|
||||
@ -727,7 +736,8 @@ int bpf_firewall_supported(void) {
|
||||
|
||||
if (bpf(BPF_PROG_DETACH, &attr, sizeof(attr)) < 0) {
|
||||
if (errno != EBADF) {
|
||||
log_debug_errno(errno, "Didn't get EBADF from BPF_PROG_DETACH, BPF firewalling is not supported: %m");
|
||||
bpf_firewall_unsupported_reason =
|
||||
log_debug_errno(errno, "Didn't get EBADF from BPF_PROG_DETACH, BPF firewalling is not supported: %m");
|
||||
return supported = BPF_FIREWALL_UNSUPPORTED;
|
||||
}
|
||||
|
||||
@ -766,3 +776,18 @@ int bpf_firewall_supported(void) {
|
||||
return supported = BPF_FIREWALL_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
void emit_bpf_firewall_warning(Unit *u) {
|
||||
static bool warned = false;
|
||||
|
||||
if (!warned) {
|
||||
bool quiet = bpf_firewall_unsupported_reason == -EPERM && detect_container();
|
||||
|
||||
log_unit_full(u, quiet ? LOG_DEBUG : LOG_WARNING, bpf_firewall_unsupported_reason,
|
||||
"unit configures an IP firewall, but %s.\n"
|
||||
"(This warning is only shown for the first unit using IP firewalling.)",
|
||||
getuid() != 0 ? "not running as root" :
|
||||
"the local system does not support BPF/cgroup firewalling");
|
||||
warned = true;
|
||||
}
|
||||
}
|
||||
|
@ -18,3 +18,5 @@ int bpf_firewall_install(Unit *u);
|
||||
|
||||
int bpf_firewall_read_accounting(int map_fd, uint64_t *ret_bytes, uint64_t *ret_packets);
|
||||
int bpf_firewall_reset_accounting(int map_fd);
|
||||
|
||||
void emit_bpf_firewall_warning(Unit *u);
|
||||
|
@ -1540,6 +1540,10 @@ CGroupMask unit_get_target_mask(Unit *u) {
|
||||
* hierarchy that shall be enabled for it. */
|
||||
|
||||
mask = unit_get_own_mask(u) | unit_get_members_mask(u) | unit_get_siblings_mask(u);
|
||||
|
||||
if (mask & CGROUP_MASK_BPF_FIREWALL & ~u->manager->cgroup_supported)
|
||||
emit_bpf_firewall_warning(u);
|
||||
|
||||
mask &= u->manager->cgroup_supported;
|
||||
mask &= ~unit_get_ancestor_disable_mask(u);
|
||||
|
||||
|
@ -1426,21 +1426,6 @@ int bus_cgroup_set_property(
|
||||
return r;
|
||||
|
||||
unit_write_setting(u, flags, name, buf);
|
||||
|
||||
if (*list) {
|
||||
r = bpf_firewall_supported();
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == BPF_FIREWALL_UNSUPPORTED) {
|
||||
static bool warned = false;
|
||||
|
||||
log_full(warned ? LOG_DEBUG : LOG_WARNING,
|
||||
"Transient unit %s configures an IP firewall, but the local system does not support BPF/cgroup firewalling.\n"
|
||||
"Proceeding WITHOUT firewalling in effect! (This warning is only shown for the first started transient unit using IP firewalling.)", u->id);
|
||||
|
||||
warned = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
@ -134,21 +134,6 @@ int config_parse_ip_address_access(
|
||||
|
||||
*list = ip_address_access_reduce(*list);
|
||||
|
||||
if (*list) {
|
||||
r = bpf_firewall_supported();
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == BPF_FIREWALL_UNSUPPORTED) {
|
||||
static bool warned = false;
|
||||
|
||||
log_full(warned ? LOG_DEBUG : LOG_WARNING,
|
||||
"File %s:%u configures an IP firewall (%s=%s), but the local system does not support BPF/cgroup based firewalling.\n"
|
||||
"Proceeding WITHOUT firewalling in effect! (This warning is only shown for the first loaded unit using IP firewalling.)", filename, line, lvalue, rvalue);
|
||||
|
||||
warned = true;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user