summaryrefslogtreecommitdiffstats
path: root/src/test/test-bpf.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/test-bpf.c')
-rw-r--r--src/test/test-bpf.c53
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;
}