mptcp: cleanup SOL_TCP handling
Most TCP-level socket options get an integer from user space, and set the corresponding field under the msk-level socket lock. Reduce the code duplication moving such operations in the common code. Signed-off-by: Paolo Abeni <pabeni@redhat.com> Reviewed-by: Mat Martineau <martineau@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
29b5e5ef87
commit
7f71a337b5
+30
-45
@@ -624,18 +624,11 @@ static int mptcp_setsockopt_sol_tcp_congestion(struct mptcp_sock *msk, sockptr_t
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mptcp_setsockopt_sol_tcp_cork(struct mptcp_sock *msk, sockptr_t optval,
|
static int __mptcp_setsockopt_sol_tcp_cork(struct mptcp_sock *msk, int val)
|
||||||
unsigned int optlen)
|
|
||||||
{
|
{
|
||||||
struct mptcp_subflow_context *subflow;
|
struct mptcp_subflow_context *subflow;
|
||||||
struct sock *sk = (struct sock *)msk;
|
struct sock *sk = (struct sock *)msk;
|
||||||
int val, ret;
|
|
||||||
|
|
||||||
ret = mptcp_get_int_option(msk, optval, optlen, &val);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
lock_sock(sk);
|
|
||||||
sockopt_seq_inc(msk);
|
sockopt_seq_inc(msk);
|
||||||
msk->cork = !!val;
|
msk->cork = !!val;
|
||||||
mptcp_for_each_subflow(msk, subflow) {
|
mptcp_for_each_subflow(msk, subflow) {
|
||||||
@@ -647,23 +640,15 @@ static int mptcp_setsockopt_sol_tcp_cork(struct mptcp_sock *msk, sockptr_t optva
|
|||||||
}
|
}
|
||||||
if (!val)
|
if (!val)
|
||||||
mptcp_check_and_set_pending(sk);
|
mptcp_check_and_set_pending(sk);
|
||||||
release_sock(sk);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mptcp_setsockopt_sol_tcp_nodelay(struct mptcp_sock *msk, sockptr_t optval,
|
static int __mptcp_setsockopt_sol_tcp_nodelay(struct mptcp_sock *msk, int val)
|
||||||
unsigned int optlen)
|
|
||||||
{
|
{
|
||||||
struct mptcp_subflow_context *subflow;
|
struct mptcp_subflow_context *subflow;
|
||||||
struct sock *sk = (struct sock *)msk;
|
struct sock *sk = (struct sock *)msk;
|
||||||
int val, ret;
|
|
||||||
|
|
||||||
ret = mptcp_get_int_option(msk, optval, optlen, &val);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
lock_sock(sk);
|
|
||||||
sockopt_seq_inc(msk);
|
sockopt_seq_inc(msk);
|
||||||
msk->nodelay = !!val;
|
msk->nodelay = !!val;
|
||||||
mptcp_for_each_subflow(msk, subflow) {
|
mptcp_for_each_subflow(msk, subflow) {
|
||||||
@@ -675,8 +660,6 @@ static int mptcp_setsockopt_sol_tcp_nodelay(struct mptcp_sock *msk, sockptr_t op
|
|||||||
}
|
}
|
||||||
if (val)
|
if (val)
|
||||||
mptcp_check_and_set_pending(sk);
|
mptcp_check_and_set_pending(sk);
|
||||||
release_sock(sk);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -799,35 +782,10 @@ static int mptcp_setsockopt_sol_tcp(struct mptcp_sock *msk, int optname,
|
|||||||
int ret, val;
|
int ret, val;
|
||||||
|
|
||||||
switch (optname) {
|
switch (optname) {
|
||||||
case TCP_INQ:
|
|
||||||
ret = mptcp_get_int_option(msk, optval, optlen, &val);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
if (val < 0 || val > 1)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
lock_sock(sk);
|
|
||||||
msk->recvmsg_inq = !!val;
|
|
||||||
release_sock(sk);
|
|
||||||
return 0;
|
|
||||||
case TCP_ULP:
|
case TCP_ULP:
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
case TCP_NOTSENT_LOWAT:
|
|
||||||
ret = mptcp_get_int_option(msk, optval, optlen, &val);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
lock_sock(sk);
|
|
||||||
WRITE_ONCE(msk->notsent_lowat, val);
|
|
||||||
mptcp_write_space(sk);
|
|
||||||
release_sock(sk);
|
|
||||||
return 0;
|
|
||||||
case TCP_CONGESTION:
|
case TCP_CONGESTION:
|
||||||
return mptcp_setsockopt_sol_tcp_congestion(msk, optval, optlen);
|
return mptcp_setsockopt_sol_tcp_congestion(msk, optval, optlen);
|
||||||
case TCP_CORK:
|
|
||||||
return mptcp_setsockopt_sol_tcp_cork(msk, optval, optlen);
|
|
||||||
case TCP_NODELAY:
|
|
||||||
return mptcp_setsockopt_sol_tcp_nodelay(msk, optval, optlen);
|
|
||||||
case TCP_DEFER_ACCEPT:
|
case TCP_DEFER_ACCEPT:
|
||||||
/* See tcp.c: TCP_DEFER_ACCEPT does not fail */
|
/* See tcp.c: TCP_DEFER_ACCEPT does not fail */
|
||||||
mptcp_setsockopt_first_sf_only(msk, SOL_TCP, optname, optval, optlen);
|
mptcp_setsockopt_first_sf_only(msk, SOL_TCP, optname, optval, optlen);
|
||||||
@@ -840,7 +798,34 @@ static int mptcp_setsockopt_sol_tcp(struct mptcp_sock *msk, int optname,
|
|||||||
optval, optlen);
|
optval, optlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
return -EOPNOTSUPP;
|
ret = mptcp_get_int_option(msk, optval, optlen, &val);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
lock_sock(sk);
|
||||||
|
switch (optname) {
|
||||||
|
case TCP_INQ:
|
||||||
|
if (val < 0 || val > 1)
|
||||||
|
ret = -EINVAL;
|
||||||
|
else
|
||||||
|
msk->recvmsg_inq = !!val;
|
||||||
|
break;
|
||||||
|
case TCP_NOTSENT_LOWAT:
|
||||||
|
WRITE_ONCE(msk->notsent_lowat, val);
|
||||||
|
mptcp_write_space(sk);
|
||||||
|
break;
|
||||||
|
case TCP_CORK:
|
||||||
|
ret = __mptcp_setsockopt_sol_tcp_cork(msk, val);
|
||||||
|
break;
|
||||||
|
case TCP_NODELAY:
|
||||||
|
ret = __mptcp_setsockopt_sol_tcp_nodelay(msk, val);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ret = -ENOPROTOOPT;
|
||||||
|
}
|
||||||
|
|
||||||
|
release_sock(sk);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mptcp_setsockopt(struct sock *sk, int level, int optname,
|
int mptcp_setsockopt(struct sock *sk, int level, int optname,
|
||||||
|
|||||||
Reference in New Issue
Block a user