From: Xiao Liang <shaw.leon@xxxxxxxxx> Date: Mon, 10 Feb 2025 21:29:56 +0800 > When link_net is set, use it as link netns instead of dev_net(). This > prepares for rtnetlink core to create device in target netns directly, > in which case the two namespaces may be different. > > Convert common ip_tunnel_newlink() to accept an extra link netns > argument. Don't overwrite ip_tunnel.net in ip_tunnel_init(). Why... ? see a comment below. [...] > diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c > index 1fe9b13d351c..26d15f907551 100644 > --- a/net/ipv4/ip_gre.c > +++ b/net/ipv4/ip_gre.c > @@ -1413,7 +1413,8 @@ static int ipgre_newlink(struct net_device *dev, > err = ipgre_netlink_parms(dev, data, tb, &p, &fwmark); > if (err < 0) > return err; > - return ip_tunnel_newlink(dev, tb, &p, fwmark); > + return ip_tunnel_newlink(params->link_net ? : dev_net(dev), dev, tb, &p, This is duplicate at all call sites, let's move it into ip_tunnel_newlink() by passing params. > + fwmark); > } > > static int erspan_newlink(struct net_device *dev, > > > diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c > index 09b73acf037a..618a50d5c0c2 100644 > --- a/net/ipv4/ip_tunnel.c > +++ b/net/ipv4/ip_tunnel.c > @@ -1213,11 +1213,11 @@ void ip_tunnel_delete_nets(struct list_head *net_list, unsigned int id, > } > EXPORT_SYMBOL_GPL(ip_tunnel_delete_nets); > > -int ip_tunnel_newlink(struct net_device *dev, struct nlattr *tb[], > - struct ip_tunnel_parm_kern *p, __u32 fwmark) > +int ip_tunnel_newlink(struct net *net, struct net_device *dev, > + struct nlattr *tb[], struct ip_tunnel_parm_kern *p, > + __u32 fwmark) > { > struct ip_tunnel *nt; > - struct net *net = dev_net(dev); > struct ip_tunnel_net *itn; > int mtu; > int err; > @@ -1326,7 +1326,9 @@ int ip_tunnel_init(struct net_device *dev) > } > > tunnel->dev = dev; > - tunnel->net = dev_net(dev); > + if (!tunnel->net) > + tunnel->net = dev_net(dev); Isn't tunnel->net always non-NULL ? ip_tunnel_newlink -> netdev_priv(dev)->net = net -> register_netdevice(dev) -> dev->netdev_ops->ndo_init(dev) -> ip_tunnel_init(dev) -> netdev_priv(dev)->net = dev_net(dev)