Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ovs/vxlan: fix rtnl notifications on iface deletion

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>

authored by

Nicolas Dichtel and committed by
David S. Miller
cf5da330 106da663

+34 -24
+34 -24
drivers/net/vxlan.c
··· 2952 2952 return 0; 2953 2953 } 2954 2954 2955 - struct net_device *vxlan_dev_create(struct net *net, const char *name, 2956 - u8 name_assign_type, struct vxlan_config *conf) 2957 - { 2958 - struct nlattr *tb[IFLA_MAX+1]; 2959 - struct net_device *dev; 2960 - int err; 2961 - 2962 - memset(&tb, 0, sizeof(tb)); 2963 - 2964 - dev = rtnl_create_link(net, name, name_assign_type, 2965 - &vxlan_link_ops, tb); 2966 - if (IS_ERR(dev)) 2967 - return dev; 2968 - 2969 - err = vxlan_dev_configure(net, dev, conf); 2970 - if (err < 0) { 2971 - free_netdev(dev); 2972 - return ERR_PTR(err); 2973 - } 2974 - 2975 - return dev; 2976 - } 2977 - EXPORT_SYMBOL_GPL(vxlan_dev_create); 2978 - 2979 2955 static int vxlan_newlink(struct net *src_net, struct net_device *dev, 2980 2956 struct nlattr *tb[], struct nlattr *data[]) 2981 2957 { ··· 3243 3267 .fill_info = vxlan_fill_info, 3244 3268 .get_link_net = vxlan_get_link_net, 3245 3269 }; 3270 + 3271 + struct net_device *vxlan_dev_create(struct net *net, const char *name, 3272 + u8 name_assign_type, 3273 + struct vxlan_config *conf) 3274 + { 3275 + struct nlattr *tb[IFLA_MAX + 1]; 3276 + struct net_device *dev; 3277 + int err; 3278 + 3279 + memset(&tb, 0, sizeof(tb)); 3280 + 3281 + dev = rtnl_create_link(net, name, name_assign_type, 3282 + &vxlan_link_ops, tb); 3283 + if (IS_ERR(dev)) 3284 + return dev; 3285 + 3286 + err = vxlan_dev_configure(net, dev, conf); 3287 + if (err < 0) { 3288 + free_netdev(dev); 3289 + return ERR_PTR(err); 3290 + } 3291 + 3292 + err = rtnl_configure_link(dev, NULL); 3293 + if (err < 0) { 3294 + LIST_HEAD(list_kill); 3295 + 3296 + vxlan_dellink(dev, &list_kill); 3297 + unregister_netdevice_many(&list_kill); 3298 + return ERR_PTR(err); 3299 + } 3300 + 3301 + return dev; 3302 + } 3303 + EXPORT_SYMBOL_GPL(vxlan_dev_create); 3246 3304 3247 3305 static void vxlan_handle_lowerdev_unregister(struct vxlan_net *vn, 3248 3306 struct net_device *dev)