]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
bpf: name unnamed bpf programs
authorJulia Kartseva <hex@fb.com>
Sat, 22 Jan 2022 02:50:26 +0000 (18:50 -0800)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Sat, 22 Jan 2022 07:48:42 +0000 (16:48 +0900)
bpf-firewall and bpf-devices do not have names. This complicates
debugging with bpftool(8).

Assign names starting with 'sd_' prefix:
* firewall program names are 'sd_fw_ingress' for ingress attach
point and 'sd_fw_egress' for egress.
* 'sd_devices' for devices prog

'sd_' prefix is already used in source-compiled programs, e.g.
sd_restrictif_i, sd_restrictif_e, sd_bind6.

The name must not be longer than 15 characters or BPF_OBJ_NAME_LEN - 1.

Assign names only to programs loaded to kernel by systemd since
programs pinned to bpffs are already loaded.

src/core/bpf-devices.c
src/core/bpf-firewall.c
src/shared/bpf-program.c
src/shared/bpf-program.h
src/test/test-bpf-firewall.c
src/test/test-bpf-foreign-programs.c

index 4d86e8665f9061ca9c74969fb554dee2329cea85..e3100b862b7bd8a035d1be055e70f429fd04fc23 100644 (file)
@@ -192,7 +192,7 @@ int bpf_devices_cgroup_init(
         if (policy == CGROUP_DEVICE_POLICY_AUTO && !allow_list)
                 return 0;
 
-        r = bpf_program_new(BPF_PROG_TYPE_CGROUP_DEVICE, &prog);
+        r = bpf_program_new(BPF_PROG_TYPE_CGROUP_DEVICE, "sd_devices", &prog);
         if (r < 0)
                 return log_error_errno(r, "Loading device control BPF program failed: %m");
 
@@ -306,7 +306,7 @@ int bpf_devices_supported(void) {
                 return supported = 0;
         }
 
-        r = bpf_program_new(BPF_PROG_TYPE_CGROUP_DEVICE, &program);
+        r = bpf_program_new(BPF_PROG_TYPE_CGROUP_DEVICE, NULL, &program);
         if (r < 0) {
                 log_debug_errno(r, "Can't allocate CGROUP DEVICE BPF program, BPF device control is not supported: %m");
                 return supported = 0;
index 3c1c02e4449649cd48afdcbb858b87112edd7d96..8158fafc8ec038ff6e5ab2327c7928e8c7b32bb3 100644 (file)
@@ -193,6 +193,7 @@ static int bpf_firewall_compile_bpf(
         };
 
         _cleanup_(bpf_program_freep) BPFProgram *p = NULL;
+        const char *prog_name = is_ingress ? "sd_fw_ingress" : "sd_fw_egress";
         int accounting_map_fd, r;
         bool access_enabled;
 
@@ -216,7 +217,7 @@ static int bpf_firewall_compile_bpf(
                 return 0;
         }
 
-        r = bpf_program_new(BPF_PROG_TYPE_CGROUP_SKB, &p);
+        r = bpf_program_new(BPF_PROG_TYPE_CGROUP_SKB, prog_name, &p);
         if (r < 0)
                 return r;
 
@@ -604,7 +605,7 @@ static int load_bpf_progs_from_fs_to_set(Unit *u, char **filter_paths, Set **set
                 _cleanup_(bpf_program_freep) BPFProgram *prog = NULL;
                 int r;
 
-                r = bpf_program_new(BPF_PROG_TYPE_CGROUP_SKB, &prog);
+                r = bpf_program_new(BPF_PROG_TYPE_CGROUP_SKB, NULL, &prog);
                 if (r < 0)
                         return log_unit_error_errno(u, r, "Can't allocate CGROUP SKB BPF program: %m");
 
@@ -825,7 +826,7 @@ int bpf_firewall_supported(void) {
                 return supported = BPF_FIREWALL_UNSUPPORTED;
         }
 
-        r = bpf_program_new(BPF_PROG_TYPE_CGROUP_SKB, &program);
+        r = bpf_program_new(BPF_PROG_TYPE_CGROUP_SKB, NULL, &program);
         if (r < 0) {
                 bpf_firewall_unsupported_reason =
                         log_debug_errno(r, "Can't allocate CGROUP SKB BPF program, BPF firewalling is not supported: %m");
index b8ca32a1f01d830cc53c32362a70fe3770a5b4b4..31fa4448b03e1bf6b76adce41c29be119ea92a3a 100644 (file)
@@ -55,6 +55,7 @@ BPFProgram *bpf_program_free(BPFProgram *p) {
         (void) bpf_program_cgroup_detach(p);
 
         safe_close(p->kernel_fd);
+        free(p->prog_name);
         free(p->instructions);
         free(p->attached_path);
 
@@ -78,8 +79,18 @@ static int bpf_program_get_info_by_fd(int prog_fd, struct bpf_prog_info *info, u
         return RET_NERRNO(bpf(BPF_OBJ_GET_INFO_BY_FD, &attr, sizeof(attr)));
 }
 
-int bpf_program_new(uint32_t prog_type, BPFProgram **ret) {
+int bpf_program_new(uint32_t prog_type, const char *prog_name, BPFProgram **ret) {
         _cleanup_(bpf_program_freep) BPFProgram *p = NULL;
+        _cleanup_free_ char *name = NULL;
+
+        if (prog_name) {
+                if (strlen(prog_name) >= BPF_OBJ_NAME_LEN)
+                        return -ENAMETOOLONG;
+
+                name = strdup(prog_name);
+                if (!name)
+                        return -ENOMEM;
+        }
 
         p = new(BPFProgram, 1);
         if (!p)
@@ -88,6 +99,7 @@ int bpf_program_new(uint32_t prog_type, BPFProgram **ret) {
         *p = (BPFProgram) {
                 .prog_type = prog_type,
                 .kernel_fd = -1,
+                .prog_name = TAKE_PTR(name),
         };
 
         *ret = TAKE_PTR(p);
@@ -165,6 +177,8 @@ int bpf_program_load_kernel(BPFProgram *p, char *log_buf, size_t log_size) {
         attr.log_buf = PTR_TO_UINT64(log_buf);
         attr.log_level = !!log_buf;
         attr.log_size = log_size;
+        if (p->prog_name)
+                strncpy(attr.prog_name, p->prog_name, BPF_OBJ_NAME_LEN - 1);
 
         p->kernel_fd = bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
         if (p->kernel_fd < 0)
index e54900fa2fe8bf3228254cf4479b42e2c4f8a937..b640fb9d9f655fa5c9f3c30aa179a3461604f773 100644 (file)
@@ -20,6 +20,7 @@ struct BPFProgram {
         /* The loaded BPF program, if loaded */
         int kernel_fd;
         uint32_t prog_type;
+        char *prog_name;
 
         /* The code of it BPF program, if known */
         size_t n_instructions;
@@ -32,7 +33,7 @@ struct BPFProgram {
         uint32_t attached_flags;
 };
 
-int bpf_program_new(uint32_t prog_type, BPFProgram **ret);
+int bpf_program_new(uint32_t prog_type, const char *prog_name, BPFProgram **ret);
 int bpf_program_new_from_bpffs_path(const char *path, BPFProgram **ret);
 BPFProgram *bpf_program_free(BPFProgram *p);
 
index 2e19db600e1bfdc79c1f3b4bb4fa37e9347aef6b..cbcb525f52de37ecfa723083ddc20e6770defa20 100644 (file)
@@ -55,7 +55,7 @@ int main(int argc, char *argv[]) {
         assert_se(set_unit_path(unit_dir) >= 0);
         assert_se(runtime_dir = setup_fake_runtime_dir());
 
-        r = bpf_program_new(BPF_PROG_TYPE_CGROUP_SKB, &p);
+        r = bpf_program_new(BPF_PROG_TYPE_CGROUP_SKB, "sd_trivial", &p);
         assert_se(r == 0);
 
         r = bpf_program_add_instructions(p, exit_insn, ELEMENTSOF(exit_insn));
index 8c3f76e9ec8bfa31e4fae8bc6746ecbdb8bda760..d73f487ff65dca1225331061715f379b11a62a80 100644 (file)
@@ -162,7 +162,7 @@ static int pin_programs(Unit *u, CGroupContext *cc, const Test *test_suite, size
                 if (r < 0)
                         return log_error_errno(r, "Failed to convert program to string");
 
-                r = bpf_program_new(test_suite[i].prog_type, &prog);
+                r = bpf_program_new(test_suite[i].prog_type, "sd_trivial", &prog);
                 if (r < 0)
                         return log_error_errno(r, "Failed to create program '%s'", str);