ovs/vxlan: fix rtnl notifications on iface deletion
commit cf5da330bbdd0c06b05c525a3d1d58ccd82c87a6 upstream. The function vxlan_dev_create() (only used by ovs) never calls rtnl_configure_link(). The consequence is that dev->rtnl_link_state is never set to RTNL_LINK_INITIALIZED. During the deletion phase, the function rollback_registered_many() sends a RTM_DELLINK only if dev->rtnl_link_state is set to RTNL_LINK_INITIALIZED. Note that the function vxlan_dev_create() is moved after the rtnl stuff so that vxlan_dellink() can be called in this function. Fixes: dcc38c033b32 ("openvswitch: Re-add CONFIG_OPENVSWITCH_VXLAN") CC: Thomas Graf <tgraf@suug.ch> CC: Pravin B Shelar <pshelar@nicira.com> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
10be8a1102
commit
885fc27636
@ -2927,30 +2927,6 @@ static int vxlan_dev_configure(struct net *src_net, struct net_device *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct net_device *vxlan_dev_create(struct net *net, const char *name,
|
||||
u8 name_assign_type, struct vxlan_config *conf)
|
||||
{
|
||||
struct nlattr *tb[IFLA_MAX+1];
|
||||
struct net_device *dev;
|
||||
int err;
|
||||
|
||||
memset(&tb, 0, sizeof(tb));
|
||||
|
||||
dev = rtnl_create_link(net, name, name_assign_type,
|
||||
&vxlan_link_ops, tb);
|
||||
if (IS_ERR(dev))
|
||||
return dev;
|
||||
|
||||
err = vxlan_dev_configure(net, dev, conf);
|
||||
if (err < 0) {
|
||||
free_netdev(dev);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
return dev;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vxlan_dev_create);
|
||||
|
||||
static int vxlan_newlink(struct net *src_net, struct net_device *dev,
|
||||
struct nlattr *tb[], struct nlattr *data[])
|
||||
{
|
||||
@ -3218,6 +3194,40 @@ static struct rtnl_link_ops vxlan_link_ops __read_mostly = {
|
||||
.get_link_net = vxlan_get_link_net,
|
||||
};
|
||||
|
||||
struct net_device *vxlan_dev_create(struct net *net, const char *name,
|
||||
u8 name_assign_type,
|
||||
struct vxlan_config *conf)
|
||||
{
|
||||
struct nlattr *tb[IFLA_MAX + 1];
|
||||
struct net_device *dev;
|
||||
int err;
|
||||
|
||||
memset(&tb, 0, sizeof(tb));
|
||||
|
||||
dev = rtnl_create_link(net, name, name_assign_type,
|
||||
&vxlan_link_ops, tb);
|
||||
if (IS_ERR(dev))
|
||||
return dev;
|
||||
|
||||
err = vxlan_dev_configure(net, dev, conf);
|
||||
if (err < 0) {
|
||||
free_netdev(dev);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
err = rtnl_configure_link(dev, NULL);
|
||||
if (err < 0) {
|
||||
LIST_HEAD(list_kill);
|
||||
|
||||
vxlan_dellink(dev, &list_kill);
|
||||
unregister_netdevice_many(&list_kill);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
return dev;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(vxlan_dev_create);
|
||||
|
||||
static void vxlan_handle_lowerdev_unregister(struct vxlan_net *vn,
|
||||
struct net_device *dev)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user