From patchwork Wed Jul 29 07:13:57 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marco Baffo X-Patchwork-Id: 5156 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:fd0b:b0:87d:ab56:3700 with SMTP id cw11csp1584964mac; Wed, 29 Jul 2026 00:14:32 -0700 (PDT) X-Forwarded-Encrypted: i=2; AHgh+RrZdvkUKC19OQaPnLBA7C+WzMOacOEsz/fkD0/bEI4vISpX+kGPyuWheeXvsuBXl2AO6LDQrMmrgds=@openvpn.net X-Received: by 2002:a05:6820:55d6:10b0:6ac:a175:fe66 with SMTP id 006d021491bc7-6aca17600bamr1232480eaf.21.1785309271853; Wed, 29 Jul 2026 00:14:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1785309271; cv=none; d=google.com; s=arc-20260327; b=OLmM3sQic5wjUJbG4wNwblU/7kdFZQlKU3dYkCFlZwS6awHXH/6zsa7vrFknnFJAmJ wGCXrt2wzxGUKL3Qbb+dWIpO4HP8j/o/SY2SnJFDh9f29LgWi6id/et1YnnstCOCrm83 xIEEMZ7QHBvahcatxeT5micw45OfYszdHFfh/yAucwxu+NtYYtD8dRDEPoqvqThI+Dff saReCDhqfe+biZlG4lpZDhcB1QbY4u5/0aaJ4mMhEW/B5goRR6EHOu4b4nY1NruXyd+H TEAs9XWFzck3zl/0PNHJCgQ6tcow4wDyEXBly/WjTmsYvlIG0WpGaBoMnWenfC+HdGgS 7V0w== 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=xgPKNnJckUB2xpNEivKnehLUzInhXriariUMhYJYxVg=; fh=BsMg/B0Yb/hS/rzP5Npz4luh0IleZm8REk1XWiWRt2A=; b=nZ8QtDvR0lHMy7sltBpvew09l1cfRQb02ax1OXWF669CAVbTH9qM5onphwN8B6CPXV xpNeOOkKcB7BxJTPdErcEemHXKWg9uFVrx0z/buuOVEa4IXG7NhGfQe3n54X0mWIXvDr ZcLPvVmnYjucspM7whMF9LPVpNvTibPIq1VZ6hGA2eia+P1z0bGb6zZcnmijdSKQYovL gX9K/kY6ikqNgnY4lFsSkdGk1XCbxZP9B8HHrjZSvk0WnOuNApHvQYctrZzg+7uhhPVi LkKagXMNO+wdNK/uFyXqUEtpYcEynoH3gPDtQDM+f1axhbcIoFbulNkAMF5jzYQC1lui DriQ==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=Pi0e8XWX; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=aSrrxppb; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=YgtReszb; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b=a22zcMek; 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-6aca51d8d4asi1274641eaf.20.2026.07.29.00.14.30 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 29 Jul 2026 00:14:31 -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=Pi0e8XWX; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=aSrrxppb; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=YgtReszb; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b=a22zcMek; 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=xgPKNnJckUB2xpNEivKnehLUzInhXriariUMhYJYxVg=; b=Pi0e8XWXqgExvzQph0ybqbpkeL d/T0Av7FoM/DqhRvYpdeurwTT/0rErxwPyYYVvKf1uIe5ifNoG+yoCGp/sy5VHXoTFX2YmUWOhizh 2DscB1UDpqs+ZPN7Yolnpu6Z35ri3b6ER/pG/84Gd64b7Js260+BCuuE4fgO4Jw7mE7o=; 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 1woyUj-0003pV-8l; Wed, 29 Jul 2026 07:14:25 +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 1woyUf-0003pL-NW for openvpn-devel@lists.sourceforge.net; Wed, 29 Jul 2026 07:14:24 +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=h8l4wg+8Jf31VppwxwhHL9jxp/6CMmWC16l7tAYaJtY=; b=aSrrxppb7ojflqyiF1EwZC6A8Q 6NRv3DNAOMuGZfIu3g9nMWYrPYeMb29xmhpo+C3YysUsBI3TAEHl4qpPXJ4EnlN5rYABQnvQ1gIbu 9vQk9uGIxe/S7eRXbzb6EQFTrBIempLkNS8hSw4hkfrgbcrnljeMVlguJZHqCVdecwts=; 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=h8l4wg+8Jf31VppwxwhHL9jxp/6CMmWC16l7tAYaJtY=; b=Y gtReszbT5DySjUtxAW+IUJfoSoHbg0NEtNaeTLcH5Cs3e8w3JlRsi68FOvOvd3gCCLo6MdLv7RJX2 xJL7LGr03QrrieqkIhzLFWxNsdh2wZkQIYIsqByu8J2SmNWWuXgSuBOM1JLWODvyZXJQeZrcVm0z5 c2EgE/DZwui7x+P8=; 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 1woyUd-00052g-1i for openvpn-devel@lists.sourceforge.net; Wed, 29 Jul 2026 07:14:22 +0000 Received: from smtp102.mailbox.org (smtp102.mailbox.org [IPv6:2001:67c:2050:b231:465::102]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-b-210.mailbox.org (Postfix) with ESMTPS id 4h93VC0g84zFqPt; Wed, 29 Jul 2026 09:14:11 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandelbit.com; s=MBO0001; t=1785309251; 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=h8l4wg+8Jf31VppwxwhHL9jxp/6CMmWC16l7tAYaJtY=; b=a22zcMekMEUQuRN/qmH74gr3a7tHYib6761Fk9FiX6TqbRhdbTLkSenlhE67du/d8P2+62 Lov7I/Nx8W6ca7QaFapbIa6vy8oeu9yCLT1IYWrS5GWnE8VFRptGVWmur46tuGyEXvEhdm xj529Wc4lXd9tqNUKatfTjo1mmCfRpqKhOnei5nKBCL4m/ayDslByCD8tNnyuPQ6CoVjRA fX53NBWJGmo6PoCrGcy9pkCgnNPZOuZOVYuIxMSV4Gs4rKYqUGXwbl0gzcbKMJuvjMf/Ev zMbl4ldYhyFOdsDbyBwmzP+XL9CR50UD3W5S5ZEbJiYCd0djEiSiED49hvTnYw== Authentication-Results: outgoing_mbo_mout; dkim=none; spf=pass (outgoing_mbo_mout: domain of marco@mandelbit.com designates 2001:67c:2050:b231:465::102 as permitted sender) smtp.mailfrom=marco@mandelbit.com From: Marco Baffo To: openvpn-devel@lists.sourceforge.net Date: Wed, 29 Jul 2026 09:13:57 +0200 Message-ID: <20260729071400.2403200-1-marco@mandelbit.com> MIME-Version: 1.0 X-Rspamd-Queue-Id: 4h93VC0g84zFqPt 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 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_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_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature X-Headers-End: 1woyUd-00052g-1i Subject: [Openvpn-devel] [PATCH ovpn net-next v2 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: 1872032454936177975 X-GMAIL-MSGID: 1872032454936177975 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 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 07:13:58 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marco Baffo X-Patchwork-Id: 5157 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:fd0b:b0:87d:ab56:3700 with SMTP id cw11csp1584966mac; Wed, 29 Jul 2026 00:14:32 -0700 (PDT) X-Forwarded-Encrypted: i=2; AHgh+RqAk0A0antdZelKt01yHvYcWxbxVYRvb2Fw4sBukPLSbqse8UzqxGa0jySH6hNQX7HWULwN9Rd6rt4=@openvpn.net X-Received: by 2002:a05:6870:a0b5:b0:43d:1473:b568 with SMTP id 586e51a60fabf-4586c67edeemr3214708fac.10.1785309271916; Wed, 29 Jul 2026 00:14:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1785309271; cv=none; d=google.com; s=arc-20260327; b=SuA3UciIEtxPIyWFby+if+QQa11XKy0rwEmQLPo29NfoG2r8tEbIvR/t5fyRbG9JKR IEP9MyYa6ZW7Hc07aseSyg4EFON4uHpZF04C1saEF+sAv0+lh4KH2zNBgTALdJc0qgcI i0prf+c2Zth+Rsy5aQ647FHIgq5Xfqz8gpdPfHqZxiSWwWrq2UfSlBjEP6DB9UccFxYA hdYichdkVxaBQACJCXXaqejKk337agWpZncbrBoUWZehD/+SQN+mR+XsWY3zljxpKfRP ceNdbn6ny7G9SZYj/VUo8PSQFOmxR+F5pFtmm5NHrwHpL98BwM8Kvo7eAkQ0cP8uHDpu tBJQ== 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=ouoMF8h/Su819JvEYNJuofAnAMyeMx4v7sVTbMxa9+Y=; fh=BsMg/B0Yb/hS/rzP5Npz4luh0IleZm8REk1XWiWRt2A=; b=F1c01SKdKfuJbu6G7mR3ibQ6g/5B84KyAukT+UABQB0rpnsrmH7bM7N5Sj6THxBY+k MhZu50VVgFBXeBFcFiF4BFhKhRrl3q+67hnyLJjaIuSrjrxJEDIfRkzqFkAFFEGNocP5 c+PwepN9LiLGC1U1ltw1zaQjhf/9S3fOGVIufkq27/1EkUEwtjTIlRWsj80avUs059EJ au4z2eXMGd+k9ctMCGCqPJm2ccZXDryzPvA8NDX7z8pT8mX4j/N9fJsRQ0aFPyCxAm7n 4BGVlqq3D8uhO/h78GVJSm8xIhjMcXRNhasmLMJ8FZLb1T3crRr4cehipNXp0kSZ3zsQ dBIg==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b="BlosR/uk"; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=j88XnqJg; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=bMlN2qNm; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b=Ivd1AB5v; 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-45886b1b7b3si2000448fac.205.2026.07.29.00.14.31 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 29 Jul 2026 00:14:31 -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="BlosR/uk"; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=j88XnqJg; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=bMlN2qNm; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b=Ivd1AB5v; 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=ouoMF8h/Su819JvEYNJuofAnAMyeMx4v7sVTbMxa9+Y=; b=BlosR/ukaniA9M0RcMIGFyy9Ny a8x6r88RNGena5UZrgY1AgBxBZnvBWRv7mzPbSCZuFoUbhduQPrud83dHI8btLwcn84SRCTQZT2go CAllimc1XFJqqsiz9kMYlJNoCpxd+MxpoFHbnSOIp/pidkkPmUq4CTX3I1+ysWfK5EIc=; 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 1woyUm-0008Td-Hn; Wed, 29 Jul 2026 07:14:28 +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 1woyUl-0008TW-Pd for openvpn-devel@lists.sourceforge.net; Wed, 29 Jul 2026 07:14:27 +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=i4/GgFLWUKLQ5Ku+pssvw7epYBWPzNQaHYNpQaIB+Rs=; b=j88XnqJgySP/FubIrjpyMjc80s 1bIimXUNYcrvmH5gDW0AJ2hvy7MMWcRLPCFRBdI7rxmHHqaOU0ilyJ8Czj7qos+DbTA1fx6MskiL6 2aFWgEwWfnmAsE81p8MJFSN1zl/taBfwHFE9tn+Y2fur2ifN9bMdEqiuTZ3+ks1m2wkY=; 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=i4/GgFLWUKLQ5Ku+pssvw7epYBWPzNQaHYNpQaIB+Rs=; b=bMlN2qNmKAjwI/M3iEPRzF8FHp 5kps7smL7AAXPHE3nSAO4G9uHPF/S3JkOfCw6kx5AJQHh6RrZqY9DcPOy6FPNCc0ggnxA1p8zCMDC js0SulYVSwNQHqDrcrPp7FLKLi1p3xO1C4zlZNvfQQv1/LVMt27MUFj+W3atTh92Vfu4=; Received: from mout-b-210.mailbox.org ([195.10.208.40]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1woyUm-0004Q3-9l for openvpn-devel@lists.sourceforge.net; Wed, 29 Jul 2026 07:14:27 +0000 Received: from smtp102.mailbox.org (smtp102.mailbox.org [IPv6:2001:67c:2050:b231:465::102]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-b-210.mailbox.org (Postfix) with ESMTPS id 4h93VJ5hNzzFr3b; Wed, 29 Jul 2026 09:14:16 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandelbit.com; s=MBO0001; t=1785309256; 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=i4/GgFLWUKLQ5Ku+pssvw7epYBWPzNQaHYNpQaIB+Rs=; b=Ivd1AB5v8jRV78WHA0mz3wkGRyYLEz9tvUm9Yz8k90A3uecpnSk14uEYH7JGJquvjNXaQJ wFoZiYfNeRFynBF2WRyonDUe9+kUAkTfTlLY48iUj7YpbW+MzKdEX7mIDjLVA4Sxjd9NDB TFBTsd7vXbG260Ei21oXfig1Bct5Ws0J3h+6fmUlA/a+VYBfzr0Cha4I7/h0yUjj0XGQV0 6yM/tr2ZCi2G7qsAyx6lXIIoNx2r1OS8Wm0bk4ndNSdP6Gz/HDoaNJQrwhKiJIabp/u4c+ KQGqgM3k6dopRp1dxItEO3nfNTdJaENE9eym0LM5pgJhBaWQAsiktMwK/GekKw== Authentication-Results: outgoing_mbo_mout; dkim=none; spf=pass (outgoing_mbo_mout: domain of marco@mandelbit.com designates 2001:67c:2050:b231:465::102 as permitted sender) smtp.mailfrom=marco@mandelbit.com From: Marco Baffo To: openvpn-devel@lists.sourceforge.net Date: Wed, 29 Jul 2026 09:13:58 +0200 Message-ID: <20260729071400.2403200-2-marco@mandelbit.com> In-Reply-To: <20260729071400.2403200-1-marco@mandelbit.com> References: <20260729071400.2403200-1-marco@mandelbit.com> MIME-Version: 1.0 X-Rspamd-Queue-Id: 4h93VJ5hNzzFr3b 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.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_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature X-Headers-End: 1woyUm-0004Q3-9l Subject: [Openvpn-devel] [PATCH ovpn net-next v2 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: 1872032455189385509 X-GMAIL-MSGID: 1872032455189385509 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. Update the Netlink specification accordingly. 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 v2: - This is a new patch. Documentation/netlink/specs/ovpn.yaml | 6 ++ drivers/net/ovpn/netlink.c | 87 +++++++++++++++------------ 2 files changed, 53 insertions(+), 40 deletions(-) diff --git a/Documentation/netlink/specs/ovpn.yaml b/Documentation/netlink/specs/ovpn.yaml index 1f0d4d6037c0..5dc998cce714 100644 --- a/Documentation/netlink/specs/ovpn.yaml +++ b/Documentation/netlink/specs/ovpn.yaml @@ -453,6 +453,8 @@ operations: - peer reply: attributes: + - ifindex + - target-netnsid - peer dump: request: @@ -461,6 +463,8 @@ operations: - target-netnsid reply: attributes: + - ifindex + - target-netnsid - peer - name: peer-del @@ -509,6 +513,8 @@ operations: - keyconf reply: attributes: + - ifindex + - target-netnsid - keyconf - name: key-swap diff --git a/drivers/net/ovpn/netlink.c b/drivers/net/ovpn/netlink.c index b70ecfaf46c8..0f15eb264332 100644 --- a/drivers/net/ovpn/netlink.c +++ b/drivers/net/ovpn/netlink.c @@ -1167,6 +1167,44 @@ 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. Use -1 if no ID can be assigned. + */ + if (!net_eq(net_sock, net_dev)) { + netnsid = peernet2id_alloc(net_sock, net_dev, GFP_ATOMIC); + 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 +1213,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 +1246,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 +1269,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 +1317,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 +1340,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 +1372,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 07:13:59 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marco Baffo X-Patchwork-Id: 5158 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:fd0b:b0:87d:ab56:3700 with SMTP id cw11csp1585093mac; Wed, 29 Jul 2026 00:14:39 -0700 (PDT) X-Forwarded-Encrypted: i=2; AHgh+RovKeIFEP+xtzAiPm+eAeTrsq8fY6feIzlF3rp9liWM0D2xB34JhP/YygWxTretRusn/8L/QEUBrlA=@openvpn.net X-Received: by 2002:a05:6830:6018:b0:7e6:fdea:7ab1 with SMTP id 46e09a7af769-7efff0c1b3amr3575666a34.8.1785309278974; Wed, 29 Jul 2026 00:14:38 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1785309278; cv=none; d=google.com; s=arc-20260327; b=mcbB7+xhSmvforEKIpXov+v0c0QxMQT/n7hHYNEAZjEm6OKOa0lLVo15sFx2VT86l/ HZHIyTVGbcc3lRdWom+s5gmZ6+1xX/786OGp3Op6yM1gRyUL18uZsjHo1DoAwgrmRPDl iMxxnyjFfVuraod6p2xgr3Ms5cp9LWHrLiEu0bwBWz+zmpoE+ZvuE8hrFma3SLdr3fXd 8mUqZ1UlEks6LIzsVEplJ4cFyR+d7hE65h7wC7WTamjF7HkyDCNFGUIQ7aWpz4eZ4A8K xjxofA8M5ZibcTftHugYsmIQMw2A89aaFrs9pyRrCvvZqI/zDpqDumMOWFQgRgii4Bkd xEMw== 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=1CtzvWsvJoBRmxfyMNS1mIFZdU1JZPYs4kNK4kPA/7s=; fh=BsMg/B0Yb/hS/rzP5Npz4luh0IleZm8REk1XWiWRt2A=; b=qWRMiywVMhdR/6dE1JrqIoEy/46klrVuwdpSrXcMD/OvpNRR6uk2q3PGv5fi21GDWn Y81jebLphfcyx5tU8KktKnPNK13YramTMT/N31KK8BOlTYM1FlBZIinxB4AAprfLjDYW 2N8gWZ7Px4qPRzT7VsjAt6IyV+lfelhXTqBgoBZWWD8i34GmJPHGEKOvvxgQECwkwwAv x2N+FHLWrQSH9Y38GTh3GCpNf6LKeCBVKUiDl2PkM31Nw9UrCnyBvNF9h/VJmGGc1XuW KxV1RMBwonbGPTsrM6WRbNaIU85TKPpo7lJ7CJTduXTh65D2K4OcdrAIpo98VTArXfYY 2nPg==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=nHrNlgHE; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=nJHDp4tl; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=JaXN7O9H; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b=fxZNTVSj; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net Received: from lists.sourceforge.net (lists.sourceforge.net. [216.105.38.7]) by mx.google.com with ESMTPS id 46e09a7af769-7f00d5dad7esi1683456a34.3.2026.07.29.00.14.38 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 29 Jul 2026 00:14:38 -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=nHrNlgHE; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=nJHDp4tl; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=JaXN7O9H; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b=fxZNTVSj; 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=1CtzvWsvJoBRmxfyMNS1mIFZdU1JZPYs4kNK4kPA/7s=; b=nHrNlgHEaD1wk/PsQtU5WzmrK7 zLXuKmOlcbtKqL9bsfxBxfva/ACMZEMCzjcSQzdsMiiM1l51NgutynkVUpoYQ1g0BAWOCPhVXmig9 Eegb6su5rEPViiRgtJmMfGiKlM67vPm+DYfSTh33Os49/ZVsou8famQ2KcKkyetUnk98=; 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 1woyUv-000639-Sq; Wed, 29 Jul 2026 07:14:35 +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 1woyUu-000631-FA for openvpn-devel@lists.sourceforge.net; Wed, 29 Jul 2026 07:14:34 +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=xZyk3IyDroL7Nn1ENLzzZgQrZaHVcIwichYBr5rnyRE=; b=nJHDp4tlbJXasoR4viuASOn6zo Qd7xVdoZY+5Rh5LtgCivG5QritJPAqcc8+vYXRoBieZkExHTW4DYFP6nvB/F9c6d1UvRE5wuHlaov DiCJauwngfN4KSl2UoVtbsqMUef+WRemLLnysW+wlBt4d/e0pEPgLj44ycjNvVTokvZY=; 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=xZyk3IyDroL7Nn1ENLzzZgQrZaHVcIwichYBr5rnyRE=; b=JaXN7O9HjbR6cAtTyhob0iknTc slE6AWD/djhrTGwIBN1zLFyMnbDACgDTITZwGJfY3CBHY2hbr3eG+Bwqfxl0+no3+1kgbR0R3CI02 qmdn0c/fVXNPNDaUaoItV9iFyJ21uZ2dqg3BL4KJtoEXBjPWCBGdJVQb797nrjXW2bcQ=; Received: from mout-b-106.mailbox.org ([195.10.208.46]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1woyUs-0004QF-9P for openvpn-devel@lists.sourceforge.net; Wed, 29 Jul 2026 07:14:33 +0000 Received: from smtp102.mailbox.org (unknown [10.196.197.102]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-b-106.mailbox.org (Postfix) with ESMTPS id 4h93VQ6BZMzNljF; Wed, 29 Jul 2026 09:14:22 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandelbit.com; s=MBO0001; t=1785309262; 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=xZyk3IyDroL7Nn1ENLzzZgQrZaHVcIwichYBr5rnyRE=; b=fxZNTVSj4WkaSHsBOe3ak21BnT1h6esL28AfjG7N79fNQdKqcmkPCV2qSkFZlucUyEp3Rr jg7VR7R20AYYLHinV6jW5p7EF6WyWmGhIQLVWauJSEidou5BWIHH4dKWd8Lb5k9n13dbMz k7bc5zlHCyXwji05bHFMMudB+KYPRJ29Xsvu2WHRjlZIdQ4bQRCFsNstLykdtX7/gKwgiL +YUU7/Q+ueGpyZgABUTWS2S0XLmOnTXEYpRT7yi9RDSMKQPgJBcEZfrkaI2UosM046P6y5 ENILB/RinbfBelZEu/6c20LgVWP9aD+R6arZ+f0EbnmsKHFjFBjNrxkgFU/Iyg== From: Marco Baffo To: openvpn-devel@lists.sourceforge.net Date: Wed, 29 Jul 2026 09:13:59 +0200 Message-ID: <20260729071400.2403200-3-marco@mandelbit.com> In-Reply-To: <20260729071400.2403200-1-marco@mandelbit.com> References: <20260729071400.2403200-1-marco@mandelbit.com> 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: 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_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_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature X-Headers-End: 1woyUs-0004QF-9P Subject: [Openvpn-devel] [PATCH ovpn net-next v2 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: 1872032462304970123 X-GMAIL-MSGID: 1872032462304970123 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 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 07:14:00 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marco Baffo X-Patchwork-Id: 5159 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:fd0b:b0:87d:ab56:3700 with SMTP id cw11csp1585173mac; Wed, 29 Jul 2026 00:14:44 -0700 (PDT) X-Forwarded-Encrypted: i=2; AHgh+RrTHEhjbnWIolhujzNcuHJ/C9UtvKK24EOFdTlMesWnuiSenp0GduyXZeg25cVaeYlcVUrq9CVIJK4=@openvpn.net X-Received: by 2002:a05:6808:1905:b0:495:fecb:bf9c with SMTP id 5614622812f47-4ad5b965d74mr3264396b6e.6.1785309284577; Wed, 29 Jul 2026 00:14:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1785309284; cv=none; d=google.com; s=arc-20260327; b=sQYWtOj2HE8uysHD9voT/nmpxSMFt3BeM+Ug415FaqHeQx5siIEm3YKxUyck0zoAxy m9zSrlrgEYDF/xsT5y/FAMa80zfA1CiSVcLIFkrAWR7HUrB1tjxf/hzdlAkgOybGgWra /Lq0ziXV4K72sidcdwpPM1TfRYkqgXIT0H/xGjlg/S0AobN3GSmsyPqfMOYQJ0l79py6 kmUoh2o3MogRbmkTqmXtp0qisrqPCKninBJ5/RCXlp5mO/hCH3TAg5sccy7O+zxHZfot punIH7gNPwqNHisuRW1ioxUo8w/dS4eug0F0psR7HRiqeCEf7hSxHV/bzb6/ZEQPy7as hfVQ== 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=Gwejz/dkk6qlG3YW7YKr5gj9hU3QBXgO0msch2J042Q=; fh=BsMg/B0Yb/hS/rzP5Npz4luh0IleZm8REk1XWiWRt2A=; b=rA8UYcgkcN19CxviO3gkZ8psN4MqCKh8IndZxYeB0FU6/3cLbQc7XKjiMwb5PcBJLW FtdQxHJeL9gebwQqEo2Fpsw8hr5bzjyophuvSjPqkdFMVACu6WzpRpWFzK1PapWydaiH VbgleoqP66OOmSJWCDHcyGs+uP4FXWjVEsWwhxRDhr6HeBQKcisO1Lydv6EV5yaqp195 Uz4eUjSs/F7SAYrU9rXqVl4mj2FFdX2mC8CjeZZfhMuCpWYqpcalO6ws/9bopgmIPSAp U5uimdF/oEQicvYVPBXQKWaymLgDMBiwQnh/ttYbq1AC86MTCgHDjBhv5m2bpD3ZRk2+ TUYg==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.sourceforge.net header.s=beta header.b=mRubyiHW; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=IskQsXIK; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=JnMGKMWL; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b=kWoJUdkU; 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-4ad6f044acesi1040848b6e.93.2026.07.29.00.14.44 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 29 Jul 2026 00:14:44 -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=mRubyiHW; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b=IskQsXIK; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b=JnMGKMWL; dkim=neutral (body hash did not verify) header.i=@mandelbit.com header.s=MBO0001 header.b=kWoJUdkU; 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=Gwejz/dkk6qlG3YW7YKr5gj9hU3QBXgO0msch2J042Q=; b=mRubyiHWtG3aF8qPwq7hsdJhWw TDv1Jxeai4td2A4a1lpW0cZ9xepnZZB2SqeKGTl4hD7608cWJbTF2yBuOzxkkzk1zrkUdV/NRyxd2 PYelnWx98b5BAYsy7nSPMN6qqENhUD9eseupjV6tZskNGpLLrCY+XVxI/LGhlDc+vEvk=; 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 1woyUy-00037l-0J; Wed, 29 Jul 2026 07:14:40 +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 1woyUw-00037R-2A for openvpn-devel@lists.sourceforge.net; Wed, 29 Jul 2026 07:14:38 +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=oHoXkqdoGfOdSMgyxtuCeOT01uX8rKspl/9/B7590nM=; b=IskQsXIKBbm6uShHTdJkURdIPt BQTQ3wU+C8bWB98CJs+VHjd1Il6VGW8mf7+UxLBM5Ad1wDY3wMTCOcQOOVxBXjhWLQ1voluBwa7jq 7rCS9XPuy1MIiMoJmFjTHAve1HgSCPj5wpEOx3/RDPMcnfSFPvbM8Pyf3jQ7zFCKsUSk=; 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=oHoXkqdoGfOdSMgyxtuCeOT01uX8rKspl/9/B7590nM=; b=JnMGKMWLUs3a0rx82pZXs80psS o7YSmAMGC6GA9sKT10LdRAcrlgWjzPKyX+VKbzzZnOlgQ0VeFX0y8gEGL4+zjqwk3muZZj6dmkYGi CL43lYrWVZ7uAvWQQBP9LEDwLhGK9X6C7/O/2jyGXIlOYUFZqPvLTf8HW7aGc2CuCKAA=; 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 1woyUw-0004QS-Ip for openvpn-devel@lists.sourceforge.net; Wed, 29 Jul 2026 07:14:38 +0000 Received: from smtp102.mailbox.org (unknown [10.196.197.102]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-b-203.mailbox.org (Postfix) with ESMTPS id 4h93VW53YPzLlnd; Wed, 29 Jul 2026 09:14:27 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandelbit.com; s=MBO0001; t=1785309267; 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=oHoXkqdoGfOdSMgyxtuCeOT01uX8rKspl/9/B7590nM=; b=kWoJUdkUUDqLooA1NhRfFc40MNiOl4dvvvbqmQsw3EvDTpLDwooQFxbgSOBIaRLu1aFIQx Xp6zXVuJ22W0JcT4MiByX/t2cICIMgrzcU2+hWHAjquzjyFTLMBXwCBBGAi+BPv53vcr96 IJX23dWQRF+MsjHVjbEuGWRisodhZTI84iWN6atUfLZNFwlYsqWXouhZnXfvRO565nwHdX aGbDXyBSjfHpYwz7L/FVCbskQI2LpNDPuJvajtxL8+MeldWZOjSXokAEUhfID1nffF+xLz 34uAh3lXdQdKr8MyGX6mQjmHnG8IfT7w1iQsmJfTl3WTO2ogMwqWQ2RtzB3KIQ== From: Marco Baffo To: openvpn-devel@lists.sourceforge.net Date: Wed, 29 Jul 2026 09:14:00 +0200 Message-ID: <20260729071400.2403200-4-marco@mandelbit.com> In-Reply-To: <20260729071400.2403200-1-marco@mandelbit.com> References: <20260729071400.2403200-1-marco@mandelbit.com> 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: 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 v2: - This is a new patch. Content analysis details: (-0.2 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -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_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature X-Headers-End: 1woyUw-0004QS-Ip Subject: [Openvpn-devel] [PATCH ovpn net-next v2 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: 1872032468342160114 X-GMAIL-MSGID: 1872032468342160114 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 v2: - This is a new patch. tools/testing/selftests/net/ovpn/common.sh | 3 ++- tools/testing/selftests/net/ovpn/test.sh | 22 ++++++++++++++++++++++ 2 files changed, 24 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..d30cf250d59a 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,26 @@ 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 '.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}"