[PATCH 1/1] Conntrack-event-generation-control, userspace part

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Patrick and Pablo,

Here follows the userspace part:

The patch adds support to control the conntrack event generation by
adding the required options to the CONNMARK target. With it, one is
able to specify exactly

- for which traffic
- and which events

should be generated by the kernel. For example with the rules

iptables -t mangle -A FORWARD -p tcp -m state NEW \
	-j CONNMARK --events ASSURED,PROTOINFO,HELPER,DESTROY
iptables -t mangle -A FORWARD -p udp -m state RELATED \
	-j CONNMARK --events ASSURED,PROTOINFO,HELPER,DESTROY

we can define that only forwarded TCP traffic and their possible
related (TCP/)UDP connections generate the listed events.

Signed-off-by: Jozsef Kadlecsik <kadlec@xxxxxxxxxxxxxxxxx>
---
 extensions/libxt_CONNMARK.c           |  493 ++++++++++++++++++++++++++++++---
 extensions/libxt_CONNMARK.man         |   11 +
 include/linux/netfilter/xt_CONNMARK.h |  113 ++++++++-
 3 files changed, 584 insertions(+), 33 deletions(-)

diff --git a/extensions/libxt_CONNMARK.c b/extensions/libxt_CONNMARK.c
index 6e42898..bf60658 100644
--- a/extensions/libxt_CONNMARK.c
+++ b/extensions/libxt_CONNMARK.c
@@ -29,8 +29,10 @@
 #include <linux/netfilter/xt_CONNMARK.h>
 
 enum {
-	F_MARK    = 1 << 0,
-	F_SR_MARK = 1 << 1,
+	F_MARK		= 1 << 0,
+	F_SR_MARK	= 1 << 1,
+	F_EVENTS	= 1 << 2,
+	F_EXP_EVENTS	= 1 << 3,
 };
 
 static void CONNMARK_help(void)
@@ -50,7 +52,7 @@ static const struct option CONNMARK_opts[] = {
 	{ .name = NULL }
 };
 
-static const struct option connmark_tg_opts[] = {
+static const struct option connmark_tg1_opts[] = {
 	{.name = "set-xmark",     .has_arg = true,  .val = '='},
 	{.name = "set-mark",      .has_arg = true,  .val = '-'},
 	{.name = "and-mark",      .has_arg = true,  .val = '&'},
@@ -64,7 +66,7 @@ static const struct option connmark_tg_opts[] = {
 	{.name = NULL},
 };
 
-static void connmark_tg_help(void)
+static void connmark_tg1_help(void)
 {
 	printf(
 "CONNMARK target options:\n"
@@ -82,7 +84,7 @@ static void connmark_tg_help(void)
 );
 }
 
-static void connmark_tg_init(struct xt_entry_target *target)
+static void connmark_tg1_init(struct xt_entry_target *target)
 {
 	struct xt_connmark_tginfo1 *info = (void *)target->data;
 
@@ -94,6 +96,78 @@ static void connmark_tg_init(struct xt_entry_target *target)
 	info->nfmask = UINT32_MAX;
 }
 
+static const struct option connmark_tg2_opts[] = {
+	{.name = "set-xmark",     .has_arg = true,  .val = '='},
+	{.name = "set-mark",      .has_arg = true,  .val = '-'},
+	{.name = "and-mark",      .has_arg = true,  .val = '&'},
+	{.name = "or-mark",       .has_arg = true,  .val = '|'},
+	{.name = "xor-mark",      .has_arg = true,  .val = '^'},
+	{.name = "save-mark",     .has_arg = false, .val = 'S'},
+	{.name = "restore-mark",  .has_arg = false, .val = 'R'},
+	{.name = "ctmask",        .has_arg = true,  .val = 'c'},
+	{.name = "nfmask",        .has_arg = true,  .val = 'n'},
+	{.name = "mask",          .has_arg = true,  .val = 'm'},
+	{.name = "events",	  .has_arg = true,  .val = 'e'},
+	{.name = "exp-events",	  .has_arg = true,  .val = 'x'},
+	{.name = NULL},
+};
+
+static void connmark_tg2_help(void)
+{
+	int i;
+
+	printf(
+"CONNMARK target options:\n"
+"  --set-xmark value[/ctmask]    Zero mask bits and XOR ctmark with value\n"
+"  --save-mark [--ctmask mask] [--nfmask mask]\n"
+"                                Copy ctmark to nfmark using masks\n"
+"  --restore-mark [--ctmask mask] [--nfmask mask]\n"
+"                                Copy nfmark to ctmark using masks\n"
+"  --set-mark value[/mask]       Set conntrack mark value\n"
+"  --save-mark [--mask mask]     Save the packet nfmark in the connection\n"
+"  --restore-mark [--mask mask]  Restore saved nfmark value\n"
+"  --and-mark value              Binary AND the ctmark with bits\n"
+"  --or-mark value               Binary OR  the ctmark with bits\n"
+"  --xor-mark value              Binary XOR the ctmark with bits\n"
+"  --events value                Comma separated list of conntrack events\n"	
+"  --exp-events value            Comma separated list of expecation events\n"
+"  Valid events:\n"
+"    NONE,"
+);
+	for (i = IPCT_NEW_BIT; i < IPCT_ALL_BIT; i++) {
+		if (events[i][0])
+			printf("%s,", events[i]);
+		if ((i + 1)%8 == 0)
+			printf("\n    ");
+	}
+	printf(
+"ALL\n"
+"  Valid expectation events:\n"
+"    NONE,"
+);
+	 for (i = IPEXP_NEW_BIT; i < IPEXP_ALL_BIT; i++) {
+		if (events[i][0])
+			printf("%s,", events[i]);
+		if ((i - IPEXP_NEW_BIT + 1)%8 == 0)
+			printf("\n    ");
+	}
+	printf("ALL\n");
+}
+
+static void connmark_tg2_init(struct xt_entry_target *target)
+{
+	struct xt_connmark_tginfo2 *info = (void *)target->data;
+
+	/*
+	 * Need these defaults for --save-mark/--restore-mark if no
+	 * --ctmark or --nfmask is given.
+	 */
+	info->ctmask = UINT32_MAX;
+	info->nfmask = UINT32_MAX;
+	/* Make possible to set events alone */
+	info->mode = XT_CONNMARK_EVENT_ONLY;
+}
+
 static int
 CONNMARK_parse(int c, char **argv, int invert, unsigned int *flags,
                const void *entry, struct xt_entry_target **target)
@@ -147,9 +221,9 @@ CONNMARK_parse(int c, char **argv, int invert, unsigned int *flags,
 	return 1;
 }
 
-static int connmark_tg_parse(int c, char **argv, int invert,
-                             unsigned int *flags, const void *entry,
-                             struct xt_entry_target **target)
+static int connmark_tg1_parse(int c, char **argv, int invert,
+                              unsigned int *flags, const void *entry,
+                              struct xt_entry_target **target)
 {
 	struct xt_connmark_tginfo1 *info = (void *)(*target)->data;
 	unsigned int value, mask = UINT32_MAX;
@@ -250,7 +324,194 @@ static int connmark_tg_parse(int c, char **argv, int invert,
 	return false;
 }
 
-static void connmark_tg_check(unsigned int flags)
+static void connmark_tg1_check(unsigned int flags)
+{
+	if (!flags)
+		xtables_error(PARAMETER_PROBLEM,
+		           "CONNMARK target: No operation specified");
+}
+
+#define STREQ(a, b)	(strncasecmp(a,b,strlen(b)) == 0)
+
+static void parse_events(uint16_t *eventmask)
+{
+	size_t offset = 0;
+	int i, m;
+	
+	if (STREQ(optarg, "NONE")) {
+		*eventmask &= ~IPCT_ALL;
+		return;
+	} else if (STREQ(optarg, "ALL")) {
+		*eventmask |= IPCT_ALL;
+		return;
+	}
+	
+	while (offset < strlen(optarg)) {
+		for (i = IPCT_NEW_BIT, m = 0; i < IPCT_ALL_BIT; i++) {
+			if (events[i][0]
+			    && STREQ(optarg + offset, events[i])) {
+				*eventmask |= (1 << i);
+				offset += strlen(events[i]);
+				offset += !!(optarg[offset] == ',');
+				m++;
+			}
+		}
+		if (m == 0)
+			xtables_error(PARAMETER_PROBLEM,
+			           "CONNMARK target: Cannot parse events '%s'",
+			           optarg + offset);
+	}
+} 
+
+static void parse_exp_events(u_int16_t *eventmask)
+{
+	size_t offset = 0;
+	int i, m;
+	
+	if (STREQ(optarg, "NONE")) {
+		*eventmask &= ~IPEXP_ALL;
+		return;
+	} else if (STREQ(optarg, "ALL")) {
+		*eventmask |= IPEXP_ALL;
+		return;
+	}
+	
+	while (offset < strlen(optarg)) {
+		for (i = IPEXP_NEW_BIT, m = 0; i < IPEXP_ALL_BIT; i++) {
+			if (events[i][0]
+			    && STREQ(optarg + offset, events[i])) {
+				*eventmask |= (1 << i);
+				offset += strlen(events[i]);
+				offset += !!(optarg[offset] == ',');
+				m++;
+			}
+		}
+		if (m == 0)
+			xtables_error(PARAMETER_PROBLEM,
+			           "CONNMARK target: Cannot parse expectation events '%s'",
+			           optarg + offset);
+	}
+} 
+
+static int connmark_tg2_parse(int c, char **argv, int invert,
+                              unsigned int *flags, const void *entry,
+                              struct xt_entry_target **target)
+{
+	struct xt_connmark_tginfo2 *info = (void *)(*target)->data;
+	unsigned int value, mask = UINT32_MAX;
+	char *end;
+
+	switch (c) {
+	case '=': /* --set-xmark */
+	case '-': /* --set-mark */
+		xtables_param_act(XTF_ONE_ACTION, "CONNMARK", *flags & F_MARK);
+		if (!xtables_strtoui(optarg, &end, &value, 0, UINT32_MAX))
+			xtables_param_act(XTF_BAD_VALUE, "CONNMARK", "--set-xmark/--set-mark", optarg);
+		if (*end == '/')
+			if (!xtables_strtoui(end + 1, &end, &mask, 0, UINT32_MAX))
+				xtables_param_act(XTF_BAD_VALUE, "CONNMARK", "--set-xmark/--set-mark", optarg);
+		if (*end != '\0')
+			xtables_param_act(XTF_BAD_VALUE, "CONNMARK", "--set-xmark/--set-mark", optarg);
+		info->mode   = XT_CONNMARK_SET;
+		info->ctmark = value;
+		info->ctmask = mask;
+		if (c == '-')
+			info->ctmask |= value;
+		*flags |= F_MARK;
+		return true;
+
+	case '&': /* --and-mark */
+		xtables_param_act(XTF_ONE_ACTION, "CONNMARK", *flags & F_MARK);
+		if (!xtables_strtoui(optarg, NULL, &mask, 0, UINT32_MAX))
+			xtables_param_act(XTF_BAD_VALUE, "CONNMARK", "--and-mark", optarg);
+		info->mode   = XT_CONNMARK_SET;
+		info->ctmark = 0;
+		info->ctmask = ~mask;
+		*flags      |= F_MARK;
+		return true;
+
+	case '|': /* --or-mark */
+		xtables_param_act(XTF_ONE_ACTION, "CONNMARK", *flags & F_MARK);
+		if (!xtables_strtoui(optarg, NULL, &value, 0, UINT32_MAX))
+			xtables_param_act(XTF_BAD_VALUE, "CONNMARK", "--or-mark", optarg);
+		info->mode   = XT_CONNMARK_SET;
+		info->ctmark = value;
+		info->ctmask = value;
+		*flags      |= F_MARK;
+		return true;
+
+	case '^': /* --xor-mark */
+		xtables_param_act(XTF_ONE_ACTION, "CONNMARK", *flags & F_MARK);
+		if (!xtables_strtoui(optarg, NULL, &value, 0, UINT32_MAX))
+			xtables_param_act(XTF_BAD_VALUE, "CONNMARK", "--xor-mark", optarg);
+		info->mode   = XT_CONNMARK_SET;
+		info->ctmark = value;
+		info->ctmask = 0;
+		*flags      |= F_MARK;
+		return true;
+
+	case 'S': /* --save-mark */
+		xtables_param_act(XTF_ONE_ACTION, "CONNMARK", *flags & F_MARK);
+		info->mode = XT_CONNMARK_SAVE;
+		*flags |= F_MARK | F_SR_MARK;
+		return true;
+
+	case 'R': /* --restore-mark */
+		xtables_param_act(XTF_ONE_ACTION, "CONNMARK", *flags & F_MARK);
+		info->mode = XT_CONNMARK_RESTORE;
+		*flags |= F_MARK | F_SR_MARK;
+		return true;
+
+	case 'n': /* --nfmask */
+		if (!(*flags & F_SR_MARK))
+			xtables_error(PARAMETER_PROBLEM, "CONNMARK: --save-mark "
+			           "or --restore-mark is required for "
+			           "--nfmask");
+		if (!xtables_strtoui(optarg, NULL, &value, 0, UINT32_MAX))
+			xtables_param_act(XTF_BAD_VALUE, "CONNMARK", "--nfmask", optarg);
+		info->nfmask = value;
+		return true;
+
+	case 'c': /* --ctmask */
+		if (!(*flags & F_SR_MARK))
+			xtables_error(PARAMETER_PROBLEM, "CONNMARK: --save-mark "
+			           "or --restore-mark is required for "
+			           "--ctmask");
+		if (!xtables_strtoui(optarg, NULL, &value, 0, UINT32_MAX))
+			xtables_param_act(XTF_BAD_VALUE, "CONNMARK", "--ctmask", optarg);
+		info->ctmask = value;
+		return true;
+
+	case 'm': /* --mask */
+		if (!(*flags & F_SR_MARK))
+			xtables_error(PARAMETER_PROBLEM, "CONNMARK: --save-mark "
+			           "or --restore-mark is required for "
+			           "--mask");
+		if (!xtables_strtoui(optarg, NULL, &value, 0, UINT32_MAX))
+			xtables_param_act(XTF_BAD_VALUE, "CONNMARK", "--mask", optarg);
+		info->nfmask = info->ctmask = value;
+		return true;
+
+	case 'e': /* --events */
+		xtables_param_act(XTF_ONE_ACTION, "CONNMARK",
+				  *flags & F_EVENTS);
+		parse_events(&info->eventmask);
+		info->events = 1;
+		*flags |= F_EVENTS;
+		return true;
+
+	case 'x': /* --exp-events */
+		xtables_param_act(XTF_ONE_ACTION, "CONNMARK",
+				  *flags & F_EXP_EVENTS);
+		parse_exp_events(&info->eventmask);
+		info->events = 1;
+		*flags |= F_EXP_EVENTS;
+		return true;
+	}
+	return false;
+}
+
+static void connmark_tg2_check(unsigned int flags)
 {
 	if (!flags)
 		xtables_error(PARAMETER_PROBLEM,
@@ -298,8 +559,8 @@ static void CONNMARK_print(const void *ip,
 }
 
 static void
-connmark_tg_print(const void *ip, const struct xt_entry_target *target,
-                  int numeric)
+connmark_tg1_print(const void *ip, const struct xt_entry_target *target,
+                   int numeric)
 {
 	const struct xt_connmark_tginfo1 *info = (const void *)target->data;
 
@@ -341,6 +602,84 @@ connmark_tg_print(const void *ip, const struct xt_entry_target *target,
 	}
 }
 
+static void
+connmark_tg2_print(const void *ip, const struct xt_entry_target *target,
+                   int numeric)
+{
+	const struct xt_connmark_tginfo2 *info = (const void *)target->data;
+
+	switch (info->mode) {
+	case XT_CONNMARK_SET:
+		if (info->ctmark == 0)
+			printf("CONNMARK and 0x%x ",
+			       (unsigned int)(u_int32_t)~info->ctmask);
+		else if (info->ctmark == info->ctmask)
+			printf("CONNMARK or 0x%x ", info->ctmark);
+		else if (info->ctmask == 0)
+			printf("CONNMARK xor 0x%x ", info->ctmark);
+		else
+			printf("CONNMARK xset 0x%x/0x%x ",
+			       info->ctmark, info->ctmask);
+		break;
+	case XT_CONNMARK_SAVE:
+		if (info->nfmask == UINT32_MAX && info->ctmask == UINT32_MAX)
+			printf("CONNMARK save ");
+		else if (info->nfmask == info->ctmask)
+			printf("CONNMARK save mask 0x%x ", info->nfmask);
+		else
+			printf("CONNMARK save nfmask 0x%x ctmask ~0x%x ",
+			       info->nfmask, info->ctmask);
+		break;
+	case XT_CONNMARK_RESTORE:
+		if (info->ctmask == UINT32_MAX && info->nfmask == UINT32_MAX)
+			printf("CONNMARK restore ");
+		else if (info->ctmask == info->nfmask)
+			printf("CONNMARK restore mask 0x%x ", info->ctmask);
+		else
+			printf("CONNMARK restore ctmask 0x%x nfmask ~0x%x ",
+			       info->ctmask, info->nfmask);
+		break;
+	case XT_CONNMARK_EVENT_ONLY:
+		printf("CONNMARK ");
+		break;
+	default:
+		printf("ERROR: UNKNOWN CONNMARK MODE");
+		break;
+	}
+	if (info->events) {
+		int i, comma;
+		if ((info->eventmask & IPCT_ALL) == IPCT_ALL)
+			printf("events ALL ");
+		else if ((info->eventmask & ~IPEXP_ALL) & IPCT_ALL) {
+			printf("events ");
+			for (i = IPCT_NEW_BIT, comma = 0; i < IPCT_ALL_BIT; i++)
+				if ((info->eventmask & (1 << i)) && events[i][0]) {
+					if (comma)
+						printf(",");
+					printf("%s", events[i]);
+					comma = 1;
+				}
+			printf(" ");
+		} else
+			printf("events NONE ");
+		
+		if ((info->eventmask & IPEXP_ALL) == IPEXP_ALL)
+			printf("exp-events ALL ");
+		else if ((info->eventmask & ~IPCT_ALL) & IPEXP_ALL) {
+			printf("exp-events ");
+			for (i = IPEXP_NEW_BIT, comma = 0; i < IPEXP_ALL_BIT; i++)
+				if ((info->eventmask & (1 << i)) && events[i][0]) {
+					if (comma)
+						printf(",");
+					printf("%s", events[i]);
+					comma = 1;
+				}
+			printf(" ");
+		} else
+			printf("exp-events NONE ");
+	}
+}
+
 static void CONNMARK_save(const void *ip, const struct xt_entry_target *target)
 {
 	const struct xt_connmark_target_info *markinfo =
@@ -376,7 +715,7 @@ static void CONNMARK_init(struct xt_entry_target *t)
 }
 
 static void
-connmark_tg_save(const void *ip, const struct xt_entry_target *target)
+connmark_tg1_save(const void *ip, const struct xt_entry_target *target)
 {
 	const struct xt_connmark_tginfo1 *info = (const void *)target->data;
 
@@ -398,6 +737,62 @@ connmark_tg_save(const void *ip, const struct xt_entry_target *target)
 	}
 }
 
+static void
+connmark_tg2_save(const void *ip, const struct xt_entry_target *target)
+{
+	const struct xt_connmark_tginfo2 *info = (const void *)target->data;
+
+	switch (info->mode) {
+	case XT_CONNMARK_SET:
+		printf("--set-xmark 0x%x/0x%x ", info->ctmark, info->ctmask);
+		break;
+	case XT_CONNMARK_SAVE:
+		printf("--save-mark --nfmask 0x%x --ctmask 0x%x ",
+		       info->nfmask, info->ctmask);
+		break;
+	case XT_CONNMARK_RESTORE:
+		printf("--restore-mark --nfmask 0x%x --ctmask 0x%x ",
+		       info->nfmask, info->ctmask);
+		break;
+	case XT_CONNMARK_EVENT_ONLY:
+		break;
+	default:
+		printf("ERROR: UNKNOWN CONNMARK MODE");
+		break;
+	}
+	if (info->events) {
+		int i, comma;
+		if ((info->eventmask & IPCT_ALL) == IPCT_ALL)
+			printf("--events ALL ");
+		else if ((info->eventmask & ~IPEXP_ALL) & IPCT_ALL) {
+			printf("--events ");
+			for (i = IPCT_NEW_BIT, comma = 0; i < IPCT_ALL_BIT; i++)
+				if ((info->eventmask & (1 << i)) && events[i][0]) {
+					if (comma)
+						printf(",");
+					printf("%s", events[i]);
+					comma = 1;
+				}
+			printf(" ");
+		} else
+			printf("--events NONE ");
+		if ((info->eventmask & IPEXP_ALL) == IPEXP_ALL)
+			printf("--exp-events ALL ");
+		else if ((info->eventmask & ~IPCT_ALL) & IPEXP_ALL) {
+			printf("--exp-events ");
+			for (i = IPEXP_NEW_BIT, comma = 0; i < IPEXP_ALL_BIT; i++)
+				if ((info->eventmask & (1 << i)) && events[i][0]) {
+					if (comma)
+						printf(",");
+					printf("%s", events[i]);
+					comma = 1;
+				}
+			printf(" ");
+		} else
+			printf("--exp-events NONE ");
+	}
+}
+
 static struct xtables_target connmark_target = {
 	.family		= NFPROTO_IPV4,
 	.name		= "CONNMARK",
@@ -408,7 +803,7 @@ static struct xtables_target connmark_target = {
 	.help		= CONNMARK_help,
 	.init           = CONNMARK_init,
 	.parse		= CONNMARK_parse,
-	.final_check	= connmark_tg_check,
+	.final_check	= connmark_tg1_check,
 	.print		= CONNMARK_print,
 	.save		= CONNMARK_save,
 	.extra_opts	= CONNMARK_opts,
@@ -424,48 +819,82 @@ static struct xtables_target connmark_target6 = {
 	.help		= CONNMARK_help,
 	.init           = CONNMARK_init,
 	.parse		= CONNMARK_parse,
-	.final_check	= connmark_tg_check,
+	.final_check	= connmark_tg1_check,
 	.print		= CONNMARK_print,
 	.save		= CONNMARK_save,
 	.extra_opts	= CONNMARK_opts,
 };
 
-static struct xtables_target connmark_tg_reg = {
+static struct xtables_target connmark_tg1_reg = {
 	.version        = XTABLES_VERSION,
 	.name           = "CONNMARK",
 	.revision       = 1,
 	.family         = NFPROTO_IPV4,
 	.size           = XT_ALIGN(sizeof(struct xt_connmark_tginfo1)),
 	.userspacesize  = XT_ALIGN(sizeof(struct xt_connmark_tginfo1)),
-	.help           = connmark_tg_help,
-	.init           = connmark_tg_init,
-	.parse          = connmark_tg_parse,
-	.final_check    = connmark_tg_check,
-	.print          = connmark_tg_print,
-	.save           = connmark_tg_save,
-	.extra_opts     = connmark_tg_opts,
+	.help           = connmark_tg1_help,
+	.init           = connmark_tg1_init,
+	.parse          = connmark_tg1_parse,
+	.final_check    = connmark_tg1_check,
+	.print          = connmark_tg1_print,
+	.save           = connmark_tg1_save,
+	.extra_opts     = connmark_tg1_opts,
 };
 
-static struct xtables_target connmark_tg6_reg = {
+static struct xtables_target connmark_tg16_reg = {
 	.version        = XTABLES_VERSION,
 	.name           = "CONNMARK",
 	.revision       = 1,
 	.family         = NFPROTO_IPV6,
 	.size           = XT_ALIGN(sizeof(struct xt_connmark_tginfo1)),
 	.userspacesize  = XT_ALIGN(sizeof(struct xt_connmark_tginfo1)),
-	.help           = connmark_tg_help,
-	.init           = connmark_tg_init,
-	.parse          = connmark_tg_parse,
-	.final_check    = connmark_tg_check,
-	.print          = connmark_tg_print,
-	.save           = connmark_tg_save,
-	.extra_opts     = connmark_tg_opts,
+	.help           = connmark_tg1_help,
+	.init           = connmark_tg1_init,
+	.parse          = connmark_tg1_parse,
+	.final_check    = connmark_tg1_check,
+	.print          = connmark_tg1_print,
+	.save           = connmark_tg1_save,
+	.extra_opts     = connmark_tg1_opts,
+};
+
+static struct xtables_target connmark_tg2_reg = {
+	.version        = XTABLES_VERSION,
+	.name           = "CONNMARK",
+	.revision       = 2,
+	.family         = NFPROTO_IPV4,
+	.size           = XT_ALIGN(sizeof(struct xt_connmark_tginfo2)),
+	.userspacesize  = XT_ALIGN(sizeof(struct xt_connmark_tginfo2)),
+	.help           = connmark_tg2_help,
+	.init           = connmark_tg2_init,
+	.parse          = connmark_tg2_parse,
+	.final_check    = connmark_tg2_check,
+	.print          = connmark_tg2_print,
+	.save           = connmark_tg2_save,
+	.extra_opts     = connmark_tg2_opts,
+};
+
+static struct xtables_target connmark_tg26_reg = {
+	.version        = XTABLES_VERSION,
+	.name           = "CONNMARK",
+	.revision       = 2,
+	.family         = NFPROTO_IPV6,
+	.size           = XT_ALIGN(sizeof(struct xt_connmark_tginfo2)),
+	.userspacesize  = XT_ALIGN(sizeof(struct xt_connmark_tginfo2)),
+	.help           = connmark_tg2_help,
+	.init           = connmark_tg2_init,
+	.parse          = connmark_tg2_parse,
+	.final_check    = connmark_tg2_check,
+	.print          = connmark_tg2_print,
+	.save           = connmark_tg2_save,
+	.extra_opts     = connmark_tg2_opts,
 };
 
 void _init(void)
 {
 	xtables_register_target(&connmark_target);
 	xtables_register_target(&connmark_target6);
-	xtables_register_target(&connmark_tg_reg);
-	xtables_register_target(&connmark_tg6_reg);
+	xtables_register_target(&connmark_tg1_reg);
+	xtables_register_target(&connmark_tg16_reg);
+	xtables_register_target(&connmark_tg2_reg);
+	xtables_register_target(&connmark_tg26_reg);
 }
diff --git a/extensions/libxt_CONNMARK.man b/extensions/libxt_CONNMARK.man
index 571ce37..0050003 100644
--- a/extensions/libxt_CONNMARK.man
+++ b/extensions/libxt_CONNMARK.man
@@ -24,6 +24,17 @@ ctmark to XOR into the nfmark. \fIctmask\fR and \fInfmask\fR default to
 0xFFFFFFFF.
 .IP
 \fB\-\-restore\-mark\fP is only valid in the \fBmangle\fP table.
+.TP
+\fB\-\-events\fP \fIevents\fP
+Set for the rule-matching conntrack entry which \fIevents\fR should be handled.
+The argument is a comma-separated list of the possible event identifier strings,
+which can be listed by specifying the \-\-help option.
+.TP
+\fB\-\-exp-events\fP \fIexp-events\fP
+Set for the rule-matching conntrack entry which \fIexpectation events\fR
+should be handled. The argument is a comma-separated list of the possible
+expectation event identifier strings which can be listed by specifying
+the \-\-help option.
 .PP
 The following mnemonics are available for \fB\-\-set\-xmark\fP:
 .TP
diff --git a/include/linux/netfilter/xt_CONNMARK.h b/include/linux/netfilter/xt_CONNMARK.h
index 4e58ba4..bc4526e 100644
--- a/include/linux/netfilter/xt_CONNMARK.h
+++ b/include/linux/netfilter/xt_CONNMARK.h
@@ -13,7 +13,8 @@
 enum {
 	XT_CONNMARK_SET = 0,
 	XT_CONNMARK_SAVE,
-	XT_CONNMARK_RESTORE
+	XT_CONNMARK_RESTORE,
+	XT_CONNMARK_EVENT_ONLY
 };
 
 struct xt_connmark_target_info {
@@ -27,4 +28,114 @@ struct xt_connmark_tginfo1 {
 	u_int8_t mode;
 };
 
+struct xt_connmark_tginfo2 {
+	u_int32_t ctmark, ctmask, nfmask;
+	u_int8_t mode;
+	u_int8_t events;
+	u_int16_t eventmask;
+};
+
+/* Connection tracking event bits */
+enum ip_conntrack_events
+{
+	/* New conntrack */
+	IPCT_NEW_BIT = 0,
+	IPCT_NEW = (1 << IPCT_NEW_BIT),
+
+	/* Expected connection */
+	IPCT_RELATED_BIT = 1,
+	IPCT_RELATED = (1 << IPCT_RELATED_BIT),
+
+	/* Destroyed conntrack */
+	IPCT_DESTROY_BIT = 2,
+	IPCT_DESTROY = (1 << IPCT_DESTROY_BIT),
+
+	/* Timer has been refreshed */
+	IPCT_REFRESH_BIT = 3,
+	IPCT_REFRESH = (1 << IPCT_REFRESH_BIT),
+
+	/* Assured bit is set */
+	IPCT_ASSURED_BIT = 4,
+	IPCT_ASSURED = (1 << IPCT_ASSURED_BIT),
+
+	/* Backward compatibility */
+	IPCT_STATUS = IPCT_ASSURED,
+
+	/* Protocol state info */
+	IPCT_PROTOINFO_BIT = 5,
+	IPCT_PROTOINFO = (1 << IPCT_PROTOINFO_BIT),
+
+	/* ICMP(v6) protocol info */
+	IPCT_ICMP_PROTOINFO_BIT = 6,
+	IPCT_ICMP_PROTOINFO = (1 << IPCT_ICMP_PROTOINFO_BIT),
+
+	/* Backward compatibility */
+	IPCT_PROTOINFO_VOLATILE = IPCT_ICMP_PROTOINFO,
+
+	/* Helper for conntrack added/removed */
+	IPCT_HELPER_BIT = 7,
+	IPCT_HELPER = (1 << IPCT_HELPER_BIT),
+
+	/* Update of helper info */
+	IPCT_HELPINFO_BIT = 8,
+	IPCT_HELPINFO = (1 << IPCT_HELPINFO_BIT),
+
+	/* Seen reply packet */
+	IPCT_SEEN_REPLY_BIT = 9,
+	IPCT_SEEN_REPLY = (1 << IPCT_SEEN_REPLY_BIT),
+
+	/* Mark is set */
+	IPCT_MARK_BIT = 10,
+	IPCT_MARK = (1 << IPCT_MARK_BIT),
+
+	/* NAT sequence adjustment */
+	IPCT_NATSEQADJ_BIT = 11,
+	IPCT_NATSEQADJ = (1 << IPCT_NATSEQADJ_BIT),
+
+	/* Secmark is set */
+	IPCT_SECMARK_BIT = 12,
+	IPCT_SECMARK = (1 << IPCT_SECMARK_BIT),
+	
+	/* All conntrack event bits */
+	IPCT_ALL_BIT = 13,
+	IPCT_ALL = ((1 << IPCT_ALL_BIT) - 1),
+
+	/* New expectation created */
+	IPEXP_NEW_BIT = 13,
+	IPEXP_NEW = (1 << IPEXP_NEW_BIT),
+
+	/* Timer has been refreshed */
+	IPEXP_REFRESH_BIT = 14,
+	IPEXP_REFRESH = (1 << IPEXP_REFRESH_BIT),
+
+	/* Expectation timed out */
+	IPEXP_TIMEOUT_BIT = 15,
+	IPEXP_TIMEOUT = (1 << IPEXP_TIMEOUT_BIT),
+
+	/* All expectation event bits */
+	IPEXP_ALL_BIT = 16,
+	IPEXP_ALL = (((1 << IPEXP_ALL_BIT) - 1) & ~IPCT_ALL)
+};
+
+static const char events[IPEXP_ALL_BIT+1][16] = {
+	[IPCT_NEW_BIT]		= "NEW",
+	[IPCT_RELATED_BIT]	= "RELATED",
+	[IPCT_DESTROY_BIT]	= "DESTROY",
+	[IPCT_REFRESH_BIT]	= "REFRESH",
+	[IPCT_ASSURED_BIT]	= "ASSURED",
+	[IPCT_PROTOINFO_BIT]	= "PROTOINFO",
+	[IPCT_ICMP_PROTOINFO_BIT] = "ICMP_PROTOINFO",
+	[IPCT_HELPER_BIT]	= "HELPER",
+	[IPCT_HELPINFO_BIT]	= "HELPINFO",
+	[IPCT_SEEN_REPLY_BIT]	= "SEEN_REPLY",
+	[IPCT_MARK_BIT]		= "MARK",
+	[IPCT_NATSEQADJ_BIT]	= "NATSEQADJ",
+	[IPCT_SECMARK_BIT]	= "SECMARK",
+	[IPCT_ALL_BIT]		= "ALL",
+	[IPEXP_NEW_BIT]		= "NEW",
+	[IPEXP_REFRESH_BIT]	= "REFRESH",
+	[IPEXP_TIMEOUT_BIT]	= "TIMEOUT",
+	[IPEXP_ALL_BIT]		= "ALL",
+};
+
 #endif /*_XT_CONNMARK_H_target*/
-- 
1.5.4.3


Best regards,
Jozsef
-
E-mail  : kadlec@xxxxxxxxxxxxxxxxx, kadlec@xxxxxxxxxxxx
PGP key : http://www.kfki.hu/~kadlec/pgp_public_key.txt
Address : KFKI Research Institute for Particle and Nuclear Physics
          H-1525 Budapest 114, POB. 49, Hungary
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux