Commit 94bcfdbf authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

net: bareudp: add missing error handling for bareudp_link_config()

.dellink does not get called after .newlink fails,
bareudp_newlink() must undo what bareudp_configure()
has done if bareudp_link_config() fails.

v2: call bareudp_dellink(), like bareudp_dev_create() does

Fixes: 571912c6 ("net: UDP tunnel encapsulation module for tunnelling different protocols like MPLS, IP, NSH etc.")
Link: https://lore.kernel.org/r/20210105190725.1736246-1-kuba@kernel.org


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 0d136f5c
Loading
Loading
Loading
Loading
+14 −8
Original line number Diff line number Diff line
@@ -645,11 +645,20 @@ static int bareudp_link_config(struct net_device *dev,
	return 0;
}

static void bareudp_dellink(struct net_device *dev, struct list_head *head)
{
	struct bareudp_dev *bareudp = netdev_priv(dev);

	list_del(&bareudp->next);
	unregister_netdevice_queue(dev, head);
}

static int bareudp_newlink(struct net *net, struct net_device *dev,
			   struct nlattr *tb[], struct nlattr *data[],
			   struct netlink_ext_ack *extack)
{
	struct bareudp_conf conf;
	LIST_HEAD(list_kill);
	int err;

	err = bareudp2info(data, &conf, extack);
@@ -662,17 +671,14 @@ static int bareudp_newlink(struct net *net, struct net_device *dev,

	err = bareudp_link_config(dev, tb);
	if (err)
		return err;
		goto err_unconfig;

	return 0;
}

static void bareudp_dellink(struct net_device *dev, struct list_head *head)
{
	struct bareudp_dev *bareudp = netdev_priv(dev);

	list_del(&bareudp->next);
	unregister_netdevice_queue(dev, head);
err_unconfig:
	bareudp_dellink(dev, &list_kill);
	unregister_netdevice_many(&list_kill);
	return err;
}

static size_t bareudp_get_size(const struct net_device *dev)