Hello,

Now it's the turn to the mark match
to be able to match nfmarks bitwise,
as indicated by the TODO. You will
find attached the patch to the
current CVS tree. Hope that helps.

Have a nice day,

Fabrice.
--
Fabrice MARIE
Senior R&D Engineer
Celestix Networks
http://www.celestix.com/

"Silly hacker, root is for administrators" 
       -Unknown
diff -uNr cvs/netfilter/TODO netfilter/TODO
--- cvs/netfilter/TODO	Mon Mar 25 21:54:17 2002
+++ netfilter/TODO	Tue Mar 26 05:37:54 2002
@@ -39,7 +39,7 @@
 - sysctl support for ftp-multi, irc-conntrack/nat, ftp-fxp
 - integrate HOPLIMIT for ipv6 in patch-o-matic [HW]
 - u32 classifier (port from tc -> iptables) [YU]
-- MARK match with boolean OR / AND (to use nfmark bitwise)
+x MARK match with boolean OR / AND (to use nfmark bitwise)
 - documentation for libiptc
 - port conntrack to IPv6 (code reuse?) [BC]
 x make patch-o-matic reversible
diff -uNr cvs/netfilter/userspace/patch-o-matic/extra/mark-bitwise-ops.patch netfilter/userspace/patch-o-matic/extra/mark-bitwise-ops.patch
--- cvs/netfilter/userspace/patch-o-matic/extra/mark-bitwise-ops.patch	Thu Jan  1 07:30:00 1970
+++ netfilter/userspace/patch-o-matic/extra/mark-bitwise-ops.patch	Tue Mar 26 05:32:46 2002
@@ -0,0 +1,39 @@
+--- include/linux/netfilter_ipv4/ipt_mark.h.old	Mon Mar 25 16:20:48 2002
++++ include/linux/netfilter_ipv4/ipt_mark.h	Fri Mar 22 14:03:48 2002
+@@ -1,9 +1,16 @@
+ #ifndef _IPT_MARK_H
+ #define _IPT_MARK_H
+ 
++enum {
++        IPT_MARK_BIT_OP_NONE,
++        IPT_MARK_BIT_OP_AND,
++        IPT_MARK_BIT_OP_OR
++};
++
+ struct ipt_mark_info {
+     unsigned long mark, mask;
+     u_int8_t invert;
++    u_int8_t bit_op;
+ };
+ 
+ #endif /*_IPT_MARK_H*/
+--- net/ipv4/netfilter/ipt_mark.c.old	Mon Mar 25 16:20:48 2002
++++ net/ipv4/netfilter/ipt_mark.c	Mon Mar 25 15:32:27 2002
+@@ -15,9 +15,15 @@
+       u_int16_t datalen,
+       int *hotdrop)
+ {
+-	const struct ipt_mark_info *info = matchinfo;
++	const struct ipt_mark_info *info = (struct ipt_mark_info *)matchinfo;
+ 
+-	return ((skb->nfmark & info->mask) == info->mark) ^ info->invert;
++	if (info->bit_op == IPT_MARK_BIT_OP_NONE)
++		return (skb->nfmark == info->mark) ^ info->invert;
++	else
++		if (info->bit_op == IPT_MARK_BIT_OP_AND)
++			return ((skb->nfmark & info->mask) == info->mark) ^ info->invert;
++		else
++			return ((skb->nfmark | info->mask) == info->mark) ^ info->invert;
+ }
+ 
+ static int
diff -uNr cvs/netfilter/userspace/patch-o-matic/extra/mark-bitwise-ops.patch.help netfilter/userspace/patch-o-matic/extra/mark-bitwise-ops.patch.help
--- cvs/netfilter/userspace/patch-o-matic/extra/mark-bitwise-ops.patch.help	Thu Jan  1 07:30:00 1970
+++ netfilter/userspace/patch-o-matic/extra/mark-bitwise-ops.patch.help	Tue Mar 26 05:32:46 2002
@@ -0,0 +1,13 @@
+Author: Fabrice MARIE <[EMAIL PROTECTED]>
+Status: Works For Me.
+
+This patch adds support for matching the nfmark bitwise (and & or).
+
+For example, to test if the second bit of nfmark is set :
+# iptables -t mangle -A PREROUTING -p icmp -m mark --markand 0x2/0x2 -j ACCEPT
+
+I'm sure you will find a use for the OR bitwise operation as well :)
+# iptables -t mangle -A PREROUTING -p icmp -m mark --markor 0x7/0x1 -j ACCEPT
+
+***** WARNING ***** This patch also patch the userspace directory which means that
+                    you have to recompile and reinstall the iptables package after that.
diff -uNr cvs/netfilter/userspace/patch-o-matic/extra/mark-bitwise-ops.patch.userspace netfilter/userspace/patch-o-matic/extra/mark-bitwise-ops.patch.userspace
--- cvs/netfilter/userspace/patch-o-matic/extra/mark-bitwise-ops.patch.userspace	Thu Jan  1 07:30:00 1970
+++ netfilter/userspace/patch-o-matic/extra/mark-bitwise-ops.patch.userspace	Tue Mar 26 05:32:46 2002
@@ -0,0 +1,155 @@
+--- extensions/libipt_mark.c.old	Mon Mar 25 16:15:47 2002
++++ extensions/libipt_mark.c	Mon Mar 25 16:06:36 2002
+@@ -14,13 +14,17 @@
+ {
+ 	printf(
+ "MARK match v%s options:\n"
+-"[!] --mark value[/mask]         Match nfmark value with optional mask\n"
++"[!] --mark    value           Match nfmark value\n"
++"[!] --markor  value/mask      Match nfmark value, the packets nfmark is ORed with mask before matching.\n"
++"[!] --markand value/mask      Match nfmark value, the packets nfmark is ORed with mask before matching.\n"
+ "\n",
+ NETFILTER_VERSION);
+ }
+ 
+ static struct option opts[] = {
+ 	{ "mark", 1, 0, '1' },
++	{ "markor", 1, 0, '2' },
++	{ "markand", 1, 0, '3' },
+ 	{0}
+ };
+ 
+@@ -41,48 +45,60 @@
+       struct ipt_entry_match **match)
+ {
+ 	struct ipt_mark_info *markinfo = (struct ipt_mark_info *)(*match)->data;
++	char *end;
+ 
+-	switch (c) {
+-		char *end;
+-	case '1':
+-		check_inverse(optarg, &invert, &optind, 0);
++	if ((c=='1') || (c=='2') || (c=='3')) // we ate an option ?
++        {
++                if (*flags)
++                        exit_error(PARAMETER_PROBLEM, "mark match: can specify only one action");
+ 		markinfo->mark = strtoul(optarg, &end, 0);
+-		if (*end == '/') {
+-			markinfo->mask = strtoul(end+1, &end, 0);
+-		} else
+-			markinfo->mask = 0xffffffff;
+-		if (*end != '\0' || end == optarg)
+-			exit_error(PARAMETER_PROBLEM, "Bad MARK value `%s'", optarg);
++		if (((*end != '\0') && (*end != '/')) || (end == optarg))
++			exit_error(PARAMETER_PROBLEM, "Bad mark value `%s'", optarg);
+ 		if (invert)
+ 			markinfo->invert = 1;
+-		*flags = 1;
++                *flags = 1;
++        }
++	else
++		return 0;
++
++	switch (c) {
++
++	case '1':
++		markinfo->bit_op = IPT_MARK_BIT_OP_NONE;
++		markinfo->mask = 0;
+ 		break;
+ 
++	case '2':
++		if (*end != '/')
++			exit_error(PARAMETER_PROBLEM, "mark match: you must specify a mask when using markor\n");
++		markinfo->mask = strtoul(end+1, &end, 0);
++                if (*end != '\0' || end == optarg)
++                        exit_error(PARAMETER_PROBLEM, "Bad mark OR value `%s'", optarg);
++		markinfo->bit_op = IPT_MARK_BIT_OP_OR;
++                break;
++
++	case '3':
++		if (*end != '/')
++			exit_error(PARAMETER_PROBLEM, "mark match: you must specify a mask when using markand\n");
++		markinfo->mask = strtoul(end+1, &end, 0);
++                if (*end != '\0' || end == optarg)
++                        exit_error(PARAMETER_PROBLEM, "Bad mark AND value `%s'", optarg);
++		markinfo->bit_op = IPT_MARK_BIT_OP_AND;
++                break;
++
+ 	default:
+-		return 0;
++		break; /* will never happen, but at least no warning */
+ 	}
+ 	return 1;
+ }
+ 
+-static void
+-print_mark(unsigned long mark, unsigned long mask, int invert, int numeric)
+-{
+-	if (invert)
+-		fputc('!', stdout);
+-
+-	if(mask != 0xffffffff)
+-		printf("0x%lx/0x%lx ", mark, mask);
+-	else
+-		printf("0x%lx ", mark);
+-}
+-
+ /* Final check; must have specified --mark. */
+ static void
+ final_check(unsigned int flags)
+ {
+ 	if (!flags)
+ 		exit_error(PARAMETER_PROBLEM,
+-			   "MARK match: You must specify `--mark'");
++			   "MARK match: you must specify a mark to match");
+ }
+ 
+ /* Prints out the matchinfo. */
+@@ -91,20 +107,39 @@
+       const struct ipt_entry_match *match,
+       int numeric)
+ {
+-	printf("MARK match ");
+-	print_mark(((struct ipt_mark_info *)match->data)->mark,
+-		  ((struct ipt_mark_info *)match->data)->mask,
+-		  ((struct ipt_mark_info *)match->data)->invert, numeric);
++	struct ipt_mark_info *info = (struct ipt_mark_info *)match->data;
++
++	printf("MARK ");
++	if (info->bit_op == IPT_MARK_BIT_OP_AND)
++		printf("& 0x%lx ", info->mask);
++	else
++		if (info->bit_op == IPT_MARK_BIT_OP_OR)
++			printf("| 0x%lx ", info->mask);
++	if (info->invert)
++		printf("! ");
++	printf("match 0x%lx ", info->mark);
+ }
+ 
+ /* Saves the union ipt_matchinfo in parsable form to stdout. */
+ static void
+ save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
+ {
+-	printf("--mark ");
+-	print_mark(((struct ipt_mark_info *)match->data)->mark,
+-		  ((struct ipt_mark_info *)match->data)->mask,
+-		  ((struct ipt_mark_info *)match->data)->invert, 0);
++	struct ipt_mark_info *info = (struct ipt_mark_info *)match->data;
++
++	if (info->invert)
++		printf("! ");
++	switch (info->bit_op)
++	{
++	case IPT_MARK_BIT_OP_AND :
++		printf("--markand 0x%lx/0x%lx ", info->mark, info->mask);
++		break;
++	case IPT_MARK_BIT_OP_OR :
++		printf("--markor 0x%lx/0x%lx ", info->mark, info->mask);
++		break;
++	case IPT_MARK_BIT_OP_NONE :
++		printf("--mark 0x%lx ", info->mark);
++		break;
++	}
+ }
+ 
+ static

Reply via email to