ipv4: lock mtu in fnhe when received PMTU < net.ipv4.route.min_pmtu
Prior to the rework of PMTU information storage in commit2c8cec5c10
("ipv4: Cache learned PMTU information in inetpeer."), when a PMTU event advertising a PMTU smaller than net.ipv4.route.min_pmtu was received, we would disable setting the DF flag on packets by locking the MTU metric, and set the PMTU to net.ipv4.route.min_pmtu. Since then, we don't disable DF, and set PMTU to net.ipv4.route.min_pmtu, so the intermediate router that has this link with a small MTU will have to drop the packets. This patch reestablishes pre-2.6.39 behavior by splitting rtable->rt_pmtu into a bitfield with rt_mtu_locked and rt_pmtu. rt_mtu_locked indicates that we shouldn't set the DF bit on that path, and is checked in ip_dont_fragment(). One possible workaround is to set net.ipv4.route.min_pmtu to a value low enough to accommodate the lowest MTU encountered. Fixes:2c8cec5c10
("ipv4: Cache learned PMTU information in inetpeer.") Signed-off-by: Sabrina Dubroca <sd@queasysnail.net> Reviewed-by: Stefano Brivio <sbrivio@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
16c2e4db83
commit
d52e5a7e7c
@@ -328,6 +328,13 @@ int ip_decrease_ttl(struct iphdr *iph)
|
||||
return --iph->ttl;
|
||||
}
|
||||
|
||||
static inline int ip_mtu_locked(const struct dst_entry *dst)
|
||||
{
|
||||
const struct rtable *rt = (const struct rtable *)dst;
|
||||
|
||||
return rt->rt_mtu_locked || dst_metric_locked(dst, RTAX_MTU);
|
||||
}
|
||||
|
||||
static inline
|
||||
int ip_dont_fragment(const struct sock *sk, const struct dst_entry *dst)
|
||||
{
|
||||
@@ -335,7 +342,7 @@ int ip_dont_fragment(const struct sock *sk, const struct dst_entry *dst)
|
||||
|
||||
return pmtudisc == IP_PMTUDISC_DO ||
|
||||
(pmtudisc == IP_PMTUDISC_WANT &&
|
||||
!(dst_metric_locked(dst, RTAX_MTU)));
|
||||
!ip_mtu_locked(dst));
|
||||
}
|
||||
|
||||
static inline bool ip_sk_accept_pmtu(const struct sock *sk)
|
||||
@@ -361,7 +368,7 @@ static inline unsigned int ip_dst_mtu_maybe_forward(const struct dst_entry *dst,
|
||||
struct net *net = dev_net(dst->dev);
|
||||
|
||||
if (net->ipv4.sysctl_ip_fwd_use_pmtu ||
|
||||
dst_metric_locked(dst, RTAX_MTU) ||
|
||||
ip_mtu_locked(dst) ||
|
||||
!forwarding)
|
||||
return dst_mtu(dst);
|
||||
|
||||
|
Reference in New Issue
Block a user