ASR_BASE

Change-Id: Icf3719cc0afe3eeb3edc7fa80a2eb5199ca9dda1
diff --git a/package/kernel/mfp/files/fp_netlink.c b/package/kernel/mfp/files/fp_netlink.c
new file mode 100644
index 0000000..3237881
--- /dev/null
+++ b/package/kernel/mfp/files/fp_netlink.c
@@ -0,0 +1,114 @@
+/*
+ *	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,
+};