mptcp: Handle MP_CAPABLE options for outgoing connections
Add hooks to tcp_output.c to add MP_CAPABLE to an outgoing SYN request, to capture the MP_CAPABLE in the received SYN-ACK, to add MP_CAPABLE to the final ACK of the three-way handshake. Use the .sk_rx_dst_set() handler in the subflow proto to capture when the responding SYN-ACK is received and notify the MPTCP connection layer. Co-developed-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com> Co-developed-by: Florian Westphal <fw@strlen.de> Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Peter Krystad <peter.krystad@linux.intel.com> Signed-off-by: Christoph Paasch <cpaasch@apple.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
2303f994b3
commit
cec37a6e41
@@ -597,6 +597,22 @@ static void smc_set_option_cond(const struct tcp_sock *tp,
|
||||
#endif
|
||||
}
|
||||
|
||||
static void mptcp_set_option_cond(const struct request_sock *req,
|
||||
struct tcp_out_options *opts,
|
||||
unsigned int *remaining)
|
||||
{
|
||||
if (rsk_is_mptcp(req)) {
|
||||
unsigned int size;
|
||||
|
||||
if (mptcp_synack_options(req, &size, &opts->mptcp)) {
|
||||
if (*remaining >= size) {
|
||||
opts->options |= OPTION_MPTCP;
|
||||
*remaining -= size;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Compute TCP options for SYN packets. This is not the final
|
||||
* network wire format yet.
|
||||
*/
|
||||
@@ -666,6 +682,15 @@ static unsigned int tcp_syn_options(struct sock *sk, struct sk_buff *skb,
|
||||
|
||||
smc_set_option(tp, opts, &remaining);
|
||||
|
||||
if (sk_is_mptcp(sk)) {
|
||||
unsigned int size;
|
||||
|
||||
if (mptcp_syn_options(sk, &size, &opts->mptcp)) {
|
||||
opts->options |= OPTION_MPTCP;
|
||||
remaining -= size;
|
||||
}
|
||||
}
|
||||
|
||||
return MAX_TCP_OPTION_SPACE - remaining;
|
||||
}
|
||||
|
||||
@@ -727,6 +752,8 @@ static unsigned int tcp_synack_options(const struct sock *sk,
|
||||
}
|
||||
}
|
||||
|
||||
mptcp_set_option_cond(req, opts, &remaining);
|
||||
|
||||
smc_set_option_cond(tcp_sk(sk), ireq, opts, &remaining);
|
||||
|
||||
return MAX_TCP_OPTION_SPACE - remaining;
|
||||
@@ -764,6 +791,23 @@ static unsigned int tcp_established_options(struct sock *sk, struct sk_buff *skb
|
||||
size += TCPOLEN_TSTAMP_ALIGNED;
|
||||
}
|
||||
|
||||
/* MPTCP options have precedence over SACK for the limited TCP
|
||||
* option space because a MPTCP connection would be forced to
|
||||
* fall back to regular TCP if a required multipath option is
|
||||
* missing. SACK still gets a chance to use whatever space is
|
||||
* left.
|
||||
*/
|
||||
if (sk_is_mptcp(sk)) {
|
||||
unsigned int remaining = MAX_TCP_OPTION_SPACE - size;
|
||||
unsigned int opt_size = 0;
|
||||
|
||||
if (mptcp_established_options(sk, skb, &opt_size, remaining,
|
||||
&opts->mptcp)) {
|
||||
opts->options |= OPTION_MPTCP;
|
||||
size += opt_size;
|
||||
}
|
||||
}
|
||||
|
||||
eff_sacks = tp->rx_opt.num_sacks + tp->rx_opt.dsack;
|
||||
if (unlikely(eff_sacks)) {
|
||||
const unsigned int remaining = MAX_TCP_OPTION_SPACE - size;
|
||||
|
Reference in New Issue
Block a user