[PATCH mptcp-next 2/6] mptcp: handle SOL_SOCKET options on first subflow only

Geliang Tang posted 6 patches 1 month ago
[PATCH mptcp-next 2/6] mptcp: handle SOL_SOCKET options on first subflow only
Posted by Geliang Tang 1 month ago
From: Geliang Tang <tanggeliang@kylinos.cn>

Refactor SOL_SOCKET option handling using the common handler
mptcp_setsockopt_sol_socket_first_sf_only(). This helper applies socket
options (SO_REUSEPORT, SO_REUSEADDR, SO_BINDTODEVICE, SO_BINDTOIFINDEX)
to the first subflow and synchronizes values back to the MPTCP socket.

Signed-off-by: Geliang Tang <tanggeliang@kylinos.cn>
---
 net/mptcp/sockopt.c | 64 +++++++++++++++++++++++++++++----------------
 1 file changed, 42 insertions(+), 22 deletions(-)

diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c
index 6cc073fab17c..8017cbad0597 100644
--- a/net/mptcp/sockopt.c
+++ b/net/mptcp/sockopt.c
@@ -17,6 +17,10 @@
 #define MIN_INFO_OPTLEN_SIZE		16
 #define MIN_FULL_INFO_OPTLEN_SIZE	40
 
+static int mptcp_setsockopt_first_sf_only(struct mptcp_sock *msk, int level,
+					  int optname, sockptr_t optval,
+					  unsigned int optlen);
+
 static struct sock *__mptcp_tcp_fallback(struct mptcp_sock *msk)
 {
 	msk_owned_by_me(msk);
@@ -287,38 +291,51 @@ static int mptcp_setsockopt_sol_socket_linger(struct mptcp_sock *msk, sockptr_t
 	return 0;
 }
 
-static int mptcp_setsockopt_sol_socket(struct mptcp_sock *msk, int optname,
-				       sockptr_t optval, unsigned int optlen)
+static int mptcp_setsockopt_sol_socket_first_sf_only(struct mptcp_sock *msk, int optname,
+						     sockptr_t optval, unsigned int optlen)
 {
 	struct sock *sk = (struct sock *)msk;
 	struct sock *ssk;
 	int ret;
 
+	if (optname != SO_REUSEPORT && optname != SO_REUSEADDR &&
+	    optname != SO_BINDTODEVICE && optname != SO_BINDTOIFINDEX)
+		return -EOPNOTSUPP;
+
+	lock_sock(sk);
+	ssk = __mptcp_nmpc_sk(msk);
+	if (IS_ERR(ssk)) {
+		release_sock(sk);
+		return PTR_ERR(ssk);
+	}
+
+	ret = sk_setsockopt(ssk, SOL_SOCKET, optname, optval, optlen);
+	if (ret == 0) {
+		if (optname == SO_REUSEPORT)
+			sk->sk_reuseport = ssk->sk_reuseport;
+		else if (optname == SO_REUSEADDR)
+			sk->sk_reuse = ssk->sk_reuse;
+		else if (optname == SO_BINDTODEVICE)
+			sk->sk_bound_dev_if = ssk->sk_bound_dev_if;
+		else if (optname == SO_BINDTOIFINDEX)
+			sk->sk_bound_dev_if = ssk->sk_bound_dev_if;
+	}
+	release_sock(sk);
+	return ret;
+}
+
+static int mptcp_setsockopt_sol_socket(struct mptcp_sock *msk, int optname,
+				       sockptr_t optval, unsigned int optlen)
+{
+	struct sock *sk = (struct sock *)msk;
+
 	switch (optname) {
 	case SO_REUSEPORT:
 	case SO_REUSEADDR:
 	case SO_BINDTODEVICE:
 	case SO_BINDTOIFINDEX:
-		lock_sock(sk);
-		ssk = __mptcp_nmpc_sk(msk);
-		if (IS_ERR(ssk)) {
-			release_sock(sk);
-			return PTR_ERR(ssk);
-		}
-
-		ret = sk_setsockopt(ssk, SOL_SOCKET, optname, optval, optlen);
-		if (ret == 0) {
-			if (optname == SO_REUSEPORT)
-				sk->sk_reuseport = ssk->sk_reuseport;
-			else if (optname == SO_REUSEADDR)
-				sk->sk_reuse = ssk->sk_reuse;
-			else if (optname == SO_BINDTODEVICE)
-				sk->sk_bound_dev_if = ssk->sk_bound_dev_if;
-			else if (optname == SO_BINDTOIFINDEX)
-				sk->sk_bound_dev_if = ssk->sk_bound_dev_if;
-		}
-		release_sock(sk);
-		return ret;
+		return mptcp_setsockopt_first_sf_only(msk, SOL_SOCKET, optname,
+						      optval, optlen);
 	case SO_KEEPALIVE:
 	case SO_PRIORITY:
 	case SO_SNDBUF:
@@ -806,6 +823,9 @@ static int mptcp_setsockopt_first_sf_only(struct mptcp_sock *msk, int level,
 	case SOL_TCP:
 		return mptcp_setsockopt_sol_tcp_first_sf_only(msk, optname,
 							      optval, optlen);
+	case SOL_SOCKET:
+		return mptcp_setsockopt_sol_socket_first_sf_only(msk, optname,
+								 optval, optlen);
 	}
 
 	return -EOPNOTSUPP;
-- 
2.48.1