linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v5] Merge ipt_LOG and ip6t_LOG, add ring bufffer support
@ 2012-02-10 22:10 Richard Weinberger
  2012-02-10 22:10 ` [PATCH 1/2] iptables: Merge libip6t_LOG and libipt_LOG into libxt_LOG Richard Weinberger
                   ` (5 more replies)
  0 siblings, 6 replies; 16+ messages in thread
From: Richard Weinberger @ 2012-02-10 22:10 UTC (permalink / raw)
  To: netfilter-devel
  Cc: netdev, linux-kernel, eric.dumazet, jengelh, rostedt, pablo, basti

This patch set merges ipt_LOG and ip6t_LOG and adds ring buffer support
to xt_LOG.

Using "--ring" a user can create LOG rules which log messages into
one or more ring buffers.
Each ring buffer is represented as pipe-like file in
/proc/net/netfilter/xt_LOG_ring/.

Ring buffer support can be enabled/disabled using
CONFIG_NETFILTER_XT_TARGET_LOG_RING.

Changes since v1:
 - Merged ipt_LOG and ip6t_LOG
 - Implemented ring buffer support as part of xt_LOG.

Changes since v2:
 - Fixed struct xt_log_info_v1's data layout
 - Removed the sizeof(void *) hack
 - Replaced BUG() by WARN_ON_ONCE()

Changes since v3:
 - Merged xt_LOG_core.c and xt_LOG_ring.c into xt_LOG.c
 - Made checkpatch.pl happy

Changes since v4:
 - Fixed a typo in include/linux/netfilter/Kbuild
   (Thanks Bastian!)

All patches can also be found at:
git://git.kernel.org/pub/scm/linux/kernel/git/rw/misc.git xt_LOG
git://git.kernel.org/pub/scm/linux/kernel/git/rw/iptables.git xt_LOG

[PATCH 1/2] iptables: Merge libip6t_LOG and libipt_LOG into
[PATCH 2/2] iptables: xt_LOG: Add ring buffer support

[PATCH 1/4] Netfilter: Merge ipt_LOG and ip6_LOG into xt_LOG
[PATCH 2/4] ring_buffer: Export for_each_buffer_cpu()
[PATCH 3/4] xt_log: Make printk() in sb_close() optional
[PATCH 4/4] Netfilter: xt_LOG: Implement ring buffer support

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 1/2] iptables: Merge libip6t_LOG and libipt_LOG into libxt_LOG
  2012-02-10 22:10 [PATCH v5] Merge ipt_LOG and ip6t_LOG, add ring bufffer support Richard Weinberger
@ 2012-02-10 22:10 ` Richard Weinberger
  2012-02-25 13:38   ` Pablo Neira Ayuso
  2012-02-10 22:10 ` [PATCH 1/4] Netfilter: Merge ipt_LOG and ip6_LOG into xt_LOG Richard Weinberger
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 16+ messages in thread
From: Richard Weinberger @ 2012-02-10 22:10 UTC (permalink / raw)
  To: netfilter-devel
  Cc: netdev, linux-kernel, eric.dumazet, jengelh, rostedt, pablo,
	basti, Richard Weinberger

libip6t_LOG and libipt_LOG share a lot of common code, merge them
to recude duplicate code.

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 extensions/libip6t_LOG.c         |  184 ----------------------------------
 extensions/libip6t_LOG.man       |   31 ------
 extensions/libipt_LOG.c          |  186 -----------------------------------
 extensions/libipt_LOG.man        |   31 ------
 extensions/libxt_LOG.c           |  201 ++++++++++++++++++++++++++++++++++++++
 extensions/libxt_LOG.man         |   31 ++++++
 include/linux/netfilter/xt_LOG.h |   19 ++++
 7 files changed, 251 insertions(+), 432 deletions(-)
 delete mode 100644 extensions/libip6t_LOG.c
 delete mode 100644 extensions/libip6t_LOG.man
 delete mode 100644 extensions/libipt_LOG.c
 delete mode 100644 extensions/libipt_LOG.man
 create mode 100644 extensions/libxt_LOG.c
 create mode 100644 extensions/libxt_LOG.man
 create mode 100644 include/linux/netfilter/xt_LOG.h

diff --git a/extensions/libip6t_LOG.c b/extensions/libip6t_LOG.c
deleted file mode 100644
index 2b1ae28..0000000
--- a/extensions/libip6t_LOG.c
+++ /dev/null
@@ -1,184 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <syslog.h>
-#include <xtables.h>
-#include <linux/netfilter_ipv6/ip6t_LOG.h>
-
-#ifndef IP6T_LOG_UID	/* Old kernel */
-#define IP6T_LOG_UID	0x08
-#undef  IP6T_LOG_MASK
-#define IP6T_LOG_MASK	0x0f
-#endif
-
-#define LOG_DEFAULT_LEVEL LOG_WARNING
-
-enum {
-	O_LOG_LEVEL = 0,
-	O_LOG_PREFIX,
-	O_LOG_TCPSEQ,
-	O_LOG_TCPOPTS,
-	O_LOG_IPOPTS,
-	O_LOG_UID,
-	O_LOG_MAC,
-};
-
-static void LOG_help(void)
-{
-	printf(
-"LOG target options:\n"
-" --log-level level		Level of logging (numeric or see syslog.conf)\n"
-" --log-prefix prefix		Prefix log messages with this prefix.\n"
-" --log-tcp-sequence		Log TCP sequence numbers.\n"
-" --log-tcp-options		Log TCP options.\n"
-" --log-ip-options		Log IP options.\n"
-" --log-uid			Log UID owning the local socket.\n"
-" --log-macdecode		Decode MAC addresses and protocol.\n");
-}
-
-#define s struct ip6t_log_info
-static const struct xt_option_entry LOG_opts[] = {
-	{.name = "log-level", .id = O_LOG_LEVEL, .type = XTTYPE_SYSLOGLEVEL,
-	 .flags = XTOPT_PUT, XTOPT_POINTER(s, level)},
-	{.name = "log-prefix", .id = O_LOG_PREFIX, .type = XTTYPE_STRING,
-	 .flags = XTOPT_PUT, XTOPT_POINTER(s, prefix), .min = 1},
-	{.name = "log-tcp-sequence", .id = O_LOG_TCPSEQ, .type = XTTYPE_NONE},
-	{.name = "log-tcp-options", .id = O_LOG_TCPOPTS, .type = XTTYPE_NONE},
-	{.name = "log-ip-options", .id = O_LOG_IPOPTS, .type = XTTYPE_NONE},
-	{.name = "log-uid", .id = O_LOG_UID, .type = XTTYPE_NONE},
-	{.name = "log-macdecode", .id = O_LOG_MAC, .type = XTTYPE_NONE},
-	XTOPT_TABLEEND,
-};
-#undef s
-
-static void LOG_init(struct xt_entry_target *t)
-{
-	struct ip6t_log_info *loginfo = (struct ip6t_log_info *)t->data;
-
-	loginfo->level = LOG_DEFAULT_LEVEL;
-
-}
-
-struct ip6t_log_names {
-	const char *name;
-	unsigned int level;
-};
-
-static const struct ip6t_log_names ip6t_log_names[]
-= { { .name = "alert",   .level = LOG_ALERT },
-    { .name = "crit",    .level = LOG_CRIT },
-    { .name = "debug",   .level = LOG_DEBUG },
-    { .name = "emerg",   .level = LOG_EMERG },
-    { .name = "error",   .level = LOG_ERR },		/* DEPRECATED */
-    { .name = "info",    .level = LOG_INFO },
-    { .name = "notice",  .level = LOG_NOTICE },
-    { .name = "panic",   .level = LOG_EMERG },		/* DEPRECATED */
-    { .name = "warning", .level = LOG_WARNING }
-};
-
-static void LOG_parse(struct xt_option_call *cb)
-{
-	struct ip6t_log_info *info = cb->data;
-
-	xtables_option_parse(cb);
-	switch (cb->entry->id) {
-	case O_LOG_PREFIX:
-		if (strchr(cb->arg, '\n') != NULL)
-			xtables_error(PARAMETER_PROBLEM,
-				   "Newlines not allowed in --log-prefix");
-		break;
-	case O_LOG_TCPSEQ:
-		info->logflags |= IP6T_LOG_TCPSEQ;
-		break;
-	case O_LOG_TCPOPTS:
-		info->logflags |= IP6T_LOG_TCPOPT;
-		break;
-	case O_LOG_IPOPTS:
-		info->logflags |= IP6T_LOG_IPOPT;
-		break;
-	case O_LOG_UID:
-		info->logflags |= IP6T_LOG_UID;
-		break;
-	case O_LOG_MAC:
-		info->logflags |= IP6T_LOG_MACDECODE;
-		break;
-	}
-}
-
-static void LOG_print(const void *ip, const struct xt_entry_target *target,
-                      int numeric)
-{
-	const struct ip6t_log_info *loginfo
-		= (const struct ip6t_log_info *)target->data;
-	unsigned int i = 0;
-
-	printf(" LOG");
-	if (numeric)
-		printf(" flags %u level %u",
-		       loginfo->logflags, loginfo->level);
-	else {
-		for (i = 0; i < ARRAY_SIZE(ip6t_log_names); ++i)
-			if (loginfo->level == ip6t_log_names[i].level) {
-				printf(" level %s", ip6t_log_names[i].name);
-				break;
-			}
-		if (i == ARRAY_SIZE(ip6t_log_names))
-			printf(" UNKNOWN level %u", loginfo->level);
-		if (loginfo->logflags & IP6T_LOG_TCPSEQ)
-			printf(" tcp-sequence");
-		if (loginfo->logflags & IP6T_LOG_TCPOPT)
-			printf(" tcp-options");
-		if (loginfo->logflags & IP6T_LOG_IPOPT)
-			printf(" ip-options");
-		if (loginfo->logflags & IP6T_LOG_UID)
-			printf(" uid");
-		if (loginfo->logflags & IP6T_LOG_MACDECODE)
-			printf(" macdecode");
-		if (loginfo->logflags & ~(IP6T_LOG_MASK))
-			printf(" unknown-flags");
-	}
-
-	if (strcmp(loginfo->prefix, "") != 0)
-		printf(" prefix \"%s\"", loginfo->prefix);
-}
-
-static void LOG_save(const void *ip, const struct xt_entry_target *target)
-{
-	const struct ip6t_log_info *loginfo
-		= (const struct ip6t_log_info *)target->data;
-
-	if (strcmp(loginfo->prefix, "") != 0)
-		printf(" --log-prefix \"%s\"", loginfo->prefix);
-
-	if (loginfo->level != LOG_DEFAULT_LEVEL)
-		printf(" --log-level %d", loginfo->level);
-
-	if (loginfo->logflags & IP6T_LOG_TCPSEQ)
-		printf(" --log-tcp-sequence");
-	if (loginfo->logflags & IP6T_LOG_TCPOPT)
-		printf(" --log-tcp-options");
-	if (loginfo->logflags & IP6T_LOG_IPOPT)
-		printf(" --log-ip-options");
-	if (loginfo->logflags & IP6T_LOG_UID)
-		printf(" --log-uid");
-	if (loginfo->logflags & IP6T_LOG_MACDECODE)
-		printf(" --log-macdecode");
-}
-
-static struct xtables_target log_tg6_reg = {
-	.name          = "LOG",
-	.version       = XTABLES_VERSION,
-	.family        = NFPROTO_IPV6,
-	.size          = XT_ALIGN(sizeof(struct ip6t_log_info)),
-	.userspacesize = XT_ALIGN(sizeof(struct ip6t_log_info)),
-	.help          = LOG_help,
-	.init          = LOG_init,
-	.print         = LOG_print,
-	.save          = LOG_save,
-	.x6_parse      = LOG_parse,
-	.x6_options    = LOG_opts,
-};
-
-void _init(void)
-{
-	xtables_register_target(&log_tg6_reg);
-}
diff --git a/extensions/libip6t_LOG.man b/extensions/libip6t_LOG.man
deleted file mode 100644
index b7803fe..0000000
--- a/extensions/libip6t_LOG.man
+++ /dev/null
@@ -1,31 +0,0 @@
-Turn on kernel logging of matching packets.  When this option is set
-for a rule, the Linux kernel will print some information on all
-matching packets (like most IPv6 IPv6-header fields) via the kernel log
-(where it can be read with
-.I dmesg
-or 
-.IR syslogd (8)).
-This is a "non-terminating target", i.e. rule traversal continues at
-the next rule.  So if you want to LOG the packets you refuse, use two
-separate rules with the same matching criteria, first using target LOG
-then DROP (or REJECT).
-.TP
-\fB\-\-log\-level\fP \fIlevel\fP
-Level of logging (numeric or see \fIsyslog.conf\fP(5)).
-.TP
-\fB\-\-log\-prefix\fP \fIprefix\fP
-Prefix log messages with the specified prefix; up to 29 letters long,
-and useful for distinguishing messages in the logs.
-.TP
-\fB\-\-log\-tcp\-sequence\fP
-Log TCP sequence numbers. This is a security risk if the log is
-readable by users.
-.TP
-\fB\-\-log\-tcp\-options\fP
-Log options from the TCP packet header.
-.TP
-\fB\-\-log\-ip\-options\fP
-Log options from the IPv6 packet header.
-.TP
-\fB\-\-log\-uid\fP
-Log the userid of the process which generated the packet.
diff --git a/extensions/libipt_LOG.c b/extensions/libipt_LOG.c
deleted file mode 100644
index 77f16d1..0000000
--- a/extensions/libipt_LOG.c
+++ /dev/null
@@ -1,186 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <syslog.h>
-#include <xtables.h>
-#include <linux/netfilter_ipv4/ipt_LOG.h>
-
-#define LOG_DEFAULT_LEVEL LOG_WARNING
-
-#ifndef IPT_LOG_UID /* Old kernel */
-#define IPT_LOG_UID	0x08	/* Log UID owning local socket */
-#undef  IPT_LOG_MASK
-#define IPT_LOG_MASK	0x0f
-#endif
-
-enum {
-	O_LOG_LEVEL = 0,
-	O_LOG_PREFIX,
-	O_LOG_TCPSEQ,
-	O_LOG_TCPOPTS,
-	O_LOG_IPOPTS,
-	O_LOG_UID,
-	O_LOG_MAC,
-};
-
-static void LOG_help(void)
-{
-	printf(
-"LOG target options:\n"
-" --log-level level		Level of logging (numeric or see syslog.conf)\n"
-" --log-prefix prefix		Prefix log messages with this prefix.\n\n"
-" --log-tcp-sequence		Log TCP sequence numbers.\n\n"
-" --log-tcp-options		Log TCP options.\n\n"
-" --log-ip-options		Log IP options.\n\n"
-" --log-uid			Log UID owning the local socket.\n\n"
-" --log-macdecode		Decode MAC addresses and protocol.\n\n");
-}
-
-#define s struct ipt_log_info
-static const struct xt_option_entry LOG_opts[] = {
-	{.name = "log-level", .id = O_LOG_LEVEL, .type = XTTYPE_SYSLOGLEVEL,
-	 .flags = XTOPT_PUT, XTOPT_POINTER(s, level)},
-	{.name = "log-prefix", .id = O_LOG_PREFIX, .type = XTTYPE_STRING,
-	 .flags = XTOPT_PUT, XTOPT_POINTER(s, prefix), .min = 1},
-	{.name = "log-tcp-sequence", .id = O_LOG_TCPSEQ, .type = XTTYPE_NONE},
-	{.name = "log-tcp-options", .id = O_LOG_TCPOPTS, .type = XTTYPE_NONE},
-	{.name = "log-ip-options", .id = O_LOG_IPOPTS, .type = XTTYPE_NONE},
-	{.name = "log-uid", .id = O_LOG_UID, .type = XTTYPE_NONE},
-	{.name = "log-macdecode", .id = O_LOG_MAC, .type = XTTYPE_NONE},
-	XTOPT_TABLEEND,
-};
-#undef s
-
-static void LOG_init(struct xt_entry_target *t)
-{
-	struct ipt_log_info *loginfo = (struct ipt_log_info *)t->data;
-
-	loginfo->level = LOG_DEFAULT_LEVEL;
-
-}
-
-struct ipt_log_names {
-	const char *name;
-	unsigned int level;
-};
-
-static const struct ipt_log_names ipt_log_names[]
-= { { .name = "alert",   .level = LOG_ALERT },
-    { .name = "crit",    .level = LOG_CRIT },
-    { .name = "debug",   .level = LOG_DEBUG },
-    { .name = "emerg",   .level = LOG_EMERG },
-    { .name = "error",   .level = LOG_ERR },		/* DEPRECATED */
-    { .name = "info",    .level = LOG_INFO },
-    { .name = "notice",  .level = LOG_NOTICE },
-    { .name = "panic",   .level = LOG_EMERG },		/* DEPRECATED */
-    { .name = "warning", .level = LOG_WARNING }
-};
-
-static void LOG_parse(struct xt_option_call *cb)
-{
-	struct ipt_log_info *info = cb->data;
-
-	xtables_option_parse(cb);
-	switch (cb->entry->id) {
-	case O_LOG_PREFIX:
-		if (strchr(cb->arg, '\n') != NULL)
-			xtables_error(PARAMETER_PROBLEM,
-				   "Newlines not allowed in --log-prefix");
-		break;
-	case O_LOG_TCPSEQ:
-		info->logflags |= IPT_LOG_TCPSEQ;
-		break;
-	case O_LOG_TCPOPTS:
-		info->logflags |= IPT_LOG_TCPOPT;
-		break;
-	case O_LOG_IPOPTS:
-		info->logflags |= IPT_LOG_IPOPT;
-		break;
-	case O_LOG_UID:
-		info->logflags |= IPT_LOG_UID;
-		break;
-	case O_LOG_MAC:
-		info->logflags |= IPT_LOG_MACDECODE;
-		break;
-	}
-}
-
-static void LOG_print(const void *ip, const struct xt_entry_target *target,
-                      int numeric)
-{
-	const struct ipt_log_info *loginfo
-		= (const struct ipt_log_info *)target->data;
-	unsigned int i = 0;
-
-	printf(" LOG");
-	if (numeric)
-		printf(" flags %u level %u",
-		       loginfo->logflags, loginfo->level);
-	else {
-		for (i = 0; i < ARRAY_SIZE(ipt_log_names); ++i)
-			if (loginfo->level == ipt_log_names[i].level) {
-				printf(" level %s", ipt_log_names[i].name);
-				break;
-			}
-		if (i == ARRAY_SIZE(ipt_log_names))
-			printf(" UNKNOWN level %u", loginfo->level);
-		if (loginfo->logflags & IPT_LOG_TCPSEQ)
-			printf(" tcp-sequence");
-		if (loginfo->logflags & IPT_LOG_TCPOPT)
-			printf(" tcp-options");
-		if (loginfo->logflags & IPT_LOG_IPOPT)
-			printf(" ip-options");
-		if (loginfo->logflags & IPT_LOG_UID)
-			printf(" uid");
-		if (loginfo->logflags & IPT_LOG_MACDECODE)
-			printf(" macdecode");
-		if (loginfo->logflags & ~(IPT_LOG_MASK))
-			printf(" unknown-flags");
-	}
-
-	if (strcmp(loginfo->prefix, "") != 0)
-		printf(" prefix \"%s\"", loginfo->prefix);
-}
-
-static void LOG_save(const void *ip, const struct xt_entry_target *target)
-{
-	const struct ipt_log_info *loginfo
-		= (const struct ipt_log_info *)target->data;
-
-	if (strcmp(loginfo->prefix, "") != 0) {
-		printf(" --log-prefix");
-		xtables_save_string(loginfo->prefix);
-	}
-
-	if (loginfo->level != LOG_DEFAULT_LEVEL)
-		printf(" --log-level %d", loginfo->level);
-
-	if (loginfo->logflags & IPT_LOG_TCPSEQ)
-		printf(" --log-tcp-sequence");
-	if (loginfo->logflags & IPT_LOG_TCPOPT)
-		printf(" --log-tcp-options");
-	if (loginfo->logflags & IPT_LOG_IPOPT)
-		printf(" --log-ip-options");
-	if (loginfo->logflags & IPT_LOG_UID)
-		printf(" --log-uid");
-	if (loginfo->logflags & IPT_LOG_MACDECODE)
-		printf(" --log-macdecode");
-}
-
-static struct xtables_target log_tg_reg = {
-	.name          = "LOG",
-	.version       = XTABLES_VERSION,
-	.family        = NFPROTO_IPV4,
-	.size          = XT_ALIGN(sizeof(struct ipt_log_info)),
-	.userspacesize = XT_ALIGN(sizeof(struct ipt_log_info)),
-	.help          = LOG_help,
-	.init          = LOG_init,
-	.print         = LOG_print,
-	.save          = LOG_save,
-	.x6_parse      = LOG_parse,
-	.x6_options    = LOG_opts,
-};
-
-void _init(void)
-{
-	xtables_register_target(&log_tg_reg);
-}
diff --git a/extensions/libipt_LOG.man b/extensions/libipt_LOG.man
deleted file mode 100644
index 47c35e0..0000000
--- a/extensions/libipt_LOG.man
+++ /dev/null
@@ -1,31 +0,0 @@
-Turn on kernel logging of matching packets.  When this option is set
-for a rule, the Linux kernel will print some information on all
-matching packets (like most IP header fields) via the kernel log
-(where it can be read with
-.I dmesg
-or 
-.IR syslogd (8)).
-This is a "non-terminating target", i.e. rule traversal continues at
-the next rule.  So if you want to LOG the packets you refuse, use two
-separate rules with the same matching criteria, first using target LOG
-then DROP (or REJECT).
-.TP
-\fB\-\-log\-level\fP \fIlevel\fP
-Level of logging (numeric or see \fIsyslog.conf\fP(5)).
-.TP
-\fB\-\-log\-prefix\fP \fIprefix\fP
-Prefix log messages with the specified prefix; up to 29 letters long,
-and useful for distinguishing messages in the logs.
-.TP
-\fB\-\-log\-tcp\-sequence\fP
-Log TCP sequence numbers. This is a security risk if the log is
-readable by users.
-.TP
-\fB\-\-log\-tcp\-options\fP
-Log options from the TCP packet header.
-.TP
-\fB\-\-log\-ip\-options\fP
-Log options from the IP packet header.
-.TP
-\fB\-\-log\-uid\fP
-Log the userid of the process which generated the packet.
diff --git a/extensions/libxt_LOG.c b/extensions/libxt_LOG.c
new file mode 100644
index 0000000..a4c11b6
--- /dev/null
+++ b/extensions/libxt_LOG.c
@@ -0,0 +1,201 @@
+#include <stdio.h>
+#include <string.h>
+#include <syslog.h>
+#include <xtables.h>
+#include <linux/netfilter/xt_LOG.h>
+
+#define LOG_DEFAULT_LEVEL LOG_WARNING
+
+#ifndef XT_LOG_UID /* Old kernel */
+#define XT_LOG_UID	0x08	/* Log UID owning local socket */
+#undef  XT_LOG_MASK
+#define XT_LOG_MASK	0x0f
+#endif
+
+enum {
+	O_LOG_LEVEL = 0,
+	O_LOG_PREFIX,
+	O_LOG_TCPSEQ,
+	O_LOG_TCPOPTS,
+	O_LOG_IPOPTS,
+	O_LOG_UID,
+	O_LOG_MAC,
+};
+
+static void LOG_help(void)
+{
+	printf(
+"LOG target options:\n"
+" --log-level level		Level of logging (numeric or see syslog.conf)\n"
+" --log-prefix prefix		Prefix log messages with this prefix.\n\n"
+" --log-tcp-sequence		Log TCP sequence numbers.\n\n"
+" --log-tcp-options		Log TCP options.\n\n"
+" --log-ip-options		Log IP options.\n\n"
+" --log-uid			Log UID owning the local socket.\n\n"
+" --log-macdecode		Decode MAC addresses and protocol.\n\n");
+}
+
+#define s struct xt_log_info
+static const struct xt_option_entry LOG_opts[] = {
+	{.name = "log-level", .id = O_LOG_LEVEL, .type = XTTYPE_SYSLOGLEVEL,
+	 .flags = XTOPT_PUT, XTOPT_POINTER(s, level)},
+	{.name = "log-prefix", .id = O_LOG_PREFIX, .type = XTTYPE_STRING,
+	 .flags = XTOPT_PUT, XTOPT_POINTER(s, prefix), .min = 1},
+	{.name = "log-tcp-sequence", .id = O_LOG_TCPSEQ, .type = XTTYPE_NONE},
+	{.name = "log-tcp-options", .id = O_LOG_TCPOPTS, .type = XTTYPE_NONE},
+	{.name = "log-ip-options", .id = O_LOG_IPOPTS, .type = XTTYPE_NONE},
+	{.name = "log-uid", .id = O_LOG_UID, .type = XTTYPE_NONE},
+	{.name = "log-macdecode", .id = O_LOG_MAC, .type = XTTYPE_NONE},
+	XTOPT_TABLEEND,
+};
+#undef s
+
+static void LOG_init(struct xt_entry_target *t)
+{
+	struct xt_log_info *loginfo = (struct xt_log_info *)t->data;
+
+	loginfo->level = LOG_DEFAULT_LEVEL;
+
+}
+
+struct ipt_log_names {
+	const char *name;
+	unsigned int level;
+};
+
+static const struct ipt_log_names ipt_log_names[]
+= { { .name = "alert",   .level = LOG_ALERT },
+    { .name = "crit",    .level = LOG_CRIT },
+    { .name = "debug",   .level = LOG_DEBUG },
+    { .name = "emerg",   .level = LOG_EMERG },
+    { .name = "error",   .level = LOG_ERR },		/* DEPRECATED */
+    { .name = "info",    .level = LOG_INFO },
+    { .name = "notice",  .level = LOG_NOTICE },
+    { .name = "panic",   .level = LOG_EMERG },		/* DEPRECATED */
+    { .name = "warning", .level = LOG_WARNING }
+};
+
+static void LOG_parse(struct xt_option_call *cb)
+{
+	struct xt_log_info *info = cb->data;
+
+	xtables_option_parse(cb);
+	switch (cb->entry->id) {
+	case O_LOG_PREFIX:
+		if (strchr(cb->arg, '\n') != NULL)
+			xtables_error(PARAMETER_PROBLEM,
+				   "Newlines not allowed in --log-prefix");
+		break;
+	case O_LOG_TCPSEQ:
+		info->logflags |= XT_LOG_TCPSEQ;
+		break;
+	case O_LOG_TCPOPTS:
+		info->logflags |= XT_LOG_TCPOPT;
+		break;
+	case O_LOG_IPOPTS:
+		info->logflags |= XT_LOG_IPOPT;
+		break;
+	case O_LOG_UID:
+		info->logflags |= XT_LOG_UID;
+		break;
+	case O_LOG_MAC:
+		info->logflags |= XT_LOG_MACDECODE;
+		break;
+	}
+}
+
+static void LOG_print(const void *ip, const struct xt_entry_target *target,
+                      int numeric)
+{
+	const struct xt_log_info *loginfo
+		= (const struct xt_log_info *)target->data;
+	unsigned int i = 0;
+
+	printf(" LOG");
+	if (numeric)
+		printf(" flags %u level %u",
+		       loginfo->logflags, loginfo->level);
+	else {
+		for (i = 0; i < ARRAY_SIZE(ipt_log_names); ++i)
+			if (loginfo->level == ipt_log_names[i].level) {
+				printf(" level %s", ipt_log_names[i].name);
+				break;
+			}
+		if (i == ARRAY_SIZE(ipt_log_names))
+			printf(" UNKNOWN level %u", loginfo->level);
+		if (loginfo->logflags & XT_LOG_TCPSEQ)
+			printf(" tcp-sequence");
+		if (loginfo->logflags & XT_LOG_TCPOPT)
+			printf(" tcp-options");
+		if (loginfo->logflags & XT_LOG_IPOPT)
+			printf(" ip-options");
+		if (loginfo->logflags & XT_LOG_UID)
+			printf(" uid");
+		if (loginfo->logflags & XT_LOG_MACDECODE)
+			printf(" macdecode");
+		if (loginfo->logflags & ~(XT_LOG_MASK))
+			printf(" unknown-flags");
+	}
+
+	if (strcmp(loginfo->prefix, "") != 0)
+		printf(" prefix \"%s\"", loginfo->prefix);
+}
+
+static void LOG_save(const void *ip, const struct xt_entry_target *target)
+{
+	const struct xt_log_info *loginfo
+		= (const struct xt_log_info *)target->data;
+
+	if (strcmp(loginfo->prefix, "") != 0) {
+		printf(" --log-prefix");
+		xtables_save_string(loginfo->prefix);
+	}
+
+	if (loginfo->level != LOG_DEFAULT_LEVEL)
+		printf(" --log-level %d", loginfo->level);
+
+	if (loginfo->logflags & XT_LOG_TCPSEQ)
+		printf(" --log-tcp-sequence");
+	if (loginfo->logflags & XT_LOG_TCPOPT)
+		printf(" --log-tcp-options");
+	if (loginfo->logflags & XT_LOG_IPOPT)
+		printf(" --log-ip-options");
+	if (loginfo->logflags & XT_LOG_UID)
+		printf(" --log-uid");
+	if (loginfo->logflags & XT_LOG_MACDECODE)
+		printf(" --log-macdecode");
+}
+
+static struct xtables_target log_tg_regs[] = {
+	{
+		.name          = "LOG",
+		.version       = XTABLES_VERSION,
+		.family        = NFPROTO_IPV4,
+		.size          = XT_ALIGN(sizeof(struct xt_log_info)),
+		.userspacesize = XT_ALIGN(sizeof(struct xt_log_info)),
+		.help          = LOG_help,
+		.init          = LOG_init,
+		.print         = LOG_print,
+		.save          = LOG_save,
+		.x6_parse      = LOG_parse,
+		.x6_options    = LOG_opts,
+	},
+	{
+		.name          = "LOG",
+		.version       = XTABLES_VERSION,
+		.family        = NFPROTO_IPV6,
+		.size          = XT_ALIGN(sizeof(struct xt_log_info)),
+		.userspacesize = XT_ALIGN(sizeof(struct xt_log_info)),
+		.help          = LOG_help,
+		.init          = LOG_init,
+		.print         = LOG_print,
+		.save          = LOG_save,
+		.x6_parse      = LOG_parse,
+		.x6_options    = LOG_opts,
+	},
+};
+
+void _init(void)
+{
+	xtables_register_targets(log_tg_regs, ARRAY_SIZE(log_tg_regs));
+}
diff --git a/extensions/libxt_LOG.man b/extensions/libxt_LOG.man
new file mode 100644
index 0000000..47c35e0
--- /dev/null
+++ b/extensions/libxt_LOG.man
@@ -0,0 +1,31 @@
+Turn on kernel logging of matching packets.  When this option is set
+for a rule, the Linux kernel will print some information on all
+matching packets (like most IP header fields) via the kernel log
+(where it can be read with
+.I dmesg
+or 
+.IR syslogd (8)).
+This is a "non-terminating target", i.e. rule traversal continues at
+the next rule.  So if you want to LOG the packets you refuse, use two
+separate rules with the same matching criteria, first using target LOG
+then DROP (or REJECT).
+.TP
+\fB\-\-log\-level\fP \fIlevel\fP
+Level of logging (numeric or see \fIsyslog.conf\fP(5)).
+.TP
+\fB\-\-log\-prefix\fP \fIprefix\fP
+Prefix log messages with the specified prefix; up to 29 letters long,
+and useful for distinguishing messages in the logs.
+.TP
+\fB\-\-log\-tcp\-sequence\fP
+Log TCP sequence numbers. This is a security risk if the log is
+readable by users.
+.TP
+\fB\-\-log\-tcp\-options\fP
+Log options from the TCP packet header.
+.TP
+\fB\-\-log\-ip\-options\fP
+Log options from the IP packet header.
+.TP
+\fB\-\-log\-uid\fP
+Log the userid of the process which generated the packet.
diff --git a/include/linux/netfilter/xt_LOG.h b/include/linux/netfilter/xt_LOG.h
new file mode 100644
index 0000000..cac0790
--- /dev/null
+++ b/include/linux/netfilter/xt_LOG.h
@@ -0,0 +1,19 @@
+#ifndef _XT_LOG_H
+#define _XT_LOG_H
+
+/* make sure not to change this without changing nf_log.h:NF_LOG_* (!) */
+#define XT_LOG_TCPSEQ		0x01	/* Log TCP sequence numbers */
+#define XT_LOG_TCPOPT		0x02	/* Log TCP options */
+#define XT_LOG_IPOPT		0x04	/* Log IP options */
+#define XT_LOG_UID		0x08	/* Log UID owning local socket */
+#define XT_LOG_NFLOG		0x10	/* Unsupported, don't reuse */
+#define XT_LOG_MACDECODE	0x20	/* Decode MAC header */
+#define XT_LOG_MASK		0x2f
+
+struct xt_log_info {
+	unsigned char level;
+	unsigned char logflags;
+	char prefix[30];
+};
+
+#endif /* _XT_LOG_H */
-- 
1.7.7.3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 1/4] Netfilter: Merge ipt_LOG and ip6_LOG into xt_LOG
  2012-02-10 22:10 [PATCH v5] Merge ipt_LOG and ip6t_LOG, add ring bufffer support Richard Weinberger
  2012-02-10 22:10 ` [PATCH 1/2] iptables: Merge libip6t_LOG and libipt_LOG into libxt_LOG Richard Weinberger
@ 2012-02-10 22:10 ` Richard Weinberger
  2012-02-13 23:56   ` Pablo Neira Ayuso
  2012-02-10 22:10 ` [PATCH 2/2] iptables: xt_LOG: Add ring buffer support Richard Weinberger
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 16+ messages in thread
From: Richard Weinberger @ 2012-02-10 22:10 UTC (permalink / raw)
  To: netfilter-devel
  Cc: netdev, linux-kernel, eric.dumazet, jengelh, rostedt, pablo,
	basti, Richard Weinberger

ipt_LOG and ip6_LOG have a lot of common code, merge them
to reduce duplicate code.

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 include/linux/netfilter/Kbuild          |    1 +
 include/linux/netfilter/xt_LOG.h        |   19 +
 include/linux/netfilter_ipv4/ipt_LOG.h  |    2 +
 include/linux/netfilter_ipv6/ip6t_LOG.h |    2 +
 net/ipv4/netfilter/Kconfig              |    9 -
 net/ipv4/netfilter/Makefile             |    1 -
 net/ipv4/netfilter/ipt_LOG.c            |  516 -----------------
 net/ipv6/netfilter/Kconfig              |    9 -
 net/ipv6/netfilter/Makefile             |    1 -
 net/ipv6/netfilter/ip6t_LOG.c           |  527 ------------------
 net/netfilter/Kconfig                   |    9 +
 net/netfilter/Makefile                  |    1 +
 net/netfilter/xt_LOG.c                  |  921 +++++++++++++++++++++++++++++++
 13 files changed, 955 insertions(+), 1063 deletions(-)
 create mode 100644 include/linux/netfilter/xt_LOG.h
 delete mode 100644 net/ipv4/netfilter/ipt_LOG.c
 delete mode 100644 net/ipv6/netfilter/ip6t_LOG.c
 create mode 100644 net/netfilter/xt_LOG.c

diff --git a/include/linux/netfilter/Kbuild b/include/linux/netfilter/Kbuild
index e144f54..aaa72aa 100644
--- a/include/linux/netfilter/Kbuild
+++ b/include/linux/netfilter/Kbuild
@@ -22,6 +22,7 @@ header-y += xt_CT.h
 header-y += xt_DSCP.h
 header-y += xt_IDLETIMER.h
 header-y += xt_LED.h
+header-y += xt_LOG.h
 header-y += xt_MARK.h
 header-y += xt_nfacct.h
 header-y += xt_NFLOG.h
diff --git a/include/linux/netfilter/xt_LOG.h b/include/linux/netfilter/xt_LOG.h
new file mode 100644
index 0000000..cac0790
--- /dev/null
+++ b/include/linux/netfilter/xt_LOG.h
@@ -0,0 +1,19 @@
+#ifndef _XT_LOG_H
+#define _XT_LOG_H
+
+/* make sure not to change this without changing nf_log.h:NF_LOG_* (!) */
+#define XT_LOG_TCPSEQ		0x01	/* Log TCP sequence numbers */
+#define XT_LOG_TCPOPT		0x02	/* Log TCP options */
+#define XT_LOG_IPOPT		0x04	/* Log IP options */
+#define XT_LOG_UID		0x08	/* Log UID owning local socket */
+#define XT_LOG_NFLOG		0x10	/* Unsupported, don't reuse */
+#define XT_LOG_MACDECODE	0x20	/* Decode MAC header */
+#define XT_LOG_MASK		0x2f
+
+struct xt_log_info {
+	unsigned char level;
+	unsigned char logflags;
+	char prefix[30];
+};
+
+#endif /* _XT_LOG_H */
diff --git a/include/linux/netfilter_ipv4/ipt_LOG.h b/include/linux/netfilter_ipv4/ipt_LOG.h
index dcdbadf..5d81520 100644
--- a/include/linux/netfilter_ipv4/ipt_LOG.h
+++ b/include/linux/netfilter_ipv4/ipt_LOG.h
@@ -1,6 +1,8 @@
 #ifndef _IPT_LOG_H
 #define _IPT_LOG_H
 
+#warning "Please update iptables, this file will be removed soon!"
+
 /* make sure not to change this without changing netfilter.h:NF_LOG_* (!) */
 #define IPT_LOG_TCPSEQ		0x01	/* Log TCP sequence numbers */
 #define IPT_LOG_TCPOPT		0x02	/* Log TCP options */
diff --git a/include/linux/netfilter_ipv6/ip6t_LOG.h b/include/linux/netfilter_ipv6/ip6t_LOG.h
index 9dd5579..3dd0bc4 100644
--- a/include/linux/netfilter_ipv6/ip6t_LOG.h
+++ b/include/linux/netfilter_ipv6/ip6t_LOG.h
@@ -1,6 +1,8 @@
 #ifndef _IP6T_LOG_H
 #define _IP6T_LOG_H
 
+#warning "Please update iptables, this file will be removed soon!"
+
 /* make sure not to change this without changing netfilter.h:NF_LOG_* (!) */
 #define IP6T_LOG_TCPSEQ		0x01	/* Log TCP sequence numbers */
 #define IP6T_LOG_TCPOPT		0x02	/* Log TCP options */
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
index 74dfc9e..fcc543c 100644
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -123,15 +123,6 @@ config IP_NF_TARGET_REJECT
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 
-config IP_NF_TARGET_LOG
-	tristate "LOG target support"
-	default m if NETFILTER_ADVANCED=n
-	help
-	  This option adds a `LOG' target, which allows you to create rules in
-	  any iptables table which records the packet header to the syslog.
-
-	  To compile it as a module, choose M here.  If unsure, say N.
-
 config IP_NF_TARGET_ULOG
 	tristate "ULOG target support"
 	default m if NETFILTER_ADVANCED=n
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
index 213a462..240b684 100644
--- a/net/ipv4/netfilter/Makefile
+++ b/net/ipv4/netfilter/Makefile
@@ -54,7 +54,6 @@ obj-$(CONFIG_IP_NF_MATCH_RPFILTER) += ipt_rpfilter.o
 # targets
 obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o
 obj-$(CONFIG_IP_NF_TARGET_ECN) += ipt_ECN.o
-obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o
 obj-$(CONFIG_IP_NF_TARGET_MASQUERADE) += ipt_MASQUERADE.o
 obj-$(CONFIG_IP_NF_TARGET_NETMAP) += ipt_NETMAP.o
 obj-$(CONFIG_IP_NF_TARGET_REDIRECT) += ipt_REDIRECT.o
diff --git a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c
deleted file mode 100644
index d76d6c9..0000000
--- a/net/ipv4/netfilter/ipt_LOG.c
+++ /dev/null
@@ -1,516 +0,0 @@
-/*
- * This is a module which is used for logging packets.
- */
-
-/* (C) 1999-2001 Paul `Rusty' Russell
- * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
- *
- * 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.
- */
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-#include <linux/module.h>
-#include <linux/spinlock.h>
-#include <linux/skbuff.h>
-#include <linux/if_arp.h>
-#include <linux/ip.h>
-#include <net/icmp.h>
-#include <net/udp.h>
-#include <net/tcp.h>
-#include <net/route.h>
-
-#include <linux/netfilter.h>
-#include <linux/netfilter/x_tables.h>
-#include <linux/netfilter_ipv4/ipt_LOG.h>
-#include <net/netfilter/nf_log.h>
-#include <net/netfilter/xt_log.h>
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
-MODULE_DESCRIPTION("Xtables: IPv4 packet logging to syslog");
-
-/* One level of recursion won't kill us */
-static void dump_packet(struct sbuff *m,
-			const struct nf_loginfo *info,
-			const struct sk_buff *skb,
-			unsigned int iphoff)
-{
-	struct iphdr _iph;
-	const struct iphdr *ih;
-	unsigned int logflags;
-
-	if (info->type == NF_LOG_TYPE_LOG)
-		logflags = info->u.log.logflags;
-	else
-		logflags = NF_LOG_MASK;
-
-	ih = skb_header_pointer(skb, iphoff, sizeof(_iph), &_iph);
-	if (ih == NULL) {
-		sb_add(m, "TRUNCATED");
-		return;
-	}
-
-	/* Important fields:
-	 * TOS, len, DF/MF, fragment offset, TTL, src, dst, options. */
-	/* Max length: 40 "SRC=255.255.255.255 DST=255.255.255.255 " */
-	sb_add(m, "SRC=%pI4 DST=%pI4 ",
-	       &ih->saddr, &ih->daddr);
-
-	/* Max length: 46 "LEN=65535 TOS=0xFF PREC=0xFF TTL=255 ID=65535 " */
-	sb_add(m, "LEN=%u TOS=0x%02X PREC=0x%02X TTL=%u ID=%u ",
-	       ntohs(ih->tot_len), ih->tos & IPTOS_TOS_MASK,
-	       ih->tos & IPTOS_PREC_MASK, ih->ttl, ntohs(ih->id));
-
-	/* Max length: 6 "CE DF MF " */
-	if (ntohs(ih->frag_off) & IP_CE)
-		sb_add(m, "CE ");
-	if (ntohs(ih->frag_off) & IP_DF)
-		sb_add(m, "DF ");
-	if (ntohs(ih->frag_off) & IP_MF)
-		sb_add(m, "MF ");
-
-	/* Max length: 11 "FRAG:65535 " */
-	if (ntohs(ih->frag_off) & IP_OFFSET)
-		sb_add(m, "FRAG:%u ", ntohs(ih->frag_off) & IP_OFFSET);
-
-	if ((logflags & IPT_LOG_IPOPT) &&
-	    ih->ihl * 4 > sizeof(struct iphdr)) {
-		const unsigned char *op;
-		unsigned char _opt[4 * 15 - sizeof(struct iphdr)];
-		unsigned int i, optsize;
-
-		optsize = ih->ihl * 4 - sizeof(struct iphdr);
-		op = skb_header_pointer(skb, iphoff+sizeof(_iph),
-					optsize, _opt);
-		if (op == NULL) {
-			sb_add(m, "TRUNCATED");
-			return;
-		}
-
-		/* Max length: 127 "OPT (" 15*4*2chars ") " */
-		sb_add(m, "OPT (");
-		for (i = 0; i < optsize; i++)
-			sb_add(m, "%02X", op[i]);
-		sb_add(m, ") ");
-	}
-
-	switch (ih->protocol) {
-	case IPPROTO_TCP: {
-		struct tcphdr _tcph;
-		const struct tcphdr *th;
-
-		/* Max length: 10 "PROTO=TCP " */
-		sb_add(m, "PROTO=TCP ");
-
-		if (ntohs(ih->frag_off) & IP_OFFSET)
-			break;
-
-		/* Max length: 25 "INCOMPLETE [65535 bytes] " */
-		th = skb_header_pointer(skb, iphoff + ih->ihl * 4,
-					sizeof(_tcph), &_tcph);
-		if (th == NULL) {
-			sb_add(m, "INCOMPLETE [%u bytes] ",
-			       skb->len - iphoff - ih->ihl*4);
-			break;
-		}
-
-		/* Max length: 20 "SPT=65535 DPT=65535 " */
-		sb_add(m, "SPT=%u DPT=%u ",
-		       ntohs(th->source), ntohs(th->dest));
-		/* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */
-		if (logflags & IPT_LOG_TCPSEQ)
-			sb_add(m, "SEQ=%u ACK=%u ",
-			       ntohl(th->seq), ntohl(th->ack_seq));
-		/* Max length: 13 "WINDOW=65535 " */
-		sb_add(m, "WINDOW=%u ", ntohs(th->window));
-		/* Max length: 9 "RES=0x3F " */
-		sb_add(m, "RES=0x%02x ", (u8)(ntohl(tcp_flag_word(th) & TCP_RESERVED_BITS) >> 22));
-		/* Max length: 32 "CWR ECE URG ACK PSH RST SYN FIN " */
-		if (th->cwr)
-			sb_add(m, "CWR ");
-		if (th->ece)
-			sb_add(m, "ECE ");
-		if (th->urg)
-			sb_add(m, "URG ");
-		if (th->ack)
-			sb_add(m, "ACK ");
-		if (th->psh)
-			sb_add(m, "PSH ");
-		if (th->rst)
-			sb_add(m, "RST ");
-		if (th->syn)
-			sb_add(m, "SYN ");
-		if (th->fin)
-			sb_add(m, "FIN ");
-		/* Max length: 11 "URGP=65535 " */
-		sb_add(m, "URGP=%u ", ntohs(th->urg_ptr));
-
-		if ((logflags & IPT_LOG_TCPOPT) &&
-		    th->doff * 4 > sizeof(struct tcphdr)) {
-			unsigned char _opt[4 * 15 - sizeof(struct tcphdr)];
-			const unsigned char *op;
-			unsigned int i, optsize;
-
-			optsize = th->doff * 4 - sizeof(struct tcphdr);
-			op = skb_header_pointer(skb,
-						iphoff+ih->ihl*4+sizeof(_tcph),
-						optsize, _opt);
-			if (op == NULL) {
-				sb_add(m, "TRUNCATED");
-				return;
-			}
-
-			/* Max length: 127 "OPT (" 15*4*2chars ") " */
-			sb_add(m, "OPT (");
-			for (i = 0; i < optsize; i++)
-				sb_add(m, "%02X", op[i]);
-			sb_add(m, ") ");
-		}
-		break;
-	}
-	case IPPROTO_UDP:
-	case IPPROTO_UDPLITE: {
-		struct udphdr _udph;
-		const struct udphdr *uh;
-
-		if (ih->protocol == IPPROTO_UDP)
-			/* Max length: 10 "PROTO=UDP "     */
-			sb_add(m, "PROTO=UDP " );
-		else	/* Max length: 14 "PROTO=UDPLITE " */
-			sb_add(m, "PROTO=UDPLITE ");
-
-		if (ntohs(ih->frag_off) & IP_OFFSET)
-			break;
-
-		/* Max length: 25 "INCOMPLETE [65535 bytes] " */
-		uh = skb_header_pointer(skb, iphoff+ih->ihl*4,
-					sizeof(_udph), &_udph);
-		if (uh == NULL) {
-			sb_add(m, "INCOMPLETE [%u bytes] ",
-			       skb->len - iphoff - ih->ihl*4);
-			break;
-		}
-
-		/* Max length: 20 "SPT=65535 DPT=65535 " */
-		sb_add(m, "SPT=%u DPT=%u LEN=%u ",
-		       ntohs(uh->source), ntohs(uh->dest),
-		       ntohs(uh->len));
-		break;
-	}
-	case IPPROTO_ICMP: {
-		struct icmphdr _icmph;
-		const struct icmphdr *ich;
-		static const size_t required_len[NR_ICMP_TYPES+1]
-			= { [ICMP_ECHOREPLY] = 4,
-			    [ICMP_DEST_UNREACH]
-			    = 8 + sizeof(struct iphdr),
-			    [ICMP_SOURCE_QUENCH]
-			    = 8 + sizeof(struct iphdr),
-			    [ICMP_REDIRECT]
-			    = 8 + sizeof(struct iphdr),
-			    [ICMP_ECHO] = 4,
-			    [ICMP_TIME_EXCEEDED]
-			    = 8 + sizeof(struct iphdr),
-			    [ICMP_PARAMETERPROB]
-			    = 8 + sizeof(struct iphdr),
-			    [ICMP_TIMESTAMP] = 20,
-			    [ICMP_TIMESTAMPREPLY] = 20,
-			    [ICMP_ADDRESS] = 12,
-			    [ICMP_ADDRESSREPLY] = 12 };
-
-		/* Max length: 11 "PROTO=ICMP " */
-		sb_add(m, "PROTO=ICMP ");
-
-		if (ntohs(ih->frag_off) & IP_OFFSET)
-			break;
-
-		/* Max length: 25 "INCOMPLETE [65535 bytes] " */
-		ich = skb_header_pointer(skb, iphoff + ih->ihl * 4,
-					 sizeof(_icmph), &_icmph);
-		if (ich == NULL) {
-			sb_add(m, "INCOMPLETE [%u bytes] ",
-			       skb->len - iphoff - ih->ihl*4);
-			break;
-		}
-
-		/* Max length: 18 "TYPE=255 CODE=255 " */
-		sb_add(m, "TYPE=%u CODE=%u ", ich->type, ich->code);
-
-		/* Max length: 25 "INCOMPLETE [65535 bytes] " */
-		if (ich->type <= NR_ICMP_TYPES &&
-		    required_len[ich->type] &&
-		    skb->len-iphoff-ih->ihl*4 < required_len[ich->type]) {
-			sb_add(m, "INCOMPLETE [%u bytes] ",
-			       skb->len - iphoff - ih->ihl*4);
-			break;
-		}
-
-		switch (ich->type) {
-		case ICMP_ECHOREPLY:
-		case ICMP_ECHO:
-			/* Max length: 19 "ID=65535 SEQ=65535 " */
-			sb_add(m, "ID=%u SEQ=%u ",
-			       ntohs(ich->un.echo.id),
-			       ntohs(ich->un.echo.sequence));
-			break;
-
-		case ICMP_PARAMETERPROB:
-			/* Max length: 14 "PARAMETER=255 " */
-			sb_add(m, "PARAMETER=%u ",
-			       ntohl(ich->un.gateway) >> 24);
-			break;
-		case ICMP_REDIRECT:
-			/* Max length: 24 "GATEWAY=255.255.255.255 " */
-			sb_add(m, "GATEWAY=%pI4 ", &ich->un.gateway);
-			/* Fall through */
-		case ICMP_DEST_UNREACH:
-		case ICMP_SOURCE_QUENCH:
-		case ICMP_TIME_EXCEEDED:
-			/* Max length: 3+maxlen */
-			if (!iphoff) { /* Only recurse once. */
-				sb_add(m, "[");
-				dump_packet(m, info, skb,
-					    iphoff + ih->ihl*4+sizeof(_icmph));
-				sb_add(m, "] ");
-			}
-
-			/* Max length: 10 "MTU=65535 " */
-			if (ich->type == ICMP_DEST_UNREACH &&
-			    ich->code == ICMP_FRAG_NEEDED)
-				sb_add(m, "MTU=%u ", ntohs(ich->un.frag.mtu));
-		}
-		break;
-	}
-	/* Max Length */
-	case IPPROTO_AH: {
-		struct ip_auth_hdr _ahdr;
-		const struct ip_auth_hdr *ah;
-
-		if (ntohs(ih->frag_off) & IP_OFFSET)
-			break;
-
-		/* Max length: 9 "PROTO=AH " */
-		sb_add(m, "PROTO=AH ");
-
-		/* Max length: 25 "INCOMPLETE [65535 bytes] " */
-		ah = skb_header_pointer(skb, iphoff+ih->ihl*4,
-					sizeof(_ahdr), &_ahdr);
-		if (ah == NULL) {
-			sb_add(m, "INCOMPLETE [%u bytes] ",
-			       skb->len - iphoff - ih->ihl*4);
-			break;
-		}
-
-		/* Length: 15 "SPI=0xF1234567 " */
-		sb_add(m, "SPI=0x%x ", ntohl(ah->spi));
-		break;
-	}
-	case IPPROTO_ESP: {
-		struct ip_esp_hdr _esph;
-		const struct ip_esp_hdr *eh;
-
-		/* Max length: 10 "PROTO=ESP " */
-		sb_add(m, "PROTO=ESP ");
-
-		if (ntohs(ih->frag_off) & IP_OFFSET)
-			break;
-
-		/* Max length: 25 "INCOMPLETE [65535 bytes] " */
-		eh = skb_header_pointer(skb, iphoff+ih->ihl*4,
-					sizeof(_esph), &_esph);
-		if (eh == NULL) {
-			sb_add(m, "INCOMPLETE [%u bytes] ",
-			       skb->len - iphoff - ih->ihl*4);
-			break;
-		}
-
-		/* Length: 15 "SPI=0xF1234567 " */
-		sb_add(m, "SPI=0x%x ", ntohl(eh->spi));
-		break;
-	}
-	/* Max length: 10 "PROTO 255 " */
-	default:
-		sb_add(m, "PROTO=%u ", ih->protocol);
-	}
-
-	/* Max length: 15 "UID=4294967295 " */
-	if ((logflags & IPT_LOG_UID) && !iphoff && skb->sk) {
-		read_lock_bh(&skb->sk->sk_callback_lock);
-		if (skb->sk->sk_socket && skb->sk->sk_socket->file)
-			sb_add(m, "UID=%u GID=%u ",
-				skb->sk->sk_socket->file->f_cred->fsuid,
-				skb->sk->sk_socket->file->f_cred->fsgid);
-		read_unlock_bh(&skb->sk->sk_callback_lock);
-	}
-
-	/* Max length: 16 "MARK=0xFFFFFFFF " */
-	if (!iphoff && skb->mark)
-		sb_add(m, "MARK=0x%x ", skb->mark);
-
-	/* Proto    Max log string length */
-	/* IP:      40+46+6+11+127 = 230 */
-	/* TCP:     10+max(25,20+30+13+9+32+11+127) = 252 */
-	/* UDP:     10+max(25,20) = 35 */
-	/* UDPLITE: 14+max(25,20) = 39 */
-	/* ICMP:    11+max(25, 18+25+max(19,14,24+3+n+10,3+n+10)) = 91+n */
-	/* ESP:     10+max(25)+15 = 50 */
-	/* AH:      9+max(25)+15 = 49 */
-	/* unknown: 10 */
-
-	/* (ICMP allows recursion one level deep) */
-	/* maxlen =  IP + ICMP +  IP + max(TCP,UDP,ICMP,unknown) */
-	/* maxlen = 230+   91  + 230 + 252 = 803 */
-}
-
-static void dump_mac_header(struct sbuff *m,
-			    const struct nf_loginfo *info,
-			    const struct sk_buff *skb)
-{
-	struct net_device *dev = skb->dev;
-	unsigned int logflags = 0;
-
-	if (info->type == NF_LOG_TYPE_LOG)
-		logflags = info->u.log.logflags;
-
-	if (!(logflags & IPT_LOG_MACDECODE))
-		goto fallback;
-
-	switch (dev->type) {
-	case ARPHRD_ETHER:
-		sb_add(m, "MACSRC=%pM MACDST=%pM MACPROTO=%04x ",
-		       eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest,
-		       ntohs(eth_hdr(skb)->h_proto));
-		return;
-	default:
-		break;
-	}
-
-fallback:
-	sb_add(m, "MAC=");
-	if (dev->hard_header_len &&
-	    skb->mac_header != skb->network_header) {
-		const unsigned char *p = skb_mac_header(skb);
-		unsigned int i;
-
-		sb_add(m, "%02x", *p++);
-		for (i = 1; i < dev->hard_header_len; i++, p++)
-			sb_add(m, ":%02x", *p);
-	}
-	sb_add(m, " ");
-}
-
-static struct nf_loginfo default_loginfo = {
-	.type	= NF_LOG_TYPE_LOG,
-	.u = {
-		.log = {
-			.level    = 5,
-			.logflags = NF_LOG_MASK,
-		},
-	},
-};
-
-static void
-ipt_log_packet(u_int8_t pf,
-	       unsigned int hooknum,
-	       const struct sk_buff *skb,
-	       const struct net_device *in,
-	       const struct net_device *out,
-	       const struct nf_loginfo *loginfo,
-	       const char *prefix)
-{
-	struct sbuff *m = sb_open();
-
-	if (!loginfo)
-		loginfo = &default_loginfo;
-
-	sb_add(m, "<%d>%sIN=%s OUT=%s ", loginfo->u.log.level,
-	       prefix,
-	       in ? in->name : "",
-	       out ? out->name : "");
-#ifdef CONFIG_BRIDGE_NETFILTER
-	if (skb->nf_bridge) {
-		const struct net_device *physindev;
-		const struct net_device *physoutdev;
-
-		physindev = skb->nf_bridge->physindev;
-		if (physindev && in != physindev)
-			sb_add(m, "PHYSIN=%s ", physindev->name);
-		physoutdev = skb->nf_bridge->physoutdev;
-		if (physoutdev && out != physoutdev)
-			sb_add(m, "PHYSOUT=%s ", physoutdev->name);
-	}
-#endif
-
-	if (in != NULL)
-		dump_mac_header(m, loginfo, skb);
-
-	dump_packet(m, loginfo, skb, 0);
-
-	sb_close(m);
-}
-
-static unsigned int
-log_tg(struct sk_buff *skb, const struct xt_action_param *par)
-{
-	const struct ipt_log_info *loginfo = par->targinfo;
-	struct nf_loginfo li;
-
-	li.type = NF_LOG_TYPE_LOG;
-	li.u.log.level = loginfo->level;
-	li.u.log.logflags = loginfo->logflags;
-
-	ipt_log_packet(NFPROTO_IPV4, par->hooknum, skb, par->in, par->out, &li,
-		       loginfo->prefix);
-	return XT_CONTINUE;
-}
-
-static int log_tg_check(const struct xt_tgchk_param *par)
-{
-	const struct ipt_log_info *loginfo = par->targinfo;
-
-	if (loginfo->level >= 8) {
-		pr_debug("level %u >= 8\n", loginfo->level);
-		return -EINVAL;
-	}
-	if (loginfo->prefix[sizeof(loginfo->prefix)-1] != '\0') {
-		pr_debug("prefix is not null-terminated\n");
-		return -EINVAL;
-	}
-	return 0;
-}
-
-static struct xt_target log_tg_reg __read_mostly = {
-	.name		= "LOG",
-	.family		= NFPROTO_IPV4,
-	.target		= log_tg,
-	.targetsize	= sizeof(struct ipt_log_info),
-	.checkentry	= log_tg_check,
-	.me		= THIS_MODULE,
-};
-
-static struct nf_logger ipt_log_logger __read_mostly = {
-	.name		= "ipt_LOG",
-	.logfn		= &ipt_log_packet,
-	.me		= THIS_MODULE,
-};
-
-static int __init log_tg_init(void)
-{
-	int ret;
-
-	ret = xt_register_target(&log_tg_reg);
-	if (ret < 0)
-		return ret;
-	nf_log_register(NFPROTO_IPV4, &ipt_log_logger);
-	return 0;
-}
-
-static void __exit log_tg_exit(void)
-{
-	nf_log_unregister(&ipt_log_logger);
-	xt_unregister_target(&log_tg_reg);
-}
-
-module_init(log_tg_init);
-module_exit(log_tg_exit);
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index 9a68fb5..d33cddd 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -154,15 +154,6 @@ config IP6_NF_TARGET_HL
 	(e.g. when running oldconfig). It selects
 	CONFIG_NETFILTER_XT_TARGET_HL.
 
-config IP6_NF_TARGET_LOG
-	tristate "LOG target support"
-	default m if NETFILTER_ADVANCED=n
-	help
-	  This option adds a `LOG' target, which allows you to create rules in
-	  any iptables table which records the packet header to the syslog.
-
-	  To compile it as a module, choose M here.  If unsure, say N.
-
 config IP6_NF_FILTER
 	tristate "Packet filtering"
 	default m if NETFILTER_ADVANCED=n
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile
index 2eaed96..d4dfd0a 100644
--- a/net/ipv6/netfilter/Makefile
+++ b/net/ipv6/netfilter/Makefile
@@ -31,5 +31,4 @@ obj-$(CONFIG_IP6_NF_MATCH_RPFILTER) += ip6t_rpfilter.o
 obj-$(CONFIG_IP6_NF_MATCH_RT) += ip6t_rt.o
 
 # targets
-obj-$(CONFIG_IP6_NF_TARGET_LOG) += ip6t_LOG.o
 obj-$(CONFIG_IP6_NF_TARGET_REJECT) += ip6t_REJECT.o
diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c
deleted file mode 100644
index e6af8d7..0000000
--- a/net/ipv6/netfilter/ip6t_LOG.c
+++ /dev/null
@@ -1,527 +0,0 @@
-/*
- * This is a module which is used for logging packets.
- */
-
-/* (C) 2001 Jan Rekorajski <baggins@pld.org.pl>
- * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
- *
- * 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.
- */
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-#include <linux/module.h>
-#include <linux/skbuff.h>
-#include <linux/if_arp.h>
-#include <linux/ip.h>
-#include <linux/spinlock.h>
-#include <linux/icmpv6.h>
-#include <net/udp.h>
-#include <net/tcp.h>
-#include <net/ipv6.h>
-#include <linux/netfilter.h>
-#include <linux/netfilter/x_tables.h>
-#include <linux/netfilter_ipv6/ip6_tables.h>
-#include <net/netfilter/nf_log.h>
-#include <net/netfilter/xt_log.h>
-
-MODULE_AUTHOR("Jan Rekorajski <baggins@pld.org.pl>");
-MODULE_DESCRIPTION("Xtables: IPv6 packet logging to syslog");
-MODULE_LICENSE("GPL");
-
-struct in_device;
-#include <net/route.h>
-#include <linux/netfilter_ipv6/ip6t_LOG.h>
-
-/* One level of recursion won't kill us */
-static void dump_packet(struct sbuff *m,
-			const struct nf_loginfo *info,
-			const struct sk_buff *skb, unsigned int ip6hoff,
-			int recurse)
-{
-	u_int8_t currenthdr;
-	int fragment;
-	struct ipv6hdr _ip6h;
-	const struct ipv6hdr *ih;
-	unsigned int ptr;
-	unsigned int hdrlen = 0;
-	unsigned int logflags;
-
-	if (info->type == NF_LOG_TYPE_LOG)
-		logflags = info->u.log.logflags;
-	else
-		logflags = NF_LOG_MASK;
-
-	ih = skb_header_pointer(skb, ip6hoff, sizeof(_ip6h), &_ip6h);
-	if (ih == NULL) {
-		sb_add(m, "TRUNCATED");
-		return;
-	}
-
-	/* Max length: 88 "SRC=0000.0000.0000.0000.0000.0000.0000.0000 DST=0000.0000.0000.0000.0000.0000.0000.0000 " */
-	sb_add(m, "SRC=%pI6 DST=%pI6 ", &ih->saddr, &ih->daddr);
-
-	/* Max length: 44 "LEN=65535 TC=255 HOPLIMIT=255 FLOWLBL=FFFFF " */
-	sb_add(m, "LEN=%Zu TC=%u HOPLIMIT=%u FLOWLBL=%u ",
-	       ntohs(ih->payload_len) + sizeof(struct ipv6hdr),
-	       (ntohl(*(__be32 *)ih) & 0x0ff00000) >> 20,
-	       ih->hop_limit,
-	       (ntohl(*(__be32 *)ih) & 0x000fffff));
-
-	fragment = 0;
-	ptr = ip6hoff + sizeof(struct ipv6hdr);
-	currenthdr = ih->nexthdr;
-	while (currenthdr != NEXTHDR_NONE && ip6t_ext_hdr(currenthdr)) {
-		struct ipv6_opt_hdr _hdr;
-		const struct ipv6_opt_hdr *hp;
-
-		hp = skb_header_pointer(skb, ptr, sizeof(_hdr), &_hdr);
-		if (hp == NULL) {
-			sb_add(m, "TRUNCATED");
-			return;
-		}
-
-		/* Max length: 48 "OPT (...) " */
-		if (logflags & IP6T_LOG_IPOPT)
-			sb_add(m, "OPT ( ");
-
-		switch (currenthdr) {
-		case IPPROTO_FRAGMENT: {
-			struct frag_hdr _fhdr;
-			const struct frag_hdr *fh;
-
-			sb_add(m, "FRAG:");
-			fh = skb_header_pointer(skb, ptr, sizeof(_fhdr),
-						&_fhdr);
-			if (fh == NULL) {
-				sb_add(m, "TRUNCATED ");
-				return;
-			}
-
-			/* Max length: 6 "65535 " */
-			sb_add(m, "%u ", ntohs(fh->frag_off) & 0xFFF8);
-
-			/* Max length: 11 "INCOMPLETE " */
-			if (fh->frag_off & htons(0x0001))
-				sb_add(m, "INCOMPLETE ");
-
-			sb_add(m, "ID:%08x ", ntohl(fh->identification));
-
-			if (ntohs(fh->frag_off) & 0xFFF8)
-				fragment = 1;
-
-			hdrlen = 8;
-
-			break;
-		}
-		case IPPROTO_DSTOPTS:
-		case IPPROTO_ROUTING:
-		case IPPROTO_HOPOPTS:
-			if (fragment) {
-				if (logflags & IP6T_LOG_IPOPT)
-					sb_add(m, ")");
-				return;
-			}
-			hdrlen = ipv6_optlen(hp);
-			break;
-		/* Max Length */
-		case IPPROTO_AH:
-			if (logflags & IP6T_LOG_IPOPT) {
-				struct ip_auth_hdr _ahdr;
-				const struct ip_auth_hdr *ah;
-
-				/* Max length: 3 "AH " */
-				sb_add(m, "AH ");
-
-				if (fragment) {
-					sb_add(m, ")");
-					return;
-				}
-
-				ah = skb_header_pointer(skb, ptr, sizeof(_ahdr),
-							&_ahdr);
-				if (ah == NULL) {
-					/*
-					 * Max length: 26 "INCOMPLETE [65535
-					 *  bytes] )"
-					 */
-					sb_add(m, "INCOMPLETE [%u bytes] )",
-					       skb->len - ptr);
-					return;
-				}
-
-				/* Length: 15 "SPI=0xF1234567 */
-				sb_add(m, "SPI=0x%x ", ntohl(ah->spi));
-
-			}
-
-			hdrlen = (hp->hdrlen+2)<<2;
-			break;
-		case IPPROTO_ESP:
-			if (logflags & IP6T_LOG_IPOPT) {
-				struct ip_esp_hdr _esph;
-				const struct ip_esp_hdr *eh;
-
-				/* Max length: 4 "ESP " */
-				sb_add(m, "ESP ");
-
-				if (fragment) {
-					sb_add(m, ")");
-					return;
-				}
-
-				/*
-				 * Max length: 26 "INCOMPLETE [65535 bytes] )"
-				 */
-				eh = skb_header_pointer(skb, ptr, sizeof(_esph),
-							&_esph);
-				if (eh == NULL) {
-					sb_add(m, "INCOMPLETE [%u bytes] )",
-					       skb->len - ptr);
-					return;
-				}
-
-				/* Length: 16 "SPI=0xF1234567 )" */
-				sb_add(m, "SPI=0x%x )", ntohl(eh->spi) );
-
-			}
-			return;
-		default:
-			/* Max length: 20 "Unknown Ext Hdr 255" */
-			sb_add(m, "Unknown Ext Hdr %u", currenthdr);
-			return;
-		}
-		if (logflags & IP6T_LOG_IPOPT)
-			sb_add(m, ") ");
-
-		currenthdr = hp->nexthdr;
-		ptr += hdrlen;
-	}
-
-	switch (currenthdr) {
-	case IPPROTO_TCP: {
-		struct tcphdr _tcph;
-		const struct tcphdr *th;
-
-		/* Max length: 10 "PROTO=TCP " */
-		sb_add(m, "PROTO=TCP ");
-
-		if (fragment)
-			break;
-
-		/* Max length: 25 "INCOMPLETE [65535 bytes] " */
-		th = skb_header_pointer(skb, ptr, sizeof(_tcph), &_tcph);
-		if (th == NULL) {
-			sb_add(m, "INCOMPLETE [%u bytes] ", skb->len - ptr);
-			return;
-		}
-
-		/* Max length: 20 "SPT=65535 DPT=65535 " */
-		sb_add(m, "SPT=%u DPT=%u ",
-		       ntohs(th->source), ntohs(th->dest));
-		/* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */
-		if (logflags & IP6T_LOG_TCPSEQ)
-			sb_add(m, "SEQ=%u ACK=%u ",
-			       ntohl(th->seq), ntohl(th->ack_seq));
-		/* Max length: 13 "WINDOW=65535 " */
-		sb_add(m, "WINDOW=%u ", ntohs(th->window));
-		/* Max length: 9 "RES=0x3C " */
-		sb_add(m, "RES=0x%02x ", (u_int8_t)(ntohl(tcp_flag_word(th) & TCP_RESERVED_BITS) >> 22));
-		/* Max length: 32 "CWR ECE URG ACK PSH RST SYN FIN " */
-		if (th->cwr)
-			sb_add(m, "CWR ");
-		if (th->ece)
-			sb_add(m, "ECE ");
-		if (th->urg)
-			sb_add(m, "URG ");
-		if (th->ack)
-			sb_add(m, "ACK ");
-		if (th->psh)
-			sb_add(m, "PSH ");
-		if (th->rst)
-			sb_add(m, "RST ");
-		if (th->syn)
-			sb_add(m, "SYN ");
-		if (th->fin)
-			sb_add(m, "FIN ");
-		/* Max length: 11 "URGP=65535 " */
-		sb_add(m, "URGP=%u ", ntohs(th->urg_ptr));
-
-		if ((logflags & IP6T_LOG_TCPOPT) &&
-		    th->doff * 4 > sizeof(struct tcphdr)) {
-			u_int8_t _opt[60 - sizeof(struct tcphdr)];
-			const u_int8_t *op;
-			unsigned int i;
-			unsigned int optsize = th->doff * 4
-					       - sizeof(struct tcphdr);
-
-			op = skb_header_pointer(skb,
-						ptr + sizeof(struct tcphdr),
-						optsize, _opt);
-			if (op == NULL) {
-				sb_add(m, "OPT (TRUNCATED)");
-				return;
-			}
-
-			/* Max length: 127 "OPT (" 15*4*2chars ") " */
-			sb_add(m, "OPT (");
-			for (i =0; i < optsize; i++)
-				sb_add(m, "%02X", op[i]);
-			sb_add(m, ") ");
-		}
-		break;
-	}
-	case IPPROTO_UDP:
-	case IPPROTO_UDPLITE: {
-		struct udphdr _udph;
-		const struct udphdr *uh;
-
-		if (currenthdr == IPPROTO_UDP)
-			/* Max length: 10 "PROTO=UDP "     */
-			sb_add(m, "PROTO=UDP " );
-		else	/* Max length: 14 "PROTO=UDPLITE " */
-			sb_add(m, "PROTO=UDPLITE ");
-
-		if (fragment)
-			break;
-
-		/* Max length: 25 "INCOMPLETE [65535 bytes] " */
-		uh = skb_header_pointer(skb, ptr, sizeof(_udph), &_udph);
-		if (uh == NULL) {
-			sb_add(m, "INCOMPLETE [%u bytes] ", skb->len - ptr);
-			return;
-		}
-
-		/* Max length: 20 "SPT=65535 DPT=65535 " */
-		sb_add(m, "SPT=%u DPT=%u LEN=%u ",
-		       ntohs(uh->source), ntohs(uh->dest),
-		       ntohs(uh->len));
-		break;
-	}
-	case IPPROTO_ICMPV6: {
-		struct icmp6hdr _icmp6h;
-		const struct icmp6hdr *ic;
-
-		/* Max length: 13 "PROTO=ICMPv6 " */
-		sb_add(m, "PROTO=ICMPv6 ");
-
-		if (fragment)
-			break;
-
-		/* Max length: 25 "INCOMPLETE [65535 bytes] " */
-		ic = skb_header_pointer(skb, ptr, sizeof(_icmp6h), &_icmp6h);
-		if (ic == NULL) {
-			sb_add(m, "INCOMPLETE [%u bytes] ", skb->len - ptr);
-			return;
-		}
-
-		/* Max length: 18 "TYPE=255 CODE=255 " */
-		sb_add(m, "TYPE=%u CODE=%u ", ic->icmp6_type, ic->icmp6_code);
-
-		switch (ic->icmp6_type) {
-		case ICMPV6_ECHO_REQUEST:
-		case ICMPV6_ECHO_REPLY:
-			/* Max length: 19 "ID=65535 SEQ=65535 " */
-			sb_add(m, "ID=%u SEQ=%u ",
-				ntohs(ic->icmp6_identifier),
-				ntohs(ic->icmp6_sequence));
-			break;
-		case ICMPV6_MGM_QUERY:
-		case ICMPV6_MGM_REPORT:
-		case ICMPV6_MGM_REDUCTION:
-			break;
-
-		case ICMPV6_PARAMPROB:
-			/* Max length: 17 "POINTER=ffffffff " */
-			sb_add(m, "POINTER=%08x ", ntohl(ic->icmp6_pointer));
-			/* Fall through */
-		case ICMPV6_DEST_UNREACH:
-		case ICMPV6_PKT_TOOBIG:
-		case ICMPV6_TIME_EXCEED:
-			/* Max length: 3+maxlen */
-			if (recurse) {
-				sb_add(m, "[");
-				dump_packet(m, info, skb,
-					    ptr + sizeof(_icmp6h), 0);
-				sb_add(m, "] ");
-			}
-
-			/* Max length: 10 "MTU=65535 " */
-			if (ic->icmp6_type == ICMPV6_PKT_TOOBIG)
-				sb_add(m, "MTU=%u ", ntohl(ic->icmp6_mtu));
-		}
-		break;
-	}
-	/* Max length: 10 "PROTO=255 " */
-	default:
-		sb_add(m, "PROTO=%u ", currenthdr);
-	}
-
-	/* Max length: 15 "UID=4294967295 " */
-	if ((logflags & IP6T_LOG_UID) && recurse && skb->sk) {
-		read_lock_bh(&skb->sk->sk_callback_lock);
-		if (skb->sk->sk_socket && skb->sk->sk_socket->file)
-			sb_add(m, "UID=%u GID=%u ",
-				skb->sk->sk_socket->file->f_cred->fsuid,
-				skb->sk->sk_socket->file->f_cred->fsgid);
-		read_unlock_bh(&skb->sk->sk_callback_lock);
-	}
-
-	/* Max length: 16 "MARK=0xFFFFFFFF " */
-	if (!recurse && skb->mark)
-		sb_add(m, "MARK=0x%x ", skb->mark);
-}
-
-static void dump_mac_header(struct sbuff *m,
-			    const struct nf_loginfo *info,
-			    const struct sk_buff *skb)
-{
-	struct net_device *dev = skb->dev;
-	unsigned int logflags = 0;
-
-	if (info->type == NF_LOG_TYPE_LOG)
-		logflags = info->u.log.logflags;
-
-	if (!(logflags & IP6T_LOG_MACDECODE))
-		goto fallback;
-
-	switch (dev->type) {
-	case ARPHRD_ETHER:
-		sb_add(m, "MACSRC=%pM MACDST=%pM MACPROTO=%04x ",
-		       eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest,
-		       ntohs(eth_hdr(skb)->h_proto));
-		return;
-	default:
-		break;
-	}
-
-fallback:
-	sb_add(m, "MAC=");
-	if (dev->hard_header_len &&
-	    skb->mac_header != skb->network_header) {
-		const unsigned char *p = skb_mac_header(skb);
-		unsigned int len = dev->hard_header_len;
-		unsigned int i;
-
-		if (dev->type == ARPHRD_SIT &&
-		    (p -= ETH_HLEN) < skb->head)
-			p = NULL;
-
-		if (p != NULL) {
-			sb_add(m, "%02x", *p++);
-			for (i = 1; i < len; i++)
-				sb_add(m, ":%02x", *p++);
-		}
-		sb_add(m, " ");
-
-		if (dev->type == ARPHRD_SIT) {
-			const struct iphdr *iph =
-				(struct iphdr *)skb_mac_header(skb);
-			sb_add(m, "TUNNEL=%pI4->%pI4 ", &iph->saddr, &iph->daddr);
-		}
-	} else
-		sb_add(m, " ");
-}
-
-static struct nf_loginfo default_loginfo = {
-	.type	= NF_LOG_TYPE_LOG,
-	.u = {
-		.log = {
-			.level	  = 5,
-			.logflags = NF_LOG_MASK,
-		},
-	},
-};
-
-static void
-ip6t_log_packet(u_int8_t pf,
-		unsigned int hooknum,
-		const struct sk_buff *skb,
-		const struct net_device *in,
-		const struct net_device *out,
-		const struct nf_loginfo *loginfo,
-		const char *prefix)
-{
-	struct sbuff *m = sb_open();
-
-	if (!loginfo)
-		loginfo = &default_loginfo;
-
-	sb_add(m, "<%d>%sIN=%s OUT=%s ", loginfo->u.log.level,
-	       prefix,
-	       in ? in->name : "",
-	       out ? out->name : "");
-
-	if (in != NULL)
-		dump_mac_header(m, loginfo, skb);
-
-	dump_packet(m, loginfo, skb, skb_network_offset(skb), 1);
-
-	sb_close(m);
-}
-
-static unsigned int
-log_tg6(struct sk_buff *skb, const struct xt_action_param *par)
-{
-	const struct ip6t_log_info *loginfo = par->targinfo;
-	struct nf_loginfo li;
-
-	li.type = NF_LOG_TYPE_LOG;
-	li.u.log.level = loginfo->level;
-	li.u.log.logflags = loginfo->logflags;
-
-	ip6t_log_packet(NFPROTO_IPV6, par->hooknum, skb, par->in, par->out,
-			&li, loginfo->prefix);
-	return XT_CONTINUE;
-}
-
-
-static int log_tg6_check(const struct xt_tgchk_param *par)
-{
-	const struct ip6t_log_info *loginfo = par->targinfo;
-
-	if (loginfo->level >= 8) {
-		pr_debug("level %u >= 8\n", loginfo->level);
-		return -EINVAL;
-	}
-	if (loginfo->prefix[sizeof(loginfo->prefix)-1] != '\0') {
-		pr_debug("prefix not null-terminated\n");
-		return -EINVAL;
-	}
-	return 0;
-}
-
-static struct xt_target log_tg6_reg __read_mostly = {
-	.name 		= "LOG",
-	.family		= NFPROTO_IPV6,
-	.target 	= log_tg6,
-	.targetsize	= sizeof(struct ip6t_log_info),
-	.checkentry	= log_tg6_check,
-	.me 		= THIS_MODULE,
-};
-
-static struct nf_logger ip6t_logger __read_mostly = {
-	.name		= "ip6t_LOG",
-	.logfn		= &ip6t_log_packet,
-	.me		= THIS_MODULE,
-};
-
-static int __init log_tg6_init(void)
-{
-	int ret;
-
-	ret = xt_register_target(&log_tg6_reg);
-	if (ret < 0)
-		return ret;
-	nf_log_register(NFPROTO_IPV6, &ip6t_logger);
-	return 0;
-}
-
-static void __exit log_tg6_exit(void)
-{
-	nf_log_unregister(&ip6t_logger);
-	xt_unregister_target(&log_tg6_reg);
-}
-
-module_init(log_tg6_init);
-module_exit(log_tg6_exit);
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index f8ac4ef..b895d8b 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -524,6 +524,15 @@ config NETFILTER_XT_TARGET_LED
 	  For more information on the LEDs available on your system, see
 	  Documentation/leds/leds-class.txt
 
+config NETFILTER_XT_TARGET_LOG
+	tristate "LOG target support"
+	default m if NETFILTER_ADVANCED=n
+	help
+	  This option adds a `LOG' target, which allows you to create rules in
+	  any iptables table which records the packet header to the syslog.
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
 config NETFILTER_XT_TARGET_MARK
 	tristate '"MARK" target support'
 	depends on NETFILTER_ADVANCED
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 40f4c3d..a28c2a6 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -58,6 +58,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CT) += xt_CT.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_HL) += xt_HL.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o
+obj-$(CONFIG_NETFILTER_XT_TARGET_LOG) += xt_LOG.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG) += xt_NFLOG.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o
 obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o
diff --git a/net/netfilter/xt_LOG.c b/net/netfilter/xt_LOG.c
new file mode 100644
index 0000000..1595608
--- /dev/null
+++ b/net/netfilter/xt_LOG.c
@@ -0,0 +1,921 @@
+/*
+ * This is a module which is used for logging packets.
+ */
+
+/* (C) 1999-2001 Paul `Rusty' Russell
+ * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
+ *
+ * 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.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/ip.h>
+#include <net/ipv6.h>
+#include <net/icmp.h>
+#include <net/udp.h>
+#include <net/tcp.h>
+#include <net/route.h>
+
+#include <linux/netfilter.h>
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter/xt_LOG.h>
+#include <linux/netfilter_ipv6/ip6_tables.h>
+#include <net/netfilter/nf_log.h>
+#include <net/netfilter/xt_log.h>
+
+static struct nf_loginfo default_loginfo = {
+	.type	= NF_LOG_TYPE_LOG,
+	.u = {
+		.log = {
+			.level    = 5,
+			.logflags = NF_LOG_MASK,
+		},
+	},
+};
+
+static int dump_udp_header(struct sbuff *m, const struct sk_buff *skb,
+			   u8 proto, int fragment, unsigned int offset)
+{
+	struct udphdr _udph;
+	const struct udphdr *uh;
+
+	if (proto == IPPROTO_UDP)
+		/* Max length: 10 "PROTO=UDP "     */
+		sb_add(m, "PROTO=UDP ");
+	else	/* Max length: 14 "PROTO=UDPLITE " */
+		sb_add(m, "PROTO=UDPLITE ");
+
+	if (fragment)
+		goto out;
+
+	/* Max length: 25 "INCOMPLETE [65535 bytes] " */
+	uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph);
+	if (uh == NULL) {
+		sb_add(m, "INCOMPLETE [%u bytes] ", skb->len - offset);
+
+		return 1;
+	}
+
+	/* Max length: 20 "SPT=65535 DPT=65535 " */
+	sb_add(m, "SPT=%u DPT=%u LEN=%u ", ntohs(uh->source), ntohs(uh->dest),
+		ntohs(uh->len));
+
+out:
+	return 0;
+}
+
+static int dump_tcp_header(struct sbuff *m, const struct sk_buff *skb,
+			   u8 proto, int fragment, unsigned int offset,
+			   unsigned int logflags)
+{
+	struct tcphdr _tcph;
+	const struct tcphdr *th;
+
+	/* Max length: 10 "PROTO=TCP " */
+	sb_add(m, "PROTO=TCP ");
+
+	if (fragment)
+		return 0;
+
+	/* Max length: 25 "INCOMPLETE [65535 bytes] " */
+	th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph);
+	if (th == NULL) {
+		sb_add(m, "INCOMPLETE [%u bytes] ", skb->len - offset);
+		return 1;
+	}
+
+	/* Max length: 20 "SPT=65535 DPT=65535 " */
+	sb_add(m, "SPT=%u DPT=%u ", ntohs(th->source), ntohs(th->dest));
+	/* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */
+	if (logflags & XT_LOG_TCPSEQ)
+		sb_add(m, "SEQ=%u ACK=%u ", ntohl(th->seq), ntohl(th->ack_seq));
+
+	/* Max length: 13 "WINDOW=65535 " */
+	sb_add(m, "WINDOW=%u ", ntohs(th->window));
+	/* Max length: 9 "RES=0x3C " */
+	sb_add(m, "RES=0x%02x ", (u_int8_t)(ntohl(tcp_flag_word(th) &
+					    TCP_RESERVED_BITS) >> 22));
+	/* Max length: 32 "CWR ECE URG ACK PSH RST SYN FIN " */
+	if (th->cwr)
+		sb_add(m, "CWR ");
+	if (th->ece)
+		sb_add(m, "ECE ");
+	if (th->urg)
+		sb_add(m, "URG ");
+	if (th->ack)
+		sb_add(m, "ACK ");
+	if (th->psh)
+		sb_add(m, "PSH ");
+	if (th->rst)
+		sb_add(m, "RST ");
+	if (th->syn)
+		sb_add(m, "SYN ");
+	if (th->fin)
+		sb_add(m, "FIN ");
+	/* Max length: 11 "URGP=65535 " */
+	sb_add(m, "URGP=%u ", ntohs(th->urg_ptr));
+
+	if ((logflags & XT_LOG_TCPOPT) && th->doff*4 > sizeof(struct tcphdr)) {
+		u_int8_t _opt[60 - sizeof(struct tcphdr)];
+		const u_int8_t *op;
+		unsigned int i;
+		unsigned int optsize = th->doff*4 - sizeof(struct tcphdr);
+
+		op = skb_header_pointer(skb, offset + sizeof(struct tcphdr),
+					optsize, _opt);
+		if (op == NULL) {
+			sb_add(m, "OPT (TRUNCATED)");
+			return 1;
+		}
+
+		/* Max length: 127 "OPT (" 15*4*2chars ") " */
+		sb_add(m, "OPT (");
+		for (i = 0; i < optsize; i++)
+			sb_add(m, "%02X", op[i]);
+
+		sb_add(m, ") ");
+	}
+
+	return 0;
+}
+
+/* One level of recursion won't kill us */
+static void dump_ipv4_packet(struct sbuff *m,
+			const struct nf_loginfo *info,
+			const struct sk_buff *skb,
+			unsigned int iphoff)
+{
+	struct iphdr _iph;
+	const struct iphdr *ih;
+	unsigned int logflags;
+
+	if (info->type == NF_LOG_TYPE_LOG)
+		logflags = info->u.log.logflags;
+	else
+		logflags = NF_LOG_MASK;
+
+	ih = skb_header_pointer(skb, iphoff, sizeof(_iph), &_iph);
+	if (ih == NULL) {
+		sb_add(m, "TRUNCATED");
+		return;
+	}
+
+	/* Important fields:
+	 * TOS, len, DF/MF, fragment offset, TTL, src, dst, options. */
+	/* Max length: 40 "SRC=255.255.255.255 DST=255.255.255.255 " */
+	sb_add(m, "SRC=%pI4 DST=%pI4 ",
+	       &ih->saddr, &ih->daddr);
+
+	/* Max length: 46 "LEN=65535 TOS=0xFF PREC=0xFF TTL=255 ID=65535 " */
+	sb_add(m, "LEN=%u TOS=0x%02X PREC=0x%02X TTL=%u ID=%u ",
+	       ntohs(ih->tot_len), ih->tos & IPTOS_TOS_MASK,
+	       ih->tos & IPTOS_PREC_MASK, ih->ttl, ntohs(ih->id));
+
+	/* Max length: 6 "CE DF MF " */
+	if (ntohs(ih->frag_off) & IP_CE)
+		sb_add(m, "CE ");
+	if (ntohs(ih->frag_off) & IP_DF)
+		sb_add(m, "DF ");
+	if (ntohs(ih->frag_off) & IP_MF)
+		sb_add(m, "MF ");
+
+	/* Max length: 11 "FRAG:65535 " */
+	if (ntohs(ih->frag_off) & IP_OFFSET)
+		sb_add(m, "FRAG:%u ", ntohs(ih->frag_off) & IP_OFFSET);
+
+	if ((logflags & XT_LOG_IPOPT) &&
+	    ih->ihl * 4 > sizeof(struct iphdr)) {
+		const unsigned char *op;
+		unsigned char _opt[4 * 15 - sizeof(struct iphdr)];
+		unsigned int i, optsize;
+
+		optsize = ih->ihl * 4 - sizeof(struct iphdr);
+		op = skb_header_pointer(skb, iphoff+sizeof(_iph),
+					optsize, _opt);
+		if (op == NULL) {
+			sb_add(m, "TRUNCATED");
+			return;
+		}
+
+		/* Max length: 127 "OPT (" 15*4*2chars ") " */
+		sb_add(m, "OPT (");
+		for (i = 0; i < optsize; i++)
+			sb_add(m, "%02X", op[i]);
+		sb_add(m, ") ");
+	}
+
+	switch (ih->protocol) {
+	case IPPROTO_TCP:
+		if (dump_tcp_header(m, skb, ih->protocol,
+				    ntohs(ih->frag_off) & IP_OFFSET,
+				    iphoff+ih->ihl*4, logflags))
+			return;
+	case IPPROTO_UDP:
+	case IPPROTO_UDPLITE:
+		if (dump_udp_header(m, skb, ih->protocol,
+				    ntohs(ih->frag_off) & IP_OFFSET,
+				    iphoff+ih->ihl*4))
+			return;
+	case IPPROTO_ICMP: {
+		struct icmphdr _icmph;
+		const struct icmphdr *ich;
+		static const size_t required_len[NR_ICMP_TYPES+1]
+			= { [ICMP_ECHOREPLY] = 4,
+			    [ICMP_DEST_UNREACH]
+			    = 8 + sizeof(struct iphdr),
+			    [ICMP_SOURCE_QUENCH]
+			    = 8 + sizeof(struct iphdr),
+			    [ICMP_REDIRECT]
+			    = 8 + sizeof(struct iphdr),
+			    [ICMP_ECHO] = 4,
+			    [ICMP_TIME_EXCEEDED]
+			    = 8 + sizeof(struct iphdr),
+			    [ICMP_PARAMETERPROB]
+			    = 8 + sizeof(struct iphdr),
+			    [ICMP_TIMESTAMP] = 20,
+			    [ICMP_TIMESTAMPREPLY] = 20,
+			    [ICMP_ADDRESS] = 12,
+			    [ICMP_ADDRESSREPLY] = 12 };
+
+		/* Max length: 11 "PROTO=ICMP " */
+		sb_add(m, "PROTO=ICMP ");
+
+		if (ntohs(ih->frag_off) & IP_OFFSET)
+			break;
+
+		/* Max length: 25 "INCOMPLETE [65535 bytes] " */
+		ich = skb_header_pointer(skb, iphoff + ih->ihl * 4,
+					 sizeof(_icmph), &_icmph);
+		if (ich == NULL) {
+			sb_add(m, "INCOMPLETE [%u bytes] ",
+			       skb->len - iphoff - ih->ihl*4);
+			break;
+		}
+
+		/* Max length: 18 "TYPE=255 CODE=255 " */
+		sb_add(m, "TYPE=%u CODE=%u ", ich->type, ich->code);
+
+		/* Max length: 25 "INCOMPLETE [65535 bytes] " */
+		if (ich->type <= NR_ICMP_TYPES &&
+		    required_len[ich->type] &&
+		    skb->len-iphoff-ih->ihl*4 < required_len[ich->type]) {
+			sb_add(m, "INCOMPLETE [%u bytes] ",
+			       skb->len - iphoff - ih->ihl*4);
+			break;
+		}
+
+		switch (ich->type) {
+		case ICMP_ECHOREPLY:
+		case ICMP_ECHO:
+			/* Max length: 19 "ID=65535 SEQ=65535 " */
+			sb_add(m, "ID=%u SEQ=%u ",
+			       ntohs(ich->un.echo.id),
+			       ntohs(ich->un.echo.sequence));
+			break;
+
+		case ICMP_PARAMETERPROB:
+			/* Max length: 14 "PARAMETER=255 " */
+			sb_add(m, "PARAMETER=%u ",
+			       ntohl(ich->un.gateway) >> 24);
+			break;
+		case ICMP_REDIRECT:
+			/* Max length: 24 "GATEWAY=255.255.255.255 " */
+			sb_add(m, "GATEWAY=%pI4 ", &ich->un.gateway);
+			/* Fall through */
+		case ICMP_DEST_UNREACH:
+		case ICMP_SOURCE_QUENCH:
+		case ICMP_TIME_EXCEEDED:
+			/* Max length: 3+maxlen */
+			if (!iphoff) { /* Only recurse once. */
+				sb_add(m, "[");
+				dump_ipv4_packet(m, info, skb,
+					    iphoff + ih->ihl*4+sizeof(_icmph));
+				sb_add(m, "] ");
+			}
+
+			/* Max length: 10 "MTU=65535 " */
+			if (ich->type == ICMP_DEST_UNREACH &&
+			    ich->code == ICMP_FRAG_NEEDED)
+				sb_add(m, "MTU=%u ", ntohs(ich->un.frag.mtu));
+		}
+		break;
+	}
+	/* Max Length */
+	case IPPROTO_AH: {
+		struct ip_auth_hdr _ahdr;
+		const struct ip_auth_hdr *ah;
+
+		if (ntohs(ih->frag_off) & IP_OFFSET)
+			break;
+
+		/* Max length: 9 "PROTO=AH " */
+		sb_add(m, "PROTO=AH ");
+
+		/* Max length: 25 "INCOMPLETE [65535 bytes] " */
+		ah = skb_header_pointer(skb, iphoff+ih->ihl*4,
+					sizeof(_ahdr), &_ahdr);
+		if (ah == NULL) {
+			sb_add(m, "INCOMPLETE [%u bytes] ",
+			       skb->len - iphoff - ih->ihl*4);
+			break;
+		}
+
+		/* Length: 15 "SPI=0xF1234567 " */
+		sb_add(m, "SPI=0x%x ", ntohl(ah->spi));
+		break;
+	}
+	case IPPROTO_ESP: {
+		struct ip_esp_hdr _esph;
+		const struct ip_esp_hdr *eh;
+
+		/* Max length: 10 "PROTO=ESP " */
+		sb_add(m, "PROTO=ESP ");
+
+		if (ntohs(ih->frag_off) & IP_OFFSET)
+			break;
+
+		/* Max length: 25 "INCOMPLETE [65535 bytes] " */
+		eh = skb_header_pointer(skb, iphoff+ih->ihl*4,
+					sizeof(_esph), &_esph);
+		if (eh == NULL) {
+			sb_add(m, "INCOMPLETE [%u bytes] ",
+			       skb->len - iphoff - ih->ihl*4);
+			break;
+		}
+
+		/* Length: 15 "SPI=0xF1234567 " */
+		sb_add(m, "SPI=0x%x ", ntohl(eh->spi));
+		break;
+	}
+	/* Max length: 10 "PROTO 255 " */
+	default:
+		sb_add(m, "PROTO=%u ", ih->protocol);
+	}
+
+	/* Max length: 15 "UID=4294967295 " */
+	if ((logflags & XT_LOG_UID) && !iphoff && skb->sk) {
+		read_lock_bh(&skb->sk->sk_callback_lock);
+		if (skb->sk->sk_socket && skb->sk->sk_socket->file)
+			sb_add(m, "UID=%u GID=%u ",
+				skb->sk->sk_socket->file->f_cred->fsuid,
+				skb->sk->sk_socket->file->f_cred->fsgid);
+		read_unlock_bh(&skb->sk->sk_callback_lock);
+	}
+
+	/* Max length: 16 "MARK=0xFFFFFFFF " */
+	if (!iphoff && skb->mark)
+		sb_add(m, "MARK=0x%x ", skb->mark);
+
+	/* Proto    Max log string length */
+	/* IP:      40+46+6+11+127 = 230 */
+	/* TCP:     10+max(25,20+30+13+9+32+11+127) = 252 */
+	/* UDP:     10+max(25,20) = 35 */
+	/* UDPLITE: 14+max(25,20) = 39 */
+	/* ICMP:    11+max(25, 18+25+max(19,14,24+3+n+10,3+n+10)) = 91+n */
+	/* ESP:     10+max(25)+15 = 50 */
+	/* AH:      9+max(25)+15 = 49 */
+	/* unknown: 10 */
+
+	/* (ICMP allows recursion one level deep) */
+	/* maxlen =  IP + ICMP +  IP + max(TCP,UDP,ICMP,unknown) */
+	/* maxlen = 230+   91  + 230 + 252 = 803 */
+}
+
+static void dump_ipv4_mac_header(struct sbuff *m,
+			    const struct nf_loginfo *info,
+			    const struct sk_buff *skb)
+{
+	struct net_device *dev = skb->dev;
+	unsigned int logflags = 0;
+
+	if (info->type == NF_LOG_TYPE_LOG)
+		logflags = info->u.log.logflags;
+
+	if (!(logflags & XT_LOG_MACDECODE))
+		goto fallback;
+
+	switch (dev->type) {
+	case ARPHRD_ETHER:
+		sb_add(m, "MACSRC=%pM MACDST=%pM MACPROTO=%04x ",
+		       eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest,
+		       ntohs(eth_hdr(skb)->h_proto));
+		return;
+	default:
+		break;
+	}
+
+fallback:
+	sb_add(m, "MAC=");
+	if (dev->hard_header_len &&
+	    skb->mac_header != skb->network_header) {
+		const unsigned char *p = skb_mac_header(skb);
+		unsigned int i;
+
+		sb_add(m, "%02x", *p++);
+		for (i = 1; i < dev->hard_header_len; i++, p++)
+			sb_add(m, ":%02x", *p);
+	}
+	sb_add(m, " ");
+}
+
+static void
+log_packet_common(struct sbuff *m,
+		  u_int8_t pf,
+		  unsigned int hooknum,
+		  const struct sk_buff *skb,
+		  const struct net_device *in,
+		  const struct net_device *out,
+		  const struct nf_loginfo *loginfo,
+		  const char *prefix)
+{
+	sb_add(m, "<%d>%sIN=%s OUT=%s ", loginfo->u.log.level,
+	       prefix,
+	       in ? in->name : "",
+	       out ? out->name : "");
+#ifdef CONFIG_BRIDGE_NETFILTER
+	if (skb->nf_bridge) {
+		const struct net_device *physindev;
+		const struct net_device *physoutdev;
+
+		physindev = skb->nf_bridge->physindev;
+		if (physindev && in != physindev)
+			sb_add(m, "PHYSIN=%s ", physindev->name);
+		physoutdev = skb->nf_bridge->physoutdev;
+		if (physoutdev && out != physoutdev)
+			sb_add(m, "PHYSOUT=%s ", physoutdev->name);
+	}
+#endif
+}
+
+
+static void
+ipt_log_packet(u_int8_t pf,
+	       unsigned int hooknum,
+	       const struct sk_buff *skb,
+	       const struct net_device *in,
+	       const struct net_device *out,
+	       const struct nf_loginfo *loginfo,
+	       const char *prefix)
+{
+	struct sbuff *m = sb_open();
+
+	if (!loginfo)
+		loginfo = &default_loginfo;
+
+	log_packet_common(m, pf, hooknum, skb, in, out, loginfo, prefix);
+
+	if (in != NULL)
+		dump_ipv4_mac_header(m, loginfo, skb);
+
+	dump_ipv4_packet(m, loginfo, skb, 0);
+
+	sb_close(m);
+}
+
+#if IS_ENABLED(CONFIG_IPV6)
+/* One level of recursion won't kill us */
+static void dump_ipv6_packet(struct sbuff *m,
+			const struct nf_loginfo *info,
+			const struct sk_buff *skb, unsigned int ip6hoff,
+			int recurse)
+{
+	u_int8_t currenthdr;
+	int fragment;
+	struct ipv6hdr _ip6h;
+	const struct ipv6hdr *ih;
+	unsigned int ptr;
+	unsigned int hdrlen = 0;
+	unsigned int logflags;
+
+	if (info->type == NF_LOG_TYPE_LOG)
+		logflags = info->u.log.logflags;
+	else
+		logflags = NF_LOG_MASK;
+
+	ih = skb_header_pointer(skb, ip6hoff, sizeof(_ip6h), &_ip6h);
+	if (ih == NULL) {
+		sb_add(m, "TRUNCATED");
+		return;
+	}
+
+	/* Max length: 88 "SRC=0000.0000.0000.0000.0000.0000.0000.0000 DST=0000.0000.0000.0000.0000.0000.0000.0000 " */
+	sb_add(m, "SRC=%pI6 DST=%pI6 ", &ih->saddr, &ih->daddr);
+
+	/* Max length: 44 "LEN=65535 TC=255 HOPLIMIT=255 FLOWLBL=FFFFF " */
+	sb_add(m, "LEN=%Zu TC=%u HOPLIMIT=%u FLOWLBL=%u ",
+	       ntohs(ih->payload_len) + sizeof(struct ipv6hdr),
+	       (ntohl(*(__be32 *)ih) & 0x0ff00000) >> 20,
+	       ih->hop_limit,
+	       (ntohl(*(__be32 *)ih) & 0x000fffff));
+
+	fragment = 0;
+	ptr = ip6hoff + sizeof(struct ipv6hdr);
+	currenthdr = ih->nexthdr;
+	while (currenthdr != NEXTHDR_NONE && ip6t_ext_hdr(currenthdr)) {
+		struct ipv6_opt_hdr _hdr;
+		const struct ipv6_opt_hdr *hp;
+
+		hp = skb_header_pointer(skb, ptr, sizeof(_hdr), &_hdr);
+		if (hp == NULL) {
+			sb_add(m, "TRUNCATED");
+			return;
+		}
+
+		/* Max length: 48 "OPT (...) " */
+		if (logflags & XT_LOG_IPOPT)
+			sb_add(m, "OPT ( ");
+
+		switch (currenthdr) {
+		case IPPROTO_FRAGMENT: {
+			struct frag_hdr _fhdr;
+			const struct frag_hdr *fh;
+
+			sb_add(m, "FRAG:");
+			fh = skb_header_pointer(skb, ptr, sizeof(_fhdr),
+						&_fhdr);
+			if (fh == NULL) {
+				sb_add(m, "TRUNCATED ");
+				return;
+			}
+
+			/* Max length: 6 "65535 " */
+			sb_add(m, "%u ", ntohs(fh->frag_off) & 0xFFF8);
+
+			/* Max length: 11 "INCOMPLETE " */
+			if (fh->frag_off & htons(0x0001))
+				sb_add(m, "INCOMPLETE ");
+
+			sb_add(m, "ID:%08x ", ntohl(fh->identification));
+
+			if (ntohs(fh->frag_off) & 0xFFF8)
+				fragment = 1;
+
+			hdrlen = 8;
+
+			break;
+		}
+		case IPPROTO_DSTOPTS:
+		case IPPROTO_ROUTING:
+		case IPPROTO_HOPOPTS:
+			if (fragment) {
+				if (logflags & XT_LOG_IPOPT)
+					sb_add(m, ")");
+				return;
+			}
+			hdrlen = ipv6_optlen(hp);
+			break;
+		/* Max Length */
+		case IPPROTO_AH:
+			if (logflags & XT_LOG_IPOPT) {
+				struct ip_auth_hdr _ahdr;
+				const struct ip_auth_hdr *ah;
+
+				/* Max length: 3 "AH " */
+				sb_add(m, "AH ");
+
+				if (fragment) {
+					sb_add(m, ")");
+					return;
+				}
+
+				ah = skb_header_pointer(skb, ptr, sizeof(_ahdr),
+							&_ahdr);
+				if (ah == NULL) {
+					/*
+					 * Max length: 26 "INCOMPLETE [65535
+					 *  bytes] )"
+					 */
+					sb_add(m, "INCOMPLETE [%u bytes] )",
+					       skb->len - ptr);
+					return;
+				}
+
+				/* Length: 15 "SPI=0xF1234567 */
+				sb_add(m, "SPI=0x%x ", ntohl(ah->spi));
+
+			}
+
+			hdrlen = (hp->hdrlen+2)<<2;
+			break;
+		case IPPROTO_ESP:
+			if (logflags & XT_LOG_IPOPT) {
+				struct ip_esp_hdr _esph;
+				const struct ip_esp_hdr *eh;
+
+				/* Max length: 4 "ESP " */
+				sb_add(m, "ESP ");
+
+				if (fragment) {
+					sb_add(m, ")");
+					return;
+				}
+
+				/*
+				 * Max length: 26 "INCOMPLETE [65535 bytes] )"
+				 */
+				eh = skb_header_pointer(skb, ptr, sizeof(_esph),
+							&_esph);
+				if (eh == NULL) {
+					sb_add(m, "INCOMPLETE [%u bytes] )",
+					       skb->len - ptr);
+					return;
+				}
+
+				/* Length: 16 "SPI=0xF1234567 )" */
+				sb_add(m, "SPI=0x%x )", ntohl(eh->spi));
+
+			}
+			return;
+		default:
+			/* Max length: 20 "Unknown Ext Hdr 255" */
+			sb_add(m, "Unknown Ext Hdr %u", currenthdr);
+			return;
+		}
+		if (logflags & XT_LOG_IPOPT)
+			sb_add(m, ") ");
+
+		currenthdr = hp->nexthdr;
+		ptr += hdrlen;
+	}
+
+	switch (currenthdr) {
+	case IPPROTO_TCP:
+		if (dump_tcp_header(m, skb, currenthdr, fragment, ptr,
+		    logflags))
+			return;
+	case IPPROTO_UDP:
+	case IPPROTO_UDPLITE:
+		if (dump_udp_header(m, skb, currenthdr, fragment, ptr))
+			return;
+	case IPPROTO_ICMPV6: {
+		struct icmp6hdr _icmp6h;
+		const struct icmp6hdr *ic;
+
+		/* Max length: 13 "PROTO=ICMPv6 " */
+		sb_add(m, "PROTO=ICMPv6 ");
+
+		if (fragment)
+			break;
+
+		/* Max length: 25 "INCOMPLETE [65535 bytes] " */
+		ic = skb_header_pointer(skb, ptr, sizeof(_icmp6h), &_icmp6h);
+		if (ic == NULL) {
+			sb_add(m, "INCOMPLETE [%u bytes] ", skb->len - ptr);
+			return;
+		}
+
+		/* Max length: 18 "TYPE=255 CODE=255 " */
+		sb_add(m, "TYPE=%u CODE=%u ", ic->icmp6_type, ic->icmp6_code);
+
+		switch (ic->icmp6_type) {
+		case ICMPV6_ECHO_REQUEST:
+		case ICMPV6_ECHO_REPLY:
+			/* Max length: 19 "ID=65535 SEQ=65535 " */
+			sb_add(m, "ID=%u SEQ=%u ",
+				ntohs(ic->icmp6_identifier),
+				ntohs(ic->icmp6_sequence));
+			break;
+		case ICMPV6_MGM_QUERY:
+		case ICMPV6_MGM_REPORT:
+		case ICMPV6_MGM_REDUCTION:
+			break;
+
+		case ICMPV6_PARAMPROB:
+			/* Max length: 17 "POINTER=ffffffff " */
+			sb_add(m, "POINTER=%08x ", ntohl(ic->icmp6_pointer));
+			/* Fall through */
+		case ICMPV6_DEST_UNREACH:
+		case ICMPV6_PKT_TOOBIG:
+		case ICMPV6_TIME_EXCEED:
+			/* Max length: 3+maxlen */
+			if (recurse) {
+				sb_add(m, "[");
+				dump_ipv6_packet(m, info, skb,
+					    ptr + sizeof(_icmp6h), 0);
+				sb_add(m, "] ");
+			}
+
+			/* Max length: 10 "MTU=65535 " */
+			if (ic->icmp6_type == ICMPV6_PKT_TOOBIG)
+				sb_add(m, "MTU=%u ", ntohl(ic->icmp6_mtu));
+		}
+		break;
+	}
+	/* Max length: 10 "PROTO=255 " */
+	default:
+		sb_add(m, "PROTO=%u ", currenthdr);
+	}
+
+	/* Max length: 15 "UID=4294967295 " */
+	if ((logflags & XT_LOG_UID) && recurse && skb->sk) {
+		read_lock_bh(&skb->sk->sk_callback_lock);
+		if (skb->sk->sk_socket && skb->sk->sk_socket->file)
+			sb_add(m, "UID=%u GID=%u ",
+				skb->sk->sk_socket->file->f_cred->fsuid,
+				skb->sk->sk_socket->file->f_cred->fsgid);
+		read_unlock_bh(&skb->sk->sk_callback_lock);
+	}
+
+	/* Max length: 16 "MARK=0xFFFFFFFF " */
+	if (!recurse && skb->mark)
+		sb_add(m, "MARK=0x%x ", skb->mark);
+}
+
+static void dump_ipv6_mac_header(struct sbuff *m,
+			    const struct nf_loginfo *info,
+			    const struct sk_buff *skb)
+{
+	struct net_device *dev = skb->dev;
+	unsigned int logflags = 0;
+
+	if (info->type == NF_LOG_TYPE_LOG)
+		logflags = info->u.log.logflags;
+
+	if (!(logflags & XT_LOG_MACDECODE))
+		goto fallback;
+
+	switch (dev->type) {
+	case ARPHRD_ETHER:
+		sb_add(m, "MACSRC=%pM MACDST=%pM MACPROTO=%04x ",
+		       eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest,
+		       ntohs(eth_hdr(skb)->h_proto));
+		return;
+	default:
+		break;
+	}
+
+fallback:
+	sb_add(m, "MAC=");
+	if (dev->hard_header_len &&
+	    skb->mac_header != skb->network_header) {
+		const unsigned char *p = skb_mac_header(skb);
+		unsigned int len = dev->hard_header_len;
+		unsigned int i;
+
+		if (dev->type == ARPHRD_SIT) {
+			p -= ETH_HLEN;
+
+			if (p < skb->head)
+				p = NULL;
+		}
+
+		if (p != NULL) {
+			sb_add(m, "%02x", *p++);
+			for (i = 1; i < len; i++)
+				sb_add(m, ":%02x", *p++);
+		}
+		sb_add(m, " ");
+
+		if (dev->type == ARPHRD_SIT) {
+			const struct iphdr *iph =
+				(struct iphdr *)skb_mac_header(skb);
+			sb_add(m, "TUNNEL=%pI4->%pI4 ", &iph->saddr,
+			       &iph->daddr);
+		}
+	} else
+		sb_add(m, " ");
+}
+
+static void
+ip6t_log_packet(u_int8_t pf,
+		unsigned int hooknum,
+		const struct sk_buff *skb,
+		const struct net_device *in,
+		const struct net_device *out,
+		const struct nf_loginfo *loginfo,
+		const char *prefix)
+{
+	struct sbuff *m = sb_open();
+
+	if (!loginfo)
+		loginfo = &default_loginfo;
+
+	log_packet_common(m, pf, hooknum, skb, in, out, loginfo, prefix);
+
+	if (in != NULL)
+		dump_ipv6_mac_header(m, loginfo, skb);
+
+	dump_ipv6_packet(m, loginfo, skb, skb_network_offset(skb), 1);
+
+	sb_close(m);
+}
+#endif
+
+static unsigned int
+log_tg(struct sk_buff *skb, const struct xt_action_param *par)
+{
+	const struct xt_log_info *loginfo = par->targinfo;
+	struct nf_loginfo li;
+
+	li.type = NF_LOG_TYPE_LOG;
+	li.u.log.level = loginfo->level;
+	li.u.log.logflags = loginfo->logflags;
+
+	if (par->family == NFPROTO_IPV4)
+		ipt_log_packet(NFPROTO_IPV4, par->hooknum, skb, par->in,
+			       par->out, &li, loginfo->prefix);
+#if IS_ENABLED(CONFIG_IPV6)
+	else if (par->family == NFPROTO_IPV6)
+		ip6t_log_packet(NFPROTO_IPV6, par->hooknum, skb, par->in,
+				par->out, &li, loginfo->prefix);
+#endif
+	else
+		WARN_ON_ONCE(1);
+
+	return XT_CONTINUE;
+}
+
+static int log_tg_check(const struct xt_tgchk_param *par)
+{
+	const struct xt_log_info *loginfo = par->targinfo;
+
+	if (par->family != NFPROTO_IPV4 && par->family != NFPROTO_IPV6)
+		return -EINVAL;
+
+	if (loginfo->level >= 8) {
+		pr_debug("level %u >= 8\n", loginfo->level);
+		return -EINVAL;
+	}
+
+	if (loginfo->prefix[sizeof(loginfo->prefix)-1] != '\0') {
+		pr_debug("prefix is not null-terminated\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static struct xt_target log_tg_regs[] __read_mostly = {
+	{
+		.name		= "LOG",
+		.family		= NFPROTO_IPV4,
+		.target		= log_tg,
+		.targetsize	= sizeof(struct xt_log_info),
+		.checkentry	= log_tg_check,
+		.me		= THIS_MODULE,
+	},
+#if IS_ENABLED(CONFIG_IPV6)
+	{
+		.name		= "LOG",
+		.family		= NFPROTO_IPV6,
+		.target		= log_tg,
+		.targetsize	= sizeof(struct xt_log_info),
+		.checkentry	= log_tg_check,
+		.me		= THIS_MODULE,
+	},
+#endif
+};
+
+static struct nf_logger ipt_log_logger __read_mostly = {
+	.name		= "ipt_LOG",
+	.logfn		= &ipt_log_packet,
+	.me		= THIS_MODULE,
+};
+
+#if IS_ENABLED(CONFIG_IPV6)
+static struct nf_logger ip6t_log_logger __read_mostly = {
+	.name		= "ip6t_LOG",
+	.logfn		= &ip6t_log_packet,
+	.me		= THIS_MODULE,
+};
+#endif
+
+static int __init log_tg_init(void)
+{
+	int ret;
+
+	ret = xt_register_targets(log_tg_regs, ARRAY_SIZE(log_tg_regs));
+	if (ret < 0)
+		return ret;
+
+	nf_log_register(NFPROTO_IPV4, &ipt_log_logger);
+#if IS_ENABLED(CONFIG_IPV6)
+	nf_log_register(NFPROTO_IPV6, &ip6t_log_logger);
+#endif
+	return 0;
+}
+
+static void __exit log_tg_exit(void)
+{
+	nf_log_unregister(&ipt_log_logger);
+#if IS_ENABLED(CONFIG_IPV6)
+	nf_log_unregister(&ip6t_log_logger);
+#endif
+	xt_unregister_targets(log_tg_regs, ARRAY_SIZE(log_tg_regs));
+}
+
+module_init(log_tg_init);
+module_exit(log_tg_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
+MODULE_AUTHOR("Jan Rekorajski <baggins@pld.org.pl>");
+MODULE_DESCRIPTION("Xtables: IPv4/IPv6 packet logging");
+MODULE_ALIAS("ipt_LOG");
+MODULE_ALIAS("ip6t_LOG");
-- 
1.7.7.3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 2/2] iptables: xt_LOG: Add ring buffer support
  2012-02-10 22:10 [PATCH v5] Merge ipt_LOG and ip6t_LOG, add ring bufffer support Richard Weinberger
  2012-02-10 22:10 ` [PATCH 1/2] iptables: Merge libip6t_LOG and libipt_LOG into libxt_LOG Richard Weinberger
  2012-02-10 22:10 ` [PATCH 1/4] Netfilter: Merge ipt_LOG and ip6_LOG into xt_LOG Richard Weinberger
@ 2012-02-10 22:10 ` Richard Weinberger
  2012-02-10 22:10 ` [PATCH 2/4] ring_buffer: Export for_each_buffer_cpu() Richard Weinberger
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 16+ messages in thread
From: Richard Weinberger @ 2012-02-10 22:10 UTC (permalink / raw)
  To: netfilter-devel
  Cc: netdev, linux-kernel, eric.dumazet, jengelh, rostedt, pablo,
	basti, Richard Weinberger

This patch adds "--ring" and "--ring-size" to xt_LOG.

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 extensions/libxt_LOG.c           |  129 ++++++++++++++++++++++++++++++++++++++
 extensions/libxt_LOG.man         |    9 +++
 include/linux/netfilter/xt_LOG.h |   13 ++++-
 3 files changed, 150 insertions(+), 1 deletions(-)

diff --git a/extensions/libxt_LOG.c b/extensions/libxt_LOG.c
index a4c11b6..a9afbb5 100644
--- a/extensions/libxt_LOG.c
+++ b/extensions/libxt_LOG.c
@@ -1,10 +1,12 @@
 #include <stdio.h>
 #include <string.h>
+#include <ctype.h>
 #include <syslog.h>
 #include <xtables.h>
 #include <linux/netfilter/xt_LOG.h>
 
 #define LOG_DEFAULT_LEVEL LOG_WARNING
+#define DEFAULT_RING_SIZE 1024
 
 #ifndef XT_LOG_UID /* Old kernel */
 #define XT_LOG_UID	0x08	/* Log UID owning local socket */
@@ -20,6 +22,9 @@ enum {
 	O_LOG_IPOPTS,
 	O_LOG_UID,
 	O_LOG_MAC,
+	O_LOG_TIMESTAMP,
+	O_LOG_RING_NAME,
+	O_LOG_RING_SIZE,
 };
 
 static void LOG_help(void)
@@ -35,6 +40,17 @@ static void LOG_help(void)
 " --log-macdecode		Decode MAC addresses and protocol.\n\n");
 }
 
+static void LOG_help_v1(void)
+{
+	LOG_help();
+
+	printf(
+" --log-timestamp		Add the current time to the log message.\n\n"
+" --ring NAME			Log messages into a ring buffer NAME instead of kernel syslog.\n\n"
+" --ring-size SIZE		Size of the ring buffer in KiB.\n\n"
+);
+}
+
 #define s struct xt_log_info
 static const struct xt_option_entry LOG_opts[] = {
 	{.name = "log-level", .id = O_LOG_LEVEL, .type = XTTYPE_SYSLOGLEVEL,
@@ -50,6 +66,26 @@ static const struct xt_option_entry LOG_opts[] = {
 };
 #undef s
 
+#define s struct xt_log_info_v1
+static const struct xt_option_entry LOG_opts_v1[] = {
+	{.name = "log-level", .id = O_LOG_LEVEL, .type = XTTYPE_SYSLOGLEVEL,
+	 .flags = XTOPT_PUT, XTOPT_POINTER(s, level)},
+	{.name = "log-prefix", .id = O_LOG_PREFIX, .type = XTTYPE_STRING,
+	 .flags = XTOPT_PUT, XTOPT_POINTER(s, prefix), .min = 1},
+	{.name = "log-tcp-sequence", .id = O_LOG_TCPSEQ, .type = XTTYPE_NONE},
+	{.name = "log-tcp-options", .id = O_LOG_TCPOPTS, .type = XTTYPE_NONE},
+	{.name = "log-ip-options", .id = O_LOG_IPOPTS, .type = XTTYPE_NONE},
+	{.name = "log-uid", .id = O_LOG_UID, .type = XTTYPE_NONE},
+	{.name = "log-macdecode", .id = O_LOG_MAC, .type = XTTYPE_NONE},
+	{.name = "log-timestamp", .id = O_LOG_TIMESTAMP, .type = XTTYPE_NONE},
+	{.name = "ring", .id = O_LOG_RING_NAME, .type = XTTYPE_STRING,
+	 .flags = XTOPT_PUT, XTOPT_POINTER(s, ring_name), .min = 1},
+	{.name = "ring-size", .id = O_LOG_RING_SIZE, .type = XTTYPE_UINT64,
+	 .flags = XTOPT_PUT, XTOPT_POINTER(s, ring_size)},
+	XTOPT_TABLEEND,
+};
+#undef s
+
 static void LOG_init(struct xt_entry_target *t)
 {
 	struct xt_log_info *loginfo = (struct xt_log_info *)t->data;
@@ -104,6 +140,29 @@ static void LOG_parse(struct xt_option_call *cb)
 	}
 }
 
+static void LOG_parse_v1(struct xt_option_call *cb)
+{
+	struct xt_log_info_v1 *info = cb->data;
+	int i;
+
+	LOG_parse(cb);
+
+	switch (cb->entry->id) {
+	case O_LOG_TIMESTAMP:
+		info->logflags |= XT_LOG_ADD_TIMESTAMP;
+		break;	
+	case O_LOG_RING_NAME:
+		if (!info->ring_size)
+			info->ring_size = DEFAULT_RING_SIZE;
+
+		for (i = 0; i < strlen(info->ring_name); i++)
+			if (!isalnum(cb->arg[i]))
+				xtables_error(PARAMETER_PROBLEM,
+				"Ring name is not alphanumeric");
+		break;
+	}
+}
+
 static void LOG_print(const void *ip, const struct xt_entry_target *target,
                       int numeric)
 {
@@ -141,6 +200,27 @@ static void LOG_print(const void *ip, const struct xt_entry_target *target,
 		printf(" prefix \"%s\"", loginfo->prefix);
 }
 
+static void LOG_print_v1(const void *ip, const struct xt_entry_target *target,
+		         int numeric)
+{
+	const struct xt_log_info_v1 *loginfo
+		= (const struct xt_log_info_v1 *)target->data;
+
+	LOG_print(ip, target, numeric);
+
+	if (!numeric) {
+		if (loginfo->logflags & XT_LOG_ADD_TIMESTAMP)
+			printf(" log-timestamp");	
+	}
+
+	if (loginfo->ring_name[0]) {
+		printf(" ring \"%s\"", loginfo->ring_name);
+
+		if (loginfo->ring_size != DEFAULT_RING_SIZE)
+			printf(" ring-size %lu", (unsigned long)loginfo->ring_size);
+	}
+}
+
 static void LOG_save(const void *ip, const struct xt_entry_target *target)
 {
 	const struct xt_log_info *loginfo
@@ -166,6 +246,25 @@ static void LOG_save(const void *ip, const struct xt_entry_target *target)
 		printf(" --log-macdecode");
 }
 
+static void LOG_save_v1(const void *ip, const struct xt_entry_target *target)
+{
+	const struct xt_log_info_v1 *loginfo
+		= (const struct xt_log_info_v1 *)target->data;
+
+	LOG_save(ip, target);
+
+	if (loginfo->logflags & XT_LOG_ADD_TIMESTAMP)
+		printf(" --log-timestamp");
+
+	if (loginfo->ring_name[0]) {
+		printf(" --ring");
+		xtables_save_string(loginfo->ring_name);
+
+		if (loginfo->ring_size != DEFAULT_RING_SIZE)
+			printf(" --ring-size %lu", (unsigned long)loginfo->ring_size);
+	}
+}
+
 static struct xtables_target log_tg_regs[] = {
 	{
 		.name          = "LOG",
@@ -176,6 +275,7 @@ static struct xtables_target log_tg_regs[] = {
 		.help          = LOG_help,
 		.init          = LOG_init,
 		.print         = LOG_print,
+		.revision      = 0,
 		.save          = LOG_save,
 		.x6_parse      = LOG_parse,
 		.x6_options    = LOG_opts,
@@ -189,10 +289,39 @@ static struct xtables_target log_tg_regs[] = {
 		.help          = LOG_help,
 		.init          = LOG_init,
 		.print         = LOG_print,
+		.revision      = 0,
 		.save          = LOG_save,
 		.x6_parse      = LOG_parse,
 		.x6_options    = LOG_opts,
 	},
+	{
+		.name          = "LOG",
+		.version       = XTABLES_VERSION,
+		.family        = NFPROTO_IPV4,
+		.size          = XT_ALIGN(sizeof(struct xt_log_info_v1)),
+		.userspacesize = offsetof(struct xt_log_info_v1, rctx),
+		.help          = LOG_help_v1,
+		.init          = LOG_init,
+		.print         = LOG_print_v1,
+		.revision      = 1,
+		.save          = LOG_save_v1,
+		.x6_parse      = LOG_parse_v1,
+		.x6_options    = LOG_opts_v1,
+	},
+	{
+		.name          = "LOG",
+		.version       = XTABLES_VERSION,
+		.family        = NFPROTO_IPV6,
+		.size          = XT_ALIGN(sizeof(struct xt_log_info_v1)),
+		.userspacesize = offsetof(struct xt_log_info_v1, rctx),
+		.help          = LOG_help_v1,
+		.init          = LOG_init,
+		.print         = LOG_print_v1,
+		.revision      = 1,
+		.save          = LOG_save_v1,
+		.x6_parse      = LOG_parse_v1,
+		.x6_options    = LOG_opts_v1,
+	},
 };
 
 void _init(void)
diff --git a/extensions/libxt_LOG.man b/extensions/libxt_LOG.man
index 47c35e0..2f0b2ff 100644
--- a/extensions/libxt_LOG.man
+++ b/extensions/libxt_LOG.man
@@ -29,3 +29,12 @@ Log options from the IP packet header.
 .TP
 \fB\-\-log\-uid\fP
 Log the userid of the process which generated the packet.
+\fB\-\-log\-timestamp\fP
+Add a timestamp to each log message.
+\fB\-\-ring\fP \fIname\fP
+Log all messages into a ring buffer identified by \fIname\fP.
+Each ring buffer is represented as file in 
+/proc/net/netfilter/xt_LOG_ring/.
+\fB\-\-ring\-size\fP \fIsize\fP
+Set the ring buffer size in KiB.
+Default is 1024 KiB.
diff --git a/include/linux/netfilter/xt_LOG.h b/include/linux/netfilter/xt_LOG.h
index cac0790..d84710c 100644
--- a/include/linux/netfilter/xt_LOG.h
+++ b/include/linux/netfilter/xt_LOG.h
@@ -8,7 +8,8 @@
 #define XT_LOG_UID		0x08	/* Log UID owning local socket */
 #define XT_LOG_NFLOG		0x10	/* Unsupported, don't reuse */
 #define XT_LOG_MACDECODE	0x20	/* Decode MAC header */
-#define XT_LOG_MASK		0x2f
+#define XT_LOG_ADD_TIMESTAMP	0x40	/* Add a timestamp */
+#define XT_LOG_MASK		0x6f
 
 struct xt_log_info {
 	unsigned char level;
@@ -16,4 +17,14 @@ struct xt_log_info {
 	char prefix[30];
 };
 
+struct xt_log_info_v1 {
+	unsigned char level;
+	unsigned char logflags;
+	char prefix[30];
+
+	char ring_name[30];
+	__aligned_u64 ring_size;
+	struct xt_LOG_ring_ctx *rctx __attribute__((aligned(8)));
+};
+
 #endif /* _XT_LOG_H */
-- 
1.7.7.3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 2/4] ring_buffer: Export for_each_buffer_cpu()
  2012-02-10 22:10 [PATCH v5] Merge ipt_LOG and ip6t_LOG, add ring bufffer support Richard Weinberger
                   ` (2 preceding siblings ...)
  2012-02-10 22:10 ` [PATCH 2/2] iptables: xt_LOG: Add ring buffer support Richard Weinberger
@ 2012-02-10 22:10 ` Richard Weinberger
  2012-02-14  0:05   ` Pablo Neira Ayuso
  2012-02-10 22:10 ` [PATCH 3/4] xt_log: Make printk() in sb_close() optional Richard Weinberger
  2012-02-10 22:10 ` [PATCH 4/4] Netfilter: xt_LOG: Implement ring buffer support Richard Weinberger
  5 siblings, 1 reply; 16+ messages in thread
From: Richard Weinberger @ 2012-02-10 22:10 UTC (permalink / raw)
  To: netfilter-devel
  Cc: netdev, linux-kernel, eric.dumazet, jengelh, rostedt, pablo,
	basti, Richard Weinberger

In order to make ring_buffer usable to other modules
for_each_buffer_cpu() needs to be exported.

Signed-off-by: Richard Weinberger <richard@nod.at>
Acked-by: Steven Rostedt <rostedt@goodmis.org>
---
 include/linux/ring_buffer.h |    5 +++++
 kernel/trace/ring_buffer.c  |    7 +++++++
 2 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h
index 67be037..5c1c29f 100644
--- a/include/linux/ring_buffer.h
+++ b/include/linux/ring_buffer.h
@@ -185,4 +185,9 @@ enum ring_buffer_flags {
 	RB_FL_OVERWRITE		= 1 << 0,
 };
 
+cpumask_var_t *ring_buffer_mask(struct ring_buffer *buffer);
+
+#define for_each_buffer_cpu(buffer, cpu) \
+	for_each_cpu(cpu, *(ring_buffer_mask(buffer)))
+
 #endif /* _LINUX_RING_BUFFER_H */
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index f5b7b5c..a4117c5 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -348,6 +348,7 @@ void *ring_buffer_event_data(struct ring_buffer_event *event)
 }
 EXPORT_SYMBOL_GPL(ring_buffer_event_data);
 
+#undef for_each_buffer_cpu
 #define for_each_buffer_cpu(buffer, cpu)		\
 	for_each_cpu(cpu, buffer->cpumask)
 
@@ -4139,3 +4140,9 @@ static int rb_cpu_notify(struct notifier_block *self,
 	return NOTIFY_OK;
 }
 #endif
+
+cpumask_var_t *ring_buffer_mask(struct ring_buffer *buffer)
+{
+	return &buffer->cpumask;
+}
+EXPORT_SYMBOL_GPL(ring_buffer_mask);
-- 
1.7.7.3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 3/4] xt_log: Make printk() in sb_close() optional
  2012-02-10 22:10 [PATCH v5] Merge ipt_LOG and ip6t_LOG, add ring bufffer support Richard Weinberger
                   ` (3 preceding siblings ...)
  2012-02-10 22:10 ` [PATCH 2/4] ring_buffer: Export for_each_buffer_cpu() Richard Weinberger
@ 2012-02-10 22:10 ` Richard Weinberger
  2012-02-14  0:12   ` Pablo Neira Ayuso
  2012-02-10 22:10 ` [PATCH 4/4] Netfilter: xt_LOG: Implement ring buffer support Richard Weinberger
  5 siblings, 1 reply; 16+ messages in thread
From: Richard Weinberger @ 2012-02-10 22:10 UTC (permalink / raw)
  To: netfilter-devel
  Cc: netdev, linux-kernel, eric.dumazet, jengelh, rostedt, pablo,
	basti, Richard Weinberger

Make printk() in sb_close() optional such that other modules
can build a log string without printing it using printk().

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 include/net/netfilter/xt_log.h |    9 ++++++---
 1 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/include/net/netfilter/xt_log.h b/include/net/netfilter/xt_log.h
index 0dfb34a..767e08d 100644
--- a/include/net/netfilter/xt_log.h
+++ b/include/net/netfilter/xt_log.h
@@ -39,10 +39,12 @@ static struct sbuff *sb_open(void)
 	return m;
 }
 
-static void sb_close(struct sbuff *m)
+static void __sb_close(struct sbuff *m, int print)
 {
-	m->buf[m->count] = 0;
-	printk("%s\n", m->buf);
+	if (print) {
+		m->buf[m->count] = 0;
+		printk("%s\n", m->buf);
+	}
 
 	if (likely(m != &emergency))
 		kfree(m);
@@ -52,3 +54,4 @@ static void sb_close(struct sbuff *m)
 	}
 }
 
+#define sb_close(m)	__sb_close(m, 1)
-- 
1.7.7.3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 4/4] Netfilter: xt_LOG: Implement ring buffer support
  2012-02-10 22:10 [PATCH v5] Merge ipt_LOG and ip6t_LOG, add ring bufffer support Richard Weinberger
                   ` (4 preceding siblings ...)
  2012-02-10 22:10 ` [PATCH 3/4] xt_log: Make printk() in sb_close() optional Richard Weinberger
@ 2012-02-10 22:10 ` Richard Weinberger
  2012-02-14  0:11   ` Pablo Neira Ayuso
  5 siblings, 1 reply; 16+ messages in thread
From: Richard Weinberger @ 2012-02-10 22:10 UTC (permalink / raw)
  To: netfilter-devel
  Cc: netdev, linux-kernel, eric.dumazet, jengelh, rostedt, pablo,
	basti, Richard Weinberger

This patch introduces NETFILTER_XT_TARGET_LOG_RING.
It allows logging into various ring buffers which are
represented as pipe-like files in /proc/net/netfilter/xt_LOG_ring/.

Signed-off-by: Richard Weinberger <richard@nod.at>
---
 include/linux/netfilter/xt_LOG.h    |   13 +-
 include/net/netfilter/nf_log.h      |    1 +
 include/net/netfilter/xt_log_ring.h |   24 ++
 net/netfilter/Kconfig               |   13 +
 net/netfilter/xt_LOG.c              |  642 ++++++++++++++++++++++++++++++++++-
 5 files changed, 674 insertions(+), 19 deletions(-)
 create mode 100644 include/net/netfilter/xt_log_ring.h

diff --git a/include/linux/netfilter/xt_LOG.h b/include/linux/netfilter/xt_LOG.h
index cac0790..d84710c 100644
--- a/include/linux/netfilter/xt_LOG.h
+++ b/include/linux/netfilter/xt_LOG.h
@@ -8,7 +8,8 @@
 #define XT_LOG_UID		0x08	/* Log UID owning local socket */
 #define XT_LOG_NFLOG		0x10	/* Unsupported, don't reuse */
 #define XT_LOG_MACDECODE	0x20	/* Decode MAC header */
-#define XT_LOG_MASK		0x2f
+#define XT_LOG_ADD_TIMESTAMP	0x40	/* Add a timestamp */
+#define XT_LOG_MASK		0x6f
 
 struct xt_log_info {
 	unsigned char level;
@@ -16,4 +17,14 @@ struct xt_log_info {
 	char prefix[30];
 };
 
+struct xt_log_info_v1 {
+	unsigned char level;
+	unsigned char logflags;
+	char prefix[30];
+
+	char ring_name[30];
+	__aligned_u64 ring_size;
+	struct xt_LOG_ring_ctx *rctx __attribute__((aligned(8)));
+};
+
 #endif /* _XT_LOG_H */
diff --git a/include/net/netfilter/nf_log.h b/include/net/netfilter/nf_log.h
index e991bd0..18a94f9 100644
--- a/include/net/netfilter/nf_log.h
+++ b/include/net/netfilter/nf_log.h
@@ -14,6 +14,7 @@
 
 #define NF_LOG_TYPE_LOG		0x01
 #define NF_LOG_TYPE_ULOG	0x02
+#define NF_LOG_TYPE_RING	0x04
 
 struct nf_loginfo {
 	u_int8_t type;
diff --git a/include/net/netfilter/xt_log_ring.h b/include/net/netfilter/xt_log_ring.h
new file mode 100644
index 0000000..c531381
--- /dev/null
+++ b/include/net/netfilter/xt_log_ring.h
@@ -0,0 +1,24 @@
+#ifndef XT_LOG_RING_H
+#define XT_LOG_RING_H
+
+struct xt_LOG_ring_ctx;
+struct xt_LOG_ring_ctx *xt_LOG_ring_new_ctx(const char *name, size_t rb_size);
+int xt_LOG_ring_add_record(const struct xt_LOG_ring_ctx *rctx, const char *buf, unsigned int len);
+void xt_LOG_ring_get(struct xt_LOG_ring_ctx *ctx);
+void xt_LOG_ring_put(struct xt_LOG_ring_ctx *ctx);
+struct xt_LOG_ring_ctx *xt_LOG_ring_find_ctx(const char *name);
+
+#ifdef CONFIG_NETFILTER_XT_TARGET_LOG_RING
+void xt_LOG_ring_exit(void);
+int xt_LOG_ring_init(void);
+#else
+static inline void xt_LOG_ring_exit(void)
+{
+}
+
+static inline int xt_LOG_ring_init(void)
+{
+	return 0;
+}
+#endif
+#endif
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index b895d8b..ac62599 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -533,6 +533,19 @@ config NETFILTER_XT_TARGET_LOG
 
 	  To compile it as a module, choose M here.  If unsure, say N.
 
+if NETFILTER_XT_TARGET_LOG
+
+config NETFILTER_XT_TARGET_LOG_RING
+	bool  'Ring buffer support'
+	default y
+	select RING_BUFFER
+	help
+	 Using this it is possible to record packets into one or more ring buffers
+	 instead of the kernel syslog.
+	 Each ring buffer is represented as file in /proc/net/netfilter/xt_LOG_ring/.
+
+endif
+
 config NETFILTER_XT_TARGET_MARK
 	tristate '"MARK" target support'
 	depends on NETFILTER_ADVANCED
diff --git a/net/netfilter/xt_LOG.c b/net/netfilter/xt_LOG.c
index 1595608..62738be 100644
--- a/net/netfilter/xt_LOG.c
+++ b/net/netfilter/xt_LOG.c
@@ -16,6 +16,21 @@
 #include <linux/skbuff.h>
 #include <linux/if_arp.h>
 #include <linux/ip.h>
+#include <linux/ctype.h>
+#include <linux/ring_buffer.h>
+#include <linux/cpu.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/fs.h>
+#include <linux/poll.h>
+#include <linux/proc_fs.h>
+#include <linux/wait.h>
+#include <linux/time.h>
+#include <linux/sched.h>
+#include <linux/list.h>
+#include <linux/atomic.h>
+#include <linux/spinlock.h>
+#include <linux/mutex.h>
 #include <net/ipv6.h>
 #include <net/icmp.h>
 #include <net/udp.h>
@@ -28,6 +43,45 @@
 #include <linux/netfilter_ipv6/ip6_tables.h>
 #include <net/netfilter/nf_log.h>
 #include <net/netfilter/xt_log.h>
+#include <net/netfilter/xt_log_ring.h>
+
+#ifdef CONFIG_NETFILTER_XT_TARGET_LOG_RING
+#define RING_DIR "xt_LOG_ring"
+
+struct xt_LOG_ring_ctx {
+	char name[32];
+	struct ring_buffer *buffer;
+	atomic_t pipe_in_use;
+	atomic_t refcnt;
+
+	struct list_head list;
+};
+
+struct rlog_entry {
+	size_t count;
+	char msg[0];
+};
+
+struct rlog_iter {
+	struct ring_buffer *buffer;
+	const char *buffer_name;
+	struct rlog_entry *ent;
+
+	char print_buf[PAGE_SIZE];
+	size_t print_buf_len;
+	size_t print_buf_pos;
+
+	unsigned long lost_events;
+	int cpu;
+
+	struct mutex lock;
+};
+
+static DEFINE_SPINLOCK(ring_list_lock);
+static LIST_HEAD(ring_list);
+static DECLARE_WAIT_QUEUE_HEAD(rlog_wait);
+static struct proc_dir_entry *prlog;
+#endif
 
 static struct nf_loginfo default_loginfo = {
 	.type	= NF_LOG_TYPE_LOG,
@@ -155,7 +209,7 @@ static void dump_ipv4_packet(struct sbuff *m,
 	const struct iphdr *ih;
 	unsigned int logflags;
 
-	if (info->type == NF_LOG_TYPE_LOG)
+	if (info->type == NF_LOG_TYPE_LOG || info->type == NF_LOG_TYPE_RING)
 		logflags = info->u.log.logflags;
 	else
 		logflags = NF_LOG_MASK;
@@ -394,7 +448,7 @@ static void dump_ipv4_mac_header(struct sbuff *m,
 	struct net_device *dev = skb->dev;
 	unsigned int logflags = 0;
 
-	if (info->type == NF_LOG_TYPE_LOG)
+	if (info->type == NF_LOG_TYPE_LOG || info->type == NF_LOG_TYPE_RING)
 		logflags = info->u.log.logflags;
 
 	if (!(logflags & XT_LOG_MACDECODE))
@@ -434,9 +488,20 @@ log_packet_common(struct sbuff *m,
 		  const struct nf_loginfo *loginfo,
 		  const char *prefix)
 {
-	sb_add(m, "<%d>%sIN=%s OUT=%s ", loginfo->u.log.level,
-	       prefix,
-	       in ? in->name : "",
+	if (loginfo->type == NF_LOG_TYPE_LOG)
+		sb_add(m, "<%d>", loginfo->u.log.level);
+
+	if (loginfo->u.log.logflags & XT_LOG_ADD_TIMESTAMP) {
+		static struct timespec tv;
+		unsigned int msec;
+
+		getnstimeofday(&tv);
+		msec = tv.tv_nsec;
+		do_div(msec, 1000000);
+		sb_add(m, "TIMESTAMP=%li.%03li ", tv.tv_sec, msec);
+	}
+
+	sb_add(m, "%sIN=%s OUT=%s ", prefix, in ? in->name : "",
 	       out ? out->name : "");
 #ifdef CONFIG_BRIDGE_NETFILTER
 	if (skb->nf_bridge) {
@@ -454,8 +519,7 @@ log_packet_common(struct sbuff *m,
 }
 
 
-static void
-ipt_log_packet(u_int8_t pf,
+static struct sbuff *ipt_log_packet(u_int8_t pf,
 	       unsigned int hooknum,
 	       const struct sk_buff *skb,
 	       const struct net_device *in,
@@ -475,6 +539,19 @@ ipt_log_packet(u_int8_t pf,
 
 	dump_ipv4_packet(m, loginfo, skb, 0);
 
+	return m;
+}
+
+static void ipt_log_packet_logger(u_int8_t pf,
+	       unsigned int hooknum,
+	       const struct sk_buff *skb,
+	       const struct net_device *in,
+	       const struct net_device *out,
+	       const struct nf_loginfo *loginfo,
+	       const char *prefix)
+{
+	struct sbuff *m = ipt_log_packet(pf, hooknum, skb, in, out, loginfo, prefix);
+
 	sb_close(m);
 }
 
@@ -493,7 +570,7 @@ static void dump_ipv6_packet(struct sbuff *m,
 	unsigned int hdrlen = 0;
 	unsigned int logflags;
 
-	if (info->type == NF_LOG_TYPE_LOG)
+	if (info->type == NF_LOG_TYPE_LOG || info->type == NF_LOG_TYPE_RING)
 		logflags = info->u.log.logflags;
 	else
 		logflags = NF_LOG_MASK;
@@ -734,7 +811,7 @@ static void dump_ipv6_mac_header(struct sbuff *m,
 	struct net_device *dev = skb->dev;
 	unsigned int logflags = 0;
 
-	if (info->type == NF_LOG_TYPE_LOG)
+	if (info->type == NF_LOG_TYPE_LOG || info->type == NF_LOG_TYPE_RING)
 		logflags = info->u.log.logflags;
 
 	if (!(logflags & XT_LOG_MACDECODE))
@@ -782,8 +859,7 @@ fallback:
 		sb_add(m, " ");
 }
 
-static void
-ip6t_log_packet(u_int8_t pf,
+static struct sbuff *ip6t_log_packet(u_int8_t pf,
 		unsigned int hooknum,
 		const struct sk_buff *skb,
 		const struct net_device *in,
@@ -803,6 +879,19 @@ ip6t_log_packet(u_int8_t pf,
 
 	dump_ipv6_packet(m, loginfo, skb, skb_network_offset(skb), 1);
 
+	return m;
+}
+
+static void ip6t_log_packet_logger(u_int8_t pf,
+	       unsigned int hooknum,
+	       const struct sk_buff *skb,
+	       const struct net_device *in,
+	       const struct net_device *out,
+	       const struct nf_loginfo *loginfo,
+	       const char *prefix)
+{
+	struct sbuff *m = ip6t_log_packet(pf, hooknum, skb, in, out, loginfo, prefix);
+
 	sb_close(m);
 }
 #endif
@@ -812,22 +901,28 @@ log_tg(struct sk_buff *skb, const struct xt_action_param *par)
 {
 	const struct xt_log_info *loginfo = par->targinfo;
 	struct nf_loginfo li;
+	struct sbuff *m;
 
 	li.type = NF_LOG_TYPE_LOG;
 	li.u.log.level = loginfo->level;
 	li.u.log.logflags = loginfo->logflags;
 
 	if (par->family == NFPROTO_IPV4)
-		ipt_log_packet(NFPROTO_IPV4, par->hooknum, skb, par->in,
-			       par->out, &li, loginfo->prefix);
+		m = ipt_log_packet(NFPROTO_IPV4, par->hooknum, skb, par->in,
+				   par->out, &li, loginfo->prefix);
 #if IS_ENABLED(CONFIG_IPV6)
 	else if (par->family == NFPROTO_IPV6)
-		ip6t_log_packet(NFPROTO_IPV6, par->hooknum, skb, par->in,
-				par->out, &li, loginfo->prefix);
+		m = ip6t_log_packet(NFPROTO_IPV6, par->hooknum, skb, par->in,
+				    par->out, &li, loginfo->prefix);
 #endif
-	else
+	else {
 		WARN_ON_ONCE(1);
+		goto out;
+	}
+
+	sb_close(m);
 
+out:
 	return XT_CONTINUE;
 }
 
@@ -851,37 +946,542 @@ static int log_tg_check(const struct xt_tgchk_param *par)
 	return 0;
 }
 
+static unsigned int
+log_tg_v1(struct sk_buff *skb, const struct xt_action_param *par)
+{
+	const struct xt_log_info_v1 *loginfo = par->targinfo;
+	struct nf_loginfo li;
+	struct sbuff *m;
+
+#ifdef CONFIG_NETFILTER_XT_TARGET_LOG_RING
+	if (loginfo->ring_size)
+		li.type = NF_LOG_TYPE_RING;
+	else
+#endif
+		li.type = NF_LOG_TYPE_LOG;
+
+	li.u.log.level = loginfo->level;
+	li.u.log.logflags = loginfo->logflags;
+
+	if (par->family == NFPROTO_IPV4)
+		m = ipt_log_packet(NFPROTO_IPV4, par->hooknum, skb, par->in,
+				   par->out, &li, loginfo->prefix);
+#if IS_ENABLED(CONFIG_IPV6)
+	else if (par->family == NFPROTO_IPV6)
+		m = ip6t_log_packet(NFPROTO_IPV6, par->hooknum, skb, par->in,
+				    par->out, &li, loginfo->prefix);
+#endif
+	else {
+		WARN_ON_ONCE(1);
+		goto out;
+	}
+
+#ifdef CONFIG_NETFILTER_XT_TARGET_LOG_RING
+	if (loginfo->ring_size) {
+		sb_add(m, "\n");
+		xt_LOG_ring_add_record(loginfo->rctx, m->buf, m->count);
+		__sb_close(m, 0);
+	} else
+#endif
+		sb_close(m);
+
+out:
+	return XT_CONTINUE;
+}
+
+static int log_tg_check_v1(const struct xt_tgchk_param *par)
+{
+	struct xt_log_info_v1 *loginfo = par->targinfo;
+
+	if (par->family != NFPROTO_IPV4 && par->family != NFPROTO_IPV6)
+		return -EINVAL;
+
+	if (loginfo->level >= 8) {
+		pr_debug("level %u >= 8\n", loginfo->level);
+		return -EINVAL;
+	}
+
+	if (loginfo->prefix[sizeof(loginfo->prefix)-1] != '\0') {
+		pr_debug("prefix is not null-terminated\n");
+		return -EINVAL;
+	}
+
+	/* a non-empty ring_size indicates that we're using ring_buffer */
+	if (loginfo->ring_size) {
+#ifdef CONFIG_NETFILTER_XT_TARGET_LOG_RING
+		int i;
+		struct xt_LOG_ring_ctx *rctx;
+
+		if (loginfo->ring_name[sizeof(loginfo->ring_name)-1] != '\0') {
+			pr_debug("ring_name is not null-terminated\n");
+			return -EINVAL;
+		}
+
+		if (!loginfo->ring_name[0]) {
+			pr_debug("ring_name is empty\n");
+			return -EINVAL;
+		}
+
+		for (i = 0; i < strlen(loginfo->ring_name); i++) {
+			if (!isalnum(loginfo->ring_name[i])) {
+				pr_debug("ring_name contains "
+					 "a non-alphanumeric character\n");
+				return -EINVAL;
+			}
+		}
+
+		rctx = xt_LOG_ring_find_ctx(loginfo->ring_name);
+		if (!rctx) {
+			rctx = xt_LOG_ring_new_ctx(loginfo->ring_name,
+			       loginfo->ring_size);
+			if (IS_ERR(rctx))
+				return PTR_ERR(rctx);
+		}
+
+		xt_LOG_ring_get(rctx);
+		loginfo->rctx = rctx;
+#else
+		pr_debug("Sorry, this kernel was built without CONFIG_NETFILTER_XT_TARGET_LOG_RING\n");
+		return -EINVAL;
+#endif
+	}
+
+	return 0;
+}
+
+static void log_tg_destroy_v1(const struct xt_tgdtor_param *par)
+{
+#ifdef CONFIG_NETFILTER_XT_TARGET_LOG_RING
+	const struct xt_log_info_v1 *loginfo = par->targinfo;
+	struct xt_LOG_ring_ctx *rctx = loginfo->rctx;
+
+	if (loginfo->ring_size)
+		xt_LOG_ring_put(rctx);
+#endif
+}
+
+#ifdef CONFIG_NETFILTER_XT_TARGET_LOG_RING
+static void wakeup_work_handler(struct work_struct *work)
+{
+	wake_up(&rlog_wait);
+}
+
+static DECLARE_WORK(wakeup_work, wakeup_work_handler);
+
+static void rlog_wake_up(void)
+{
+	schedule_work(&wakeup_work);
+}
+
+int xt_LOG_ring_add_record(const struct xt_LOG_ring_ctx *rctx,
+			   const char *buf, unsigned int len)
+{
+	struct rlog_entry *entry;
+	struct ring_buffer_event *event;
+
+	event = ring_buffer_lock_reserve(rctx->buffer, sizeof(*entry) + len);
+	if (!event)
+		return 1;
+
+	entry = ring_buffer_event_data(event);
+	memcpy(entry->msg, buf, len);
+	entry->count = len;
+
+	ring_buffer_unlock_commit(rctx->buffer, event);
+	rlog_wake_up();
+
+	return 0;
+}
+
+static struct rlog_entry *peek_next_entry(struct rlog_iter *iter, int cpu,
+					  unsigned long long *ts)
+{
+	struct ring_buffer_event *event;
+
+	event = ring_buffer_peek(iter->buffer, cpu, ts, &iter->lost_events);
+
+	if (event)
+		return ring_buffer_event_data(event);
+
+	return NULL;
+}
+
+static struct rlog_entry *find_next_entry(struct rlog_iter *iter)
+{
+	struct rlog_entry *ent, *next = NULL;
+	unsigned long long next_ts = 0, ts;
+	int cpu, next_cpu = -1;
+
+	for_each_buffer_cpu (iter->buffer, cpu) {
+		if (ring_buffer_empty_cpu(iter->buffer, cpu))
+			continue;
+
+		ent = peek_next_entry(iter, cpu, &ts);
+
+		if (ent && (!next || ts < next_ts)) {
+			next = ent;
+			next_cpu = cpu;
+			next_ts = ts;
+		}
+	}
+
+	iter->cpu = next_cpu;
+
+	return next;
+}
+
+static struct rlog_iter *find_next_entry_inc(struct rlog_iter *iter)
+{
+	iter->ent = find_next_entry(iter);
+
+	if (iter->ent)
+		return iter;
+
+	return NULL;
+}
+
+static int buffer_empty(struct rlog_iter *iter)
+{
+	int cpu;
+
+	for_each_buffer_cpu (iter->buffer, cpu) {
+		if (!ring_buffer_empty_cpu(iter->buffer, cpu))
+			return 0;
+	}
+
+	return 1;
+}
+
+static ssize_t rlog_to_user(struct rlog_iter *iter, char __user *ubuf,
+			    size_t cnt)
+{
+	int ret;
+	int len;
+
+	if (!cnt)
+		goto out;
+
+	len = iter->print_buf_len - iter->print_buf_pos;
+	if (len < 1)
+		return -EBUSY;
+
+	if (cnt > len)
+		cnt = len;
+
+	ret = copy_to_user(ubuf, iter->print_buf + iter->print_buf_pos, cnt);
+	if (ret == cnt)
+		return -EFAULT;
+
+	cnt -= ret;
+	iter->print_buf_pos += cnt;
+
+out:
+	return cnt;
+}
+
+static int rlog_open_pipe(struct inode *inode, struct file *file)
+{
+	struct rlog_iter *iter;
+	struct xt_LOG_ring_ctx *tgt = PDE(inode)->data;
+	int ret = 0;
+
+	/* only one consuming reader is allowed */
+	if (atomic_cmpxchg(&tgt->pipe_in_use, 0, 1)) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	iter = kzalloc(sizeof(*iter), GFP_KERNEL);
+	if (!iter) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	mutex_init(&iter->lock);
+	iter->buffer = tgt->buffer;
+	iter->buffer_name = tgt->name;
+
+	file->private_data = iter;
+out:
+	return ret;
+}
+
+static unsigned int rlog_poll_pipe(struct file *file, poll_table *poll_table)
+{
+	struct rlog_iter *iter = file->private_data;
+
+	if (!buffer_empty(iter))
+		return POLLIN | POLLRDNORM;
+
+	poll_wait(file, &rlog_wait, poll_table);
+
+	if (!buffer_empty(iter))
+		return POLLIN | POLLRDNORM;
+
+	return 0;
+}
+
+static int rlog_release_pipe(struct inode *inode, struct file *file)
+{
+	struct rlog_iter *iter = file->private_data;
+	struct xt_LOG_ring_ctx *tgt = PDE(inode)->data;
+
+	mutex_destroy(&iter->lock);
+	kfree(iter);
+	atomic_set(&tgt->pipe_in_use, 0);
+
+	return 0;
+}
+
+static void wait_pipe(struct rlog_iter *iter)
+{
+	DEFINE_WAIT(wait);
+
+	prepare_to_wait(&rlog_wait, &wait, TASK_INTERRUPTIBLE);
+
+	if (buffer_empty(iter))
+		schedule();
+
+	finish_wait(&rlog_wait, &wait);
+}
+
+static int rlog_wait_pipe(struct file *file)
+{
+	struct rlog_iter *iter = file->private_data;
+
+	while (buffer_empty(iter)) {
+		if (file->f_flags & O_NONBLOCK)
+			return -EAGAIN;
+
+		mutex_unlock(&iter->lock);
+
+		wait_pipe(iter);
+
+		mutex_lock(&iter->lock);
+
+		if (signal_pending(current))
+			return -EINTR;
+	}
+
+	return 1;
+}
+
+static ssize_t rlog_read_pipe(struct file *file, char __user *ubuf,
+			      size_t cnt, loff_t *ppos)
+{
+	struct rlog_iter *iter = file->private_data;
+	ssize_t ret;
+
+	ret = rlog_to_user(iter, ubuf, cnt);
+	if (ret != -EBUSY)
+		goto out;
+
+	iter->print_buf_pos = 0;
+	iter->print_buf_len = 0;
+
+	if (cnt >= PAGE_SIZE)
+		cnt = PAGE_SIZE - 1;
+
+	mutex_lock(&iter->lock);
+again:
+	ret = rlog_wait_pipe(file);
+	if (ret <= 0)
+		goto out_unlock;
+
+	while (find_next_entry_inc(iter) != NULL) {
+		struct rlog_entry *ent;
+		ent = iter->ent;
+
+		if (ent->count >= PAGE_SIZE - iter->print_buf_len)
+			break;
+
+		memcpy(iter->print_buf + iter->print_buf_len, ent->msg,
+			ent->count);
+		iter->print_buf_len += ent->count;
+
+		ring_buffer_consume(iter->buffer, iter->cpu, NULL,
+			&iter->lost_events);
+		if (iter->lost_events)
+			printk(KERN_WARNING KBUILD_MODNAME ": Ring %s "
+				"lost %lu events\n", iter->buffer_name,
+				iter->lost_events);
+
+		if (iter->print_buf_len >= cnt)
+			break;
+	}
+
+	ret = rlog_to_user(iter, ubuf, cnt);
+
+	if (iter->print_buf_pos >= iter->print_buf_len) {
+		iter->print_buf_pos = 0;
+		iter->print_buf_len = 0;
+	}
+
+	if (ret == -EBUSY)
+		goto again;
+out_unlock:
+	mutex_unlock(&iter->lock);
+out:
+	return ret;
+}
+
+static const struct file_operations rlog_pipe_fops = {
+	.open		= rlog_open_pipe,
+	.poll		= rlog_poll_pipe,
+	.read		= rlog_read_pipe,
+	.release	= rlog_release_pipe,
+	.llseek		= no_llseek,
+};
+
+struct xt_LOG_ring_ctx *xt_LOG_ring_new_ctx(const char *name, size_t rb_size)
+{
+	struct xt_LOG_ring_ctx *new;
+
+	new = kmalloc(sizeof(*new), GFP_KERNEL);
+	if (!new) {
+		new = ERR_PTR(-ENOMEM);
+
+		goto out;
+	}
+
+	new->buffer = ring_buffer_alloc(rb_size << 10, RB_FL_OVERWRITE);
+	if (!new->buffer) {
+		kfree(new);
+		new = ERR_PTR(-ENOMEM);
+
+		goto out;
+	}
+
+	strlcpy(new->name, name, sizeof new->name);
+
+	if (!proc_create_data(name, 0400, prlog, &rlog_pipe_fops, new)) {
+		ring_buffer_free(new->buffer);
+		kfree(new);
+		new = ERR_PTR(-ENOMEM);
+
+		goto out;
+	}
+
+	atomic_set(&new->pipe_in_use, 0);
+	atomic_set(&new->refcnt, 0);
+
+	spin_lock(&ring_list_lock);
+	list_add(&new->list, &ring_list);
+	spin_unlock(&ring_list_lock);
+out:
+	return new;
+}
+
+static void free_xt_LOG_ring_ctx(struct xt_LOG_ring_ctx *ctx)
+{
+	remove_proc_entry(ctx->name, prlog);
+	ring_buffer_free(ctx->buffer);
+	list_del(&ctx->list);
+	kfree(ctx);
+}
+
+void xt_LOG_ring_get(struct xt_LOG_ring_ctx *ctx)
+{
+	atomic_inc(&ctx->refcnt);
+}
+
+void xt_LOG_ring_put(struct xt_LOG_ring_ctx *ctx)
+{
+	if (atomic_dec_and_test(&ctx->refcnt))
+		free_xt_LOG_ring_ctx(ctx);
+}
+
+struct xt_LOG_ring_ctx *xt_LOG_ring_find_ctx(const char *name)
+{
+	struct list_head *e;
+	struct xt_LOG_ring_ctx *tmp, *victim = NULL;
+
+	spin_lock(&ring_list_lock);
+
+	list_for_each(e, &ring_list) {
+		tmp = list_entry(e, struct xt_LOG_ring_ctx, list);
+		if (strcmp(tmp->name, name) == 0) {
+			victim = tmp;
+
+			goto out;
+		}
+	}
+
+out:
+	spin_unlock(&ring_list_lock);
+
+	return victim;
+}
+
+void __exit xt_LOG_ring_exit(void)
+{
+	WARN_ON(!list_empty(&ring_list));
+	remove_proc_entry(RING_DIR, proc_net_netfilter);
+}
+
+int __init xt_LOG_ring_init(void)
+{
+	prlog = proc_mkdir(RING_DIR, proc_net_netfilter);
+	if (!prlog)
+		return -ENOMEM;
+
+	return 0;
+}
+#endif /* CONFIG_NETFILTER_XT_TARGET_LOG_RING */
+
 static struct xt_target log_tg_regs[] __read_mostly = {
 	{
 		.name		= "LOG",
 		.family		= NFPROTO_IPV4,
+		.revision	= 0,
 		.target		= log_tg,
 		.targetsize	= sizeof(struct xt_log_info),
 		.checkentry	= log_tg_check,
 		.me		= THIS_MODULE,
 	},
+	{
+		.name		= "LOG",
+		.family		= NFPROTO_IPV4,
+		.revision	= 1,
+		.target		= log_tg_v1,
+		.targetsize	= sizeof(struct xt_log_info_v1),
+		.checkentry	= log_tg_check_v1,
+		.destroy	= log_tg_destroy_v1,
+		.me		= THIS_MODULE,
+	},
 #if IS_ENABLED(CONFIG_IPV6)
 	{
 		.name		= "LOG",
 		.family		= NFPROTO_IPV6,
+		.revision	= 0,
 		.target		= log_tg,
 		.targetsize	= sizeof(struct xt_log_info),
 		.checkentry	= log_tg_check,
 		.me		= THIS_MODULE,
 	},
+	{
+		.name		= "LOG",
+		.family		= NFPROTO_IPV6,
+		.revision	= 1,
+		.target		= log_tg_v1,
+		.targetsize	= sizeof(struct xt_log_info_v1),
+		.checkentry	= log_tg_check_v1,
+		.destroy	= log_tg_destroy_v1,
+		.me		= THIS_MODULE,
+	},
 #endif
 };
 
 static struct nf_logger ipt_log_logger __read_mostly = {
 	.name		= "ipt_LOG",
-	.logfn		= &ipt_log_packet,
+	.logfn		= &ipt_log_packet_logger,
 	.me		= THIS_MODULE,
 };
 
 #if IS_ENABLED(CONFIG_IPV6)
 static struct nf_logger ip6t_log_logger __read_mostly = {
 	.name		= "ip6t_LOG",
-	.logfn		= &ip6t_log_packet,
+	.logfn		= &ip6t_log_packet_logger,
 	.me		= THIS_MODULE,
 };
 #endif
@@ -890,6 +1490,10 @@ static int __init log_tg_init(void)
 {
 	int ret;
 
+	ret = xt_LOG_ring_init();
+	if (ret < 0)
+		return ret;
+
 	ret = xt_register_targets(log_tg_regs, ARRAY_SIZE(log_tg_regs));
 	if (ret < 0)
 		return ret;
@@ -908,6 +1512,7 @@ static void __exit log_tg_exit(void)
 	nf_log_unregister(&ip6t_log_logger);
 #endif
 	xt_unregister_targets(log_tg_regs, ARRAY_SIZE(log_tg_regs));
+	xt_LOG_ring_exit();
 }
 
 module_init(log_tg_init);
@@ -916,6 +1521,7 @@ module_exit(log_tg_exit);
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
 MODULE_AUTHOR("Jan Rekorajski <baggins@pld.org.pl>");
+MODULE_AUTHOR("Richard Weinberger <richard@nod.at>");
 MODULE_DESCRIPTION("Xtables: IPv4/IPv6 packet logging");
 MODULE_ALIAS("ipt_LOG");
 MODULE_ALIAS("ip6t_LOG");
-- 
1.7.7.3


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/4] Netfilter: Merge ipt_LOG and ip6_LOG into xt_LOG
  2012-02-10 22:10 ` [PATCH 1/4] Netfilter: Merge ipt_LOG and ip6_LOG into xt_LOG Richard Weinberger
@ 2012-02-13 23:56   ` Pablo Neira Ayuso
  0 siblings, 0 replies; 16+ messages in thread
From: Pablo Neira Ayuso @ 2012-02-13 23:56 UTC (permalink / raw)
  To: Richard Weinberger
  Cc: netfilter-devel, netdev, linux-kernel, eric.dumazet, jengelh,
	rostedt, basti

On Fri, Feb 10, 2012 at 11:10:52PM +0100, Richard Weinberger wrote:
> ipt_LOG and ip6_LOG have a lot of common code, merge them
> to reduce duplicate code.

Applied, thanks.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 2/4] ring_buffer: Export for_each_buffer_cpu()
  2012-02-10 22:10 ` [PATCH 2/4] ring_buffer: Export for_each_buffer_cpu() Richard Weinberger
@ 2012-02-14  0:05   ` Pablo Neira Ayuso
  0 siblings, 0 replies; 16+ messages in thread
From: Pablo Neira Ayuso @ 2012-02-14  0:05 UTC (permalink / raw)
  To: Richard Weinberger
  Cc: netfilter-devel, netdev, linux-kernel, eric.dumazet, jengelh,
	rostedt, basti

On Fri, Feb 10, 2012 at 11:10:54PM +0100, Richard Weinberger wrote:
> In order to make ring_buffer usable to other modules
> for_each_buffer_cpu() needs to be exported.
> 
> Signed-off-by: Richard Weinberger <richard@nod.at>
> Acked-by: Steven Rostedt <rostedt@goodmis.org>

I've taken this one as well since we need it for the ring_buffer
support for your extension for xt_LOG.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 4/4] Netfilter: xt_LOG: Implement ring buffer support
  2012-02-10 22:10 ` [PATCH 4/4] Netfilter: xt_LOG: Implement ring buffer support Richard Weinberger
@ 2012-02-14  0:11   ` Pablo Neira Ayuso
  2012-02-14  0:12     ` Richard Weinberger
  0 siblings, 1 reply; 16+ messages in thread
From: Pablo Neira Ayuso @ 2012-02-14  0:11 UTC (permalink / raw)
  To: Richard Weinberger
  Cc: netfilter-devel, netdev, linux-kernel, eric.dumazet, jengelh,
	rostedt, basti

On Fri, Feb 10, 2012 at 11:10:56PM +0100, Richard Weinberger wrote:
> This patch introduces NETFILTER_XT_TARGET_LOG_RING.
> It allows logging into various ring buffers which are
> represented as pipe-like files in /proc/net/netfilter/xt_LOG_ring/.
> 
> Signed-off-by: Richard Weinberger <richard@nod.at>
> ---
>  include/linux/netfilter/xt_LOG.h    |   13 +-
>  include/net/netfilter/nf_log.h      |    1 +
>  include/net/netfilter/xt_log_ring.h |   24 ++

Could merge xt_log_ring.h with xt_log.h?

>  net/netfilter/Kconfig               |   13 +
>  net/netfilter/xt_LOG.c              |  642 ++++++++++++++++++++++++++++++++++-
>  5 files changed, 674 insertions(+), 19 deletions(-)
>  create mode 100644 include/net/netfilter/xt_log_ring.h
> 
> diff --git a/include/linux/netfilter/xt_LOG.h b/include/linux/netfilter/xt_LOG.h
> index cac0790..d84710c 100644
> --- a/include/linux/netfilter/xt_LOG.h
> +++ b/include/linux/netfilter/xt_LOG.h
> @@ -8,7 +8,8 @@
>  #define XT_LOG_UID		0x08	/* Log UID owning local socket */
>  #define XT_LOG_NFLOG		0x10	/* Unsupported, don't reuse */
>  #define XT_LOG_MACDECODE	0x20	/* Decode MAC header */
> -#define XT_LOG_MASK		0x2f
> +#define XT_LOG_ADD_TIMESTAMP	0x40	/* Add a timestamp */

Please, I'd appreciate if you can split this timestamp support in a
separated patch.

Thanks.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 3/4] xt_log: Make printk() in sb_close() optional
  2012-02-10 22:10 ` [PATCH 3/4] xt_log: Make printk() in sb_close() optional Richard Weinberger
@ 2012-02-14  0:12   ` Pablo Neira Ayuso
  0 siblings, 0 replies; 16+ messages in thread
From: Pablo Neira Ayuso @ 2012-02-14  0:12 UTC (permalink / raw)
  To: Richard Weinberger
  Cc: netfilter-devel, netdev, linux-kernel, eric.dumazet, jengelh,
	rostedt, basti

On Fri, Feb 10, 2012 at 11:10:55PM +0100, Richard Weinberger wrote:
> Make printk() in sb_close() optional such that other modules
> can build a log string without printing it using printk().

Applied, thanks.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 4/4] Netfilter: xt_LOG: Implement ring buffer support
  2012-02-14  0:11   ` Pablo Neira Ayuso
@ 2012-02-14  0:12     ` Richard Weinberger
  0 siblings, 0 replies; 16+ messages in thread
From: Richard Weinberger @ 2012-02-14  0:12 UTC (permalink / raw)
  To: Pablo Neira Ayuso
  Cc: netfilter-devel, netdev, linux-kernel, eric.dumazet, jengelh,
	rostedt, basti

Am 14.02.2012 01:11, schrieb Pablo Neira Ayuso:
> On Fri, Feb 10, 2012 at 11:10:56PM +0100, Richard Weinberger wrote:
>> This patch introduces NETFILTER_XT_TARGET_LOG_RING.
>> It allows logging into various ring buffers which are
>> represented as pipe-like files in /proc/net/netfilter/xt_LOG_ring/.
>>
>> Signed-off-by: Richard Weinberger<richard@nod.at>
>> ---
>>   include/linux/netfilter/xt_LOG.h    |   13 +-
>>   include/net/netfilter/nf_log.h      |    1 +
>>   include/net/netfilter/xt_log_ring.h |   24 ++
>
> Could merge xt_log_ring.h with xt_log.h?

Sure.

>>   net/netfilter/Kconfig               |   13 +
>>   net/netfilter/xt_LOG.c              |  642 ++++++++++++++++++++++++++++++++++-
>>   5 files changed, 674 insertions(+), 19 deletions(-)
>>   create mode 100644 include/net/netfilter/xt_log_ring.h
>>
>> diff --git a/include/linux/netfilter/xt_LOG.h b/include/linux/netfilter/xt_LOG.h
>> index cac0790..d84710c 100644
>> --- a/include/linux/netfilter/xt_LOG.h
>> +++ b/include/linux/netfilter/xt_LOG.h
>> @@ -8,7 +8,8 @@
>>   #define XT_LOG_UID		0x08	/* Log UID owning local socket */
>>   #define XT_LOG_NFLOG		0x10	/* Unsupported, don't reuse */
>>   #define XT_LOG_MACDECODE	0x20	/* Decode MAC header */
>> -#define XT_LOG_MASK		0x2f
>> +#define XT_LOG_ADD_TIMESTAMP	0x40	/* Add a timestamp */
>
> Please, I'd appreciate if you can split this timestamp support in a
> separated patch.
>

Will do.

Thanks,
//richard


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/2] iptables: Merge libip6t_LOG and libipt_LOG into libxt_LOG
  2012-02-10 22:10 ` [PATCH 1/2] iptables: Merge libip6t_LOG and libipt_LOG into libxt_LOG Richard Weinberger
@ 2012-02-25 13:38   ` Pablo Neira Ayuso
  2012-02-28 16:06     ` Richard Weinberger
  0 siblings, 1 reply; 16+ messages in thread
From: Pablo Neira Ayuso @ 2012-02-25 13:38 UTC (permalink / raw)
  To: Richard Weinberger
  Cc: netfilter-devel, netdev, linux-kernel, eric.dumazet, jengelh,
	rostedt, basti

On Fri, Feb 10, 2012 at 11:10:51PM +0100, Richard Weinberger wrote:
> libip6t_LOG and libipt_LOG share a lot of common code, merge them
> to recude duplicate code.

I have applied this to the net-next branch of iptables.

See git.netfilter.org

I'll merge it to master once linux kernel 3.3 is released.

Please, send follow up patches if you find any issue. Thanks.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/2] iptables: Merge libip6t_LOG and libipt_LOG into libxt_LOG
  2012-02-25 13:38   ` Pablo Neira Ayuso
@ 2012-02-28 16:06     ` Richard Weinberger
  2012-02-28 16:15       ` Dave Taht
  0 siblings, 1 reply; 16+ messages in thread
From: Richard Weinberger @ 2012-02-28 16:06 UTC (permalink / raw)
  To: Pablo Neira Ayuso
  Cc: netfilter-devel, netdev, linux-kernel, eric.dumazet, jengelh,
	rostedt, basti

[-- Attachment #1: Type: text/plain, Size: 477 bytes --]

Am 25.02.2012 14:38, schrieb Pablo Neira Ayuso:
> On Fri, Feb 10, 2012 at 11:10:51PM +0100, Richard Weinberger wrote:
>> libip6t_LOG and libipt_LOG share a lot of common code, merge them
>> to recude duplicate code.
> 
> I have applied this to the net-next branch of iptables.
> 
> See git.netfilter.org
> 
> I'll merge it to master once linux kernel 3.3 is released.

Okay. What about the ring buffer feature?
Is there anything missing?

Thanks,
//richard



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 490 bytes --]

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/2] iptables: Merge libip6t_LOG and libipt_LOG into libxt_LOG
  2012-02-28 16:06     ` Richard Weinberger
@ 2012-02-28 16:15       ` Dave Taht
  2012-02-28 22:54         ` Pablo Neira Ayuso
  0 siblings, 1 reply; 16+ messages in thread
From: Dave Taht @ 2012-02-28 16:15 UTC (permalink / raw)
  To: Richard Weinberger
  Cc: Pablo Neira Ayuso, netfilter-devel, netdev, linux-kernel,
	eric.dumazet, jengelh, rostedt, basti

On Tue, Feb 28, 2012 at 5:06 PM, Richard Weinberger <richard@nod.at> wrote:
> Am 25.02.2012 14:38, schrieb Pablo Neira Ayuso:
>> On Fri, Feb 10, 2012 at 11:10:51PM +0100, Richard Weinberger wrote:
>>> libip6t_LOG and libipt_LOG share a lot of common code, merge them
>>> to recude duplicate code.
>>
>> I have applied this to the net-next branch of iptables.
>>
>> See git.netfilter.org
>>
>> I'll merge it to master once linux kernel 3.3 is released.
>
> Okay. What about the ring buffer feature?
> Is there anything missing?

I'm under the impression that the ecn related changes didn't make it
as yet. I'm in a position to test that stuff this month, if it needs
further testing and hasn't actually made it in.

> Thanks,
> //richard
>
>



-- 
Dave Täht
SKYPE: davetaht
US Tel: 1-239-829-5608
http://www.bufferbloat.net

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/2] iptables: Merge libip6t_LOG and libipt_LOG into libxt_LOG
  2012-02-28 16:15       ` Dave Taht
@ 2012-02-28 22:54         ` Pablo Neira Ayuso
  0 siblings, 0 replies; 16+ messages in thread
From: Pablo Neira Ayuso @ 2012-02-28 22:54 UTC (permalink / raw)
  To: Dave Taht
  Cc: Richard Weinberger, netfilter-devel, netdev, linux-kernel,
	eric.dumazet, jengelh, rostedt, basti

On Tue, Feb 28, 2012 at 05:15:59PM +0100, Dave Taht wrote:
> On Tue, Feb 28, 2012 at 5:06 PM, Richard Weinberger <richard@nod.at> wrote:
> > Am 25.02.2012 14:38, schrieb Pablo Neira Ayuso:
> >> On Fri, Feb 10, 2012 at 11:10:51PM +0100, Richard Weinberger wrote:
> >>> libip6t_LOG and libipt_LOG share a lot of common code, merge them
> >>> to recude duplicate code.
> >>
> >> I have applied this to the net-next branch of iptables.
> >>
> >> See git.netfilter.org
> >>
> >> I'll merge it to master once linux kernel 3.3 is released.
> >
> > Okay. What about the ring buffer feature?
> > Is there anything missing?
> 
> I'm under the impression that the ecn related changes didn't make it
> as yet. I'm in a position to test that stuff this month, if it needs
> further testing and hasn't actually made it in.

You mean this?

commit af0d29cd2a732f70882e6122b9f9df8b0d84515e
Author: Patrick McHardy <kaber@trash.net>
Date:   Thu Jun 9 15:20:27 2011 +0200

    netfilter: xtables: add an IPv6 capable version of the ECN match

It's already 3.3-rc.

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2012-02-28 22:55 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-02-10 22:10 [PATCH v5] Merge ipt_LOG and ip6t_LOG, add ring bufffer support Richard Weinberger
2012-02-10 22:10 ` [PATCH 1/2] iptables: Merge libip6t_LOG and libipt_LOG into libxt_LOG Richard Weinberger
2012-02-25 13:38   ` Pablo Neira Ayuso
2012-02-28 16:06     ` Richard Weinberger
2012-02-28 16:15       ` Dave Taht
2012-02-28 22:54         ` Pablo Neira Ayuso
2012-02-10 22:10 ` [PATCH 1/4] Netfilter: Merge ipt_LOG and ip6_LOG into xt_LOG Richard Weinberger
2012-02-13 23:56   ` Pablo Neira Ayuso
2012-02-10 22:10 ` [PATCH 2/2] iptables: xt_LOG: Add ring buffer support Richard Weinberger
2012-02-10 22:10 ` [PATCH 2/4] ring_buffer: Export for_each_buffer_cpu() Richard Weinberger
2012-02-14  0:05   ` Pablo Neira Ayuso
2012-02-10 22:10 ` [PATCH 3/4] xt_log: Make printk() in sb_close() optional Richard Weinberger
2012-02-14  0:12   ` Pablo Neira Ayuso
2012-02-10 22:10 ` [PATCH 4/4] Netfilter: xt_LOG: Implement ring buffer support Richard Weinberger
2012-02-14  0:11   ` Pablo Neira Ayuso
2012-02-14  0:12     ` Richard Weinberger

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).