hulk inclusion category: featrue bugzilla: https://atomgit.com/openeuler/kernel/issues/7116 -------------------------------- Some refactor for hisock. Signed-off-by: Pu Lehui <pulehui@huawei.com> --- net/Kconfig | 1 + samples/bpf/hisock/bpf.c | 108 +++++++++++++++++++------------- samples/bpf/hisock/hisock_cmd.c | 15 ++++- 3 files changed, 77 insertions(+), 47 deletions(-) diff --git a/net/Kconfig b/net/Kconfig index 31e8a650bb7b..f738a37a68d0 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -360,6 +360,7 @@ config BPF_STREAM_PARSER config HISOCK bool "enable HiSock Redirect Framework" depends on INET + depends on ARM64 depends on CGROUP_BPF depends on BPF_SYSCALL default n diff --git a/samples/bpf/hisock/bpf.c b/samples/bpf/hisock/bpf.c index 0eb25a845db9..b76bba218304 100644 --- a/samples/bpf/hisock/bpf.c +++ b/samples/bpf/hisock/bpf.c @@ -120,51 +120,65 @@ static void handle_listen_cb(struct bpf_sock_ops *skops) } } -SEC("hisock_sockops") -int hisock_sockops_prog(struct bpf_sock_ops *skops) +static void handle_establish_inet_cb(struct bpf_sock_ops *skops) { struct sock_tuple key = { 0 }; struct sock_value val = { 0 }; + key.saddr = skops->remote_ip4; + key.daddr = skops->local_ip4; + key.sport = bpf_ntohl(skops->remote_port); + key.dport = skops->local_port; + + val.sk = (unsigned long)skops->sk; + val.ingress_dev = parse_ingress_dev(skops); + + bpf_map_update_elem(&connmap, &key, &val, BPF_ANY); + + bpf_sock_ops_cb_flags_set(skops, BPF_SOCK_OPS_STATE_CB_FLAG); +} + +static void handle_terminate_inet_cb(struct bpf_sock_ops *skops) +{ + struct sock_tuple key = { 0 }; + + if (skops->args[1] != BPF_TCP_CLOSE_WAIT && + skops->args[1] != BPF_TCP_FIN_WAIT1 && + skops->args[1] != BPF_TCP_CLOSE) + return; + + key.saddr = skops->remote_ip4; + key.daddr = skops->local_ip4; + key.sport = bpf_ntohl(skops->remote_port); + key.dport = skops->local_port; + + bpf_map_delete_elem(&connmap, &key); + + bpf_sock_ops_cb_flags_set(skops, + skops->bpf_sock_ops_cb_flags & ~BPF_SOCK_OPS_STATE_CB_FLAG); +} + +SEC("hisock_sockops") +int hisock_sockops_prog(struct bpf_sock_ops *skops) +{ if (skops->op == BPF_SOCK_OPS_TCP_LISTEN_CB) { handle_listen_cb(skops); return 1; } - if (!is_speed_flow(skops->local_port)) - return 1; - - switch (skops->op) { - case BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB: - key.saddr = skops->remote_ip4; - key.sport = bpf_ntohl(skops->remote_port); - key.daddr = skops->local_ip4; - key.dport = skops->local_port; - - val.sk = (unsigned long)skops->sk; - val.ingress_dev = parse_ingress_dev(skops); - bpf_map_update_elem(&connmap, &key, &val, BPF_ANY); - - bpf_sock_ops_cb_flags_set(skops, BPF_SOCK_OPS_STATE_CB_FLAG); - break; - case BPF_SOCK_OPS_STATE_CB: - if (skops->args[1] != BPF_TCP_CLOSE_WAIT && - skops->args[1] != BPF_TCP_FIN_WAIT1 && - skops->args[1] != BPF_TCP_CLOSE) + if (skops->family == AF_INET) { + switch (skops->op) { + case BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB: + if (!is_speed_flow(skops->local_port)) + break; + handle_establish_inet_cb(skops); break; - - key.saddr = skops->remote_ip4; - key.sport = bpf_ntohl(skops->remote_port); - key.daddr = skops->local_ip4; - key.dport = skops->local_port; - - bpf_map_delete_elem(&connmap, &key); - - bpf_sock_ops_cb_flags_set(skops, - skops->bpf_sock_ops_cb_flags & ~BPF_SOCK_OPS_STATE_CB_FLAG); - break; - default: - break; + case BPF_SOCK_OPS_STATE_CB: + handle_terminate_inet_cb(skops); + break; + default: + break; + } } return 1; @@ -214,7 +228,7 @@ int hisock_ingress_prog(struct xdp_md *ctx) if (!val) return XDP_PASS; - if (unlikely(!val->eth_updated)) { + if (!val->eth_updated) { memcpy(val->ingress_eth.h_source, ehdr->h_dest, ETH_ALEN); memcpy(val->ingress_eth.h_dest, ehdr->h_source, ETH_ALEN); val->ingress_eth.h_proto = ehdr->h_proto; @@ -250,8 +264,19 @@ int hisock_egress_prog(struct __sk_buff *skb) struct sock_tuple key = { 0 }; struct sock_value *val; struct ethhdr *ehdr; + struct tcphdr *thdr; struct iphdr *ihdr; - int ret; + + ihdr = (struct iphdr *)data; + if (ihdr + 1 > data_end) + return HISOCK_PASS; + + thdr = (struct tcphdr *)(ihdr + 1); + if (thdr + 1 > data_end) + return HISOCK_PASS; + + if (thdr->syn || thdr->fin || thdr->rst) + return HISOCK_PASS; key.saddr = skb->remote_ip4; key.sport = bpf_ntohl(skb->remote_port); @@ -262,18 +287,13 @@ int hisock_egress_prog(struct __sk_buff *skb) if (!val) return HISOCK_PASS; - if (unlikely(!val->eth_updated)) + if (!val->eth_updated) goto redirect; - ihdr = (struct iphdr *)data; - if (ihdr + 1 > data_end) - return HISOCK_PASS; - ihdr->tot_len = bpf_htons(skb->len); ipv4_csum(ihdr); - ret = bpf_skb_change_head(skb, ETH_HLEN, 0); - if (ret < 0) + if (bpf_skb_change_head(skb, ETH_HLEN, 0) < 0) goto redirect; data = (void *)(long)skb->data; diff --git a/samples/bpf/hisock/hisock_cmd.c b/samples/bpf/hisock/hisock_cmd.c index 777a06f78ab3..f44c98d529da 100644 --- a/samples/bpf/hisock/hisock_cmd.c +++ b/samples/bpf/hisock/hisock_cmd.c @@ -156,8 +156,12 @@ static int parse_port_range(const char *port_str, int map_fd) return -1; } - for (port = start; port <= end; port++) - bpf_map_update_elem(map_fd, &port, &val, BPF_ANY); + for (port = start; port <= end; port++) { + if (bpf_map_update_elem(map_fd, &port, &val, BPF_ANY) < 0) { + fprintf(stderr, "ERROR: failed to update port\n"); + return -1; + } + } printf("Speed port range: %u-%u\n", start, end); } else { @@ -166,7 +170,12 @@ static int parse_port_range(const char *port_str, int map_fd) fprintf(stderr, "Invalid port: %s\n", token); return -1; } - bpf_map_update_elem(map_fd, &port, &val, BPF_ANY); + + if (bpf_map_update_elem(map_fd, &port, &val, BPF_ANY) < 0) { + fprintf(stderr, "ERROR: failed to update port range\n"); + return -1; + } + printf("Speed port: %u\n", port); } } -- 2.34.1