diff -uNr linux-2.6.4-rc1/include/linux.orig/netfilter_ipv4/ip_conntrack.h linux-2.6.4-rc1/include/linux/netfilter_ipv4/ip_conntrack.h --- linux-2.6.4-rc1/include/linux.orig/netfilter_ipv4/ip_conntrack.h 2004-03-03 03:30:33.000000000 +0100 +++ linux-2.6.4-rc1/include/linux/netfilter_ipv4/ip_conntrack.h 2004-03-03 03:58:03.401720416 +0100 @@ -206,6 +206,9 @@ } nat; #endif /* CONFIG_IP_NF_NAT_NEEDED */ +#if defined(CONFIG_IP_NF_CONNTRACK_MARK) + unsigned long mark; +#endif }; /* get master conntrack via master expectation */ diff -uNr linux-2.6.4-rc1/include/linux.orig/netfilter_ipv4/ipt_connmark.h linux-2.6.4-rc1/include/linux/netfilter_ipv4/ipt_connmark.h --- linux-2.6.4-rc1/include/linux.orig/netfilter_ipv4/ipt_connmark.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.4-rc1/include/linux/netfilter_ipv4/ipt_connmark.h 2004-03-03 03:58:03.402720264 +0100 @@ -0,0 +1,9 @@ +#ifndef _IPT_CONNMARK_H +#define _IPT_CONNMARK_H + +struct ipt_connmark_info { + unsigned long mark, mask; + u_int8_t invert; +}; + +#endif /*_IPT_CONNMARK_H*/ diff -uNr linux-2.6.4-rc1/include/linux.orig/netfilter_ipv4/ipt_CONNMARK.h linux-2.6.4-rc1/include/linux/netfilter_ipv4/ipt_CONNMARK.h --- linux-2.6.4-rc1/include/linux.orig/netfilter_ipv4/ipt_CONNMARK.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.4-rc1/include/linux/netfilter_ipv4/ipt_CONNMARK.h 2004-03-03 03:58:03.402720264 +0100 @@ -0,0 +1,15 @@ +#ifndef _IPT_CONNMARK_H_target +#define _IPT_CONNMARK_H_target + +enum { + IPT_CONNMARK_SET = 0, + IPT_CONNMARK_SAVE, + IPT_CONNMARK_RESTORE +}; + +struct ipt_connmark_target_info { + unsigned long mark, mask; + u_int8_t mode; +}; + +#endif /*_IPT_CONNMARK_H_target*/ diff -uNr linux-2.6.4-rc1/net/ipv4.orig/netfilter/ip_conntrack_core.c linux-2.6.4-rc1/net/ipv4/netfilter/ip_conntrack_core.c --- linux-2.6.4-rc1/net/ipv4.orig/netfilter/ip_conntrack_core.c 2004-03-03 03:30:33.000000000 +0100 +++ linux-2.6.4-rc1/net/ipv4/netfilter/ip_conntrack_core.c 2004-03-03 03:58:03.418717832 +0100 @@ -718,6 +718,9 @@ __set_bit(IPS_EXPECTED_BIT, &conntrack->status); conntrack->master = expected; expected->sibling = conntrack; +#if CONFIG_IP_NF_CONNTRACK_MARK + conntrack->mark = expected->expectant->mark; +#endif LIST_DELETE(&ip_conntrack_expect_list, expected); expected->expectant->expecting--; nf_conntrack_get(&master_ct(conntrack)->infos[0]); diff -uNr linux-2.6.4-rc1/net/ipv4.orig/netfilter/ip_conntrack_standalone.c linux-2.6.4-rc1/net/ipv4/netfilter/ip_conntrack_standalone.c --- linux-2.6.4-rc1/net/ipv4.orig/netfilter/ip_conntrack_standalone.c 2004-03-03 03:30:33.000000000 +0100 +++ linux-2.6.4-rc1/net/ipv4/netfilter/ip_conntrack_standalone.c 2004-03-03 03:58:03.420717528 +0100 @@ -110,6 +110,9 @@ len += sprintf(buffer + len, "[ASSURED] "); len += sprintf(buffer + len, "use=%u ", atomic_read(&conntrack->ct_general.use)); +#if defined(CONFIG_IP_NF_CONNTRACK_MARK) + len += sprintf(buffer + len, "mark=%ld ", conntrack->mark); +#endif len += sprintf(buffer + len, "\n"); return len; diff -uNr linux-2.6.4-rc1/net/ipv4.orig/netfilter/ipt_connmark.c linux-2.6.4-rc1/net/ipv4/netfilter/ipt_connmark.c --- linux-2.6.4-rc1/net/ipv4.orig/netfilter/ipt_connmark.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.4-rc1/net/ipv4/netfilter/ipt_connmark.c 2004-03-03 03:58:03.429716160 +0100 @@ -0,0 +1,57 @@ +/* Kernel module to match connection mark values. */ +#include +#include + +#include +#include +#include + +static int +match(const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const void *matchinfo, + int offset, + int *hotdrop) +{ + const struct ipt_connmark_info *info = matchinfo; + enum ip_conntrack_info ctinfo; + struct ip_conntrack *ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo); + if (!ct) + return 0; + + return ((ct->mark & info->mask) == info->mark) ^ info->invert; +} + +static int +checkentry(const char *tablename, + const struct ipt_ip *ip, + void *matchinfo, + unsigned int matchsize, + unsigned int hook_mask) +{ + if (matchsize != IPT_ALIGN(sizeof(struct ipt_connmark_info))) + return 0; + + return 1; +} + +static struct ipt_match connmark_match = { + .name = "connmark", + .match = &match, + .checkentry = &checkentry, + .me = THIS_MODULE +}; + +static int __init init(void) +{ + return ipt_register_match(&connmark_match); +} + +static void __exit fini(void) +{ + ipt_unregister_match(&connmark_match); +} + +module_init(init); +module_exit(fini); diff -uNr linux-2.6.4-rc1/net/ipv4.orig/netfilter/ipt_CONNMARK.c linux-2.6.4-rc1/net/ipv4/netfilter/ipt_CONNMARK.c --- linux-2.6.4-rc1/net/ipv4.orig/netfilter/ipt_CONNMARK.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.4-rc1/net/ipv4/netfilter/ipt_CONNMARK.c 2004-03-03 03:58:03.427716464 +0100 @@ -0,0 +1,91 @@ +/* This is a module which is used for setting/remembering the mark field of + * an connection, or optionally restore it to the skb + */ +#include +#include +#include +#include + +#include +#include +#include + +static unsigned int +target(struct sk_buff **pskb, + const struct net_device *in, + const struct net_device *out, + unsigned int hooknum, + const void *targinfo, + void *userinfo) +{ + const struct ipt_connmark_target_info *markinfo = targinfo; + + enum ip_conntrack_info ctinfo; + struct ip_conntrack *ct = ip_conntrack_get((*pskb), &ctinfo); + if (ct) { + switch(markinfo->mode) { + case IPT_CONNMARK_SET: + ct->mark = markinfo->mark; + break; + case IPT_CONNMARK_SAVE: + ct->mark = (*pskb)->nfmark; + break; + case IPT_CONNMARK_RESTORE: + if (ct->mark != (*pskb)->nfmark) { + (*pskb)->nfmark = ct->mark; + (*pskb)->nfcache |= NFC_ALTERED; + } + break; + } + } + + return IPT_CONTINUE; +} + +static int +checkentry(const char *tablename, + const struct ipt_entry *e, + void *targinfo, + unsigned int targinfosize, + unsigned int hook_mask) +{ + struct ipt_connmark_target_info *matchinfo = targinfo; + if (targinfosize != IPT_ALIGN(sizeof(struct ipt_connmark_target_info))) { + printk(KERN_WARNING "CONNMARK: targinfosize %u != %Zu\n", + targinfosize, + IPT_ALIGN(sizeof(struct ipt_connmark_target_info))); + return 0; + } + + if (matchinfo->mode == IPT_CONNMARK_RESTORE) { + if (strcmp(tablename, "mangle") != 0) { + printk(KERN_WARNING "CONNMARK: restore can only be called from \"mangle\" table, not \"%s\"\n", tablename); + return 0; + } + } + + return 1; +} + +static struct ipt_target ipt_connmark_reg = { + .name = "CONNMARK", + .target = target, + .checkentry = checkentry, + .me = THIS_MODULE +}; + +static int __init init(void) +{ + if (ipt_register_target(&ipt_connmark_reg)) + return -EINVAL; + + return 0; +} + +static void __exit fini(void) +{ + ipt_unregister_target(&ipt_connmark_reg); +} + +module_init(init); +module_exit(fini); diff -uNr linux-2.6.4-rc1/net/ipv4.orig/netfilter/Kconfig linux-2.6.4-rc1/net/ipv4/netfilter/Kconfig --- linux-2.6.4-rc1/net/ipv4.orig/netfilter/Kconfig 2004-03-03 03:43:30.000000000 +0100 +++ linux-2.6.4-rc1/net/ipv4/netfilter/Kconfig 2004-03-03 03:58:03.414718440 +0100 @@ -29,6 +29,15 @@ To compile it as a module, choose M here. If unsure, say Y. +config IP_NF_CONNTRACK_MARK + bool "Connection mark tracking support" + depends on IP_NF_CONNTRACK + help + This option enables support for connection marks, used by the + `CONNMARK' target and `connmark' match. Similar to the mark value + of packets, but this mark value is kept in the conntrack session + instead of the individual packets. + config IP_NF_IRC tristate "IRC protocol support" depends on IP_NF_CONNTRACK @@ -244,6 +253,15 @@ To compile it as a module, choose M here. If unsure, say N. +config IP_NF_MATCH_CONNMARK + tristate "Connection mark match support" + depends on IP_NF_CONNTRACK_MARK && IP_NF_CONNTRACK && IP_NF_IPTABLES + help + This option adds a `connmark' match, which allows you to match the + connection mark value previously set for the session by `CONNMARK'. + + To compile it as a module, choose M here. If unsure, say N. + config IP_NF_MATCH_CONNTRACK tristate "Connection tracking match support" depends on IP_NF_CONNTRACK && IP_NF_IPTABLES @@ -487,6 +505,17 @@ To compile it as a module, choose M here. If unsure, say N. +config IP_NF_TARGET_CONNMARK + tristate "CONNMARK target support" + depends on IP_NF_CONNTRACK_MARK && IP_NF_CONNTRACK && IP_NF_IPTABLES + help + This option adds a `CONNMARK' target, which allows one to manipulate + the connection mark value. Similar to the MARK target, but + affects the connection mark value rather than the packet mark value. + + To compile it as a module, choose M here, the module will be called + ipt_CONNMARK.o. If unsure, say N. + config IP_NF_TARGET_ULOG tristate "ULOG target support" depends on IP_NF_IPTABLES diff -uNr linux-2.6.4-rc1/net/ipv4.orig/netfilter/Makefile linux-2.6.4-rc1/net/ipv4/netfilter/Makefile --- linux-2.6.4-rc1/net/ipv4.orig/netfilter/Makefile 2004-03-03 03:43:30.000000000 +0100 +++ linux-2.6.4-rc1/net/ipv4/netfilter/Makefile 2004-03-03 04:01:17.565203080 +0100 @@ -76,6 +76,7 @@ obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o obj-$(CONFIG_IP_NF_MATCH_CONNLIMIT) += ipt_connlimit.o +obj-$(CONFIG_IP_NF_MATCH_CONNMARK) += ipt_connmark.o obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o @@ -97,6 +98,7 @@ obj-$(CONFIG_IP_NF_NAT_SNMP_BASIC) += ip_nat_snmp_basic.o obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o +obj-$(CONFIG_IP_NF_TARGET_CONNMARK) += ipt_CONNMARK.o obj-$(CONFIG_IP_NF_TARGET_IPV4OPTSSTRIP) += ipt_IPV4OPTSSTRIP.o obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o obj-$(CONFIG_IP_NF_TARGET_TCPMSS) += ipt_TCPMSS.o