From patchwork Tue Jan 8 16:48:11 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ido Schimmel X-Patchwork-Id: 1022042 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=mellanox.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=Mellanox.com header.i=@Mellanox.com header.b="GQ9Ds3m4"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 43YyrJ5QqHz9sLw for ; Wed, 9 Jan 2019 03:48:32 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729140AbfAHQsb (ORCPT ); Tue, 8 Jan 2019 11:48:31 -0500 Received: from mail-eopbgr50086.outbound.protection.outlook.com ([40.107.5.86]:21248 "EHLO EUR03-VE1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1729043AbfAHQsa (ORCPT ); Tue, 8 Jan 2019 11:48:30 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Mellanox.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=irBq6d+Vz3Sw+oCxjqZCdLasQkY69eFd2VGVc5REPGY=; b=GQ9Ds3m49U4VzLlPYDzXJGfnCuCWsSzsT/yzPaIMTpeJz/nrEyP7ME0aiZ2W8I7UyC4pmoPi0z5esNh5/FZMnQUbfLNtXDGzxJo+/jAaf3OaYjm0Entp0p7NZzw3MOxx2PQe9DEJuWZR9BnZFJsCy3YUSuL5renFXHecV+nqEIU= Received: from AM6PR05MB6056.eurprd05.prod.outlook.com (20.179.2.148) by AM6PR05MB4405.eurprd05.prod.outlook.com (52.135.163.23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1495.6; Tue, 8 Jan 2019 16:48:11 +0000 Received: from AM6PR05MB6056.eurprd05.prod.outlook.com ([fe80::5490:e4ea:7798:e65f]) by AM6PR05MB6056.eurprd05.prod.outlook.com ([fe80::5490:e4ea:7798:e65f%3]) with mapi id 15.20.1516.010; Tue, 8 Jan 2019 16:48:11 +0000 From: Ido Schimmel To: "netdev@vger.kernel.org" CC: "davem@davemloft.net" , Jiri Pirko , Petr Machata , Nir Dotan , mlxsw , Ido Schimmel , Roopa Prabhu , Nikolay Aleksandrov , "bridge@lists.linux-foundation.org" Subject: [PATCH net 08/11] net: bridge: Fix VLANs memory leak Thread-Topic: [PATCH net 08/11] net: bridge: Fix VLANs memory leak Thread-Index: AQHUp3HwDXy9vcGAcEqIUNVwy3i28w== Date: Tue, 8 Jan 2019 16:48:11 +0000 Message-ID: <20190108164732.4024-9-idosch@mellanox.com> References: <20190108164732.4024-1-idosch@mellanox.com> In-Reply-To: <20190108164732.4024-1-idosch@mellanox.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-clientproxiedby: AM6P192CA0024.EURP192.PROD.OUTLOOK.COM (2603:10a6:209:83::37) To AM6PR05MB6056.eurprd05.prod.outlook.com (2603:10a6:20b:ab::20) authentication-results: spf=none (sender IP is ) smtp.mailfrom=idosch@mellanox.com; x-ms-exchange-messagesentrepresentingtype: 1 x-mailer: git-send-email 2.20.1 x-originating-ip: [193.47.165.251] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; AM6PR05MB4405; 6:vTCaUe5eboUZnssfBscjKb0uzibKhWa+a07IARer6kQdtNWpCeN1CWGr3Q4BL8tLkfdjTpNMLQ2Au+xRNr/JCJmZ+b8JM2lVLFmI5tBz8QHI3n/KaIdf0GJ41xw1Xf9Zo2DZxhVNzr6ciN885+DBxJ2wsXPWx3yHykD46DgGueRhUNRsKQc2F+TUD39ZaKq8uhRisBxVHDuGvo6wo4vGT7UxCFLYloA82FSM76KkzjcWMz5o7lUxxHuA1o8z47T7661EtTWFPKQn8JDcSLKnnflbgXsW/HMJZmvXTNAeB9ZAToZ1/pTgbetvxNGacAj297FjHjHBYHGDqqOLJgi9HaxgZS9kAaBoytDrgbKvlZlnYclKGYI4kbCrl+l9LSXG6dzvWM02qNThDPNCza0zrVXS6KuJ41024SnpOyuEhQzLmJLpYTrAOZw8sr8V6s6D5XTrPWOSpAYY0b86hcINTA==; 5:O0WoFvyy4ArSONdYYuuHNpBgffkYlzcKe5P2wHPuSBza3XIX/pcE5ThjHoh/8deJC1B6dpsl0b9y0+zfUh3M+c7N9BeL0j4CoOmVlwyJQVIsXKtwrE0mVZVKochy4/brbWYDhVZsx/kMlJ6jluE+K3S7KGwSMWZl0Ipwl13vpk3j2o4mdw4zIEeaTa2NYAtXamsPPXUAZitDbfOyWcQOsQ==; 7:q7lpMTQyr4LAqHTMdzNxsFg9eJUK+PFnKVH4NtqruQkm8WpSXfuU0pEiZH6GWUJ9qvDz/OlfxnqvKp/RGaeINnqvs1W3DTvgrk+XcYwpvYg2wIgRZr2spqURUYogVdpiI1+QNMtFAanzuDegU3CqEg== x-ms-office365-filtering-correlation-id: 26b1f9d6-3691-4d40-ef0a-08d675891338 x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0; PCL:0; RULEID:(2390118)(7020095)(4652040)(8989299)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(5600109)(711020)(4618075)(2017052603328)(7153060)(7193020); SRVR:AM6PR05MB4405; x-ms-traffictypediagnostic: AM6PR05MB4405: x-microsoft-antispam-prvs: x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(8211001083)(3230021)(908002)(999002)(5005026)(6040522)(8220060)(2401047)(8121501046)(3002001)(10201501046)(93006095)(93001095)(3231475)(944501520)(52105112)(6055026)(6041310)(20161123564045)(20161123560045)(20161123562045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123558120)(201708071742011)(7699051)(76991095); SRVR:AM6PR05MB4405; BCL:0; PCL:0; RULEID:; SRVR:AM6PR05MB4405; x-forefront-prvs: 0911D5CE78 x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(376002)(346002)(136003)(39860400002)(396003)(366004)(189003)(199004)(106356001)(105586002)(2906002)(6486002)(6116002)(3846002)(99286004)(6506007)(305945005)(486006)(7736002)(102836004)(386003)(76176011)(86362001)(52116002)(26005)(66066001)(5640700003)(6436002)(186003)(97736004)(2501003)(6512007)(2351001)(25786009)(1076003)(478600001)(81156014)(8936002)(36756003)(81166006)(68736007)(4326008)(50226002)(5660300001)(14444005)(256004)(1730700003)(8676002)(6916009)(53936002)(54906003)(316002)(11346002)(14454004)(2616005)(71200400001)(71190400001)(476003)(446003)(505234006); DIR:OUT; SFP:1101; SCL:1; SRVR:AM6PR05MB4405; H:AM6PR05MB6056.eurprd05.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; received-spf: None (protection.outlook.com: mellanox.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam-message-info: YXXB3/QYZW6SQVeES2f1zdu3vJwuN2Z5F3/Imrj/uyNSoXa+ecmd/nwPu+2CTvmmRZ0WKJgm1KAlY9bu/F/Mdc1kf0laNVI3tsL0284msTbW6E2XkiUVqEEBlCVnFmDT2t/6TZYMZuEmSDBiw1WVsVcy8WBRddFd/c4nnW/+1275J/a8PDtruOJfRhfSGRzwef0U7ANEGZ3zwJ9hoxzDx9qXFzMBAtM/QAH0yNvch0nmPa0fLubjxdMjlIiM20MgDCSx4nFb5cSK9XK9t2f3LdbQFCekxLlnHSzRU7yuCMgOfddzppLvEgP+ApuLWN/l spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-OriginatorOrg: Mellanox.com X-MS-Exchange-CrossTenant-Network-Message-Id: 26b1f9d6-3691-4d40-ef0a-08d675891338 X-MS-Exchange-CrossTenant-originalarrivaltime: 08 Jan 2019 16:48:10.5546 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: a652971c-7d2e-4d9b-a6a4-d149256f461b X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM6PR05MB4405 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org When adding / deleting VLANs to / from a bridge port, the bridge driver first tries to propagate the information via switchdev and falls back to the 8021q driver in case the underlying driver does not support switchdev. This can result in a memory leak [1] when VXLAN and mlxsw ports are enslaved to the bridge: $ ip link set dev vxlan0 master br0 # No mlxsw ports are enslaved to 'br0', so mlxsw ignores the switchdev # notification and the bridge driver adds the VLAN on 'vxlan0' via the # 8021q driver $ bridge vlan add vid 10 dev vxlan0 pvid untagged # mlxsw port is enslaved to the bridge $ ip link set dev swp1 master br0 # mlxsw processes the switchdev notification and the 8021q driver is # skipped $ bridge vlan del vid 10 dev vxlan0 This results in 'struct vlan_info' and 'struct vlan_vid_info' being leaked, as they were allocated by the 8021q driver during VLAN addition, but never freed as the 8021q driver was skipped during deletion. Fix this by introducing a new VLAN private flag that indicates whether the VLAN was added on the port by switchdev or the 8021q driver. If the VLAN was added by the 8021q driver, then we make sure to delete it via the 8021q driver as well. [1] unreferenced object 0xffff88822d20b1e8 (size 256): comm "bridge", pid 2532, jiffies 4295216998 (age 1188.830s) hex dump (first 32 bytes): e0 42 97 ce 81 88 ff ff 00 00 00 00 00 00 00 00 .B.............. 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ backtrace: [<00000000f82d851d>] kmem_cache_alloc_trace+0x1be/0x330 [<00000000e0178b02>] vlan_vid_add+0x661/0x920 [<00000000218ebd5f>] __vlan_add+0x1be9/0x3a00 [<000000006eafa1ca>] nbp_vlan_add+0x8b3/0xd90 [<000000003535392c>] br_vlan_info+0x132/0x410 [<00000000aedaa9dc>] br_afspec+0x75c/0x870 [<00000000f5716133>] br_setlink+0x3dc/0x6d0 [<00000000aceca5e2>] rtnl_bridge_setlink+0x615/0xb30 [<00000000a2f2d23e>] rtnetlink_rcv_msg+0x3a3/0xa80 [<0000000064097e69>] netlink_rcv_skb+0x152/0x3c0 [<000000008be8d614>] rtnetlink_rcv+0x21/0x30 [<000000009ab2ca25>] netlink_unicast+0x52f/0x740 [<00000000e7d9ac96>] netlink_sendmsg+0x9c7/0xf50 [<000000005d1e2050>] sock_sendmsg+0xbe/0x120 [<00000000d51426bc>] ___sys_sendmsg+0x778/0x8f0 [<00000000b9d7b2cc>] __sys_sendmsg+0x112/0x270 unreferenced object 0xffff888227454308 (size 32): comm "bridge", pid 2532, jiffies 4295216998 (age 1188.882s) hex dump (first 32 bytes): 88 b2 20 2d 82 88 ff ff 88 b2 20 2d 82 88 ff ff .. -...... -.... 81 00 0a 00 01 00 00 00 00 00 00 00 00 00 00 00 ................ backtrace: [<00000000f82d851d>] kmem_cache_alloc_trace+0x1be/0x330 [<0000000018050631>] vlan_vid_add+0x3e6/0x920 [<00000000218ebd5f>] __vlan_add+0x1be9/0x3a00 [<000000006eafa1ca>] nbp_vlan_add+0x8b3/0xd90 [<000000003535392c>] br_vlan_info+0x132/0x410 [<00000000aedaa9dc>] br_afspec+0x75c/0x870 [<00000000f5716133>] br_setlink+0x3dc/0x6d0 [<00000000aceca5e2>] rtnl_bridge_setlink+0x615/0xb30 [<00000000a2f2d23e>] rtnetlink_rcv_msg+0x3a3/0xa80 [<0000000064097e69>] netlink_rcv_skb+0x152/0x3c0 [<000000008be8d614>] rtnetlink_rcv+0x21/0x30 [<000000009ab2ca25>] netlink_unicast+0x52f/0x740 [<00000000e7d9ac96>] netlink_sendmsg+0x9c7/0xf50 [<000000005d1e2050>] sock_sendmsg+0xbe/0x120 [<00000000d51426bc>] ___sys_sendmsg+0x778/0x8f0 [<00000000b9d7b2cc>] __sys_sendmsg+0x112/0x270 Fixes: d70e42b22dd4 ("mlxsw: spectrum: Enable VxLAN enslavement to VLAN-aware bridges") Signed-off-by: Ido Schimmel Reviewed-by: Petr Machata Cc: Roopa Prabhu Cc: Nikolay Aleksandrov Cc: bridge@lists.linux-foundation.org Acked-by: Nikolay Aleksandrov --- net/bridge/br_private.h | 1 + net/bridge/br_vlan.c | 26 +++++++++++++------------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index d240b3e7919f..eabf8bf28a3f 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -107,6 +107,7 @@ struct br_tunnel_info { /* private vlan flags */ enum { BR_VLFLAG_PER_PORT_STATS = BIT(0), + BR_VLFLAG_ADDED_BY_SWITCHDEV = BIT(1), }; /** diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c index 4a2f31157ef5..96abf8feb9dc 100644 --- a/net/bridge/br_vlan.c +++ b/net/bridge/br_vlan.c @@ -80,16 +80,18 @@ static bool __vlan_add_flags(struct net_bridge_vlan *v, u16 flags) } static int __vlan_vid_add(struct net_device *dev, struct net_bridge *br, - u16 vid, u16 flags, struct netlink_ext_ack *extack) + struct net_bridge_vlan *v, u16 flags, + struct netlink_ext_ack *extack) { int err; /* Try switchdev op first. In case it is not supported, fallback to * 8021q add. */ - err = br_switchdev_port_vlan_add(dev, vid, flags, extack); + err = br_switchdev_port_vlan_add(dev, v->vid, flags, extack); if (err == -EOPNOTSUPP) - return vlan_vid_add(dev, br->vlan_proto, vid); + return vlan_vid_add(dev, br->vlan_proto, v->vid); + v->priv_flags |= BR_VLFLAG_ADDED_BY_SWITCHDEV; return err; } @@ -121,19 +123,17 @@ static void __vlan_del_list(struct net_bridge_vlan *v) } static int __vlan_vid_del(struct net_device *dev, struct net_bridge *br, - u16 vid) + const struct net_bridge_vlan *v) { int err; /* Try switchdev op first. In case it is not supported, fallback to * 8021q del. */ - err = br_switchdev_port_vlan_del(dev, vid); - if (err == -EOPNOTSUPP) { - vlan_vid_del(dev, br->vlan_proto, vid); - return 0; - } - return err; + err = br_switchdev_port_vlan_del(dev, v->vid); + if (!(v->priv_flags & BR_VLFLAG_ADDED_BY_SWITCHDEV)) + vlan_vid_del(dev, br->vlan_proto, v->vid); + return err == -EOPNOTSUPP ? 0 : err; } /* Returns a master vlan, if it didn't exist it gets created. In all cases a @@ -242,7 +242,7 @@ static int __vlan_add(struct net_bridge_vlan *v, u16 flags, * This ensures tagged traffic enters the bridge when * promiscuous mode is disabled by br_manage_promisc(). */ - err = __vlan_vid_add(dev, br, v->vid, flags, extack); + err = __vlan_vid_add(dev, br, v, flags, extack); if (err) goto out; @@ -305,7 +305,7 @@ static int __vlan_add(struct net_bridge_vlan *v, u16 flags, out_filt: if (p) { - __vlan_vid_del(dev, br, v->vid); + __vlan_vid_del(dev, br, v); if (masterv) { if (v->stats && masterv->stats != v->stats) free_percpu(v->stats); @@ -338,7 +338,7 @@ static int __vlan_del(struct net_bridge_vlan *v) __vlan_delete_pvid(vg, v->vid); if (p) { - err = __vlan_vid_del(p->dev, p->br, v->vid); + err = __vlan_vid_del(p->dev, p->br, v); if (err) goto out; } else {