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,
+};