* [PATCH] netfilter: xtables: userspace notification target
@ 2010-07-13 0:11 Samuel Ortiz
2010-07-13 5:56 ` Jan Engelhardt
` (2 more replies)
0 siblings, 3 replies; 16+ messages in thread
From: Samuel Ortiz @ 2010-07-13 0:11 UTC (permalink / raw)
To: Patrick McHardy, David S. Miller; +Cc: netdev, netfilter-devel, Luciano Coelho
The userspace notification Xtables target sends a netlink notification
whenever a packet hits the target. Notifications have a label attribute
for userspace to match it against a previously set rule. The rules also
take a --all option to switch between sending a notification for all
packets or for the first one only.
Userspace can also send a netlink message to toggle this switch while the
target is in place. This target uses the nefilter netlink framework.
This target combined with various matches (quota, rateest, etc..) allows
userspace to make decisions on interfaces handling. One could for example
decide to switch between power saving modes depending on estimated rate
thresholds.
Reviewed-by: Luciano Coelho <luciano.coelho@nokia.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
---
include/linux/netfilter/Kbuild | 1 +
include/linux/netfilter/nfnetlink.h | 5 +-
include/linux/netfilter/nfnetlink_compat.h | 1 +
include/linux/netfilter/xt_NFNOTIF.h | 55 +++++
net/netfilter/Kconfig | 17 ++
net/netfilter/Makefile | 1 +
net/netfilter/xt_NFNOTIF.c | 300 ++++++++++++++++++++++++++++
7 files changed, 379 insertions(+), 1 deletions(-)
create mode 100644 include/linux/netfilter/xt_NFNOTIF.h
create mode 100644 net/netfilter/xt_NFNOTIF.c
diff --git a/include/linux/netfilter/Kbuild b/include/linux/netfilter/Kbuild
index bb103f4..1b80b27 100644
--- a/include/linux/netfilter/Kbuild
+++ b/include/linux/netfilter/Kbuild
@@ -12,6 +12,7 @@ header-y += xt_IDLETIMER.h
header-y += xt_LED.h
header-y += xt_MARK.h
header-y += xt_NFLOG.h
+header-y += xt_NFNOTIF.h
header-y += xt_NFQUEUE.h
header-y += xt_RATEEST.h
header-y += xt_SECMARK.h
diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h
index 361d6b5..e336f03 100644
--- a/include/linux/netfilter/nfnetlink.h
+++ b/include/linux/netfilter/nfnetlink.h
@@ -18,6 +18,8 @@ enum nfnetlink_groups {
#define NFNLGRP_CONNTRACK_EXP_UPDATE NFNLGRP_CONNTRACK_EXP_UPDATE
NFNLGRP_CONNTRACK_EXP_DESTROY,
#define NFNLGRP_CONNTRACK_EXP_DESTROY NFNLGRP_CONNTRACK_EXP_DESTROY
+ NFNLGRP_NFNOTIF,
+#define NFNLGRP_NFNOTIF NFNLGRP_NFNOTIF
__NFNLGRP_MAX,
};
#define NFNLGRP_MAX (__NFNLGRP_MAX - 1)
@@ -47,7 +49,8 @@ struct nfgenmsg {
#define NFNL_SUBSYS_QUEUE 3
#define NFNL_SUBSYS_ULOG 4
#define NFNL_SUBSYS_OSF 5
-#define NFNL_SUBSYS_COUNT 6
+#define NFNL_SUBSYS_NFNOTIF 6
+#define NFNL_SUBSYS_COUNT 7
#ifdef __KERNEL__
diff --git a/include/linux/netfilter/nfnetlink_compat.h b/include/linux/netfilter/nfnetlink_compat.h
index ffb9503..dca8ab2 100644
--- a/include/linux/netfilter/nfnetlink_compat.h
+++ b/include/linux/netfilter/nfnetlink_compat.h
@@ -13,6 +13,7 @@
#define NF_NETLINK_CONNTRACK_EXP_NEW 0x00000008
#define NF_NETLINK_CONNTRACK_EXP_UPDATE 0x00000010
#define NF_NETLINK_CONNTRACK_EXP_DESTROY 0x00000020
+#define NF_NETLINK_NFNOTIF 0x00000040
/* Generic structure for encapsulation optional netfilter information.
* It is reminiscent of sockaddr, but with sa_family replaced
diff --git a/include/linux/netfilter/xt_NFNOTIF.h b/include/linux/netfilter/xt_NFNOTIF.h
new file mode 100644
index 0000000..8fae827
--- /dev/null
+++ b/include/linux/netfilter/xt_NFNOTIF.h
@@ -0,0 +1,55 @@
+/*
+ * linux/include/linux/netfilter/xt_NFNOTIF.h
+ *
+ * Header file for Xtables notification target module.
+ *
+ * Copyright (C) 2010 Intel Corporation
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef _XT_NFNOTIF_H
+#define _XT_NFNOTIF_H
+
+#include <linux/types.h>
+
+enum nfnotif_msg_type {
+ NFNOTIF_TG_MSG_PACKETS,
+
+ NFNOTIF_TG_MSG_MAX
+};
+
+enum nfnotif_attr_type {
+ NFNOTIF_TG_ATTR_UNSPEC,
+ NFNOTIF_TG_ATTR_LABEL,
+ NFNOTIF_TG_ATTR_SEND_NOTIF,
+
+ __NFNOTIF_TG_ATTR_AFTER_LAST
+};
+#define NFNOTIF_TG_ATTR_MAX (__NFNOTIF_TG_ATTR_AFTER_LAST - 1)
+
+#define MAX_NFNOTIF_LABEL_SIZE 31
+
+struct nfnotif_tg_info {
+ __u8 all_packets;
+
+ char label[MAX_NFNOTIF_LABEL_SIZE];
+
+ /* for kernel module internal use only */
+ struct nfnotif_tg *notif __attribute((aligned(8)));
+};
+
+#endif
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index aa2f106..0e2de36 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -469,6 +469,23 @@ config NETFILTER_XT_TARGET_NFQUEUE
To compile it as a module, choose M here. If unsure, say N.
+config NETFILTER_XT_TARGET_NFNOTIF
+ tristate '"NFNOTIF" target Support'
+ depends on NETFILTER_ADVANCED
+ select NETFILTER_NETLINK
+ help
+
+ This option adds the `NFNOTIF' target, which allows to send
+ netfilter netlink messages when packets hit the target.
+
+ This target comes with an option to specify if one wants all
+ packets hitting the target to trigger the netlink message
+ transmission, or only the first one.
+ It also listen on its netfilter netlink subsystem for messages
+ allowing to reset the above option.
+
+ To compile it as a module, choose M here. If unsure, say N.
+
config NETFILTER_XT_TARGET_NOTRACK
tristate '"NOTRACK" target support'
depends on IP_NF_RAW || IP6_NF_RAW
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index e28420a..5d9c9e9 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -62,6 +62,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP) += xt_TCPOPTSTRIP.o
obj-$(CONFIG_NETFILTER_XT_TARGET_TEE) += xt_TEE.o
obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o
obj-$(CONFIG_NETFILTER_XT_TARGET_IDLETIMER) += xt_IDLETIMER.o
+obj-$(CONFIG_NETFILTER_XT_TARGET_NFNOTIF) += xt_NFNOTIF.o
# matches
obj-$(CONFIG_NETFILTER_XT_MATCH_CLUSTER) += xt_cluster.o
diff --git a/net/netfilter/xt_NFNOTIF.c b/net/netfilter/xt_NFNOTIF.c
new file mode 100644
index 0000000..e6e906b
--- /dev/null
+++ b/net/netfilter/xt_NFNOTIF.c
@@ -0,0 +1,300 @@
+/*
+ * linux/net/netfilter/xt_NFNOTIF.c
+ *
+ * Copyright (C) 2010 Intel Corporation
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/netfilter.h>
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter/nfnetlink.h>
+#include <linux/netfilter/xt_NFNOTIF.h>
+
+struct nfnotif_tg {
+ struct list_head entry;
+ struct work_struct work;
+
+ char *label;
+ __u8 all_packets;
+ struct net *net;
+
+ __u8 send_notif;
+
+ unsigned int refcnt;
+};
+
+static LIST_HEAD(nfnotif_tg_list);
+static DEFINE_MUTEX(list_mutex);
+
+static int __nfnotif_tg_netlink_send(struct nfnotif_tg *nfnotif)
+{
+ struct nlmsghdr *nlh;
+ struct nfgenmsg *nfmsg;
+ struct sk_buff *skb;
+ struct net *net = nfnotif->net;
+ unsigned int type;
+ int flags;
+
+ type = NFNL_SUBSYS_NFNOTIF << 8;
+ flags = NLM_F_CREATE;
+
+ skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+ if (skb == NULL)
+ goto error_out;
+
+ nlh = nlmsg_put(skb, 0, 0, type, sizeof(*nfmsg), flags);
+ if (nlh == NULL)
+ goto nlmsg_put_failure;
+
+ nfmsg = nlmsg_data(nlh);
+ nfmsg->version = NFNETLINK_V0;
+ nfmsg->res_id = 0;
+
+ NLA_PUT_STRING(skb, NFNOTIF_TG_ATTR_LABEL, nfnotif->label);
+
+ nlmsg_end(skb, nlh);
+
+ return nfnetlink_send(skb, net, 0, NFNLGRP_NFNOTIF, 0, GFP_KERNEL);
+
+nla_put_failure:
+ nlmsg_cancel(skb, nlh);
+
+nlmsg_put_failure:
+ kfree_skb(skb);
+
+error_out:
+ return nfnetlink_set_err(net, 0, 0, -ENOBUFS);
+}
+
+static void nfnotif_tg_work(struct work_struct *work)
+{
+ struct nfnotif_tg *notif = container_of(work, struct nfnotif_tg, work);
+
+
+ if (__nfnotif_tg_netlink_send(notif) < 0)
+ pr_debug("Could not send notification");
+
+ if (!notif->all_packets)
+ notif->send_notif = 0;
+}
+
+static struct nfnotif_tg *__nfnotif_tg_find_by_label(const char *label)
+{
+ struct nfnotif_tg *entry;
+
+ BUG_ON(!label);
+
+ list_for_each_entry(entry, &nfnotif_tg_list, entry) {
+ if (!strcmp(label, entry->label))
+ return entry;
+ }
+
+ return NULL;
+}
+
+static int nfnotif_tg_create(struct nfnotif_tg_info *info)
+{
+ info->notif = kmalloc(sizeof(*info->notif), GFP_KERNEL);
+ if (!info->notif) {
+ pr_debug("Couldn't allocate notification\n");
+ return -ENOMEM;
+ }
+
+ info->notif->label = kstrdup(info->label, GFP_KERNEL);
+ if (!info->notif->label) {
+ pr_debug("Couldn't allocate label\n");
+ kfree(info->notif);
+ return -ENOMEM;
+ }
+
+ info->notif->all_packets = info->all_packets;
+ info->notif->send_notif = 1;
+
+ list_add(&info->notif->entry, &nfnotif_tg_list);
+
+ info->notif->refcnt = 1;
+
+ INIT_WORK(&info->notif->work, nfnotif_tg_work);
+
+ return 0;
+}
+
+static unsigned int nfnotif_tg_target(struct sk_buff *skb,
+ const struct xt_action_param *par)
+{
+ const struct nfnotif_tg_info *info = par->targinfo;
+
+ BUG_ON(!info->notif);
+
+ if (!info->notif->send_notif)
+ return XT_CONTINUE;
+
+ pr_debug("Sending notification for %s\n", info->label);
+
+ schedule_work(&info->notif->work);
+
+ return XT_CONTINUE;
+}
+
+static int nfnotif_tg_checkentry(const struct xt_tgchk_param *par)
+{
+ struct nfnotif_tg_info *info = par->targinfo;
+ int ret;
+
+ pr_debug("Checkentry targinfo %s\n", info->label);
+
+ if (info->label[0] == '\0' ||
+ strnlen(info->label,
+ MAX_NFNOTIF_LABEL_SIZE) == MAX_NFNOTIF_LABEL_SIZE) {
+ pr_debug("Label is empty or not nul-terminated\n");
+ return -EINVAL;
+ }
+
+ mutex_lock(&list_mutex);
+
+ info->notif = __nfnotif_tg_find_by_label(info->label);
+ if (info->notif) {
+ info->notif->refcnt++;
+
+ pr_debug("Increased refcnt for %s to %u\n",
+ info->label, info->notif->refcnt);
+ } else {
+ ret = nfnotif_tg_create(info);
+ if (ret < 0) {
+ pr_debug("Failed to create notification\n");
+ mutex_unlock(&list_mutex);
+ return ret;
+ }
+ }
+
+ info->notif->net = par->net;
+
+ mutex_unlock(&list_mutex);
+ return 0;
+}
+
+static void nfnotif_tg_destroy(const struct xt_tgdtor_param *par)
+{
+ const struct nfnotif_tg_info *info = par->targinfo;
+
+ pr_debug("Destroy targinfo %s\n", info->label);
+
+ mutex_lock(&list_mutex);
+
+ if (--info->notif->refcnt == 0) {
+ pr_debug("Deleting notification %s\n", info->label);
+
+ list_del(&info->notif->entry);
+ kfree(info->notif->label);
+ kfree(info->notif);
+ }
+
+ mutex_unlock(&list_mutex);
+}
+
+static struct xt_target nfnotif_tg __read_mostly = {
+ .name = "NFNOTIF",
+ .family = NFPROTO_UNSPEC,
+ .target = nfnotif_tg_target,
+ .targetsize = sizeof(struct nfnotif_tg_info),
+ .checkentry = nfnotif_tg_checkentry,
+ .destroy = nfnotif_tg_destroy,
+ .me = THIS_MODULE,
+};
+
+static int nfnotif_msg_send_notif(struct sock *nfnl, struct sk_buff *skb,
+ const struct nlmsghdr *nlh,
+ const struct nlattr * const attrs[])
+{
+ struct nfnotif_tg *notif;
+ char *label;
+ u8 send_notif;
+
+ if (attrs[NFNOTIF_TG_ATTR_LABEL] == NULL ||
+ attrs[NFNOTIF_TG_ATTR_SEND_NOTIF] == NULL)
+ return -EINVAL;
+
+ label = nla_data(attrs[NFNOTIF_TG_ATTR_LABEL]);
+ send_notif = nla_get_u8(attrs[NFNOTIF_TG_ATTR_SEND_NOTIF]);
+
+ pr_debug("Label %s send %d\n", label, send_notif);
+
+ notif = __nfnotif_tg_find_by_label(label);
+ if (notif == NULL)
+ return -EINVAL;
+
+ notif->send_notif = send_notif;
+
+ return 0;
+}
+
+
+static const struct nla_policy nfnotif_nla_policy[NFNOTIF_TG_ATTR_MAX + 1] = {
+ [NFNOTIF_TG_ATTR_LABEL] = { .type = NLA_NUL_STRING },
+ [NFNOTIF_TG_ATTR_SEND_NOTIF] = { .type = NLA_U8 },
+};
+
+static const struct nfnl_callback nfnotif_cb[NFNOTIF_TG_MSG_MAX] = {
+ [NFNOTIF_TG_MSG_PACKETS] = { .call = nfnotif_msg_send_notif,
+ .attr_count = NFNOTIF_TG_ATTR_MAX,
+ .policy = nfnotif_nla_policy },
+};
+
+static const struct nfnetlink_subsystem nfnotif_subsys = {
+ .name = "nfnotif",
+ .subsys_id = NFNL_SUBSYS_NFNOTIF,
+ .cb_count = NFNOTIF_TG_MSG_MAX,
+ .cb = nfnotif_cb,
+};
+
+static int __init nfnotif_tg_init(void)
+{
+ int ret;
+
+ ret = nfnetlink_subsys_register(&nfnotif_subsys);
+ if (ret < 0) {
+ pr_err("%s: Cannot register with nfnetlink\n", __func__);
+ return ret;
+ }
+
+ ret = xt_register_target(&nfnotif_tg);
+ if (ret < 0) {
+ pr_err("%s: Cannot register target\n", __func__);
+ nfnetlink_subsys_unregister(&nfnotif_subsys);
+ }
+
+ return ret;
+}
+
+static void __exit nfnotif_tg_exit(void)
+{
+ nfnetlink_subsys_unregister(&nfnotif_subsys);
+ xt_unregister_target(&nfnotif_tg);
+}
+
+module_init(nfnotif_tg_init);
+module_exit(nfnotif_tg_exit);
+
+MODULE_AUTHOR("Samuel Ortiz <samuel.ortiz@intel.com>");
+MODULE_DESCRIPTION("Xtables: userspace notification");
+MODULE_LICENSE("GPL v2");
--
1.7.1
--
Intel Open Source Technology Centre
http://oss.intel.com/
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH] netfilter: xtables: userspace notification target
2010-07-13 0:11 [PATCH] netfilter: xtables: userspace notification target Samuel Ortiz
@ 2010-07-13 5:56 ` Jan Engelhardt
2010-07-13 13:19 ` Samuel Ortiz
2010-07-13 6:18 ` Changli Gao
2010-07-13 14:57 ` [PATCH v2] " Samuel Ortiz
2 siblings, 1 reply; 16+ messages in thread
From: Jan Engelhardt @ 2010-07-13 5:56 UTC (permalink / raw)
To: Samuel Ortiz
Cc: Patrick McHardy, David S. Miller, netdev, netfilter-devel,
Luciano Coelho
On Tuesday 2010-07-13 02:11, Samuel Ortiz wrote:
>
>The userspace notification Xtables target sends a netlink notification
>whenever a packet hits the target. Notifications have a label attribute
>for userspace to match it against a previously set rule. The rules also
>take a --all option to switch between sending a notification for all
>packets or for the first one only.
>Userspace can also send a netlink message to toggle this switch while the
>target is in place. This target uses the nefilter netlink framework.
Would it not make sense to modify that module?
Sounds an awful lot like NFQUEUE without passing the payload :)
>+++ b/net/netfilter/xt_NFNOTIF.c
>+struct nfnotif_tg {
>+ struct list_head entry;
>+ struct work_struct work;
>+
>+ char *label;
>+ __u8 all_packets;
>+ struct net *net;
>+
>+ __u8 send_notif;
>+
>+ unsigned int refcnt;
>+};
Has unnecessary padding holes.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] netfilter: xtables: userspace notification target
2010-07-13 0:11 [PATCH] netfilter: xtables: userspace notification target Samuel Ortiz
2010-07-13 5:56 ` Jan Engelhardt
@ 2010-07-13 6:18 ` Changli Gao
2010-07-13 8:50 ` Pablo Neira Ayuso
2010-07-13 13:28 ` Samuel Ortiz
2010-07-13 14:57 ` [PATCH v2] " Samuel Ortiz
2 siblings, 2 replies; 16+ messages in thread
From: Changli Gao @ 2010-07-13 6:18 UTC (permalink / raw)
To: Samuel Ortiz
Cc: Patrick McHardy, David S. Miller, netdev, netfilter-devel,
Luciano Coelho
On Tue, Jul 13, 2010 at 8:11 AM, Samuel Ortiz <sameo@linux.intel.com> wrote:
>
> The userspace notification Xtables target sends a netlink notification
> whenever a packet hits the target. Notifications have a label attribute
> for userspace to match it against a previously set rule. The rules also
> take a --all option to switch between sending a notification for all
> packets or for the first one only.
> Userspace can also send a netlink message to toggle this switch while the
> target is in place. This target uses the nefilter netlink framework.
>
> This target combined with various matches (quota, rateest, etc..) allows
> userspace to make decisions on interfaces handling. One could for example
> decide to switch between power saving modes depending on estimated rate
> thresholds.
>
It much like the following iptables rules.
iptables -N log_and_drop
iptables -A log_and_drop -j NFLOG --nflog-group 1 --nflog-prefix "log_and_drop"
iptables -A log_and_drop -j DROP
...
iptables ... -m quota --quota-bytes 20000 -j log_and_drop
...
> include/linux/netfilter/Kbuild | 1 +
> include/linux/netfilter/nfnetlink.h | 5 +-
> include/linux/netfilter/nfnetlink_compat.h | 1 +
> include/linux/netfilter/xt_NFNOTIF.h | 55 +++++
> net/netfilter/Kconfig | 17 ++
> net/netfilter/Makefile | 1 +
> net/netfilter/xt_NFNOTIF.c | 300 ++++++++++++++++++++++++++++
> 7 files changed, 379 insertions(+), 1 deletions(-)
> create mode 100644 include/linux/netfilter/xt_NFNOTIF.h
> create mode 100644 net/netfilter/xt_NFNOTIF.c
>
> diff --git a/include/linux/netfilter/Kbuild b/include/linux/netfilter/Kbuild
> index bb103f4..1b80b27 100644
> --- a/include/linux/netfilter/Kbuild
> +++ b/include/linux/netfilter/Kbuild
> @@ -12,6 +12,7 @@ header-y += xt_IDLETIMER.h
> header-y += xt_LED.h
> header-y += xt_MARK.h
> header-y += xt_NFLOG.h
> +header-y += xt_NFNOTIF.h
> header-y += xt_NFQUEUE.h
> header-y += xt_RATEEST.h
> header-y += xt_SECMARK.h
> diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h
> index 361d6b5..e336f03 100644
> --- a/include/linux/netfilter/nfnetlink.h
> +++ b/include/linux/netfilter/nfnetlink.h
> @@ -18,6 +18,8 @@ enum nfnetlink_groups {
> #define NFNLGRP_CONNTRACK_EXP_UPDATE NFNLGRP_CONNTRACK_EXP_UPDATE
> NFNLGRP_CONNTRACK_EXP_DESTROY,
> #define NFNLGRP_CONNTRACK_EXP_DESTROY NFNLGRP_CONNTRACK_EXP_DESTROY
> + NFNLGRP_NFNOTIF,
> +#define NFNLGRP_NFNOTIF NFNLGRP_NFNOTIF
> __NFNLGRP_MAX,
> };
> #define NFNLGRP_MAX (__NFNLGRP_MAX - 1)
> @@ -47,7 +49,8 @@ struct nfgenmsg {
> #define NFNL_SUBSYS_QUEUE 3
> #define NFNL_SUBSYS_ULOG 4
> #define NFNL_SUBSYS_OSF 5
> -#define NFNL_SUBSYS_COUNT 6
> +#define NFNL_SUBSYS_NFNOTIF 6
> +#define NFNL_SUBSYS_COUNT 7
>
> #ifdef __KERNEL__
>
> diff --git a/include/linux/netfilter/nfnetlink_compat.h b/include/linux/netfilter/nfnetlink_compat.h
> index ffb9503..dca8ab2 100644
> --- a/include/linux/netfilter/nfnetlink_compat.h
> +++ b/include/linux/netfilter/nfnetlink_compat.h
> @@ -13,6 +13,7 @@
> #define NF_NETLINK_CONNTRACK_EXP_NEW 0x00000008
> #define NF_NETLINK_CONNTRACK_EXP_UPDATE 0x00000010
> #define NF_NETLINK_CONNTRACK_EXP_DESTROY 0x00000020
> +#define NF_NETLINK_NFNOTIF 0x00000040
>
> /* Generic structure for encapsulation optional netfilter information.
> * It is reminiscent of sockaddr, but with sa_family replaced
> diff --git a/include/linux/netfilter/xt_NFNOTIF.h b/include/linux/netfilter/xt_NFNOTIF.h
> new file mode 100644
> index 0000000..8fae827
> --- /dev/null
> +++ b/include/linux/netfilter/xt_NFNOTIF.h
> @@ -0,0 +1,55 @@
> +/*
> + * linux/include/linux/netfilter/xt_NFNOTIF.h
> + *
> + * Header file for Xtables notification target module.
> + *
> + * Copyright (C) 2010 Intel Corporation
> + * Samuel Ortiz <samuel.ortiz@intel.com>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License version
> + * 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> + * 02110-1301, USA.
> + */
> +
> +#ifndef _XT_NFNOTIF_H
> +#define _XT_NFNOTIF_H
> +
> +#include <linux/types.h>
> +
> +enum nfnotif_msg_type {
> + NFNOTIF_TG_MSG_PACKETS,
> +
> + NFNOTIF_TG_MSG_MAX
> +};
> +
> +enum nfnotif_attr_type {
> + NFNOTIF_TG_ATTR_UNSPEC,
> + NFNOTIF_TG_ATTR_LABEL,
> + NFNOTIF_TG_ATTR_SEND_NOTIF,
> +
> + __NFNOTIF_TG_ATTR_AFTER_LAST
> +};
> +#define NFNOTIF_TG_ATTR_MAX (__NFNOTIF_TG_ATTR_AFTER_LAST - 1)
> +
> +#define MAX_NFNOTIF_LABEL_SIZE 31
> +
> +struct nfnotif_tg_info {
> + __u8 all_packets;
> +
> + char label[MAX_NFNOTIF_LABEL_SIZE];
> +
> + /* for kernel module internal use only */
> + struct nfnotif_tg *notif __attribute((aligned(8)));
> +};
> +
> +#endif
> diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
> index aa2f106..0e2de36 100644
> --- a/net/netfilter/Kconfig
> +++ b/net/netfilter/Kconfig
> @@ -469,6 +469,23 @@ config NETFILTER_XT_TARGET_NFQUEUE
>
> To compile it as a module, choose M here. If unsure, say N.
>
> +config NETFILTER_XT_TARGET_NFNOTIF
> + tristate '"NFNOTIF" target Support'
> + depends on NETFILTER_ADVANCED
> + select NETFILTER_NETLINK
> + help
> +
> + This option adds the `NFNOTIF' target, which allows to send
> + netfilter netlink messages when packets hit the target.
> +
> + This target comes with an option to specify if one wants all
> + packets hitting the target to trigger the netlink message
> + transmission, or only the first one.
> + It also listen on its netfilter netlink subsystem for messages
> + allowing to reset the above option.
> +
> + To compile it as a module, choose M here. If unsure, say N.
> +
> config NETFILTER_XT_TARGET_NOTRACK
> tristate '"NOTRACK" target support'
> depends on IP_NF_RAW || IP6_NF_RAW
> diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
> index e28420a..5d9c9e9 100644
> --- a/net/netfilter/Makefile
> +++ b/net/netfilter/Makefile
> @@ -62,6 +62,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP) += xt_TCPOPTSTRIP.o
> obj-$(CONFIG_NETFILTER_XT_TARGET_TEE) += xt_TEE.o
> obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o
> obj-$(CONFIG_NETFILTER_XT_TARGET_IDLETIMER) += xt_IDLETIMER.o
> +obj-$(CONFIG_NETFILTER_XT_TARGET_NFNOTIF) += xt_NFNOTIF.o
>
> # matches
> obj-$(CONFIG_NETFILTER_XT_MATCH_CLUSTER) += xt_cluster.o
> diff --git a/net/netfilter/xt_NFNOTIF.c b/net/netfilter/xt_NFNOTIF.c
> new file mode 100644
> index 0000000..e6e906b
> --- /dev/null
> +++ b/net/netfilter/xt_NFNOTIF.c
> @@ -0,0 +1,300 @@
> +/*
> + * linux/net/netfilter/xt_NFNOTIF.c
> + *
> + * Copyright (C) 2010 Intel Corporation
> + * Samuel Ortiz <samuel.ortiz@intel.com>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License version
> + * 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> + * 02110-1301, USA.
> + *
> + */
> +
> +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> +
> +#include <linux/module.h>
> +#include <linux/list.h>
> +#include <linux/mutex.h>
> +#include <linux/netfilter.h>
> +#include <linux/netfilter/x_tables.h>
> +#include <linux/netfilter/nfnetlink.h>
> +#include <linux/netfilter/xt_NFNOTIF.h>
> +
> +struct nfnotif_tg {
> + struct list_head entry;
> + struct work_struct work;
> +
> + char *label;
> + __u8 all_packets;
> + struct net *net;
> +
> + __u8 send_notif;
> +
> + unsigned int refcnt;
> +};
> +
> +static LIST_HEAD(nfnotif_tg_list);
> +static DEFINE_MUTEX(list_mutex);
> +
> +static int __nfnotif_tg_netlink_send(struct nfnotif_tg *nfnotif)
> +{
> + struct nlmsghdr *nlh;
> + struct nfgenmsg *nfmsg;
> + struct sk_buff *skb;
> + struct net *net = nfnotif->net;
> + unsigned int type;
> + int flags;
> +
> + type = NFNL_SUBSYS_NFNOTIF << 8;
> + flags = NLM_F_CREATE;
> +
> + skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
> + if (skb == NULL)
> + goto error_out;
> +
> + nlh = nlmsg_put(skb, 0, 0, type, sizeof(*nfmsg), flags);
> + if (nlh == NULL)
> + goto nlmsg_put_failure;
> +
> + nfmsg = nlmsg_data(nlh);
> + nfmsg->version = NFNETLINK_V0;
> + nfmsg->res_id = 0;
> +
> + NLA_PUT_STRING(skb, NFNOTIF_TG_ATTR_LABEL, nfnotif->label);
> +
> + nlmsg_end(skb, nlh);
> +
> + return nfnetlink_send(skb, net, 0, NFNLGRP_NFNOTIF, 0, GFP_KERNEL);
> +
> +nla_put_failure:
> + nlmsg_cancel(skb, nlh);
> +
> +nlmsg_put_failure:
> + kfree_skb(skb);
> +
> +error_out:
> + return nfnetlink_set_err(net, 0, 0, -ENOBUFS);
> +}
> +
> +static void nfnotif_tg_work(struct work_struct *work)
> +{
> + struct nfnotif_tg *notif = container_of(work, struct nfnotif_tg, work);
> +
> +
> + if (__nfnotif_tg_netlink_send(notif) < 0)
> + pr_debug("Could not send notification");
> +
> + if (!notif->all_packets)
> + notif->send_notif = 0;
> +}
> +
> +static struct nfnotif_tg *__nfnotif_tg_find_by_label(const char *label)
> +{
> + struct nfnotif_tg *entry;
> +
> + BUG_ON(!label);
> +
> + list_for_each_entry(entry, &nfnotif_tg_list, entry) {
> + if (!strcmp(label, entry->label))
> + return entry;
> + }
> +
> + return NULL;
> +}
> +
> +static int nfnotif_tg_create(struct nfnotif_tg_info *info)
> +{
> + info->notif = kmalloc(sizeof(*info->notif), GFP_KERNEL);
> + if (!info->notif) {
> + pr_debug("Couldn't allocate notification\n");
> + return -ENOMEM;
> + }
> +
> + info->notif->label = kstrdup(info->label, GFP_KERNEL);
> + if (!info->notif->label) {
> + pr_debug("Couldn't allocate label\n");
> + kfree(info->notif);
> + return -ENOMEM;
> + }
> +
> + info->notif->all_packets = info->all_packets;
> + info->notif->send_notif = 1;
> +
> + list_add(&info->notif->entry, &nfnotif_tg_list);
> +
> + info->notif->refcnt = 1;
> +
> + INIT_WORK(&info->notif->work, nfnotif_tg_work);
> +
> + return 0;
> +}
> +
> +static unsigned int nfnotif_tg_target(struct sk_buff *skb,
> + const struct xt_action_param *par)
> +{
> + const struct nfnotif_tg_info *info = par->targinfo;
> +
> + BUG_ON(!info->notif);
> +
> + if (!info->notif->send_notif)
> + return XT_CONTINUE;
> +
> + pr_debug("Sending notification for %s\n", info->label);
> +
> + schedule_work(&info->notif->work);
> +
Why do you use another kernel activity: kernel thread? netlink
messages can be sent in atomic context.
> + return XT_CONTINUE;
> +}
> +
> +static int nfnotif_tg_checkentry(const struct xt_tgchk_param *par)
> +{
> + struct nfnotif_tg_info *info = par->targinfo;
> + int ret;
> +
> + pr_debug("Checkentry targinfo %s\n", info->label);
> +
> + if (info->label[0] == '\0' ||
> + strnlen(info->label,
> + MAX_NFNOTIF_LABEL_SIZE) == MAX_NFNOTIF_LABEL_SIZE) {
> + pr_debug("Label is empty or not nul-terminated\n");
> + return -EINVAL;
> + }
> +
> + mutex_lock(&list_mutex);
> +
> + info->notif = __nfnotif_tg_find_by_label(info->label);
> + if (info->notif) {
> + info->notif->refcnt++;
> +
> + pr_debug("Increased refcnt for %s to %u\n",
> + info->label, info->notif->refcnt);
> + } else {
> + ret = nfnotif_tg_create(info);
> + if (ret < 0) {
> + pr_debug("Failed to create notification\n");
> + mutex_unlock(&list_mutex);
> + return ret;
> + }
> + }
> +
> + info->notif->net = par->net;
> +
> + mutex_unlock(&list_mutex);
> + return 0;
> +}
> +
> +static void nfnotif_tg_destroy(const struct xt_tgdtor_param *par)
> +{
> + const struct nfnotif_tg_info *info = par->targinfo;
> +
> + pr_debug("Destroy targinfo %s\n", info->label);
> +
> + mutex_lock(&list_mutex);
> +
> + if (--info->notif->refcnt == 0) {
> + pr_debug("Deleting notification %s\n", info->label);
> +
> + list_del(&info->notif->entry);
> + kfree(info->notif->label);
> + kfree(info->notif);
> + }
> +
> + mutex_unlock(&list_mutex);
> +}
> +
> +static struct xt_target nfnotif_tg __read_mostly = {
> + .name = "NFNOTIF",
> + .family = NFPROTO_UNSPEC,
> + .target = nfnotif_tg_target,
> + .targetsize = sizeof(struct nfnotif_tg_info),
> + .checkentry = nfnotif_tg_checkentry,
> + .destroy = nfnotif_tg_destroy,
> + .me = THIS_MODULE,
> +};
> +
> +static int nfnotif_msg_send_notif(struct sock *nfnl, struct sk_buff *skb,
> + const struct nlmsghdr *nlh,
> + const struct nlattr * const attrs[])
> +{
> + struct nfnotif_tg *notif;
> + char *label;
> + u8 send_notif;
> +
> + if (attrs[NFNOTIF_TG_ATTR_LABEL] == NULL ||
> + attrs[NFNOTIF_TG_ATTR_SEND_NOTIF] == NULL)
> + return -EINVAL;
> +
> + label = nla_data(attrs[NFNOTIF_TG_ATTR_LABEL]);
> + send_notif = nla_get_u8(attrs[NFNOTIF_TG_ATTR_SEND_NOTIF]);
> +
> + pr_debug("Label %s send %d\n", label, send_notif);
> +
> + notif = __nfnotif_tg_find_by_label(label);
> + if (notif == NULL)
> + return -EINVAL;
> +
> + notif->send_notif = send_notif;
> +
> + return 0;
> +}
> +
> +
> +static const struct nla_policy nfnotif_nla_policy[NFNOTIF_TG_ATTR_MAX + 1] = {
> + [NFNOTIF_TG_ATTR_LABEL] = { .type = NLA_NUL_STRING },
> + [NFNOTIF_TG_ATTR_SEND_NOTIF] = { .type = NLA_U8 },
> +};
> +
> +static const struct nfnl_callback nfnotif_cb[NFNOTIF_TG_MSG_MAX] = {
> + [NFNOTIF_TG_MSG_PACKETS] = { .call = nfnotif_msg_send_notif,
> + .attr_count = NFNOTIF_TG_ATTR_MAX,
> + .policy = nfnotif_nla_policy },
> +};
> +
> +static const struct nfnetlink_subsystem nfnotif_subsys = {
> + .name = "nfnotif",
> + .subsys_id = NFNL_SUBSYS_NFNOTIF,
> + .cb_count = NFNOTIF_TG_MSG_MAX,
> + .cb = nfnotif_cb,
> +};
> +
> +static int __init nfnotif_tg_init(void)
> +{
> + int ret;
> +
> + ret = nfnetlink_subsys_register(&nfnotif_subsys);
> + if (ret < 0) {
> + pr_err("%s: Cannot register with nfnetlink\n", __func__);
> + return ret;
> + }
> +
> + ret = xt_register_target(&nfnotif_tg);
> + if (ret < 0) {
> + pr_err("%s: Cannot register target\n", __func__);
> + nfnetlink_subsys_unregister(&nfnotif_subsys);
> + }
> +
> + return ret;
> +}
> +
> +static void __exit nfnotif_tg_exit(void)
> +{
> + nfnetlink_subsys_unregister(&nfnotif_subsys);
> + xt_unregister_target(&nfnotif_tg);
> +}
> +
> +module_init(nfnotif_tg_init);
> +module_exit(nfnotif_tg_exit);
> +
> +MODULE_AUTHOR("Samuel Ortiz <samuel.ortiz@intel.com>");
> +MODULE_DESCRIPTION("Xtables: userspace notification");
> +MODULE_LICENSE("GPL v2");
> --
> 1.7.1
>
> --
> Intel Open Source Technology Centre
> http://oss.intel.com/
> --
> To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
--
Regards,
Changli Gao(xiaosuo@gmail.com)
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] netfilter: xtables: userspace notification target
2010-07-13 6:18 ` Changli Gao
@ 2010-07-13 8:50 ` Pablo Neira Ayuso
2010-07-13 10:23 ` Luciano Coelho
2010-07-13 13:28 ` Samuel Ortiz
1 sibling, 1 reply; 16+ messages in thread
From: Pablo Neira Ayuso @ 2010-07-13 8:50 UTC (permalink / raw)
To: Changli Gao
Cc: Samuel Ortiz, Patrick McHardy, David S. Miller, netdev,
netfilter-devel, Luciano Coelho
On 13/07/10 08:18, Changli Gao wrote:
> On Tue, Jul 13, 2010 at 8:11 AM, Samuel Ortiz <sameo@linux.intel.com> wrote:
>>
>> The userspace notification Xtables target sends a netlink notification
>> whenever a packet hits the target. Notifications have a label attribute
>> for userspace to match it against a previously set rule. The rules also
>> take a --all option to switch between sending a notification for all
>> packets or for the first one only.
>> Userspace can also send a netlink message to toggle this switch while the
>> target is in place. This target uses the nefilter netlink framework.
>>
>> This target combined with various matches (quota, rateest, etc..) allows
>> userspace to make decisions on interfaces handling. One could for example
>> decide to switch between power saving modes depending on estimated rate
>> thresholds.
>>
>
> It much like the following iptables rules.
>
> iptables -N log_and_drop
> iptables -A log_and_drop -j NFLOG --nflog-group 1 --nflog-prefix "log_and_drop"
> iptables -A log_and_drop -j DROP
>
> ...
> iptables ... -m quota --quota-bytes 20000 -j log_and_drop
> ...
Indeed, this looks to me like something that you can do with NFLOG and
some combination of matches.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] netfilter: xtables: userspace notification target
2010-07-13 8:50 ` Pablo Neira Ayuso
@ 2010-07-13 10:23 ` Luciano Coelho
2010-07-13 11:49 ` Jan Engelhardt
2010-07-13 16:38 ` Pablo Neira Ayuso
0 siblings, 2 replies; 16+ messages in thread
From: Luciano Coelho @ 2010-07-13 10:23 UTC (permalink / raw)
To: ext Pablo Neira Ayuso
Cc: Changli Gao, Samuel Ortiz, Patrick McHardy, David S. Miller,
netdev@vger.kernel.org, netfilter-devel@vger.kernel.org
On Tue, 2010-07-13 at 10:50 +0200, ext Pablo Neira Ayuso wrote:
> On 13/07/10 08:18, Changli Gao wrote:
> > On Tue, Jul 13, 2010 at 8:11 AM, Samuel Ortiz <sameo@linux.intel.com> wrote:
> >>
> >> The userspace notification Xtables target sends a netlink notification
> >> whenever a packet hits the target. Notifications have a label attribute
> >> for userspace to match it against a previously set rule. The rules also
> >> take a --all option to switch between sending a notification for all
> >> packets or for the first one only.
> >> Userspace can also send a netlink message to toggle this switch while the
> >> target is in place. This target uses the nefilter netlink framework.
> >>
> >> This target combined with various matches (quota, rateest, etc..) allows
> >> userspace to make decisions on interfaces handling. One could for example
> >> decide to switch between power saving modes depending on estimated rate
> >> thresholds.
> >>
> >
> > It much like the following iptables rules.
> >
> > iptables -N log_and_drop
> > iptables -A log_and_drop -j NFLOG --nflog-group 1 --nflog-prefix "log_and_drop"
> > iptables -A log_and_drop -j DROP
> >
> > ...
> > iptables ... -m quota --quota-bytes 20000 -j log_and_drop
> > ...
>
> Indeed, this looks to me like something that you can do with NFLOG and
> some combination of matches.
Is it possible to have the NFLOG send only one notification to the
userspace? In the example above, once the quota exceeds, the userspace
will be notified of every packet arriving, won't it? That would cause
unnecessary processing in the userspace.
The userspace could remove the rule when it gets the first notification
and only add it again when it needs to get the information again (as a
"toggle" functionality), but I think that would take too long and there
would be several packets going through before the rule could be removed.
--
Cheers,
Luca.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] netfilter: xtables: userspace notification target
2010-07-13 10:23 ` Luciano Coelho
@ 2010-07-13 11:49 ` Jan Engelhardt
2010-07-13 13:24 ` Luciano Coelho
2010-07-13 16:38 ` Pablo Neira Ayuso
1 sibling, 1 reply; 16+ messages in thread
From: Jan Engelhardt @ 2010-07-13 11:49 UTC (permalink / raw)
To: Luciano Coelho
Cc: ext Pablo Neira Ayuso, Changli Gao, Samuel Ortiz, Patrick McHardy,
David S. Miller, netdev@vger.kernel.org,
netfilter-devel@vger.kernel.org
On Tuesday 2010-07-13 12:23, Luciano Coelho wrote:
>>
>> Indeed, this looks to me like something that you can do with NFLOG and
>> some combination of matches.
>
>Is it possible to have the NFLOG send only one notification to the
>userspace? In the example above, once the quota exceeds, the userspace
>will be notified of every packet arriving, won't it? That would cause
>unnecessary processing in the userspace.
>
>The userspace could remove the rule when it gets the first notification
>and only add it again when it needs to get the information again (as a
>"toggle" functionality), but I think that would take too long and there
>would be several packets going through before the rule could be removed.
With xt_condition that should not be a problem
(-A INPUT -m condition --name ruleXYZ -j NFLOG..)
This is settable through procfs.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] netfilter: xtables: userspace notification target
2010-07-13 5:56 ` Jan Engelhardt
@ 2010-07-13 13:19 ` Samuel Ortiz
0 siblings, 0 replies; 16+ messages in thread
From: Samuel Ortiz @ 2010-07-13 13:19 UTC (permalink / raw)
To: Jan Engelhardt
Cc: Patrick McHardy, David S. Miller, netdev, netfilter-devel,
Luciano Coelho
Hi Jan,
On Tue, Jul 13, 2010 at 07:56:31AM +0200, Jan Engelhardt wrote:
>
> On Tuesday 2010-07-13 02:11, Samuel Ortiz wrote:
> >
> >The userspace notification Xtables target sends a netlink notification
> >whenever a packet hits the target. Notifications have a label attribute
> >for userspace to match it against a previously set rule. The rules also
> >take a --all option to switch between sending a notification for all
> >packets or for the first one only.
> >Userspace can also send a netlink message to toggle this switch while the
> >target is in place. This target uses the nefilter netlink framework.
>
> Would it not make sense to modify that module?
> Sounds an awful lot like NFQUEUE without passing the payload :)
yes, except for the payload, the missing "send one" packet toggle, and the
verdict we'd have to send back, it's almost identical ;)
What I'm trying to achieve with this target is a simple way to send a
userspace notification to userspace, without having to define a complex set of
rules, matches and having to pass some initial netlink message to set the
target properly (to avoid the payload passing in the NFLOG case).
> >+++ b/net/netfilter/xt_NFNOTIF.c
> >+struct nfnotif_tg {
> >+ struct list_head entry;
> >+ struct work_struct work;
> >+
> >+ char *label;
> >+ __u8 all_packets;
> >+ struct net *net;
> >+
> >+ __u8 send_notif;
> >+
> >+ unsigned int refcnt;
> >+};
>
> Has unnecessary padding holes.
Right, I will send a v2 later today.
Thanks for your comments and review.
Cheers,
Samuel.
--
Intel Open Source Technology Centre
http://oss.intel.com/
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] netfilter: xtables: userspace notification target
2010-07-13 11:49 ` Jan Engelhardt
@ 2010-07-13 13:24 ` Luciano Coelho
0 siblings, 0 replies; 16+ messages in thread
From: Luciano Coelho @ 2010-07-13 13:24 UTC (permalink / raw)
To: ext Jan Engelhardt
Cc: ext Pablo Neira Ayuso, Changli Gao, Samuel Ortiz, Patrick McHardy,
David S. Miller, netdev@vger.kernel.org,
netfilter-devel@vger.kernel.org
On Tue, 2010-07-13 at 13:49 +0200, ext Jan Engelhardt wrote:
> On Tuesday 2010-07-13 12:23, Luciano Coelho wrote:
> >>
> >> Indeed, this looks to me like something that you can do with NFLOG and
> >> some combination of matches.
> >
> >Is it possible to have the NFLOG send only one notification to the
> >userspace? In the example above, once the quota exceeds, the userspace
> >will be notified of every packet arriving, won't it? That would cause
> >unnecessary processing in the userspace.
> >
> >The userspace could remove the rule when it gets the first notification
> >and only add it again when it needs to get the information again (as a
> >"toggle" functionality), but I think that would take too long and there
> >would be several packets going through before the rule could be removed.
>
> With xt_condition that should not be a problem
> (-A INPUT -m condition --name ruleXYZ -j NFLOG..)
> This is settable through procfs.
Right. I didn't know about the condition match, because I can't see it
either on net-next-2.6 nor on nf-next-2.6. I found your patch in the
netfilter-devel archives, though. Any idea when it will be applied?
--
Cheers,
Luca.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] netfilter: xtables: userspace notification target
2010-07-13 6:18 ` Changli Gao
2010-07-13 8:50 ` Pablo Neira Ayuso
@ 2010-07-13 13:28 ` Samuel Ortiz
1 sibling, 0 replies; 16+ messages in thread
From: Samuel Ortiz @ 2010-07-13 13:28 UTC (permalink / raw)
To: Changli Gao
Cc: Patrick McHardy, David S. Miller, netdev, netfilter-devel,
Luciano Coelho
On Tue, Jul 13, 2010 at 02:18:26PM +0800, Changli Gao wrote:
> On Tue, Jul 13, 2010 at 8:11 AM, Samuel Ortiz <sameo@linux.intel.com> wrote:
> >
> > The userspace notification Xtables target sends a netlink notification
> > whenever a packet hits the target. Notifications have a label attribute
> > for userspace to match it against a previously set rule. The rules also
> > take a --all option to switch between sending a notification for all
> > packets or for the first one only.
> > Userspace can also send a netlink message to toggle this switch while the
> > target is in place. This target uses the nefilter netlink framework.
> >
> > This target combined with various matches (quota, rateest, etc..) allows
> > userspace to make decisions on interfaces handling. One could for example
> > decide to switch between power saving modes depending on estimated rate
> > thresholds.
> >
>
> It much like the following iptables rules.
>
> iptables -N log_and_drop
> iptables -A log_and_drop -j NFLOG --nflog-group 1 --nflog-prefix "log_and_drop"
> iptables -A log_and_drop -j DROP
>
> ...
> iptables ... -m quota --quota-bytes 20000 -j log_and_drop
> ...
We'd still be missing the possibility of having only the first packet logged,
and we'd have to also send an initial netlink message to switch the copy_mode
to COPY_NONE. We're not interested in the actual packet, but just by the match
hit.
I know it's not big deal after all, I'm just trying to have one simple target
for that simple task of notifying userspace of a match hit.
> > +static unsigned int nfnotif_tg_target(struct sk_buff *skb,
> > + const struct xt_action_param *par)
> > +{
> > + const struct nfnotif_tg_info *info = par->targinfo;
> > +
> > + BUG_ON(!info->notif);
> > +
> > + if (!info->notif->send_notif)
> > + return XT_CONTINUE;
> > +
> > + pr_debug("Sending notification for %s\n", info->label);
> > +
> > + schedule_work(&info->notif->work);
> > +
>
> Why do you use another kernel activity: kernel thread? netlink
> messages can be sent in atomic context.
That's right, I should have used the ATOMIC gfp flags from my sending routine.
I'll fix that with my next revision of the patch.
Thanks for the review.
Cheers,
Samuel.
--
Intel Open Source Technology Centre
http://oss.intel.com/
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v2] netfilter: xtables: userspace notification target
2010-07-13 0:11 [PATCH] netfilter: xtables: userspace notification target Samuel Ortiz
2010-07-13 5:56 ` Jan Engelhardt
2010-07-13 6:18 ` Changli Gao
@ 2010-07-13 14:57 ` Samuel Ortiz
2 siblings, 0 replies; 16+ messages in thread
From: Samuel Ortiz @ 2010-07-13 14:57 UTC (permalink / raw)
To: Patrick McHardy, David S. Miller
Cc: netdev, netfilter-devel, Luciano Coelho, sameo, Jan Engelhardt,
Changli Gao, Pablo Neira Ayuso
The userspace notification Xtables target sends a netlink notification
whenever a packet hits the target. Notifications have a label attribute
for userspace to match it against a previously set rule. The rules also
take a --all option to switch between sending a notification for all
packets or for the first one only.
Userspace can also send a netlink message to toggle this switch while the
target is in place. This target uses the nefilter netlink framework.
This target combined with various matches (quota, rateest, etc..) allows
userspace to make decisions on interfaces handling. One could for example
decide to switch between power saving modes depending on estimated rate
thresholds.
Reviewed-by: Luciano Coelho <luciano.coelho@nokia.com>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
---
v2:
- Remove the work structure and make the netlink sending routine atomic.
- Reformat struct nfnotif_tg to get rid of unnecessary padding holes.
---
include/linux/netfilter/Kbuild | 1 +
include/linux/netfilter/nfnetlink.h | 5 +-
include/linux/netfilter/nfnetlink_compat.h | 1 +
include/linux/netfilter/xt_NFNOTIF.h | 55 ++++++
net/netfilter/Kconfig | 17 ++
net/netfilter/Makefile | 1 +
net/netfilter/xt_NFNOTIF.c | 287 ++++++++++++++++++++++++++++
7 files changed, 366 insertions(+), 1 deletions(-)
create mode 100644 include/linux/netfilter/xt_NFNOTIF.h
create mode 100644 net/netfilter/xt_NFNOTIF.c
diff --git a/include/linux/netfilter/Kbuild b/include/linux/netfilter/Kbuild
index bb103f4..1b80b27 100644
--- a/include/linux/netfilter/Kbuild
+++ b/include/linux/netfilter/Kbuild
@@ -12,6 +12,7 @@ header-y += xt_IDLETIMER.h
header-y += xt_LED.h
header-y += xt_MARK.h
header-y += xt_NFLOG.h
+header-y += xt_NFNOTIF.h
header-y += xt_NFQUEUE.h
header-y += xt_RATEEST.h
header-y += xt_SECMARK.h
diff --git a/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h
index 361d6b5..e336f03 100644
--- a/include/linux/netfilter/nfnetlink.h
+++ b/include/linux/netfilter/nfnetlink.h
@@ -18,6 +18,8 @@ enum nfnetlink_groups {
#define NFNLGRP_CONNTRACK_EXP_UPDATE NFNLGRP_CONNTRACK_EXP_UPDATE
NFNLGRP_CONNTRACK_EXP_DESTROY,
#define NFNLGRP_CONNTRACK_EXP_DESTROY NFNLGRP_CONNTRACK_EXP_DESTROY
+ NFNLGRP_NFNOTIF,
+#define NFNLGRP_NFNOTIF NFNLGRP_NFNOTIF
__NFNLGRP_MAX,
};
#define NFNLGRP_MAX (__NFNLGRP_MAX - 1)
@@ -47,7 +49,8 @@ struct nfgenmsg {
#define NFNL_SUBSYS_QUEUE 3
#define NFNL_SUBSYS_ULOG 4
#define NFNL_SUBSYS_OSF 5
-#define NFNL_SUBSYS_COUNT 6
+#define NFNL_SUBSYS_NFNOTIF 6
+#define NFNL_SUBSYS_COUNT 7
#ifdef __KERNEL__
diff --git a/include/linux/netfilter/nfnetlink_compat.h b/include/linux/netfilter/nfnetlink_compat.h
index ffb9503..dca8ab2 100644
--- a/include/linux/netfilter/nfnetlink_compat.h
+++ b/include/linux/netfilter/nfnetlink_compat.h
@@ -13,6 +13,7 @@
#define NF_NETLINK_CONNTRACK_EXP_NEW 0x00000008
#define NF_NETLINK_CONNTRACK_EXP_UPDATE 0x00000010
#define NF_NETLINK_CONNTRACK_EXP_DESTROY 0x00000020
+#define NF_NETLINK_NFNOTIF 0x00000040
/* Generic structure for encapsulation optional netfilter information.
* It is reminiscent of sockaddr, but with sa_family replaced
diff --git a/include/linux/netfilter/xt_NFNOTIF.h b/include/linux/netfilter/xt_NFNOTIF.h
new file mode 100644
index 0000000..8fae827
--- /dev/null
+++ b/include/linux/netfilter/xt_NFNOTIF.h
@@ -0,0 +1,55 @@
+/*
+ * linux/include/linux/netfilter/xt_NFNOTIF.h
+ *
+ * Header file for Xtables notification target module.
+ *
+ * Copyright (C) 2010 Intel Corporation
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef _XT_NFNOTIF_H
+#define _XT_NFNOTIF_H
+
+#include <linux/types.h>
+
+enum nfnotif_msg_type {
+ NFNOTIF_TG_MSG_PACKETS,
+
+ NFNOTIF_TG_MSG_MAX
+};
+
+enum nfnotif_attr_type {
+ NFNOTIF_TG_ATTR_UNSPEC,
+ NFNOTIF_TG_ATTR_LABEL,
+ NFNOTIF_TG_ATTR_SEND_NOTIF,
+
+ __NFNOTIF_TG_ATTR_AFTER_LAST
+};
+#define NFNOTIF_TG_ATTR_MAX (__NFNOTIF_TG_ATTR_AFTER_LAST - 1)
+
+#define MAX_NFNOTIF_LABEL_SIZE 31
+
+struct nfnotif_tg_info {
+ __u8 all_packets;
+
+ char label[MAX_NFNOTIF_LABEL_SIZE];
+
+ /* for kernel module internal use only */
+ struct nfnotif_tg *notif __attribute((aligned(8)));
+};
+
+#endif
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index aa2f106..0e2de36 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -469,6 +469,23 @@ config NETFILTER_XT_TARGET_NFQUEUE
To compile it as a module, choose M here. If unsure, say N.
+config NETFILTER_XT_TARGET_NFNOTIF
+ tristate '"NFNOTIF" target Support'
+ depends on NETFILTER_ADVANCED
+ select NETFILTER_NETLINK
+ help
+
+ This option adds the `NFNOTIF' target, which allows to send
+ netfilter netlink messages when packets hit the target.
+
+ This target comes with an option to specify if one wants all
+ packets hitting the target to trigger the netlink message
+ transmission, or only the first one.
+ It also listen on its netfilter netlink subsystem for messages
+ allowing to reset the above option.
+
+ To compile it as a module, choose M here. If unsure, say N.
+
config NETFILTER_XT_TARGET_NOTRACK
tristate '"NOTRACK" target support'
depends on IP_NF_RAW || IP6_NF_RAW
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index e28420a..5d9c9e9 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -62,6 +62,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP) += xt_TCPOPTSTRIP.o
obj-$(CONFIG_NETFILTER_XT_TARGET_TEE) += xt_TEE.o
obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o
obj-$(CONFIG_NETFILTER_XT_TARGET_IDLETIMER) += xt_IDLETIMER.o
+obj-$(CONFIG_NETFILTER_XT_TARGET_NFNOTIF) += xt_NFNOTIF.o
# matches
obj-$(CONFIG_NETFILTER_XT_MATCH_CLUSTER) += xt_cluster.o
diff --git a/net/netfilter/xt_NFNOTIF.c b/net/netfilter/xt_NFNOTIF.c
new file mode 100644
index 0000000..75ddeba
--- /dev/null
+++ b/net/netfilter/xt_NFNOTIF.c
@@ -0,0 +1,287 @@
+/*
+ * linux/net/netfilter/xt_NFNOTIF.c
+ *
+ * Copyright (C) 2010 Intel Corporation
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/netfilter.h>
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter/nfnetlink.h>
+#include <linux/netfilter/xt_NFNOTIF.h>
+
+struct nfnotif_tg {
+ struct list_head entry;
+
+ char *label;
+ struct net *net;
+ unsigned int refcnt;
+ __u8 all_packets;
+ __u8 send_notif;
+};
+
+static LIST_HEAD(nfnotif_tg_list);
+static DEFINE_MUTEX(list_mutex);
+
+static int __nfnotif_tg_netlink_send(struct nfnotif_tg *nfnotif)
+{
+ struct nlmsghdr *nlh;
+ struct nfgenmsg *nfmsg;
+ struct sk_buff *skb;
+ struct net *net = nfnotif->net;
+ unsigned int type;
+ int flags;
+
+ type = NFNL_SUBSYS_NFNOTIF << 8;
+ flags = NLM_F_CREATE;
+
+ skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
+ if (skb == NULL)
+ goto error_out;
+
+ nlh = nlmsg_put(skb, 0, 0, type, sizeof(*nfmsg), flags);
+ if (nlh == NULL)
+ goto nlmsg_put_failure;
+
+ nfmsg = nlmsg_data(nlh);
+ nfmsg->version = NFNETLINK_V0;
+ nfmsg->res_id = 0;
+
+ NLA_PUT_STRING(skb, NFNOTIF_TG_ATTR_LABEL, nfnotif->label);
+
+ nlmsg_end(skb, nlh);
+
+ return nfnetlink_send(skb, net, 0, NFNLGRP_NFNOTIF, 0, GFP_ATOMIC);
+
+nla_put_failure:
+ nlmsg_cancel(skb, nlh);
+
+nlmsg_put_failure:
+ kfree_skb(skb);
+
+error_out:
+ return nfnetlink_set_err(net, 0, 0, -ENOBUFS);
+}
+
+static struct nfnotif_tg *__nfnotif_tg_find_by_label(const char *label)
+{
+ struct nfnotif_tg *entry;
+
+ BUG_ON(!label);
+
+ list_for_each_entry(entry, &nfnotif_tg_list, entry) {
+ if (!strcmp(label, entry->label))
+ return entry;
+ }
+
+ return NULL;
+}
+
+static int nfnotif_tg_create(struct nfnotif_tg_info *info)
+{
+ info->notif = kmalloc(sizeof(*info->notif), GFP_KERNEL);
+ if (!info->notif) {
+ pr_debug("Couldn't allocate notification\n");
+ return -ENOMEM;
+ }
+
+ info->notif->label = kstrdup(info->label, GFP_KERNEL);
+ if (!info->notif->label) {
+ pr_debug("Couldn't allocate label\n");
+ kfree(info->notif);
+ return -ENOMEM;
+ }
+
+ info->notif->all_packets = info->all_packets;
+ info->notif->send_notif = 1;
+
+ list_add(&info->notif->entry, &nfnotif_tg_list);
+
+ info->notif->refcnt = 1;
+
+ return 0;
+}
+
+static unsigned int nfnotif_tg_target(struct sk_buff *skb,
+ const struct xt_action_param *par)
+{
+ const struct nfnotif_tg_info *info = par->targinfo;
+
+ BUG_ON(!info->notif);
+
+ if (!info->notif->send_notif)
+ return XT_CONTINUE;
+
+ pr_debug("Sending notification for %s\n", info->label);
+
+ if (__nfnotif_tg_netlink_send(info->notif) < 0)
+ pr_debug("Could not send notification");
+
+ if (!info->notif->all_packets)
+ info->notif->send_notif = 0;
+
+ return XT_CONTINUE;
+}
+
+static int nfnotif_tg_checkentry(const struct xt_tgchk_param *par)
+{
+ struct nfnotif_tg_info *info = par->targinfo;
+ int ret;
+
+ pr_debug("Checkentry targinfo %s\n", info->label);
+
+ if (info->label[0] == '\0' ||
+ strnlen(info->label,
+ MAX_NFNOTIF_LABEL_SIZE) == MAX_NFNOTIF_LABEL_SIZE) {
+ pr_debug("Label is empty or not nul-terminated\n");
+ return -EINVAL;
+ }
+
+ mutex_lock(&list_mutex);
+
+ info->notif = __nfnotif_tg_find_by_label(info->label);
+ if (info->notif) {
+ info->notif->refcnt++;
+
+ pr_debug("Increased refcnt for %s to %u\n",
+ info->label, info->notif->refcnt);
+ } else {
+ ret = nfnotif_tg_create(info);
+ if (ret < 0) {
+ pr_debug("Failed to create notification\n");
+ mutex_unlock(&list_mutex);
+ return ret;
+ }
+ }
+
+ info->notif->net = par->net;
+
+ mutex_unlock(&list_mutex);
+ return 0;
+}
+
+static void nfnotif_tg_destroy(const struct xt_tgdtor_param *par)
+{
+ const struct nfnotif_tg_info *info = par->targinfo;
+
+ pr_debug("Destroy targinfo %s\n", info->label);
+
+ mutex_lock(&list_mutex);
+
+ if (--info->notif->refcnt == 0) {
+ pr_debug("Deleting notification %s\n", info->label);
+
+ list_del(&info->notif->entry);
+ kfree(info->notif->label);
+ kfree(info->notif);
+ }
+
+ mutex_unlock(&list_mutex);
+}
+
+static struct xt_target nfnotif_tg __read_mostly = {
+ .name = "NFNOTIF",
+ .family = NFPROTO_UNSPEC,
+ .target = nfnotif_tg_target,
+ .targetsize = sizeof(struct nfnotif_tg_info),
+ .checkentry = nfnotif_tg_checkentry,
+ .destroy = nfnotif_tg_destroy,
+ .me = THIS_MODULE,
+};
+
+static int nfnotif_msg_send_notif(struct sock *nfnl, struct sk_buff *skb,
+ const struct nlmsghdr *nlh,
+ const struct nlattr * const attrs[])
+{
+ struct nfnotif_tg *notif;
+ char *label;
+ u8 send_notif;
+
+ if (attrs[NFNOTIF_TG_ATTR_LABEL] == NULL ||
+ attrs[NFNOTIF_TG_ATTR_SEND_NOTIF] == NULL)
+ return -EINVAL;
+
+ label = nla_data(attrs[NFNOTIF_TG_ATTR_LABEL]);
+ send_notif = nla_get_u8(attrs[NFNOTIF_TG_ATTR_SEND_NOTIF]);
+
+ pr_debug("Label %s send %d\n", label, send_notif);
+
+ notif = __nfnotif_tg_find_by_label(label);
+ if (notif == NULL)
+ return -EINVAL;
+
+ notif->send_notif = send_notif;
+
+ return 0;
+}
+
+
+static const struct nla_policy nfnotif_nla_policy[NFNOTIF_TG_ATTR_MAX + 1] = {
+ [NFNOTIF_TG_ATTR_LABEL] = { .type = NLA_NUL_STRING },
+ [NFNOTIF_TG_ATTR_SEND_NOTIF] = { .type = NLA_U8 },
+};
+
+static const struct nfnl_callback nfnotif_cb[NFNOTIF_TG_MSG_MAX] = {
+ [NFNOTIF_TG_MSG_PACKETS] = { .call = nfnotif_msg_send_notif,
+ .attr_count = NFNOTIF_TG_ATTR_MAX,
+ .policy = nfnotif_nla_policy },
+};
+
+static const struct nfnetlink_subsystem nfnotif_subsys = {
+ .name = "nfnotif",
+ .subsys_id = NFNL_SUBSYS_NFNOTIF,
+ .cb_count = NFNOTIF_TG_MSG_MAX,
+ .cb = nfnotif_cb,
+};
+
+static int __init nfnotif_tg_init(void)
+{
+ int ret;
+
+ ret = nfnetlink_subsys_register(&nfnotif_subsys);
+ if (ret < 0) {
+ pr_err("%s: Cannot register with nfnetlink\n", __func__);
+ return ret;
+ }
+
+ ret = xt_register_target(&nfnotif_tg);
+ if (ret < 0) {
+ pr_err("%s: Cannot register target\n", __func__);
+ nfnetlink_subsys_unregister(&nfnotif_subsys);
+ }
+
+ return ret;
+}
+
+static void __exit nfnotif_tg_exit(void)
+{
+ nfnetlink_subsys_unregister(&nfnotif_subsys);
+ xt_unregister_target(&nfnotif_tg);
+}
+
+module_init(nfnotif_tg_init);
+module_exit(nfnotif_tg_exit);
+
+MODULE_AUTHOR("Samuel Ortiz <samuel.ortiz@intel.com>");
+MODULE_DESCRIPTION("Xtables: userspace notification");
+MODULE_LICENSE("GPL v2");
--
1.7.1
--
Intel Open Source Technology Centre
http://oss.intel.com/
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH] netfilter: xtables: userspace notification target
2010-07-13 10:23 ` Luciano Coelho
2010-07-13 11:49 ` Jan Engelhardt
@ 2010-07-13 16:38 ` Pablo Neira Ayuso
2010-07-14 11:48 ` Patrick McHardy
1 sibling, 1 reply; 16+ messages in thread
From: Pablo Neira Ayuso @ 2010-07-13 16:38 UTC (permalink / raw)
To: Luciano Coelho
Cc: Changli Gao, Samuel Ortiz, Patrick McHardy, David S. Miller,
netdev@vger.kernel.org, netfilter-devel@vger.kernel.org
On 13/07/10 12:23, Luciano Coelho wrote:
> On Tue, 2010-07-13 at 10:50 +0200, ext Pablo Neira Ayuso wrote:
>> On 13/07/10 08:18, Changli Gao wrote:
>>> On Tue, Jul 13, 2010 at 8:11 AM, Samuel Ortiz<sameo@linux.intel.com> wrote:
>>>>
>>>> The userspace notification Xtables target sends a netlink notification
>>>> whenever a packet hits the target. Notifications have a label attribute
>>>> for userspace to match it against a previously set rule. The rules also
>>>> take a --all option to switch between sending a notification for all
>>>> packets or for the first one only.
>>>> Userspace can also send a netlink message to toggle this switch while the
>>>> target is in place. This target uses the nefilter netlink framework.
>>>>
>>>> This target combined with various matches (quota, rateest, etc..) allows
>>>> userspace to make decisions on interfaces handling. One could for example
>>>> decide to switch between power saving modes depending on estimated rate
>>>> thresholds.
>>>>
>>>
>>> It much like the following iptables rules.
>>>
>>> iptables -N log_and_drop
>>> iptables -A log_and_drop -j NFLOG --nflog-group 1 --nflog-prefix "log_and_drop"
>>> iptables -A log_and_drop -j DROP
>>>
>>> ...
>>> iptables ... -m quota --quota-bytes 20000 -j log_and_drop
>>> ...
>>
>> Indeed, this looks to me like something that you can do with NFLOG and
>> some combination of matches.
>
> Is it possible to have the NFLOG send only one notification to the
> userspace?
Not possible, but you could easily extend NFLOG to implement this
feature if it's not possible to do what you need with the existing
matches/targets. This NOTIF infrastructure is redundant and it looks
like a subset of NFLOG.
There's a padding field in xt_NFLOG that is currently unused, it could
be used for this.
Or we could add some 'count' match to store the number of packets that
have matched a rule (although not sure if this is generic enough to be
useful for others).
> In the example above, once the quota exceeds, the userspace
> will be notified of every packet arriving, won't it? That would cause
> unnecessary processing in the userspace.
>
> The userspace could remove the rule when it gets the first notification
> and only add it again when it needs to get the information again (as a
> "toggle" functionality), but I think that would take too long and there
> would be several packets going through before the rule could be removed.
You can do that with libnetfilter_log to handle the log messages
received and the minor change for xt_NFLOG that I proposed.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] netfilter: xtables: userspace notification target
2010-07-13 16:38 ` Pablo Neira Ayuso
@ 2010-07-14 11:48 ` Patrick McHardy
2010-07-14 12:22 ` Luciano Coelho
0 siblings, 1 reply; 16+ messages in thread
From: Patrick McHardy @ 2010-07-14 11:48 UTC (permalink / raw)
To: Pablo Neira Ayuso
Cc: Luciano Coelho, Changli Gao, Samuel Ortiz, David S. Miller,
netdev@vger.kernel.org, netfilter-devel@vger.kernel.org
On 13.07.2010 18:38, Pablo Neira Ayuso wrote:
> On 13/07/10 12:23, Luciano Coelho wrote:
>> On Tue, 2010-07-13 at 10:50 +0200, ext Pablo Neira Ayuso wrote:
>>> On 13/07/10 08:18, Changli Gao wrote:
>>>> On Tue, Jul 13, 2010 at 8:11 AM, Samuel
>>>> Ortiz<sameo@linux.intel.com> wrote:
>>>>>
>>>>> The userspace notification Xtables target sends a netlink notification
>>>>> whenever a packet hits the target. Notifications have a label
>>>>> attribute
>>>>> for userspace to match it against a previously set rule. The rules
>>>>> also
>>>>> take a --all option to switch between sending a notification for all
>>>>> packets or for the first one only.
>>>>> Userspace can also send a netlink message to toggle this switch
>>>>> while the
>>>>> target is in place. This target uses the nefilter netlink framework.
>>>>>
>>>>> This target combined with various matches (quota, rateest, etc..)
>>>>> allows
>>>>> userspace to make decisions on interfaces handling. One could for
>>>>> example
>>>>> decide to switch between power saving modes depending on estimated
>>>>> rate
>>>>> thresholds.
>>>>>
>>>>
>>>> It much like the following iptables rules.
>>>>
>>>> iptables -N log_and_drop
>>>> iptables -A log_and_drop -j NFLOG --nflog-group 1 --nflog-prefix
>>>> "log_and_drop"
>>>> iptables -A log_and_drop -j DROP
>>>>
>>>> ...
>>>> iptables ... -m quota --quota-bytes 20000 -j log_and_drop
>>>> ...
>>>
>>> Indeed, this looks to me like something that you can do with NFLOG and
>>> some combination of matches.
>>
>> Is it possible to have the NFLOG send only one notification to the
>> userspace?
>
> Not possible, but you could easily extend NFLOG to implement this
> feature if it's not possible to do what you need with the existing
> matches/targets. This NOTIF infrastructure is redundant and it looks
> like a subset of NFLOG.
If you're using connection tracking, you can use conntrack marks
to avoid sending more than a single message:
iptables ... -m connmark --mark 0x1/0x1 -j RETURN
iptables ... -j NFLOG ...
iptables ... -j CONNMARK --set-mark 0x1/0x1
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] netfilter: xtables: userspace notification target
2010-07-14 11:48 ` Patrick McHardy
@ 2010-07-14 12:22 ` Luciano Coelho
2010-07-14 16:34 ` Pablo Neira Ayuso
0 siblings, 1 reply; 16+ messages in thread
From: Luciano Coelho @ 2010-07-14 12:22 UTC (permalink / raw)
To: ext Patrick McHardy
Cc: Pablo Neira Ayuso, Changli Gao, Samuel Ortiz, David S. Miller,
netdev@vger.kernel.org, netfilter-devel@vger.kernel.org
On Wed, 2010-07-14 at 13:48 +0200, ext Patrick McHardy wrote:
> On 13.07.2010 18:38, Pablo Neira Ayuso wrote:
> > On 13/07/10 12:23, Luciano Coelho wrote:
> >> On Tue, 2010-07-13 at 10:50 +0200, ext Pablo Neira Ayuso wrote:
> >>> On 13/07/10 08:18, Changli Gao wrote:
> >>>> On Tue, Jul 13, 2010 at 8:11 AM, Samuel
> >>>> Ortiz<sameo@linux.intel.com> wrote:
> >>>>>
> >>>>> The userspace notification Xtables target sends a netlink notification
> >>>>> whenever a packet hits the target. Notifications have a label
> >>>>> attribute
> >>>>> for userspace to match it against a previously set rule. The rules
> >>>>> also
> >>>>> take a --all option to switch between sending a notification for all
> >>>>> packets or for the first one only.
> >>>>> Userspace can also send a netlink message to toggle this switch
> >>>>> while the
> >>>>> target is in place. This target uses the nefilter netlink framework.
> >>>>>
> >>>>> This target combined with various matches (quota, rateest, etc..)
> >>>>> allows
> >>>>> userspace to make decisions on interfaces handling. One could for
> >>>>> example
> >>>>> decide to switch between power saving modes depending on estimated
> >>>>> rate
> >>>>> thresholds.
> >>>>>
> >>>>
> >>>> It much like the following iptables rules.
> >>>>
> >>>> iptables -N log_and_drop
> >>>> iptables -A log_and_drop -j NFLOG --nflog-group 1 --nflog-prefix
> >>>> "log_and_drop"
> >>>> iptables -A log_and_drop -j DROP
> >>>>
> >>>> ...
> >>>> iptables ... -m quota --quota-bytes 20000 -j log_and_drop
> >>>> ...
> >>>
> >>> Indeed, this looks to me like something that you can do with NFLOG and
> >>> some combination of matches.
> >>
> >> Is it possible to have the NFLOG send only one notification to the
> >> userspace?
> >
> > Not possible, but you could easily extend NFLOG to implement this
> > feature if it's not possible to do what you need with the existing
> > matches/targets. This NOTIF infrastructure is redundant and it looks
> > like a subset of NFLOG.
>
> If you're using connection tracking, you can use conntrack marks
> to avoid sending more than a single message:
>
> iptables ... -m connmark --mark 0x1/0x1 -j RETURN
> iptables ... -j NFLOG ...
> iptables ... -j CONNMARK --set-mark 0x1/0x1
Cool, thanks.
It seems that there are lots of possibilities to get this to work, but
this is starting to get quite complex. I would still prefer having the
NFNOTIF module included, since we would be able to do what we want in a
very simple way. It's also probably much more efficient that using
several rules, which would increase the CPU usage considerably (in our
device we are already reaching the limit of a reasonable CPU resource
usage with high throughput WLAN connections).
While I agree that it is possible to achieve the NFNOTIF functionality
with existing modules, I still think there is a "niche" for such module,
because it is very simple, has a very clear purpose and would make the
ruleset simpler and more efficient.
Does this make any sense?
--
Cheers,
Luca.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] netfilter: xtables: userspace notification target
2010-07-14 12:22 ` Luciano Coelho
@ 2010-07-14 16:34 ` Pablo Neira Ayuso
2010-07-15 9:05 ` Patrick McHardy
0 siblings, 1 reply; 16+ messages in thread
From: Pablo Neira Ayuso @ 2010-07-14 16:34 UTC (permalink / raw)
To: Luciano Coelho
Cc: ext Patrick McHardy, Changli Gao, Samuel Ortiz, David S. Miller,
netdev@vger.kernel.org, netfilter-devel@vger.kernel.org
Hi Luciano,
On 14/07/10 14:22, Luciano Coelho wrote:
> On Wed, 2010-07-14 at 13:48 +0200, ext Patrick McHardy wrote:
>> If you're using connection tracking, you can use conntrack marks
>> to avoid sending more than a single message:
>>
>> iptables ... -m connmark --mark 0x1/0x1 -j RETURN
>> iptables ... -j NFLOG ...
>> iptables ... -j CONNMARK --set-mark 0x1/0x1
>
> Cool, thanks.
>
> It seems that there are lots of possibilities to get this to work, but
> this is starting to get quite complex. I would still prefer having the
> NFNOTIF module included, since we would be able to do what we want in a
> very simple way. It's also probably much more efficient that using
> several rules, which would increase the CPU usage considerably (in our
> device we are already reaching the limit of a reasonable CPU resource
> usage with high throughput WLAN connections).
>
> While I agree that it is possible to achieve the NFNOTIF functionality
> with existing modules, I still think there is a "niche" for such module,
> because it is very simple, has a very clear purpose and would make the
> ruleset simpler and more efficient.
>
> Does this make any sense?
I don't think that the NFNOTIF infrastructure fulfill the policy for
inclusion. It seems to me like something quite specific for your needs.
It is simple, yes, but we already have this feature into the kernel. I
don't think that this will reduce CPU usage considerably with regards to
the NFLOG way.
I would still prefer adding the once-per-matching notification feature
to NFLOG than these extra lines in the kernel, Patrick?
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] netfilter: xtables: userspace notification target
2010-07-14 16:34 ` Pablo Neira Ayuso
@ 2010-07-15 9:05 ` Patrick McHardy
2010-07-15 9:18 ` Luciano Coelho
0 siblings, 1 reply; 16+ messages in thread
From: Patrick McHardy @ 2010-07-15 9:05 UTC (permalink / raw)
To: Pablo Neira Ayuso
Cc: Luciano Coelho, Changli Gao, Samuel Ortiz, David S. Miller,
netdev@vger.kernel.org, netfilter-devel@vger.kernel.org
Am 14.07.2010 18:34, schrieb Pablo Neira Ayuso:
> Hi Luciano,
>
> On 14/07/10 14:22, Luciano Coelho wrote:
>> On Wed, 2010-07-14 at 13:48 +0200, ext Patrick McHardy wrote:
>>> If you're using connection tracking, you can use conntrack marks
>>> to avoid sending more than a single message:
>>>
>>> iptables ... -m connmark --mark 0x1/0x1 -j RETURN
>>> iptables ... -j NFLOG ...
>>> iptables ... -j CONNMARK --set-mark 0x1/0x1
>>
>> Cool, thanks.
>>
>> It seems that there are lots of possibilities to get this to work, but
>> this is starting to get quite complex. I would still prefer having the
>> NFNOTIF module included, since we would be able to do what we want in a
>> very simple way. It's also probably much more efficient that using
>> several rules, which would increase the CPU usage considerably (in our
>> device we are already reaching the limit of a reasonable CPU resource
>> usage with high throughput WLAN connections).
Its hard to believe that a connmark match filtering out notifications
would require more CPU time than doing the same in a new target module.
>> While I agree that it is possible to achieve the NFNOTIF functionality
>> with existing modules, I still think there is a "niche" for such module,
>> because it is very simple, has a very clear purpose and would make the
>> ruleset simpler and more efficient.
>>
>> Does this make any sense?
>
> I don't think that the NFNOTIF infrastructure fulfill the policy for
> inclusion. It seems to me like something quite specific for your needs.
> It is simple, yes, but we already have this feature into the kernel. I
> don't think that this will reduce CPU usage considerably with regards to
> the NFLOG way.
>
> I would still prefer adding the once-per-matching notification feature
> to NFLOG than these extra lines in the kernel, Patrick?
I agree with Pablo.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] netfilter: xtables: userspace notification target
2010-07-15 9:05 ` Patrick McHardy
@ 2010-07-15 9:18 ` Luciano Coelho
0 siblings, 0 replies; 16+ messages in thread
From: Luciano Coelho @ 2010-07-15 9:18 UTC (permalink / raw)
To: ext Patrick McHardy
Cc: Pablo Neira Ayuso, Changli Gao, Samuel Ortiz, David S. Miller,
netdev@vger.kernel.org, netfilter-devel@vger.kernel.org
On Thu, 2010-07-15 at 11:05 +0200, ext Patrick McHardy wrote:
> Am 14.07.2010 18:34, schrieb Pablo Neira Ayuso:
> >> It seems that there are lots of possibilities to get this to work, but
> >> this is starting to get quite complex. I would still prefer having the
> >> NFNOTIF module included, since we would be able to do what we want in a
> >> very simple way. It's also probably much more efficient that using
> >> several rules, which would increase the CPU usage considerably (in our
> >> device we are already reaching the limit of a reasonable CPU resource
> >> usage with high throughput WLAN connections).
>
> Its hard to believe that a connmark match filtering out notifications
> would require more CPU time than doing the same in a new target module.
Okay, you have convinced me. :) I studied connmark a bit more and now I
realize that it won't take more CPU. In the solution with connmark that
you proposed the packets coming from a connection that is already marked
will be quickly returned to normal processing, so it will be fairly
efficient and certainly not more CPU hungry than the NFNOTIF.
> >> While I agree that it is possible to achieve the NFNOTIF functionality
> >> with existing modules, I still think there is a "niche" for such module,
> >> because it is very simple, has a very clear purpose and would make the
> >> ruleset simpler and more efficient.
> >>
> >> Does this make any sense?
> >
> > I don't think that the NFNOTIF infrastructure fulfill the policy for
> > inclusion. It seems to me like something quite specific for your needs.
> > It is simple, yes, but we already have this feature into the kernel. I
> > don't think that this will reduce CPU usage considerably with regards to
> > the NFLOG way.
> >
> > I would still prefer adding the once-per-matching notification feature
> > to NFLOG than these extra lines in the kernel, Patrick?
>
> I agree with Pablo.
I have to admit that you're right here again. I think that it will not
be necessary to make this change in the NFLOG, since the connmark
solution is actually pretty clear too. If needed, I'll make this simple
change in the NFLOG module and submit.
Thanks for your help.
--
Cheers,
Luca.
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2010-07-15 9:18 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-07-13 0:11 [PATCH] netfilter: xtables: userspace notification target Samuel Ortiz
2010-07-13 5:56 ` Jan Engelhardt
2010-07-13 13:19 ` Samuel Ortiz
2010-07-13 6:18 ` Changli Gao
2010-07-13 8:50 ` Pablo Neira Ayuso
2010-07-13 10:23 ` Luciano Coelho
2010-07-13 11:49 ` Jan Engelhardt
2010-07-13 13:24 ` Luciano Coelho
2010-07-13 16:38 ` Pablo Neira Ayuso
2010-07-14 11:48 ` Patrick McHardy
2010-07-14 12:22 ` Luciano Coelho
2010-07-14 16:34 ` Pablo Neira Ayuso
2010-07-15 9:05 ` Patrick McHardy
2010-07-15 9:18 ` Luciano Coelho
2010-07-13 13:28 ` Samuel Ortiz
2010-07-13 14:57 ` [PATCH v2] " Samuel Ortiz
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).