From patchwork Thu Dec 10 01:35:08 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Ahern X-Patchwork-Id: 554969 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 85735140F99 for ; Thu, 10 Dec 2015 12:35:42 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=cumulusnetworks.com header.i=@cumulusnetworks.com header.b=SblI8j4p; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751286AbbLJBfi (ORCPT ); Wed, 9 Dec 2015 20:35:38 -0500 Received: from mail-pf0-f172.google.com ([209.85.192.172]:33322 "EHLO mail-pf0-f172.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750910AbbLJBfh (ORCPT ); Wed, 9 Dec 2015 20:35:37 -0500 Received: by pfnn128 with SMTP id n128so38979026pfn.0 for ; Wed, 09 Dec 2015 17:35:36 -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=QBidr2buF12i3dTaK7LoEVrW8ogYZBkNEEbAEs5bFL4=; b=SblI8j4pMinAxqXU1BelZq1CHan/pfakQmq/DSex6ccC8mhSkSGFBq6us9jvDbc0pJ hm78gFvM1jZDrdr5UoRKDI2T3kGZ7gf3OEcBxSunsDZPfhq/23jVzN62H95GzYtQ5XB3 kaSXOg0tHJ6g2Eu/k90UN/v9upjFeEPKdDBXI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=QBidr2buF12i3dTaK7LoEVrW8ogYZBkNEEbAEs5bFL4=; b=JXkM2A/AUF3kTKQ3dmqumf5IVaDWx5l5Gf6w9ELc6n41mG3gcKJ0djvw0P6QNCNKtF x0uPDAzUtW1nTeisJHeF1zMvAUpdv3ist6YDqJYEBGpSwLU/OFmiOD8UnDwatc7pWMeF IQHqkQnkQcGBDiL4sdJXF9A+GJgFD4Py7X1uEbcSSPLlXvkkyCOhzNBjEEv848jE3gJq 9gyZCHkMX/eCgPXGmAJzN/VbCww9HAha3u2hMqlZTpBDCPlPjPbWc2zK4rRtjP519pEN FD2OkBVoiyfbmo1xwiXG+Fehfbzs8hPNWXWCuqNaboPwwiSm3d40PaPbiI2cA0mCbJVK Q4uQ== X-Gm-Message-State: ALoCoQlwdcKVxd3FMskjgMBBeBaO+ECZlN75D2guoYQEbiTsgcQG+m92HFXYKSB73GHXg3AztLIX+IG6jL6Fpu8tSm1DJOCb5g== X-Received: by 10.98.8.211 with SMTP id 80mr2961872pfi.136.1449711336615; Wed, 09 Dec 2015 17:35:36 -0800 (PST) Received: from monster-14.cumulusnetworks.com. ([216.129.126.126]) by smtp.googlemail.com with ESMTPSA id sg4sm14532421pac.48.2015.12.09.17.35.35 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 09 Dec 2015 17:35:35 -0800 (PST) From: David Ahern To: netdev@vger.kernel.org Cc: ja@ssi.bg, David Ahern Subject: [PATCH net] net: Flush local routes when device changes vrf association Date: Wed, 9 Dec 2015 17:35:08 -0800 Message-Id: <1449711308-35842-1-git-send-email-dsa@cumulusnetworks.com> X-Mailer: git-send-email 1.9.1 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The VRF driver cycles netdevs when an interface is enslaved or released: the down event is used to flush neighbor and route tables and the up event (if the interface was already up) effectively moves local and connected routes to the proper table. As of 4f823defdd5b the local route is left hanging around after a link down, so when a netdev is moved from one VRF to another (or released from a VRF altogether) local routes are left in the wrong table. Fix by introducing a NETDEV_VRF_CHANGE event that can be used to trigger the flush of all routes, including local ones. Fixes: 4f823defdd5b ("ipv4: fix to not remove local route on link down") Cc: Julian Anastasov Signed-off-by: David Ahern --- Dave: longer term I would like to use the NETDEV_VRF_CHANGE event to reduce the processing on a VRF change, for instance not losing IPv6 addresses on the move. drivers/net/vrf.c | 9 +++++++-- include/linux/netdevice.h | 1 + net/ipv4/fib_frontend.c | 3 +++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c index b9918e8415ea..36d57f06efde 100644 --- a/drivers/net/vrf.c +++ b/drivers/net/vrf.c @@ -601,12 +601,17 @@ static void cycle_netdev(struct net_device *dev) unsigned int flags = dev->flags; int ret; - if (!netif_running(dev)) + if (!netif_running(dev)) { + call_netdevice_notifiers(NETDEV_VRF_CHANGE, dev); return; + } ret = dev_change_flags(dev, flags & ~IFF_UP); - if (ret >= 0) + if (ret >= 0) { + call_netdevice_notifiers(NETDEV_VRF_CHANGE, dev); + ret = dev_change_flags(dev, flags); + } if (ret < 0) { netdev_err(dev, diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 1bb21ff0fa64..858fa09423ea 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -2165,6 +2165,7 @@ struct netdev_lag_lower_state_info { #define NETDEV_BONDING_INFO 0x0019 #define NETDEV_PRECHANGEUPPER 0x001A #define NETDEV_CHANGELOWERSTATE 0x001B +#define NETDEV_VRF_CHANGE 0x001C int register_netdevice_notifier(struct notifier_block *nb); int unregister_netdevice_notifier(struct notifier_block *nb); diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index cc8f3e506cde..7d30f6436e3b 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -1193,6 +1193,9 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo case NETDEV_CHANGEMTU: rt_cache_flush(net); break; + case NETDEV_VRF_CHANGE: + fib_disable_ip(dev, NETDEV_DOWN, true); + break; } return NOTIFY_DONE; }