| From ccab044697980c6c01ab51f43f48f13b8a3e5c33 Mon Sep 17 00:00:00 2001 |
| From: Christoph Paasch <cpaasch@openai.com> |
| Date: Fri, 15 Aug 2025 19:28:19 +0200 |
| Subject: mptcp: drop skb if MPTCP skb extension allocation fails |
| |
| From: Christoph Paasch <cpaasch@openai.com> |
| |
| commit ccab044697980c6c01ab51f43f48f13b8a3e5c33 upstream. |
| |
| When skb_ext_add(skb, SKB_EXT_MPTCP) fails in mptcp_incoming_options(), |
| we used to return true, letting the segment proceed through the TCP |
| receive path without a DSS mapping. Such segments can leave inconsistent |
| mapping state and trigger a mid-stream fallback to TCP, which in testing |
| collapsed (by artificially forcing failures in skb_ext_add) throughput |
| to zero. |
| |
| Return false instead so the TCP input path drops the skb (see |
| tcp_data_queue() and step-7 processing). This is the safer choice |
| under memory pressure: it preserves MPTCP correctness and provides |
| backpressure to the sender. |
| |
| Control packets remain unaffected: ACK updates and DATA_FIN handling |
| happen before attempting the extension allocation, and tcp_reset() |
| continues to ignore the return value. |
| |
| With this change, MPTCP continues to work at high throughput if we |
| artificially inject failures into skb_ext_add. |
| |
| Fixes: 6787b7e350d3 ("mptcp: avoid processing packet if a subflow reset") |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Christoph Paasch <cpaasch@openai.com> |
| Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> |
| Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> |
| Link: https://patch.msgid.link/20250815-net-mptcp-misc-fixes-6-17-rc2-v1-1-521fe9957892@kernel.org |
| Signed-off-by: Jakub Kicinski <kuba@kernel.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| net/mptcp/options.c | 6 ++++-- |
| 1 file changed, 4 insertions(+), 2 deletions(-) |
| |
| --- a/net/mptcp/options.c |
| +++ b/net/mptcp/options.c |
| @@ -1100,7 +1100,9 @@ static bool add_addr_hmac_valid(struct m |
| return hmac == mp_opt->ahmac; |
| } |
| |
| -/* Return false if a subflow has been reset, else return true */ |
| +/* Return false in case of error (or subflow has been reset), |
| + * else return true. |
| + */ |
| bool mptcp_incoming_options(struct sock *sk, struct sk_buff *skb) |
| { |
| struct mptcp_subflow_context *subflow = mptcp_subflow_ctx(sk); |
| @@ -1198,7 +1200,7 @@ bool mptcp_incoming_options(struct sock |
| |
| mpext = skb_ext_add(skb, SKB_EXT_MPTCP); |
| if (!mpext) |
| - return true; |
| + return false; |
| |
| memset(mpext, 0, sizeof(*mpext)); |
| |