introduction of bpf_xdp_adjust_tail
Subsystems (14)
v2 cover introduction of bpf_xdp_adjust_tail
In this patch series i'm add new bpf helper which allow to manupulate xdp's data_end pointer. right now only "shrinking" (reduce packet's size by moving pointer) is supported (and i see no use case for "growing"). Main use case for such helper is to be able to generate controll (ICMP) messages from XDP context. such messages usually contains first N bytes from original packets as a payload, and this is exactly what this helper would allow us to do (see patch 3 for sample program, where we generate ICMP "packet too big" message). This helper could be usefull for load balancing applications where after additional encapsulation, resulting packet could be bigger then interface MTU.
Aside from new helper this patch series contains minor changes in device drivers (for ones which requires), so they would recal packet's length not only when head pointer was adjusted, but if tail's one as well.
v1->v2:
* fixed kbuild warning
* made offset eq 0 invalid for xdp_bpf_adjust_tail
* splitted bpf_prog_test_run fix and selftests in sep commits
* added SPDX licence where applicable
* some reshuffling in patches order (tests now in the end)
Nikita V. Shirokov (11):
bpf: making bpf_prog_test run aware of possible data_end ptr change
bpf: adding tests for bpf_xdp_adjust_tail
bpf: adding bpf_xdp_adjust_tail helper
bpf: make generic xdp compatible w/ bpf_xdp_adjust_tail
bpf: make mlx4 compatible w/ bpf_xdp_adjust_tail
bpf: make bnxt compatible w/ bpf_xdp_adjust_tail
bpf: make cavium thunder compatible w/ bpf_xdp_adjust_tail
bpf: make netronome nfp compatible w/ bpf_xdp_adjust_tail
bpf: make tun compatible w/ bpf_xdp_adjust_tail
bpf: make virtio compatible w/ bpf_xdp_adjust_tail
bpf: add bpf_xdp_adjust_tail sample prog
drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c | 2 +- drivers/net/ethernet/cavium/thunder/nicvf_main.c | 2 +- drivers/net/ethernet/mellanox/mlx4/en_rx.c | 2 +- .../net/ethernet/netronome/nfp/nfp_net_common.c | 2 +- drivers/net/tun.c | 3 +- drivers/net/virtio_net.c | 7 +- include/uapi/linux/bpf.h | 10 +- net/bpf/test_run.c | 3 +- net/core/dev.c | 10 +- net/core/filter.c | 29 +++- samples/bpf/Makefile | 4 + samples/bpf/xdp_adjust_tail_kern.c | 152 +++++++++++++++++++++ samples/bpf/xdp_adjust_tail_user.c | 142 +++++++++++++++++++ tools/include/uapi/linux/bpf.h | 10 +- tools/testing/selftests/bpf/Makefile | 2 +- tools/testing/selftests/bpf/bpf_helpers.h | 5 + tools/testing/selftests/bpf/test_adjust_tail.c | 30 ++++ tools/testing/selftests/bpf/test_progs.c | 32 +++++ 18 files changed, 435 insertions(+), 12 deletions(-) create mode 100644 samples/bpf/xdp_adjust_tail_kern.c create mode 100644 samples/bpf/xdp_adjust_tail_user.c create mode 100644 tools/testing/selftests/bpf/test_adjust_tail.c
Signature · 1 line
2.15.1
PATCH v2 1/11 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.
--- include/uapi/linux/bpf.h | 10 +++++++++- net/core/filter.c | 29 ++++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 2 deletions(-)
include/uapi/linux/bpf.h +9 -1
@@ -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
net/core/filter.c +28 -1
@@ -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); }
Signature · 1 line
2.15.1
Re: [PATCH bpf-next v2 01/11] bpf: adding bpf_xdp_adjust_tail helper
Quoted 5 lines · Nikita V. Shirokov
Adding new bpf helper which would allow us to manipulate xdp's
data_endpointer, 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.
---
your SOB is now missing in all patches.
PATCH v2 2/11 bpf: make generic xdp compatible w/ bpf_xdp_adjust_tail
In reply to Nikita V. Shirokovw/ bpf_xdp_adjust_tail helper xdp's data_end pointer could be changed as well (only "decrease" of pointer's location is going to be supported). changing of this pointer will change packet's size.
for generic XDP we need to reflect this packet's length change by adjusting skb's tail pointer
--- net/core/dev.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
net/core/dev.c +9 -1
@@ -3996,9 +3996,9 @@ static u32 netif_receive_generic_xdp(struct sk_buff *skb, struct bpf_prog *xdp_prog) {struct netdev_rx_queue *rxqueue; +void *orig_data, *orig_data_end;u32 metalen, act =XDP_DROP ;struct xdp_buff xdp; -void *orig_data;int hlen, off;u32 mac_len;
@@ -4037,6 +4037,7 @@ static u32 netif_receive_generic_xdp(struct sk_buff *skb, xdp.data_meta = xdp.data; xdp.data_end = xdp.data + hlen; xdp.data_hard_start = skb->data -skb_headroom (skb); + orig_data_end = xdp.data_end; orig_data = xdp.data; rxqueue =netif_get_rxqueue (skb);
@@ -4051,6 +4052,13 @@ static u32 netif_receive_generic_xdp(struct sk_buff *skb,__skb_push (skb, -off); skb->mac_header += off; +/* check if bpf_xdp_adjust_tail was used. it can only "shrink" +* pckt. +*/ + off = orig_data_end - xdp.data_end; +if (off !=0 ) +skb_set_tail_pointer (skb, xdp.data_end - xdp.data); +switch (act) {case XDP_REDIRECT :case XDP_TX :
Signature · 1 line
2.15.1
Re: [PATCH bpf-next v2 02/11] bpf: make generic xdp compatible w/ bpf_xdp_adjust_tail
Quoted 7 lines · On Tue, 17 Apr 2018 21:29:42 -0700 "Nikita V. Shirokov" <[email protected]>…
w/
bpf_xdp_adjust_tailhelper xdp'sdata_endpointer could be changed as well (only "decrease" of pointer's location is going to be supported). changing of this pointer will change packet's size.
for generic XDP we need to reflect this packet's length change by adjusting skb's tail pointer
You are missing your own Signed-off-by: line on all of the patches.
BTW, thank you for working on this! It have been on my todo-list for a while now!
_After_ this patchset, I would like to see adding support for "increasing" the data_end location to create a larger packet. For that we should likely add a data_hard_end pointer. This, would also be helpful in cpu_map_build_skb() to know the data_hard_end, to determine the frame size (as some driver doesn't use PAGE_SIZE frames, ixgbe).
Signature · 4 lines
Best regards, Jesper Dangaard Brouer MSc.CS, Principal Kernel Engineer at Red Hat LinkedIn: http://www.linkedin.com/in/brouer
Re: [PATCH bpf-next v2 02/11] bpf: make generic xdp compatible w/ bpf_xdp_adjust_tail
Quoted 9 lines · Jesper Dangaard Brouer
Quoted 6 lines · On Tue, 17 Apr 2018 21:29:42 -0700 "Nikita V. Shirokov" <[email protected]>…
w/
bpf_xdp_adjust_tailhelper xdp'sdata_endpointer could be changed as well (only "decrease" of pointer's location is going to be supported). changing of this pointer will change packet's size.
for generic XDP we need to reflect this packet's length change by adjusting skb's tail pointer
Quoted 4 lines
Quoted 1 line
You are missing your own Signed-off-by: line on all of the patches.
yeah, somehow lost it between v1 and v2 :) thanks !
Quoted 9 lines
BTW, thank you for working on this! It have been on my todo-list for a while now!
_After_ this patchset, I would like to see adding support for "increasing" the
data_endlocation to create a larger packet. For that we should likely add adata_hard_endpointer. This, would also be helpful incpu_map_build_skb()to know thedata_hard_end, to determine the frame size (as some driver doesn't usePAGE_SIZEframes, ixgbe).
yeah, increasing the size would be nice to have, but will require more thinking / rework on drivers side (as you pointed out it's not as easy as "every driver have at least PAGE_SIZE of data available for xdp".). will add to my TODO
Quoted 6 lines
Signature · 5 lines
-- Best regards, Jesper Dangaard Brouer MSc.CS, Principal Kernel Engineer at Red Hat LinkedIn: http://www.linkedin.com/in/brouer
PATCH v2 3/11 bpf: make mlx4 compatible w/ bpf_xdp_adjust_tail
In reply to Nikita V. Shirokovw/ bpf_xdp_adjust_tail helper xdp's data_end pointer could be changed as well (only "decrease" of pointer's location is going to be supported). changing of this pointer will change packet's size.
for mlx4 driver we will just calculate packet's length unconditionally (the same way as it's already being done in mlx5)
--- drivers/net/ethernet/mellanox/mlx4/en_rx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/mellanox/mlx4/en_rx.c +1 -1
@@ -775,8 +775,8 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud act =bpf_prog_run_xdp (xdp_prog, &xdp); + length = xdp.data_end - xdp.data;if (xdp.data != orig_data) { - length = xdp.data_end - xdp.data; frags[0 ].page_offset = xdp.data - xdp.data_hard_start; va = xdp.data;
Signature · 1 line
2.15.1
Re: [PATCH bpf-next v2 03/11] bpf: make mlx4 compatible w/ bpf_xdp_adjust_tail
Quoted 17 lines · Nikita V. Shirokov
w/
bpf_xdp_adjust_tailhelper xdp'sdata_endpointer could be changed as well (only "decrease" of pointer's location is going to be supported). changing of this pointer will change packet's size.
for mlx4 driver we will just calculate packet's length unconditionally (the same way as it's already being done in mlx5)--- drivers/net/ethernet/mellanox/mlx4/en_rx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)drivers/net/ethernet/mellanox/mlx4/en_rx.c +0
-0
drivers/net/ethernet/mellanox/mlx4/en_rx.c int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud · line 782
Quoted 9 lines
drivers/net/ethernet/mellanox/mlx4/en_rx.c +1
-1@@ -775,8 +775,8 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud act =bpf_prog_run_xdp (xdp_prog, &xdp); + length = xdp.data_end - xdp.data;if (xdp.data != orig_data) { - length = xdp.data_end - xdp.data; frags[0 ].page_offset = xdp.data - xdp.data_hard_start; va = xdp.data;
Thanks.
PATCH v2 4/11 bpf: make bnxt compatible w/ bpf_xdp_adjust_tail
In reply to Nikita V. Shirokovw/ bpf_xdp_adjust_tail helper xdp's data_end pointer could be changed as well (only "decrease" of pointer's location is going to be supported). changing of this pointer will change packet's size.
for bnxt driver we will just calculate packet's length unconditionally
--- drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c +1 -1
@@ -113,10 +113,10 @@ bool bnxt_rx_xdp(struct bnxt *bp, struct bnxt_rx_ring_info *rxr, u16 cons,if (tx_avail != bp->tx_ring_size) *event &= ~BNXT_RX_EVENT ; + *len = xdp.data_end - xdp.data;if (orig_data != xdp.data) { offset = xdp.data - xdp.data_hard_start; *data_ptr = xdp.data_hard_start + offset; - *len = xdp.data_end - xdp.data; }switch (act) {case XDP_PASS :
Signature · 1 line
2.15.1
PATCH v2 5/11 bpf: make cavium thunder compatible w/ bpf_xdp_adjust_tail
In reply to Nikita V. Shirokovw/ bpf_xdp_adjust_tail helper xdp's data_end pointer could be changed as well (only "decrease" of pointer's location is going to be supported). changing of this pointer will change packet's size.
for cavium's thunder driver we will just calculate packet's length unconditionally
--- drivers/net/ethernet/cavium/thunder/nicvf_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/cavium/thunder/nicvf_main.c +1 -1
@@ -538,9 +538,9 @@ static inline bool nicvf_xdp_rx(struct nicvf *nic, struct bpf_prog *prog, action =bpf_prog_run_xdp (prog, &xdp);rcu_read_unlock (); + len = xdp.data_end - xdp.data;/* Check if XDP program has changed headers */ if (orig_data != xdp.data) { - len = xdp.data_end - xdp.data; offset = orig_data - xdp.data; dma_addr -= offset; }
Signature · 1 line
2.15.1
PATCH v2 6/11 bpf: make netronome nfp compatible w/ bpf_xdp_adjust_tail
In reply to Nikita V. Shirokovw/ bpf_xdp_adjust_tail helper xdp's data_end pointer could be changed as well (only "decrease" of pointer's location is going to be supported). changing of this pointer will change packet's size.
for nfp driver we will just calculate packet's length unconditionally
--- drivers/net/ethernet/netronome/nfp/nfp_net_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/netronome/nfp/nfp_net_common.c +1 -1
@@ -1722,7 +1722,7 @@ static int nfp_net_rx(struct nfp_net_rx_ring *rx_ring, int budget) act =bpf_prog_run_xdp (xdp_prog, &xdp); - pkt_len -= xdp.data - orig_data; + pkt_len = xdp.data_end - xdp.data; pkt_off += xdp.data - orig_data;switch (act) {
Signature · 1 line
2.15.1
PATCH v2 7/11 bpf: make tun compatible w/ bpf_xdp_adjust_tail
In reply to Nikita V. Shirokovw/ bpf_xdp_adjust_tail helper xdp's data_end pointer could be changed as well (only "decrease" of pointer's location is going to be supported). changing of this pointer will change packet's size.
for tun driver we need to adjust XDP_PASS handling by recalculating length of the packet if it was passed to the TCP/IP stack (in case if after xdp's prog run data_end pointer was adjusted)
--- drivers/net/tun.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/tun.c +2 -1
@@ -1696,6 +1696,7 @@ static struct sk_buff *tun_build_skb(struct tun_struct *tun,return NULL ;case XDP_PASS : delta = orig_data - xdp.data; + len = xdp.data_end - xdp.data;break ;default :bpf_warn_invalid_xdp_action (act);
@@ -1716,7 +1717,7 @@ static struct sk_buff *tun_build_skb(struct tun_struct *tun, }skb_reserve (skb, pad - delta); -skb_put (skb, len + delta); +skb_put (skb, len);get_page (alloc_frag->page); alloc_frag->offset += buflen;
Signature · 1 line
2.15.1
PATCH v2 8/11 bpf: make virtio compatible w/ bpf_xdp_adjust_tail
In reply to Nikita V. Shirokovw/ bpf_xdp_adjust_tail helper xdp's data_end pointer could be changed as well (only "decrease" of pointer's location is going to be supported). changing of this pointer will change packet's size.
for virtio driver we need to adjust XDP_PASS handling by recalculating length of the packet if it was passed to the TCP/IP stack
--- drivers/net/virtio_net.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/net/virtio_net.c +6 -1
@@ -606,6 +606,7 @@ static struct sk_buff *receive_small(struct net_device *dev,case XDP_PASS :/* Recalculate length in case bpf program changed it */ delta = orig_data - xdp.data; + len = xdp.data_end - xdp.data;break ;case XDP_TX : xdpf =convert_to_xdp_frame (&xdp);
@@ -642,7 +643,7 @@ static struct sk_buff *receive_small(struct net_device *dev, goto err; }skb_reserve (skb, headroom - delta); -skb_put (skb, len + delta); +skb_put (skb, len);if (!delta) { buf += header_offset;memcpy (skb_vnet_hdr (skb), buf, vi->hdr_len);
@@ -757,6 +758,10 @@ static struct sk_buff *receive_mergeable(struct net_device *dev, offset = xdp.data -page_address (xdp_page) - vi->hdr_len; +/* recalculate len if xdp.data or xdp.data_end were +* adjusted +*/ + len = xdp.data_end - xdp.data;/* We can only create skb based on xdp_page. */ if (unlikely (xdp_page != page)) {rcu_read_unlock ();
Signature · 1 line
2.15.1
PATCH v2 9/11 bpf: making bpf_prog_test run aware of possible data_end ptr change
In reply to Nikita V. Shirokovafter introduction of bpf_xdp_adjust_tail helper packet length could be changed not only if xdp->data pointer has been changed but xdp->data_end as well. making bpf_prog_test_run aware of this possibility
--- net/bpf/test_run.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/bpf/test_run.c +2 -1
@@ -170,7 +170,8 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, xdp.rxq = &rxqueue->xdp_rxq; retval =bpf_test_run (prog, &xdp, repeat, &duration); -if (xdp.data != data +XDP_PACKET_HEADROOM +NET_IP_ALIGN ) +if (xdp.data != data +XDP_PACKET_HEADROOM +NET_IP_ALIGN || + xdp.data_end != xdp.data + size) size = xdp.data_end - xdp.data; ret =bpf_test_finish (kattr, uattr, xdp.data, size, retval, duration);kfree (data);
Signature · 1 line
2.15.1
PATCH v2 10/11 bpf: adding tests for bpf_xdp_adjust_tail
In reply to Nikita V. Shirokovadding selftests for bpf_xdp_adjust_tail helper. in this synthetic test we are testing that 1) if data_end < data helper will return EINVAL
2) for normal use case packet's length would be reduced.
--- tools/include/uapi/linux/bpf.h | 10 +++++++- tools/testing/selftests/bpf/Makefile | 2 +- tools/testing/selftests/bpf/bpf_helpers.h | 3 +++ tools/testing/selftests/bpf/test_adjust_tail.c | 30 ++++++++++++++++++++++++ tools/testing/selftests/bpf/test_progs.c | 32 ++++++++++++++++++++++++++ 5 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 tools/testing/selftests/bpf/test_adjust_tail.c
tools/include/uapi/linux/bpf.h +9 -1
@@ -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
tools/testing/selftests/bpf/Makefile +1 -1
@@ -31,7 +31,7 @@ TEST_GEN_FILES = test_pkt_access.o test_xdp.o test_l4lb.o test_tcp_estats.o test sockmap_verdict_prog.o dev_cgroup.o sample_ret0.o test_tracepoint.o \ test_l4lb_noinline.o test_xdp_noinline.o test_stacktrace_map.o \ sample_map_ret0.o test_tcpbpf_kern.o test_stacktrace_build_id.o \ - sockmap_tcp_msg_prog.o connect4_prog.o connect6_prog.o + sockmap_tcp_msg_prog.o connect4_prog.o connect6_prog.o test_adjust_tail.o # Order correspond to 'make run_tests' order TEST_PROGS := test_kmod.sh \
tools/testing/selftests/bpf/bpf_helpers.h +3 -0
@@ -96,6 +96,9 @@ static int (*bpf_msg_pull_data)(void *ctx, int start, int end, int flags) = (void *) BPF_FUNC_msg_pull_data;static int (*bpf_bind)(void *ctx,void *addr,int addr_len) = (void *) BPF_FUNC_bind; +static int (*bpf_xdp_adjust_tail)(void *ctx,int offset) = + (void *) BPF_FUNC_xdp_adjust_tail; +/* llvm builtin functions that eBPF C program may use to * emit BPF_LD_ABS and BPF_LD_IND instructions
tools/testing/selftests/bpf/test_adjust_tail.c new file +30 -0
@@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0 +* Copyright (c) 2018 Facebook +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of version 2 of the GNU General Public +* License as published by the Free Software Foundation. +*/ +#include <linux/bpf.h> +#include <linux/if_ether.h> +#include "bpf_helpers.h" + +int _version SEC("version") = 1; + +SEC("xdp_adjust_tail") +int _xdp_adjust_tail (struct xdp_md *xdp) +{ +void *data_end = (void *)(long )xdp->data_end; +void *data = (void *)(long )xdp->data; +int offset =0 ; + +if (data_end - data ==54 ) + offset =256 ; +else + offset =20 ; +if (bpf_xdp_adjust_tail (xdp,0 - offset)) +return XDP_DROP ; +return XDP_TX ; +} + +char _license[] SEC("license") = "GPL";
tools/testing/selftests/bpf/test_progs.c +32 -0
@@ -166,6 +166,37 @@ static void test_xdp(void)bpf_object__close (obj); } +static void test_xdp_adjust_tail (void ) +{ +const char *file ="./test_adjust_tail.o" ; +struct bpf_object *obj; +char buf[128 ]; +__u32 duration, retval, size; +int err, prog_fd; + + err =bpf_prog_load (file,BPF_PROG_TYPE_XDP , &obj, &prog_fd); +if (err) { + error_cnt++; +return ; + } + + err =bpf_prog_test_run (prog_fd,1 , &pkt_v4,sizeof (pkt_v4), + buf, &size, &retval, &duration); + +CHECK (err || errno || retval !=XDP_DROP , +"ipv4" ,"err %d errno %d retval %d size %d\n" , + err, errno, retval, size); + + err =bpf_prog_test_run (prog_fd,1 , &pkt_v6,sizeof (pkt_v6), + buf, &size, &retval, &duration); +CHECK (err || errno || retval !=XDP_TX || size !=54 , +"ipv6" ,"err %d errno %d retval %d size %d\n" , + err, errno, retval, size); +bpf_object__close (obj); +} + + +#define MAGIC_VAL 0x1234#define NUM_ITER 100000#define VIP_NUM 5
@@ -1177,6 +1208,7 @@ int main(void) {test_pkt_access ();test_xdp (); +test_xdp_adjust_tail ();test_l4lb_all ();test_xdp_noinline ();test_tcp_estats ();
Signature · 1 line
2.15.1
PATCH v2 11/11 bpf: add bpf_xdp_adjust_tail sample prog
In reply to Nikita V. Shirokovadding bpf's sample program which is using bpf_xdp_adjust_tail helper by generating ICMPv4 "packet to big" message if ingress packet's size is bigger then 600 bytes
--- samples/bpf/Makefile | 4 + samples/bpf/xdp_adjust_tail_kern.c | 152 ++++++++++++++++++++++++++++++ samples/bpf/xdp_adjust_tail_user.c | 142 ++++++++++++++++++++++++++++ tools/testing/selftests/bpf/bpf_helpers.h | 2 + 4 files changed, 300 insertions(+) create mode 100644 samples/bpf/xdp_adjust_tail_kern.c create mode 100644 samples/bpf/xdp_adjust_tail_user.c
samples/bpf/Makefile +4 -0
@@ -44,6 +44,7 @@ hostprogs-y += xdp_monitor hostprogs-y += xdp_rxq_info hostprogs-y += syscall_tp hostprogs-y += cpustat +hostprogs-y += xdp_adjust_tail # Libbpf dependencies LIBBPF := ../../tools/lib/bpf/bpf.o ../../tools/lib/bpf/nlattr.o
@@ -95,6 +96,7 @@ xdp_monitor-objs := bpf_load.o $(LIBBPF) xdp_monitor_user.o xdp_rxq_info-objs := bpf_load.o $(LIBBPF) xdp_rxq_info_user.o syscall_tp-objs := bpf_load.o $(LIBBPF) syscall_tp_user.o cpustat-objs := bpf_load.o $(LIBBPF) cpustat_user.o +xdp_adjust_tail-objs := bpf_load.o $(LIBBPF) xdp_adjust_tail_user.o # Tell kbuild to always build the programs always := $(hostprogs-y)
@@ -148,6 +150,7 @@ always += xdp_rxq_info_kern.o always += xdp2skb_meta_kern.o always += syscall_tp_kern.o always += cpustat_kern.o +always += xdp_adjust_tail_kern.o HOSTCFLAGS += -I$(objtree)/usr/include HOSTCFLAGS += -I$(srctree)/tools/lib/
@@ -193,6 +196,7 @@ HOSTLOADLIBES_xdp_monitor += -lelf HOSTLOADLIBES_xdp_rxq_info += -lelf HOSTLOADLIBES_syscall_tp += -lelf HOSTLOADLIBES_cpustat += -lelf +HOSTLOADLIBES_xdp_adjust_tail += -lelf # Allows pointing LLC/CLANG to a LLVM backend with bpf support, redefine on cmdline: # make samples/bpf/ LLC=~/git/llvm/build/bin/llc CLANG=~/git/llvm/build/bin/clang
samples/bpf/xdp_adjust_tail_kern.c new file +152 -0
152 lines not on this page · raw message
samples/bpf/xdp_adjust_tail_user.c new file +142 -0
142 lines not on this page · raw message
tools/testing/selftests/bpf/bpf_helpers.h +2 -0
@@ -132,6 +132,8 @@ static int (*bpf_l3_csum_replace)(void *ctx, int off, int from, int to, int flag (void *) BPF_FUNC_l3_csum_replace;static int (*bpf_l4_csum_replace)(void *ctx,int off,int from,int to,int flags) = (void *) BPF_FUNC_l4_csum_replace; +static int (*bpf_csum_diff)(void *from,int from_size,void *to,int to_size,int seed) = + (void *) BPF_FUNC_csum_diff;static int (*bpf_skb_under_cgroup)(void *ctx,void *map,int index) = (void *) BPF_FUNC_skb_under_cgroup; static int (*bpf_skb_change_head)(void *, int len, int flags) =
Signature · 1 line
2.15.1
Daniel Borkmann
maintainerQuoted 5 lines · Nikita V. Shirokov
In this patch series i'm add new bpf helper which allow to manupulate xdp's
data_endpointer. right now only "shrinking" (reduce packet's size by moving pointer) is supported (and i see no use case for "growing"). Main use case for such helper is to be able to generate controll (ICMP) messages from XDP context. such messages usually contains first N bytes
Quoted 8 lines
from original packets as a payload, and this is exactly what this helper would allow us to do (see patch 3 for sample program, where we generate ICMP "packet too big" message). This helper could be usefull for load balancing applications where after additional encapsulation, resulting packet could be bigger then interface MTU.
Aside from new helper this patch series contains minor changes in device drivers (for ones which requires), so they would recal packet's length not only when head pointer was adjusted, but if tail's one as well.
The whole set doesn't have any SoBs from you which is mandatory before applying anything. Please add.
Thanks,
Daniel
Quoted 44 lines
v1->v2:
* fixed kbuild warning
* made offset eq 0 invalid forxdp_bpf_adjust_tail
* splittedbpf_prog_test_runfix and selftests in sep commits
* added SPDX licence where applicable
* some reshuffling in patches order (tests now in the end)Nikita V. Shirokov (11):
bpf: makingbpf_prog_testrun aware of possibledata_endptr change
bpf: adding tests forbpf_xdp_adjust_tail
bpf: addingbpf_xdp_adjust_tailhelper
bpf: make generic xdp compatible w/bpf_xdp_adjust_tail
bpf: make mlx4 compatible w/bpf_xdp_adjust_tail
bpf: make bnxt compatible w/bpf_xdp_adjust_tail
bpf: make cavium thunder compatible w/bpf_xdp_adjust_tail
bpf: make netronome nfp compatible w/bpf_xdp_adjust_tail
bpf: make tun compatible w/bpf_xdp_adjust_tail
bpf: make virtio compatible w/bpf_xdp_adjust_tail
bpf: addbpf_xdp_adjust_tailsample progdrivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c | 2 +- drivers/net/ethernet/cavium/thunder/nicvf_main.c | 2 +- drivers/net/ethernet/mellanox/mlx4/en_rx.c | 2 +- .../net/ethernet/netronome/nfp/nfp_net_common.c | 2 +- drivers/net/tun.c | 3 +- drivers/net/virtio_net.c | 7 +- include/uapi/linux/bpf.h | 10 +- net/bpf/test_run.c | 3 +- net/core/dev.c | 10 +- net/core/filter.c | 29 +++- samples/bpf/Makefile | 4 + samples/bpf/xdp_adjust_tail_kern.c | 152 +++++++++++++++++++++ samples/bpf/xdp_adjust_tail_user.c | 142 +++++++++++++++++++ tools/include/uapi/linux/bpf.h | 10 +- tools/testing/selftests/bpf/Makefile | 2 +- tools/testing/selftests/bpf/bpf_helpers.h | 5 + tools/testing/selftests/bpf/test_adjust_tail.c | 30 ++++ tools/testing/selftests/bpf/test_progs.c | 32 +++++ 18 files changed, 435 insertions(+), 12 deletions(-) create mode 100644 samples/bpf/xdp_adjust_tail_kern.c create mode 100644 samples/bpf/xdp_adjust_tail_user.c create mode 100644 tools/testing/selftests/bpf/test_adjust_tail.c
Quoted 15 lines · Daniel Borkmann
Quoted 5 lines · Nikita V. Shirokov
In this patch series i'm add new bpf helper which allow to manupulate xdp's
data_endpointer. right now only "shrinking" (reduce packet's size by moving pointer) is supported (and i see no use case for "growing"). Main use case for such helper is to be able to generate controll (ICMP) messages from XDP context. such messages usually contains first N bytesQuoted 8 lines
from original packets as a payload, and this is exactly what this helper would allow us to do (see patch 3 for sample program, where we generate ICMP "packet too big" message). This helper could be usefull for load balancing applications where after additional encapsulation, resulting packet could be bigger then interface MTU.
Aside from new helper this patch series contains minor changes in device drivers (for ones which requires), so they would recal packet's length not only when head pointer was adjusted, but if tail's one as well.
Quoted 3 lines
The whole set doesn't have any SoBs from you which is mandatory before applying anything. Please add.
sorry about that, somehow lost it between v1 and v2 ;)
Quoted 48 lines
Thanks,
DanielQuoted 44 lines
v1->v2:
* fixed kbuild warning
* made offset eq 0 invalid forxdp_bpf_adjust_tail
* splittedbpf_prog_test_runfix and selftests in sep commits
* added SPDX licence where applicable
* some reshuffling in patches order (tests now in the end)Nikita V. Shirokov (11):
bpf: makingbpf_prog_testrun aware of possibledata_endptr change
bpf: adding tests forbpf_xdp_adjust_tail
bpf: addingbpf_xdp_adjust_tailhelper
bpf: make generic xdp compatible w/bpf_xdp_adjust_tail
bpf: make mlx4 compatible w/bpf_xdp_adjust_tail
bpf: make bnxt compatible w/bpf_xdp_adjust_tail
bpf: make cavium thunder compatible w/bpf_xdp_adjust_tail
bpf: make netronome nfp compatible w/bpf_xdp_adjust_tail
bpf: make tun compatible w/bpf_xdp_adjust_tail
bpf: make virtio compatible w/bpf_xdp_adjust_tail
bpf: addbpf_xdp_adjust_tailsample progdrivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c | 2 +- drivers/net/ethernet/cavium/thunder/nicvf_main.c | 2 +- drivers/net/ethernet/mellanox/mlx4/en_rx.c | 2 +- .../net/ethernet/netronome/nfp/nfp_net_common.c | 2 +- drivers/net/tun.c | 3 +- drivers/net/virtio_net.c | 7 +- include/uapi/linux/bpf.h | 10 +- net/bpf/test_run.c | 3 +- net/core/dev.c | 10 +- net/core/filter.c | 29 +++- samples/bpf/Makefile | 4 + samples/bpf/xdp_adjust_tail_kern.c | 152 +++++++++++++++++++++ samples/bpf/xdp_adjust_tail_user.c | 142 +++++++++++++++++++ tools/include/uapi/linux/bpf.h | 10 +- tools/testing/selftests/bpf/Makefile | 2 +- tools/testing/selftests/bpf/bpf_helpers.h | 5 + tools/testing/selftests/bpf/test_adjust_tail.c | 30 ++++ tools/testing/selftests/bpf/test_progs.c | 32 +++++ 18 files changed, 435 insertions(+), 12 deletions(-) create mode 100644 samples/bpf/xdp_adjust_tail_kern.c create mode 100644 samples/bpf/xdp_adjust_tail_user.c create mode 100644 tools/testing/selftests/bpf/test_adjust_tail.c