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

ovpn: implement basic RX path (UDP)

Packets received over the socket are forwarded to the user device.

Implementation is UDP only. TCP will be added by a later patch.

Note: no decryption/decapsulation exists yet, packets are forwarded as
they arrive without much processing.

Signed-off-by: Antonio Quartulli <antonio@openvpn.net>
Link: https://patch.msgid.link/20250415-b4-ovpn-v26-8-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
ab66abbc 08857b5e

+290 -5
+63 -1
drivers/net/ovpn/io.c
··· 9 9 10 10 #include <linux/netdevice.h> 11 11 #include <linux/skbuff.h> 12 + #include <net/gro_cells.h> 12 13 #include <net/gso.h> 13 14 14 - #include "io.h" 15 15 #include "ovpnpriv.h" 16 16 #include "peer.h" 17 + #include "io.h" 18 + #include "netlink.h" 19 + #include "proto.h" 17 20 #include "udp.h" 18 21 #include "skb.h" 19 22 #include "socket.h" 23 + 24 + /* Called after decrypt to write the IP packet to the device. 25 + * This method is expected to manage/free the skb. 26 + */ 27 + static void ovpn_netdev_write(struct ovpn_peer *peer, struct sk_buff *skb) 28 + { 29 + unsigned int pkt_len; 30 + int ret; 31 + 32 + /* we can't guarantee the packet wasn't corrupted before entering the 33 + * VPN, therefore we give other layers a chance to check that 34 + */ 35 + skb->ip_summed = CHECKSUM_NONE; 36 + 37 + /* skb hash for transport packet no longer valid after decapsulation */ 38 + skb_clear_hash(skb); 39 + 40 + /* post-decrypt scrub -- prepare to inject encapsulated packet onto the 41 + * interface, based on __skb_tunnel_rx() in dst.h 42 + */ 43 + skb->dev = peer->ovpn->dev; 44 + skb_set_queue_mapping(skb, 0); 45 + skb_scrub_packet(skb, true); 46 + 47 + skb_reset_network_header(skb); 48 + skb_reset_transport_header(skb); 49 + skb_reset_inner_headers(skb); 50 + 51 + /* cause packet to be "received" by the interface */ 52 + pkt_len = skb->len; 53 + ret = gro_cells_receive(&peer->ovpn->gro_cells, skb); 54 + if (likely(ret == NET_RX_SUCCESS)) 55 + /* update RX stats with the size of decrypted packet */ 56 + dev_dstats_rx_add(peer->ovpn->dev, pkt_len); 57 + } 58 + 59 + static void ovpn_decrypt_post(struct sk_buff *skb, int ret) 60 + { 61 + struct ovpn_peer *peer = ovpn_skb_cb(skb)->peer; 62 + 63 + if (unlikely(ret < 0)) 64 + goto drop; 65 + 66 + ovpn_netdev_write(peer, skb); 67 + /* skb is passed to upper layer - don't free it */ 68 + skb = NULL; 69 + drop: 70 + if (unlikely(skb)) 71 + dev_dstats_rx_dropped(peer->ovpn->dev); 72 + ovpn_peer_put(peer); 73 + kfree_skb(skb); 74 + } 75 + 76 + /* RX path entry point: decrypt packet and forward it to the device */ 77 + void ovpn_recv(struct ovpn_peer *peer, struct sk_buff *skb) 78 + { 79 + ovpn_skb_cb(skb)->peer = peer; 80 + ovpn_decrypt_post(skb, 0); 81 + } 20 82 21 83 static void ovpn_encrypt_post(struct sk_buff *skb, int ret) 22 84 {
+2
drivers/net/ovpn/io.h
··· 21 21 22 22 netdev_tx_t ovpn_net_xmit(struct sk_buff *skb, struct net_device *dev); 23 23 24 + void ovpn_recv(struct ovpn_peer *peer, struct sk_buff *skb); 25 + 24 26 #endif /* _NET_OVPN_OVPN_H_ */
+18
drivers/net/ovpn/main.c
··· 11 11 #include <linux/module.h> 12 12 #include <linux/netdevice.h> 13 13 #include <linux/inetdevice.h> 14 + #include <net/gro_cells.h> 14 15 #include <net/ip.h> 15 16 #include <net/rtnetlink.h> 16 17 #include <uapi/linux/if_arp.h> ··· 22 21 #include "io.h" 23 22 #include "peer.h" 24 23 #include "proto.h" 24 + #include "udp.h" 25 + 26 + static int ovpn_net_init(struct net_device *dev) 27 + { 28 + struct ovpn_priv *ovpn = netdev_priv(dev); 29 + 30 + return gro_cells_init(&ovpn->gro_cells, dev); 31 + } 32 + 33 + static void ovpn_net_uninit(struct net_device *dev) 34 + { 35 + struct ovpn_priv *ovpn = netdev_priv(dev); 36 + 37 + gro_cells_destroy(&ovpn->gro_cells); 38 + } 25 39 26 40 static const struct net_device_ops ovpn_netdev_ops = { 41 + .ndo_init = ovpn_net_init, 42 + .ndo_uninit = ovpn_net_uninit, 27 43 .ndo_start_xmit = ovpn_net_xmit, 28 44 }; 29 45
+3
drivers/net/ovpn/ovpnpriv.h
··· 10 10 #ifndef _NET_OVPN_OVPNSTRUCT_H_ 11 11 #define _NET_OVPN_OVPNSTRUCT_H_ 12 12 13 + #include <net/gro_cells.h> 13 14 #include <uapi/linux/if_link.h> 14 15 #include <uapi/linux/ovpn.h> 15 16 ··· 20 19 * @mode: device operation mode (i.e. p2p, mp, ..) 21 20 * @lock: protect this object 22 21 * @peer: in P2P mode, this is the only remote peer 22 + * @gro_cells: pointer to the Generic Receive Offload cell 23 23 */ 24 24 struct ovpn_priv { 25 25 struct net_device *dev; 26 26 enum ovpn_mode mode; 27 27 spinlock_t lock; /* protect writing to the ovpn_priv object */ 28 28 struct ovpn_peer __rcu *peer; 29 + struct gro_cells gro_cells; 29 30 }; 30 31 31 32 #endif /* _NET_OVPN_OVPNSTRUCT_H_ */
+49 -1
drivers/net/ovpn/proto.h
··· 10 10 #ifndef _NET_OVPN_PROTO_H_ 11 11 #define _NET_OVPN_PROTO_H_ 12 12 13 + #include "main.h" 14 + 15 + #include <linux/bitfield.h> 16 + #include <linux/skbuff.h> 17 + 13 18 /* When the OpenVPN protocol is ran in AEAD mode, use 14 19 * the OpenVPN packet ID as the AEAD nonce: 15 20 * ··· 39 34 #define OVPN_NONCE_WIRE_SIZE (OVPN_NONCE_SIZE - OVPN_NONCE_TAIL_SIZE) 40 35 41 36 #define OVPN_OPCODE_SIZE 4 /* DATA_V2 opcode size */ 37 + #define OVPN_OPCODE_KEYID_MASK 0x07000000 38 + #define OVPN_OPCODE_PKTTYPE_MASK 0xF8000000 39 + #define OVPN_OPCODE_PEERID_MASK 0x00FFFFFF 42 40 43 - #endif /* _NET_OVPN_PROTO_H_ */ 41 + /* packet opcodes of interest to us */ 42 + #define OVPN_DATA_V1 6 /* data channel v1 packet */ 43 + #define OVPN_DATA_V2 9 /* data channel v2 packet */ 44 + 45 + #define OVPN_PEER_ID_UNDEF 0x00FFFFFF 46 + 47 + /** 48 + * ovpn_opcode_from_skb - extract OP code from skb at specified offset 49 + * @skb: the packet to extract the OP code from 50 + * @offset: the offset in the data buffer where the OP code is located 51 + * 52 + * Note: this function assumes that the skb head was pulled enough 53 + * to access the first 4 bytes. 54 + * 55 + * Return: the OP code 56 + */ 57 + static inline u8 ovpn_opcode_from_skb(const struct sk_buff *skb, u16 offset) 58 + { 59 + u32 opcode = be32_to_cpu(*(__be32 *)(skb->data + offset)); 60 + 61 + return FIELD_GET(OVPN_OPCODE_PKTTYPE_MASK, opcode); 62 + } 63 + 64 + /** 65 + * ovpn_peer_id_from_skb - extract peer ID from skb at specified offset 66 + * @skb: the packet to extract the OP code from 67 + * @offset: the offset in the data buffer where the OP code is located 68 + * 69 + * Note: this function assumes that the skb head was pulled enough 70 + * to access the first 4 bytes. 71 + * 72 + * Return: the peer ID 73 + */ 74 + static inline u32 ovpn_peer_id_from_skb(const struct sk_buff *skb, u16 offset) 75 + { 76 + u32 opcode = be32_to_cpu(*(__be32 *)(skb->data + offset)); 77 + 78 + return FIELD_GET(OVPN_OPCODE_PEERID_MASK, opcode); 79 + } 80 + 81 + #endif /* _NET_OVPN_OVPNPROTO_H_ */
+12 -2
drivers/net/ovpn/socket.c
··· 23 23 struct ovpn_socket *sock = container_of(kref, struct ovpn_socket, 24 24 refcount); 25 25 26 - if (sock->sock->sk->sk_protocol == IPPROTO_UDP) 26 + if (sock->sock->sk->sk_protocol == IPPROTO_UDP) { 27 27 ovpn_udp_socket_detach(sock); 28 + netdev_put(sock->ovpn->dev, &sock->dev_tracker); 29 + } 28 30 29 31 kfree_rcu(sock, rcu); 30 32 } ··· 181 179 goto sock_release; 182 180 } 183 181 184 - ovpn_sock->ovpn = peer->ovpn; 185 182 ovpn_sock->sock = sock; 186 183 kref_init(&ovpn_sock->refcount); 187 184 ··· 189 188 kfree(ovpn_sock); 190 189 ovpn_sock = ERR_PTR(ret); 191 190 goto sock_release; 191 + } 192 + 193 + if (sock->sk->sk_protocol == IPPROTO_UDP) { 194 + /* in UDP we only link the ovpn instance since the socket is 195 + * shared among multiple peers 196 + */ 197 + ovpn_sock->ovpn = peer->ovpn; 198 + netdev_hold(peer->ovpn->dev, &ovpn_sock->dev_tracker, 199 + GFP_KERNEL); 192 200 } 193 201 194 202 rcu_assign_sk_user_data(sock->sk, ovpn_sock);
+8 -1
drivers/net/ovpn/socket.h
··· 20 20 /** 21 21 * struct ovpn_socket - a kernel socket referenced in the ovpn code 22 22 * @ovpn: ovpn instance owning this socket (UDP only) 23 + * @dev_tracker: reference tracker for associated dev (UDP only) 23 24 * @sock: the low level sock object 24 25 * @refcount: amount of contexts currently referencing this object 25 26 * @rcu: member used to schedule RCU destructor callback 26 27 */ 27 28 struct ovpn_socket { 28 - struct ovpn_priv *ovpn; 29 + union { 30 + struct { 31 + struct ovpn_priv *ovpn; 32 + netdevice_tracker dev_tracker; 33 + }; 34 + }; 35 + 29 36 struct socket *sock; 30 37 struct kref refcount; 31 38 struct rcu_head rcu;
+135
drivers/net/ovpn/udp.c
··· 15 15 #include <net/dst_cache.h> 16 16 #include <net/route.h> 17 17 #include <net/ipv6_stubs.h> 18 + #include <net/transp_v6.h> 18 19 #include <net/udp.h> 19 20 #include <net/udp_tunnel.h> 20 21 ··· 24 23 #include "bind.h" 25 24 #include "io.h" 26 25 #include "peer.h" 26 + #include "proto.h" 27 27 #include "socket.h" 28 28 #include "udp.h" 29 + 30 + /* Retrieve the corresponding ovpn object from a UDP socket 31 + * rcu_read_lock must be held on entry 32 + */ 33 + static struct ovpn_socket *ovpn_socket_from_udp_sock(struct sock *sk) 34 + { 35 + struct ovpn_socket *ovpn_sock; 36 + 37 + if (unlikely(READ_ONCE(udp_sk(sk)->encap_type) != UDP_ENCAP_OVPNINUDP)) 38 + return NULL; 39 + 40 + ovpn_sock = rcu_dereference_sk_user_data(sk); 41 + if (unlikely(!ovpn_sock)) 42 + return NULL; 43 + 44 + /* make sure that sk matches our stored transport socket */ 45 + if (unlikely(!ovpn_sock->sock || sk != ovpn_sock->sock->sk)) 46 + return NULL; 47 + 48 + return ovpn_sock; 49 + } 50 + 51 + /** 52 + * ovpn_udp_encap_recv - Start processing a received UDP packet. 53 + * @sk: socket over which the packet was received 54 + * @skb: the received packet 55 + * 56 + * If the first byte of the payload is: 57 + * - DATA_V2 the packet is accepted for further processing, 58 + * - DATA_V1 the packet is dropped as not supported, 59 + * - anything else the packet is forwarded to the UDP stack for 60 + * delivery to user space. 61 + * 62 + * Return: 63 + * 0 if skb was consumed or dropped 64 + * >0 if skb should be passed up to userspace as UDP (packet not consumed) 65 + * <0 if skb should be resubmitted as proto -N (packet not consumed) 66 + */ 67 + static int ovpn_udp_encap_recv(struct sock *sk, struct sk_buff *skb) 68 + { 69 + struct ovpn_socket *ovpn_sock; 70 + struct ovpn_priv *ovpn; 71 + struct ovpn_peer *peer; 72 + u32 peer_id; 73 + u8 opcode; 74 + 75 + ovpn_sock = ovpn_socket_from_udp_sock(sk); 76 + if (unlikely(!ovpn_sock)) { 77 + net_err_ratelimited("ovpn: %s invoked on non ovpn socket\n", 78 + __func__); 79 + goto drop_noovpn; 80 + } 81 + 82 + ovpn = ovpn_sock->ovpn; 83 + if (unlikely(!ovpn)) { 84 + net_err_ratelimited("ovpn: cannot obtain ovpn object from UDP socket\n"); 85 + goto drop_noovpn; 86 + } 87 + 88 + /* Make sure the first 4 bytes of the skb data buffer after the UDP 89 + * header are accessible. 90 + * They are required to fetch the OP code, the key ID and the peer ID. 91 + */ 92 + if (unlikely(!pskb_may_pull(skb, sizeof(struct udphdr) + 93 + OVPN_OPCODE_SIZE))) { 94 + net_dbg_ratelimited("%s: packet too small from UDP socket\n", 95 + netdev_name(ovpn->dev)); 96 + goto drop; 97 + } 98 + 99 + opcode = ovpn_opcode_from_skb(skb, sizeof(struct udphdr)); 100 + if (unlikely(opcode != OVPN_DATA_V2)) { 101 + /* DATA_V1 is not supported */ 102 + if (opcode == OVPN_DATA_V1) 103 + goto drop; 104 + 105 + /* unknown or control packet: let it bubble up to userspace */ 106 + return 1; 107 + } 108 + 109 + peer_id = ovpn_peer_id_from_skb(skb, sizeof(struct udphdr)); 110 + /* some OpenVPN server implementations send data packets with the 111 + * peer-id set to UNDEF. In this case we skip the peer lookup by peer-id 112 + * and we try with the transport address 113 + */ 114 + if (peer_id == OVPN_PEER_ID_UNDEF) 115 + peer = ovpn_peer_get_by_transp_addr(ovpn, skb); 116 + else 117 + peer = ovpn_peer_get_by_id(ovpn, peer_id); 118 + 119 + if (unlikely(!peer)) 120 + goto drop; 121 + 122 + /* pop off outer UDP header */ 123 + __skb_pull(skb, sizeof(struct udphdr)); 124 + ovpn_recv(peer, skb); 125 + return 0; 126 + 127 + drop: 128 + dev_dstats_rx_dropped(ovpn->dev); 129 + drop_noovpn: 130 + kfree_skb(skb); 131 + return 0; 132 + } 29 133 30 134 /** 31 135 * ovpn_udp4_output - send IPv4 packet over udp socket ··· 353 247 } 354 248 } 355 249 250 + static void ovpn_udp_encap_destroy(struct sock *sk) 251 + { 252 + struct ovpn_socket *sock; 253 + struct ovpn_priv *ovpn; 254 + 255 + rcu_read_lock(); 256 + sock = rcu_dereference_sk_user_data(sk); 257 + if (!sock || !sock->ovpn) { 258 + rcu_read_unlock(); 259 + return; 260 + } 261 + ovpn = sock->ovpn; 262 + rcu_read_unlock(); 263 + 264 + if (ovpn->mode == OVPN_MODE_P2P) 265 + ovpn_peer_release_p2p(ovpn, sk, 266 + OVPN_DEL_PEER_REASON_TRANSPORT_DISCONNECT); 267 + } 268 + 356 269 /** 357 270 * ovpn_udp_socket_attach - set udp-tunnel CBs on socket and link it to ovpn 358 271 * @ovpn_sock: socket to configure ··· 385 260 int ovpn_udp_socket_attach(struct ovpn_socket *ovpn_sock, 386 261 struct ovpn_priv *ovpn) 387 262 { 263 + struct udp_tunnel_sock_cfg cfg = { 264 + .encap_type = UDP_ENCAP_OVPNINUDP, 265 + .encap_rcv = ovpn_udp_encap_recv, 266 + .encap_destroy = ovpn_udp_encap_destroy, 267 + }; 388 268 struct socket *sock = ovpn_sock->sock; 389 269 struct ovpn_socket *old_data; 390 270 int ret; ··· 400 270 if (!old_data) { 401 271 /* socket is currently unused - we can take it */ 402 272 rcu_read_unlock(); 273 + setup_udp_tunnel_sock(sock_net(sock->sk), sock, &cfg); 403 274 return 0; 404 275 } 405 276 ··· 434 303 */ 435 304 void ovpn_udp_socket_detach(struct ovpn_socket *ovpn_sock) 436 305 { 306 + struct udp_tunnel_sock_cfg cfg = { }; 307 + 308 + setup_udp_tunnel_sock(sock_net(ovpn_sock->sock->sk), ovpn_sock->sock, 309 + &cfg); 437 310 }