// SPDX-License-Identifier: GPL-2.0-only
/*
 * Stream Parser
 *
 * Copyright (c) 2016 Tom Herbert <tom@herbertland.com>
 */

#include <linux/bpf.h>
#include <linux/errno.h>
#include <linux/errqueue.h>
#include <linux/file.h>
#include <linux/in.h>
#include <linux/kernel.h>
#include <linux/export.h>
#include <linux/init.h>
#include <linux/net.h>
#include <linux/netdevice.h>
#include <linux/poll.h>
#include <linux/rculist.h>
#include <linux/skbuff.h>
#include <linux/socket.h>
#include <linux/uaccess.h>
#include <linux/workqueue.h>
#include <net/strparser.h>
#include <net/netns/generic.h>
#include <net/sock.h>

static struct workqueue_struct *strp_wq;

static inline struct _strp_msg *_strp_msg(struct sk_buff *skb)
{
	return (struct _strp_msg *)((void *)skb->cb +
		offsetof(struct sk_skb_cb, strp));
}

/* Lower lock held */
static void strp_abort_strp(struct strparser *strp, int err)
{
	/* Unrecoverable error in receive */

	cancel_delayed_work(&strp->msg_timer_work);

	if (strp->stopped)
		return;

	strp->stopped = 1;

	if (strp->sk) {
		struct sock *sk = strp->sk;

		/* Report an error on the lower socket */
		sk->sk_err = -err;
		sk_error_report(sk);
	}
}

static void strp_start_timer(struct strparser *strp, long timeo)
{
	if (timeo && timeo != LONG_MAX)
		mod_delayed_work(strp_wq, &strp->msg_timer_work, timeo);
}

/* Lower lock held */
static void strp_parser_err(struct strparser *strp, int err,
			    read_descriptor_t *desc)
{
	desc->error = err;
	kfree_skb(strp->skb_head);
	strp->skb_head = NULL;
	strp->cb.abort_parser(strp, err);
}

static inline int strp_peek_len(struct strparser *strp)
{
	if (strp->sk) {
		struct socket *sock = strp->sk->sk_socket;

		return sock->ops->peek_len(sock);
	}

	/* If we don't have an associated socket there's nothing to peek.
	 * Return int max to avoid stopping the strparser.
	 */

	return INT_MAX;
}

/* Lower socket lock held */
static int __strp_recv(read_descriptor_t *desc, struct sk_buff *orig_skb,
		       unsigned int orig_offset, size_t orig_len,
		       size_t max_msg_size, long timeo)
{
	struct strparser *strp = (struct strparser *)desc->arg.data;
	struct _strp_msg *stm;
	struct sk_buff *head, *skb;
	size_t eaten = 0, cand_len;
	ssize_t extra;
	int err;
	bool cloned_orig = false;

	if (strp->paused)
		return 0;

	head = strp->skb_head;
	if (head) {
		/* Message already in progress */
		if (unlikely(orig_offset)) {
			/* Getting data with a non-zero offset when a message is
			 * in progress is not expected. If it does happen, we
			 * need to clone and pull since we can't deal with
			 * offsets in the skbs for a message expect in the head.
			 */
			orig_skb = skb_clone(orig_skb, GFP_ATOMIC);
			if (!orig_skb) {
				STRP_STATS_INCR(strp->stats.mem_fail);
				desc->error = -ENOMEM;
				return 0;
			}
			if (!pskb_pull(orig_skb, orig_offset)) {
				STRP_STATS_INCR(strp->stats.mem_fail);
				kfree_skb(orig_skb);
				desc->error = -ENOMEM;
				return 0;
			}
			cloned_orig = true;
			orig_offset = 0;
		}

		if (!strp->skb_nextp) {
			/* We are going to append to the frags_list of head.
			 * Need to unshare the frag_list.
			 */
			err = skb_unclone(head, GFP_ATOMIC);
			if (err) {
				STRP_STATS_INCR(strp->stats.mem_fail);
				desc->error = err;
				return 0;
			}

			if (unlikely(skb_shinfo(head)->frag_list)) {
				/* We can't append to an sk_buff that already
				 * has a frag_list. We create a new head, point
				 * the frag_list of that to the old head, and
				 * then are able to use the old head->next for
				 * appending to the message.
				 */
				if (WARN_ON(head->next)) {
					desc->error = -EINVAL;
					return 0;
				}

				skb = alloc_skb_for_msg(head);
				if (!skb) {
					STRP_STATS_INCR(strp->stats.mem_fail);
					desc->error = -ENOMEM;
					return 0;
				}

				strp->skb_nextp = &head->next;
				strp->skb_head = skb;
				head = skb;
			} else {
				strp->skb_nextp =
				    &skb_shinfo(head)->frag_list;
			}
		}
	}

	while (eaten < orig_len) {
		/* Always clone since we will consume something */
		skb = skb_clone(orig_skb, GFP_ATOMIC);
		if (!skb) {
			STRP_STATS_INCR(strp->stats.mem_fail);
			desc->error = -ENOMEM;
			break;
		}

		cand_len = orig_len - eaten;

		head = strp->skb_head;
		if (!head) {
			head = skb;
			strp->skb_head = head;
			/* Will set skb_nextp on next packet if needed */
			strp->skb_nextp = NULL;
			stm = _strp_msg(head);
			memset(stm, 0, sizeof(*stm));
			stm->strp.offset = orig_offset + eaten;
		} else {
			/* Unclone if we are appending to an skb that we
			 * already share a frag_list with.
			 */
			if (skb_has_frag_list(skb)) {
				err = skb_unclone(skb, GFP_ATOMIC);
				if (err) {
					STRP_STATS_INCR(strp->stats.mem_fail);
					desc->error = err;
					break;
				}
			}

			stm = _strp_msg(head);
			*strp->skb_nextp = skb;
			strp->skb_nextp = &skb->next;
			head->data_len += skb->len;
			head->len += skb->len;
			head->truesize += skb->truesize;
		}

		if (!stm->strp.full_len) {
			ssize_t len;

			len = (*strp->cb.parse_msg)(strp, head);

			if (!len) {
				/* Need more header to determine length */
				if (!stm->accum_len) {
					/* Start RX timer for new message */
					strp_start_timer(strp, timeo);
				}
				stm->accum_len += cand_len;
				eaten += cand_len;
				STRP_STATS_INCR(strp->stats.need_more_hdr);
				WARN_ON(eaten != orig_len);
				break;
			} else if (len < 0) {
				if (len == -ESTRPIPE && stm->accum_len) {
					len = -ENODATA;
					strp->unrecov_intr = 1;
				} else {
					strp->interrupted = 1;
				}
				strp_parser_err(strp, len, desc);
				break;
			} else if (len > max_msg_size) {
				/* Message length exceeds maximum allowed */
				STRP_STATS_INCR(strp->stats.msg_too_big);
				strp_parser_err(strp, -EMSGSIZE, desc);
				break;
			} else if (len <= (ssize_t)head->len -
					  skb->len - stm->strp.offset) {
				/* Length must be into new skb (and also
				 * greater than zero)
				 */
				STRP_STATS_INCR(strp->stats.bad_hdr_len);
				strp_parser_err(strp, -EPROTO, desc);
				break;
			}

			stm->strp.full_len = len;
		}

		extra = (ssize_t)(stm->accum_len + cand_len) -
			stm->strp.full_len;

		if (extra < 0) {
			/* Message not complete yet. */
			if (stm->strp.full_len - stm->accum_len >
			    strp_peek_len(strp)) {
				/* Don't have the whole message in the socket
				 * buffer. Set strp->need_bytes to wait for
				 * the rest of the message. Also, set "early
				 * eaten" since we've already buffered the skb
				 * but don't consume yet per strp_read_sock.
				 */

				if (!stm->accum_len) {
					/* Start RX timer for new message */
					strp_start_timer(strp, timeo);
				}

				stm->accum_len += cand_len;
				eaten += cand_len;
				strp->need_bytes = stm->strp.full_len -
						       stm->accum_len;
				STRP_STATS_ADD(strp->stats.bytes, cand_len);
				desc->count = 0; /* Stop reading socket */
				break;
			}
			stm->accum_len += cand_len;
			eaten += cand_len;
			WARN_ON(eaten != orig_len);
			break;
		}

		/* Positive extra indicates more bytes than needed for the
		 * message
		 */

		WARN_ON(extra > cand_len);

		eaten += (cand_len - extra);

		/* Hurray, we have a new message! */
		cancel_delayed_work(&strp->msg_timer_work);
		strp->skb_head = NULL;
		strp->need_bytes = 0;
		STRP_STATS_INCR(strp->stats.msgs);

		/* Give skb to upper layer */
		strp->cb.rcv_msg(strp, head);

		if (unlikely(strp->paused)) {
			/* Upper layer paused strp */
			break;
		}
	}

	if (cloned_orig)
		kfree_skb(orig_skb);

	STRP_STATS_ADD(strp->stats.bytes, eaten);

	return eaten;
}

int strp_process(struct strparser *strp, struct sk_buff *orig_skb,
		 unsigned int orig_offset, size_t orig_len,
		 size_t max_msg_size, long timeo)
{
	read_descriptor_t desc; /* Dummy arg to strp_recv */

	desc.arg.data = strp;

	return __strp_recv(&desc, orig_skb, orig_offset, orig_len,
			   max_msg_size, timeo);
}
EXPORT_SYMBOL_GPL(strp_process);

static int strp_recv(read_descriptor_t *desc, struct sk_buff *orig_skb,
		     unsigned int orig_offset, size_t orig_len)
{
	struct strparser *strp = (struct strparser *)desc->arg.data;

	return __strp_recv(desc, orig_skb, orig_offset, orig_len,
			   strp->sk->sk_rcvbuf, READ_ONCE(strp->sk->sk_rcvtimeo));
}

static int default_read_sock_done(struct strparser *strp, int err)
{
	return err;
}

/* Called with lock held on lower socket */
static int strp_read_sock(struct strparser *strp)
{
	struct socket *sock = strp->sk->sk_socket;
	read_descriptor_t desc;

	if (unlikely(!sock || !sock->ops))
		return -EBUSY;

	if (unlikely(!strp->cb.read_sock && !sock->ops->read_sock))
		return -EBUSY;

	desc.arg.data = strp;
	desc.error = 0;
	desc.count = 1; /* give more than one skb per call */

	/* sk should be locked here, so okay to do read_sock */
	if (strp->cb.read_sock)
		strp->cb.read_sock(strp, &desc, strp_recv);
	else
		sock->ops->read_sock(strp->sk, &desc, strp_recv);

	desc.error = strp->cb.read_sock_done(strp, desc.error);

	return desc.error;
}

/* Lower sock lock held */
void strp_data_ready(struct strparser *strp)
{
	if (unlikely(strp->stopped) || strp->paused)
		return;

	/* This check is needed to synchronize with do_strp_work.
	 * do_strp_work acquires a process lock (lock_sock) whereas
	 * the lock held here is bh_lock_sock. The two locks can be
	 * held by different threads at the same time, but bh_lock_sock
	 * allows a thread in BH context to safely check if the process
	 * lock is held. In this case, if the lock is held, queue work.
	 */
	if (sock_owned_by_user_nocheck(strp->sk)) {
		queue_work(strp_wq, &strp->work);
		return;
	}

	if (strp->need_bytes) {
		if (strp_peek_len(strp) < strp->need_bytes)
			return;
	}

	if (strp_read_sock(strp) == -ENOMEM)
		queue_work(strp_wq, &strp->work);
}
EXPORT_SYMBOL_GPL(strp_data_ready);

static void do_strp_work(struct strparser *strp)
{
	/* We need the read lock to synchronize with strp_data_ready. We
	 * need the socket lock for calling strp_read_sock.
	 */
	strp->cb.lock(strp);

	if (unlikely(strp->stopped))
		goto out;

	if (strp->paused)
		goto out;

	if (strp_read_sock(strp) == -ENOMEM)
		queue_work(strp_wq, &strp->work);

out:
	strp->cb.unlock(strp);
}

static void strp_work(struct work_struct *w)
{
	do_strp_work(container_of(w, struct strparser, work));
}

static void strp_msg_timeout(struct work_struct *w)
{
	struct strparser *strp = container_of(w, struct strparser,
					      msg_timer_work.work);

	/* Message assembly timed out */
	STRP_STATS_INCR(strp->stats.msg_timeouts);
	strp->cb.lock(strp);
	strp->cb.abort_parser(strp, -ETIMEDOUT);
	strp->cb.unlock(strp);
}

static void strp_sock_lock(struct strparser *strp)
{
	lock_sock(strp->sk);
}

static void strp_sock_unlock(struct strparser *strp)
{
	release_sock(strp->sk);
}

int strp_init(struct strparser *strp, struct sock *sk,
	      const struct strp_callbacks *cb)
{

	if (!cb || !cb->rcv_msg || !cb->parse_msg)
		return -EINVAL;

	/* The sk (sock) arg determines the mode of the stream parser.
	 *
	 * If the sock is set then the strparser is in receive callback mode.
	 * The upper layer calls strp_data_ready to kick receive processing
	 * and strparser calls the read_sock function on the socket to
	 * get packets.
	 *
	 * If the sock is not set then the strparser is in general mode.
	 * The upper layer calls strp_process for each skb to be parsed.
	 */

	if (!sk) {
		if (!cb->lock || !cb->unlock)
			return -EINVAL;
	}

	memset(strp, 0, sizeof(*strp));

	strp->sk = sk;

	strp->cb.lock = cb->lock ? : strp_sock_lock;
	strp->cb.unlock = cb->unlock ? : strp_sock_unlock;
	strp->cb.rcv_msg = cb->rcv_msg;
	strp->cb.parse_msg = cb->parse_msg;
	strp->cb.read_sock = cb->read_sock;
	strp->cb.read_sock_done = cb->read_sock_done ? : default_read_sock_done;
	strp->cb.abort_parser = cb->abort_parser ? : strp_abort_strp;

	INIT_DELAYED_WORK(&strp->msg_timer_work, strp_msg_timeout);
	INIT_WORK(&strp->work, strp_work);

	return 0;
}
EXPORT_SYMBOL_GPL(strp_init);

void strp_unpause(struct strparser *strp)
{
	strp->paused = 0;

	/* Sync setting paused with RX work */
	smp_mb();

	queue_work(strp_wq, &strp->work);
}
EXPORT_SYMBOL_GPL(strp_unpause);

/* strp must already be stopped so that strp_recv will no longer be called.
 * Note that strp_done is not called with the lower socket held.
 */
void strp_done(struct strparser *strp)
{
	WARN_ON(!strp->stopped);

	cancel_delayed_work_sync(&strp->msg_timer_work);
	cancel_work_sync(&strp->work);

	if (strp->skb_head) {
		kfree_skb(strp->skb_head);
		strp->skb_head = NULL;
	}
}
EXPORT_SYMBOL_GPL(strp_done);

void strp_stop(struct strparser *strp)
{
	strp->stopped = 1;
}
EXPORT_SYMBOL_GPL(strp_stop);

void strp_check_rcv(struct strparser *strp)
{
	queue_work(strp_wq, &strp->work);
}
EXPORT_SYMBOL_GPL(strp_check_rcv);

static int __init strp_dev_init(void)
{
	BUILD_BUG_ON(sizeof(struct sk_skb_cb) >
		     sizeof_field(struct sk_buff, cb));

	strp_wq = create_singlethread_workqueue("kstrp");
	if (unlikely(!strp_wq))
		return -ENOMEM;

	return 0;
}
device_initcall(strp_dev_init);
