diff mbox series

[RFC,mptcp-next,v2,5/8] mptcp: setsockopt: add SO_MARK support

Message ID 20210324131546.13730-6-fw@strlen.de
State Superseded, archived
Delegated to: Paolo Abeni
Headers show
Series initial SOL_SOCKET support | expand

Commit Message

Florian Westphal March 24, 2021, 1:15 p.m. UTC
Value is synced to all subflows.

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

Comments

Mat Martineau March 25, 2021, 1:22 a.m. UTC | #1
On Wed, 24 Mar 2021, Florian Westphal wrote:

> Value is synced to all subflows.
>

The use case I remember for SO_MARK with MPTCP was to designate different 
interfaces for different subflows:

https://lore.kernel.org/mptcp/CAKD1Yr2sBCdUO48cp=rZQ6s4v13ytpPd9oPT+U=iYrdXtba5HA@mail.gmail.com/


Once we have a way to set individual subflow options, it could both be 
useful to set sk_mark on all subflows, and also to not override individual 
settings. The current sync mechanism would overwrite all supported options 
when any single option changes.

There's no way for these options to diverge yet, so we could wait on 
solving that problem. Do you think it's better to stick with the current 
syncing method for now, or to do more detailed tracking of which options 
need to be synced?


Mat


> Signed-off-by: Florian Westphal <fw@strlen.de>
> ---
> net/mptcp/sockopt.c | 13 +++++++++++++
> 1 file changed, 13 insertions(+)
>
> diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c
> index f33a9ee12544..cb29013d7d74 100644
> --- a/net/mptcp/sockopt.c
> +++ b/net/mptcp/sockopt.c
> @@ -66,6 +66,12 @@ static void mptcp_sol_socket_sync_intval(struct mptcp_sock *msk, int optname, in
> 			ssk->sk_userlocks |= SOCK_RCVBUF_LOCK;
> 			WRITE_ONCE(ssk->sk_rcvbuf, sk->sk_rcvbuf);
> 			break;
> +		case SO_MARK:
> +			if (READ_ONCE(ssk->sk_mark) != sk->sk_mark) {
> +				ssk->sk_mark = sk->sk_mark;
> +				sk_dst_reset(ssk);
> +			}
> +			break;
> 		}
>
> 		subflow->setsockopt_seq = msk->setsockopt_seq;
> @@ -103,6 +109,7 @@ static int mptcp_setsockopt_sol_socket_int(struct mptcp_sock *msk, int optname,
> 	case SO_KEEPALIVE:
> 		mptcp_sol_socket_sync_intval(msk, optname, val);
> 		return 0;
> +	case SO_MARK:
> 	case SO_PRIORITY:
> 	case SO_SNDBUF:
> 	case SO_SNDBUFFORCE:
> @@ -193,6 +200,7 @@ static int mptcp_setsockopt_sol_socket(struct mptcp_sock *msk, int optname,
> 	case SO_SNDBUFFORCE:
> 	case SO_RCVBUF:
> 	case SO_RCVBUFFORCE:
> +	case SO_MARK:
> 		return mptcp_setsockopt_sol_socket_int(msk, optname, optval, optlen);
> 	case SO_LINGER:
> 		return mptcp_setsockopt_sol_socket_linger(msk, optval, optlen);
> @@ -521,6 +529,11 @@ static void sync_socket_options(struct mptcp_sock *msk, struct sock *ssk)
> 	} else {
> 		sock_reset_flag(ssk, SOCK_LINGER);
> 	}
> +
> +	if (sk->sk_mark != ssk->sk_mark) {
> +		ssk->sk_mark = sk->sk_mark;
> +		sk_dst_reset(ssk);
> +	}
> }
>
> void mptcp_sockopt_sync(struct mptcp_sock *msk, struct sock *ssk)
> -- 
> 2.26.3
>
>
>

--
Mat Martineau
Intel
Florian Westphal March 25, 2021, 9:32 a.m. UTC | #2
Mat Martineau <mathew.j.martineau@linux.intel.com> wrote:
> On Wed, 24 Mar 2021, Florian Westphal wrote:
> 
> > Value is synced to all subflows.
> > 
> 
> The use case I remember for SO_MARK with MPTCP was to designate different
> interfaces for different subflows:
> 
> https://lore.kernel.org/mptcp/CAKD1Yr2sBCdUO48cp=rZQ6s4v13ytpPd9oPT+U=iYrdXtba5HA@mail.gmail.com/
> 
> 
> Once we have a way to set individual subflow options, it could both be
> useful to set sk_mark on all subflows, and also to not override individual
> settings. The current sync mechanism would overwrite all supported options
> when any single option changes.
> 
> There's no way for these options to diverge yet, so we could wait on solving
> that problem. Do you think it's better to stick with the current syncing
> method for now, or to do more detailed tracking of which options need to be
> synced?

Looks like same issue as with TCP_CONGESTION.
Q is how we can expose the individual subflows.

I see
https://tools.ietf.org/html/draft-hesmans-mptcp-socket-03

Should that be implemented instead of this?
Mat Martineau March 26, 2021, 12:14 a.m. UTC | #3
On Thu, 25 Mar 2021, Florian Westphal wrote:

> Mat Martineau <mathew.j.martineau@linux.intel.com> wrote:
>> On Wed, 24 Mar 2021, Florian Westphal wrote:
>>
>>> Value is synced to all subflows.
>>>
>>
>> The use case I remember for SO_MARK with MPTCP was to designate different
>> interfaces for different subflows:
>>
>> https://lore.kernel.org/mptcp/CAKD1Yr2sBCdUO48cp=rZQ6s4v13ytpPd9oPT+U=iYrdXtba5HA@mail.gmail.com/
>>
>>
>> Once we have a way to set individual subflow options, it could both be
>> useful to set sk_mark on all subflows, and also to not override individual
>> settings. The current sync mechanism would overwrite all supported options
>> when any single option changes.
>>
>> There's no way for these options to diverge yet, so we could wait on solving
>> that problem. Do you think it's better to stick with the current syncing
>> method for now, or to do more detailed tracking of which options need to be
>> synced?
>
> Looks like same issue as with TCP_CONGESTION.
> Q is how we can expose the individual subflows.
>
> I see
> https://tools.ietf.org/html/draft-hesmans-mptcp-socket-03
>
> Should that be implemented instead of this?
>

I had a chance to look at the linked draft, and I think where we ended up 
in the discussion earlier today was this:

  * per-subflow options are useful (SO_MASK, etc)

  * overall settings like this patch set does are also helpful, I think 
especially to make MPTCP sockets behave more like TCP sockets.


The two should be compatible, and the concern I'm pointing out is that the 
proposed sync would clobber individual subflow options even if the 
matching MPTCP-level sockopts had never been set. That may be addressible 
by only syncing "new" subflows rather than all of them in the list.

--
Mat Martineau
Intel
diff mbox series

Patch

diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c
index f33a9ee12544..cb29013d7d74 100644
--- a/net/mptcp/sockopt.c
+++ b/net/mptcp/sockopt.c
@@ -66,6 +66,12 @@  static void mptcp_sol_socket_sync_intval(struct mptcp_sock *msk, int optname, in
 			ssk->sk_userlocks |= SOCK_RCVBUF_LOCK;
 			WRITE_ONCE(ssk->sk_rcvbuf, sk->sk_rcvbuf);
 			break;
+		case SO_MARK:
+			if (READ_ONCE(ssk->sk_mark) != sk->sk_mark) {
+				ssk->sk_mark = sk->sk_mark;
+				sk_dst_reset(ssk);
+			}
+			break;
 		}
 
 		subflow->setsockopt_seq = msk->setsockopt_seq;
@@ -103,6 +109,7 @@  static int mptcp_setsockopt_sol_socket_int(struct mptcp_sock *msk, int optname,
 	case SO_KEEPALIVE:
 		mptcp_sol_socket_sync_intval(msk, optname, val);
 		return 0;
+	case SO_MARK:
 	case SO_PRIORITY:
 	case SO_SNDBUF:
 	case SO_SNDBUFFORCE:
@@ -193,6 +200,7 @@  static int mptcp_setsockopt_sol_socket(struct mptcp_sock *msk, int optname,
 	case SO_SNDBUFFORCE:
 	case SO_RCVBUF:
 	case SO_RCVBUFFORCE:
+	case SO_MARK:
 		return mptcp_setsockopt_sol_socket_int(msk, optname, optval, optlen);
 	case SO_LINGER:
 		return mptcp_setsockopt_sol_socket_linger(msk, optval, optlen);
@@ -521,6 +529,11 @@  static void sync_socket_options(struct mptcp_sock *msk, struct sock *ssk)
 	} else {
 		sock_reset_flag(ssk, SOCK_LINGER);
 	}
+
+	if (sk->sk_mark != ssk->sk_mark) {
+		ssk->sk_mark = sk->sk_mark;
+		sk_dst_reset(ssk);
+	}
 }
 
 void mptcp_sockopt_sync(struct mptcp_sock *msk, struct sock *ssk)