From patchwork Wed Jul 29 15:38:12 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marco Baffo X-Patchwork-Id: 5176 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:fd0b:b0:87d:ab56:3700 with SMTP id cw11csp2127481mac; Wed, 29 Jul 2026 08:38:47 -0700 (PDT) X-Forwarded-Encrypted: i=2; AHgh+RpEwtzEi6LfI9Mu4Pg+/ffwp/Hbj2XPzcN5y7XR/4uzI9Cg1IljYZBYuj6zxP8fej67Nn7UkvHtHO0=@openvpn.net X-Received: by 2002:a05:6808:e8c:b0:497:c1f1:1511 with SMTP id 5614622812f47-4ad5b87f3a3mr3954175b6e.16.1785339526778; Wed, 29 Jul 2026 08:38:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1785339526; cv=none; d=google.com; s=arc-20260327; b=SmcCI1+/42GCzPCE4XK322Lqq+edhMS5aejAHjYjhtrUrg0y31E1dmOCjF6Yy3MIEu LtTdKEYkPY1xdEC+pDrzw1J+V3tyVIDIVWDQfp3HffD/A8IWzkyQCb9u1fe8KZj4G1Mc +7225xb1DEswZTHW4c0M3g10qp0EtokAegZ9QUQ4zfnrNIzbfwtz3b6JBBQz26sVfNNX OLR0Pbprp4SvTpNWw4N6GRLA5vuBnWHqw6xTX0UfNkpmR6sJWiyciVc2GopviBPRcRzv /QcPLywmINstYB8fwil/DzRk7m5bTzWoyEH5nEURTxk1NPrBxinjtr3Cxzj5a2eDdj8Q hS/A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; h=errors-to:content-transfer-encoding:cc:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence:subject :mime-version:message-id:date:to:from:dkim-signature:dkim-signature :dkim-signature:dkim-signature; bh=flU2E9eHjxcY3BwRUmf+82nVyOm0GTN9MmO78CNQxYw=; fh=BsMg/B0Yb/hS/rzP5Npz4luh0IleZm8REk1XWiWRt2A=; b=S+MJ7qj0uNovAstrfme9fFBobkkOQff3D31NJifZYrfxT6tUkfeqgu+JG0cYR/yrv/ Fy65Gm+N6+LI0vDwfozXyEZVInrJmjpGvtX+XnNYSPVa2cYO2asWlViW1y564MY7qAKB o+B3w0GmhNIHu8/BAB+/6k2ISpSla+OxM0zHnsfWHKssN0LBeTacdlbaLa1CUm+YI9fk SOwzIME6hBYEWw/LvglcWqwyNd3T5dl0RufKqWYzeiK6UTdiU8dGeQ9jDzED34TNKqXc 78rLaGldvDGm586IfcRtKnQEA86lcWKD9nYFg5/uTtHOrzIrg+7M1r9LGz64/U6o5caW Cw7w==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=CUbw5l+i; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=mzN89rTV; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=jiQlFlMm; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b=tmeihN2o; 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-4ad6eca6eb9si1775145b6e.13.2026.07.29.08.38.46 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 29 Jul 2026 08:38:46 -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=CUbw5l+i; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=mzN89rTV; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=jiQlFlMm; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b=tmeihN2o; 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:Cc: List-Subscribe:List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id: Subject:MIME-Version:Message-ID:Date:To:From:Sender:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Owner; bh=flU2E9eHjxcY3BwRUmf+82nVyOm0GTN9MmO78CNQxYw=; b=CUbw5l+iIVtCS5vCm7zRrYM+cS QouLggIepFstdYCtt7Hzit4pNi4YdPKOrS6osYjCP1DFT5+oltQLc9TyNGIiyTV7ACWyRcwvMCQwk PQOOWk1Xzw9MTgHuCTQDghW5gK8divg01/penQ0yTmp7LxfnO+UQ4y8KqYpA8eSf8amk=; 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 1wp6Mk-00006q-6b; Wed, 29 Jul 2026 15:38:39 +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 1wp6Mh-00006h-7S for openvpn-devel@lists.sourceforge.net; Wed, 29 Jul 2026 15:38:37 +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: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:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=Lb0YP1uJIfAnj2rVGAeXX6Qm4EZjASdPl0bfvXjvuNY=; b=mzN89rTV1yZRAs4VWZeowkGXyl kibyR2qUDJMur+BPiFFaE/35YSlnFxrJo5q3RhD9YaYYtWJ169hhU4l9JACIN77dGrLvTRpMWTyLF am+rsMQ3BwnIG4GcDidjG4SkLvNQVpFJGUlOmEDpUPzhpcG3ovCeLxk0g5nhB/QrZr58=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version: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:In-Reply-To: References:List-Id:List-Help:List-Unsubscribe:List-Subscribe:List-Post: List-Owner:List-Archive; bh=Lb0YP1uJIfAnj2rVGAeXX6Qm4EZjASdPl0bfvXjvuNY=; b=j iQlFlMmkAIt6nDSSXYbOQB4xE6U2dCR0bi/3kHFEBsVPfRRotprmI2E6zq/9751rM+cUzImjrdfyH uss5zInrF8jPjf+IQUgY5ul0wB91CThvSaMKn8XUrUFxMwPEBY+2N95jPRYF59VNBVQVo7cqPFYCG hVbWJeAVLLzctMLQ=; Received: from mout-b-210.mailbox.org ([195.10.208.40]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1wp6Mb-0002oE-Bq for openvpn-devel@lists.sourceforge.net; Wed, 29 Jul 2026 15:38:35 +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-210.mailbox.org (Postfix) with ESMTPS id 4h9Gh130fpzFr08; Wed, 29 Jul 2026 17:38:25 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandelbit.com; s=MBO0001; t=1785339505; 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; bh=Lb0YP1uJIfAnj2rVGAeXX6Qm4EZjASdPl0bfvXjvuNY=; b=tmeihN2oK7/SCfvTOo1v06n7OWBT6pY7yUMoXHIuHQp4O4B2CSBTSih90XQgR1mcSObWvr cLL4Xca3+nMqK37a/wIJBaCxfgqFyTN9dskTI7piMZIod7u5R4xz8Y3FrewDarT37Cd6+V VYySsGCICvlySi8sT/C9zRcNAWD6wqSX+JX6SECHcFuF/BVk5qA53aM2ruC1Lf+znMzARO /r6NbyIAbZZa4di5yBdPvQ4fgcOgYdtux2W3I32qBnDOvOxyG+IDxhYQsIV/KN+Y43GNy7 M1q/49QZ5spqRGO0np38fHbuAyK0j5RBUbRv9BeOCe+84ugKJnX28A6LwkN9fw== Authentication-Results: outgoing_mbo_mout; dkim=none; spf=pass (outgoing_mbo_mout: domain of marco@mandelbit.com designates 2001:67c:2050:b231:465::1 as permitted sender) smtp.mailfrom=marco@mandelbit.com From: Marco Baffo To: openvpn-devel@lists.sourceforge.net Date: Wed, 29 Jul 2026 17:38:12 +0200 Message-ID: <20260729153815.2637139-1-marco@mandelbit.com> MIME-Version: 1.0 X-Rspamd-Queue-Id: 4h9Gh130fpzFr08 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 currently looks up the target interface in the network namespace associated with the netlink socket. This prevents a userspace process from controlling an ovpn interface located in another namesp [...] 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: 1wp6Mb-0002oE-Bq Subject: [Openvpn-devel] [PATCH ovpn net-next v3 1/4] ovpn: support operations on interfaces in foreign netns 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: , Cc: Antonio Quartulli Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox X-GMAIL-THRID: 1872064179805157747 X-GMAIL-MSGID: 1872064179805157747 ovpn currently looks up the target interface in the network namespace associated with the netlink socket. This prevents a userspace process from controlling an ovpn interface located in another namespace. Add the optional OVPN_A_TARGET_NETNSID attribute. When present, it identifies the namespace containing the target interface relative to the namespace of the requesting Netlink socket. Resolve the ID and perform the interface lookup there. When absent, preserve the existing lookup behavior. Allow the attribute in all peer and key request policies, including peer dump requests. Signed-off-by: Marco Baffo --- Changes in v3: - None. Changes in v2: - Improved Doc. Documentation/netlink/specs/ovpn.yaml | 27 ++++++++++++++++ drivers/net/ovpn/netlink-gen.c | 45 ++++++++++++++++----------- drivers/net/ovpn/netlink.c | 17 ++++++++++ include/uapi/linux/ovpn.h | 1 + 4 files changed, 72 insertions(+), 18 deletions(-) diff --git a/Documentation/netlink/specs/ovpn.yaml b/Documentation/netlink/specs/ovpn.yaml index b0c782e59a32..1f0d4d6037c0 100644 --- a/Documentation/netlink/specs/ovpn.yaml +++ b/Documentation/netlink/specs/ovpn.yaml @@ -337,12 +337,20 @@ attribute-sets: type: nest doc: Peer specific cipher configuration nested-attributes: keyconf + - + name: target-netnsid + type: s32 + doc: >- + ID of the network namespace containing the ovpn interface, relative to + the network namespace of the requesting Netlink socket - name: ovpn-peer-new-input subset-of: ovpn attributes: - name: ifindex + - + name: target-netnsid - name: peer nested-attributes: peer-new-input @@ -352,6 +360,8 @@ attribute-sets: attributes: - name: ifindex + - + name: target-netnsid - name: peer nested-attributes: peer-set-input @@ -361,6 +371,8 @@ attribute-sets: attributes: - name: ifindex + - + name: target-netnsid - name: peer nested-attributes: peer-del-input @@ -370,6 +382,8 @@ attribute-sets: attributes: - name: ifindex + - + name: target-netnsid - name: keyconf nested-attributes: keyconf-get @@ -379,6 +393,8 @@ attribute-sets: attributes: - name: ifindex + - + name: target-netnsid - name: keyconf nested-attributes: keyconf-swap-input @@ -388,6 +404,8 @@ attribute-sets: attributes: - name: ifindex + - + name: target-netnsid - name: keyconf nested-attributes: keyconf-del-input @@ -405,6 +423,7 @@ operations: request: attributes: - ifindex + - target-netnsid - peer - name: peer-set @@ -417,6 +436,7 @@ operations: request: attributes: - ifindex + - target-netnsid - peer - name: peer-get @@ -429,6 +449,7 @@ operations: request: attributes: - ifindex + - target-netnsid - peer reply: attributes: @@ -437,6 +458,7 @@ operations: request: attributes: - ifindex + - target-netnsid reply: attributes: - peer @@ -451,6 +473,7 @@ operations: request: attributes: - ifindex + - target-netnsid - peer - name: peer-del-ntf @@ -469,6 +492,7 @@ operations: request: attributes: - ifindex + - target-netnsid - keyconf - name: key-get @@ -481,6 +505,7 @@ operations: request: attributes: - ifindex + - target-netnsid - keyconf reply: attributes: @@ -496,6 +521,7 @@ operations: request: attributes: - ifindex + - target-netnsid - keyconf - name: key-swap-ntf @@ -515,6 +541,7 @@ operations: request: attributes: - ifindex + - target-netnsid - keyconf - diff --git a/drivers/net/ovpn/netlink-gen.c b/drivers/net/ovpn/netlink-gen.c index 2147cec7c2c5..3f513e3675a3 100644 --- a/drivers/net/ovpn/netlink-gen.c +++ b/drivers/net/ovpn/netlink-gen.c @@ -118,55 +118,64 @@ const struct nla_policy ovpn_peer_set_input_nl_policy[OVPN_A_PEER_TX_ID + 1] = { }; /* OVPN_CMD_PEER_NEW - do */ -static const struct nla_policy ovpn_peer_new_nl_policy[OVPN_A_PEER + 1] = { +static const struct nla_policy ovpn_peer_new_nl_policy[OVPN_A_TARGET_NETNSID + 1] = { [OVPN_A_IFINDEX] = { .type = NLA_U32, }, + [OVPN_A_TARGET_NETNSID] = { .type = NLA_S32, }, [OVPN_A_PEER] = NLA_POLICY_NESTED(ovpn_peer_new_input_nl_policy), }; /* OVPN_CMD_PEER_SET - do */ -static const struct nla_policy ovpn_peer_set_nl_policy[OVPN_A_PEER + 1] = { +static const struct nla_policy ovpn_peer_set_nl_policy[OVPN_A_TARGET_NETNSID + 1] = { [OVPN_A_IFINDEX] = { .type = NLA_U32, }, + [OVPN_A_TARGET_NETNSID] = { .type = NLA_S32, }, [OVPN_A_PEER] = NLA_POLICY_NESTED(ovpn_peer_set_input_nl_policy), }; /* OVPN_CMD_PEER_GET - do */ -static const struct nla_policy ovpn_peer_get_do_nl_policy[OVPN_A_PEER + 1] = { +static const struct nla_policy ovpn_peer_get_do_nl_policy[OVPN_A_TARGET_NETNSID + 1] = { [OVPN_A_IFINDEX] = { .type = NLA_U32, }, + [OVPN_A_TARGET_NETNSID] = { .type = NLA_S32, }, [OVPN_A_PEER] = NLA_POLICY_NESTED(ovpn_peer_nl_policy), }; /* OVPN_CMD_PEER_GET - dump */ -static const struct nla_policy ovpn_peer_get_dump_nl_policy[OVPN_A_IFINDEX + 1] = { +static const struct nla_policy ovpn_peer_get_dump_nl_policy[OVPN_A_TARGET_NETNSID + 1] = { [OVPN_A_IFINDEX] = { .type = NLA_U32, }, + [OVPN_A_TARGET_NETNSID] = { .type = NLA_S32, }, }; /* OVPN_CMD_PEER_DEL - do */ -static const struct nla_policy ovpn_peer_del_nl_policy[OVPN_A_PEER + 1] = { +static const struct nla_policy ovpn_peer_del_nl_policy[OVPN_A_TARGET_NETNSID + 1] = { [OVPN_A_IFINDEX] = { .type = NLA_U32, }, + [OVPN_A_TARGET_NETNSID] = { .type = NLA_S32, }, [OVPN_A_PEER] = NLA_POLICY_NESTED(ovpn_peer_del_input_nl_policy), }; /* OVPN_CMD_KEY_NEW - do */ -static const struct nla_policy ovpn_key_new_nl_policy[OVPN_A_KEYCONF + 1] = { +static const struct nla_policy ovpn_key_new_nl_policy[OVPN_A_TARGET_NETNSID + 1] = { [OVPN_A_IFINDEX] = { .type = NLA_U32, }, + [OVPN_A_TARGET_NETNSID] = { .type = NLA_S32, }, [OVPN_A_KEYCONF] = NLA_POLICY_NESTED(ovpn_keyconf_nl_policy), }; /* OVPN_CMD_KEY_GET - do */ -static const struct nla_policy ovpn_key_get_nl_policy[OVPN_A_KEYCONF + 1] = { +static const struct nla_policy ovpn_key_get_nl_policy[OVPN_A_TARGET_NETNSID + 1] = { [OVPN_A_IFINDEX] = { .type = NLA_U32, }, + [OVPN_A_TARGET_NETNSID] = { .type = NLA_S32, }, [OVPN_A_KEYCONF] = NLA_POLICY_NESTED(ovpn_keyconf_get_nl_policy), }; /* OVPN_CMD_KEY_SWAP - do */ -static const struct nla_policy ovpn_key_swap_nl_policy[OVPN_A_KEYCONF + 1] = { +static const struct nla_policy ovpn_key_swap_nl_policy[OVPN_A_TARGET_NETNSID + 1] = { [OVPN_A_IFINDEX] = { .type = NLA_U32, }, + [OVPN_A_TARGET_NETNSID] = { .type = NLA_S32, }, [OVPN_A_KEYCONF] = NLA_POLICY_NESTED(ovpn_keyconf_swap_input_nl_policy), }; /* OVPN_CMD_KEY_DEL - do */ -static const struct nla_policy ovpn_key_del_nl_policy[OVPN_A_KEYCONF + 1] = { +static const struct nla_policy ovpn_key_del_nl_policy[OVPN_A_TARGET_NETNSID + 1] = { [OVPN_A_IFINDEX] = { .type = NLA_U32, }, + [OVPN_A_TARGET_NETNSID] = { .type = NLA_S32, }, [OVPN_A_KEYCONF] = NLA_POLICY_NESTED(ovpn_keyconf_del_input_nl_policy), }; @@ -178,7 +187,7 @@ static const struct genl_split_ops ovpn_nl_ops[] = { .doit = ovpn_nl_peer_new_doit, .post_doit = ovpn_nl_post_doit, .policy = ovpn_peer_new_nl_policy, - .maxattr = OVPN_A_PEER, + .maxattr = OVPN_A_TARGET_NETNSID, .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO, }, { @@ -187,7 +196,7 @@ static const struct genl_split_ops ovpn_nl_ops[] = { .doit = ovpn_nl_peer_set_doit, .post_doit = ovpn_nl_post_doit, .policy = ovpn_peer_set_nl_policy, - .maxattr = OVPN_A_PEER, + .maxattr = OVPN_A_TARGET_NETNSID, .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO, }, { @@ -196,14 +205,14 @@ static const struct genl_split_ops ovpn_nl_ops[] = { .doit = ovpn_nl_peer_get_doit, .post_doit = ovpn_nl_post_doit, .policy = ovpn_peer_get_do_nl_policy, - .maxattr = OVPN_A_PEER, + .maxattr = OVPN_A_TARGET_NETNSID, .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO, }, { .cmd = OVPN_CMD_PEER_GET, .dumpit = ovpn_nl_peer_get_dumpit, .policy = ovpn_peer_get_dump_nl_policy, - .maxattr = OVPN_A_IFINDEX, + .maxattr = OVPN_A_TARGET_NETNSID, .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DUMP, }, { @@ -212,7 +221,7 @@ static const struct genl_split_ops ovpn_nl_ops[] = { .doit = ovpn_nl_peer_del_doit, .post_doit = ovpn_nl_post_doit, .policy = ovpn_peer_del_nl_policy, - .maxattr = OVPN_A_PEER, + .maxattr = OVPN_A_TARGET_NETNSID, .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO, }, { @@ -221,7 +230,7 @@ static const struct genl_split_ops ovpn_nl_ops[] = { .doit = ovpn_nl_key_new_doit, .post_doit = ovpn_nl_post_doit, .policy = ovpn_key_new_nl_policy, - .maxattr = OVPN_A_KEYCONF, + .maxattr = OVPN_A_TARGET_NETNSID, .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO, }, { @@ -230,7 +239,7 @@ static const struct genl_split_ops ovpn_nl_ops[] = { .doit = ovpn_nl_key_get_doit, .post_doit = ovpn_nl_post_doit, .policy = ovpn_key_get_nl_policy, - .maxattr = OVPN_A_KEYCONF, + .maxattr = OVPN_A_TARGET_NETNSID, .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO, }, { @@ -239,7 +248,7 @@ static const struct genl_split_ops ovpn_nl_ops[] = { .doit = ovpn_nl_key_swap_doit, .post_doit = ovpn_nl_post_doit, .policy = ovpn_key_swap_nl_policy, - .maxattr = OVPN_A_KEYCONF, + .maxattr = OVPN_A_TARGET_NETNSID, .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO, }, { @@ -248,7 +257,7 @@ static const struct genl_split_ops ovpn_nl_ops[] = { .doit = ovpn_nl_key_del_doit, .post_doit = ovpn_nl_post_doit, .policy = ovpn_key_del_nl_policy, - .maxattr = OVPN_A_KEYCONF, + .maxattr = OVPN_A_TARGET_NETNSID, .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO, }, }; diff --git a/drivers/net/ovpn/netlink.c b/drivers/net/ovpn/netlink.c index 4c66c1ec497e..b70ecfaf46c8 100644 --- a/drivers/net/ovpn/netlink.c +++ b/drivers/net/ovpn/netlink.c @@ -38,6 +38,7 @@ ovpn_get_dev_from_attrs(struct net *net, const struct genl_info *info, { struct ovpn_priv *ovpn; struct net_device *dev; + struct net *target_net = NULL; int ifindex; if (GENL_REQ_ATTR_CHECK(info, OVPN_A_IFINDEX)) @@ -45,12 +46,26 @@ ovpn_get_dev_from_attrs(struct net *net, const struct genl_info *info, ifindex = nla_get_u32(info->attrs[OVPN_A_IFINDEX]); + if (info->attrs[OVPN_A_TARGET_NETNSID]) { + /* Target netns IDs are relative to the requesting Netlink socket */ + target_net = get_net_ns_by_id(net, nla_get_s32(info->attrs[OVPN_A_TARGET_NETNSID])); + if (!target_net) { + NL_SET_ERR_MSG_MOD(info->extack, + "invalid target network namespace ID"); + NL_SET_BAD_ATTR(info->extack, + info->attrs[OVPN_A_TARGET_NETNSID]); + return ERR_PTR(-EINVAL); + } + net = target_net; + } + rcu_read_lock(); dev = dev_get_by_index_rcu(net, ifindex); if (!dev) { rcu_read_unlock(); NL_SET_ERR_MSG_MOD(info->extack, "ifindex does not match any interface"); + put_net(target_net); return ERR_PTR(-ENODEV); } @@ -59,12 +74,14 @@ ovpn_get_dev_from_attrs(struct net *net, const struct genl_info *info, NL_SET_ERR_MSG_MOD(info->extack, "specified interface is not ovpn"); NL_SET_BAD_ATTR(info->extack, info->attrs[OVPN_A_IFINDEX]); + put_net(target_net); return ERR_PTR(-EINVAL); } ovpn = netdev_priv(dev); netdev_hold(dev, tracker, GFP_ATOMIC); rcu_read_unlock(); + put_net(target_net); return ovpn; } diff --git a/include/uapi/linux/ovpn.h b/include/uapi/linux/ovpn.h index 06690090a1a9..3fdf24182df4 100644 --- a/include/uapi/linux/ovpn.h +++ b/include/uapi/linux/ovpn.h @@ -85,6 +85,7 @@ enum { OVPN_A_IFINDEX = 1, OVPN_A_PEER, OVPN_A_KEYCONF, + OVPN_A_TARGET_NETNSID, __OVPN_A_MAX, OVPN_A_MAX = (__OVPN_A_MAX - 1) From patchwork Wed Jul 29 15:38:13 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marco Baffo X-Patchwork-Id: 5177 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:fd0b:b0:87d:ab56:3700 with SMTP id cw11csp2127850mac; Wed, 29 Jul 2026 08:39:08 -0700 (PDT) X-Forwarded-Encrypted: i=2; AHgh+RpjM5qzf2z5kNowei6c4Nwtdo4ZlttLAzKY+dcd+fr7/V3zkpv/W8ZmbG/dDICXr08lBsy7yeOAoac=@openvpn.net X-Received: by 2002:a05:6870:ac13:b0:43e:e5bf:1ab4 with SMTP id 586e51a60fabf-4586cd1cec4mr4096567fac.21.1785339548300; Wed, 29 Jul 2026 08:39:08 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1785339548; cv=none; d=google.com; s=arc-20260327; b=kFi+52Y6TwVPGYXpyuMnsGzucMzBoq10sXDpyAnTd+UBx31vgOSiJruuSTRCVJ70g5 dWK2D9VAJHuNPEPZxa6jWmPwkeQ1fQeN3d1siX2hqhKvmsL8jUKsqLFrPO0e1DTuS4mM nj6wceIBmUF1ZZJ7AYGjj9qeUCaiU1yQuWbtjOlxYtUvztsNeCB5r0T+PiyFeYrh8m8D VftwbVa70UgNAswPiahdzVLr7hEPQ1Pp+zZ/r9YFYfV1WhxIFzqU8HqWwH1QAEG2kyYp BzbrHiYF9Heo++zxXhPm5isjBTpLHX+SAKESOrurts2GwekIGQmPIWcZGk8v94zWgcE3 ooxw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; h=errors-to:content-transfer-encoding:cc: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=vZy8/s1/M3pW3MqUAPtGervPmvq3KSBM+HQm5wXq11Y=; fh=BsMg/B0Yb/hS/rzP5Npz4luh0IleZm8REk1XWiWRt2A=; b=sdo1EQO8DRQTJp9KvpKVnTmsLSTuuzJn+az4PHYPYAt9H53l37JDavpTmRgcrW9aqV 9B6jNPpbSxozMc45F4BAPFC2NaeHc+budAaOemkw0wTYXJ4kjdv1wmE4WJnllfUZ0VEl ZVfDiE65UloyWTLCCL5nL1WrYJmfxw0BA4tCNKEYftGZxbz5cQIqZl55K4loVUNo7YVX gVkc4nqiUc9t05spCd29b7SWTAhtask8ZOmUtTmywGZ7lw4RH0weYSNjZ6JD0bVu1s82 KjKQmYRjul2HYru50oFQqoIes9YI1rT2P2IPTxezC82RunEhz7SIZ6iVe8lIoMhcsRki o9NQ==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=DUrLCZpg; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=Wts+6xUQ; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=c5KsnzHP; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b=SrSKeWdb; 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-45886b510c2si2789984fac.229.2026.07.29.08.39.07 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 29 Jul 2026 08:39:08 -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=DUrLCZpg; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=Wts+6xUQ; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=c5KsnzHP; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b=SrSKeWdb; 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:Cc: 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:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender :Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=vZy8/s1/M3pW3MqUAPtGervPmvq3KSBM+HQm5wXq11Y=; b=DUrLCZpg8vZskzN3JdKPjq/DIF GpP3EVyIdnbkEySlmwcYj3MIw1MNkW9qA7MT3G6fs7vv12FeiV6jRz0s8Zj9VwyvfKsXPMFiGXEvZ TVcA5Ft5T+14pIgHgNfN+CCGWqEy190YFsRz1TxNo9EvwtABTtuk3h4CyP5nyyBmaI9E=; 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 1wp6N7-0002Ms-6x; Wed, 29 Jul 2026 15:39:05 +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 1wp6N5-0002Mk-KU for openvpn-devel@lists.sourceforge.net; Wed, 29 Jul 2026 15:39:03 +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=g2NhgoJnpn0gnAXzqvlVQGlVg8JdU49jbycZsnpmd8g=; b=Wts+6xUQ1L67jke7Oenwu0DsWr 2oQSjtJ6s86MKOBbxAWWULgyL5ZKnZlVu5ybOa7A95TnCgTGikSrqox69zM6w0k6E330kO6tgI4Yy Ll5XTdfoPLNWQuIOAK/4JaC3gehOvHKZdXiPqrZgfIJySTDoywAKJ8ZkjMUNuW4QDz+A=; 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=g2NhgoJnpn0gnAXzqvlVQGlVg8JdU49jbycZsnpmd8g=; b=c5KsnzHPY+oq4Wd/pj0TI26xi3 +qG5gZPVv68DaFNuD87zBmbnWV1jIcmuMLdDEchT9QX3HvRYy61MShwS/Yg92pvyXqIOso6N6VXcp Zc8xKuef6S8vmdOkOYmAOxzVtF+T0By9i4EhMJUwIgxtXd/hy6FXOY6hXnDTCh/iuGsU=; Received: from mout-b-201.mailbox.org ([195.10.208.61]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1wp6N1-0002oq-Ik for openvpn-devel@lists.sourceforge.net; Wed, 29 Jul 2026 15:39:03 +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-201.mailbox.org (Postfix) with ESMTPS id 4h9GhX1kSbzLm5m; Wed, 29 Jul 2026 17:38:52 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandelbit.com; s=MBO0001; t=1785339532; 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=g2NhgoJnpn0gnAXzqvlVQGlVg8JdU49jbycZsnpmd8g=; b=SrSKeWdbwjzNqSA/H8Kbp9bn9oY2NOPAoKKgQgi/sw08caI+fXMEEo19zFbEnhkBAVDBWi UIlzeqmkocGntTwKVop2QbtV2SXsbAJTt53slP2a54IV0Kkb/+GWEzI/+HsBh6maQZcfHX DdrqgLGRhSqAWKFoLwcXtLElJvMDCUQ6Etq7+YmUh19ZbSAt0CTjNMvN2qbKoL34Q4ggYK 8WUuUtZxm1ZR/xWORsnSez2lovumrlvw3YK/ie65+K4KRpdl6SCydKC7Sk1DA1FTLEAjbA wZBfij4vk8N5L7d+5HuUJH0p2XdTjpx41UBodEy833/T8zC1cyViBTjokUf2iQ== Authentication-Results: outgoing_mbo_mout; dkim=none; spf=pass (outgoing_mbo_mout: domain of marco@mandelbit.com designates 2001:67c:2050:b231:465::1 as permitted sender) smtp.mailfrom=marco@mandelbit.com From: Marco Baffo To: openvpn-devel@lists.sourceforge.net Date: Wed, 29 Jul 2026 17:38:13 +0200 Message-ID: <20260729153815.2637139-2-marco@mandelbit.com> In-Reply-To: <20260729153815.2637139-1-marco@mandelbit.com> References: <20260729153815.2637139-1-marco@mandelbit.com> MIME-Version: 1.0 X-Rspamd-Queue-Id: 4h9GhX1kSbzLm5m 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 notifications are multicast in the network namespace of the peer transport socket, but carry an ifindex from the ovpn device namespace. If these namespaces differ, the ifindex alone is ambiguous [...] Content analysis details: (-0.2 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 URIBL_BLOCKED ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [URI: mandelbit.com] -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: 1wp6N1-0002oq-Ik Subject: [Openvpn-devel] [PATCH ovpn net-next v3 2/4] ovpn: include target netns ID in notifications 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: , Cc: Antonio Quartulli Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox X-GMAIL-THRID: 1872064202238064756 X-GMAIL-MSGID: 1872064202238064756 ovpn notifications are multicast in the network namespace of the peer transport socket, but carry an ifindex from the ovpn device namespace. If these namespaces differ, the ifindex alone is ambiguous to listeners. Include the device namespace ID relative to the receiving namespace when the two namespaces differ. Notifications may be generated from softirq context, so use peernet2id() without allocating a namespace ID. When the Netlink control and transport sockets share a namespace, the mapping normally already exists because it was needed to address the foreign interface. Otherwise, report NETNSA_NSID_NOT_ASSIGNED unless userspace established the mapping beforehand. Fixes: 89d3c0e4612a ("ovpn: kill key and notify userspace in case of IV exhaustion") Fixes: a215d253c17a ("ovpn: notify userspace when a peer is deleted") Fixes: c841b676da98 ("ovpn: notify userspace on client float event") Signed-off-by: Marco Baffo --- Changes in v3: - Removed changes in the ovpn.yaml . - Changed peernet2id_alloc() to peernet2id() to avoid potential deadlock when the notication is send from softirq context (peer-float, key-swap). Changes in v2: - This is a new patch. drivers/net/ovpn/netlink.c | 90 +++++++++++++++++++++----------------- 1 file changed, 50 insertions(+), 40 deletions(-) diff --git a/drivers/net/ovpn/netlink.c b/drivers/net/ovpn/netlink.c index b70ecfaf46c8..81953467e6fb 100644 --- a/drivers/net/ovpn/netlink.c +++ b/drivers/net/ovpn/netlink.c @@ -1167,6 +1167,47 @@ int ovpn_nl_key_del_doit(struct sk_buff *skb, struct genl_info *info) return 0; } +static int ovpn_nl_send_notify(struct ovpn_peer *peer, struct sk_buff *msg, + void *hdr) +{ + struct ovpn_socket *sock; + struct net *net_sock, *net_dev; + int netnsid, ret = 0; + + rcu_read_lock(); + sock = rcu_dereference(peer->sock); + if (!sock) { + ret = -EINVAL; + goto unlock; + } + + net_sock = sock_net(sock->sk); + net_dev = dev_net(peer->ovpn->dev); + + /* The notification is delivered in the transport socket's netns. If the + * ovpn device is elsewhere, report its netns ID relative to that netns. + */ + if (!net_eq(net_sock, net_dev)) { + /* Peer-float and key-swap notifications may be generated from + * softirq context, so do not allocate an NSID here. If none + * exists, peernet2id() returns NETNSA_NSID_NOT_ASSIGNED. + */ + netnsid = peernet2id(net_sock, net_dev); + if (nla_put_s32(msg, OVPN_A_TARGET_NETNSID, netnsid)) { + ret = -EMSGSIZE; + goto unlock; + } + } + + genlmsg_end(msg, hdr); + genlmsg_multicast_netns(&ovpn_nl_family, net_sock, msg, 0, + OVPN_NLGRP_PEERS, GFP_ATOMIC); +unlock: + rcu_read_unlock(); + + return ret; +} + /** * ovpn_nl_peer_del_notify - notify userspace about peer being deleted * @peer: the peer being deleted @@ -1175,7 +1216,6 @@ int ovpn_nl_key_del_doit(struct sk_buff *skb, struct genl_info *info) */ int ovpn_nl_peer_del_notify(struct ovpn_peer *peer) { - struct ovpn_socket *sock; struct sk_buff *msg; struct nlattr *attr; int ret = -EMSGSIZE; @@ -1209,22 +1249,12 @@ int ovpn_nl_peer_del_notify(struct ovpn_peer *peer) nla_nest_end(msg, attr); - genlmsg_end(msg, hdr); - - rcu_read_lock(); - sock = rcu_dereference(peer->sock); - if (!sock) { - ret = -EINVAL; - goto err_unlock; - } - genlmsg_multicast_netns(&ovpn_nl_family, sock_net(sock->sk), msg, 0, - OVPN_NLGRP_PEERS, GFP_ATOMIC); - rcu_read_unlock(); + ret = ovpn_nl_send_notify(peer, msg, hdr); + if (ret < 0) + goto err_cancel_msg; return 0; -err_unlock: - rcu_read_unlock(); err_cancel_msg: genlmsg_cancel(msg, hdr); err_free_msg: @@ -1242,7 +1272,6 @@ int ovpn_nl_peer_del_notify(struct ovpn_peer *peer) int ovpn_nl_peer_float_notify(struct ovpn_peer *peer, const struct sockaddr_storage *ss) { - struct ovpn_socket *sock; struct sockaddr_in6 *sa6; struct sockaddr_in *sa; struct sk_buff *msg; @@ -1291,22 +1320,13 @@ int ovpn_nl_peer_float_notify(struct ovpn_peer *peer, } nla_nest_end(msg, attr); - genlmsg_end(msg, hdr); - rcu_read_lock(); - sock = rcu_dereference(peer->sock); - if (!sock) { - ret = -EINVAL; - goto err_unlock; - } - genlmsg_multicast_netns(&ovpn_nl_family, sock_net(sock->sk), msg, - 0, OVPN_NLGRP_PEERS, GFP_ATOMIC); - rcu_read_unlock(); + ret = ovpn_nl_send_notify(peer, msg, hdr); + if (ret < 0) + goto err_cancel_msg; return 0; -err_unlock: - rcu_read_unlock(); err_cancel_msg: genlmsg_cancel(msg, hdr); err_free_msg: @@ -1323,7 +1343,6 @@ int ovpn_nl_peer_float_notify(struct ovpn_peer *peer, */ int ovpn_nl_key_swap_notify(struct ovpn_peer *peer, u8 key_id) { - struct ovpn_socket *sock; struct nlattr *k_attr; struct sk_buff *msg; int ret = -EMSGSIZE; @@ -1356,21 +1375,12 @@ int ovpn_nl_key_swap_notify(struct ovpn_peer *peer, u8 key_id) goto err_cancel_msg; nla_nest_end(msg, k_attr); - genlmsg_end(msg, hdr); - rcu_read_lock(); - sock = rcu_dereference(peer->sock); - if (!sock) { - ret = -EINVAL; - goto err_unlock; - } - genlmsg_multicast_netns(&ovpn_nl_family, sock_net(sock->sk), msg, 0, - OVPN_NLGRP_PEERS, GFP_ATOMIC); - rcu_read_unlock(); + ret = ovpn_nl_send_notify(peer, msg, hdr); + if (ret < 0) + goto err_cancel_msg; return 0; -err_unlock: - rcu_read_unlock(); err_cancel_msg: genlmsg_cancel(msg, hdr); err_free_msg: From patchwork Wed Jul 29 15:38:14 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marco Baffo X-Patchwork-Id: 5178 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:fd0b:b0:87d:ab56:3700 with SMTP id cw11csp2127946mac; Wed, 29 Jul 2026 08:39:13 -0700 (PDT) X-Forwarded-Encrypted: i=2; AHgh+RonzgxYjs8QqcAmfSZaoK4d9zu5AcbDu9/e8GL8CqPOVo4wEI4z/vrZrVBkr1MMXa9CVrTdcxDJNUI=@openvpn.net X-Received: by 2002:a05:6808:1908:b0:49a:8f0d:cdbb with SMTP id 5614622812f47-4ad5bd29b67mr5053705b6e.31.1785339553197; Wed, 29 Jul 2026 08:39:13 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1785339553; cv=none; d=google.com; s=arc-20260327; b=QJGNd1n44bMuJ9HJJGLp3PVnsrH9uqzHxNvfr0CL4XUjdLQakNiC80q7b72ysyCklI V4gApH339zdZM14JkEWUO0VdYM1u5OzkkNFwK4Eu+RIl7yVRENZkxgdgzyiZcUWuPpkc WRFkEBWRFCEMHx566V0PDZ2H5PjPVJPGElJPMsn5BpsxLWCqzKl3/4MGuk6NaTGelc5U tXeCVbgK7WwnngYZz8x3eleh0StnrKdb0oOzWoiW0r5AsGBrH34tHGHcJ1zqwesdmvkR krOVLWQjSIjJgNRrtna+h898aMiQVBDivPeu+PP8jC/BFhdGbeCN38L/lbU0ecgp4sZv 0KJQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; h=errors-to:content-transfer-encoding:cc: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=NaZ6fRZO//M758KgOqdUF8Zu+57xxcnp0A2y/71pXpo=; fh=BsMg/B0Yb/hS/rzP5Npz4luh0IleZm8REk1XWiWRt2A=; b=Z7rcq+Hgr80zRRwWh6F04121HoU7SIKEWZ0MEuncQh3J0a5TiRc1KhvynpQBlANm3G QaDrRcjPdDbJasx0i9HEYUuItPURzgc0EU5PWcOnYf0Ddk0L5aK6NQFXbbp2lsXAlbxh rXZlW5SJik0Sy9IJ7vPuCoDGqn90u7U74MH4mMx1hDDo14CdFhB1/eDHqyogdyRkG6a8 9fUIgNFwoQQ0TtKbkuSq3JvUlaNzS7ImjzbJGeJgAiBbEWEgf+aWjSy+Tf1e9692gdxp Ih5Z5s843eWLTvrKCNFLFwQYkP0mttH8I5qatElieqodQQcoz2c0vRNYvFOeZ8UTi1zH Or+Q==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=VRTVEpNO; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=cCJ3LIRK; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=EuvxwFH4; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b=tta8xAJK; 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-4ad6eca6eb9si1775827b6e.13.2026.07.29.08.39.12 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 29 Jul 2026 08:39:13 -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=VRTVEpNO; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=cCJ3LIRK; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=EuvxwFH4; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b=tta8xAJK; 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:Cc: 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:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender :Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=NaZ6fRZO//M758KgOqdUF8Zu+57xxcnp0A2y/71pXpo=; b=VRTVEpNOJ2/R6pydtPuajtDgRC Bozl/eWhXiITBoLGHC+w5px1xGm7WLdOmidzAO3UlzIT19OZtg0BFJIwbjuO9zPm5osSWw0H4mD0r 1ajOKp/Dx/Sv4V+pB6xZXwxNkR7Q2z0k4zOYJqVeyC+Ys0qRVR52bH4bplYOkJnejwF8=; 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 1wp6NE-00008M-Lj; Wed, 29 Jul 2026 15:39:10 +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 1wp6ND-00008D-44 for openvpn-devel@lists.sourceforge.net; Wed, 29 Jul 2026 15:39:08 +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=DLxemB7r739PuPvMKLKCiNyWpGf3rKMq5Dl9+FxEFNg=; b=cCJ3LIRK6/Yijcz4lC7PraoBUQ Ry6v2z3vOMXba9lQe9scGq0V+cOpkX+r224YoeTsaqFF6limsU81GPNYmXizx3WFf8y047onlqwZM SkQ5XlaP23NjkIDttRmS/Oh+Gtbb1kEx79GSvdfu/ETqAReULYhnJWN34IMbf0/7ULrI=; 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=DLxemB7r739PuPvMKLKCiNyWpGf3rKMq5Dl9+FxEFNg=; b=EuvxwFH43ODRQBl+Fnqg+sYk8s XViZO194EzPJT5SjiMCFq4NWjlDg5L7Tn6vWhMHVUpEcfssmk2O65gErIVGv7TqycPa6wIhyY8Kz4 VgU6dB6TvNp6GzTrU2VQ3AS3YxV4MEvUuk5Fsm2lvi5zQBB7aG9yhDKojkxYcYeAl+EE=; Received: from mout-b-201.mailbox.org ([195.10.208.61]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1wp6NB-0001Oy-Vb for openvpn-devel@lists.sourceforge.net; Wed, 29 Jul 2026 15:39:08 +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-201.mailbox.org (Postfix) with ESMTPS id 4h9Ghd5wg9zLlqy; Wed, 29 Jul 2026 17:38:57 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandelbit.com; s=MBO0001; t=1785339537; 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=DLxemB7r739PuPvMKLKCiNyWpGf3rKMq5Dl9+FxEFNg=; b=tta8xAJKR/9/oAx30wKfl1xGS/bCJj3QqhW/Dx8Xrz9nuSS5qf394RO78VeCapgYbNKs3k zSb52U3DkZa83yWPuUhynPgNw3+I59BAea2+LRjr+COIv6hs70j4F7qYLWcpqx0yFOrRjv Z38O2ag7zDAALYN6/CjkO56Ye5b5niYC1PtMxx9fdJoeO4R8JOwtYBCh1ocFNQ4aXJadhn D6LhBCW6ChqUH7/idyeWgXb0EgLTY0KRhsJP+1TBWp9gENUxM14TTkm09EQAH/nKmb9wkn 4W2avaPy6exdoLGjCsa/1wgg93fkb+0WSM5/qbPX1r4Dp1qb44cfbLAqZyy+rw== Authentication-Results: outgoing_mbo_mout; dkim=none; spf=pass (outgoing_mbo_mout: domain of marco@mandelbit.com designates 2001:67c:2050:b231:465::1 as permitted sender) smtp.mailfrom=marco@mandelbit.com From: Marco Baffo To: openvpn-devel@lists.sourceforge.net Date: Wed, 29 Jul 2026 17:38:14 +0200 Message-ID: <20260729153815.2637139-3-marco@mandelbit.com> In-Reply-To: <20260729153815.2637139-1-marco@mandelbit.com> References: <20260729153815.2637139-1-marco@mandelbit.com> MIME-Version: 1.0 X-Rspamd-Queue-Id: 4h9Ghd5wg9zLlqy 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: Extend ovpn-cli with -n to resolve an interface in a named network namespace and include OVPN_A_TARGET_NETNSID in peer and key requests. Use -n for existing peer and key operations that do not create transport sockets, exercising foreign-netns requests throughout the test suite. 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: 1wp6NB-0001Oy-Vb Subject: [Openvpn-devel] [PATCH ovpn net-next v3 3/4] selftests: ovpn: test operations in a foreign netns 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: , Cc: Antonio Quartulli Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox X-GMAIL-THRID: 1872064206934645760 X-GMAIL-MSGID: 1872064206934645760 Extend ovpn-cli with -n to resolve an interface in a named network namespace and include OVPN_A_TARGET_NETNSID in peer and key requests. Use -n for existing peer and key operations that do not create transport sockets, exercising foreign-netns requests throughout the test suite. Signed-off-by: Marco Baffo --- Changes in v3: - None. Changes in v2: - Used "ovpn-cli -n" instead of "ip netns exec ovpn-cli" where possible. - Removed additional tests since we modified the existing ones to exercise the new code path. tools/testing/selftests/net/ovpn/common.sh | 8 +- tools/testing/selftests/net/ovpn/ovpn-cli.c | 266 +++++++++++++++++- .../selftests/net/ovpn/test-close-socket.sh | 4 +- tools/testing/selftests/net/ovpn/test-mark.sh | 6 +- tools/testing/selftests/net/ovpn/test.sh | 50 ++-- 5 files changed, 289 insertions(+), 45 deletions(-) diff --git a/tools/testing/selftests/net/ovpn/common.sh b/tools/testing/selftests/net/ovpn/common.sh index 2d844eb3aa6e..4f2510fb6d7f 100644 --- a/tools/testing/selftests/net/ovpn/common.sh +++ b/tools/testing/selftests/net/ovpn/common.sh @@ -221,7 +221,7 @@ ovpn_add_peer() { ${OVPN_UDP_PEERS_FILE} for p in $(seq 1 ${OVPN_NUM_PEERS}); do - ip netns exec "${server_ns}" ${OVPN_CLI} \ + "${OVPN_CLI}" -n "${server_ns}" \ new_key tun0 ${p} 1 0 ${OVPN_ALG} 0 \ data64.key done @@ -244,7 +244,7 @@ ovpn_add_peer() { ip netns exec "${peer_ns}" ${OVPN_CLI} new_peer \ tun${1} ${PEER_ID} ${TX_ID} ${LPORT} ${RADDR} \ ${RPORT} - ip netns exec "${peer_ns}" ${OVPN_CLI} new_key tun${1} \ + "${OVPN_CLI}" -n "${peer_ns}" new_key tun${1} \ ${PEER_ID} 1 0 ${OVPN_ALG} 1 data64.key fi else @@ -252,8 +252,8 @@ ovpn_add_peer() { (ip netns exec "${server_ns}" ${OVPN_CLI} listen tun0 \ 1 ${M_ID} ${OVPN_TCP_PEERS_FILE} && { for p in $(seq 1 ${OVPN_NUM_PEERS}); do - ip netns exec "${server_ns}" \ - ${OVPN_CLI} new_key tun0 ${p} \ + "${OVPN_CLI}" -n "${server_ns}" \ + new_key tun0 ${p} \ 1 0 ${OVPN_ALG} 0 data64.key done }) & diff --git a/tools/testing/selftests/net/ovpn/ovpn-cli.c b/tools/testing/selftests/net/ovpn/ovpn-cli.c index d40953375c86..6ea39b3ecc29 100644 --- a/tools/testing/selftests/net/ovpn/ovpn-cli.c +++ b/tools/testing/selftests/net/ovpn/ovpn-cli.c @@ -6,6 +6,7 @@ * Author: Antonio Quartulli */ +#include #include #include #include @@ -21,6 +22,7 @@ #include #include #include +#include #include #include @@ -121,6 +123,8 @@ struct ovpn_ctx { unsigned int ifindex; char ifname[IFNAMSIZ]; + const char *target_netns_name; + int target_netnsid; enum ovpn_mode mode; bool mode_set; @@ -224,6 +228,10 @@ static struct nl_ctx *nl_ctx_alloc_flags(struct ovpn_ctx *ovpn, int cmd, if (ovpn->ifindex > 0) NLA_PUT_U32(ctx->nl_msg, OVPN_A_IFINDEX, ovpn->ifindex); + if (ovpn->target_netnsid >= 0) + NLA_PUT_S32(ctx->nl_msg, OVPN_A_TARGET_NETNSID, + ovpn->target_netnsid); + return ctx; nla_put_failure: err_msg: @@ -1365,12 +1373,196 @@ static int ovpn_rt_send(struct nlmsghdr *payload, pid_t peer, return ret; } +static int ovpn_parse_netnsid(struct nlmsghdr *msg, void *arg) +{ + struct rtgenmsg *gen; + struct rtattr *attr; + int len; + + if (msg->nlmsg_type != RTM_NEWNSID || + msg->nlmsg_len < NLMSG_LENGTH(sizeof(*gen))) + return -EINVAL; + + gen = NLMSG_DATA(msg); + len = NLMSG_PAYLOAD(msg, sizeof(*gen)); + attr = (struct rtattr *)((char *)gen + NLMSG_ALIGN(sizeof(*gen))); + + for (; RTA_OK(attr, len); attr = RTA_NEXT(attr, len)) { + if (attr->rta_type != NETNSA_NSID) + continue; + + if (RTA_PAYLOAD(attr) < sizeof(int32_t)) + return -EINVAL; + + memcpy(arg, RTA_DATA(attr), sizeof(int32_t)); + return 0; + } + + return -ENOENT; +} + +struct ovpn_netns_req { + struct nlmsghdr n; + struct rtgenmsg g; + char buf[64]; +}; + +static int ovpn_get_netnsid(int netns_fd, int *netnsid) +{ + struct ovpn_netns_req req = { 0 }; + uint32_t fd = netns_fd; + + req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.g)); + req.n.nlmsg_flags = NLM_F_REQUEST; + req.n.nlmsg_type = RTM_GETNSID; + req.g.rtgen_family = AF_UNSPEC; + + if (ovpn_addattr(&req.n, sizeof(req), NETNSA_FD, &fd, + sizeof(fd)) < 0) + return -EMSGSIZE; + + *netnsid = NETNSA_NSID_NOT_ASSIGNED; + return ovpn_rt_send(&req.n, 0, 0, ovpn_parse_netnsid, netnsid); +} + +static int ovpn_assign_netnsid(int netns_fd) +{ + /* NETNSA_NSID_NOT_ASSIGNED asks the kernel to allocate an NSID. */ + int32_t netnsid = NETNSA_NSID_NOT_ASSIGNED; + struct ovpn_netns_req req = { 0 }; + uint32_t fd = netns_fd; + + req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.g)); + req.n.nlmsg_flags = NLM_F_REQUEST; + req.n.nlmsg_type = RTM_NEWNSID; + req.g.rtgen_family = AF_UNSPEC; + + if (ovpn_addattr(&req.n, sizeof(req), NETNSA_NSID, &netnsid, + sizeof(netnsid)) < 0 || + ovpn_addattr(&req.n, sizeof(req), NETNSA_FD, &fd, + sizeof(fd)) < 0) + return -EMSGSIZE; + + return ovpn_rt_send(&req.n, 0, 0, NULL, NULL); +} + +/* Get the target NSID relative to the current netns, assigning one if necessary. */ +static int ovpn_get_or_assign_netnsid(int netns_fd) +{ + int netnsid, ret; + + ret = ovpn_get_netnsid(netns_fd, &netnsid); + if (ret < 0) + return ret; + + if (netnsid >= 0) + return netnsid; + + ret = ovpn_assign_netnsid(netns_fd); + if (ret < 0 && ret != -EEXIST) + return ret; + + ret = ovpn_get_netnsid(netns_fd, &netnsid); + if (ret < 0) + return ret; + + if (netnsid < 0) + return -ENOENT; + + return netnsid; +} + +static int ovpn_parse_ifindex(struct nlmsghdr *msg, void *arg) +{ + struct ifinfomsg *ifinfo; + + if (msg->nlmsg_type != RTM_NEWLINK || + msg->nlmsg_len < NLMSG_LENGTH(sizeof(*ifinfo))) + return -EINVAL; + + ifinfo = NLMSG_DATA(msg); + if (ifinfo->ifi_index <= 0) + return -EINVAL; + + *(unsigned int *)arg = ifinfo->ifi_index; + + return 0; +} + struct ovpn_link_req { struct nlmsghdr n; struct ifinfomsg i; char buf[256]; }; +static int ovpn_get_ifindex(int netnsid, const char *ifname, + unsigned int *ifindex) +{ + struct ovpn_link_req req = { 0 }; + int32_t id = netnsid; + + req.n.nlmsg_len = NLMSG_LENGTH(sizeof(req.i)); + req.n.nlmsg_flags = NLM_F_REQUEST; + req.n.nlmsg_type = RTM_GETLINK; + req.i.ifi_family = AF_UNSPEC; + + if (ovpn_addattr(&req.n, sizeof(req), IFLA_TARGET_NETNSID, &id, + sizeof(id)) < 0 || + ovpn_addattr(&req.n, sizeof(req), IFLA_IFNAME, ifname, + strlen(ifname) + 1) < 0) + return -EMSGSIZE; + + return ovpn_rt_send(&req.n, 0, 0, ovpn_parse_ifindex, ifindex); +} + +#define NETNS_RUN_DIR "/var/run/netns" + +static int ovpn_resolve_netns(struct ovpn_ctx *ovpn) +{ + int target_fd, ret; + char path[PATH_MAX]; + int len; + + if (!ovpn->target_netns_name[0] || + strchr(ovpn->target_netns_name, '/')) { + fprintf(stderr, "invalid network namespace name: %s\n", + ovpn->target_netns_name); + return -EINVAL; + } + + len = snprintf(path, sizeof(path), "%s/%s", NETNS_RUN_DIR, + ovpn->target_netns_name); + if (len < 0 || len >= (int)sizeof(path)) + return -ENAMETOOLONG; + + target_fd = open(path, O_RDONLY); + if (target_fd < 0) { + ret = errno; + fprintf(stderr, "cannot open network namespace %s: %s\n", + ovpn->target_netns_name, strerror(ret)); + return -ret; + } + + ovpn->target_netnsid = ovpn_get_or_assign_netnsid(target_fd); + if (ovpn->target_netnsid < 0) { + ret = ovpn->target_netnsid; + fprintf(stderr, "cannot resolve network namespace ID for %s\n", + ovpn->target_netns_name); + goto out; + } + + ret = ovpn_get_ifindex(ovpn->target_netnsid, ovpn->ifname, + &ovpn->ifindex); + if (ret < 0) { + fprintf(stderr, "cannot find interface %s in namespace %s\n", + ovpn->ifname, ovpn->target_netns_name); + } +out: + close(target_fd); + + return ret; +} + static int ovpn_new_iface(struct ovpn_ctx *ovpn) { struct rtattr *linkinfo, *data; @@ -1662,8 +1854,10 @@ static int ovpn_listen_mcast(void) static void usage(const char *cmd) { fprintf(stderr, - "Usage %s [arguments..]\n", + "Usage %s [-n ] [arguments..]\n", cmd); + fprintf(stderr, + "\t-n netns: run peer/key operations on an interface in the named network namespace\n"); fprintf(stderr, "where can be one of the following\n\n"); fprintf(stderr, "* new_iface [mode]: create new ovpn interface\n"); @@ -1966,6 +2160,26 @@ static enum ovpn_cmd ovpn_parse_cmd(const char *cmd) return CMD_INVALID; } +static bool ovpn_cmd_supports_target_netns(enum ovpn_cmd cmd) +{ + switch (cmd) { + case CMD_LISTEN: + case CMD_CONNECT: + case CMD_NEW_PEER: + case CMD_NEW_MULTI_PEER: + case CMD_SET_PEER: + case CMD_DEL_PEER: + case CMD_GET_PEER: + case CMD_NEW_KEY: + case CMD_DEL_KEY: + case CMD_GET_KEY: + case CMD_SWAP_KEYS: + return true; + default: + return false; + } +} + /* Send process to background and waits for signal. * * This helper is called at the end of commands @@ -2021,6 +2235,7 @@ static int ovpn_run_cmd(struct ovpn_ctx *ovpn) } peer_ctx.ifindex = ovpn->ifindex; + peer_ctx.target_netnsid = ovpn->target_netnsid; peer_ctx.sa_family = ovpn->sa_family; peer_ctx.asymm_id = ovpn->asymm_id; @@ -2107,6 +2322,7 @@ static int ovpn_run_cmd(struct ovpn_ctx *ovpn) struct ovpn_ctx peer_ctx = { 0 }; peer_ctx.ifindex = ovpn->ifindex; + peer_ctx.target_netnsid = ovpn->target_netnsid; peer_ctx.socket = ovpn->socket; peer_ctx.sa_family = AF_UNSPEC; peer_ctx.asymm_id = ovpn->asymm_id; @@ -2179,13 +2395,19 @@ static int ovpn_parse_cmd_args(struct ovpn_ctx *ovpn, int argc, char *argv[]) strscpy(ovpn->ifname, argv[2], IFNAMSIZ - 1); ovpn->ifname[IFNAMSIZ - 1] = '\0'; - /* all commands, except NEW_IFNAME, needs an ifindex */ + /* all commands, except NEW_IFACE, need an ifindex */ if (ovpn->cmd != CMD_NEW_IFACE) { - ovpn->ifindex = if_nametoindex(ovpn->ifname); - if (!ovpn->ifindex) { - fprintf(stderr, "cannot find interface: %s\n", - strerror(errno)); - return -1; + if (ovpn->target_netns_name) { + ret = ovpn_resolve_netns(ovpn); + if (ret < 0) + return ret; + } else { + ovpn->ifindex = if_nametoindex(ovpn->ifname); + if (!ovpn->ifindex) { + fprintf(stderr, "cannot find interface: %s\n", + strerror(errno)); + return -1; + } } } @@ -2432,29 +2654,51 @@ static int ovpn_parse_cmd_args(struct ovpn_ctx *ovpn, int argc, char *argv[]) int main(int argc, char *argv[]) { struct ovpn_ctx ovpn; + const char *program = argv[0]; int ret; + memset(&ovpn, 0, sizeof(ovpn)); + if (argc > 1 && !strcmp(argv[1], "-n")) { + if (argc < 4) { + fprintf(stderr, + "Error: -n requires a namespace and a command.\n\n"); + usage(program); + return -EINVAL; + } + + ovpn.target_netns_name = argv[2]; + argc -= 2; + argv += 2; + } + if (argc < 2) { - usage(argv[0]); + usage(program); return -1; } - memset(&ovpn, 0, sizeof(ovpn)); + ovpn.target_netnsid = NETNSA_NSID_NOT_ASSIGNED; ovpn.sa_family = AF_UNSPEC; ovpn.cipher = OVPN_CIPHER_ALG_NONE; ovpn.cmd = ovpn_parse_cmd(argv[1]); if (ovpn.cmd == CMD_INVALID) { fprintf(stderr, "Error: unknown command.\n\n"); - usage(argv[0]); + usage(program); return -1; } + if (ovpn.target_netns_name && + !ovpn_cmd_supports_target_netns(ovpn.cmd)) { + fprintf(stderr, "Error: -n is not supported for command %s.\n", + argv[1]); + return -EOPNOTSUPP; + } + ret = ovpn_parse_cmd_args(&ovpn, argc, argv); if (ret < 0) { fprintf(stderr, "Error: invalid arguments.\n\n"); if (ret == -EINVAL) - usage(argv[0]); + usage(program); return ret; } diff --git a/tools/testing/selftests/net/ovpn/test-close-socket.sh b/tools/testing/selftests/net/ovpn/test-close-socket.sh index ec9a51bbf3c9..0e4e33b2973f 100755 --- a/tools/testing/selftests/net/ovpn/test-close-socket.sh +++ b/tools/testing/selftests/net/ovpn/test-close-socket.sh @@ -40,10 +40,10 @@ ovpn_prepare_network() { for p in $(seq 1 ${OVPN_NUM_PEERS}); do peer_ns="ovpn_peer${p}" ovpn_cmd_ok "set peer0 timeout for peer ${p}" \ - ip netns exec ovpn_peer0 ${OVPN_CLI} set_peer tun0 \ + "${OVPN_CLI}" -n ovpn_peer0 set_peer tun0 \ ${p} 60 120 ovpn_cmd_ok "set peer${p} timeout for peer ${p}" \ - ip netns exec "${peer_ns}" ${OVPN_CLI} set_peer \ + "${OVPN_CLI}" -n "${peer_ns}" set_peer \ tun${p} $((p + OVPN_ID_OFFSET)) 60 120 done } diff --git a/tools/testing/selftests/net/ovpn/test-mark.sh b/tools/testing/selftests/net/ovpn/test-mark.sh index 7c1d56e9c525..8a9ca52f86be 100755 --- a/tools/testing/selftests/net/ovpn/test-mark.sh +++ b/tools/testing/selftests/net/ovpn/test-mark.sh @@ -42,7 +42,7 @@ ovpn_mark_prepare_network() { ASYMM "${OVPN_UDP_PEERS_FILE}" "${MARK}" for p in $(seq 1 3); do ovpn_cmd_ok "install server key for peer ${p}" \ - ip netns exec ovpn_peer0 "${OVPN_CLI}" new_key tun0 \ + "${OVPN_CLI}" -n ovpn_peer0 new_key tun0 \ "${p}" 1 0 "${OVPN_ALG}" 0 data64.key done @@ -53,10 +53,10 @@ ovpn_mark_prepare_network() { for p in $(seq 1 3); do peer_ns="ovpn_peer${p}" ovpn_cmd_ok "set peer0 timeout for peer ${p}" \ - ip netns exec ovpn_peer0 "${OVPN_CLI}" set_peer tun0 \ + "${OVPN_CLI}" -n ovpn_peer0 set_peer tun0 \ "${p}" 60 120 ovpn_cmd_ok "set peer${p} timeout for peer ${p}" \ - ip netns exec "${peer_ns}" "${OVPN_CLI}" set_peer \ + "${OVPN_CLI}" -n "${peer_ns}" set_peer \ tun"${p}" $((p + OVPN_ID_OFFSET)) 60 120 done } diff --git a/tools/testing/selftests/net/ovpn/test.sh b/tools/testing/selftests/net/ovpn/test.sh index 9b5610837032..468dd7985c8f 100755 --- a/tools/testing/selftests/net/ovpn/test.sh +++ b/tools/testing/selftests/net/ovpn/test.sh @@ -48,10 +48,10 @@ ovpn_prepare_network() { for p in $(seq 1 ${OVPN_NUM_PEERS}); do peer_ns="ovpn_peer${p}" ovpn_cmd_ok "set peer0 timeout for peer ${p}" \ - ip netns exec ovpn_peer0 ${OVPN_CLI} set_peer tun0 \ + "${OVPN_CLI}" -n ovpn_peer0 set_peer tun0 \ ${p} 60 120 ovpn_cmd_ok "set peer${p} timeout for peer ${p}" \ - ip netns exec "${peer_ns}" ${OVPN_CLI} set_peer \ + "${OVPN_CLI}" -n "${peer_ns}" set_peer \ tun${p} $((p + OVPN_ID_OFFSET)) 60 120 done } @@ -151,14 +151,14 @@ ovpn_run_key_rollover() { for p in $(seq 1 ${OVPN_NUM_PEERS}); do peer_ns="ovpn_peer${p}" ovpn_cmd_ok "add secondary key on peer0 for peer ${p}" \ - ip netns exec ovpn_peer0 ${OVPN_CLI} new_key tun0 \ + "${OVPN_CLI}" -n ovpn_peer0 new_key tun0 \ ${p} 2 1 ${OVPN_ALG} 0 data64.key ovpn_cmd_ok "add secondary key on peer${p} for peer ${p}" \ - ip netns exec "${peer_ns}" ${OVPN_CLI} new_key tun${p} \ + "${OVPN_CLI}" -n "${peer_ns}" new_key tun${p} \ $((p + OVPN_ID_OFFSET)) 2 1 ${OVPN_ALG} 1 \ data64.key ovpn_cmd_ok "swap keys on peer${p}" \ - ip netns exec "${peer_ns}" ${OVPN_CLI} swap_keys \ + "${OVPN_CLI}" -n "${peer_ns}" swap_keys \ tun${p} $((p + OVPN_ID_OFFSET)) done } @@ -166,22 +166,22 @@ ovpn_run_key_rollover() { ovpn_run_queries() { ovpn_log "Querying all peers:" - ovpn_cmd_ok "query all peers from peer0" \ - ip netns exec ovpn_peer0 ${OVPN_CLI} get_peer tun0 - ovpn_cmd_ok "query all peers from peer1" \ - ip netns exec ovpn_peer1 ${OVPN_CLI} get_peer tun1 + ovpn_cmd_ok "query all peers on peer0" \ + "${OVPN_CLI}" -n ovpn_peer0 get_peer tun0 + ovpn_cmd_ok "query all peers on peer1" \ + "${OVPN_CLI}" -n ovpn_peer1 get_peer tun1 ovpn_log "Querying peer 1:" - ovpn_cmd_ok "query peer 1 from peer0" \ - ip netns exec ovpn_peer0 ${OVPN_CLI} get_peer tun0 1 + ovpn_cmd_ok "query peer 1 on peer0" \ + "${OVPN_CLI}" -n ovpn_peer0 get_peer tun0 1 } ovpn_query_peer_missing() { ovpn_log "Querying non-existent peer 20:" ovpn_cmd_fail "query missing peer 20 on peer0" \ - ip netns exec ovpn_peer0 ${OVPN_CLI} get_peer tun0 20 + "${OVPN_CLI}" -n ovpn_peer0 get_peer tun0 20 } ovpn_run_peer_cleanup() { @@ -191,9 +191,9 @@ ovpn_run_peer_cleanup() { ovpn_log "Deleting peer 1:" ovpn_cmd_ok "delete peer1 on peer0" \ - ip netns exec ovpn_peer0 ${OVPN_CLI} del_peer tun0 1 + "${OVPN_CLI}" -n ovpn_peer0 del_peer tun0 1 ovpn_cmd_ok "delete peer1 on peer1" \ - ip netns exec ovpn_peer1 ${OVPN_CLI} del_peer tun1 \ + "${OVPN_CLI}" -n ovpn_peer1 del_peer tun1 \ $((1 + OVPN_ID_OFFSET)) ovpn_log "Querying keys:" @@ -201,10 +201,10 @@ ovpn_run_peer_cleanup() { for p in $(seq 2 ${OVPN_NUM_PEERS}); do peer_ns="ovpn_peer${p}" ovpn_cmd_ok "query peer${p} key 1" \ - ip netns exec "${peer_ns}" ${OVPN_CLI} get_key tun${p} \ + "${OVPN_CLI}" -n "${peer_ns}" get_key tun${p} \ $((p + OVPN_ID_OFFSET)) 1 ovpn_cmd_ok "query peer${p} key 2" \ - ip netns exec "${peer_ns}" ${OVPN_CLI} get_key tun${p} \ + "${OVPN_CLI}" -n "${peer_ns}" get_key tun${p} \ $((p + OVPN_ID_OFFSET)) 2 done } @@ -217,16 +217,16 @@ ovpn_run_traffic_delete_peer() { ovpn_run_bg ping_pid ip netns exec ovpn_peer2 ping -qf -w 4 5.5.5.1 sleep 2 ovpn_cmd_ok "delete peer0 peer 2" \ - ip netns exec ovpn_peer0 ${OVPN_CLI} del_peer tun0 2 + "${OVPN_CLI}" -n ovpn_peer0 del_peer tun0 2 if [ "${OVPN_PROTO}" == "TCP" ]; then # In TCP mode this command is expected to fail for both peers. ovpn_cmd_mayfail "delete peer2 peer 2 (TCP non-fatal)" \ - ip netns exec ovpn_peer2 ${OVPN_CLI} del_peer tun2 \ + "${OVPN_CLI}" -n ovpn_peer2 del_peer tun2 \ $((2 + OVPN_ID_OFFSET)) else - ovpn_cmd_ok "delete peer2 peer 2" ip netns exec ovpn_peer2 \ - ${OVPN_CLI} del_peer tun2 $((2 + OVPN_ID_OFFSET)) + ovpn_cmd_ok "delete peer2 peer 2" "${OVPN_CLI}" -n ovpn_peer2 \ + del_peer tun2 $((2 + OVPN_ID_OFFSET)) fi wait "${ping_pid}" || true @@ -241,10 +241,10 @@ ovpn_run_key_cleanup() { for p in $(seq 3 ${OVPN_NUM_PEERS}); do peer_ns="ovpn_peer${p}" ovpn_cmd_ok "delete key 1 for peer${p}" \ - ip netns exec "${peer_ns}" ${OVPN_CLI} del_key tun${p} \ + "${OVPN_CLI}" -n "${peer_ns}" del_key tun${p} \ $((p + OVPN_ID_OFFSET)) 1 ovpn_cmd_ok "delete key 2 for peer${p}" \ - ip netns exec "${peer_ns}" ${OVPN_CLI} del_key tun${p} \ + "${OVPN_CLI}" -n "${peer_ns}" del_key tun${p} \ $((p + OVPN_ID_OFFSET)) 2 done } @@ -258,11 +258,11 @@ ovpn_run_timeouts() { for p in $(seq 3 ${OVPN_NUM_PEERS}); do # Non-fatal: this may fail in some protocol modes. ovpn_cmd_mayfail "set peer0 timeout for peer ${p} (non-fatal)" \ - ip netns exec ovpn_peer0 ${OVPN_CLI} set_peer tun0 \ + "${OVPN_CLI}" -n ovpn_peer0 set_peer tun0 \ ${p} 3 3 peer_ns="ovpn_peer${p}" ovpn_cmd_ok "disable timeout on peer${p} while peer0 adjusts \ - state" ip netns exec "${peer_ns}" ${OVPN_CLI} set_peer \ + state" "${OVPN_CLI}" -n "${peer_ns}" set_peer \ tun${p} $((p + OVPN_ID_OFFSET)) 0 0 done # wait for peers to timeout @@ -273,7 +273,7 @@ ovpn_run_timeouts() { for p in $(seq 3 ${OVPN_NUM_PEERS}); do peer_ns="ovpn_peer${p}" ovpn_cmd_ok "set peer${p} P2P timeout" \ - ip netns exec "${peer_ns}" ${OVPN_CLI} set_peer \ + "${OVPN_CLI}" -n "${peer_ns}" set_peer \ tun${p} $((p + OVPN_ID_OFFSET)) 3 3 done sleep 5 From patchwork Wed Jul 29 15:38:15 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marco Baffo X-Patchwork-Id: 5179 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:fd0b:b0:87d:ab56:3700 with SMTP id cw11csp2128063mac; Wed, 29 Jul 2026 08:39:19 -0700 (PDT) X-Forwarded-Encrypted: i=2; AHgh+RqMrkN1C3acDqEjMk55cHQMr6JSZsGDOKCxM3muKqAmc8ghbs8CevE7qR6EzsqJkacoYHNIR6K0NrU=@openvpn.net X-Received: by 2002:a05:6870:7204:b0:43b:3d67:5fa0 with SMTP id 586e51a60fabf-4586cfdf4b8mr3798674fac.33.1785339559264; Wed, 29 Jul 2026 08:39:19 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1785339559; cv=none; d=google.com; s=arc-20260327; b=nrYOvlLgYvQJIn0sI4/9kM9GcRnHseo+8EWli9UNmBEC61kO+JW7/f5b4U4qwHGV0a dLZ4qFjSq+UgHkgKBgNwQEGMEW5D/DkjAtwZUOrz+WBAlApGhd68rw0qQewJBkHOVU5H 1IYgEttt5Qjfj94joO3vVQYALp3rHngLP2/CVO0nEdk+8N8xAcZ2jv1j2EQyLHkrnWKa J9TfXJbPgxU2hjf5nnvfocLlFHuWzBFUMn2763nthj0scuP+EZA3CeN0U8M1liTG6+82 Et1mzDOMtoZtvnvj6Kb3AF6b2iPfFAo+SjUvgZ3MP53VAuMCkm/SypzHVq8W0btEMHPQ BR4A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20260327; h=errors-to:content-transfer-encoding:cc: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=y6ZG8HufGNFuzv4KbdMmmc+uki3k3ZL6y7H+1cVGCB8=; fh=BsMg/B0Yb/hS/rzP5Npz4luh0IleZm8REk1XWiWRt2A=; b=NrrgMEmgzNxcV+MGLZnZ+vKQ8ePaidHyex00jJeBECxI/suSaXskJt6irxrClThp4p q6LgXQKrXSU3b4iyMFB/o27vHHFALaacbtlZ5Jpq2r8zsnhnkKSOl+qTwIDGY9mTWyNE vJGuXwgufr8IeOnDeW3aQLvGTZPYZY0Q80p3qXvHWgLmGMKiXyutfJSBGNEvew8/xlSC zRcNCIs9ANdaEGDfyqjoLGEBwWJHoU4p+UzZz293Uwfq0cHTYghKVBEORx5NbtiHOq5z LUwxt/+t6vNKBaBUA1PnyQOLnqXv2MkMSiVoPZaFUT+4I0EL4KJxOpaEIWvtTFpazr9E prPQ==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=FUBJEUtX; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=ZbYl5XO1; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=gQtlLYpJ; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b=l96ppsA+; 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-458863bc56dsi2938961fac.31.2026.07.29.08.39.19 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 29 Jul 2026 08:39:19 -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=FUBJEUtX; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=ZbYl5XO1; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=gQtlLYpJ; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b=l96ppsA+; 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:Cc: 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:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender :Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=y6ZG8HufGNFuzv4KbdMmmc+uki3k3ZL6y7H+1cVGCB8=; b=FUBJEUtXuTReAVpN7c3DNGjrx+ t37Rg4bhfGi4LJ6ELUH42sHm/jR0ob1LSnjFoHH1tcYzCgVRPZ0JOBPsTVDdvPD8z+f8i9ISb1wMT WtUSCyd8AdDUK1PrZ0uDus3GBjZY+I2DuEXrERt4pFupJaSYewX5nPMcM+KS+0G2C9RI=; 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 1wp6NH-0006Xi-EU; Wed, 29 Jul 2026 15:39:16 +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 1wp6NF-0006XY-TH for openvpn-devel@lists.sourceforge.net; Wed, 29 Jul 2026 15:39:14 +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=uxFnNYWi9JqAYKRB0/CmXjoJavVFqxjWbA5wHRXq/xg=; b=ZbYl5XO1DR4yO36EfxZ/sDt34v zGrbD4+c8aVHSVBDYFak6I/QPuaQrOR6Cplj0feByGT6xUOmTXTr8dl3LQB+4xum1bKAkEMzpDnha mBA6cvMxb7cHKFwDja/c6hrJYK3WNy0LCgOHXfrOVIrRANs6aMdQF6CThzcFKTjZSCuY=; 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=uxFnNYWi9JqAYKRB0/CmXjoJavVFqxjWbA5wHRXq/xg=; b=gQtlLYpJTKOd0Vtrv7HYK8gFuf jQ3KVMMkDZtspXa8B+3KiLOQ265kstfjLlbii9o73fCvJlCRU5h8lCpItHhEu2LA+pg0GU1KQlmv9 15LIESA3QcJBD0GnBX14o8VvROCrx0bFOpdm/lzv0NK9wiEcsti+z8XzwJaSxmLy+DiM=; Received: from mout-b-105.mailbox.org ([195.10.208.50]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1wp6NC-0002p7-Ck for openvpn-devel@lists.sourceforge.net; Wed, 29 Jul 2026 15:39:14 +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 4h9Ghk4N89z9tFx; Wed, 29 Jul 2026 17:39:02 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandelbit.com; s=MBO0001; t=1785339542; 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=uxFnNYWi9JqAYKRB0/CmXjoJavVFqxjWbA5wHRXq/xg=; b=l96ppsA+yyQAlrdq5KNXB+0/de9k6N3X3o9b98jy+DtQlpHqISN0f9OstsRds2Fb/URD4h 5VxKgVUYaS/j+eFYpfj4uYVTXpBksmT3Ew/OL5vzpjSmzct+m7eb6UC2j/ResZxdlAtIGr MH5yjDthXkM7n4MASeUi84EwNA6u9bc9C1ZmyaeA0lFwfBWoCsxyujATX9U6dpIuG2YJam qOTeeOT/vrZnXote2keQleZIYLrXsOjFwikr5U5OaraTjgv+xbSSwmFuIvj+cGAu2kGJvd vN1Oi9eW5kXNC6XIUFRURx+xuUAd9AU2o6RRMcuf6dxV4jAXacrzrMk/SzqGgQ== Authentication-Results: outgoing_mbo_mout; dkim=none; spf=pass (outgoing_mbo_mout: domain of marco@mandelbit.com designates 2001:67c:2050:b231:465::1 as permitted sender) smtp.mailfrom=marco@mandelbit.com From: Marco Baffo To: openvpn-devel@lists.sourceforge.net Date: Wed, 29 Jul 2026 17:38:15 +0200 Message-ID: <20260729153815.2637139-4-marco@mandelbit.com> In-Reply-To: <20260729153815.2637139-1-marco@mandelbit.com> References: <20260729153815.2637139-1-marco@mandelbit.com> MIME-Version: 1.0 X-Rspamd-Queue-Id: 4h9Ghk4N89z9tFx 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: Move one peer interface to a foreign namespace while keeping its transport socket in the original namespace. Verify that its deletion notification contains the expected target namespace ID. Signed-off-by: Marco Baffo --- Changes in v3: - Ignore unrelated events when validating notification target netns IDs. 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: 1wp6NC-0002p7-Ck Subject: [Openvpn-devel] [PATCH ovpn net-next v3 4/4] selftests: ovpn: validate target netns ID in notifications 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: , Cc: Antonio Quartulli Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox X-GMAIL-THRID: 1872064213836575098 X-GMAIL-MSGID: 1872064213836575098 Move one peer interface to a foreign namespace while keeping its transport socket in the original namespace. Verify that its deletion notification contains the expected target namespace ID. Signed-off-by: Marco Baffo --- Changes in v3: - Ignore unrelated events when validating notification target netns IDs. Changes in v2: - This is a new patch. tools/testing/selftests/net/ovpn/common.sh | 3 ++- tools/testing/selftests/net/ovpn/test.sh | 25 ++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/net/ovpn/common.sh b/tools/testing/selftests/net/ovpn/common.sh index 4f2510fb6d7f..2b90b7bf8700 100644 --- a/tools/testing/selftests/net/ovpn/common.sh +++ b/tools/testing/selftests/net/ovpn/common.sh @@ -21,7 +21,8 @@ export OVPN_ID_OFFSET=$(( 9 * (OVPN_SYMMETRIC_ID == 0) )) OVPN_JQ_FILTER='map(if type == "array" then .[] else . end) | map(select(.msg.peer | has("remote-ipv6") | not)) | - map(del(.msg.ifindex)) | sort_by(.msg.peer.id)[]' + map(del(.msg.ifindex, .msg["target-netnsid"])) | + sort_by(.msg.peer.id)[]' OVPN_LAN_IP="11.11.11.11" declare -A OVPN_TMP_JSONS=() diff --git a/tools/testing/selftests/net/ovpn/test.sh b/tools/testing/selftests/net/ovpn/test.sh index 468dd7985c8f..52e482641016 100755 --- a/tools/testing/selftests/net/ovpn/test.sh +++ b/tools/testing/selftests/net/ovpn/test.sh @@ -270,8 +270,13 @@ ovpn_run_timeouts() { ovpn_log "Setting timeout to 3s P2P:" + # The transport socket stays in peer3 when its interface is moved. + ovpn_cmd_ok "move peer3 interface to peer0" \ + ip -n ovpn_peer3 link set tun3 netns ovpn_peer0 + for p in $(seq 3 ${OVPN_NUM_PEERS}); do peer_ns="ovpn_peer${p}" + [ "${p}" -eq 3 ] && peer_ns="ovpn_peer0" ovpn_cmd_ok "set peer${p} P2P timeout" \ "${OVPN_CLI}" -n "${peer_ns}" set_peer \ tun${p} $((p + OVPN_ID_OFFSET)) 3 3 @@ -279,9 +284,29 @@ ovpn_run_timeouts() { sleep 5 } +ovpn_validate_ntf_netnsid() { + local peer="$1" + local target="$2" + local expected_netnsid + local received_netnsid + + expected_netnsid=$(ip -n "ovpn_peer${peer}" -j netns list-id | + jq -er --arg target "${target}" \ + '.[] | select(.name == $target) | .nsid') + received_netnsid=$(jq -er \ + 'select(.name == "peer-del-ntf" and + (.msg | has("target-netnsid"))) | + .msg["target-netnsid"]' \ + "${OVPN_TMP_JSONS[$peer]}") + + [ "${received_netnsid}" -eq "${expected_netnsid}" ] +} + ovpn_run_notifications() { local p + ovpn_cmd_ok "validate peer3 target netns ID" \ + ovpn_validate_ntf_netnsid 3 ovpn_peer0 for p in $(seq 0 ${OVPN_NUM_PEERS}); do ovpn_cmd_ok "validate listener output for peer ${p}" \ ovpn_compare_ntfs "${p}"