From patchwork Fri Mar 10 22:11:39 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Ahern X-Patchwork-Id: 737594 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3vg1hB5zbWz9s7v for ; Sat, 11 Mar 2017 09:11:54 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=cumulusnetworks.com header.i=@cumulusnetworks.com header.b="P7SFJKV9"; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934257AbdCJWLs (ORCPT ); Fri, 10 Mar 2017 17:11:48 -0500 Received: from mail-pf0-f176.google.com ([209.85.192.176]:35725 "EHLO mail-pf0-f176.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932482AbdCJWLq (ORCPT ); Fri, 10 Mar 2017 17:11:46 -0500 Received: by mail-pf0-f176.google.com with SMTP id j5so46608473pfb.2 for ; Fri, 10 Mar 2017 14:11:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cumulusnetworks.com; s=google; h=from:to:cc:subject:date:message-id; bh=OYqCx5bcZVuxv10t+kb0CuSsxTr6aPDVQtEsJmwhrnA=; b=P7SFJKV9RSz6jnQoUTMTooTOrEw3yMj783zSXnhT1rriqa1sI+iulzZfFYLg0aSFyk y05JPvqKfoL76loSoq8VJzeb8c4Sj6aTqc17tFzVqZklpQk3F3a53O3ElCSPomAsRhjA hWz1bz32HgD7tEDQDECiVzVLQ5uvAK/JBkuvA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=OYqCx5bcZVuxv10t+kb0CuSsxTr6aPDVQtEsJmwhrnA=; b=XlMQrJFO6pgkbXUO4WySAA+fnKGbcm9k+XrfsMzDkjDj08K2JJ+7c99/nRiNEznULK UmbjnTCTwVIHzF3Kxms0PqJKkuPHVVoAqeNlsq1z0DVKRbr6H79Js8+N9+T29+2UpHtX 0CF7RmT8IXq4Q8bmLmcfWzERY9n+SHRlHzZeXYy5O7/SdOb4C1inU1/20YtaKpvtADh7 tjb5bN3iup89mhbW8ABX70bLQIScpyQV4SfZDgNi5W2tbRdyN8rYuMxWqJGKiYpUG64c WTdsoWbxE6A7w9tH9LD6Uc1/cJ+9VwKsVLc26i7WuGMEoKiyM0B2EGhJPmOoVUS2WxRq EXpg== X-Gm-Message-State: AMke39kML3Gk3Tq2U1mwZtT1vqBoGJ7W90pYX7+IIFB/wyPKiek5CEfImhcCruP8Mon0c+Gr X-Received: by 10.98.59.8 with SMTP id i8mr23787165pfa.132.1489183904645; Fri, 10 Mar 2017 14:11:44 -0800 (PST) Received: from kenny.it.cumulusnetworks.com. ([216.129.126.126]) by smtp.googlemail.com with ESMTPSA id m20sm20525318pgd.67.2017.03.10.14.11.43 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 10 Mar 2017 14:11:44 -0800 (PST) From: David Ahern To: netdev@vger.kernel.org Cc: roopa@cumulusnetworks.com, David Ahern Subject: [PATCH] mpls: Do not decrement alive counter for unregister events Date: Fri, 10 Mar 2017 14:11:39 -0800 Message-Id: <1489183899-2397-1-git-send-email-dsa@cumulusnetworks.com> X-Mailer: git-send-email 2.1.4 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Multipath routes can be rendered usesless when a device in one of the paths is deleted. For example: $ ip -f mpls ro ls 100 nexthop as to 200 via inet 172.16.2.2 dev virt12 nexthop as to 300 via inet 172.16.3.2 dev br0 101 nexthop as to 201 via inet6 2000:2::2 dev virt12 nexthop as to 301 via inet6 2000:3::2 dev br0 $ ip li del br0 When br0 is deleted the other hop is not considered in mpls_select_multipath because of the alive check -- rt_nhn_alive is 0. rt_nhn_alive is decremented once in mpls_ifdown when the device is taken down (NETDEV_DOWN) and again when it is deleted (NETDEV_UNREGISTER). For a 2 hop route, deleting one device drops the alive count to 0. Since devices are taken down before unregistering, the decrement on NETDEV_UNREGISTER is redundant. Fixes: c89359a42e2a4 ("mpls: support for dead routes") Signed-off-by: David Ahern --- net/mpls/af_mpls.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c index ccdac9c44fdc..22a9971aa484 100644 --- a/net/mpls/af_mpls.c +++ b/net/mpls/af_mpls.c @@ -1288,7 +1288,8 @@ static void mpls_ifdown(struct net_device *dev, int event) /* fall through */ case NETDEV_CHANGE: nh->nh_flags |= RTNH_F_LINKDOWN; - ACCESS_ONCE(rt->rt_nhn_alive) = rt->rt_nhn_alive - 1; + if (event != NETDEV_UNREGISTER) + ACCESS_ONCE(rt->rt_nhn_alive) = rt->rt_nhn_alive - 1; break; } if (event == NETDEV_UNREGISTER)