mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
ip6_tunnel: annotate data-races around t->err_count and t->err_time
ip6_tnl_xmit() and ipip6_tunnel_xmit() run locklessly (dev->lltx == true). ip6gre_err() and ipip6_err() also run locklessly. We need to add READ_ONCE() and WRITE_ONCE() annotations around t->err_count and t->err_time. Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Link: https://patch.msgid.link/20260610171458.1359630-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
9bbdc7dc40
commit
f6033078a9
|
|
@ -445,11 +445,11 @@ static int ip6gre_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (time_before(jiffies, t->err_time + IP6TUNNEL_ERR_TIMEO))
|
||||
t->err_count++;
|
||||
if (time_before(jiffies, READ_ONCE(t->err_time) + IP6TUNNEL_ERR_TIMEO))
|
||||
WRITE_ONCE(t->err_count, READ_ONCE(t->err_count) + 1);
|
||||
else
|
||||
t->err_count = 1;
|
||||
t->err_time = jiffies;
|
||||
WRITE_ONCE(t->err_count, 1);
|
||||
WRITE_ONCE(t->err_time, jiffies);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1104,7 +1104,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield,
|
|||
struct ipv6_tel_txoption opt;
|
||||
struct dst_entry *dst = NULL, *ndst = NULL;
|
||||
struct net_device *tdev;
|
||||
int mtu;
|
||||
int err_count, mtu;
|
||||
unsigned int eth_hlen = t->dev->type == ARPHRD_ETHER ? ETH_HLEN : 0;
|
||||
unsigned int psh_hlen = sizeof(struct ipv6hdr) + t->encap_hlen;
|
||||
unsigned int max_headroom = psh_hlen;
|
||||
|
|
@ -1214,14 +1214,15 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield,
|
|||
goto tx_err_dst_release;
|
||||
}
|
||||
|
||||
if (t->err_count > 0) {
|
||||
err_count = READ_ONCE(t->err_count);
|
||||
if (err_count > 0) {
|
||||
if (time_before(jiffies,
|
||||
t->err_time + IP6TUNNEL_ERR_TIMEO)) {
|
||||
t->err_count--;
|
||||
READ_ONCE(t->err_time) + IP6TUNNEL_ERR_TIMEO)) {
|
||||
WRITE_ONCE(t->err_count, err_count - 1);
|
||||
|
||||
dst_link_failure(skb);
|
||||
} else {
|
||||
t->err_count = 0;
|
||||
WRITE_ONCE(t->err_count, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -595,11 +595,11 @@ static int ipip6_err(struct sk_buff *skb, u32 info)
|
|||
if (t->parms.iph.ttl == 0 && type == ICMP_TIME_EXCEEDED)
|
||||
goto out;
|
||||
|
||||
if (time_before(jiffies, t->err_time + IPTUNNEL_ERR_TIMEO))
|
||||
t->err_count++;
|
||||
if (time_before(jiffies, READ_ONCE(t->err_time) + IPTUNNEL_ERR_TIMEO))
|
||||
WRITE_ONCE(t->err_count, READ_ONCE(t->err_count) + 1);
|
||||
else
|
||||
t->err_count = 1;
|
||||
t->err_time = jiffies;
|
||||
WRITE_ONCE(t->err_count, 1);
|
||||
WRITE_ONCE(t->err_time, jiffies);
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
|
@ -909,8 +909,8 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
|
|||
struct net_device *tdev; /* Device to other host */
|
||||
unsigned int max_headroom; /* The extra header space needed */
|
||||
__be32 dst = tiph->daddr;
|
||||
int err_count, mtu;
|
||||
struct flowi4 fl4;
|
||||
int mtu;
|
||||
u8 ttl;
|
||||
u8 protocol = IPPROTO_IPV6;
|
||||
int t_hlen = tunnel->hlen + sizeof(struct iphdr);
|
||||
|
|
@ -987,13 +987,15 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
|
|||
}
|
||||
}
|
||||
|
||||
if (tunnel->err_count > 0) {
|
||||
err_count = READ_ONCE(tunnel->err_count);
|
||||
if (err_count > 0) {
|
||||
if (time_before(jiffies,
|
||||
tunnel->err_time + IPTUNNEL_ERR_TIMEO)) {
|
||||
tunnel->err_count--;
|
||||
READ_ONCE(tunnel->err_time) + IPTUNNEL_ERR_TIMEO)) {
|
||||
WRITE_ONCE(tunnel->err_count, err_count - 1);
|
||||
dst_link_failure(skb);
|
||||
} else
|
||||
tunnel->err_count = 0;
|
||||
} else {
|
||||
WRITE_ONCE(tunnel->err_count, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user