Subject: Re: [PATCH net-next v1] net: tpmr: add Two-Port MAC Relay driver

From: Nikolay Aleksandrov <[email-masked]>
Date: Sun, 17 May 2026 16:43:12 +0300

On Sun, May 17, 2026 at 05:13:06AM +0100, David Carlier wrote:
> Add a driver implementing the Two-Port MAC Relay as defined by IEEE
> 802.1Q-2014 §6.7.1. A TPMR is a minimal L2 relay between exactly two
> member ports: no FDB, no MAC learning, no STP, and -- by
> specification -- it forwards most of the 01:80:C2:00:00:0X reserved
> group address range that a regular bridge would consume. This makes
> it suitable as a bump-in-the-wire element that is transparent to the
> control plane on both sides (LACP, LLDP, EAPOL, and so on continue
> to reach the far end as if the relay were not present).
> 
> The driver is created with "ip link add type tpmr" and slaves are
> attached through ndo_add_slave, with a hard cap of two members.
> Forwarding is implemented as an rx_handler: a frame arriving on one
> slave is sent out the other via dev_queue_xmit(), with no FDB
> lookup. The IEEE-permitted subset of reserved multicasts is relayed;
> the remainder is delivered to the host stack via RX_HANDLER_PASS,
> preserving today's behaviour for protocols that genuinely target the
> local machine. Only 01:80:C2:00:00:01 (IEEE 802.3x PAUSE) is
> terminated, as required by the MAC layer.
> 
> The master's carrier follows the logical AND of both slaves'
> carriers, propagated via a netdev notifier. Both slaves enter
> IFF_PROMISC on enslave (and the refcount is balanced on detach) so
> the relay sees all unicast on the wire. rx_handler_register()
> provides exclusivity for free: a netdevice that is already a member
> of a bridge, bond, team, or macvlan is rejected with -EBUSY at
> enslave time.
> 
> MTU consistency is enforced at enslave: a second slave whose MTU
> differs from the first is rejected. Subsequent member MTU changes
> are blocked via NETDEV_PRECHANGEMTU; to change a member's MTU,
> detach it first.
> 
> Inspired by OpenBSD's tpmr(4) (David Gwynne, 2019), reimplemented
> against Linux's rx_handler / rtnl_link_ops infrastructure.
> 
> Signed-off-by: David Carlier <[email-masked]>
> ---
> 
> v1 (from RFC, addressing Andrew Lunn review):
>   - Inline reserved-address check; only PAUSE is passed up,
>     gated on is_multicast_ether_addr() + unlikely().
>   - Fix MTU check that assumed ports[0] is always the
>     surviving slot after a detach-then-add sequence;
>     iterate ports[] to find the populated entry instead.
>   - Reject member MTU changes via NETDEV_PRECHANGEMTU.
>   - Drop driver version string; let ethtool core fill it.
>   - Keep driver in drivers/net/ (precedent: veth, bonding,
>     macvlan).
> RFC: https://lore.kernel.org/netdev/[email-masked]/
> 
 
Hi David,
Please give people more time to review the proposed RFCs before sending v1.
Also you specifically asked bridge maintainers to comment and did not
wait for us to do so.

Now to the point - I don't think this device is needed at all, this task can
be accomplished in multiple ways with what we currently have, there is no 
need to add another software device for something so simple.

First, I'd like to ask: could you please elaborate why bridge's group_fwd_mask
isn't working out for you? How exactly are you trying to use it?
It was added for this purpose, to forward link-local frames and should be
able to do the same as what you're describing. If there is a problem I'd
rather we fix it or extend the bridge if something's missing instead of
adding so much new code that we'll have to maintain forever.

Second, what else did you try and how exactly did you try it?

Examples of a few ways to solve this:
 - tc: why dismiss mirred so fast, it can do the same combined with some matching?
       Did you check mirred redirect?
       cls_bpf/ebpf - definitely can do it as well
 - nftables: should be able to solve it, too
 - XDP: I wouldn't dismiss it because network managers cannot control it,
        all modern network managers support custom scripts in some form
        where you can load your custom XDP program and solve the problem

Cheers,
 Nik