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
next prev parent 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