/*
 **************************************************************************
 * Copyright (c) 2020, The Linux Foundation. All rights reserved.
 *
 * Permission to use, copy, modify, and/or distribute this software for
 * any purpose with or without fee is hereby granted, provided that the
 * above copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 **************************************************************************
 */

/*
 * nss_nln2h.c
 *      NSS Netlink n2h Handler
 */
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/netlink.h>
#include <linux/version.h>
#include <linux/vmalloc.h>
#include <linux/notifier.h>

#include <net/genetlink.h>
#include <net/sock.h>

#include <nss_api_if.h>
#include <nss_cmn.h>
#include <nss_nl_if.h>
#include "nss_nl.h"
#include "nss_nlcmn_if.h"
#include "nss_nln2h_if.h"
#include "nss_n2h.h"

/*
 * prototypes
 */
static int nss_nln2h_ops_get_stats(struct sk_buff *skb, struct genl_info *info);
static int nss_nln2h_process_notify(struct notifier_block *nb,  unsigned long val, void *data);

/*
 * multicast group for sending message status & events
 */
static const struct genl_multicast_group nss_nln2h_mcgrp[] = {
	{.name = NSS_NLN2H_MCAST_GRP},
};

/*
 * operation table called by the generic netlink layer based on the command
 */
static struct genl_ops nss_nln2h_ops[] = {
	{.cmd = NSS_STATS_EVENT_NOTIFY, .doit = nss_nln2h_ops_get_stats},
};

/*
 * n2h family definition
 */
static struct genl_family nss_nln2h_family = {
#if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 9, 0))
	.id = GENL_ID_GENERATE,					/* Auto generate ID */
#endif
	.name = NSS_NLN2H_FAMILY,				/* family name string */
	.hdrsize = sizeof(struct nss_n2h_stats_notification),	/* NSS NETLINK n2h stats */
	.version = NSS_NL_VER,					/* Set it to NSS_NLN2H version */
	.maxattr = NSS_STATS_EVENT_MAX,				/* maximum commands supported */
	.netnsok = true,
	.pre_doit = NULL,
	.post_doit = NULL,
	.ops = nss_nln2h_ops,
	.n_ops = ARRAY_SIZE(nss_nln2h_ops),
	.mcgrps = nss_nln2h_mcgrp,
	.n_mcgrps = ARRAY_SIZE(nss_nln2h_mcgrp)
};

/*
 * stats call back handler for n2h from NSS
 */
static struct notifier_block nss_n2h_stats_notifier_nb = {
	.notifier_call = nss_nln2h_process_notify,
};

/*
 * nss_nln2h_ops_get_stats()
 *	get stats handler
 */
static int nss_nln2h_ops_get_stats(struct sk_buff *skb, struct genl_info *info)
{
	return 0;
}

/*
 * nss_nln2h_process_notify()
 *	process notification messages from NSS
 */
static int nss_nln2h_process_notify(struct notifier_block *nb,	unsigned long val, void *data)
{
	struct sk_buff *skb;
	struct nss_n2h_stats_notification *nss_stats, *nl_stats;

	skb = nss_nl_new_msg(&nss_nln2h_family, NSS_NLCMN_SUBSYS_N2H);
	if (!skb) {
		nss_nl_error("unable to allocate NSS_NLN2H event\n");
		return NOTIFY_DONE;
	}

	nl_stats = nss_nl_get_data(skb);
	nss_stats = (struct nss_n2h_stats_notification *)data;
	memcpy(nl_stats, nss_stats, sizeof(struct nss_n2h_stats_notification));
	nss_nl_mcast_event(&nss_nln2h_family, skb);

	return NOTIFY_DONE;
}

/*
 * nss_nln2h_init()
 *	handler init
 */
bool nss_nln2h_init(void)
{
	int error,ret;

	nss_nl_info_always("Init NSS netlink n2h handler\n");

	/*
	 * register NETLINK ops with the family
	 */
	error = genl_register_family(&nss_nln2h_family);
	if (error) {
		nss_nl_info_always("Error: unable to register n2h family\n");
		return false;
	}

	/*
	 * register device call back handler for n2h from NSS
	 */
	ret = nss_n2h_stats_register_notifier(&nss_n2h_stats_notifier_nb);
	if (ret) {
		nss_nl_info_always("Error: retreiving the NSS Context\n");
		genl_unregister_family(&nss_nln2h_family);
		return false;
	}

	return true;
}

/*
 * nss_nln2h_exit()
 *	handler exit
 */
bool nss_nln2h_exit(void)
{
	int error;

	nss_nl_info_always("Exit NSS netlink n2h handler\n");

	/*
	 * Unregister the device callback handler for n2h
	 */
	nss_n2h_stats_unregister_notifier(&nss_n2h_stats_notifier_nb);

	/*
	 * unregister the ops family
	 */
	error = genl_unregister_family(&nss_nln2h_family);
	if (error) {
		nss_nl_info_always("unable to unregister n2h NETLINK family\n");
		return false;
	}

	return true;
}
