[RFC PATCH 3/4] net/ipv6: respect MTU determined by `ndo_lookup_mtu`

leon at is.currently.online leon at is.currently.online
Tue Dec 28 23:45:27 UTC 2021


From: Leon Schuermann <leon at is.currently.online>

This integrates the newly introduced dynamic MTU lookup mechanism with
the IPv6 stack. It will attempt to query the destination netdevice for
the individual packet MTU and, if not found or the mechanism is not
implemented, fall back to the device MTU.

`ndo_lookup_mtu` will not be queried and respected for every
packet. For instance, flow offloading with netfilter will only take
the device MTU into account.

Signed-off-by: Leon Schuermann <leon at is.currently.online>
---
 include/net/ip6_route.h | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
index 2a5277758379..97e304291d1f 100644
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -264,11 +264,21 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
 
 static inline int ip6_skb_dst_mtu(struct sk_buff *skb)
 {
+	int mtu;
+	int err;
+	struct net_device *dev = skb_dst(skb)->dev;
 	struct ipv6_pinfo *np = skb->sk && !dev_recursion_level() ?
 				inet6_sk(skb->sk) : NULL;
 
-	return (np && np->pmtudisc >= IPV6_PMTUDISC_PROBE) ?
-	       skb_dst(skb)->dev->mtu : dst_mtu(skb_dst(skb));
+	err = -ENODATA;
+	if (dev->netdev_ops->ndo_lookup_mtu)
+		err = dev->netdev_ops->ndo_lookup_mtu(skb, dev);
+	mtu = (err >= 0) ? err : READ_ONCE(dev->mtu);
+
+	if (np && np->pmtudisc < IPV6_PMTUDISC_PROBE)
+		mtu = min_t(int, mtu, dst_mtu(skb_dst(skb)));
+
+	return mtu;
 }
 
 static inline bool ip6_sk_accept_pmtu(const struct sock *sk)
-- 
2.33.1



More information about the WireGuard mailing list