diff --git a/drivers/net/team/team_core.c b/drivers/net/team/team_core.c index ab1935a4aa2c..a12366fd420c 100644 --- a/drivers/net/team/team_core.c +++ b/drivers/net/team/team_core.c @@ -1142,31 +1142,37 @@ static int team_port_add(struct team *team, struct net_device *port_dev, char *portname = port_dev->name; int err; + rtnl_lock(); + if (port_dev->flags & IFF_LOOPBACK) { NL_SET_ERR_MSG(extack, "Loopback device can't be added as a team port"); netdev_err(dev, "Device %s is loopback device. Loopback devices can't be added as a team port\n", portname); - return -EINVAL; + err = -EINVAL; + goto err_out; } if (netif_is_team_port(port_dev)) { NL_SET_ERR_MSG(extack, "Device is already a port of a team device"); netdev_err(dev, "Device %s is already a port " "of a team device\n", portname); - return -EBUSY; + err = -EBUSY; + goto err_out; } if (dev == port_dev) { NL_SET_ERR_MSG(extack, "Cannot enslave team device to itself"); netdev_err(dev, "Cannot enslave team device to itself\n"); - return -EINVAL; + err = -EINVAL; + goto err_out; } if (netdev_has_upper_dev(dev, port_dev)) { NL_SET_ERR_MSG(extack, "Device is already an upper device of the team interface"); netdev_err(dev, "Device %s is already an upper device of the team interface\n", portname); - return -EBUSY; + err = -EBUSY; + goto err_out; } if (port_dev->features & NETIF_F_VLAN_CHALLENGED && @@ -1174,7 +1180,8 @@ static int team_port_add(struct team *team, struct net_device *port_dev, NL_SET_ERR_MSG(extack, "Device is VLAN challenged and team device has VLAN set up"); netdev_err(dev, "Device %s is VLAN challenged and team device has VLAN set up\n", portname); - return -EPERM; + err = -EPERM; + goto err_out; } err = team_dev_type_check_change(dev, port_dev); @@ -1185,13 +1192,16 @@ static int team_port_add(struct team *team, struct net_device *port_dev, NL_SET_ERR_MSG(extack, "Device is up. Set it down before adding it as a team port"); netdev_err(dev, "Device %s is up. Set it down before adding it as a team port\n", portname); - return -EBUSY; + err = -EBUSY; + goto err_out; } port = kzalloc(sizeof(struct team_port) + team->mode->port_priv_size, GFP_KERNEL); - if (!port) - return -ENOMEM; + if (!port) { + err = -ENOMEM; + goto err_out; + } port->dev = port_dev; port->team = team; @@ -1213,7 +1223,9 @@ static int team_port_add(struct team *team, struct net_device *port_dev, goto err_port_enter; } + mutex_unlock(&team->lock); err = dev_open(port_dev, extack); + mutex_lock(&team->lock); if (err) { netdev_dbg(dev, "Device %s opening failed\n", portname); @@ -1292,6 +1304,7 @@ static int team_port_add(struct team *team, struct net_device *port_dev, netdev_info(dev, "Port device %s added\n", portname); + rtnl_unlock(); return 0; err_set_slave_promisc: @@ -1321,7 +1334,8 @@ static int team_port_add(struct team *team, struct net_device *port_dev, err_set_mtu: kfree(port); - +err_out: + rtnl_unlock(); return err; }