diff options
Diffstat (limited to 'src/test/test-bpf.c')
-rw-r--r-- | src/test/test-bpf.c | 53 |
1 files changed, 50 insertions, 3 deletions
diff --git a/src/test/test-bpf.c b/src/test/test-bpf.c index 90ab15c549..6a75221542 100644 --- a/src/test/test-bpf.c +++ b/src/test/test-bpf.c @@ -9,6 +9,7 @@ #include "bpf-program.h" #include "load-fragment.h" #include "manager.h" +#include "missing.h" #include "rm-rf.h" #include "service.h" #include "test-helper.h" @@ -42,7 +43,7 @@ static bool can_memlock(void) { int main(int argc, char *argv[]) { struct bpf_insn exit_insn[] = { - BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_MOV64_IMM(BPF_REG_0, 0), /* drop */ BPF_EXIT_INSN() }; @@ -54,6 +55,9 @@ int main(int argc, char *argv[]) { char log_buf[65535]; struct rlimit rl; int r; + union bpf_attr attr; + bool test_custom_filter = false; + const char *test_prog = "/sys/fs/bpf/test-dropper"; test_setup_logging(LOG_DEBUG); @@ -88,14 +92,31 @@ int main(int argc, char *argv[]) { return log_tests_skipped("BPF firewalling not supported"); assert_se(r > 0); - if (r == BPF_FIREWALL_SUPPORTED_WITH_MULTI) + if (r == BPF_FIREWALL_SUPPORTED_WITH_MULTI) { log_notice("BPF firewalling with BPF_F_ALLOW_MULTI supported. Yay!"); - else + test_custom_filter = true; + } else log_notice("BPF firewalling (though without BPF_F_ALLOW_MULTI) supported. Good."); r = bpf_program_load_kernel(p, log_buf, ELEMENTSOF(log_buf)); assert(r >= 0); + if (test_custom_filter) { + attr = (union bpf_attr) { + .pathname = PTR_TO_UINT64(test_prog), + .bpf_fd = p->kernel_fd, + .file_flags = 0, + }; + + (void) unlink(test_prog); + + r = bpf(BPF_OBJ_PIN, &attr, sizeof(attr)); + if (r < 0) { + log_warning_errno(errno, "BPF object pinning failed, will not run custom filter test: %m"); + test_custom_filter = false; + } + } + p = bpf_program_unref(p); /* The simple tests succeeded. Now let's try full unit-based use-case. */ @@ -175,5 +196,31 @@ int main(int argc, char *argv[]) { assert_se(SERVICE(u)->exec_command[SERVICE_EXEC_START]->command_next->exec_status.code != CLD_EXITED || SERVICE(u)->exec_command[SERVICE_EXEC_START]->command_next->exec_status.status != EXIT_SUCCESS); + if (test_custom_filter) { + assert_se(u = unit_new(m, sizeof(Service))); + assert_se(unit_add_name(u, "custom-filter.service") == 0); + assert_se(cc = unit_get_cgroup_context(u)); + u->perpetual = true; + + cc->ip_accounting = true; + + assert_se(config_parse_ip_filter_bpf_progs(u->id, "filename", 1, "Service", 1, "IPIngressFilterPath", 0, test_prog, &cc->ip_filters_ingress, u) == 0); + assert_se(config_parse_exec(u->id, "filename", 1, "Service", 1, "ExecStart", SERVICE_EXEC_START, "-/bin/ping -c 1 127.0.0.1 -W 5", SERVICE(u)->exec_command, u) == 0); + + SERVICE(u)->type = SERVICE_ONESHOT; + u->load_state = UNIT_LOADED; + + assert_se(unit_start(u) >= 0); + + while (!IN_SET(SERVICE(u)->state, SERVICE_DEAD, SERVICE_FAILED)) + assert_se(sd_event_run(m->event, UINT64_MAX) >= 0); + + assert_se(SERVICE(u)->exec_command[SERVICE_EXEC_START]->exec_status.code != CLD_EXITED || + SERVICE(u)->exec_command[SERVICE_EXEC_START]->exec_status.status != EXIT_SUCCESS); + + (void) unlink(test_prog); + assert_se(SERVICE(u)->state == SERVICE_DEAD); + } + return 0; } |