/*
 *  Event notification code.
 *
 *  Copyright (C) 2005 FUJITA Tomonori <tomof@acm.org>
 *  Copyright (C) 2007 - 2018 Vladislav Bolkhovitin
 *  Copyright (C) 2007 - 2018 Western Digital Corporation
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License
 *  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>
#ifdef INSIDE_KERNEL_TREE
#include <scst/iscsi_scst.h>
#else
#include "iscsi_scst.h"
#endif
#include "iscsi_trace_flag.h"
#include "iscsi.h"

struct net *iscsi_net_ns;
EXPORT_SYMBOL(iscsi_net_ns);

/* See also commit 2d4bc93368f5 ("netlink: extended ACK reporting") */
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0)
struct netlink_ext_ack;

static inline void netlink_ack_backport(struct sk_buff *in_skb,
					struct nlmsghdr *nlh, int err,
					const struct netlink_ext_ack *extack)
{
	WARN_ON_ONCE(extack);
	netlink_ack(in_skb, nlh, err);
}
#define netlink_ack netlink_ack_backport
#endif

static struct sock *nl;
static u32 iscsid_pid;

static int event_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
{
	u32 pid;

#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0))
	pid = NETLINK_CB(skb).pid;
#else
	pid = NETLINK_CB(skb).portid;
#endif
	WARN_ON(pid == 0);

	iscsid_pid = pid;

	return 0;
}

#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24))
static int event_recv_skb(struct sk_buff *skb)
#else
static void event_recv_skb(struct sk_buff *skb)
#endif
{
	int err;
	struct nlmsghdr	*nlh;
	u32 rlen;

	while (skb->len >= NLMSG_SPACE(0)) {
		nlh = (struct nlmsghdr *)skb->data;
		if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len)
			goto out;
		rlen = NLMSG_ALIGN(nlh->nlmsg_len);
		if (rlen > skb->len)
			rlen = skb->len;
		err = event_recv_msg(skb, nlh);
		if (err)
			netlink_ack(skb, nlh, -err, NULL);
		else if (nlh->nlmsg_flags & NLM_F_ACK)
			netlink_ack(skb, nlh, 0, NULL);
		skb_pull(skb, rlen);
	}

out:
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24))
	return 0;
#else
	return;
#endif
}

#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24))
static void event_recv(struct sock *sk, int length)
{
	struct sk_buff *skb;

	while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
		if (event_recv_skb(skb) && skb->len)
			skb_queue_head(&sk->sk_receive_queue, skb);
		else
			kfree_skb(skb);
	}
}
#endif

/* event_mutex supposed to be held */
static int __event_send(const void *buf, int buf_len)
{
	int res = 0, len;
	struct sk_buff *skb;
	struct nlmsghdr *nlh;
	static u32 seq; /* protected by event_mutex */

	TRACE_ENTRY();

	if (ctr_open_state != ISCSI_CTR_OPEN_STATE_OPEN)
		goto out;

	len = NLMSG_SPACE(buf_len);

	skb = alloc_skb(len, GFP_KERNEL);
	if (skb == NULL) {
		PRINT_ERROR("alloc_skb() failed (len %d)", len);
		res =  -ENOMEM;
		goto out;
	}

	nlh = __nlmsg_put(skb, iscsid_pid, seq++, NLMSG_DONE, buf_len, 0);

	memcpy(NLMSG_DATA(nlh), buf, buf_len);
	res = netlink_unicast(nl, skb, iscsid_pid, 0);
	if (res <= 0) {
		if (res != -ECONNREFUSED)
			PRINT_ERROR("netlink_unicast() failed: %d", res);
		else
			TRACE(TRACE_MINOR,
			      "netlink_unicast() failed: %s. Not functioning user space?",
			      "Connection refused");
		goto out;
	}

out:
	TRACE_EXIT_RES(res);
	return res;
}

int event_send(u32 tid, u64 sid, u32 cid, u32 cookie,
	enum iscsi_kern_event_code code,
	const char *param1, const char *param2)
{
	int err;
	static DEFINE_MUTEX(event_mutex);
	struct iscsi_kern_event event;
	int param1_size, param2_size;

	param1_size = (param1 != NULL) ? strlen(param1) : 0;
	param2_size = (param2 != NULL) ? strlen(param2) : 0;

	event.tid = tid;
	event.sid = sid;
	event.cid = cid;
	event.code = code;
	event.cookie = cookie;
	event.param1_size = param1_size;
	event.param2_size = param2_size;

	mutex_lock(&event_mutex);

	err = __event_send(&event, sizeof(event));
	if (err <= 0)
		goto out_unlock;

	if (param1_size > 0) {
		err = __event_send(param1, param1_size);
		if (err <= 0)
			goto out_unlock;
	}

	if (param2_size > 0) {
		err = __event_send(param2, param2_size);
		if (err <= 0)
			goto out_unlock;
	}

out_unlock:
	mutex_unlock(&event_mutex);
	return err;
}

int __init event_init(void)
{
	iscsi_net_ns = kobj_ns_grab_current(KOBJ_NS_TYPE_NET);

#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22))
	nl = netlink_kernel_create(NETLINK_ISCSI_SCST, 1, event_recv,
		THIS_MODULE);
#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24))
	nl = netlink_kernel_create(NETLINK_ISCSI_SCST, 1, event_recv, NULL,
				   THIS_MODULE);
#elif (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
	nl = netlink_kernel_create(iscsi_net_ns, NETLINK_ISCSI_SCST, 1,
				   event_recv_skb, NULL, THIS_MODULE);
#else
	{
		struct netlink_kernel_cfg cfg = {
			.input = event_recv_skb,
			.groups = 1,
		};
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 0))
		nl = netlink_kernel_create(iscsi_net_ns, NETLINK_ISCSI_SCST,
				   THIS_MODULE, &cfg);
#else
		nl = netlink_kernel_create(iscsi_net_ns, NETLINK_ISCSI_SCST,
					   &cfg);
#endif
	}
#endif
	if (!nl)
		goto drop_ns;

	return 0;

drop_ns:
	PRINT_ERROR("%s", "netlink_kernel_create() failed");
	kobj_ns_drop(KOBJ_NS_TYPE_NET, iscsi_net_ns);
	iscsi_net_ns = NULL;
	return -ENOMEM;
}

void event_exit(void)
{
#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 24))
	if (nl)
		sock_release(nl->sk_socket);
#else
	netlink_kernel_release(nl);
#endif
	kobj_ns_drop(KOBJ_NS_TYPE_NET, iscsi_net_ns);
	iscsi_net_ns = NULL;
}
