From: Leon Schuermann <leon@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@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