Currently some IPv6 tunnel drivers set tnl->net to dev_net(dev) in
ndo_init(), which is called in register_netdevice(). However, it lacks
the context of link-netns when we enable cross-net tunnels at device
registration time.
Let's move the init of tunnel link-netns before register_netdevice().
ip6_gre has already initialized netns, so just remove the redundant
assignment.
Signed-off-by: Xiao Liang <shaw.leon@gmail.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Link: https://patch.msgid.link/20250219125039.18024-8-shaw.leon@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
        tunnel = netdev_priv(dev);
 
        tunnel->dev = dev;
-       tunnel->net = dev_net(dev);
        strcpy(tunnel->parms.name, dev->name);
 
        ret = dst_cache_init(&tunnel->dst_cache, GFP_KERNEL);
        tunnel = netdev_priv(dev);
 
        tunnel->dev = dev;
-       tunnel->net = dev_net(dev);
        strcpy(tunnel->parms.name, dev->name);
 
        ret = dst_cache_init(&tunnel->dst_cache, GFP_KERNEL);
 
        int t_hlen;
 
        t->dev = dev;
-       t->net = dev_net(dev);
 
        ret = dst_cache_init(&t->dst_cache, GFP_KERNEL);
        if (ret)
        struct net *net = dev_net(dev);
        struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
 
+       t->net = net;
        t->parms.proto = IPPROTO_IPV6;
 
        rcu_assign_pointer(ip6n->tnls_wc[0], t);
        int err;
 
        nt = netdev_priv(dev);
+       nt->net = net;
 
        if (ip_tunnel_netlink_encap_parms(data, &ipencap)) {
                err = ip6_tnl_encap_setup(nt, &ipencap);
 
        struct ip6_tnl *t = netdev_priv(dev);
 
        t->dev = dev;
-       t->net = dev_net(dev);
        netdev_hold(dev, &t->dev_tracker, GFP_KERNEL);
        netdev_lockdep_set_classes(dev);
        return 0;
        struct net *net = dev_net(dev);
        struct vti6_net *ip6n = net_generic(net, vti6_net_id);
 
+       t->net = net;
        t->parms.proto = IPPROTO_IPV6;
 
        rcu_assign_pointer(ip6n->tnls_wc[0], t);
        vti6_netlink_parms(data, &nt->parms);
 
        nt->parms.proto = IPPROTO_IPV6;
+       nt->net = net;
 
        if (vti6_locate(net, &nt->parms, 0))
                return -EEXIST;
 
 
        nt = netdev_priv(dev);
 
+       nt->net = net;
        nt->parms = *parms;
        if (ipip6_tunnel_create(dev) < 0)
                goto failed_free;
        int err;
 
        tunnel->dev = dev;
-       tunnel->net = dev_net(dev);
        strcpy(tunnel->parms.name, dev->name);
 
        ipip6_tunnel_bind_dev(dev);
        int err;
 
        nt = netdev_priv(dev);
+       nt->net = net;
 
        if (ip_tunnel_netlink_encap_parms(data, &ipencap)) {
                err = ip_tunnel_encap_setup(nt, &ipencap);
         */
        sitn->fb_tunnel_dev->netns_local = true;
 
+       t = netdev_priv(sitn->fb_tunnel_dev);
+       t->net = net;
+
        err = register_netdev(sitn->fb_tunnel_dev);
        if (err)
                goto err_reg_dev;
        ipip6_tunnel_clone_6rd(sitn->fb_tunnel_dev, sitn);
        ipip6_fb_tunnel_init(sitn->fb_tunnel_dev);
 
-       t = netdev_priv(sitn->fb_tunnel_dev);
-
        strcpy(t->parms.name, sitn->fb_tunnel_dev->name);
        return 0;