static void detach_program(void) { char command[64]; int ret; ret = bpf_prog_detach(0, BPF_FLOW_DISSECTOR); if (ret) error(1, 0, "bpf_prog_detach"); /* To unpin, it is necessary and sufficient to just remove this dir */ sprintf(command, "rm -r %s", cfg_pin_path); ret = system(command); if (ret) error(1, errno, command); }
int main(int argc, char **argv) { int detach_only = 0, verdict = 1; enum bpf_attach_type type; int opt, cg_fd, ret; while ((opt = getopt(argc, argv, "Dd")) != -1) { switch (opt) { case 'd': verdict = 0; break; case 'D': detach_only = 1; break; default: return usage(argv[0]); } } if (argc - optind < 2) return usage(argv[0]); if (strcmp(argv[optind + 1], "ingress") == 0) type = BPF_CGROUP_INET_INGRESS; else if (strcmp(argv[optind + 1], "egress") == 0) type = BPF_CGROUP_INET_EGRESS; else return usage(argv[0]); cg_fd = open(argv[optind], O_DIRECTORY | O_RDONLY); if (cg_fd < 0) { printf("Failed to open cgroup path: '%s'\n", strerror(errno)); return EXIT_FAILURE; } if (detach_only) { ret = bpf_prog_detach(cg_fd, type); printf("bpf_prog_detach() returned '%s' (%d)\n", strerror(errno), errno); } else ret = attach_filter(cg_fd, type, verdict); return ret; }
static int test_foo_bar(void) { int drop_prog, allow_prog, foo = 0, bar = 0, rc = 0; allow_prog = prog_load(1); if (!allow_prog) goto err; drop_prog = prog_load(0); if (!drop_prog) goto err; if (setup_cgroup_environment()) goto err; /* Create cgroup /foo, get fd, and join it */ foo = create_and_get_cgroup(FOO); if (foo < 0) goto err; if (join_cgroup(FOO)) goto err; if (bpf_prog_attach(drop_prog, foo, BPF_CGROUP_INET_EGRESS, BPF_F_ALLOW_OVERRIDE)) { log_err("Attaching prog to /foo"); goto err; } printf("Attached DROP prog. This ping in cgroup /foo should fail...\n"); assert(system(PING_CMD) != 0); /* Create cgroup /foo/bar, get fd, and join it */ bar = create_and_get_cgroup(BAR); if (bar < 0) goto err; if (join_cgroup(BAR)) goto err; printf("Attached DROP prog. This ping in cgroup /foo/bar should fail...\n"); assert(system(PING_CMD) != 0); if (bpf_prog_attach(allow_prog, bar, BPF_CGROUP_INET_EGRESS, BPF_F_ALLOW_OVERRIDE)) { log_err("Attaching prog to /foo/bar"); goto err; } printf("Attached PASS prog. This ping in cgroup /foo/bar should pass...\n"); assert(system(PING_CMD) == 0); if (bpf_prog_detach(bar, BPF_CGROUP_INET_EGRESS)) { log_err("Detaching program from /foo/bar"); goto err; } printf("Detached PASS from /foo/bar while DROP is attached to /foo.\n" "This ping in cgroup /foo/bar should fail...\n"); assert(system(PING_CMD) != 0); if (bpf_prog_attach(allow_prog, bar, BPF_CGROUP_INET_EGRESS, BPF_F_ALLOW_OVERRIDE)) { log_err("Attaching prog to /foo/bar"); goto err; } if (bpf_prog_detach(foo, BPF_CGROUP_INET_EGRESS)) { log_err("Detaching program from /foo"); goto err; } printf("Attached PASS from /foo/bar and detached DROP from /foo.\n" "This ping in cgroup /foo/bar should pass...\n"); assert(system(PING_CMD) == 0); if (bpf_prog_attach(allow_prog, bar, BPF_CGROUP_INET_EGRESS, BPF_F_ALLOW_OVERRIDE)) { log_err("Attaching prog to /foo/bar"); goto err; } if (!bpf_prog_attach(allow_prog, bar, BPF_CGROUP_INET_EGRESS, 0)) { errno = 0; log_err("Unexpected success attaching prog to /foo/bar"); goto err; } if (bpf_prog_detach(bar, BPF_CGROUP_INET_EGRESS)) { log_err("Detaching program from /foo/bar"); goto err; } if (!bpf_prog_detach(foo, BPF_CGROUP_INET_EGRESS)) { errno = 0; log_err("Unexpected success in double detach from /foo"); goto err; } if (bpf_prog_attach(allow_prog, foo, BPF_CGROUP_INET_EGRESS, 0)) { log_err("Attaching non-overridable prog to /foo"); goto err; } if (!bpf_prog_attach(allow_prog, bar, BPF_CGROUP_INET_EGRESS, 0)) { errno = 0; log_err("Unexpected success attaching non-overridable prog to /foo/bar"); goto err; } if (!bpf_prog_attach(allow_prog, bar, BPF_CGROUP_INET_EGRESS, BPF_F_ALLOW_OVERRIDE)) { errno = 0; log_err("Unexpected success attaching overridable prog to /foo/bar"); goto err; } if (!bpf_prog_attach(allow_prog, foo, BPF_CGROUP_INET_EGRESS, BPF_F_ALLOW_OVERRIDE)) { errno = 0; log_err("Unexpected success attaching overridable prog to /foo"); goto err; } if (bpf_prog_attach(drop_prog, foo, BPF_CGROUP_INET_EGRESS, 0)) { log_err("Attaching different non-overridable prog to /foo"); goto err; } goto out; err: rc = 1; out: close(foo); close(bar); cleanup_cgroup_environment(); if (!rc) printf("### override:PASS\n"); else printf("### override:FAIL\n"); return rc; }
int main(int argc, char **argv) { int logFlag = 0; int error = 0; char *cg_path; char fn[500]; char *prog; int cg_fd; if (argc < 3) usage(argv[0]); if (!strcmp(argv[1], "-r")) { cg_path = argv[2]; cg_fd = open(cg_path, O_DIRECTORY, O_RDONLY); error = bpf_prog_detach(cg_fd, BPF_CGROUP_SOCK_OPS); if (error) { printf("ERROR: bpf_prog_detach: %d (%s)\n", error, strerror(errno)); return 2; } return 0; } else if (!strcmp(argv[1], "-h")) { usage(argv[0]); } else if (!strcmp(argv[1], "-l")) { logFlag = 1; if (argc < 4) usage(argv[0]); } prog = argv[argc - 1]; cg_path = argv[argc - 2]; if (strlen(prog) > 480) { fprintf(stderr, "ERROR: program name too long (> 480 chars)\n"); return 3; } cg_fd = open(cg_path, O_DIRECTORY, O_RDONLY); if (!strcmp(prog + strlen(prog)-2, ".o")) strcpy(fn, prog); else sprintf(fn, "%s_kern.o", prog); if (logFlag) printf("loading bpf file:%s\n", fn); if (load_bpf_file(fn)) { printf("ERROR: load_bpf_file failed for: %s\n", fn); printf("%s", bpf_log_buf); return 4; } if (logFlag) printf("TCP BPF Loaded %s\n", fn); error = bpf_prog_attach(prog_fd[0], cg_fd, BPF_CGROUP_SOCK_OPS, 0); if (error) { printf("ERROR: bpf_prog_attach: %d (%s)\n", error, strerror(errno)); return 5; } else if (logFlag) { read_trace_pipe(); } return error; }
int main(int argc, char **argv) { const char *file = "test_tcpbpf_kern.o"; int prog_fd, map_fd, sock_map_fd; struct tcpbpf_globals g = {0}; const char *cg_path = "/foo"; int error = EXIT_FAILURE; struct bpf_object *obj; int cg_fd = -1; __u32 key = 0; int rv; if (setup_cgroup_environment()) goto err; cg_fd = create_and_get_cgroup(cg_path); if (cg_fd < 0) goto err; if (join_cgroup(cg_path)) goto err; if (bpf_prog_load(file, BPF_PROG_TYPE_SOCK_OPS, &obj, &prog_fd)) { printf("FAILED: load_bpf_file failed for: %s\n", file); goto err; } rv = bpf_prog_attach(prog_fd, cg_fd, BPF_CGROUP_SOCK_OPS, 0); if (rv) { printf("FAILED: bpf_prog_attach: %d (%s)\n", error, strerror(errno)); goto err; } if (system("./tcp_server.py")) { printf("FAILED: TCP server\n"); goto err; } map_fd = bpf_find_map(__func__, obj, "global_map"); if (map_fd < 0) goto err; sock_map_fd = bpf_find_map(__func__, obj, "sockopt_results"); if (sock_map_fd < 0) goto err; rv = bpf_map_lookup_elem(map_fd, &key, &g); if (rv != 0) { printf("FAILED: bpf_map_lookup_elem returns %d\n", rv); goto err; } if (verify_result(&g)) { printf("FAILED: Wrong stats\n"); goto err; } if (verify_sockopt_result(sock_map_fd)) { printf("FAILED: Wrong sockopt stats\n"); goto err; } printf("PASSED!\n"); error = 0; err: bpf_prog_detach(cg_fd, BPF_CGROUP_SOCK_OPS); close(cg_fd); cleanup_cgroup_environment(); return error; }
int main(int argc, char **argv) { const char *file = "test_tcpnotify_kern.o"; int prog_fd, map_fd, perf_event_fd; struct tcpnotify_globals g = {0}; const char *cg_path = "/foo"; int error = EXIT_FAILURE; struct bpf_object *obj; int cg_fd = -1; __u32 key = 0; int rv; char test_script[80]; int pmu_fd; cpu_set_t cpuset; CPU_ZERO(&cpuset); CPU_SET(0, &cpuset); pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset); if (setup_cgroup_environment()) goto err; cg_fd = create_and_get_cgroup(cg_path); if (!cg_fd) goto err; if (join_cgroup(cg_path)) goto err; if (bpf_prog_load(file, BPF_PROG_TYPE_SOCK_OPS, &obj, &prog_fd)) { printf("FAILED: load_bpf_file failed for: %s\n", file); goto err; } rv = bpf_prog_attach(prog_fd, cg_fd, BPF_CGROUP_SOCK_OPS, 0); if (rv) { printf("FAILED: bpf_prog_attach: %d (%s)\n", error, strerror(errno)); goto err; } perf_event_fd = bpf_find_map(__func__, obj, "perf_event_map"); if (perf_event_fd < 0) goto err; map_fd = bpf_find_map(__func__, obj, "global_map"); if (map_fd < 0) goto err; pmu_fd = setup_bpf_perf_event(perf_event_fd); if (pmu_fd < 0 || perf_event_mmap(pmu_fd) < 0) goto err; pthread_create(&tid, NULL, poller_thread, (void *)&pmu_fd); sprintf(test_script, "/usr/sbin/iptables -A INPUT -p tcp --dport %d -j DROP", TESTPORT); system(test_script); sprintf(test_script, "/usr/bin/nc 127.0.0.1 %d < /etc/passwd > /dev/null 2>&1 ", TESTPORT); system(test_script); sprintf(test_script, "/usr/sbin/iptables -D INPUT -p tcp --dport %d -j DROP", TESTPORT); system(test_script); rv = bpf_map_lookup_elem(map_fd, &key, &g); if (rv != 0) { printf("FAILED: bpf_map_lookup_elem returns %d\n", rv); goto err; } sleep(10); if (verify_result(&g)) { printf("FAILED: Wrong stats Expected %d calls, got %d\n", g.ncalls, rx_callbacks); goto err; } printf("PASSED!\n"); error = 0; err: bpf_prog_detach(cg_fd, BPF_CGROUP_SOCK_OPS); close(cg_fd); cleanup_cgroup_environment(); return error; }