]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
bpf: set BPF_F_ALLOW_OVERRIDE when attaching a cgroup program if Delegate=yes is set
authorLennart Poettering <lennart@poettering.net>
Thu, 21 Sep 2017 18:38:07 +0000 (20:38 +0200)
committerLennart Poettering <lennart@poettering.net>
Fri, 22 Sep 2017 13:28:05 +0000 (15:28 +0200)
Let's permit installing BPF programs in cgroup subtrees if
Delegeate=yes. Let's not document this precise behaviour for now though,
as most likely the logic here should become recursive, but that's only
going to happen if the kernel starts supporting that. Until then,
support this in a non-recursive fashion.

src/basic/bpf-program.c
src/basic/bpf-program.h
src/core/bpf-firewall.c

index 9326176743f0d5cc4f36b1767f9fc20aaf01e739..ce6f9e440985eb92a60a82beb8b962cdb69ca73d 100644 (file)
@@ -91,7 +91,7 @@ int bpf_program_load_kernel(BPFProgram *p, char *log_buf, size_t log_size) {
         return 0;
 }
 
-int bpf_program_cgroup_attach(BPFProgram *p, int type, const char *path) {
+int bpf_program_cgroup_attach(BPFProgram *p, int type, const char *path, uint32_t flags) {
         _cleanup_close_ int fd = -1;
         union bpf_attr attr;
 
@@ -107,6 +107,7 @@ int bpf_program_cgroup_attach(BPFProgram *p, int type, const char *path) {
                 .attach_type = type,
                 .target_fd = fd,
                 .attach_bpf_fd = p->kernel_fd,
+                .attach_flags = flags,
         };
 
         if (bpf(BPF_PROG_ATTACH, &attr, sizeof(attr)) < 0)
index 0dd150b60a0629dd595a7d6e7065182fa74554bc..35a41ffc4468e4cb02f283db1db2c07e8ffd10da 100644 (file)
@@ -45,7 +45,7 @@ BPFProgram *bpf_program_unref(BPFProgram *p);
 int bpf_program_add_instructions(BPFProgram *p, const struct bpf_insn *insn, size_t count);
 int bpf_program_load_kernel(BPFProgram *p, char *log_buf, size_t log_size);
 
-int bpf_program_cgroup_attach(BPFProgram *p, int type, const char *path);
+int bpf_program_cgroup_attach(BPFProgram *p, int type, const char *path, uint32_t flags);
 int bpf_program_cgroup_detach(int type, const char *path);
 
 int bpf_map_new(enum bpf_map_type type, size_t key_size, size_t value_size, size_t max_entries, uint32_t flags);
index 732c36fc1a8bc3963d811f41cf0af37178c8f997..909c1c8253f43e7a980101e85c5574bc72ad3347 100644 (file)
@@ -539,10 +539,18 @@ int bpf_firewall_compile(Unit *u) {
 
 int bpf_firewall_install(Unit *u) {
         _cleanup_free_ char *path = NULL;
+        CGroupContext *cc;
         int r;
 
         assert(u);
 
+        if (!u->cgroup_path)
+                return -EINVAL;
+
+        cc = unit_get_cgroup_context(u);
+        if (!cc)
+                return -EINVAL;
+
         r = bpf_firewall_supported();
         if (r < 0)
                 return r;
@@ -560,7 +568,7 @@ int bpf_firewall_install(Unit *u) {
                 if (r < 0)
                         return log_error_errno(r, "Kernel upload of egress BPF program failed: %m");
 
-                r = bpf_program_cgroup_attach(u->ip_bpf_egress, BPF_CGROUP_INET_EGRESS, path);
+                r = bpf_program_cgroup_attach(u->ip_bpf_egress, BPF_CGROUP_INET_EGRESS, path, cc->delegate ? BPF_F_ALLOW_OVERRIDE : 0);
                 if (r < 0)
                         return log_error_errno(r, "Attaching egress BPF program to cgroup %s failed: %m", path);
         } else {
@@ -575,7 +583,7 @@ int bpf_firewall_install(Unit *u) {
                 if (r < 0)
                         return log_error_errno(r, "Kernel upload of ingress BPF program failed: %m");
 
-                r = bpf_program_cgroup_attach(u->ip_bpf_ingress, BPF_CGROUP_INET_INGRESS, path);
+                r = bpf_program_cgroup_attach(u->ip_bpf_ingress, BPF_CGROUP_INET_INGRESS, path, cc->delegate ? BPF_F_ALLOW_OVERRIDE : 0);
                 if (r < 0)
                         return log_error_errno(r, "Attaching ingress BPF program to cgroup %s failed: %m", path);
         } else {