Thread (24 messages) 24 messages, 3 authors, 2d ago

[PATCH net-next 07/13] amt: size the encapsulation headroom by the outer IP version

flat view
WARM2d

From: Omar Ramadan <hidden>
Date: 2026-10-09 12:24:46
Also in: linux-kselftest, lkml
Subsystem: amt (automatic multicast tunneling), networking drivers, networking [general], the rest · Maintainers: Taehee Yoo, Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds

The amt device reserves AMT_RELAY_HLEN or AMT_GW_HLEN of headroom and
subtracts the same amount from the stream device's MTU. Both assume a
20-byte IPv4 outer header. An IPv6 outer header is 40 bytes, so an IPv6
relay's MTU admits Multicast Data up to 10 bytes too long for the stream
device once encapsulated, which the relay's tunnel MTU check then drops.

Compute the headroom in amt_hlen() from amt_ip_hlen() and the AMT
headers of the mode, and use it wherever the device sizes its headroom
and MTU: once for both modes at newlink, and on NETDEV_CHANGEMTU of the
stream device. AMT_RELAY_HLEN and AMT_GW_HLEN have no other user and
are removed.

No functional change: amt_v6() is still false for every device.

Assisted-by: LLM
Signed-off-by: Omar Ramadan <redacted>
---
 drivers/net/amt.c | 31 +++++++++++++++----------------
 include/net/amt.h |  6 ------
 2 files changed, 15 insertions(+), 22 deletions(-)
diff --git a/drivers/net/amt.c b/drivers/net/amt.c
index 412d23c..969ecfe 100644
--- a/drivers/net/amt.c
+++ b/drivers/net/amt.c
@@ -93,6 +93,16 @@ static unsigned int amt_ip_hlen(const struct amt_dev *amt)
 	return amt_v6(amt) ? sizeof(struct ipv6hdr) : sizeof(struct iphdr);
 }
 
+/* Headroom the device reserves for its outer encapsulation. */
+static unsigned int amt_hlen(const struct amt_dev *amt)
+{
+	unsigned int hlen = amt_ip_hlen(amt) + sizeof(struct udphdr);
+
+	if (amt->mode == AMT_MODE_RELAY)
+		return hlen + sizeof(struct amt_relay_headers);
+	return hlen + sizeof(struct amt_gw_headers);
+}
+
 /* Copy the outer source address of a received message by value, so that
  * the caller may pull the skb afterwards.
  */
@@ -3513,11 +3523,6 @@ static int amt_newlink(struct net_device *dev,
 	if (amt->mode == AMT_MODE_RELAY) {
 		amt->qrv = READ_ONCE(amt->net->ipv4.sysctl_igmp_qrv);
 		amt->qri = 10;
-		dev->needed_headroom = amt->stream_dev->needed_headroom +
-				       AMT_RELAY_HLEN;
-		dev->mtu = amt->stream_dev->mtu - AMT_RELAY_HLEN;
-		dev->max_mtu = dev->mtu;
-		dev->min_mtu = ETH_MIN_MTU + AMT_RELAY_HLEN;
 	} else {
 		if (!data[IFLA_AMT_DISCOVERY_IP]) {
 			NL_SET_ERR_MSG_ATTR(extack, tb[IFLA_AMT_DISCOVERY_IP],
@@ -3538,13 +3543,11 @@ static int amt_newlink(struct net_device *dev,
 					    "discovery must be unicast");
 			goto err;
 		}
-
-		dev->needed_headroom = amt->stream_dev->needed_headroom +
-				       AMT_GW_HLEN;
-		dev->mtu = amt->stream_dev->mtu - AMT_GW_HLEN;
-		dev->max_mtu = dev->mtu;
-		dev->min_mtu = ETH_MIN_MTU + AMT_GW_HLEN;
 	}
+	dev->needed_headroom = amt->stream_dev->needed_headroom + amt_hlen(amt);
+	dev->mtu = amt->stream_dev->mtu - amt_hlen(amt);
+	dev->max_mtu = dev->mtu;
+	dev->min_mtu = ETH_MIN_MTU + amt_hlen(amt);
 	amt->qi = AMT_INIT_QUERY_INTERVAL;
 
 	err = register_netdevice(dev);
@@ -3676,11 +3679,7 @@ static int amt_device_event(struct notifier_block *unused,
 		unregister_netdevice_many(&list);
 		break;
 	case NETDEV_CHANGEMTU:
-		if (amt->mode == AMT_MODE_RELAY)
-			new_mtu = dev->mtu - AMT_RELAY_HLEN;
-		else
-			new_mtu = dev->mtu - AMT_GW_HLEN;
-
+		new_mtu = dev->mtu - amt_hlen(amt);
 		dev_set_mtu(amt->dev, new_mtu);
 		break;
 	}
diff --git a/include/net/amt.h b/include/net/amt.h
index 77d17fc..d8798a9 100644
--- a/include/net/amt.h
+++ b/include/net/amt.h
@@ -398,12 +398,6 @@ struct amt_dev {
 #define IANA_AMT_UDP_PORT	2268
 #define AMT_MAX_TUNNELS         128
 #define AMT_MAX_REQS		128
-#define AMT_GW_HLEN (sizeof(struct iphdr) + \
-		     sizeof(struct udphdr) + \
-		     sizeof(struct amt_gw_headers))
-#define AMT_RELAY_HLEN (sizeof(struct iphdr) + \
-		     sizeof(struct udphdr) + \
-		     sizeof(struct amt_relay_headers))
 
 static inline bool netif_is_amt(const struct net_device *dev)
 {
-- 
2.43.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help