Hi Paolo -
On Mon, 2019-11-11 at 17:53 +0100, Paolo Abeni wrote:
since such option will always fit the tcp header, module bugs.
"modulo"
How is it guaranteed that it will always fit, now and in the future?
Peter.
Note that this patch preserve a bool ret value for
mptcp_established_options_dss(),
even if it now always returns true. That will simplify a bit later patches
for v1 support.
Squash-to: "mptcp: Write MPTCP DSS headers to outgoing data packets"
Signed-off-by: Paolo Abeni <pabeni(a)redhat.com>
---
net/mptcp/options.c | 71 ++++++++++++++++++++-------------------------
1 file changed, 31 insertions(+), 40 deletions(-)
diff --git a/net/mptcp/options.c b/net/mptcp/options.c
index fa10086b5b74..cd16baea0666 100644
--- a/net/mptcp/options.c
+++ b/net/mptcp/options.c
@@ -200,7 +200,7 @@ static bool mptcp_established_options_mp(struct sock *sk, unsigned
int *size,
{
struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk);
- if (!subflow->fourth_ack && remaining >= TCPOLEN_MPTCP_MPC_ACK) {
+ if (!subflow->fourth_ack) {
opts->suboptions = OPTION_MPTCP_MPC_ACK;
opts->sndr_key = subflow->local_key;
opts->rcvr_key = subflow->remote_key;
@@ -220,6 +220,7 @@ static bool mptcp_established_options_dss(struct sock *sk, struct
sk_buff *skb,
{
unsigned int dss_size = 0;
struct mptcp_ext *mpext;
+ struct mptcp_sock *msk;
unsigned int ack_size;
mpext = skb ? mptcp_get_ext(skb) : NULL;
@@ -229,15 +230,10 @@ static bool mptcp_established_options_dss(struct sock *sk, struct
sk_buff *skb,
map_size = TCPOLEN_MPTCP_DSS_BASE + TCPOLEN_MPTCP_DSS_MAP64;
- if (map_size <= remaining) {
- remaining -= map_size;
- dss_size = map_size;
- if (mpext)
- opts->ext_copy = *mpext;
- } else {
- opts->ext_copy.use_map = 0;
- WARN_ONCE(1, "MPTCP: Map dropped");
- }
+ remaining -= map_size;
+ dss_size = map_size;
+ if (mpext)
+ opts->ext_copy = *mpext;
}
ack_size = TCPOLEN_MPTCP_DSS_ACK64;
@@ -246,29 +242,19 @@ static bool mptcp_established_options_dss(struct sock *sk, struct
sk_buff *skb,
if (dss_size == 0)
ack_size += TCPOLEN_MPTCP_DSS_BASE;
- if (ack_size <= remaining) {
- struct mptcp_sock *msk;
-
- dss_size += ack_size;
-
- msk = mptcp_sk(mptcp_subflow_ctx(sk)->conn);
- if (msk) {
- opts->ext_copy.data_ack = msk->ack_seq;
- } else {
- mptcp_crypto_key_sha1(mptcp_subflow_ctx(sk)->remote_key,
- NULL, &opts->ext_copy.data_ack);
- opts->ext_copy.data_ack++;
- }
+ dss_size += ack_size;
- opts->ext_copy.ack64 = 1;
- opts->ext_copy.use_ack = 1;
+ msk = mptcp_sk(mptcp_subflow_ctx(sk)->conn);
+ if (msk) {
+ opts->ext_copy.data_ack = msk->ack_seq;
} else {
- opts->ext_copy.use_ack = 0;
- WARN(1, "MPTCP: Ack dropped");
+ mptcp_crypto_key_sha1(mptcp_subflow_ctx(sk)->remote_key,
+ NULL, &opts->ext_copy.data_ack);
+ opts->ext_copy.data_ack++;
}
- if (!dss_size)
- return false;
+ opts->ext_copy.ack64 = 1;
+ opts->ext_copy.use_ack = 1;
*size = ALIGN(dss_size, 4);
return true;
@@ -279,22 +265,27 @@ bool mptcp_established_options(struct sock *sk, struct sk_buff
*skb,
struct mptcp_out_options *opts)
{
unsigned int opt_size = 0;
+ bool ret = true;
if (!mptcp_subflow_ctx(sk)->mp_capable)
return false;
- if (mptcp_established_options_mp(sk, &opt_size, remaining, opts)) {
- *size += opt_size;
- remaining -= opt_size;
- return true;
- } else if (mptcp_established_options_dss(sk, skb, &opt_size, remaining,
- opts)) {
- *size += opt_size;
- remaining -= opt_size;
- return true;
- }
+ if (mptcp_established_options_mp(sk, &opt_size, remaining, opts))
+ ret = true;
+ else if (mptcp_established_options_dss(sk, skb, &opt_size, remaining,
+ opts))
+ ret = true;
- return false;
+ /* we reserved enough space for the above options, and exceeding the
+ * TCP option space would be fatal
+ */
+ if (WARN_ON_ONCE(opt_size > remaining))
+ return false;
+
+ *size += opt_size;
+ remaining -= opt_size;
+
+ return ret;
}
bool mptcp_synack_options(const struct request_sock *req, unsigned int *size,