Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b32cc5b9 authored by Nikita V. Shirokov's avatar Nikita V. Shirokov Committed by Daniel Borkmann
Browse files

bpf: adding bpf_xdp_adjust_tail helper



Adding new bpf helper which would allow us to manipulate
xdp's data_end pointer, and allow us to reduce packet's size
indended use case: to generate ICMP messages from XDP context,
where such message would contain truncated original packet.

Signed-off-by: default avatarNikita V. Shirokov <tehnerd@tehnerd.com>
Acked-by: default avatarAlexei Starovoitov <ast@kernel.org>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
parent 0c90f224
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -755,6 +755,13 @@ union bpf_attr {
 *     @addr: pointer to struct sockaddr to bind socket to
 *     @addr_len: length of sockaddr structure
 *     Return: 0 on success or negative error code
 *
 * int bpf_xdp_adjust_tail(xdp_md, delta)
 *     Adjust the xdp_md.data_end by delta. Only shrinking of packet's
 *     size is supported.
 *     @xdp_md: pointer to xdp_md
 *     @delta: A negative integer to be added to xdp_md.data_end
 *     Return: 0 on success or negative on error
 */
#define __BPF_FUNC_MAPPER(FN)		\
	FN(unspec),			\
@@ -821,7 +828,8 @@ union bpf_attr {
	FN(msg_apply_bytes),		\
	FN(msg_cork_bytes),		\
	FN(msg_pull_data),		\
	FN(bind),
	FN(bind),			\
	FN(xdp_adjust_tail),

/* integer value in 'imm' field of BPF_CALL instruction selects which helper
 * function eBPF program intends to call
+28 −1
Original line number Diff line number Diff line
@@ -2725,6 +2725,30 @@ static const struct bpf_func_proto bpf_xdp_adjust_head_proto = {
	.arg2_type	= ARG_ANYTHING,
};

BPF_CALL_2(bpf_xdp_adjust_tail, struct xdp_buff *, xdp, int, offset)
{
	void *data_end = xdp->data_end + offset;

	/* only shrinking is allowed for now. */
	if (unlikely(offset >= 0))
		return -EINVAL;

	if (unlikely(data_end < xdp->data + ETH_HLEN))
		return -EINVAL;

	xdp->data_end = data_end;

	return 0;
}

static const struct bpf_func_proto bpf_xdp_adjust_tail_proto = {
	.func		= bpf_xdp_adjust_tail,
	.gpl_only	= false,
	.ret_type	= RET_INTEGER,
	.arg1_type	= ARG_PTR_TO_CTX,
	.arg2_type	= ARG_ANYTHING,
};

BPF_CALL_2(bpf_xdp_adjust_meta, struct xdp_buff *, xdp, int, offset)
{
	void *meta = xdp->data_meta + offset;
@@ -3074,7 +3098,8 @@ bool bpf_helper_changes_pkt_data(void *func)
	    func == bpf_l4_csum_replace ||
	    func == bpf_xdp_adjust_head ||
	    func == bpf_xdp_adjust_meta ||
	    func == bpf_msg_pull_data)
	    func == bpf_msg_pull_data ||
	    func == bpf_xdp_adjust_tail)
		return true;

	return false;
@@ -3888,6 +3913,8 @@ xdp_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
		return &bpf_xdp_redirect_proto;
	case BPF_FUNC_redirect_map:
		return &bpf_xdp_redirect_map_proto;
	case BPF_FUNC_xdp_adjust_tail:
		return &bpf_xdp_adjust_tail_proto;
	default:
		return bpf_base_func_proto(func_id);
	}