Skip to content

Commit 3d027d4

Browse files
author
Julia Kartseva
committed
shared, bpf: add bpf link serialization
core: serialize socket_bind bpf links
1 parent 8dd210a commit 3d027d4

File tree

7 files changed

+99
-1
lines changed

7 files changed

+99
-1
lines changed

src/core/socket-bind.c

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,25 @@ int socket_bind_supported(void) {
132132
return can_link_bpf_program(obj->progs.sd_bind4);
133133
}
134134

135-
int socket_bind_install(Unit *u) {
135+
int socket_bind_add_initial_link_fd(Unit *u, int fd) {
136+
int r;
137+
138+
assert(u);
139+
140+
if (!u->initial_socket_bind_link_fds) {
141+
u->initial_socket_bind_link_fds = fdset_new();
142+
if (!u->initial_socket_bind_link_fds)
143+
return log_oom();
144+
}
145+
146+
r = fdset_put(u->initial_socket_bind_link_fds, fd);
147+
if (r < 0)
148+
return log_unit_error_errno(u, r, "Failed to put socket-bind BPF link fd %d to initial fdset", fd);
149+
150+
return 0;
151+
}
152+
153+
static int socket_bind_install_impl(Unit *u) {
136154
_cleanup_(bpf_link_freep) struct bpf_link *ipv4 = NULL, *ipv6 = NULL;
137155
_cleanup_(socket_bind_bpf_freep) struct socket_bind_bpf *obj = NULL;
138156
_cleanup_free_ char *cgroup_path = NULL;
@@ -177,14 +195,44 @@ int socket_bind_install(Unit *u) {
177195

178196
return 0;
179197
}
198+
199+
int socket_bind_install(Unit *u) {
200+
int r = socket_bind_install_impl(u);
201+
if (r == -ENOMEM)
202+
return r;
203+
204+
fdset_close(u->initial_socket_bind_link_fds);
205+
206+
return r;
207+
}
208+
209+
int serialize_socket_bind(Unit *u, FILE *f, FDSet *fds) {
210+
int r;
211+
212+
assert(u);
213+
214+
r = serialize_bpf_link(f, fds, "ipv4-socket-bind-bpf-link", u->ipv4_socket_bind_link);
215+
if (r < 0)
216+
return r;
217+
218+
return serialize_bpf_link(f, fds, "ipv6-socket-bind-bpf-link", u->ipv6_socket_bind_link);
219+
}
220+
180221
#else /* ! BPF_FRAMEWORK */
181222
int socket_bind_supported(void) {
182223
return 0;
183224
}
184225

226+
int socket_bind_add_initial_link_fd(Unit *u, int fd) {
227+
return 0;
228+
}
229+
185230
int socket_bind_install(Unit *u) {
186231
log_unit_debug(u, "Failed to install socket bind: BPF framework is not supported");
187232
return 0;
188233
}
189234

235+
int serialize_socket_bind(Unit *u, FILE *f, FDSet *fds) {
236+
return 0;
237+
}
190238
#endif

src/core/socket-bind.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
/* SPDX-License-Identifier: LGPL-2.1+ */
22
#pragma once
33

4+
#include "fdset.h"
45
#include "unit.h"
56

67
int socket_bind_supported(void);
78

9+
/* Add BPF link fd created before daemon-reload or daemon-reexec.
10+
* FDs will be closed at the end of socket_bind_install. */
11+
int socket_bind_add_initial_link_fd(Unit *u, int fd);
12+
813
int socket_bind_install(Unit *u);
14+
15+
int serialize_socket_bind(Unit *u, FILE *f, FDSet *fds);

src/core/unit-serialize.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "format-util.h"
88
#include "parse-util.h"
99
#include "serialize.h"
10+
#include "socket-bind.h"
1011
#include "string-table.h"
1112
#include "unit-serialize.h"
1213
#include "user-util.h"
@@ -151,6 +152,8 @@ int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) {
151152
(void) serialize_cgroup_mask(f, "cgroup-enabled-mask", u->cgroup_enabled_mask);
152153
(void) serialize_cgroup_mask(f, "cgroup-invalidated-mask", u->cgroup_invalidated_mask);
153154

155+
(void) serialize_socket_bind(u, f, fds);
156+
154157
if (uid_is_valid(u->ref_uid))
155158
(void) serialize_item_format(f, "ref-uid", UID_FMT, u->ref_uid);
156159
if (gid_is_valid(u->ref_gid))
@@ -362,6 +365,23 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
362365
else if (MATCH_DESERIALIZE_IMMEDIATE("cgroup-invalidated-mask", l, v, cg_mask_from_string, u->cgroup_invalidated_mask))
363366
continue;
364367

368+
else if (STR_IN_SET(l, "ipv4-socket-bind-bpf-link-fd", "ipv6-socket-bind-bpf-link-fd")) {
369+
int fd;
370+
371+
if (safe_atoi(v, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
372+
log_unit_debug(u, "Failed to parse %s value: %s, ignoring.", l, v);
373+
else {
374+
if (fdset_remove(fds, fd) < 0) {
375+
log_unit_debug(u, "Failed to remove %s value=%d from fdset", l, fd);
376+
377+
continue;
378+
}
379+
380+
(void) socket_bind_add_initial_link_fd(u, fd);
381+
}
382+
continue;
383+
}
384+
365385
else if (streq(l, "ref-uid")) {
366386
uid_t uid;
367387

src/core/unit.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,8 @@ Unit* unit_free(Unit *u) {
667667
if (u->on_console)
668668
manager_unref_console(u->manager);
669669

670+
671+
fdset_free(u->initial_socket_bind_link_fds);
670672
#if BPF_FRAMEWORK
671673
bpf_link_free(u->ipv4_socket_bind_link);
672674
bpf_link_free(u->ipv6_socket_bind_link);

src/core/unit.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,7 @@ typedef struct Unit {
309309
* attached to unit cgroup by provided program fd and attach type. */
310310
Hashmap *bpf_foreign_by_key;
311311

312+
FDSet *initial_socket_bind_link_fds;
312313
#if BPF_FRAMEWORK
313314
/* BPF links to BPF programs attached to cgroup/bind{4|6} hooks and
314315
* responsible for allowing or denying a unit to bind(2) to a socket

src/shared/bpf-link.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/* SPDX-License-Identifier: LGPL-2.1+ */
22

33
#include "bpf-link.h"
4+
#include "serialize.h"
45

56
bool can_link_bpf_program(struct bpf_program *prog) {
67
_cleanup_(bpf_link_freep) struct bpf_link *link = NULL;
@@ -14,6 +15,21 @@ bool can_link_bpf_program(struct bpf_program *prog) {
1415
return libbpf_get_error(link) == -EBADF;
1516
}
1617

18+
int serialize_bpf_link(FILE *f, FDSet *fds, const char *key, struct bpf_link *link) {
19+
int fd;
20+
21+
assert(key);
22+
23+
if (!link)
24+
return -ENOENT;
25+
26+
if (libbpf_get_error(link) != 0)
27+
return -EINVAL;
28+
29+
fd = bpf_link__fd(link);
30+
return serialize_fd(f, fds, key, fd);
31+
}
32+
1733
struct bpf_link *bpf_link_free(struct bpf_link *link) {
1834
/* bpf_link__destroy handles link == NULL case */
1935
(void) bpf_link__destroy(link);

src/shared/bpf-link.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,14 @@
33
#pragma once
44

55
#include <bpf/libbpf.h>
6+
#include <stdio.h>
67

8+
#include "fdset.h"
79
#include "macro.h"
810

911
bool can_link_bpf_program(struct bpf_program *prog);
1012

13+
int serialize_bpf_link(FILE *f, FDSet *fds, const char *key, struct bpf_link *link);
14+
1115
struct bpf_link *bpf_link_free(struct bpf_link *p);
1216
DEFINE_TRIVIAL_CLEANUP_FUNC(struct bpf_link *, bpf_link_free);

0 commit comments

Comments
 (0)