X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=src%2Fcore%2Fbpf-socket-bind.c;h=465216a7d0dfd29708ffe42b5d4d1f481fa6ac15;hb=9cc545447e31ed38d71c00d5957c4dee0b5bce97;hp=9983691575579f8ed8f29b58be59362b8362ab8e;hpb=b34a4f0e6729de292cb3b0c03c1d48f246ad896b;p=thirdparty%2Fsystemd.git diff --git a/src/core/bpf-socket-bind.c b/src/core/bpf-socket-bind.c index 99836915755..465216a7d0d 100644 --- a/src/core/bpf-socket-bind.c +++ b/src/core/bpf-socket-bind.c @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: LGPL-2.1+ */ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ #if BPF_FRAMEWORK #include @@ -11,8 +11,9 @@ /* libbpf, clang, llvm and bpftool compile time dependencies are satisfied */ #include "bpf-dlopen.h" #include "bpf-link.h" -#include "bpf/socket_bind/socket-bind.skel.h" +#include "bpf-util.h" #include "bpf/socket_bind/socket-bind-api.bpf.h" +#include "bpf/socket_bind/socket-bind-skel.h" static struct socket_bind_bpf *socket_bind_bpf_free(struct socket_bind_bpf *obj) { /* socket_bind_bpf__destroy handles object == NULL case */ @@ -27,7 +28,6 @@ static int update_rules_map( int map_fd, CGroupSocketBindItem *head) { - CGroupSocketBindItem *item; uint32_t i = 0; assert(map_fd >= 0); @@ -58,7 +58,6 @@ static int prepare_socket_bind_bpf( _cleanup_(socket_bind_bpf_freep) struct socket_bind_bpf *obj = NULL; size_t allow_count = 0, deny_count = 0; int allow_map_fd, deny_map_fd, r; - CGroupSocketBindItem *item; assert(ret_obj); @@ -70,28 +69,27 @@ static int prepare_socket_bind_bpf( if (allow_count > SOCKET_BIND_MAX_RULES) return log_unit_full_errno(u, u ? LOG_ERR : LOG_WARNING, SYNTHETIC_ERRNO(EINVAL), - "Maximum number of socket bind rules=%u is exceeded", SOCKET_BIND_MAX_RULES); + "bpf-socket-bind: Maximum number of socket bind rules=%i is exceeded", SOCKET_BIND_MAX_RULES); if (deny_count > SOCKET_BIND_MAX_RULES) return log_unit_full_errno(u, u ? LOG_ERR : LOG_WARNING, SYNTHETIC_ERRNO(EINVAL), - "Maximum number of socket bind rules=%u is exceeded", SOCKET_BIND_MAX_RULES); + "bpf-socket-bind: Maximum number of socket bind rules=%i is exceeded", SOCKET_BIND_MAX_RULES); obj = socket_bind_bpf__open(); if (!obj) - return log_unit_full_errno(u, u ? LOG_ERR : LOG_DEBUG, SYNTHETIC_ERRNO(ENOMEM), - "Failed to open BPF object"); + return log_unit_full_errno(u, u ? LOG_ERR : LOG_DEBUG, errno, "bpf-socket-bind: Failed to open BPF object: %m"); - if (sym_bpf_map__resize(obj->maps.sd_bind_allow, MAX(allow_count, 1u)) != 0) + if (sym_bpf_map__set_max_entries(obj->maps.sd_bind_allow, MAX(allow_count, 1u)) != 0) return log_unit_full_errno(u, u ? LOG_ERR : LOG_WARNING, errno, - "Failed to resize BPF map '%s': %m", sym_bpf_map__name(obj->maps.sd_bind_allow)); + "bpf-socket-bind: Failed to resize BPF map '%s': %m", sym_bpf_map__name(obj->maps.sd_bind_allow)); - if (sym_bpf_map__resize(obj->maps.sd_bind_deny, MAX(deny_count, 1u)) != 0) + if (sym_bpf_map__set_max_entries(obj->maps.sd_bind_deny, MAX(deny_count, 1u)) != 0) return log_unit_full_errno(u, u ? LOG_ERR : LOG_WARNING, errno, - "Failed to resize BPF map '%s': %m", sym_bpf_map__name(obj->maps.sd_bind_deny)); + "bpf-socket-bind: Failed to resize BPF map '%s': %m", sym_bpf_map__name(obj->maps.sd_bind_deny)); if (socket_bind_bpf__load(obj) != 0) return log_unit_full_errno(u, u ? LOG_ERR : LOG_DEBUG, errno, - "Failed to load BPF object: %m"); + "bpf-socket-bind: Failed to load BPF object: %m"); allow_map_fd = sym_bpf_map__fd(obj->maps.sd_bind_allow); assert(allow_map_fd >= 0); @@ -99,7 +97,7 @@ static int prepare_socket_bind_bpf( r = update_rules_map(allow_map_fd, allow); if (r < 0) return log_unit_full_errno(u, u ? LOG_ERR : LOG_WARNING, r, - "Failed to put socket bind allow rules into BPF map '%s'", + "bpf-socket-bind: Failed to put socket bind allow rules into BPF map '%s'", sym_bpf_map__name(obj->maps.sd_bind_allow)); deny_map_fd = sym_bpf_map__fd(obj->maps.sd_bind_deny); @@ -108,7 +106,7 @@ static int prepare_socket_bind_bpf( r = update_rules_map(deny_map_fd, deny); if (r < 0) return log_unit_full_errno(u, u ? LOG_ERR : LOG_WARNING, r, - "Failed to put socket bind deny rules into BPF map '%s'", + "bpf-socket-bind: Failed to put socket bind deny rules into BPF map '%s'", sym_bpf_map__name(obj->maps.sd_bind_deny)); *ret_obj = TAKE_PTR(obj); @@ -119,25 +117,17 @@ int bpf_socket_bind_supported(void) { _cleanup_(socket_bind_bpf_freep) struct socket_bind_bpf *obj = NULL; int r; - r = cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER); - if (r < 0) - return log_debug_errno(r, "Can't determine whether the unified hierarchy is used: %m"); - if (r == 0) { - log_debug("Not running with unified cgroup hierarchy, BPF is not supported"); - return false; - } - - if (dlopen_bpf() < 0) + if (!cgroup_bpf_supported()) return false; - if (!sym_bpf_probe_prog_type(BPF_PROG_TYPE_CGROUP_SOCK_ADDR, /*ifindex=*/0)) { - log_debug("BPF program type cgroup_sock_addr is not supported"); + if (!compat_libbpf_probe_bpf_prog_type(BPF_PROG_TYPE_CGROUP_SOCK_ADDR, /*opts=*/NULL)) { + log_debug("bpf-socket-bind: BPF program type cgroup_sock_addr is not supported"); return false; } r = prepare_socket_bind_bpf(/*unit=*/NULL, /*allow_rules=*/NULL, /*deny_rules=*/NULL, &obj); if (r < 0) { - log_debug_errno(r, "BPF based socket_bind is not supported: %m"); + log_debug_errno(r, "bpf-socket-bind: socket bind filtering is not supported: %m"); return false; } @@ -149,15 +139,20 @@ int bpf_socket_bind_add_initial_link_fd(Unit *u, int fd) { assert(u); - if (!u->initial_socket_bind_link_fds) { - u->initial_socket_bind_link_fds = fdset_new(); - if (!u->initial_socket_bind_link_fds) + CGroupRuntime *crt = unit_get_cgroup_runtime(u); + if (!crt) + return log_unit_error_errno(u, SYNTHETIC_ERRNO(EINVAL), + "Failed to get control group runtime object."); + + if (!crt->initial_socket_bind_link_fds) { + crt->initial_socket_bind_link_fds = fdset_new(); + if (!crt->initial_socket_bind_link_fds) return log_oom(); } - r = fdset_put(u->initial_socket_bind_link_fds, fd); + r = fdset_put(crt->initial_socket_bind_link_fds, fd); if (r < 0) - return log_unit_error_errno(u, r, "Failed to put socket-bind BPF link fd %d to initial fdset", fd); + return log_unit_error_errno(u, r, "bpf-socket-bind: Failed to put BPF fd %d to initial fdset", fd); return 0; } @@ -166,8 +161,9 @@ static int socket_bind_install_impl(Unit *u) { _cleanup_(bpf_link_freep) struct bpf_link *ipv4 = NULL, *ipv6 = NULL; _cleanup_(socket_bind_bpf_freep) struct socket_bind_bpf *obj = NULL; _cleanup_free_ char *cgroup_path = NULL; - _cleanup_close_ int cgroup_fd = -1; + _cleanup_close_ int cgroup_fd = -EBADF; CGroupContext *cc; + CGroupRuntime *crt; int r; assert(u); @@ -176,62 +172,73 @@ static int socket_bind_install_impl(Unit *u) { if (!cc) return 0; - r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, NULL, &cgroup_path); + crt = unit_get_cgroup_runtime(u); + if (!crt) + return 0; + + r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, crt->cgroup_path, NULL, &cgroup_path); if (r < 0) - return log_unit_error_errno(u, r, "Failed to get cgroup path: %m"); + return log_unit_error_errno(u, r, "bpf-socket-bind: Failed to get cgroup path: %m"); if (!cc->socket_bind_allow && !cc->socket_bind_deny) return 0; r = prepare_socket_bind_bpf(u, cc->socket_bind_allow, cc->socket_bind_deny, &obj); if (r < 0) - return log_unit_error_errno(u, r, "Failed to load BPF object: %m"); + return log_unit_error_errno(u, r, "bpf-socket-bind: Failed to load BPF object: %m"); cgroup_fd = open(cgroup_path, O_RDONLY | O_CLOEXEC, 0); if (cgroup_fd < 0) - return log_unit_error_errno(u, errno, "Failed to open cgroup=%s for reading: %m", cgroup_path); + return log_unit_error_errno(u, errno, "bpf-socket-bind: Failed to open cgroup %s for reading: %m", cgroup_path); ipv4 = sym_bpf_program__attach_cgroup(obj->progs.sd_bind4, cgroup_fd); r = sym_libbpf_get_error(ipv4); if (r != 0) - return log_unit_error_errno(u, r, "Failed to link '%s' cgroup-bpf program: %m", + return log_unit_error_errno(u, r, "bpf-socket-bind: Failed to link '%s' cgroup-bpf program: %m", sym_bpf_program__name(obj->progs.sd_bind4)); ipv6 = sym_bpf_program__attach_cgroup(obj->progs.sd_bind6, cgroup_fd); r = sym_libbpf_get_error(ipv6); if (r != 0) - return log_unit_error_errno(u, r, "Failed to link '%s' cgroup-bpf program: %m", + return log_unit_error_errno(u, r, "bpf-socket-bind: Failed to link '%s' cgroup-bpf program: %m", sym_bpf_program__name(obj->progs.sd_bind6)); - u->ipv4_socket_bind_link = TAKE_PTR(ipv4); - u->ipv6_socket_bind_link = TAKE_PTR(ipv6); + crt->ipv4_socket_bind_link = TAKE_PTR(ipv4); + crt->ipv6_socket_bind_link = TAKE_PTR(ipv6); return 0; } int bpf_socket_bind_install(Unit *u) { + CGroupRuntime *crt; int r; assert(u); - r = socket_bind_install_impl(u); - if (r == -ENOMEM) - return r; + crt = unit_get_cgroup_runtime(u); + if (!crt) + return 0; - fdset_close(u->initial_socket_bind_link_fds); + r = socket_bind_install_impl(u); + fdset_close(crt->initial_socket_bind_link_fds); return r; } -int bpf_serialize_socket_bind(Unit *u, FILE *f, FDSet *fds) { +int bpf_socket_bind_serialize(Unit *u, FILE *f, FDSet *fds) { + CGroupRuntime *crt; int r; assert(u); - r = bpf_serialize_link(f, fds, "ipv4-socket-bind-bpf-link", u->ipv4_socket_bind_link); + crt = unit_get_cgroup_runtime(u); + if (!crt) + return 0; + + r = bpf_serialize_link(f, fds, "ipv4-socket-bind-bpf-link", crt->ipv4_socket_bind_link); if (r < 0) return r; - return bpf_serialize_link(f, fds, "ipv6-socket-bind-bpf-link", u->ipv6_socket_bind_link); + return bpf_serialize_link(f, fds, "ipv6-socket-bind-bpf-link", crt->ipv6_socket_bind_link); } #else /* ! BPF_FRAMEWORK */ @@ -244,10 +251,11 @@ int bpf_socket_bind_add_initial_link_fd(Unit *u, int fd) { } int bpf_socket_bind_install(Unit *u) { - return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EOPNOTSUPP), "Failed to install socket bind: BPF framework is not supported"); + return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EOPNOTSUPP), + "bpf-socket-bind: Failed to install; BPF framework is not supported"); } -int bpf_serialize_socket_bind(Unit *u, FILE *f, FDSet *fds) { +int bpf_socket_bind_serialize(Unit *u, FILE *f, FDSet *fds) { return 0; } #endif