From patchwork Fri Aug 28 14:50:22 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ralf Lici X-Patchwork-Id: 5297 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:c317:b0:87d:ab56:3700 with SMTP id jk23csp51124mab; Fri, 28 Aug 2026 07:50:59 -0700 (PDT) X-Forwarded-Encrypted: i=2; AHgh+RrrVRVFxZS7Yha679+pcZz7x551DK8YoRzX/KmlLNBjZfNYJyt2Kcf/JFFuRw2sSlx2qWH22zwy8II=@openvpn.net X-Received: by 2002:a05:6830:680f:b0:7f4:c88c:7b10 with SMTP id 46e09a7af769-7f4f24de4efmr8575413a34.12.1787928659236; Fri, 28 Aug 2026 07:50:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1787928659; cv=none; d=google.com; s=arc-20260327; b=WJIv3nSs2CoCMpyVgizBoTFBDg2NF7eKoAbtdYt/7pgFgzV00GUt8ChVZ2SKqG/3GM P7MRtW5kM/f4jX/oW55tG748Z9ksGrVEHF7SijQa2A3BjAQ64vTEVY3DqF3pDXgkgNPm N8gm/OjQAFkytO3tEwrbIPrtD2ukz41il4iLZjcDBfHw16zNhHxM1onulTFPwJpD9Dzi DO0bX5U1pqdiVVw2EnfwlfRKhS5A5PhlK+pOSrFt7PCuZ4J0u89SbN1t+2d9Kg+Xb7dr HNv2K+TGb+4CjfaOUseWTM1d4pJy747Xyni1ZVvAPRFRugsEeXYFuw9dbn9gC3yHZ8Gt XUbw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; h=errors-to:content-transfer-encoding:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence:subject :mime-version:references:in-reply-to:message-id:date:to:from :dkim-signature:dkim-signature:dkim-signature:dkim-signature; bh=BpStNCLB/icquu9vAztURt9kx1UAANcphcF4V2xD0b4=; fh=4NbAC/LsuMLI0S0hprUlLSLCiHwg6SCAifhH718Jh0Q=; b=CxSq5Xzp/JDHpPN+bbFTyL+4RtAdAKGCoOJb1H4tdu8HLCujvnbmIOdznUwSMonBuP tjiN+15BpSIrqwQ788p1vJ6glAWDg7fPwXSKhPpTaK0A41CQf28J97Azda9Cer+6UzYv wUYShqpe3tRwWpSLl18pKJmRdl0x18pfD7uDN93msdP3S51MaWVyJd5bFRnvnACWkz3K hJC4EV84SV0TVLRLeo8hCjDMnot20pYTzQ4iby584TGCNwz8+hU2JzE/zAd8mZ3C7bye vY8sFetv3PIOCWhrurp0JuKDhIl6jn6m5eMgcdpayEoYu9moLsVYcMirExZUc97ZQUIF 1iDw==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=OaTJ5bGS; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=Q52bIxvx; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=DfSdMQEh; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b="d/hrcb7f"; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net Received: from lists.sourceforge.net (lists.sourceforge.net. [216.105.38.7]) by mx.google.com with ESMTPS id 46e09a7af769-7f4fa7c9a9asi2808481a34.26.2026.08.28.07.50.57 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 28 Aug 2026 07:50:58 -0700 (PDT) Received-SPF: pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) client-ip=216.105.38.7; Authentication-Results: mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=OaTJ5bGS; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=Q52bIxvx; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=DfSdMQEh; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b="d/hrcb7f"; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.sourceforge.net; s=beta; h=Content-Transfer-Encoding:Content-Type: List-Subscribe:List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id: Subject:MIME-Version:References:In-Reply-To:Message-ID:Date:To:From:Sender: Reply-To:Cc:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=BpStNCLB/icquu9vAztURt9kx1UAANcphcF4V2xD0b4=; b=OaTJ5bGSAdypXqfPhKlkffB+iU 6150ZleDt+2CxsdGjQmT6/fP+eA1XLXg7Ec/moq32zcRcuTE8Ls92ljPOBeb9T8xotXUhzkvDBxY7 5g8SMN+qwGi3hjB0aVNeSTQWOYWBWNyY5wHLN6KKonUNpxu2rVnMsKC9sGMDAS6v+J5M=; Received: from [127.0.0.1] (helo=sfs-ml-4.v29.lw.sourceforge.com) by sfs-ml-4.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1wzxuw-0003lB-Fn; Fri, 28 Aug 2026 14:50:54 +0000 Received: from [172.30.29.66] (helo=mx.sourceforge.net) by sfs-ml-4.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1wzxuu-0003l4-N4 for openvpn-devel@lists.sourceforge.net; Fri, 28 Aug 2026 14:50:52 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=Qm2WApMEB3Msc9WYkr9RkT7HPiUkRIZqD8uAotX4ZkY=; b=Q52bIxvxLRn+GlPGmbV84zQtDx 87oky0AJiH+Qs9WpN/xobQJBuGhA/ZKBxkXzaUJDQucDATW7Ec3TYq5PhvoF6RUeUHeZPbP7ID6OF Uk8koQF8IFrIYzrO0+L4yVe7Cy95YRztk065SnkxTUuNJVpAeBOZwBQD+ACmu9bH9pYk=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID: Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=Qm2WApMEB3Msc9WYkr9RkT7HPiUkRIZqD8uAotX4ZkY=; b=DfSdMQEhIj7riUTG+nJdzoTQca KxqDBUd6EUd4SS5qgE3GH2TDVHqQX3tQasXHGWU/EivAF0FijPqBaAj/O0GU3/HmRchFUGeQGNgf+ zREORtzq7HX52HzthkmNy/qBslBZORjozyK1uLPaUuGDT+7WH9eMboIo+IwIkITH/8qk=; Received: from mout-b-110.mailbox.org ([195.10.208.55]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1wzxuq-0005qV-AU for openvpn-devel@lists.sourceforge.net; Fri, 28 Aug 2026 14:50:52 +0000 Received: from smtp102.mailbox.org (smtp102.mailbox.org [10.196.197.102]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-b-110.mailbox.org (Postfix) with ESMTPS id 4hWhC35fcxzNlf3 for ; Fri, 28 Aug 2026 16:50:39 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandelbit.com; s=MBO0001; t=1787928639; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Qm2WApMEB3Msc9WYkr9RkT7HPiUkRIZqD8uAotX4ZkY=; b=d/hrcb7f9wFxV8g0RxyefADHIRw4TfGzb+fsHAEy3w6CkdzI3TCLexeTdYj08cwsRQF7xh 8Fgz5JULPRBUlrE9DjTRx1ikngn4BHRr9uvSTJdqr78hbgkYDuFK3JrhWVoCE/CjlmxpTu JSvRX0ESOCpGsdrs1c68sdWuMqDj505SrQeySLCOz1jUXfMJfMtCq38lBfhH5Jjid5dHEf z7l58ixzDQPfCee6XwfoYB3LzjSx3PRWaKB9yjoRS7UpfnKXiVrZ8amD7rCGXz3DK8i6Hp OnNqhyFDfQoxHLC17nWsiBAPFd2hJSd57vo4yB9gyE1V92WiM6knHUI/aWrclA== From: Ralf Lici To: openvpn-devel@lists.sourceforge.net Date: Fri, 28 Aug 2026 16:50:22 +0200 Message-ID: <87624efbd20845abc23ebde353e82d5a90e0325c.1787925761.git.ralf@mandelbit.com> In-Reply-To: References: MIME-Version: 1.0 X-Spam-Score: -0.2 (/) X-Spam-Report: Spam detection software, running on the system "sfi-spamd-1.hosts.colo.sdot.me", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: ovpn accepts OVPN_A_PEER_REMOTE_IPV6_SCOPE_ID and reports bind->remote.in6.sin6_scope_id in peer dumps, but the netlink endpoint parser never copied the attribute into the sockaddr_in6 used to create [...] Content analysis details: (-0.2 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid X-Headers-End: 1wzxuq-0005qV-AU Subject: [Openvpn-devel] [PATCH ovpn net v3 1/6] ovpn: preserve IPv6 scope id for netlink peer endpoints X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox X-GMAIL-THRID: 1874779080549191326 X-GMAIL-MSGID: 1874779080549191326 ovpn accepts OVPN_A_PEER_REMOTE_IPV6_SCOPE_ID and reports bind->remote.in6.sin6_scope_id in peer dumps, but the netlink endpoint parser never copied the attribute into the sockaddr_in6 used to create or update the peer bind. As a result, an IPv6 link-local remote endpoint configured through netlink loses its interface scope, unlike on the peer float path where ipv6_iface_scope_id populates the field. The UDPv6 output path then builds a flow with flowi6_oif set to zero and route lookup can fail or select the wrong interface. Copy the scope id when parsing non-v4-mapped IPv6 remote endpoints. The existing precheck already rejects the scope-id attribute for IPv4 and v4-mapped IPv6 remotes. Fixes: 1d36a36f6d53 ("ovpn: implement peer add/get/dump/delete via netlink") Signed-off-by: Ralf Lici --- No changes since v2 https://lore.kernel.org/openvpn-devel/87f7c1a6eea0005a067889e9b6f73fc6bd4f40e1.1785308184.git.ralf@mandelbit.com/ No changes since v1 https://lore.kernel.org/openvpn-devel/87f7c1a6eea0005a067889e9b6f73fc6bd4f40e1.1785253480.git.ralf@mandelbit.com/ drivers/net/ovpn/netlink.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/ovpn/netlink.c b/drivers/net/ovpn/netlink.c index 4dad85294198..2ba762082acc 100644 --- a/drivers/net/ovpn/netlink.c +++ b/drivers/net/ovpn/netlink.c @@ -100,6 +100,8 @@ static bool ovpn_nl_attr_sockaddr_remote(struct nlattr **attrs, struct sockaddr_in6 *sin6; struct sockaddr_in *sin; struct in6_addr *in6; + struct nlattr *scope; + u32 scope_id = 0; __be16 port = 0; __be32 *in; @@ -114,6 +116,9 @@ static bool ovpn_nl_attr_sockaddr_remote(struct nlattr **attrs, } else if (attrs[OVPN_A_PEER_REMOTE_IPV6]) { ss->ss_family = AF_INET6; in6 = nla_data(attrs[OVPN_A_PEER_REMOTE_IPV6]); + scope = attrs[OVPN_A_PEER_REMOTE_IPV6_SCOPE_ID]; + if (scope) + scope_id = nla_get_u32(scope); } else { return false; } @@ -126,6 +131,7 @@ static bool ovpn_nl_attr_sockaddr_remote(struct nlattr **attrs, if (!ipv6_addr_v4mapped(in6)) { sin6 = (struct sockaddr_in6 *)ss; sin6->sin6_port = port; + sin6->sin6_scope_id = scope_id; memcpy(&sin6->sin6_addr, in6, sizeof(*in6)); break; } From patchwork Fri Aug 28 14:50:23 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ralf Lici X-Patchwork-Id: 5296 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:c317:b0:87d:ab56:3700 with SMTP id jk23csp51120mab; Fri, 28 Aug 2026 07:50:59 -0700 (PDT) X-Forwarded-Encrypted: i=2; AHgh+RoHNlHH4Of23DJB8d04+crrFQPnV5xSECsp2r8BZY1Vu+9sP1LiAuTb/BzMK2PiWlnj/gTgtgGk5FU=@openvpn.net X-Received: by 2002:a05:6820:4cc8:b0:6b1:42ab:d040 with SMTP id 006d021491bc7-6b1c6744b43mr5863924eaf.28.1787928659117; Fri, 28 Aug 2026 07:50:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1787928659; cv=none; d=google.com; s=arc-20260327; b=bfY1PhlvKjGi/hHIVh1vxchj00bsCBUGxWMa17hWvDlzjcg1Ye2yz2Hrw7iKVAP6LM bE23BHqmeJGRqcAAtlYvPo7kTtNHBSAG8yKGMHAXgloNRcpaMF/Lx+b+WbZVa03qly6q icjCao4umgeGvSF1uZm1hmINb0BRETCQ7aQccDE+nNsan6IqDkMy0673KYPAWSyyYLwV LgT6x1XQ/icWak3+ylrBhJu3N+lQEbxJUhjTAAS8lXdaYTBSp9Cf6kAOmCVZZuJu/gNs sZwmYuke5C2DnVdyBVtSuStmFM1lnUzqhrWf7yLG8VpJxsSDTUJMTekUbJ4FIiIgIAP8 WfAQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; h=errors-to:content-transfer-encoding:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence:subject :mime-version:references:in-reply-to:message-id:date:to:from :dkim-signature:dkim-signature:dkim-signature:dkim-signature; bh=qYzwudV+NzBLNRJEmob+rXxGadxGGgQK8RELb0n1irM=; fh=4NbAC/LsuMLI0S0hprUlLSLCiHwg6SCAifhH718Jh0Q=; b=mnUwwwZHhXBFt1z4xjDaSax6BQdaSP3oKS8CYjd408hf1c9T5jkguWx0QkVNQnHgaM OvVJuV+fB2Z6FJlU0B93sDa2h0BW8j5s064q5aYudVzpIPq7Kp4GREJ85FCyTfjgxnDx 3OKey74sBag4aLSw+ptomlQn+RrNsLTNwCCSTA/kouZphg3orf8ZPgr5qh3X6ZjzQ32A MCwsutoHqJF5QEoXVyexR7/MTQbGjm1ZL7Pru/s9glLeNnnnX9MdaBQnFVlRKKtfSM1a 6zGjlAoOXoM3tFci4zVm2NcNXDryEuWBZkX+nTREIiKGaupl5/Dc4OrW5EcYf4EqF90D c5Eg==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=GUgnJjKR; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=AUz7ic8F; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=K+0GPBGu; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b=crTjqrp4; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net Received: from lists.sourceforge.net (lists.sourceforge.net. [216.105.38.7]) by mx.google.com with ESMTPS id 006d021491bc7-6b1ce3eb96bsi2494505eaf.84.2026.08.28.07.50.58 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 28 Aug 2026 07:50:59 -0700 (PDT) Received-SPF: pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) client-ip=216.105.38.7; Authentication-Results: mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=GUgnJjKR; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=AUz7ic8F; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=K+0GPBGu; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b=crTjqrp4; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.sourceforge.net; s=beta; h=Content-Transfer-Encoding:Content-Type: List-Subscribe:List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id: Subject:MIME-Version:References:In-Reply-To:Message-ID:Date:To:From:Sender: Reply-To:Cc:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=qYzwudV+NzBLNRJEmob+rXxGadxGGgQK8RELb0n1irM=; b=GUgnJjKRLCF/1iFD7OidIlmeHT oWBalfpoWTViBoYUlv3pIYoAmX50dVXlvcLq/dzhWghnRgdm6e7QbTNza89AThhGZzvWqkepqKmEZ z5FyZ1FnbZf8vtMoIZGzyY0NxTn7BiQC3TnjM0bv4SjeIa2PIElsZeurB6cOtGYpQfak=; Received: from [127.0.0.1] (helo=sfs-ml-1.v29.lw.sourceforge.com) by sfs-ml-1.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1wzxv0-00048C-P0; Fri, 28 Aug 2026 14:50:56 +0000 Received: from [172.30.29.66] (helo=mx.sourceforge.net) by sfs-ml-1.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1wzxux-000484-Aq for openvpn-devel@lists.sourceforge.net; Fri, 28 Aug 2026 14:50:52 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=mGXWEtESJmpRf+hvG7ryt7oZfowt9ZJ+xoPXROLSSX0=; b=AUz7ic8FgU2QraKkRzD48lEznJ WTWO4H2Dc1JAlok+92GfwxKvIkcwkN43gR+OuCMutWaBF1hlTJxC9vrRxzb4dsZc5DxQX4b+iL9T+ TVts33oMt6jabxAP7iPxiyNGpk504c1+nhUASlifB2EGEEEEdEr4DQY8Oudlnncf3HPs=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID: Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=mGXWEtESJmpRf+hvG7ryt7oZfowt9ZJ+xoPXROLSSX0=; b=K+0GPBGucahgmXfski1KEcZ9vA AQ2N2IHMH6NmhIWdEP74jDM5rJt69TOIB1GcTccM1ZMkYenlcTRfITvlQhyj1de3PD9phwT2+sPbt dEMmNbQn+eBbAbBUP2ZoqBr6IMzMWjXM9/ogArSMxBBJyZAJGL1jg8JAAmQaPJlHpbyA=; Received: from mout-b-110.mailbox.org ([195.10.208.55]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1wzxuq-0005qW-Mm for openvpn-devel@lists.sourceforge.net; Fri, 28 Aug 2026 14:50:52 +0000 Received: from smtp102.mailbox.org (smtp102.mailbox.org [IPv6:2001:67c:2050:b231:465::102]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-b-110.mailbox.org (Postfix) with ESMTPS id 4hWhC43lkzzNlfQ for ; Fri, 28 Aug 2026 16:50:40 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandelbit.com; s=MBO0001; t=1787928640; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=mGXWEtESJmpRf+hvG7ryt7oZfowt9ZJ+xoPXROLSSX0=; b=crTjqrp4dosbNRoMW125l7hCu+h5pPouZNYToUaWv74IJrwSZ0B/N9LocP6MeFnBDdjqXm Bx+prHmUKaw6IYR8O3x6T//BTX+4vSitxvlf6eqksaqU39zLdUsjnzQz1G5Prvu0qi/ZnK FIgYZnnhoJnPOHDW9tDiGSJBUmHuuOXsJZnehYZBpu4Y2jIZv1VnZ4Xdx15aPp4RLyAVNc quLKoAQVRz2B831ClUCDPAsiaJxLu6a1sBgaEc7nkzEzZI9iMIgvVQ046J8gNtNFtIsxCN LZ1ufB7MHa+kSM/ZPjQgKppdQP/tRC0gnODuj9tcJZ74F18M24UaH4N3JX1xxA== Authentication-Results: outgoing_mbo_mout; dkim=none; spf=pass (outgoing_mbo_mout: domain of ralf@mandelbit.com designates 2001:67c:2050:b231:465::102 as permitted sender) smtp.mailfrom=ralf@mandelbit.com From: Ralf Lici To: openvpn-devel@lists.sourceforge.net Date: Fri, 28 Aug 2026 16:50:23 +0200 Message-ID: <204af84e2b14079780e06d32ad24c88f1b2d1999.1787925761.git.ralf@mandelbit.com> In-Reply-To: References: MIME-Version: 1.0 X-Rspamd-Queue-Id: 4hWhC43lkzzNlfQ X-Spam-Score: -0.2 (/) X-Spam-Report: Spam detection software, running on the system "sfi-spamd-1.hosts.colo.sdot.me", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: ovpn validates the cached local UDP source address before reusing or refreshing a peer dst cache. This is only meaningful when a concrete source address is selected. For IPv6, calling ipv6_chk_addr with :: checks whether the unspecified address itself is configured on the host. A peer may legitimately have bind->local.ipv6 set to :: when no local endpoint was conf [...] Content analysis details: (-0.2 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid X-Headers-End: 1wzxuq-0005qW-Mm Subject: [Openvpn-devel] [PATCH ovpn net v3 2/6] ovpn: skip UDP source validation for unspecified addresses X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox X-GMAIL-THRID: 1874779081564273996 X-GMAIL-MSGID: 1874779081564273996 ovpn validates the cached local UDP source address before reusing or refreshing a peer dst cache. This is only meaningful when a concrete source address is selected. For IPv6, calling ipv6_chk_addr with :: checks whether the unspecified address itself is configured on the host. A peer may legitimately have bind->local.ipv6 set to :: when no local endpoint was configured or after a stale learned address was cleared. In that case the source should be left unspecified and selected by ip6_dst_lookup_flow(). For IPv4, inet_confirm_addr(..., local = 0, ...) asks for local address autoselection rather than validating a chosen source. Skip the precheck there as well and let ip_route_output_flow select or reject the source. Only validate non-zero/non-any source addresses. Fixes: 08857b5ec5d9 ("ovpn: implement basic TX path (UDP)") Signed-off-by: Ralf Lici --- No changes since v2 https://lore.kernel.org/openvpn-devel/cb51001bfdaeba899b6ca9b22186ea2ebb49c23c.1785308184.git.ralf@mandelbit.com/ No changes since v1 https://lore.kernel.org/openvpn-devel/cb51001bfdaeba899b6ca9b22186ea2ebb49c23c.1785253480.git.ralf@mandelbit.com/ drivers/net/ovpn/udp.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/ovpn/udp.c b/drivers/net/ovpn/udp.c index 7f69e8890b5b..df4750dabd1e 100644 --- a/drivers/net/ovpn/udp.c +++ b/drivers/net/ovpn/udp.c @@ -161,8 +161,8 @@ static int ovpn_udp4_output(struct ovpn_peer *peer, struct ovpn_bind *bind, if (rt) goto transmit; - if (unlikely(!inet_confirm_addr(sock_net(sk), NULL, 0, fl.saddr, - RT_SCOPE_HOST))) { + if (fl.saddr && unlikely(!inet_confirm_addr(sock_net(sk), NULL, 0, + fl.saddr, RT_SCOPE_HOST))) { /* we may end up here when the cached address is not usable * anymore. In this case we reset address/cache and perform a * new look up @@ -238,7 +238,8 @@ static int ovpn_udp6_output(struct ovpn_peer *peer, struct ovpn_bind *bind, if (dst) goto transmit; - if (unlikely(!ipv6_chk_addr(sock_net(sk), &fl.saddr, NULL, 0))) { + if (!ipv6_addr_any(&fl.saddr) && + unlikely(!ipv6_chk_addr(sock_net(sk), &fl.saddr, NULL, 0))) { /* we may end up here when the cached address is not usable * anymore. In this case we reset address/cache and perform a * new look up From patchwork Fri Aug 28 14:50:24 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ralf Lici X-Patchwork-Id: 5298 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:c317:b0:87d:ab56:3700 with SMTP id jk23csp51153mab; Fri, 28 Aug 2026 07:51:00 -0700 (PDT) X-Forwarded-Encrypted: i=2; AHgh+RrS11nUoBIjN8+TGxgoHXmXWDoLWezargnQMsRmB7P/QtGxmgl2xXfyj/pIDN8sqThCC/c6GCpm5f8=@openvpn.net X-Received: by 2002:a05:6820:4c89:b0:6b0:b6a2:1ef5 with SMTP id 006d021491bc7-6b1b01b0b60mr11444605eaf.17.1787928660500; Fri, 28 Aug 2026 07:51:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1787928660; cv=none; d=google.com; s=arc-20260327; b=RznKgV9JGMkNMO8qN0RfuGcywNSKT7YZvrEafVpsfL/MBRHsp92U88GC8HuTctsXN0 9cFfN1FeDeynJYE+49yXTndxFAKk9kJ69USVdg5GVypzJ4hUPDatego4qw8ZeivCZojA JfX2s8h2HggY06jp9i0BmEJ5UOI0F8EAI0BzMOccTTODDOOa2PxcJ1utoYnG509R43c+ tmDdo4eNMV44mQ7jTmGmxzbUTuWFDbvBbyoqVlPHJscJDEmqHSYfYW6YbsJYIUW1fLfz 9q6r7PUaPJdqvCdg/IiW2Y4+zL9nyQ0DDbKTWmHT1K1pTUGpStRlZxFVc+r8ZRy7MEb5 7HKw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; h=errors-to:content-transfer-encoding:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence:subject :mime-version:references:in-reply-to:message-id:date:to:from :dkim-signature:dkim-signature:dkim-signature:dkim-signature; bh=f4pAYerNnEp/cTHKV4sE10LY/k4TAsxZ13RFpz8GmfU=; fh=4NbAC/LsuMLI0S0hprUlLSLCiHwg6SCAifhH718Jh0Q=; b=ntckMizKKf5F0mhTu6Ry+u8TSlMOv6K0/xWpCtbUUS7Ff3o4zBKaGihzHRntBpSMMI ITMg/yen0beLI0PlENv4ubYsPK9SeeKZxCLdfMpKm+1GhUzSvtZNbQK1LuWPTeD3ua/J x3gbHvjURq1/vAb33Y4cabqZpmTUC+q6IuFBahQN2L820mAnl29V1f5eXsEk54js3c+l prhRsYhwCmiumuAIcFUOpErL0wh/Xb5kyHCaAWcWzrTu/Yq5OCkEJoAxKR8mF8uEe2TA GHsO1B1s4HCSMCjbUVyqYb8M7m1a+3Q+hY2ZH8/a72DLEQl0T+apJtl5XTwUvVqk279l Nj+w==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=dQv9iYJl; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=kRJsH6Em; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=ON0ZXKsj; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b=bwlfZISs; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net Received: from lists.sourceforge.net (lists.sourceforge.net. [216.105.38.7]) by mx.google.com with ESMTPS id 586e51a60fabf-468a59ae607si2182951fac.182.2026.08.28.07.51.00 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 28 Aug 2026 07:51:00 -0700 (PDT) Received-SPF: pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) client-ip=216.105.38.7; Authentication-Results: mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=dQv9iYJl; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=kRJsH6Em; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=ON0ZXKsj; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b=bwlfZISs; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.sourceforge.net; s=beta; h=Content-Transfer-Encoding:Content-Type: List-Subscribe:List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id: Subject:MIME-Version:References:In-Reply-To:Message-ID:Date:To:From:Sender: Reply-To:Cc:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=f4pAYerNnEp/cTHKV4sE10LY/k4TAsxZ13RFpz8GmfU=; b=dQv9iYJlrwWuOUMMNOoizul2Kq imZiQNgVgYWmnZCyiNM9H3O4GwF4yNQjMDV6W+R6kyXHLcYTFgo14X0AASxOuafWvFWfryB3OdzgH jqRCiOpkr2+K1QwwShkTipqDCqG1/55wnZ+4CV1In5g1kxUkboGE7l0P5Ze6w6ckNaRM=; Received: from [127.0.0.1] (helo=sfs-ml-4.v29.lw.sourceforge.com) by sfs-ml-4.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1wzxuz-0003li-1Y; Fri, 28 Aug 2026 14:50:57 +0000 Received: from [172.30.29.66] (helo=mx.sourceforge.net) by sfs-ml-4.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1wzxux-0003lN-BE for openvpn-devel@lists.sourceforge.net; Fri, 28 Aug 2026 14:50:55 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=hMLQhg4jRBvzq8SQ0G9OMO0zBFJJXot2Uhu4sgDz98c=; b=kRJsH6EmjlVlAORqxPMBzj15Ut LcydWo0ixqxBooy3b+yd0nLU9pKW5FaRKnQIvnLVrhqc2o9BlLI3JWSe68B5CBr2y3wn8fJAZhd1y 9YpCHCUm7LVom2jTQzZF2OUBAEqx9iOzj0hLy8zkJkIx4ITttEakb1gbSqc4/seRW4a8=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID: Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=hMLQhg4jRBvzq8SQ0G9OMO0zBFJJXot2Uhu4sgDz98c=; b=ON0ZXKsj7sDCkhyvmBb3SnbGVZ DiZNh55/Rr3ISEgDAONdulEZYKGIG5phMFTygQ71tOPOdNShjWS0jfN9IlP9RkztVbbGczxIGrblT 52Pt0dCc+kXxUl5+ojj5KWv2MX9NrzyVwibcErRHwZx4D0/jsymkPw3MoSEvFG0Wbg5k=; Received: from mout-b-106.mailbox.org ([195.10.208.46]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1wzxur-0005qY-SJ for openvpn-devel@lists.sourceforge.net; Fri, 28 Aug 2026 14:50:55 +0000 Received: from smtp102.mailbox.org (smtp102.mailbox.org [10.196.197.102]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-b-106.mailbox.org (Postfix) with ESMTPS id 4hWhC60ZLJzNlZB for ; Fri, 28 Aug 2026 16:50:42 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandelbit.com; s=MBO0001; t=1787928642; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=hMLQhg4jRBvzq8SQ0G9OMO0zBFJJXot2Uhu4sgDz98c=; b=bwlfZISsOc5vrx9cIXXCnPGvdk24ZAWuKXxO07uAggNnb/sbtJF9mgxGOZWnQwzGP1UMZH bVuo1XJ5Sgc22qid2yAqs8U+pA1H+g1Kj0/DYQSk3P9vVCLz9qQdBK5oTtRI/Podg2+drv +8JlxAPpU0Et3iWuoXRhNgIbxGOlKV7kXS42uL1Fp6tmZGF+/T8FtGyJDi13WnJzGecB0z XAtP+PLguAYPFtxci7H5akcz3S3rqR/rNva6dZ+9OLhuQ9U/jugoT9e6uN03nOSACjKmaB syk1H5aVbhnPfyptDpvcHJzfQ+i5/McSVi808z5HC/ti3Ion8X0zTox78z4LGA== From: Ralf Lici To: openvpn-devel@lists.sourceforge.net Date: Fri, 28 Aug 2026 16:50:24 +0200 Message-ID: <2bcaad8bb9c79b499f754324d6723a74ecd13c76.1787925761.git.ralf@mandelbit.com> In-Reply-To: References: MIME-Version: 1.0 X-Spam-Score: -0.2 (/) X-Spam-Report: Spam detection software, running on the system "sfi-spamd-1.hosts.colo.sdot.me", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: ovpn stores the route used to transmit UDP packets in a per-peer dst cache. A cached dst is only valid for the route lookup inputs used when it was resolved. Some of those inputs are mutable while userspace still owns the UDP socket. In particular, changes to the socket mark or UDP source port do not invalidate ovpn's peer dst cache, so ovpn can keep using [...] Content analysis details: (-0.2 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid X-Headers-End: 1wzxur-0005qY-SJ Subject: [Openvpn-devel] [PATCH ovpn net v3 3/6] ovpn: track UDP socket route key for peer dst cache X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox X-GMAIL-THRID: 1874779082827335596 X-GMAIL-MSGID: 1874779082827335596 ovpn stores the route used to transmit UDP packets in a per-peer dst cache. A cached dst is only valid for the route lookup inputs used when it was resolved. Some of those inputs are mutable while userspace still owns the UDP socket. In particular, changes to the socket mark or UDP source port do not invalidate ovpn's peer dst cache, so ovpn can keep using a route selected with an old socket route key. Replace the cached mark with a route key containing the socket-owned lookup inputs currently used by ovpn, and reset the peer dst cache when the key changes. Before storing a newly looked-up dst, recheck the route key under the peer lock so a dst resolved for stale socket state is not published. Fixes: 08857b5ec5d9 ("ovpn: implement basic TX path (UDP)") Signed-off-by: Ralf Lici --- No changes since v2 https://lore.kernel.org/openvpn-devel/15a79f79de3cf192bc862acfd07534c1995f7ad8.1785308184.git.ralf@mandelbit.com/ No changes since v1 https://lore.kernel.org/openvpn-devel/15a79f79de3cf192bc862acfd07534c1995f7ad8.1785253480.git.ralf@mandelbit.com/ drivers/net/ovpn/peer.c | 1 + drivers/net/ovpn/peer.h | 19 ++++++++- drivers/net/ovpn/udp.c | 90 +++++++++++++++++++++++++++++++++++------ 3 files changed, 95 insertions(+), 15 deletions(-) diff --git a/drivers/net/ovpn/peer.c b/drivers/net/ovpn/peer.c index c95656ca7c35..b400783c2efa 100644 --- a/drivers/net/ovpn/peer.c +++ b/drivers/net/ovpn/peer.c @@ -113,6 +113,7 @@ struct ovpn_peer *ovpn_peer_new(struct ovpn_priv *ovpn, u32 id) RCU_INIT_POINTER(peer->bind, NULL); ovpn_crypto_state_init(&peer->crypto); spin_lock_init(&peer->lock); + seqcount_spinlock_init(&peer->route_key_seq, &peer->lock); kref_init(&peer->refcount); ovpn_peer_stats_init(&peer->vpn_stats); ovpn_peer_stats_init(&peer->link_stats); diff --git a/drivers/net/ovpn/peer.h b/drivers/net/ovpn/peer.h index dfa5c0037e02..063535699ecd 100644 --- a/drivers/net/ovpn/peer.h +++ b/drivers/net/ovpn/peer.h @@ -10,6 +10,7 @@ #ifndef _NET_OVPN_OVPNPEER_H_ #define _NET_OVPN_OVPNPEER_H_ +#include #include #include @@ -17,6 +18,16 @@ #include "socket.h" #include "stats.h" +/** + * struct ovpn_route_key - route key used for the peer dst cache + * @mark: fwmark used for route lookup + * @sport: UDP source port used for route lookup + */ +struct ovpn_route_key { + u32 mark; + __be16 sport; +}; + /** * struct ovpn_peer - the main remote peer object * @ovpn: main openvpn instance this peer belongs to @@ -45,6 +56,8 @@ * @tcp.sk_cb.ops: pointer to the original prot_ops object (TCP only) * @crypto: the crypto configuration (ciphers, keys, etc..) * @dst_cache: cache for dst_entry used to send to peer + * @route_key: route key matching the current dst cache contents + * @route_key_seq: seqcount protecting lockless route_key reads * @bind: remote peer binding * @keepalive_interval: seconds after which a new keepalive should be sent * @keepalive_xmit_exp: future timestamp when next keepalive should be sent @@ -55,7 +68,7 @@ * @vpn_stats: per-peer in-VPN TX/RX stats * @link_stats: per-peer link/transport TX/RX stats * @delete_reason: why peer was deleted (i.e. timeout, transport error, ..) - * @lock: protects binding to peer (bind) and keepalive* fields + * @lock: protects binding to peer (bind), route_key and keepalive* fields * @refcount: reference counter * @rcu: used to free peer in an RCU safe way * @release_entry: entry for the socket release list @@ -99,6 +112,8 @@ struct ovpn_peer { } tcp; struct ovpn_crypto_state crypto; struct dst_cache dst_cache; + struct ovpn_route_key route_key; + seqcount_spinlock_t route_key_seq; struct ovpn_bind __rcu *bind; unsigned long keepalive_interval; unsigned long keepalive_xmit_exp; @@ -109,7 +124,7 @@ struct ovpn_peer { struct ovpn_peer_stats vpn_stats; struct ovpn_peer_stats link_stats; enum ovpn_del_peer_reason delete_reason; - spinlock_t lock; /* protects bind and keepalive* */ + spinlock_t lock; /* protects bind, route_key and keepalive* */ struct kref refcount; struct rcu_head rcu; struct llist_node release_entry; diff --git a/drivers/net/ovpn/udp.c b/drivers/net/ovpn/udp.c index df4750dabd1e..c6d591cb7ff4 100644 --- a/drivers/net/ovpn/udp.c +++ b/drivers/net/ovpn/udp.c @@ -131,6 +131,48 @@ static int ovpn_udp_encap_recv(struct sock *sk, struct sk_buff *skb) return 0; } +static bool ovpn_route_key_equal(const struct ovpn_route_key *a, + const struct ovpn_route_key *b) +{ + return a->mark == b->mark && a->sport == b->sport; +} + +/** + * ovpn_dst_cache_check_key - reset peer dst cache after key changes + * @peer: the peer owning the dst cache + * @cache: the cache that might need to be reset + * @key: the route key for the packet being transmitted + * + * Reset the peer dst cache if it was populated for a different route key. + */ +static void ovpn_dst_cache_check_key(struct ovpn_peer *peer, + struct dst_cache *cache, + const struct ovpn_route_key *key) +{ + struct ovpn_route_key old_key; + unsigned int seq; + + /* snapshot the saved key before deciding whether the cache matches */ + do { + seq = read_seqcount_begin(&peer->route_key_seq); + old_key = peer->route_key; + } while (read_seqcount_retry(&peer->route_key_seq, seq)); + + /* nothing changed: the current cache can be reused */ + if (likely(ovpn_route_key_equal(&old_key, key))) + return; + + /* recheck under lock because another path may have updated the key */ + spin_lock_bh(&peer->lock); + if (!ovpn_route_key_equal(&peer->route_key, key)) { + write_seqcount_begin(&peer->route_key_seq); + peer->route_key = *key; + dst_cache_reset(cache); + write_seqcount_end(&peer->route_key_seq); + } + spin_unlock_bh(&peer->lock); +} + /** * ovpn_udp4_output - send IPv4 packet over udp socket * @peer: the destination peer @@ -138,21 +180,23 @@ static int ovpn_udp_encap_recv(struct sock *sk, struct sk_buff *skb) * @cache: dst cache * @sk: the socket to send the packet over * @skb: the packet to send + * @key: the route key snapshot used for cache validation and flow lookup * * Return: 0 on success or a negative error code otherwise */ static int ovpn_udp4_output(struct ovpn_peer *peer, struct ovpn_bind *bind, struct dst_cache *cache, struct sock *sk, - struct sk_buff *skb) + struct sk_buff *skb, + const struct ovpn_route_key *key) { struct rtable *rt; struct flowi4 fl = { .saddr = bind->local.ipv4.s_addr, .daddr = bind->remote.in4.sin_addr.s_addr, - .fl4_sport = inet_sk(sk)->inet_sport, + .fl4_sport = key->sport, .fl4_dport = bind->remote.in4.sin_port, .flowi4_proto = sk->sk_protocol, - .flowi4_mark = sk->sk_mark, + .flowi4_mark = key->mark, }; int ret; @@ -193,7 +237,12 @@ static int ovpn_udp4_output(struct ovpn_peer *peer, struct ovpn_bind *bind, ret); goto err; } - dst_cache_set_ip4(cache, &rt->dst, fl.saddr); + + /* avoid storing a stale cache */ + spin_lock_bh(&peer->lock); + if (likely(ovpn_route_key_equal(key, &peer->route_key))) + dst_cache_set_ip4(cache, &rt->dst, fl.saddr); + spin_unlock_bh(&peer->lock); transmit: udp_tunnel_xmit_skb(rt, sk, skb, fl.saddr, fl.daddr, 0, @@ -213,12 +262,14 @@ static int ovpn_udp4_output(struct ovpn_peer *peer, struct ovpn_bind *bind, * @cache: dst cache * @sk: the socket to send the packet over * @skb: the packet to send + * @key: the route key snapshot used for cache validation and flow lookup * * Return: 0 on success or a negative error code otherwise */ static int ovpn_udp6_output(struct ovpn_peer *peer, struct ovpn_bind *bind, struct dst_cache *cache, struct sock *sk, - struct sk_buff *skb) + struct sk_buff *skb, + const struct ovpn_route_key *key) { struct dst_entry *dst; int ret; @@ -226,10 +277,10 @@ static int ovpn_udp6_output(struct ovpn_peer *peer, struct ovpn_bind *bind, struct flowi6 fl = { .saddr = bind->local.ipv6, .daddr = bind->remote.in6.sin6_addr, - .fl6_sport = inet_sk(sk)->inet_sport, + .fl6_sport = key->sport, .fl6_dport = bind->remote.in6.sin6_port, .flowi6_proto = sk->sk_protocol, - .flowi6_mark = sk->sk_mark, + .flowi6_mark = key->mark, .flowi6_oif = bind->remote.in6.sin6_scope_id, }; @@ -259,7 +310,12 @@ static int ovpn_udp6_output(struct ovpn_peer *peer, struct ovpn_bind *bind, &bind->remote.in6, ret); goto err; } - dst_cache_set_ip6(cache, dst, &fl.saddr); + + /* avoid storing a stale cache */ + spin_lock_bh(&peer->lock); + if (likely(ovpn_route_key_equal(key, &peer->route_key))) + dst_cache_set_ip6(cache, dst, &fl.saddr); + spin_unlock_bh(&peer->lock); transmit: /* user IPv6 packets may be larger than the transport interface @@ -288,6 +344,7 @@ static int ovpn_udp6_output(struct ovpn_peer *peer, struct ovpn_bind *bind, * @cache: dst cache * @sk: the socket to send the packet over * @skb: the packet to send + * @key: route key snapshot used for cache validation and flow lookup * * rcu_read_lock should be held on entry. * On return, the skb is consumed. @@ -295,7 +352,8 @@ static int ovpn_udp6_output(struct ovpn_peer *peer, struct ovpn_bind *bind, * Return: 0 on success or a negative error code otherwise */ static int ovpn_udp_output(struct ovpn_peer *peer, struct dst_cache *cache, - struct sock *sk, struct sk_buff *skb) + struct sock *sk, struct sk_buff *skb, + struct ovpn_route_key *key) { struct ovpn_bind *bind; int ret; @@ -315,11 +373,11 @@ static int ovpn_udp_output(struct ovpn_peer *peer, struct dst_cache *cache, switch (bind->remote.in4.sin_family) { case AF_INET: - ret = ovpn_udp4_output(peer, bind, cache, sk, skb); + ret = ovpn_udp4_output(peer, bind, cache, sk, skb, key); break; #if IS_ENABLED(CONFIG_IPV6) case AF_INET6: - ret = ovpn_udp6_output(peer, bind, cache, sk, skb); + ret = ovpn_udp6_output(peer, bind, cache, sk, skb, key); break; #endif default: @@ -341,15 +399,21 @@ static int ovpn_udp_output(struct ovpn_peer *peer, struct dst_cache *cache, void ovpn_udp_send_skb(struct ovpn_peer *peer, struct sock *sk, struct sk_buff *skb) { + struct ovpn_route_key key = { + .mark = READ_ONCE(sk->sk_mark), + .sport = READ_ONCE(inet_sk(sk)->inet_sport), + }; int ret; skb->dev = peer->ovpn->dev; - skb->mark = READ_ONCE(sk->sk_mark); + skb->mark = key.mark; /* no checksum performed at this layer */ skb->ip_summed = CHECKSUM_NONE; + ovpn_dst_cache_check_key(peer, &peer->dst_cache, &key); + /* crypto layer -> transport (UDP) */ - ret = ovpn_udp_output(peer, &peer->dst_cache, sk, skb); + ret = ovpn_udp_output(peer, &peer->dst_cache, sk, skb, &key); if (unlikely(ret < 0)) kfree_skb(skb); } From patchwork Fri Aug 28 14:50:25 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ralf Lici X-Patchwork-Id: 5293 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:c317:b0:87d:ab56:3700 with SMTP id jk23csp51078mab; Fri, 28 Aug 2026 07:50:57 -0700 (PDT) X-Forwarded-Encrypted: i=2; AHgh+RpPlF+dYvK2r3lKuWsheLAIIilqaECcpnlDotpj+RwI0TUL0d0k7DBGJ81nURGsplfkDdz9JaGfXAI=@openvpn.net X-Received: by 2002:a05:6808:4fe8:b0:4b3:8d45:aa2b with SMTP id 5614622812f47-4b398446f03mr8458971b6e.16.1787928657210; Fri, 28 Aug 2026 07:50:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1787928657; cv=none; d=google.com; s=arc-20260327; b=SBzmyPFDc+asYIh7eLYq+nLA+h6WPbmqRwm0e4EZpjsz2SIIlS23fZh2UtcUBiwpDj zGn9iViT4f35AWIbK+7UnDDARR8bV0F34NiRqloY00OZy01GLhMMRKlGMAs/8NVo8AaV apuZndlFXQ9VGl1AuafqqL1nbCsqZCyUeJaYRo3hosFn2VTsrA9L5Ziyc8EmHcuTbjI/ hCH+YRnVcj5M5++8ivtcSm3LxPxxaHpo1W35HQNEXZ8kON839dzFfyUQ2D+0izXXLDn+ mGEMXVlq2CMsoxMD7Nv39DT7LCjGQDzYgeRrSOelWPyzjHU9/sx2/AkC093gE7KyH9Ah y6wQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; h=errors-to:content-transfer-encoding:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence:subject :mime-version:references:in-reply-to:message-id:date:to:from :dkim-signature:dkim-signature:dkim-signature:dkim-signature; bh=ELx5LRO3lDOlRkDR+ouAd3zdPw3UmhzB+p/Cb62Gc14=; fh=4NbAC/LsuMLI0S0hprUlLSLCiHwg6SCAifhH718Jh0Q=; b=ol9KwEues6dAIvldn0AhUrX0YCSsZbmGTkc6mGWpLugJ2AB+zxIjWYzV+JC5SW0yp1 s6/3Y7OMH5qjWHNz4/mUqJfa0Z05gDKOZ+D3XazFLSodM0iZKU9t+Aw/gGQCnD1+6EOw /IJw2moirkzWm4eVCwSOCIT83otSrJSiSyEiCgka14+9wnzVS6lD2/CLXC1M+3g7TnL2 5kgCEInpp01qZNkEaLVFWHR0HnYjqan+iY/RjrSSenqdznKuCoygSQzFDYaqy5d5hywS 6tswzdPI0B7TIzuiSsUYlc55AQ3C2QPwFl/SmKqjWD/xWQInluzu3zLd0nEno6zJVH6r 9dxw==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=c8wf5KZt; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=SqOk8xm1; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=EwWDxtkn; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b=ltq9CUzV; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net Received: from lists.sourceforge.net (lists.sourceforge.net. [216.105.38.7]) by mx.google.com with ESMTPS id 5614622812f47-4b3a1b32bb4si2588582b6e.89.2026.08.28.07.50.56 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 28 Aug 2026 07:50:57 -0700 (PDT) Received-SPF: pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) client-ip=216.105.38.7; Authentication-Results: mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=c8wf5KZt; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=SqOk8xm1; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=EwWDxtkn; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b=ltq9CUzV; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.sourceforge.net; s=beta; h=Content-Transfer-Encoding:Content-Type: List-Subscribe:List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id: Subject:MIME-Version:References:In-Reply-To:Message-ID:Date:To:From:Sender: Reply-To:Cc:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=ELx5LRO3lDOlRkDR+ouAd3zdPw3UmhzB+p/Cb62Gc14=; b=c8wf5KZthxGgf92K875/R+sLh8 jfSlEQ9rn+rIQmqP6YcNU/Av3QxxkLsMe8yqNuV06xNjr+Gjiw9LFag+9cIJ4CoYWvv15qyM9EvQz hDgKMBIMlaTZ2BObNjScQJ1ReZ/ZkMvwn3JAac0YXGS+cpsQFfmV9ZfgJ3/r9/ROBkII=; Received: from [127.0.0.1] (helo=sfs-ml-3.v29.lw.sourceforge.com) by sfs-ml-3.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1wzxuu-000461-FZ; Fri, 28 Aug 2026 14:50:53 +0000 Received: from [172.30.29.66] (helo=mx.sourceforge.net) by sfs-ml-3.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1wzxus-00045s-Fw for openvpn-devel@lists.sourceforge.net; Fri, 28 Aug 2026 14:50:51 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=VYn7N7+p3t22KtbOVVZD7mPOoWipWB0Ve99bGZcjiRM=; b=SqOk8xm1GifM4/8dZFDe8UWHRf ZBYsKHP6prMT0fYKUCPonD1ejoQLeMBMCB5ZNnf5ISatti6UAJ8Xoy3Yo+dVbFPLTSvB2r2dsZy0t f8RZDQUxmnIuWcbaxE5VFPoKEjsQfNg/X1487jCOPnusrfU7sVJ8xY7YZMt+9O6NYAsU=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID: Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=VYn7N7+p3t22KtbOVVZD7mPOoWipWB0Ve99bGZcjiRM=; b=EwWDxtknsGFUD6kQs3vntBOKOZ fplSB2e8hkxk1vhXBqFmmwV3EG3cKJKRmXJUXwbB1iN3y1+hmjNbA60LPcXLVzxZAKnjuTamIuuNZ zyaHIWcuuljW45ajAuEcaUdQhABzhdlx2enq0x17BIhDWtEhF4+vKr0IMXkWC8ndoCW0=; Received: from mout-b-110.mailbox.org ([195.10.208.55]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1wzxus-000860-JH for openvpn-devel@lists.sourceforge.net; Fri, 28 Aug 2026 14:50:51 +0000 Received: from smtp102.mailbox.org (smtp102.mailbox.org [IPv6:2001:67c:2050:b231:465::102]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-b-110.mailbox.org (Postfix) with ESMTPS id 4hWhC65HZGzNlfS for ; Fri, 28 Aug 2026 16:50:42 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandelbit.com; s=MBO0001; t=1787928642; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=VYn7N7+p3t22KtbOVVZD7mPOoWipWB0Ve99bGZcjiRM=; b=ltq9CUzVsEuZmxeveqmIoPGU1yx8fRyKhMAVr6OCoUNPN/MkQ7BNt3bELTWoT5tFMpXsng Tt02ufFZOAlHaw/vlAWuo3xrjtwrwRiL9UFCM/znL282fP4Ojq63ITillUJ2jJ17lVRzZS 9V8Bj/O8byK6K09dQpeSB59buTA6qdXUX/O7XZ+oUqfkz3gGwgfCXuM6vmJ3KamyU+376/ 8z/RQb8czypAPSEDMH9hP8kdBSkW9WHk2DuDH1LQW6RgDnhs3SYbZXfuIPz7qB7BgtoiAf shyEmYvCapaZ8YurUNedtjnHD6a+rGjEafbSzNl4VrpMLq4mNE7NVGEnwjmv0A== Authentication-Results: outgoing_mbo_mout; dkim=none; spf=pass (outgoing_mbo_mout: domain of ralf@mandelbit.com designates 2001:67c:2050:b231:465::102 as permitted sender) smtp.mailfrom=ralf@mandelbit.com From: Ralf Lici To: openvpn-devel@lists.sourceforge.net Date: Fri, 28 Aug 2026 16:50:25 +0200 Message-ID: In-Reply-To: References: MIME-Version: 1.0 X-Rspamd-Queue-Id: 4hWhC65HZGzNlfS X-Spam-Score: -0.2 (/) X-Spam-Report: Spam detection software, running on the system "sfi-spamd-2.hosts.colo.sdot.me", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: UDP route lookup runs without peer->lock while the bind is protected by RCU. The route key is snapshotted separately. Either can change while the lookup is in progress. The TX path currently checks only the route key before publishing the looked-up dst. If the bind changes but the route key does not, a dst resolved from the old endpoint can be installed in the cache [...] Content analysis details: (-0.2 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid X-Headers-End: 1wzxus-000860-JH Subject: [Openvpn-devel] [PATCH ovpn net v3 4/6] ovpn: validate peer state before caching UDP dst X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox X-GMAIL-THRID: 1874779079725256323 X-GMAIL-MSGID: 1874779079725256323 UDP route lookup runs without peer->lock while the bind is protected by RCU. The route key is snapshotted separately. Either can change while the lookup is in progress. The TX path currently checks only the route key before publishing the looked-up dst. If the bind changes but the route key does not, a dst resolved from the old endpoint can be installed in the cache after the bind replacement. Compare both the bind pointer and the route key under peer->lock before updating the cache. The RCU read-side critical section keeps the old bind alive throughout the lookup, so pointer identity is sufficient to detect a replacement. Fixes: f0281c1d3732 ("ovpn: add support for updating local or remote UDP endpoint") Signed-off-by: Ralf Lici --- Changes since v2 https://lore.kernel.org/openvpn-devel/082540583b9145d89e1cdd5a74c485ea3a53d285.1785308184.git.ralf@mandelbit.com/ - Split former 4/5 into this plus the next two patches. (Sabrina) - No functional changes. No changes since v1 https://lore.kernel.org/openvpn-devel/082540583b9145d89e1cdd5a74c485ea3a53d285.1785253480.git.ralf@mandelbit.com/ drivers/net/ovpn/udp.c | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/drivers/net/ovpn/udp.c b/drivers/net/ovpn/udp.c index c6d591cb7ff4..eeef4a7229f5 100644 --- a/drivers/net/ovpn/udp.c +++ b/drivers/net/ovpn/udp.c @@ -173,6 +173,35 @@ static void ovpn_dst_cache_check_key(struct ovpn_peer *peer, spin_unlock_bh(&peer->lock); } +/** + * ovpn_dst_cache_current - check whether a route lookup matches peer state + * @peer: the peer owning the bind and dst cache + * @bind: the RCU bind used for the route lookup + * @key: the route key used for the route lookup + * + * Check that @bind is still the current peer bind and that @key still matches + * the peer route key. The caller must hold @peer->lock. The TX path keeps + * @bind inside an RCU read-side critical section, so pointer identity is enough + * to detect whether the bind was replaced while the route lookup was running. + * + * Return: true if the lookup result still matches the current peer state and + * may update the dst cache. + */ +static bool ovpn_dst_cache_current(const struct ovpn_peer *peer, + const struct ovpn_bind *bind, + const struct ovpn_route_key *key) +{ + const struct ovpn_bind *curr_bind; + + lockdep_assert_held(&peer->lock); + + curr_bind = rcu_dereference_protected(peer->bind, + lockdep_is_held(&peer->lock)); + + return curr_bind == bind && + ovpn_route_key_equal(key, &peer->route_key); +} + /** * ovpn_udp4_output - send IPv4 packet over udp socket * @peer: the destination peer @@ -240,7 +269,7 @@ static int ovpn_udp4_output(struct ovpn_peer *peer, struct ovpn_bind *bind, /* avoid storing a stale cache */ spin_lock_bh(&peer->lock); - if (likely(ovpn_route_key_equal(key, &peer->route_key))) + if (likely(ovpn_dst_cache_current(peer, bind, key))) dst_cache_set_ip4(cache, &rt->dst, fl.saddr); spin_unlock_bh(&peer->lock); @@ -313,7 +342,7 @@ static int ovpn_udp6_output(struct ovpn_peer *peer, struct ovpn_bind *bind, /* avoid storing a stale cache */ spin_lock_bh(&peer->lock); - if (likely(ovpn_route_key_equal(key, &peer->route_key))) + if (likely(ovpn_dst_cache_current(peer, bind, key))) dst_cache_set_ip6(cache, dst, &fl.saddr); spin_unlock_bh(&peer->lock); From patchwork Fri Aug 28 14:50:26 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ralf Lici X-Patchwork-Id: 5295 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:c317:b0:87d:ab56:3700 with SMTP id jk23csp51112mab; Fri, 28 Aug 2026 07:50:59 -0700 (PDT) X-Forwarded-Encrypted: i=2; AHgh+RqcJGrxanVeCY3/ejS4rX8637REIlBeotSogapIot8G7Ey44laH3jhrjgk6la1BPzMEMLcZWuA2hkY=@openvpn.net X-Received: by 2002:a05:6820:4b0f:b0:6b2:f445:af17 with SMTP id 006d021491bc7-6b2f445b157mr1047772eaf.26.1787928658534; Fri, 28 Aug 2026 07:50:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1787928658; cv=none; d=google.com; s=arc-20260327; b=CUocUO7KhMo59jDN9q/5J2946AEey2BxQwm+1cqt+ebmAVtCF2OLY05iy/x6a1c7jq C6SuER0TsefkNvMdq2xymMaa9ivTaXqCqxpbr4uY+v40rmlgmsAK1WT6Xg2kazzSdJ07 aYolXEGs3Kr3o8BXmBq2ZYQ57ZYSD8S4m+GRSagRpu+O+cYXAKRBPrw2Eo1a7167RCc3 72ziVylb82hJzQwcmXS0NzCe6G5mSAGsbmnm+HH+/oA1iU38hsJ9xwqjkvNwMpow9dJa Uhm88vnRYjxLAACBcCu89Aqxu9ob3OTq8TjCihvXEbON5ploB9XilqQMvJp/bvA1M5O1 k84Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; h=errors-to:content-transfer-encoding:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence:subject :mime-version:references:in-reply-to:message-id:date:to:from :dkim-signature:dkim-signature:dkim-signature:dkim-signature; bh=Dkr9P7bf0MFoeVTMvsZYuVFQHk4ioDZgiY46AACerqg=; fh=4NbAC/LsuMLI0S0hprUlLSLCiHwg6SCAifhH718Jh0Q=; b=P/cwtX7pISu4RxF6qHv/TyfNkA749BFEMeYYQ2MAfJxd3UfP/Emr3cX09nRbeD0IW2 rB51IIXWnmreoxWP2IbXZ8U9eUza7TlsvpodBLqHYd0Gp5+pYxU5TzZMHMwL8caISB0y ODG+mycoTyis2mRfkuvZv0YW/0dKkGSeWRUCHup87DKom1vOrwPOJvEA4gpfgjdKcrW/ n7o2jOXkG63PQkJXwaszpeCzSt2JbiD1oi7dlpJldA1j838VlacT98rgzys0CH224/UD TlP70pOA3OmDiwnsbWp7+WD9NLTFuFS+w22QrTEqnCJwGXhMA3wTPVHUubpo/1A1VRPW 8u5Q==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=RA2NCHVt; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=W26QTmE7; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=be7vfujf; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b=dG3ys2jP; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net Received: from lists.sourceforge.net (lists.sourceforge.net. [216.105.38.7]) by mx.google.com with ESMTPS id 586e51a60fabf-468a3525953si2222283fac.111.2026.08.28.07.50.58 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 28 Aug 2026 07:50:58 -0700 (PDT) Received-SPF: pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) client-ip=216.105.38.7; Authentication-Results: mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=RA2NCHVt; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=W26QTmE7; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=be7vfujf; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b=dG3ys2jP; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.sourceforge.net; s=beta; h=Content-Transfer-Encoding:Content-Type: List-Subscribe:List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id: Subject:MIME-Version:References:In-Reply-To:Message-ID:Date:To:From:Sender: Reply-To:Cc:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=Dkr9P7bf0MFoeVTMvsZYuVFQHk4ioDZgiY46AACerqg=; b=RA2NCHVt9lX2CY27MNnlZtVgHl 88dkMSme37k7SoNDlEQ7aImSRC+48dcpZP5rnKqP1eA3jIni1tdMqGPRSMI28nP5iTH3QiJyNyoj5 fzJtSNZmes4z+3pgI53DAytUOPTWQ2c44BTvlID6Wv4W1VugPZHo4y01TB/0Eso5Tigs=; Received: from [127.0.0.1] (helo=sfs-ml-3.v29.lw.sourceforge.com) by sfs-ml-3.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1wzxuw-00046P-QB; Fri, 28 Aug 2026 14:50:55 +0000 Received: from [172.30.29.66] (helo=mx.sourceforge.net) by sfs-ml-3.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1wzxuv-00046A-4Z for openvpn-devel@lists.sourceforge.net; Fri, 28 Aug 2026 14:50:53 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=c5sz0/xLsrD5HMxlj6w/xp0zpsYJ0lexaVHSBaKgrLM=; b=W26QTmE7eb55/GCdI1UWmU/VLe 8UQqqVd8wy97Z/ygfKtXmEfLw7DfezAfq19tNlA0MWLZoMos3Sqfric5SLDsytjBGPgT0XEg+3DgN N8RtW92td91/LfvlojJjVN8O7HJunoorAombwphj4hEocMAu8WGeQLKQx8gOV4cbRxAA=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID: Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=c5sz0/xLsrD5HMxlj6w/xp0zpsYJ0lexaVHSBaKgrLM=; b=be7vfujf1NCnGRrr2sGLnydWA7 p3wffkMX27rR65yxMrclEqEgO6PIQsN37D07rh7RlsdcXMyhWL5KkAi0mIQeA247vA2TyLW8xZPZ8 Fxe+/IjdWMNlxWnag1hoXHoz8SpN7dbHsE0DnHI2S55eP8O8fwnWfnetU3uNRIsUlHcA=; Received: from mout-b-210.mailbox.org ([195.10.208.40]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1wzxut-0005qZ-Fz for openvpn-devel@lists.sourceforge.net; Fri, 28 Aug 2026 14:50:53 +0000 Received: from smtp102.mailbox.org (smtp102.mailbox.org [IPv6:2001:67c:2050:b231:465::102]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-b-210.mailbox.org (Postfix) with ESMTPS id 4hWhC71R3GzFpwZ for ; Fri, 28 Aug 2026 16:50:43 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandelbit.com; s=MBO0001; t=1787928643; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=c5sz0/xLsrD5HMxlj6w/xp0zpsYJ0lexaVHSBaKgrLM=; b=dG3ys2jPFttsgfvfJpXgWcOM5U02+sl+MvOXSMMoMRwdJIIBCC2agAJH4OR58Ap6/Vhgc+ n7/jHIZc7GMlefTYE462jj+wm1dx7GvpqVw3ydBBycBbZlgWM5xYpELecil3wWMmah25p3 KaBM5UAXlzpTPVCXjO4+BbkeqMVc5NjewHggicFbfdl09jGEFtoUK0fDJoyyADMZjqK5a0 CvmfYoscDxpBPHwMCdDcp9nSoL0Ws2FKkevBNgmzsqqFl0c+maKv22ABFyBwocEp/oXBDy 8CbYBR0MsCLQOLHuBnsQdcIuW7WhuM0+KKPzPO8n/Cmu3AgYjKF7LbcpsSx9dQ== Authentication-Results: outgoing_mbo_mout; dkim=none; spf=pass (outgoing_mbo_mout: domain of ralf@mandelbit.com designates 2001:67c:2050:b231:465::102 as permitted sender) smtp.mailfrom=ralf@mandelbit.com From: Ralf Lici To: openvpn-devel@lists.sourceforge.net Date: Fri, 28 Aug 2026 16:50:26 +0200 Message-ID: In-Reply-To: References: MIME-Version: 1.0 X-Rspamd-Queue-Id: 4hWhC71R3GzFpwZ X-Spam-Score: -0.2 (/) X-Spam-Report: Spam detection software, running on the system "sfi-spamd-1.hosts.colo.sdot.me", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: struct ovpn_bind is published through peer->bind with RCU, but local endpoint learning updates bind->local in place under peer->lock. UDP TX reads the field without that lock. In particular, a concurr [...] Content analysis details: (-0.2 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid X-Headers-End: 1wzxut-0005qZ-Fz Subject: [Openvpn-devel] [PATCH ovpn net v3 5/6] ovpn: replace bind when learning local endpoint X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox X-GMAIL-THRID: 1874779080953082855 X-GMAIL-MSGID: 1874779080953082855 struct ovpn_bind is published through peer->bind with RCU, but local endpoint learning updates bind->local in place under peer->lock. UDP TX reads the field without that lock. In particular, a concurrent IPv6 update can therefore result in a torn address read. Use ovpn_peer_reset_sockaddr to publish a replacement bind when learning a new local endpoint, just as a remote endpoint change does. Preserve the current remote address and reset the dst cache only after the new bind has been published successfully. Track remote endpoint changes separately so that float notification and transport-address rehashing remain limited to actual peer floats. Fixes: f0281c1d3732 ("ovpn: add support for updating local or remote UDP endpoint") Signed-off-by: Ralf Lici --- Changes since v2 https://lore.kernel.org/openvpn-devel/082540583b9145d89e1cdd5a74c485ea3a53d285.1785308184.git.ralf@mandelbit.com/ - Split former 4/5 into this plus the previous and the next patch. (Sabrina) - Tracked float with the specific floated boolean rather than indirectly through salen. - Refactored the code into a cleaner shape. (Sabrina) drivers/net/ovpn/peer.c | 43 ++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/drivers/net/ovpn/peer.c b/drivers/net/ovpn/peer.c index b400783c2efa..430c6cd48db8 100644 --- a/drivers/net/ovpn/peer.c +++ b/drivers/net/ovpn/peer.c @@ -200,13 +200,12 @@ static void __ovpn_peer_hash_transp_addr(struct ovpn_peer *peer, */ void ovpn_peer_endpoints_update(struct ovpn_peer *peer, struct sk_buff *skb) { + const void *local_ip = NULL; struct sockaddr_storage ss; struct sockaddr_in6 *sa6; - bool reset_cache = false; struct sockaddr_in *sa; struct ovpn_bind *bind; - const void *local_ip; - size_t salen = 0; + bool floated = false; spin_lock_bh(&peer->lock); bind = rcu_dereference_protected(peer->bind, @@ -233,8 +232,7 @@ void ovpn_peer_endpoints_update(struct ovpn_peer *peer, struct sk_buff *skb) .sin_addr.s_addr = ip_hdr(skb)->saddr, .sin_port = udp_hdr(skb)->source, }; - salen = sizeof(*sa); - reset_cache = true; + floated = true; break; } @@ -246,10 +244,12 @@ void ovpn_peer_endpoints_update(struct ovpn_peer *peer, struct sk_buff *skb) netdev_name(peer->ovpn->dev), peer->id, &bind->local.ipv4.s_addr, &ip_hdr(skb)->daddr); - bind->local.ipv4.s_addr = ip_hdr(skb)->daddr; - reset_cache = true; + local_ip = &ip_hdr(skb)->daddr; + memcpy(&ss, &bind->remote, sizeof(struct sockaddr_in)); + break; } - break; + /* nothing changed */ + goto unlock; case htons(ETH_P_IPV6): /* float check */ if (unlikely(!ovpn_bind_skb_src_match(bind, skb))) { @@ -271,8 +271,7 @@ void ovpn_peer_endpoints_update(struct ovpn_peer *peer, struct sk_buff *skb) ipv6_iface_scope_id(&ipv6_hdr(skb)->saddr, skb->skb_iif), }; - salen = sizeof(*sa6); - reset_cache = true; + floated = true; break; } @@ -285,26 +284,30 @@ void ovpn_peer_endpoints_update(struct ovpn_peer *peer, struct sk_buff *skb) netdev_name(peer->ovpn->dev), peer->id, &bind->local.ipv6, &ipv6_hdr(skb)->daddr); - bind->local.ipv6 = ipv6_hdr(skb)->daddr; - reset_cache = true; + local_ip = &ipv6_hdr(skb)->daddr; + memcpy(&ss, &bind->remote, sizeof(struct sockaddr_in6)); + break; } - break; + /* nothing changed */ + goto unlock; default: goto unlock; } - if (unlikely(reset_cache)) - dst_cache_reset(&peer->dst_cache); - - /* if the peer did not float, we can bail out now */ - if (likely(!salen)) - goto unlock; - if (unlikely(ovpn_peer_reset_sockaddr(peer, (struct sockaddr_storage *)&ss, local_ip) < 0)) goto unlock; + /* reset the cache only after a successful bind update to avoid useless + * cache misses on concurrent TX + */ + dst_cache_reset(&peer->dst_cache); + + /* if only the local address changed, bail out now */ + if (!floated) + goto unlock; + net_dbg_ratelimited("%s: peer %d floated to %pIScp", netdev_name(peer->ovpn->dev), peer->id, &ss); From patchwork Fri Aug 28 14:50:27 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ralf Lici X-Patchwork-Id: 5294 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:c317:b0:87d:ab56:3700 with SMTP id jk23csp51097mab; Fri, 28 Aug 2026 07:50:58 -0700 (PDT) X-Forwarded-Encrypted: i=2; AHgh+RrgpeOMgE7iRpU8wBRbnCZNiRMQzIbYa7iNod4GaIoF0goni2tpvahy1BjtH52YY+oOJ/dBMAKNrNA=@openvpn.net X-Received: by 2002:a05:6820:1f03:b0:6b0:40d9:8ac6 with SMTP id 006d021491bc7-6b1c65c0755mr6888174eaf.9.1787928658316; Fri, 28 Aug 2026 07:50:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1787928658; cv=none; d=google.com; s=arc-20260327; b=QeOA7c0S+9E3SQ6XAS1xMOBXWAoTw0xNlu/Ipbro7WzD42jVY//MFsPlxh2WK4XS0v qEsdDmIoJo0oe+1HGK8w2TTJ6MXV8HsOqA78j094TXt5VXKh89sYtesgTU4F30RtVFAS DTgSk64UYcVx0zccAO3Fl60PWvhHWzZPjtCBqRnh/+2f5qdfew0NJ3A7ZOg8cZxFZ6uM z+dVanfN0oI3+AvqMCLYIK4qGI6tvGbghnlD+1QhwSJcq+sfqiilvAOPjBiuGMOUzbzi 8cHqA/pvOS4TRnRZZHgnP0pVQ6dP20CGN7OIpljpPBgy1lMCm9iT5lGBelkyhiFmeD5s 0L0g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; h=errors-to:content-transfer-encoding:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence:subject :mime-version:references:in-reply-to:message-id:date:to:from :dkim-signature:dkim-signature:dkim-signature:dkim-signature; bh=tClRIUGyA55VhPe3NOA8IHNCvXbiHNuJVk3aYt69FyI=; fh=4NbAC/LsuMLI0S0hprUlLSLCiHwg6SCAifhH718Jh0Q=; b=WX7PJIAjQCMf7KtJJKv8adkOAiUwnqYRYIMoP6AdReB7Ia+5bMeEvomRIAe+KCilWQ aMvappqoQePZ7EFn48thIayIOTemFsYqt4kGCLfVlF1kevO6v1ytWz1TK/VVuqG8f8Of g3OWRFyV4QjbAMpah/wlo7rFa1lIKg7a+zAu2VVWxmSMVMNEYykPV917iA9ufOGd/fCt RtR1r84aBI2w1IKZvJGG2HP9q2clBbMXgy+Tqu5TIvDvg/Auv0XXmx1AzqQvqUBtcLft gieazqUYiR4gHhvjp8EfP8nxazELGP44HQOBg/ifU5i1ymO4+h+ERP2WlSWeai7pSD97 ywMg==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=OQMgUkcb; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=elqDQuQW; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=K6ajQTMY; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b=yuzbJ6hd; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net Received: from lists.sourceforge.net (lists.sourceforge.net. [216.105.38.7]) by mx.google.com with ESMTPS id 006d021491bc7-6b1ce0bb5d4si2574838eaf.14.2026.08.28.07.50.57 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 28 Aug 2026 07:50:58 -0700 (PDT) Received-SPF: pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) client-ip=216.105.38.7; Authentication-Results: mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=OQMgUkcb; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=elqDQuQW; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=K6ajQTMY; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b=yuzbJ6hd; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.sourceforge.net; s=beta; h=Content-Transfer-Encoding:Content-Type: List-Subscribe:List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id: Subject:MIME-Version:References:In-Reply-To:Message-ID:Date:To:From:Sender: Reply-To:Cc:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=tClRIUGyA55VhPe3NOA8IHNCvXbiHNuJVk3aYt69FyI=; b=OQMgUkcbkm/ge5cxRXt0jT0ONh SWJcYFgxnwX+SDTJ/UiJbLknOrC0DKy+kjqsMJSJMvrOkONLe6TuazlRkn4gUQxVnmTB5amUcqAhM 3PCovlQ9ztkDFYlfnAJfn7HwlbSFtwpwIT41I9/pdMnJo3ZVw69E4E8//0UNliG37Fkc=; Received: from [127.0.0.1] (helo=sfs-ml-2.v29.lw.sourceforge.com) by sfs-ml-2.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1wzxuv-0000qh-RC; Fri, 28 Aug 2026 14:50:54 +0000 Received: from [172.30.29.66] (helo=mx.sourceforge.net) by sfs-ml-2.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1wzxuu-0000qI-Sh for openvpn-devel@lists.sourceforge.net; Fri, 28 Aug 2026 14:50:53 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=qltw84WDSXhVRMZbKrtV9oCHvmhpOCFBhSIDfqS5hB8=; b=elqDQuQWCahO7BctQ0uN38n4Hq rJwXOmIilWHjnnAhy1IM8rZNIqgHprUh8ANYF8ATLsu1cMI7jpt1uvje7e17bIi4QxAA+6l+sHfE2 Uy55sT0iy2RlshdkiHLLdu0intdtg0azLNYynyBtk4sjBGtqtMUyEjDYr1jwElM/QIyc=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID: Date:Subject:To:From:Sender:Reply-To:Cc:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=qltw84WDSXhVRMZbKrtV9oCHvmhpOCFBhSIDfqS5hB8=; b=K6ajQTMYuomZD10nQn26dWZbgu dsDX2bhAg/25cGo8w5tFNHgTJL9iEtmNcBiUWQhl0mrc9/7NvvA99IVVw/9G8InUKwSPXLoDCWTOj 3Sig6vyl7/OnSb18K+835XAo6CQnhiJj7MmAWZBFQhb1jg4sYggxyHscOIgjXajXnbqk=; Received: from mout-b-202.mailbox.org ([195.10.208.62]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1wzxuu-0005qe-4L for openvpn-devel@lists.sourceforge.net; Fri, 28 Aug 2026 14:50:53 +0000 Received: from smtp102.mailbox.org (smtp102.mailbox.org [IPv6:2001:67c:2050:b231:465::102]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-b-202.mailbox.org (Postfix) with ESMTPS id 4hWhC75fXszKnTQ for ; Fri, 28 Aug 2026 16:50:43 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandelbit.com; s=MBO0001; t=1787928643; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=qltw84WDSXhVRMZbKrtV9oCHvmhpOCFBhSIDfqS5hB8=; b=yuzbJ6hd8UQdXJ3QO9eakKZ5jVzSSXTUgKQV4xe0xNFFkMvSlXIg73qHeBuml66fXVBuav xfC0EDDqJQcuH5OvLc8A2KEVzp34TPA5x1YUhCNO0t0toP2SEYWOJOcmQHvlO2q+EmEF0p VAgAgCSDNGztPpOix7iBzfK0Wc//oSOteeOPDaK8TpsKsnH4tn/0TTTfFX9bQRTItIGTb5 epdseoJeEs2JG4GnEYpz3SgXUHU1eS8B8Ng8uvv004zaiPBOP+slaFwld+MSCVYZcsQk4k CuiZUfWoWibtItbyMj6PLbP8ILo8vv5Wpf8OWX55kRP2nKNQbaou0qQa8JcXpg== Authentication-Results: outgoing_mbo_mout; dkim=none; spf=pass (outgoing_mbo_mout: domain of ralf@mandelbit.com designates 2001:67c:2050:b231:465::102 as permitted sender) smtp.mailfrom=ralf@mandelbit.com From: Ralf Lici To: openvpn-devel@lists.sourceforge.net Date: Fri, 28 Aug 2026 16:50:27 +0200 Message-ID: <733af95bec0add37f18117c674543d4191f89d26.1787925761.git.ralf@mandelbit.com> In-Reply-To: References: MIME-Version: 1.0 X-Rspamd-Queue-Id: 4hWhC75fXszKnTQ X-Spam-Score: -0.2 (/) X-Spam-Report: Spam detection software, running on the system "sfi-spamd-2.hosts.colo.sdot.me", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: The UDP output fallback clears bind->local in place when the remembered source address is no longer usable. The bind is RCU-published and read locklessly by concurrent TX, so an IPv6 reader can observ [...] Content analysis details: (-0.2 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid X-Headers-End: 1wzxuu-0005qe-4L Subject: [Openvpn-devel] [PATCH ovpn net v3 6/6] ovpn: replace bind when clearing stale local source X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox X-GMAIL-THRID: 1874779080484845483 X-GMAIL-MSGID: 1874779080484845483 The UDP output fallback clears bind->local in place when the remembered source address is no longer usable. The bind is RCU-published and read locklessly by concurrent TX, so an IPv6 reader can observe a torn address. Retry the route lookup with source address autoselection without modifying the bind. After a successful lookup, revalidate the bind and route key under peer->lock, reset the dst cache, and best-effort publish a replacement bind with a wildcard local address. Do not cache the resolved dst when clearing the local source. Replacing the source invalidates all per-CPU cache entries, while dst_cache_set_ip4 and dst_cache_set_ip6 update only the current CPU slot. The current packet can still use the resolved route; if bind allocation fails, a later cache miss retries the repair. Fixes: 08857b5ec5d9 ("ovpn: implement basic TX path (UDP)") Signed-off-by: Ralf Lici --- Changes since v2 https://lore.kernel.org/openvpn-devel/082540583b9145d89e1cdd5a74c485ea3a53d285.1785308184.git.ralf@mandelbit.com/ - Split former 4/5 into this plus the previous two patches. (Sabrina) - No functional changes. No changes since v1 https://lore.kernel.org/openvpn-devel/082540583b9145d89e1cdd5a74c485ea3a53d285.1785253480.git.ralf@mandelbit.com/ drivers/net/ovpn/udp.c | 81 +++++++++++++++++++++++++++++------------- 1 file changed, 56 insertions(+), 25 deletions(-) diff --git a/drivers/net/ovpn/udp.c b/drivers/net/ovpn/udp.c index eeef4a7229f5..055cdb1bee13 100644 --- a/drivers/net/ovpn/udp.c +++ b/drivers/net/ovpn/udp.c @@ -185,7 +185,7 @@ static void ovpn_dst_cache_check_key(struct ovpn_peer *peer, * to detect whether the bind was replaced while the route lookup was running. * * Return: true if the lookup result still matches the current peer state and - * may update the dst cache. + * may update the dst cache or replace the bind. */ static bool ovpn_dst_cache_current(const struct ovpn_peer *peer, const struct ovpn_bind *bind, @@ -218,6 +218,9 @@ static int ovpn_udp4_output(struct ovpn_peer *peer, struct ovpn_bind *bind, struct sk_buff *skb, const struct ovpn_route_key *key) { + struct sockaddr_storage remote; + struct in_addr local = {}; + bool reset_local = false; struct rtable *rt; struct flowi4 fl = { .saddr = bind->local.ipv4.s_addr, @@ -236,24 +239,17 @@ static int ovpn_udp4_output(struct ovpn_peer *peer, struct ovpn_bind *bind, if (fl.saddr && unlikely(!inet_confirm_addr(sock_net(sk), NULL, 0, fl.saddr, RT_SCOPE_HOST))) { - /* we may end up here when the cached address is not usable - * anymore. In this case we reset address/cache and perform a - * new look up + /* The learned local address is not usable anymore. + * Retry with source address autoselection. */ fl.saddr = 0; - spin_lock_bh(&peer->lock); - bind->local.ipv4.s_addr = 0; - spin_unlock_bh(&peer->lock); - dst_cache_reset(cache); + reset_local = true; } rt = ip_route_output_flow(sock_net(sk), &fl, sk); if (IS_ERR(rt) && PTR_ERR(rt) == -EINVAL) { fl.saddr = 0; - spin_lock_bh(&peer->lock); - bind->local.ipv4.s_addr = 0; - spin_unlock_bh(&peer->lock); - dst_cache_reset(cache); + reset_local = true; rt = ip_route_output_flow(sock_net(sk), &fl, sk); } @@ -267,10 +263,28 @@ static int ovpn_udp4_output(struct ovpn_peer *peer, struct ovpn_bind *bind, goto err; } - /* avoid storing a stale cache */ + /* avoid storing a stale cache or local address */ spin_lock_bh(&peer->lock); - if (likely(ovpn_dst_cache_current(peer, bind, key))) - dst_cache_set_ip4(cache, &rt->dst, fl.saddr); + if (likely(ovpn_dst_cache_current(peer, bind, key))) { + if (!reset_local) { + dst_cache_set_ip4(cache, &rt->dst, fl.saddr); + spin_unlock_bh(&peer->lock); + goto transmit; + } + + /* invalidate per-CPU dst entries that may still carry + * the stale source + */ + dst_cache_reset(cache); + + /* preserve the current remote */ + memcpy(&remote, &bind->remote, sizeof(struct sockaddr_in)); + /* The current packet already has a valid wildcard-source route. + * If replacing the bind fails, leave the stale local in place; + * a later cache miss will retry the repair. + */ + ovpn_peer_reset_sockaddr(peer, &remote, &local); + } spin_unlock_bh(&peer->lock); transmit: @@ -300,6 +314,9 @@ static int ovpn_udp6_output(struct ovpn_peer *peer, struct ovpn_bind *bind, struct sk_buff *skb, const struct ovpn_route_key *key) { + struct in6_addr local = in6addr_any; + struct sockaddr_storage remote; + bool reset_local = false; struct dst_entry *dst; int ret; @@ -320,15 +337,11 @@ static int ovpn_udp6_output(struct ovpn_peer *peer, struct ovpn_bind *bind, if (!ipv6_addr_any(&fl.saddr) && unlikely(!ipv6_chk_addr(sock_net(sk), &fl.saddr, NULL, 0))) { - /* we may end up here when the cached address is not usable - * anymore. In this case we reset address/cache and perform a - * new look up + /* The learned local address is not usable anymore. + * Retry with source address autoselection. */ fl.saddr = in6addr_any; - spin_lock_bh(&peer->lock); - bind->local.ipv6 = in6addr_any; - spin_unlock_bh(&peer->lock); - dst_cache_reset(cache); + reset_local = true; } dst = ip6_dst_lookup_flow(sock_net(sk), sk, &fl, NULL); @@ -340,10 +353,28 @@ static int ovpn_udp6_output(struct ovpn_peer *peer, struct ovpn_bind *bind, goto err; } - /* avoid storing a stale cache */ + /* avoid storing a stale cache or local address */ spin_lock_bh(&peer->lock); - if (likely(ovpn_dst_cache_current(peer, bind, key))) - dst_cache_set_ip6(cache, dst, &fl.saddr); + if (likely(ovpn_dst_cache_current(peer, bind, key))) { + if (!reset_local) { + dst_cache_set_ip6(cache, dst, &fl.saddr); + spin_unlock_bh(&peer->lock); + goto transmit; + } + + /* invalidate per-CPU dst entries that may still carry + * the stale source + */ + dst_cache_reset(cache); + + /* preserve the current remote */ + memcpy(&remote, &bind->remote, sizeof(struct sockaddr_in6)); + /* The current packet already has a valid wildcard-source route. + * If replacing the bind fails, leave the stale local in place; + * a later cache miss will retry the repair. + */ + ovpn_peer_reset_sockaddr(peer, &remote, &local); + } spin_unlock_bh(&peer->lock); transmit: