1 // SPDX-License-Identifier: GPL-2.0 2 /* OpenVPN data channel offload 3 * 4 * Copyright (C) 2020-2025 OpenVPN, Inc. 5 * 6 * Author: James Yonan <james@openvpn.net> 7 * Antonio Quartulli <antonio@openvpn.net> 8 */ 9 10 #include <linux/net.h> 11 #include <linux/netdevice.h> 12 #include <linux/udp.h> 13 14 #include "ovpnpriv.h" 15 #include "main.h" 16 #include "io.h" 17 #include "peer.h" 18 #include "socket.h" 19 #include "tcp.h" 20 #include "udp.h" 21 22 static void ovpn_socket_release_kref(struct kref *kref) 23 { 24 struct ovpn_socket *sock = container_of(kref, struct ovpn_socket, 25 refcount); 26 27 if (sock->sk->sk_protocol == IPPROTO_UDP) 28 ovpn_udp_socket_detach(sock); 29 else if (sock->sk->sk_protocol == IPPROTO_TCP) 30 ovpn_tcp_socket_detach(sock); 31 } 32 33 /** 34 * ovpn_socket_put - decrease reference counter 35 * @peer: peer whose socket reference counter should be decreased 36 * @sock: the RCU protected peer socket 37 * 38 * This function is only used internally. Users willing to release 39 * references to the ovpn_socket should use ovpn_socket_release() 40 * 41 * Return: true if the socket was released, false otherwise 42 */ 43 static bool ovpn_socket_put(struct ovpn_peer *peer, struct ovpn_socket *sock) 44 { 45 return kref_put(&sock->refcount, ovpn_socket_release_kref); 46 } 47 48 /** 49 * ovpn_socket_release - release resources owned by socket user 50 * @peer: peer whose socket should be released 51 * 52 * This function should be invoked when the peer is being removed 53 * and wants to drop its link to the socket. 54 * 55 * In case of UDP, the detach routine will drop a reference to the 56 * ovpn netdev, pointed by the ovpn_socket. 57 * 58 * In case of TCP, releasing the socket will cause dropping 59 * the refcounter for the peer it is linked to, thus allowing the peer 60 * disappear as well. 61 * 62 * This function is expected to be invoked exactly once per peer 63 * 64 * NOTE: this function may sleep 65 */ 66 void ovpn_socket_release(struct ovpn_peer *peer) 67 { 68 struct ovpn_socket *sock; 69 bool released; 70 71 might_sleep(); 72 73 sock = rcu_replace_pointer(peer->sock, NULL, true); 74 /* release may be invoked after socket was detached */ 75 if (!sock) 76 return; 77 78 /* Drop the reference while holding the sock lock to avoid 79 * concurrent ovpn_socket_new call to mess up with a partially 80 * detached socket. 81 * 82 * Holding the lock ensures that a socket with refcnt 0 is fully 83 * detached before it can be picked by a concurrent reader. 84 */ 85 lock_sock(sock->sk); 86 released = ovpn_socket_put(peer, sock); 87 release_sock(sock->sk); 88 89 /* align all readers with sk_user_data being NULL */ 90 synchronize_rcu(); 91 92 /* following cleanup should happen with lock released */ 93 if (released) { 94 if (sock->sk->sk_protocol == IPPROTO_UDP) { 95 netdev_put(sock->ovpn->dev, &sock->dev_tracker); 96 } else if (sock->sk->sk_protocol == IPPROTO_TCP) { 97 /* wait for TCP jobs to terminate */ 98 ovpn_tcp_socket_wait_finish(sock); 99 ovpn_peer_put(sock->peer); 100 } 101 /* drop reference acquired in ovpn_socket_new() */ 102 sock_put(sock->sk); 103 /* we can call plain kfree() because we already waited one RCU 104 * period due to synchronize_rcu() 105 */ 106 kfree(sock); 107 } 108 } 109 110 static bool ovpn_socket_hold(struct ovpn_socket *sock) 111 { 112 return kref_get_unless_zero(&sock->refcount); 113 } 114 115 static int ovpn_socket_attach(struct ovpn_socket *ovpn_sock, 116 struct socket *sock, 117 struct ovpn_peer *peer) 118 { 119 if (sock->sk->sk_protocol == IPPROTO_UDP) 120 return ovpn_udp_socket_attach(ovpn_sock, sock, peer->ovpn); 121 else if (sock->sk->sk_protocol == IPPROTO_TCP) 122 return ovpn_tcp_socket_attach(ovpn_sock, peer); 123 124 return -EOPNOTSUPP; 125 } 126 127 /** 128 * ovpn_socket_new - create a new socket and initialize it 129 * @sock: the kernel socket to embed 130 * @peer: the peer reachable via this socket 131 * 132 * Return: an openvpn socket on success or a negative error code otherwise 133 */ 134 struct ovpn_socket *ovpn_socket_new(struct socket *sock, struct ovpn_peer *peer) 135 { 136 struct ovpn_socket *ovpn_sock; 137 struct sock *sk = sock->sk; 138 int ret; 139 140 lock_sock(sk); 141 142 /* a TCP socket can only be owned by a single peer, therefore there 143 * can't be any other user 144 */ 145 if (sk->sk_protocol == IPPROTO_TCP && sk->sk_user_data) { 146 ovpn_sock = ERR_PTR(-EBUSY); 147 goto sock_release; 148 } 149 150 /* a UDP socket can be shared across multiple peers, but we must make 151 * sure it is not owned by something else 152 */ 153 if (sk->sk_protocol == IPPROTO_UDP) { 154 u8 type = READ_ONCE(udp_sk(sk)->encap_type); 155 156 /* socket owned by other encapsulation module */ 157 if (type && type != UDP_ENCAP_OVPNINUDP) { 158 ovpn_sock = ERR_PTR(-EBUSY); 159 goto sock_release; 160 } 161 162 rcu_read_lock(); 163 ovpn_sock = rcu_dereference_sk_user_data(sk); 164 if (ovpn_sock) { 165 /* something else filled the sk_user_data without 166 * setting the encap_type. Reject the socket. 167 */ 168 if (!type) { 169 ovpn_sock = ERR_PTR(-EBUSY); 170 rcu_read_unlock(); 171 goto sock_release; 172 } 173 174 /* socket owned by another ovpn instance, we can't use it */ 175 if (ovpn_sock->ovpn != peer->ovpn) { 176 ovpn_sock = ERR_PTR(-EBUSY); 177 rcu_read_unlock(); 178 goto sock_release; 179 } 180 181 /* this socket is already owned by this instance, 182 * therefore we can increase the refcounter and 183 * use it as expected 184 */ 185 if (WARN_ON(!ovpn_socket_hold(ovpn_sock))) { 186 /* this should never happen because setting 187 * the refcnt to 0 and detaching the socket 188 * is expected to be atomic 189 */ 190 ovpn_sock = ERR_PTR(-EAGAIN); 191 rcu_read_unlock(); 192 goto sock_release; 193 } 194 195 rcu_read_unlock(); 196 goto sock_release; 197 } 198 rcu_read_unlock(); 199 } 200 201 /* socket is not owned: attach to this ovpn instance */ 202 203 ovpn_sock = kzalloc_obj(*ovpn_sock); 204 if (!ovpn_sock) { 205 ovpn_sock = ERR_PTR(-ENOMEM); 206 goto sock_release; 207 } 208 209 ovpn_sock->sk = sk; 210 kref_init(&ovpn_sock->refcount); 211 212 /* TCP sockets are per-peer, therefore they are linked to their unique 213 * peer 214 */ 215 if (sk->sk_protocol == IPPROTO_TCP) { 216 INIT_WORK(&ovpn_sock->tcp_tx_work, ovpn_tcp_tx_work); 217 ovpn_sock->peer = peer; 218 ovpn_peer_hold(peer); 219 } else if (sk->sk_protocol == IPPROTO_UDP) { 220 /* in UDP we only link the ovpn instance since the socket is 221 * shared among multiple peers 222 */ 223 ovpn_sock->ovpn = peer->ovpn; 224 netdev_hold(peer->ovpn->dev, &ovpn_sock->dev_tracker, 225 GFP_KERNEL); 226 } 227 228 /* the newly created ovpn_socket is holding reference to sk, 229 * therefore we increase its refcounter. 230 * 231 * This ovpn_socket instance is referenced by all peers 232 * using the same socket. 233 * 234 * ovpn_socket_release() will take care of dropping the reference. 235 */ 236 sock_hold(sk); 237 238 ret = ovpn_socket_attach(ovpn_sock, sock, peer); 239 if (ret < 0) { 240 if (sk->sk_protocol == IPPROTO_TCP) 241 ovpn_peer_put(peer); 242 else if (sk->sk_protocol == IPPROTO_UDP) 243 netdev_put(peer->ovpn->dev, &ovpn_sock->dev_tracker); 244 245 sock_put(sk); 246 kfree(ovpn_sock); 247 ovpn_sock = ERR_PTR(ret); 248 } 249 250 sock_release: 251 release_sock(sk); 252 return ovpn_sock; 253 } 254