From patchwork Fri Sep 2 05:26:07 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Tomlinson X-Patchwork-Id: 665118 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 3sQSK91DSFz9s5g for ; Fri, 2 Sep 2016 15:26:21 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=alliedtelesis.co.nz header.i=@alliedtelesis.co.nz header.b=N4KvuSru; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751615AbcIBF0Q (ORCPT ); Fri, 2 Sep 2016 01:26:16 -0400 Received: from gate2.alliedtelesis.co.nz ([202.36.163.20]:36405 "EHLO gate2.alliedtelesis.co.nz" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750998AbcIBF0O (ORCPT ); Fri, 2 Sep 2016 01:26:14 -0400 Received: from mmarshal3.atlnz.lc (mmarshal3.atlnz.lc [10.32.18.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by gate2.alliedtelesis.co.nz (Postfix) with ESMTPS id CAB27806B6 for ; Fri, 2 Sep 2016 17:26:10 +1200 (NZST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=alliedtelesis.co.nz; s=mail; t=1472793970; bh=vU/WnIDIDYtxJLKgnnohAx4cFIMWOI+W/HUMrqo4C4s=; h=From:To:Cc:Subject:Date; b=N4KvuSruOix9uY8o0LGNDN1bArGdsP1CPAPF7YRbqYmcSs2VGWtDH94qHzoI27bHX RQTY+vmZNJIUWc1vBIdYjzy4n6ma6WNNZX1yQgB2o9Bzqp1KgerlAcVqv6JIVbYLz9 BGgXqQYaMBibE40MkGL97Yblj/yFtjOJIrHGXoRE= Received: from smtp (Not Verified[10.32.16.33]) by mmarshal3.atlnz.lc with Trustwave SEG (v7, 3, 6, 7949) id ; Fri, 02 Sep 2016 17:26:10 +1200 Received: from markto-dl.ws.atlnz.lc (markto-dl.ws.atlnz.lc [10.33.23.36]) by smtp (Postfix) with ESMTP id 1476B13EC2D; Fri, 2 Sep 2016 17:26:09 +1200 (NZST) Received: by markto-dl.ws.atlnz.lc (Postfix, from userid 1155) id 3ECBC2FEBCF; Fri, 2 Sep 2016 17:26:10 +1200 (NZST) From: Mark Tomlinson To: netdev@vger.kernel.org Cc: Mark Tomlinson Subject: [PATCH] net: Don't delete routes in different VRFs Date: Fri, 2 Sep 2016 17:26:07 +1200 Message-Id: <20160902052607.9303-1-mark.tomlinson@alliedtelesis.co.nz> X-Mailer: git-send-email 2.9.3 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org When deleting an IP address from an interface, there is a clean-up of routes which refer to this local address. However, there was no check to see that the VRF matched. This meant that deletion wasn't confined to the VRF it should have been. To solve this, a new field has been added to fib_info to hold a table id. When removing fib entries corresponding to a local ip address, this table id is also used in the comparison. The table id is populated when the fib_info is created. This was already done in some places, but not in ip_rt_ioctl(). This has now been fixed. Signed-off-by: Mark Tomlinson Acked-by: David Ahern Tested-by: David Ahern --- include/net/ip_fib.h | 3 ++- net/ipv4/fib_frontend.c | 3 ++- net/ipv4/fib_semantics.c | 8 ++++++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h index 4079fc1..7d4a72e 100644 --- a/include/net/ip_fib.h +++ b/include/net/ip_fib.h @@ -111,6 +111,7 @@ struct fib_info { unsigned char fib_scope; unsigned char fib_type; __be32 fib_prefsrc; + u32 fib_tb_id; u32 fib_priority; u32 *fib_metrics; #define fib_mtu fib_metrics[RTAX_MTU-1] @@ -319,7 +320,7 @@ void fib_flush_external(struct net *net); /* Exported by fib_semantics.c */ int ip_fib_check_default(__be32 gw, struct net_device *dev); int fib_sync_down_dev(struct net_device *dev, unsigned long event, bool force); -int fib_sync_down_addr(struct net *net, __be32 local); +int fib_sync_down_addr(struct net_device *dev, __be32 local); int fib_sync_up(struct net_device *dev, unsigned int nh_flags); extern u32 fib_multipath_secret __read_mostly; diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index ef2ebeb..1b25daf 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -509,6 +509,7 @@ static int rtentry_to_fib_config(struct net *net, int cmd, struct rtentry *rt, if (!dev) return -ENODEV; cfg->fc_oif = dev->ifindex; + cfg->fc_table = l3mdev_fib_table(dev); if (colon) { struct in_ifaddr *ifa; struct in_device *in_dev = __in_dev_get_rtnl(dev); @@ -1027,7 +1028,7 @@ no_promotions: * First of all, we scan fib_info list searching * for stray nexthop entries, then ignite fib_flush. */ - if (fib_sync_down_addr(dev_net(dev), ifa->ifa_local)) + if (fib_sync_down_addr(dev, ifa->ifa_local)) fib_flush(dev_net(dev)); } } diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index 539fa26..e9f5622 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c @@ -1057,6 +1057,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg) fi->fib_priority = cfg->fc_priority; fi->fib_prefsrc = cfg->fc_prefsrc; fi->fib_type = cfg->fc_type; + fi->fib_tb_id = cfg->fc_table; fi->fib_nhs = nhs; change_nexthops(fi) { @@ -1337,18 +1338,21 @@ nla_put_failure: * referring to it. * - device went down -> we must shutdown all nexthops going via it. */ -int fib_sync_down_addr(struct net *net, __be32 local) +int fib_sync_down_addr(struct net_device *dev, __be32 local) { int ret = 0; unsigned int hash = fib_laddr_hashfn(local); struct hlist_head *head = &fib_info_laddrhash[hash]; + struct net *net = dev_net(dev); + int tb_id = l3mdev_fib_table(dev); struct fib_info *fi; if (!fib_info_laddrhash || local == 0) return 0; hlist_for_each_entry(fi, head, fib_lhash) { - if (!net_eq(fi->fib_net, net)) + if (!net_eq(fi->fib_net, net) || + fi->fib_tb_id != tb_id) continue; if (fi->fib_prefsrc == local) { fi->fib_flags |= RTNH_F_DEAD;