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

Configure Feed

Select the types of activity you want to include in your feed.

ovpn: notify userspace on client float event

Send a netlink notification when a client updates its remote UDP
endpoint. The notification includes the new IP address, port, and scope
ID (for IPv6).

Cc: linux-kselftest@vger.kernel.org
Cc: horms@kernel.org
Cc: shuah@kernel.org
Cc: donald.hunter@gmail.com
Signed-off-by: Ralf Lici <ralf@mandelbit.com>
Signed-off-by: Antonio Quartulli <antonio@openvpn.net>
Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>

authored by

Ralf Lici and committed by
Antonio Quartulli
c841b676 4a648059

+96
+6
Documentation/netlink/specs/ovpn.yaml
··· 502 502 - ifindex 503 503 - keyconf 504 504 505 + - 506 + name: peer-float-ntf 507 + doc: Notification about a peer floating (changing its remote UDP endpoint) 508 + notify: peer-get 509 + mcgrp: peers 510 + 505 511 mcast-groups: 506 512 list: 507 513 -
+82
drivers/net/ovpn/netlink.c
··· 1204 1204 } 1205 1205 1206 1206 /** 1207 + * ovpn_nl_peer_float_notify - notify userspace about peer floating 1208 + * @peer: the floated peer 1209 + * @ss: sockaddr representing the new remote endpoint 1210 + * 1211 + * Return: 0 on success or a negative error code otherwise 1212 + */ 1213 + int ovpn_nl_peer_float_notify(struct ovpn_peer *peer, 1214 + const struct sockaddr_storage *ss) 1215 + { 1216 + struct ovpn_socket *sock; 1217 + struct sockaddr_in6 *sa6; 1218 + struct sockaddr_in *sa; 1219 + struct sk_buff *msg; 1220 + struct nlattr *attr; 1221 + int ret = -EMSGSIZE; 1222 + void *hdr; 1223 + 1224 + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); 1225 + if (!msg) 1226 + return -ENOMEM; 1227 + 1228 + hdr = genlmsg_put(msg, 0, 0, &ovpn_nl_family, 0, 1229 + OVPN_CMD_PEER_FLOAT_NTF); 1230 + if (!hdr) { 1231 + ret = -ENOBUFS; 1232 + goto err_free_msg; 1233 + } 1234 + 1235 + if (nla_put_u32(msg, OVPN_A_IFINDEX, peer->ovpn->dev->ifindex)) 1236 + goto err_cancel_msg; 1237 + 1238 + attr = nla_nest_start(msg, OVPN_A_PEER); 1239 + if (!attr) 1240 + goto err_cancel_msg; 1241 + 1242 + if (nla_put_u32(msg, OVPN_A_PEER_ID, peer->id)) 1243 + goto err_cancel_msg; 1244 + 1245 + if (ss->ss_family == AF_INET) { 1246 + sa = (struct sockaddr_in *)ss; 1247 + if (nla_put_in_addr(msg, OVPN_A_PEER_REMOTE_IPV4, 1248 + sa->sin_addr.s_addr) || 1249 + nla_put_net16(msg, OVPN_A_PEER_REMOTE_PORT, sa->sin_port)) 1250 + goto err_cancel_msg; 1251 + } else if (ss->ss_family == AF_INET6) { 1252 + sa6 = (struct sockaddr_in6 *)ss; 1253 + if (nla_put_in6_addr(msg, OVPN_A_PEER_REMOTE_IPV6, 1254 + &sa6->sin6_addr) || 1255 + nla_put_u32(msg, OVPN_A_PEER_REMOTE_IPV6_SCOPE_ID, 1256 + sa6->sin6_scope_id) || 1257 + nla_put_net16(msg, OVPN_A_PEER_REMOTE_PORT, sa6->sin6_port)) 1258 + goto err_cancel_msg; 1259 + } else { 1260 + ret = -EAFNOSUPPORT; 1261 + goto err_cancel_msg; 1262 + } 1263 + 1264 + nla_nest_end(msg, attr); 1265 + genlmsg_end(msg, hdr); 1266 + 1267 + rcu_read_lock(); 1268 + sock = rcu_dereference(peer->sock); 1269 + if (!sock) { 1270 + ret = -EINVAL; 1271 + goto err_unlock; 1272 + } 1273 + genlmsg_multicast_netns(&ovpn_nl_family, sock_net(sock->sk), msg, 1274 + 0, OVPN_NLGRP_PEERS, GFP_ATOMIC); 1275 + rcu_read_unlock(); 1276 + 1277 + return 0; 1278 + 1279 + err_unlock: 1280 + rcu_read_unlock(); 1281 + err_cancel_msg: 1282 + genlmsg_cancel(msg, hdr); 1283 + err_free_msg: 1284 + nlmsg_free(msg); 1285 + return ret; 1286 + } 1287 + 1288 + /** 1207 1289 * ovpn_nl_key_swap_notify - notify userspace peer's key must be renewed 1208 1290 * @peer: the peer whose key needs to be renewed 1209 1291 * @key_id: the ID of the key that needs to be renewed
+2
drivers/net/ovpn/netlink.h
··· 13 13 void ovpn_nl_unregister(void); 14 14 15 15 int ovpn_nl_peer_del_notify(struct ovpn_peer *peer); 16 + int ovpn_nl_peer_float_notify(struct ovpn_peer *peer, 17 + const struct sockaddr_storage *ss); 16 18 int ovpn_nl_key_swap_notify(struct ovpn_peer *peer, u8 key_id); 17 19 18 20 #endif /* _NET_OVPN_NETLINK_H_ */
+2
drivers/net/ovpn/peer.c
··· 287 287 288 288 spin_unlock_bh(&peer->lock); 289 289 290 + ovpn_nl_peer_float_notify(peer, &ss); 291 + 290 292 /* rehashing is required only in MP mode as P2P has one peer 291 293 * only and thus there is no hashtable 292 294 */
+1
include/uapi/linux/ovpn.h
··· 100 100 OVPN_CMD_KEY_SWAP, 101 101 OVPN_CMD_KEY_SWAP_NTF, 102 102 OVPN_CMD_KEY_DEL, 103 + OVPN_CMD_PEER_FLOAT_NTF, 103 104 104 105 __OVPN_CMD_MAX, 105 106 OVPN_CMD_MAX = (__OVPN_CMD_MAX - 1)
+3
tools/testing/selftests/net/ovpn/ovpn-cli.c
··· 1516 1516 case OVPN_CMD_PEER_DEL_NTF: 1517 1517 fprintf(stdout, "received CMD_PEER_DEL_NTF\n"); 1518 1518 break; 1519 + case OVPN_CMD_PEER_FLOAT_NTF: 1520 + fprintf(stdout, "received CMD_PEER_FLOAT_NTF\n"); 1521 + break; 1519 1522 case OVPN_CMD_KEY_SWAP_NTF: 1520 1523 fprintf(stdout, "received CMD_KEY_SWAP_NTF\n"); 1521 1524 break;