@@ -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
@@ -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: