From patchwork Mon Mar 13 23:49:10 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Ahern X-Patchwork-Id: 738475 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 3vhvjD4hV2z9s3w for ; Tue, 14 Mar 2017 10:49:20 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=cumulusnetworks.com header.i=@cumulusnetworks.com header.b="XaMLcvZR"; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752354AbdCMXtU (ORCPT ); Mon, 13 Mar 2017 19:49:20 -0400 Received: from mail-pg0-f48.google.com ([74.125.83.48]:34009 "EHLO mail-pg0-f48.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751330AbdCMXtR (ORCPT ); Mon, 13 Mar 2017 19:49:17 -0400 Received: by mail-pg0-f48.google.com with SMTP id 77so72718412pgc.1 for ; Mon, 13 Mar 2017 16:49:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cumulusnetworks.com; s=google; h=from:to:cc:subject:date:message-id; bh=sORn8SzqtpkPLIu19Xc8ERnrCqE9zVpsmFtOR/YDGJ0=; b=XaMLcvZReNEH2CHcMgDHfY7MoZeYmicQrqZkO2DndX2Z3FjQ4xsVdzszbUVuEGvR1e NhCR5Y4X/UoRdOxIvNLbgdyRukmxJ0ve7bb63T2Axo4EPnR7FRxVNYnNpCttyLjPLH5M vb/S+5/GSYHceG1u8pbVztJccS9BUCWv//7yc= 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=sORn8SzqtpkPLIu19Xc8ERnrCqE9zVpsmFtOR/YDGJ0=; b=D6Kqz5KawzzOrHGynegAUuxNYMQf4Jdvts3+ihIvdnTwurTfB75WzLqQx1Qk5kPW5U O0lFBa152eSFk0Zx8jcVKovKfCWJiWQSxJIWN4tAOc0bip7QGcXWjIbexlA9FvjkbIP3 n4784CULUfBvnq8HrYeGr3bkRZBLUALu5t4eL2bdUOwwOwpytjRN5P9e+Y0qTu69nIBW TdVzfpKeFnyfaty2+6txY+kTXfLpEGdQ6fww0KANNlQ+tlCrShAgPIsNtCQcdB6IACgu xA826caZiSX+y2af1wj0XX2Gdn+OGpfj+sv7O24/9wVv31Hjkfv82Z8jIOGfZp6PTRUs TEJw== X-Gm-Message-State: AMke39lIvIwW7IiXEgIGQeczqabXLKV3f9dGkIQMYon9KryMapjevgL7nyWd4kUAxLSjus3P X-Received: by 10.99.126.76 with SMTP id o12mr39465684pgn.1.1489448955635; Mon, 13 Mar 2017 16:49:15 -0700 (PDT) Received: from kenny.it.cumulusnetworks.com. ([216.129.126.126]) by smtp.googlemail.com with ESMTPSA id b190sm34537651pfa.110.2017.03.13.16.49.14 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 13 Mar 2017 16:49:15 -0700 (PDT) From: David Ahern To: netdev@vger.kernel.org Cc: roopa@cumulusnetworks.com, rshearma@brocade.com, David Ahern Subject: [PATCH] net: mpls: Fix nexthop alive tracking on down events Date: Mon, 13 Mar 2017 16:49:10 -0700 Message-Id: <1489448950-13340-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 Alive tracking of nexthops can account for a link twice if the carrier goes down followed by an admin down of the same link rendering multipath routes useless. This is similar to 79099aab38c8 for UNREGISTER events and DOWN events. Fix by tracking number of alive nexthops in mpls_ifdown similar to the logic in mpls_ifup. Checking the flags per nexthop once after all events have been processed is simpler than trying to maintian a running count through all event combinations. Also, WRITE_ONCE is used instead of ACCESS_ONCE to set rt_nhn_alive per a comment from checkpatch: WARNING: Prefer WRITE_ONCE(, ) over ACCESS_ONCE() = Fixes: c89359a42e2a4 ("mpls: support for dead routes") Signed-off-by: David Ahern Acked-by: Robert Shearman --- net/mpls/af_mpls.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c index 33211f9a2656..6414079aa729 100644 --- a/net/mpls/af_mpls.c +++ b/net/mpls/af_mpls.c @@ -1269,6 +1269,8 @@ static void mpls_ifdown(struct net_device *dev, int event) { struct mpls_route __rcu **platform_label; struct net *net = dev_net(dev); + unsigned int nh_flags = RTNH_F_DEAD | RTNH_F_LINKDOWN; + unsigned int alive; unsigned index; platform_label = rtnl_dereference(net->mpls.platform_label); @@ -1278,9 +1280,11 @@ static void mpls_ifdown(struct net_device *dev, int event) if (!rt) continue; + alive = 0; change_nexthops(rt) { if (rtnl_dereference(nh->nh_dev) != dev) - continue; + goto next; + switch (event) { case NETDEV_DOWN: case NETDEV_UNREGISTER: @@ -1288,13 +1292,16 @@ static void mpls_ifdown(struct net_device *dev, int event) /* fall through */ case NETDEV_CHANGE: nh->nh_flags |= RTNH_F_LINKDOWN; - if (event != NETDEV_UNREGISTER) - ACCESS_ONCE(rt->rt_nhn_alive) = rt->rt_nhn_alive - 1; break; } if (event == NETDEV_UNREGISTER) RCU_INIT_POINTER(nh->nh_dev, NULL); +next: + if (!(nh->nh_flags & nh_flags)) + alive++; } endfor_nexthops(rt); + + WRITE_ONCE(rt->rt_nhn_alive, alive); } }