From patchwork Thu Apr 7 18:10:41 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Ahern X-Patchwork-Id: 607613 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 3qgrHc59qkz9t7R for ; Fri, 8 Apr 2016 04:10:52 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=cumulusnetworks.com header.i=@cumulusnetworks.com header.b=P+tDGwEn; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757160AbcDGSKv (ORCPT ); Thu, 7 Apr 2016 14:10:51 -0400 Received: from mail-pf0-f182.google.com ([209.85.192.182]:35025 "EHLO mail-pf0-f182.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756790AbcDGSKt (ORCPT ); Thu, 7 Apr 2016 14:10:49 -0400 Received: by mail-pf0-f182.google.com with SMTP id n1so60116389pfn.2 for ; Thu, 07 Apr 2016 11:10:49 -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=ruTi+CIIKzSGFm9PZYGYh87aF1X08RD8wthv/T0nu8Q=; b=P+tDGwEnn/7GFRko+B+MqBbcJqfKJJi2zyE9+Dg3Hk4ST1IKZRqJBCJJ73lQFgzTKJ dKtw2JerG1liKFxlxJLATmXcdU1wuV0/pF7kDodNH8wARpA2VpX2aMgCPX/bdRG+v04J NSvZfnPpxSt07cgGNh6QPBhzRvqZaaC/Utsng= 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=ruTi+CIIKzSGFm9PZYGYh87aF1X08RD8wthv/T0nu8Q=; b=jLDWFQkILQ5aFwhvM0mflR2y1rTr2y3cIrd2ox+7Ph/EUkRRDu8Hz4PrvhX+ENY5ts voqiq2EPrO+5zuk/xtTiD8GYmpt9+2maGbBGcCUoyUzN6yvNgIoJsY9OPkSboE03pxnj Qticf71cDSomWPlWjz8ph9yIAlkOlOw/zCL+k7J69qRoIHEYYtkMZapObpn1uA1GkBs8 7DgAo+e4kYzG2Sr3kb13aWcw72K4tMU0hfQl+VBC9ZQHVvKE5ctPQX0ILe4e0KMbXfSN dqNJAHSojJAVjY4/iYouYu/o1iGeKKs5kZ6GDKjFtoKadDBSwqn1XmeiIBjPKo1Izqp/ MCmg== X-Gm-Message-State: AD7BkJKkOXTBwwVHMl4XA/dd3jaUd41m2b7GD5lfjzKLY+rmmaqoJnIxJIsxXh0ry7D3mCFl X-Received: by 10.98.71.147 with SMTP id p19mr6384744pfi.135.1460052649056; Thu, 07 Apr 2016 11:10:49 -0700 (PDT) Received: from kenny.cumulusnetworks.com. ([216.129.126.126]) by smtp.googlemail.com with ESMTPSA id l4sm13654360pfi.73.2016.04.07.11.10.47 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 07 Apr 2016 11:10:48 -0700 (PDT) From: David Ahern To: netdev@vger.kernel.org Cc: David Ahern Subject: [PATCH] net: vrf: Fix dev refcnt leak due to IPv6 prefix route Date: Thu, 7 Apr 2016 11:10:41 -0700 Message-Id: <1460052641-1155-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 ifupdown2 found a kernel bug with IPv6 routes and movement from the main table to the VRF table. Sequence of events: Create the interface and add addresses: ip link add dev eth4.105 link eth4 type vlan id 105 ip addr add dev eth4.105 8.105.105.10/24 ip -6 addr add dev eth4.105 2008:105:105::10/64 At this point IPv6 has inserted a prefix route in the main table even though the interface is 'down'. From there the VRF device is created: ip link add dev vrf105 type vrf table 105 ip addr add dev vrf105 9.9.105.10/32 ip -6 addr add dev vrf105 2000:9:105::10/128 ip link set vrf105 up Then the interface is enslaved, while still in the 'down' state: ip link set dev eth4.105 master vrf105 Since the device is down the VRF driver cycling the device does not send the NETDEV_UP and NETDEV_DOWN but rather the NETDEV_CHANGE event which does not flush the routes inserted prior. When the link is brought up ip link set dev eth4.105 up the prefix route is added in the VRF table, but does not remove the route from the main table. Fix by handling the NETDEV_CHANGEUPPER event similar what was implemented for IPv4 in 7f49e7a38b77 ("net: Flush local routes when device changes vrf association") Fixes: 35402e3136634 ("net: Add IPv6 support to VRF device") Signed-off-by: David Ahern --- net/ipv6/addrconf.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 27aed1afcf81..2db2116d3e6b 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -3255,6 +3255,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, void *ptr) { struct net_device *dev = netdev_notifier_info_to_dev(ptr); + struct netdev_notifier_changeupper_info *info; struct inet6_dev *idev = __in6_dev_get(dev); int run_pending = 0; int err; @@ -3413,6 +3414,15 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, if (idev) addrconf_type_change(dev, event); break; + + case NETDEV_CHANGEUPPER: + info = ptr; + + /* flush all routes if dev is linked to or unlinked from + * an L3 master device (e.g., VRF) + */ + if (info->upper_dev && netif_is_l3_master(info->upper_dev)) + addrconf_ifdown(dev, 0); } return NOTIFY_OK;