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