summaryrefslogtreecommitdiffstats
path: root/drivers/net/macvlan.c
diff options
context:
space:
mode:
authorGao Feng <fgao@ikuai8.com>2016-11-03 22:28:49 -0400
committerDavid S. Miller <davem@davemloft.net>2016-11-09 13:14:47 -0500
commitaa5fd0fb77486b8a6764ead8627baa14790e4280 (patch)
tree6e70de9e52fc25034e88dd6836a418e795b23ec1 /drivers/net/macvlan.c
parentfd0285a39b1cb496f60210a9a00ad33a815603e7 (diff)
driver: macvlan: Destroy new macvlan port if macvlan_common_newlink failed.
When there is no existing macvlan port in lowdev, one new macvlan port would be created. But it doesn't be destoried when something failed later. It casues some memleak. Now add one flag to indicate if new macvlan port is created. Signed-off-by: Gao Feng <fgao@ikuai8.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/macvlan.c')
-rw-r--r--drivers/net/macvlan.c31
1 files changed, 22 insertions, 9 deletions
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 3234fcdea317..d2d6f12a112f 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -1278,6 +1278,7 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
1278 struct net_device *lowerdev; 1278 struct net_device *lowerdev;
1279 int err; 1279 int err;
1280 int macmode; 1280 int macmode;
1281 bool create = false;
1281 1282
1282 if (!tb[IFLA_LINK]) 1283 if (!tb[IFLA_LINK])
1283 return -EINVAL; 1284 return -EINVAL;
@@ -1304,12 +1305,18 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
1304 err = macvlan_port_create(lowerdev); 1305 err = macvlan_port_create(lowerdev);
1305 if (err < 0) 1306 if (err < 0)
1306 return err; 1307 return err;
1308 create = true;
1307 } 1309 }
1308 port = macvlan_port_get_rtnl(lowerdev); 1310 port = macvlan_port_get_rtnl(lowerdev);
1309 1311
1310 /* Only 1 macvlan device can be created in passthru mode */ 1312 /* Only 1 macvlan device can be created in passthru mode */
1311 if (port->passthru) 1313 if (port->passthru) {
1312 return -EINVAL; 1314 /* The macvlan port must be not created this time,
1315 * still goto destroy_macvlan_port for readability.
1316 */
1317 err = -EINVAL;
1318 goto destroy_macvlan_port;
1319 }
1313 1320
1314 vlan->lowerdev = lowerdev; 1321 vlan->lowerdev = lowerdev;
1315 vlan->dev = dev; 1322 vlan->dev = dev;
@@ -1325,24 +1332,28 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
1325 vlan->flags = nla_get_u16(data[IFLA_MACVLAN_FLAGS]); 1332 vlan->flags = nla_get_u16(data[IFLA_MACVLAN_FLAGS]);
1326 1333
1327 if (vlan->mode == MACVLAN_MODE_PASSTHRU) { 1334 if (vlan->mode == MACVLAN_MODE_PASSTHRU) {
1328 if (port->count) 1335 if (port->count) {
1329 return -EINVAL; 1336 err = -EINVAL;
1337 goto destroy_macvlan_port;
1338 }
1330 port->passthru = true; 1339 port->passthru = true;
1331 eth_hw_addr_inherit(dev, lowerdev); 1340 eth_hw_addr_inherit(dev, lowerdev);
1332 } 1341 }
1333 1342
1334 if (data && data[IFLA_MACVLAN_MACADDR_MODE]) { 1343 if (data && data[IFLA_MACVLAN_MACADDR_MODE]) {
1335 if (vlan->mode != MACVLAN_MODE_SOURCE) 1344 if (vlan->mode != MACVLAN_MODE_SOURCE) {
1336 return -EINVAL; 1345 err = -EINVAL;
1346 goto destroy_macvlan_port;
1347 }
1337 macmode = nla_get_u32(data[IFLA_MACVLAN_MACADDR_MODE]); 1348 macmode = nla_get_u32(data[IFLA_MACVLAN_MACADDR_MODE]);
1338 err = macvlan_changelink_sources(vlan, macmode, data); 1349 err = macvlan_changelink_sources(vlan, macmode, data);
1339 if (err) 1350 if (err)
1340 return err; 1351 goto destroy_macvlan_port;
1341 } 1352 }
1342 1353
1343 err = register_netdevice(dev); 1354 err = register_netdevice(dev);
1344 if (err < 0) 1355 if (err < 0)
1345 return err; 1356 goto destroy_macvlan_port;
1346 1357
1347 dev->priv_flags |= IFF_MACVLAN; 1358 dev->priv_flags |= IFF_MACVLAN;
1348 err = netdev_upper_dev_link(lowerdev, dev); 1359 err = netdev_upper_dev_link(lowerdev, dev);
@@ -1357,7 +1368,9 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
1357 1368
1358unregister_netdev: 1369unregister_netdev:
1359 unregister_netdevice(dev); 1370 unregister_netdevice(dev);
1360 1371destroy_macvlan_port:
1372 if (create)
1373 macvlan_port_destroy(port->dev);
1361 return err; 1374 return err;
1362} 1375}
1363EXPORT_SYMBOL_GPL(macvlan_common_newlink); 1376EXPORT_SYMBOL_GPL(macvlan_common_newlink);