Netdev List
 help / color / mirror / Atom feed
From: Eric Dumazet <edumazet@google.com>
To: "David S . Miller" <davem@davemloft.net>,
	Jakub Kicinski <kuba@kernel.org>,
	 Paolo Abeni <pabeni@redhat.com>
Cc: Simon Horman <horms@kernel.org>,
	Kuniyuki Iwashima <kuniyu@google.com>,
	 Ido Schimmel <idosch@nvidia.com>,
	David Ahern <dsahern@kernel.org>,
	netdev@vger.kernel.org,  eric.dumazet@gmail.com,
	Eric Dumazet <edumazet@google.com>
Subject: [PATCH net-next 2/2] sit: no longer rely on RTNL in ipip6_fill_info()
Date: Wed,  1 Jul 2026 15:51:35 +0000	[thread overview]
Message-ID: <20260701155135.3962058-3-edumazet@google.com> (raw)
In-Reply-To: <20260701155135.3962058-1-edumazet@google.com>

Update ipip6_fill_info() to read configuration fields (link, ttl, tos,
proto, i_flags, fwmark, 6rd prefix, encap type/sport/dport/flags)
locklessly using READ_ONCE().

Annotate the bitmap reads for i_flags by copying the first element
atomically using READ_ONCE() into a local variable, as the whole
bitmap fits in one unsigned long.

This allows ipip6_fill_info() to run safely without RTNL.

Signed-off-by: Eric Dumazet <edumazet@google.com>
---
 net/ipv6/sit.c | 70 ++++++++++++++++++++++++++++----------------------
 1 file changed, 40 insertions(+), 30 deletions(-)

diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index a38b24fb838424b6d3cb063d77aa85cf719ce6c5..c7abbb09bfd3dfada6fc1e1682ac42acb7248ad9 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -1143,17 +1143,17 @@ static void ipip6_tunnel_update(struct ip_tunnel *t,
 
 	ipip6_tunnel_unlink(sitn, t);
 	synchronize_net();
-	t->parms.iph.saddr = p->iph.saddr;
-	t->parms.iph.daddr = p->iph.daddr;
+	WRITE_ONCE(t->parms.iph.saddr, p->iph.saddr);
+	WRITE_ONCE(t->parms.iph.daddr, p->iph.daddr);
 	__dev_addr_set(t->dev, &p->iph.saddr, 4);
 	memcpy(t->dev->broadcast, &p->iph.daddr, 4);
 	ipip6_tunnel_link(sitn, t);
-	t->parms.iph.ttl = p->iph.ttl;
-	t->parms.iph.tos = p->iph.tos;
-	t->parms.iph.frag_off = p->iph.frag_off;
-	if (t->parms.link != p->link || t->fwmark != fwmark) {
-		t->parms.link = p->link;
-		t->fwmark = fwmark;
+	WRITE_ONCE(t->parms.iph.ttl, p->iph.ttl);
+	WRITE_ONCE(t->parms.iph.tos, p->iph.tos);
+	WRITE_ONCE(t->parms.iph.frag_off, p->iph.frag_off);
+	if (READ_ONCE(t->parms.link) != p->link || READ_ONCE(t->fwmark) != fwmark) {
+		WRITE_ONCE(t->parms.link, p->link);
+		WRITE_ONCE(t->fwmark, fwmark);
 		ipip6_tunnel_bind_dev(t->dev);
 	}
 	dst_cache_reset(&t->dst_cache);
@@ -1184,9 +1184,9 @@ static int ipip6_tunnel_update_6rd(struct ip_tunnel *t,
 		return -EINVAL;
 
 	t->ip6rd.prefix = prefix;
-	t->ip6rd.relay_prefix = relay_prefix;
-	t->ip6rd.prefixlen = ip6rd->prefixlen;
-	t->ip6rd.relay_prefixlen = ip6rd->relay_prefixlen;
+	WRITE_ONCE(t->ip6rd.relay_prefix, relay_prefix);
+	WRITE_ONCE(t->ip6rd.prefixlen, ip6rd->prefixlen);
+	WRITE_ONCE(t->ip6rd.relay_prefixlen, ip6rd->relay_prefixlen);
 	dst_cache_reset(&t->dst_cache);
 	netdev_state_change(t->dev);
 	return 0;
@@ -1693,42 +1693,52 @@ static size_t ipip6_get_size(const struct net_device *dev)
 
 static int ipip6_fill_info(struct sk_buff *skb, const struct net_device *dev)
 {
-	struct ip_tunnel *tunnel = netdev_priv(dev);
-	struct ip_tunnel_parm_kern *parm = &tunnel->parms;
-
-	if (nla_put_u32(skb, IFLA_IPTUN_LINK, parm->link) ||
-	    nla_put_in_addr(skb, IFLA_IPTUN_LOCAL, parm->iph.saddr) ||
-	    nla_put_in_addr(skb, IFLA_IPTUN_REMOTE, parm->iph.daddr) ||
-	    nla_put_u8(skb, IFLA_IPTUN_TTL, parm->iph.ttl) ||
-	    nla_put_u8(skb, IFLA_IPTUN_TOS, parm->iph.tos) ||
+	const struct ip_tunnel *tunnel = netdev_priv(dev);
+	const struct ip_tunnel_parm_kern *parm;
+	IP_TUNNEL_DECLARE_FLAGS(i_flags);
+	__be16 frag_off;
+	__be32 daddr;
+	__be32 saddr;
+
+	parm = &tunnel->parms;
+	i_flags[0] = READ_ONCE(parm->i_flags[0]);
+	frag_off = READ_ONCE(parm->iph.frag_off);
+	saddr = READ_ONCE(parm->iph.saddr);
+	daddr = READ_ONCE(parm->iph.daddr);
+
+	if (nla_put_u32(skb, IFLA_IPTUN_LINK, READ_ONCE(parm->link)) ||
+	    nla_put_in_addr(skb, IFLA_IPTUN_LOCAL, saddr) ||
+	    nla_put_in_addr(skb, IFLA_IPTUN_REMOTE, daddr) ||
+	    nla_put_u8(skb, IFLA_IPTUN_TTL, READ_ONCE(parm->iph.ttl)) ||
+	    nla_put_u8(skb, IFLA_IPTUN_TOS, READ_ONCE(parm->iph.tos)) ||
 	    nla_put_u8(skb, IFLA_IPTUN_PMTUDISC,
-		       !!(parm->iph.frag_off & htons(IP_DF))) ||
-	    nla_put_u8(skb, IFLA_IPTUN_PROTO, parm->iph.protocol) ||
+		       !!(frag_off & htons(IP_DF))) ||
+	    nla_put_u8(skb, IFLA_IPTUN_PROTO, READ_ONCE(parm->iph.protocol)) ||
 	    nla_put_be16(skb, IFLA_IPTUN_FLAGS,
-			 ip_tunnel_flags_to_be16(parm->i_flags)) ||
-	    nla_put_u32(skb, IFLA_IPTUN_FWMARK, tunnel->fwmark))
+			 ip_tunnel_flags_to_be16(i_flags)) ||
+	    nla_put_u32(skb, IFLA_IPTUN_FWMARK, READ_ONCE(tunnel->fwmark)))
 		goto nla_put_failure;
 
 #ifdef CONFIG_IPV6_SIT_6RD
 	if (nla_put_in6_addr(skb, IFLA_IPTUN_6RD_PREFIX,
 			     &tunnel->ip6rd.prefix) ||
 	    nla_put_in_addr(skb, IFLA_IPTUN_6RD_RELAY_PREFIX,
-			    tunnel->ip6rd.relay_prefix) ||
+			    READ_ONCE(tunnel->ip6rd.relay_prefix)) ||
 	    nla_put_u16(skb, IFLA_IPTUN_6RD_PREFIXLEN,
-			tunnel->ip6rd.prefixlen) ||
+			READ_ONCE(tunnel->ip6rd.prefixlen)) ||
 	    nla_put_u16(skb, IFLA_IPTUN_6RD_RELAY_PREFIXLEN,
-			tunnel->ip6rd.relay_prefixlen))
+			READ_ONCE(tunnel->ip6rd.relay_prefixlen)))
 		goto nla_put_failure;
 #endif
 
 	if (nla_put_u16(skb, IFLA_IPTUN_ENCAP_TYPE,
-			tunnel->encap.type) ||
+			READ_ONCE(tunnel->encap.type)) ||
 	    nla_put_be16(skb, IFLA_IPTUN_ENCAP_SPORT,
-			tunnel->encap.sport) ||
+			READ_ONCE(tunnel->encap.sport)) ||
 	    nla_put_be16(skb, IFLA_IPTUN_ENCAP_DPORT,
-			tunnel->encap.dport) ||
+			READ_ONCE(tunnel->encap.dport)) ||
 	    nla_put_u16(skb, IFLA_IPTUN_ENCAP_FLAGS,
-			tunnel->encap.flags))
+			READ_ONCE(tunnel->encap.flags)))
 		goto nla_put_failure;
 
 	return 0;
-- 
2.55.0.rc0.799.gd6f94ed593-goog


  parent reply	other threads:[~2026-07-01 15:51 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-01 15:51 [PATCH net-next 0/2] sit: prepare for RTNL-less link dumping Eric Dumazet
2026-07-01 15:51 ` [PATCH net-next 1/2] ip_tunnel: use WRITE_ONCE in ip_tunnel_encap_setup Eric Dumazet
2026-07-02  3:11   ` Kuniyuki Iwashima
2026-07-01 15:51 ` Eric Dumazet [this message]
2026-07-02  3:13   ` [PATCH net-next 2/2] sit: no longer rely on RTNL in ipip6_fill_info() Kuniyuki Iwashima

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260701155135.3962058-3-edumazet@google.com \
    --to=edumazet@google.com \
    --cc=davem@davemloft.net \
    --cc=dsahern@kernel.org \
    --cc=eric.dumazet@gmail.com \
    --cc=horms@kernel.org \
    --cc=idosch@nvidia.com \
    --cc=kuba@kernel.org \
    --cc=kuniyu@google.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox