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