mirror of
https://github.com/torvalds/linux
synced 2024-07-21 18:51:47 +00:00
mptcp: sockopt: support IP_LOCAL_PORT_RANGE and IP_BIND_ADDRESS_NO_PORT
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] commit90c337da15
("inet: add IP_BIND_ADDRESS_NO_PORT to overcome bind(0) limitations") [2] commitca571e2eb7
("inet: move inet->bind_address_no_port to inet->inet_flags") [3] commit91d0b78c51
("inet: Add IP_LOCAL_PORT_RANGE socket option") [4] commitae5439658c
("selftests/net: Cover the IP_LOCAL_PORT_RANGE socket option") Signed-off-by: Maxim Galaganov <max@internet.ru> Reviewed-by: Mat Martineau <martineau@kernel.org> Signed-off-by: Matthieu Baerts <matttbe@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
57d3117ca8
commit
c85636a292
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue