xref: /linux/drivers/net/ovpn/tcp.c (revision 2c7e4a2663a1ab5a740c59c31991579b6b865a26)
111851cbdSAntonio Quartulli // SPDX-License-Identifier: GPL-2.0
211851cbdSAntonio Quartulli /*  OpenVPN data channel offload
311851cbdSAntonio Quartulli  *
411851cbdSAntonio Quartulli  *  Copyright (C) 2019-2025 OpenVPN, Inc.
511851cbdSAntonio Quartulli  *
611851cbdSAntonio Quartulli  *  Author:	Antonio Quartulli <antonio@openvpn.net>
711851cbdSAntonio Quartulli  */
811851cbdSAntonio Quartulli 
911851cbdSAntonio Quartulli #include <linux/skbuff.h>
1011851cbdSAntonio Quartulli #include <net/hotdata.h>
1111851cbdSAntonio Quartulli #include <net/inet_common.h>
1211851cbdSAntonio Quartulli #include <net/ipv6.h>
1311851cbdSAntonio Quartulli #include <net/tcp.h>
1411851cbdSAntonio Quartulli #include <net/transp_v6.h>
1511851cbdSAntonio Quartulli #include <net/route.h>
1611851cbdSAntonio Quartulli #include <trace/events/sock.h>
1711851cbdSAntonio Quartulli 
1811851cbdSAntonio Quartulli #include "ovpnpriv.h"
1911851cbdSAntonio Quartulli #include "main.h"
2011851cbdSAntonio Quartulli #include "io.h"
2111851cbdSAntonio Quartulli #include "peer.h"
2211851cbdSAntonio Quartulli #include "proto.h"
2311851cbdSAntonio Quartulli #include "skb.h"
2411851cbdSAntonio Quartulli #include "tcp.h"
2511851cbdSAntonio Quartulli 
2611851cbdSAntonio Quartulli #define OVPN_TCP_DEPTH_NESTING	2
2711851cbdSAntonio Quartulli #if OVPN_TCP_DEPTH_NESTING == SINGLE_DEPTH_NESTING
2811851cbdSAntonio Quartulli #error "OVPN TCP requires its own lockdep subclass"
2911851cbdSAntonio Quartulli #endif
3011851cbdSAntonio Quartulli 
3111851cbdSAntonio Quartulli static struct proto ovpn_tcp_prot __ro_after_init;
3211851cbdSAntonio Quartulli static struct proto_ops ovpn_tcp_ops __ro_after_init;
3311851cbdSAntonio Quartulli static struct proto ovpn_tcp6_prot __ro_after_init;
3411851cbdSAntonio Quartulli static struct proto_ops ovpn_tcp6_ops __ro_after_init;
3511851cbdSAntonio Quartulli 
ovpn_tcp_parse(struct strparser * strp,struct sk_buff * skb)3611851cbdSAntonio Quartulli static int ovpn_tcp_parse(struct strparser *strp, struct sk_buff *skb)
3711851cbdSAntonio Quartulli {
3811851cbdSAntonio Quartulli 	struct strp_msg *rxm = strp_msg(skb);
3911851cbdSAntonio Quartulli 	__be16 blen;
4011851cbdSAntonio Quartulli 	u16 len;
4111851cbdSAntonio Quartulli 	int err;
4211851cbdSAntonio Quartulli 
4311851cbdSAntonio Quartulli 	/* when packets are written to the TCP stream, they are prepended with
4411851cbdSAntonio Quartulli 	 * two bytes indicating the actual packet size.
4511851cbdSAntonio Quartulli 	 * Parse accordingly and return the actual size (including the size
4611851cbdSAntonio Quartulli 	 * header)
4711851cbdSAntonio Quartulli 	 */
4811851cbdSAntonio Quartulli 
4911851cbdSAntonio Quartulli 	if (skb->len < rxm->offset + 2)
5011851cbdSAntonio Quartulli 		return 0;
5111851cbdSAntonio Quartulli 
5211851cbdSAntonio Quartulli 	err = skb_copy_bits(skb, rxm->offset, &blen, sizeof(blen));
5311851cbdSAntonio Quartulli 	if (err < 0)
5411851cbdSAntonio Quartulli 		return err;
5511851cbdSAntonio Quartulli 
5611851cbdSAntonio Quartulli 	len = be16_to_cpu(blen);
5711851cbdSAntonio Quartulli 	if (len < 2)
5811851cbdSAntonio Quartulli 		return -EINVAL;
5911851cbdSAntonio Quartulli 
6011851cbdSAntonio Quartulli 	return len + 2;
6111851cbdSAntonio Quartulli }
6211851cbdSAntonio Quartulli 
6311851cbdSAntonio Quartulli /* queue skb for sending to userspace via recvmsg on the socket */
ovpn_tcp_to_userspace(struct ovpn_peer * peer,struct sock * sk,struct sk_buff * skb)6411851cbdSAntonio Quartulli static void ovpn_tcp_to_userspace(struct ovpn_peer *peer, struct sock *sk,
6511851cbdSAntonio Quartulli 				  struct sk_buff *skb)
6611851cbdSAntonio Quartulli {
6711851cbdSAntonio Quartulli 	skb_set_owner_r(skb, sk);
6811851cbdSAntonio Quartulli 	memset(skb->cb, 0, sizeof(skb->cb));
6911851cbdSAntonio Quartulli 	skb_queue_tail(&peer->tcp.user_queue, skb);
7011851cbdSAntonio Quartulli 	peer->tcp.sk_cb.sk_data_ready(sk);
7111851cbdSAntonio Quartulli }
7211851cbdSAntonio Quartulli 
ovpn_tcp_rcv(struct strparser * strp,struct sk_buff * skb)7311851cbdSAntonio Quartulli static void ovpn_tcp_rcv(struct strparser *strp, struct sk_buff *skb)
7411851cbdSAntonio Quartulli {
7511851cbdSAntonio Quartulli 	struct ovpn_peer *peer = container_of(strp, struct ovpn_peer, tcp.strp);
7611851cbdSAntonio Quartulli 	struct strp_msg *msg = strp_msg(skb);
7711851cbdSAntonio Quartulli 	size_t pkt_len = msg->full_len - 2;
7811851cbdSAntonio Quartulli 	size_t off = msg->offset + 2;
7911851cbdSAntonio Quartulli 	u8 opcode;
8011851cbdSAntonio Quartulli 
8111851cbdSAntonio Quartulli 	/* ensure skb->data points to the beginning of the openvpn packet */
8211851cbdSAntonio Quartulli 	if (!pskb_pull(skb, off)) {
8311851cbdSAntonio Quartulli 		net_warn_ratelimited("%s: packet too small for peer %u\n",
8411851cbdSAntonio Quartulli 				     netdev_name(peer->ovpn->dev), peer->id);
8511851cbdSAntonio Quartulli 		goto err;
8611851cbdSAntonio Quartulli 	}
8711851cbdSAntonio Quartulli 
8811851cbdSAntonio Quartulli 	/* strparser does not trim the skb for us, therefore we do it now */
8911851cbdSAntonio Quartulli 	if (pskb_trim(skb, pkt_len) != 0) {
9011851cbdSAntonio Quartulli 		net_warn_ratelimited("%s: trimming skb failed for peer %u\n",
9111851cbdSAntonio Quartulli 				     netdev_name(peer->ovpn->dev), peer->id);
9211851cbdSAntonio Quartulli 		goto err;
9311851cbdSAntonio Quartulli 	}
9411851cbdSAntonio Quartulli 
9511851cbdSAntonio Quartulli 	/* we need the first 4 bytes of data to be accessible
9611851cbdSAntonio Quartulli 	 * to extract the opcode and the key ID later on
9711851cbdSAntonio Quartulli 	 */
9811851cbdSAntonio Quartulli 	if (!pskb_may_pull(skb, OVPN_OPCODE_SIZE)) {
9911851cbdSAntonio Quartulli 		net_warn_ratelimited("%s: packet too small to fetch opcode for peer %u\n",
10011851cbdSAntonio Quartulli 				     netdev_name(peer->ovpn->dev), peer->id);
10111851cbdSAntonio Quartulli 		goto err;
10211851cbdSAntonio Quartulli 	}
10311851cbdSAntonio Quartulli 
10411851cbdSAntonio Quartulli 	/* DATA_V2 packets are handled in kernel, the rest goes to user space */
10511851cbdSAntonio Quartulli 	opcode = ovpn_opcode_from_skb(skb, 0);
10611851cbdSAntonio Quartulli 	if (unlikely(opcode != OVPN_DATA_V2)) {
10711851cbdSAntonio Quartulli 		if (opcode == OVPN_DATA_V1) {
10811851cbdSAntonio Quartulli 			net_warn_ratelimited("%s: DATA_V1 detected on the TCP stream\n",
10911851cbdSAntonio Quartulli 					     netdev_name(peer->ovpn->dev));
11011851cbdSAntonio Quartulli 			goto err;
11111851cbdSAntonio Quartulli 		}
11211851cbdSAntonio Quartulli 
11311851cbdSAntonio Quartulli 		/* The packet size header must be there when sending the packet
11411851cbdSAntonio Quartulli 		 * to userspace, therefore we put it back
11511851cbdSAntonio Quartulli 		 */
11611851cbdSAntonio Quartulli 		skb_push(skb, 2);
11711851cbdSAntonio Quartulli 		ovpn_tcp_to_userspace(peer, strp->sk, skb);
11811851cbdSAntonio Quartulli 		return;
11911851cbdSAntonio Quartulli 	}
12011851cbdSAntonio Quartulli 
12111851cbdSAntonio Quartulli 	/* hold reference to peer as required by ovpn_recv().
12211851cbdSAntonio Quartulli 	 *
12311851cbdSAntonio Quartulli 	 * NOTE: in this context we should already be holding a reference to
12411851cbdSAntonio Quartulli 	 * this peer, therefore ovpn_peer_hold() is not expected to fail
12511851cbdSAntonio Quartulli 	 */
12611851cbdSAntonio Quartulli 	if (WARN_ON(!ovpn_peer_hold(peer)))
127*a6a5e87bSAntonio Quartulli 		goto err_nopeer;
12811851cbdSAntonio Quartulli 
12911851cbdSAntonio Quartulli 	ovpn_recv(peer, skb);
13011851cbdSAntonio Quartulli 	return;
13111851cbdSAntonio Quartulli err:
132*a6a5e87bSAntonio Quartulli 	/* take reference for deferred peer deletion. should never fail */
133*a6a5e87bSAntonio Quartulli 	if (WARN_ON(!ovpn_peer_hold(peer)))
134*a6a5e87bSAntonio Quartulli 		goto err_nopeer;
135*a6a5e87bSAntonio Quartulli 	schedule_work(&peer->tcp.defer_del_work);
13611851cbdSAntonio Quartulli 	dev_dstats_rx_dropped(peer->ovpn->dev);
137*a6a5e87bSAntonio Quartulli err_nopeer:
13811851cbdSAntonio Quartulli 	kfree_skb(skb);
13911851cbdSAntonio Quartulli }
14011851cbdSAntonio Quartulli 
ovpn_tcp_recvmsg(struct sock * sk,struct msghdr * msg,size_t len,int flags,int * addr_len)14111851cbdSAntonio Quartulli static int ovpn_tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
14211851cbdSAntonio Quartulli 			    int flags, int *addr_len)
14311851cbdSAntonio Quartulli {
14411851cbdSAntonio Quartulli 	int err = 0, off, copied = 0, ret;
14511851cbdSAntonio Quartulli 	struct ovpn_socket *sock;
14611851cbdSAntonio Quartulli 	struct ovpn_peer *peer;
14711851cbdSAntonio Quartulli 	struct sk_buff *skb;
14811851cbdSAntonio Quartulli 
14911851cbdSAntonio Quartulli 	rcu_read_lock();
15011851cbdSAntonio Quartulli 	sock = rcu_dereference_sk_user_data(sk);
15111851cbdSAntonio Quartulli 	if (unlikely(!sock || !sock->peer || !ovpn_peer_hold(sock->peer))) {
15211851cbdSAntonio Quartulli 		rcu_read_unlock();
15311851cbdSAntonio Quartulli 		return -EBADF;
15411851cbdSAntonio Quartulli 	}
15511851cbdSAntonio Quartulli 	peer = sock->peer;
15611851cbdSAntonio Quartulli 	rcu_read_unlock();
15711851cbdSAntonio Quartulli 
15811851cbdSAntonio Quartulli 	skb = __skb_recv_datagram(sk, &peer->tcp.user_queue, flags, &off, &err);
15911851cbdSAntonio Quartulli 	if (!skb) {
16011851cbdSAntonio Quartulli 		if (err == -EAGAIN && sk->sk_shutdown & RCV_SHUTDOWN) {
16111851cbdSAntonio Quartulli 			ret = 0;
16211851cbdSAntonio Quartulli 			goto out;
16311851cbdSAntonio Quartulli 		}
16411851cbdSAntonio Quartulli 		ret = err;
16511851cbdSAntonio Quartulli 		goto out;
16611851cbdSAntonio Quartulli 	}
16711851cbdSAntonio Quartulli 
16811851cbdSAntonio Quartulli 	copied = len;
16911851cbdSAntonio Quartulli 	if (copied > skb->len)
17011851cbdSAntonio Quartulli 		copied = skb->len;
17111851cbdSAntonio Quartulli 	else if (copied < skb->len)
17211851cbdSAntonio Quartulli 		msg->msg_flags |= MSG_TRUNC;
17311851cbdSAntonio Quartulli 
17411851cbdSAntonio Quartulli 	err = skb_copy_datagram_msg(skb, 0, msg, copied);
17511851cbdSAntonio Quartulli 	if (unlikely(err)) {
17611851cbdSAntonio Quartulli 		kfree_skb(skb);
17711851cbdSAntonio Quartulli 		ret = err;
17811851cbdSAntonio Quartulli 		goto out;
17911851cbdSAntonio Quartulli 	}
18011851cbdSAntonio Quartulli 
18111851cbdSAntonio Quartulli 	if (flags & MSG_TRUNC)
18211851cbdSAntonio Quartulli 		copied = skb->len;
18311851cbdSAntonio Quartulli 	kfree_skb(skb);
18411851cbdSAntonio Quartulli 	ret = copied;
18511851cbdSAntonio Quartulli out:
18611851cbdSAntonio Quartulli 	ovpn_peer_put(peer);
18711851cbdSAntonio Quartulli 	return ret;
18811851cbdSAntonio Quartulli }
18911851cbdSAntonio Quartulli 
ovpn_tcp_socket_detach(struct ovpn_socket * ovpn_sock)19011851cbdSAntonio Quartulli void ovpn_tcp_socket_detach(struct ovpn_socket *ovpn_sock)
19111851cbdSAntonio Quartulli {
19211851cbdSAntonio Quartulli 	struct ovpn_peer *peer = ovpn_sock->peer;
193ba499a07SAntonio Quartulli 	struct sock *sk = ovpn_sock->sk;
19411851cbdSAntonio Quartulli 
19511851cbdSAntonio Quartulli 	strp_stop(&peer->tcp.strp);
19611851cbdSAntonio Quartulli 	skb_queue_purge(&peer->tcp.user_queue);
19711851cbdSAntonio Quartulli 
19811851cbdSAntonio Quartulli 	/* restore CBs that were saved in ovpn_sock_set_tcp_cb() */
199ba499a07SAntonio Quartulli 	sk->sk_data_ready = peer->tcp.sk_cb.sk_data_ready;
200ba499a07SAntonio Quartulli 	sk->sk_write_space = peer->tcp.sk_cb.sk_write_space;
201ba499a07SAntonio Quartulli 	sk->sk_prot = peer->tcp.sk_cb.prot;
202ba499a07SAntonio Quartulli 	sk->sk_socket->ops = peer->tcp.sk_cb.ops;
20311851cbdSAntonio Quartulli 
204ba499a07SAntonio Quartulli 	rcu_assign_sk_user_data(sk, NULL);
20511851cbdSAntonio Quartulli }
20611851cbdSAntonio Quartulli 
ovpn_tcp_socket_wait_finish(struct ovpn_socket * sock)20711851cbdSAntonio Quartulli void ovpn_tcp_socket_wait_finish(struct ovpn_socket *sock)
20811851cbdSAntonio Quartulli {
20911851cbdSAntonio Quartulli 	struct ovpn_peer *peer = sock->peer;
21011851cbdSAntonio Quartulli 
21111851cbdSAntonio Quartulli 	/* NOTE: we don't wait for peer->tcp.defer_del_work to finish:
21211851cbdSAntonio Quartulli 	 * either the worker is not running or this function
21311851cbdSAntonio Quartulli 	 * was invoked by that worker.
21411851cbdSAntonio Quartulli 	 */
21511851cbdSAntonio Quartulli 
21611851cbdSAntonio Quartulli 	cancel_work_sync(&sock->tcp_tx_work);
21711851cbdSAntonio Quartulli 	strp_done(&peer->tcp.strp);
21811851cbdSAntonio Quartulli 
21911851cbdSAntonio Quartulli 	skb_queue_purge(&peer->tcp.out_queue);
22011851cbdSAntonio Quartulli 	kfree_skb(peer->tcp.out_msg.skb);
22111851cbdSAntonio Quartulli 	peer->tcp.out_msg.skb = NULL;
22211851cbdSAntonio Quartulli }
22311851cbdSAntonio Quartulli 
ovpn_tcp_send_sock(struct ovpn_peer * peer,struct sock * sk)22411851cbdSAntonio Quartulli static void ovpn_tcp_send_sock(struct ovpn_peer *peer, struct sock *sk)
22511851cbdSAntonio Quartulli {
22611851cbdSAntonio Quartulli 	struct sk_buff *skb = peer->tcp.out_msg.skb;
22736bb1d71SAntonio Quartulli 	int ret, flags;
22811851cbdSAntonio Quartulli 
22911851cbdSAntonio Quartulli 	if (!skb)
23011851cbdSAntonio Quartulli 		return;
23111851cbdSAntonio Quartulli 
23211851cbdSAntonio Quartulli 	if (peer->tcp.tx_in_progress)
23311851cbdSAntonio Quartulli 		return;
23411851cbdSAntonio Quartulli 
23511851cbdSAntonio Quartulli 	peer->tcp.tx_in_progress = true;
23611851cbdSAntonio Quartulli 
23711851cbdSAntonio Quartulli 	do {
23836bb1d71SAntonio Quartulli 		flags = ovpn_skb_cb(skb)->nosignal ? MSG_NOSIGNAL : 0;
23936bb1d71SAntonio Quartulli 		ret = skb_send_sock_locked_with_flags(sk, skb,
24011851cbdSAntonio Quartulli 						      peer->tcp.out_msg.offset,
24136bb1d71SAntonio Quartulli 						      peer->tcp.out_msg.len,
24236bb1d71SAntonio Quartulli 						      flags);
24311851cbdSAntonio Quartulli 		if (unlikely(ret < 0)) {
24411851cbdSAntonio Quartulli 			if (ret == -EAGAIN)
24511851cbdSAntonio Quartulli 				goto out;
24611851cbdSAntonio Quartulli 
24711851cbdSAntonio Quartulli 			net_warn_ratelimited("%s: TCP error to peer %u: %d\n",
24811851cbdSAntonio Quartulli 					     netdev_name(peer->ovpn->dev),
24911851cbdSAntonio Quartulli 					     peer->id, ret);
25011851cbdSAntonio Quartulli 
25111851cbdSAntonio Quartulli 			/* in case of TCP error we can't recover the VPN
25211851cbdSAntonio Quartulli 			 * stream therefore we abort the connection
25311851cbdSAntonio Quartulli 			 */
25411851cbdSAntonio Quartulli 			ovpn_peer_hold(peer);
25511851cbdSAntonio Quartulli 			schedule_work(&peer->tcp.defer_del_work);
25611851cbdSAntonio Quartulli 
25711851cbdSAntonio Quartulli 			/* we bail out immediately and keep tx_in_progress set
25811851cbdSAntonio Quartulli 			 * to true. This way we prevent more TX attempts
25911851cbdSAntonio Quartulli 			 * which would lead to more invocations of
26011851cbdSAntonio Quartulli 			 * schedule_work()
26111851cbdSAntonio Quartulli 			 */
26211851cbdSAntonio Quartulli 			return;
26311851cbdSAntonio Quartulli 		}
26411851cbdSAntonio Quartulli 
26511851cbdSAntonio Quartulli 		peer->tcp.out_msg.len -= ret;
26611851cbdSAntonio Quartulli 		peer->tcp.out_msg.offset += ret;
26711851cbdSAntonio Quartulli 	} while (peer->tcp.out_msg.len > 0);
26811851cbdSAntonio Quartulli 
26911851cbdSAntonio Quartulli 	if (!peer->tcp.out_msg.len) {
27011851cbdSAntonio Quartulli 		preempt_disable();
27111851cbdSAntonio Quartulli 		dev_dstats_tx_add(peer->ovpn->dev, skb->len);
27211851cbdSAntonio Quartulli 		preempt_enable();
27311851cbdSAntonio Quartulli 	}
27411851cbdSAntonio Quartulli 
27511851cbdSAntonio Quartulli 	kfree_skb(peer->tcp.out_msg.skb);
27611851cbdSAntonio Quartulli 	peer->tcp.out_msg.skb = NULL;
27711851cbdSAntonio Quartulli 	peer->tcp.out_msg.len = 0;
27811851cbdSAntonio Quartulli 	peer->tcp.out_msg.offset = 0;
27911851cbdSAntonio Quartulli 
28011851cbdSAntonio Quartulli out:
28111851cbdSAntonio Quartulli 	peer->tcp.tx_in_progress = false;
28211851cbdSAntonio Quartulli }
28311851cbdSAntonio Quartulli 
ovpn_tcp_tx_work(struct work_struct * work)28411851cbdSAntonio Quartulli void ovpn_tcp_tx_work(struct work_struct *work)
28511851cbdSAntonio Quartulli {
28611851cbdSAntonio Quartulli 	struct ovpn_socket *sock;
28711851cbdSAntonio Quartulli 
28811851cbdSAntonio Quartulli 	sock = container_of(work, struct ovpn_socket, tcp_tx_work);
28911851cbdSAntonio Quartulli 
290ba499a07SAntonio Quartulli 	lock_sock(sock->sk);
29111851cbdSAntonio Quartulli 	if (sock->peer)
292ba499a07SAntonio Quartulli 		ovpn_tcp_send_sock(sock->peer, sock->sk);
293ba499a07SAntonio Quartulli 	release_sock(sock->sk);
29411851cbdSAntonio Quartulli }
29511851cbdSAntonio Quartulli 
ovpn_tcp_send_sock_skb(struct ovpn_peer * peer,struct sock * sk,struct sk_buff * skb)29611851cbdSAntonio Quartulli static void ovpn_tcp_send_sock_skb(struct ovpn_peer *peer, struct sock *sk,
29711851cbdSAntonio Quartulli 				   struct sk_buff *skb)
29811851cbdSAntonio Quartulli {
29911851cbdSAntonio Quartulli 	if (peer->tcp.out_msg.skb)
30011851cbdSAntonio Quartulli 		ovpn_tcp_send_sock(peer, sk);
30111851cbdSAntonio Quartulli 
30211851cbdSAntonio Quartulli 	if (peer->tcp.out_msg.skb) {
30311851cbdSAntonio Quartulli 		dev_dstats_tx_dropped(peer->ovpn->dev);
30411851cbdSAntonio Quartulli 		kfree_skb(skb);
30511851cbdSAntonio Quartulli 		return;
30611851cbdSAntonio Quartulli 	}
30711851cbdSAntonio Quartulli 
30811851cbdSAntonio Quartulli 	peer->tcp.out_msg.skb = skb;
30911851cbdSAntonio Quartulli 	peer->tcp.out_msg.len = skb->len;
31011851cbdSAntonio Quartulli 	peer->tcp.out_msg.offset = 0;
31111851cbdSAntonio Quartulli 	ovpn_tcp_send_sock(peer, sk);
31211851cbdSAntonio Quartulli }
31311851cbdSAntonio Quartulli 
ovpn_tcp_send_skb(struct ovpn_peer * peer,struct sock * sk,struct sk_buff * skb)314ba499a07SAntonio Quartulli void ovpn_tcp_send_skb(struct ovpn_peer *peer, struct sock *sk,
31511851cbdSAntonio Quartulli 		       struct sk_buff *skb)
31611851cbdSAntonio Quartulli {
31711851cbdSAntonio Quartulli 	u16 len = skb->len;
31811851cbdSAntonio Quartulli 
31911851cbdSAntonio Quartulli 	*(__be16 *)__skb_push(skb, sizeof(u16)) = htons(len);
32011851cbdSAntonio Quartulli 
321ba499a07SAntonio Quartulli 	spin_lock_nested(&sk->sk_lock.slock, OVPN_TCP_DEPTH_NESTING);
322ba499a07SAntonio Quartulli 	if (sock_owned_by_user(sk)) {
32311851cbdSAntonio Quartulli 		if (skb_queue_len(&peer->tcp.out_queue) >=
32411851cbdSAntonio Quartulli 		    READ_ONCE(net_hotdata.max_backlog)) {
32511851cbdSAntonio Quartulli 			dev_dstats_tx_dropped(peer->ovpn->dev);
32611851cbdSAntonio Quartulli 			kfree_skb(skb);
32711851cbdSAntonio Quartulli 			goto unlock;
32811851cbdSAntonio Quartulli 		}
32911851cbdSAntonio Quartulli 		__skb_queue_tail(&peer->tcp.out_queue, skb);
33011851cbdSAntonio Quartulli 	} else {
331ba499a07SAntonio Quartulli 		ovpn_tcp_send_sock_skb(peer, sk, skb);
33211851cbdSAntonio Quartulli 	}
33311851cbdSAntonio Quartulli unlock:
334ba499a07SAntonio Quartulli 	spin_unlock(&sk->sk_lock.slock);
33511851cbdSAntonio Quartulli }
33611851cbdSAntonio Quartulli 
ovpn_tcp_release(struct sock * sk)33711851cbdSAntonio Quartulli static void ovpn_tcp_release(struct sock *sk)
33811851cbdSAntonio Quartulli {
33911851cbdSAntonio Quartulli 	struct sk_buff_head queue;
34011851cbdSAntonio Quartulli 	struct ovpn_socket *sock;
34111851cbdSAntonio Quartulli 	struct ovpn_peer *peer;
34211851cbdSAntonio Quartulli 	struct sk_buff *skb;
34311851cbdSAntonio Quartulli 
34411851cbdSAntonio Quartulli 	rcu_read_lock();
34511851cbdSAntonio Quartulli 	sock = rcu_dereference_sk_user_data(sk);
34611851cbdSAntonio Quartulli 	if (!sock) {
34711851cbdSAntonio Quartulli 		rcu_read_unlock();
34811851cbdSAntonio Quartulli 		return;
34911851cbdSAntonio Quartulli 	}
35011851cbdSAntonio Quartulli 
35111851cbdSAntonio Quartulli 	peer = sock->peer;
35211851cbdSAntonio Quartulli 
35311851cbdSAntonio Quartulli 	/* during initialization this function is called before
35411851cbdSAntonio Quartulli 	 * assigning sock->peer
35511851cbdSAntonio Quartulli 	 */
35611851cbdSAntonio Quartulli 	if (unlikely(!peer || !ovpn_peer_hold(peer))) {
35711851cbdSAntonio Quartulli 		rcu_read_unlock();
35811851cbdSAntonio Quartulli 		return;
35911851cbdSAntonio Quartulli 	}
36011851cbdSAntonio Quartulli 	rcu_read_unlock();
36111851cbdSAntonio Quartulli 
36211851cbdSAntonio Quartulli 	__skb_queue_head_init(&queue);
36311851cbdSAntonio Quartulli 	skb_queue_splice_init(&peer->tcp.out_queue, &queue);
36411851cbdSAntonio Quartulli 
36511851cbdSAntonio Quartulli 	while ((skb = __skb_dequeue(&queue)))
36611851cbdSAntonio Quartulli 		ovpn_tcp_send_sock_skb(peer, sk, skb);
36711851cbdSAntonio Quartulli 
36811851cbdSAntonio Quartulli 	peer->tcp.sk_cb.prot->release_cb(sk);
36911851cbdSAntonio Quartulli 	ovpn_peer_put(peer);
37011851cbdSAntonio Quartulli }
37111851cbdSAntonio Quartulli 
ovpn_tcp_sendmsg(struct sock * sk,struct msghdr * msg,size_t size)37211851cbdSAntonio Quartulli static int ovpn_tcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)
37311851cbdSAntonio Quartulli {
37411851cbdSAntonio Quartulli 	struct ovpn_socket *sock;
37511851cbdSAntonio Quartulli 	int ret, linear = PAGE_SIZE;
37611851cbdSAntonio Quartulli 	struct ovpn_peer *peer;
37711851cbdSAntonio Quartulli 	struct sk_buff *skb;
37811851cbdSAntonio Quartulli 
37911851cbdSAntonio Quartulli 	lock_sock(sk);
38011851cbdSAntonio Quartulli 	rcu_read_lock();
38111851cbdSAntonio Quartulli 	sock = rcu_dereference_sk_user_data(sk);
38211851cbdSAntonio Quartulli 	if (unlikely(!sock || !sock->peer || !ovpn_peer_hold(sock->peer))) {
38311851cbdSAntonio Quartulli 		rcu_read_unlock();
38411851cbdSAntonio Quartulli 		release_sock(sk);
38511851cbdSAntonio Quartulli 		return -EIO;
38611851cbdSAntonio Quartulli 	}
38711851cbdSAntonio Quartulli 	rcu_read_unlock();
38811851cbdSAntonio Quartulli 	peer = sock->peer;
38911851cbdSAntonio Quartulli 
39036bb1d71SAntonio Quartulli 	if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_NOSIGNAL)) {
39111851cbdSAntonio Quartulli 		ret = -EOPNOTSUPP;
39211851cbdSAntonio Quartulli 		goto peer_free;
39311851cbdSAntonio Quartulli 	}
39411851cbdSAntonio Quartulli 
39511851cbdSAntonio Quartulli 	if (peer->tcp.out_msg.skb) {
39611851cbdSAntonio Quartulli 		ret = -EAGAIN;
39711851cbdSAntonio Quartulli 		goto peer_free;
39811851cbdSAntonio Quartulli 	}
39911851cbdSAntonio Quartulli 
40011851cbdSAntonio Quartulli 	if (size < linear)
40111851cbdSAntonio Quartulli 		linear = size;
40211851cbdSAntonio Quartulli 
40311851cbdSAntonio Quartulli 	skb = sock_alloc_send_pskb(sk, linear, size - linear,
40411851cbdSAntonio Quartulli 				   msg->msg_flags & MSG_DONTWAIT, &ret, 0);
40511851cbdSAntonio Quartulli 	if (!skb) {
40611851cbdSAntonio Quartulli 		net_err_ratelimited("%s: skb alloc failed: %d\n",
40711851cbdSAntonio Quartulli 				    netdev_name(peer->ovpn->dev), ret);
40811851cbdSAntonio Quartulli 		goto peer_free;
40911851cbdSAntonio Quartulli 	}
41011851cbdSAntonio Quartulli 
41111851cbdSAntonio Quartulli 	skb_put(skb, linear);
41211851cbdSAntonio Quartulli 	skb->len = size;
41311851cbdSAntonio Quartulli 	skb->data_len = size - linear;
41411851cbdSAntonio Quartulli 
41511851cbdSAntonio Quartulli 	ret = skb_copy_datagram_from_iter(skb, 0, &msg->msg_iter, size);
41611851cbdSAntonio Quartulli 	if (ret) {
41711851cbdSAntonio Quartulli 		kfree_skb(skb);
41811851cbdSAntonio Quartulli 		net_err_ratelimited("%s: skb copy from iter failed: %d\n",
41911851cbdSAntonio Quartulli 				    netdev_name(peer->ovpn->dev), ret);
42011851cbdSAntonio Quartulli 		goto peer_free;
42111851cbdSAntonio Quartulli 	}
42211851cbdSAntonio Quartulli 
42336bb1d71SAntonio Quartulli 	ovpn_skb_cb(skb)->nosignal = msg->msg_flags & MSG_NOSIGNAL;
42411851cbdSAntonio Quartulli 	ovpn_tcp_send_sock_skb(peer, sk, skb);
42511851cbdSAntonio Quartulli 	ret = size;
42611851cbdSAntonio Quartulli peer_free:
42711851cbdSAntonio Quartulli 	release_sock(sk);
42811851cbdSAntonio Quartulli 	ovpn_peer_put(peer);
42911851cbdSAntonio Quartulli 	return ret;
43011851cbdSAntonio Quartulli }
43111851cbdSAntonio Quartulli 
ovpn_tcp_disconnect(struct sock * sk,int flags)43211851cbdSAntonio Quartulli static int ovpn_tcp_disconnect(struct sock *sk, int flags)
43311851cbdSAntonio Quartulli {
43411851cbdSAntonio Quartulli 	return -EBUSY;
43511851cbdSAntonio Quartulli }
43611851cbdSAntonio Quartulli 
ovpn_tcp_data_ready(struct sock * sk)43711851cbdSAntonio Quartulli static void ovpn_tcp_data_ready(struct sock *sk)
43811851cbdSAntonio Quartulli {
43911851cbdSAntonio Quartulli 	struct ovpn_socket *sock;
44011851cbdSAntonio Quartulli 
44111851cbdSAntonio Quartulli 	trace_sk_data_ready(sk);
44211851cbdSAntonio Quartulli 
44311851cbdSAntonio Quartulli 	rcu_read_lock();
44411851cbdSAntonio Quartulli 	sock = rcu_dereference_sk_user_data(sk);
44511851cbdSAntonio Quartulli 	if (likely(sock && sock->peer))
44611851cbdSAntonio Quartulli 		strp_data_ready(&sock->peer->tcp.strp);
44711851cbdSAntonio Quartulli 	rcu_read_unlock();
44811851cbdSAntonio Quartulli }
44911851cbdSAntonio Quartulli 
ovpn_tcp_write_space(struct sock * sk)45011851cbdSAntonio Quartulli static void ovpn_tcp_write_space(struct sock *sk)
45111851cbdSAntonio Quartulli {
45211851cbdSAntonio Quartulli 	struct ovpn_socket *sock;
45311851cbdSAntonio Quartulli 
45411851cbdSAntonio Quartulli 	rcu_read_lock();
45511851cbdSAntonio Quartulli 	sock = rcu_dereference_sk_user_data(sk);
45611851cbdSAntonio Quartulli 	if (likely(sock && sock->peer)) {
45711851cbdSAntonio Quartulli 		schedule_work(&sock->tcp_tx_work);
45811851cbdSAntonio Quartulli 		sock->peer->tcp.sk_cb.sk_write_space(sk);
45911851cbdSAntonio Quartulli 	}
46011851cbdSAntonio Quartulli 	rcu_read_unlock();
46111851cbdSAntonio Quartulli }
46211851cbdSAntonio Quartulli 
46311851cbdSAntonio Quartulli static void ovpn_tcp_build_protos(struct proto *new_prot,
46411851cbdSAntonio Quartulli 				  struct proto_ops *new_ops,
46511851cbdSAntonio Quartulli 				  const struct proto *orig_prot,
46611851cbdSAntonio Quartulli 				  const struct proto_ops *orig_ops);
46711851cbdSAntonio Quartulli 
ovpn_tcp_peer_del_work(struct work_struct * work)46811851cbdSAntonio Quartulli static void ovpn_tcp_peer_del_work(struct work_struct *work)
46911851cbdSAntonio Quartulli {
47011851cbdSAntonio Quartulli 	struct ovpn_peer *peer = container_of(work, struct ovpn_peer,
47111851cbdSAntonio Quartulli 					      tcp.defer_del_work);
47211851cbdSAntonio Quartulli 
47311851cbdSAntonio Quartulli 	ovpn_peer_del(peer, OVPN_DEL_PEER_REASON_TRANSPORT_ERROR);
47411851cbdSAntonio Quartulli 	ovpn_peer_put(peer);
47511851cbdSAntonio Quartulli }
47611851cbdSAntonio Quartulli 
47711851cbdSAntonio Quartulli /* Set TCP encapsulation callbacks */
ovpn_tcp_socket_attach(struct ovpn_socket * ovpn_sock,struct ovpn_peer * peer)47811851cbdSAntonio Quartulli int ovpn_tcp_socket_attach(struct ovpn_socket *ovpn_sock,
47911851cbdSAntonio Quartulli 			   struct ovpn_peer *peer)
48011851cbdSAntonio Quartulli {
48111851cbdSAntonio Quartulli 	struct strp_callbacks cb = {
48211851cbdSAntonio Quartulli 		.rcv_msg = ovpn_tcp_rcv,
48311851cbdSAntonio Quartulli 		.parse_msg = ovpn_tcp_parse,
48411851cbdSAntonio Quartulli 	};
48511851cbdSAntonio Quartulli 	int ret;
48611851cbdSAntonio Quartulli 
48711851cbdSAntonio Quartulli 	/* make sure no pre-existing encapsulation handler exists */
488ba499a07SAntonio Quartulli 	if (ovpn_sock->sk->sk_user_data)
48911851cbdSAntonio Quartulli 		return -EBUSY;
49011851cbdSAntonio Quartulli 
49111851cbdSAntonio Quartulli 	/* only a fully connected socket is expected. Connection should be
49211851cbdSAntonio Quartulli 	 * handled in userspace
49311851cbdSAntonio Quartulli 	 */
494ba499a07SAntonio Quartulli 	if (ovpn_sock->sk->sk_state != TCP_ESTABLISHED) {
49511851cbdSAntonio Quartulli 		net_err_ratelimited("%s: provided TCP socket is not in ESTABLISHED state: %d\n",
49611851cbdSAntonio Quartulli 				    netdev_name(peer->ovpn->dev),
497ba499a07SAntonio Quartulli 				    ovpn_sock->sk->sk_state);
49811851cbdSAntonio Quartulli 		return -EINVAL;
49911851cbdSAntonio Quartulli 	}
50011851cbdSAntonio Quartulli 
501ba499a07SAntonio Quartulli 	ret = strp_init(&peer->tcp.strp, ovpn_sock->sk, &cb);
50211851cbdSAntonio Quartulli 	if (ret < 0) {
50311851cbdSAntonio Quartulli 		DEBUG_NET_WARN_ON_ONCE(1);
50411851cbdSAntonio Quartulli 		return ret;
50511851cbdSAntonio Quartulli 	}
50611851cbdSAntonio Quartulli 
50711851cbdSAntonio Quartulli 	INIT_WORK(&peer->tcp.defer_del_work, ovpn_tcp_peer_del_work);
50811851cbdSAntonio Quartulli 
509ba499a07SAntonio Quartulli 	__sk_dst_reset(ovpn_sock->sk);
51011851cbdSAntonio Quartulli 	skb_queue_head_init(&peer->tcp.user_queue);
51111851cbdSAntonio Quartulli 	skb_queue_head_init(&peer->tcp.out_queue);
51211851cbdSAntonio Quartulli 
51311851cbdSAntonio Quartulli 	/* save current CBs so that they can be restored upon socket release */
514ba499a07SAntonio Quartulli 	peer->tcp.sk_cb.sk_data_ready = ovpn_sock->sk->sk_data_ready;
515ba499a07SAntonio Quartulli 	peer->tcp.sk_cb.sk_write_space = ovpn_sock->sk->sk_write_space;
516ba499a07SAntonio Quartulli 	peer->tcp.sk_cb.prot = ovpn_sock->sk->sk_prot;
517ba499a07SAntonio Quartulli 	peer->tcp.sk_cb.ops = ovpn_sock->sk->sk_socket->ops;
51811851cbdSAntonio Quartulli 
51911851cbdSAntonio Quartulli 	/* assign our static CBs and prot/ops */
520ba499a07SAntonio Quartulli 	ovpn_sock->sk->sk_data_ready = ovpn_tcp_data_ready;
521ba499a07SAntonio Quartulli 	ovpn_sock->sk->sk_write_space = ovpn_tcp_write_space;
52211851cbdSAntonio Quartulli 
523ba499a07SAntonio Quartulli 	if (ovpn_sock->sk->sk_family == AF_INET) {
524ba499a07SAntonio Quartulli 		ovpn_sock->sk->sk_prot = &ovpn_tcp_prot;
525ba499a07SAntonio Quartulli 		ovpn_sock->sk->sk_socket->ops = &ovpn_tcp_ops;
52611851cbdSAntonio Quartulli 	} else {
527ba499a07SAntonio Quartulli 		ovpn_sock->sk->sk_prot = &ovpn_tcp6_prot;
528ba499a07SAntonio Quartulli 		ovpn_sock->sk->sk_socket->ops = &ovpn_tcp6_ops;
52911851cbdSAntonio Quartulli 	}
53011851cbdSAntonio Quartulli 
53111851cbdSAntonio Quartulli 	/* avoid using task_frag */
532ba499a07SAntonio Quartulli 	ovpn_sock->sk->sk_allocation = GFP_ATOMIC;
533ba499a07SAntonio Quartulli 	ovpn_sock->sk->sk_use_task_frag = false;
53411851cbdSAntonio Quartulli 
53511851cbdSAntonio Quartulli 	/* enqueue the RX worker */
53611851cbdSAntonio Quartulli 	strp_check_rcv(&peer->tcp.strp);
53711851cbdSAntonio Quartulli 
53811851cbdSAntonio Quartulli 	return 0;
53911851cbdSAntonio Quartulli }
54011851cbdSAntonio Quartulli 
ovpn_tcp_close(struct sock * sk,long timeout)54111851cbdSAntonio Quartulli static void ovpn_tcp_close(struct sock *sk, long timeout)
54211851cbdSAntonio Quartulli {
54311851cbdSAntonio Quartulli 	struct ovpn_socket *sock;
54411851cbdSAntonio Quartulli 	struct ovpn_peer *peer;
54511851cbdSAntonio Quartulli 
54611851cbdSAntonio Quartulli 	rcu_read_lock();
54711851cbdSAntonio Quartulli 	sock = rcu_dereference_sk_user_data(sk);
54811851cbdSAntonio Quartulli 	if (!sock || !sock->peer || !ovpn_peer_hold(sock->peer)) {
54911851cbdSAntonio Quartulli 		rcu_read_unlock();
55011851cbdSAntonio Quartulli 		return;
55111851cbdSAntonio Quartulli 	}
55211851cbdSAntonio Quartulli 	peer = sock->peer;
55311851cbdSAntonio Quartulli 	rcu_read_unlock();
55411851cbdSAntonio Quartulli 
55511851cbdSAntonio Quartulli 	ovpn_peer_del(sock->peer, OVPN_DEL_PEER_REASON_TRANSPORT_DISCONNECT);
55611851cbdSAntonio Quartulli 	peer->tcp.sk_cb.prot->close(sk, timeout);
55711851cbdSAntonio Quartulli 	ovpn_peer_put(peer);
55811851cbdSAntonio Quartulli }
55911851cbdSAntonio Quartulli 
ovpn_tcp_poll(struct file * file,struct socket * sock,poll_table * wait)56011851cbdSAntonio Quartulli static __poll_t ovpn_tcp_poll(struct file *file, struct socket *sock,
56111851cbdSAntonio Quartulli 			      poll_table *wait)
56211851cbdSAntonio Quartulli {
56311851cbdSAntonio Quartulli 	__poll_t mask = datagram_poll(file, sock, wait);
56411851cbdSAntonio Quartulli 	struct ovpn_socket *ovpn_sock;
56511851cbdSAntonio Quartulli 
56611851cbdSAntonio Quartulli 	rcu_read_lock();
56711851cbdSAntonio Quartulli 	ovpn_sock = rcu_dereference_sk_user_data(sock->sk);
56811851cbdSAntonio Quartulli 	if (ovpn_sock && ovpn_sock->peer &&
56911851cbdSAntonio Quartulli 	    !skb_queue_empty(&ovpn_sock->peer->tcp.user_queue))
57011851cbdSAntonio Quartulli 		mask |= EPOLLIN | EPOLLRDNORM;
57111851cbdSAntonio Quartulli 	rcu_read_unlock();
57211851cbdSAntonio Quartulli 
57311851cbdSAntonio Quartulli 	return mask;
57411851cbdSAntonio Quartulli }
57511851cbdSAntonio Quartulli 
ovpn_tcp_build_protos(struct proto * new_prot,struct proto_ops * new_ops,const struct proto * orig_prot,const struct proto_ops * orig_ops)57611851cbdSAntonio Quartulli static void ovpn_tcp_build_protos(struct proto *new_prot,
57711851cbdSAntonio Quartulli 				  struct proto_ops *new_ops,
57811851cbdSAntonio Quartulli 				  const struct proto *orig_prot,
57911851cbdSAntonio Quartulli 				  const struct proto_ops *orig_ops)
58011851cbdSAntonio Quartulli {
58111851cbdSAntonio Quartulli 	memcpy(new_prot, orig_prot, sizeof(*new_prot));
58211851cbdSAntonio Quartulli 	memcpy(new_ops, orig_ops, sizeof(*new_ops));
58311851cbdSAntonio Quartulli 	new_prot->recvmsg = ovpn_tcp_recvmsg;
58411851cbdSAntonio Quartulli 	new_prot->sendmsg = ovpn_tcp_sendmsg;
58511851cbdSAntonio Quartulli 	new_prot->disconnect = ovpn_tcp_disconnect;
58611851cbdSAntonio Quartulli 	new_prot->close = ovpn_tcp_close;
58711851cbdSAntonio Quartulli 	new_prot->release_cb = ovpn_tcp_release;
58811851cbdSAntonio Quartulli 	new_ops->poll = ovpn_tcp_poll;
58911851cbdSAntonio Quartulli }
59011851cbdSAntonio Quartulli 
59111851cbdSAntonio Quartulli /* Initialize TCP static objects */
ovpn_tcp_init(void)59211851cbdSAntonio Quartulli void __init ovpn_tcp_init(void)
59311851cbdSAntonio Quartulli {
59411851cbdSAntonio Quartulli 	ovpn_tcp_build_protos(&ovpn_tcp_prot, &ovpn_tcp_ops, &tcp_prot,
59511851cbdSAntonio Quartulli 			      &inet_stream_ops);
59611851cbdSAntonio Quartulli 
59711851cbdSAntonio Quartulli #if IS_ENABLED(CONFIG_IPV6)
59811851cbdSAntonio Quartulli 	ovpn_tcp_build_protos(&ovpn_tcp6_prot, &ovpn_tcp6_ops, &tcpv6_prot,
59911851cbdSAntonio Quartulli 			      &inet6_stream_ops);
60011851cbdSAntonio Quartulli #endif
60111851cbdSAntonio Quartulli }
602