mptcp.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
* [PATCH mptcp-next 0/8] add cmsg support to receive path
@ 2021-05-06 10:22 Florian Westphal
  2021-05-06 10:22 ` [PATCH mptcp-next 1/8] mptcp: enable busypoll from mptcp " Florian Westphal
                   ` (7 more replies)
  0 siblings, 8 replies; 12+ messages in thread
From: Florian Westphal @ 2021-05-06 10:22 UTC (permalink / raw)
  To: mptcp; +Cc: Florian Westphal

This adds setsockopt support for busypoll + and the various
SO_TIMESTAMP variants.

To reduce copy&paste, a few helper functions get exported for
mptcp sake.

Last patch extends the existing setsockopt test case to also
cover/enable SO_TIMESTAMP.

Florian Westphal (8):
  mptcp: enable busypoll from mptcp receive path
  sock: expose so_timestamp options for mptcp
  sock: expose so_timestamping options for mptcp
  mptcp: sockopt: propagate timestamp request to subflows
  mptcp: setsockopt: handle SOL_SOCKET in one place only
  tcp: export timestamp helpers for mptcp
  mptcp: receive path cmsg support
  selftests: mptcp_connect: add SO_TIMESTAMPNS cmsg support

 include/net/sock.h                            |   3 +
 include/net/tcp.h                             |   4 +
 net/core/sock.c                               |  97 +++++++-----
 net/ipv4/tcp.c                                |  10 +-
 net/mptcp/protocol.c                          |  35 ++++-
 net/mptcp/sockopt.c                           | 145 ++++++++++--------
 .../selftests/net/mptcp/mptcp_connect.c       | 125 ++++++++++++++-
 .../selftests/net/mptcp/mptcp_sockopt.sh      |   4 +-
 8 files changed, 303 insertions(+), 120 deletions(-)

-- 
2.26.3


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH mptcp-next 1/8] mptcp: enable busypoll from mptcp receive path
  2021-05-06 10:22 [PATCH mptcp-next 0/8] add cmsg support to receive path Florian Westphal
@ 2021-05-06 10:22 ` Florian Westphal
  2021-05-11  0:02   ` Mat Martineau
  2021-05-06 10:22 ` [PATCH mptcp-next 2/8] sock: expose so_timestamp options for mptcp Florian Westphal
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 12+ messages in thread
From: Florian Westphal @ 2021-05-06 10:22 UTC (permalink / raw)
  To: mptcp; +Cc: Florian Westphal

The setting is only relevant for the msk socket.
While at it, also handle rcvlowat/rcvtimeo this way.

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 net/mptcp/protocol.c | 7 +++++++
 net/mptcp/sockopt.c  | 8 ++++++++
 2 files changed, 15 insertions(+)

diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index aec8e77b18e4..e51070883064 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -12,6 +12,7 @@
 #include <linux/sched/signal.h>
 #include <linux/atomic.h>
 #include <net/sock.h>
+#include <net/busy_poll.h>
 #include <net/inet_common.h>
 #include <net/inet_hashtables.h>
 #include <net/protocol.h>
@@ -1966,6 +1967,12 @@ static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
 	if (unlikely(flags & MSG_ERRQUEUE))
 		return inet_recv_error(sk, msg, len, addr_len);
 
+	if (sk_can_busy_loop(sk) &&
+	    skb_queue_empty_lockless(&msk->receive_queue) &&
+	    skb_queue_empty_lockless(&sk->sk_receive_queue) &&
+	     inet_sk_state_load(sk) == TCP_ESTABLISHED)
+		sk_busy_loop(sk, nonblock);
+
 	mptcp_lock_sock(sk, __mptcp_splice_receive_queue(sk));
 	if (unlikely(sk->sk_state == TCP_LISTEN)) {
 		copied = -ENOTCONN;
diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c
index 00d941b66c1e..c98e4e116992 100644
--- a/net/mptcp/sockopt.c
+++ b/net/mptcp/sockopt.c
@@ -254,6 +254,14 @@ static int mptcp_setsockopt_sol_socket(struct mptcp_sock *msk, int optname,
 		return mptcp_setsockopt_sol_socket_int(msk, optname, optval, optlen);
 	case SO_LINGER:
 		return mptcp_setsockopt_sol_socket_linger(msk, optval, optlen);
+	case SO_RCVLOWAT:
+	case SO_RCVTIMEO_OLD:
+	case SO_RCVTIMEO_NEW:
+	case SO_BUSY_POLL:
+	case SO_PREFER_BUSY_POLL:
+	case SO_BUSY_POLL_BUDGET:
+		/* No need to copy: only relevant for msk */
+		break;
 	case SO_NO_CHECK:
 	case SO_DONTROUTE:
 	case SO_BROADCAST:
-- 
2.26.3


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH mptcp-next 2/8] sock: expose so_timestamp options for mptcp
  2021-05-06 10:22 [PATCH mptcp-next 0/8] add cmsg support to receive path Florian Westphal
  2021-05-06 10:22 ` [PATCH mptcp-next 1/8] mptcp: enable busypoll from mptcp " Florian Westphal
@ 2021-05-06 10:22 ` Florian Westphal
  2021-05-06 10:22 ` [PATCH mptcp-next 3/8] sock: expose so_timestamping " Florian Westphal
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: Florian Westphal @ 2021-05-06 10:22 UTC (permalink / raw)
  To: mptcp; +Cc: Florian Westphal

This exports SO_TIMESTAMP_* function for re-use by MPTCP.

Without this there is too much copy & paste needed to support
this from mptcp setsockopt path.

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 include/net/sock.h |  1 +
 net/core/sock.c    | 26 +++++++++++++++++++-------
 2 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/include/net/sock.h b/include/net/sock.h
index 42bc5e1a627f..7ee2347846b6 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -2741,6 +2741,7 @@ static inline bool sk_dev_equal_l3scope(struct sock *sk, int dif)
 void sock_def_readable(struct sock *sk);
 
 int sock_bindtoindex(struct sock *sk, int ifindex, bool lock_sk);
+void sock_set_timestamp(struct sock *sk, int optname, bool valbool);
 void sock_enable_timestamps(struct sock *sk);
 void sock_no_linger(struct sock *sk);
 void sock_set_keepalive(struct sock *sk);
diff --git a/net/core/sock.c b/net/core/sock.c
index c761c4a0b66b..294b5a9bf520 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -776,6 +776,24 @@ void sock_enable_timestamps(struct sock *sk)
 }
 EXPORT_SYMBOL(sock_enable_timestamps);
 
+void sock_set_timestamp(struct sock *sk, int optname, bool valbool)
+{
+	switch (optname) {
+	case SO_TIMESTAMP_OLD:
+		__sock_set_timestamps(sk, valbool, false, false);
+		break;
+	case SO_TIMESTAMP_NEW:
+		__sock_set_timestamps(sk, valbool, true, false);
+		break;
+	case SO_TIMESTAMPNS_OLD:
+		__sock_set_timestamps(sk, valbool, false, true);
+		break;
+	case SO_TIMESTAMPNS_NEW:
+		__sock_set_timestamps(sk, valbool, true, true);
+		break;
+	}
+}
+
 void sock_set_keepalive(struct sock *sk)
 {
 	lock_sock(sk);
@@ -989,16 +1007,10 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
 		break;
 
 	case SO_TIMESTAMP_OLD:
-		__sock_set_timestamps(sk, valbool, false, false);
-		break;
 	case SO_TIMESTAMP_NEW:
-		__sock_set_timestamps(sk, valbool, true, false);
-		break;
 	case SO_TIMESTAMPNS_OLD:
-		__sock_set_timestamps(sk, valbool, false, true);
-		break;
 	case SO_TIMESTAMPNS_NEW:
-		__sock_set_timestamps(sk, valbool, true, true);
+		sock_set_timestamp(sk, valbool, optname);
 		break;
 	case SO_TIMESTAMPING_NEW:
 	case SO_TIMESTAMPING_OLD:
-- 
2.26.3


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH mptcp-next 3/8] sock: expose so_timestamping options for mptcp
  2021-05-06 10:22 [PATCH mptcp-next 0/8] add cmsg support to receive path Florian Westphal
  2021-05-06 10:22 ` [PATCH mptcp-next 1/8] mptcp: enable busypoll from mptcp " Florian Westphal
  2021-05-06 10:22 ` [PATCH mptcp-next 2/8] sock: expose so_timestamp options for mptcp Florian Westphal
@ 2021-05-06 10:22 ` Florian Westphal
  2021-05-06 10:22 ` [PATCH mptcp-next 4/8] mptcp: sockopt: propagate timestamp request to subflows Florian Westphal
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: Florian Westphal @ 2021-05-06 10:22 UTC (permalink / raw)
  To: mptcp; +Cc: Florian Westphal

Similar to previous patch: expose SO_TIMESTAMPING helper so we do not
have to copy & paste this into the mptcp core.

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 include/net/sock.h |  2 ++
 net/core/sock.c    | 71 +++++++++++++++++++++++-----------------------
 2 files changed, 38 insertions(+), 35 deletions(-)

diff --git a/include/net/sock.h b/include/net/sock.h
index 7ee2347846b6..636416631913 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -2742,6 +2742,8 @@ void sock_def_readable(struct sock *sk);
 
 int sock_bindtoindex(struct sock *sk, int ifindex, bool lock_sk);
 void sock_set_timestamp(struct sock *sk, int optname, bool valbool);
+int sock_set_timestamping(struct sock *sk, int optname, int val);
+
 void sock_enable_timestamps(struct sock *sk);
 void sock_no_linger(struct sock *sk);
 void sock_set_keepalive(struct sock *sk);
diff --git a/net/core/sock.c b/net/core/sock.c
index 294b5a9bf520..aba9d8de5303 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -794,6 +794,40 @@ void sock_set_timestamp(struct sock *sk, int optname, bool valbool)
 	}
 }
 
+int sock_set_timestamping(struct sock *sk, int optname, int val)
+{
+	if (val & ~SOF_TIMESTAMPING_MASK)
+		return -EINVAL;
+
+	if (val & SOF_TIMESTAMPING_OPT_ID &&
+	    !(sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID)) {
+		if (sk->sk_protocol == IPPROTO_TCP &&
+		    sk->sk_type == SOCK_STREAM) {
+			if ((1 << sk->sk_state) &
+			    (TCPF_CLOSE | TCPF_LISTEN))
+				return -EINVAL;
+			sk->sk_tskey = tcp_sk(sk)->snd_una;
+		} else {
+			sk->sk_tskey = 0;
+		}
+	}
+
+	if (val & SOF_TIMESTAMPING_OPT_STATS &&
+	    !(val & SOF_TIMESTAMPING_OPT_TSONLY))
+		return -EINVAL;
+
+	sk->sk_tsflags = val;
+	sock_valbool_flag(sk, SOCK_TSTAMP_NEW, optname == SO_TIMESTAMPING_NEW);
+
+	if (val & SOF_TIMESTAMPING_RX_SOFTWARE)
+		sock_enable_timestamp(sk,
+				      SOCK_TIMESTAMPING_RX_SOFTWARE);
+	else
+		sock_disable_timestamp(sk,
+				       (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE));
+	return 0;
+}
+
 void sock_set_keepalive(struct sock *sk)
 {
 	lock_sock(sk);
@@ -1012,43 +1046,10 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
 	case SO_TIMESTAMPNS_NEW:
 		sock_set_timestamp(sk, valbool, optname);
 		break;
+
 	case SO_TIMESTAMPING_NEW:
 	case SO_TIMESTAMPING_OLD:
-		if (val & ~SOF_TIMESTAMPING_MASK) {
-			ret = -EINVAL;
-			break;
-		}
-
-		if (val & SOF_TIMESTAMPING_OPT_ID &&
-		    !(sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID)) {
-			if (sk->sk_protocol == IPPROTO_TCP &&
-			    sk->sk_type == SOCK_STREAM) {
-				if ((1 << sk->sk_state) &
-				    (TCPF_CLOSE | TCPF_LISTEN)) {
-					ret = -EINVAL;
-					break;
-				}
-				sk->sk_tskey = tcp_sk(sk)->snd_una;
-			} else {
-				sk->sk_tskey = 0;
-			}
-		}
-
-		if (val & SOF_TIMESTAMPING_OPT_STATS &&
-		    !(val & SOF_TIMESTAMPING_OPT_TSONLY)) {
-			ret = -EINVAL;
-			break;
-		}
-
-		sk->sk_tsflags = val;
-		sock_valbool_flag(sk, SOCK_TSTAMP_NEW, optname == SO_TIMESTAMPING_NEW);
-
-		if (val & SOF_TIMESTAMPING_RX_SOFTWARE)
-			sock_enable_timestamp(sk,
-					      SOCK_TIMESTAMPING_RX_SOFTWARE);
-		else
-			sock_disable_timestamp(sk,
-					       (1UL << SOCK_TIMESTAMPING_RX_SOFTWARE));
+		ret = sock_set_timestamping(sk, optname, val);
 		break;
 
 	case SO_RCVLOWAT:
-- 
2.26.3


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH mptcp-next 4/8] mptcp: sockopt: propagate timestamp request to subflows
  2021-05-06 10:22 [PATCH mptcp-next 0/8] add cmsg support to receive path Florian Westphal
                   ` (2 preceding siblings ...)
  2021-05-06 10:22 ` [PATCH mptcp-next 3/8] sock: expose so_timestamping " Florian Westphal
@ 2021-05-06 10:22 ` Florian Westphal
  2021-05-06 10:22 ` [PATCH mptcp-next 5/8] mptcp: setsockopt: handle SOL_SOCKET in one place only Florian Westphal
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 12+ messages in thread
From: Florian Westphal @ 2021-05-06 10:22 UTC (permalink / raw)
  To: mptcp; +Cc: Florian Westphal

This adds support for TIMESTAMP(NS) setsockopt.

This doesn't make things work yet, because the mptcp receive path
doesn't convert the skb timestamps to cmsgs for userspace consumption.

receive path cmsg support is added ina followup patch.

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 net/mptcp/sockopt.c | 50 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c
index c98e4e116992..7b47204ecb9a 100644
--- a/net/mptcp/sockopt.c
+++ b/net/mptcp/sockopt.c
@@ -140,6 +140,43 @@ static void mptcp_so_incoming_cpu(struct mptcp_sock *msk, int val)
 	mptcp_sol_socket_sync_intval(msk, SO_INCOMING_CPU, val);
 }
 
+static int mptcp_setsockopt_sol_socket_tstamp(struct mptcp_sock *msk, int optname, int val)
+{
+	sockptr_t optval = KERNEL_SOCKPTR(&val);
+	struct mptcp_subflow_context *subflow;
+	struct sock *sk = (struct sock *)msk;
+	int ret;
+
+	ret = sock_setsockopt(sk->sk_socket, SOL_SOCKET, optname,
+			      optval, sizeof(val));
+	if (ret)
+		return ret;
+
+	lock_sock(sk);
+	mptcp_for_each_subflow(msk, subflow) {
+		struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
+		bool slow = lock_sock_fast(ssk);
+
+		switch (optname) {
+		case SO_TIMESTAMP_OLD:
+		case SO_TIMESTAMP_NEW:
+		case SO_TIMESTAMPNS_OLD:
+		case SO_TIMESTAMPNS_NEW:
+			sock_set_timestamp(sk, optname, !!val);
+			break;
+		case SO_TIMESTAMPING_NEW:
+		case SO_TIMESTAMPING_OLD:
+			sock_set_timestamping(sk, optname, val);
+			break;
+		}
+
+		unlock_sock_fast(ssk, slow);
+	}
+
+	release_sock(sk);
+	return 0;
+}
+
 static int mptcp_setsockopt_sol_socket_int(struct mptcp_sock *msk, int optname,
 					   sockptr_t optval, unsigned int optlen)
 {
@@ -164,6 +201,13 @@ static int mptcp_setsockopt_sol_socket_int(struct mptcp_sock *msk, int optname,
 	case SO_INCOMING_CPU:
 		mptcp_so_incoming_cpu(msk, val);
 		return 0;
+	case SO_TIMESTAMP_OLD:
+	case SO_TIMESTAMP_NEW:
+	case SO_TIMESTAMPNS_OLD:
+	case SO_TIMESTAMPNS_NEW:
+	case SO_TIMESTAMPING_OLD:
+	case SO_TIMESTAMPING_NEW:
+		return mptcp_setsockopt_sol_socket_tstamp(msk, optname, val);
 	}
 
 	return -ENOPROTOOPT;
@@ -251,6 +295,12 @@ static int mptcp_setsockopt_sol_socket(struct mptcp_sock *msk, int optname,
 	case SO_MARK:
 	case SO_INCOMING_CPU:
 	case SO_DEBUG:
+	case SO_TIMESTAMP_OLD:
+	case SO_TIMESTAMP_NEW:
+	case SO_TIMESTAMPNS_OLD:
+	case SO_TIMESTAMPNS_NEW:
+	case SO_TIMESTAMPING_OLD:
+	case SO_TIMESTAMPING_NEW:
 		return mptcp_setsockopt_sol_socket_int(msk, optname, optval, optlen);
 	case SO_LINGER:
 		return mptcp_setsockopt_sol_socket_linger(msk, optval, optlen);
-- 
2.26.3


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH mptcp-next 5/8] mptcp: setsockopt: handle SOL_SOCKET in one place only
  2021-05-06 10:22 [PATCH mptcp-next 0/8] add cmsg support to receive path Florian Westphal
                   ` (3 preceding siblings ...)
  2021-05-06 10:22 ` [PATCH mptcp-next 4/8] mptcp: sockopt: propagate timestamp request to subflows Florian Westphal
@ 2021-05-06 10:22 ` Florian Westphal
  2021-05-11  0:05   ` Mat Martineau
  2021-05-06 10:22 ` [PATCH mptcp-next 6/8] tcp: export timestamp helpers for mptcp Florian Westphal
                   ` (2 subsequent siblings)
  7 siblings, 1 reply; 12+ messages in thread
From: Florian Westphal @ 2021-05-06 10:22 UTC (permalink / raw)
  To: mptcp; +Cc: Florian Westphal

Move the pre-check to the function that handles all SOL_SOCKET
values.

At this point there is complete coverage for all values that have
been accepted previously.

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 net/mptcp/sockopt.c | 89 +++++++++++----------------------------------
 1 file changed, 22 insertions(+), 67 deletions(-)

diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c
index 7b47204ecb9a..a83c0e4669d7 100644
--- a/net/mptcp/sockopt.c
+++ b/net/mptcp/sockopt.c
@@ -311,7 +311,8 @@ static int mptcp_setsockopt_sol_socket(struct mptcp_sock *msk, int optname,
 	case SO_PREFER_BUSY_POLL:
 	case SO_BUSY_POLL_BUDGET:
 		/* No need to copy: only relevant for msk */
-		break;
+		return sock_setsockopt(sk->sk_socket, SOL_SOCKET, optname, optval, optlen);
+
 	case SO_NO_CHECK:
 	case SO_DONTROUTE:
 	case SO_BROADCAST:
@@ -325,7 +326,24 @@ static int mptcp_setsockopt_sol_socket(struct mptcp_sock *msk, int optname,
 		return 0;
 	}
 
-	return sock_setsockopt(sk->sk_socket, SOL_SOCKET, optname, optval, optlen);
+	/* SO_OOBINLINE is not supported, let's avoid the related mess
+	 * SO_ATTACH_FILTER, SO_ATTACH_BPF, SO_ATTACH_REUSEPORT_CBPF,
+	 * SO_DETACH_REUSEPORT_BPF, SO_DETACH_FILTER, SO_LOCK_FILTER,
+	 * we must be careful with subflows
+	 *
+	 * SO_ATTACH_REUSEPORT_EBPF is not supported, at it checks
+	 * explicitly the sk_protocol field
+	 *
+	 * SO_PEEK_OFF is unsupported, as it is for plain TCP
+	 * SO_MAX_PACING_RATE is unsupported, we must be careful with subflows
+	 * SO_CNX_ADVICE is currently unsupported, could possibly be relevant,
+	 * but likely needs careful design
+	 *
+	 * SO_ZEROCOPY is currently unsupported, TODO in sndmsg
+	 * SO_TXTIME is currently unsupported
+	 */
+
+	return -EOPNOTSUPP;
 }
 
 static int mptcp_setsockopt_v6(struct mptcp_sock *msk, int optname,
@@ -357,72 +375,9 @@ static int mptcp_setsockopt_v6(struct mptcp_sock *msk, int optname,
 
 static bool mptcp_supported_sockopt(int level, int optname)
 {
-	if (level == SOL_SOCKET) {
-		switch (optname) {
-		case SO_DEBUG:
-		case SO_REUSEPORT:
-		case SO_REUSEADDR:
-
-		/* the following ones need a better implementation,
-		 * but are quite common we want to preserve them
-		 */
-		case SO_BINDTODEVICE:
-		case SO_SNDBUF:
-		case SO_SNDBUFFORCE:
-		case SO_RCVBUF:
-		case SO_RCVBUFFORCE:
-		case SO_KEEPALIVE:
-		case SO_PRIORITY:
-		case SO_LINGER:
-		case SO_TIMESTAMP_OLD:
-		case SO_TIMESTAMP_NEW:
-		case SO_TIMESTAMPNS_OLD:
-		case SO_TIMESTAMPNS_NEW:
-		case SO_TIMESTAMPING_OLD:
-		case SO_TIMESTAMPING_NEW:
-		case SO_RCVLOWAT:
-		case SO_RCVTIMEO_OLD:
-		case SO_RCVTIMEO_NEW:
-		case SO_SNDTIMEO_OLD:
-		case SO_SNDTIMEO_NEW:
-		case SO_MARK:
-		case SO_INCOMING_CPU:
-		case SO_BINDTOIFINDEX:
-		case SO_BUSY_POLL:
-		case SO_PREFER_BUSY_POLL:
-		case SO_BUSY_POLL_BUDGET:
-
-		/* next ones are no-op for plain TCP */
-		case SO_NO_CHECK:
-		case SO_DONTROUTE:
-		case SO_BROADCAST:
-		case SO_BSDCOMPAT:
-		case SO_PASSCRED:
-		case SO_PASSSEC:
-		case SO_RXQ_OVFL:
-		case SO_WIFI_STATUS:
-		case SO_NOFCS:
-		case SO_SELECT_ERR_QUEUE:
-			return true;
-		}
+	if (level == SOL_SOCKET)
+		return true; /* mptcp_setsockopt_sol_socket handles this */
 
-		/* SO_OOBINLINE is not supported, let's avoid the related mess */
-		/* SO_ATTACH_FILTER, SO_ATTACH_BPF, SO_ATTACH_REUSEPORT_CBPF,
-		 * SO_DETACH_REUSEPORT_BPF, SO_DETACH_FILTER, SO_LOCK_FILTER,
-		 * we must be careful with subflows
-		 */
-		/* SO_ATTACH_REUSEPORT_EBPF is not supported, at it checks
-		 * explicitly the sk_protocol field
-		 */
-		/* SO_PEEK_OFF is unsupported, as it is for plain TCP */
-		/* SO_MAX_PACING_RATE is unsupported, we must be careful with subflows */
-		/* SO_CNX_ADVICE is currently unsupported, could possibly be relevant,
-		 * but likely needs careful design
-		 */
-		/* SO_ZEROCOPY is currently unsupported, TODO in sndmsg */
-		/* SO_TXTIME is currently unsupported */
-		return false;
-	}
 	if (level == SOL_IP) {
 		switch (optname) {
 		/* should work fine */
-- 
2.26.3


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH mptcp-next 6/8] tcp: export timestamp helpers for mptcp
  2021-05-06 10:22 [PATCH mptcp-next 0/8] add cmsg support to receive path Florian Westphal
                   ` (4 preceding siblings ...)
  2021-05-06 10:22 ` [PATCH mptcp-next 5/8] mptcp: setsockopt: handle SOL_SOCKET in one place only Florian Westphal
@ 2021-05-06 10:22 ` Florian Westphal
  2021-05-06 10:22 ` [PATCH mptcp-next 7/8] mptcp: receive path cmsg support Florian Westphal
  2021-05-06 10:22 ` [PATCH mptcp-next 8/8] selftests: mptcp_connect: add SO_TIMESTAMPNS " Florian Westphal
  7 siblings, 0 replies; 12+ messages in thread
From: Florian Westphal @ 2021-05-06 10:22 UTC (permalink / raw)
  To: mptcp; +Cc: Florian Westphal

MPTCP is builtin, so no need to add EXPORT_SYMBOL()s.

It will be used to support SO_TIMESTAMP(NS) ancillary
messages in the mptcp receive path.

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 include/net/tcp.h |  4 ++++
 net/ipv4/tcp.c    | 10 ++++------
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/include/net/tcp.h b/include/net/tcp.h
index d05193cb0d99..e668f1bf780d 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -412,6 +412,10 @@ int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock,
 		int flags, int *addr_len);
 int tcp_set_rcvlowat(struct sock *sk, int val);
 int tcp_set_window_clamp(struct sock *sk, int val);
+void tcp_update_recv_tstamps(struct sk_buff *skb,
+			     struct scm_timestamping_internal *tss);
+void tcp_recv_timestamp(struct msghdr *msg, const struct sock *sk,
+			struct scm_timestamping_internal *tss);
 void tcp_data_ready(struct sock *sk);
 #ifdef CONFIG_MMU
 int tcp_mmap(struct file *file, struct socket *sock,
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index e14fd0c50c10..ad18c3ab1e17 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1738,8 +1738,8 @@ int tcp_set_rcvlowat(struct sock *sk, int val)
 }
 EXPORT_SYMBOL(tcp_set_rcvlowat);
 
-static void tcp_update_recv_tstamps(struct sk_buff *skb,
-				    struct scm_timestamping_internal *tss)
+void tcp_update_recv_tstamps(struct sk_buff *skb,
+			     struct scm_timestamping_internal *tss)
 {
 	if (skb->tstamp)
 		tss->ts[0] = ktime_to_timespec64(skb->tstamp);
@@ -2024,8 +2024,6 @@ static int tcp_zerocopy_vm_insert_batch(struct vm_area_struct *vma,
 }
 
 #define TCP_VALID_ZC_MSG_FLAGS   (TCP_CMSG_TS)
-static void tcp_recv_timestamp(struct msghdr *msg, const struct sock *sk,
-			       struct scm_timestamping_internal *tss);
 static void tcp_zc_finalize_rx_tstamp(struct sock *sk,
 				      struct tcp_zerocopy_receive *zc,
 				      struct scm_timestamping_internal *tss)
@@ -2196,8 +2194,8 @@ static int tcp_zerocopy_receive(struct sock *sk,
 #endif
 
 /* Similar to __sock_recv_timestamp, but does not require an skb */
-static void tcp_recv_timestamp(struct msghdr *msg, const struct sock *sk,
-			       struct scm_timestamping_internal *tss)
+void tcp_recv_timestamp(struct msghdr *msg, const struct sock *sk,
+			struct scm_timestamping_internal *tss)
 {
 	int new_tstamp = sock_flag(sk, SOCK_TSTAMP_NEW);
 	bool has_timestamping = false;
-- 
2.26.3


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH mptcp-next 7/8] mptcp: receive path cmsg support
  2021-05-06 10:22 [PATCH mptcp-next 0/8] add cmsg support to receive path Florian Westphal
                   ` (5 preceding siblings ...)
  2021-05-06 10:22 ` [PATCH mptcp-next 6/8] tcp: export timestamp helpers for mptcp Florian Westphal
@ 2021-05-06 10:22 ` Florian Westphal
  2021-05-06 10:22 ` [PATCH mptcp-next 8/8] selftests: mptcp_connect: add SO_TIMESTAMPNS " Florian Westphal
  7 siblings, 0 replies; 12+ messages in thread
From: Florian Westphal @ 2021-05-06 10:22 UTC (permalink / raw)
  To: mptcp; +Cc: Florian Westphal

This adds support for SO_TIMESTAMP(NS).  Timestamps are passed to
userspace in the same way as for plain tcp sockets.

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 net/mptcp/protocol.c | 28 +++++++++++++++++++++++++---
 1 file changed, 25 insertions(+), 3 deletions(-)

diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index e51070883064..93a6d5515ae4 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -40,10 +40,15 @@ struct mptcp_skb_cb {
 	u64 map_seq;
 	u64 end_seq;
 	u32 offset;
+	u8  has_rxtstamp:1;
 };
 
 #define MPTCP_SKB_CB(__skb)	((struct mptcp_skb_cb *)&((__skb)->cb[0]))
 
+enum {
+	MPTCP_CMSG_TS = BIT(0),
+};
+
 static struct percpu_counter mptcp_sockets_allocated;
 
 static void __mptcp_destroy_sock(struct sock *sk);
@@ -273,6 +278,7 @@ static bool __mptcp_move_skb(struct mptcp_sock *msk, struct sock *ssk,
 	struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(ssk);
 	struct sock *sk = (struct sock *)msk;
 	struct sk_buff *tail;
+	bool has_rxtstamp;
 
 	__skb_unlink(skb, &ssk->sk_receive_queue);
 
@@ -288,6 +294,8 @@ static bool __mptcp_move_skb(struct mptcp_sock *msk, struct sock *ssk,
 			goto drop;
 	}
 
+	has_rxtstamp = TCP_SKB_CB(skb)->has_rxtstamp;
+
 	/* the skb map_seq accounts for the skb offset:
 	 * mptcp_subflow_get_mapped_dsn() is based on the current tp->copied_seq
 	 * value
@@ -295,6 +303,7 @@ static bool __mptcp_move_skb(struct mptcp_sock *msk, struct sock *ssk,
 	MPTCP_SKB_CB(skb)->map_seq = mptcp_subflow_get_mapped_dsn(subflow);
 	MPTCP_SKB_CB(skb)->end_seq = MPTCP_SKB_CB(skb)->map_seq + copy_len;
 	MPTCP_SKB_CB(skb)->offset = offset;
+	MPTCP_SKB_CB(skb)->has_rxtstamp = has_rxtstamp;
 
 	if (MPTCP_SKB_CB(skb)->map_seq == msk->ack_seq) {
 		/* in sequence */
@@ -1752,7 +1761,9 @@ static void mptcp_wait_data(struct sock *sk, long *timeo)
 
 static int __mptcp_recvmsg_mskq(struct mptcp_sock *msk,
 				struct msghdr *msg,
-				size_t len, int flags)
+				size_t len, int flags,
+				struct scm_timestamping_internal *tss,
+				int *cmsg_flags)
 {
 	struct sk_buff *skb, *tmp;
 	int copied = 0;
@@ -1772,6 +1783,11 @@ static int __mptcp_recvmsg_mskq(struct mptcp_sock *msk,
 			}
 		}
 
+		if (MPTCP_SKB_CB(skb)->has_rxtstamp) {
+			tcp_update_recv_tstamps(skb, tss);
+			*cmsg_flags |= MPTCP_CMSG_TS;
+		}
+
 		copied += count;
 
 		if (count < data_len) {
@@ -1959,7 +1975,8 @@ static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
 			 int nonblock, int flags, int *addr_len)
 {
 	struct mptcp_sock *msk = mptcp_sk(sk);
-	int copied = 0;
+	struct scm_timestamping_internal tss;
+	int copied = 0, cmsg_flags = 0;
 	int target;
 	long timeo;
 
@@ -1987,7 +2004,7 @@ static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
 	while (copied < len) {
 		int bytes_read;
 
-		bytes_read = __mptcp_recvmsg_mskq(msk, msg, len - copied, flags);
+		bytes_read = __mptcp_recvmsg_mskq(msk, msg, len - copied, flags, &tss, &cmsg_flags);
 		if (unlikely(bytes_read < 0)) {
 			if (!copied)
 				copied = bytes_read;
@@ -2068,6 +2085,11 @@ static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
 		set_bit(MPTCP_DATA_READY, &msk->flags);
 	}
 out_err:
+	if (cmsg_flags && copied >= 0) {
+		if (cmsg_flags & MPTCP_CMSG_TS)
+			tcp_recv_timestamp(msg, sk, &tss);
+	}
+
 	pr_debug("msk=%p data_ready=%d rx queue empty=%d copied=%d",
 		 msk, test_bit(MPTCP_DATA_READY, &msk->flags),
 		 skb_queue_empty_lockless(&sk->sk_receive_queue), copied);
-- 
2.26.3


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH mptcp-next 8/8] selftests: mptcp_connect: add SO_TIMESTAMPNS cmsg support
  2021-05-06 10:22 [PATCH mptcp-next 0/8] add cmsg support to receive path Florian Westphal
                   ` (6 preceding siblings ...)
  2021-05-06 10:22 ` [PATCH mptcp-next 7/8] mptcp: receive path cmsg support Florian Westphal
@ 2021-05-06 10:22 ` Florian Westphal
  7 siblings, 0 replies; 12+ messages in thread
From: Florian Westphal @ 2021-05-06 10:22 UTC (permalink / raw)
  To: mptcp; +Cc: Florian Westphal

This extends the existing setsockopt test case to also check for cmsg
timestamps.

mptcp_connect will abort/fail if the setockopt was passed but the
timestamp cmsg isn't present after successful recvmsg().

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 .../selftests/net/mptcp/mptcp_connect.c       | 125 +++++++++++++++++-
 .../selftests/net/mptcp/mptcp_sockopt.sh      |   4 +-
 2 files changed, 126 insertions(+), 3 deletions(-)

diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect.c b/tools/testing/selftests/net/mptcp/mptcp_connect.c
index d88e1fdfb147..b0457f76968c 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_connect.c
+++ b/tools/testing/selftests/net/mptcp/mptcp_connect.c
@@ -6,6 +6,7 @@
 #include <limits.h>
 #include <fcntl.h>
 #include <string.h>
+#include <stdarg.h>
 #include <stdbool.h>
 #include <stdint.h>
 #include <stdio.h>
@@ -25,6 +26,7 @@
 #include <netinet/in.h>
 
 #include <linux/tcp.h>
+#include <linux/time_types.h>
 
 extern int optind;
 
@@ -66,6 +68,13 @@ static unsigned int cfg_do_w;
 static int cfg_wait;
 static uint32_t cfg_mark;
 
+struct cfg_cmsg_types {
+	unsigned int cmsg_enabled:1;
+	unsigned int timestampns:1;
+};
+
+static struct cfg_cmsg_types cfg_cmsg_types;
+
 static void die_usage(void)
 {
 	fprintf(stderr, "Usage: mptcp_connect [-6] [-u] [-s MPTCP|TCP] [-p port] [-m mode]"
@@ -80,11 +89,22 @@ static void die_usage(void)
 	fprintf(stderr, "\t-M mark -- set socket packet mark\n");
 	fprintf(stderr, "\t-u -- check mptcp ulp\n");
 	fprintf(stderr, "\t-w num -- wait num sec before closing the socket\n");
+	fprintf(stderr, "\t-c cmsg -- test cmsg type <cmsg>\n");
 	fprintf(stderr,
 		"\t-P [saveWithPeek|saveAfterPeek] -- save data with/after MSG_PEEK form tcp socket\n");
 	exit(1);
 }
 
+static void xerror(const char *fmt, ...)
+{
+	va_list ap;
+
+	va_start(ap, fmt);
+	vfprintf(stderr, fmt, ap);
+	va_end(ap);
+	exit(1);
+}
+
 static void handle_signal(int nr)
 {
 	quit = true;
@@ -338,6 +358,58 @@ static size_t do_write(const int fd, char *buf, const size_t len)
 	return offset;
 }
 
+static void process_cmsg(struct msghdr *msgh)
+{
+	struct __kernel_timespec ts;
+	bool ts_found = false;
+	struct cmsghdr *cmsg;
+
+	for (cmsg = CMSG_FIRSTHDR(msgh); cmsg ; cmsg = CMSG_NXTHDR(msgh, cmsg)) {
+		if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_TIMESTAMPNS_NEW) {
+			memcpy(&ts, CMSG_DATA(cmsg), sizeof(ts));
+			ts_found = true;
+			continue;
+		}
+	}
+
+	if (cfg_cmsg_types.timestampns) {
+		if (!ts_found)
+			xerror("TIMESTAMPNS not present\n");
+	}
+}
+
+static ssize_t do_recvmsg_cmsg(const int fd, char *buf, const size_t len)
+{
+	char msg_buf[8192];
+	struct iovec iov = {
+		.iov_base = buf,
+		.iov_len = len,
+	};
+	struct msghdr msg = {
+		.msg_iov = &iov,
+		.msg_iovlen = 1,
+		.msg_control = msg_buf,
+		.msg_controllen = sizeof(msg_buf),
+	};
+	int flags = 0;
+	int ret = recvmsg(fd, &msg, flags);
+
+	if (ret <= 0)
+		return ret;
+
+	if (msg.msg_controllen && !cfg_cmsg_types.cmsg_enabled)
+		xerror("got %lu bytes of cmsg data, expected 0\n",
+			(unsigned long)msg.msg_controllen);
+
+	if (msg.msg_controllen == 0 && cfg_cmsg_types.cmsg_enabled)
+		xerror("%s\n", "got no cmsg data");
+
+	if (msg.msg_controllen)
+		process_cmsg(&msg);
+
+	return ret;
+}
+
 static ssize_t do_rnd_read(const int fd, char *buf, const size_t len)
 {
 	int ret = 0;
@@ -357,6 +429,8 @@ static ssize_t do_rnd_read(const int fd, char *buf, const size_t len)
 	} else if (cfg_peek == CFG_AFTER_PEEK) {
 		ret = recv(fd, buf, cap, MSG_PEEK);
 		ret = (ret < 0) ? ret : read(fd, buf, cap);
+	} else if (cfg_cmsg_types.cmsg_enabled) {
+		ret = do_recvmsg_cmsg(fd, buf, cap);
 	} else {
 		ret = read(fd, buf, cap);
 	}
@@ -786,6 +860,48 @@ static void init_rng(void)
 	srand(foo);
 }
 
+static void xsetsockopt(int fd, int level, int optname, const void *optval, socklen_t optlen)
+{
+	int err;
+
+	err = setsockopt(fd, level, optname, optval, optlen);
+	if (err) {
+		perror("setsockopt");
+		exit(1);
+	}
+}
+
+static void apply_cmsg_types(int fd, const struct cfg_cmsg_types *cmsg)
+{
+	static const unsigned int on = 1;
+
+	if (cmsg->timestampns)
+		xsetsockopt(fd, SOL_SOCKET, SO_TIMESTAMPNS_NEW, &on, sizeof(on));
+}
+
+static void parse_cmsg_types(const char *type)
+{
+	char *next = strchr(type, ',');
+	unsigned int len = 0;
+
+	cfg_cmsg_types.cmsg_enabled = 1;
+
+	if (next) {
+		parse_cmsg_types(next + 1);
+		len = next - type;
+	} else {
+		len = strlen(type);
+	}
+
+	if (strncmp(type, "TIMESTAMPNS", len) == 0) {
+		cfg_cmsg_types.timestampns = 1;
+		return;
+	}
+
+	fprintf(stderr, "Unrecognized cmsg option %s\n", type);
+	exit(1);
+}
+
 int main_loop(void)
 {
 	int fd;
@@ -801,6 +917,8 @@ int main_loop(void)
 		set_rcvbuf(fd, cfg_rcvbuf);
 	if (cfg_sndbuf)
 		set_sndbuf(fd, cfg_sndbuf);
+	if (cfg_cmsg_types.cmsg_enabled)
+		apply_cmsg_types(fd, &cfg_cmsg_types);
 
 	return copyfd_io(0, fd, 1);
 }
@@ -887,7 +1005,7 @@ static void parse_opts(int argc, char **argv)
 {
 	int c;
 
-	while ((c = getopt(argc, argv, "6jr:lp:s:hut:m:S:R:w:M:P:")) != -1) {
+	while ((c = getopt(argc, argv, "6jr:lp:s:hut:m:S:R:w:M:P:c:")) != -1) {
 		switch (c) {
 		case 'j':
 			cfg_join = true;
@@ -943,6 +1061,9 @@ static void parse_opts(int argc, char **argv)
 		case 'P':
 			cfg_peek = parse_peek(optarg);
 			break;
+		case 'c':
+			parse_cmsg_types(optarg);
+			break;
 		}
 	}
 
@@ -976,6 +1097,8 @@ int main(int argc, char *argv[])
 			set_sndbuf(fd, cfg_sndbuf);
 		if (cfg_mark)
 			set_mark(fd, cfg_mark);
+		if (cfg_cmsg_types.cmsg_enabled)
+			apply_cmsg_types(fd, &cfg_cmsg_types);
 
 		return main_loop_s(fd);
 	}
diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
index 2fa13946ac04..1579e471a5e7 100755
--- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.sh
@@ -178,7 +178,7 @@ do_transfer()
 
 	timeout ${timeout_test} \
 		ip netns exec ${listener_ns} \
-			$mptcp_connect -t ${timeout_poll} -l -M 1 -p $port -s ${srv_proto} \
+			$mptcp_connect -t ${timeout_poll} -l -M 1 -p $port -s ${srv_proto} -c TIMESTAMPNS \
 				${local_addr} < "$sin" > "$sout" &
 	spid=$!
 
@@ -186,7 +186,7 @@ do_transfer()
 
 	timeout ${timeout_test} \
 		ip netns exec ${connector_ns} \
-			$mptcp_connect -t ${timeout_poll} -M 2 -p $port -s ${cl_proto} \
+			$mptcp_connect -t ${timeout_poll} -M 2 -p $port -s ${cl_proto} -c TIMESTAMPNS \
 				$connect_addr < "$cin" > "$cout" &
 
 	cpid=$!
-- 
2.26.3


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH mptcp-next 1/8] mptcp: enable busypoll from mptcp receive path
  2021-05-06 10:22 ` [PATCH mptcp-next 1/8] mptcp: enable busypoll from mptcp " Florian Westphal
@ 2021-05-11  0:02   ` Mat Martineau
  0 siblings, 0 replies; 12+ messages in thread
From: Mat Martineau @ 2021-05-11  0:02 UTC (permalink / raw)
  To: Florian Westphal; +Cc: mptcp

On Thu, 6 May 2021, Florian Westphal wrote:

> The setting is only relevant for the msk socket.
> While at it, also handle rcvlowat/rcvtimeo this way.
>
> Signed-off-by: Florian Westphal <fw@strlen.de>
> ---
> net/mptcp/protocol.c | 7 +++++++
> net/mptcp/sockopt.c  | 8 ++++++++
> 2 files changed, 15 insertions(+)
>
> diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
> index aec8e77b18e4..e51070883064 100644
> --- a/net/mptcp/protocol.c
> +++ b/net/mptcp/protocol.c
> @@ -12,6 +12,7 @@
> #include <linux/sched/signal.h>
> #include <linux/atomic.h>
> #include <net/sock.h>
> +#include <net/busy_poll.h>
> #include <net/inet_common.h>
> #include <net/inet_hashtables.h>
> #include <net/protocol.h>
> @@ -1966,6 +1967,12 @@ static int mptcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
> 	if (unlikely(flags & MSG_ERRQUEUE))
> 		return inet_recv_error(sk, msg, len, addr_len);
>
> +	if (sk_can_busy_loop(sk) &&
> +	    skb_queue_empty_lockless(&msk->receive_queue) &&
> +	    skb_queue_empty_lockless(&sk->sk_receive_queue) &&
> +	     inet_sk_state_load(sk) == TCP_ESTABLISHED)

Minor nit-pick - extra indent space on the last line of this conditional. 
I'd just ask Matthieu to fix up when applying but I have one more comment 
on patch 5.


Mat


> +		sk_busy_loop(sk, nonblock);
> +
> 	mptcp_lock_sock(sk, __mptcp_splice_receive_queue(sk));
> 	if (unlikely(sk->sk_state == TCP_LISTEN)) {
> 		copied = -ENOTCONN;
> diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c
> index 00d941b66c1e..c98e4e116992 100644
> --- a/net/mptcp/sockopt.c
> +++ b/net/mptcp/sockopt.c
> @@ -254,6 +254,14 @@ static int mptcp_setsockopt_sol_socket(struct mptcp_sock *msk, int optname,
> 		return mptcp_setsockopt_sol_socket_int(msk, optname, optval, optlen);
> 	case SO_LINGER:
> 		return mptcp_setsockopt_sol_socket_linger(msk, optval, optlen);
> +	case SO_RCVLOWAT:
> +	case SO_RCVTIMEO_OLD:
> +	case SO_RCVTIMEO_NEW:
> +	case SO_BUSY_POLL:
> +	case SO_PREFER_BUSY_POLL:
> +	case SO_BUSY_POLL_BUDGET:
> +		/* No need to copy: only relevant for msk */
> +		break;
> 	case SO_NO_CHECK:
> 	case SO_DONTROUTE:
> 	case SO_BROADCAST:
> -- 
> 2.26.3
>
>
>

--
Mat Martineau
Intel

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH mptcp-next 5/8] mptcp: setsockopt: handle SOL_SOCKET in one place only
  2021-05-06 10:22 ` [PATCH mptcp-next 5/8] mptcp: setsockopt: handle SOL_SOCKET in one place only Florian Westphal
@ 2021-05-11  0:05   ` Mat Martineau
  2021-05-11 13:36     ` Florian Westphal
  0 siblings, 1 reply; 12+ messages in thread
From: Mat Martineau @ 2021-05-11  0:05 UTC (permalink / raw)
  To: Florian Westphal; +Cc: mptcp

On Thu, 6 May 2021, Florian Westphal wrote:

> Move the pre-check to the function that handles all SOL_SOCKET
> values.
>
> At this point there is complete coverage for all values that have
> been accepted previously.
>
> Signed-off-by: Florian Westphal <fw@strlen.de>
> ---
> net/mptcp/sockopt.c | 89 +++++++++++----------------------------------
> 1 file changed, 22 insertions(+), 67 deletions(-)
>
> diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c
> index 7b47204ecb9a..a83c0e4669d7 100644
> --- a/net/mptcp/sockopt.c
> +++ b/net/mptcp/sockopt.c
> @@ -311,7 +311,8 @@ static int mptcp_setsockopt_sol_socket(struct mptcp_sock *msk, int optname,
> 	case SO_PREFER_BUSY_POLL:
> 	case SO_BUSY_POLL_BUDGET:
> 		/* No need to copy: only relevant for msk */
> -		break;
> +		return sock_setsockopt(sk->sk_socket, SOL_SOCKET, optname, optval, optlen);
> +
> 	case SO_NO_CHECK:
> 	case SO_DONTROUTE:
> 	case SO_BROADCAST:
> @@ -325,7 +326,24 @@ static int mptcp_setsockopt_sol_socket(struct mptcp_sock *msk, int optname,
> 		return 0;
> 	}
>
> -	return sock_setsockopt(sk->sk_socket, SOL_SOCKET, optname, optval, optlen);
> +	/* SO_OOBINLINE is not supported, let's avoid the related mess
> +	 * SO_ATTACH_FILTER, SO_ATTACH_BPF, SO_ATTACH_REUSEPORT_CBPF,
> +	 * SO_DETACH_REUSEPORT_BPF, SO_DETACH_FILTER, SO_LOCK_FILTER,
> +	 * we must be careful with subflows
> +	 *
> +	 * SO_ATTACH_REUSEPORT_EBPF is not supported, at it checks
> +	 * explicitly the sk_protocol field
> +	 *
> +	 * SO_PEEK_OFF is unsupported, as it is for plain TCP
> +	 * SO_MAX_PACING_RATE is unsupported, we must be careful with subflows
> +	 * SO_CNX_ADVICE is currently unsupported, could possibly be relevant,
> +	 * but likely needs careful design
> +	 *
> +	 * SO_ZEROCOPY is currently unsupported, TODO in sndmsg
> +	 * SO_TXTIME is currently unsupported
> +	 */
> +
> +	return -EOPNOTSUPP;
> }
>
> static int mptcp_setsockopt_v6(struct mptcp_sock *msk, int optname,
> @@ -357,72 +375,9 @@ static int mptcp_setsockopt_v6(struct mptcp_sock *msk, int optname,
>
> static bool mptcp_supported_sockopt(int level, int optname)
> {
> -	if (level == SOL_SOCKET) {
> -		switch (optname) {
> -		case SO_DEBUG:
> -		case SO_REUSEPORT:
> -		case SO_REUSEADDR:
> -
> -		/* the following ones need a better implementation,
> -		 * but are quite common we want to preserve them
> -		 */
> -		case SO_BINDTODEVICE:
> -		case SO_SNDBUF:
> -		case SO_SNDBUFFORCE:
> -		case SO_RCVBUF:
> -		case SO_RCVBUFFORCE:
> -		case SO_KEEPALIVE:
> -		case SO_PRIORITY:
> -		case SO_LINGER:
> -		case SO_TIMESTAMP_OLD:
> -		case SO_TIMESTAMP_NEW:
> -		case SO_TIMESTAMPNS_OLD:
> -		case SO_TIMESTAMPNS_NEW:
> -		case SO_TIMESTAMPING_OLD:
> -		case SO_TIMESTAMPING_NEW:
> -		case SO_RCVLOWAT:
> -		case SO_RCVTIMEO_OLD:
> -		case SO_RCVTIMEO_NEW:
> -		case SO_SNDTIMEO_OLD:
> -		case SO_SNDTIMEO_NEW:
> -		case SO_MARK:
> -		case SO_INCOMING_CPU:
> -		case SO_BINDTOIFINDEX:
> -		case SO_BUSY_POLL:
> -		case SO_PREFER_BUSY_POLL:
> -		case SO_BUSY_POLL_BUDGET:
> -
> -		/* next ones are no-op for plain TCP */
> -		case SO_NO_CHECK:
> -		case SO_DONTROUTE:
> -		case SO_BROADCAST:
> -		case SO_BSDCOMPAT:
> -		case SO_PASSCRED:
> -		case SO_PASSSEC:
> -		case SO_RXQ_OVFL:
> -		case SO_WIFI_STATUS:
> -		case SO_NOFCS:
> -		case SO_SELECT_ERR_QUEUE:
> -			return true;
> -		}
> +	if (level == SOL_SOCKET)
> +		return true; /* mptcp_setsockopt_sol_socket handles this */

I suggest not adding these two lines, and moving the call to 
mptcp_supported_sockopt() after the SOL_SOCKET handling at the beginning 
of mptcp_setsockopt(). What do you think?

Mat


>
> -		/* SO_OOBINLINE is not supported, let's avoid the related mess */
> -		/* SO_ATTACH_FILTER, SO_ATTACH_BPF, SO_ATTACH_REUSEPORT_CBPF,
> -		 * SO_DETACH_REUSEPORT_BPF, SO_DETACH_FILTER, SO_LOCK_FILTER,
> -		 * we must be careful with subflows
> -		 */
> -		/* SO_ATTACH_REUSEPORT_EBPF is not supported, at it checks
> -		 * explicitly the sk_protocol field
> -		 */
> -		/* SO_PEEK_OFF is unsupported, as it is for plain TCP */
> -		/* SO_MAX_PACING_RATE is unsupported, we must be careful with subflows */
> -		/* SO_CNX_ADVICE is currently unsupported, could possibly be relevant,
> -		 * but likely needs careful design
> -		 */
> -		/* SO_ZEROCOPY is currently unsupported, TODO in sndmsg */
> -		/* SO_TXTIME is currently unsupported */
> -		return false;
> -	}
> 	if (level == SOL_IP) {
> 		switch (optname) {
> 		/* should work fine */
> -- 
> 2.26.3
>
>
>

--
Mat Martineau
Intel

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH mptcp-next 5/8] mptcp: setsockopt: handle SOL_SOCKET in one place only
  2021-05-11  0:05   ` Mat Martineau
@ 2021-05-11 13:36     ` Florian Westphal
  0 siblings, 0 replies; 12+ messages in thread
From: Florian Westphal @ 2021-05-11 13:36 UTC (permalink / raw)
  To: Mat Martineau; +Cc: Florian Westphal, mptcp

Mat Martineau <mathew.j.martineau@linux.intel.com> wrote:
> On Thu, 6 May 2021, Florian Westphal wrote:
> > +	if (level == SOL_SOCKET)
> > +		return true; /* mptcp_setsockopt_sol_socket handles this */
> 
> I suggest not adding these two lines, and moving the call to
> mptcp_supported_sockopt() after the SOL_SOCKET handling at the beginning of
> mptcp_setsockopt(). What do you think?

I think thats better.  V2 coming in a second.

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2021-05-11 13:36 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-06 10:22 [PATCH mptcp-next 0/8] add cmsg support to receive path Florian Westphal
2021-05-06 10:22 ` [PATCH mptcp-next 1/8] mptcp: enable busypoll from mptcp " Florian Westphal
2021-05-11  0:02   ` Mat Martineau
2021-05-06 10:22 ` [PATCH mptcp-next 2/8] sock: expose so_timestamp options for mptcp Florian Westphal
2021-05-06 10:22 ` [PATCH mptcp-next 3/8] sock: expose so_timestamping " Florian Westphal
2021-05-06 10:22 ` [PATCH mptcp-next 4/8] mptcp: sockopt: propagate timestamp request to subflows Florian Westphal
2021-05-06 10:22 ` [PATCH mptcp-next 5/8] mptcp: setsockopt: handle SOL_SOCKET in one place only Florian Westphal
2021-05-11  0:05   ` Mat Martineau
2021-05-11 13:36     ` Florian Westphal
2021-05-06 10:22 ` [PATCH mptcp-next 6/8] tcp: export timestamp helpers for mptcp Florian Westphal
2021-05-06 10:22 ` [PATCH mptcp-next 7/8] mptcp: receive path cmsg support Florian Westphal
2021-05-06 10:22 ` [PATCH mptcp-next 8/8] selftests: mptcp_connect: add SO_TIMESTAMPNS " Florian Westphal

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).