hulk inclusion category: featrue bugzilla: https://atomgit.com/openeuler/kernel/issues/8480 -------------------------------- Add bpf_set_ingress_dst helper function to set the receive dst entry of sock to ingress skb. Signed-off-by: Pu Lehui <pulehui@huawei.com> --- include/uapi/linux/bpf.h | 15 +++++++++---- net/core/filter.c | 39 ++++++++++++++++++++++++++++++++-- samples/bpf/hisock/bpf.c | 4 ++-- tools/include/uapi/linux/bpf.h | 15 +++++++++---- 4 files changed, 61 insertions(+), 12 deletions(-) diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index faf056fccf13..3a415984bc27 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -3944,14 +3944,14 @@ union bpf_attr { * Return * 0 on success, or a negative error in case of failure. * - * void *bpf_get_ingress_dst(struct bpf_sock_ops *skops) + * void *bpf_get_rx_dst(struct bpf_sock_ops *skops) * Description * Get the ingress dst entry of the full sock. * Return * Valid ingress dst on success, or negative error * in case of failure. * - * int bpf_set_ingress_dst(struct xdp_buff *xdp, void *dst) + * int bpf_set_rx_dst(struct xdp_buff *xdp, void *dst) * Description * Set valid ingress dst entry to the skb associated * with xdp_buff. @@ -3974,6 +3974,12 @@ union bpf_attr { * Copy *src_sz* bytes from *src* to *dst* if *dst_sz* >= *src_sz*. * Return * 0 on success, or negative error in case of failure. + * + * int bpf_set_ingress_dst(struct sk_buff *skb, void *sk) + * Description + * Set skb ingress dst entry with valid sock rx dst entry. + * Return + * 0 on success, or a negative error in case of failure. */ #define __BPF_FUNC_MAPPER(FN) \ FN(unspec), \ @@ -4152,10 +4158,11 @@ union bpf_attr { FN(get_node_stats), \ FN(sched_net_rship_submit), \ FN(sched_set_task_prefer_cpumask), \ - FN(get_ingress_dst), \ - FN(set_ingress_dst), \ + FN(get_rx_dst), \ + FN(set_rx_dst), \ FN(change_skb_dev), \ FN(ext_memcpy), \ + FN(set_ingress_dst), \ /* */ /* integer value in 'imm' field of BPF_CALL instruction selects which helper diff --git a/net/core/filter.c b/net/core/filter.c index cec7eace2d5c..ff0a2845ae13 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -3701,6 +3701,36 @@ static const struct bpf_func_proto bpf_skb_adjust_room_proto = { }; #ifdef CONFIG_HISOCK +BPF_CALL_2(bpf_set_ingress_dst, struct sk_buff *, skb, unsigned long, _sk) +{ + struct sock *sk = (struct sock *)_sk; + struct dst_entry *dst; + + WARN_ON_ONCE(!rcu_read_lock_held()); + + 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 && inet_sk(sk)->rx_dst_ifindex == skb->skb_iif) + skb_dst_set_noref(skb, dst); + + return 0; +} + +static const struct bpf_func_proto bpf_set_ingress_dst_proto = { + .func = bpf_set_ingress_dst, + .gpl_only = false, + .ret_type = RET_INTEGER, + .arg1_type = ARG_PTR_TO_CTX, + .arg2_type = ARG_ANYTHING, +}; + BPF_CALL_2(bpf_skb_change_skb_dev, struct sk_buff *, skb, u32, ifindex) { struct net_device *dev; @@ -7410,6 +7440,8 @@ cg_skb_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) static const struct bpf_func_proto * hisock_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) { + bool is_ingress = prog->expected_attach_type == BPF_HISOCK_INGRESS; + switch (func_id) { case BPF_FUNC_skb_store_bytes: return &bpf_skb_store_bytes_proto; @@ -7425,6 +7457,9 @@ hisock_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) return &bpf_skb_adjust_room_proto; case BPF_FUNC_change_skb_dev: return &bpf_skb_change_skb_dev_proto; + case BPF_FUNC_set_ingress_dst: + return is_ingress ? &bpf_set_ingress_dst_proto : NULL; + default: return bpf_base_func_proto(func_id); } @@ -7575,7 +7610,7 @@ xdp_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) case BPF_FUNC_fib_lookup: return &bpf_xdp_fib_lookup_proto; #ifdef CONFIG_HISOCK - case BPF_FUNC_set_ingress_dst: + case BPF_FUNC_set_rx_dst: return &bpf_xdp_set_ingress_dst_proto; case BPF_FUNC_change_skb_dev: return &bpf_xdp_change_skb_dev_proto; @@ -7642,7 +7677,7 @@ sock_ops_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) case BPF_FUNC_reserve_hdr_opt: return &bpf_sock_ops_reserve_hdr_opt_proto; #ifdef CONFIG_HISOCK - case BPF_FUNC_get_ingress_dst: + case BPF_FUNC_get_rx_dst: return &bpf_sock_ops_get_ingress_dst_proto; #endif case BPF_FUNC_tcp_sock: diff --git a/samples/bpf/hisock/bpf.c b/samples/bpf/hisock/bpf.c index 375f33fdf2e7..c87ddad7fe2f 100644 --- a/samples/bpf/hisock/bpf.c +++ b/samples/bpf/hisock/bpf.c @@ -84,7 +84,7 @@ int hisock_sockops_prog(struct bpf_sock_ops *skops) switch (skops->op) { case BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB: case BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB: - dst = bpf_get_ingress_dst(skops); + dst = bpf_get_rx_dst(skops); if (!dst) return SOCKOPS_FAIL; @@ -178,7 +178,7 @@ int hisock_ingress_prog(struct xdp_md *ctx) val->ingress_ifindex = ctx->ingress_ifindex; if (likely(val->ingress_dst)) - bpf_set_ingress_dst(ctx, val->ingress_dst); + bpf_set_rx_dst(ctx, val->ingress_dst); return XDP_HISOCK_REDIRECT; } diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 3501e5461a0a..48c0c054f82d 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -3944,14 +3944,14 @@ union bpf_attr { * Return * 0 on success, or a negative error in case of failure. * - * void *bpf_get_ingress_dst(struct bpf_sock_ops *skops) + * void *bpf_get_rx_dst(struct bpf_sock_ops *skops) * Description * Get the ingress dst entry of the full sock. * Return * Valid ingress dst on success, or negative error * in case of failure. * - * int bpf_set_ingress_dst(struct xdp_buff *xdp, void *dst) + * int bpf_set_rx_dst(struct xdp_buff *xdp, void *dst) * Description * Set valid ingress dst entry to the skb associated * with xdp_buff. @@ -3974,6 +3974,12 @@ union bpf_attr { * Copy *src_sz* bytes from *src* to *dst* if *dst_sz* >= *src_sz*. * Return * 0 on success, or negative error in case of failure. + * + * int bpf_set_ingress_dst(struct sk_buff *skb, void *sk) + * Description + * Set skb ingress dst entry with valid sock rx dst entry. + * Return + * 0 on success, or a negative error in case of failure. */ #define __BPF_FUNC_MAPPER(FN) \ FN(unspec), \ @@ -4152,10 +4158,11 @@ union bpf_attr { FN(get_node_stats), \ FN(sched_net_rship_submit), \ FN(sched_set_task_prefer_cpumask), \ - FN(get_ingress_dst), \ - FN(set_ingress_dst), \ + FN(get_rx_dst), \ + FN(set_rx_dst), \ FN(change_skb_dev), \ FN(ext_memcpy), \ + FN(set_ingress_dst), \ /* */ /* integer value in 'imm' field of BPF_CALL instruction selects which helper -- 2.34.1