From patchwork Wed Apr 20 21:38:21 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Francesco Ruggeri X-Patchwork-Id: 612859 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 3qqwH76ffdz9t3c for ; Thu, 21 Apr 2016 07:38:27 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=arista.com header.i=@arista.com header.b=jyv/74Rw; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751471AbcDTViZ (ORCPT ); Wed, 20 Apr 2016 17:38:25 -0400 Received: from prod-mx.aristanetworks.com ([162.210.130.12]:3364 "EHLO prod-mx.aristanetworks.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751179AbcDTViZ (ORCPT ); Wed, 20 Apr 2016 17:38:25 -0400 Received: from prod-mx.aristanetworks.com (localhost [127.0.0.1]) by prod-mx.aristanetworks.com (Postfix) with ESMTP id DDBF21387; Wed, 20 Apr 2016 14:38:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=arista.com; s=AristaCom; t=1461188303; bh=oHF2PHFtYxr6DyxzacOumG5J7zekpdPau4NPCd0nwv0=; h=From:To:Cc:Subject:Date; b=jyv/74RwdOo+C1cWBUE28Nbm/6O20XmcQ62gujfEuk2fJlukxX1z1H5rLwp6CXEMw Is3QtMn8xtjz+cvhY5/b22tecHS60bCahR86K9UgYYzmV8BJ3U6r1EF7cJ9BIymoiN 5lcTTUMtES7XXjWBfCVuqfgp+/XmPWuXk1AjzhfQ= Received: from fruggeri-Arora18-1.sjc.aristanetworks.com (unknown [10.95.0.201]) by prod-mx.aristanetworks.com (Postfix) with ESMTP id CE2F2AE8; Wed, 20 Apr 2016 14:38:23 -0700 (PDT) Received: by fruggeri-Arora18-1.sjc.aristanetworks.com (Postfix, from userid 10189) id 931B2203F81; Wed, 20 Apr 2016 14:38:23 -0700 (PDT) From: Francesco Ruggeri To: netdev@vger.kernel.org Cc: Francesco Ruggeri , "David S. Miller" , "Eric W. Biederman" , Mahesh Bandewar Subject: [PATCH net-next] macvlan: fix failure during registration v2 Date: Wed, 20 Apr 2016 14:38:21 -0700 Message-Id: <1461188301-4466-1-git-send-email-fruggeri@arista.com> X-Mailer: git-send-email 1.8.1.4 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org If macvlan_common_newlink fails in register_netdevice after macvlan_init then it decrements port->count twice, first in macvlan_uninit (from register_netdevice or rollback_registered) and then again in macvlan_common_newlink. A similar problem may exist in the ipvlan driver. This patch consolidates modifications to port->count into macvlan_init and macvlan_uninit (thanks to Eric Biederman for suggesting this approach). In macvtap_device_event it also avoids cleaning up in NETDEV_UNREGISTER if NETDEV_REGISTER had previously failed. Signed-off-by: Francesco Ruggeri --- drivers/net/macvlan.c | 10 ++++------ drivers/net/macvtap.c | 2 ++ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 2bcf1f3..cb01023 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -795,6 +795,7 @@ static int macvlan_init(struct net_device *dev) { struct macvlan_dev *vlan = netdev_priv(dev); const struct net_device *lowerdev = vlan->lowerdev; + struct macvlan_port *port = vlan->port; dev->state = (dev->state & ~MACVLAN_STATE_MASK) | (lowerdev->state & MACVLAN_STATE_MASK); @@ -812,6 +813,8 @@ static int macvlan_init(struct net_device *dev) if (!vlan->pcpu_stats) return -ENOMEM; + port->count += 1; + return 0; } @@ -1312,10 +1315,9 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev, return err; } - port->count += 1; err = register_netdevice(dev); if (err < 0) - goto destroy_port; + return err; dev->priv_flags |= IFF_MACVLAN; err = netdev_upper_dev_link(lowerdev, dev); @@ -1330,10 +1332,6 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev, unregister_netdev: unregister_netdevice(dev); -destroy_port: - port->count -= 1; - if (!port->count) - macvlan_port_destroy(lowerdev); return err; } diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 95394ed..e770221 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c @@ -1303,6 +1303,8 @@ static int macvtap_device_event(struct notifier_block *unused, } break; case NETDEV_UNREGISTER: + if (vlan->minor == 0) + break; devt = MKDEV(MAJOR(macvtap_major), vlan->minor); device_destroy(macvtap_class, devt); macvtap_free_minor(vlan);