[iptables] extensions: add CT extension

Patrick McHardy netfilter-cvslog-bounces at lists.netfilter.org
Mon Mar 8 13:57:56 CET 2010


Gitweb:		http://git.netfilter.org/cgi-bin/gitweb.cgi?p=iptables.git;a=commit;h=9fdbaa71452edaac9d5906716c15937f670341fa
commit 9fdbaa71452edaac9d5906716c15937f670341fa
Author:     Patrick McHardy <kaber at trash.net>
AuthorDate: Mon Mar 8 13:57:24 2010 +0100
Commit:     Patrick McHardy <kaber at trash.net>
CommitDate: Mon Mar 8 13:57:24 2010 +0100

    extensions: add CT extension
    
    Signed-off-by: Patrick McHardy <kaber at trash.net>
       via  9fdbaa71452edaac9d5906716c15937f670341fa (commit)
      from  cf7e42ffbb624c27591f6d55606bdccd358c7785 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 9fdbaa71452edaac9d5906716c15937f670341fa
Author: Patrick McHardy <kaber at trash.net>
Date:   Mon Mar 8 13:57:24 2010 +0100

    extensions: add CT extension
    
    Signed-off-by: Patrick McHardy <kaber at trash.net>

-----------------------------------------------------------------------

 extensions/libxt_CT.c                         |  188 +++++++++++++++++++++++++
 include/linux/netfilter/nf_conntrack_common.h |   21 +++
 include/linux/netfilter/xt_CT.h               |   17 +++
 3 files changed, 226 insertions(+), 0 deletions(-)
 create mode 100644 extensions/libxt_CT.c
 create mode 100644 include/linux/netfilter/xt_CT.h
Signed-off-by: Patrick McHardy <kaber at trash.net>

diff --git a/extensions/libxt_CT.c b/extensions/libxt_CT.c
new file mode 100644
index 0000000..79fa8d0
--- /dev/null
+++ b/extensions/libxt_CT.c
@@ -0,0 +1,188 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <getopt.h>
+#include <xtables.h>
+#include <linux/netfilter/nf_conntrack_common.h>
+#include <linux/netfilter/xt_CT.h>
+
+static void ct_help(void)
+{
+	printf(
+"CT target options:\n"
+" --notrack			Don't track connection\n"
+" --helper name			Use conntrack helper 'name' for connection\n"
+" --ctevents event[,event...]	Generate specified conntrack vents for connection\n"
+" --expevents event[,event...]	Generate specified expectation events for connection\n"
+" --zone ID			Assign/Lookup connection in zone ID\n"
+	);
+}
+
+enum ct_options {
+	CT_OPT_NOTRACK		= 0x1,
+	CT_OPT_HELPER		= 0x2,
+	CT_OPT_CTEVENTS		= 0x4,
+	CT_OPT_EXPEVENTS	= 0x8,
+	CT_OPT_ZONE		= 0x10,
+};
+
+static const struct option ct_opts[] = {
+	{ "notrack",	0, NULL, CT_OPT_NOTRACK },
+	{ "helper",	1, NULL, CT_OPT_HELPER },
+	{ "ctevents",	1, NULL, CT_OPT_CTEVENTS },
+	{ "expevents",	1, NULL, CT_OPT_EXPEVENTS },
+	{ "zone",	1, NULL, CT_OPT_ZONE },
+	{ .name	= NULL },
+};
+
+struct event_tbl {
+	const char	*name;
+	unsigned int	event;
+};
+
+static const struct event_tbl ct_event_tbl[] = {
+	{ "new",		IPCT_NEW },
+	{ "related",		IPCT_RELATED },
+	{ "destroy",		IPCT_DESTROY },
+	{ "reply",		IPCT_REPLY },
+	{ "assured",		IPCT_ASSURED },
+	{ "protoinfo",		IPCT_PROTOINFO },
+	{ "helper",		IPCT_HELPER },
+	{ "mark",		IPCT_MARK },
+	{ "natseqinfo",		IPCT_NATSEQADJ },
+	{ "secmark",		IPCT_SECMARK },
+};
+
+static const struct event_tbl exp_event_tbl[] = {
+	{ "new",		IPEXP_NEW },
+};
+
+static uint32_t ct_parse_events(const struct event_tbl *tbl, unsigned int size,
+				const char *events)
+{
+	char str[strlen(events) + 1], *e = str, *t;
+	unsigned int mask = 0, i;
+
+	strcpy(str, events);
+	while ((t = strsep(&e, ","))) {
+		for (i = 0; i < size; i++) {
+			if (strcmp(t, tbl->name))
+				continue;
+			mask |= 1 << tbl->event;
+			break;
+		}
+
+		if (i == size)
+			xtables_error(PARAMETER_PROBLEM, "Unknown event type \"%s\"", t);
+	}
+
+	return mask;
+}
+
+static void ct_print_events(const char *pfx, const struct event_tbl *tbl,
+			    unsigned int size, uint32_t mask)
+{
+	const char *sep = "";
+	unsigned int i;
+
+	printf("%s ", pfx);
+	for (i = 0; i < size; i++) {
+		if (mask & (1 << tbl[i].event)) {
+			printf("%s%s", sep, tbl[i].name);
+			sep = ",";
+		}
+	}
+	printf(" ");
+}
+
+static int ct_parse(int c, char **argv, int invert, unsigned int *flags,
+		    const void *entry, struct xt_entry_target **target)
+{
+	struct xt_ct_target_info *info = (struct xt_ct_target_info *)(*target)->data;
+	unsigned int zone;
+
+	switch (c) {
+	case CT_OPT_NOTRACK:
+		xtables_param_act(XTF_ONLY_ONCE, "CT", "--notrack", *flags & CT_OPT_NOTRACK);
+		info->flags |= XT_CT_NOTRACK;
+		break;
+	case CT_OPT_HELPER:
+		xtables_param_act(XTF_ONLY_ONCE, "CT", "--helper", *flags & CT_OPT_HELPER);
+		strncpy(info->helper, optarg, sizeof(info->helper));
+		info->helper[sizeof(info->helper) - 1] = '\0';
+		break;
+	case CT_OPT_CTEVENTS:
+		xtables_param_act(XTF_ONLY_ONCE, "CT", "--ctevents", *flags & CT_OPT_CTEVENTS);
+		info->ct_events = ct_parse_events(ct_event_tbl, ARRAY_SIZE(ct_event_tbl), optarg);
+		break;
+	case CT_OPT_EXPEVENTS:
+		xtables_param_act(XTF_ONLY_ONCE, "CT", "--expevents", *flags & CT_OPT_EXPEVENTS);
+		info->exp_events = ct_parse_events(exp_event_tbl, ARRAY_SIZE(exp_event_tbl), optarg);
+		break;
+	case CT_OPT_ZONE:
+		xtables_param_act(XTF_ONLY_ONCE, "CT", "--zone", *flags & CT_OPT_ZONE);
+		if (!xtables_strtoui(optarg, NULL, &zone, 0, UINT16_MAX))
+			xtables_error(PARAMETER_PROBLEM, "Bad zone value \"%s\"", optarg);
+		info->zone = zone;
+		break;
+	default:
+		return 0;
+	}
+
+	*flags |= c;
+	return 1;
+}
+
+static void ct_print(const void *ip, const struct xt_entry_target *target, int numeric)
+{
+	const struct xt_ct_target_info *info =
+		(const struct xt_ct_target_info *)target->data;
+
+	printf("CT ");
+	if (info->flags & XT_CT_NOTRACK)
+		printf("notrack ");
+	if (info->helper[0])
+		printf("helper %s ", info->helper);
+	if (info->ct_events)
+		ct_print_events("ctevents", ct_event_tbl,
+				ARRAY_SIZE(ct_event_tbl), info->ct_events);
+	if (info->exp_events)
+		ct_print_events("expevents", exp_event_tbl,
+				ARRAY_SIZE(exp_event_tbl), info->exp_events);
+}
+
+static void ct_save(const void *ip, const struct xt_entry_target *target)
+{
+	const struct xt_ct_target_info *info =
+		(const struct xt_ct_target_info *)target->data;
+
+	if (info->flags & XT_CT_NOTRACK)
+		printf("--notrack ");
+	if (info->helper[0])
+		printf("--helper %s ", info->helper);
+	if (info->ct_events)
+		ct_print_events("--ctevents", ct_event_tbl,
+				ARRAY_SIZE(ct_event_tbl), info->ct_events);
+	if (info->exp_events)
+		ct_print_events("--expevents", exp_event_tbl,
+				ARRAY_SIZE(exp_event_tbl), info->exp_events);
+}
+
+static struct xtables_target ct_target = {
+	.family		= NFPROTO_UNSPEC,
+	.name		= "CT",
+	.version	= XTABLES_VERSION,
+	.size		= XT_ALIGN(sizeof(struct xt_ct_target_info)),
+	.userspacesize	= offsetof(struct xt_ct_target_info, ct),
+	.help		= ct_help,
+	.parse		= ct_parse,
+	.print		= ct_print,
+	.save		= ct_save,
+	.extra_opts	= ct_opts,
+};
+
+void _init(void)
+{
+	xtables_register_target(&ct_target);
+}
diff --git a/include/linux/netfilter/nf_conntrack_common.h b/include/linux/netfilter/nf_conntrack_common.h
index 978cecd..34a7fc6 100644
--- a/include/linux/netfilter/nf_conntrack_common.h
+++ b/include/linux/netfilter/nf_conntrack_common.h
@@ -72,7 +72,28 @@ enum ip_conntrack_status {
 	/* Connection has fixed timeout. */
 	IPS_FIXED_TIMEOUT_BIT = 10,
 	IPS_FIXED_TIMEOUT = (1 << IPS_FIXED_TIMEOUT_BIT),
+
+	/* Conntrack is a template */
+	IPS_TEMPLATE_BIT = 11,
+	IPS_TEMPLATE = (1 << IPS_TEMPLATE_BIT),
+};
+
+/* Connection tracking event types */
+enum ip_conntrack_events {
+	IPCT_NEW,		/* new conntrack */
+	IPCT_RELATED,		/* related conntrack */
+	IPCT_DESTROY,		/* destroyed conntrack */
+	IPCT_REPLY,		/* connection has seen two-way traffic */
+	IPCT_ASSURED,		/* connection status has changed to assured */
+	IPCT_PROTOINFO,		/* protocol information has changed */
+	IPCT_HELPER,		/* new helper has been set */
+	IPCT_MARK,		/* new mark has been set */
+	IPCT_NATSEQADJ,		/* NAT is doing sequence adjustment */
+	IPCT_SECMARK,		/* new security mark has been set */
 };
 
+enum ip_conntrack_expect_events {
+	IPEXP_NEW,		/* new expectation */
+};
 
 #endif /* _NF_CONNTRACK_COMMON_H */
diff --git a/include/linux/netfilter/xt_CT.h b/include/linux/netfilter/xt_CT.h
new file mode 100644
index 0000000..1b56410
--- /dev/null
+++ b/include/linux/netfilter/xt_CT.h
@@ -0,0 +1,17 @@
+#ifndef _XT_CT_H
+#define _XT_CT_H
+
+#define XT_CT_NOTRACK	0x1
+
+struct xt_ct_target_info {
+	u_int16_t	flags;
+	u_int16_t	zone;
+	u_int32_t	ct_events;
+	u_int32_t	exp_events;
+	char		helper[16];
+
+	/* Used internally by the kernel */
+	struct nf_conn	*ct __attribute__((aligned(8)));
+};
+
+#endif /* _XT_CT_H */



More information about the netfilter-cvslog mailing list