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 |
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 |
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 --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)
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(-)