From patchwork Wed Jul 29 07:20:32 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ralf Lici X-Patchwork-Id: 5160 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:fd0b:b0:87d:ab56:3700 with SMTP id cw11csp1591225mac; Wed, 29 Jul 2026 00:21:03 -0700 (PDT) X-Forwarded-Encrypted: i=2; AHgh+RqoOWbn4myXZv0uyf6ugNHYnB7OCrmxcfCzrT8piDSHjrPRs6gVz8TO467FgEzT9sIEG349//FJ8kw=@openvpn.net X-Received: by 2002:a05:6870:ac28:b0:456:5873:3b56 with SMTP id 586e51a60fabf-4586c9ea3e1mr3461488fac.27.1785309662909; Wed, 29 Jul 2026 00:21:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1785309662; cv=none; d=google.com; s=arc-20260327; b=ZO2LWUTTNjpOxZU4NTSlj3QI5vXg2x98tCyEcvaVPGt0gwEd9wrcMcSsDTdPo+Llum g7Qo1ZzPLrQbptXDBcYLwwNJTqFk6oYqcZYKvOk63TffoVF+aSCZSExa2VSjQIxsFhpT t+37eBmZdImmSotzB5946CSJP3sNOi95J8/Kei5L1kUSl2Y2f6M+7LZnSLQ/XRr7GSos UUDbPIy86gauY3fUs3UolSnxmpLidipgVhjnPhy3mF7n7+KmiWa/iK/bA5q0bq7mDHYk cURFH8FhMxXibRGTMYntoVxC0Xs+wmihb2jievrRVlbSHzl3EYg5TD3iDMa95aC7HnK5 VwbQ== 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=WV1gq7Pzen/8u1HLK2NQnE+/KJUg4zbN32LEfgyU/kg=; fh=4NbAC/LsuMLI0S0hprUlLSLCiHwg6SCAifhH718Jh0Q=; b=dYe66gKSojf89IXgVAVWTRG1Kxm6W4MLjYMxdYKEZLIE/KbOqhxbkVeBOUnjZN3Rv5 Rh6lL/62FVJXXMCrI6Al7KafA4tweJVGWAPHIPu/d0iXux7bWfBRhJQ8kmP1PP4+hNDw s73ZKGnfsbE7VhshZtzh/ywqUo+NCU2JZ1KzJrE6LCOned9rNkrGOD49nUolwE/tJFRw ShOCAKmH+55IRKgEF0Z/XsMAXS3Nmx7M0VG2SvVV2JMmO1TWSTOAeKBeK7GJwZNu/z8Y NlrWnt/I4QdDm4NtWK/IVsMM8dYP1uOd8NXeOByuipQfBheqOCf/VysDiNIPyAiMRGsI gviw==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=UWyvMnOr; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=hXgLovVd; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=QoIkjPMM; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b=Ebf5OQ+w; 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-45886b4feadsi1988074fac.247.2026.07.29.00.21.02 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 29 Jul 2026 00:21:02 -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=UWyvMnOr; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=hXgLovVd; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=QoIkjPMM; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b=Ebf5OQ+w; 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=WV1gq7Pzen/8u1HLK2NQnE+/KJUg4zbN32LEfgyU/kg=; b=UWyvMnOrcNBT3VJGYXbJlx0f31 mghjcXCiAljME36JlpEHhU7sdf8+TNVUsltkeRzyOdVHidDw2bSS8KhISwPa+VoCdoS/+1pONTpGJ grRxeZDZc2V+L27pZZzaUJPR19FX/ycXai6DRuzdBDcsMS5jMz30jcGVbA0/O+NU2iaU=; 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 1woyb5-0000Bu-C6; Wed, 29 Jul 2026 07:20:59 +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 1woyb4-0000Bn-57 for openvpn-devel@lists.sourceforge.net; Wed, 29 Jul 2026 07:20:58 +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:Cc:To:From:Sender:Reply-To: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=ipEaZg7tfzbAlF4Sgl6jeb1UbMREFHEpCQfumpuH4O4=; b=hXgLovVdz5tsbGMxhK4+WqBl0e GvKkmghEr4m6P+5MNdJPqx9n1fyiU9kuV7S1tTkYkOeP9+V2dMhGaY1iaQnerw/MnuH5Or4BG7V7X lq97NdQcIxblbjj+wJhV1GHFULDxGbS8EPBxNG5WtPnxe54CXN0mUgA/wBHt5N46b3tM=; 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:Cc:To:From:Sender:Reply-To: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=ipEaZg7tfzbAlF4Sgl6jeb1UbMREFHEpCQfumpuH4O4=; b=QoIkjPMM69NnvFrlmAB2dyHuYi 5X46jrvrdJG6y/cQy928WIkZKkdzfe88NmbgucppvRYEH3ZHgWyweA7DzDeborqJAAMQVCjYBgDKo RJ3XkByUKIAo1X6URoBHz+yaddHhXP7yd9cDU/taqBP9e1CSbMsALH19cjRtGABepvDM=; Received: from mout-b-105.mailbox.org ([195.10.208.50]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1woyb5-0004eQ-0i for openvpn-devel@lists.sourceforge.net; Wed, 29 Jul 2026 07:20:58 +0000 Received: from smtp1.mailbox.org (smtp1.mailbox.org [IPv6:2001:67c:2050:b231:465::1]) (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-105.mailbox.org (Postfix) with ESMTPS id 4h93dq4d1zz9tLy; Wed, 29 Jul 2026 09:20:47 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandelbit.com; s=MBO0001; t=1785309647; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ipEaZg7tfzbAlF4Sgl6jeb1UbMREFHEpCQfumpuH4O4=; b=Ebf5OQ+wegkxNvLyjqXi4hEULx3ZoqkHeQTIdS5qzkIBDa1uckZd6GXf9Xe7j1DP1prOwP Wd3Qu/98Vf4ooVvwHtehWOOY6CjQRvijMUyWn+wSDpgYQzjWjZb2UA5Ojm5n0TidS0Rzbt tBaDBVWDZ8wiSCeIow1W01VeRRsynJl3tGGd9GuIE/AZpPClmi976g/QUlKM0JT5msS0ut aAVk0e31pxQfRMhBjKF3v18fta2IVHUGMBTQMHEHlf1uHq5qbKwwq5qWIFfgbrBWpKmK0J afk0kp+yi1eEcs258+xszbjAEjjHHzklf0P5d4icnGkriTSy/WVBbuUXDIItjw== Authentication-Results: outgoing_mbo_mout; dkim=none; spf=pass (outgoing_mbo_mout: domain of ralf@mandelbit.com designates 2001:67c:2050:b231:465::1 as permitted sender) smtp.mailfrom=ralf@mandelbit.com From: Ralf Lici To: openvpn-devel@lists.sourceforge.net Date: Wed, 29 Jul 2026 09:20:32 +0200 Message-ID: <87f7c1a6eea0005a067889e9b6f73fc6bd4f40e1.1785308184.git.ralf@mandelbit.com> In-Reply-To: References: MIME-Version: 1.0 X-Rspamd-Queue-Id: 4h93dq4d1zz9tLy 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: 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_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -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.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [195.10.208.50 listed in wl.mailspike.net] X-Headers-End: 1woyb5-0004eQ-0i Subject: [Openvpn-devel] [PATCH ovpn net v2 1/5] 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: 1872032865184295881 X-GMAIL-MSGID: 1872032865184295881 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 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 291e2e5bb450..883a28d69d8e 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 Wed Jul 29 07:20:33 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ralf Lici X-Patchwork-Id: 5161 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:fd0b:b0:87d:ab56:3700 with SMTP id cw11csp1591227mac; Wed, 29 Jul 2026 00:21:03 -0700 (PDT) X-Forwarded-Encrypted: i=2; AHgh+RqPw8JEUojPn3n/O5E+6vf9IJVdBTdCjG5Yb3mE0BmJgJW1r8KOXsUztBy9ycsIXOSPlyxzbx/uC1Q=@openvpn.net X-Received: by 2002:a05:6871:800b:b0:451:b9ed:5684 with SMTP id 586e51a60fabf-4586cd13461mr2897790fac.34.1785309663142; Wed, 29 Jul 2026 00:21:03 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1785309663; cv=none; d=google.com; s=arc-20260327; b=GCizJlhtHc/lLBRj+xUEgURapEjPME1lxHKjZ1NqzS1HLTCmWlGm8hqlYWI/oOje60 dSf78goCVltFsfhZ6WYpUFcfBnXYYb4bidzYb3CdPfmudiZbIm79PGs9MVtvHw+wHYPC CfYZ957c8Ff/LWGRNEQU1bz6MkPaiuCQtgOmxB12sunJMYajrE6M1FjCjtd5woDLXalA wB950bmiv3S6S8iBqtqIMPO2Kpif2RQ/g+DjB/NH2x5lPKNh6QT4oBf4KirGZu44WjYY xepruZTuIhMl6svZKGF4ZJsOT/a44dbMZ6F7ne4LqEpfXYbrw0HGqvrOadqF8J3HM7CB 0LiQ== 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=4ljfiyeO3VDJQ4sgKYBTKTmTdsjkIKSSTTuadrFUADc=; fh=4NbAC/LsuMLI0S0hprUlLSLCiHwg6SCAifhH718Jh0Q=; b=fbsZFm7OH7VVfm0hKmiQYjuxfGU5xUbGaE+njAv5cT4Ws01PT1NfEPFpJ4KirunhvB rskp+h1e8fyp66D3N+wHAj9Ezmnnzns8ZrEarsoVXnGGiGNxAqxicjYgNDShFlc44Ota JQUw9VizrUnA8dOASOAernygfOz5Ve4G5uj+RBtGTW1fcdShH7BhFBFudZgSR27jCCcH dqCVAR05mhMMOhnMwCcmi+sLDnVzL/6qZRmEU1ipFJnjTUCdwEAmAg/h6LGAQngiX1NH gJnKdF8PFdI/KE9t8v9KtKX9oMmST7WSECYRLkT13dIkYTydMH3DVjyyfnkaAKj4U8HI PNXA==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=Yu57yea8; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=SqGzpPnt; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=Jd5RayPH; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b=Ycju+t9l; 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-45886b51045si1867708fac.246.2026.07.29.00.21.02 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 29 Jul 2026 00:21:03 -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=Yu57yea8; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=SqGzpPnt; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=Jd5RayPH; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b=Ycju+t9l; 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=4ljfiyeO3VDJQ4sgKYBTKTmTdsjkIKSSTTuadrFUADc=; b=Yu57yea8j49WBk+xeeJwusjR8Z WClswy0YM1zFpy7F3wtdfyoLYpsnHMp+whyYwkJj9WBEZMV2MyBwnkAK3KzZNdH/06k40/kB64WrF aYZgNd9OeeDPeLxUH8JttZV5gh5hLdG3j/7sx5D30+c/Xej9tMpPoT9G8mvsWh3CE1Yo=; 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 1woyb4-0003zq-GX; Wed, 29 Jul 2026 07:20:59 +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 1woyb2-0003zi-Dw for openvpn-devel@lists.sourceforge.net; Wed, 29 Jul 2026 07:20:57 +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:Cc:To:From:Sender:Reply-To: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=oGXHWlz0X58ND2Q1t9QiDKv7FLuqLrjAxFhwirx7mLI=; b=SqGzpPntyvDktUQZGk5m+r2hD3 l5I9tpeLV3xUI9dX4GRwgHmMXRwBp0U+ycGz6Moj56CScH4FWkGMvSqiCv0KhYOrsYRflu8qHmn8O 6EewKOaVSGkSx+DvDOnIyaDQYR9LQKKX/nvRdKv68GhUG3+xeSnirgmN71n1dfZfnep8=; 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:Cc:To:From:Sender:Reply-To: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=oGXHWlz0X58ND2Q1t9QiDKv7FLuqLrjAxFhwirx7mLI=; b=Jd5RayPHRUJIqmVe9t9R8Q/Ge9 NKoHDZnTBa4flv2OXsNdshuDMLXKJ+G755gNRoAaWzex0gAHGzqGBfq1uvRuW255mw1QtEQqmM4pV yzpwVBzVxzEg1cAHk2E/bjKXbAmtfZCkn8rqPC35cmtzNp4JOMbSE1UnFh7tbmoiqi0U=; Received: from mout-b-203.mailbox.org ([195.10.208.52]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1woyb2-0005D8-CB for openvpn-devel@lists.sourceforge.net; Wed, 29 Jul 2026 07:20:57 +0000 Received: from smtp1.mailbox.org (smtp1.mailbox.org [IPv6:2001:67c:2050:b231:465::1]) (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-203.mailbox.org (Postfix) with ESMTPS id 4h93dr3h28zLlsF; Wed, 29 Jul 2026 09:20:48 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandelbit.com; s=MBO0001; t=1785309648; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=oGXHWlz0X58ND2Q1t9QiDKv7FLuqLrjAxFhwirx7mLI=; b=Ycju+t9l8IPHzChtQsL5T3gYL7fzINRcTpJvfDj+jYs6XwknDa2tBPxdjGAkDAy9UHv+7Z A7PvgkWoOnDXqHkdwsQAbtTGVQPMBEAkVw9lbi5/jkk7TpxxleKa5vXsPeHZ8W5Fe4llTP eS7JfZZrZMwZk7f/m+6J1d3jdVVIjH9YRaOlF7d0O49kI1wy2RDfQyi4fZpD8zkCQ9zq94 1HnoFc4wIl8vqCFPGmnOlGJo+qlEShz0dMU0bgBFVaO3aoyFdEgXQYpKHRGuz0LQzrh4Ye lfUrE3bvtn3sYrDKDXv2X6G68DrfezUzVZwnRAhtzrRaRrggJA8Jlz6embJIuw== Authentication-Results: outgoing_mbo_mout; dkim=none; spf=pass (outgoing_mbo_mout: domain of ralf@mandelbit.com designates 2001:67c:2050:b231:465::1 as permitted sender) smtp.mailfrom=ralf@mandelbit.com From: Ralf Lici To: openvpn-devel@lists.sourceforge.net Date: Wed, 29 Jul 2026 09:20:33 +0200 Message-ID: In-Reply-To: References: MIME-Version: 1.0 X-Rspamd-Queue-Id: 4h93dr3h28zLlsF 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_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_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid X-Headers-End: 1woyb2-0005D8-CB Subject: [Openvpn-devel] [PATCH ovpn net v2 2/5] 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: 1872032865047528965 X-GMAIL-MSGID: 1872032865047528965 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 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 493a5a0744af..eb342c7eef29 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 Wed Jul 29 07:20:34 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ralf Lici X-Patchwork-Id: 5164 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:fd0b:b0:87d:ab56:3700 with SMTP id cw11csp1591313mac; Wed, 29 Jul 2026 00:21:07 -0700 (PDT) X-Forwarded-Encrypted: i=2; AHgh+RrPttSJLuhf1PYNK81OSWKHiU9GYPApi6ngsHiwykwM0ljrrq6l5kQ6+ixwPXMxswGBi35Hh5OF9mE=@openvpn.net X-Received: by 2002:a05:6820:1793:b0:6a1:3fff:a863 with SMTP id 006d021491bc7-6ac96c299camr2720116eaf.49.1785309667600; Wed, 29 Jul 2026 00:21:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1785309667; cv=none; d=google.com; s=arc-20260327; b=eJ7tWRmW4HK18uF5yEFJbdCbJGo6n7w8PDx23/Y/DFk3P3Q6xqwc96xwBOVr3pDHyx MJ48+AN0ooC2l/dzhPQ+bjYoiwoxWQGMTTtHm7+fq6+M7JdgHhzWlkazLPOii/u18R2M RINvlSN+ajAxZjQcPd8f5gSp7GEqSNeYbFcGjQRbv1EI5FW/SBx5x+KQrA3tbGxFuECE NArWypLGmCj1QJ3cdMJMX0/De7RK4XcW7lkHXFKt3DWlG/FgBu18AhWeQ1Ce4qb/iUrQ BngMhOTPImgP90HbQJChcO2N3Og3/ofnRfWFbsbCAmBfaEfTybmXc2rGLqiOZiL+0ysO 6dtw== 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=8/VdNDD6br3qtYnovb1gtEJtQLrtPBMpFbqrH/TzULs=; fh=4NbAC/LsuMLI0S0hprUlLSLCiHwg6SCAifhH718Jh0Q=; b=JBn7XkTZWT7z/d3bdO8G2LqfkhN8CJeeoIg/jk0kD1Nawf4tS2/whY2BYjndrDJdrQ Se5eMLxeEfrzPZCMwGpEelXESpvlQoQLYD08sryH9yrxy513SsXXCQUvNOtg4yKi7bv9 +isDuGCM5W19mAkrTYDmr49SS37Q9Sfxxl/kbZy/ldmoevqkwj2zpqY9zJ8OtsnmZl3C pel46cKECluIPT5p6ybE4hTTxvsZp+56FbaPmVQ0sGD/aqMx+cpXbnwxdP959wcMjyqc 6soJSJlHMnlVkvKfSQn/Lrg9wM7Mi9dPJGG9tk0aZcQ9aXAwAenqZluciY6Vp7+2aHQd 9h0w==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=NDnxJyZ2; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=Nt5KvuGj; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=Qus6LiSR; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b=JPMDHJjW; 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-45886b4fdd5si2010181fac.233.2026.07.29.00.21.07 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 29 Jul 2026 00:21:07 -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=NDnxJyZ2; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=Nt5KvuGj; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=Qus6LiSR; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b=JPMDHJjW; 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=8/VdNDD6br3qtYnovb1gtEJtQLrtPBMpFbqrH/TzULs=; b=NDnxJyZ27hL3ENARhuiRQjwu+b IIH4v70QUFIFY6Ndzx8dmXV5ZLFVvcRxdzs7uUkGZ7XO4q4hVv1FCyDmCsQtd0f2GqgZmQPHN4BRn QULKiaIc0SrEgQdGEyoH0YNWuoHITRrPANTICC5cs+gxiH+Nx92Gr31B2FwWvj0p41Hc=; 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 1woybA-0000Cd-Mn; Wed, 29 Jul 2026 07:21:04 +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 1woyb7-0000CM-Pj for openvpn-devel@lists.sourceforge.net; Wed, 29 Jul 2026 07:21:01 +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:Cc:To:From:Sender:Reply-To: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=STLroDnus9LsbjuVp2hTvs0trhRnUMgl7rpByrNHwLA=; b=Nt5KvuGjsf5G0KPKF8pCSsxrSS ty6W4GIZs+6TG3MKOQkKhOWZMlaHDT9Icd2uGw66YifkkWTvMArYN7TA7q/LdwrWWxairdOkinuvN 0izfVuQaJp6EsPKzegp+XS/9kjKXeYBlnNbBA619XDQdJDTshT2gR6WHaEHix1HEefvY=; 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:Cc:To:From:Sender:Reply-To: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=STLroDnus9LsbjuVp2hTvs0trhRnUMgl7rpByrNHwLA=; b=Qus6LiSRSbXZjJtPu0JCi9oX3x NZ7en/GOiAYsA3Utni+he3PZxI2pIDgRBD6qPi0H2WMkJcqVrgaid8+MkPnwfmBFnLqvsp6rGeGCf s2YOPvrW2/dXa7w2RMCOrELGpycjj7me5aO8+GJp64QM5K6XgLnOhOaq/phUSchD0cJ8=; Received: from mout-b-112.mailbox.org ([195.10.208.42]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1woyb3-0005D9-JO for openvpn-devel@lists.sourceforge.net; Wed, 29 Jul 2026 07:21:01 +0000 Received: from smtp1.mailbox.org (unknown [10.196.197.1]) (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-112.mailbox.org (Postfix) with ESMTPS id 4h93ds2Dhhz5wDD; Wed, 29 Jul 2026 09:20:49 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandelbit.com; s=MBO0001; t=1785309649; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=STLroDnus9LsbjuVp2hTvs0trhRnUMgl7rpByrNHwLA=; b=JPMDHJjW8RJmRmmi3OiBhXY5ERuY9pMFDF8HfiHSJK5TUyonnRrvQPfHyosDIyDw9bFVng CM1zbk5GZbHBFHnAU1ad44Mjgq7CQhvO2scJT7TnRpe/fWEsQ0bNBm31+QlhRDjqKKYkmu vxaoCErjwDWDEnQoDRz4tGMxK2by7J+vQ1AmE2VX3DnSRKoU0+L776Vds5rilmmHG1Y+IH 35uAvKYG25LOpXlbdNv6gKRBWgL0wlx0vmhRf6wRKa3b09ex8ef1t8OaKol018VSsqLSm2 HElcxpOSpoohE7iEp+priBHTBBPNLpuc5bxKrYwV9WmO6I2R+u9notq/euW3lA== From: Ralf Lici To: openvpn-devel@lists.sourceforge.net Date: Wed, 29 Jul 2026 09:20:34 +0200 Message-ID: <15a79f79de3cf192bc862acfd07534c1995f7ad8.1785308184.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-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: 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_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -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 X-Headers-End: 1woyb3-0005D9-JO Subject: [Openvpn-devel] [PATCH ovpn net v2 3/5] 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: 1872032869762691992 X-GMAIL-MSGID: 1872032869762691992 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 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 c02dfab51a6e..4806e942be27 100644 --- a/drivers/net/ovpn/peer.c +++ b/drivers/net/ovpn/peer.c @@ -112,6 +112,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 328401570cba..72a9cbb8c31f 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 eb342c7eef29..e43b946c8289 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 Wed Jul 29 07:20:35 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ralf Lici X-Patchwork-Id: 5162 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:fd0b:b0:87d:ab56:3700 with SMTP id cw11csp1591270mac; Wed, 29 Jul 2026 00:21:05 -0700 (PDT) X-Forwarded-Encrypted: i=2; AHgh+RpwvmVWjRfflsMYhRu35EFm8zxgHYxhn/ZdNWszdBIuhYW0aiGiVl7jk9TBMvRTmZLKl/0f3guZazE=@openvpn.net X-Received: by 2002:a05:6820:2d49:b0:6a3:7437:3c61 with SMTP id 006d021491bc7-6ac96c533a2mr2576307eaf.57.1785309665103; Wed, 29 Jul 2026 00:21:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1785309665; cv=none; d=google.com; s=arc-20260327; b=A9fHV/dVzpD2RBvjGdmQ2EPMyQYm0oHnvo3RQVimei4GhpP4AwDIZbFbzZxZf2THpe UJ3mstkiYN4ivuGkvvgK0LaUtvQ7SbnoxSgVjALZaSEn4Ypt9M1RpRb0x92UqgjTTy0F lYXTC8t/aR8GLo8i6R7g1zGhSL9AmzitjNo12GkTj4G0TSk5mNlcd00pzdXt1DMeDvy1 RdlNd5qAN6IHYGo9LL8H7KXKJ1Q1Uid6h64U1z1pY7NBEV6eVz0zyBWj+3qI/P5akCba hba7z85ZgtDC4Z4WdrhwrKlhaJ2MHzLp1wzkW8Ipt09tK0glXZVZuSd2Y501lSurAr+2 wlWA== 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=4RUYp5DWQ+9ckPfsNtsG/38/xTxV/0tjAlJSzNYiOX4=; fh=4NbAC/LsuMLI0S0hprUlLSLCiHwg6SCAifhH718Jh0Q=; b=BRQDTFqcgkaM3z+z5MmWz7tyIHtsUfwOMZLCZIXrXF7v0aWPhNJOXE+QbUG1YEWs+I B9pF1w7bx8sJEyODZ+AA+w0+1J8l0dVc9h7lty+AV8VfrUSJYSYUXprHtXUmRvWZGTn7 /qRNvDzG06uhekGSnqb8i19q1ZQ+2XRYXik9JAAfnlt8JIznoRPTQRzI7y0Ib7NBJwq4 v4novJnIs4GwOLo6U7QauQb0SVYFZOl6L8w2m/K6tMK58HMn7Ga8fP0I3g2p8xRZQR86 2bnIEanUwKu8Tn5ENc3P3wR53nngBqcy8Dn7kJOERBvyNNWSLpttfd0HICJ4Y7IBxpCv 0deg==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=D1pHkE6S; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b="XNCslx/f"; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=TbkTuvhN; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b=DJClmo3S; 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-45886cb0452si1885983fac.359.2026.07.29.00.21.04 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 29 Jul 2026 00:21:05 -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=D1pHkE6S; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b="XNCslx/f"; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=TbkTuvhN; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b=DJClmo3S; 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=4RUYp5DWQ+9ckPfsNtsG/38/xTxV/0tjAlJSzNYiOX4=; b=D1pHkE6St1xrAdREGEIs01QAEs 7dk/vjCqokCxTHd3T1XzTq6Nw4Gk8O4dabfWgePON8AjqQbjUyG1TUOAlJ9y8aTXy/SwUfXKZTlQc dzCqzJSICneM81USyugsngaRtaL2JjQnRVi9AwDquW+hnlcnH36JvTQW5pGeLDL3p3Xs=; 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 1woyb6-0003fH-Ui; Wed, 29 Jul 2026 07:21:01 +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 1woyb5-0003ep-8B for openvpn-devel@lists.sourceforge.net; Wed, 29 Jul 2026 07:21:00 +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:Cc:To:From:Sender:Reply-To: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=CtZDNY1+Y75MIpkfMo8eQmOheAJnJhCZlHBKpozqcG0=; b=XNCslx/fH2hQoezDQN+1VYu5QW zT2BkAQWBNO0PGeAtVtSncUoXuXn+dn8pt/rJ8Y3gYfqIMkCSGN0GzT/RMu+YRwF1Idx7wXHm4mrD acTmhwm/f+J3RPA0VT6txuI83ckWQiuaazlO/vvgTmGcqWkyc7hs2VGRGkpMrXqrh4WQ=; 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:Cc:To:From:Sender:Reply-To: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=CtZDNY1+Y75MIpkfMo8eQmOheAJnJhCZlHBKpozqcG0=; b=TbkTuvhNKH7c3UISSIcTj/QteB HYuG+v9YWNCdXweEBkEc6ictlEQ0olhQzHuqJD4jMmTPW+kt5InQtCGtF0DWvu/a0tKSzM7ZI/W1E WxbTAxlNu5XkntELxainuvhOg0wn/wjFioD516/jIpo9OA5i81YOdBdpXBxpEx0I/W48=; Received: from mout-b-203.mailbox.org ([195.10.208.52]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1woyb8-0004eU-39 for openvpn-devel@lists.sourceforge.net; Wed, 29 Jul 2026 07:20:59 +0000 Received: from smtp1.mailbox.org (unknown [10.196.197.1]) (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-203.mailbox.org (Postfix) with ESMTPS id 4h93dt1Cw7zLltF; Wed, 29 Jul 2026 09:20:50 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandelbit.com; s=MBO0001; t=1785309650; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=CtZDNY1+Y75MIpkfMo8eQmOheAJnJhCZlHBKpozqcG0=; b=DJClmo3SuZCGkxnzSdCKvOk8XD/7LJgm7HM5s1XRxFH5K8j9VY7TFMdd03xUvWYReTuduz x/A48Q99OU0CUerdAk6Q6sAAhzSvtT6STHztIMymYmFUMQ5SUPQ/AOvuoUbeuMgefVWYO3 cVq7noLSAPuq6Z+VUwmj9UomcXwOfdpsOSap9s+Ce2ro0R+r5/2Dr0GE0PWe4rNSF/Iy0H uswx1ufpD0V4mf4cNUxhKl2bWJNfoXVJ8ER9v6i99336ScE85pLA8ISvVjPnCQ0s75GlCs H9TdyX3L82nzqBUL/IaGlzGgkfon1E7GcrrjapEXLemWRcJIMn3YA2urv0bK9g== From: Ralf Lici To: openvpn-devel@lists.sourceforge.net Date: Wed, 29 Jul 2026 09:20:35 +0200 Message-ID: <082540583b9145d89e1cdd5a74c485ea3a53d285.1785308184.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-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: struct ovpn_bind is published through peer->bind with RCU. Remote endpoint changes already replace the whole bind object, but local endpoint learning and UDP source fallback still updated bind->local [...] Content analysis details: (-0.2 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -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 X-Headers-End: 1woyb8-0004eU-39 Subject: [Openvpn-devel] [PATCH ovpn net v2 4/5] ovpn: avoid in-place updates of peer bind local address 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: 1872032867244334234 X-GMAIL-MSGID: 1872032867244334234 struct ovpn_bind is published through peer->bind with RCU. Remote endpoint changes already replace the whole bind object, but local endpoint learning and UDP source fallback still updated bind->local in place. UDP TX can read it locklessly while another CPU updates it under peer->lock. For IPv6, that can produce torn reads of the address field. Fix this by making the local endpoint immutable after publication too: build a new bind object with the updated local address and publish it through peer->bind. When UDP TX discovers that the remembered local source is no longer usable, retry route lookup with a wildcard source. If the lookup succeeds and the bind used for the lookup is still current, invalidate the peer dst cache and best-effort publish a replacement bind with wildcard local address. The current packet can still be transmitted with the resolved route even if that bind replacement fails; a later cache miss will retry the repair. Only store the resolved dst when the local address did not need to be reset. A local address change invalidates all per-CPU dst cache entries, while dst_cache_set_ip4 and dst_cache_set_ip6 only update the current CPU slot. Avoid the old reset-then-set pattern and let the next TX repopulate the cache from the new bind state. Fixes: f0281c1d3732 ("ovpn: add support for updating local or remote UDP endpoint") Fixes: 08857b5ec5d9 ("ovpn: implement basic TX path (UDP)") Signed-off-by: Ralf Lici --- No changes since v1 https://lore.kernel.org/openvpn-devel/082540583b9145d89e1cdd5a74c485ea3a53d285.1785253480.git.ralf@mandelbit.com/ drivers/net/ovpn/peer.c | 36 +++++++++----- drivers/net/ovpn/udp.c | 108 +++++++++++++++++++++++++++++++--------- 2 files changed, 107 insertions(+), 37 deletions(-) diff --git a/drivers/net/ovpn/peer.c b/drivers/net/ovpn/peer.c index 4806e942be27..383d712582c9 100644 --- a/drivers/net/ovpn/peer.c +++ b/drivers/net/ovpn/peer.c @@ -197,12 +197,11 @@ int ovpn_peer_reset_sockaddr(struct ovpn_peer *peer, void ovpn_peer_endpoints_update(struct ovpn_peer *peer, struct sk_buff *skb) { struct hlist_nulls_head *nhead; + 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; spin_lock_bh(&peer->lock); @@ -224,7 +223,6 @@ void ovpn_peer_endpoints_update(struct ovpn_peer *peer, struct sk_buff *skb) sa->sin_addr.s_addr = ip_hdr(skb)->saddr; sa->sin_port = udp_hdr(skb)->source; salen = sizeof(*sa); - reset_cache = true; break; } @@ -236,8 +234,7 @@ 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; } break; case htons(ETH_P_IPV6): @@ -254,7 +251,6 @@ void ovpn_peer_endpoints_update(struct ovpn_peer *peer, struct sk_buff *skb) sa6->sin6_scope_id = ipv6_iface_scope_id(&ipv6_hdr(skb)->saddr, skb->skb_iif); salen = sizeof(*sa6); - reset_cache = true; break; } @@ -267,26 +263,40 @@ 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; } break; 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)) + /* if there was no float and the local address is unchanged, bail out */ + if (likely(!salen && !local_ip)) goto unlock; + /* if only the local address changed, populate ss with the current + * remote + */ + if (!salen) + memcpy(&ss, &bind->remote, + bind->remote.in4.sin_family == AF_INET ? + sizeof(struct sockaddr_in) : + sizeof(struct sockaddr_in6)); + 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 the peer did not float, we can bail out now */ + if (!salen) + goto unlock; + net_dbg_ratelimited("%s: peer %d floated to %pIScp", netdev_name(peer->ovpn->dev), peer->id, &ss); diff --git a/drivers/net/ovpn/udp.c b/drivers/net/ovpn/udp.c index e43b946c8289..ced4f9ff4a08 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 or replace the bind. + */ +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 @@ -189,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, @@ -207,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); } @@ -238,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_route_key_equal(key, &peer->route_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: @@ -271,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; @@ -291,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); @@ -311,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_route_key_equal(key, &peer->route_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: From patchwork Wed Jul 29 07:20:36 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ralf Lici X-Patchwork-Id: 5163 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:fd0b:b0:87d:ab56:3700 with SMTP id cw11csp1591271mac; Wed, 29 Jul 2026 00:21:05 -0700 (PDT) X-Forwarded-Encrypted: i=2; AHgh+RoWeEOh8nKulvSI1YHQrOEKe8jS2KccqA0tXRo6MY6M7SiN/kbdrfE6VCBkYODW+K3Yufm3KZKcMws=@openvpn.net X-Received: by 2002:a05:6820:200d:b0:6aa:e844:fb2c with SMTP id 006d021491bc7-6ac96a7f973mr2415067eaf.7.1785309665453; Wed, 29 Jul 2026 00:21:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1785309665; cv=none; d=google.com; s=arc-20260327; b=FzfDC0SvlY2FH/3wkgs+vWgwnNB/pn93iaHUGO9q318qIM2T2oyH9di4zv5pjPG1L9 9GhJCWC1HUiMfmGNPksrUqR+7jTauLUjv8DtplLeC8FTuJCyvWobkLYEit7Sbhr+mrbq rxjw+32DyLgZsYNdqUHEBrLrY3r57NzeQutZYAknVbLpbsAkr+ssdIUFzQ0Dc0twEBWU c9aE51IsFmBcPIK7QaGXnkV+EFdbn8Jlt6jkXq5EaPXYgybYkqe5LrOcW9faez+j6x4C 7uv5foyRsWfGMmy5V1mbncaz/9hbtL8IyKMvWJ9y44WlA+H7C9JLJlBBvRz4fgmZ0DZF NkoQ== 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=hHtzRsKbfUPaNqUZwKuBtjv1tDojxCxK0GzZa0PWIv4=; fh=4NbAC/LsuMLI0S0hprUlLSLCiHwg6SCAifhH718Jh0Q=; b=dFaqyyVZ5yF+34sURnwudXs7AxzC3UbAveJ0ir2iQlWgrMbHfylArugUp6qJEgBRmi glQr/Rr8SNjTZj7HwE0G5zTgVyqKXjMfhYDcWkq4ZId92u/mTiJEU2UUEnLKANX+2bjp e9h1yyT7amN5FZUtDS83KWMjCLQZEeftk5mzp+VPpri1JeOmZs7GXMVAAz5ji8aKpoYy aDhVaiRZaQcP4qRgQCjZHo0WkNeVllqylEIZ75r38ogqJBZLfjut1PKUwaQRQqvieF59 ESkEGZwpasnvWSDm8riEjWWU4GJxDHhWOIVE/pDdWFQnU5YArPUu6TqdXc7jMlzJ/KfC Hpdg==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=PGyK0TPu; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b="FaZY/Rkw"; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=Nz2uGR2g; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b=FfX6UhJX; 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-6aca55110efsi1246012eaf.74.2026.07.29.00.21.05 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 29 Jul 2026 00:21:05 -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=PGyK0TPu; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b="FaZY/Rkw"; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=Nz2uGR2g; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b=FfX6UhJX; 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=hHtzRsKbfUPaNqUZwKuBtjv1tDojxCxK0GzZa0PWIv4=; b=PGyK0TPuwWeCyQ1JpX+FIYeCzU GXfw4fjT9ZDiD8NDrBMMeh94CGaETReyiswLQFUqFU0q83ApydVygWsvbK7c36jm7ZDLpx4SYbX61 oOjq/oYRWqQbdhczqxWKw5l8chO48w+c0gl49/3mL66Iz0uUX6bWw9rdV5mz23XNFIYE=; 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 1woybA-0006Cz-63; Wed, 29 Jul 2026 07:21:01 +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 1woyb8-0006Ch-GU for openvpn-devel@lists.sourceforge.net; Wed, 29 Jul 2026 07:21:00 +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:Cc:To:From:Sender:Reply-To: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=WlSjJprjE27nbG6MAH0mKdobcRi/jozOgltDv1/cdxY=; b=FaZY/RkwiDBisFf8AVqqrfLxFd NkqbMRt9yHq3nP68HMT5KEyIFK5tFn8TP4G3gZ+If7ggb+kIKRLxbPuL1o/fBegTrPZN9P0yCl/sd 8UK9BN+c6bPHLlwc6OU5t7mcDfOmhkweQOtyQXWx6P7u65RXmIYrXp4s5g8bx0Y03fQg=; 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:Cc:To:From:Sender:Reply-To: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=WlSjJprjE27nbG6MAH0mKdobcRi/jozOgltDv1/cdxY=; b=Nz2uGR2gNLfA5ZJc1pUuI+lLFt vCLKP+1bL27wwb9NBkQ/leudMX3z3a3bVZRTSv5R+TSrasEzky7+ayRLfHvFdcvyc2yfHlHJqYkms 1yqPpuI5yIAURoqpelVew0hMDDE/cPX46rVkw5v52ACjpx8rG4hJfs9rTkex02fXu5SI=; Received: from mout-b-107.mailbox.org ([195.10.208.47]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1woyb8-0004eW-Ni for openvpn-devel@lists.sourceforge.net; Wed, 29 Jul 2026 07:20:59 +0000 Received: from smtp1.mailbox.org (unknown [10.196.197.1]) (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-107.mailbox.org (Postfix) with ESMTPS id 4h93dt63MKz3wvY; Wed, 29 Jul 2026 09:20:50 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandelbit.com; s=MBO0001; t=1785309650; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=WlSjJprjE27nbG6MAH0mKdobcRi/jozOgltDv1/cdxY=; b=FfX6UhJXOYCi0zUHFbiXB6bObeZDFMyuNcaEZyo7DpOwwdwlj37Bx1XZT2cVfS1SQRGbl1 3dK/zG8s0p4BlXqCwFx5ka71n/MJ7A59jFUQfzLluBI1EYqxPlnMxZDdfKu+9/omBYm7Cf OzqFgZHTH1wUQDQb/50jryBpKolXLmxpCmQ3h3n/UFG12uIe3q5xUex+Q/02NZXLYp/WCF Oa0BkW740swYKGArSJqrTJseVUpuK8qeX1Lss+91nQgAozswsl4MGDTyYYK4Z2pwSPyOOl c+A0UZ3g1Q/nmGtKe1xlYXyVol0jgddkgljFqlB3HJjLkBL3Kir29rxFlaJUbw== From: Ralf Lici To: openvpn-devel@lists.sourceforge.net Date: Wed, 29 Jul 2026 09:20:36 +0200 Message-ID: <25d830e082b03afb4615aaeed6e0dc1d1370ecbc.1785308184.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 IPv6 route used for UDP transmission in a per-peer dst cache. IPv6 dst validation uses a cookie derived from the route itself, or, for routes without their own sernum, from the associa [...] 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_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid X-Headers-End: 1woyb8-0004eW-Ni Subject: [Openvpn-devel] [PATCH ovpn net v2 5/5] ovpn: avoid caching stale IPv6 dst after FIB changes 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: 1872032867630572633 X-GMAIL-MSGID: 1872032867630572633 ovpn stores the IPv6 route used for UDP transmission in a per-peer dst cache. IPv6 dst validation uses a cookie derived from the route itself, or, for routes without their own sernum, from the associated fib6 node. If the IPv6 FIB changes after ip6_dst_lookup_flow returns but before dst_cache_set_ip6 reads the cookie, ovpn can store an old dst with a new cookie. Later dst_cache_get_ip6 can then consider that stale dst valid because the stored cookie matches the updated fib6 node sernum. Sample the IPv6 FIB generation before and after route lookup, and only populate ovpn's peer dst cache if the generation did not change while the lookup was in flight. Also add a dst_cache helper that stores a caller-provided IPv6 cookie, so the cached dst carries the cookie sampled from the lookup result instead of one read after a concurrent FIB update. The current packet may still be transmitted with the route returned by the lookup if the FIB changes before TX completion. This patch only prevents that potentially stale route from being preserved in ovpn's peer dst cache and reused for later packets. Fixes: 08857b5ec5d9 ("ovpn: implement basic TX path (UDP)") Signed-off-by: Ralf Lici --- Changes since v1 https://lore.kernel.org/openvpn-devel/d6c941fe19455b940dd24019e32b121f332fdc95.1785253480.git.ralf@mandelbit.com/ - Add smp_rmb barriers after the initial generation read and before the final generation read to avoid reordering around the lookup on weakly ordered architectures (Sashiko). drivers/net/ovpn/udp.c | 50 ++++++++++++++++++++++++++++------------- include/net/dst_cache.h | 13 +++++++++++ net/core/dst_cache.c | 16 +++++++++---- 3 files changed, 60 insertions(+), 19 deletions(-) diff --git a/drivers/net/ovpn/udp.c b/drivers/net/ovpn/udp.c index ced4f9ff4a08..e429bfa694fc 100644 --- a/drivers/net/ovpn/udp.c +++ b/drivers/net/ovpn/udp.c @@ -316,9 +316,11 @@ static int ovpn_udp6_output(struct ovpn_peer *peer, struct ovpn_bind *bind, { struct in6_addr local = in6addr_any; struct sockaddr_storage remote; + struct net *net = sock_net(sk); bool reset_local = false; struct dst_entry *dst; - int ret; + int gen0, gen1, ret; + u32 cookie; struct flowi6 fl = { .saddr = bind->local.ipv6, @@ -344,7 +346,11 @@ static int ovpn_udp6_output(struct ovpn_peer *peer, struct ovpn_bind *bind, reset_local = true; } - dst = ip6_dst_lookup_flow(sock_net(sk), sk, &fl, NULL); + gen0 = rt_genid_ipv6(net); + /* keep the unordered initial generation read before the FIB lookup */ + smp_rmb(); + + dst = ip6_dst_lookup_flow(net, sk, &fl, NULL); if (IS_ERR(dst)) { ret = PTR_ERR(dst); net_dbg_ratelimited("%s: no route to host %pISpc: %d\n", @@ -353,27 +359,41 @@ static int ovpn_udp6_output(struct ovpn_peer *peer, struct ovpn_bind *bind, goto err; } + cookie = rt6_get_cookie(dst_rt6_info(dst)); + + /* keep the FIB and cookie reads before the final generation read */ + smp_rmb(); + gen1 = rt_genid_ipv6(net); + /* avoid storing a stale cache or local address */ spin_lock_bh(&peer->lock); if (likely(ovpn_dst_cache_current(peer, bind, key))) { - if (!reset_local) { - dst_cache_set_ip6(cache, dst, &fl.saddr); + /* cache the dst with the original cookie only if the learned + * local source was not reset and the FIB did not change + */ + if (!reset_local && likely(gen0 == gen1)) { + dst_cache_set_ip6_cookie(cache, dst, &fl.saddr, cookie); spin_unlock_bh(&peer->lock); goto transmit; } - /* invalidate per-CPU dst entries that may still carry - * the stale source - */ - dst_cache_reset(cache); + if (reset_local) { + /* 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); + } - /* 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); diff --git a/include/net/dst_cache.h b/include/net/dst_cache.h index 1961699598e2..5f9cc4fe926c 100644 --- a/include/net/dst_cache.h +++ b/include/net/dst_cache.h @@ -45,6 +45,19 @@ void dst_cache_set_ip4(struct dst_cache *dst_cache, struct dst_entry *dst, #if IS_ENABLED(CONFIG_IPV6) +/** + * dst_cache_set_ip6_cookie - store ipv6 dst with caller-provided cookie + * @dst_cache: the cache + * @dst: the entry to be cached + * @saddr: the source address to be stored inside the cache + * @cookie: the route validation cookie to store with @dst + * + * local BH must be disabled. + */ +void dst_cache_set_ip6_cookie(struct dst_cache *dst_cache, + struct dst_entry *dst, + const struct in6_addr *saddr, u32 cookie); + /** * dst_cache_set_ip6 - store the ipv6 dst into the cache * @dst_cache: the cache diff --git a/net/core/dst_cache.c b/net/core/dst_cache.c index 9ab4902324e1..1b5e825818ab 100644 --- a/net/core/dst_cache.c +++ b/net/core/dst_cache.c @@ -117,8 +117,9 @@ void dst_cache_set_ip4(struct dst_cache *dst_cache, struct dst_entry *dst, EXPORT_SYMBOL_GPL(dst_cache_set_ip4); #if IS_ENABLED(CONFIG_IPV6) -void dst_cache_set_ip6(struct dst_cache *dst_cache, struct dst_entry *dst, - const struct in6_addr *saddr) +void dst_cache_set_ip6_cookie(struct dst_cache *dst_cache, + struct dst_entry *dst, + const struct in6_addr *saddr, u32 cookie) { struct dst_cache_pcpu *idst; @@ -128,11 +129,18 @@ void dst_cache_set_ip6(struct dst_cache *dst_cache, struct dst_entry *dst, local_lock_nested_bh(&dst_cache->cache->bh_lock); idst = this_cpu_ptr(dst_cache->cache); - dst_cache_per_cpu_dst_set(idst, dst, - rt6_get_cookie(dst_rt6_info(dst))); + dst_cache_per_cpu_dst_set(idst, dst, cookie); idst->in6_saddr = *saddr; local_unlock_nested_bh(&dst_cache->cache->bh_lock); } +EXPORT_SYMBOL_GPL(dst_cache_set_ip6_cookie); + +void dst_cache_set_ip6(struct dst_cache *dst_cache, struct dst_entry *dst, + const struct in6_addr *saddr) +{ + dst_cache_set_ip6_cookie(dst_cache, dst, saddr, + rt6_get_cookie(dst_rt6_info(dst))); +} EXPORT_SYMBOL_GPL(dst_cache_set_ip6); struct dst_entry *dst_cache_get_ip6(struct dst_cache *dst_cache,