Skip to content

Commit

Permalink
driver: macvlan: Destroy new macvlan port if macvlan_common_newlink f…
Browse files Browse the repository at this point in the history
…ailed.

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>
  • Loading branch information
Gao Feng authored and David S. Miller committed Nov 9, 2016
1 parent fd0285a commit aa5fd0f
Showing 1 changed file with 22 additions and 9 deletions.
31 changes: 22 additions & 9 deletions drivers/net/macvlan.c
Original file line number Diff line number Diff line change
Expand Up @@ -1278,6 +1278,7 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
struct net_device *lowerdev;
int err;
int macmode;
bool create = false;

if (!tb[IFLA_LINK])
return -EINVAL;
Expand All @@ -1304,12 +1305,18 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
err = macvlan_port_create(lowerdev);
if (err < 0)
return err;
create = true;
}
port = macvlan_port_get_rtnl(lowerdev);

/* Only 1 macvlan device can be created in passthru mode */
if (port->passthru)
return -EINVAL;
if (port->passthru) {
/* The macvlan port must be not created this time,
* still goto destroy_macvlan_port for readability.
*/
err = -EINVAL;
goto destroy_macvlan_port;
}

vlan->lowerdev = lowerdev;
vlan->dev = dev;
Expand All @@ -1325,24 +1332,28 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
vlan->flags = nla_get_u16(data[IFLA_MACVLAN_FLAGS]);

if (vlan->mode == MACVLAN_MODE_PASSTHRU) {
if (port->count)
return -EINVAL;
if (port->count) {
err = -EINVAL;
goto destroy_macvlan_port;
}
port->passthru = true;
eth_hw_addr_inherit(dev, lowerdev);
}

if (data && data[IFLA_MACVLAN_MACADDR_MODE]) {
if (vlan->mode != MACVLAN_MODE_SOURCE)
return -EINVAL;
if (vlan->mode != MACVLAN_MODE_SOURCE) {
err = -EINVAL;
goto destroy_macvlan_port;
}
macmode = nla_get_u32(data[IFLA_MACVLAN_MACADDR_MODE]);
err = macvlan_changelink_sources(vlan, macmode, data);
if (err)
return err;
goto destroy_macvlan_port;
}

err = register_netdevice(dev);
if (err < 0)
return err;
goto destroy_macvlan_port;

dev->priv_flags |= IFF_MACVLAN;
err = netdev_upper_dev_link(lowerdev, dev);
Expand All @@ -1357,7 +1368,9 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,

unregister_netdev:
unregister_netdevice(dev);

destroy_macvlan_port:
if (create)
macvlan_port_destroy(port->dev);
return err;
}
EXPORT_SYMBOL_GPL(macvlan_common_newlink);
Expand Down

0 comments on commit aa5fd0f

Please sign in to comment.