#include "memory-util.h"
#include "missing_syscall.h"
#include "unit.h"
+#include "virt.h"
enum {
MAP_KEY_PACKETS,
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),
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;
}
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;
}
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;
}
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;
}
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;
}
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;
}
}