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:
