diff options
author | Eric Dumazet <edumazet@google.com> | 2023-09-22 06:42:15 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2023-10-01 21:39:18 +0300 |
commit | ceaa714138a372ac63cc2c5c19ee0882d22827f9 (patch) | |
tree | 73b347539e9039e35d9ef9566cf38ec5e6cfb214 /net/ipv4/ip_output.c | |
parent | c9746e6a19c24b2d9a74d6657daee3b39fdc1bec (diff) | |
download | linux-ceaa714138a372ac63cc2c5c19ee0882d22827f9.tar.xz |
inet: implement lockless IP_MTU_DISCOVER
inet->pmtudisc can be read locklessly.
Implement proper lockless reads and writes to inet->pmtudisc
ip_sock_set_mtu_discover() can now be called from arbitrary
contexts.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/ip_output.c')
-rw-r--r-- | net/ipv4/ip_output.c | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index f07ce051760d..9fc7be2c2033 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -1387,8 +1387,8 @@ struct sk_buff *__ip_make_skb(struct sock *sk, struct ip_options *opt = NULL; struct rtable *rt = (struct rtable *)cork->dst; struct iphdr *iph; + u8 pmtudisc, ttl; __be16 df = 0; - __u8 ttl; skb = __skb_dequeue(queue); if (!skb) @@ -1418,8 +1418,9 @@ struct sk_buff *__ip_make_skb(struct sock *sk, /* DF bit is set when we want to see DF on outgoing frames. * If ignore_df is set too, we still allow to fragment this frame * locally. */ - if (inet->pmtudisc == IP_PMTUDISC_DO || - inet->pmtudisc == IP_PMTUDISC_PROBE || + pmtudisc = READ_ONCE(inet->pmtudisc); + if (pmtudisc == IP_PMTUDISC_DO || + pmtudisc == IP_PMTUDISC_PROBE || (skb->len <= dst_mtu(&rt->dst) && ip_dont_fragment(sk, &rt->dst))) df = htons(IP_DF); |