diff options
author | Eric Dumazet <edumazet@google.com> | 2023-08-16 08:15:47 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2023-08-16 11:09:18 +0100 |
commit | 12af73269fd942c98ff9999a2ce0c04165aae136 (patch) | |
tree | 6f331e6826eefbbc3a1bfc3fc24eac5434fabfad /net/ipv4 | |
parent | 10f42426e5bcea728d7fae96609b29b4fb1f7518 (diff) | |
download | linux-12af73269fd942c98ff9999a2ce0c04165aae136.tar.gz linux-12af73269fd942c98ff9999a2ce0c04165aae136.tar.bz2 linux-12af73269fd942c98ff9999a2ce0c04165aae136.zip |
inet: implement lockless IP_MINTTL
inet->min_ttl is already read with READ_ONCE().
Implementing IP_MINTTL socket option set/read
without holding the socket lock is easy.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Acked-by: Soheil Hassas Yeganeh <soheil@google.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/ip_sockglue.c | 32 |
1 files changed, 14 insertions, 18 deletions
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index dbb2d2342ebf..61b2e7bc7031 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -1030,6 +1030,17 @@ int do_ip_setsockopt(struct sock *sk, int level, int optname, return -EINVAL; WRITE_ONCE(inet->uc_ttl, val); return 0; + case IP_MINTTL: + if (optlen < 1) + return -EINVAL; + if (val < 0 || val > 255) + return -EINVAL; + + if (val) + static_branch_enable(&ip4_min_ttl); + + WRITE_ONCE(inet->min_ttl, val); + return 0; } err = 0; @@ -1326,21 +1337,6 @@ int do_ip_setsockopt(struct sock *sk, int level, int optname, err = xfrm_user_policy(sk, optname, optval, optlen); break; - case IP_MINTTL: - if (optlen < 1) - goto e_inval; - if (val < 0 || val > 255) - goto e_inval; - - if (val) - static_branch_enable(&ip4_min_ttl); - - /* tcp_v4_err() and tcp_v4_rcv() might read min_ttl - * while we are changint it. - */ - WRITE_ONCE(inet->min_ttl, val); - break; - case IP_LOCAL_PORT_RANGE: { const __u16 lo = val; @@ -1595,6 +1591,9 @@ int do_ip_getsockopt(struct sock *sk, int level, int optname, if (val < 0) val = READ_ONCE(sock_net(sk)->ipv4.sysctl_ip_default_ttl); goto copyval; + case IP_MINTTL: + val = READ_ONCE(inet->min_ttl); + goto copyval; } if (needs_rtnl) @@ -1731,9 +1730,6 @@ int do_ip_getsockopt(struct sock *sk, int level, int optname, len -= msg.msg_controllen; return copy_to_sockptr(optlen, &len, sizeof(int)); } - case IP_MINTTL: - val = inet->min_ttl; - break; case IP_LOCAL_PORT_RANGE: val = inet->local_port_range.hi << 16 | inet->local_port_range.lo; break; |