diff --git a/src/core/bpf-firewall.c b/src/core/bpf-firewall.c index 32eb8700e3..7b9aeb6fbf 100644 --- a/src/core/bpf-firewall.c +++ b/src/core/bpf-firewall.c @@ -23,6 +23,7 @@ #include "memory-util.h" #include "missing_syscall.h" #include "unit.h" +#include "virt.h" enum { MAP_KEY_PACKETS, @@ -643,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), @@ -667,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; } @@ -675,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; } @@ -685,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; } @@ -693,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; } @@ -725,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; } @@ -769,10 +781,13 @@ void emit_bpf_firewall_warning(Unit *u) { static bool warned = false; if (!warned) { - log_unit_warning(u, "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"); + 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; } }