Skip to content

Commit

Permalink
mptcp: sockopt: add SOL_IP freebind & transparent options
Browse files Browse the repository at this point in the history
These options also need to be set before bind, so do the sync of msk to
new ssk socket a bit earlier.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Florian Westphal authored and David S. Miller committed Nov 20, 2021
1 parent ffcacff commit c9406a2
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 2 deletions.
66 changes: 65 additions & 1 deletion net/mptcp/sockopt.c
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,8 @@ static int mptcp_setsockopt_v6(struct mptcp_sock *msk, int optname,

switch (optname) {
case IPV6_V6ONLY:
case IPV6_TRANSPARENT:
case IPV6_FREEBIND:
lock_sock(sk);
ssock = __mptcp_nmpc_socket(msk);
if (!ssock) {
Expand All @@ -398,8 +400,24 @@ static int mptcp_setsockopt_v6(struct mptcp_sock *msk, int optname,
}

ret = tcp_setsockopt(ssock->sk, SOL_IPV6, optname, optval, optlen);
if (ret == 0)
if (ret != 0) {
release_sock(sk);
return ret;
}

sockopt_seq_inc(msk);

switch (optname) {
case IPV6_V6ONLY:
sk->sk_ipv6only = ssock->sk->sk_ipv6only;
break;
case IPV6_TRANSPARENT:
inet_sk(sk)->transparent = inet_sk(ssock->sk)->transparent;
break;
case IPV6_FREEBIND:
inet_sk(sk)->freebind = inet_sk(ssock->sk)->freebind;
break;
}

release_sock(sk);
break;
Expand Down Expand Up @@ -598,6 +616,46 @@ static int mptcp_setsockopt_sol_tcp_congestion(struct mptcp_sock *msk, sockptr_t
return ret;
}

static int mptcp_setsockopt_sol_ip_set_transparent(struct mptcp_sock *msk, int optname,
sockptr_t optval, unsigned int optlen)
{
struct sock *sk = (struct sock *)msk;
struct inet_sock *issk;
struct socket *ssock;
int err;

err = ip_setsockopt(sk, SOL_IP, optname, optval, optlen);
if (err != 0)
return err;

lock_sock(sk);

ssock = __mptcp_nmpc_socket(msk);
if (!ssock) {
release_sock(sk);
return -EINVAL;
}

issk = inet_sk(ssock->sk);

switch (optname) {
case IP_FREEBIND:
issk->freebind = inet_sk(sk)->freebind;
break;
case IP_TRANSPARENT:
issk->transparent = inet_sk(sk)->transparent;
break;
default:
release_sock(sk);
WARN_ON_ONCE(1);
return -EOPNOTSUPP;
}

sockopt_seq_inc(msk);
release_sock(sk);
return 0;
}

static int mptcp_setsockopt_v4_set_tos(struct mptcp_sock *msk, int optname,
sockptr_t optval, unsigned int optlen)
{
Expand Down Expand Up @@ -627,6 +685,9 @@ static int mptcp_setsockopt_v4(struct mptcp_sock *msk, int optname,
sockptr_t optval, unsigned int optlen)
{
switch (optname) {
case IP_FREEBIND:
case IP_TRANSPARENT:
return mptcp_setsockopt_sol_ip_set_transparent(msk, optname, optval, optlen);
case IP_TOS:
return mptcp_setsockopt_v4_set_tos(msk, optname, optval, optlen);
}
Expand Down Expand Up @@ -1068,6 +1129,9 @@ static void sync_socket_options(struct mptcp_sock *msk, struct sock *ssk)

if (inet_csk(sk)->icsk_ca_ops != inet_csk(ssk)->icsk_ca_ops)
tcp_set_congestion_control(ssk, msk->ca_name, false, true);

inet_sk(ssk)->transparent = inet_sk(sk)->transparent;
inet_sk(ssk)->freebind = inet_sk(sk)->freebind;
}

static void __mptcp_sockopt_sync(struct mptcp_sock *msk, struct sock *ssk)
Expand Down
3 changes: 2 additions & 1 deletion net/mptcp/subflow.c
Original file line number Diff line number Diff line change
Expand Up @@ -1425,6 +1425,8 @@ int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc,
if (addr.ss_family == AF_INET6)
addrlen = sizeof(struct sockaddr_in6);
#endif
mptcp_sockopt_sync(msk, ssk);

ssk->sk_bound_dev_if = ifindex;
err = kernel_bind(sf, (struct sockaddr *)&addr, addrlen);
if (err)
Expand All @@ -1441,7 +1443,6 @@ int __mptcp_subflow_connect(struct sock *sk, const struct mptcp_addr_info *loc,
mptcp_info2sockaddr(remote, &addr, ssk->sk_family);

mptcp_add_pending_subflow(msk, subflow);
mptcp_sockopt_sync(msk, ssk);
err = kernel_connect(sf, (struct sockaddr *)&addr, addrlen, O_NONBLOCK);
if (err && err != -EINPROGRESS)
goto failed_unlink;
Expand Down

0 comments on commit c9406a2

Please sign in to comment.