ip_tunnel: annotate data-races around t->parms.link
authorEric Dumazet <edumazet@google.com>
Tue, 13 Feb 2024 06:32:34 +0000 (06:32 +0000)
committerDavid S. Miller <davem@davemloft.net>
Wed, 14 Feb 2024 11:20:13 +0000 (11:20 +0000)
t->parms.link is read locklessly, annotate these reads
and opposite writes accordingly.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv4/ip_tunnel.c

index 58de780..9f44c49 100644 (file)
@@ -102,10 +102,9 @@ struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn,
                if (!ip_tunnel_key_match(&t->parms, flags, key))
                        continue;
 
-               if (t->parms.link == link)
+               if (READ_ONCE(t->parms.link) == link)
                        return t;
-               else
-                       cand = t;
+               cand = t;
        }
 
        hlist_for_each_entry_rcu(t, head, hash_node) {
@@ -117,9 +116,9 @@ struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn,
                if (!ip_tunnel_key_match(&t->parms, flags, key))
                        continue;
 
-               if (t->parms.link == link)
+               if (READ_ONCE(t->parms.link) == link)
                        return t;
-               else if (!cand)
+               if (!cand)
                        cand = t;
        }
 
@@ -137,9 +136,9 @@ struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn,
                if (!ip_tunnel_key_match(&t->parms, flags, key))
                        continue;
 
-               if (t->parms.link == link)
+               if (READ_ONCE(t->parms.link) == link)
                        return t;
-               else if (!cand)
+               if (!cand)
                        cand = t;
        }
 
@@ -150,9 +149,9 @@ struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn,
                    !(t->dev->flags & IFF_UP))
                        continue;
 
-               if (t->parms.link == link)
+               if (READ_ONCE(t->parms.link) == link)
                        return t;
-               else if (!cand)
+               if (!cand)
                        cand = t;
        }
 
@@ -221,7 +220,7 @@ static struct ip_tunnel *ip_tunnel_find(struct ip_tunnel_net *itn,
        hlist_for_each_entry_rcu(t, head, hash_node) {
                if (local == t->parms.iph.saddr &&
                    remote == t->parms.iph.daddr &&
-                   link == t->parms.link &&
+                   link == READ_ONCE(t->parms.link) &&
                    type == t->dev->type &&
                    ip_tunnel_key_match(&t->parms, flags, key))
                        break;
@@ -747,7 +746,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
 
        ip_tunnel_init_flow(&fl4, protocol, dst, tnl_params->saddr,
                            tunnel->parms.o_key, RT_TOS(tos),
-                           dev_net(dev), tunnel->parms.link,
+                           dev_net(dev), READ_ONCE(tunnel->parms.link),
                            tunnel->fwmark, skb_get_hash(skb), 0);
 
        if (ip_tunnel_encap(skb, &tunnel->encap, &protocol, &fl4) < 0)
@@ -867,7 +866,7 @@ static void ip_tunnel_update(struct ip_tunnel_net *itn,
        if (t->parms.link != p->link || t->fwmark != fwmark) {
                int mtu;
 
-               t->parms.link = p->link;
+               WRITE_ONCE(t->parms.link, p->link);
                t->fwmark = fwmark;
                mtu = ip_tunnel_bind_dev(dev);
                if (set_mtu)
@@ -1057,9 +1056,9 @@ EXPORT_SYMBOL(ip_tunnel_get_link_net);
 
 int ip_tunnel_get_iflink(const struct net_device *dev)
 {
-       struct ip_tunnel *tunnel = netdev_priv(dev);
+       const struct ip_tunnel *tunnel = netdev_priv(dev);
 
-       return tunnel->parms.link;
+       return READ_ONCE(tunnel->parms.link);
 }
 EXPORT_SYMBOL(ip_tunnel_get_iflink);