Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ovpn: notify userspace when a peer is deleted

Whenever a peer is deleted, send a notification to userspace so that it
can react accordingly.

This is most important when a peer is deleted due to ping timeout,
because it all happens in kernelspace and thus userspace has no direct
way to learn about it.

Signed-off-by: Antonio Quartulli <antonio@openvpn.net>
Link: https://patch.msgid.link/20250415-b4-ovpn-v26-21-577f6097b964@openvpn.net
Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

authored by

Antonio Quartulli and committed by
Paolo Abeni
a215d253 89d3c0e4

+67
+65
drivers/net/ovpn/netlink.c
··· 1104 1104 } 1105 1105 1106 1106 /** 1107 + * ovpn_nl_peer_del_notify - notify userspace about peer being deleted 1108 + * @peer: the peer being deleted 1109 + * 1110 + * Return: 0 on success or a negative error code otherwise 1111 + */ 1112 + int ovpn_nl_peer_del_notify(struct ovpn_peer *peer) 1113 + { 1114 + struct ovpn_socket *sock; 1115 + struct sk_buff *msg; 1116 + struct nlattr *attr; 1117 + int ret = -EMSGSIZE; 1118 + void *hdr; 1119 + 1120 + netdev_info(peer->ovpn->dev, "deleting peer with id %u, reason %d\n", 1121 + peer->id, peer->delete_reason); 1122 + 1123 + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); 1124 + if (!msg) 1125 + return -ENOMEM; 1126 + 1127 + hdr = genlmsg_put(msg, 0, 0, &ovpn_nl_family, 0, OVPN_CMD_PEER_DEL_NTF); 1128 + if (!hdr) { 1129 + ret = -ENOBUFS; 1130 + goto err_free_msg; 1131 + } 1132 + 1133 + if (nla_put_u32(msg, OVPN_A_IFINDEX, peer->ovpn->dev->ifindex)) 1134 + goto err_cancel_msg; 1135 + 1136 + attr = nla_nest_start(msg, OVPN_A_PEER); 1137 + if (!attr) 1138 + goto err_cancel_msg; 1139 + 1140 + if (nla_put_u32(msg, OVPN_A_PEER_DEL_REASON, peer->delete_reason)) 1141 + goto err_cancel_msg; 1142 + 1143 + if (nla_put_u32(msg, OVPN_A_PEER_ID, peer->id)) 1144 + goto err_cancel_msg; 1145 + 1146 + nla_nest_end(msg, attr); 1147 + 1148 + genlmsg_end(msg, hdr); 1149 + 1150 + rcu_read_lock(); 1151 + sock = rcu_dereference(peer->sock); 1152 + if (!sock) { 1153 + ret = -EINVAL; 1154 + goto err_unlock; 1155 + } 1156 + genlmsg_multicast_netns(&ovpn_nl_family, sock_net(sock->sock->sk), 1157 + msg, 0, OVPN_NLGRP_PEERS, GFP_ATOMIC); 1158 + rcu_read_unlock(); 1159 + 1160 + return 0; 1161 + 1162 + err_unlock: 1163 + rcu_read_unlock(); 1164 + err_cancel_msg: 1165 + genlmsg_cancel(msg, hdr); 1166 + err_free_msg: 1167 + nlmsg_free(msg); 1168 + return ret; 1169 + } 1170 + 1171 + /** 1107 1172 * ovpn_nl_key_swap_notify - notify userspace peer's key must be renewed 1108 1173 * @peer: the peer whose key needs to be renewed 1109 1174 * @key_id: the ID of the key that needs to be renewed
+1
drivers/net/ovpn/netlink.h
··· 12 12 int ovpn_nl_register(void); 13 13 void ovpn_nl_unregister(void); 14 14 15 + int ovpn_nl_peer_del_notify(struct ovpn_peer *peer); 15 16 int ovpn_nl_key_swap_notify(struct ovpn_peer *peer, u8 key_id); 16 17 17 18 #endif /* _NET_OVPN_NETLINK_H_ */
+1
drivers/net/ovpn/peer.c
··· 706 706 } 707 707 708 708 peer->delete_reason = reason; 709 + ovpn_nl_peer_del_notify(peer); 709 710 710 711 /* append to provided list for later socket release and ref drop */ 711 712 llist_add(&peer->release_entry, release_list);