vpn notifications are multicast in the network namespace of the peer
transport socket, but carry an ifindex that is only meaningful in the
ovpn device namespace. If the two namespaces differ, listeners resolve
it to an unrelated interface, as ifindexes are numbered per netns.
Multicast notifications in the device namespace instead. This also
avoids depending on the transport socket when sending a notification.
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 <marco@mandelbit.com>
---
drivers/net/ovpn/netlink.c | 44 +++++---------------------------------
1 file changed, 5 insertions(+), 39 deletions(-)
@@ -1188,7 +1188,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;
@@ -1221,23 +1220,12 @@ int ovpn_nl_peer_del_notify(struct ovpn_peer *peer)
goto err_cancel_msg;
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();
+ genlmsg_multicast_netns(&ovpn_nl_family, dev_net(peer->ovpn->dev), msg,
+ 0, OVPN_NLGRP_PEERS, GFP_ATOMIC);
return 0;
-err_unlock:
- rcu_read_unlock();
err_cancel_msg:
genlmsg_cancel(msg, hdr);
err_free_msg:
@@ -1255,7 +1243,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;
@@ -1305,21 +1292,11 @@ 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,
+ genlmsg_multicast_netns(&ovpn_nl_family, dev_net(peer->ovpn->dev), msg,
0, OVPN_NLGRP_PEERS, GFP_ATOMIC);
- rcu_read_unlock();
return 0;
-err_unlock:
- rcu_read_unlock();
err_cancel_msg:
genlmsg_cancel(msg, hdr);
err_free_msg:
@@ -1336,7 +1313,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;
@@ -1370,20 +1346,10 @@ int ovpn_nl_key_swap_notify(struct ovpn_peer *peer, u8 key_id)
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();
+ genlmsg_multicast_netns(&ovpn_nl_family, dev_net(peer->ovpn->dev), msg,
+ 0, OVPN_NLGRP_PEERS, GFP_ATOMIC);
return 0;
-err_unlock:
- rcu_read_unlock();
err_cancel_msg:
genlmsg_cancel(msg, hdr);
err_free_msg: