/*
 * Copyright (c) 2014 Chelsio, Inc. All rights reserved.
 * Copyright (c) 2014 Intel Corporation. All rights reserved.
 *
 * This software is available to you under a choice of one of two
 * licenses.  You may choose to be licensed under the terms of the GNU
 * General Public License (GPL) Version 2, available from the file
 * COPYING in the main directory of this source tree, or the
 * OpenIB.org BSD license below:
 *
 *     Redistribution and use in source and binary forms, with or
 *     without modification, are permitted provided that the following
 *     conditions are met:
 *
 *      - Redistributions of source code must retain the above
 *	  copyright notice, this list of conditions and the following
 *	  disclaimer.
 *
 *      - Redistributions in binary form must reproduce the above
 *	  copyright notice, this list of conditions and the following
 *	  disclaimer in the documentation and/or other materials
 *	  provided with the distribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include "iwpm_util.h"

#define IWPM_MAPINFO_HASH_SIZE	512
#define IWPM_MAPINFO_HASH_MASK	(IWPM_MAPINFO_HASH_SIZE - 1)
#define IWPM_REMINFO_HASH_SIZE	64
#define IWPM_REMINFO_HASH_MASK	(IWPM_REMINFO_HASH_SIZE - 1)

static LIST_HEAD(iwpm_nlmsg_req_list);
static DEFINE_SPINLOCK(iwpm_nlmsg_req_lock);

static struct hlist_head *iwpm_hash_bucket;
static DEFINE_SPINLOCK(iwpm_mapinfo_lock);

static struct hlist_head *iwpm_reminfo_bucket;
static DEFINE_SPINLOCK(iwpm_reminfo_lock);

static DEFINE_MUTEX(iwpm_admin_lock);
static struct iwpm_admin_data iwpm_admin;

int iwpm_init(u8 nl_client)
{
	int ret = 0;
	if (iwpm_valid_client(nl_client))
		return -EINVAL;
	mutex_lock(&iwpm_admin_lock);
	if (atomic_read(&iwpm_admin.refcount) == 0) {
		iwpm_hash_bucket = kzalloc(IWPM_MAPINFO_HASH_SIZE *
					sizeof(struct hlist_head), GFP_KERNEL);
		if (!iwpm_hash_bucket) {
			ret = -ENOMEM;
			pr_err("%s Unable to create mapinfo hash table\n", __func__);
			goto init_exit;
		}
		iwpm_reminfo_bucket = kzalloc(IWPM_REMINFO_HASH_SIZE *
					sizeof(struct hlist_head), GFP_KERNEL);
		if (!iwpm_reminfo_bucket) {
			kfree(iwpm_hash_bucket);
			ret = -ENOMEM;
			pr_err("%s Unable to create reminfo hash table\n", __func__);
			goto init_exit;
		}
	}
	atomic_inc(&iwpm_admin.refcount);
init_exit:
	mutex_unlock(&iwpm_admin_lock);
	if (!ret) {
		iwpm_set_valid(nl_client, 1);
		iwpm_set_registration(nl_client, IWPM_REG_UNDEF);
		pr_debug("%s: Mapinfo and reminfo tables are created\n",
				__func__);
	}
	return ret;
}
EXPORT_SYMBOL(iwpm_init);

static void free_hash_bucket(void);
static void free_reminfo_bucket(void);

int iwpm_exit(u8 nl_client)
{

	if (!iwpm_valid_client(nl_client))
		return -EINVAL;
	mutex_lock(&iwpm_admin_lock);
	if (atomic_read(&iwpm_admin.refcount) == 0) {
		mutex_unlock(&iwpm_admin_lock);
		pr_err("%s Incorrect usage - negative refcount\n", __func__);
		return -EINVAL;
	}
	if (atomic_dec_and_test(&iwpm_admin.refcount)) {
		free_hash_bucket();
		free_reminfo_bucket();
		pr_debug("%s: Resources are destroyed\n", __func__);
	}
	mutex_unlock(&iwpm_admin_lock);
	iwpm_set_valid(nl_client, 0);
	iwpm_set_registration(nl_client, IWPM_REG_UNDEF);
	return 0;
}
EXPORT_SYMBOL(iwpm_exit);

static struct hlist_head *get_mapinfo_hash_bucket(struct sockaddr_storage *,
					       struct sockaddr_storage *);

int iwpm_create_mapinfo(struct sockaddr_storage *local_sockaddr,
			struct sockaddr_storage *mapped_sockaddr,
			u8 nl_client)
{
	struct hlist_head *hash_bucket_head;
	struct iwpm_mapping_info *map_info;
	unsigned long flags;
	int ret = -EINVAL;

	if (!iwpm_valid_client(nl_client))
		return ret;
	map_info = kzalloc(sizeof(struct iwpm_mapping_info), GFP_KERNEL);
	if (!map_info) {
		pr_err("%s: Unable to allocate a mapping info\n", __func__);
		return -ENOMEM;
	}
	memcpy(&map_info->local_sockaddr, local_sockaddr,
	       sizeof(struct sockaddr_storage));
	memcpy(&map_info->mapped_sockaddr, mapped_sockaddr,
	       sizeof(struct sockaddr_storage));
	map_info->nl_client = nl_client;

	spin_lock_irqsave(&iwpm_mapinfo_lock, flags);
	if (iwpm_hash_bucket) {
		hash_bucket_head = get_mapinfo_hash_bucket(
					&map_info->local_sockaddr,
					&map_info->mapped_sockaddr);
		if (hash_bucket_head) {
			hlist_add_head(&map_info->hlist_node, hash_bucket_head);
			ret = 0;
		}
	}
	spin_unlock_irqrestore(&iwpm_mapinfo_lock, flags);
	return ret;
}
EXPORT_SYMBOL(iwpm_create_mapinfo);

int iwpm_remove_mapinfo(struct sockaddr_storage *local_sockaddr,
			struct sockaddr_storage *mapped_local_addr)
{
	struct hlist_node *tmp_hlist_node;
	struct hlist_head *hash_bucket_head;
	struct iwpm_mapping_info *map_info = NULL;
	unsigned long flags;
	int ret = -EINVAL;

	spin_lock_irqsave(&iwpm_mapinfo_lock, flags);
	if (iwpm_hash_bucket) {
		hash_bucket_head = get_mapinfo_hash_bucket(
					local_sockaddr,
					mapped_local_addr);
		if (!hash_bucket_head)
			goto remove_mapinfo_exit;

		hlist_for_each_entry_safe(map_info, tmp_hlist_node,
					hash_bucket_head, hlist_node) {

			if (!iwpm_compare_sockaddr(&map_info->mapped_sockaddr,
						mapped_local_addr)) {

				hlist_del_init(&map_info->hlist_node);
				kfree(map_info);
				ret = 0;
				break;
			}
		}
	}
remove_mapinfo_exit:
	spin_unlock_irqrestore(&iwpm_mapinfo_lock, flags);
	return ret;
}
EXPORT_SYMBOL(iwpm_remove_mapinfo);

static void free_hash_bucket(void)
{
	struct hlist_node *tmp_hlist_node;
	struct iwpm_mapping_info *map_info;
	unsigned long flags;
	int i;

	/* remove all the mapinfo data from the list */
	spin_lock_irqsave(&iwpm_mapinfo_lock, flags);
	for (i = 0; i < IWPM_MAPINFO_HASH_SIZE; i++) {
		hlist_for_each_entry_safe(map_info, tmp_hlist_node,
			&iwpm_hash_bucket[i], hlist_node) {

				hlist_del_init(&map_info->hlist_node);
				kfree(map_info);
			}
	}
	/* free the hash list */
	kfree(iwpm_hash_bucket);
	iwpm_hash_bucket = NULL;
	spin_unlock_irqrestore(&iwpm_mapinfo_lock, flags);
}

static void free_reminfo_bucket(void)
{
	struct hlist_node *tmp_hlist_node;
	struct iwpm_remote_info *rem_info;
	unsigned long flags;
	int i;

	/* remove all the remote info from the list */
	spin_lock_irqsave(&iwpm_reminfo_lock, flags);
	for (i = 0; i < IWPM_REMINFO_HASH_SIZE; i++) {
		hlist_for_each_entry_safe(rem_info, tmp_hlist_node,
			&iwpm_reminfo_bucket[i], hlist_node) {

				hlist_del_init(&rem_info->hlist_node);
				kfree(rem_info);
			}
	}
	/* free the hash list */
	kfree(iwpm_reminfo_bucket);
	iwpm_reminfo_bucket = NULL;
	spin_unlock_irqrestore(&iwpm_reminfo_lock, flags);
}

static struct hlist_head *get_reminfo_hash_bucket(struct sockaddr_storage *,
						struct sockaddr_storage *);

void iwpm_add_remote_info(struct iwpm_remote_info *rem_info)
{
	struct hlist_head *hash_bucket_head;
	unsigned long flags;

	spin_lock_irqsave(&iwpm_reminfo_lock, flags);
	if (iwpm_reminfo_bucket) {
		hash_bucket_head = get_reminfo_hash_bucket(
					&rem_info->mapped_loc_sockaddr,
					&rem_info->mapped_rem_sockaddr);
		if (hash_bucket_head)
			hlist_add_head(&rem_info->hlist_node, hash_bucket_head);
	}
	spin_unlock_irqrestore(&iwpm_reminfo_lock, flags);
}

int iwpm_get_remote_info(struct sockaddr_storage *mapped_loc_addr,
				struct sockaddr_storage *mapped_rem_addr,
				struct sockaddr_storage *remote_addr,
				u8 nl_client)
{
	struct hlist_node *tmp_hlist_node;
	struct hlist_head *hash_bucket_head;
	struct iwpm_remote_info *rem_info = NULL;
	unsigned long flags;
	int ret = -EINVAL;

	if (!iwpm_valid_client(nl_client)) {
		pr_info("%s: Invalid client = %d\n", __func__, nl_client);
		return ret;
	}
	spin_lock_irqsave(&iwpm_reminfo_lock, flags);
	if (iwpm_reminfo_bucket) {
		hash_bucket_head = get_reminfo_hash_bucket(
					mapped_loc_addr,
					mapped_rem_addr);
		if (!hash_bucket_head)
			goto get_remote_info_exit;
		hlist_for_each_entry_safe(rem_info, tmp_hlist_node,
					hash_bucket_head, hlist_node) {

			if (!iwpm_compare_sockaddr(&rem_info->mapped_loc_sockaddr,
				mapped_loc_addr) &&
				!iwpm_compare_sockaddr(&rem_info->mapped_rem_sockaddr,
				mapped_rem_addr)) {

				memcpy(remote_addr, &rem_info->remote_sockaddr,
					sizeof(struct sockaddr_storage));
				iwpm_print_sockaddr(remote_addr,
						"get_remote_info: Remote sockaddr:");

				hlist_del_init(&rem_info->hlist_node);
				kfree(rem_info);
				ret = 0;
				break;
			}
		}
	}
get_remote_info_exit:
	spin_unlock_irqrestore(&iwpm_reminfo_lock, flags);
	return ret;
}
EXPORT_SYMBOL(iwpm_get_remote_info);

struct iwpm_nlmsg_request *iwpm_get_nlmsg_request(__u32 nlmsg_seq,
					u8 nl_client, gfp_t gfp)
{
	struct iwpm_nlmsg_request *nlmsg_request = NULL;
	unsigned long flags;

	nlmsg_request = kzalloc(sizeof(struct iwpm_nlmsg_request), gfp);
	if (!nlmsg_request) {
		pr_err("%s Unable to allocate a nlmsg_request\n", __func__);
		return NULL;
	}
	spin_lock_irqsave(&iwpm_nlmsg_req_lock, flags);
	list_add_tail(&nlmsg_request->inprocess_list, &iwpm_nlmsg_req_list);
	spin_unlock_irqrestore(&iwpm_nlmsg_req_lock, flags);

	kref_init(&nlmsg_request->kref);
	kref_get(&nlmsg_request->kref);
	nlmsg_request->nlmsg_seq = nlmsg_seq;
	nlmsg_request->nl_client = nl_client;
	nlmsg_request->request_done = 0;
	nlmsg_request->err_code = 0;
	return nlmsg_request;
}

void iwpm_free_nlmsg_request(struct kref *kref)
{
	struct iwpm_nlmsg_request *nlmsg_request;
	unsigned long flags;

	nlmsg_request = container_of(kref, struct iwpm_nlmsg_request, kref);

	spin_lock_irqsave(&iwpm_nlmsg_req_lock, flags);
	list_del_init(&nlmsg_request->inprocess_list);
	spin_unlock_irqrestore(&iwpm_nlmsg_req_lock, flags);

	if (!nlmsg_request->request_done)
		pr_debug("%s Freeing incomplete nlmsg request (seq = %u).\n",
			__func__, nlmsg_request->nlmsg_seq);
	kfree(nlmsg_request);
}

struct iwpm_nlmsg_request *iwpm_find_nlmsg_request(__u32 echo_seq)
{
	struct iwpm_nlmsg_request *nlmsg_request;
	struct iwpm_nlmsg_request *found_request = NULL;
	unsigned long flags;

	spin_lock_irqsave(&iwpm_nlmsg_req_lock, flags);
	list_for_each_entry(nlmsg_request, &iwpm_nlmsg_req_list,
			    inprocess_list) {
		if (nlmsg_request->nlmsg_seq == echo_seq) {
			found_request = nlmsg_request;
			kref_get(&nlmsg_request->kref);
			break;
		}
	}
	spin_unlock_irqrestore(&iwpm_nlmsg_req_lock, flags);
	return found_request;
}

int iwpm_wait_complete_req(struct iwpm_nlmsg_request *nlmsg_request)
{
	int ret;
	init_waitqueue_head(&nlmsg_request->waitq);

	ret = wait_event_timeout(nlmsg_request->waitq,
			(nlmsg_request->request_done != 0), IWPM_NL_TIMEOUT);
	if (!ret) {
		ret = -EINVAL;
		pr_info("%s: Timeout %d sec for netlink request (seq = %u)\n",
			__func__, (IWPM_NL_TIMEOUT/HZ), nlmsg_request->nlmsg_seq);
	} else {
		ret = nlmsg_request->err_code;
	}
	kref_put(&nlmsg_request->kref, iwpm_free_nlmsg_request);
	return ret;
}

int iwpm_get_nlmsg_seq(void)
{
	return atomic_inc_return(&iwpm_admin.nlmsg_seq);
}

int iwpm_valid_client(u8 nl_client)
{
	if (nl_client >= RDMA_NL_NUM_CLIENTS)
		return 0;
	return iwpm_admin.client_list[nl_client];
}

void iwpm_set_valid(u8 nl_client, int valid)
{
	if (nl_client >= RDMA_NL_NUM_CLIENTS)
		return;
	iwpm_admin.client_list[nl_client] = valid;
}

/* valid client */
u32 iwpm_get_registration(u8 nl_client)
{
	return iwpm_admin.reg_list[nl_client];
}

/* valid client */
void iwpm_set_registration(u8 nl_client, u32 reg)
{
	iwpm_admin.reg_list[nl_client] = reg;
}

/* valid client */
u32 iwpm_check_registration(u8 nl_client, u32 reg)
{
	return (iwpm_get_registration(nl_client) & reg);
}

int iwpm_compare_sockaddr(struct sockaddr_storage *a_sockaddr,
				struct sockaddr_storage *b_sockaddr)
{
	if (a_sockaddr->ss_family != b_sockaddr->ss_family)
		return 1;
	if (a_sockaddr->ss_family == AF_INET) {
		struct sockaddr_in *a4_sockaddr =
			(struct sockaddr_in *)a_sockaddr;
		struct sockaddr_in *b4_sockaddr =
			(struct sockaddr_in *)b_sockaddr;
		if (!memcmp(&a4_sockaddr->sin_addr,
			&b4_sockaddr->sin_addr, sizeof(struct in_addr))
			&& a4_sockaddr->sin_port == b4_sockaddr->sin_port)
				return 0;

	} else if (a_sockaddr->ss_family == AF_INET6) {
		struct sockaddr_in6 *a6_sockaddr =
			(struct sockaddr_in6 *)a_sockaddr;
		struct sockaddr_in6 *b6_sockaddr =
			(struct sockaddr_in6 *)b_sockaddr;
		if (!memcmp(&a6_sockaddr->sin6_addr,
			&b6_sockaddr->sin6_addr, sizeof(struct in6_addr))
			&& a6_sockaddr->sin6_port == b6_sockaddr->sin6_port)
				return 0;

	} else {
		pr_err("%s: Invalid sockaddr family\n", __func__);
	}
	return 1;
}

struct sk_buff *iwpm_create_nlmsg(u32 nl_op, struct nlmsghdr **nlh,
						int nl_client)
{
	struct sk_buff *skb = NULL;

	skb = dev_alloc_skb(NLMSG_GOODSIZE);
	if (!skb) {
		pr_err("%s Unable to allocate skb\n", __func__);
		goto create_nlmsg_exit;
	}
	if (!(ibnl_put_msg(skb, nlh, 0, 0, nl_client, nl_op,
			   NLM_F_REQUEST))) {
		pr_warn("%s: Unable to put the nlmsg header\n", __func__);
		dev_kfree_skb(skb);
		skb = NULL;
	}
create_nlmsg_exit:
	return skb;
}

int iwpm_parse_nlmsg(struct netlink_callback *cb, int policy_max,
				   const struct nla_policy *nlmsg_policy,
				   struct nlattr *nltb[], const char *msg_type)
{
	int nlh_len = 0;
	int ret;
	const char *err_str = "";

	ret = nlmsg_validate(cb->nlh, nlh_len, policy_max-1, nlmsg_policy);
	if (ret) {
		err_str = "Invalid attribute";
		goto parse_nlmsg_error;
	}
	ret = nlmsg_parse(cb->nlh, nlh_len, nltb, policy_max-1, nlmsg_policy);
	if (ret) {
		err_str = "Unable to parse the nlmsg";
		goto parse_nlmsg_error;
	}
	ret = iwpm_validate_nlmsg_attr(nltb, policy_max);
	if (ret) {
		err_str = "Invalid NULL attribute";
		goto parse_nlmsg_error;
	}
	return 0;
parse_nlmsg_error:
	pr_warn("%s: %s (msg type %s ret = %d)\n",
			__func__, err_str, msg_type, ret);
	return ret;
}

void iwpm_print_sockaddr(struct sockaddr_storage *sockaddr, char *msg)
{
	struct sockaddr_in6 *sockaddr_v6;
	struct sockaddr_in *sockaddr_v4;

	switch (sockaddr->ss_family) {
	case AF_INET:
		sockaddr_v4 = (struct sockaddr_in *)sockaddr;
		pr_debug("%s IPV4 %pI4: %u(0x%04X)\n",
			msg, &sockaddr_v4->sin_addr,
			ntohs(sockaddr_v4->sin_port),
			ntohs(sockaddr_v4->sin_port));
		break;
	case AF_INET6:
		sockaddr_v6 = (struct sockaddr_in6 *)sockaddr;
		pr_debug("%s IPV6 %pI6: %u(0x%04X)\n",
			msg, &sockaddr_v6->sin6_addr,
			ntohs(sockaddr_v6->sin6_port),
			ntohs(sockaddr_v6->sin6_port));
		break;
	default:
		break;
	}
}

static u32 iwpm_ipv6_jhash(struct sockaddr_in6 *ipv6_sockaddr)
{
	u32 ipv6_hash = jhash(&ipv6_sockaddr->sin6_addr, sizeof(struct in6_addr), 0);
	u32 hash = jhash_2words(ipv6_hash, (__force u32) ipv6_sockaddr->sin6_port, 0);
	return hash;
}

static u32 iwpm_ipv4_jhash(struct sockaddr_in *ipv4_sockaddr)
{
	u32 ipv4_hash = jhash(&ipv4_sockaddr->sin_addr, sizeof(struct in_addr), 0);
	u32 hash = jhash_2words(ipv4_hash, (__force u32) ipv4_sockaddr->sin_port, 0);
	return hash;
}

static int get_hash_bucket(struct sockaddr_storage *a_sockaddr,
				struct sockaddr_storage *b_sockaddr, u32 *hash)
{
	u32 a_hash, b_hash;

	if (a_sockaddr->ss_family == AF_INET) {
		a_hash = iwpm_ipv4_jhash((struct sockaddr_in *) a_sockaddr);
		b_hash = iwpm_ipv4_jhash((struct sockaddr_in *) b_sockaddr);

	} else if (a_sockaddr->ss_family == AF_INET6) {
		a_hash = iwpm_ipv6_jhash((struct sockaddr_in6 *) a_sockaddr);
		b_hash = iwpm_ipv6_jhash((struct sockaddr_in6 *) b_sockaddr);
	} else {
		pr_err("%s: Invalid sockaddr family\n", __func__);
		return -EINVAL;
	}

	if (a_hash == b_hash) /* if port mapper isn't available */
		*hash = a_hash;
	else
		*hash = jhash_2words(a_hash, b_hash, 0);
	return 0;
}

static struct hlist_head *get_mapinfo_hash_bucket(struct sockaddr_storage
				*local_sockaddr, struct sockaddr_storage
				*mapped_sockaddr)
{
	u32 hash;
	int ret;

	ret = get_hash_bucket(local_sockaddr, mapped_sockaddr, &hash);
	if (ret)
		return NULL;
	return &iwpm_hash_bucket[hash & IWPM_MAPINFO_HASH_MASK];
}

static struct hlist_head *get_reminfo_hash_bucket(struct sockaddr_storage
				*mapped_loc_sockaddr, struct sockaddr_storage
				*mapped_rem_sockaddr)
{
	u32 hash;
	int ret;

	ret = get_hash_bucket(mapped_loc_sockaddr, mapped_rem_sockaddr, &hash);
	if (ret)
		return NULL;
	return &iwpm_reminfo_bucket[hash & IWPM_REMINFO_HASH_MASK];
}

static int send_mapinfo_num(u32 mapping_num, u8 nl_client, int iwpm_pid)
{
	struct sk_buff *skb = NULL;
	struct nlmsghdr *nlh;
	u32 msg_seq;
	const char *err_str = "";
	int ret = -EINVAL;

	skb = iwpm_create_nlmsg(RDMA_NL_IWPM_MAPINFO_NUM, &nlh, nl_client);
	if (!skb) {
		err_str = "Unable to create a nlmsg";
		goto mapinfo_num_error;
	}
	nlh->nlmsg_seq = iwpm_get_nlmsg_seq();
	msg_seq = 0;
	err_str = "Unable to put attribute of mapinfo number nlmsg";
	ret = ibnl_put_attr(skb, nlh, sizeof(u32), &msg_seq, IWPM_NLA_MAPINFO_SEQ);
	if (ret)
		goto mapinfo_num_error;
	ret = ibnl_put_attr(skb, nlh, sizeof(u32),
				&mapping_num, IWPM_NLA_MAPINFO_SEND_NUM);
	if (ret)
		goto mapinfo_num_error;
	ret = ibnl_unicast(skb, nlh, iwpm_pid);
	if (ret) {
		skb = NULL;
		err_str = "Unable to send a nlmsg";
		goto mapinfo_num_error;
	}
	pr_debug("%s: Sent mapping number = %d\n", __func__, mapping_num);
	return 0;
mapinfo_num_error:
	pr_info("%s: %s\n", __func__, err_str);
	if (skb)
		dev_kfree_skb(skb);
	return ret;
}

static int send_nlmsg_done(struct sk_buff *skb, u8 nl_client, int iwpm_pid)
{
	struct nlmsghdr *nlh = NULL;
	int ret = 0;

	if (!skb)
		return ret;
	if (!(ibnl_put_msg(skb, &nlh, 0, 0, nl_client,
			   RDMA_NL_IWPM_MAPINFO, NLM_F_MULTI))) {
		pr_warn("%s Unable to put NLMSG_DONE\n", __func__);
		dev_kfree_skb(skb);
		return -ENOMEM;
	}
	nlh->nlmsg_type = NLMSG_DONE;
	ret = ibnl_unicast(skb, (struct nlmsghdr *)skb->data, iwpm_pid);
	if (ret)
		pr_warn("%s Unable to send a nlmsg\n", __func__);
	return ret;
}

int iwpm_send_mapinfo(u8 nl_client, int iwpm_pid)
{
	struct iwpm_mapping_info *map_info;
	struct sk_buff *skb = NULL;
	struct nlmsghdr *nlh;
	int skb_num = 0, mapping_num = 0;
	int i = 0, nlmsg_bytes = 0;
	unsigned long flags;
	const char *err_str = "";
	int ret;

	skb = dev_alloc_skb(NLMSG_GOODSIZE);
	if (!skb) {
		ret = -ENOMEM;
		err_str = "Unable to allocate skb";
		goto send_mapping_info_exit;
	}
	skb_num++;
	spin_lock_irqsave(&iwpm_mapinfo_lock, flags);
	for (i = 0; i < IWPM_MAPINFO_HASH_SIZE; i++) {
		hlist_for_each_entry(map_info, &iwpm_hash_bucket[i],
				     hlist_node) {
			if (map_info->nl_client != nl_client)
				continue;
			nlh = NULL;
			if (!(ibnl_put_msg(skb, &nlh, 0, 0, nl_client,
					RDMA_NL_IWPM_MAPINFO, NLM_F_MULTI))) {
				ret = -ENOMEM;
				err_str = "Unable to put the nlmsg header";
				goto send_mapping_info_unlock;
			}
			err_str = "Unable to put attribute of the nlmsg";
			ret = ibnl_put_attr(skb, nlh,
					sizeof(struct sockaddr_storage),
					&map_info->local_sockaddr,
					IWPM_NLA_MAPINFO_LOCAL_ADDR);
			if (ret)
				goto send_mapping_info_unlock;

			ret = ibnl_put_attr(skb, nlh,
					sizeof(struct sockaddr_storage),
					&map_info->mapped_sockaddr,
					IWPM_NLA_MAPINFO_MAPPED_ADDR);
			if (ret)
				goto send_mapping_info_unlock;

			iwpm_print_sockaddr(&map_info->local_sockaddr,
				"send_mapping_info: Local sockaddr:");
			iwpm_print_sockaddr(&map_info->mapped_sockaddr,
				"send_mapping_info: Mapped local sockaddr:");
			mapping_num++;
			nlmsg_bytes += nlh->nlmsg_len;

			/* check if all mappings can fit in one skb */
			if (NLMSG_GOODSIZE - nlmsg_bytes < nlh->nlmsg_len * 2) {
				/* and leave room for NLMSG_DONE */
				nlmsg_bytes = 0;
				skb_num++;
				spin_unlock_irqrestore(&iwpm_mapinfo_lock,
						       flags);
				/* send the skb */
				ret = send_nlmsg_done(skb, nl_client, iwpm_pid);
				skb = NULL;
				if (ret) {
					err_str = "Unable to send map info";
					goto send_mapping_info_exit;
				}
				if (skb_num == IWPM_MAPINFO_SKB_COUNT) {
					ret = -ENOMEM;
					err_str = "Insufficient skbs for map info";
					goto send_mapping_info_exit;
				}
				skb = dev_alloc_skb(NLMSG_GOODSIZE);
				if (!skb) {
					ret = -ENOMEM;
					err_str = "Unable to allocate skb";
					goto send_mapping_info_exit;
				}
				spin_lock_irqsave(&iwpm_mapinfo_lock, flags);
			}
		}
	}
send_mapping_info_unlock:
	spin_unlock_irqrestore(&iwpm_mapinfo_lock, flags);
send_mapping_info_exit:
	if (ret) {
		pr_warn("%s: %s (ret = %d)\n", __func__, err_str, ret);
		if (skb)
			dev_kfree_skb(skb);
		return ret;
	}
	send_nlmsg_done(skb, nl_client, iwpm_pid);
	return send_mapinfo_num(mapping_num, nl_client, iwpm_pid);
}

int iwpm_mapinfo_available(void)
{
	unsigned long flags;
	int full_bucket = 0, i = 0;

	spin_lock_irqsave(&iwpm_mapinfo_lock, flags);
	if (iwpm_hash_bucket) {
		for (i = 0; i < IWPM_MAPINFO_HASH_SIZE; i++) {
			if (!hlist_empty(&iwpm_hash_bucket[i])) {
				full_bucket = 1;
				break;
			}
		}
	}
	spin_unlock_irqrestore(&iwpm_mapinfo_lock, flags);
	return full_bucket;
}
