return (supported = bpf_can_link_program(obj->progs.sd_bind_interface));
}
-int bpf_bind_network_interface_install(Unit *u) {
+static int bind_network_interface_install_impl(Unit *u, CGroupRuntime *crt) {
_cleanup_(bpf_link_freep) struct bpf_link *link = NULL;
_cleanup_(bind_iface_bpf_freep) struct bind_iface_bpf *obj = NULL;
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
_cleanup_free_ char *cgroup_path = NULL;
_cleanup_close_ int cgroup_fd = -EBADF;
- CGroupContext *cc;
- CGroupRuntime *crt;
int r, ifindex;
assert(u);
+ assert(crt);
- cc = unit_get_cgroup_context(u);
- if (!cc)
- return 0;
-
- crt = unit_get_cgroup_runtime(u);
- if (!crt)
- return 0;
+ CGroupContext *cc = ASSERT_PTR(unit_get_cgroup_context(u));
if (isempty(cc->bind_network_interface))
return 0;
return 0;
}
+int bpf_bind_network_interface_install(Unit *u) {
+ CGroupRuntime *crt;
+ int r;
+
+ assert(u);
+
+ crt = unit_get_cgroup_runtime(u);
+ if (!crt)
+ return 0;
+
+ r = bind_network_interface_install_impl(u, crt);
+ crt->initial_bind_network_interface_link_fd = safe_close(crt->initial_bind_network_interface_link_fd);
+ return r;
+}
+
int bpf_bind_network_interface_serialize(Unit *u, FILE *f, FDSet *fds) {
CGroupRuntime *crt;
if (!crt)
return 0;
- return bpf_serialize_link(f, fds, "bind-interface-fd", crt->bpf_bind_network_interface_link);
+ return bpf_serialize_link(f, fds, "bind-iface-bpf-fd", crt->bpf_bind_network_interface_link);
}
#else /* ! BPF_FRAMEWORK */
.ipv4_deny_map_fd = -EBADF,
.ipv6_deny_map_fd = -EBADF,
+ .initial_bind_network_interface_link_fd = -EBADF,
+
.cgroup_invalidated_mask = _CGROUP_MASK_ALL,
.deserialized_cgroup_realized = -1,
#endif
fdset_free(crt->initial_restrict_ifaces_link_fds);
+ safe_close(crt->initial_bind_network_interface_link_fd);
bpf_firewall_close(crt);
return 1;
}
+ if (streq(key, "bind-iface-bpf-fd")) {
+ _cleanup_close_ int fd = -EBADF;
+
+ fd = deserialize_fd(fds, value);
+ if (fd >= 0) {
+ CGroupRuntime *crt = unit_setup_cgroup_runtime(u);
+ if (!crt)
+ log_oom_debug();
+ else
+ close_and_replace(crt->initial_bind_network_interface_link_fd, fd);
+ }
+
+ return 1;
+ }
+
CGroupMemoryAccountingMetric mm = memory_accounting_metric_field_last_from_string(key);
if (mm >= 0) {
uint64_t c;
struct bpf_link *restrict_ifaces_egress_bpf_link;
#endif
+#if BPF_FRAMEWORK
+ /* BPF link to BPF programs attached to cgroup/sock_create hooks and
+ * responsible for binding created sockets to a given VRF interface. */
+ struct bpf_link *bpf_bind_network_interface_link;
+#endif
+ int initial_bind_network_interface_link_fd;
+
bool cgroup_members_mask_valid:1;
/* Reset cgroup accounting next time we fork something off */
bool warned_clamping_cpu_quota_period:1;
int deserialized_cgroup_realized; /* tristate, for backwards compat */
-
-#if BPF_FRAMEWORK
- /* BPF link to BPF programs attached to cgroup/sock_create hooks and
- * responsible for binding created sockets to a given VRF interface. */
- struct bpf_link *bpf_bind_network_interface_link;
-#endif
} CGroupRuntime;
uint64_t cgroup_context_cpu_weight(CGroupContext *c, ManagerState state);