summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/socket-bind.c50
-rw-r--r--src/core/socket-bind.h7
-rw-r--r--src/core/unit-serialize.c20
-rw-r--r--src/core/unit.c2
-rw-r--r--src/core/unit.h1
-rw-r--r--src/shared/bpf-link.c16
-rw-r--r--src/shared/bpf-link.h4
7 files changed, 99 insertions, 1 deletions
diff --git a/src/core/socket-bind.c b/src/core/socket-bind.c
index f03bed5888..ed6c36c11f 100644
--- a/src/core/socket-bind.c
+++ b/src/core/socket-bind.c
@@ -132,7 +132,25 @@ int socket_bind_supported(void) {
return can_link_bpf_program(obj->progs.sd_bind4);
}
-int socket_bind_install(Unit *u) {
+int socket_bind_add_initial_link_fd(Unit *u, int fd) {
+ int r;
+
+ assert(u);
+
+ if (!u->initial_socket_bind_link_fds) {
+ u->initial_socket_bind_link_fds = fdset_new();
+ if (!u->initial_socket_bind_link_fds)
+ return log_oom();
+ }
+
+ r = fdset_put(u->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 0;
+}
+
+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;
@@ -177,14 +195,44 @@ int socket_bind_install(Unit *u) {
return 0;
}
+
+int socket_bind_install(Unit *u) {
+ int r = socket_bind_install_impl(u);
+ if (r == -ENOMEM)
+ return r;
+
+ fdset_close(u->initial_socket_bind_link_fds);
+
+ return r;
+}
+
+int serialize_socket_bind(Unit *u, FILE *f, FDSet *fds) {
+ int r;
+
+ assert(u);
+
+ r = serialize_bpf_link(f, fds, "ipv4-socket-bind-bpf-link", u->ipv4_socket_bind_link);
+ if (r < 0)
+ return r;
+
+ return serialize_bpf_link(f, fds, "ipv6-socket-bind-bpf-link", u->ipv6_socket_bind_link);
+}
+
#else /* ! BPF_FRAMEWORK */
int socket_bind_supported(void) {
return 0;
}
+int socket_bind_add_initial_link_fd(Unit *u, int fd) {
+ return 0;
+}
+
int socket_bind_install(Unit *u) {
log_unit_debug(u, "Failed to install socket bind: BPF framework is not supported");
return 0;
}
+int serialize_socket_bind(Unit *u, FILE *f, FDSet *fds) {
+ return 0;
+}
#endif
diff --git a/src/core/socket-bind.h b/src/core/socket-bind.h
index 58b73579ac..2a6e71a9b9 100644
--- a/src/core/socket-bind.h
+++ b/src/core/socket-bind.h
@@ -1,8 +1,15 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
+#include "fdset.h"
#include "unit.h"
int socket_bind_supported(void);
+/* Add BPF link fd created before daemon-reload or daemon-reexec.
+ * FDs will be closed at the end of socket_bind_install. */
+int socket_bind_add_initial_link_fd(Unit *u, int fd);
+
int socket_bind_install(Unit *u);
+
+int serialize_socket_bind(Unit *u, FILE *f, FDSet *fds);
diff --git a/src/core/unit-serialize.c b/src/core/unit-serialize.c
index 3f099248ce..509210ad5e 100644
--- a/src/core/unit-serialize.c
+++ b/src/core/unit-serialize.c
@@ -7,6 +7,7 @@
#include "format-util.h"
#include "parse-util.h"
#include "serialize.h"
+#include "socket-bind.h"
#include "string-table.h"
#include "unit-serialize.h"
#include "user-util.h"
@@ -151,6 +152,8 @@ int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) {
(void) serialize_cgroup_mask(f, "cgroup-enabled-mask", u->cgroup_enabled_mask);
(void) serialize_cgroup_mask(f, "cgroup-invalidated-mask", u->cgroup_invalidated_mask);
+ (void) serialize_socket_bind(u, f, fds);
+
if (uid_is_valid(u->ref_uid))
(void) serialize_item_format(f, "ref-uid", UID_FMT, u->ref_uid);
if (gid_is_valid(u->ref_gid))
@@ -362,6 +365,23 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
else if (MATCH_DESERIALIZE_IMMEDIATE("cgroup-invalidated-mask", l, v, cg_mask_from_string, u->cgroup_invalidated_mask))
continue;
+ else if (STR_IN_SET(l, "ipv4-socket-bind-bpf-link-fd", "ipv6-socket-bind-bpf-link-fd")) {
+ int fd;
+
+ if (safe_atoi(v, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
+ log_unit_debug(u, "Failed to parse %s value: %s, ignoring.", l, v);
+ else {
+ if (fdset_remove(fds, fd) < 0) {
+ log_unit_debug(u, "Failed to remove %s value=%d from fdset", l, fd);
+
+ continue;
+ }
+
+ (void) socket_bind_add_initial_link_fd(u, fd);
+ }
+ continue;
+ }
+
else if (streq(l, "ref-uid")) {
uid_t uid;
diff --git a/src/core/unit.c b/src/core/unit.c
index e8c0631429..6ef90eea0e 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -667,6 +667,8 @@ Unit* unit_free(Unit *u) {
if (u->on_console)
manager_unref_console(u->manager);
+
+ fdset_free(u->initial_socket_bind_link_fds);
#if BPF_FRAMEWORK
bpf_link_free(u->ipv4_socket_bind_link);
bpf_link_free(u->ipv6_socket_bind_link);
diff --git a/src/core/unit.h b/src/core/unit.h
index a124376b78..5bc1237ce0 100644
--- a/src/core/unit.h
+++ b/src/core/unit.h
@@ -309,6 +309,7 @@ typedef struct Unit {
* attached to unit cgroup by provided program fd and attach type. */
Hashmap *bpf_foreign_by_key;
+ FDSet *initial_socket_bind_link_fds;
#if BPF_FRAMEWORK
/* BPF links to BPF programs attached to cgroup/bind{4|6} hooks and
* responsible for allowing or denying a unit to bind(2) to a socket
diff --git a/src/shared/bpf-link.c b/src/shared/bpf-link.c
index 94d1a8c7ac..f718cb7d2d 100644
--- a/src/shared/bpf-link.c
+++ b/src/shared/bpf-link.c
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#include "bpf-link.h"
+#include "serialize.h"
bool can_link_bpf_program(struct bpf_program *prog) {
_cleanup_(bpf_link_freep) struct bpf_link *link = NULL;
@@ -14,6 +15,21 @@ bool can_link_bpf_program(struct bpf_program *prog) {
return libbpf_get_error(link) == -EBADF;
}
+int serialize_bpf_link(FILE *f, FDSet *fds, const char *key, struct bpf_link *link) {
+ int fd;
+
+ assert(key);
+
+ if (!link)
+ return -ENOENT;
+
+ if (libbpf_get_error(link) != 0)
+ return -EINVAL;
+
+ fd = bpf_link__fd(link);
+ return serialize_fd(f, fds, key, fd);
+}
+
struct bpf_link *bpf_link_free(struct bpf_link *link) {
/* bpf_link__destroy handles link == NULL case */
(void) bpf_link__destroy(link);
diff --git a/src/shared/bpf-link.h b/src/shared/bpf-link.h
index 7d529ad2cd..095465b07c 100644
--- a/src/shared/bpf-link.h
+++ b/src/shared/bpf-link.h
@@ -3,10 +3,14 @@
#pragma once
#include <bpf/libbpf.h>
+#include <stdio.h>
+#include "fdset.h"
#include "macro.h"
bool can_link_bpf_program(struct bpf_program *prog);
+int serialize_bpf_link(FILE *f, FDSet *fds, const char *key, struct bpf_link *link);
+
struct bpf_link *bpf_link_free(struct bpf_link *p);
DEFINE_TRIVIAL_CLEANUP_FUNC(struct bpf_link *, bpf_link_free);