/* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/module.h>
#include <linux/types.h>
#include <linux/net.h>
#include <linux/socket.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/poll.h>
#include <linux/fcntl.h>
#include <linux/gfp.h>
#include <linux/msm_ipc.h>
#include <linux/sched.h>
#include <linux/thread_info.h>
#include <linux/slab.h>
#include <linux/kmemleak.h>
#include <linux/ipc_logging.h>
#include <linux/string.h>
#include <linux/atomic.h>
#include <linux/ipc_router.h>

#include <net/sock.h>

#include "ipc_router_private.h"
#include "ipc_router_security.h"

#define msm_ipc_sk(sk) ((struct msm_ipc_sock *)(sk))
#define msm_ipc_sk_port(sk) ((struct msm_ipc_port *)(msm_ipc_sk(sk)->port))

#ifndef SIZE_MAX
#define SIZE_MAX ((size_t)-1)
#endif

static int sockets_enabled;
static struct proto msm_ipc_proto;
static const struct proto_ops msm_ipc_proto_ops;
static RAW_NOTIFIER_HEAD(ipcrtr_af_init_chain);
static DEFINE_MUTEX(ipcrtr_af_init_lock);

static struct sk_buff_head *msm_ipc_router_build_msg(struct msghdr *m,
						     size_t total_len)
{
	struct sk_buff_head *msg_head;
	struct sk_buff *msg;
	int first = 1;
	int last = 1;
	size_t data_size = 0;
	size_t alloc_size, align_size;
	void *data;
	size_t total_copied_size = 0, copied_size;

	if (iov_iter_count(&m->msg_iter) == total_len)
		data_size = total_len;

	if (!data_size)
		return NULL;
	align_size = ALIGN_SIZE(data_size);

	msg_head = kmalloc(sizeof(*msg_head), GFP_KERNEL);
	if (!msg_head) {
		IPC_RTR_ERR("%s: cannot allocate skb_head\n", __func__);
		return NULL;
	}
	skb_queue_head_init(msg_head);

	while (total_copied_size < total_len) {
		alloc_size = data_size;
		if (first)
			alloc_size += IPC_ROUTER_HDR_SIZE;
		if (last)
			alloc_size += align_size;

		msg = alloc_skb(alloc_size, GFP_KERNEL);
		if (!msg) {
			if (alloc_size <= (PAGE_SIZE / 2)) {
				IPC_RTR_ERR("%s: cannot allocated skb\n",
					    __func__);
				goto msg_build_failure;
			}
			data_size = data_size / 2;
			last = 0;
			continue;
		}

		if (first) {
			skb_reserve(msg, IPC_ROUTER_HDR_SIZE);
			first = 0;
		}

		data = skb_put(msg, data_size);
		copied_size = copy_from_iter(msg->data, data_size,
					     &m->msg_iter);
		if (copied_size != data_size) {
			IPC_RTR_ERR("%s: copy_from_iter failed %zu %zu %zu\n",
				    __func__, alloc_size, data_size,
				    copied_size);
			kfree_skb(msg);
			goto msg_build_failure;
		}
		skb_queue_tail(msg_head, msg);
		total_copied_size += data_size;
		data_size = total_len - total_copied_size;
		last = 1;
	}
	return msg_head;

msg_build_failure:
	while (!skb_queue_empty(msg_head)) {
		msg = skb_dequeue(msg_head);
		kfree_skb(msg);
	}
	kfree(msg_head);
	return NULL;
}

static int msm_ipc_router_extract_msg(struct msghdr *m,
				      struct rr_packet *pkt)
{
	struct sockaddr_msm_ipc *addr;
	struct rr_header_v1 *hdr;
	struct sk_buff *temp;
	union rr_control_msg *ctl_msg;
	int offset = 0, data_len = 0, copy_len, copied_len;

	if (!m || !pkt) {
		IPC_RTR_ERR("%s: Invalid pointers passed\n", __func__);
		return -EINVAL;
	}
	addr = (struct sockaddr_msm_ipc *)m->msg_name;

	hdr = &pkt->hdr;
	if (addr && (hdr->type == IPC_ROUTER_CTRL_CMD_RESUME_TX)) {
		temp = skb_peek(pkt->pkt_fragment_q);
		if (!temp || !temp->data) {
			IPC_RTR_ERR("%s: Invalid skb\n", __func__);
			return -EINVAL;
		}
		ctl_msg = (union rr_control_msg *)(temp->data);
		memset(addr, 0x0, sizeof(*addr));
		addr->family = AF_MSM_IPC;
		addr->address.addrtype = MSM_IPC_ADDR_ID;
		addr->address.addr.port_addr.node_id = ctl_msg->cli.node_id;
		addr->address.addr.port_addr.port_id = ctl_msg->cli.port_id;
		m->msg_namelen = sizeof(struct sockaddr_msm_ipc);
		return offset;
	}
	if (addr && (hdr->type == IPC_ROUTER_CTRL_CMD_DATA)) {
		memset(addr, 0x0, sizeof(*addr));
		addr->family = AF_MSM_IPC;
		addr->address.addrtype = MSM_IPC_ADDR_ID;
		addr->address.addr.port_addr.node_id = hdr->src_node_id;
		addr->address.addr.port_addr.port_id = hdr->src_port_id;
		m->msg_namelen = sizeof(struct sockaddr_msm_ipc);
	}

	data_len = hdr->size;
	skb_queue_walk(pkt->pkt_fragment_q, temp) {
		copy_len = data_len < temp->len ? data_len : temp->len;
		copied_len = copy_to_iter(temp->data, copy_len, &m->msg_iter);
		if (copy_len != copied_len) {
			IPC_RTR_ERR("%s: Copy to user failed\n", __func__);
			return -EFAULT;
		}
		offset += copy_len;
		data_len -= copy_len;
	}
	return offset;
}

static int msm_ipc_router_create(struct net *net,
				 struct socket *sock,
				 int protocol,
				 int kern)
{
	struct sock *sk;
	struct msm_ipc_port *port_ptr;

	if (unlikely(protocol != 0)) {
		IPC_RTR_ERR("%s: Protocol not supported\n", __func__);
		return -EPROTONOSUPPORT;
	}

	switch (sock->type) {
	case SOCK_DGRAM:
		break;
	default:
		IPC_RTR_ERR("%s: Protocol type not supported\n", __func__);
		return -EPROTOTYPE;
	}

	sk = sk_alloc(net, AF_MSM_IPC, GFP_KERNEL, &msm_ipc_proto, kern);
	if (!sk) {
		IPC_RTR_ERR("%s: sk_alloc failed\n", __func__);
		return -ENOMEM;
	}

	sock->ops = &msm_ipc_proto_ops;
	sock_init_data(sock, sk);
	sk->sk_data_ready = NULL;
	sk->sk_write_space = ipc_router_dummy_write_space;
	sk->sk_rcvtimeo = DEFAULT_RCV_TIMEO;
	sk->sk_sndtimeo = DEFAULT_SND_TIMEO;

	port_ptr = msm_ipc_router_create_raw_port(sk, NULL, NULL);
	if (!port_ptr) {
		IPC_RTR_ERR("%s: port_ptr alloc failed\n", __func__);
		sock_put(sk);
		sock->sk = NULL;
		return -ENOMEM;
	}

	port_ptr->check_send_permissions = msm_ipc_check_send_permissions;
	msm_ipc_sk(sk)->port = port_ptr;
	msm_ipc_sk(sk)->default_node_vote_info = NULL;

	return 0;
}

int msm_ipc_router_bind(struct socket *sock, struct sockaddr *uaddr,
			int uaddr_len)
{
	struct sockaddr_msm_ipc *addr = (struct sockaddr_msm_ipc *)uaddr;
	struct sock *sk = sock->sk;
	struct msm_ipc_port *port_ptr;
	int ret;

	if (!sk)
		return -EINVAL;

	if (!check_permissions()) {
		IPC_RTR_ERR("%s: %s Do not have permissions\n",
			    __func__, current->comm);
		return -EPERM;
	}

	if (!uaddr_len) {
		IPC_RTR_ERR("%s: Invalid address length\n", __func__);
		return -EINVAL;
	}

	if (addr->family != AF_MSM_IPC) {
		IPC_RTR_ERR("%s: Address family is incorrect\n", __func__);
		return -EAFNOSUPPORT;
	}

	if (addr->address.addrtype != MSM_IPC_ADDR_NAME) {
		IPC_RTR_ERR("%s: Address type is incorrect\n", __func__);
		return -EINVAL;
	}

	port_ptr = msm_ipc_sk_port(sk);
	if (!port_ptr)
		return -ENODEV;

	if (!msm_ipc_sk(sk)->default_node_vote_info)
		msm_ipc_sk(sk)->default_node_vote_info =
			msm_ipc_load_default_node();
	lock_sock(sk);

	ret = msm_ipc_router_register_server(port_ptr, &addr->address);

	release_sock(sk);
	return ret;
}

static int ipc_router_connect(struct socket *sock, struct sockaddr *uaddr,
			      int uaddr_len, int flags)
{
	struct sockaddr_msm_ipc *addr = (struct sockaddr_msm_ipc *)uaddr;
	struct sock *sk = sock->sk;
	struct msm_ipc_port *port_ptr;
	int ret;

	if (!sk)
		return -EINVAL;

	if (uaddr_len <= 0) {
		IPC_RTR_ERR("%s: Invalid address length\n", __func__);
		return -EINVAL;
	}

	if (!addr) {
		IPC_RTR_ERR("%s: Invalid address\n", __func__);
		return -EINVAL;
	}

	if (addr->family != AF_MSM_IPC) {
		IPC_RTR_ERR("%s: Address family is incorrect\n", __func__);
		return -EAFNOSUPPORT;
	}

	port_ptr = msm_ipc_sk_port(sk);
	if (!port_ptr)
		return -ENODEV;

	lock_sock(sk);
	ret = ipc_router_set_conn(port_ptr, &addr->address);
	release_sock(sk);
	return ret;
}

static int msm_ipc_router_sendmsg(struct socket *sock,
				  struct msghdr *m, size_t total_len)
{
	struct sock *sk = sock->sk;
	struct msm_ipc_port *port_ptr = msm_ipc_sk_port(sk);
	struct sockaddr_msm_ipc *dest = (struct sockaddr_msm_ipc *)m->msg_name;
	struct sk_buff_head *msg;
	int ret;
	struct msm_ipc_addr dest_addr = {0};
	long timeout;

	if (dest) {
		if (m->msg_namelen < sizeof(*dest) ||
		    dest->family != AF_MSM_IPC)
			return -EINVAL;
		memcpy(&dest_addr, &dest->address, sizeof(dest_addr));
	} else {
		if (port_ptr->conn_status == NOT_CONNECTED)
			return -EDESTADDRREQ;
		if (port_ptr->conn_status < CONNECTION_RESET)
			return -ENETRESET;
		memcpy(&dest_addr.addr.port_addr, &port_ptr->dest_addr,
		       sizeof(struct msm_ipc_port_addr));
		dest_addr.addrtype = MSM_IPC_ADDR_ID;
	}

	if (total_len > MAX_IPC_PKT_SIZE)
		return -EINVAL;

	lock_sock(sk);
	timeout = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT);
	msg = msm_ipc_router_build_msg(m, total_len);
	if (!msg) {
		IPC_RTR_ERR("%s: Msg build failure\n", __func__);
		ret = -ENOMEM;
		goto out_sendmsg;
	}
	kmemleak_not_leak(msg);

	if (port_ptr->type == CLIENT_PORT)
		wait_for_irsc_completion();
	ret = msm_ipc_router_send_to(port_ptr, msg, &dest_addr, timeout);
	if (ret != total_len) {
		if (ret < 0) {
			if (ret != -EAGAIN)
				IPC_RTR_ERR("%s: Send_to failure %d\n",
					    __func__, ret);
			msm_ipc_router_free_skb(msg);
		} else if (ret >= 0) {
			ret = -EFAULT;
		}
	}

out_sendmsg:
	release_sock(sk);
	return ret;
}

static int msm_ipc_router_recvmsg(struct socket *sock,
				  struct msghdr *m, size_t buf_len, int flags)
{
	struct sock *sk = sock->sk;
	struct msm_ipc_port *port_ptr = msm_ipc_sk_port(sk);
	struct rr_packet *pkt;
	long timeout;
	int ret;

	lock_sock(sk);
	if (!buf_len) {
		if (flags & MSG_PEEK)
			ret = msm_ipc_router_get_curr_pkt_size(port_ptr);
		else
			ret = -EINVAL;
		release_sock(sk);
		return ret;
	}
	timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);

	ret = msm_ipc_router_rx_data_wait(port_ptr, timeout);
	if (ret) {
		release_sock(sk);
		if (ret == -ENOMSG)
			m->msg_namelen = 0;
		return ret;
	}

	ret = msm_ipc_router_read(port_ptr, &pkt, buf_len);
	if (ret <= 0 || !pkt) {
		release_sock(sk);
		return ret;
	}

	ret = msm_ipc_router_extract_msg(m, pkt);
	release_pkt(pkt);
	release_sock(sk);
	return ret;
}

static int msm_ipc_router_ioctl(struct socket *sock,
				unsigned int cmd, unsigned long arg)
{
	struct sock *sk = sock->sk;
	struct msm_ipc_port *port_ptr;
	struct server_lookup_args server_arg;
	struct msm_ipc_server_info *srv_info = NULL;
	unsigned int n;
	size_t srv_info_sz = 0;
	int ret;

	if (!sk)
		return -EINVAL;

	lock_sock(sk);
	port_ptr = msm_ipc_sk_port(sock->sk);
	if (!port_ptr) {
		release_sock(sk);
		return -EINVAL;
	}

	switch (cmd) {
	case IPC_ROUTER_IOCTL_GET_VERSION:
		n = IPC_ROUTER_V1;
		ret = put_user(n, (unsigned int *)arg);
		break;

	case IPC_ROUTER_IOCTL_GET_MTU:
		n = (MAX_IPC_PKT_SIZE - IPC_ROUTER_HDR_SIZE);
		ret = put_user(n, (unsigned int *)arg);
		break;

	case IPC_ROUTER_IOCTL_GET_CURR_PKT_SIZE:
		ret = msm_ipc_router_get_curr_pkt_size(port_ptr);
		break;

	case IPC_ROUTER_IOCTL_LOOKUP_SERVER:
		if (!msm_ipc_sk(sk)->default_node_vote_info)
			msm_ipc_sk(sk)->default_node_vote_info =
				msm_ipc_load_default_node();

		ret = copy_from_user(&server_arg, (void *)arg,
				     sizeof(server_arg));
		if (ret) {
			ret = -EFAULT;
			break;
		}

		if (server_arg.num_entries_in_array < 0) {
			ret = -EINVAL;
			break;
		}
		if (server_arg.num_entries_in_array) {
			if (server_arg.num_entries_in_array >
				(SIZE_MAX / sizeof(*srv_info))) {
				IPC_RTR_ERR("%s: Integer Overflow %zu * %d\n",
					    __func__, sizeof(*srv_info),
					server_arg.num_entries_in_array);
				ret = -EINVAL;
				break;
			}
			srv_info_sz = server_arg.num_entries_in_array *
					sizeof(*srv_info);
			srv_info = kmalloc(srv_info_sz, GFP_KERNEL);
			if (!srv_info) {
				ret = -ENOMEM;
				break;
			}
		}
		ret = msm_ipc_router_lookup_server_name
				(&server_arg.port_name, srv_info,
				server_arg.num_entries_in_array,
				server_arg.lookup_mask);
		if (ret < 0) {
			IPC_RTR_ERR("%s: Server not found\n", __func__);
			ret = -ENODEV;
			kfree(srv_info);
			break;
		}
		server_arg.num_entries_found = ret;

		ret = copy_to_user((void *)arg, &server_arg,
				   sizeof(server_arg));

		n = min(server_arg.num_entries_found,
			server_arg.num_entries_in_array);

		if (ret == 0 && n) {
			ret = copy_to_user((void *)(arg + sizeof(server_arg)),
					   srv_info, n * sizeof(*srv_info));
		}

		if (ret)
			ret = -EFAULT;
		kfree(srv_info);
		break;

	case IPC_ROUTER_IOCTL_BIND_CONTROL_PORT:
		ret = msm_ipc_router_bind_control_port(port_ptr);
		break;

	case IPC_ROUTER_IOCTL_CONFIG_SEC_RULES:
		ret = msm_ipc_config_sec_rules((void *)arg);
		if (ret != -EPERM)
			port_ptr->type = IRSC_PORT;
		break;

	default:
		ret = -EINVAL;
	}
	release_sock(sk);
	return ret;
}

static unsigned int msm_ipc_router_poll(struct file *file, struct socket *sock,
					poll_table *wait)
{
	struct sock *sk = sock->sk;
	struct msm_ipc_port *port_ptr;
	u32 mask = 0;

	if (!sk)
		return -EINVAL;

	port_ptr = msm_ipc_sk_port(sk);
	if (!port_ptr)
		return -EINVAL;

	poll_wait(file, &port_ptr->port_rx_wait_q, wait);

	if (!list_empty(&port_ptr->port_rx_q))
		mask |= (POLLRDNORM | POLLIN);

	if (port_ptr->conn_status == CONNECTION_RESET)
		mask |= (POLLHUP | POLLERR);

	return mask;
}

static int msm_ipc_router_close(struct socket *sock)
{
	struct sock *sk = sock->sk;
	struct msm_ipc_port *port_ptr;
	int ret;

	if (!sk)
		return -EINVAL;

	lock_sock(sk);
	port_ptr = msm_ipc_sk_port(sk);
	if (!port_ptr) {
		release_sock(sk);
		return -EINVAL;
	}
	ret = msm_ipc_router_close_port(port_ptr);
	msm_ipc_unload_default_node(msm_ipc_sk(sk)->default_node_vote_info);
	release_sock(sk);
	sock_put(sk);
	sock->sk = NULL;

	return ret;
}

/**
 * register_ipcrtr_af_init_notifier() - Register for ipc router socket
 *				address family initialization callback
 * @nb: Notifier block which will be notified when address family is
 *	initialized.
 *
 * Return: 0 on success, standard error code otherwise.
 */
int register_ipcrtr_af_init_notifier(struct notifier_block *nb)
{
	int ret;

	if (!nb)
		return -EINVAL;
	mutex_lock(&ipcrtr_af_init_lock);
	if (sockets_enabled)
		nb->notifier_call(nb, IPCRTR_AF_INIT, NULL);
	ret = raw_notifier_chain_register(&ipcrtr_af_init_chain, nb);
	mutex_unlock(&ipcrtr_af_init_lock);
	return ret;
}
EXPORT_SYMBOL(register_ipcrtr_af_init_notifier);

/**
 * unregister_ipcrtr_af_init_notifier() - Unregister for ipc router socket
 *				address family initialization callback
 * @nb: Notifier block which will be notified once address family is
 *	initialized.
 *
 * Return: 0 on success, standard error code otherwise.
 */
int unregister_ipcrtr_af_init_notifier(struct notifier_block *nb)
{
	int ret;

	if (!nb)
		return -EINVAL;
	ret = raw_notifier_chain_unregister(&ipcrtr_af_init_chain, nb);
	return ret;
}
EXPORT_SYMBOL(unregister_ipcrtr_af_init_notifier);

static const struct net_proto_family msm_ipc_family_ops = {
	.owner		= THIS_MODULE,
	.family		= AF_MSM_IPC,
	.create		= msm_ipc_router_create
};

static const struct proto_ops msm_ipc_proto_ops = {
	.family			= AF_MSM_IPC,
	.owner			= THIS_MODULE,
	.release		= msm_ipc_router_close,
	.bind			= msm_ipc_router_bind,
	.connect		= ipc_router_connect,
	.socketpair		= sock_no_socketpair,
	.accept			= sock_no_accept,
	.getname		= sock_no_getname,
	.poll			= msm_ipc_router_poll,
	.ioctl			= msm_ipc_router_ioctl,
#ifdef CONFIG_COMPAT
	.compat_ioctl		= msm_ipc_router_ioctl,
#endif
	.listen			= sock_no_listen,
	.shutdown		= sock_no_shutdown,
	.setsockopt		= sock_no_setsockopt,
	.getsockopt		= sock_no_getsockopt,
#ifdef CONFIG_COMPAT
	.compat_setsockopt	= sock_no_setsockopt,
	.compat_getsockopt	= sock_no_getsockopt,
#endif
	.sendmsg		= msm_ipc_router_sendmsg,
	.recvmsg		= msm_ipc_router_recvmsg,
	.mmap			= sock_no_mmap,
	.sendpage		= sock_no_sendpage,
};

static struct proto msm_ipc_proto = {
	.name           = "MSM_IPC",
	.owner          = THIS_MODULE,
	.obj_size       = sizeof(struct msm_ipc_sock),
};

int msm_ipc_router_init_sockets(void)
{
	int ret;

	ret = proto_register(&msm_ipc_proto, 1);
	if (ret) {
		IPC_RTR_ERR("%s: Failed to register MSM_IPC protocol type\n",
			    __func__);
		goto out_init_sockets;
	}

	ret = sock_register(&msm_ipc_family_ops);
	if (ret) {
		IPC_RTR_ERR("%s: Failed to register MSM_IPC socket type\n",
			    __func__);
		proto_unregister(&msm_ipc_proto);
		goto out_init_sockets;
	}

	mutex_lock(&ipcrtr_af_init_lock);
	sockets_enabled = 1;
	raw_notifier_call_chain(&ipcrtr_af_init_chain,
				IPCRTR_AF_INIT, NULL);
	mutex_unlock(&ipcrtr_af_init_lock);
out_init_sockets:
	return ret;
}

void msm_ipc_router_exit_sockets(void)
{
	if (!sockets_enabled)
		return;

	sock_unregister(msm_ipc_family_ops.family);
	proto_unregister(&msm_ipc_proto);
	mutex_lock(&ipcrtr_af_init_lock);
	sockets_enabled = 0;
	raw_notifier_call_chain(&ipcrtr_af_init_chain,
				IPCRTR_AF_DEINIT, NULL);
	mutex_unlock(&ipcrtr_af_init_lock);
}
