Subject: [RFC net-next 0/1] net: add Two-Port MAC Relay (TPMR) driver

From: David Carlier <[email-masked]>
Date: Sat, 16 May 2026 06:08:57 +0100

Hi,

This is an RFC for a small netdevice driver implementing the
Two-Port MAC Relay from IEEE 802.1Q-2014 §6.7.1. A TPMR is a
deliberately stripped-down L2 relay: exactly two ports, no FDB, no
MAC learning, no STP, and -- by spec -- it forwards most of the
01:80:C2:00:00:0X reserved group that a regular bridge consumes
(LACPDUs, LLDP, EAPOL, and so on).

The reason I started looking at this is that there is no clean way
to put a Linux box in the middle of a link without breaking the
control plane on either side. The obvious answer -- "use a bridge
with learning and STP disabled" -- doesn't actually work, because
br_input.c filters BPDUs / PAE / LACP before group_fwd_mask gets a
chance to forward them, so anything on the wire that relies on
those frames reaching the far end (link aggregation, MACsec setups,
802.1X) silently breaks. tc mirred only mirrors; macvlan passthru
is single-master; an XDP redirect between two ifaces works but
isn't a netdevice, so neither ip link nor any of the network
managers can drive it. None of these are what the IEEE standard
already describes.

OpenBSD's tpmr(4) [1] has filled this niche since 2019. The driver
proposed here is inspired by that one but mapped onto rx_handler /
rtnl_link_ops, which lets us drop a lot of the BSD bookkeeping
since the Linux framework already provides it. Details are in the
patch's commit message.

It's sent as an RFC because there are a handful of design choices
I'd rather get pushback on now than after I've written the
selftests:

1. New driver vs. a tpmr mode of the bridge. The fundamental
   question. A separate driver keeps the bridge code untouched and
   sidesteps br_input.c's filtering entirely; a bridge mode would
   reuse the slave management you already have. I lean toward the
   separate driver -- the semantics are different from what a
   bridge guarantees and switchdev offload would be cleaner -- but
   I'd genuinely rather hear from the bridge maintainers before
   going further.

2. MTU policy. Strict (reject mismatched slaves, refuse desyncing
   changes, bridge-like) or pass-through (bond-like). The current
   patch enforces strict at enslave time (a second slave whose MTU
   differs is rejected); runtime MTU policing via a notifier is
   left for v1 so the shape of that callback can be discussed
   first.

3. VLAN-tagged frames. The OpenBSD driver bails out on them. Here
   they are forwarded with the tag preserved -- in the MACsec /
   LAG cases that's almost certainly what users want -- but worth
   confirming.

4. Reserved-multicast forwarding table. The IEEE spec lists exactly
   which 01:80:C2:00:00:0X addresses a TPMR relays vs. terminates.
   Only 01:80:C2:00:00:01 (PAUSE) is terminated, as it must be by
   the MAC layer; the rest are relayed. The table is hardcoded.
   Making it per-instance configurable feels like premature
   flexibility, but I can be talked out of it.

5. Statistics. ndo_get_stats64 on the master via dev_get_tstats64
   over pcpu_sw_netstats is what's implemented. Per-slave
   forwarded/dropped counters would be nice but add ABI surface;
   master-only for v1 unless someone has a stronger view.

6. Netlink shape. IFLA_INFO_KIND="tpmr" with an (initially empty)
   IFLA_INFO_DATA nest, leaving room for a policy flag if #4 ends
   up configurable. Flagging it so the shape can be argued before
   it's frozen.

Not in this RFC, planned for v1: selftest under
tools/testing/selftests/net/ (bidirectional forwarding, link-state
aggregation, MTU sync, third-slave rejection, rx_handler conflict
rejection, reserved-multicast pass-through), Documentation/
networking/tpmr.rst, MAINTAINERS entry, and iproute2 support as a
separate series once the kernel ABI is settled. switchdev/DSA
offload and richer ethtool_ops are deliberately follow-ups -- only
worth doing once the base lands and if there's demand.

Thanks for taking a look,
David

[1] https://man.openbsd.org/tpmr.4

David Carlier (1):
  net: tpmr: add Two-Port MAC Relay driver

 drivers/net/Kconfig          |  14 ++
 drivers/net/Makefile         |   1 +
 drivers/net/tpmr.c           | 409 +++++++++++++++++++++++++++++++++++
 include/uapi/linux/if_link.h |   8 +
 4 files changed, 432 insertions(+)
 create mode 100644 drivers/net/tpmr.c

-- 
2.53.0