Commit 12af7326 authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller
Browse files

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: default avatarEric Dumazet <edumazet@google.com>
Acked-by: default avatarSoheil Hassas Yeganeh <soheil@google.com>
Reviewed-by: default avatarSimon Horman <horms@kernel.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 10f42426
Loading
Loading
Loading
Loading
+14 −18
Original line number Diff line number Diff line
@@ -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;