From: Xu Kuohai xukuohai@huawei.com
Offering: HULK hulk inclusion category: feature bugzilla: N/A
--------------------------------
Add sample helper to store bytes to XDP buffer and load bytes from XDP buffer.
Signed-off-by: Xu Kuohai xukuohai@huawei.com --- include/uapi/linux/bpf.h | 16 ++++++++++++ net/core/filter.c | 48 ++++++++++++++++++++++++++++++++++ tools/include/uapi/linux/bpf.h | 16 ++++++++++++ 3 files changed, 80 insertions(+)
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index dd54acedc646..db585d960d64 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -4056,6 +4056,20 @@ union bpf_attr { * Update tcp seq * Return * 0 on success, or a negative error in case of failure. + * + * int bpf_xdp_store_bytes(struct xdp_buff *ctx, u32 offset, const void *from, u32 len) + * Description + * store *len* bytes from address *from* into xdp buffer *ctx*, at + * *offset* + * Return + * 0 on success, or a negative error in case of failure. + * + * int bpf_xdp_load_bytes(struct xdp_buff *ctx, u32 offset, void *to, u32 len) + * Description + * load *len* bytes to address *to* from xdp buffer *ctx*, at + * *offset* + * Return + * 0 on success, or a negative error in case of failure. */ #define __BPF_FUNC_MAPPER(FN) \ FN(unspec), \ @@ -4242,6 +4256,8 @@ union bpf_attr { FN(sys_close), \ FN(kallsyms_lookup_name), \ FN(update_tcp_seq), \ + FN(xdp_store_bytes), \ + FN(xdp_load_bytes), \ /* */
/* 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 3065b103f65e..2750e94b025d 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -6287,6 +6287,50 @@ static const struct bpf_func_proto bpf_xdp_update_tcp_seq_proto = { .arg5_type = ARG_ANYTHING, };
+BPF_CALL_4(bpf_xdp_store_bytes, struct xdp_buff *, xdp, u32, offset, + const void *, from, u32, len) +{ + if (unlikely(offset > xdp->data_end - xdp->data || + len > xdp->data_end - xdp->data - offset)) + return -EINVAL; + + memmove(xdp->data + offset, from, len); + + return 0; +} + +static const struct bpf_func_proto bpf_xdp_store_bytes_proto = { + .func = bpf_xdp_store_bytes, + .gpl_only = false, + .ret_type = RET_INTEGER, + .arg1_type = ARG_PTR_TO_CTX, + .arg2_type = ARG_ANYTHING, + .arg3_type = ARG_ANYTHING, + .arg4_type = ARG_ANYTHING, +}; + +BPF_CALL_4(bpf_xdp_load_bytes, struct xdp_buff *, xdp, u32, offset, + void *, to, u32, len) +{ + if (unlikely(offset > xdp->data_end - xdp->data || + len > xdp->data_end - xdp->data - offset)) + return -EINVAL; + + memmove(to, xdp->data + offset, len); + + return 0; +} + +static const struct bpf_func_proto bpf_xdp_load_bytes_proto = { + .func = bpf_xdp_load_bytes, + .gpl_only = false, + .ret_type = RET_INTEGER, + .arg1_type = ARG_PTR_TO_CTX, + .arg2_type = ARG_ANYTHING, + .arg3_type = ARG_ANYTHING, + .arg4_type = ARG_ANYTHING, +}; + BPF_CALL_5(bpf_sock_addr_skc_lookup_tcp, struct bpf_sock_addr_kern *, ctx, struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags) { @@ -7376,6 +7420,10 @@ xdp_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) case BPF_FUNC_tcp_gen_syncookie: return &bpf_tcp_gen_syncookie_proto; #endif + case BPF_FUNC_xdp_store_bytes: + return &bpf_xdp_store_bytes_proto; + case BPF_FUNC_xdp_load_bytes: + return &bpf_xdp_load_bytes_proto; default: return bpf_sk_base_func_proto(func_id); } diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 4f86c2187ada..57b927e99092 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -4766,6 +4766,20 @@ union bpf_attr { * Update tcp seq * Return * 0 on success, or a negative error in case of failure. + * + * int bpf_xdp_store_bytes(struct xdp_buff *ctx, u32 offset, const void *from, u32 len) + * Description + * store *len* bytes from address *from* into xdp buffer *ctx*, at + * *offset* + * Return + * 0 on success, or a negative error in case of failure. + * + * int bpf_xdp_load_bytes(struct xdp_buff *ctx, u32 offset, void *to, u32 len) + * Description + * load *len* bytes to address *to* from xdp buffer *ctx*, at + * *offset* + * Return + * 0 on success, or a negative error in case of failure. */ #define __BPF_FUNC_MAPPER(FN) \ FN(unspec), \ @@ -4952,6 +4966,8 @@ union bpf_attr { FN(sys_close), \ FN(kallsyms_lookup_name), \ FN(update_tcp_seq), \ + FN(xdp_store_bytes), \ + FN(xdp_load_bytes), \ /* */
/* integer value in 'imm' field of BPF_CALL instruction selects which helper