#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/module.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 <linux/syscalls.h>
#include <net/kcm.h>
#include <net/netns/generic.h>
#include <net/sock.h>
#include <net/tcp.h>
#include <uapi/linux/kcm.h>

unsigned int kcm_net_id;

static struct kmem_cache *kcm_psockp __read_mostly;
static struct kmem_cache *kcm_muxp __read_mostly;
static struct workqueue_struct *kcm_wq;

static inline struct kcm_sock *kcm_sk(const struct sock *sk)
{
	return (struct kcm_sock *)sk;
}

static inline struct kcm_tx_msg *kcm_tx_msg(struct sk_buff *skb)
{
	return (struct kcm_tx_msg *)skb->cb;
}

static inline struct kcm_rx_msg *kcm_rx_msg(struct sk_buff *skb)
{
	return (struct kcm_rx_msg *)((void *)skb->cb +
				     offsetof(struct qdisc_skb_cb, data));
}

static void report_csk_error(struct sock *csk, int err)
{
	csk->sk_err = EPIPE;
	csk->sk_error_report(csk);
}

/* Callback lock held */
static void kcm_abort_rx_psock(struct kcm_psock *psock, int err,
			       struct sk_buff *skb)
{
	struct sock *csk = psock->sk;

	/* Unrecoverable error in receive */

	del_timer(&psock->rx_msg_timer);

	if (psock->rx_stopped)
		return;

	psock->rx_stopped = 1;
	KCM_STATS_INCR(psock->stats.rx_aborts);

	/* Report an error on the lower socket */
	report_csk_error(csk, err);
}

static void kcm_abort_tx_psock(struct kcm_psock *psock, int err,
			       bool wakeup_kcm)
{
	struct sock *csk = psock->sk;
	struct kcm_mux *mux = psock->mux;

	/* Unrecoverable error in transmit */

	spin_lock_bh(&mux->lock);

	if (psock->tx_stopped) {
		spin_unlock_bh(&mux->lock);
		return;
	}

	psock->tx_stopped = 1;
	KCM_STATS_INCR(psock->stats.tx_aborts);

	if (!psock->tx_kcm) {
		/* Take off psocks_avail list */
		list_del(&psock->psock_avail_list);
	} else if (wakeup_kcm) {
		/* In this case psock is being aborted while outside of
		 * write_msgs and psock is reserved. Schedule tx_work
		 * to handle the failure there. Need to commit tx_stopped
		 * before queuing work.
		 */
		smp_mb();

		queue_work(kcm_wq, &psock->tx_kcm->tx_work);
	}

	spin_unlock_bh(&mux->lock);

	/* Report error on lower socket */
	report_csk_error(csk, err);
}

/* RX mux lock held. */
static void kcm_update_rx_mux_stats(struct kcm_mux *mux,
				    struct kcm_psock *psock)
{
	KCM_STATS_ADD(mux->stats.rx_bytes,
		      psock->stats.rx_bytes - psock->saved_rx_bytes);
	mux->stats.rx_msgs +=
		psock->stats.rx_msgs - psock->saved_rx_msgs;
	psock->saved_rx_msgs = psock->stats.rx_msgs;
	psock->saved_rx_bytes = psock->stats.rx_bytes;
}

static void kcm_update_tx_mux_stats(struct kcm_mux *mux,
				    struct kcm_psock *psock)
{
	KCM_STATS_ADD(mux->stats.tx_bytes,
		      psock->stats.tx_bytes - psock->saved_tx_bytes);
	mux->stats.tx_msgs +=
		psock->stats.tx_msgs - psock->saved_tx_msgs;
	psock->saved_tx_msgs = psock->stats.tx_msgs;
	psock->saved_tx_bytes = psock->stats.tx_bytes;
}

static int kcm_queue_rcv_skb(struct sock *sk, struct sk_buff *skb);

/* KCM is ready to receive messages on its queue-- either the KCM is new or
 * has become unblocked after being blocked on full socket buffer. Queue any
 * pending ready messages on a psock. RX mux lock held.
 */
static void kcm_rcv_ready(struct kcm_sock *kcm)
{
	struct kcm_mux *mux = kcm->mux;
	struct kcm_psock *psock;
	struct sk_buff *skb;

	if (unlikely(kcm->rx_wait || kcm->rx_psock || kcm->rx_disabled))
		return;

	while (unlikely((skb = __skb_dequeue(&mux->rx_hold_queue)))) {
		if (kcm_queue_rcv_skb(&kcm->sk, skb)) {
			/* Assuming buffer limit has been reached */
			skb_queue_head(&mux->rx_hold_queue, skb);
			WARN_ON(!sk_rmem_alloc_get(&kcm->sk));
			return;
		}
	}

	while (!list_empty(&mux->psocks_ready)) {
		psock = list_first_entry(&mux->psocks_ready, struct kcm_psock,
					 psock_ready_list);

		if (kcm_queue_rcv_skb(&kcm->sk, psock->ready_rx_msg)) {
			/* Assuming buffer limit has been reached */
			WARN_ON(!sk_rmem_alloc_get(&kcm->sk));
			return;
		}

		/* Consumed the ready message on the psock. Schedule rx_work to
		 * get more messages.
		 */
		list_del(&psock->psock_ready_list);
		psock->ready_rx_msg = NULL;

		/* Commit clearing of ready_rx_msg for queuing work */
		smp_mb();

		queue_work(kcm_wq, &psock->rx_work);
	}

	/* Buffer limit is okay now, add to ready list */
	list_add_tail(&kcm->wait_rx_list,
		      &kcm->mux->kcm_rx_waiters);
	kcm->rx_wait = true;
}

static void kcm_rfree(struct sk_buff *skb)
{
	struct sock *sk = skb->sk;
	struct kcm_sock *kcm = kcm_sk(sk);
	struct kcm_mux *mux = kcm->mux;
	unsigned int len = skb->truesize;

	sk_mem_uncharge(sk, len);
	atomic_sub(len, &sk->sk_rmem_alloc);

	/* For reading rx_wait and rx_psock without holding lock */
	smp_mb__after_atomic();

	if (!kcm->rx_wait && !kcm->rx_psock &&
	    sk_rmem_alloc_get(sk) < sk->sk_rcvlowat) {
		spin_lock_bh(&mux->rx_lock);
		kcm_rcv_ready(kcm);
		spin_unlock_bh(&mux->rx_lock);
	}
}

static int kcm_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
{
	struct sk_buff_head *list = &sk->sk_receive_queue;

	if (atomic_read(&sk->sk_rmem_alloc) >= sk->sk_rcvbuf)
		return -ENOMEM;

	if (!sk_rmem_schedule(sk, skb, skb->truesize))
		return -ENOBUFS;

	skb->dev = NULL;

	skb_orphan(skb);
	skb->sk = sk;
	skb->destructor = kcm_rfree;
	atomic_add(skb->truesize, &sk->sk_rmem_alloc);
	sk_mem_charge(sk, skb->truesize);

	skb_queue_tail(list, skb);

	if (!sock_flag(sk, SOCK_DEAD))
		sk->sk_data_ready(sk);

	return 0;
}

/* Requeue received messages for a kcm socket to other kcm sockets. This is
 * called with a kcm socket is receive disabled.
 * RX mux lock held.
 */
static void requeue_rx_msgs(struct kcm_mux *mux, struct sk_buff_head *head)
{
	struct sk_buff *skb;
	struct kcm_sock *kcm;

	while ((skb = __skb_dequeue(head))) {
		/* Reset destructor to avoid calling kcm_rcv_ready */
		skb->destructor = sock_rfree;
		skb_orphan(skb);
try_again:
		if (list_empty(&mux->kcm_rx_waiters)) {
			skb_queue_tail(&mux->rx_hold_queue, skb);
			continue;
		}

		kcm = list_first_entry(&mux->kcm_rx_waiters,
				       struct kcm_sock, wait_rx_list);

		if (kcm_queue_rcv_skb(&kcm->sk, skb)) {
			/* Should mean socket buffer full */
			list_del(&kcm->wait_rx_list);
			kcm->rx_wait = false;

			/* Commit rx_wait to read in kcm_free */
			smp_wmb();

			goto try_again;
		}
	}
}

/* Lower sock lock held */
static struct kcm_sock *reserve_rx_kcm(struct kcm_psock *psock,
				       struct sk_buff *head)
{
	struct kcm_mux *mux = psock->mux;
	struct kcm_sock *kcm;

	WARN_ON(psock->ready_rx_msg);

	if (psock->rx_kcm)
		return psock->rx_kcm;

	spin_lock_bh(&mux->rx_lock);

	if (psock->rx_kcm) {
		spin_unlock_bh(&mux->rx_lock);
		return psock->rx_kcm;
	}

	kcm_update_rx_mux_stats(mux, psock);

	if (list_empty(&mux->kcm_rx_waiters)) {
		psock->ready_rx_msg = head;
		list_add_tail(&psock->psock_ready_list,
			      &mux->psocks_ready);
		spin_unlock_bh(&mux->rx_lock);
		return NULL;
	}

	kcm = list_first_entry(&mux->kcm_rx_waiters,
			       struct kcm_sock, wait_rx_list);
	list_del(&kcm->wait_rx_list);
	kcm->rx_wait = false;

	psock->rx_kcm = kcm;
	kcm->rx_psock = psock;

	spin_unlock_bh(&mux->rx_lock);

	return kcm;
}

static void kcm_done(struct kcm_sock *kcm);

static void kcm_done_work(struct work_struct *w)
{
	kcm_done(container_of(w, struct kcm_sock, done_work));
}

/* Lower sock held */
static void unreserve_rx_kcm(struct kcm_psock *psock,
			     bool rcv_ready)
{
	struct kcm_sock *kcm = psock->rx_kcm;
	struct kcm_mux *mux = psock->mux;

	if (!kcm)
		return;

	spin_lock_bh(&mux->rx_lock);

	psock->rx_kcm = NULL;
	kcm->rx_psock = NULL;

	/* Commit kcm->rx_psock before sk_rmem_alloc_get to sync with
	 * kcm_rfree
	 */
	smp_mb();

	if (unlikely(kcm->done)) {
		spin_unlock_bh(&mux->rx_lock);

		/* Need to run kcm_done in a task since we need to qcquire
		 * callback locks which may already be held here.
		 */
		INIT_WORK(&kcm->done_work, kcm_done_work);
		schedule_work(&kcm->done_work);
		return;
	}

	if (unlikely(kcm->rx_disabled)) {
		requeue_rx_msgs(mux, &kcm->sk.sk_receive_queue);
	} else if (rcv_ready || unlikely(!sk_rmem_alloc_get(&kcm->sk))) {
		/* Check for degenerative race with rx_wait that all
		 * data was dequeued (accounted for in kcm_rfree).
		 */
		kcm_rcv_ready(kcm);
	}
	spin_unlock_bh(&mux->rx_lock);
}

static void kcm_start_rx_timer(struct kcm_psock *psock)
{
	if (psock->sk->sk_rcvtimeo)
		mod_timer(&psock->rx_msg_timer, psock->sk->sk_rcvtimeo);
}

/* Macro to invoke filter function. */
#define KCM_RUN_FILTER(prog, ctx) \
	(*prog->bpf_func)(ctx, prog->insnsi)

/* Lower socket lock held */
static int kcm_tcp_recv(read_descriptor_t *desc, struct sk_buff *orig_skb,
			unsigned int orig_offset, size_t orig_len)
{
	struct kcm_psock *psock = (struct kcm_psock *)desc->arg.data;
	struct kcm_rx_msg *rxm;
	struct kcm_sock *kcm;
	struct sk_buff *head, *skb;
	size_t eaten = 0, cand_len;
	ssize_t extra;
	int err;
	bool cloned_orig = false;

	if (psock->ready_rx_msg)
		return 0;

	head = psock->rx_skb_head;
	if (head) {
		/* Message already in progress */

		rxm = kcm_rx_msg(head);
		if (unlikely(rxm->early_eaten)) {
			/* Already some number of bytes on the receive sock
			 * data saved in rx_skb_head, just indicate they
			 * are consumed.
			 */
			eaten = orig_len <= rxm->early_eaten ?
				orig_len : rxm->early_eaten;
			rxm->early_eaten -= eaten;

			return eaten;
		}

		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) {
				KCM_STATS_INCR(psock->stats.rx_mem_fail);
				desc->error = -ENOMEM;
				return 0;
			}
			if (!pskb_pull(orig_skb, orig_offset)) {
				KCM_STATS_INCR(psock->stats.rx_mem_fail);
				kfree_skb(orig_skb);
				desc->error = -ENOMEM;
				return 0;
			}
			cloned_orig = true;
			orig_offset = 0;
		}

		if (!psock->rx_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) {
				KCM_STATS_INCR(psock->stats.rx_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(0, GFP_ATOMIC);
				if (!skb) {
					KCM_STATS_INCR(psock->stats.rx_mem_fail);
					desc->error = -ENOMEM;
					return 0;
				}
				skb->len = head->len;
				skb->data_len = head->len;
				skb->truesize = head->truesize;
				*kcm_rx_msg(skb) = *kcm_rx_msg(head);
				psock->rx_skb_nextp = &head->next;
				skb_shinfo(skb)->frag_list = head;
				psock->rx_skb_head = skb;
				head = skb;
			} else {
				psock->rx_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) {
			KCM_STATS_INCR(psock->stats.rx_mem_fail);
			desc->error = -ENOMEM;
			break;
		}

		cand_len = orig_len - eaten;

		head = psock->rx_skb_head;
		if (!head) {
			head = skb;
			psock->rx_skb_head = head;
			/* Will set rx_skb_nextp on next packet if needed */
			psock->rx_skb_nextp = NULL;
			rxm = kcm_rx_msg(head);
			memset(rxm, 0, sizeof(*rxm));
			rxm->offset = orig_offset + eaten;
		} else {
			/* Unclone since we may be appending to an skb that we
			 * already share a frag_list with.
			 */
			err = skb_unclone(skb, GFP_ATOMIC);
			if (err) {
				KCM_STATS_INCR(psock->stats.rx_mem_fail);
				desc->error = err;
				break;
			}

			rxm = kcm_rx_msg(head);
			*psock->rx_skb_nextp = skb;
			psock->rx_skb_nextp = &skb->next;
			head->data_len += skb->len;
			head->len += skb->len;
			head->truesize += skb->truesize;
		}

		if (!rxm->full_len) {
			ssize_t len;

			len = KCM_RUN_FILTER(psock->bpf_prog, head);

			if (!len) {
				/* Need more header to determine length */
				if (!rxm->accum_len) {
					/* Start RX timer for new message */
					kcm_start_rx_timer(psock);
				}
				rxm->accum_len += cand_len;
				eaten += cand_len;
				KCM_STATS_INCR(psock->stats.rx_need_more_hdr);
				WARN_ON(eaten != orig_len);
				break;
			} else if (len > psock->sk->sk_rcvbuf) {
				/* Message length exceeds maximum allowed */
				KCM_STATS_INCR(psock->stats.rx_msg_too_big);
				desc->error = -EMSGSIZE;
				psock->rx_skb_head = NULL;
				kcm_abort_rx_psock(psock, EMSGSIZE, head);
				break;
			} else if (len <= (ssize_t)head->len -
					  skb->len - rxm->offset) {
				/* Length must be into new skb (and also
				 * greater than zero)
				 */
				KCM_STATS_INCR(psock->stats.rx_bad_hdr_len);
				desc->error = -EPROTO;
				psock->rx_skb_head = NULL;
				kcm_abort_rx_psock(psock, EPROTO, head);
				break;
			}

			rxm->full_len = len;
		}

		extra = (ssize_t)(rxm->accum_len + cand_len) - rxm->full_len;

		if (extra < 0) {
			/* Message not complete yet. */
			if (rxm->full_len - rxm->accum_len >
			    tcp_inq(psock->sk)) {
				/* Don't have the whole messages in the socket
				 * buffer. Set psock->rx_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 tcp_read_sock.
				 */

				if (!rxm->accum_len) {
					/* Start RX timer for new message */
					kcm_start_rx_timer(psock);
				}

				psock->rx_need_bytes = rxm->full_len -
						       rxm->accum_len;
				rxm->accum_len += cand_len;
				rxm->early_eaten = cand_len;
				KCM_STATS_ADD(psock->stats.rx_bytes, cand_len);
				desc->count = 0; /* Stop reading socket */
				break;
			}
			rxm->accum_len += cand_len;
			eaten += cand_len;
			WARN_ON(eaten != orig_len);
			break;
		}

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

		WARN_ON(extra > cand_len);

		eaten += (cand_len - extra);

		/* Hurray, we have a new message! */
		del_timer(&psock->rx_msg_timer);
		psock->rx_skb_head = NULL;
		KCM_STATS_INCR(psock->stats.rx_msgs);

try_queue:
		kcm = reserve_rx_kcm(psock, head);
		if (!kcm) {
			/* Unable to reserve a KCM, message is held in psock. */
			break;
		}

		if (kcm_queue_rcv_skb(&kcm->sk, head)) {
			/* Should mean socket buffer full */
			unreserve_rx_kcm(psock, false);
			goto try_queue;
		}
	}

	if (cloned_orig)
		kfree_skb(orig_skb);

	KCM_STATS_ADD(psock->stats.rx_bytes, eaten);

	return eaten;
}

/* Called with lock held on lower socket */
static int psock_tcp_read_sock(struct kcm_psock *psock)
{
	read_descriptor_t desc;

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

	/* sk should be locked here, so okay to do tcp_read_sock */
	tcp_read_sock(psock->sk, &desc, kcm_tcp_recv);

	unreserve_rx_kcm(psock, true);

	return desc.error;
}

/* Lower sock lock held */
static void psock_tcp_data_ready(struct sock *sk)
{
	struct kcm_psock *psock;

	read_lock_bh(&sk->sk_callback_lock);

	psock = (struct kcm_psock *)sk->sk_user_data;
	if (unlikely(!psock || psock->rx_stopped))
		goto out;

	if (psock->ready_rx_msg)
		goto out;

	if (psock->rx_need_bytes) {
		if (tcp_inq(sk) >= psock->rx_need_bytes)
			psock->rx_need_bytes = 0;
		else
			goto out;
	}

	if (psock_tcp_read_sock(psock) == -ENOMEM)
		queue_delayed_work(kcm_wq, &psock->rx_delayed_work, 0);

out:
	read_unlock_bh(&sk->sk_callback_lock);
}

static void do_psock_rx_work(struct kcm_psock *psock)
{
	read_descriptor_t rd_desc;
	struct sock *csk = psock->sk;

	/* We need the read lock to synchronize with psock_tcp_data_ready. We
	 * need the socket lock for calling tcp_read_sock.
	 */
	lock_sock(csk);
	read_lock_bh(&csk->sk_callback_lock);

	if (unlikely(csk->sk_user_data != psock))
		goto out;

	if (unlikely(psock->rx_stopped))
		goto out;

	if (psock->ready_rx_msg)
		goto out;

	rd_desc.arg.data = psock;

	if (psock_tcp_read_sock(psock) == -ENOMEM)
		queue_delayed_work(kcm_wq, &psock->rx_delayed_work, 0);

out:
	read_unlock_bh(&csk->sk_callback_lock);
	release_sock(csk);
}

static void psock_rx_work(struct work_struct *w)
{
	do_psock_rx_work(container_of(w, struct kcm_psock, rx_work));
}

static void psock_rx_delayed_work(struct work_struct *w)
{
	do_psock_rx_work(container_of(w, struct kcm_psock,
				      rx_delayed_work.work));
}

static void psock_tcp_state_change(struct sock *sk)
{
	/* TCP only does a POLLIN for a half close. Do a POLLHUP here
	 * since application will normally not poll with POLLIN
	 * on the TCP sockets.
	 */

	report_csk_error(sk, EPIPE);
}

static void psock_tcp_write_space(struct sock *sk)
{
	struct kcm_psock *psock;
	struct kcm_mux *mux;
	struct kcm_sock *kcm;

	read_lock_bh(&sk->sk_callback_lock);

	psock = (struct kcm_psock *)sk->sk_user_data;
	if (unlikely(!psock))
		goto out;

	mux = psock->mux;

	spin_lock_bh(&mux->lock);

	/* Check if the socket is reserved so someone is waiting for sending. */
	kcm = psock->tx_kcm;
	if (kcm)
		queue_work(kcm_wq, &kcm->tx_work);

	spin_unlock_bh(&mux->lock);
out:
	read_unlock_bh(&sk->sk_callback_lock);
}

static void unreserve_psock(struct kcm_sock *kcm);

/* kcm sock is locked. */
static struct kcm_psock *reserve_psock(struct kcm_sock *kcm)
{
	struct kcm_mux *mux = kcm->mux;
	struct kcm_psock *psock;

	psock = kcm->tx_psock;

	smp_rmb(); /* Must read tx_psock before tx_wait */

	if (psock) {
		WARN_ON(kcm->tx_wait);
		if (unlikely(psock->tx_stopped))
			unreserve_psock(kcm);
		else
			return kcm->tx_psock;
	}

	spin_lock_bh(&mux->lock);

	/* Check again under lock to see if psock was reserved for this
	 * psock via psock_unreserve.
	 */
	psock = kcm->tx_psock;
	if (unlikely(psock)) {
		WARN_ON(kcm->tx_wait);
		spin_unlock_bh(&mux->lock);
		return kcm->tx_psock;
	}

	if (!list_empty(&mux->psocks_avail)) {
		psock = list_first_entry(&mux->psocks_avail,
					 struct kcm_psock,
					 psock_avail_list);
		list_del(&psock->psock_avail_list);
		if (kcm->tx_wait) {
			list_del(&kcm->wait_psock_list);
			kcm->tx_wait = false;
		}
		kcm->tx_psock = psock;
		psock->tx_kcm = kcm;
		KCM_STATS_INCR(psock->stats.reserved);
	} else if (!kcm->tx_wait) {
		list_add_tail(&kcm->wait_psock_list,
			      &mux->kcm_tx_waiters);
		kcm->tx_wait = true;
	}

	spin_unlock_bh(&mux->lock);

	return psock;
}

/* mux lock held */
static void psock_now_avail(struct kcm_psock *psock)
{
	struct kcm_mux *mux = psock->mux;
	struct kcm_sock *kcm;

	if (list_empty(&mux->kcm_tx_waiters)) {
		list_add_tail(&psock->psock_avail_list,
			      &mux->psocks_avail);
	} else {
		kcm = list_first_entry(&mux->kcm_tx_waiters,
				       struct kcm_sock,
				       wait_psock_list);
		list_del(&kcm->wait_psock_list);
		kcm->tx_wait = false;
		psock->tx_kcm = kcm;

		/* Commit before changing tx_psock since that is read in
		 * reserve_psock before queuing work.
		 */
		smp_mb();

		kcm->tx_psock = psock;
		KCM_STATS_INCR(psock->stats.reserved);
		queue_work(kcm_wq, &kcm->tx_work);
	}
}

/* kcm sock is locked. */
static void unreserve_psock(struct kcm_sock *kcm)
{
	struct kcm_psock *psock;
	struct kcm_mux *mux = kcm->mux;

	spin_lock_bh(&mux->lock);

	psock = kcm->tx_psock;

	if (WARN_ON(!psock)) {
		spin_unlock_bh(&mux->lock);
		return;
	}

	smp_rmb(); /* Read tx_psock before tx_wait */

	kcm_update_tx_mux_stats(mux, psock);

	WARN_ON(kcm->tx_wait);

	kcm->tx_psock = NULL;
	psock->tx_kcm = NULL;
	KCM_STATS_INCR(psock->stats.unreserved);

	if (unlikely(psock->tx_stopped)) {
		if (psock->done) {
			/* Deferred free */
			list_del(&psock->psock_list);
			mux->psocks_cnt--;
			sock_put(psock->sk);
			fput(psock->sk->sk_socket->file);
			kmem_cache_free(kcm_psockp, psock);
		}

		/* Don't put back on available list */

		spin_unlock_bh(&mux->lock);

		return;
	}

	psock_now_avail(psock);

	spin_unlock_bh(&mux->lock);
}

static void kcm_report_tx_retry(struct kcm_sock *kcm)
{
	struct kcm_mux *mux = kcm->mux;

	spin_lock_bh(&mux->lock);
	KCM_STATS_INCR(mux->stats.tx_retries);
	spin_unlock_bh(&mux->lock);
}

/* Write any messages ready on the kcm socket.  Called with kcm sock lock
 * held.  Return bytes actually sent or error.
 */
static int kcm_write_msgs(struct kcm_sock *kcm)
{
	struct sock *sk = &kcm->sk;
	struct kcm_psock *psock;
	struct sk_buff *skb, *head;
	struct kcm_tx_msg *txm;
	unsigned short fragidx, frag_offset;
	unsigned int sent, total_sent = 0;
	int ret = 0;

	kcm->tx_wait_more = false;
	psock = kcm->tx_psock;
	if (unlikely(psock && psock->tx_stopped)) {
		/* A reserved psock was aborted asynchronously. Unreserve
		 * it and we'll retry the message.
		 */
		unreserve_psock(kcm);
		kcm_report_tx_retry(kcm);
		if (skb_queue_empty(&sk->sk_write_queue))
			return 0;

		kcm_tx_msg(skb_peek(&sk->sk_write_queue))->sent = 0;

	} else if (skb_queue_empty(&sk->sk_write_queue)) {
		return 0;
	}

	head = skb_peek(&sk->sk_write_queue);
	txm = kcm_tx_msg(head);

	if (txm->sent) {
		/* Send of first skbuff in queue already in progress */
		if (WARN_ON(!psock)) {
			ret = -EINVAL;
			goto out;
		}
		sent = txm->sent;
		frag_offset = txm->frag_offset;
		fragidx = txm->fragidx;
		skb = txm->frag_skb;

		goto do_frag;
	}

try_again:
	psock = reserve_psock(kcm);
	if (!psock)
		goto out;

	do {
		skb = head;
		txm = kcm_tx_msg(head);
		sent = 0;

do_frag_list:
		if (WARN_ON(!skb_shinfo(skb)->nr_frags)) {
			ret = -EINVAL;
			goto out;
		}

		for (fragidx = 0; fragidx < skb_shinfo(skb)->nr_frags;
		     fragidx++) {
			skb_frag_t *frag;

			frag_offset = 0;
do_frag:
			frag = &skb_shinfo(skb)->frags[fragidx];
			if (WARN_ON(!frag->size)) {
				ret = -EINVAL;
				goto out;
			}

			ret = kernel_sendpage(psock->sk->sk_socket,
					      frag->page.p,
					      frag->page_offset + frag_offset,
					      frag->size - frag_offset,
					      MSG_DONTWAIT);
			if (ret <= 0) {
				if (ret == -EAGAIN) {
					/* Save state to try again when there's
					 * write space on the socket
					 */
					txm->sent = sent;
					txm->frag_offset = frag_offset;
					txm->fragidx = fragidx;
					txm->frag_skb = skb;

					ret = 0;
					goto out;
				}

				/* Hard failure in sending message, abort this
				 * psock since it has lost framing
				 * synchonization and retry sending the
				 * message from the beginning.
				 */
				kcm_abort_tx_psock(psock, ret ? -ret : EPIPE,
						   true);
				unreserve_psock(kcm);

				txm->sent = 0;
				kcm_report_tx_retry(kcm);
				ret = 0;

				goto try_again;
			}

			sent += ret;
			frag_offset += ret;
			KCM_STATS_ADD(psock->stats.tx_bytes, ret);
			if (frag_offset < frag->size) {
				/* Not finished with this frag */
				goto do_frag;
			}
		}

		if (skb == head) {
			if (skb_has_frag_list(skb)) {
				skb = skb_shinfo(skb)->frag_list;
				goto do_frag_list;
			}
		} else if (skb->next) {
			skb = skb->next;
			goto do_frag_list;
		}

		/* Successfully sent the whole packet, account for it. */
		skb_dequeue(&sk->sk_write_queue);
		kfree_skb(head);
		sk->sk_wmem_queued -= sent;
		total_sent += sent;
		KCM_STATS_INCR(psock->stats.tx_msgs);
	} while ((head = skb_peek(&sk->sk_write_queue)));
out:
	if (!head) {
		/* Done with all queued messages. */
		WARN_ON(!skb_queue_empty(&sk->sk_write_queue));
		unreserve_psock(kcm);
	}

	/* Check if write space is available */
	sk->sk_write_space(sk);

	return total_sent ? : ret;
}

static void kcm_tx_work(struct work_struct *w)
{
	struct kcm_sock *kcm = container_of(w, struct kcm_sock, tx_work);
	struct sock *sk = &kcm->sk;
	int err;

	lock_sock(sk);

	/* Primarily for SOCK_DGRAM sockets, also handle asynchronous tx
	 * aborts
	 */
	err = kcm_write_msgs(kcm);
	if (err < 0) {
		/* Hard failure in write, report error on KCM socket */
		pr_warn("KCM: Hard failure on kcm_write_msgs %d\n", err);
		report_csk_error(&kcm->sk, -err);
		goto out;
	}

	/* Primarily for SOCK_SEQPACKET sockets */
	if (likely(sk->sk_socket) &&
	    test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) {
		clear_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
		sk->sk_write_space(sk);
	}

out:
	release_sock(sk);
}

static void kcm_push(struct kcm_sock *kcm)
{
	if (kcm->tx_wait_more)
		kcm_write_msgs(kcm);
}

static ssize_t kcm_sendpage(struct socket *sock, struct page *page,
			    int offset, size_t size, int flags)

{
	struct sock *sk = sock->sk;
	struct kcm_sock *kcm = kcm_sk(sk);
	struct sk_buff *skb = NULL, *head = NULL;
	long timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT);
	bool eor;
	int err = 0;
	int i;

	if (flags & MSG_SENDPAGE_NOTLAST)
		flags |= MSG_MORE;

	/* No MSG_EOR from splice, only look at MSG_MORE */
	eor = !(flags & MSG_MORE);

	lock_sock(sk);

	sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk);

	err = -EPIPE;
	if (sk->sk_err)
		goto out_error;

	if (kcm->seq_skb) {
		/* Previously opened message */
		head = kcm->seq_skb;
		skb = kcm_tx_msg(head)->last_skb;
		i = skb_shinfo(skb)->nr_frags;

		if (skb_can_coalesce(skb, i, page, offset)) {
			skb_frag_size_add(&skb_shinfo(skb)->frags[i - 1], size);
			skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG;
			goto coalesced;
		}

		if (i >= MAX_SKB_FRAGS) {
			struct sk_buff *tskb;

			tskb = alloc_skb(0, sk->sk_allocation);
			while (!tskb) {
				kcm_push(kcm);
				err = sk_stream_wait_memory(sk, &timeo);
				if (err)
					goto out_error;
			}

			if (head == skb)
				skb_shinfo(head)->frag_list = tskb;
			else
				skb->next = tskb;

			skb = tskb;
			skb->ip_summed = CHECKSUM_UNNECESSARY;
			i = 0;
		}
	} else {
		/* Call the sk_stream functions to manage the sndbuf mem. */
		if (!sk_stream_memory_free(sk)) {
			kcm_push(kcm);
			set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
			err = sk_stream_wait_memory(sk, &timeo);
			if (err)
				goto out_error;
		}

		head = alloc_skb(0, sk->sk_allocation);
		while (!head) {
			kcm_push(kcm);
			err = sk_stream_wait_memory(sk, &timeo);
			if (err)
				goto out_error;
		}

		skb = head;
		i = 0;
	}

	get_page(page);
	skb_fill_page_desc(skb, i, page, offset, size);
	skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG;

coalesced:
	skb->len += size;
	skb->data_len += size;
	skb->truesize += size;
	sk->sk_wmem_queued += size;
	sk_mem_charge(sk, size);

	if (head != skb) {
		head->len += size;
		head->data_len += size;
		head->truesize += size;
	}

	if (eor) {
		bool not_busy = skb_queue_empty(&sk->sk_write_queue);

		/* Message complete, queue it on send buffer */
		__skb_queue_tail(&sk->sk_write_queue, head);
		kcm->seq_skb = NULL;
		KCM_STATS_INCR(kcm->stats.tx_msgs);

		if (flags & MSG_BATCH) {
			kcm->tx_wait_more = true;
		} else if (kcm->tx_wait_more || not_busy) {
			err = kcm_write_msgs(kcm);
			if (err < 0) {
				/* We got a hard error in write_msgs but have
				 * already queued this message. Report an error
				 * in the socket, but don't affect return value
				 * from sendmsg
				 */
				pr_warn("KCM: Hard failure on kcm_write_msgs\n");
				report_csk_error(&kcm->sk, -err);
			}
		}
	} else {
		/* Message not complete, save state */
		kcm->seq_skb = head;
		kcm_tx_msg(head)->last_skb = skb;
	}

	KCM_STATS_ADD(kcm->stats.tx_bytes, size);

	release_sock(sk);
	return size;

out_error:
	kcm_push(kcm);

	err = sk_stream_error(sk, flags, err);

	/* make sure we wake any epoll edge trigger waiter */
	if (unlikely(skb_queue_len(&sk->sk_write_queue) == 0 && err == -EAGAIN))
		sk->sk_write_space(sk);

	release_sock(sk);
	return err;
}

static int kcm_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
{
	struct sock *sk = sock->sk;
	struct kcm_sock *kcm = kcm_sk(sk);
	struct sk_buff *skb = NULL, *head = NULL;
	size_t copy, copied = 0;
	long timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
	int eor = (sock->type == SOCK_DGRAM) ?
		  !(msg->msg_flags & MSG_MORE) : !!(msg->msg_flags & MSG_EOR);
	int err = -EPIPE;

	lock_sock(sk);

	/* Per tcp_sendmsg this should be in poll */
	sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk);

	if (sk->sk_err)
		goto out_error;

	if (kcm->seq_skb) {
		/* Previously opened message */
		head = kcm->seq_skb;
		skb = kcm_tx_msg(head)->last_skb;
		goto start;
	}

	/* Call the sk_stream functions to manage the sndbuf mem. */
	if (!sk_stream_memory_free(sk)) {
		kcm_push(kcm);
		set_bit(SOCK_NOSPACE, &sk->sk_socket->flags);
		err = sk_stream_wait_memory(sk, &timeo);
		if (err)
			goto out_error;
	}

	/* New message, alloc head skb */
	head = alloc_skb(0, sk->sk_allocation);
	while (!head) {
		kcm_push(kcm);
		err = sk_stream_wait_memory(sk, &timeo);
		if (err)
			goto out_error;

		head = alloc_skb(0, sk->sk_allocation);
	}

	skb = head;

	/* Set ip_summed to CHECKSUM_UNNECESSARY to avoid calling
	 * csum_and_copy_from_iter from skb_do_copy_data_nocache.
	 */
	skb->ip_summed = CHECKSUM_UNNECESSARY;

start:
	while (msg_data_left(msg)) {
		bool merge = true;
		int i = skb_shinfo(skb)->nr_frags;
		struct page_frag *pfrag = sk_page_frag(sk);

		if (!sk_page_frag_refill(sk, pfrag))
			goto wait_for_memory;

		if (!skb_can_coalesce(skb, i, pfrag->page,
				      pfrag->offset)) {
			if (i == MAX_SKB_FRAGS) {
				struct sk_buff *tskb;

				tskb = alloc_skb(0, sk->sk_allocation);
				if (!tskb)
					goto wait_for_memory;

				if (head == skb)
					skb_shinfo(head)->frag_list = tskb;
				else
					skb->next = tskb;

				skb = tskb;
				skb->ip_summed = CHECKSUM_UNNECESSARY;
				continue;
			}
			merge = false;
		}

		copy = min_t(int, msg_data_left(msg),
			     pfrag->size - pfrag->offset);

		if (!sk_wmem_schedule(sk, copy))
			goto wait_for_memory;

		err = skb_copy_to_page_nocache(sk, &msg->msg_iter, skb,
					       pfrag->page,
					       pfrag->offset,
					       copy);
		if (err)
			goto out_error;

		/* Update the skb. */
		if (merge) {
			skb_frag_size_add(&skb_shinfo(skb)->frags[i - 1], copy);
		} else {
			skb_fill_page_desc(skb, i, pfrag->page,
					   pfrag->offset, copy);
			get_page(pfrag->page);
		}

		pfrag->offset += copy;
		copied += copy;
		if (head != skb) {
			head->len += copy;
			head->data_len += copy;
		}

		continue;

wait_for_memory:
		kcm_push(kcm);
		err = sk_stream_wait_memory(sk, &timeo);
		if (err)
			goto out_error;
	}

	if (eor) {
		bool not_busy = skb_queue_empty(&sk->sk_write_queue);

		/* Message complete, queue it on send buffer */
		__skb_queue_tail(&sk->sk_write_queue, head);
		kcm->seq_skb = NULL;
		KCM_STATS_INCR(kcm->stats.tx_msgs);

		if (msg->msg_flags & MSG_BATCH) {
			kcm->tx_wait_more = true;
		} else if (kcm->tx_wait_more || not_busy) {
			err = kcm_write_msgs(kcm);
			if (err < 0) {
				/* We got a hard error in write_msgs but have
				 * already queued this message. Report an error
				 * in the socket, but don't affect return value
				 * from sendmsg
				 */
				pr_warn("KCM: Hard failure on kcm_write_msgs\n");
				report_csk_error(&kcm->sk, -err);
			}
		}
	} else {
		/* Message not complete, save state */
partial_message:
		kcm->seq_skb = head;
		kcm_tx_msg(head)->last_skb = skb;
	}

	KCM_STATS_ADD(kcm->stats.tx_bytes, copied);

	release_sock(sk);
	return copied;

out_error:
	kcm_push(kcm);

	if (copied && sock->type == SOCK_SEQPACKET) {
		/* Wrote some bytes before encountering an
		 * error, return partial success.
		 */
		goto partial_message;
	}

	if (head != kcm->seq_skb)
		kfree_skb(head);

	err = sk_stream_error(sk, msg->msg_flags, err);

	/* make sure we wake any epoll edge trigger waiter */
	if (unlikely(skb_queue_len(&sk->sk_write_queue) == 0 && err == -EAGAIN))
		sk->sk_write_space(sk);

	release_sock(sk);
	return err;
}

static struct sk_buff *kcm_wait_data(struct sock *sk, int flags,
				     long timeo, int *err)
{
	struct sk_buff *skb;

	while (!(skb = skb_peek(&sk->sk_receive_queue))) {
		if (sk->sk_err) {
			*err = sock_error(sk);
			return NULL;
		}

		if (sock_flag(sk, SOCK_DONE))
			return NULL;

		if ((flags & MSG_DONTWAIT) || !timeo) {
			*err = -EAGAIN;
			return NULL;
		}

		sk_wait_data(sk, &timeo, NULL);

		/* Handle signals */
		if (signal_pending(current)) {
			*err = sock_intr_errno(timeo);
			return NULL;
		}
	}

	return skb;
}

static int kcm_recvmsg(struct socket *sock, struct msghdr *msg,
		       size_t len, int flags)
{
	struct sock *sk = sock->sk;
	struct kcm_sock *kcm = kcm_sk(sk);
	int err = 0;
	long timeo;
	struct kcm_rx_msg *rxm;
	int copied = 0;
	struct sk_buff *skb;

	timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);

	lock_sock(sk);

	skb = kcm_wait_data(sk, flags, timeo, &err);
	if (!skb)
		goto out;

	/* Okay, have a message on the receive queue */

	rxm = kcm_rx_msg(skb);

	if (len > rxm->full_len)
		len = rxm->full_len;

	err = skb_copy_datagram_msg(skb, rxm->offset, msg, len);
	if (err < 0)
		goto out;

	copied = len;
	if (likely(!(flags & MSG_PEEK))) {
		KCM_STATS_ADD(kcm->stats.rx_bytes, copied);
		if (copied < rxm->full_len) {
			if (sock->type == SOCK_DGRAM) {
				/* Truncated message */
				msg->msg_flags |= MSG_TRUNC;
				goto msg_finished;
			}
			rxm->offset += copied;
			rxm->full_len -= copied;
		} else {
msg_finished:
			/* Finished with message */
			msg->msg_flags |= MSG_EOR;
			KCM_STATS_INCR(kcm->stats.rx_msgs);
			skb_unlink(skb, &sk->sk_receive_queue);
			kfree_skb(skb);
		}
	}

out:
	release_sock(sk);

	return copied ? : err;
}

static ssize_t kcm_sock_splice(struct sock *sk,
			       struct pipe_inode_info *pipe,
			       struct splice_pipe_desc *spd)
{
	int ret;

	release_sock(sk);
	ret = splice_to_pipe(pipe, spd);
	lock_sock(sk);

	return ret;
}

static ssize_t kcm_splice_read(struct socket *sock, loff_t *ppos,
			       struct pipe_inode_info *pipe, size_t len,
			       unsigned int flags)
{
	struct sock *sk = sock->sk;
	struct kcm_sock *kcm = kcm_sk(sk);
	long timeo;
	struct kcm_rx_msg *rxm;
	int err = 0;
	ssize_t copied;
	struct sk_buff *skb;

	/* Only support splice for SOCKSEQPACKET */

	timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);

	lock_sock(sk);

	skb = kcm_wait_data(sk, flags, timeo, &err);
	if (!skb)
		goto err_out;

	/* Okay, have a message on the receive queue */

	rxm = kcm_rx_msg(skb);

	if (len > rxm->full_len)
		len = rxm->full_len;

	copied = skb_splice_bits(skb, sk, rxm->offset, pipe, len, flags,
				 kcm_sock_splice);
	if (copied < 0) {
		err = copied;
		goto err_out;
	}

	KCM_STATS_ADD(kcm->stats.rx_bytes, copied);

	rxm->offset += copied;
	rxm->full_len -= copied;

	/* We have no way to return MSG_EOR. If all the bytes have been
	 * read we still leave the message in the receive socket buffer.
	 * A subsequent recvmsg needs to be done to return MSG_EOR and
	 * finish reading the message.
	 */

	release_sock(sk);

	return copied;

err_out:
	release_sock(sk);

	return err;
}

/* kcm sock lock held */
static void kcm_recv_disable(struct kcm_sock *kcm)
{
	struct kcm_mux *mux = kcm->mux;

	if (kcm->rx_disabled)
		return;

	spin_lock_bh(&mux->rx_lock);

	kcm->rx_disabled = 1;

	/* If a psock is reserved we'll do cleanup in unreserve */
	if (!kcm->rx_psock) {
		if (kcm->rx_wait) {
			list_del(&kcm->wait_rx_list);
			kcm->rx_wait = false;
		}

		requeue_rx_msgs(mux, &kcm->sk.sk_receive_queue);
	}

	spin_unlock_bh(&mux->rx_lock);
}

/* kcm sock lock held */
static void kcm_recv_enable(struct kcm_sock *kcm)
{
	struct kcm_mux *mux = kcm->mux;

	if (!kcm->rx_disabled)
		return;

	spin_lock_bh(&mux->rx_lock);

	kcm->rx_disabled = 0;
	kcm_rcv_ready(kcm);

	spin_unlock_bh(&mux->rx_lock);
}

static int kcm_setsockopt(struct socket *sock, int level, int optname,
			  char __user *optval, unsigned int optlen)
{
	struct kcm_sock *kcm = kcm_sk(sock->sk);
	int val, valbool;
	int err = 0;

	if (level != SOL_KCM)
		return -ENOPROTOOPT;

	if (optlen < sizeof(int))
		return -EINVAL;

	if (get_user(val, (int __user *)optval))
		return -EINVAL;

	valbool = val ? 1 : 0;

	switch (optname) {
	case KCM_RECV_DISABLE:
		lock_sock(&kcm->sk);
		if (valbool)
			kcm_recv_disable(kcm);
		else
			kcm_recv_enable(kcm);
		release_sock(&kcm->sk);
		break;
	default:
		err = -ENOPROTOOPT;
	}

	return err;
}

static int kcm_getsockopt(struct socket *sock, int level, int optname,
			  char __user *optval, int __user *optlen)
{
	struct kcm_sock *kcm = kcm_sk(sock->sk);
	int val, len;

	if (level != SOL_KCM)
		return -ENOPROTOOPT;

	if (get_user(len, optlen))
		return -EFAULT;

	len = min_t(unsigned int, len, sizeof(int));
	if (len < 0)
		return -EINVAL;

	switch (optname) {
	case KCM_RECV_DISABLE:
		val = kcm->rx_disabled;
		break;
	default:
		return -ENOPROTOOPT;
	}

	if (put_user(len, optlen))
		return -EFAULT;
	if (copy_to_user(optval, &val, len))
		return -EFAULT;
	return 0;
}

static void init_kcm_sock(struct kcm_sock *kcm, struct kcm_mux *mux)
{
	struct kcm_sock *tkcm;
	struct list_head *head;
	int index = 0;

	/* For SOCK_SEQPACKET sock type, datagram_poll checks the sk_state, so
	 * we set sk_state, otherwise epoll_wait always returns right away with
	 * POLLHUP
	 */
	kcm->sk.sk_state = TCP_ESTABLISHED;

	/* Add to mux's kcm sockets list */
	kcm->mux = mux;
	spin_lock_bh(&mux->lock);

	head = &mux->kcm_socks;
	list_for_each_entry(tkcm, &mux->kcm_socks, kcm_sock_list) {
		if (tkcm->index != index)
			break;
		head = &tkcm->kcm_sock_list;
		index++;
	}

	list_add(&kcm->kcm_sock_list, head);
	kcm->index = index;

	mux->kcm_socks_cnt++;
	spin_unlock_bh(&mux->lock);

	INIT_WORK(&kcm->tx_work, kcm_tx_work);

	spin_lock_bh(&mux->rx_lock);
	kcm_rcv_ready(kcm);
	spin_unlock_bh(&mux->rx_lock);
}

static void kcm_rx_msg_timeout(unsigned long arg)
{
	struct kcm_psock *psock = (struct kcm_psock *)arg;

	/* Message assembly timed out */
	KCM_STATS_INCR(psock->stats.rx_msg_timeouts);
	kcm_abort_rx_psock(psock, ETIMEDOUT, NULL);
}

static int kcm_attach(struct socket *sock, struct socket *csock,
		      struct bpf_prog *prog)
{
	struct kcm_sock *kcm = kcm_sk(sock->sk);
	struct kcm_mux *mux = kcm->mux;
	struct sock *csk;
	struct kcm_psock *psock = NULL, *tpsock;
	struct list_head *head;
	int index = 0;

	if (csock->ops->family != PF_INET &&
	    csock->ops->family != PF_INET6)
		return -EINVAL;

	csk = csock->sk;
	if (!csk)
		return -EINVAL;

	/* Only support TCP for now */
	if (csk->sk_protocol != IPPROTO_TCP)
		return -EINVAL;

	psock = kmem_cache_zalloc(kcm_psockp, GFP_KERNEL);
	if (!psock)
		return -ENOMEM;

	psock->mux = mux;
	psock->sk = csk;
	psock->bpf_prog = prog;

	setup_timer(&psock->rx_msg_timer, kcm_rx_msg_timeout,
		    (unsigned long)psock);

	INIT_WORK(&psock->rx_work, psock_rx_work);
	INIT_DELAYED_WORK(&psock->rx_delayed_work, psock_rx_delayed_work);

	sock_hold(csk);

	write_lock_bh(&csk->sk_callback_lock);
	psock->save_data_ready = csk->sk_data_ready;
	psock->save_write_space = csk->sk_write_space;
	psock->save_state_change = csk->sk_state_change;
	csk->sk_user_data = psock;
	csk->sk_data_ready = psock_tcp_data_ready;
	csk->sk_write_space = psock_tcp_write_space;
	csk->sk_state_change = psock_tcp_state_change;
	write_unlock_bh(&csk->sk_callback_lock);

	/* Finished initialization, now add the psock to the MUX. */
	spin_lock_bh(&mux->lock);
	head = &mux->psocks;
	list_for_each_entry(tpsock, &mux->psocks, psock_list) {
		if (tpsock->index != index)
			break;
		head = &tpsock->psock_list;
		index++;
	}

	list_add(&psock->psock_list, head);
	psock->index = index;

	KCM_STATS_INCR(mux->stats.psock_attach);
	mux->psocks_cnt++;
	psock_now_avail(psock);
	spin_unlock_bh(&mux->lock);

	/* Schedule RX work in case there are already bytes queued */
	queue_work(kcm_wq, &psock->rx_work);

	return 0;
}

static int kcm_attach_ioctl(struct socket *sock, struct kcm_attach *info)
{
	struct socket *csock;
	struct bpf_prog *prog;
	int err;

	csock = sockfd_lookup(info->fd, &err);
	if (!csock)
		return -ENOENT;

	prog = bpf_prog_get_type(info->bpf_fd, BPF_PROG_TYPE_SOCKET_FILTER);
	if (IS_ERR(prog)) {
		err = PTR_ERR(prog);
		goto out;
	}

	err = kcm_attach(sock, csock, prog);
	if (err) {
		bpf_prog_put(prog);
		goto out;
	}

	/* Keep reference on file also */

	return 0;
out:
	fput(csock->file);
	return err;
}

static void kcm_unattach(struct kcm_psock *psock)
{
	struct sock *csk = psock->sk;
	struct kcm_mux *mux = psock->mux;

	/* Stop getting callbacks from TCP socket. After this there should
	 * be no way to reserve a kcm for this psock.
	 */
	write_lock_bh(&csk->sk_callback_lock);
	csk->sk_user_data = NULL;
	csk->sk_data_ready = psock->save_data_ready;
	csk->sk_write_space = psock->save_write_space;
	csk->sk_state_change = psock->save_state_change;
	psock->rx_stopped = 1;

	if (WARN_ON(psock->rx_kcm)) {
		write_unlock_bh(&csk->sk_callback_lock);
		return;
	}

	spin_lock_bh(&mux->rx_lock);

	/* Stop receiver activities. After this point psock should not be
	 * able to get onto ready list either through callbacks or work.
	 */
	if (psock->ready_rx_msg) {
		list_del(&psock->psock_ready_list);
		kfree_skb(psock->ready_rx_msg);
		psock->ready_rx_msg = NULL;
		KCM_STATS_INCR(mux->stats.rx_ready_drops);
	}

	spin_unlock_bh(&mux->rx_lock);

	write_unlock_bh(&csk->sk_callback_lock);

	del_timer_sync(&psock->rx_msg_timer);
	cancel_work_sync(&psock->rx_work);
	cancel_delayed_work_sync(&psock->rx_delayed_work);

	bpf_prog_put(psock->bpf_prog);

	kfree_skb(psock->rx_skb_head);
	psock->rx_skb_head = NULL;

	spin_lock_bh(&mux->lock);

	aggregate_psock_stats(&psock->stats, &mux->aggregate_psock_stats);

	KCM_STATS_INCR(mux->stats.psock_unattach);

	if (psock->tx_kcm) {
		/* psock was reserved.  Just mark it finished and we will clean
		 * up in the kcm paths, we need kcm lock which can not be
		 * acquired here.
		 */
		KCM_STATS_INCR(mux->stats.psock_unattach_rsvd);
		spin_unlock_bh(&mux->lock);

		/* We are unattaching a socket that is reserved. Abort the
		 * socket since we may be out of sync in sending on it. We need
		 * to do this without the mux lock.
		 */
		kcm_abort_tx_psock(psock, EPIPE, false);

		spin_lock_bh(&mux->lock);
		if (!psock->tx_kcm) {
			/* psock now unreserved in window mux was unlocked */
			goto no_reserved;
		}
		psock->done = 1;

		/* Commit done before queuing work to process it */
		smp_mb();

		/* Queue tx work to make sure psock->done is handled */
		queue_work(kcm_wq, &psock->tx_kcm->tx_work);
		spin_unlock_bh(&mux->lock);
	} else {
no_reserved:
		if (!psock->tx_stopped)
			list_del(&psock->psock_avail_list);
		list_del(&psock->psock_list);
		mux->psocks_cnt--;
		spin_unlock_bh(&mux->lock);

		sock_put(csk);
		fput(csk->sk_socket->file);
		kmem_cache_free(kcm_psockp, psock);
	}
}

static int kcm_unattach_ioctl(struct socket *sock, struct kcm_unattach *info)
{
	struct kcm_sock *kcm = kcm_sk(sock->sk);
	struct kcm_mux *mux = kcm->mux;
	struct kcm_psock *psock;
	struct socket *csock;
	struct sock *csk;
	int err;

	csock = sockfd_lookup(info->fd, &err);
	if (!csock)
		return -ENOENT;

	csk = csock->sk;
	if (!csk) {
		err = -EINVAL;
		goto out;
	}

	err = -ENOENT;

	spin_lock_bh(&mux->lock);

	list_for_each_entry(psock, &mux->psocks, psock_list) {
		if (psock->sk != csk)
			continue;

		/* Found the matching psock */

		if (psock->unattaching || WARN_ON(psock->done)) {
			err = -EALREADY;
			break;
		}

		psock->unattaching = 1;

		spin_unlock_bh(&mux->lock);

		kcm_unattach(psock);

		err = 0;
		goto out;
	}

	spin_unlock_bh(&mux->lock);

out:
	fput(csock->file);
	return err;
}

static struct proto kcm_proto = {
	.name	= "KCM",
	.owner	= THIS_MODULE,
	.obj_size = sizeof(struct kcm_sock),
};

/* Clone a kcm socket. */
static int kcm_clone(struct socket *osock, struct kcm_clone *info,
		     struct socket **newsockp)
{
	struct socket *newsock;
	struct sock *newsk;
	struct file *newfile;
	int err, newfd;

	err = -ENFILE;
	newsock = sock_alloc();
	if (!newsock)
		goto out;

	newsock->type = osock->type;
	newsock->ops = osock->ops;

	__module_get(newsock->ops->owner);

	newfd = get_unused_fd_flags(0);
	if (unlikely(newfd < 0)) {
		err = newfd;
		goto out_fd_fail;
	}

	newfile = sock_alloc_file(newsock, 0, osock->sk->sk_prot_creator->name);
	if (unlikely(IS_ERR(newfile))) {
		err = PTR_ERR(newfile);
		goto out_sock_alloc_fail;
	}

	newsk = sk_alloc(sock_net(osock->sk), PF_KCM, GFP_KERNEL,
			 &kcm_proto, true);
	if (!newsk) {
		err = -ENOMEM;
		goto out_sk_alloc_fail;
	}

	sock_init_data(newsock, newsk);
	init_kcm_sock(kcm_sk(newsk), kcm_sk(osock->sk)->mux);

	fd_install(newfd, newfile);
	*newsockp = newsock;
	info->fd = newfd;

	return 0;

out_sk_alloc_fail:
	fput(newfile);
out_sock_alloc_fail:
	put_unused_fd(newfd);
out_fd_fail:
	sock_release(newsock);
out:
	return err;
}

static int kcm_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{
	int err;

	switch (cmd) {
	case SIOCKCMATTACH: {
		struct kcm_attach info;

		if (copy_from_user(&info, (void __user *)arg, sizeof(info)))
			err = -EFAULT;

		err = kcm_attach_ioctl(sock, &info);

		break;
	}
	case SIOCKCMUNATTACH: {
		struct kcm_unattach info;

		if (copy_from_user(&info, (void __user *)arg, sizeof(info)))
			err = -EFAULT;

		err = kcm_unattach_ioctl(sock, &info);

		break;
	}
	case SIOCKCMCLONE: {
		struct kcm_clone info;
		struct socket *newsock = NULL;

		if (copy_from_user(&info, (void __user *)arg, sizeof(info)))
			err = -EFAULT;

		err = kcm_clone(sock, &info, &newsock);

		if (!err) {
			if (copy_to_user((void __user *)arg, &info,
					 sizeof(info))) {
				err = -EFAULT;
				sys_close(info.fd);
			}
		}

		break;
	}
	default:
		err = -ENOIOCTLCMD;
		break;
	}

	return err;
}

static void free_mux(struct rcu_head *rcu)
{
	struct kcm_mux *mux = container_of(rcu,
	    struct kcm_mux, rcu);

	kmem_cache_free(kcm_muxp, mux);
}

static void release_mux(struct kcm_mux *mux)
{
	struct kcm_net *knet = mux->knet;
	struct kcm_psock *psock, *tmp_psock;

	/* Release psocks */
	list_for_each_entry_safe(psock, tmp_psock,
				 &mux->psocks, psock_list) {
		if (!WARN_ON(psock->unattaching))
			kcm_unattach(psock);
	}

	if (WARN_ON(mux->psocks_cnt))
		return;

	__skb_queue_purge(&mux->rx_hold_queue);

	mutex_lock(&knet->mutex);
	aggregate_mux_stats(&mux->stats, &knet->aggregate_mux_stats);
	aggregate_psock_stats(&mux->aggregate_psock_stats,
			      &knet->aggregate_psock_stats);
	list_del_rcu(&mux->kcm_mux_list);
	knet->count--;
	mutex_unlock(&knet->mutex);

	call_rcu(&mux->rcu, free_mux);
}

static void kcm_done(struct kcm_sock *kcm)
{
	struct kcm_mux *mux = kcm->mux;
	struct sock *sk = &kcm->sk;
	int socks_cnt;

	spin_lock_bh(&mux->rx_lock);
	if (kcm->rx_psock) {
		/* Cleanup in unreserve_rx_kcm */
		WARN_ON(kcm->done);
		kcm->rx_disabled = 1;
		kcm->done = 1;
		spin_unlock_bh(&mux->rx_lock);
		return;
	}

	if (kcm->rx_wait) {
		list_del(&kcm->wait_rx_list);
		kcm->rx_wait = false;
	}
	/* Move any pending receive messages to other kcm sockets */
	requeue_rx_msgs(mux, &sk->sk_receive_queue);

	spin_unlock_bh(&mux->rx_lock);

	if (WARN_ON(sk_rmem_alloc_get(sk)))
		return;

	/* Detach from MUX */
	spin_lock_bh(&mux->lock);

	list_del(&kcm->kcm_sock_list);
	mux->kcm_socks_cnt--;
	socks_cnt = mux->kcm_socks_cnt;

	spin_unlock_bh(&mux->lock);

	if (!socks_cnt) {
		/* We are done with the mux now. */
		release_mux(mux);
	}

	WARN_ON(kcm->rx_wait);

	sock_put(&kcm->sk);
}

/* Called by kcm_release to close a KCM socket.
 * If this is the last KCM socket on the MUX, destroy the MUX.
 */
static int kcm_release(struct socket *sock)
{
	struct sock *sk = sock->sk;
	struct kcm_sock *kcm;
	struct kcm_mux *mux;
	struct kcm_psock *psock;

	if (!sk)
		return 0;

	kcm = kcm_sk(sk);
	mux = kcm->mux;

	sock_orphan(sk);
	kfree_skb(kcm->seq_skb);

	lock_sock(sk);
	/* Purge queue under lock to avoid race condition with tx_work trying
	 * to act when queue is nonempty. If tx_work runs after this point
	 * it will just return.
	 */
	__skb_queue_purge(&sk->sk_write_queue);
	release_sock(sk);

	spin_lock_bh(&mux->lock);
	if (kcm->tx_wait) {
		/* Take of tx_wait list, after this point there should be no way
		 * that a psock will be assigned to this kcm.
		 */
		list_del(&kcm->wait_psock_list);
		kcm->tx_wait = false;
	}
	spin_unlock_bh(&mux->lock);

	/* Cancel work. After this point there should be no outside references
	 * to the kcm socket.
	 */
	cancel_work_sync(&kcm->tx_work);

	lock_sock(sk);
	psock = kcm->tx_psock;
	if (psock) {
		/* A psock was reserved, so we need to kill it since it
		 * may already have some bytes queued from a message. We
		 * need to do this after removing kcm from tx_wait list.
		 */
		kcm_abort_tx_psock(psock, EPIPE, false);
		unreserve_psock(kcm);
	}
	release_sock(sk);

	WARN_ON(kcm->tx_wait);
	WARN_ON(kcm->tx_psock);

	sock->sk = NULL;

	kcm_done(kcm);

	return 0;
}

static const struct proto_ops kcm_dgram_ops = {
	.family =	PF_KCM,
	.owner =	THIS_MODULE,
	.release =	kcm_release,
	.bind =		sock_no_bind,
	.connect =	sock_no_connect,
	.socketpair =	sock_no_socketpair,
	.accept =	sock_no_accept,
	.getname =	sock_no_getname,
	.poll =		datagram_poll,
	.ioctl =	kcm_ioctl,
	.listen =	sock_no_listen,
	.shutdown =	sock_no_shutdown,
	.setsockopt =	kcm_setsockopt,
	.getsockopt =	kcm_getsockopt,
	.sendmsg =	kcm_sendmsg,
	.recvmsg =	kcm_recvmsg,
	.mmap =		sock_no_mmap,
	.sendpage =	kcm_sendpage,
};

static const struct proto_ops kcm_seqpacket_ops = {
	.family =	PF_KCM,
	.owner =	THIS_MODULE,
	.release =	kcm_release,
	.bind =		sock_no_bind,
	.connect =	sock_no_connect,
	.socketpair =	sock_no_socketpair,
	.accept =	sock_no_accept,
	.getname =	sock_no_getname,
	.poll =		datagram_poll,
	.ioctl =	kcm_ioctl,
	.listen =	sock_no_listen,
	.shutdown =	sock_no_shutdown,
	.setsockopt =	kcm_setsockopt,
	.getsockopt =	kcm_getsockopt,
	.sendmsg =	kcm_sendmsg,
	.recvmsg =	kcm_recvmsg,
	.mmap =		sock_no_mmap,
	.sendpage =	kcm_sendpage,
	.splice_read =	kcm_splice_read,
};

/* Create proto operation for kcm sockets */
static int kcm_create(struct net *net, struct socket *sock,
		      int protocol, int kern)
{
	struct kcm_net *knet = net_generic(net, kcm_net_id);
	struct sock *sk;
	struct kcm_mux *mux;

	switch (sock->type) {
	case SOCK_DGRAM:
		sock->ops = &kcm_dgram_ops;
		break;
	case SOCK_SEQPACKET:
		sock->ops = &kcm_seqpacket_ops;
		break;
	default:
		return -ESOCKTNOSUPPORT;
	}

	if (protocol != KCMPROTO_CONNECTED)
		return -EPROTONOSUPPORT;

	sk = sk_alloc(net, PF_KCM, GFP_KERNEL, &kcm_proto, kern);
	if (!sk)
		return -ENOMEM;

	/* Allocate a kcm mux, shared between KCM sockets */
	mux = kmem_cache_zalloc(kcm_muxp, GFP_KERNEL);
	if (!mux) {
		sk_free(sk);
		return -ENOMEM;
	}

	spin_lock_init(&mux->lock);
	spin_lock_init(&mux->rx_lock);
	INIT_LIST_HEAD(&mux->kcm_socks);
	INIT_LIST_HEAD(&mux->kcm_rx_waiters);
	INIT_LIST_HEAD(&mux->kcm_tx_waiters);

	INIT_LIST_HEAD(&mux->psocks);
	INIT_LIST_HEAD(&mux->psocks_ready);
	INIT_LIST_HEAD(&mux->psocks_avail);

	mux->knet = knet;

	/* Add new MUX to list */
	mutex_lock(&knet->mutex);
	list_add_rcu(&mux->kcm_mux_list, &knet->mux_list);
	knet->count++;
	mutex_unlock(&knet->mutex);

	skb_queue_head_init(&mux->rx_hold_queue);

	/* Init KCM socket */
	sock_init_data(sock, sk);
	init_kcm_sock(kcm_sk(sk), mux);

	return 0;
}

static struct net_proto_family kcm_family_ops = {
	.family = PF_KCM,
	.create = kcm_create,
	.owner  = THIS_MODULE,
};

static __net_init int kcm_init_net(struct net *net)
{
	struct kcm_net *knet = net_generic(net, kcm_net_id);

	INIT_LIST_HEAD_RCU(&knet->mux_list);
	mutex_init(&knet->mutex);

	return 0;
}

static __net_exit void kcm_exit_net(struct net *net)
{
	struct kcm_net *knet = net_generic(net, kcm_net_id);

	/* All KCM sockets should be closed at this point, which should mean
	 * that all multiplexors and psocks have been destroyed.
	 */
	WARN_ON(!list_empty(&knet->mux_list));
}

static struct pernet_operations kcm_net_ops = {
	.init = kcm_init_net,
	.exit = kcm_exit_net,
	.id   = &kcm_net_id,
	.size = sizeof(struct kcm_net),
};

static int __init kcm_init(void)
{
	int err = -ENOMEM;

	kcm_muxp = kmem_cache_create("kcm_mux_cache",
				     sizeof(struct kcm_mux), 0,
				     SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL);
	if (!kcm_muxp)
		goto fail;

	kcm_psockp = kmem_cache_create("kcm_psock_cache",
				       sizeof(struct kcm_psock), 0,
					SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL);
	if (!kcm_psockp)
		goto fail;

	kcm_wq = create_singlethread_workqueue("kkcmd");
	if (!kcm_wq)
		goto fail;

	err = proto_register(&kcm_proto, 1);
	if (err)
		goto fail;

	err = sock_register(&kcm_family_ops);
	if (err)
		goto sock_register_fail;

	err = register_pernet_device(&kcm_net_ops);
	if (err)
		goto net_ops_fail;

	err = kcm_proc_init();
	if (err)
		goto proc_init_fail;

	return 0;

proc_init_fail:
	unregister_pernet_device(&kcm_net_ops);

net_ops_fail:
	sock_unregister(PF_KCM);

sock_register_fail:
	proto_unregister(&kcm_proto);

fail:
	kmem_cache_destroy(kcm_muxp);
	kmem_cache_destroy(kcm_psockp);

	if (kcm_wq)
		destroy_workqueue(kcm_wq);

	return err;
}

static void __exit kcm_exit(void)
{
	kcm_proc_exit();
	unregister_pernet_device(&kcm_net_ops);
	sock_unregister(PF_KCM);
	proto_unregister(&kcm_proto);
	destroy_workqueue(kcm_wq);

	kmem_cache_destroy(kcm_muxp);
	kmem_cache_destroy(kcm_psockp);
}

module_init(kcm_init);
module_exit(kcm_exit);

MODULE_LICENSE("GPL");
MODULE_ALIAS_NETPROTO(PF_KCM);

