]> git.dujemihanovic.xyz Git - linux.git/commitdiff
rtnetlink: allow rtnl_fill_link_netnsid() to run under RCU protection
authorEric Dumazet <edumazet@google.com>
Fri, 3 May 2024 19:20:59 +0000 (19:20 +0000)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 7 May 2024 09:14:50 +0000 (11:14 +0200)
We want to be able to run rtnl_fill_ifinfo() under RCU protection
instead of RTNL in the future.

All rtnl_link_ops->get_link_net() methods already using dev_net()
are ready. I added READ_ONCE() annotations on others.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
drivers/net/ppp/ppp_generic.c
drivers/net/vxlan/vxlan_core.c
net/core/rtnetlink.c
net/ipv4/ip_tunnel.c
net/ipv6/ip6_tunnel.c
net/xfrm/xfrm_interface_core.c

index fe380fe196e7b4a1ab4a6f15569d258132c00bac..0a65b6d690feb9fb5d4f1a2046d6195ac0bd39f9 100644 (file)
@@ -1357,7 +1357,7 @@ static struct net *ppp_nl_get_link_net(const struct net_device *dev)
 {
        struct ppp *ppp = netdev_priv(dev);
 
-       return ppp->ppp_net;
+       return READ_ONCE(ppp->ppp_net);
 }
 
 static struct rtnl_link_ops ppp_link_ops __read_mostly = {
index 8884913e04738b32848b951c671ae3ede9a828e7..7e3a7d1f2018120fbe729eb5c53a6783f492ead6 100644 (file)
@@ -4569,7 +4569,7 @@ static struct net *vxlan_get_link_net(const struct net_device *dev)
 {
        struct vxlan_dev *vxlan = netdev_priv(dev);
 
-       return vxlan->net;
+       return READ_ONCE(vxlan->net);
 }
 
 static struct rtnl_link_ops vxlan_link_ops __read_mostly = {
index 41eb8bca530587074611d85e02b0a083ad367ed4..af8da8aeed395741b045f5ae5fd4bbaead2e199a 100644 (file)
@@ -1923,9 +1923,6 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb,
                        goto nla_put_failure;
        }
 
-       if (rtnl_fill_link_netnsid(skb, dev, src_net, gfp))
-               goto nla_put_failure;
-
        if (new_nsid &&
            nla_put_s32(skb, IFLA_NEW_NETNSID, *new_nsid) < 0)
                goto nla_put_failure;
@@ -1938,6 +1935,8 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb,
                goto nla_put_failure;
 
        rcu_read_lock();
+       if (rtnl_fill_link_netnsid(skb, dev, src_net, GFP_ATOMIC))
+               goto nla_put_failure_rcu;
        qdisc = rcu_dereference(dev->qdisc);
        if (qdisc && nla_put_string(skb, IFLA_QDISC, qdisc->ops->id))
                goto nla_put_failure_rcu;
index ba46cf7612f4fc2cba33c098933b6578dd885587..f1c5f6c3f2f82e19b8e9b696c6900948a946bacc 100644 (file)
@@ -1120,7 +1120,7 @@ struct net *ip_tunnel_get_link_net(const struct net_device *dev)
 {
        struct ip_tunnel *tunnel = netdev_priv(dev);
 
-       return tunnel->net;
+       return READ_ONCE(tunnel->net);
 }
 EXPORT_SYMBOL(ip_tunnel_get_link_net);
 
index 57bb3b3ea0c5a463f0c90659fcffe9358a4084b2..5aec79c2af1a58ed1c57cca6d06951403e087d62 100644 (file)
@@ -2146,7 +2146,7 @@ struct net *ip6_tnl_get_link_net(const struct net_device *dev)
 {
        struct ip6_tnl *tunnel = netdev_priv(dev);
 
-       return tunnel->net;
+       return READ_ONCE(tunnel->net);
 }
 EXPORT_SYMBOL(ip6_tnl_get_link_net);
 
index 4df5c06e3ece834039e1713377538bd7f4d12a3e..e50e4bf993fa473769a0062ffcc661daefaf1b6b 100644 (file)
@@ -926,7 +926,7 @@ static struct net *xfrmi_get_link_net(const struct net_device *dev)
 {
        struct xfrm_if *xi = netdev_priv(dev);
 
-       return xi->net;
+       return READ_ONCE(xi->net);
 }
 
 static const struct nla_policy xfrmi_policy[IFLA_XFRM_MAX + 1] = {