[PATCH OLK-6.6 00/11] HiSock Enhancement
Liu Jian (1): cgroup: make cgroup_bpf_prog_attach work when cgroup2 is not mounted Pu Lehui (10): bpf: Only deploy hisock in server bpf: Add multi port parse to hisock_cmd bpf: Add target comm parse to hisock_cmd bpf: Add bpf_xdp_early_demux kfunc bpf: Add bpf_xdp_set_ingress_dev kfunc bpf: Add bpf_skb_set_egress_dev kfunc bpf: Deprecate some unused hisock kfuncs bpf: Some refactor for hisock bpf: Add ipv4-mapped ipv6 addr support for hisock bpf: Add local connect support for hisock include/linux/cgroup.h | 1 + kernel/bpf/cgroup.c | 8 +- kernel/cgroup/cgroup.c | 22 +++ net/Kconfig | 1 + net/core/dev.c | 5 +- net/core/filter.c | 83 +++------ samples/bpf/hisock/bpf.c | 315 ++++++++++++++++++++++++-------- samples/bpf/hisock/hisock_cmd.c | 211 ++++++++++++++++----- 8 files changed, 469 insertions(+), 177 deletions(-) -- 2.34.1
From: Liu Jian <liujian56@huawei.com> hulk inclusion category: featrue bugzilla: https://atomgit.com/openeuler/kernel/issues/7116 -------------------------------- BPF_PROG_TYPE_CGROUP* bpf programs is associated with cgroup2. If cgroup2 is not mounted, the bpf program is associated with cgrp_dfl_root.cgrp by default. Then we can use it like below: bpftool cgroup attach /sys/fs/cgroup/cpu sock_ops pinned /sys/fs/bpf/xxx Signed-off-by: Liu Jian <liujian56@huawei.com> Signed-off-by: Pu Lehui <pulehui@huawei.com> --- include/linux/cgroup.h | 1 + kernel/bpf/cgroup.c | 8 ++++---- kernel/cgroup/cgroup.c | 22 ++++++++++++++++++++++ 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 05a9cef2edac..1d239e457c44 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -108,6 +108,7 @@ struct cgroup_subsys_state *css_tryget_online_from_dir(struct dentry *dentry, struct cgroup *cgroup_get_from_path(const char *path); struct cgroup *cgroup_get_from_fd(int fd); +struct cgroup *cgroup_get_from_fd_v2(int fd); struct cgroup *cgroup_v1v2_get_from_fd(int fd); int cgroup_attach_task_all(struct task_struct *from, struct task_struct *); diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c index 90cc73c762cf..2315dd1b1363 100644 --- a/kernel/bpf/cgroup.c +++ b/kernel/bpf/cgroup.c @@ -1157,7 +1157,7 @@ int cgroup_bpf_prog_attach(const union bpf_attr *attr, struct cgroup *cgrp; int ret; - cgrp = cgroup_get_from_fd(attr->target_fd); + cgrp = cgroup_get_from_fd_v2(attr->target_fd); if (IS_ERR(cgrp)) return PTR_ERR(cgrp); @@ -1185,7 +1185,7 @@ int cgroup_bpf_prog_detach(const union bpf_attr *attr, enum bpf_prog_type ptype) struct cgroup *cgrp; int ret; - cgrp = cgroup_get_from_fd(attr->target_fd); + cgrp = cgroup_get_from_fd_v2(attr->target_fd); if (IS_ERR(cgrp)) return PTR_ERR(cgrp); @@ -1304,7 +1304,7 @@ int cgroup_bpf_link_attach(const union bpf_attr *attr, struct bpf_prog *prog) if (attr->link_create.flags) return -EINVAL; - cgrp = cgroup_get_from_fd(attr->link_create.target_fd); + cgrp = cgroup_get_from_fd_v2(attr->link_create.target_fd); if (IS_ERR(cgrp)) return PTR_ERR(cgrp); @@ -1344,7 +1344,7 @@ int cgroup_bpf_prog_query(const union bpf_attr *attr, struct cgroup *cgrp; int ret; - cgrp = cgroup_get_from_fd(attr->query.target_fd); + cgrp = cgroup_get_from_fd_v2(attr->query.target_fd); if (IS_ERR(cgrp)) return PTR_ERR(cgrp); diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index 7df73d1d6628..6eea5518971d 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -7109,6 +7109,28 @@ struct cgroup *cgroup_get_from_fd(int fd) } EXPORT_SYMBOL_GPL(cgroup_get_from_fd); +/** + * same with cgroup_get_from_fd, only add cgrp_dfl_visible check + */ +struct cgroup *cgroup_get_from_fd_v2(int fd) +{ + struct cgroup *cgrp = cgroup_v1v2_get_from_fd(fd); + + if (IS_ERR(cgrp)) + return ERR_CAST(cgrp); + + if (!cgroup_on_dfl(cgrp)) { + cgroup_put(cgrp); + if (cgrp_dfl_visible) + return ERR_PTR(-EBADF); + + cgrp = &cgrp_dfl_root.cgrp; + cgroup_get(cgrp); + } + return cgrp; +} +EXPORT_SYMBOL_GPL(cgroup_get_from_fd_v2); + static u64 power_of_ten(int power) { u64 v = 1; -- 2.34.1
hulk inclusion category: featrue bugzilla: https://atomgit.com/openeuler/kernel/issues/7116 -------------------------------- Only deploy hisock in server. Signed-off-by: Pu Lehui <pulehui@huawei.com> --- samples/bpf/hisock/bpf.c | 16 ++++---------- samples/bpf/hisock/hisock_cmd.c | 39 +++++++++++---------------------- 2 files changed, 17 insertions(+), 38 deletions(-) diff --git a/samples/bpf/hisock/bpf.c b/samples/bpf/hisock/bpf.c index 46159c96cb18..3b10f341aef4 100644 --- a/samples/bpf/hisock/bpf.c +++ b/samples/bpf/hisock/bpf.c @@ -23,9 +23,6 @@ #define SOCKOPS_SUCC 1 #define SOCKOPS_FAIL 0 -#define PORT_LOCAL 1 -#define PORT_REMOTE 2 - #define MAX_NUMA 8 #define MAX_CONN_NUMA 4096 #define MAX_CONN (MAX_CONN_NUMA * MAX_NUMA * 2) @@ -62,16 +59,12 @@ struct dst_entry *bpf_skops_get_ingress_dst(struct bpf_sock_ops *skops) __ksym; int bpf_xdp_set_ingress_dst(struct xdp_md *xdp, void *dst) __ksym; int bpf_skb_change_dev(struct __sk_buff *skb, u32 ifindex) __ksym; -static inline bool is_speed_flow(u32 local, u32 remote) +static inline bool is_speed_flow(u16 port) { u8 *val; - val = bpf_map_lookup_elem(&speed_port, &local); - if (val && *val == PORT_LOCAL) - return true; - - val = bpf_map_lookup_elem(&speed_port, &remote); - if (val && *val == PORT_REMOTE) + val = bpf_map_lookup_elem(&speed_port, &port); + if (val && *val == 1) return true; return false; @@ -84,12 +77,11 @@ int hisock_sockops_prog(struct bpf_sock_ops *skops) struct sock_value val = { 0 }; struct dst_entry *dst; - if (!is_speed_flow(skops->local_port, bpf_ntohl(skops->remote_port))) + if (!is_speed_flow(skops->local_port)) return SOCKOPS_SUCC; switch (skops->op) { case BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB: - case BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB: dst = bpf_skops_get_ingress_dst(skops); if (!dst) return SOCKOPS_FAIL; diff --git a/samples/bpf/hisock/hisock_cmd.c b/samples/bpf/hisock/hisock_cmd.c index 6b64c008b6c7..7e348dfb944d 100644 --- a/samples/bpf/hisock/hisock_cmd.c +++ b/samples/bpf/hisock/hisock_cmd.c @@ -29,15 +29,12 @@ #include <bpf/libbpf.h> #define DEF_BPF_PATH "bpf.o" -#define PORT_LOCAL 1 -#define PORT_REMOTE 2 #define MAX_IF_NUM 8 struct { __u32 ifindex[MAX_IF_NUM]; int if_num; - char *local_port; - char *remote_port; + char *port; char *cgrp_path; char *bpf_path; bool unload; @@ -131,10 +128,11 @@ static int find_progs(struct bpf_object *obj) return 0; } -static int parse_port_range(const char *port_str, __u8 status, int map_fd) +static int parse_port_range(const char *port_str, int map_fd) { char *str = strdup(port_str); char *token, *rest = str; + __u8 val = 1; __u16 port; while ((token = strtok_r(rest, ",", &rest))) { @@ -151,17 +149,17 @@ static int parse_port_range(const char *port_str, __u8 status, int map_fd) } for (port = start; port <= end; port++) - bpf_map_update_elem(map_fd, &port, &status, BPF_ANY); + bpf_map_update_elem(map_fd, &port, &val, BPF_ANY); - printf("Speed port range %u-%u:%u\n", start, end, status); + printf("Speed port range: %u-%u\n", start, end); } else { port = atoi(token); if (port == 0 || port > 65535) { fprintf(stderr, "Invalid port: %s\n", token); return -1; } - bpf_map_update_elem(map_fd, &port, &status, BPF_ANY); - printf("Speed port %u:%u\n", port, status); + bpf_map_update_elem(map_fd, &port, &val, BPF_ANY); + printf("Speed port: %u\n", port); } } @@ -179,15 +177,8 @@ static int set_speed_port(struct bpf_object *obj) return -1; } - if (hisock.local_port && - parse_port_range(hisock.local_port, PORT_LOCAL, map_fd)) { - fprintf(stderr, "ERROR: failed to update local port\n"); - return -1; - } - - if (hisock.remote_port && - parse_port_range(hisock.remote_port, PORT_REMOTE, map_fd)) { - fprintf(stderr, "ERROR: failed to update remote port\n"); + if (hisock.port && parse_port_range(hisock.port, map_fd)) { + fprintf(stderr, "ERROR: failed to update speed port\n"); return -1; } @@ -318,7 +309,7 @@ static void do_help(void) { fprintf(stderr, "Load: hisock_cmd [-f BPF_FILE] [-c CGRP_PATH] " - "[-p LOCAL_PORT] [-r REMOTE_PORT] [-i INTERFACE]\n" + "[-p PORT] [-i INTERFACE]\n" "Unload: hisock_cmd -u [-c CGRP_PATH] [-i INTERFACE]\n"); } @@ -330,7 +321,7 @@ static int parse_args(int argc, char **argv) hisock.bpf_path = DEF_BPF_PATH; hisock.if_num = 0; - while ((opt = getopt(argc, argv, "f:c:p:r:i:uh")) != -1) { + while ((opt = getopt(argc, argv, "f:c:p:i:uh")) != -1) { switch (opt) { case 'f': hisock.bpf_path = optarg; @@ -339,10 +330,7 @@ static int parse_args(int argc, char **argv) hisock.cgrp_path = optarg; break; case 'p': - hisock.local_port = optarg; - break; - case 'r': - hisock.remote_port = optarg; + hisock.port = optarg; break; case 'i': ifname = optarg; @@ -364,8 +352,7 @@ static int parse_args(int argc, char **argv) if (hisock.cgrp_path == NULL || hisock.if_num == 0 || (!hisock.unload && - hisock.local_port == NULL && - hisock.remote_port == NULL)) { + hisock.port == NULL)) { do_help(); return -1; } -- 2.34.1
ihulk inclusion category: featrue bugzilla: https://atomgit.com/openeuler/kernel/issues/7116 -------------------------------- Add multi port parse to hisock_cmd. Signed-off-by: Pu Lehui <pulehui@huawei.com> --- samples/bpf/hisock/hisock_cmd.c | 44 +++++++++++++++++---------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/samples/bpf/hisock/hisock_cmd.c b/samples/bpf/hisock/hisock_cmd.c index 7e348dfb944d..763e4b3698ca 100644 --- a/samples/bpf/hisock/hisock_cmd.c +++ b/samples/bpf/hisock/hisock_cmd.c @@ -30,15 +30,16 @@ #define DEF_BPF_PATH "bpf.o" #define MAX_IF_NUM 8 +#define MAX_PORT_NUM 8 struct { __u32 ifindex[MAX_IF_NUM]; int if_num; - char *port; + char *port[MAX_PORT_NUM]; + int port_num; char *cgrp_path; char *bpf_path; bool unload; - bool help; } hisock; struct hisock_prog_info { @@ -170,6 +171,7 @@ static int parse_port_range(const char *port_str, int map_fd) static int set_speed_port(struct bpf_object *obj) { int map_fd; + int i; map_fd = bpf_object__find_map_fd_by_name(obj, "speed_port"); if (map_fd < 0) { @@ -177,9 +179,11 @@ static int set_speed_port(struct bpf_object *obj) return -1; } - if (hisock.port && parse_port_range(hisock.port, map_fd)) { - fprintf(stderr, "ERROR: failed to update speed port\n"); - return -1; + for (i = 0; i < hisock.port_num; i++) { + if (hisock.port[i] && parse_port_range(hisock.port[i], map_fd)) { + fprintf(stderr, "ERROR: failed to update speed port\n"); + return -1; + } } return 0; @@ -315,11 +319,9 @@ static void do_help(void) static int parse_args(int argc, char **argv) { - char *ifname; int opt; hisock.bpf_path = DEF_BPF_PATH; - hisock.if_num = 0; while ((opt = getopt(argc, argv, "f:c:p:i:uh")) != -1) { switch (opt) { @@ -330,29 +332,34 @@ static int parse_args(int argc, char **argv) hisock.cgrp_path = optarg; break; case 'p': - hisock.port = optarg; + hisock.port[hisock.port_num] = optarg; + hisock.port_num++; break; case 'i': - ifname = optarg; - hisock.ifindex[hisock.if_num] = if_nametoindex(ifname); + hisock.ifindex[hisock.if_num] = if_nametoindex(optarg); hisock.if_num++; break; case 'u': hisock.unload = true; break; case 'h': - hisock.help = true; - break; + do_help(); + exit(0); default: fprintf(stderr, "ERROR: unknown option %c\n", opt); return -1; } } - if (hisock.cgrp_path == NULL || - hisock.if_num == 0 || - (!hisock.unload && - hisock.port == NULL)) { + if (hisock.unload && + (hisock.cgrp_path == NULL || hisock.if_num == 0)) { + do_help(); + return -1; + } + + if (!hisock.unload && + (hisock.cgrp_path == NULL || hisock.if_num == 0 || + hisock.port_num == 0)) { do_help(); return -1; } @@ -367,11 +374,6 @@ int main(int argc, char **argv) return -1; } - if (hisock.help) { - do_help(); - return 0; - } - if (hisock.unload) { if (detach_progs()) { fprintf(stderr, "ERROR: failed to detach progs\n"); -- 2.34.1
hulk inclusion category: featrue bugzilla: https://atomgit.com/openeuler/kernel/issues/7116 -------------------------------- Add target comm parse to hisock_cmd. Signed-off-by: Pu Lehui <pulehui@huawei.com> --- samples/bpf/hisock/bpf.c | 30 ++++++++++++++++++++ samples/bpf/hisock/hisock_cmd.c | 49 +++++++++++++++++++++++++++++++-- 2 files changed, 76 insertions(+), 3 deletions(-) diff --git a/samples/bpf/hisock/bpf.c b/samples/bpf/hisock/bpf.c index 3b10f341aef4..dc6250ea0b5f 100644 --- a/samples/bpf/hisock/bpf.c +++ b/samples/bpf/hisock/bpf.c @@ -27,6 +27,8 @@ #define MAX_CONN_NUMA 4096 #define MAX_CONN (MAX_CONN_NUMA * MAX_NUMA * 2) +#define MAX_COMM_NUM 8 + struct sock_tuple { u32 saddr; u32 daddr; @@ -55,6 +57,13 @@ struct { __uint(max_entries, 128); } speed_port SEC(".maps"); +struct { + __uint(type, BPF_MAP_TYPE_HASH); + __uint(key_size, sizeof(char[TASK_COMM_LEN])); + __uint(value_size, sizeof(u8)); + __uint(max_entries, MAX_COMM_NUM); +} target_comm SEC(".maps"); + struct dst_entry *bpf_skops_get_ingress_dst(struct bpf_sock_ops *skops) __ksym; int bpf_xdp_set_ingress_dst(struct xdp_md *xdp, void *dst) __ksym; int bpf_skb_change_dev(struct __sk_buff *skb, u32 ifindex) __ksym; @@ -70,6 +79,22 @@ static inline bool is_speed_flow(u16 port) return false; } +static void handle_listen_cb(struct bpf_sock_ops *skops) +{ + char comm[TASK_COMM_LEN] = { 0 }; + u8 *comm_val; + + bpf_get_current_comm(comm, sizeof(comm)); + + comm_val = bpf_map_lookup_elem(&target_comm, comm); + if (comm_val && *comm_val == 1) { + u16 key = skops->local_port; + u8 val = 1; + + bpf_map_update_elem(&speed_port, &key, &val, BPF_ANY); + } +} + SEC("hisock_sockops") int hisock_sockops_prog(struct bpf_sock_ops *skops) { @@ -77,6 +102,11 @@ int hisock_sockops_prog(struct bpf_sock_ops *skops) struct sock_value val = { 0 }; struct dst_entry *dst; + if (skops->op == BPF_SOCK_OPS_TCP_LISTEN_CB) { + handle_listen_cb(skops); + return SOCKOPS_SUCC; + } + if (!is_speed_flow(skops->local_port)) return SOCKOPS_SUCC; diff --git a/samples/bpf/hisock/hisock_cmd.c b/samples/bpf/hisock/hisock_cmd.c index 763e4b3698ca..777a06f78ab3 100644 --- a/samples/bpf/hisock/hisock_cmd.c +++ b/samples/bpf/hisock/hisock_cmd.c @@ -28,15 +28,22 @@ #include <bpf/bpf.h> #include <bpf/libbpf.h> +#ifndef TASK_COMM_LEN +#define TASK_COMM_LEN 16 +#endif + #define DEF_BPF_PATH "bpf.o" #define MAX_IF_NUM 8 #define MAX_PORT_NUM 8 +#define MAX_COMM_NUM 8 struct { __u32 ifindex[MAX_IF_NUM]; int if_num; char *port[MAX_PORT_NUM]; int port_num; + char *comm[MAX_COMM_NUM]; + int comm_num; char *cgrp_path; char *bpf_path; bool unload; @@ -189,6 +196,32 @@ static int set_speed_port(struct bpf_object *obj) return 0; } +static int set_target_comm(struct bpf_object *obj) +{ + int map_fd; + int i; + + map_fd = bpf_object__find_map_fd_by_name(obj, "target_comm"); + if (map_fd < 0) { + fprintf(stderr, "ERROR: failed to find map fd\n"); + return -1; + } + + for (i = 0; i < hisock.comm_num; i++) { + char key[TASK_COMM_LEN] = { 0 }; + __u8 val = 1; + + strncpy(key, hisock.comm[i], sizeof(key) - 1); + if (bpf_map_update_elem(map_fd, &key, &val, BPF_ANY) < 0) { + fprintf(stderr, "ERROR: failed to update comm\n"); + return -1; + } + printf("Target comm: %s\n", key); + } + + return 0; +} + static int detach_progs(void) { struct hisock_prog_info *info; @@ -299,6 +332,12 @@ static int do_hisock(void) return -1; } + if (set_target_comm(obj)) { + fprintf(stderr, "ERROR: failed to set target comm\n"); + bpf_object__close(obj); + return -1; + } + if (attach_progs()) { fprintf(stderr, "ERROR: failed to attach progs\n"); bpf_object__close(obj); @@ -313,7 +352,7 @@ static void do_help(void) { fprintf(stderr, "Load: hisock_cmd [-f BPF_FILE] [-c CGRP_PATH] " - "[-p PORT] [-i INTERFACE]\n" + "[-p PORT] [-C COMM] [-i INTERFACE]\n" "Unload: hisock_cmd -u [-c CGRP_PATH] [-i INTERFACE]\n"); } @@ -323,7 +362,7 @@ static int parse_args(int argc, char **argv) hisock.bpf_path = DEF_BPF_PATH; - while ((opt = getopt(argc, argv, "f:c:p:i:uh")) != -1) { + while ((opt = getopt(argc, argv, "f:c:p:i:C:uh")) != -1) { switch (opt) { case 'f': hisock.bpf_path = optarg; @@ -339,6 +378,10 @@ static int parse_args(int argc, char **argv) hisock.ifindex[hisock.if_num] = if_nametoindex(optarg); hisock.if_num++; break; + case 'C': + hisock.comm[hisock.comm_num] = optarg; + hisock.comm_num++; + break; case 'u': hisock.unload = true; break; @@ -359,7 +402,7 @@ static int parse_args(int argc, char **argv) if (!hisock.unload && (hisock.cgrp_path == NULL || hisock.if_num == 0 || - hisock.port_num == 0)) { + (hisock.port_num == 0 && hisock.comm_num == 0))) { do_help(); return -1; } -- 2.34.1
hulk inclusion category: featrue bugzilla: https://atomgit.com/openeuler/kernel/issues/7116 -------------------------------- Add bpf_xdp_early_demux kfunc. Signed-off-by: Pu Lehui <pulehui@huawei.com> --- net/core/dev.c | 5 +++-- net/core/filter.c | 27 +++++++++++++++++++++++++++ samples/bpf/hisock/bpf.c | 24 +++++++----------------- 3 files changed, 37 insertions(+), 19 deletions(-) diff --git a/net/core/dev.c b/net/core/dev.c index e2d61f786c8a..2bf4986d1690 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -5122,9 +5122,10 @@ static int generic_xdp_hisock_redirect(struct sk_buff *skb) iph = ip_hdr(skb); skb->transport_header = skb->network_header + iph->ihl * 4; - skb_orphan(skb); + if (!skb_sk_is_prefetched(skb)) + skb_orphan(skb); - if (!skb_valid_dst(skb)) { + if (unlikely(!skb_valid_dst(skb))) { if (ip_route_input_noref(skb, iph->daddr, iph->saddr, iph->tos, skb->dev)) goto free_skb; diff --git a/net/core/filter.c b/net/core/filter.c index eee64a67df40..abf0c7abe20a 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -12109,6 +12109,32 @@ __bpf_kfunc int bpf_xdp_set_ingress_dst(struct xdp_md *xdp_ctx, void *dst__ign) return 0; } +__bpf_kfunc int bpf_xdp_early_demux(struct xdp_md *xdp_ctx, unsigned long _sk) +{ + struct dst_entry *dst; + struct sock *sk = (struct sock *)_sk; + struct xdp_buff *xdp = (struct xdp_buff *)xdp_ctx; + struct hisock_xdp_buff *hxdp = (struct hisock_xdp_buff *)xdp; + struct sk_buff *skb = hxdp->skb; + + if (!skb) + return -EOPNOTSUPP; + + if (!sk || !virt_addr_valid(sk)) + return -EFAULT; + + if (!sk_fullsock(sk)) + return -EINVAL; + + dst = rcu_dereference(sk->sk_rx_dst); + if (dst) + dst = dst_check(dst, 0); + if (dst && sk->sk_rx_dst_ifindex == skb->skb_iif) + skb_dst_set_noref(skb, dst); + + return 0; +} + __bpf_kfunc int bpf_xdp_change_dev(struct xdp_md *xdp_ctx, u32 ifindex) { struct xdp_buff *xdp = (struct xdp_buff *)xdp_ctx; @@ -12167,6 +12193,7 @@ BTF_SET8_START(bpf_kfunc_check_set_xdp) BTF_ID_FLAGS(func, bpf_dynptr_from_xdp) #ifdef CONFIG_HISOCK BTF_ID_FLAGS(func, bpf_xdp_set_ingress_dst) +BTF_ID_FLAGS(func, bpf_xdp_early_demux) BTF_ID_FLAGS(func, bpf_xdp_change_dev) #endif BTF_SET8_END(bpf_kfunc_check_set_xdp) diff --git a/samples/bpf/hisock/bpf.c b/samples/bpf/hisock/bpf.c index dc6250ea0b5f..9c1d5bd9b570 100644 --- a/samples/bpf/hisock/bpf.c +++ b/samples/bpf/hisock/bpf.c @@ -20,9 +20,6 @@ #define IP_OFFSET 0x1FFF #define CSUM_SHIFT_BITS 16 -#define SOCKOPS_SUCC 1 -#define SOCKOPS_FAIL 0 - #define MAX_NUMA 8 #define MAX_CONN_NUMA 4096 #define MAX_CONN (MAX_CONN_NUMA * MAX_NUMA * 2) @@ -37,7 +34,7 @@ struct sock_tuple { }; struct sock_value { - struct dst_entry *ingress_dst; + unsigned long sk; struct ethhdr ingress_eth; bool eth_updated; u32 ingress_ifindex; @@ -64,8 +61,7 @@ struct { __uint(max_entries, MAX_COMM_NUM); } target_comm SEC(".maps"); -struct dst_entry *bpf_skops_get_ingress_dst(struct bpf_sock_ops *skops) __ksym; -int bpf_xdp_set_ingress_dst(struct xdp_md *xdp, void *dst) __ksym; +int bpf_xdp_early_demux(struct xdp_md *xdp_ctx, unsigned long sk) __ksym; int bpf_skb_change_dev(struct __sk_buff *skb, u32 ifindex) __ksym; static inline bool is_speed_flow(u16 port) @@ -100,28 +96,23 @@ int hisock_sockops_prog(struct bpf_sock_ops *skops) { struct sock_tuple key = { 0 }; struct sock_value val = { 0 }; - struct dst_entry *dst; if (skops->op == BPF_SOCK_OPS_TCP_LISTEN_CB) { handle_listen_cb(skops); - return SOCKOPS_SUCC; + return 1; } if (!is_speed_flow(skops->local_port)) - return SOCKOPS_SUCC; + return 1; switch (skops->op) { case BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB: - dst = bpf_skops_get_ingress_dst(skops); - if (!dst) - return SOCKOPS_FAIL; - key.saddr = skops->remote_ip4; key.sport = bpf_ntohl(skops->remote_port); key.daddr = skops->local_ip4; key.dport = skops->local_port; - val.ingress_dst = dst; + val.sk = (unsigned long)skops->sk; bpf_map_update_elem(&connmap, &key, &val, BPF_ANY); bpf_sock_ops_cb_flags_set(skops, BPF_SOCK_OPS_STATE_CB_FLAG); @@ -146,7 +137,7 @@ int hisock_sockops_prog(struct bpf_sock_ops *skops) break; } - return SOCKOPS_SUCC; + return 1; } SEC("hisock_ingress") @@ -203,8 +194,7 @@ int hisock_ingress_prog(struct xdp_md *ctx) if (unlikely(!val->ingress_ifindex)) val->ingress_ifindex = ctx->ingress_ifindex; - if (likely(val->ingress_dst)) - bpf_xdp_set_ingress_dst(ctx, val->ingress_dst); + bpf_xdp_early_demux(ctx, val->sk); return XDP_HISOCK_REDIRECT; } -- 2.34.1
hulk inclusion category: featrue bugzilla: https://atomgit.com/openeuler/kernel/issues/7116 -------------------------------- Add bpf_xdp_set_ingress_dev kfunc. Signed-off-by: Pu Lehui <pulehui@huawei.com> --- net/core/filter.c | 20 ++++++++++++++++++++ samples/bpf/hisock/bpf.c | 18 ++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/net/core/filter.c b/net/core/filter.c index abf0c7abe20a..3c3c4bf63f2c 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -12135,6 +12135,25 @@ __bpf_kfunc int bpf_xdp_early_demux(struct xdp_md *xdp_ctx, unsigned long _sk) return 0; } +__bpf_kfunc int +bpf_xdp_set_ingress_dev(struct xdp_md *xdp_ctx, unsigned long _dev) +{ + struct net_device *dev = (struct net_device *)_dev; + struct xdp_buff *xdp = (struct xdp_buff *)xdp_ctx; + struct hisock_xdp_buff *hxdp = (void *)xdp; + struct sk_buff *skb = hxdp->skb; + + if (!skb) + return -EOPNOTSUPP; + + if (!dev || !virt_addr_valid(dev)) + return -EFAULT; + + skb->dev = dev; + skb->skb_iif = dev->ifindex; + return 0; +} + __bpf_kfunc int bpf_xdp_change_dev(struct xdp_md *xdp_ctx, u32 ifindex) { struct xdp_buff *xdp = (struct xdp_buff *)xdp_ctx; @@ -12194,6 +12213,7 @@ BTF_ID_FLAGS(func, bpf_dynptr_from_xdp) #ifdef CONFIG_HISOCK BTF_ID_FLAGS(func, bpf_xdp_set_ingress_dst) BTF_ID_FLAGS(func, bpf_xdp_early_demux) +BTF_ID_FLAGS(func, bpf_xdp_set_ingress_dev) BTF_ID_FLAGS(func, bpf_xdp_change_dev) #endif BTF_SET8_END(bpf_kfunc_check_set_xdp) diff --git a/samples/bpf/hisock/bpf.c b/samples/bpf/hisock/bpf.c index 9c1d5bd9b570..fab5ea7ed0db 100644 --- a/samples/bpf/hisock/bpf.c +++ b/samples/bpf/hisock/bpf.c @@ -4,7 +4,9 @@ * * Description: End-to-End HiSock Redirect sample. */ +#define KBUILD_MODNAME "foo" #include <linux/if_vlan.h> +#include <linux/filter.h> #include <net/dst.h> #include <uapi/linux/in.h> @@ -15,6 +17,7 @@ #include <bpf/bpf_endian.h> #include <bpf/bpf_helpers.h> +#include <bpf/bpf_core_read.h> #define IP_MF 0x2000 #define IP_OFFSET 0x1FFF @@ -35,6 +38,7 @@ struct sock_tuple { struct sock_value { unsigned long sk; + unsigned long ingress_dev; struct ethhdr ingress_eth; bool eth_updated; u32 ingress_ifindex; @@ -62,6 +66,7 @@ struct { } target_comm SEC(".maps"); int bpf_xdp_early_demux(struct xdp_md *xdp_ctx, unsigned long sk) __ksym; +int bpf_xdp_set_ingress_dev(struct xdp_md *xdp_ctx, unsigned long dev) __ksym; int bpf_skb_change_dev(struct __sk_buff *skb, u32 ifindex) __ksym; static inline bool is_speed_flow(u16 port) @@ -75,6 +80,17 @@ static inline bool is_speed_flow(u16 port) return false; } +static inline unsigned long parse_ingress_dev(struct bpf_sock_ops *skops) +{ + struct sk_buff *skb; + struct net_device *dev; + + skb = BPF_CORE_READ((struct bpf_sock_ops_kern *)skops, skb); + dev = BPF_CORE_READ(skb, dev); + + return (unsigned long)dev; +} + static void handle_listen_cb(struct bpf_sock_ops *skops) { char comm[TASK_COMM_LEN] = { 0 }; @@ -113,6 +129,7 @@ int hisock_sockops_prog(struct bpf_sock_ops *skops) 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); @@ -194,6 +211,7 @@ int hisock_ingress_prog(struct xdp_md *ctx) if (unlikely(!val->ingress_ifindex)) val->ingress_ifindex = ctx->ingress_ifindex; + bpf_xdp_set_ingress_dev(ctx, val->ingress_dev); bpf_xdp_early_demux(ctx, val->sk); return XDP_HISOCK_REDIRECT; -- 2.34.1
hulk inclusion category: featrue bugzilla: https://atomgit.com/openeuler/kernel/issues/7116 -------------------------------- Add bpf_skb_set_egress_dev kfunc. Signed-off-by: Pu Lehui <pulehui@huawei.com> --- net/core/filter.c | 14 ++++++++++++++ samples/bpf/hisock/bpf.c | 22 +++++++++++++++++----- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/net/core/filter.c b/net/core/filter.c index 3c3c4bf63f2c..b02a8b229395 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -12173,6 +12173,19 @@ __bpf_kfunc int bpf_xdp_change_dev(struct xdp_md *xdp_ctx, u32 ifindex) return 0; } +__bpf_kfunc int +bpf_skb_set_egress_dev(struct __sk_buff *skb_ctx, unsigned long _dev) +{ + struct net_device *dev = (struct net_device *)_dev; + struct sk_buff *skb = (struct sk_buff *)skb_ctx; + + if (!dev || !virt_addr_valid(dev)) + return -EFAULT; + + skb->dev = dev; + return 0; +} + __bpf_kfunc int bpf_skb_change_dev(struct __sk_buff *skb_ctx, u32 ifindex) { struct sk_buff *skb = (struct sk_buff *)skb_ctx; @@ -12229,6 +12242,7 @@ BTF_SET8_END(bpf_kfunc_check_set_sock_ops) BTF_SET8_START(bpf_kfunc_check_set_hisock) BTF_ID_FLAGS(func, bpf_skb_change_dev) +BTF_ID_FLAGS(func, bpf_skb_set_egress_dev) BTF_SET8_END(bpf_kfunc_check_set_hisock) #endif diff --git a/samples/bpf/hisock/bpf.c b/samples/bpf/hisock/bpf.c index fab5ea7ed0db..0eb25a845db9 100644 --- a/samples/bpf/hisock/bpf.c +++ b/samples/bpf/hisock/bpf.c @@ -8,6 +8,7 @@ #include <linux/if_vlan.h> #include <linux/filter.h> #include <net/dst.h> +#include <net/xdp.h> #include <uapi/linux/in.h> #include <uapi/linux/if_ether.h> @@ -39,6 +40,7 @@ struct sock_tuple { struct sock_value { unsigned long sk; unsigned long ingress_dev; + unsigned long egress_dev; struct ethhdr ingress_eth; bool eth_updated; u32 ingress_ifindex; @@ -67,7 +69,7 @@ struct { int bpf_xdp_early_demux(struct xdp_md *xdp_ctx, unsigned long sk) __ksym; int bpf_xdp_set_ingress_dev(struct xdp_md *xdp_ctx, unsigned long dev) __ksym; -int bpf_skb_change_dev(struct __sk_buff *skb, u32 ifindex) __ksym; +int bpf_skb_set_egress_dev(struct __sk_buff *skb, unsigned long dev) __ksym; static inline bool is_speed_flow(u16 port) { @@ -91,6 +93,17 @@ static inline unsigned long parse_ingress_dev(struct bpf_sock_ops *skops) return (unsigned long)dev; } +static inline unsigned long parse_egress_dev(struct xdp_md *ctx) +{ + struct sk_buff *skb; + struct net_device *dev; + + skb = BPF_CORE_READ((struct hisock_xdp_buff *)ctx, skb); + dev = BPF_CORE_READ(skb, dev); + + return (unsigned long)dev; +} + static void handle_listen_cb(struct bpf_sock_ops *skops) { char comm[TASK_COMM_LEN] = { 0 }; @@ -208,8 +221,8 @@ int hisock_ingress_prog(struct xdp_md *ctx) val->eth_updated = true; } - if (unlikely(!val->ingress_ifindex)) - val->ingress_ifindex = ctx->ingress_ifindex; + if (!val->egress_dev) + val->egress_dev = parse_egress_dev(ctx); bpf_xdp_set_ingress_dev(ctx, val->ingress_dev); bpf_xdp_early_demux(ctx, val->sk); @@ -272,8 +285,7 @@ int hisock_egress_prog(struct __sk_buff *skb) memcpy(ehdr, &val->ingress_eth, ETH_HLEN); redirect: - if (likely(val->ingress_ifindex)) - bpf_skb_change_dev(skb, val->ingress_ifindex); + bpf_skb_set_egress_dev(skb, val->egress_dev); return HISOCK_REDIRECT; } -- 2.34.1
hulk inclusion category: featrue bugzilla: https://atomgit.com/openeuler/kernel/issues/7116 -------------------------------- Deprecate some unused hisock kfuncs. Signed-off-by: Pu Lehui <pulehui@huawei.com> --- net/core/filter.c | 86 ----------------------------------------------- 1 file changed, 86 deletions(-) diff --git a/net/core/filter.c b/net/core/filter.c index b02a8b229395..a8557ec2f431 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -12070,45 +12070,6 @@ __bpf_kfunc int bpf_sock_addr_set_sun_path(struct bpf_sock_addr_kern *sa_kern, } #ifdef CONFIG_HISOCK -__bpf_kfunc struct dst_entry * -bpf_skops_get_ingress_dst(struct bpf_sock_ops *skops_ctx) -{ - struct bpf_sock_ops_kern *skops = (struct bpf_sock_ops_kern *)skops_ctx; - struct sock *sk = skops->sk; - struct dst_entry *dst; - - WARN_ON_ONCE(!rcu_read_lock_held()); - - if (!sk || !sk_fullsock(sk)) - return NULL; - - dst = rcu_dereference(sk->sk_rx_dst); - if (dst) - dst = dst_check(dst, 0); - - return dst; -} - -__bpf_kfunc int bpf_xdp_set_ingress_dst(struct xdp_md *xdp_ctx, void *dst__ign) -{ - struct xdp_buff *xdp = (struct xdp_buff *)xdp_ctx; - struct hisock_xdp_buff *hxdp = (struct hisock_xdp_buff *)xdp; - struct dst_entry *_dst = (struct dst_entry *)dst__ign; - - if (!hxdp->skb) - return -EOPNOTSUPP; - - if (!_dst || !virt_addr_valid(_dst)) - return -EFAULT; - - /* same as skb_valid_dst */ - if (_dst->flags & DST_METADATA) - return -EINVAL; - - skb_dst_set_noref(hxdp->skb, _dst); - return 0; -} - __bpf_kfunc int bpf_xdp_early_demux(struct xdp_md *xdp_ctx, unsigned long _sk) { struct dst_entry *dst; @@ -12154,25 +12115,6 @@ bpf_xdp_set_ingress_dev(struct xdp_md *xdp_ctx, unsigned long _dev) return 0; } -__bpf_kfunc int bpf_xdp_change_dev(struct xdp_md *xdp_ctx, u32 ifindex) -{ - struct xdp_buff *xdp = (struct xdp_buff *)xdp_ctx; - struct hisock_xdp_buff *hxdp = (void *)xdp; - struct net_device *dev; - - WARN_ON_ONCE(!rcu_read_lock_held()); - - if (!hxdp->skb) - return -EOPNOTSUPP; - - dev = dev_get_by_index_rcu(&init_net, ifindex); - if (!dev) - return -ENODEV; - - hxdp->skb->dev = dev; - return 0; -} - __bpf_kfunc int bpf_skb_set_egress_dev(struct __sk_buff *skb_ctx, unsigned long _dev) { @@ -12185,21 +12127,6 @@ bpf_skb_set_egress_dev(struct __sk_buff *skb_ctx, unsigned long _dev) skb->dev = dev; return 0; } - -__bpf_kfunc int bpf_skb_change_dev(struct __sk_buff *skb_ctx, u32 ifindex) -{ - struct sk_buff *skb = (struct sk_buff *)skb_ctx; - struct net_device *dev; - - WARN_ON_ONCE(!rcu_read_lock_held()); - - dev = dev_get_by_index_rcu(&init_net, ifindex); - if (!dev) - return -ENODEV; - - skb->dev = dev; - return 0; -} #endif __diag_pop(); @@ -12224,10 +12151,8 @@ BTF_SET8_END(bpf_kfunc_check_set_skb) BTF_SET8_START(bpf_kfunc_check_set_xdp) BTF_ID_FLAGS(func, bpf_dynptr_from_xdp) #ifdef CONFIG_HISOCK -BTF_ID_FLAGS(func, bpf_xdp_set_ingress_dst) BTF_ID_FLAGS(func, bpf_xdp_early_demux) BTF_ID_FLAGS(func, bpf_xdp_set_ingress_dev) -BTF_ID_FLAGS(func, bpf_xdp_change_dev) #endif BTF_SET8_END(bpf_kfunc_check_set_xdp) @@ -12236,12 +12161,7 @@ BTF_ID_FLAGS(func, bpf_sock_addr_set_sun_path) BTF_SET8_END(bpf_kfunc_check_set_sock_addr) #ifdef CONFIG_HISOCK -BTF_SET8_START(bpf_kfunc_check_set_sock_ops) -BTF_ID_FLAGS(func, bpf_skops_get_ingress_dst, KF_RET_NULL) -BTF_SET8_END(bpf_kfunc_check_set_sock_ops) - BTF_SET8_START(bpf_kfunc_check_set_hisock) -BTF_ID_FLAGS(func, bpf_skb_change_dev) BTF_ID_FLAGS(func, bpf_skb_set_egress_dev) BTF_SET8_END(bpf_kfunc_check_set_hisock) #endif @@ -12262,11 +12182,6 @@ static const struct btf_kfunc_id_set bpf_kfunc_set_sock_addr = { }; #ifdef CONFIG_HISOCK -static const struct btf_kfunc_id_set bpf_kfunc_set_sock_ops = { - .owner = THIS_MODULE, - .set = &bpf_kfunc_check_set_sock_ops, -}; - static const struct btf_kfunc_id_set bpf_kfunc_set_hisock = { .owner = THIS_MODULE, .set = &bpf_kfunc_check_set_hisock, @@ -12289,7 +12204,6 @@ static int __init bpf_kfunc_init(void) ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_NETFILTER, &bpf_kfunc_set_skb); ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_XDP, &bpf_kfunc_set_xdp); #ifdef CONFIG_HISOCK - ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_SOCK_OPS, &bpf_kfunc_set_sock_ops); ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_HISOCK, &bpf_kfunc_set_hisock); #endif return ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_CGROUP_SOCK_ADDR, -- 2.34.1
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
hulk inclusion category: featrue bugzilla: https://atomgit.com/openeuler/kernel/issues/7116 -------------------------------- Add ipv4-mapped ipv6 addr support for hisock. Signed-off-by: Pu Lehui <pulehui@huawei.com> --- samples/bpf/hisock/bpf.c | 54 +++++++++++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 6 deletions(-) diff --git a/samples/bpf/hisock/bpf.c b/samples/bpf/hisock/bpf.c index b76bba218304..777d1c19d38f 100644 --- a/samples/bpf/hisock/bpf.c +++ b/samples/bpf/hisock/bpf.c @@ -82,6 +82,12 @@ static inline bool is_speed_flow(u16 port) return false; } +static inline bool is_ipv6_addr_mapped(u32 *addr6) +{ + return addr6[0] == 0 && addr6[1] == 0 && + addr6[2] == bpf_htonl(0x0000ffff); +} + static inline unsigned long parse_ingress_dev(struct bpf_sock_ops *skops) { struct sk_buff *skb; @@ -120,13 +126,14 @@ static void handle_listen_cb(struct bpf_sock_ops *skops) } } -static void handle_establish_inet_cb(struct bpf_sock_ops *skops) +static inline void +handle_establish_cb(struct bpf_sock_ops *skops, u32 laddr, u32 raddr) { struct sock_tuple key = { 0 }; struct sock_value val = { 0 }; - key.saddr = skops->remote_ip4; - key.daddr = skops->local_ip4; + key.saddr = raddr; + key.daddr = laddr; key.sport = bpf_ntohl(skops->remote_port); key.dport = skops->local_port; @@ -138,7 +145,18 @@ static void handle_establish_inet_cb(struct bpf_sock_ops *skops) bpf_sock_ops_cb_flags_set(skops, BPF_SOCK_OPS_STATE_CB_FLAG); } -static void handle_terminate_inet_cb(struct bpf_sock_ops *skops) +static void handle_establish_inet_cb(struct bpf_sock_ops *skops) +{ + handle_establish_cb(skops, skops->local_ip4, skops->remote_ip4); +} + +static void handle_establish_inet6_cb(struct bpf_sock_ops *skops) +{ + handle_establish_cb(skops, skops->local_ip6[3], skops->remote_ip6[3]); +} + +static inline void +handle_terminate_cb(struct bpf_sock_ops *skops, u32 laddr, u32 raddr) { struct sock_tuple key = { 0 }; @@ -147,8 +165,8 @@ static void handle_terminate_inet_cb(struct bpf_sock_ops *skops) skops->args[1] != BPF_TCP_CLOSE) return; - key.saddr = skops->remote_ip4; - key.daddr = skops->local_ip4; + key.saddr = raddr; + key.daddr = laddr; key.sport = bpf_ntohl(skops->remote_port); key.dport = skops->local_port; @@ -158,6 +176,16 @@ static void handle_terminate_inet_cb(struct bpf_sock_ops *skops) skops->bpf_sock_ops_cb_flags & ~BPF_SOCK_OPS_STATE_CB_FLAG); } +static void handle_terminate_inet_cb(struct bpf_sock_ops *skops) +{ + handle_terminate_cb(skops, skops->local_ip4, skops->remote_ip4); +} + +static void handle_terminate_inet6_cb(struct bpf_sock_ops *skops) +{ + handle_terminate_cb(skops, skops->local_ip6[3], skops->remote_ip6[3]); +} + SEC("hisock_sockops") int hisock_sockops_prog(struct bpf_sock_ops *skops) { @@ -179,6 +207,20 @@ int hisock_sockops_prog(struct bpf_sock_ops *skops) default: break; } + } else if (skops->family == AF_INET6 && + is_ipv6_addr_mapped(skops->local_ip6)) { + switch (skops->op) { + case BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB: + if (!is_speed_flow(skops->local_port)) + break; + handle_establish_inet6_cb(skops); + break; + case BPF_SOCK_OPS_STATE_CB: + handle_terminate_inet6_cb(skops); + break; + default: + break; + } } return 1; -- 2.34.1
hulk inclusion category: featrue bugzilla: https://atomgit.com/openeuler/kernel/issues/7116 -------------------------------- Add local connect support for hisock. Signed-off-by: Pu Lehui <pulehui@huawei.com> --- samples/bpf/hisock/bpf.c | 67 +++++++++++++++++++++++ samples/bpf/hisock/hisock_cmd.c | 96 ++++++++++++++++++++++++++++++--- 2 files changed, 155 insertions(+), 8 deletions(-) diff --git a/samples/bpf/hisock/bpf.c b/samples/bpf/hisock/bpf.c index 777d1c19d38f..dcbd50bd6cf6 100644 --- a/samples/bpf/hisock/bpf.c +++ b/samples/bpf/hisock/bpf.c @@ -46,6 +46,10 @@ struct sock_value { u32 ingress_ifindex; }; +struct { + u32 local_mask; +} g_bss = {}; + struct { __uint(type, BPF_MAP_TYPE_HASH); __uint(key_size, sizeof(struct sock_tuple)); @@ -53,6 +57,13 @@ struct { __uint(max_entries, MAX_CONN); } connmap SEC(".maps"); +struct { + __uint(type, BPF_MAP_TYPE_SOCKHASH); + __uint(key_size, sizeof(struct sock_tuple)); + __uint(value_size, sizeof(int)); + __uint(max_entries, MAX_CONN); +} local_connmap SEC(".maps"); + struct { __uint(type, BPF_MAP_TYPE_HASH); __uint(key_size, sizeof(u16)); @@ -82,6 +93,12 @@ static inline bool is_speed_flow(u16 port) return false; } +static inline bool is_local_conn(u32 laddr, u32 raddr) +{ + return (bpf_ntohl(laddr) & g_bss.local_mask) == + (bpf_ntohl(raddr) & g_bss.local_mask); +} + static inline bool is_ipv6_addr_mapped(u32 *addr6) { return addr6[0] == 0 && addr6[1] == 0 && @@ -137,6 +154,11 @@ handle_establish_cb(struct bpf_sock_ops *skops, u32 laddr, u32 raddr) key.sport = bpf_ntohl(skops->remote_port); key.dport = skops->local_port; + if (is_local_conn(laddr, raddr)) { + bpf_sock_hash_update(skops, &local_connmap, &key, BPF_NOEXIST); + return; + } + val.sk = (unsigned long)skops->sk; val.ingress_dev = parse_ingress_dev(skops); @@ -201,6 +223,11 @@ int hisock_sockops_prog(struct bpf_sock_ops *skops) break; handle_establish_inet_cb(skops); break; + case BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB: + if (!is_speed_flow(bpf_ntohl(skops->remote_port))) + break; + handle_establish_inet_cb(skops); + break; case BPF_SOCK_OPS_STATE_CB: handle_terminate_inet_cb(skops); break; @@ -215,6 +242,11 @@ int hisock_sockops_prog(struct bpf_sock_ops *skops) break; handle_establish_inet6_cb(skops); break; + case BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB: + if (!is_speed_flow(bpf_ntohl(skops->remote_port))) + break; + handle_establish_inet6_cb(skops); + break; case BPF_SOCK_OPS_STATE_CB: handle_terminate_inet6_cb(skops); break; @@ -226,6 +258,41 @@ int hisock_sockops_prog(struct bpf_sock_ops *skops) return 1; } +static inline void +msg_redirect_cb(struct sk_msg_md *msg, u32 laddr, u32 raddr) +{ + struct sock_tuple key = { 0 }; + + key.daddr = raddr; + key.saddr = laddr; + key.dport = bpf_ntohl(msg->remote_port); + key.sport = msg->local_port; + + bpf_msg_redirect_hash(msg, &local_connmap, &key, BPF_F_INGRESS); +} + +static void msg_redirect_inet_cb(struct sk_msg_md *msg) +{ + msg_redirect_cb(msg, msg->local_ip4, msg->remote_ip4); +} + +static void msg_redirect_inet6_cb(struct sk_msg_md *msg) +{ + msg_redirect_cb(msg, msg->local_ip6[3], msg->remote_ip6[3]); +} + +SEC("hisock_skmsg") +int hisock_skmsg_prog(struct sk_msg_md *msg) +{ + if (msg->family == AF_INET) + msg_redirect_inet_cb(msg); + else if (msg->family == AF_INET6 && + is_ipv6_addr_mapped(msg->local_ip6)) + msg_redirect_inet6_cb(msg); + + return SK_PASS; +} + SEC("hisock_ingress") int hisock_ingress_prog(struct xdp_md *ctx) { diff --git a/samples/bpf/hisock/hisock_cmd.c b/samples/bpf/hisock/hisock_cmd.c index f44c98d529da..64a5a63ddb05 100644 --- a/samples/bpf/hisock/hisock_cmd.c +++ b/samples/bpf/hisock/hisock_cmd.c @@ -32,6 +32,8 @@ #define TASK_COMM_LEN 16 #endif +#define HISOCK_BPFFS "/sys/fs/bpf/hisock" +#define DEF_LOCAL_MASK 0xFFFF0000 #define DEF_BPF_PATH "bpf.o" #define MAX_IF_NUM 8 #define MAX_PORT_NUM 8 @@ -44,6 +46,7 @@ struct { int port_num; char *comm[MAX_COMM_NUM]; int comm_num; + __u32 local_mask; char *cgrp_path; char *bpf_path; bool unload; @@ -51,20 +54,31 @@ struct { struct hisock_prog_info { const char *prog_name; + const char *pin_map; enum bpf_prog_type prog_type; enum bpf_attach_type attach_type; int attach_flag; int prog_fd; + bool is_skmsg; bool is_xdp; }; +struct bss { + __u32 local_mask; +}; + static struct hisock_prog_info prog_infos[] = { { .prog_name = "hisock_sockops_prog", .prog_type = BPF_PROG_TYPE_SOCK_OPS, .attach_type = BPF_CGROUP_SOCK_OPS, - .attach_flag = 0, - .is_xdp = false, + }, + { + .prog_name = "hisock_skmsg_prog", + .prog_type = BPF_PROG_TYPE_SK_MSG, + .attach_type = BPF_SK_MSG_VERDICT, + .pin_map = "local_connmap", + .is_skmsg = true, }, { .prog_name = "hisock_ingress_prog", @@ -77,8 +91,6 @@ static struct hisock_prog_info prog_infos[] = { .prog_name = "hisock_egress_prog", .prog_type = BPF_PROG_TYPE_HISOCK, .attach_type = BPF_HISOCK_EGRESS, - .attach_flag = 0, - .is_xdp = false, }, }; @@ -231,6 +243,30 @@ static int set_target_comm(struct bpf_object *obj) return 0; } +static int set_global_bss(struct bpf_object *obj) +{ + struct bpf_map *bss_map; + struct bss g_bss; + int zero = 0; + int map_fd; + + g_bss.local_mask = hisock.local_mask ?: DEF_LOCAL_MASK; + + bss_map = bpf_object__find_map_by_name(obj, ".bss"); + if (!bss_map) { + fprintf(stderr, "ERROR: failed to find bss map\n"); + return -1; + } + + map_fd = bpf_map__fd(bss_map); + if (bpf_map_update_elem(map_fd, &zero, &g_bss, BPF_ANY) < 0) { + fprintf(stderr, "ERROR: failed to update bss map\n"); + return -1; + } + + return 0; +} + static int detach_progs(void) { struct hisock_prog_info *info; @@ -258,6 +294,16 @@ static int detach_progs(void) continue; } + if (info->is_skmsg) { + char pin_path[64]; + + snprintf(pin_path, sizeof(pin_path), "%s/%s", + HISOCK_BPFFS, info->pin_map); + + unlink(pin_path); + continue; + } + if (bpf_prog_detach(cgrp_fd, info->attach_type)) { fprintf(stderr, "ERROR: failed to detach prog %s\n", info->prog_name); err_cnt++; @@ -268,7 +314,7 @@ static int detach_progs(void) return -err_cnt; } -static int attach_progs(void) +static int attach_progs(struct bpf_object *obj) { struct hisock_prog_info *info; int i, j, cgrp_fd; @@ -290,6 +336,31 @@ static int attach_progs(void) continue; } + if (info->is_skmsg) { + struct bpf_map *map; + char pin_path[64]; + + map = bpf_object__find_map_by_name(obj, info->pin_map); + if (!map) { + fprintf(stderr, "ERROR: failed to find pin map\n"); + goto fail; + } + + snprintf(pin_path, sizeof(pin_path), "%s/%s", + HISOCK_BPFFS, info->pin_map); + + if (bpf_map__pin(map, pin_path)) { + fprintf(stderr, "ERROR: failed to pin map\n"); + goto fail; + } + + if (bpf_prog_attach(info->prog_fd, bpf_map__fd(map), + info->attach_type, info->attach_flag)) + goto fail; + + continue; + } + if (bpf_prog_attach(info->prog_fd, cgrp_fd, info->attach_type, info->attach_flag)) goto fail; @@ -347,7 +418,13 @@ static int do_hisock(void) return -1; } - if (attach_progs()) { + if (set_global_bss(obj)) { + fprintf(stderr, "ERROR: failed to set global bss\n"); + bpf_object__close(obj); + return -1; + } + + if (attach_progs(obj)) { fprintf(stderr, "ERROR: failed to attach progs\n"); bpf_object__close(obj); return -1; @@ -361,7 +438,7 @@ static void do_help(void) { fprintf(stderr, "Load: hisock_cmd [-f BPF_FILE] [-c CGRP_PATH] " - "[-p PORT] [-C COMM] [-i INTERFACE]\n" + "[-p PORT] [-C COMM] [-m LOCAL_MASK] [-i INTERFACE]\n" "Unload: hisock_cmd -u [-c CGRP_PATH] [-i INTERFACE]\n"); } @@ -371,7 +448,7 @@ static int parse_args(int argc, char **argv) hisock.bpf_path = DEF_BPF_PATH; - while ((opt = getopt(argc, argv, "f:c:p:i:C:uh")) != -1) { + while ((opt = getopt(argc, argv, "f:c:p:i:C:m:uh")) != -1) { switch (opt) { case 'f': hisock.bpf_path = optarg; @@ -391,6 +468,9 @@ static int parse_args(int argc, char **argv) hisock.comm[hisock.comm_num] = optarg; hisock.comm_num++; break; + case 'm': + hisock.local_mask = (__u32)strtoul(optarg, NULL, 16); + break; case 'u': hisock.unload = true; break; -- 2.34.1
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://atomgit.com/openeuler/kernel/merge_requests/20122 邮件列表地址:https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/H5I... FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://atomgit.com/openeuler/kernel/merge_requests/20122 Mailing list address: https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/H5I...
participants (2)
-
patchwork bot -
Pu Lehui