[Openvpn-devel] [PATCH ovpn net-next v2 2/4] ovpn: include target netns ID in notifications

Marco Baffo <[email protected]> Wed, 29 Jul 2026 09:13:58 +0200
Newsgroups net.sourceforge.lists.openvpn-devel
Message-ID <[email protected]>
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 <[email protected]>
---
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:
-- 
2.43.0



_______________________________________________
Openvpn-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openvpn-devel