diff mbox series

[v3,mptcp-next,2/3] mptcp: sockopt: support IP_LOCAL_PORT_RANGE and IP_BIND_ADDRESS_NO_PORT

Message ID 20231211120309.20752-3-max@internet.ru (mailing list archive)
State Accepted, archived
Commit be6fee83fad16dee6b5629485bd66bdf8183429e
Delegated to: Matthieu Baerts
Headers show
Series more sockopts for ephemeral ports | expand

Checks

Context Check Description
matttbe/build success Build and static analysis OK
matttbe/checkpatch success total: 0 errors, 0 warnings, 0 checks, 57 lines checked
matttbe/KVM_Validation__normal__except_selftest_mptcp_join_ warning Unstable: 1 failed test(s): selftest_simult_flows
matttbe/KVM_Validation__normal__only_selftest_mptcp_join_ success Success! ✅
matttbe/KVM_Validation__debug__except_selftest_mptcp_join_ warning Unstable: 1 failed test(s): packetdrill_regressions
matttbe/KVM_Validation__debug__only_selftest_mptcp_join_ warning Unstable: 1 failed test(s): selftest_mptcp_join

Commit Message

Maxim Galaganov Dec. 11, 2023, 12:03 p.m. UTC
Support for IP_BIND_ADDRESS_NO_PORT sockopt was introduced in [1].
Recently [2] allowed its value to be accessed without locking the
socket.

Support for (newer) IP_LOCAL_PORT_RANGE sockopt was introduced in [3].
In the same series a selftest was added in [4]. This selftest also
covers the IP_BIND_ADDRESS_NO_PORT sockopt.

This patch enables getsockopt()/setsockopt() on MPTCP sockets for these
socket options, syncing set values to subflows in sync_socket_options().
Ephemeral port range is synced to subflows, enabling NAT usecase
described in [3].

[1] commit 90c337da1524 ("inet: add IP_BIND_ADDRESS_NO_PORT to overcome
bind(0) limitations")
[2] commit ca571e2eb7eb ("inet: move inet->bind_address_no_port to
inet->inet_flags")
[3] commit 91d0b78c5177 ("inet: Add IP_LOCAL_PORT_RANGE socket option")
[4] commit ae5439658cce ("selftests/net: Cover the IP_LOCAL_PORT_RANGE
socket option")

Signed-off-by: Maxim Galaganov <max@internet.ru>
---
 net/mptcp/sockopt.c | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

Comments

Mat Martineau Dec. 13, 2023, 5:07 p.m. UTC | #1
On Mon, 11 Dec 2023, Maxim Galaganov wrote:

> Support for IP_BIND_ADDRESS_NO_PORT sockopt was introduced in [1].
> Recently [2] allowed its value to be accessed without locking the
> socket.
>
> Support for (newer) IP_LOCAL_PORT_RANGE sockopt was introduced in [3].
> In the same series a selftest was added in [4]. This selftest also
> covers the IP_BIND_ADDRESS_NO_PORT sockopt.
>
> This patch enables getsockopt()/setsockopt() on MPTCP sockets for these
> socket options, syncing set values to subflows in sync_socket_options().
> Ephemeral port range is synced to subflows, enabling NAT usecase
> described in [3].
>
> [1] commit 90c337da1524 ("inet: add IP_BIND_ADDRESS_NO_PORT to overcome
> bind(0) limitations")
> [2] commit ca571e2eb7eb ("inet: move inet->bind_address_no_port to
> inet->inet_flags")
> [3] commit 91d0b78c5177 ("inet: Add IP_LOCAL_PORT_RANGE socket option")
> [4] commit ae5439658cce ("selftests/net: Cover the IP_LOCAL_PORT_RANGE
> socket option")
>
> Signed-off-by: Maxim Galaganov <max@internet.ru>

v3 looks good, thanks Maxim!

Reviewed-by: Mat Martineau <martineau@kernel.org>

> ---
> net/mptcp/sockopt.c | 21 ++++++++++++++++++++-
> 1 file changed, 20 insertions(+), 1 deletion(-)
>
> diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c
> index a4bf337e6f77..c40f1428e602 100644
> --- a/net/mptcp/sockopt.c
> +++ b/net/mptcp/sockopt.c
> @@ -440,6 +440,8 @@ static bool mptcp_supported_sockopt(int level, int optname)
> 		/* should work fine */
> 		case IP_FREEBIND:
> 		case IP_TRANSPARENT:
> +		case IP_BIND_ADDRESS_NO_PORT:
> +		case IP_LOCAL_PORT_RANGE:
>
> 		/* the following are control cmsg related */
> 		case IP_PKTINFO:
> @@ -455,7 +457,6 @@ static bool mptcp_supported_sockopt(int level, int optname)
> 		/* common stuff that need some love */
> 		case IP_TOS:
> 		case IP_TTL:
> -		case IP_BIND_ADDRESS_NO_PORT:
> 		case IP_MTU_DISCOVER:
> 		case IP_RECVERR:
>
> @@ -710,6 +711,14 @@ static int mptcp_setsockopt_sol_ip_set(struct mptcp_sock *msk, int optname,
> 		inet_assign_bit(TRANSPARENT, ssk,
> 				inet_test_bit(TRANSPARENT, sk));
> 		break;
> +	case IP_BIND_ADDRESS_NO_PORT:
> +		inet_assign_bit(BIND_ADDRESS_NO_PORT, ssk,
> +				inet_test_bit(BIND_ADDRESS_NO_PORT, sk));
> +		break;
> +	case IP_LOCAL_PORT_RANGE:
> +		WRITE_ONCE(inet_sk(ssk)->local_port_range,
> +			   READ_ONCE(inet_sk(sk)->local_port_range));
> +		break;
> 	default:
> 		release_sock(sk);
> 		WARN_ON_ONCE(1);
> @@ -755,6 +764,8 @@ static int mptcp_setsockopt_v4(struct mptcp_sock *msk, int optname,
> 	switch (optname) {
> 	case IP_FREEBIND:
> 	case IP_TRANSPARENT:
> +	case IP_BIND_ADDRESS_NO_PORT:
> +	case IP_LOCAL_PORT_RANGE:
> 		return mptcp_setsockopt_sol_ip_set(msk, optname, optval, optlen);
> 	case IP_TOS:
> 		return mptcp_setsockopt_v4_set_tos(msk, optname, optval, optlen);
> @@ -1350,6 +1361,12 @@ static int mptcp_getsockopt_v4(struct mptcp_sock *msk, int optname,
> 	switch (optname) {
> 	case IP_TOS:
> 		return mptcp_put_int_option(msk, optval, optlen, READ_ONCE(inet_sk(sk)->tos));
> +	case IP_BIND_ADDRESS_NO_PORT:
> +		return mptcp_put_int_option(msk, optval, optlen,
> +				inet_test_bit(BIND_ADDRESS_NO_PORT, sk));
> +	case IP_LOCAL_PORT_RANGE:
> +		return mptcp_put_int_option(msk, optval, optlen,
> +				READ_ONCE(inet_sk(sk)->local_port_range));
> 	}
>
> 	return -EOPNOTSUPP;
> @@ -1450,6 +1467,8 @@ static void sync_socket_options(struct mptcp_sock *msk, struct sock *ssk)
>
> 	inet_assign_bit(TRANSPARENT, ssk, inet_test_bit(TRANSPARENT, sk));
> 	inet_assign_bit(FREEBIND, ssk, inet_test_bit(FREEBIND, sk));
> +	inet_assign_bit(BIND_ADDRESS_NO_PORT, ssk, inet_test_bit(BIND_ADDRESS_NO_PORT, sk));
> +	WRITE_ONCE(inet_sk(ssk)->local_port_range, READ_ONCE(inet_sk(sk)->local_port_range));
> }
>
> void mptcp_sockopt_sync_locked(struct mptcp_sock *msk, struct sock *ssk)
> -- 
> 2.43.0
>
>
diff mbox series

Patch

diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c
index a4bf337e6f77..c40f1428e602 100644
--- a/net/mptcp/sockopt.c
+++ b/net/mptcp/sockopt.c
@@ -440,6 +440,8 @@  static bool mptcp_supported_sockopt(int level, int optname)
 		/* should work fine */
 		case IP_FREEBIND:
 		case IP_TRANSPARENT:
+		case IP_BIND_ADDRESS_NO_PORT:
+		case IP_LOCAL_PORT_RANGE:
 
 		/* the following are control cmsg related */
 		case IP_PKTINFO:
@@ -455,7 +457,6 @@  static bool mptcp_supported_sockopt(int level, int optname)
 		/* common stuff that need some love */
 		case IP_TOS:
 		case IP_TTL:
-		case IP_BIND_ADDRESS_NO_PORT:
 		case IP_MTU_DISCOVER:
 		case IP_RECVERR:
 
@@ -710,6 +711,14 @@  static int mptcp_setsockopt_sol_ip_set(struct mptcp_sock *msk, int optname,
 		inet_assign_bit(TRANSPARENT, ssk,
 				inet_test_bit(TRANSPARENT, sk));
 		break;
+	case IP_BIND_ADDRESS_NO_PORT:
+		inet_assign_bit(BIND_ADDRESS_NO_PORT, ssk,
+				inet_test_bit(BIND_ADDRESS_NO_PORT, sk));
+		break;
+	case IP_LOCAL_PORT_RANGE:
+		WRITE_ONCE(inet_sk(ssk)->local_port_range,
+			   READ_ONCE(inet_sk(sk)->local_port_range));
+		break;
 	default:
 		release_sock(sk);
 		WARN_ON_ONCE(1);
@@ -755,6 +764,8 @@  static int mptcp_setsockopt_v4(struct mptcp_sock *msk, int optname,
 	switch (optname) {
 	case IP_FREEBIND:
 	case IP_TRANSPARENT:
+	case IP_BIND_ADDRESS_NO_PORT:
+	case IP_LOCAL_PORT_RANGE:
 		return mptcp_setsockopt_sol_ip_set(msk, optname, optval, optlen);
 	case IP_TOS:
 		return mptcp_setsockopt_v4_set_tos(msk, optname, optval, optlen);
@@ -1350,6 +1361,12 @@  static int mptcp_getsockopt_v4(struct mptcp_sock *msk, int optname,
 	switch (optname) {
 	case IP_TOS:
 		return mptcp_put_int_option(msk, optval, optlen, READ_ONCE(inet_sk(sk)->tos));
+	case IP_BIND_ADDRESS_NO_PORT:
+		return mptcp_put_int_option(msk, optval, optlen,
+				inet_test_bit(BIND_ADDRESS_NO_PORT, sk));
+	case IP_LOCAL_PORT_RANGE:
+		return mptcp_put_int_option(msk, optval, optlen,
+				READ_ONCE(inet_sk(sk)->local_port_range));
 	}
 
 	return -EOPNOTSUPP;
@@ -1450,6 +1467,8 @@  static void sync_socket_options(struct mptcp_sock *msk, struct sock *ssk)
 
 	inet_assign_bit(TRANSPARENT, ssk, inet_test_bit(TRANSPARENT, sk));
 	inet_assign_bit(FREEBIND, ssk, inet_test_bit(FREEBIND, sk));
+	inet_assign_bit(BIND_ADDRESS_NO_PORT, ssk, inet_test_bit(BIND_ADDRESS_NO_PORT, sk));
+	WRITE_ONCE(inet_sk(ssk)->local_port_range, READ_ONCE(inet_sk(sk)->local_port_range));
 }
 
 void mptcp_sockopt_sync_locked(struct mptcp_sock *msk, struct sock *ssk)