diff -NurpP --minimal linux-2.6.21.a/include/linux/netfilter_ipv4/ipt_IPMARK.h linux-2.6.21.b/include/linux/netfilter_ipv4/ipt_IPMARK.h --- linux-2.6.21.a/include/linux/netfilter_ipv4/ipt_IPMARK.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.21.b/include/linux/netfilter_ipv4/ipt_IPMARK.h 2007-05-30 12:01:20.000000000 +0200 @@ -0,0 +1,13 @@ +#ifndef _IPT_IPMARK_H_target +#define _IPT_IPMARK_H_target + +struct ipt_ipmark_target_info { + unsigned long andmask; + unsigned long ormask; + unsigned char addr; +}; + +#define IPT_IPMARK_SRC 0 +#define IPT_IPMARK_DST 1 + +#endif /*_IPT_IPMARK_H_target*/ diff -NurpP --minimal linux-2.6.21.a/net/ipv4/netfilter/Kconfig linux-2.6.21.b/net/ipv4/netfilter/Kconfig --- linux-2.6.21.a/net/ipv4/netfilter/Kconfig 2007-05-30 12:01:03.000000000 +0200 +++ linux-2.6.21.b/net/ipv4/netfilter/Kconfig 2007-05-30 12:01:20.000000000 +0200 @@ -893,5 +893,23 @@ config IP_NF_RSH If you want to compile it as a module, say M here and read . If unsure, say `N'. +config IP_NF_TARGET_IPMARK + tristate 'IPMARK target support' + depends on IP_NF_MANGLE + help + This option adds a `IPMARK' target, which allows you to create rules + in the `mangle' table which alter the netfilter mark field basing + on the source or destination ip address of the packet. + This is very useful for very fast massive shaping - using only one + rule you can direct packets to houndreds different queues. + You will probably find it helpful only if your linux machine acts as + a shaper for many others computers. + + If you want to compile it as a module, say M here and read + . The module will be called + ipt_IPMARK.o. If unsure, say `N'. + + + endmenu diff -NurpP --minimal linux-2.6.21.a/net/ipv4/netfilter/Makefile linux-2.6.21.b/net/ipv4/netfilter/Makefile --- linux-2.6.21.a/net/ipv4/netfilter/Makefile 2007-05-30 12:01:03.000000000 +0200 +++ linux-2.6.21.b/net/ipv4/netfilter/Makefile 2007-05-30 12:01:21.000000000 +0200 @@ -82,6 +82,7 @@ obj-$(CONFIG_IP_NF_TARGET_TOS) += ipt_TOS.o obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o +obj-$(CONFIG_IP_NF_TARGET_IPMARK) += ipt_IPMARK.o obj-$(CONFIG_IP_NF_MATCH_IPV4OPTIONS) += ipt_ipv4options.o diff -NurpP --minimal linux-2.6.21.a/net/ipv4/netfilter/ipt_IPMARK.c linux-2.6.21.b/net/ipv4/netfilter/ipt_IPMARK.c --- linux-2.6.21.a/net/ipv4/netfilter/ipt_IPMARK.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.21.b/net/ipv4/netfilter/ipt_IPMARK.c 2007-05-30 12:01:21.000000000 +0200 @@ -0,0 +1,99 @@ +#include +#include +#include +#include +#include + +#include +#include + +MODULE_AUTHOR("Grzegorz Janoszka "); +MODULE_DESCRIPTION("IP tables IPMARK: mark based on ip address"); +MODULE_LICENSE("GPL"); + +static unsigned int +target(struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + unsigned int hooknum, + const struct xt_target *target, + const void *targinfo) +{ + const struct ipt_ipmark_target_info *ipmarkinfo = targinfo; + struct iphdr *iph = ip_hdr(skb); + unsigned long mark; + + if (ipmarkinfo->addr == IPT_IPMARK_SRC) + mark = (unsigned long) ntohl(iph->saddr); + else + mark = (unsigned long) ntohl(iph->daddr); + + mark &= ipmarkinfo->andmask; + mark |= ipmarkinfo->ormask; + + if (skb->mark != mark) + skb->mark = mark; + return IPT_CONTINUE; +} + +static bool +checkentry(const char *tablename, + const void *e, + const struct xt_target *target, + void *targinfo, + unsigned int hook_mask) +{ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,17) + if (targinfosize != IPT_ALIGN(sizeof(struct ipt_ipmark_target_info))) { + printk(KERN_WARNING "IPMARK: targinfosize %u != %Zu\n", + targinfosize, + IPT_ALIGN(sizeof(struct ipt_ipmark_target_info))); + return 0; + } +#endif + + if (strcmp(tablename, "mangle") != 0) { + printk(KERN_WARNING "IPMARK: can only be called from \"mangle\" table, not \"%s\"\n", tablename); + return 0; + } + + return 1; +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21) +static struct xt_target ipt_ipmark_reg = { +#else +static struct ipt_target ipt_ipmark_reg = { +#endif + .name = "IPMARK", +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21) + .family = AF_INET, +#endif + .target = target, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,17) + .targetsize = sizeof(struct ipt_ipmark_target_info), +#endif + .checkentry = checkentry, + .me = THIS_MODULE +}; + +static int __init init(void) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21) + return xt_register_target(&ipt_ipmark_reg); +#else + return ipt_register_target(&ipt_ipmark_reg); +#endif +} + +static void __exit fini(void) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21) + xt_unregister_target(&ipt_ipmark_reg); +#else + ipt_unregister_target(&ipt_ipmark_reg); +#endif +} + +module_init(init); +module_exit(fini);