> -----Original Message-----
> From: Intel-wired-lan <[email protected]> On Behalf
> Of Matteo Croce
> Sent: Monday, March 23, 2026 7:28 PM
> To: Nguyen, Anthony L <[email protected]>; Kitszel,
> Przemyslaw <[email protected]>; Andrew Lunn
> <[email protected]>; David S. Miller <[email protected]>; Eric
> Dumazet <[email protected]>; Jakub Kicinski <[email protected]>; Paolo
> Abeni <[email protected]>; Alexei Starovoitov <[email protected]>; Daniel
> Borkmann <[email protected]>; Jesper Dangaard Brouer
> <[email protected]>; John Fastabend <[email protected]>; Mohsin
> Bashir <[email protected]>
> Cc: [email protected]; [email protected]; intel-wired-
> [email protected]; [email protected]
> Subject: [Intel-wired-lan] [PATCH net-next v4 2/2] e1000e: add
> XDP_REDIRECT support
>
> Add the ability to redirect packets to other devices via XDP_REDIRECT
> and to receive redirected frames from other devices via ndo_xdp_xmit.
>
> New functionality:
> - XDP_REDIRECT case in e1000_run_xdp() using xdp_do_redirect()
> - e1000_xdp_xmit() as the ndo_xdp_xmit callback for receiving
> redirected frames from other devices
> - xdp_do_flush() in e1000_finalize_xdp() for REDIR completions
> - xdp_features_set/clear_redirect_target() in e1000_xdp_setup()
> - NETDEV_XDP_ACT_REDIRECT and NETDEV_XDP_ACT_NDO_XMIT advertised
>
> Assisted-by: claude-opus-4-6
> Signed-off-by: Matteo Croce <[email protected]>
> ---
> drivers/net/ethernet/intel/e1000e/netdev.c | 85
> +++++++++++++++++++++-
> 1 file changed, 81 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c
> b/drivers/net/ethernet/intel/e1000e/netdev.c
> index d77f208f00cc..01661e1a74e5 100644
> --- a/drivers/net/ethernet/intel/e1000e/netdev.c
> +++ b/drivers/net/ethernet/intel/e1000e/netdev.c
> @@ -41,6 +41,7 @@ char e1000e_driver_name[] = "e1000e";
> #define E1000_XDP_PASS 0
> #define E1000_XDP_CONSUMED BIT(0)
> #define E1000_XDP_TX BIT(1)
...
>
> +/**
> + * e1000_xdp_xmit - transmit XDP frames from another device
> + * @netdev: network interface device structure
> + * @n: number of frames to transmit
> + * @frames: array of XDP frame pointers
> + * @flags: XDP transmit flags
> + *
> + * This is the ndo_xdp_xmit callback, called when other devices
> +redirect
> + * frames to this device.
> + **/
> +static int e1000_xdp_xmit(struct net_device *netdev, int n,
> + struct xdp_frame **frames, u32 flags) {
> + struct e1000_adapter *adapter = netdev_priv(netdev);
> + struct e1000_ring *tx_ring = adapter->tx_ring;
> + struct netdev_queue *nq = netdev_get_tx_queue(netdev, 0);
> + int cpu = smp_processor_id();
> + int nxmit = 0;
> + int i;
> +
> + if (unlikely(test_bit(__E1000_DOWN, &adapter->state)))
> + return -ENETDOWN;
> +
> + if (unlikely(flags & ~XDP_XMIT_FLAGS_MASK))
> + return -EINVAL;
> +
> + if (!adapter->xdp_prog)
> + return -ENXIO;
> +
> + __netif_tx_lock(nq, cpu);
> + txq_trans_cond_update(nq);
> +
> + for (i = 0; i < n; i++) {
> + int err;
> +
> + err = e1000_xdp_xmit_ring(adapter, tx_ring, frames[i]);
> + if (err != E1000_XDP_TX)
> + break;
On first failure, we break out of the loop. frames[i] through frames[n-1] are
silently abandoned.
It should be no memleaks I hope, but silent packets drop is nasty!
> + nxmit++;
> + }
> +
> + if (unlikely(flags & XDP_XMIT_FLUSH)) {
> + /* Force memory writes to complete before letting h/w
> + * know there are new descriptors to fetch.
> + */
> + wmb();
> + if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA)
> + e1000e_update_tdt_wa(tx_ring,
> + tx_ring->next_to_use);
> + else
> + writel(tx_ring->next_to_use, tx_ring->tail);
> + }
> +
> + __netif_tx_unlock(nq);
> +
> + return nxmit;
> +}
> +
...
> --
> 2.53.0