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