mptcp: handle consistently DSS corruption
commite32d262c89upstream. Bugged peer implementation can send corrupted DSS options, consistently hitting a few warning in the data path. Use DEBUG_NET assertions, to avoid the splat on some builds and handle consistently the error, dumping related MIBs and performing fallback and/or reset according to the subflow type. Fixes:6771bfd9ee("mptcp: update mptcp ack sequence from work queue") Cc: stable@vger.kernel.org Signed-off-by: Paolo Abeni <pabeni@redhat.com> Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20241008-net-mptcp-fallback-fixes-v1-1-c6fb8e93e551@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org> [ Conflicts in mib.[ch], because commit104125b82e("mptcp: add mib for infinite map sending") is linked to a new feature, not available in this version. Resolving the conflicts is easy, simply adding the new lines declaring the new "DSS corruptions" MIB entries. Also removed in protocol.c and subflow.c all DEBUG_NET_WARN_ON_ONCE because they are not defined in this version: enough with the MIB counters that have been added in this commit. ] Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
6654efe264
commit
12c1676d59
@@ -26,6 +26,8 @@ static const struct snmp_mib mptcp_snmp_list[] = {
|
||||
SNMP_MIB_ITEM("MPJoinAckRx", MPTCP_MIB_JOINACKRX),
|
||||
SNMP_MIB_ITEM("MPJoinAckHMacFailure", MPTCP_MIB_JOINACKMAC),
|
||||
SNMP_MIB_ITEM("DSSNotMatching", MPTCP_MIB_DSSNOMATCH),
|
||||
SNMP_MIB_ITEM("DSSCorruptionFallback", MPTCP_MIB_DSSCORRUPTIONFALLBACK),
|
||||
SNMP_MIB_ITEM("DSSCorruptionReset", MPTCP_MIB_DSSCORRUPTIONRESET),
|
||||
SNMP_MIB_ITEM("InfiniteMapRx", MPTCP_MIB_INFINITEMAPRX),
|
||||
SNMP_MIB_ITEM("DSSNoMatchTCP", MPTCP_MIB_DSSTCPMISMATCH),
|
||||
SNMP_MIB_ITEM("DataCsumErr", MPTCP_MIB_DATACSUMERR),
|
||||
|
||||
@@ -19,6 +19,8 @@ enum linux_mptcp_mib_field {
|
||||
MPTCP_MIB_JOINACKRX, /* Received an ACK + MP_JOIN */
|
||||
MPTCP_MIB_JOINACKMAC, /* HMAC was wrong on ACK + MP_JOIN */
|
||||
MPTCP_MIB_DSSNOMATCH, /* Received a new mapping that did not match the previous one */
|
||||
MPTCP_MIB_DSSCORRUPTIONFALLBACK,/* DSS corruption detected, fallback */
|
||||
MPTCP_MIB_DSSCORRUPTIONRESET, /* DSS corruption detected, MPJ subflow reset */
|
||||
MPTCP_MIB_INFINITEMAPRX, /* Received an infinite mapping */
|
||||
MPTCP_MIB_DSSTCPMISMATCH, /* DSS-mapping did not map with TCP's sequence numbers */
|
||||
MPTCP_MIB_DATACSUMERR, /* The data checksum fail */
|
||||
|
||||
+17
-3
@@ -554,6 +554,18 @@ static bool mptcp_check_data_fin(struct sock *sk)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void mptcp_dss_corruption(struct mptcp_sock *msk, struct sock *ssk)
|
||||
{
|
||||
if (READ_ONCE(msk->allow_infinite_fallback)) {
|
||||
MPTCP_INC_STATS(sock_net(ssk),
|
||||
MPTCP_MIB_DSSCORRUPTIONFALLBACK);
|
||||
mptcp_do_fallback(ssk);
|
||||
} else {
|
||||
MPTCP_INC_STATS(sock_net(ssk), MPTCP_MIB_DSSCORRUPTIONRESET);
|
||||
mptcp_subflow_reset(ssk);
|
||||
}
|
||||
}
|
||||
|
||||
static bool __mptcp_move_skbs_from_subflow(struct mptcp_sock *msk,
|
||||
struct sock *ssk,
|
||||
unsigned int *bytes)
|
||||
@@ -626,10 +638,12 @@ static bool __mptcp_move_skbs_from_subflow(struct mptcp_sock *msk,
|
||||
moved += len;
|
||||
seq += len;
|
||||
|
||||
if (WARN_ON_ONCE(map_remaining < len))
|
||||
break;
|
||||
if (unlikely(map_remaining < len))
|
||||
mptcp_dss_corruption(msk, ssk);
|
||||
} else {
|
||||
WARN_ON_ONCE(!fin);
|
||||
if (unlikely(!fin))
|
||||
mptcp_dss_corruption(msk, ssk);
|
||||
|
||||
sk_eat_skb(ssk, skb);
|
||||
done = true;
|
||||
}
|
||||
|
||||
+1
-1
@@ -847,7 +847,7 @@ static bool skb_is_fully_mapped(struct sock *ssk, struct sk_buff *skb)
|
||||
unsigned int skb_consumed;
|
||||
|
||||
skb_consumed = tcp_sk(ssk)->copied_seq - TCP_SKB_CB(skb)->seq;
|
||||
if (WARN_ON_ONCE(skb_consumed >= skb->len))
|
||||
if (unlikely(skb_consumed >= skb->len))
|
||||
return true;
|
||||
|
||||
return skb->len - skb_consumed <= subflow->map_data_len -
|
||||
|
||||
Reference in New Issue
Block a user