|
@@ -905,6 +905,15 @@ static int vti6_newlink(struct net *src_net, struct net_device *dev,
|
|
|
return vti6_tnl_create2(dev);
|
|
|
}
|
|
|
|
|
|
+static void vti6_dellink(struct net_device *dev, struct list_head *head)
|
|
|
+{
|
|
|
+ struct net *net = dev_net(dev);
|
|
|
+ struct vti6_net *ip6n = net_generic(net, vti6_net_id);
|
|
|
+
|
|
|
+ if (dev != ip6n->fb_tnl_dev)
|
|
|
+ unregister_netdevice_queue(dev, head);
|
|
|
+}
|
|
|
+
|
|
|
static int vti6_changelink(struct net_device *dev, struct nlattr *tb[],
|
|
|
struct nlattr *data[])
|
|
|
{
|
|
@@ -980,6 +989,7 @@ static struct rtnl_link_ops vti6_link_ops __read_mostly = {
|
|
|
.setup = vti6_dev_setup,
|
|
|
.validate = vti6_validate,
|
|
|
.newlink = vti6_newlink,
|
|
|
+ .dellink = vti6_dellink,
|
|
|
.changelink = vti6_changelink,
|
|
|
.get_size = vti6_get_size,
|
|
|
.fill_info = vti6_fill_info,
|
|
@@ -1020,6 +1030,7 @@ static int __net_init vti6_init_net(struct net *net)
|
|
|
if (!ip6n->fb_tnl_dev)
|
|
|
goto err_alloc_dev;
|
|
|
dev_net_set(ip6n->fb_tnl_dev, net);
|
|
|
+ ip6n->fb_tnl_dev->rtnl_link_ops = &vti6_link_ops;
|
|
|
|
|
|
err = vti6_fb_tnl_dev_init(ip6n->fb_tnl_dev);
|
|
|
if (err < 0)
|