diff options
-rw-r--r-- | include/net/ip6_route.h | 2 | ||||
-rw-r--r-- | net/ipv4/route.c | 5 | ||||
-rw-r--r-- | net/ipv6/route.c | 8 |
3 files changed, 9 insertions, 6 deletions
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index 2a5277758379..a54b2ece5ef7 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h @@ -326,7 +326,7 @@ static inline unsigned int ip6_dst_mtu_forward(const struct dst_entry *dst) mtu = idev->cnf.mtu6; rcu_read_unlock(); - return mtu; + return mtu - lwtunnel_headroom(dst->lwtstate, mtu); } u32 ip6_mtu_from_fib6(const struct fib6_result *res, diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 9bd30fd4de4b..8bd74d5c4a44 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1407,8 +1407,11 @@ u32 ip_mtu_from_fib_result(struct fib_result *res, __be32 daddr) u32 mtu = 0; if (dev_net(dev)->ipv4.sysctl_ip_fwd_use_pmtu || - fi->fib_metrics->metrics[RTAX_LOCK - 1] & (1 << RTAX_MTU)) + fi->fib_metrics->metrics[RTAX_LOCK - 1] & (1 << RTAX_MTU)) { mtu = fi->fib_mtu; + if (mtu) + return mtu; + } if (likely(!mtu)) { struct fib_nh_exception *fnhe; diff --git a/net/ipv6/route.c b/net/ipv6/route.c index fb075d9545b9..f7f0e830b596 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1587,7 +1587,7 @@ static unsigned int fib6_mtu(const struct fib6_result *res) unsigned int mtu; if (res->f6i->fib6_pmtu) { - mtu = res->f6i->fib6_pmtu; + return min_t(unsigned int, res->f6i->fib6_pmtu, IP6_MAX_MTU); } else { struct net_device *dev = nh->fib_nh_dev; struct inet6_dev *idev; @@ -3095,7 +3095,7 @@ static unsigned int ip6_mtu(const struct dst_entry *dst) mtu = dst_metric_raw(dst, RTAX_MTU); if (mtu) - goto out; + return min_t(unsigned int, mtu, IP6_MAX_MTU); mtu = IPV6_MIN_MTU; @@ -3132,12 +3132,12 @@ u32 ip6_mtu_from_fib6(const struct fib6_result *res, if (unlikely(fib6_metric_locked(f6i, RTAX_MTU))) { mtu = f6i->fib6_pmtu; if (mtu) - goto out; + return mtu; } rt = rt6_find_cached_rt(res, daddr, saddr); if (unlikely(rt)) { - mtu = dst_metric_raw(&rt->dst, RTAX_MTU); + return dst_metric_raw(&rt->dst, RTAX_MTU); } else { struct net_device *dev = nh->fib_nh_dev; |