From c2cc02d2036076a01cf0d8d69d40829cb2e7fb6c Mon Sep 17 00:00:00 2001 From: tongzongzhen Date: Mon, 2 Sep 2024 17:28:37 +0800 Subject: fix tc dettach error --- dummy_ebpf_2/include/tc_prog_user.h | 2 +- dummy_ebpf_2/send.py | 2 +- dummy_ebpf_2/src/main.c | 2 +- dummy_ebpf_2/src/tc_prog_kernel.c | 2 +- dummy_ebpf_2/src/tc_prog_user.c | 70 ++++++++++++++++++++++++++----------- 5 files changed, 54 insertions(+), 24 deletions(-) diff --git a/dummy_ebpf_2/include/tc_prog_user.h b/dummy_ebpf_2/include/tc_prog_user.h index d3366dd..fc0536c 100644 --- a/dummy_ebpf_2/include/tc_prog_user.h +++ b/dummy_ebpf_2/include/tc_prog_user.h @@ -2,4 +2,4 @@ struct bpf_object *load_bpf_and_tc_attach(); void redirect_rule_set(struct bpf_object *obj); -void tc_dettach(); \ No newline at end of file +void tc_dettach(struct bpf_object *obj); \ No newline at end of file diff --git a/dummy_ebpf_2/send.py b/dummy_ebpf_2/send.py index 5d74fd9..f4d86e4 100644 --- a/dummy_ebpf_2/send.py +++ b/dummy_ebpf_2/send.py @@ -2,7 +2,7 @@ from scapy.all import * def arp_test(): # 构建一个 ARP 请求数据包 - arp_request = Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(pdst="10.0.1.15") + arp_request = Ether(dst="ff:ff:ff:ff:ff:ff") / ARP(pdst="10.10.10.10") # 在数据包负载后面追加一个不属于这个数据包的字符 extra_data = '0' diff --git a/dummy_ebpf_2/src/main.c b/dummy_ebpf_2/src/main.c index c76aded..bce7e10 100644 --- a/dummy_ebpf_2/src/main.c +++ b/dummy_ebpf_2/src/main.c @@ -55,5 +55,5 @@ int main(int argc, char *argv[]) { } cleanup: - tc_dettach(); + tc_dettach(obj); } \ No newline at end of file diff --git a/dummy_ebpf_2/src/tc_prog_kernel.c b/dummy_ebpf_2/src/tc_prog_kernel.c index cde2c17..7c58ff6 100644 --- a/dummy_ebpf_2/src/tc_prog_kernel.c +++ b/dummy_ebpf_2/src/tc_prog_kernel.c @@ -72,7 +72,7 @@ int tc_redirect_map_func(struct __sk_buff *skb) { } // Redirect the packet to the endpoint referenced by map at index key. - action = bpf_redirect(*ifindex, 0); + action = bpf_redirect(*ifindex, BPF_F_INGRESS); if (action != TC_ACT_REDIRECT) { bpf_printk("bpf_redirect_map failed. return code:%d", ret); } diff --git a/dummy_ebpf_2/src/tc_prog_user.c b/dummy_ebpf_2/src/tc_prog_user.c index 315f9a4..28e9581 100644 --- a/dummy_ebpf_2/src/tc_prog_user.c +++ b/dummy_ebpf_2/src/tc_prog_user.c @@ -9,17 +9,23 @@ #include "device.h" #include "tc_prog_user.h" +static bool created_hook = true; +struct bpf_tc_hook hook = {}; +struct bpf_tc_opts tc_opt = {}; + +static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va_list args) { + return vfprintf(stderr, format, args); +} + struct bpf_object *load_bpf_and_tc_attach() { int err; const struct config *conf = global_config_get(); int ifindex = xdp_device_index_get(); - DECLARE_LIBBPF_OPTS(bpf_tc_hook, hook, .attach_point = BPF_TC_EGRESS); - DECLARE_LIBBPF_OPTS(bpf_tc_opts, attach); - - // Clear previous prog - tc_dettach(); + hook.sz = sizeof(struct bpf_tc_hook); + hook.attach_point = BPF_TC_EGRESS; + tc_opt.sz = sizeof(struct bpf_tc_opts); struct bpf_object *obj = bpf_object__open(conf->open_filename); if (obj == NULL) { @@ -40,17 +46,24 @@ struct bpf_object *load_bpf_and_tc_attach() { exit(EXIT_FAILURE); } - attach.prog_fd = prog_fd; + // + // export LIBBPF_LOG_LEVEL=info + // bpf_program__set_log_level(prog, LIBBPF_DEBUG); + // libbpf_set_print(libbpf_print_fn); + + tc_opt.prog_fd = prog_fd; hook.ifindex = ifindex; err = bpf_tc_hook_create(&hook); - if (err && err != -EEXIST) { + if (err && err == -EEXIST) { + created_hook = false; + } else if (err) { fprintf(stderr, "Couldn't create hook for ifindex %d\n", ifindex); exit(EXIT_FAILURE); } - err = bpf_tc_attach(&hook, &attach); + err = bpf_tc_attach(&hook, &tc_opt); if (err) { fprintf(stderr, "Couldn't attach program to ifindex %d\n", hook.ifindex); exit(EXIT_FAILURE); @@ -90,27 +103,44 @@ failure: exit(EXIT_FAILURE); } -void tc_dettach() { +void tc_dettach(struct bpf_object *obj) { + // ref: bpf-examples/tc-policy/tc_txq_policy.c + int err = 0; int ifindex = xdp_device_index_get(); + const struct config *conf = global_config_get(); - DECLARE_LIBBPF_OPTS(bpf_tc_hook, hook, .attach_point = BPF_TC_EGRESS); - DECLARE_LIBBPF_OPTS(bpf_tc_opts, opts); - - hook.ifindex = ifindex; - opts.prog_fd = -1; + // look at the source code of libbpf, it must be cleared to zero. otherwise it is considered + // an illegal parameter. + tc_opt.prog_fd = 0; + tc_opt.prog_id = 0; + tc_opt.flags = 0; - err = bpf_tc_query(&hook, NULL); + // opt's hanlde is important + err = bpf_tc_query(&hook, &tc_opt); if (err == 0) { - printf("BPF program found with FD: %d\n", opts.prog_fd); + printf("BPF program found. its program id is: %d\n", tc_opt.prog_id); } else { printf("no BPF program need to dettach: %d\n", err); return; } - err = bpf_tc_hook_destroy(&hook); - if (err && err != -EEXIST) { - fprintf(stderr, "bpf_tc_hook_destroy failed %s\n", strerror(errno)); - exit(EXIT_FAILURE); + tc_opt.prog_id = 0; + err = bpf_tc_detach(&hook, &tc_opt); + if (err == 0) { + printf("detach %s successfully.\n", conf->prog_name); + } else { + printf("detach %s failed:%s\n", conf->prog_name, strerror(errno)); } + + if (created_hook) { + // Even if this function executes successfully, qdisc clsact still exists + err = bpf_tc_hook_destroy(&hook); + if (err) { + fprintf(stderr, "bpf_tc_hook_destroy failed %s\n", strerror(errno)); + exit(EXIT_FAILURE); + } + } + + bpf_object__close(obj); } \ No newline at end of file -- cgit v1.2.3