/*
 *	Fastpath Netlink Interface
 *
 *	This program is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU FP_ERR( Public License
 *	as published by the Free Software Foundation; either version
 *	2 of the License, or (at your option) any later version.
 */

#define pr_fmt(fmt) "mfp" " netlink:%s:%d: " fmt, __func__, __LINE__

#include "fp_common.h"
#include "fp_core.h"
#include "fp_netlink.h"

struct nla_policy fp_netlink_policy[FASTPATH_NL_A_MAX + 1] __maybe_unused = {
	[FASTPATH_NL_A_MSG] = { .type = NLA_NUL_STRING },
};

/* Optional: Add rule parsing to avoid blocking all entries */
static int fp_netlink_ipt_notify(struct sk_buff *skb, struct genl_info *info)
{
	struct fastpath_module *m = fp_module_get_by_name("fp_learner");
	int ret = -EINVAL;

	if (!m) {
		pr_err("failed to get fp_learner module\n");
		return -EINVAL;
	}

	if (m->ops && m->ops->ioctl) {
		ret = m->ops->ioctl(m, FASTPATH_NL_C_IPT_NOTIFY, NULL);
		goto out;
	}

out:
	fp_module_put(m);
	return ret;
}

static struct genl_ops fp_netlink_genl_ops[] = {
	FASTPATH_NL_OP(FASTPATH_NL_C_IPT_NOTIFY, fp_netlink_ipt_notify),
};

static struct genl_family fp_netlink_family = {
	.hdrsize = 0,
	.name = "FASTPATH",
	.version = 1,
	.maxattr = FASTPATH_NL_A_MAX,
	.ops     = fp_netlink_genl_ops,
	.n_ops   = ARRAY_SIZE(fp_netlink_genl_ops),
};

static struct attribute *fp_netlink_attrs[] = {
	NULL, /* need to NULL terminate the list of attributes */
};

static void fp_netlink_release(struct kobject *kobj)
{
	struct fastpath_module *module = to_fpmod(kobj);

	genl_unregister_family(&fp_netlink_family);

	pr_debug("fp_netlink released\n");
	kfree(module);
}

static struct kobj_type ktype_netlink = {
	.sysfs_ops	= &fp_sysfs_ops,
	.default_attrs	= fp_netlink_attrs,
	.release	= fp_netlink_release,
};

static int fp_netlink_probe(struct fastpath_module *module)
{
	int ret;


	module->priv = NULL;
	snprintf(module->name, sizeof(module->name),"fp_netlink");

	ret = genl_register_family(&fp_netlink_family);

	kobject_init(&module->kobj, &ktype_netlink);
	ret = kobject_add(&module->kobj, module->fastpath->kobj, "%s", module->name);
	if (ret < 0) {
		pr_err("kobject_add failed (%d)\n", ret);
		goto err_register_ops;
	}

	kobject_uevent(&module->kobj, KOBJ_ADD);

	pr_debug("fp_netlink probed\n");
	return 0;

err_register_ops:
	kobject_put(&module->kobj);
	genl_unregister_family(&fp_netlink_family);

	return ret;
}

static int fp_netlink_remove(struct fastpath_module *module)
{
	kobject_put(&module->kobj);

	pr_debug("fp_netlink removed\n");
	return 0;
}

struct fastpath_module_ops fp_netlink_ops = {
	.probe = fp_netlink_probe,
	.remove = fp_netlink_remove,
};
