The IPV6_TCLASS setsockopt just needs to be forwarded to the individual TCP sockets, like IP_TOS is already handled for IPv4. The code here is pretty much identical, except there's no helper for IPv6 like IPv4's __ip_sock_set_tos(). Coincidentally, ssh uses this sockopt and prints an error in the middle of your ongoing SSH session when it doesn't work (very annoying when doing SCP/SFTP on a multiplexed session.) Signed-off-by: David 'equinox' Lamparter Cc: Matthieu Baerts Cc: Mat Martineau Cc: Geliang Tang --- note: I wasn't entirely sure what tree this should be on top of, with the mptcp trees on github & kernel.org; this is on top of net-next. It shouldn't really matter though. --- net/mptcp/sockopt.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c index fcf6feb2a9eb..edddafebb8de 100644 --- a/net/mptcp/sockopt.c +++ b/net/mptcp/sockopt.c @@ -394,6 +394,35 @@ static int mptcp_setsockopt_sol_socket(struct mptcp_sock *msk, int optname, return -EOPNOTSUPP; } +static int mptcp_setsockopt_v6_set_tclass(struct mptcp_sock *msk, int optname, + sockptr_t optval, unsigned int optlen) +{ + struct mptcp_subflow_context *subflow; + struct sock *sk = (struct sock *)msk; + int err, val; + + err = ipv6_setsockopt(sk, SOL_IPV6, optname, optval, optlen); + + if (err != 0) + return err; + + lock_sock(sk); + sockopt_seq_inc(msk); + val = READ_ONCE(inet6_sk(sk)->tclass); + mptcp_for_each_subflow(msk, subflow) { + struct sock *ssk = mptcp_subflow_tcp_sock(subflow); + bool slow; + + slow = lock_sock_fast(ssk); + inet6_sk(ssk)->tclass = val; + sk_dst_reset(ssk); + unlock_sock_fast(ssk, slow); + } + release_sock(sk); + + return 0; +} + static int mptcp_setsockopt_v6(struct mptcp_sock *msk, int optname, sockptr_t optval, unsigned int optlen) { @@ -436,6 +465,8 @@ static int mptcp_setsockopt_v6(struct mptcp_sock *msk, int optname, release_sock(sk); break; + case IPV6_TCLASS: + return mptcp_setsockopt_v6_set_tclass(msk, optname, optval, optlen); } return ret; @@ -1485,6 +1516,9 @@ static int mptcp_getsockopt_v6(struct mptcp_sock *msk, int optname, struct sock *sk = (void *)msk; switch (optname) { + case IPV6_TCLASS: + return mptcp_put_int_option(msk, optval, optlen, + READ_ONCE(inet6_sk(sk)->tclass)); case IPV6_V6ONLY: return mptcp_put_int_option(msk, optval, optlen, sk->sk_ipv6only); -- 2.53.0