diff options
Diffstat (limited to 'net/ipv6/ip6_vti.c')
-rw-r--r-- | net/ipv6/ip6_vti.c | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c index d440bb585524..bcda14de7f84 100644 --- a/net/ipv6/ip6_vti.c +++ b/net/ipv6/ip6_vti.c | |||
@@ -172,10 +172,6 @@ static int vti6_tnl_create2(struct net_device *dev) | |||
172 | struct vti6_net *ip6n = net_generic(net, vti6_net_id); | 172 | struct vti6_net *ip6n = net_generic(net, vti6_net_id); |
173 | int err; | 173 | int err; |
174 | 174 | ||
175 | err = vti6_dev_init(dev); | ||
176 | if (err < 0) | ||
177 | goto out; | ||
178 | |||
179 | err = register_netdevice(dev); | 175 | err = register_netdevice(dev); |
180 | if (err < 0) | 176 | if (err < 0) |
181 | goto out; | 177 | goto out; |
@@ -783,6 +779,7 @@ static int vti6_change_mtu(struct net_device *dev, int new_mtu) | |||
783 | } | 779 | } |
784 | 780 | ||
785 | static const struct net_device_ops vti6_netdev_ops = { | 781 | static const struct net_device_ops vti6_netdev_ops = { |
782 | .ndo_init = vti6_dev_init, | ||
786 | .ndo_uninit = vti6_dev_uninit, | 783 | .ndo_uninit = vti6_dev_uninit, |
787 | .ndo_start_xmit = vti6_tnl_xmit, | 784 | .ndo_start_xmit = vti6_tnl_xmit, |
788 | .ndo_do_ioctl = vti6_ioctl, | 785 | .ndo_do_ioctl = vti6_ioctl, |
@@ -852,16 +849,10 @@ static int __net_init vti6_fb_tnl_dev_init(struct net_device *dev) | |||
852 | struct ip6_tnl *t = netdev_priv(dev); | 849 | struct ip6_tnl *t = netdev_priv(dev); |
853 | struct net *net = dev_net(dev); | 850 | struct net *net = dev_net(dev); |
854 | struct vti6_net *ip6n = net_generic(net, vti6_net_id); | 851 | struct vti6_net *ip6n = net_generic(net, vti6_net_id); |
855 | int err = vti6_dev_init_gen(dev); | ||
856 | |||
857 | if (err) | ||
858 | return err; | ||
859 | 852 | ||
860 | t->parms.proto = IPPROTO_IPV6; | 853 | t->parms.proto = IPPROTO_IPV6; |
861 | dev_hold(dev); | 854 | dev_hold(dev); |
862 | 855 | ||
863 | vti6_link_config(t); | ||
864 | |||
865 | rcu_assign_pointer(ip6n->tnls_wc[0], t); | 856 | rcu_assign_pointer(ip6n->tnls_wc[0], t); |
866 | return 0; | 857 | return 0; |
867 | } | 858 | } |
@@ -914,6 +905,15 @@ static int vti6_newlink(struct net *src_net, struct net_device *dev, | |||
914 | return vti6_tnl_create2(dev); | 905 | return vti6_tnl_create2(dev); |
915 | } | 906 | } |
916 | 907 | ||
908 | static void vti6_dellink(struct net_device *dev, struct list_head *head) | ||
909 | { | ||
910 | struct net *net = dev_net(dev); | ||
911 | struct vti6_net *ip6n = net_generic(net, vti6_net_id); | ||
912 | |||
913 | if (dev != ip6n->fb_tnl_dev) | ||
914 | unregister_netdevice_queue(dev, head); | ||
915 | } | ||
916 | |||
917 | static int vti6_changelink(struct net_device *dev, struct nlattr *tb[], | 917 | static int vti6_changelink(struct net_device *dev, struct nlattr *tb[], |
918 | struct nlattr *data[]) | 918 | struct nlattr *data[]) |
919 | { | 919 | { |
@@ -989,6 +989,7 @@ static struct rtnl_link_ops vti6_link_ops __read_mostly = { | |||
989 | .setup = vti6_dev_setup, | 989 | .setup = vti6_dev_setup, |
990 | .validate = vti6_validate, | 990 | .validate = vti6_validate, |
991 | .newlink = vti6_newlink, | 991 | .newlink = vti6_newlink, |
992 | .dellink = vti6_dellink, | ||
992 | .changelink = vti6_changelink, | 993 | .changelink = vti6_changelink, |
993 | .get_size = vti6_get_size, | 994 | .get_size = vti6_get_size, |
994 | .fill_info = vti6_fill_info, | 995 | .fill_info = vti6_fill_info, |
@@ -1029,6 +1030,7 @@ static int __net_init vti6_init_net(struct net *net) | |||
1029 | if (!ip6n->fb_tnl_dev) | 1030 | if (!ip6n->fb_tnl_dev) |
1030 | goto err_alloc_dev; | 1031 | goto err_alloc_dev; |
1031 | dev_net_set(ip6n->fb_tnl_dev, net); | 1032 | dev_net_set(ip6n->fb_tnl_dev, net); |
1033 | ip6n->fb_tnl_dev->rtnl_link_ops = &vti6_link_ops; | ||
1032 | 1034 | ||
1033 | err = vti6_fb_tnl_dev_init(ip6n->fb_tnl_dev); | 1035 | err = vti6_fb_tnl_dev_init(ip6n->fb_tnl_dev); |
1034 | if (err < 0) | 1036 | if (err < 0) |