rtnetlink: allow rtnl_fill_link_netnsid() to run under RCU protection

JIRA: https://issues.redhat.com/browse/RHEL-57756

Upstream commit(s):
commit 9cf621bd5fcbeadc2804951d13d487e22e95b363
Author: Eric Dumazet <edumazet@google.com>
Date:   Fri May 3 19:20:59 2024 +0000

    rtnetlink: allow rtnl_fill_link_netnsid() to run under RCU protection

    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>

Signed-off-by: Petr Oros <poros@redhat.com>
This commit is contained in:
Petr Oros 2024-11-25 10:55:06 +01:00
parent 1f803ff5bd
commit 5f99ca47f6
6 changed files with 7 additions and 8 deletions

View File

@ -1370,7 +1370,7 @@ static struct net *ppp_nl_get_link_net(const struct net_device *dev)
{ {
struct ppp *ppp = netdev_priv(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 = { static struct rtnl_link_ops ppp_link_ops __read_mostly = {

View File

@ -4370,7 +4370,7 @@ static struct net *vxlan_get_link_net(const struct net_device *dev)
{ {
struct vxlan_dev *vxlan = netdev_priv(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 = { static struct rtnl_link_ops vxlan_link_ops __read_mostly = {

View File

@ -1938,9 +1938,6 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb,
goto nla_put_failure; goto nla_put_failure;
} }
if (rtnl_fill_link_netnsid(skb, dev, src_net, gfp))
goto nla_put_failure;
if (new_nsid && if (new_nsid &&
nla_put_s32(skb, IFLA_NEW_NETNSID, *new_nsid) < 0) nla_put_s32(skb, IFLA_NEW_NETNSID, *new_nsid) < 0)
goto nla_put_failure; goto nla_put_failure;
@ -1953,6 +1950,8 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb,
goto nla_put_failure; goto nla_put_failure;
rcu_read_lock(); rcu_read_lock();
if (rtnl_fill_link_netnsid(skb, dev, src_net, GFP_ATOMIC))
goto nla_put_failure_rcu;
qdisc = rcu_dereference(dev->qdisc); qdisc = rcu_dereference(dev->qdisc);
if (qdisc && nla_put_string(skb, IFLA_QDISC, qdisc->ops->id)) if (qdisc && nla_put_string(skb, IFLA_QDISC, qdisc->ops->id))
goto nla_put_failure_rcu; goto nla_put_failure_rcu;

View File

@ -1102,7 +1102,7 @@ struct net *ip_tunnel_get_link_net(const struct net_device *dev)
{ {
struct ip_tunnel *tunnel = netdev_priv(dev); struct ip_tunnel *tunnel = netdev_priv(dev);
return tunnel->net; return READ_ONCE(tunnel->net);
} }
EXPORT_SYMBOL(ip_tunnel_get_link_net); EXPORT_SYMBOL(ip_tunnel_get_link_net);

View File

@ -2161,7 +2161,7 @@ struct net *ip6_tnl_get_link_net(const struct net_device *dev)
{ {
struct ip6_tnl *tunnel = netdev_priv(dev); struct ip6_tnl *tunnel = netdev_priv(dev);
return tunnel->net; return READ_ONCE(tunnel->net);
} }
EXPORT_SYMBOL(ip6_tnl_get_link_net); EXPORT_SYMBOL(ip6_tnl_get_link_net);

View File

@ -886,7 +886,7 @@ static struct net *xfrmi_get_link_net(const struct net_device *dev)
{ {
struct xfrm_if *xi = netdev_priv(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] = { static const struct nla_policy xfrmi_policy[IFLA_XFRM_MAX + 1] = {