BPF List
 help / color / mirror / Atom feed
From: Nicolai Buchwitz <nb@tipi-net.de>
To: sashiko@lists.linux.dev
Cc: bpf@vger.kernel.org
Subject: Re: [PATCH net-next v8 5/7] net: bcmgenet: add XDP_REDIRECT and ndo_xdp_xmit support
Date: Thu, 30 Apr 2026 00:50:59 +0200	[thread overview]
Message-ID: <6f05e119f0c419047313a20707e7fba5@tipi-net.de> (raw)
In-Reply-To: <20260429211703.19EC9C2BCB4@smtp.kernel.org>

On 29.4.2026 23:17, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 6 potential 
> issue(s) to consider:
> - [Critical] Prepended TSB in ndo_xdp_xmit completely overwrites struct 
> xdp_frame.
> - [Critical] Headroom validation in XDP_TX ignores metadata size, 
> allowing out-of-bounds writes.
> - [High] DMA mapping address in XDP_TX is incorrect when XDP metadata 
> is present.
> - [High] Redirected XDP frames will be leaked indefinitely if the 
> target interface is idle.
> - [Medium] bcmgenet_xdp_setup() clears NETDEV_XDP_ACT_NDO_XMIT when 
> detaching an XDP program, hiding device capabilities.
> - [Medium] Runt XDP frames (less than 60 bytes) will not be padded by 
> the hardware and will be transmitted as undersized packets.
> --
> 
> commit 893d59a522f087d2ccf486f06a06bb9e815cf330
> Author: Nicolai Buchwitz <nb@tipi-net.de>
> 
> net: bcmgenet: add XDP_REDIRECT and ndo_xdp_xmit support
> 
> Add XDP_REDIRECT support and implement ndo_xdp_xmit for receiving
> redirected frames from other devices.
> 
>> diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c 
>> b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
>> index 3c3b0c44ea8a..9dd258567824 100644
>> --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
>> +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
> 
> [ ... ]
> 
>> @@ -2451,11 +2452,25 @@ static unsigned int bcmgenet_run_xdp(struct 
>> bcmgenet_rx_ring *ring,
>>  						true);
>>  			return XDP_DROP;
>>  		}
>> -		if (unlikely(!bcmgenet_xdp_xmit_frame(priv, xdpf, false))) {
>> +
>> +		tx_ring = &priv->xdp_tx_ring;
>> +		spin_lock(&tx_ring->lock);
>> +		if (unlikely(!bcmgenet_xdp_xmit_frame(priv, tx_ring,
>> +						      xdpf, false))) {
> 
> Does the DMA mapping calculation in bcmgenet_xdp_xmit_frame() for this 
> local
> XDP_TX path (dma_map == false) account for XDP metadata?

For local XDP_TX, the caller adjusts xdp->data backwards to include the
prepended TSB before xdp_convert_buff_to_frame(). xdpf->data then points
to the TSB start, and the mapping calculation correctly resolves to that
location.

> 
> If an XDP program populates metadata, the calculation sizeof(*xdpf) +
> xdpf->headroom in the else block of bcmgenet_xdp_xmit_frame() will 
> point
> to the start of the metadata rather than where the TSB was actually 
> prepended
> at xdpf->data. The hardware expects the TSB at the DMA address, so it 
> might
> misinterpret the metadata as the status block.
> 
>> +			spin_unlock(&tx_ring->lock);
>>  			xdp_return_frame_rx_napi(xdpf);
>>  			return XDP_DROP;
>>  		}
>> +		bcmgenet_xdp_ring_doorbell(priv, tx_ring);
>> +		spin_unlock(&tx_ring->lock);
>>  		return XDP_TX;
> 
> Does the headroom check earlier in this XDP_TX block adequately 
> validate
> xdp->data_meta?

xdp_convert_buff_to_frame() validates the remaining headroom against
sizeof(struct xdp_frame) and returns NULL on insufficient space, which
we handle by dropping the frame.

> 
> Before backing up the pointers:
> 	if (xdp->data - xdp->data_hard_start <
> 	    sizeof(struct status_64) + sizeof(struct xdp_frame)) {
> 
> This check validates the space before xdp->data, but the code then 
> subtracts
> 64 bytes from xdp->data_meta:
> 	xdp->data -= sizeof(struct status_64);
> 	xdp->data_meta -= sizeof(struct status_64);
> 
> If an XDP program populates metadata, xdp->data_meta will be lower than
> xdp->data. The subtraction might push xdp->data_meta below
> xdp->data_hard_start, causing out-of-bounds writes when
> xdp_convert_buff_to_frame() constructs the struct xdp_frame.
> 
> [ ... ]
> 
>> @@ -3996,10 +4017,16 @@ static int bcmgenet_xdp_setup(struct 
>> net_device *dev,
>>  		return -EOPNOTSUPP;
>>  	}
>> 
>> +	if (!prog)
>> +		xdp_features_clear_redirect_target(dev);
>> +
>>  	old_prog = xchg(&priv->xdp_prog, prog);
>>  	if (old_prog)
>>  		bpf_prog_put(old_prog);
>> 
>> +	if (prog)
>> +		xdp_features_set_redirect_target(dev, false);
>> +
>>  	return 0;
>>  }
> 
> Can this unintentionally clear NETDEV_XDP_ACT_NDO_XMIT when detaching 
> an XDP
> program?

xdp_features_clear_redirect_target() / 
xdp_features_set_redirect_target()
only manipulate the redirect-target advertisement, not
NETDEV_XDP_ACT_NDO_XMIT. The same pattern is used by ice, bnxt and
others.

> 
> The driver statically implements ndo_xdp_xmit and advertises it in
> dev->xdp_features during probe, indicating the interface can receive 
> XDP
> redirected frames from other interfaces regardless of its own XDP 
> program state.
> Calling xdp_features_clear_redirect_target(dev) when prog is NULL will
> clear the NETDEV_XDP_ACT_NDO_XMIT capability, hiding it from discovery.
> 
> [ ... ]
> 
>> @@ -4013,6 +4040,36 @@ static int bcmgenet_xdp(struct net_device *dev, 
>> struct netdev_bpf *xdp)
>>  	}
>>  }
>> 
>> +static int bcmgenet_xdp_xmit(struct net_device *dev, int num_frames,
>> +			     struct xdp_frame **frames, u32 flags)
>> +{
>> +	struct bcmgenet_priv *priv = netdev_priv(dev);
>> +	struct bcmgenet_tx_ring *ring = &priv->xdp_tx_ring;
>> +	int sent = 0;
>> +	int i;
>> +
>> +	if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK))
>> +		return -EINVAL;
>> +
>> +	if (unlikely(!netif_running(dev)))
>> +		return -ENETDOWN;
>> +
>> +	spin_lock(&ring->lock);
>> +
>> +	for (i = 0; i < num_frames; i++) {
>> +		if (!bcmgenet_xdp_xmit_frame(priv, ring, frames[i], true))
>> +			break;
> 
> Does bcmgenet_xdp_xmit_frame() overwrite the struct xdp_frame metadata 
> when
> handling these redirected frames?

No. The xdp_frame ends at data_hard_start + sizeof(xdp_frame). The TSB
is written at xdpf->data - 64, which falls inside the headroom (after
the xdp_frame). The check xdpf->headroom < sizeof(struct status_64)
ensures no overlap with the xdp_frame.

> 
> When dma_map == true for redirected frames, the driver prepends a 
> 64-byte
> hardware TSB by calling memset(xdpf->data - sizeof(struct status_64), 
> 0, 64).
> Since the struct xdp_frame is located right before xdpf->data (or any 
> prepended
> metadata), writing backwards into the headroom could completely zero 
> out the
> struct xdp_frame fields, leading to crashes when returning the frame.
> 
> Also, does this cause runt frames to be transmitted as undersized 
> packets?

Padding short frames is the responsibility of the XDP program / source
device, same as in other XDP drivers.

> 
> If the XDP frame is less than 60 bytes, enabling DMA_TX_APPEND_CRC 
> inside
> bcmgenet_xdp_xmit_frame() without first padding the frame might trigger 
> the
> GENET hardware quirk where it fails to pad packets to the minimum 
> Ethernet size,
> causing them to be dropped by receiving switches.
> 
> Is there a mechanism to ensure these redirected frames won't be leaked 
> if the
> target interface is idle?

Known limitation of piggybacked TX reclaim, shared by other drivers.
In practice, redirect targets see bidirectional traffic. Frames are
dropped (not leaked) when the ring fills

> 
> Without setting DMA_TX_REQ_INTR in len_stat during transmission in
> bcmgenet_xdp_xmit_frame(), TX completions for the XDP TX ring rely 
> entirely
> on being polled during the RX NAPI cycle. If the interface is receiving 
> no
> normal traffic, the NAPI poll might never run, causing the redirected 
> frames to
> sit in the TX ring indefinitely.
> 
>> +		sent++;
>> +	}

Thanks,
Nicolai

  reply	other threads:[~2026-04-29 22:51 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-28 20:58 [PATCH net-next v8 0/7] net: bcmgenet: add XDP support Nicolai Buchwitz
2026-04-28 20:58 ` [PATCH net-next v8 2/7] net: bcmgenet: register xdp_rxq_info for each RX ring Nicolai Buchwitz
2026-04-28 20:58 ` [PATCH net-next v8 3/7] net: bcmgenet: add basic XDP support (PASS/DROP) Nicolai Buchwitz
2026-04-29 21:17   ` sashiko-bot
2026-04-29 22:24     ` Nicolai Buchwitz
2026-04-28 20:58 ` [PATCH net-next v8 4/7] net: bcmgenet: add XDP_TX support Nicolai Buchwitz
2026-04-29 21:17   ` sashiko-bot
2026-04-29 22:28     ` Nicolai Buchwitz
2026-04-28 20:58 ` [PATCH net-next v8 5/7] net: bcmgenet: add XDP_REDIRECT and ndo_xdp_xmit support Nicolai Buchwitz
2026-04-29 21:17   ` sashiko-bot
2026-04-29 22:50     ` Nicolai Buchwitz [this message]
2026-04-28 20:58 ` [PATCH net-next v8 6/7] net: bcmgenet: add XDP statistics counters Nicolai Buchwitz
2026-04-29 21:17   ` sashiko-bot
2026-04-29 22:39     ` Nicolai Buchwitz
2026-04-28 20:58 ` [PATCH net-next v8 7/7] net: bcmgenet: reject MTU changes incompatible with XDP Nicolai Buchwitz
2026-04-29 21:17   ` sashiko-bot
2026-04-29 22:35     ` Nicolai Buchwitz

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=6f05e119f0c419047313a20707e7fba5@tipi-net.de \
    --to=nb@tipi-net.de \
    --cc=bpf@vger.kernel.org \
    --cc=sashiko@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox