From ffcacff87cd65dc09b97982acf3a771713983a28 Mon Sep 17 00:00:00 2001 From: Poorva Sonparote Date: Fri, 19 Nov 2021 12:41:35 -0800 Subject: [PATCH] mptcp: Support for IP_TOS for MPTCP setsockopt() SOL_IP provides a way to configure network layer attributes in a socket. This patch adds support for IP_TOS for setsockopt(.. ,SOL_IP, ..) Support for SOL_IP is added in mptcp_setsockopt() and IP_TOS is handled in a private function. The idea here is to take in the value passed for IP_TOS and set it to the current subflow, open subflows as well new subflows that might be created after the initial call to setsockopt(). This sync is done using sync_socket_options(.., ssk) and setting the value of tos using __ip_sock_set_tos(ssk,..). The patch has been tested using the packetdrill script here - https://github.com/multipath-tcp/mptcp_net-next/issues/220#issuecomment-947863717 Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/220 Signed-off-by: Poorva Sonparote Signed-off-by: Mat Martineau Signed-off-by: David S. Miller --- net/mptcp/sockopt.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c index 0f1e661c2032..b452571e8d9b 100644 --- a/net/mptcp/sockopt.c +++ b/net/mptcp/sockopt.c @@ -598,6 +598,42 @@ static int mptcp_setsockopt_sol_tcp_congestion(struct mptcp_sock *msk, sockptr_t return ret; } +static int mptcp_setsockopt_v4_set_tos(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 = ip_setsockopt(sk, SOL_IP, optname, optval, optlen); + + if (err != 0) + return err; + + lock_sock(sk); + sockopt_seq_inc(msk); + val = inet_sk(sk)->tos; + mptcp_for_each_subflow(msk, subflow) { + struct sock *ssk = mptcp_subflow_tcp_sock(subflow); + + __ip_sock_set_tos(ssk, val); + } + release_sock(sk); + + return err; +} + +static int mptcp_setsockopt_v4(struct mptcp_sock *msk, int optname, + sockptr_t optval, unsigned int optlen) +{ + switch (optname) { + case IP_TOS: + return mptcp_setsockopt_v4_set_tos(msk, optname, optval, optlen); + } + + return -EOPNOTSUPP; +} + static int mptcp_setsockopt_sol_tcp(struct mptcp_sock *msk, int optname, sockptr_t optval, unsigned int optlen) { @@ -637,6 +673,9 @@ int mptcp_setsockopt(struct sock *sk, int level, int optname, if (ssk) return tcp_setsockopt(ssk, level, optname, optval, optlen); + if (level == SOL_IP) + return mptcp_setsockopt_v4(msk, optname, optval, optlen); + if (level == SOL_IPV6) return mptcp_setsockopt_v6(msk, optname, optval, optlen); @@ -1003,6 +1042,7 @@ static void sync_socket_options(struct mptcp_sock *msk, struct sock *ssk) ssk->sk_priority = sk->sk_priority; ssk->sk_bound_dev_if = sk->sk_bound_dev_if; ssk->sk_incoming_cpu = sk->sk_incoming_cpu; + __ip_sock_set_tos(ssk, inet_sk(sk)->tos); if (sk->sk_userlocks & tx_rx_locks) { ssk->sk_userlocks |= sk->sk_userlocks & tx_rx_locks;