Commit 147fd287 authored by Gao Feng's avatar Gao Feng Committed by David S. Miller

driver: ipvlan: Fix one possible memleak in ipvlan_link_new

When ipvlan_link_new fails and creates one ipvlan port, it does not
destroy the ipvlan port created. It causes mem leak and the physical
device contains invalid ipvlan data.
Signed-off-by: default avatarGao Feng <fgao@ikuai8.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d8e435f3
...@@ -497,6 +497,7 @@ static int ipvlan_link_new(struct net *src_net, struct net_device *dev, ...@@ -497,6 +497,7 @@ static int ipvlan_link_new(struct net *src_net, struct net_device *dev,
struct net_device *phy_dev; struct net_device *phy_dev;
int err; int err;
u16 mode = IPVLAN_MODE_L3; u16 mode = IPVLAN_MODE_L3;
bool create = false;
if (!tb[IFLA_LINK]) if (!tb[IFLA_LINK])
return -EINVAL; return -EINVAL;
...@@ -513,6 +514,7 @@ static int ipvlan_link_new(struct net *src_net, struct net_device *dev, ...@@ -513,6 +514,7 @@ static int ipvlan_link_new(struct net *src_net, struct net_device *dev,
err = ipvlan_port_create(phy_dev); err = ipvlan_port_create(phy_dev);
if (err < 0) if (err < 0)
return err; return err;
create = true;
} }
if (data && data[IFLA_IPVLAN_MODE]) if (data && data[IFLA_IPVLAN_MODE])
...@@ -536,22 +538,27 @@ static int ipvlan_link_new(struct net *src_net, struct net_device *dev, ...@@ -536,22 +538,27 @@ static int ipvlan_link_new(struct net *src_net, struct net_device *dev,
err = register_netdevice(dev); err = register_netdevice(dev);
if (err < 0) if (err < 0)
return err; goto destroy_ipvlan_port;
err = netdev_upper_dev_link(phy_dev, dev); err = netdev_upper_dev_link(phy_dev, dev);
if (err) { if (err) {
unregister_netdevice(dev); goto unregister_netdev;
return err;
} }
err = ipvlan_set_port_mode(port, mode); err = ipvlan_set_port_mode(port, mode);
if (err) { if (err) {
unregister_netdevice(dev); goto unregister_netdev;
return err;
} }
list_add_tail_rcu(&ipvlan->pnode, &port->ipvlans); list_add_tail_rcu(&ipvlan->pnode, &port->ipvlans);
netif_stacked_transfer_operstate(phy_dev, dev); netif_stacked_transfer_operstate(phy_dev, dev);
return 0; return 0;
unregister_netdev:
unregister_netdevice(dev);
destroy_ipvlan_port:
if (create)
ipvlan_port_destroy(phy_dev);
return err;
} }
static void ipvlan_link_delete(struct net_device *dev, struct list_head *head) static void ipvlan_link_delete(struct net_device *dev, struct list_head *head)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment