From nobody Mon Jun 8 07:21:46 2026 Received: from mail-wr1-f46.google.com (mail-wr1-f46.google.com [209.85.221.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CBEDB38F623 for ; Sun, 31 May 2026 15:00:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780239605; cv=none; b=G5j4MzvoJ1tlrJfV38FfAOHZTfDkSBmaMFrWf/Whst2TDwJiLvfpbrC4vxfXpn/z3Y24Pq75IAwMy9u3RtAgx+4w4pyLzkaHQXmsDdqdFDdKqjDXtFxxNsXQ7xnmS9/QYq0LeYirbbtFidFWf5B3+2uX5tQocrt+Ehm62BIuJIs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780239605; c=relaxed/simple; bh=HDrK1qDMbcBPHnB/F5xX4si1f7gfI6iTgCS94VY6xjc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=kulms3kals5nehGPiQcdEtUZxxVdn/Qb/hPC9Mf5YuSoxLfdhBWI/Jv4PfpAoL3jruX4IO7RDnGqk6EGzbbY8xGr8IxZbQCBu3bQCtAQVLKQiGY3VgEpqsRX8aZUIGwqIFOt/EAQYCoESgh0yOI7Me4ti7aBNE5qv1IAGDdtobg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=qF3UDWp/; arc=none smtp.client-ip=209.85.221.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="qF3UDWp/" Received: by mail-wr1-f46.google.com with SMTP id ffacd0b85a97d-45efa80e0afso735951f8f.2 for ; Sun, 31 May 2026 08:00:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1780239600; x=1780844400; darn=lists.linux.dev; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=O0WMAu7ksHy8NjaFaPp0ygI7JxHIIKVNl9Xb2HItZvE=; b=qF3UDWp/vewDX87pKKP5dJRdxw2HQXruahGF1M127ejyOCHGXd2zYbnOxjvHNt1i4P sWjYyDxkVfI0Az3BI6f6mbIibY0K71RIW1IE/5KDslE9bllt5wwjoRA4qgBwVoDOw4nb DONSCP4aEdQAdFY5hfjN+tJRY9Bk0y3tWf3rarYf44pEhzsLcSqX6qtAoXw+mHqwMy/R 9zpp4zHiDNVd7DQAYBXgysmXmfbP30VuNvouLU+uYHJvH/PhAZ12P9c8KiA39Ck6NXNc dX1fsnyTKn5NDoYnnwYQWA9iuplkvDwHZcFGby/G7bVJ7Gw2zAfAmkcc/ER5URAOv7UC COcw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780239600; x=1780844400; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=O0WMAu7ksHy8NjaFaPp0ygI7JxHIIKVNl9Xb2HItZvE=; b=Gc1mhATSsqfvnQaKCbuov383MOjcfzpMQPE5FmXwdGxeSoFMA+Q5jKN2pUOohpOYiP LgBwQgY7a8vXzGa2d0MD/ifVx8ub25FOHR46tFFKumC9NMop6FFZoTSsPhBxVoG0dY3o iUXLUBsuwYXR1+rJ1b/RnTvYAZahamPhL0IbgnXeEwkokMfzadjt4qXpmX5S9SJIhsr0 Sv72wmJ1WbhtUguxNyTLmwHQ69Mxs8nXjbbgfOhw8NsXWELnSpeKsdNc2BNbssj4/Kwg 59Fpzm2/R1UI5IA02neQX9WGzDtqkadbuLwRYrlv3dcNWEvqCwVWO0pwxE9hwu/3Vw8g 8F3w== X-Gm-Message-State: AOJu0Ywv3zk7GAdMQph4psrF0yD4SgnEs5IPrezzrEQzZeLsASZvGUfV nTMDMp02kx7mZRVXnUh8vpljr5NUtGwXOTIzh1MG9IIH/Cv2mDtlrd9HPXuuDA== X-Gm-Gg: Acq92OEg69pNIFNXOZJ6bPEat2Gz3majcMVs1VDaF2+poocUrLVFEXsBAXueC+U1O7D ZurAmdntpoVlenoI31XICQaAo8E4fsBBGigimuLtMgIWLtgpgWHAS2ajKEX/IF2WhnqQPoc/yH4 vcbs3J9FowObnFtNgbfWs8rbuutNFl+jyrb2xiEbHPS990npLcVJ1SWAfeSStx65LnK+ppzTRbA Wq3baHrawZSkDPymk0eYBju+dQf/5Lg3IqNhZJN5RMX2kIRfzHkTEmuOjQfczpbHHqMLG8OmaIo OO4Qy2IVe7NUliSc0NEV9yiiH4SC1f6yXxsB41TiCPxtnBve+A4mjnw1sUSBsH+XZ2bcP3jSUY7 U1RKViJWQ+qBkGbDopiYblEWOPcJpWOZO40ylRc6SwExk/0RKu2g5LeA/vFHac2Ziu2p1tC5Ze/ EtosBdap3LCaP2+UyQyPjdReBK7JGrfgxH3dFbm0LgUTcOS0WGCIFXwbYUEbU38N3/ukBO4H1sR 2aGEkVAMBEiW/VbY1afCg== X-Received: by 2002:adf:f2cf:0:b0:43b:5097:6f62 with SMTP id ffacd0b85a97d-45ef6b99e1amr10028763f8f.36.1780239599870; Sun, 31 May 2026 07:59:59 -0700 (PDT) Received: from dohko.chello.ie (188-141-5-72.dynamic.upc.ie. [188.141.5.72]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-45ef3587072sm19133545f8f.34.2026.05.31.07.59.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 31 May 2026 07:59:59 -0700 (PDT) From: David Carlier To: mptcp@lists.linux.dev Cc: matttbe@kernel.org, martineau@kernel.org, geliang@kernel.org, pabeni@redhat.com, David Carlier Subject: [PATCH mptcp-next v11 1/4] mptcp: sockopt: factor inet_flags propagation into a mask Date: Sun, 31 May 2026 15:59:50 +0100 Message-ID: <20260531145955.322337-2-devnexen@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260531145955.322337-1-devnexen@gmail.com> References: <20260531145955.322337-1-devnexen@gmail.com> Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Introduce MPTCP_INET_FLAGS_MASK and replace the per-flag inet_assign_bit() calls in sync_socket_options() with a loop driven by the mask that calls assign_bit() per set bit, preserving the per-bit atomicity of the original. Further flags propagated by MPTCP can be added by extending the mask rather than touching the call site. No functional change. Suggested-by: Paolo Abeni Signed-off-by: David Carlier --- net/mptcp/sockopt.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c index fcf6feb2a9eb..7be9a46cbdbe 100644 --- a/net/mptcp/sockopt.c +++ b/net/mptcp/sockopt.c @@ -16,6 +16,10 @@ =20 #define MIN_INFO_OPTLEN_SIZE 16 #define MIN_FULL_INFO_OPTLEN_SIZE 40 +#define MPTCP_INET_FLAGS_MASK \ + (BIT(INET_FLAGS_TRANSPARENT) | \ + BIT(INET_FLAGS_FREEBIND) | \ + BIT(INET_FLAGS_BIND_ADDRESS_NO_PORT)) =20 static struct sock *__mptcp_tcp_fallback(struct mptcp_sock *msk) { @@ -1551,6 +1555,9 @@ static void sync_socket_options(struct mptcp_sock *ms= k, struct sock *ssk) { static const unsigned int tx_rx_locks =3D SOCK_RCVBUF_LOCK | SOCK_SNDBUF_= LOCK; struct sock *sk =3D (struct sock *)msk; + unsigned long mask =3D MPTCP_INET_FLAGS_MASK; + unsigned long src; + int b; bool keep_open; =20 keep_open =3D sock_flag(sk, SOCK_KEEPOPEN); @@ -1597,9 +1604,11 @@ static void sync_socket_options(struct mptcp_sock *m= sk, struct sock *ssk) tcp_sock_set_keepcnt(ssk, msk->keepalive_cnt); tcp_sock_set_maxseg(ssk, msk->maxseg); =20 - inet_assign_bit(TRANSPARENT, ssk, inet_test_bit(TRANSPARENT, sk)); - inet_assign_bit(FREEBIND, ssk, inet_test_bit(FREEBIND, sk)); - inet_assign_bit(BIND_ADDRESS_NO_PORT, ssk, inet_test_bit(BIND_ADDRESS_NO_= PORT, sk)); + src =3D READ_ONCE(inet_sk(sk)->inet_flags); + + for_each_set_bit(b, &mask, BITS_PER_LONG) + assign_bit(b, &inet_sk(ssk)->inet_flags, src & BIT(b)); + WRITE_ONCE(inet_sk(ssk)->local_port_range, READ_ONCE(inet_sk(sk)->local_p= ort_range)); } =20 --=20 2.53.0 From nobody Mon Jun 8 07:21:46 2026 Received: from mail-wr1-f54.google.com (mail-wr1-f54.google.com [209.85.221.54]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DE84038F653 for ; Sun, 31 May 2026 15:00:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780239606; cv=none; b=H79h+mnrrD7bdckAWQUr3rlnqRCmNxMAp7yNE6XIkkxUDPuXomyRgRvAt+5CR1mwFg/87M3HUwwrgwORxv3lD2j/VHLwf6107cexHGkmLJERLuDzdlG2BSMjRR9SRbWUgeEsUaFkg90VVqhHpWnDTlJd6n2Jk3XmAQqOTvQaUOk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780239606; c=relaxed/simple; bh=Sm1aRJcx9WN39lT7jimSfvsGSCRCbwufyUnFWQtkyJU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=nDdxXEzP90bcUVhEGpBOnfQ8ras3tnsl/lMb7fzvhvE6ts9FkH/AahUg0LunJQCHeY1FPK0AFl7vRB8pWLZvKZVy4lqflobm00Zkp84ICthjm9/dPa/dlGBngFphi+7PLkWymR9iSAvVxqjZwtAxFnN2wyKrJS86UWE0VcXeuqE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=oI+jWl93; arc=none smtp.client-ip=209.85.221.54 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="oI+jWl93" Received: by mail-wr1-f54.google.com with SMTP id ffacd0b85a97d-45ef56d9b67so1338528f8f.2 for ; Sun, 31 May 2026 08:00:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1780239601; x=1780844401; darn=lists.linux.dev; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Y2bQNClhWj4BQV5TCxgPeXRdDDcMegD7PhEQZl5kbOY=; b=oI+jWl93sSLP8oD2TMyTKkg439Mq8rd+taqiljozjjFz9a9FskdJEQGngD9WNTS4Sc m3LwPapdDiMCpLhTKFkUooJec51yGb8GTtQAmrJ2M0LiS14s/EjlhAisHiJT7intXVuM yIPlu103fmt8X9xAiTWTxYIw0RY4oTvXMXWvA6OmsgN1QpL02BPBJiO0UwDwAiVVOmxI 7q58ilTWq6FtGSF6LwiWuEJg43TMIWwHbhkBeKhXb0vbPl+qNafoemOBplgaIBoio/v7 oGzYQN88X9m3QHOXg7y5EfraFfvkyha5yEqy48iP9s1Wx+0/amqnHaHj0RaOTu2Vm4Wm xpqQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780239601; x=1780844401; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=Y2bQNClhWj4BQV5TCxgPeXRdDDcMegD7PhEQZl5kbOY=; b=ZWYMG34I6JxFNk5ZF0KfvMDM4FGuYhxmFvmphHTyoDXr+W6rW7be6wMAQbUyMualtW rXQ//XSnMv93wrZupy+K9wkt/7Y4pRpSlwjJFJq8GF3aCJuoQ/1w1TirnxAnGyxmufa9 eMNa6zWSZdIR1UUJ49shhZx3gQe9SiVSSMyFxlWd7ZvWel1bVVjZ0797CQqI5dGlHQZ2 aG1aESbE266zhJX4C0Hs6GLWKpeE1fa1E4rRZm2VJWdVO3zPXLKggukHwP634USKGlnF 0b1+93uM/I+QXsd7O4Tmlj5sjVsreRpTekDJzyg2j9ROv8w65WEbuQZJu0FvGy0AGqsT 5YxA== X-Gm-Message-State: AOJu0YwmrrzmQ7NOfVGVfIEf8KeRLqLOf5WTCMFOC/vu6hUaClekjRTT TXAwT63QKIJUyqA4byZ3u8QgZ7RESZP7AkmYNuCYfIYyi4jw2NxH0hlqP2KBjA== X-Gm-Gg: Acq92OGaTXH2CISRL/Sa+3XKlg+mIyrL62tk4vhbnW0T9Fir346MF3P58SJIHDPdDjH nGv4AcI7420nuRTbCzV37iYryFDgJfdptWkDB0EWGsiuQ90mDJ7zXZ8i/Bv29F+dFW90RTVAqQh OIhdwVK1ajTN/JESMBN/Rx+UT0wJ2zrgnvDev//l9bbcCt6lbiJDlCmywJOtHn7eJSx5JwRs4si 3Bo1i8H7RoODxjzz1I5bTmaCpif+xuP6nt8q2WOQsWJhfnWk3KY7H71oaDkp5oGUnBV75oIknIV 0CtQ+1FGV3m42Mxe5dAt9q47ucAxXBay+y5wsIQaFeaYIoWYhJbm/BuzlgTFucbHjbcUqCkV/Fi ozGXEa2kbvotiYHvdJInYP2GZUWH9TniQ4ArhhYH3yj+ng/K5nfzH+xwW99gIwAKHKChMXwhNtE RyGqAxs3o1GbbVMLwW+AwL/uJ1Mowz3jUsNwBh39c8RK2lgI+dkRii5e/PEq2/mHsvh1XMsB5JL d/Dqjobb2+ad/l7kf58fg== X-Received: by 2002:adf:f611:0:b0:45e:e44b:312b with SMTP id ffacd0b85a97d-45ef6b55d5bmr9607699f8f.18.1780239601050; Sun, 31 May 2026 08:00:01 -0700 (PDT) Received: from dohko.chello.ie (188-141-5-72.dynamic.upc.ie. [188.141.5.72]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-45ef3587072sm19133545f8f.34.2026.05.31.08.00.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 31 May 2026 08:00:00 -0700 (PDT) From: David Carlier To: mptcp@lists.linux.dev Cc: matttbe@kernel.org, martineau@kernel.org, geliang@kernel.org, pabeni@redhat.com, David Carlier Subject: [PATCH mptcp-next v11 2/4] mptcp: propagate RECVERR sockopts to subflows Date: Sun, 31 May 2026 15:59:51 +0100 Message-ID: <20260531145955.322337-3-devnexen@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260531145955.322337-1-devnexen@gmail.com> References: <20260531145955.322337-1-devnexen@gmail.com> Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Propagate IP_RECVERR/IP_RECVERR_RFC4884 and IPV6_RECVERR/IPV6_RECVERR_RFC4884 from the MPTCP socket to existing and future subflows. mptcp_setsockopt_recverr() snapshots optval into a local int, applies it to the parent socket via ip_setsockopt() / ipv6_setsockopt(), bumps msk->setsockopt_seq, and forwards to every subflow via mptcp_setsockopt_all_sf(). Newly-joining subflows pick up the four RECVERR bits through sync_socket_options() now that MPTCP_INET_FLAGS_MASK covers them. mptcp_setsockopt_all_sf() skips IPv4 subflows when called with SOL_IPV6: ipv6_setsockopt() on a sock with sk_family !=3D AF_INET6 returns an error, which would abort the loop and leave the remaining subflows desynchronised. This branch was unreachable before this patch (the only caller was TCP_MAXSEG, family-agnostic); it becomes live with the new IPV6_RECVERR / IPV6_RECVERR_RFC4884 caller and the v4-subflow-on-AF_INET6-msk case (v4 MP_JOIN, or userspace PM grafting a v4 subflow onto a v6 msk). Suggested-by: Paolo Abeni Assisted-by: Codex:gpt-5 Signed-off-by: David Carlier --- net/mptcp/sockopt.c | 140 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 117 insertions(+), 23 deletions(-) diff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c index 7be9a46cbdbe..a2a980304660 100644 --- a/net/mptcp/sockopt.c +++ b/net/mptcp/sockopt.c @@ -8,6 +8,7 @@ =20 #include #include +#include #include #include #include @@ -19,7 +20,11 @@ #define MPTCP_INET_FLAGS_MASK \ (BIT(INET_FLAGS_TRANSPARENT) | \ BIT(INET_FLAGS_FREEBIND) | \ - BIT(INET_FLAGS_BIND_ADDRESS_NO_PORT)) + BIT(INET_FLAGS_BIND_ADDRESS_NO_PORT) | \ + BIT(INET_FLAGS_RECVERR) | \ + BIT(INET_FLAGS_RECVERR_RFC4884) | \ + BIT(INET_FLAGS_RECVERR6) | \ + BIT(INET_FLAGS_RECVERR6_RFC4884)) =20 static struct sock *__mptcp_tcp_fallback(struct mptcp_sock *msk) { @@ -398,6 +403,86 @@ static int mptcp_setsockopt_sol_socket(struct mptcp_so= ck *msk, int optname, return -EOPNOTSUPP; } =20 +static int mptcp_setsockopt_all_sf(struct mptcp_sock *msk, int level, + int optname, sockptr_t optval, + unsigned int optlen) +{ + struct mptcp_subflow_context *subflow; + int ret =3D 0; + + mptcp_for_each_subflow(msk, subflow) { + struct sock *ssk =3D mptcp_subflow_tcp_sock(subflow); + int err; + + /* SOL_IPV6 options on a v4 subflow (v4 MP_JOIN, or userspace PM + * grafting a v4 subflow onto an AF_INET6 msk) would otherwise + * abort the loop with -EAFNOSUPPORT from ipv6_setsockopt(). + */ + if (level =3D=3D SOL_IPV6 && ssk->sk_family !=3D AF_INET6) + continue; + + err =3D tcp_setsockopt(ssk, level, optname, optval, optlen); + if (err < 0 && ret =3D=3D 0) + ret =3D err; + } + + if (!ret) + sockopt_seq_inc(msk); + + return ret; +} + +static int mptcp_setsockopt_recverr(struct mptcp_sock *msk, int level, + int optname, sockptr_t optval, + unsigned int optlen) +{ + struct sock *sk =3D (struct sock *)msk; + int val =3D 0, ret; + + /* Let ip_setsockopt() / ipv6_setsockopt() validate optval and optlen + * (so 1-byte boolean writes keep the same ABI as plain TCP) and update + * the parent's RECVERR bit. Re-read that bit under lock_sock() and + * push it to the subflows: concurrent setsockopt callers cannot leave + * parent and subflows desynchronized this way. + */ + if (level =3D=3D SOL_IP) + ret =3D ip_setsockopt(sk, level, optname, optval, optlen); +#if IS_ENABLED(CONFIG_IPV6) + else if (level =3D=3D SOL_IPV6) { + if (sk->sk_family !=3D AF_INET6) + return -ENOPROTOOPT; + ret =3D ipv6_setsockopt(sk, level, optname, optval, optlen); + } +#endif + else + return -EOPNOTSUPP; + if (ret) + return ret; + + lock_sock(sk); + switch (optname) { + case IP_RECVERR: + val =3D inet_test_bit(RECVERR, sk); + break; + case IP_RECVERR_RFC4884: + val =3D inet_test_bit(RECVERR_RFC4884, sk); + break; +#if IS_ENABLED(CONFIG_IPV6) + case IPV6_RECVERR: + val =3D inet6_test_bit(RECVERR6, sk); + break; + case IPV6_RECVERR_RFC4884: + val =3D inet6_test_bit(RECVERR6_RFC4884, sk); + break; +#endif + } + + ret =3D mptcp_setsockopt_all_sf(msk, level, optname, + KERNEL_SOCKPTR(&val), sizeof(val)); + release_sock(sk); + return ret; +} + static int mptcp_setsockopt_v6(struct mptcp_sock *msk, int optname, sockptr_t optval, unsigned int optlen) { @@ -440,6 +525,10 @@ static int mptcp_setsockopt_v6(struct mptcp_sock *msk,= int optname, =20 release_sock(sk); break; + case IPV6_RECVERR: + case IPV6_RECVERR_RFC4884: + ret =3D mptcp_setsockopt_recverr(msk, SOL_IPV6, optname, optval, optlen); + break; } =20 return ret; @@ -785,6 +874,9 @@ static int mptcp_setsockopt_v4(struct mptcp_sock *msk, = int optname, return mptcp_setsockopt_sol_ip_set(msk, optname, optval, optlen); case IP_TOS: return mptcp_setsockopt_v4_set_tos(msk, optname, optval, optlen); + case IP_RECVERR: + case IP_RECVERR_RFC4884: + return mptcp_setsockopt_recverr(msk, SOL_IP, optname, optval, optlen); } =20 return -EOPNOTSUPP; @@ -812,28 +904,6 @@ static int mptcp_setsockopt_first_sf_only(struct mptcp= _sock *msk, int level, int return ret; } =20 -static int mptcp_setsockopt_all_sf(struct mptcp_sock *msk, int level, - int optname, sockptr_t optval, - unsigned int optlen) -{ - struct mptcp_subflow_context *subflow; - int ret =3D 0; - - mptcp_for_each_subflow(msk, subflow) { - struct sock *ssk =3D mptcp_subflow_tcp_sock(subflow); - int err; - - err =3D tcp_setsockopt(ssk, level, optname, optval, optlen); - if (err < 0 && ret =3D=3D 0) - ret =3D err; - } - - if (!ret) - sockopt_seq_inc(msk); - - return ret; -} - static int mptcp_setsockopt_sol_tcp(struct mptcp_sock *msk, int optname, sockptr_t optval, unsigned int optlen) { @@ -1478,6 +1548,12 @@ static int mptcp_getsockopt_v4(struct mptcp_sock *ms= k, int optname, case IP_LOCAL_PORT_RANGE: return mptcp_put_int_option(msk, optval, optlen, READ_ONCE(inet_sk(sk)->local_port_range)); + case IP_RECVERR: + return mptcp_put_int_option(msk, optval, optlen, + inet_test_bit(RECVERR, sk)); + case IP_RECVERR_RFC4884: + return mptcp_put_int_option(msk, optval, optlen, + inet_test_bit(RECVERR_RFC4884, sk)); } =20 return -EOPNOTSUPP; @@ -1498,6 +1574,16 @@ static int mptcp_getsockopt_v6(struct mptcp_sock *ms= k, int optname, case IPV6_FREEBIND: return mptcp_put_int_option(msk, optval, optlen, inet_test_bit(FREEBIND, sk)); + case IPV6_RECVERR: + if (sk->sk_family !=3D AF_INET6) + return -ENOPROTOOPT; + return mptcp_put_int_option(msk, optval, optlen, + inet6_test_bit(RECVERR6, sk)); + case IPV6_RECVERR_RFC4884: + if (sk->sk_family !=3D AF_INET6) + return -ENOPROTOOPT; + return mptcp_put_int_option(msk, optval, optlen, + inet6_test_bit(RECVERR6_RFC4884, sk)); } =20 return -EOPNOTSUPP; @@ -1606,6 +1692,14 @@ static void sync_socket_options(struct mptcp_sock *m= sk, struct sock *ssk) =20 src =3D READ_ONCE(inet_sk(sk)->inet_flags); =20 + /* RECVERR6 bits are only read on AF_INET6 sockets; copying them onto a + * v4 subflow is dead state and diverges from the SOL_IPV6 skip in + * mptcp_setsockopt_all_sf(). + */ + if (ssk->sk_family !=3D AF_INET6) + mask &=3D ~(BIT(INET_FLAGS_RECVERR6) | + BIT(INET_FLAGS_RECVERR6_RFC4884)); + for_each_set_bit(b, &mask, BITS_PER_LONG) assign_bit(b, &inet_sk(ssk)->inet_flags, src & BIT(b)); =20 --=20 2.53.0 From nobody Mon Jun 8 07:21:46 2026 Received: from mail-wr1-f48.google.com (mail-wr1-f48.google.com [209.85.221.48]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 437E038F651 for ; Sun, 31 May 2026 15:00:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780239607; cv=none; b=e8LKBbkfLd5klpd1Urz0t3kRJvlAO+Xgargy0b/x4XjOTFknQMx4xD8I0fhaqlomR6L/k7ftEF5apxyr6x5zfBBAs8FlKRCTYhtWp5wZ4AlZcxy2vD4EUC2tgH5tbkhWElX3kzFovNouJFbZmrcIVHae84PdVWuC8mvzCmUrJxA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780239607; c=relaxed/simple; bh=wFdKLtZamkQHV6GIN0O3mMCrNWO46pV7+i+eGCV6yLA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Cq7BhHtkUS6sri3qo5pA6xeKRSveqWCo6fI0r8KhUMpgHloBzqaHiL7hB6+yv7FMrj6BXCjLME8QvfNowgfNSkfoEbBUw/p8tmsc7k4W7xRoTTUMfMBfbr8yEB2gJecsTChYwW8g5RvnWAbfdgvRIR9BAal0OEcSHixST6bI980= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=KcoaAOFP; arc=none smtp.client-ip=209.85.221.48 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="KcoaAOFP" Received: by mail-wr1-f48.google.com with SMTP id ffacd0b85a97d-45ef29c5561so1089699f8f.0 for ; Sun, 31 May 2026 08:00:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1780239602; x=1780844402; darn=lists.linux.dev; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=qJnjeINp9vZ1pv2Fi0ORekBEc6b4xUxFfCkGr6FTptA=; b=KcoaAOFPAEgOOLITUkAUuBdJHGrvgGoAqcr5O8Zu5vLI3fNmFIiO3b+xKiMAbIObpr 1JKt4WbSPPcc21IMIT4ILTNztz5gM1FJL+LsSsh3vf8Sa24ccId46TFZwCEhTLWpWblp CkdogdaEPi/fTy3ByQ37V6raIC87/S5z3jwHZ0wsKUbKtmYir479bB8VQF11CCjb0Lnh gZWOCIBkdllXaSss32qi/6eHtlXx+BMIJXEHiLwi0+D0Q8HxwpF6h3ibABucw/5wFEdG m945ogG1ewA8QMp6MjPeg0c0YpYQJBYyKmIRCt/mWcXdcl27VWvJkXDilucdiu1OuIVJ DsFA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780239602; x=1780844402; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=qJnjeINp9vZ1pv2Fi0ORekBEc6b4xUxFfCkGr6FTptA=; b=I4bq3ByTo1+BgbJeN7t+IBUGGOhjMqTbiR9p7yj6F7xWAIHuvBayOKR5Nlzna+H4s4 GnrcTdpesm+GpLJVFkO7yFDkUz39Tmijyetj+hQnUWeWP2S9duc2HDnY5ICkD1kh1sTe bU1PzgSeoxBsAWicdhurfvdFZOzgiHrVWu9C7xnphFX6/cx533Av9PVr6aDdJlHK2b3X hF1YVJQraRY+JDRyv+raejJRGpdI00auYF6AcBe1iW9VIT80/5FA/kevuibQ+ZBtbRS/ Jr18dyiwpUvRX1euGg7NPCOVcd/UZUI1j4ocYw9KGrYsp2eWE/UEwGBZFllRA461jPNV nlPw== X-Gm-Message-State: AOJu0YwHav2gJEnlG7m0sfRcuM++iXaOsTPz0wVqJEAHJT8hudaaJFQf CwzzFAI2f7bJi7mUnsGJ32hjxSMeBB42seu11EdnN10yrBeKSRcpwoI3mLkaZg== X-Gm-Gg: Acq92OH60N11EAkYj9hJySbXh5LCs7T2TANuL5pfBAq0p3tV6xYXU1Cgr1A/y6I9OgM 1jPpg/SSYrWQSqEm3EPSI2zyPoHFMKNdsm88gArSGLFhbZqaVpdWWatf/Uci+sTX/a+bz1NARav OWjXBw63Rse3H5n9WhNzLJcTPlFtlBcYv7LuHQGS1GtemteJ8Kv8XWHP7OxYA3joVdtMYAnt0gN cXoZObZtYartToqC/qO+kt6wYFtifW4b8kNUQMJ2EiIidsPt04GzugTxerryAgKpCClJucsAOZ4 PLShhSmLRI2awc/+zWvjuq1heKjycnDpD4lkRJXREJUW3DUBJaJQpdzGaYFttKOTYC5uH+tQ+q2 NqMulmjXnv4FCdpAHiDmCJLgRi6lsxJR+q9ibc0S+QkAlTB8vndOVDzR350Znh/9B+F8LFUiBzR 8n2jy2F1dt7/hUN7MDuv+IonvU3CSYrxuhHbXTPMo+aVF3cOVjAaNQwe8iSdS/0W4OluNWIxgDj //MMZkxK+T5hbFJx0oqIw== X-Received: by 2002:a05:6000:2892:b0:45e:f68d:e791 with SMTP id ffacd0b85a97d-45ef6a946a9mr13999005f8f.0.1780239602168; Sun, 31 May 2026 08:00:02 -0700 (PDT) Received: from dohko.chello.ie (188-141-5-72.dynamic.upc.ie. [188.141.5.72]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-45ef3587072sm19133545f8f.34.2026.05.31.08.00.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 31 May 2026 08:00:01 -0700 (PDT) From: David Carlier To: mptcp@lists.linux.dev Cc: matttbe@kernel.org, martineau@kernel.org, geliang@kernel.org, pabeni@redhat.com, David Carlier Subject: [PATCH mptcp-next v11 3/4] mptcp: support MSG_ERRQUEUE on the parent socket Date: Sun, 31 May 2026 15:59:52 +0100 Message-ID: <20260531145955.322337-4-devnexen@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260531145955.322337-1-devnexen@gmail.com> References: <20260531145955.322337-1-devnexen@gmail.com> Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Splice pending err skbs from each subflow's error queue onto the parent msk's error queue at error-report time, so poll() and recvmsg(MSG_ERRQUEUE) on the parent socket observe TX timestamps and MSG_ZEROCOPY completion notifications through the standard inet ABI. The splice filters by SO_EE_ORIGIN: TIMESTAMPING / ZEROCOPY / LOCAL events forward to the parent because they are tied to user-handed data, not to a specific path; subflow-level ICMP errors are dropped because the legacy RECVERR ABI cannot meaningfully convey their per-subflow peer identity to single-path-aware userspace. Such events will be carried by a future MPTCP_RECERR channel. Forwarded events all go through sock_queue_err_skb(), which re-homes skb->sk onto the parent and charges sk_rmem_alloc, so the parent's error queue stays bounded by sk_rcvbuf and is dropped under rmem pressure (sk_rmem_alloc + truesize >=3D sk_rcvbuf), matching tcp's sk_rcvbuf-gated tx-timestamp path and ip_icmp_error() / ipv6_icmp_error(). MPTCP itself never originates MSG_ZEROCOPY or OPT_ID tx-timestamp completions -- its data path copies into msk-owned pages and bypasses tcp_sendmsg_locked() -- so no subflow-relative ee_data sequence is ever forwarded to the parent. The MSG_ERRQUEUE branch of mptcp_recvmsg() forwards to inet_recv_error() directly, and poll() advertises EPOLLERR purely on the parent's sk_err / sk_error_queue, matching tcp_poll(). Suggested-by: Paolo Abeni Signed-off-by: David Carlier --- net/mptcp/protocol.c | 63 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 54 insertions(+), 9 deletions(-) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index f1d74d4b28cf..42a355311c81 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -894,21 +895,61 @@ static bool __mptcp_ofo_queue(struct mptcp_sock *msk) return moved; } =20 +static bool mptcp_errqueue_skb_forwardable(const struct sk_buff *skb) +{ + u8 origin =3D SKB_EXT_ERR(skb)->ee.ee_origin; + + return origin =3D=3D SO_EE_ORIGIN_TIMESTAMPING || + origin =3D=3D SO_EE_ORIGIN_ZEROCOPY || + origin =3D=3D SO_EE_ORIGIN_LOCAL; +} + +static bool __mptcp_subflow_splice_errqueue(struct sock *sk, struct sock *= ssk) +{ + struct sk_buff *skb; + bool moved =3D false; + + while ((skb =3D skb_dequeue(&ssk->sk_error_queue))) { + if (!mptcp_errqueue_skb_forwardable(skb)) { + kfree_skb(skb); /* path-specific (ICMP) =E2=80=94 belongs in MPTCP_REC= ERR */ + continue; + } + /* sock_queue_err_skb() re-homes skb->sk onto the parent and + * charges its sk_rmem_alloc, so the error queue stays bounded by + * sk_rcvbuf; drop on overflow, matching tcp's tx-timestamp path. + * MPTCP never originates MSG_ZEROCOPY or OPT_ID tx-timestamp + * completions (the data path copies and bypasses + * tcp_sendmsg_locked()), so no subflow-relative ee_data sequence + * is ever forwarded. + */ + if (sock_queue_err_skb(sk, skb)) { + kfree_skb(skb); + continue; + } + moved =3D true; + } + + return moved; +} + static bool __mptcp_subflow_error_report(struct sock *sk, struct sock *ssk) { + bool propagated =3D false; int ssk_state; + bool report; int err; =20 + report =3D __mptcp_subflow_splice_errqueue(sk, ssk); + /* only propagate errors on fallen-back sockets or * on MPC connect */ if (sk->sk_state !=3D TCP_SYN_SENT && !__mptcp_check_fallback(mptcp_sk(sk= ))) - return false; + goto out; =20 err =3D sock_error(ssk); if (!err) - return false; - + goto out; /* We need to propagate only transition to CLOSE state. * Orphaned socket will see such state change via * subflow_sched_work_if_closed() and that path will properly @@ -918,11 +959,15 @@ static bool __mptcp_subflow_error_report(struct sock = *sk, struct sock *ssk) if (ssk_state =3D=3D TCP_CLOSE && !sock_flag(sk, SOCK_DEAD)) mptcp_set_state(sk, ssk_state); WRITE_ONCE(sk->sk_err, -err); + report =3D propagated =3D true; =20 - /* This barrier is coupled with smp_rmb() in mptcp_poll() */ - smp_wmb(); - sk_error_report(sk); - return true; +out: + if (report) { + /* This barrier is coupled with smp_rmb() in mptcp_poll() */ + smp_wmb(); + sk_error_report(sk); + } + return propagated; } =20 void __mptcp_error_report(struct sock *sk) @@ -2363,7 +2408,6 @@ static int mptcp_recvmsg(struct sock *sk, struct msgh= dr *msg, size_t len, int target; long timeo; =20 - /* MSG_ERRQUEUE is really a no-op till we support IP_RECVERR */ if (unlikely(flags & MSG_ERRQUEUE)) return inet_recv_error(sk, msg, len); =20 @@ -4413,7 +4457,8 @@ static __poll_t mptcp_poll(struct file *file, struct = socket *sock, =20 /* This barrier is coupled with smp_wmb() in __mptcp_error_report() */ smp_rmb(); - if (READ_ONCE(sk->sk_err)) + if (READ_ONCE(sk->sk_err) || + !skb_queue_empty_lockless(&sk->sk_error_queue)) mask |=3D EPOLLERR; =20 return mask; --=20 2.53.0 From nobody Mon Jun 8 07:21:46 2026 Received: from mail-wr1-f53.google.com (mail-wr1-f53.google.com [209.85.221.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 80CB8390219 for ; Sun, 31 May 2026 15:00:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780239608; cv=none; b=ZMFOcORYuiTh9X9AqJHeuecxKzAFUzrirQw1xrUkjEj40ddeC2tkHRiv3EwQ8lzoXXA5OpqIeDl9oMHdvELdP2DvzMuSD29ETl6qtDo07xPeAcRLtYNu6Ybx9i42MxQd9Xj21FkiZLo6hviMuDgpJ2KsFiDPaRxYih79ey1Nmhc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780239608; c=relaxed/simple; bh=QcNVzrHJDmzDhVBtHzMTu8HUGMD/QTYlMSpRK5EIoOU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Yc7Q7bhqXi1neI34fxk+rBMUE6rFCXMbEmcqL5YBhWDjT1NwqbJ0tpMhUQb6u5C8DR4k/MHnypmsf0ABrHT1F0t7sG0uDAdiIxUDGJ/HdVWr9uB+sz+338vpKFKENhZscWDiK4hJEU8M9o48MT7M8z/i1kas4PvuOO4UFvEPFiU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=kpgYchbZ; arc=none smtp.client-ip=209.85.221.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="kpgYchbZ" Received: by mail-wr1-f53.google.com with SMTP id ffacd0b85a97d-45f3cf907ceso392585f8f.2 for ; Sun, 31 May 2026 08:00:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1780239604; x=1780844404; darn=lists.linux.dev; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=+lXcg061bbhFrI0v23H2NQAB6iGsZBPcokYpsEnhLcE=; b=kpgYchbZGLnb+9cHLzGLQQwMNCJ6ka4LbbSnYvfVXCc4wGpEorFJOVCHPZ3HSt/R7U rTEq4/fmNRjzhRXw3rXPup9iE67EE6FlQC3ZH0/YctKvQ/uThIN7tMx/Plp7rftS9Mwh E4kNVvtFDMXxv3MziuR0wLbwOtLxGIWo3Qi8GXBayVfFey15XddT1In1UPUcHAMLVhrV BAeor0byFkLI+baymIXLQ4fR4O6GvEasIsXw27VXhxLbph/7fi1i6WjPwStlpGvHNtzP Tpn3W58EQ4znz3s9oHHzwnZzOOLN4/EBdefn/SssOT3oQLSytg86MGub8taxAZw2AbRn sDpg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780239604; x=1780844404; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=+lXcg061bbhFrI0v23H2NQAB6iGsZBPcokYpsEnhLcE=; b=PovbyQRAGaOEuNkktlUJAEK9//6zWACVhVrT+kdi06RdLPDzhGHVNheS1SRRQdhcIe U+XTxTKhm6MKFvfk8Z+3lYdyi9tObkeXP6Yd+IinnOCgnhLA4Gs56KzAcQl0IDrSc7oQ xauRZ87IIpCApjTMNrjS45V/p7kfdk0tVl3DmdRk66yHQ6fuAO0Kst/fyKRsLX5uBYt/ lwsYKJyFuDpIvuF9o8kdSre6r6fDgmVRTULxMHb5ilKfDtShj1CvzNEebM8H/qZT2MTx H2n1UXSVJdV/SV5sky9pvo18HnjiiLXl//CmZRLPfI1q+hFEq+MGcL9dZmT7gGfrT8qb oiuA== X-Gm-Message-State: AOJu0YwyvrdMm2Ovv4DOE1kT/gA3x5Mdl8LLB8AcvEA0e8V68io35lMm ZoyjaVzZ4f6UaVHMTydQlnnZj8d88bOiVoEkrQEA/B9VD5hxWsCj+qDmx+sAEw== X-Gm-Gg: Acq92OFWT8G274d7OSBLN8DUUG8ru9qdeGwHeAIRMjW/3Cggf31kt5eZcryLS3RZ7o4 DQhV+hK1LjDeiUwy/zZKXA9zbsTmUicuAer22UbmYWexTKGRfP5vKwZTf3KFLPLQnhTPCdGdSpd r6e6hRd6wnpMijuP1L53K7q19UJpm7I8dd7AcFYaapU6biwYLaTAlhcPyLNrj2tQjGEmn3eZ7pz E8gsU/xoj8yhmA8qcDvTK2v6035iH7MGZfnp65a0ul5tbq7kBUH/dlhJFN/oJvGRPTDGSdk02oH RgUSX9H9gxETR5epCxgiMB+XUOrw72Aa5qSAI5svM3qeR9Wd0gJ3oxIcfLU/2cxUf2z7GDs/9dL C6Qi8UuliL3n7vEZuBXTf48O5dypALaJiQWxDHyAXYZ3/RjtLFBlTb+RjUD9NfOtZ/kUfwgmoFi mFGNmZTzsn0TdS/9vs7NyTg77eyTelloDWnx2S+rXN4fi0ipejLfosRVbIyIQsXRuH/CQPfocdp XwmBRfLjCQ2/5GNzMwN8A== X-Received: by 2002:a05:600c:8b6c:b0:48f:e249:4094 with SMTP id 5b1f17b1804b1-490a292fba3mr140199185e9.18.1780239603569; Sun, 31 May 2026 08:00:03 -0700 (PDT) Received: from dohko.chello.ie (188-141-5-72.dynamic.upc.ie. [188.141.5.72]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-45ef3587072sm19133545f8f.34.2026.05.31.08.00.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 31 May 2026 08:00:02 -0700 (PDT) From: David Carlier To: mptcp@lists.linux.dev Cc: matttbe@kernel.org, martineau@kernel.org, geliang@kernel.org, pabeni@redhat.com, David Carlier Subject: [PATCH mptcp-next v11 4/4] selftests: mptcp: cover IP_RECVERR sockopt propagation Date: Sun, 31 May 2026 15:59:53 +0100 Message-ID: <20260531145955.322337-5-devnexen@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260531145955.322337-1-devnexen@gmail.com> References: <20260531145955.322337-1-devnexen@gmail.com> Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Exercise setsockopt/getsockopt of IP_RECVERR and IPV6_RECVERR on the MPTCP parent socket, including the empty-errqueue EAGAIN contract on MSG_ERRQUEUE|MSG_DONTWAIT. End-to-end errqueue delivery (ICMP, TX timestamps, zerocopy) depends on subflow-side producers that are out of scope for this series and will be covered by follow-up work. Assisted-by: Codex:gpt-5 Signed-off-by: David Carlier --- .../selftests/net/mptcp/mptcp_sockopt.c | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c b/tools/test= ing/selftests/net/mptcp/mptcp_sockopt.c index b6e58d936ebe..95bb2cc8e2ff 100644 --- a/tools/testing/selftests/net/mptcp/mptcp_sockopt.c +++ b/tools/testing/selftests/net/mptcp/mptcp_sockopt.c @@ -769,6 +769,60 @@ static void test_ip_tos_sockopt(int fd) xerror("expect socklen_t =3D=3D -1"); } =20 +static void test_ip_recverr_sockopt(int fd) +{ + struct iovec iov =3D { + .iov_base =3D &(char){ 0 }, + .iov_len =3D 1, + }; + struct msghdr msg =3D { + .msg_iov =3D &iov, + .msg_iovlen =3D 1, + }; + int one =3D 1, zero =3D 0, val =3D -1; + socklen_t s =3D sizeof(val); + int level, optname, r; + + switch (pf) { + case AF_INET: + level =3D SOL_IP; + optname =3D IP_RECVERR; + break; + case AF_INET6: + level =3D SOL_IPV6; + optname =3D IPV6_RECVERR; + break; + default: + xerror("Unknown pf %d\n", pf); + } + + r =3D setsockopt(fd, level, optname, &one, sizeof(one)); + if (r) + die_perror("setsockopt recverr on"); + + r =3D getsockopt(fd, level, optname, &val, &s); + if (r) + die_perror("getsockopt recverr on"); + if (s !=3D sizeof(val) || val !=3D one) + xerror("recverr on mismatch val=3D%d len=3D%u", val, s); + + r =3D recvmsg(fd, &msg, MSG_ERRQUEUE | MSG_DONTWAIT); + if (r !=3D -1 || errno !=3D EAGAIN) + xerror("expected empty errqueue to return EAGAIN, ret=3D%d errno=3D%d", = r, errno); + + r =3D setsockopt(fd, level, optname, &zero, sizeof(zero)); + if (r) + die_perror("setsockopt recverr off"); + + val =3D -1; + s =3D sizeof(val); + r =3D getsockopt(fd, level, optname, &val, &s); + if (r) + die_perror("getsockopt recverr off"); + if (s !=3D sizeof(val) || val !=3D zero) + xerror("recverr off mismatch val=3D%d len=3D%u", val, s); +} + static int client(int pipefd) { int fd =3D -1; @@ -787,6 +841,7 @@ static int client(int pipefd) } =20 test_ip_tos_sockopt(fd); + test_ip_recverr_sockopt(fd); =20 connect_one_server(fd, pipefd); =20 --=20 2.53.0