Received: by 10.213.65.68 with SMTP id h4csp1823853imn; Thu, 29 Mar 2018 11:42:26 -0700 (PDT) X-Google-Smtp-Source: AIpwx488PMh0PVnGvmW2ujA3IUqsD/f+eH0ZURY9EJl0oj8f7YBbKdNB5VBc9CShMHgaVKkQhMCd X-Received: by 10.167.128.71 with SMTP id y7mr4851117pfm.12.1522348946005; Thu, 29 Mar 2018 11:42:26 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1522348945; cv=none; d=google.com; s=arc-20160816; b=Zvpjr3mE9KmBO8t16fYU3pYvm8pJDnVpvSzOBaLSPYDSdVhQfEieVT4a2KKAVBLoBI PSWgBI9vjWzbtw2FC3cVsceRD0ats3TB2UVcNROGpmGwwn/KDH9kXr5QXKhAM4d8FWND 6FNL0zrs5NfWmKkog1FXWb+byQUVvDdFJ8xMw2w5JpkZ3J3jGqXO4BosU+k+qCGAvIUF g+QZ4UePXKn1rT8zZK6WX6YyZc4z139j85nVZMRVGxXLFoSFEA9fzL389fJMRkKnzgJT iQzZruiVUQTvPzMBlvGoK0oNsq6PN6gn8KO3IoBKjcaJqH/jB6M5duyIHcoC4TZQkJ/j Cl7Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:user-agent:references :in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=gu8nIKo1SR78OdYOk9jbi/ZVYlLrYIep7NpCUpPwTe8=; b=Hm2IugVoTeM1qMaOaLBPbLYaKDQW0GgrBy7Vf9GyT6wKCwQanJfr/Jz7MQLRvWIYYn KPMx3rgkikp+GAGoIfl/R8OzOye/zF0oXsuf0lYFgSGiEUjR+6ssgiuCtVXGsnc/9KY2 3t2gurXm0/eElSgs9W6RkU2K2DeWhMIkqOI1W37NXGRDtBBuF8HIx5NEskpFlq08eTR4 tJrPJhVCY30Mfk+9bduFC/n4SoueEzPbIkXD9zayqLHlwBA5r9vRBb5v/rTH+jtFd9Jl zYI+W6M1at+Eqt9SPoQz1Uob4Z9LtTzXswywxKMvmk4uR5yy7XmNGm05tOyggdxW5Fxn wxiQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id l186si4322423pge.224.2018.03.29.11.42.12; Thu, 29 Mar 2018 11:42:25 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752645AbeC2Sk5 (ORCPT + 99 others); Thu, 29 Mar 2018 14:40:57 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:58066 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752236AbeC2SCF (ORCPT ); Thu, 29 Mar 2018 14:02:05 -0400 Received: from localhost (LFbn-1-12247-202.w90-92.abo.wanadoo.fr [90.92.61.202]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id A68E4C13; Thu, 29 Mar 2018 18:02:04 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Xiumei Mu , Stefano Brivio , David Ahern , "David S. Miller" Subject: [PATCH 4.15 16/47] ipv6: Reflect MTU changes on PMTU of exceptions for MTU-less routes Date: Thu, 29 Mar 2018 19:59:57 +0200 Message-Id: <20180329175730.282656709@linuxfoundation.org> X-Mailer: git-send-email 2.16.3 In-Reply-To: <20180329175729.225211114@linuxfoundation.org> References: <20180329175729.225211114@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.15-stable review patch. If anyone has any objections, please let me know. ------------------ From: Stefano Brivio [ Upstream commit e9fa1495d738e34fcec88a3d2ec9101a9ee5b310 ] Currently, administrative MTU changes on a given netdevice are not reflected on route exceptions for MTU-less routes, with a set PMTU value, for that device: # ip -6 route get 2001:db8::b 2001:db8::b from :: dev vti_a proto kernel src 2001:db8::a metric 256 pref medium # ping6 -c 1 -q -s10000 2001:db8::b > /dev/null # ip netns exec a ip -6 route get 2001:db8::b 2001:db8::b from :: dev vti_a src 2001:db8::a metric 0 cache expires 571sec mtu 4926 pref medium # ip link set dev vti_a mtu 3000 # ip -6 route get 2001:db8::b 2001:db8::b from :: dev vti_a src 2001:db8::a metric 0 cache expires 571sec mtu 4926 pref medium # ip link set dev vti_a mtu 9000 # ip -6 route get 2001:db8::b 2001:db8::b from :: dev vti_a src 2001:db8::a metric 0 cache expires 571sec mtu 4926 pref medium The first issue is that since commit fb56be83e43d ("net-ipv6: on device mtu change do not add mtu to mtu-less routes") we don't call rt6_exceptions_update_pmtu() from rt6_mtu_change_route(), which handles administrative MTU changes, if the regular route is MTU-less. However, PMTU exceptions should be always updated, as long as RTAX_MTU is not locked. Keep the check for MTU-less main route, as introduced by that commit, but, for exceptions, call rt6_exceptions_update_pmtu() regardless of that check. Once that is fixed, one problem remains: MTU changes are not reflected if the new MTU is higher than the previous one, because rt6_exceptions_update_pmtu() doesn't allow that. We should instead allow PMTU increase if the old PMTU matches the local MTU, as that implies that the old MTU was the lowest in the path, and PMTU discovery might lead to different results. The existing check in rt6_mtu_change_route() correctly took that case into account (for regular routes only), so factor it out and re-use it also in rt6_exceptions_update_pmtu(). While at it, fix comments style and grammar, and try to be a bit more descriptive. Reported-by: Xiumei Mu Fixes: fb56be83e43d ("net-ipv6: on device mtu change do not add mtu to mtu-less routes") Fixes: f5bbe7ee79c2 ("ipv6: prepare rt6_mtu_change() for exception table") Signed-off-by: Stefano Brivio Acked-by: David Ahern Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/ipv6/route.c | 71 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 42 insertions(+), 29 deletions(-) --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1510,7 +1510,30 @@ static void rt6_exceptions_remove_prefsr } } -static void rt6_exceptions_update_pmtu(struct rt6_info *rt, int mtu) +static bool rt6_mtu_change_route_allowed(struct inet6_dev *idev, + struct rt6_info *rt, int mtu) +{ + /* If the new MTU is lower than the route PMTU, this new MTU will be the + * lowest MTU in the path: always allow updating the route PMTU to + * reflect PMTU decreases. + * + * If the new MTU is higher, and the route PMTU is equal to the local + * MTU, this means the old MTU is the lowest in the path, so allow + * updating it: if other nodes now have lower MTUs, PMTU discovery will + * handle this. + */ + + if (dst_mtu(&rt->dst) >= mtu) + return true; + + if (dst_mtu(&rt->dst) == idev->cnf.mtu6) + return true; + + return false; +} + +static void rt6_exceptions_update_pmtu(struct inet6_dev *idev, + struct rt6_info *rt, int mtu) { struct rt6_exception_bucket *bucket; struct rt6_exception *rt6_ex; @@ -1519,20 +1542,22 @@ static void rt6_exceptions_update_pmtu(s bucket = rcu_dereference_protected(rt->rt6i_exception_bucket, lockdep_is_held(&rt6_exception_lock)); - if (bucket) { - for (i = 0; i < FIB6_EXCEPTION_BUCKET_SIZE; i++) { - hlist_for_each_entry(rt6_ex, &bucket->chain, hlist) { - struct rt6_info *entry = rt6_ex->rt6i; - /* For RTF_CACHE with rt6i_pmtu == 0 - * (i.e. a redirected route), - * the metrics of its rt->dst.from has already - * been updated. - */ - if (entry->rt6i_pmtu && entry->rt6i_pmtu > mtu) - entry->rt6i_pmtu = mtu; - } - bucket++; + if (!bucket) + return; + + for (i = 0; i < FIB6_EXCEPTION_BUCKET_SIZE; i++) { + hlist_for_each_entry(rt6_ex, &bucket->chain, hlist) { + struct rt6_info *entry = rt6_ex->rt6i; + + /* For RTF_CACHE with rt6i_pmtu == 0 (i.e. a redirected + * route), the metrics of its rt->dst.from have already + * been updated. + */ + if (entry->rt6i_pmtu && + rt6_mtu_change_route_allowed(idev, entry, mtu)) + entry->rt6i_pmtu = mtu; } + bucket++; } } @@ -3521,25 +3546,13 @@ static int rt6_mtu_change_route(struct r Since RFC 1981 doesn't include administrative MTU increase update PMTU increase is a MUST. (i.e. jumbo frame) */ - /* - If new MTU is less than route PMTU, this new MTU will be the - lowest MTU in the path, update the route PMTU to reflect PMTU - decreases; if new MTU is greater than route PMTU, and the - old MTU is the lowest MTU in the path, update the route PMTU - to reflect the increase. In this case if the other nodes' MTU - also have the lowest MTU, TOO BIG MESSAGE will be lead to - PMTU discovery. - */ if (rt->dst.dev == arg->dev && - dst_metric_raw(&rt->dst, RTAX_MTU) && !dst_metric_locked(&rt->dst, RTAX_MTU)) { spin_lock_bh(&rt6_exception_lock); - if (dst_mtu(&rt->dst) >= arg->mtu || - (dst_mtu(&rt->dst) < arg->mtu && - dst_mtu(&rt->dst) == idev->cnf.mtu6)) { + if (dst_metric_raw(&rt->dst, RTAX_MTU) && + rt6_mtu_change_route_allowed(idev, rt, arg->mtu)) dst_metric_set(&rt->dst, RTAX_MTU, arg->mtu); - } - rt6_exceptions_update_pmtu(rt, arg->mtu); + rt6_exceptions_update_pmtu(idev, rt, arg->mtu); spin_unlock_bh(&rt6_exception_lock); } return 0;