Message ID | 20210607234307.3375806-1-zenczykowski@gmail.com (mailing list archive) |
---|---|
State | Changes Requested |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | ipv6: ensure ip6_dst_mtu_forward() returns at least IPV6_MIN_MTU | expand |
Context | Check | Description |
---|---|---|
netdev/tree_selection | success | Guessing tree name failed - patch did not apply |
On 6/7/21 5:43 PM, Maciej Żenczykowski wrote: > From: Maciej Żenczykowski <maze@google.com> > > ip6_dst_mtu_forward() has just two call sites, one of which already > enforces the minimum mtu (which we can now remove), but it does > materially affect the other (presumably buggy) call site in: > net/netfilter/nf_flow_table_core.c > flow_offload_fill_route() > > Cc: David S. Miller <davem@davemloft.net> > Cc: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org> > Cc: David Ahern <dsahern@kernel.org> > Cc: Jakub Kicinski <kuba@kernel.org> > Signed-off-by: Maciej Żenczykowski <maze@google.com> > --- > include/net/ip6_route.h | 4 ++-- > net/ipv6/ip6_output.c | 2 -- > 2 files changed, 2 insertions(+), 4 deletions(-) > > diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h > index 9dd3c75a4d62..e01364c0821d 100644 > --- a/include/net/ip6_route.h > +++ b/include/net/ip6_route.h > @@ -315,14 +315,14 @@ static inline unsigned int ip6_dst_mtu_forward(const struct dst_entry *dst) > unsigned int mtu = dst_metric_raw(dst, RTAX_MTU); we can prevent a route getting an mtu as a metric that is < IPV6_MIN_MTU. > > if (mtu) > - return mtu; > + return max_t(unsigned int, mtu, IPV6_MIN_MTU); > > rcu_read_lock(); > idev = __in6_dev_get(dst->dev); > mtu = idev ? idev->cnf.mtu6 : IPV6_MIN_MTU; and we can prevent cnf.mtu6 getting set < IPV6_MIN_MTU: addrconf_notify(), NETDEV_CHANGEMTU case. ipv6_add_dev() already requires dev->mtu to be > IPV6_MIN_MTU ndisc_router_discovery requires it. so it seems implausible for the idev to get a value below the minimum. the metric is less clear that it is checked, so it would be the one to make sure is meeting expectations.
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index 9dd3c75a4d62..e01364c0821d 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h @@ -315,14 +315,14 @@ static inline unsigned int ip6_dst_mtu_forward(const struct dst_entry *dst) unsigned int mtu = dst_metric_raw(dst, RTAX_MTU); if (mtu) - return mtu; + return max_t(unsigned int, mtu, IPV6_MIN_MTU); rcu_read_lock(); idev = __in6_dev_get(dst->dev); mtu = idev ? idev->cnf.mtu6 : IPV6_MIN_MTU; rcu_read_unlock(); - return mtu; + return max_t(unsigned int, mtu, IPV6_MIN_MTU); } u32 ip6_mtu_from_fib6(const struct fib6_result *res, diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index ff4f9ebcf7f6..8e56378713cd 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -578,8 +578,6 @@ int ip6_forward(struct sk_buff *skb) } mtu = ip6_dst_mtu_forward(dst); - if (mtu < IPV6_MIN_MTU) - mtu = IPV6_MIN_MTU; if (ip6_pkt_too_big(skb, mtu)) { /* Again, force OUTPUT device used as source address */