Commit 9e365ff5 authored by Paolo Abeni's avatar Paolo Abeni Committed by David S. Miller

mptcp: drop MP_JOIN request sock on syn cookies

Currently any MPTCP socket using syn cookies will fallback to
TCP at 3rd ack time. In case of MP_JOIN requests, the RFC mandate
closing the child and sockets, but the existing error paths
do not handle the syncookie scenario correctly.

Address the issue always forcing the child shutdown in case of
MP_JOIN fallback.

Fixes: ae2dd716 ("mptcp: handle tcp fallback when using syn cookies")
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
Reviewed-by: default avatarMat Martineau <mathew.j.martineau@linux.intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 8fd4de12
...@@ -431,22 +431,25 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk, ...@@ -431,22 +431,25 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
struct mptcp_subflow_context *listener = mptcp_subflow_ctx(sk); struct mptcp_subflow_context *listener = mptcp_subflow_ctx(sk);
struct mptcp_subflow_request_sock *subflow_req; struct mptcp_subflow_request_sock *subflow_req;
struct mptcp_options_received mp_opt; struct mptcp_options_received mp_opt;
bool fallback_is_fatal = false; bool fallback, fallback_is_fatal;
struct sock *new_msk = NULL; struct sock *new_msk = NULL;
bool fallback = false;
struct sock *child; struct sock *child;
pr_debug("listener=%p, req=%p, conn=%p", listener, req, listener->conn); pr_debug("listener=%p, req=%p, conn=%p", listener, req, listener->conn);
/* we need later a valid 'mp_capable' value even when options are not /* After child creation we must look for 'mp_capable' even when options
* parsed * are not parsed
*/ */
mp_opt.mp_capable = 0; mp_opt.mp_capable = 0;
if (tcp_rsk(req)->is_mptcp == 0)
/* hopefully temporary handling for MP_JOIN+syncookie */
subflow_req = mptcp_subflow_rsk(req);
fallback_is_fatal = subflow_req->mp_join;
fallback = !tcp_rsk(req)->is_mptcp;
if (fallback)
goto create_child; goto create_child;
/* if the sk is MP_CAPABLE, we try to fetch the client key */ /* if the sk is MP_CAPABLE, we try to fetch the client key */
subflow_req = mptcp_subflow_rsk(req);
if (subflow_req->mp_capable) { if (subflow_req->mp_capable) {
if (TCP_SKB_CB(skb)->seq != subflow_req->ssn_offset + 1) { if (TCP_SKB_CB(skb)->seq != subflow_req->ssn_offset + 1) {
/* here we can receive and accept an in-window, /* here we can receive and accept an in-window,
...@@ -467,12 +470,11 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk, ...@@ -467,12 +470,11 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
if (!new_msk) if (!new_msk)
fallback = true; fallback = true;
} else if (subflow_req->mp_join) { } else if (subflow_req->mp_join) {
fallback_is_fatal = true;
mptcp_get_options(skb, &mp_opt); mptcp_get_options(skb, &mp_opt);
if (!mp_opt.mp_join || if (!mp_opt.mp_join ||
!subflow_hmac_valid(req, &mp_opt)) { !subflow_hmac_valid(req, &mp_opt)) {
SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINACKMAC); SUBFLOW_REQ_INC_STATS(req, MPTCP_MIB_JOINACKMAC);
return NULL; fallback = true;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment