From 9c08fe97f010249de4f33511f06b5cea14ac37ff Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Fri, 12 Oct 2007 14:58:35 +0000 Subject: [PATCH] [kernel] netfilter/ipset cleanups * rename patches to follow our naming conventions * update ipset patches with revision 7096 of [https://svn.netfilter.org/netfilter/trunk/patch-o-matic-ng pom] * add CONFIG_IP_NF_SET_IPTREEMAP to default kernel configs * add ip_set_iptreemap to include/netfilter.mk * update kmod-ipt-ipset module description git-svn-id: svn://svn.openwrt.org/openwrt/trunk@9269 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- include/netfilter.mk | 1 + package/kernel/modules/netfilter.mk | 12 + target/linux/generic-2.6/config-2.6.22 | 1 + target/linux/generic-2.6/config-2.6.23 | 1 + target/linux/generic-2.6/config-default | 1 + ...-ipset.patch => 130-netfilter_ipset.patch} | 1567 ++++++++++++++-- .../130-netfilter_ipset.patch} | 1370 ++++++++++++-- .../130-netfilter_ipset.patch} | 1569 +++++++++++++++-- 8 files changed, 3994 insertions(+), 528 deletions(-) rename target/linux/generic-2.6/patches-2.6.22/{130-netfilter-ipset.patch => 130-netfilter_ipset.patch} (79%) rename target/linux/generic-2.6/{patches/130-netfilter-ipset.patch => patches-2.6.23/130-netfilter_ipset.patch} (81%) rename target/linux/generic-2.6/{patches-2.6.23/130-netfilter-ipset.patch => patches/130-netfilter_ipset.patch} (79%) diff --git a/include/netfilter.mk b/include/netfilter.mk index bb59bf03d8..0a0e54af16 100644 --- a/include/netfilter.mk +++ b/include/netfilter.mk @@ -135,6 +135,7 @@ $(eval $(call nf_add,IPT_IPSET,CONFIG_IP_NF_SET_IPHASH, $(P_V4)ip_set_iphash)) $(eval $(call nf_add,IPT_IPSET,CONFIG_IP_NF_SET_IPMAP, $(P_V4)ip_set_ipmap)) $(eval $(call nf_add,IPT_IPSET,CONFIG_IP_NF_SET_IPPORTHASH, $(P_V4)ip_set_ipporthash)) $(eval $(call nf_add,IPT_IPSET,CONFIG_IP_NF_SET_IPTREE, $(P_V4)ip_set_iptree)) +$(eval $(call nf_add,IPT_IPSET,CONFIG_IP_NF_SET_IPTREEMAP, $(P_V4)ip_set_iptreemap)) $(eval $(call nf_add,IPT_IPSET,CONFIG_IP_NF_SET_MACIPMAP, $(P_V4)ip_set_macipmap)) $(eval $(call nf_add,IPT_IPSET,CONFIG_IP_NF_SET_NETHASH, $(P_V4)ip_set_nethash)) $(eval $(call nf_add,IPT_IPSET,CONFIG_IP_NF_SET_PORTMAP, $(P_V4)ip_set_portmap)) diff --git a/package/kernel/modules/netfilter.mk b/package/kernel/modules/netfilter.mk index 7813eef395..61a4013c39 100644 --- a/package/kernel/modules/netfilter.mk +++ b/package/kernel/modules/netfilter.mk @@ -227,6 +227,18 @@ endef define KernelPackage/ipt-ipset/description Netfilter kernel modules for ipset + Includes: + - ip_set + - ip_set_iphash + - ip_set_ipmap + - ip_set_ipporthash + - ip_set_iptree + - ip_set_iptreemap + - ip_set_macipmap + - ip_set_nethash + - ip_set_portmap + - ipt_set + - ipt_SET endef $(eval $(call KernelPackage,ipt-ipset)) diff --git a/target/linux/generic-2.6/config-2.6.22 b/target/linux/generic-2.6/config-2.6.22 index 9b07183880..96d4859456 100644 --- a/target/linux/generic-2.6/config-2.6.22 +++ b/target/linux/generic-2.6/config-2.6.22 @@ -577,6 +577,7 @@ CONFIG_IP_NF_SET_IPHASH=m CONFIG_IP_NF_SET_IPMAP=m CONFIG_IP_NF_SET_IPPORTHASH=m CONFIG_IP_NF_SET_IPTREE=m +CONFIG_IP_NF_SET_IPTREEMAP=m CONFIG_IP_NF_SET_MACIPMAP=m CONFIG_IP_NF_SET_MAX=256 CONFIG_IP_NF_SET_NETHASH=m diff --git a/target/linux/generic-2.6/config-2.6.23 b/target/linux/generic-2.6/config-2.6.23 index bf26b76b6c..b74173153d 100644 --- a/target/linux/generic-2.6/config-2.6.23 +++ b/target/linux/generic-2.6/config-2.6.23 @@ -584,6 +584,7 @@ CONFIG_IP_NF_SET_IPHASH=m CONFIG_IP_NF_SET_IPMAP=m CONFIG_IP_NF_SET_IPPORTHASH=m CONFIG_IP_NF_SET_IPTREE=m +CONFIG_IP_NF_SET_IPTREEMAP=m CONFIG_IP_NF_SET_MACIPMAP=m CONFIG_IP_NF_SET_MAX=256 CONFIG_IP_NF_SET_NETHASH=m diff --git a/target/linux/generic-2.6/config-default b/target/linux/generic-2.6/config-default index e90c0425be..9370fa9b88 100644 --- a/target/linux/generic-2.6/config-default +++ b/target/linux/generic-2.6/config-default @@ -561,6 +561,7 @@ CONFIG_IP_NF_SET_IPHASH=m CONFIG_IP_NF_SET_IPMAP=m CONFIG_IP_NF_SET_IPPORTHASH=m CONFIG_IP_NF_SET_IPTREE=m +CONFIG_IP_NF_SET_IPTREEMAP=m CONFIG_IP_NF_SET_MACIPMAP=m CONFIG_IP_NF_SET_MAX=256 CONFIG_IP_NF_SET_NETHASH=m diff --git a/target/linux/generic-2.6/patches-2.6.22/130-netfilter-ipset.patch b/target/linux/generic-2.6/patches-2.6.22/130-netfilter_ipset.patch similarity index 79% rename from target/linux/generic-2.6/patches-2.6.22/130-netfilter-ipset.patch rename to target/linux/generic-2.6/patches-2.6.22/130-netfilter_ipset.patch index a9b3c35430..ef08d05d62 100644 --- a/target/linux/generic-2.6/patches-2.6.22/130-netfilter-ipset.patch +++ b/target/linux/generic-2.6/patches-2.6.22/130-netfilter_ipset.patch @@ -1,7 +1,6 @@ -Index: linux-2.6.22-rc5/include/linux/netfilter_ipv4/ip_set.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.22-rc5/include/linux/netfilter_ipv4/ip_set.h 2007-06-19 23:19:01.000000000 +0100 +diff -Nru ./linux-2.6.22.4/include/linux/netfilter_ipv4/ip_set.h linux-2.6.22.4.pom2patch.set/include/linux/netfilter_ipv4/ip_set.h +--- ./linux-2.6.22.4/include/linux/netfilter_ipv4/ip_set.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22.4.pom2patch.set/include/linux/netfilter_ipv4/ip_set.h 2007-10-12 14:31:55.000000000 +0200 @@ -0,0 +1,498 @@ +#ifndef _IP_SET_H +#define _IP_SET_H @@ -501,10 +500,9 @@ Index: linux-2.6.22-rc5/include/linux/netfilter_ipv4/ip_set.h +#endif /* __KERNEL__ */ + +#endif /*_IP_SET_H*/ -Index: linux-2.6.22-rc5/include/linux/netfilter_ipv4/ip_set_iphash.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.22-rc5/include/linux/netfilter_ipv4/ip_set_iphash.h 2007-06-19 23:19:01.000000000 +0100 +diff -Nru ./linux-2.6.22.4/include/linux/netfilter_ipv4/ip_set_iphash.h linux-2.6.22.4.pom2patch.set/include/linux/netfilter_ipv4/ip_set_iphash.h +--- ./linux-2.6.22.4/include/linux/netfilter_ipv4/ip_set_iphash.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22.4.pom2patch.set/include/linux/netfilter_ipv4/ip_set_iphash.h 2007-10-12 14:31:55.000000000 +0200 @@ -0,0 +1,30 @@ +#ifndef __IP_SET_IPHASH_H +#define __IP_SET_IPHASH_H @@ -536,10 +534,9 @@ Index: linux-2.6.22-rc5/include/linux/netfilter_ipv4/ip_set_iphash.h +}; + +#endif /* __IP_SET_IPHASH_H */ -Index: linux-2.6.22-rc5/include/linux/netfilter_ipv4/ip_set_ipmap.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.22-rc5/include/linux/netfilter_ipv4/ip_set_ipmap.h 2007-06-19 23:19:01.000000000 +0100 +diff -Nru ./linux-2.6.22.4/include/linux/netfilter_ipv4/ip_set_ipmap.h linux-2.6.22.4.pom2patch.set/include/linux/netfilter_ipv4/ip_set_ipmap.h +--- ./linux-2.6.22.4/include/linux/netfilter_ipv4/ip_set_ipmap.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22.4.pom2patch.set/include/linux/netfilter_ipv4/ip_set_ipmap.h 2007-10-12 14:31:55.000000000 +0200 @@ -0,0 +1,56 @@ +#ifndef __IP_SET_IPMAP_H +#define __IP_SET_IPMAP_H @@ -597,10 +594,9 @@ Index: linux-2.6.22-rc5/include/linux/netfilter_ipv4/ip_set_ipmap.h +} + +#endif /* __IP_SET_IPMAP_H */ -Index: linux-2.6.22-rc5/include/linux/netfilter_ipv4/ip_set_ipporthash.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.22-rc5/include/linux/netfilter_ipv4/ip_set_ipporthash.h 2007-06-19 23:19:01.000000000 +0100 +diff -Nru ./linux-2.6.22.4/include/linux/netfilter_ipv4/ip_set_ipporthash.h linux-2.6.22.4.pom2patch.set/include/linux/netfilter_ipv4/ip_set_ipporthash.h +--- ./linux-2.6.22.4/include/linux/netfilter_ipv4/ip_set_ipporthash.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22.4.pom2patch.set/include/linux/netfilter_ipv4/ip_set_ipporthash.h 2007-10-12 14:31:55.000000000 +0200 @@ -0,0 +1,34 @@ +#ifndef __IP_SET_IPPORTHASH_H +#define __IP_SET_IPPORTHASH_H @@ -636,10 +632,9 @@ Index: linux-2.6.22-rc5/include/linux/netfilter_ipv4/ip_set_ipporthash.h +}; + +#endif /* __IP_SET_IPPORTHASH_H */ -Index: linux-2.6.22-rc5/include/linux/netfilter_ipv4/ip_set_iptree.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.22-rc5/include/linux/netfilter_ipv4/ip_set_iptree.h 2007-06-19 23:19:01.000000000 +0100 +diff -Nru ./linux-2.6.22.4/include/linux/netfilter_ipv4/ip_set_iptree.h linux-2.6.22.4.pom2patch.set/include/linux/netfilter_ipv4/ip_set_iptree.h +--- ./linux-2.6.22.4/include/linux/netfilter_ipv4/ip_set_iptree.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22.4.pom2patch.set/include/linux/netfilter_ipv4/ip_set_iptree.h 2007-10-12 14:31:55.000000000 +0200 @@ -0,0 +1,40 @@ +#ifndef __IP_SET_IPTREE_H +#define __IP_SET_IPTREE_H @@ -681,10 +676,205 @@ Index: linux-2.6.22-rc5/include/linux/netfilter_ipv4/ip_set_iptree.h +}; + +#endif /* __IP_SET_IPTREE_H */ -Index: linux-2.6.22-rc5/include/linux/netfilter_ipv4/ip_set_macipmap.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.22-rc5/include/linux/netfilter_ipv4/ip_set_macipmap.h 2007-06-19 23:19:01.000000000 +0100 +diff -Nru ./linux-2.6.22.4/include/linux/netfilter_ipv4/ip_set_iptreemap.h linux-2.6.22.4.pom2patch.set/include/linux/netfilter_ipv4/ip_set_iptreemap.h +--- ./linux-2.6.22.4/include/linux/netfilter_ipv4/ip_set_iptreemap.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22.4.pom2patch.set/include/linux/netfilter_ipv4/ip_set_iptreemap.h 2007-10-12 14:31:55.000000000 +0200 +@@ -0,0 +1,40 @@ ++#ifndef __IP_SET_IPTREEMAP_H ++#define __IP_SET_IPTREEMAP_H ++ ++#include ++ ++#define SETTYPE_NAME "iptreemap" ++ ++#ifdef __KERNEL__ ++struct ip_set_iptreemap_d { ++ unsigned char bitmap[32]; /* x.x.x.y */ ++}; ++ ++struct ip_set_iptreemap_c { ++ struct ip_set_iptreemap_d *tree[256]; /* x.x.y.x */ ++}; ++ ++struct ip_set_iptreemap_b { ++ struct ip_set_iptreemap_c *tree[256]; /* x.y.x.x */ ++ unsigned char dirty[32]; ++}; ++#endif ++ ++struct ip_set_iptreemap { ++ unsigned int gc_interval; ++#ifdef __KERNEL__ ++ struct timer_list gc; ++ struct ip_set_iptreemap_b *tree[256]; /* y.x.x.x */ ++#endif ++}; ++ ++struct ip_set_req_iptreemap_create { ++ unsigned int gc_interval; ++}; ++ ++struct ip_set_req_iptreemap { ++ ip_set_ip_t start; ++ ip_set_ip_t end; ++}; ++ ++#endif /* __IP_SET_IPTREEMAP_H */ +diff -Nru ./linux-2.6.22.4/include/linux/netfilter_ipv4/ip_set_jhash.h linux-2.6.22.4.pom2patch.set/include/linux/netfilter_ipv4/ip_set_jhash.h +--- ./linux-2.6.22.4/include/linux/netfilter_ipv4/ip_set_jhash.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22.4.pom2patch.set/include/linux/netfilter_ipv4/ip_set_jhash.h 2007-10-12 14:31:55.000000000 +0200 +@@ -0,0 +1,148 @@ ++#ifndef _LINUX_IPSET_JHASH_H ++#define _LINUX_IPSET_JHASH_H ++ ++/* This is a copy of linux/jhash.h but the types u32/u8 are changed ++ * to __u32/__u8 so that the header file can be included into ++ * userspace code as well. Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) ++ */ ++ ++/* jhash.h: Jenkins hash support. ++ * ++ * Copyright (C) 1996 Bob Jenkins (bob_jenkins@burtleburtle.net) ++ * ++ * http://burtleburtle.net/bob/hash/ ++ * ++ * These are the credits from Bob's sources: ++ * ++ * lookup2.c, by Bob Jenkins, December 1996, Public Domain. ++ * hash(), hash2(), hash3, and mix() are externally useful functions. ++ * Routines to test the hash are included if SELF_TEST is defined. ++ * You can use this free for any purpose. It has no warranty. ++ * ++ * Copyright (C) 2003 David S. Miller (davem@redhat.com) ++ * ++ * I've modified Bob's hash to be useful in the Linux kernel, and ++ * any bugs present are surely my fault. -DaveM ++ */ ++ ++/* NOTE: Arguments are modified. */ ++#define __jhash_mix(a, b, c) \ ++{ \ ++ a -= b; a -= c; a ^= (c>>13); \ ++ b -= c; b -= a; b ^= (a<<8); \ ++ c -= a; c -= b; c ^= (b>>13); \ ++ a -= b; a -= c; a ^= (c>>12); \ ++ b -= c; b -= a; b ^= (a<<16); \ ++ c -= a; c -= b; c ^= (b>>5); \ ++ a -= b; a -= c; a ^= (c>>3); \ ++ b -= c; b -= a; b ^= (a<<10); \ ++ c -= a; c -= b; c ^= (b>>15); \ ++} ++ ++/* The golden ration: an arbitrary value */ ++#define JHASH_GOLDEN_RATIO 0x9e3779b9 ++ ++/* The most generic version, hashes an arbitrary sequence ++ * of bytes. No alignment or length assumptions are made about ++ * the input key. ++ */ ++static inline __u32 jhash(void *key, __u32 length, __u32 initval) ++{ ++ __u32 a, b, c, len; ++ __u8 *k = key; ++ ++ len = length; ++ a = b = JHASH_GOLDEN_RATIO; ++ c = initval; ++ ++ while (len >= 12) { ++ a += (k[0] +((__u32)k[1]<<8) +((__u32)k[2]<<16) +((__u32)k[3]<<24)); ++ b += (k[4] +((__u32)k[5]<<8) +((__u32)k[6]<<16) +((__u32)k[7]<<24)); ++ c += (k[8] +((__u32)k[9]<<8) +((__u32)k[10]<<16)+((__u32)k[11]<<24)); ++ ++ __jhash_mix(a,b,c); ++ ++ k += 12; ++ len -= 12; ++ } ++ ++ c += length; ++ switch (len) { ++ case 11: c += ((__u32)k[10]<<24); ++ case 10: c += ((__u32)k[9]<<16); ++ case 9 : c += ((__u32)k[8]<<8); ++ case 8 : b += ((__u32)k[7]<<24); ++ case 7 : b += ((__u32)k[6]<<16); ++ case 6 : b += ((__u32)k[5]<<8); ++ case 5 : b += k[4]; ++ case 4 : a += ((__u32)k[3]<<24); ++ case 3 : a += ((__u32)k[2]<<16); ++ case 2 : a += ((__u32)k[1]<<8); ++ case 1 : a += k[0]; ++ }; ++ ++ __jhash_mix(a,b,c); ++ ++ return c; ++} ++ ++/* A special optimized version that handles 1 or more of __u32s. ++ * The length parameter here is the number of __u32s in the key. ++ */ ++static inline __u32 jhash2(__u32 *k, __u32 length, __u32 initval) ++{ ++ __u32 a, b, c, len; ++ ++ a = b = JHASH_GOLDEN_RATIO; ++ c = initval; ++ len = length; ++ ++ while (len >= 3) { ++ a += k[0]; ++ b += k[1]; ++ c += k[2]; ++ __jhash_mix(a, b, c); ++ k += 3; len -= 3; ++ } ++ ++ c += length * 4; ++ ++ switch (len) { ++ case 2 : b += k[1]; ++ case 1 : a += k[0]; ++ }; ++ ++ __jhash_mix(a,b,c); ++ ++ return c; ++} ++ ++ ++/* A special ultra-optimized versions that knows they are hashing exactly ++ * 3, 2 or 1 word(s). ++ * ++ * NOTE: In partilar the "c += length; __jhash_mix(a,b,c);" normally ++ * done at the end is not done here. ++ */ ++static inline __u32 jhash_3words(__u32 a, __u32 b, __u32 c, __u32 initval) ++{ ++ a += JHASH_GOLDEN_RATIO; ++ b += JHASH_GOLDEN_RATIO; ++ c += initval; ++ ++ __jhash_mix(a, b, c); ++ ++ return c; ++} ++ ++static inline __u32 jhash_2words(__u32 a, __u32 b, __u32 initval) ++{ ++ return jhash_3words(a, b, 0, initval); ++} ++ ++static inline __u32 jhash_1word(__u32 a, __u32 initval) ++{ ++ return jhash_3words(a, 0, 0, initval); ++} ++ ++#endif /* _LINUX_IPSET_JHASH_H */ +diff -Nru ./linux-2.6.22.4/include/linux/netfilter_ipv4/ip_set_macipmap.h linux-2.6.22.4.pom2patch.set/include/linux/netfilter_ipv4/ip_set_macipmap.h +--- ./linux-2.6.22.4/include/linux/netfilter_ipv4/ip_set_macipmap.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22.4.pom2patch.set/include/linux/netfilter_ipv4/ip_set_macipmap.h 2007-10-12 14:31:55.000000000 +0200 @@ -0,0 +1,38 @@ +#ifndef __IP_SET_MACIPMAP_H +#define __IP_SET_MACIPMAP_H @@ -724,10 +914,9 @@ Index: linux-2.6.22-rc5/include/linux/netfilter_ipv4/ip_set_macipmap.h +}; + +#endif /* __IP_SET_MACIPMAP_H */ -Index: linux-2.6.22-rc5/include/linux/netfilter_ipv4/ip_set_malloc.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.22-rc5/include/linux/netfilter_ipv4/ip_set_malloc.h 2007-06-19 23:19:01.000000000 +0100 +diff -Nru ./linux-2.6.22.4/include/linux/netfilter_ipv4/ip_set_malloc.h linux-2.6.22.4.pom2patch.set/include/linux/netfilter_ipv4/ip_set_malloc.h +--- ./linux-2.6.22.4/include/linux/netfilter_ipv4/ip_set_malloc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22.4.pom2patch.set/include/linux/netfilter_ipv4/ip_set_malloc.h 2007-10-12 14:31:55.000000000 +0200 @@ -0,0 +1,116 @@ +#ifndef _IP_SET_MALLOC_H +#define _IP_SET_MALLOC_H @@ -845,10 +1034,9 @@ Index: linux-2.6.22-rc5/include/linux/netfilter_ipv4/ip_set_malloc.h +#endif /* __KERNEL__ */ + +#endif /*_IP_SET_MALLOC_H*/ -Index: linux-2.6.22-rc5/include/linux/netfilter_ipv4/ip_set_nethash.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.22-rc5/include/linux/netfilter_ipv4/ip_set_nethash.h 2007-06-19 23:19:01.000000000 +0100 +diff -Nru ./linux-2.6.22.4/include/linux/netfilter_ipv4/ip_set_nethash.h linux-2.6.22.4.pom2patch.set/include/linux/netfilter_ipv4/ip_set_nethash.h +--- ./linux-2.6.22.4/include/linux/netfilter_ipv4/ip_set_nethash.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22.4.pom2patch.set/include/linux/netfilter_ipv4/ip_set_nethash.h 2007-10-12 14:31:55.000000000 +0200 @@ -0,0 +1,55 @@ +#ifndef __IP_SET_NETHASH_H +#define __IP_SET_NETHASH_H @@ -905,10 +1093,9 @@ Index: linux-2.6.22-rc5/include/linux/netfilter_ipv4/ip_set_nethash.h +} + +#endif /* __IP_SET_NETHASH_H */ -Index: linux-2.6.22-rc5/include/linux/netfilter_ipv4/ip_set_portmap.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.22-rc5/include/linux/netfilter_ipv4/ip_set_portmap.h 2007-06-19 23:19:01.000000000 +0100 +diff -Nru ./linux-2.6.22.4/include/linux/netfilter_ipv4/ip_set_portmap.h linux-2.6.22.4.pom2patch.set/include/linux/netfilter_ipv4/ip_set_portmap.h +--- ./linux-2.6.22.4/include/linux/netfilter_ipv4/ip_set_portmap.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22.4.pom2patch.set/include/linux/netfilter_ipv4/ip_set_portmap.h 2007-10-12 14:31:55.000000000 +0200 @@ -0,0 +1,25 @@ +#ifndef __IP_SET_PORTMAP_H +#define __IP_SET_PORTMAP_H @@ -935,10 +1122,9 @@ Index: linux-2.6.22-rc5/include/linux/netfilter_ipv4/ip_set_portmap.h +}; + +#endif /* __IP_SET_PORTMAP_H */ -Index: linux-2.6.22-rc5/include/linux/netfilter_ipv4/ipt_set.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.22-rc5/include/linux/netfilter_ipv4/ipt_set.h 2007-06-19 23:19:01.000000000 +0100 +diff -Nru ./linux-2.6.22.4/include/linux/netfilter_ipv4/ipt_set.h linux-2.6.22.4.pom2patch.set/include/linux/netfilter_ipv4/ipt_set.h +--- ./linux-2.6.22.4/include/linux/netfilter_ipv4/ipt_set.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22.4.pom2patch.set/include/linux/netfilter_ipv4/ipt_set.h 2007-10-12 14:31:55.000000000 +0200 @@ -0,0 +1,21 @@ +#ifndef _IPT_SET_H +#define _IPT_SET_H @@ -961,11 +1147,10 @@ Index: linux-2.6.22-rc5/include/linux/netfilter_ipv4/ipt_set.h +}; + +#endif /*_IPT_SET_H*/ -Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.22-rc5/net/ipv4/netfilter/ip_set.c 2007-06-19 23:19:01.000000000 +0100 -@@ -0,0 +1,2001 @@ +diff -Nru ./linux-2.6.22.4/net/ipv4/netfilter/ip_set.c linux-2.6.22.4.pom2patch.set/net/ipv4/netfilter/ip_set.c +--- ./linux-2.6.22.4/net/ipv4/netfilter/ip_set.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22.4.pom2patch.set/net/ipv4/netfilter/ip_set.c 2007-10-12 14:31:55.000000000 +0200 +@@ -0,0 +1,2003 @@ +/* Copyright (C) 2000-2002 Joakim Axelsson + * Patrick Schaaf + * Copyright (C) 2003-2004 Jozsef Kadlecsik @@ -2896,7 +3081,9 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set.c + .get_optmin = SO_IP_SET, + .get_optmax = SO_IP_SET + 1, + .get = &ip_set_sockfn_get, -+ .use = 0 ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) ++ .owner = THIS_MODULE, ++#endif +}; + +static int max_sets, hash_size; @@ -2908,7 +3095,7 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set.c +MODULE_AUTHOR("Jozsef Kadlecsik "); +MODULE_DESCRIPTION("module implementing core IP set support"); + -+static int __init init(void) ++static int __init ip_set_init(void) +{ + int res; + ip_set_id_t i; @@ -2945,7 +3132,7 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set.c + return 0; +} + -+static void __exit fini(void) ++static void __exit ip_set_fini(void) +{ + /* There can't be any existing set or binding */ + nf_unregister_sockopt(&so_set); @@ -2965,13 +3152,12 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set.c +EXPORT_SYMBOL(ip_set_delip_kernel); +EXPORT_SYMBOL(ip_set_testip_kernel); + -+module_init(init); -+module_exit(fini); -Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_iphash.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_iphash.c 2007-06-19 23:19:01.000000000 +0100 -@@ -0,0 +1,413 @@ ++module_init(ip_set_init); ++module_exit(ip_set_fini); +diff -Nru ./linux-2.6.22.4/net/ipv4/netfilter/ip_set_iphash.c linux-2.6.22.4.pom2patch.set/net/ipv4/netfilter/ip_set_iphash.c +--- ./linux-2.6.22.4/net/ipv4/netfilter/ip_set_iphash.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22.4.pom2patch.set/net/ipv4/netfilter/ip_set_iphash.c 2007-10-12 14:31:55.000000000 +0200 +@@ -0,0 +1,429 @@ +/* Copyright (C) 2003-2004 Jozsef Kadlecsik + * + * This program is free software; you can redistribute it and/or modify @@ -2984,6 +3170,8 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_iphash.c +#include +#include +#include ++#include ++#include +#include +#include +#include @@ -2992,7 +3180,6 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_iphash.c +#include +#include +#include -+#include + +#include + @@ -3062,8 +3249,13 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_iphash.c +{ + return __testip(set, + ntohl(flags[index] & IPSET_SRC ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + ? ip_hdr(skb)->saddr + : ip_hdr(skb)->daddr), ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr), ++#endif + hash_ip); +} + @@ -3074,7 +3266,7 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_iphash.c + u_int16_t i; + ip_set_ip_t *elem; + -+ if (!ip || map->elements > limit) ++ if (!ip || map->elements >= limit) + return -ERANGE; + + *hash_ip = ip & map->netmask; @@ -3119,8 +3311,13 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_iphash.c +{ + return __addip((struct ip_set_iphash *) set->data, + ntohl(flags[index] & IPSET_SRC -+ ? ip_hdr(skb)->saddr ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr + : ip_hdr(skb)->daddr), ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr), ++#endif + hash_ip); +} + @@ -3242,8 +3439,13 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_iphash.c +{ + return __delip(set, + ntohl(flags[index] & IPSET_SRC ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + ? ip_hdr(skb)->saddr + : ip_hdr(skb)->daddr), ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr), ++#endif + hash_ip); +} + @@ -3372,24 +3574,23 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_iphash.c +module_param(limit, int, 0600); +MODULE_PARM_DESC(limit, "maximal number of elements stored in the sets"); + -+static int __init init(void) ++static int __init ip_set_iphash_init(void) +{ + return ip_set_register_set_type(&ip_set_iphash); +} + -+static void __exit fini(void) ++static void __exit ip_set_iphash_fini(void) +{ + /* FIXME: possible race with ip_set_create() */ + ip_set_unregister_set_type(&ip_set_iphash); +} + -+module_init(init); -+module_exit(fini); -Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_ipmap.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_ipmap.c 2007-06-19 23:19:01.000000000 +0100 -@@ -0,0 +1,327 @@ ++module_init(ip_set_iphash_init); ++module_exit(ip_set_iphash_fini); +diff -Nru ./linux-2.6.22.4/net/ipv4/netfilter/ip_set_ipmap.c linux-2.6.22.4.pom2patch.set/net/ipv4/netfilter/ip_set_ipmap.c +--- ./linux-2.6.22.4/net/ipv4/netfilter/ip_set_ipmap.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22.4.pom2patch.set/net/ipv4/netfilter/ip_set_ipmap.c 2007-10-12 14:31:55.000000000 +0200 +@@ -0,0 +1,336 @@ +/* Copyright (C) 2000-2002 Joakim Axelsson + * Patrick Schaaf + * Copyright (C) 2003-2004 Jozsef Kadlecsik @@ -3404,13 +3605,14 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_ipmap.c +#include +#include +#include ++#include +#include +#include +#include +#include +#include +#include -+#include ++ +#include + +static inline ip_set_ip_t @@ -3456,17 +3658,15 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_ipmap.c + const u_int32_t *flags, + unsigned char index) +{ -+ int res; -+ -+ DP("flag: %s src: %u.%u.%u.%u dst: %u.%u.%u.%u", -+ flags[index] & IPSET_SRC ? "SRC" : "DST", -+ NIPQUAD(ip_hdr(skb)->saddr), -+ NIPQUAD(ip_hdr(skb)->daddr)); -+ -+ res = __testip(set, -+ ntohl(flags[index] & IPSET_SRC ++ int res = __testip(set, ++ ntohl(flags[index] & IPSET_SRC ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + ? ip_hdr(skb)->saddr + : ip_hdr(skb)->daddr), ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr), ++#endif + hash_ip); + return (res < 0 ? 0 : res); +} @@ -3513,8 +3713,13 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_ipmap.c +{ + return __addip(set, + ntohl(flags[index] & IPSET_SRC -+ ? ip_hdr(skb)->saddr ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr + : ip_hdr(skb)->daddr), ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr), ++#endif + hash_ip); +} + @@ -3559,8 +3764,13 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_ipmap.c +{ + return __delip(set, + ntohl(flags[index] & IPSET_SRC ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + ? ip_hdr(skb)->saddr + : ip_hdr(skb)->daddr), ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr), ++#endif + hash_ip); +} + @@ -3704,24 +3914,23 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_ipmap.c +MODULE_AUTHOR("Jozsef Kadlecsik "); +MODULE_DESCRIPTION("ipmap type of IP sets"); + -+static int __init init(void) ++static int __init ip_set_ipmap_init(void) +{ + return ip_set_register_set_type(&ip_set_ipmap); +} + -+static void __exit fini(void) ++static void __exit ip_set_ipmap_fini(void) +{ + /* FIXME: possible race with ip_set_create() */ + ip_set_unregister_set_type(&ip_set_ipmap); +} + -+module_init(init); -+module_exit(fini); -Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_ipporthash.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_ipporthash.c 2007-06-20 20:00:06.000000000 +0100 -@@ -0,0 +1,535 @@ ++module_init(ip_set_ipmap_init); ++module_exit(ip_set_ipmap_fini); +diff -Nru ./linux-2.6.22.4/net/ipv4/netfilter/ip_set_ipporthash.c linux-2.6.22.4.pom2patch.set/net/ipv4/netfilter/ip_set_ipporthash.c +--- ./linux-2.6.22.4/net/ipv4/netfilter/ip_set_ipporthash.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22.4.pom2patch.set/net/ipv4/netfilter/ip_set_ipporthash.c 2007-10-12 14:31:55.000000000 +0200 +@@ -0,0 +1,581 @@ +/* Copyright (C) 2003-2004 Jozsef Kadlecsik + * + * This program is free software; you can redistribute it and/or modify @@ -3736,6 +3945,8 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_ipporthash.c +#include +#include +#include ++#include ++#include +#include +#include +#include @@ -3744,7 +3955,6 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_ipporthash.c +#include +#include +#include -+#include + +#include + @@ -3757,7 +3967,11 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_ipporthash.c +static inline ip_set_ip_t +get_port(const struct sk_buff *skb, u_int32_t flags) +{ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + struct iphdr *iph = ip_hdr(skb); ++#else ++ struct iphdr *iph = skb->nh.iph; ++#endif + u_int16_t offset = ntohs(iph->frag_off) & IP_OFFSET; + + switch (iph->protocol) { @@ -3768,7 +3982,11 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_ipporthash.c + if (offset) + return INVALID_PORT; + -+ if (skb_copy_bits(skb, ip_hdrlen(skb), &tcph, sizeof(tcph)) < 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ if (skb_copy_bits(skb, ip_hdr(skb)->ihl*4, &tcph, sizeof(tcph)) < 0) ++#else ++ if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &tcph, sizeof(tcph)) < 0) ++#endif + /* No choice either */ + return INVALID_PORT; + @@ -3781,7 +3999,11 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_ipporthash.c + if (offset) + return INVALID_PORT; + -+ if (skb_copy_bits(skb, ip_hdrlen(skb), &udph, sizeof(udph)) < 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ if (skb_copy_bits(skb, ip_hdr(skb)->ihl*4, &udph, sizeof(udph)) < 0) ++#else ++ if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &udph, sizeof(udph)) < 0) ++#endif + /* No choice either */ + return INVALID_PORT; + @@ -3863,28 +4085,41 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_ipporthash.c + unsigned char index) +{ + ip_set_ip_t port; ++ int res; + + if (flags[index+1] == 0) -+ return -EINVAL; ++ return 0; + + port = get_port(skb, flags[index+1]); + + DP("flag: %s src: %u.%u.%u.%u dst: %u.%u.%u.%u", + flags[index] & IPSET_SRC ? "SRC" : "DST", ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + NIPQUAD(ip_hdr(skb)->saddr), + NIPQUAD(ip_hdr(skb)->daddr)); ++#else ++ NIPQUAD(skb->nh.iph->saddr), ++ NIPQUAD(skb->nh.iph->daddr)); ++#endif + DP("flag %s port %u", + flags[index+1] & IPSET_SRC ? "SRC" : "DST", + port); + if (port == INVALID_PORT) + return 0; + -+ return __testip(set, ++ res = __testip(set, + ntohl(flags[index] & IPSET_SRC ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + ? ip_hdr(skb)->saddr + : ip_hdr(skb)->daddr), ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr), ++#endif + port, + hash_ip); ++ return (res < 0 ? 0 : res); ++ +} + +static inline int @@ -3956,8 +4191,13 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_ipporthash.c + + DP("flag: %s src: %u.%u.%u.%u dst: %u.%u.%u.%u", + flags[index] & IPSET_SRC ? "SRC" : "DST", ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + NIPQUAD(ip_hdr(skb)->saddr), + NIPQUAD(ip_hdr(skb)->daddr)); ++#else ++ NIPQUAD(skb->nh.iph->saddr), ++ NIPQUAD(skb->nh.iph->daddr)); ++#endif + DP("flag %s port %u", + flags[index+1] & IPSET_SRC ? "SRC" : "DST", + port); @@ -3966,8 +4206,13 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_ipporthash.c + + return __addip((struct ip_set_ipporthash *) set->data, + ntohl(flags[index] & IPSET_SRC -+ ? ip_hdr(skb)->saddr ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr + : ip_hdr(skb)->daddr), ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr), ++#endif + port, + hash_ip); +} @@ -4101,8 +4346,13 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_ipporthash.c + + DP("flag: %s src: %u.%u.%u.%u dst: %u.%u.%u.%u", + flags[index] & IPSET_SRC ? "SRC" : "DST", ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + NIPQUAD(ip_hdr(skb)->saddr), + NIPQUAD(ip_hdr(skb)->daddr)); ++#else ++ NIPQUAD(skb->nh.iph->saddr), ++ NIPQUAD(skb->nh.iph->daddr)); ++#endif + DP("flag %s port %u", + flags[index+1] & IPSET_SRC ? "SRC" : "DST", + port); @@ -4111,8 +4361,13 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_ipporthash.c + + return __delip(set, + ntohl(flags[index] & IPSET_SRC -+ ? ip_hdr(skb)->saddr ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr + : ip_hdr(skb)->daddr), ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr), ++#endif + port, + hash_ip); +} @@ -4244,24 +4499,23 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_ipporthash.c +module_param(limit, int, 0600); +MODULE_PARM_DESC(limit, "maximal number of elements stored in the sets"); + -+static int __init init(void) ++static int __init ip_set_ipporthash_init(void) +{ + return ip_set_register_set_type(&ip_set_ipporthash); +} + -+static void __exit fini(void) ++static void __exit ip_set_ipporthash_fini(void) +{ + /* FIXME: possible race with ip_set_create() */ + ip_set_unregister_set_type(&ip_set_ipporthash); +} + -+module_init(init); -+module_exit(fini); -Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_iptree.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_iptree.c 2007-06-19 23:19:01.000000000 +0100 -@@ -0,0 +1,571 @@ ++module_init(ip_set_ipporthash_init); ++module_exit(ip_set_ipporthash_fini); +diff -Nru ./linux-2.6.22.4/net/ipv4/netfilter/ip_set_iptree.c linux-2.6.22.4.pom2patch.set/net/ipv4/netfilter/ip_set_iptree.c +--- ./linux-2.6.22.4/net/ipv4/netfilter/ip_set_iptree.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22.4.pom2patch.set/net/ipv4/netfilter/ip_set_iptree.c 2007-10-12 14:31:55.000000000 +0200 +@@ -0,0 +1,612 @@ +/* Copyright (C) 2005 Jozsef Kadlecsik + * + * This program is free software; you can redistribute it and/or modify @@ -4307,12 +4561,23 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_iptree.c +static kmem_cache_t *leaf_cachep; +#endif + ++#if defined(__LITTLE_ENDIAN) +#define ABCD(a,b,c,d,addrp) do { \ + a = ((unsigned char *)addrp)[3]; \ + b = ((unsigned char *)addrp)[2]; \ + c = ((unsigned char *)addrp)[1]; \ + d = ((unsigned char *)addrp)[0]; \ +} while (0) ++#elif defined(__BIG_ENDIAN) ++#define ABCD(a,b,c,d,addrp) do { \ ++ a = ((unsigned char *)addrp)[0]; \ ++ b = ((unsigned char *)addrp)[1]; \ ++ c = ((unsigned char *)addrp)[2]; \ ++ d = ((unsigned char *)addrp)[3]; \ ++} while (0) ++#else ++#error "Please fix asm/byteorder.h" ++#endif /* __LITTLE_ENDIAN */ + +#define TESTIP_WALK(map, elem, branch) do { \ + if ((map)->tree[elem]) { \ @@ -4340,8 +4605,9 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_iptree.c + TESTIP_WALK(btree, b, ctree); + TESTIP_WALK(ctree, c, dtree); + DP("%lu %lu", dtree->expires[d], jiffies); -+ return !!(map->timeout ? (time_after(dtree->expires[d], jiffies)) -+ : dtree->expires[d]); ++ return dtree->expires[d] ++ && (!map->timeout ++ || time_after(dtree->expires[d], jiffies)); +} + +static int @@ -4371,24 +4637,34 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_iptree.c + + DP("flag: %s src: %u.%u.%u.%u dst: %u.%u.%u.%u", + flags[index] & IPSET_SRC ? "SRC" : "DST", ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + NIPQUAD(ip_hdr(skb)->saddr), + NIPQUAD(ip_hdr(skb)->daddr)); ++#else ++ NIPQUAD(skb->nh.iph->saddr), ++ NIPQUAD(skb->nh.iph->daddr)); ++#endif + + res = __testip(set, + ntohl(flags[index] & IPSET_SRC ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + ? ip_hdr(skb)->saddr + : ip_hdr(skb)->daddr), ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr), ++#endif + hash_ip); + return (res < 0 ? 0 : res); +} + -+#define ADDIP_WALK(map, elem, branch, type, cachep, flags) do { \ ++#define ADDIP_WALK(map, elem, branch, type, cachep) do { \ + if ((map)->tree[elem]) { \ + DP("found %u", elem); \ + branch = (map)->tree[elem]; \ + } else { \ + branch = (type *) \ -+ kmem_cache_alloc(cachep, flags); \ ++ kmem_cache_alloc(cachep, GFP_ATOMIC); \ + if (branch == NULL) \ + return -ENOMEM; \ + memset(branch, 0, sizeof(*branch)); \ @@ -4399,8 +4675,7 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_iptree.c + +static inline int +__addip(struct ip_set *set, ip_set_ip_t ip, unsigned int timeout, -+ ip_set_ip_t *hash_ip, -+ unsigned int __nocast flags) ++ ip_set_ip_t *hash_ip) +{ + struct ip_set_iptree *map = (struct ip_set_iptree *) set->data; + struct ip_set_iptreeb *btree; @@ -4409,7 +4684,7 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_iptree.c + unsigned char a,b,c,d; + int ret = 0; + -+ if (!ip || map->elements > limit) ++ if (!ip || map->elements >= limit) + /* We could call the garbage collector + * but it's probably overkill */ + return -ERANGE; @@ -4417,14 +4692,14 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_iptree.c + *hash_ip = ip; + ABCD(a, b, c, d, hash_ip); + DP("%u %u %u %u timeout %u", a, b, c, d, timeout); -+ ADDIP_WALK(map, a, btree, struct ip_set_iptreeb, branch_cachep, flags); -+ ADDIP_WALK(btree, b, ctree, struct ip_set_iptreec, branch_cachep, flags); -+ ADDIP_WALK(ctree, c, dtree, struct ip_set_iptreed, leaf_cachep, flags); ++ ADDIP_WALK(map, a, btree, struct ip_set_iptreeb, branch_cachep); ++ ADDIP_WALK(btree, b, ctree, struct ip_set_iptreec, branch_cachep); ++ ADDIP_WALK(ctree, c, dtree, struct ip_set_iptreed, leaf_cachep); + if (dtree->expires[d] + && (!map->timeout || time_after(dtree->expires[d], jiffies))) + ret = -EEXIST; + dtree->expires[d] = map->timeout ? (timeout * HZ + jiffies) : 1; -+ /* Lottery */ ++ /* Lottery: I won! */ + if (dtree->expires[d] == 0) + dtree->expires[d] = 1; + DP("%u %lu", d, dtree->expires[d]); @@ -4450,8 +4725,7 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_iptree.c + DP("%u.%u.%u.%u %u", HIPQUAD(req->ip), req->timeout); + return __addip(set, req->ip, + req->timeout ? req->timeout : map->timeout, -+ hash_ip, -+ GFP_ATOMIC); ++ hash_ip); +} + +static int @@ -4465,11 +4739,15 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_iptree.c + + return __addip(set, + ntohl(flags[index] & IPSET_SRC -+ ? ip_hdr(skb)->saddr ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr + : ip_hdr(skb)->daddr), ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr), ++#endif + map->timeout, -+ hash_ip, -+ GFP_ATOMIC); ++ hash_ip); +} + +#define DELIP_WALK(map, elem, branch) do { \ @@ -4530,8 +4808,13 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_iptree.c +{ + return __delip(set, + ntohl(flags[index] & IPSET_SRC -+ ? ip_hdr(skb)->saddr ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr + : ip_hdr(skb)->daddr), ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr), ++#endif + hash_ip); +} + @@ -4792,21 +5075,33 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_iptree.c +module_param(limit, int, 0600); +MODULE_PARM_DESC(limit, "maximal number of elements stored in the sets"); + -+static int __init init(void) ++static int __init ip_set_iptree_init(void) +{ + int ret; + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) ++ branch_cachep = kmem_cache_create("ip_set_iptreeb", ++ sizeof(struct ip_set_iptreeb), ++ 0, 0, NULL); ++#else + branch_cachep = kmem_cache_create("ip_set_iptreeb", + sizeof(struct ip_set_iptreeb), + 0, 0, NULL, NULL); ++#endif + if (!branch_cachep) { + printk(KERN_ERR "Unable to create ip_set_iptreeb slab cache\n"); + ret = -ENOMEM; + goto out; + } ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) ++ leaf_cachep = kmem_cache_create("ip_set_iptreed", ++ sizeof(struct ip_set_iptreed), ++ 0, 0, NULL); ++#else + leaf_cachep = kmem_cache_create("ip_set_iptreed", + sizeof(struct ip_set_iptreed), + 0, 0, NULL, NULL); ++#endif + if (!leaf_cachep) { + printk(KERN_ERR "Unable to create ip_set_iptreed slab cache\n"); + ret = -ENOMEM; @@ -4823,7 +5118,7 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_iptree.c + return ret; +} + -+static void __exit fini(void) ++static void __exit ip_set_iptree_fini(void) +{ + /* FIXME: possible race with ip_set_create() */ + ip_set_unregister_set_type(&ip_set_iptree); @@ -4831,13 +5126,845 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_iptree.c + kmem_cache_destroy(branch_cachep); +} + -+module_init(init); -+module_exit(fini); -Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_macipmap.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_macipmap.c 2007-06-19 23:19:01.000000000 +0100 -@@ -0,0 +1,353 @@ ++module_init(ip_set_iptree_init); ++module_exit(ip_set_iptree_fini); +diff -Nru ./linux-2.6.22.4/net/ipv4/netfilter/ip_set_iptreemap.c linux-2.6.22.4.pom2patch.set/net/ipv4/netfilter/ip_set_iptreemap.c +--- ./linux-2.6.22.4/net/ipv4/netfilter/ip_set_iptreemap.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22.4.pom2patch.set/net/ipv4/netfilter/ip_set_iptreemap.c 2007-10-12 14:31:55.000000000 +0200 +@@ -0,0 +1,829 @@ ++/* Copyright (C) 2007 Sven Wegener ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published by ++ * the Free Software Foundation. ++ */ ++ ++/* This modules implements the iptreemap ipset type. It uses bitmaps to ++ * represent every single IPv4 address as a single bit. The bitmaps are managed ++ * in a tree structure, where the first three octets of an addresses are used ++ * as an index to find the bitmap and the last octet is used as the bit number. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#define IPTREEMAP_DEFAULT_GC_TIME (5 * 60) ++#define IPTREEMAP_DESTROY_SLEEP (100) ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21) ++static struct kmem_cache *cachep_b; ++static struct kmem_cache *cachep_c; ++static struct kmem_cache *cachep_d; ++#else ++static kmem_cache_t *cachep_b; ++static kmem_cache_t *cachep_c; ++static kmem_cache_t *cachep_d; ++#endif ++ ++static struct ip_set_iptreemap_d *fullbitmap_d; ++static struct ip_set_iptreemap_c *fullbitmap_c; ++static struct ip_set_iptreemap_b *fullbitmap_b; ++ ++#if defined(__LITTLE_ENDIAN) ++#define ABCD(a, b, c, d, addr) \ ++ do { \ ++ a = ((unsigned char *)addr)[3]; \ ++ b = ((unsigned char *)addr)[2]; \ ++ c = ((unsigned char *)addr)[1]; \ ++ d = ((unsigned char *)addr)[0]; \ ++ } while (0) ++#elif defined(__BIG_ENDIAN) ++#define ABCD(a,b,c,d,addrp) do { \ ++ a = ((unsigned char *)addrp)[0]; \ ++ b = ((unsigned char *)addrp)[1]; \ ++ c = ((unsigned char *)addrp)[2]; \ ++ d = ((unsigned char *)addrp)[3]; \ ++} while (0) ++#else ++#error "Please fix asm/byteorder.h" ++#endif /* __LITTLE_ENDIAN */ ++ ++#define TESTIP_WALK(map, elem, branch, full) \ ++ do { \ ++ branch = (map)->tree[elem]; \ ++ if (!branch) \ ++ return 0; \ ++ else if (branch == full) \ ++ return 1; \ ++ } while (0) ++ ++#define ADDIP_WALK(map, elem, branch, type, cachep, full) \ ++ do { \ ++ branch = (map)->tree[elem]; \ ++ if (!branch) { \ ++ branch = (type *) kmem_cache_alloc(cachep, GFP_ATOMIC); \ ++ if (!branch) \ ++ return -ENOMEM; \ ++ memset(branch, 0, sizeof(*branch)); \ ++ (map)->tree[elem] = branch; \ ++ } else if (branch == full) { \ ++ return -EEXIST; \ ++ } \ ++ } while (0) ++ ++#define ADDIP_RANGE_LOOP(map, a, a1, a2, hint, branch, full, cachep, free) \ ++ for (a = a1; a <= a2; a++) { \ ++ branch = (map)->tree[a]; \ ++ if (branch != full) { \ ++ if ((a > a1 && a < a2) || (hint)) { \ ++ if (branch) \ ++ free(branch); \ ++ (map)->tree[a] = full; \ ++ continue; \ ++ } else if (!branch) { \ ++ branch = kmem_cache_alloc(cachep, GFP_ATOMIC); \ ++ if (!branch) \ ++ return -ENOMEM; \ ++ memset(branch, 0, sizeof(*branch)); \ ++ (map)->tree[a] = branch; \ ++ } ++ ++#define ADDIP_RANGE_LOOP_END() \ ++ } \ ++ } ++ ++#define DELIP_WALK(map, elem, branch, cachep, full, flags) \ ++ do { \ ++ branch = (map)->tree[elem]; \ ++ if (!branch) { \ ++ return -EEXIST; \ ++ } else if (branch == full) { \ ++ branch = kmem_cache_alloc(cachep, flags); \ ++ if (!branch) \ ++ return -ENOMEM; \ ++ memcpy(branch, full, sizeof(*full)); \ ++ (map)->tree[elem] = branch; \ ++ } \ ++ } while (0) ++ ++#define DELIP_RANGE_LOOP(map, a, a1, a2, hint, branch, full, cachep, free, flags) \ ++ for (a = a1; a <= a2; a++) { \ ++ branch = (map)->tree[a]; \ ++ if (branch) { \ ++ if ((a > a1 && a < a2) || (hint)) { \ ++ if (branch != full) \ ++ free(branch); \ ++ (map)->tree[a] = NULL; \ ++ continue; \ ++ } else if (branch == full) { \ ++ branch = kmem_cache_alloc(cachep, flags); \ ++ if (!branch) \ ++ return -ENOMEM; \ ++ memcpy(branch, full, sizeof(*branch)); \ ++ (map)->tree[a] = branch; \ ++ } ++ ++#define DELIP_RANGE_LOOP_END() \ ++ } \ ++ } ++ ++#define LOOP_WALK_BEGIN(map, i, branch) \ ++ for (i = 0; i < 256; i++) { \ ++ branch = (map)->tree[i]; \ ++ if (likely(!branch)) \ ++ continue; ++ ++#define LOOP_WALK_END() \ ++ } ++ ++#define LOOP_WALK_BEGIN_GC(map, i, branch, full, cachep, count) \ ++ count = -256; \ ++ for (i = 0; i < 256; i++) { \ ++ branch = (map)->tree[i]; \ ++ if (likely(!branch)) \ ++ continue; \ ++ count++; \ ++ if (branch == full) { \ ++ count++; \ ++ continue; \ ++ } ++ ++#define LOOP_WALK_END_GC(map, i, branch, full, cachep, count) \ ++ if (-256 == count) { \ ++ kmem_cache_free(cachep, branch); \ ++ (map)->tree[i] = NULL; \ ++ } else if (256 == count) { \ ++ kmem_cache_free(cachep, branch); \ ++ (map)->tree[i] = full; \ ++ } \ ++ } ++ ++#define LOOP_WALK_BEGIN_COUNT(map, i, branch, inrange, count) \ ++ for (i = 0; i < 256; i++) { \ ++ if (!(map)->tree[i]) { \ ++ if (inrange) { \ ++ count++; \ ++ inrange = 0; \ ++ } \ ++ continue; \ ++ } \ ++ branch = (map)->tree[i]; ++ ++#define LOOP_WALK_END_COUNT() \ ++ } ++ ++#define MIN(a, b) (a < b ? a : b) ++#define MAX(a, b) (a > b ? a : b) ++ ++#define GETVALUE1(a, a1, b1, r) \ ++ (a == a1 ? b1 : r) ++ ++#define GETVALUE2(a, b, a1, b1, c1, r) \ ++ (a == a1 && b == b1 ? c1 : r) ++ ++#define GETVALUE3(a, b, c, a1, b1, c1, d1, r) \ ++ (a == a1 && b == b1 && c == c1 ? d1 : r) ++ ++#define CHECK1(a, a1, a2, b1, b2, c1, c2, d1, d2) \ ++ ( \ ++ GETVALUE1(a, a1, b1, 0) == 0 \ ++ && GETVALUE1(a, a2, b2, 255) == 255 \ ++ && c1 == 0 \ ++ && c2 == 255 \ ++ && d1 == 0 \ ++ && d2 == 255 \ ++ ) ++ ++#define CHECK2(a, b, a1, a2, b1, b2, c1, c2, d1, d2) \ ++ ( \ ++ GETVALUE2(a, b, a1, b1, c1, 0) == 0 \ ++ && GETVALUE2(a, b, a2, b2, c2, 255) == 255 \ ++ && d1 == 0 \ ++ && d2 == 255 \ ++ ) ++ ++#define CHECK3(a, b, c, a1, a2, b1, b2, c1, c2, d1, d2) \ ++ ( \ ++ GETVALUE3(a, b, c, a1, b1, c1, d1, 0) == 0 \ ++ && GETVALUE3(a, b, c, a2, b2, c2, d2, 255) == 255 \ ++ ) ++ ++ ++static inline void ++free_d(struct ip_set_iptreemap_d *map) ++{ ++ kmem_cache_free(cachep_d, map); ++} ++ ++static inline void ++free_c(struct ip_set_iptreemap_c *map) ++{ ++ struct ip_set_iptreemap_d *dtree; ++ unsigned int i; ++ ++ LOOP_WALK_BEGIN(map, i, dtree) { ++ if (dtree != fullbitmap_d) ++ free_d(dtree); ++ } LOOP_WALK_END(); ++ ++ kmem_cache_free(cachep_c, map); ++} ++ ++static inline void ++free_b(struct ip_set_iptreemap_b *map) ++{ ++ struct ip_set_iptreemap_c *ctree; ++ unsigned int i; ++ ++ LOOP_WALK_BEGIN(map, i, ctree) { ++ if (ctree != fullbitmap_c) ++ free_c(ctree); ++ } LOOP_WALK_END(); ++ ++ kmem_cache_free(cachep_b, map); ++} ++ ++static inline int ++__testip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip) ++{ ++ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; ++ struct ip_set_iptreemap_b *btree; ++ struct ip_set_iptreemap_c *ctree; ++ struct ip_set_iptreemap_d *dtree; ++ unsigned char a, b, c, d; ++ ++ *hash_ip = ip; ++ ++ ABCD(a, b, c, d, hash_ip); ++ ++ TESTIP_WALK(map, a, btree, fullbitmap_b); ++ TESTIP_WALK(btree, b, ctree, fullbitmap_c); ++ TESTIP_WALK(ctree, c, dtree, fullbitmap_d); ++ ++ return !!test_bit(d, (void *) dtree->bitmap); ++} ++ ++static int ++testip(struct ip_set *set, const void *data, size_t size, ip_set_ip_t *hash_ip) ++{ ++ struct ip_set_req_iptreemap *req = (struct ip_set_req_iptreemap *) data; ++ ++ if (size != sizeof(struct ip_set_req_iptreemap)) { ++ ip_set_printk("data length wrong (want %zu, have %zu)", sizeof(struct ip_set_req_iptreemap), size); ++ return -EINVAL; ++ } ++ ++ return __testip(set, req->start, hash_ip); ++} ++ ++static int ++testip_kernel(struct ip_set *set, const struct sk_buff *skb, ip_set_ip_t *hash_ip, const u_int32_t *flags, unsigned char index) ++{ ++ int res; ++ ++ res = __testip(set, ++ ntohl(flags[index] & IPSET_SRC ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr ++ : ip_hdr(skb)->daddr), ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr), ++#endif ++ hash_ip); ++ ++ return (res < 0 ? 0 : res); ++} ++ ++static inline int ++__addip_single(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip) ++{ ++ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; ++ struct ip_set_iptreemap_b *btree; ++ struct ip_set_iptreemap_c *ctree; ++ struct ip_set_iptreemap_d *dtree; ++ unsigned char a, b, c, d; ++ ++ *hash_ip = ip; ++ ++ ABCD(a, b, c, d, hash_ip); ++ ++ ADDIP_WALK(map, a, btree, struct ip_set_iptreemap_b, cachep_b, fullbitmap_b); ++ ADDIP_WALK(btree, b, ctree, struct ip_set_iptreemap_c, cachep_c, fullbitmap_c); ++ ADDIP_WALK(ctree, c, dtree, struct ip_set_iptreemap_d, cachep_d, fullbitmap_d); ++ ++ if (test_and_set_bit(d, (void *) dtree->bitmap)) ++ return -EEXIST; ++ ++ set_bit(b, (void *) btree->dirty); ++ ++ return 0; ++} ++ ++static inline int ++__addip_range(struct ip_set *set, ip_set_ip_t start, ip_set_ip_t end, ip_set_ip_t *hash_ip) ++{ ++ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; ++ struct ip_set_iptreemap_b *btree; ++ struct ip_set_iptreemap_c *ctree; ++ struct ip_set_iptreemap_d *dtree; ++ unsigned int a, b, c, d; ++ unsigned char a1, b1, c1, d1; ++ unsigned char a2, b2, c2, d2; ++ ++ if (start == end) ++ return __addip_single(set, start, hash_ip); ++ ++ *hash_ip = start; ++ ++ ABCD(a1, b1, c1, d1, &start); ++ ABCD(a2, b2, c2, d2, &end); ++ ++ /* This is sooo ugly... */ ++ ADDIP_RANGE_LOOP(map, a, a1, a2, CHECK1(a, a1, a2, b1, b2, c1, c2, d1, d2), btree, fullbitmap_b, cachep_b, free_b) { ++ ADDIP_RANGE_LOOP(btree, b, GETVALUE1(a, a1, b1, 0), GETVALUE1(a, a2, b2, 255), CHECK2(a, b, a1, a2, b1, b2, c1, c2, d1, d2), ctree, fullbitmap_c, cachep_c, free_c) { ++ ADDIP_RANGE_LOOP(ctree, c, GETVALUE2(a, b, a1, b1, c1, 0), GETVALUE2(a, b, a2, b2, c2, 255), CHECK3(a, b, c, a1, a2, b1, b2, c1, c2, d1, d2), dtree, fullbitmap_d, cachep_d, free_d) { ++ for (d = GETVALUE3(a, b, c, a1, b1, c1, d1, 0); d <= GETVALUE3(a, b, c, a2, b2, c2, d2, 255); d++) ++ set_bit(d, (void *) dtree->bitmap); ++ set_bit(b, (void *) btree->dirty); ++ } ADDIP_RANGE_LOOP_END(); ++ } ADDIP_RANGE_LOOP_END(); ++ } ADDIP_RANGE_LOOP_END(); ++ ++ return 0; ++} ++ ++static int ++addip(struct ip_set *set, const void *data, size_t size, ip_set_ip_t *hash_ip) ++{ ++ struct ip_set_req_iptreemap *req = (struct ip_set_req_iptreemap *) data; ++ ++ if (size != sizeof(struct ip_set_req_iptreemap)) { ++ ip_set_printk("data length wrong (want %zu, have %zu)", sizeof(struct ip_set_req_iptreemap), size); ++ return -EINVAL; ++ } ++ ++ return __addip_range(set, MIN(req->start, req->end), MAX(req->start, req->end), hash_ip); ++} ++ ++static int ++addip_kernel(struct ip_set *set, const struct sk_buff *skb, ip_set_ip_t *hash_ip, const u_int32_t *flags, unsigned char index) ++{ ++ ++ return __addip_single(set, ++ ntohl(flags[index] & IPSET_SRC ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr ++ : ip_hdr(skb)->daddr), ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr), ++#endif ++ hash_ip); ++} ++ ++static inline int ++__delip_single(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip, unsigned int __nocast flags) ++{ ++ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; ++ struct ip_set_iptreemap_b *btree; ++ struct ip_set_iptreemap_c *ctree; ++ struct ip_set_iptreemap_d *dtree; ++ unsigned char a,b,c,d; ++ ++ *hash_ip = ip; ++ ++ ABCD(a, b, c, d, hash_ip); ++ ++ DELIP_WALK(map, a, btree, cachep_b, fullbitmap_b, flags); ++ DELIP_WALK(btree, b, ctree, cachep_c, fullbitmap_c, flags); ++ DELIP_WALK(ctree, c, dtree, cachep_d, fullbitmap_d, flags); ++ ++ if (!test_and_clear_bit(d, (void *) dtree->bitmap)) ++ return -EEXIST; ++ ++ set_bit(b, (void *) btree->dirty); ++ ++ return 0; ++} ++ ++static inline int ++__delip_range(struct ip_set *set, ip_set_ip_t start, ip_set_ip_t end, ip_set_ip_t *hash_ip, unsigned int __nocast flags) ++{ ++ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; ++ struct ip_set_iptreemap_b *btree; ++ struct ip_set_iptreemap_c *ctree; ++ struct ip_set_iptreemap_d *dtree; ++ unsigned int a, b, c, d; ++ unsigned char a1, b1, c1, d1; ++ unsigned char a2, b2, c2, d2; ++ ++ if (start == end) ++ return __delip_single(set, start, hash_ip, flags); ++ ++ *hash_ip = start; ++ ++ ABCD(a1, b1, c1, d1, &start); ++ ABCD(a2, b2, c2, d2, &end); ++ ++ /* This is sooo ugly... */ ++ DELIP_RANGE_LOOP(map, a, a1, a2, CHECK1(a, a1, a2, b1, b2, c1, c2, d1, d2), btree, fullbitmap_b, cachep_b, free_b, flags) { ++ DELIP_RANGE_LOOP(btree, b, GETVALUE1(a, a1, b1, 0), GETVALUE1(a, a2, b2, 255), CHECK2(a, b, a1, a2, b1, b2, c1, c2, d1, d2), ctree, fullbitmap_c, cachep_c, free_c, flags) { ++ DELIP_RANGE_LOOP(ctree, c, GETVALUE2(a, b, a1, b1, c1, 0), GETVALUE2(a, b, a2, b2, c2, 255), CHECK3(a, b, c, a1, a2, b1, b2, c1, c2, d1, d2), dtree, fullbitmap_d, cachep_d, free_d, flags) { ++ for (d = GETVALUE3(a, b, c, a1, b1, c1, d1, 0); d <= GETVALUE3(a, b, c, a2, b2, c2, d2, 255); d++) ++ clear_bit(d, (void *) dtree->bitmap); ++ set_bit(b, (void *) btree->dirty); ++ } DELIP_RANGE_LOOP_END(); ++ } DELIP_RANGE_LOOP_END(); ++ } DELIP_RANGE_LOOP_END(); ++ ++ return 0; ++} ++ ++static int ++delip(struct ip_set *set, const void *data, size_t size, ip_set_ip_t *hash_ip) ++{ ++ struct ip_set_req_iptreemap *req = (struct ip_set_req_iptreemap *) data; ++ ++ if (size != sizeof(struct ip_set_req_iptreemap)) { ++ ip_set_printk("data length wrong (want %zu, have %zu)", sizeof(struct ip_set_req_iptreemap), size); ++ return -EINVAL; ++ } ++ ++ return __delip_range(set, MIN(req->start, req->end), MAX(req->start, req->end), hash_ip, GFP_KERNEL); ++} ++ ++static int ++delip_kernel(struct ip_set *set, const struct sk_buff *skb, ip_set_ip_t *hash_ip, const u_int32_t *flags, unsigned char index) ++{ ++ return __delip_single(set, ++ ntohl(flags[index] & IPSET_SRC ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr ++ : ip_hdr(skb)->daddr), ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr), ++#endif ++ hash_ip, ++ GFP_ATOMIC); ++} ++ ++/* Check the status of the bitmap ++ * -1 == all bits cleared ++ * 1 == all bits set ++ * 0 == anything else ++ */ ++static inline int ++bitmap_status(struct ip_set_iptreemap_d *dtree) ++{ ++ unsigned char first = dtree->bitmap[0]; ++ int a; ++ ++ for (a = 1; a < 32; a++) ++ if (dtree->bitmap[a] != first) ++ return 0; ++ ++ return (first == 0 ? -1 : (first == 255 ? 1 : 0)); ++} ++ ++static void ++gc(unsigned long addr) ++{ ++ struct ip_set *set = (struct ip_set *) addr; ++ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; ++ struct ip_set_iptreemap_b *btree; ++ struct ip_set_iptreemap_c *ctree; ++ struct ip_set_iptreemap_d *dtree; ++ unsigned int a, b, c; ++ int i, j, k; ++ ++ write_lock_bh(&set->lock); ++ ++ LOOP_WALK_BEGIN_GC(map, a, btree, fullbitmap_b, cachep_b, i) { ++ LOOP_WALK_BEGIN_GC(btree, b, ctree, fullbitmap_c, cachep_c, j) { ++ if (!test_and_clear_bit(b, (void *) btree->dirty)) ++ continue; ++ LOOP_WALK_BEGIN_GC(ctree, c, dtree, fullbitmap_d, cachep_d, k) { ++ switch (bitmap_status(dtree)) { ++ case -1: ++ kmem_cache_free(cachep_d, dtree); ++ ctree->tree[c] = NULL; ++ k--; ++ break; ++ case 1: ++ kmem_cache_free(cachep_d, dtree); ++ ctree->tree[c] = fullbitmap_d; ++ k++; ++ break; ++ } ++ } LOOP_WALK_END(); ++ } LOOP_WALK_END_GC(btree, b, ctree, fullbitmap_c, cachep_c, k); ++ } LOOP_WALK_END_GC(map, a, btree, fullbitmap_b, cachep_b, j); ++ ++ write_unlock_bh(&set->lock); ++ ++ map->gc.expires = jiffies + map->gc_interval * HZ; ++ add_timer(&map->gc); ++} ++ ++static inline void ++init_gc_timer(struct ip_set *set) ++{ ++ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; ++ ++ init_timer(&map->gc); ++ map->gc.data = (unsigned long) set; ++ map->gc.function = gc; ++ map->gc.expires = jiffies + map->gc_interval * HZ; ++ add_timer(&map->gc); ++} ++ ++static int create(struct ip_set *set, const void *data, size_t size) ++{ ++ struct ip_set_req_iptreemap_create *req = (struct ip_set_req_iptreemap_create *) data; ++ struct ip_set_iptreemap *map; ++ ++ if (size != sizeof(struct ip_set_req_iptreemap_create)) { ++ ip_set_printk("data length wrong (want %zu, have %zu)", sizeof(struct ip_set_req_iptreemap_create), size); ++ return -EINVAL; ++ } ++ ++ map = kzalloc(sizeof(*map), GFP_KERNEL); ++ if (!map) ++ return -ENOMEM; ++ ++ map->gc_interval = req->gc_interval ? req->gc_interval : IPTREEMAP_DEFAULT_GC_TIME; ++ set->data = map; ++ ++ init_gc_timer(set); ++ ++ return 0; ++} ++ ++static inline void __flush(struct ip_set_iptreemap *map) ++{ ++ struct ip_set_iptreemap_b *btree; ++ unsigned int a; ++ ++ LOOP_WALK_BEGIN(map, a, btree); ++ if (btree != fullbitmap_b) ++ free_b(btree); ++ LOOP_WALK_END(); ++} ++ ++static void destroy(struct ip_set *set) ++{ ++ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; ++ ++ while (!del_timer(&map->gc)) ++ msleep(IPTREEMAP_DESTROY_SLEEP); ++ ++ __flush(map); ++ kfree(map); ++ ++ set->data = NULL; ++} ++ ++static void flush(struct ip_set *set) ++{ ++ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; ++ ++ while (!del_timer(&map->gc)) ++ msleep(IPTREEMAP_DESTROY_SLEEP); ++ ++ __flush(map); ++ ++ memset(map, 0, sizeof(*map)); ++ ++ init_gc_timer(set); ++} ++ ++static void list_header(const struct ip_set *set, void *data) ++{ ++ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; ++ struct ip_set_req_iptreemap_create *header = (struct ip_set_req_iptreemap_create *) data; ++ ++ header->gc_interval = map->gc_interval; ++} ++ ++static int list_members_size(const struct ip_set *set) ++{ ++ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; ++ struct ip_set_iptreemap_b *btree; ++ struct ip_set_iptreemap_c *ctree; ++ struct ip_set_iptreemap_d *dtree; ++ unsigned int a, b, c, d, inrange = 0, count = 0; ++ ++ LOOP_WALK_BEGIN_COUNT(map, a, btree, inrange, count) { ++ LOOP_WALK_BEGIN_COUNT(btree, b, ctree, inrange, count) { ++ LOOP_WALK_BEGIN_COUNT(ctree, c, dtree, inrange, count) { ++ for (d = 0; d < 256; d++) { ++ if (test_bit(d, (void *) dtree->bitmap)) { ++ inrange = 1; ++ } else if (inrange) { ++ count++; ++ inrange = 0; ++ } ++ } ++ } LOOP_WALK_END_COUNT(); ++ } LOOP_WALK_END_COUNT(); ++ } LOOP_WALK_END_COUNT(); ++ ++ if (inrange) ++ count++; ++ ++ return (count * sizeof(struct ip_set_req_iptreemap)); ++} ++ ++static inline size_t add_member(void *data, size_t offset, ip_set_ip_t start, ip_set_ip_t end) ++{ ++ struct ip_set_req_iptreemap *entry = (struct ip_set_req_iptreemap *) (data + offset); ++ ++ entry->start = start; ++ entry->end = end; ++ ++ return sizeof(*entry); ++} ++ ++static void list_members(const struct ip_set *set, void *data) ++{ ++ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; ++ struct ip_set_iptreemap_b *btree; ++ struct ip_set_iptreemap_c *ctree; ++ struct ip_set_iptreemap_d *dtree; ++ unsigned int a, b, c, d, inrange = 0; ++ size_t offset = 0; ++ ip_set_ip_t start = 0, end = 0, ip; ++ ++ LOOP_WALK_BEGIN(map, a, btree) { ++ LOOP_WALK_BEGIN(btree, b, ctree) { ++ LOOP_WALK_BEGIN(ctree, c, dtree) { ++ for (d = 0; d < 256; d++) { ++ if (test_bit(d, (void *) dtree->bitmap)) { ++ ip = ((a << 24) | (b << 16) | (c << 8) | d); ++ if (!inrange) { ++ inrange = 1; ++ start = ip; ++ } else if (end < ip - 1) { ++ offset += add_member(data, offset, start, end); ++ start = ip; ++ } ++ end = ip; ++ } else if (inrange) { ++ offset += add_member(data, offset, start, end); ++ inrange = 0; ++ } ++ } ++ } LOOP_WALK_END(); ++ } LOOP_WALK_END(); ++ } LOOP_WALK_END(); ++ ++ if (inrange) ++ add_member(data, offset, start, end); ++} ++ ++static struct ip_set_type ip_set_iptreemap = { ++ .typename = SETTYPE_NAME, ++ .features = IPSET_TYPE_IP | IPSET_DATA_SINGLE, ++ .protocol_version = IP_SET_PROTOCOL_VERSION, ++ .create = create, ++ .destroy = destroy, ++ .flush = flush, ++ .reqsize = sizeof(struct ip_set_req_iptreemap), ++ .addip = addip, ++ .addip_kernel = addip_kernel, ++ .delip = delip, ++ .delip_kernel = delip_kernel, ++ .testip = testip, ++ .testip_kernel = testip_kernel, ++ .header_size = sizeof(struct ip_set_req_iptreemap_create), ++ .list_header = list_header, ++ .list_members_size = list_members_size, ++ .list_members = list_members, ++ .me = THIS_MODULE, ++}; ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Sven Wegener "); ++MODULE_DESCRIPTION("iptreemap type of IP sets"); ++ ++static int __init ip_set_iptreemap_init(void) ++{ ++ int ret = -ENOMEM; ++ int a; ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) ++ cachep_b = kmem_cache_create("ip_set_iptreemap_b", ++ sizeof(struct ip_set_iptreemap_b), ++ 0, 0, NULL); ++#else ++ cachep_b = kmem_cache_create("ip_set_iptreemap_b", ++ sizeof(struct ip_set_iptreemap_b), ++ 0, 0, NULL, NULL); ++#endif ++ if (!cachep_b) { ++ ip_set_printk("Unable to create ip_set_iptreemap_b slab cache"); ++ goto out; ++ } ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) ++ cachep_c = kmem_cache_create("ip_set_iptreemap_c", ++ sizeof(struct ip_set_iptreemap_c), ++ 0, 0, NULL); ++#else ++ cachep_c = kmem_cache_create("ip_set_iptreemap_c", ++ sizeof(struct ip_set_iptreemap_c), ++ 0, 0, NULL, NULL); ++#endif ++ if (!cachep_c) { ++ ip_set_printk("Unable to create ip_set_iptreemap_c slab cache"); ++ goto outb; ++ } ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) ++ cachep_d = kmem_cache_create("ip_set_iptreemap_d", ++ sizeof(struct ip_set_iptreemap_d), ++ 0, 0, NULL); ++#else ++ cachep_d = kmem_cache_create("ip_set_iptreemap_d", ++ sizeof(struct ip_set_iptreemap_d), ++ 0, 0, NULL, NULL); ++#endif ++ if (!cachep_d) { ++ ip_set_printk("Unable to create ip_set_iptreemap_d slab cache"); ++ goto outc; ++ } ++ ++ fullbitmap_d = kmem_cache_alloc(cachep_d, GFP_KERNEL); ++ if (!fullbitmap_d) ++ goto outd; ++ ++ fullbitmap_c = kmem_cache_alloc(cachep_c, GFP_KERNEL); ++ if (!fullbitmap_c) ++ goto outbitmapd; ++ ++ fullbitmap_b = kmem_cache_alloc(cachep_b, GFP_KERNEL); ++ if (!fullbitmap_b) ++ goto outbitmapc; ++ ++ ret = ip_set_register_set_type(&ip_set_iptreemap); ++ if (0 > ret) ++ goto outbitmapb; ++ ++ /* Now init our global bitmaps */ ++ memset(fullbitmap_d->bitmap, 0xff, sizeof(fullbitmap_d->bitmap)); ++ ++ for (a = 0; a < 256; a++) ++ fullbitmap_c->tree[a] = fullbitmap_d; ++ ++ for (a = 0; a < 256; a++) ++ fullbitmap_b->tree[a] = fullbitmap_c; ++ memset(fullbitmap_b->dirty, 0, sizeof(fullbitmap_b->dirty)); ++ ++ return 0; ++ ++outbitmapb: ++ kmem_cache_free(cachep_b, fullbitmap_b); ++outbitmapc: ++ kmem_cache_free(cachep_c, fullbitmap_c); ++outbitmapd: ++ kmem_cache_free(cachep_d, fullbitmap_d); ++outd: ++ kmem_cache_destroy(cachep_d); ++outc: ++ kmem_cache_destroy(cachep_c); ++outb: ++ kmem_cache_destroy(cachep_b); ++out: ++ ++ return ret; ++} ++ ++static void __exit ip_set_iptreemap_fini(void) ++{ ++ ip_set_unregister_set_type(&ip_set_iptreemap); ++ kmem_cache_free(cachep_d, fullbitmap_d); ++ kmem_cache_free(cachep_c, fullbitmap_c); ++ kmem_cache_free(cachep_b, fullbitmap_b); ++ kmem_cache_destroy(cachep_d); ++ kmem_cache_destroy(cachep_c); ++ kmem_cache_destroy(cachep_b); ++} ++ ++module_init(ip_set_iptreemap_init); ++module_exit(ip_set_iptreemap_fini); +diff -Nru ./linux-2.6.22.4/net/ipv4/netfilter/ip_set_macipmap.c linux-2.6.22.4.pom2patch.set/net/ipv4/netfilter/ip_set_macipmap.c +--- ./linux-2.6.22.4/net/ipv4/netfilter/ip_set_macipmap.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22.4.pom2patch.set/net/ipv4/netfilter/ip_set_macipmap.c 2007-10-12 14:31:55.000000000 +0200 +@@ -0,0 +1,375 @@ +/* Copyright (C) 2000-2002 Joakim Axelsson + * Patrick Schaaf + * Martin Josefsson @@ -4853,6 +5980,7 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_macipmap.c +#include +#include +#include ++#include +#include +#include +#include @@ -4909,12 +6037,13 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_macipmap.c + ip_set_ip_t ip; + + ip = ntohl(flags[index] & IPSET_SRC -+ ? ip_hdr(skb)->saddr ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr + : ip_hdr(skb)->daddr); -+ DP("flag: %s src: %u.%u.%u.%u dst: %u.%u.%u.%u", -+ flags[index] & IPSET_SRC ? "SRC" : "DST", -+ NIPQUAD(ip_hdr(skb)->saddr), -+ NIPQUAD(ip_hdr(skb)->daddr)); ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr); ++#endif + + if (ip < map->first_ip || ip > map->last_ip) + return 0; @@ -4926,8 +6055,13 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_macipmap.c + (void *) &table[ip - map->first_ip].flags)) { + /* Is mac pointer valid? + * If so, compare... */ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + return (skb_mac_header(skb) >= skb->head + && (skb_mac_header(skb) + ETH_HLEN) <= skb->data ++#else ++ return (skb->mac.raw >= skb->head ++ && (skb->mac.raw + ETH_HLEN) <= skb->data ++#endif + && (memcmp(eth_hdr(skb)->h_source, + &table[ip - map->first_ip].ethernet, + ETH_ALEN) == 0)); @@ -4984,11 +6118,21 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_macipmap.c + ip_set_ip_t ip; + + ip = ntohl(flags[index] & IPSET_SRC -+ ? ip_hdr(skb)->saddr ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr + : ip_hdr(skb)->daddr); ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr); ++#endif + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + if (!(skb_mac_header(skb) >= skb->head + && (skb_mac_header(skb) + ETH_HLEN) <= skb->data)) ++#else ++ if (!(skb->mac.raw >= skb->head ++ && (skb->mac.raw + ETH_HLEN) <= skb->data)) ++#endif + return -EINVAL; + + return __addip(set, ip, eth_hdr(skb)->h_source, hash_ip); @@ -5038,8 +6182,13 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_macipmap.c +{ + return __delip(set, + ntohl(flags[index] & IPSET_SRC -+ ? ip_hdr(skb)->saddr ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr + : ip_hdr(skb)->daddr), ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr), ++#endif + hash_ip); +} + @@ -5177,25 +6326,24 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_macipmap.c +MODULE_AUTHOR("Jozsef Kadlecsik "); +MODULE_DESCRIPTION("macipmap type of IP sets"); + -+static int __init init(void) ++static int __init ip_set_macipmap_init(void) +{ + init_max_malloc_size(); + return ip_set_register_set_type(&ip_set_macipmap); +} + -+static void __exit fini(void) ++static void __exit ip_set_macipmap_fini(void) +{ + /* FIXME: possible race with ip_set_create() */ + ip_set_unregister_set_type(&ip_set_macipmap); +} + -+module_init(init); -+module_exit(fini); -Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_nethash.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_nethash.c 2007-06-19 23:19:01.000000000 +0100 -@@ -0,0 +1,481 @@ ++module_init(ip_set_macipmap_init); ++module_exit(ip_set_macipmap_fini); +diff -Nru ./linux-2.6.22.4/net/ipv4/netfilter/ip_set_nethash.c linux-2.6.22.4.pom2patch.set/net/ipv4/netfilter/ip_set_nethash.c +--- ./linux-2.6.22.4/net/ipv4/netfilter/ip_set_nethash.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22.4.pom2patch.set/net/ipv4/netfilter/ip_set_nethash.c 2007-10-12 14:31:55.000000000 +0200 +@@ -0,0 +1,497 @@ +/* Copyright (C) 2003-2004 Jozsef Kadlecsik + * + * This program is free software; you can redistribute it and/or modify @@ -5208,6 +6356,8 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_nethash.c +#include +#include +#include ++#include ++#include +#include +#include +#include @@ -5216,7 +6366,6 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_nethash.c +#include +#include +#include -+#include + +#include + @@ -5309,8 +6458,13 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_nethash.c +{ + return __testip(set, + ntohl(flags[index] & IPSET_SRC ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + ? ip_hdr(skb)->saddr + : ip_hdr(skb)->daddr), ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr), ++#endif + hash_ip); +} + @@ -5340,7 +6494,7 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_nethash.c +__addip(struct ip_set_nethash *map, ip_set_ip_t ip, unsigned char cidr, + ip_set_ip_t *hash_ip) +{ -+ if (!ip || map->elements > limit) ++ if (!ip || map->elements >= limit) + return -ERANGE; + + *hash_ip = pack(ip, cidr); @@ -5402,8 +6556,13 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_nethash.c + struct ip_set_nethash *map = (struct ip_set_nethash *) set->data; + int ret = -ERANGE; + ip_set_ip_t ip = ntohl(flags[index] & IPSET_SRC -+ ? ip_hdr(skb)->saddr ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr + : ip_hdr(skb)->daddr); ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr); ++#endif + + if (map->cidr[0]) + ret = __addip(map, ip, map->cidr[0], hash_ip); @@ -5531,8 +6690,13 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_nethash.c + struct ip_set_nethash *map = (struct ip_set_nethash *) set->data; + int ret = -ERANGE; + ip_set_ip_t ip = ntohl(flags[index] & IPSET_SRC -+ ? ip_hdr(skb)->saddr ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr + : ip_hdr(skb)->daddr); ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr); ++#endif + + if (map->cidr[0]) + ret = __delip(map, ip, map->cidr[0], hash_ip); @@ -5664,24 +6828,23 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_nethash.c +module_param(limit, int, 0600); +MODULE_PARM_DESC(limit, "maximal number of elements stored in the sets"); + -+static int __init init(void) ++static int __init ip_set_nethash_init(void) +{ + return ip_set_register_set_type(&ip_set_nethash); +} + -+static void __exit fini(void) ++static void __exit ip_set_nethash_fini(void) +{ + /* FIXME: possible race with ip_set_create() */ + ip_set_unregister_set_type(&ip_set_nethash); +} + -+module_init(init); -+module_exit(fini); -Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_portmap.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_portmap.c 2007-06-19 23:19:01.000000000 +0100 -@@ -0,0 +1,334 @@ ++module_init(ip_set_nethash_init); ++module_exit(ip_set_nethash_fini); +diff -Nru ./linux-2.6.22.4/net/ipv4/netfilter/ip_set_portmap.c linux-2.6.22.4.pom2patch.set/net/ipv4/netfilter/ip_set_portmap.c +--- ./linux-2.6.22.4/net/ipv4/netfilter/ip_set_portmap.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22.4.pom2patch.set/net/ipv4/netfilter/ip_set_portmap.c 2007-10-12 14:31:55.000000000 +0200 +@@ -0,0 +1,346 @@ +/* Copyright (C) 2003-2004 Jozsef Kadlecsik + * + * This program is free software; you can redistribute it and/or modify @@ -5696,6 +6859,7 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_portmap.c +#include +#include +#include ++#include +#include +#include +#include @@ -5711,9 +6875,12 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_portmap.c +static inline ip_set_ip_t +get_port(const struct sk_buff *skb, u_int32_t flags) +{ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + struct iphdr *iph = ip_hdr(skb); ++#else ++ struct iphdr *iph = skb->nh.iph; ++#endif + u_int16_t offset = ntohs(iph->frag_off) & IP_OFFSET; -+ + switch (iph->protocol) { + case IPPROTO_TCP: { + struct tcphdr tcph; @@ -5722,7 +6889,11 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_portmap.c + if (offset) + return INVALID_PORT; + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + if (skb_copy_bits(skb, ip_hdr(skb)->ihl*4, &tcph, sizeof(tcph)) < 0) ++#else ++ if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &tcph, sizeof(tcph)) < 0) ++#endif + /* No choice either */ + return INVALID_PORT; + @@ -5735,7 +6906,11 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_portmap.c + if (offset) + return INVALID_PORT; + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + if (skb_copy_bits(skb, ip_hdr(skb)->ihl*4, &udph, sizeof(udph)) < 0) ++#else ++ if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &udph, sizeof(udph)) < 0) ++#endif + /* No choice either */ + return INVALID_PORT; + @@ -6003,24 +7178,23 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ip_set_portmap.c +MODULE_AUTHOR("Jozsef Kadlecsik "); +MODULE_DESCRIPTION("portmap type of IP sets"); + -+static int __init init(void) ++static int __init ip_set_portmap_init(void) +{ + return ip_set_register_set_type(&ip_set_portmap); +} + -+static void __exit fini(void) ++static void __exit ip_set_portmap_fini(void) +{ + /* FIXME: possible race with ip_set_create() */ + ip_set_unregister_set_type(&ip_set_portmap); +} + -+module_init(init); -+module_exit(fini); -Index: linux-2.6.22-rc5/net/ipv4/netfilter/ipt_set.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.22-rc5/net/ipv4/netfilter/ipt_set.c 2007-06-19 23:19:01.000000000 +0100 -@@ -0,0 +1,150 @@ ++module_init(ip_set_portmap_init); ++module_exit(ip_set_portmap_fini); +diff -Nru ./linux-2.6.22.4/net/ipv4/netfilter/ipt_set.c linux-2.6.22.4.pom2patch.set/net/ipv4/netfilter/ipt_set.c +--- ./linux-2.6.22.4/net/ipv4/netfilter/ipt_set.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22.4.pom2patch.set/net/ipv4/netfilter/ipt_set.c 2007-10-12 14:31:55.000000000 +0200 +@@ -0,0 +1,160 @@ +/* Copyright (C) 2000-2002 Joakim Axelsson + * Patrick Schaaf + * Martin Josefsson @@ -6052,7 +7226,11 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ipt_set.c + return inv; +} + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) ++static bool ++#else +static int ++#endif +match(const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, @@ -6060,7 +7238,9 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ipt_set.c + const struct xt_match *match, +#endif + const void *matchinfo, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) ++ int offset, unsigned int protoff, bool *hotdrop) ++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) + int offset, unsigned int protoff, int *hotdrop) +#else + int offset, int *hotdrop) @@ -6073,7 +7253,11 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ipt_set.c + info->match_set.flags[0] & IPSET_MATCH_INV); +} + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) ++bool ++#else +static int ++#endif +checkentry(const char *tablename, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) + const void *inf, @@ -6171,11 +7355,10 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ipt_set.c + +module_init(ipt_ipset_init); +module_exit(ipt_ipset_fini); -Index: linux-2.6.22-rc5/net/ipv4/netfilter/ipt_SET.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.22-rc5/net/ipv4/netfilter/ipt_SET.c 2007-06-19 23:19:01.000000000 +0100 -@@ -0,0 +1,169 @@ +diff -Nru ./linux-2.6.22.4/net/ipv4/netfilter/ipt_SET.c linux-2.6.22.4.pom2patch.set/net/ipv4/netfilter/ipt_SET.c +--- ./linux-2.6.22.4/net/ipv4/netfilter/ipt_SET.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.22.4.pom2patch.set/net/ipv4/netfilter/ipt_SET.c 2007-10-12 14:31:55.000000000 +0200 +@@ -0,0 +1,172 @@ +/* Copyright (C) 2000-2002 Joakim Axelsson + * Patrick Schaaf + * Martin Josefsson @@ -6197,7 +7380,6 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ipt_SET.c +#include +#include +#include -+#include +#include +#include +#include @@ -6233,7 +7415,11 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ipt_SET.c + return IPT_CONTINUE; +} + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) ++static bool ++#else +static int ++#endif +checkentry(const char *tablename, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) + const void *e, @@ -6345,11 +7531,10 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/ipt_SET.c + +module_init(ipt_SET_init); +module_exit(ipt_SET_fini); -Index: linux-2.6.22-rc5/net/ipv4/netfilter/Kconfig -=================================================================== ---- linux-2.6.22-rc5.orig/net/ipv4/netfilter/Kconfig 2007-06-19 23:19:01.000000000 +0100 -+++ linux-2.6.22-rc5/net/ipv4/netfilter/Kconfig 2007-06-20 19:20:37.000000000 +0100 -@@ -426,5 +426,114 @@ +diff -Nru ./linux-2.6.22.4/net/ipv4/netfilter/Kconfig linux-2.6.22.4.pom2patch.set/net/ipv4/netfilter/Kconfig +--- ./linux-2.6.22.4/net/ipv4/netfilter/Kconfig 2007-08-21 06:33:06.000000000 +0200 ++++ linux-2.6.22.4.pom2patch.set/net/ipv4/netfilter/Kconfig 2007-10-12 14:31:55.000000000 +0200 +@@ -402,5 +402,122 @@ Allows altering the ARP packet payload: source and destination hardware and network addresses. @@ -6442,6 +7627,14 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/Kconfig + + To compile it as a module, choose M here. If unsure, say N. + ++config IP_NF_SET_IPTREEMAP ++ tristate "iptreemap set support" ++ depends on IP_NF_SET ++ help ++ This option adds the iptreemap set type support. ++ ++ To compile it as a module, choose M here. If unsure, say N. ++ +config IP_NF_MATCH_SET + tristate "set match support" + depends on IP_NF_SET @@ -6464,19 +7657,18 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/Kconfig + endmenu -Index: linux-2.6.22-rc5/net/ipv4/netfilter/Makefile -=================================================================== ---- linux-2.6.22-rc5.orig/net/ipv4/netfilter/Makefile 2007-06-19 23:19:01.000000000 +0100 -+++ linux-2.6.22-rc5/net/ipv4/netfilter/Makefile 2007-06-20 19:20:37.000000000 +0100 +diff -Nru ./linux-2.6.22.4/net/ipv4/netfilter/Makefile linux-2.6.22.4.pom2patch.set/net/ipv4/netfilter/Makefile +--- ./linux-2.6.22.4/net/ipv4/netfilter/Makefile 2007-08-21 06:33:06.000000000 +0200 ++++ linux-2.6.22.4.pom2patch.set/net/ipv4/netfilter/Makefile 2007-10-12 14:31:55.000000000 +0200 @@ -48,6 +48,7 @@ obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o +obj-$(CONFIG_IP_NF_MATCH_SET) += ipt_set.o obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o - obj-$(CONFIG_IP_NF_MATCH_IPP2P) += ipt_ipp2p.o - obj-$(CONFIG_IP_NF_MATCH_LAYER7) += ipt_layer7.o -@@ -64,6 +65,17 @@ + + # targets +@@ -62,6 +63,18 @@ obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o @@ -6491,6 +7683,7 @@ Index: linux-2.6.22-rc5/net/ipv4/netfilter/Makefile +obj-$(CONFIG_IP_NF_SET_NETHASH) += ip_set_nethash.o +obj-$(CONFIG_IP_NF_SET_IPPORTHASH) += ip_set_ipporthash.o +obj-$(CONFIG_IP_NF_SET_IPTREE) += ip_set_iptree.o ++obj-$(CONFIG_IP_NF_SET_IPTREEMAP) += ip_set_iptreemap.o # generic ARP tables obj-$(CONFIG_IP_NF_ARPTABLES) += arp_tables.o diff --git a/target/linux/generic-2.6/patches/130-netfilter-ipset.patch b/target/linux/generic-2.6/patches-2.6.23/130-netfilter_ipset.patch similarity index 81% rename from target/linux/generic-2.6/patches/130-netfilter-ipset.patch rename to target/linux/generic-2.6/patches-2.6.23/130-netfilter_ipset.patch index f52d0ea730..7c065e8e80 100644 --- a/target/linux/generic-2.6/patches/130-netfilter-ipset.patch +++ b/target/linux/generic-2.6/patches-2.6.23/130-netfilter_ipset.patch @@ -1,6 +1,6 @@ -diff -ruN linux-2.6.21.1/include/linux/netfilter_ipv4/ip_set.h linux-2.6.21.1.new/include/linux/netfilter_ipv4/ip_set.h ---- linux-2.6.21.1/include/linux/netfilter_ipv4/ip_set.h 1969-12-31 18:00:00.000000000 -0600 -+++ linux-2.6.21.1.new/include/linux/netfilter_ipv4/ip_set.h 2007-06-08 16:29:31.825808000 -0500 +diff -Nru linux-2.6.23/include/linux/netfilter_ipv4/ip_set.h linux-2.6.23.pom2patch.set/include/linux/netfilter_ipv4/ip_set.h +--- linux-2.6.23/include/linux/netfilter_ipv4/ip_set.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.23.pom2patch.set/include/linux/netfilter_ipv4/ip_set.h 2007-10-12 11:52:37.000000000 +0200 @@ -0,0 +1,498 @@ +#ifndef _IP_SET_H +#define _IP_SET_H @@ -500,9 +500,9 @@ diff -ruN linux-2.6.21.1/include/linux/netfilter_ipv4/ip_set.h linux-2.6.21.1.ne +#endif /* __KERNEL__ */ + +#endif /*_IP_SET_H*/ -diff -ruN linux-2.6.21.1/include/linux/netfilter_ipv4/ip_set_iphash.h linux-2.6.21.1.new/include/linux/netfilter_ipv4/ip_set_iphash.h ---- linux-2.6.21.1/include/linux/netfilter_ipv4/ip_set_iphash.h 1969-12-31 18:00:00.000000000 -0600 -+++ linux-2.6.21.1.new/include/linux/netfilter_ipv4/ip_set_iphash.h 2007-06-08 16:29:31.829808250 -0500 +diff -Nru linux-2.6.23/include/linux/netfilter_ipv4/ip_set_iphash.h linux-2.6.23.pom2patch.set/include/linux/netfilter_ipv4/ip_set_iphash.h +--- linux-2.6.23/include/linux/netfilter_ipv4/ip_set_iphash.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.23.pom2patch.set/include/linux/netfilter_ipv4/ip_set_iphash.h 2007-10-12 11:52:37.000000000 +0200 @@ -0,0 +1,30 @@ +#ifndef __IP_SET_IPHASH_H +#define __IP_SET_IPHASH_H @@ -534,9 +534,9 @@ diff -ruN linux-2.6.21.1/include/linux/netfilter_ipv4/ip_set_iphash.h linux-2.6. +}; + +#endif /* __IP_SET_IPHASH_H */ -diff -ruN linux-2.6.21.1/include/linux/netfilter_ipv4/ip_set_ipmap.h linux-2.6.21.1.new/include/linux/netfilter_ipv4/ip_set_ipmap.h ---- linux-2.6.21.1/include/linux/netfilter_ipv4/ip_set_ipmap.h 1969-12-31 18:00:00.000000000 -0600 -+++ linux-2.6.21.1.new/include/linux/netfilter_ipv4/ip_set_ipmap.h 2007-06-08 16:29:31.829808250 -0500 +diff -Nru linux-2.6.23/include/linux/netfilter_ipv4/ip_set_ipmap.h linux-2.6.23.pom2patch.set/include/linux/netfilter_ipv4/ip_set_ipmap.h +--- linux-2.6.23/include/linux/netfilter_ipv4/ip_set_ipmap.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.23.pom2patch.set/include/linux/netfilter_ipv4/ip_set_ipmap.h 2007-10-12 11:52:37.000000000 +0200 @@ -0,0 +1,56 @@ +#ifndef __IP_SET_IPMAP_H +#define __IP_SET_IPMAP_H @@ -594,9 +594,9 @@ diff -ruN linux-2.6.21.1/include/linux/netfilter_ipv4/ip_set_ipmap.h linux-2.6.2 +} + +#endif /* __IP_SET_IPMAP_H */ -diff -ruN linux-2.6.21.1/include/linux/netfilter_ipv4/ip_set_ipporthash.h linux-2.6.21.1.new/include/linux/netfilter_ipv4/ip_set_ipporthash.h ---- linux-2.6.21.1/include/linux/netfilter_ipv4/ip_set_ipporthash.h 1969-12-31 18:00:00.000000000 -0600 -+++ linux-2.6.21.1.new/include/linux/netfilter_ipv4/ip_set_ipporthash.h 2007-06-08 16:29:31.829808250 -0500 +diff -Nru linux-2.6.23/include/linux/netfilter_ipv4/ip_set_ipporthash.h linux-2.6.23.pom2patch.set/include/linux/netfilter_ipv4/ip_set_ipporthash.h +--- linux-2.6.23/include/linux/netfilter_ipv4/ip_set_ipporthash.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.23.pom2patch.set/include/linux/netfilter_ipv4/ip_set_ipporthash.h 2007-10-12 11:52:37.000000000 +0200 @@ -0,0 +1,34 @@ +#ifndef __IP_SET_IPPORTHASH_H +#define __IP_SET_IPPORTHASH_H @@ -632,9 +632,9 @@ diff -ruN linux-2.6.21.1/include/linux/netfilter_ipv4/ip_set_ipporthash.h linux- +}; + +#endif /* __IP_SET_IPPORTHASH_H */ -diff -ruN linux-2.6.21.1/include/linux/netfilter_ipv4/ip_set_iptree.h linux-2.6.21.1.new/include/linux/netfilter_ipv4/ip_set_iptree.h ---- linux-2.6.21.1/include/linux/netfilter_ipv4/ip_set_iptree.h 1969-12-31 18:00:00.000000000 -0600 -+++ linux-2.6.21.1.new/include/linux/netfilter_ipv4/ip_set_iptree.h 2007-06-08 16:29:31.829808250 -0500 +diff -Nru linux-2.6.23/include/linux/netfilter_ipv4/ip_set_iptree.h linux-2.6.23.pom2patch.set/include/linux/netfilter_ipv4/ip_set_iptree.h +--- linux-2.6.23/include/linux/netfilter_ipv4/ip_set_iptree.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.23.pom2patch.set/include/linux/netfilter_ipv4/ip_set_iptree.h 2007-10-12 11:52:37.000000000 +0200 @@ -0,0 +1,40 @@ +#ifndef __IP_SET_IPTREE_H +#define __IP_SET_IPTREE_H @@ -676,9 +676,53 @@ diff -ruN linux-2.6.21.1/include/linux/netfilter_ipv4/ip_set_iptree.h linux-2.6. +}; + +#endif /* __IP_SET_IPTREE_H */ -diff -ruN linux-2.6.21.1/include/linux/netfilter_ipv4/ip_set_jhash.h linux-2.6.21.1.new/include/linux/netfilter_ipv4/ip_set_jhash.h ---- linux-2.6.21.1/include/linux/netfilter_ipv4/ip_set_jhash.h 1969-12-31 18:00:00.000000000 -0600 -+++ linux-2.6.21.1.new/include/linux/netfilter_ipv4/ip_set_jhash.h 2007-06-08 16:29:31.829808250 -0500 +diff -Nru linux-2.6.23/include/linux/netfilter_ipv4/ip_set_iptreemap.h linux-2.6.23.pom2patch.set/include/linux/netfilter_ipv4/ip_set_iptreemap.h +--- linux-2.6.23/include/linux/netfilter_ipv4/ip_set_iptreemap.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.23.pom2patch.set/include/linux/netfilter_ipv4/ip_set_iptreemap.h 2007-10-12 11:52:37.000000000 +0200 +@@ -0,0 +1,40 @@ ++#ifndef __IP_SET_IPTREEMAP_H ++#define __IP_SET_IPTREEMAP_H ++ ++#include ++ ++#define SETTYPE_NAME "iptreemap" ++ ++#ifdef __KERNEL__ ++struct ip_set_iptreemap_d { ++ unsigned char bitmap[32]; /* x.x.x.y */ ++}; ++ ++struct ip_set_iptreemap_c { ++ struct ip_set_iptreemap_d *tree[256]; /* x.x.y.x */ ++}; ++ ++struct ip_set_iptreemap_b { ++ struct ip_set_iptreemap_c *tree[256]; /* x.y.x.x */ ++ unsigned char dirty[32]; ++}; ++#endif ++ ++struct ip_set_iptreemap { ++ unsigned int gc_interval; ++#ifdef __KERNEL__ ++ struct timer_list gc; ++ struct ip_set_iptreemap_b *tree[256]; /* y.x.x.x */ ++#endif ++}; ++ ++struct ip_set_req_iptreemap_create { ++ unsigned int gc_interval; ++}; ++ ++struct ip_set_req_iptreemap { ++ ip_set_ip_t start; ++ ip_set_ip_t end; ++}; ++ ++#endif /* __IP_SET_IPTREEMAP_H */ +diff -Nru linux-2.6.23/include/linux/netfilter_ipv4/ip_set_jhash.h linux-2.6.23.pom2patch.set/include/linux/netfilter_ipv4/ip_set_jhash.h +--- linux-2.6.23/include/linux/netfilter_ipv4/ip_set_jhash.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.23.pom2patch.set/include/linux/netfilter_ipv4/ip_set_jhash.h 2007-10-12 11:52:37.000000000 +0200 @@ -0,0 +1,148 @@ +#ifndef _LINUX_IPSET_JHASH_H +#define _LINUX_IPSET_JHASH_H @@ -828,9 +872,9 @@ diff -ruN linux-2.6.21.1/include/linux/netfilter_ipv4/ip_set_jhash.h linux-2.6.2 +} + +#endif /* _LINUX_IPSET_JHASH_H */ -diff -ruN linux-2.6.21.1/include/linux/netfilter_ipv4/ip_set_macipmap.h linux-2.6.21.1.new/include/linux/netfilter_ipv4/ip_set_macipmap.h ---- linux-2.6.21.1/include/linux/netfilter_ipv4/ip_set_macipmap.h 1969-12-31 18:00:00.000000000 -0600 -+++ linux-2.6.21.1.new/include/linux/netfilter_ipv4/ip_set_macipmap.h 2007-06-08 16:29:31.829808250 -0500 +diff -Nru linux-2.6.23/include/linux/netfilter_ipv4/ip_set_macipmap.h linux-2.6.23.pom2patch.set/include/linux/netfilter_ipv4/ip_set_macipmap.h +--- linux-2.6.23/include/linux/netfilter_ipv4/ip_set_macipmap.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.23.pom2patch.set/include/linux/netfilter_ipv4/ip_set_macipmap.h 2007-10-12 11:52:37.000000000 +0200 @@ -0,0 +1,38 @@ +#ifndef __IP_SET_MACIPMAP_H +#define __IP_SET_MACIPMAP_H @@ -870,9 +914,9 @@ diff -ruN linux-2.6.21.1/include/linux/netfilter_ipv4/ip_set_macipmap.h linux-2. +}; + +#endif /* __IP_SET_MACIPMAP_H */ -diff -ruN linux-2.6.21.1/include/linux/netfilter_ipv4/ip_set_malloc.h linux-2.6.21.1.new/include/linux/netfilter_ipv4/ip_set_malloc.h ---- linux-2.6.21.1/include/linux/netfilter_ipv4/ip_set_malloc.h 1969-12-31 18:00:00.000000000 -0600 -+++ linux-2.6.21.1.new/include/linux/netfilter_ipv4/ip_set_malloc.h 2007-06-08 16:29:31.829808250 -0500 +diff -Nru linux-2.6.23/include/linux/netfilter_ipv4/ip_set_malloc.h linux-2.6.23.pom2patch.set/include/linux/netfilter_ipv4/ip_set_malloc.h +--- linux-2.6.23/include/linux/netfilter_ipv4/ip_set_malloc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.23.pom2patch.set/include/linux/netfilter_ipv4/ip_set_malloc.h 2007-10-12 11:52:37.000000000 +0200 @@ -0,0 +1,116 @@ +#ifndef _IP_SET_MALLOC_H +#define _IP_SET_MALLOC_H @@ -990,9 +1034,9 @@ diff -ruN linux-2.6.21.1/include/linux/netfilter_ipv4/ip_set_malloc.h linux-2.6. +#endif /* __KERNEL__ */ + +#endif /*_IP_SET_MALLOC_H*/ -diff -ruN linux-2.6.21.1/include/linux/netfilter_ipv4/ip_set_nethash.h linux-2.6.21.1.new/include/linux/netfilter_ipv4/ip_set_nethash.h ---- linux-2.6.21.1/include/linux/netfilter_ipv4/ip_set_nethash.h 1969-12-31 18:00:00.000000000 -0600 -+++ linux-2.6.21.1.new/include/linux/netfilter_ipv4/ip_set_nethash.h 2007-06-08 16:29:31.829808250 -0500 +diff -Nru linux-2.6.23/include/linux/netfilter_ipv4/ip_set_nethash.h linux-2.6.23.pom2patch.set/include/linux/netfilter_ipv4/ip_set_nethash.h +--- linux-2.6.23/include/linux/netfilter_ipv4/ip_set_nethash.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.23.pom2patch.set/include/linux/netfilter_ipv4/ip_set_nethash.h 2007-10-12 11:52:37.000000000 +0200 @@ -0,0 +1,55 @@ +#ifndef __IP_SET_NETHASH_H +#define __IP_SET_NETHASH_H @@ -1049,9 +1093,9 @@ diff -ruN linux-2.6.21.1/include/linux/netfilter_ipv4/ip_set_nethash.h linux-2.6 +} + +#endif /* __IP_SET_NETHASH_H */ -diff -ruN linux-2.6.21.1/include/linux/netfilter_ipv4/ip_set_portmap.h linux-2.6.21.1.new/include/linux/netfilter_ipv4/ip_set_portmap.h ---- linux-2.6.21.1/include/linux/netfilter_ipv4/ip_set_portmap.h 1969-12-31 18:00:00.000000000 -0600 -+++ linux-2.6.21.1.new/include/linux/netfilter_ipv4/ip_set_portmap.h 2007-06-08 16:29:31.829808250 -0500 +diff -Nru linux-2.6.23/include/linux/netfilter_ipv4/ip_set_portmap.h linux-2.6.23.pom2patch.set/include/linux/netfilter_ipv4/ip_set_portmap.h +--- linux-2.6.23/include/linux/netfilter_ipv4/ip_set_portmap.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.23.pom2patch.set/include/linux/netfilter_ipv4/ip_set_portmap.h 2007-10-12 11:52:37.000000000 +0200 @@ -0,0 +1,25 @@ +#ifndef __IP_SET_PORTMAP_H +#define __IP_SET_PORTMAP_H @@ -1078,9 +1122,9 @@ diff -ruN linux-2.6.21.1/include/linux/netfilter_ipv4/ip_set_portmap.h linux-2.6 +}; + +#endif /* __IP_SET_PORTMAP_H */ -diff -ruN linux-2.6.21.1/include/linux/netfilter_ipv4/ipt_set.h linux-2.6.21.1.new/include/linux/netfilter_ipv4/ipt_set.h ---- linux-2.6.21.1/include/linux/netfilter_ipv4/ipt_set.h 1969-12-31 18:00:00.000000000 -0600 -+++ linux-2.6.21.1.new/include/linux/netfilter_ipv4/ipt_set.h 2007-06-08 16:29:31.829808250 -0500 +diff -Nru linux-2.6.23/include/linux/netfilter_ipv4/ipt_set.h linux-2.6.23.pom2patch.set/include/linux/netfilter_ipv4/ipt_set.h +--- linux-2.6.23/include/linux/netfilter_ipv4/ipt_set.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.23.pom2patch.set/include/linux/netfilter_ipv4/ipt_set.h 2007-10-12 11:52:37.000000000 +0200 @@ -0,0 +1,21 @@ +#ifndef _IPT_SET_H +#define _IPT_SET_H @@ -1103,10 +1147,10 @@ diff -ruN linux-2.6.21.1/include/linux/netfilter_ipv4/ipt_set.h linux-2.6.21.1.n +}; + +#endif /*_IPT_SET_H*/ -diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set.c linux-2.6.21.1.new/net/ipv4/netfilter/ip_set.c ---- linux-2.6.21.1/net/ipv4/netfilter/ip_set.c 1969-12-31 18:00:00.000000000 -0600 -+++ linux-2.6.21.1.new/net/ipv4/netfilter/ip_set.c 2007-06-08 16:29:31.829808250 -0500 -@@ -0,0 +1,2001 @@ +diff -Nru linux-2.6.23/net/ipv4/netfilter/ip_set.c linux-2.6.23.pom2patch.set/net/ipv4/netfilter/ip_set.c +--- linux-2.6.23/net/ipv4/netfilter/ip_set.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.23.pom2patch.set/net/ipv4/netfilter/ip_set.c 2007-10-12 11:52:37.000000000 +0200 +@@ -0,0 +1,2003 @@ +/* Copyright (C) 2000-2002 Joakim Axelsson + * Patrick Schaaf + * Copyright (C) 2003-2004 Jozsef Kadlecsik @@ -3037,7 +3081,9 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set.c linux-2.6.21.1.new/net/ipv4 + .get_optmin = SO_IP_SET, + .get_optmax = SO_IP_SET + 1, + .get = &ip_set_sockfn_get, -+ .use = 0 ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) ++ .owner = THIS_MODULE, ++#endif +}; + +static int max_sets, hash_size; @@ -3049,7 +3095,7 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set.c linux-2.6.21.1.new/net/ipv4 +MODULE_AUTHOR("Jozsef Kadlecsik "); +MODULE_DESCRIPTION("module implementing core IP set support"); + -+static int __init init(void) ++static int __init ip_set_init(void) +{ + int res; + ip_set_id_t i; @@ -3086,7 +3132,7 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set.c linux-2.6.21.1.new/net/ipv4 + return 0; +} + -+static void __exit fini(void) ++static void __exit ip_set_fini(void) +{ + /* There can't be any existing set or binding */ + nf_unregister_sockopt(&so_set); @@ -3106,12 +3152,12 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set.c linux-2.6.21.1.new/net/ipv4 +EXPORT_SYMBOL(ip_set_delip_kernel); +EXPORT_SYMBOL(ip_set_testip_kernel); + -+module_init(init); -+module_exit(fini); -diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_iphash.c linux-2.6.21.1.new/net/ipv4/netfilter/ip_set_iphash.c ---- linux-2.6.21.1/net/ipv4/netfilter/ip_set_iphash.c 1969-12-31 18:00:00.000000000 -0600 -+++ linux-2.6.21.1.new/net/ipv4/netfilter/ip_set_iphash.c 2007-06-08 16:29:31.829808250 -0500 -@@ -0,0 +1,413 @@ ++module_init(ip_set_init); ++module_exit(ip_set_fini); +diff -Nru linux-2.6.23/net/ipv4/netfilter/ip_set_iphash.c linux-2.6.23.pom2patch.set/net/ipv4/netfilter/ip_set_iphash.c +--- linux-2.6.23/net/ipv4/netfilter/ip_set_iphash.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.23.pom2patch.set/net/ipv4/netfilter/ip_set_iphash.c 2007-10-12 11:52:37.000000000 +0200 +@@ -0,0 +1,429 @@ +/* Copyright (C) 2003-2004 Jozsef Kadlecsik + * + * This program is free software; you can redistribute it and/or modify @@ -3124,6 +3170,8 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_iphash.c linux-2.6.21.1.new/n +#include +#include +#include ++#include ++#include +#include +#include +#include @@ -3137,7 +3185,6 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_iphash.c linux-2.6.21.1.new/n + +#include +#include -+#include + +static int limit = MAX_RANGE; + @@ -3202,8 +3249,13 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_iphash.c linux-2.6.21.1.new/n +{ + return __testip(set, + ntohl(flags[index] & IPSET_SRC ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr ++ : ip_hdr(skb)->daddr), ++#else + ? skb->nh.iph->saddr + : skb->nh.iph->daddr), ++#endif + hash_ip); +} + @@ -3214,7 +3266,7 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_iphash.c linux-2.6.21.1.new/n + u_int16_t i; + ip_set_ip_t *elem; + -+ if (!ip || map->elements > limit) ++ if (!ip || map->elements >= limit) + return -ERANGE; + + *hash_ip = ip & map->netmask; @@ -3259,8 +3311,13 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_iphash.c linux-2.6.21.1.new/n +{ + return __addip((struct ip_set_iphash *) set->data, + ntohl(flags[index] & IPSET_SRC ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr ++ : ip_hdr(skb)->daddr), ++#else + ? skb->nh.iph->saddr + : skb->nh.iph->daddr), ++#endif + hash_ip); +} + @@ -3382,8 +3439,13 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_iphash.c linux-2.6.21.1.new/n +{ + return __delip(set, + ntohl(flags[index] & IPSET_SRC ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr ++ : ip_hdr(skb)->daddr), ++#else + ? skb->nh.iph->saddr + : skb->nh.iph->daddr), ++#endif + hash_ip); +} + @@ -3512,23 +3574,23 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_iphash.c linux-2.6.21.1.new/n +module_param(limit, int, 0600); +MODULE_PARM_DESC(limit, "maximal number of elements stored in the sets"); + -+static int __init init(void) ++static int __init ip_set_iphash_init(void) +{ + return ip_set_register_set_type(&ip_set_iphash); +} + -+static void __exit fini(void) ++static void __exit ip_set_iphash_fini(void) +{ + /* FIXME: possible race with ip_set_create() */ + ip_set_unregister_set_type(&ip_set_iphash); +} + -+module_init(init); -+module_exit(fini); -diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_ipmap.c linux-2.6.21.1.new/net/ipv4/netfilter/ip_set_ipmap.c ---- linux-2.6.21.1/net/ipv4/netfilter/ip_set_ipmap.c 1969-12-31 18:00:00.000000000 -0600 -+++ linux-2.6.21.1.new/net/ipv4/netfilter/ip_set_ipmap.c 2007-06-08 16:29:31.833808500 -0500 -@@ -0,0 +1,327 @@ ++module_init(ip_set_iphash_init); ++module_exit(ip_set_iphash_fini); +diff -Nru linux-2.6.23/net/ipv4/netfilter/ip_set_ipmap.c linux-2.6.23.pom2patch.set/net/ipv4/netfilter/ip_set_ipmap.c +--- linux-2.6.23/net/ipv4/netfilter/ip_set_ipmap.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.23.pom2patch.set/net/ipv4/netfilter/ip_set_ipmap.c 2007-10-12 11:52:37.000000000 +0200 +@@ -0,0 +1,336 @@ +/* Copyright (C) 2000-2002 Joakim Axelsson + * Patrick Schaaf + * Copyright (C) 2003-2004 Jozsef Kadlecsik @@ -3543,6 +3605,7 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_ipmap.c linux-2.6.21.1.new/ne +#include +#include +#include ++#include +#include +#include +#include @@ -3595,17 +3658,15 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_ipmap.c linux-2.6.21.1.new/ne + const u_int32_t *flags, + unsigned char index) +{ -+ int res; -+ -+ DP("flag: %s src: %u.%u.%u.%u dst: %u.%u.%u.%u", -+ flags[index] & IPSET_SRC ? "SRC" : "DST", -+ NIPQUAD(skb->nh.iph->saddr), -+ NIPQUAD(skb->nh.iph->daddr)); -+ -+ res = __testip(set, -+ ntohl(flags[index] & IPSET_SRC ++ int res = __testip(set, ++ ntohl(flags[index] & IPSET_SRC ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr ++ : ip_hdr(skb)->daddr), ++#else + ? skb->nh.iph->saddr + : skb->nh.iph->daddr), ++#endif + hash_ip); + return (res < 0 ? 0 : res); +} @@ -3652,8 +3713,13 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_ipmap.c linux-2.6.21.1.new/ne +{ + return __addip(set, + ntohl(flags[index] & IPSET_SRC ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr ++ : ip_hdr(skb)->daddr), ++#else + ? skb->nh.iph->saddr + : skb->nh.iph->daddr), ++#endif + hash_ip); +} + @@ -3698,8 +3764,13 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_ipmap.c linux-2.6.21.1.new/ne +{ + return __delip(set, + ntohl(flags[index] & IPSET_SRC ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr ++ : ip_hdr(skb)->daddr), ++#else + ? skb->nh.iph->saddr + : skb->nh.iph->daddr), ++#endif + hash_ip); +} + @@ -3843,23 +3914,23 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_ipmap.c linux-2.6.21.1.new/ne +MODULE_AUTHOR("Jozsef Kadlecsik "); +MODULE_DESCRIPTION("ipmap type of IP sets"); + -+static int __init init(void) ++static int __init ip_set_ipmap_init(void) +{ + return ip_set_register_set_type(&ip_set_ipmap); +} + -+static void __exit fini(void) ++static void __exit ip_set_ipmap_fini(void) +{ + /* FIXME: possible race with ip_set_create() */ + ip_set_unregister_set_type(&ip_set_ipmap); +} + -+module_init(init); -+module_exit(fini); -diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_ipporthash.c linux-2.6.21.1.new/net/ipv4/netfilter/ip_set_ipporthash.c ---- linux-2.6.21.1/net/ipv4/netfilter/ip_set_ipporthash.c 1969-12-31 18:00:00.000000000 -0600 -+++ linux-2.6.21.1.new/net/ipv4/netfilter/ip_set_ipporthash.c 2007-06-08 16:29:31.833808500 -0500 -@@ -0,0 +1,535 @@ ++module_init(ip_set_ipmap_init); ++module_exit(ip_set_ipmap_fini); +diff -Nru linux-2.6.23/net/ipv4/netfilter/ip_set_ipporthash.c linux-2.6.23.pom2patch.set/net/ipv4/netfilter/ip_set_ipporthash.c +--- linux-2.6.23/net/ipv4/netfilter/ip_set_ipporthash.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.23.pom2patch.set/net/ipv4/netfilter/ip_set_ipporthash.c 2007-10-12 11:52:37.000000000 +0200 +@@ -0,0 +1,581 @@ +/* Copyright (C) 2003-2004 Jozsef Kadlecsik + * + * This program is free software; you can redistribute it and/or modify @@ -3874,6 +3945,8 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_ipporthash.c linux-2.6.21.1.n +#include +#include +#include ++#include ++#include +#include +#include +#include @@ -3887,7 +3960,6 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_ipporthash.c linux-2.6.21.1.n + +#include +#include -+#include + +static int limit = MAX_RANGE; + @@ -3895,7 +3967,11 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_ipporthash.c linux-2.6.21.1.n +static inline ip_set_ip_t +get_port(const struct sk_buff *skb, u_int32_t flags) +{ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ struct iphdr *iph = ip_hdr(skb); ++#else + struct iphdr *iph = skb->nh.iph; ++#endif + u_int16_t offset = ntohs(iph->frag_off) & IP_OFFSET; + + switch (iph->protocol) { @@ -3906,7 +3982,11 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_ipporthash.c linux-2.6.21.1.n + if (offset) + return INVALID_PORT; + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ if (skb_copy_bits(skb, ip_hdr(skb)->ihl*4, &tcph, sizeof(tcph)) < 0) ++#else + if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &tcph, sizeof(tcph)) < 0) ++#endif + /* No choice either */ + return INVALID_PORT; + @@ -3919,7 +3999,11 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_ipporthash.c linux-2.6.21.1.n + if (offset) + return INVALID_PORT; + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ if (skb_copy_bits(skb, ip_hdr(skb)->ihl*4, &udph, sizeof(udph)) < 0) ++#else + if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &udph, sizeof(udph)) < 0) ++#endif + /* No choice either */ + return INVALID_PORT; + @@ -4001,28 +4085,41 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_ipporthash.c linux-2.6.21.1.n + unsigned char index) +{ + ip_set_ip_t port; ++ int res; + + if (flags[index+1] == 0) -+ return -EINVAL; ++ return 0; + + port = get_port(skb, flags[index+1]); + + DP("flag: %s src: %u.%u.%u.%u dst: %u.%u.%u.%u", + flags[index] & IPSET_SRC ? "SRC" : "DST", ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ NIPQUAD(ip_hdr(skb)->saddr), ++ NIPQUAD(ip_hdr(skb)->daddr)); ++#else + NIPQUAD(skb->nh.iph->saddr), + NIPQUAD(skb->nh.iph->daddr)); ++#endif + DP("flag %s port %u", + flags[index+1] & IPSET_SRC ? "SRC" : "DST", + port); + if (port == INVALID_PORT) + return 0; + -+ return __testip(set, ++ res = __testip(set, + ntohl(flags[index] & IPSET_SRC ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr ++ : ip_hdr(skb)->daddr), ++#else + ? skb->nh.iph->saddr + : skb->nh.iph->daddr), ++#endif + port, + hash_ip); ++ return (res < 0 ? 0 : res); ++ +} + +static inline int @@ -4094,8 +4191,13 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_ipporthash.c linux-2.6.21.1.n + + DP("flag: %s src: %u.%u.%u.%u dst: %u.%u.%u.%u", + flags[index] & IPSET_SRC ? "SRC" : "DST", ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ NIPQUAD(ip_hdr(skb)->saddr), ++ NIPQUAD(ip_hdr(skb)->daddr)); ++#else + NIPQUAD(skb->nh.iph->saddr), + NIPQUAD(skb->nh.iph->daddr)); ++#endif + DP("flag %s port %u", + flags[index+1] & IPSET_SRC ? "SRC" : "DST", + port); @@ -4104,8 +4206,13 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_ipporthash.c linux-2.6.21.1.n + + return __addip((struct ip_set_ipporthash *) set->data, + ntohl(flags[index] & IPSET_SRC ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr ++ : ip_hdr(skb)->daddr), ++#else + ? skb->nh.iph->saddr + : skb->nh.iph->daddr), ++#endif + port, + hash_ip); +} @@ -4239,8 +4346,13 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_ipporthash.c linux-2.6.21.1.n + + DP("flag: %s src: %u.%u.%u.%u dst: %u.%u.%u.%u", + flags[index] & IPSET_SRC ? "SRC" : "DST", ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ NIPQUAD(ip_hdr(skb)->saddr), ++ NIPQUAD(ip_hdr(skb)->daddr)); ++#else + NIPQUAD(skb->nh.iph->saddr), + NIPQUAD(skb->nh.iph->daddr)); ++#endif + DP("flag %s port %u", + flags[index+1] & IPSET_SRC ? "SRC" : "DST", + port); @@ -4249,8 +4361,13 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_ipporthash.c linux-2.6.21.1.n + + return __delip(set, + ntohl(flags[index] & IPSET_SRC ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr ++ : ip_hdr(skb)->daddr), ++#else + ? skb->nh.iph->saddr + : skb->nh.iph->daddr), ++#endif + port, + hash_ip); +} @@ -4382,23 +4499,23 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_ipporthash.c linux-2.6.21.1.n +module_param(limit, int, 0600); +MODULE_PARM_DESC(limit, "maximal number of elements stored in the sets"); + -+static int __init init(void) ++static int __init ip_set_ipporthash_init(void) +{ + return ip_set_register_set_type(&ip_set_ipporthash); +} + -+static void __exit fini(void) ++static void __exit ip_set_ipporthash_fini(void) +{ + /* FIXME: possible race with ip_set_create() */ + ip_set_unregister_set_type(&ip_set_ipporthash); +} + -+module_init(init); -+module_exit(fini); -diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_iptree.c linux-2.6.21.1.new/net/ipv4/netfilter/ip_set_iptree.c ---- linux-2.6.21.1/net/ipv4/netfilter/ip_set_iptree.c 1969-12-31 18:00:00.000000000 -0600 -+++ linux-2.6.21.1.new/net/ipv4/netfilter/ip_set_iptree.c 2007-06-08 16:29:31.833808500 -0500 -@@ -0,0 +1,571 @@ ++module_init(ip_set_ipporthash_init); ++module_exit(ip_set_ipporthash_fini); +diff -Nru linux-2.6.23/net/ipv4/netfilter/ip_set_iptree.c linux-2.6.23.pom2patch.set/net/ipv4/netfilter/ip_set_iptree.c +--- linux-2.6.23/net/ipv4/netfilter/ip_set_iptree.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.23.pom2patch.set/net/ipv4/netfilter/ip_set_iptree.c 2007-10-12 11:52:37.000000000 +0200 +@@ -0,0 +1,612 @@ +/* Copyright (C) 2005 Jozsef Kadlecsik + * + * This program is free software; you can redistribute it and/or modify @@ -4444,12 +4561,23 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_iptree.c linux-2.6.21.1.new/n +static kmem_cache_t *leaf_cachep; +#endif + ++#if defined(__LITTLE_ENDIAN) +#define ABCD(a,b,c,d,addrp) do { \ + a = ((unsigned char *)addrp)[3]; \ + b = ((unsigned char *)addrp)[2]; \ + c = ((unsigned char *)addrp)[1]; \ + d = ((unsigned char *)addrp)[0]; \ +} while (0) ++#elif defined(__BIG_ENDIAN) ++#define ABCD(a,b,c,d,addrp) do { \ ++ a = ((unsigned char *)addrp)[0]; \ ++ b = ((unsigned char *)addrp)[1]; \ ++ c = ((unsigned char *)addrp)[2]; \ ++ d = ((unsigned char *)addrp)[3]; \ ++} while (0) ++#else ++#error "Please fix asm/byteorder.h" ++#endif /* __LITTLE_ENDIAN */ + +#define TESTIP_WALK(map, elem, branch) do { \ + if ((map)->tree[elem]) { \ @@ -4477,8 +4605,9 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_iptree.c linux-2.6.21.1.new/n + TESTIP_WALK(btree, b, ctree); + TESTIP_WALK(ctree, c, dtree); + DP("%lu %lu", dtree->expires[d], jiffies); -+ return !!(map->timeout ? (time_after(dtree->expires[d], jiffies)) -+ : dtree->expires[d]); ++ return dtree->expires[d] ++ && (!map->timeout ++ || time_after(dtree->expires[d], jiffies)); +} + +static int @@ -4508,24 +4637,34 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_iptree.c linux-2.6.21.1.new/n + + DP("flag: %s src: %u.%u.%u.%u dst: %u.%u.%u.%u", + flags[index] & IPSET_SRC ? "SRC" : "DST", ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ NIPQUAD(ip_hdr(skb)->saddr), ++ NIPQUAD(ip_hdr(skb)->daddr)); ++#else + NIPQUAD(skb->nh.iph->saddr), + NIPQUAD(skb->nh.iph->daddr)); ++#endif + + res = __testip(set, + ntohl(flags[index] & IPSET_SRC ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr ++ : ip_hdr(skb)->daddr), ++#else + ? skb->nh.iph->saddr + : skb->nh.iph->daddr), ++#endif + hash_ip); + return (res < 0 ? 0 : res); +} + -+#define ADDIP_WALK(map, elem, branch, type, cachep, flags) do { \ ++#define ADDIP_WALK(map, elem, branch, type, cachep) do { \ + if ((map)->tree[elem]) { \ + DP("found %u", elem); \ + branch = (map)->tree[elem]; \ + } else { \ + branch = (type *) \ -+ kmem_cache_alloc(cachep, flags); \ ++ kmem_cache_alloc(cachep, GFP_ATOMIC); \ + if (branch == NULL) \ + return -ENOMEM; \ + memset(branch, 0, sizeof(*branch)); \ @@ -4536,8 +4675,7 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_iptree.c linux-2.6.21.1.new/n + +static inline int +__addip(struct ip_set *set, ip_set_ip_t ip, unsigned int timeout, -+ ip_set_ip_t *hash_ip, -+ unsigned int __nocast flags) ++ ip_set_ip_t *hash_ip) +{ + struct ip_set_iptree *map = (struct ip_set_iptree *) set->data; + struct ip_set_iptreeb *btree; @@ -4546,7 +4684,7 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_iptree.c linux-2.6.21.1.new/n + unsigned char a,b,c,d; + int ret = 0; + -+ if (!ip || map->elements > limit) ++ if (!ip || map->elements >= limit) + /* We could call the garbage collector + * but it's probably overkill */ + return -ERANGE; @@ -4554,14 +4692,14 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_iptree.c linux-2.6.21.1.new/n + *hash_ip = ip; + ABCD(a, b, c, d, hash_ip); + DP("%u %u %u %u timeout %u", a, b, c, d, timeout); -+ ADDIP_WALK(map, a, btree, struct ip_set_iptreeb, branch_cachep, flags); -+ ADDIP_WALK(btree, b, ctree, struct ip_set_iptreec, branch_cachep, flags); -+ ADDIP_WALK(ctree, c, dtree, struct ip_set_iptreed, leaf_cachep, flags); ++ ADDIP_WALK(map, a, btree, struct ip_set_iptreeb, branch_cachep); ++ ADDIP_WALK(btree, b, ctree, struct ip_set_iptreec, branch_cachep); ++ ADDIP_WALK(ctree, c, dtree, struct ip_set_iptreed, leaf_cachep); + if (dtree->expires[d] + && (!map->timeout || time_after(dtree->expires[d], jiffies))) + ret = -EEXIST; + dtree->expires[d] = map->timeout ? (timeout * HZ + jiffies) : 1; -+ /* Lottery */ ++ /* Lottery: I won! */ + if (dtree->expires[d] == 0) + dtree->expires[d] = 1; + DP("%u %lu", d, dtree->expires[d]); @@ -4587,8 +4725,7 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_iptree.c linux-2.6.21.1.new/n + DP("%u.%u.%u.%u %u", HIPQUAD(req->ip), req->timeout); + return __addip(set, req->ip, + req->timeout ? req->timeout : map->timeout, -+ hash_ip, -+ GFP_ATOMIC); ++ hash_ip); +} + +static int @@ -4602,11 +4739,15 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_iptree.c linux-2.6.21.1.new/n + + return __addip(set, + ntohl(flags[index] & IPSET_SRC ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr ++ : ip_hdr(skb)->daddr), ++#else + ? skb->nh.iph->saddr + : skb->nh.iph->daddr), ++#endif + map->timeout, -+ hash_ip, -+ GFP_ATOMIC); ++ hash_ip); +} + +#define DELIP_WALK(map, elem, branch) do { \ @@ -4667,8 +4808,13 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_iptree.c linux-2.6.21.1.new/n +{ + return __delip(set, + ntohl(flags[index] & IPSET_SRC ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr ++ : ip_hdr(skb)->daddr), ++#else + ? skb->nh.iph->saddr + : skb->nh.iph->daddr), ++#endif + hash_ip); +} + @@ -4929,21 +5075,33 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_iptree.c linux-2.6.21.1.new/n +module_param(limit, int, 0600); +MODULE_PARM_DESC(limit, "maximal number of elements stored in the sets"); + -+static int __init init(void) ++static int __init ip_set_iptree_init(void) +{ + int ret; + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) ++ branch_cachep = kmem_cache_create("ip_set_iptreeb", ++ sizeof(struct ip_set_iptreeb), ++ 0, 0, NULL); ++#else + branch_cachep = kmem_cache_create("ip_set_iptreeb", + sizeof(struct ip_set_iptreeb), + 0, 0, NULL, NULL); ++#endif + if (!branch_cachep) { + printk(KERN_ERR "Unable to create ip_set_iptreeb slab cache\n"); + ret = -ENOMEM; + goto out; + } ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) ++ leaf_cachep = kmem_cache_create("ip_set_iptreed", ++ sizeof(struct ip_set_iptreed), ++ 0, 0, NULL); ++#else + leaf_cachep = kmem_cache_create("ip_set_iptreed", + sizeof(struct ip_set_iptreed), + 0, 0, NULL, NULL); ++#endif + if (!leaf_cachep) { + printk(KERN_ERR "Unable to create ip_set_iptreed slab cache\n"); + ret = -ENOMEM; @@ -4960,7 +5118,7 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_iptree.c linux-2.6.21.1.new/n + return ret; +} + -+static void __exit fini(void) ++static void __exit ip_set_iptree_fini(void) +{ + /* FIXME: possible race with ip_set_create() */ + ip_set_unregister_set_type(&ip_set_iptree); @@ -4968,12 +5126,845 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_iptree.c linux-2.6.21.1.new/n + kmem_cache_destroy(branch_cachep); +} + -+module_init(init); -+module_exit(fini); -diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_macipmap.c linux-2.6.21.1.new/net/ipv4/netfilter/ip_set_macipmap.c ---- linux-2.6.21.1/net/ipv4/netfilter/ip_set_macipmap.c 1969-12-31 18:00:00.000000000 -0600 -+++ linux-2.6.21.1.new/net/ipv4/netfilter/ip_set_macipmap.c 2007-06-08 16:29:31.833808500 -0500 -@@ -0,0 +1,353 @@ ++module_init(ip_set_iptree_init); ++module_exit(ip_set_iptree_fini); +diff -Nru linux-2.6.23/net/ipv4/netfilter/ip_set_iptreemap.c linux-2.6.23.pom2patch.set/net/ipv4/netfilter/ip_set_iptreemap.c +--- linux-2.6.23/net/ipv4/netfilter/ip_set_iptreemap.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.23.pom2patch.set/net/ipv4/netfilter/ip_set_iptreemap.c 2007-10-12 11:52:37.000000000 +0200 +@@ -0,0 +1,829 @@ ++/* Copyright (C) 2007 Sven Wegener ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published by ++ * the Free Software Foundation. ++ */ ++ ++/* This modules implements the iptreemap ipset type. It uses bitmaps to ++ * represent every single IPv4 address as a single bit. The bitmaps are managed ++ * in a tree structure, where the first three octets of an addresses are used ++ * as an index to find the bitmap and the last octet is used as the bit number. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#define IPTREEMAP_DEFAULT_GC_TIME (5 * 60) ++#define IPTREEMAP_DESTROY_SLEEP (100) ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21) ++static struct kmem_cache *cachep_b; ++static struct kmem_cache *cachep_c; ++static struct kmem_cache *cachep_d; ++#else ++static kmem_cache_t *cachep_b; ++static kmem_cache_t *cachep_c; ++static kmem_cache_t *cachep_d; ++#endif ++ ++static struct ip_set_iptreemap_d *fullbitmap_d; ++static struct ip_set_iptreemap_c *fullbitmap_c; ++static struct ip_set_iptreemap_b *fullbitmap_b; ++ ++#if defined(__LITTLE_ENDIAN) ++#define ABCD(a, b, c, d, addr) \ ++ do { \ ++ a = ((unsigned char *)addr)[3]; \ ++ b = ((unsigned char *)addr)[2]; \ ++ c = ((unsigned char *)addr)[1]; \ ++ d = ((unsigned char *)addr)[0]; \ ++ } while (0) ++#elif defined(__BIG_ENDIAN) ++#define ABCD(a,b,c,d,addrp) do { \ ++ a = ((unsigned char *)addrp)[0]; \ ++ b = ((unsigned char *)addrp)[1]; \ ++ c = ((unsigned char *)addrp)[2]; \ ++ d = ((unsigned char *)addrp)[3]; \ ++} while (0) ++#else ++#error "Please fix asm/byteorder.h" ++#endif /* __LITTLE_ENDIAN */ ++ ++#define TESTIP_WALK(map, elem, branch, full) \ ++ do { \ ++ branch = (map)->tree[elem]; \ ++ if (!branch) \ ++ return 0; \ ++ else if (branch == full) \ ++ return 1; \ ++ } while (0) ++ ++#define ADDIP_WALK(map, elem, branch, type, cachep, full) \ ++ do { \ ++ branch = (map)->tree[elem]; \ ++ if (!branch) { \ ++ branch = (type *) kmem_cache_alloc(cachep, GFP_ATOMIC); \ ++ if (!branch) \ ++ return -ENOMEM; \ ++ memset(branch, 0, sizeof(*branch)); \ ++ (map)->tree[elem] = branch; \ ++ } else if (branch == full) { \ ++ return -EEXIST; \ ++ } \ ++ } while (0) ++ ++#define ADDIP_RANGE_LOOP(map, a, a1, a2, hint, branch, full, cachep, free) \ ++ for (a = a1; a <= a2; a++) { \ ++ branch = (map)->tree[a]; \ ++ if (branch != full) { \ ++ if ((a > a1 && a < a2) || (hint)) { \ ++ if (branch) \ ++ free(branch); \ ++ (map)->tree[a] = full; \ ++ continue; \ ++ } else if (!branch) { \ ++ branch = kmem_cache_alloc(cachep, GFP_ATOMIC); \ ++ if (!branch) \ ++ return -ENOMEM; \ ++ memset(branch, 0, sizeof(*branch)); \ ++ (map)->tree[a] = branch; \ ++ } ++ ++#define ADDIP_RANGE_LOOP_END() \ ++ } \ ++ } ++ ++#define DELIP_WALK(map, elem, branch, cachep, full, flags) \ ++ do { \ ++ branch = (map)->tree[elem]; \ ++ if (!branch) { \ ++ return -EEXIST; \ ++ } else if (branch == full) { \ ++ branch = kmem_cache_alloc(cachep, flags); \ ++ if (!branch) \ ++ return -ENOMEM; \ ++ memcpy(branch, full, sizeof(*full)); \ ++ (map)->tree[elem] = branch; \ ++ } \ ++ } while (0) ++ ++#define DELIP_RANGE_LOOP(map, a, a1, a2, hint, branch, full, cachep, free, flags) \ ++ for (a = a1; a <= a2; a++) { \ ++ branch = (map)->tree[a]; \ ++ if (branch) { \ ++ if ((a > a1 && a < a2) || (hint)) { \ ++ if (branch != full) \ ++ free(branch); \ ++ (map)->tree[a] = NULL; \ ++ continue; \ ++ } else if (branch == full) { \ ++ branch = kmem_cache_alloc(cachep, flags); \ ++ if (!branch) \ ++ return -ENOMEM; \ ++ memcpy(branch, full, sizeof(*branch)); \ ++ (map)->tree[a] = branch; \ ++ } ++ ++#define DELIP_RANGE_LOOP_END() \ ++ } \ ++ } ++ ++#define LOOP_WALK_BEGIN(map, i, branch) \ ++ for (i = 0; i < 256; i++) { \ ++ branch = (map)->tree[i]; \ ++ if (likely(!branch)) \ ++ continue; ++ ++#define LOOP_WALK_END() \ ++ } ++ ++#define LOOP_WALK_BEGIN_GC(map, i, branch, full, cachep, count) \ ++ count = -256; \ ++ for (i = 0; i < 256; i++) { \ ++ branch = (map)->tree[i]; \ ++ if (likely(!branch)) \ ++ continue; \ ++ count++; \ ++ if (branch == full) { \ ++ count++; \ ++ continue; \ ++ } ++ ++#define LOOP_WALK_END_GC(map, i, branch, full, cachep, count) \ ++ if (-256 == count) { \ ++ kmem_cache_free(cachep, branch); \ ++ (map)->tree[i] = NULL; \ ++ } else if (256 == count) { \ ++ kmem_cache_free(cachep, branch); \ ++ (map)->tree[i] = full; \ ++ } \ ++ } ++ ++#define LOOP_WALK_BEGIN_COUNT(map, i, branch, inrange, count) \ ++ for (i = 0; i < 256; i++) { \ ++ if (!(map)->tree[i]) { \ ++ if (inrange) { \ ++ count++; \ ++ inrange = 0; \ ++ } \ ++ continue; \ ++ } \ ++ branch = (map)->tree[i]; ++ ++#define LOOP_WALK_END_COUNT() \ ++ } ++ ++#define MIN(a, b) (a < b ? a : b) ++#define MAX(a, b) (a > b ? a : b) ++ ++#define GETVALUE1(a, a1, b1, r) \ ++ (a == a1 ? b1 : r) ++ ++#define GETVALUE2(a, b, a1, b1, c1, r) \ ++ (a == a1 && b == b1 ? c1 : r) ++ ++#define GETVALUE3(a, b, c, a1, b1, c1, d1, r) \ ++ (a == a1 && b == b1 && c == c1 ? d1 : r) ++ ++#define CHECK1(a, a1, a2, b1, b2, c1, c2, d1, d2) \ ++ ( \ ++ GETVALUE1(a, a1, b1, 0) == 0 \ ++ && GETVALUE1(a, a2, b2, 255) == 255 \ ++ && c1 == 0 \ ++ && c2 == 255 \ ++ && d1 == 0 \ ++ && d2 == 255 \ ++ ) ++ ++#define CHECK2(a, b, a1, a2, b1, b2, c1, c2, d1, d2) \ ++ ( \ ++ GETVALUE2(a, b, a1, b1, c1, 0) == 0 \ ++ && GETVALUE2(a, b, a2, b2, c2, 255) == 255 \ ++ && d1 == 0 \ ++ && d2 == 255 \ ++ ) ++ ++#define CHECK3(a, b, c, a1, a2, b1, b2, c1, c2, d1, d2) \ ++ ( \ ++ GETVALUE3(a, b, c, a1, b1, c1, d1, 0) == 0 \ ++ && GETVALUE3(a, b, c, a2, b2, c2, d2, 255) == 255 \ ++ ) ++ ++ ++static inline void ++free_d(struct ip_set_iptreemap_d *map) ++{ ++ kmem_cache_free(cachep_d, map); ++} ++ ++static inline void ++free_c(struct ip_set_iptreemap_c *map) ++{ ++ struct ip_set_iptreemap_d *dtree; ++ unsigned int i; ++ ++ LOOP_WALK_BEGIN(map, i, dtree) { ++ if (dtree != fullbitmap_d) ++ free_d(dtree); ++ } LOOP_WALK_END(); ++ ++ kmem_cache_free(cachep_c, map); ++} ++ ++static inline void ++free_b(struct ip_set_iptreemap_b *map) ++{ ++ struct ip_set_iptreemap_c *ctree; ++ unsigned int i; ++ ++ LOOP_WALK_BEGIN(map, i, ctree) { ++ if (ctree != fullbitmap_c) ++ free_c(ctree); ++ } LOOP_WALK_END(); ++ ++ kmem_cache_free(cachep_b, map); ++} ++ ++static inline int ++__testip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip) ++{ ++ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; ++ struct ip_set_iptreemap_b *btree; ++ struct ip_set_iptreemap_c *ctree; ++ struct ip_set_iptreemap_d *dtree; ++ unsigned char a, b, c, d; ++ ++ *hash_ip = ip; ++ ++ ABCD(a, b, c, d, hash_ip); ++ ++ TESTIP_WALK(map, a, btree, fullbitmap_b); ++ TESTIP_WALK(btree, b, ctree, fullbitmap_c); ++ TESTIP_WALK(ctree, c, dtree, fullbitmap_d); ++ ++ return !!test_bit(d, (void *) dtree->bitmap); ++} ++ ++static int ++testip(struct ip_set *set, const void *data, size_t size, ip_set_ip_t *hash_ip) ++{ ++ struct ip_set_req_iptreemap *req = (struct ip_set_req_iptreemap *) data; ++ ++ if (size != sizeof(struct ip_set_req_iptreemap)) { ++ ip_set_printk("data length wrong (want %zu, have %zu)", sizeof(struct ip_set_req_iptreemap), size); ++ return -EINVAL; ++ } ++ ++ return __testip(set, req->start, hash_ip); ++} ++ ++static int ++testip_kernel(struct ip_set *set, const struct sk_buff *skb, ip_set_ip_t *hash_ip, const u_int32_t *flags, unsigned char index) ++{ ++ int res; ++ ++ res = __testip(set, ++ ntohl(flags[index] & IPSET_SRC ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr ++ : ip_hdr(skb)->daddr), ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr), ++#endif ++ hash_ip); ++ ++ return (res < 0 ? 0 : res); ++} ++ ++static inline int ++__addip_single(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip) ++{ ++ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; ++ struct ip_set_iptreemap_b *btree; ++ struct ip_set_iptreemap_c *ctree; ++ struct ip_set_iptreemap_d *dtree; ++ unsigned char a, b, c, d; ++ ++ *hash_ip = ip; ++ ++ ABCD(a, b, c, d, hash_ip); ++ ++ ADDIP_WALK(map, a, btree, struct ip_set_iptreemap_b, cachep_b, fullbitmap_b); ++ ADDIP_WALK(btree, b, ctree, struct ip_set_iptreemap_c, cachep_c, fullbitmap_c); ++ ADDIP_WALK(ctree, c, dtree, struct ip_set_iptreemap_d, cachep_d, fullbitmap_d); ++ ++ if (test_and_set_bit(d, (void *) dtree->bitmap)) ++ return -EEXIST; ++ ++ set_bit(b, (void *) btree->dirty); ++ ++ return 0; ++} ++ ++static inline int ++__addip_range(struct ip_set *set, ip_set_ip_t start, ip_set_ip_t end, ip_set_ip_t *hash_ip) ++{ ++ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; ++ struct ip_set_iptreemap_b *btree; ++ struct ip_set_iptreemap_c *ctree; ++ struct ip_set_iptreemap_d *dtree; ++ unsigned int a, b, c, d; ++ unsigned char a1, b1, c1, d1; ++ unsigned char a2, b2, c2, d2; ++ ++ if (start == end) ++ return __addip_single(set, start, hash_ip); ++ ++ *hash_ip = start; ++ ++ ABCD(a1, b1, c1, d1, &start); ++ ABCD(a2, b2, c2, d2, &end); ++ ++ /* This is sooo ugly... */ ++ ADDIP_RANGE_LOOP(map, a, a1, a2, CHECK1(a, a1, a2, b1, b2, c1, c2, d1, d2), btree, fullbitmap_b, cachep_b, free_b) { ++ ADDIP_RANGE_LOOP(btree, b, GETVALUE1(a, a1, b1, 0), GETVALUE1(a, a2, b2, 255), CHECK2(a, b, a1, a2, b1, b2, c1, c2, d1, d2), ctree, fullbitmap_c, cachep_c, free_c) { ++ ADDIP_RANGE_LOOP(ctree, c, GETVALUE2(a, b, a1, b1, c1, 0), GETVALUE2(a, b, a2, b2, c2, 255), CHECK3(a, b, c, a1, a2, b1, b2, c1, c2, d1, d2), dtree, fullbitmap_d, cachep_d, free_d) { ++ for (d = GETVALUE3(a, b, c, a1, b1, c1, d1, 0); d <= GETVALUE3(a, b, c, a2, b2, c2, d2, 255); d++) ++ set_bit(d, (void *) dtree->bitmap); ++ set_bit(b, (void *) btree->dirty); ++ } ADDIP_RANGE_LOOP_END(); ++ } ADDIP_RANGE_LOOP_END(); ++ } ADDIP_RANGE_LOOP_END(); ++ ++ return 0; ++} ++ ++static int ++addip(struct ip_set *set, const void *data, size_t size, ip_set_ip_t *hash_ip) ++{ ++ struct ip_set_req_iptreemap *req = (struct ip_set_req_iptreemap *) data; ++ ++ if (size != sizeof(struct ip_set_req_iptreemap)) { ++ ip_set_printk("data length wrong (want %zu, have %zu)", sizeof(struct ip_set_req_iptreemap), size); ++ return -EINVAL; ++ } ++ ++ return __addip_range(set, MIN(req->start, req->end), MAX(req->start, req->end), hash_ip); ++} ++ ++static int ++addip_kernel(struct ip_set *set, const struct sk_buff *skb, ip_set_ip_t *hash_ip, const u_int32_t *flags, unsigned char index) ++{ ++ ++ return __addip_single(set, ++ ntohl(flags[index] & IPSET_SRC ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr ++ : ip_hdr(skb)->daddr), ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr), ++#endif ++ hash_ip); ++} ++ ++static inline int ++__delip_single(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip, unsigned int __nocast flags) ++{ ++ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; ++ struct ip_set_iptreemap_b *btree; ++ struct ip_set_iptreemap_c *ctree; ++ struct ip_set_iptreemap_d *dtree; ++ unsigned char a,b,c,d; ++ ++ *hash_ip = ip; ++ ++ ABCD(a, b, c, d, hash_ip); ++ ++ DELIP_WALK(map, a, btree, cachep_b, fullbitmap_b, flags); ++ DELIP_WALK(btree, b, ctree, cachep_c, fullbitmap_c, flags); ++ DELIP_WALK(ctree, c, dtree, cachep_d, fullbitmap_d, flags); ++ ++ if (!test_and_clear_bit(d, (void *) dtree->bitmap)) ++ return -EEXIST; ++ ++ set_bit(b, (void *) btree->dirty); ++ ++ return 0; ++} ++ ++static inline int ++__delip_range(struct ip_set *set, ip_set_ip_t start, ip_set_ip_t end, ip_set_ip_t *hash_ip, unsigned int __nocast flags) ++{ ++ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; ++ struct ip_set_iptreemap_b *btree; ++ struct ip_set_iptreemap_c *ctree; ++ struct ip_set_iptreemap_d *dtree; ++ unsigned int a, b, c, d; ++ unsigned char a1, b1, c1, d1; ++ unsigned char a2, b2, c2, d2; ++ ++ if (start == end) ++ return __delip_single(set, start, hash_ip, flags); ++ ++ *hash_ip = start; ++ ++ ABCD(a1, b1, c1, d1, &start); ++ ABCD(a2, b2, c2, d2, &end); ++ ++ /* This is sooo ugly... */ ++ DELIP_RANGE_LOOP(map, a, a1, a2, CHECK1(a, a1, a2, b1, b2, c1, c2, d1, d2), btree, fullbitmap_b, cachep_b, free_b, flags) { ++ DELIP_RANGE_LOOP(btree, b, GETVALUE1(a, a1, b1, 0), GETVALUE1(a, a2, b2, 255), CHECK2(a, b, a1, a2, b1, b2, c1, c2, d1, d2), ctree, fullbitmap_c, cachep_c, free_c, flags) { ++ DELIP_RANGE_LOOP(ctree, c, GETVALUE2(a, b, a1, b1, c1, 0), GETVALUE2(a, b, a2, b2, c2, 255), CHECK3(a, b, c, a1, a2, b1, b2, c1, c2, d1, d2), dtree, fullbitmap_d, cachep_d, free_d, flags) { ++ for (d = GETVALUE3(a, b, c, a1, b1, c1, d1, 0); d <= GETVALUE3(a, b, c, a2, b2, c2, d2, 255); d++) ++ clear_bit(d, (void *) dtree->bitmap); ++ set_bit(b, (void *) btree->dirty); ++ } DELIP_RANGE_LOOP_END(); ++ } DELIP_RANGE_LOOP_END(); ++ } DELIP_RANGE_LOOP_END(); ++ ++ return 0; ++} ++ ++static int ++delip(struct ip_set *set, const void *data, size_t size, ip_set_ip_t *hash_ip) ++{ ++ struct ip_set_req_iptreemap *req = (struct ip_set_req_iptreemap *) data; ++ ++ if (size != sizeof(struct ip_set_req_iptreemap)) { ++ ip_set_printk("data length wrong (want %zu, have %zu)", sizeof(struct ip_set_req_iptreemap), size); ++ return -EINVAL; ++ } ++ ++ return __delip_range(set, MIN(req->start, req->end), MAX(req->start, req->end), hash_ip, GFP_KERNEL); ++} ++ ++static int ++delip_kernel(struct ip_set *set, const struct sk_buff *skb, ip_set_ip_t *hash_ip, const u_int32_t *flags, unsigned char index) ++{ ++ return __delip_single(set, ++ ntohl(flags[index] & IPSET_SRC ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr ++ : ip_hdr(skb)->daddr), ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr), ++#endif ++ hash_ip, ++ GFP_ATOMIC); ++} ++ ++/* Check the status of the bitmap ++ * -1 == all bits cleared ++ * 1 == all bits set ++ * 0 == anything else ++ */ ++static inline int ++bitmap_status(struct ip_set_iptreemap_d *dtree) ++{ ++ unsigned char first = dtree->bitmap[0]; ++ int a; ++ ++ for (a = 1; a < 32; a++) ++ if (dtree->bitmap[a] != first) ++ return 0; ++ ++ return (first == 0 ? -1 : (first == 255 ? 1 : 0)); ++} ++ ++static void ++gc(unsigned long addr) ++{ ++ struct ip_set *set = (struct ip_set *) addr; ++ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; ++ struct ip_set_iptreemap_b *btree; ++ struct ip_set_iptreemap_c *ctree; ++ struct ip_set_iptreemap_d *dtree; ++ unsigned int a, b, c; ++ int i, j, k; ++ ++ write_lock_bh(&set->lock); ++ ++ LOOP_WALK_BEGIN_GC(map, a, btree, fullbitmap_b, cachep_b, i) { ++ LOOP_WALK_BEGIN_GC(btree, b, ctree, fullbitmap_c, cachep_c, j) { ++ if (!test_and_clear_bit(b, (void *) btree->dirty)) ++ continue; ++ LOOP_WALK_BEGIN_GC(ctree, c, dtree, fullbitmap_d, cachep_d, k) { ++ switch (bitmap_status(dtree)) { ++ case -1: ++ kmem_cache_free(cachep_d, dtree); ++ ctree->tree[c] = NULL; ++ k--; ++ break; ++ case 1: ++ kmem_cache_free(cachep_d, dtree); ++ ctree->tree[c] = fullbitmap_d; ++ k++; ++ break; ++ } ++ } LOOP_WALK_END(); ++ } LOOP_WALK_END_GC(btree, b, ctree, fullbitmap_c, cachep_c, k); ++ } LOOP_WALK_END_GC(map, a, btree, fullbitmap_b, cachep_b, j); ++ ++ write_unlock_bh(&set->lock); ++ ++ map->gc.expires = jiffies + map->gc_interval * HZ; ++ add_timer(&map->gc); ++} ++ ++static inline void ++init_gc_timer(struct ip_set *set) ++{ ++ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; ++ ++ init_timer(&map->gc); ++ map->gc.data = (unsigned long) set; ++ map->gc.function = gc; ++ map->gc.expires = jiffies + map->gc_interval * HZ; ++ add_timer(&map->gc); ++} ++ ++static int create(struct ip_set *set, const void *data, size_t size) ++{ ++ struct ip_set_req_iptreemap_create *req = (struct ip_set_req_iptreemap_create *) data; ++ struct ip_set_iptreemap *map; ++ ++ if (size != sizeof(struct ip_set_req_iptreemap_create)) { ++ ip_set_printk("data length wrong (want %zu, have %zu)", sizeof(struct ip_set_req_iptreemap_create), size); ++ return -EINVAL; ++ } ++ ++ map = kzalloc(sizeof(*map), GFP_KERNEL); ++ if (!map) ++ return -ENOMEM; ++ ++ map->gc_interval = req->gc_interval ? req->gc_interval : IPTREEMAP_DEFAULT_GC_TIME; ++ set->data = map; ++ ++ init_gc_timer(set); ++ ++ return 0; ++} ++ ++static inline void __flush(struct ip_set_iptreemap *map) ++{ ++ struct ip_set_iptreemap_b *btree; ++ unsigned int a; ++ ++ LOOP_WALK_BEGIN(map, a, btree); ++ if (btree != fullbitmap_b) ++ free_b(btree); ++ LOOP_WALK_END(); ++} ++ ++static void destroy(struct ip_set *set) ++{ ++ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; ++ ++ while (!del_timer(&map->gc)) ++ msleep(IPTREEMAP_DESTROY_SLEEP); ++ ++ __flush(map); ++ kfree(map); ++ ++ set->data = NULL; ++} ++ ++static void flush(struct ip_set *set) ++{ ++ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; ++ ++ while (!del_timer(&map->gc)) ++ msleep(IPTREEMAP_DESTROY_SLEEP); ++ ++ __flush(map); ++ ++ memset(map, 0, sizeof(*map)); ++ ++ init_gc_timer(set); ++} ++ ++static void list_header(const struct ip_set *set, void *data) ++{ ++ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; ++ struct ip_set_req_iptreemap_create *header = (struct ip_set_req_iptreemap_create *) data; ++ ++ header->gc_interval = map->gc_interval; ++} ++ ++static int list_members_size(const struct ip_set *set) ++{ ++ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; ++ struct ip_set_iptreemap_b *btree; ++ struct ip_set_iptreemap_c *ctree; ++ struct ip_set_iptreemap_d *dtree; ++ unsigned int a, b, c, d, inrange = 0, count = 0; ++ ++ LOOP_WALK_BEGIN_COUNT(map, a, btree, inrange, count) { ++ LOOP_WALK_BEGIN_COUNT(btree, b, ctree, inrange, count) { ++ LOOP_WALK_BEGIN_COUNT(ctree, c, dtree, inrange, count) { ++ for (d = 0; d < 256; d++) { ++ if (test_bit(d, (void *) dtree->bitmap)) { ++ inrange = 1; ++ } else if (inrange) { ++ count++; ++ inrange = 0; ++ } ++ } ++ } LOOP_WALK_END_COUNT(); ++ } LOOP_WALK_END_COUNT(); ++ } LOOP_WALK_END_COUNT(); ++ ++ if (inrange) ++ count++; ++ ++ return (count * sizeof(struct ip_set_req_iptreemap)); ++} ++ ++static inline size_t add_member(void *data, size_t offset, ip_set_ip_t start, ip_set_ip_t end) ++{ ++ struct ip_set_req_iptreemap *entry = (struct ip_set_req_iptreemap *) (data + offset); ++ ++ entry->start = start; ++ entry->end = end; ++ ++ return sizeof(*entry); ++} ++ ++static void list_members(const struct ip_set *set, void *data) ++{ ++ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; ++ struct ip_set_iptreemap_b *btree; ++ struct ip_set_iptreemap_c *ctree; ++ struct ip_set_iptreemap_d *dtree; ++ unsigned int a, b, c, d, inrange = 0; ++ size_t offset = 0; ++ ip_set_ip_t start = 0, end = 0, ip; ++ ++ LOOP_WALK_BEGIN(map, a, btree) { ++ LOOP_WALK_BEGIN(btree, b, ctree) { ++ LOOP_WALK_BEGIN(ctree, c, dtree) { ++ for (d = 0; d < 256; d++) { ++ if (test_bit(d, (void *) dtree->bitmap)) { ++ ip = ((a << 24) | (b << 16) | (c << 8) | d); ++ if (!inrange) { ++ inrange = 1; ++ start = ip; ++ } else if (end < ip - 1) { ++ offset += add_member(data, offset, start, end); ++ start = ip; ++ } ++ end = ip; ++ } else if (inrange) { ++ offset += add_member(data, offset, start, end); ++ inrange = 0; ++ } ++ } ++ } LOOP_WALK_END(); ++ } LOOP_WALK_END(); ++ } LOOP_WALK_END(); ++ ++ if (inrange) ++ add_member(data, offset, start, end); ++} ++ ++static struct ip_set_type ip_set_iptreemap = { ++ .typename = SETTYPE_NAME, ++ .features = IPSET_TYPE_IP | IPSET_DATA_SINGLE, ++ .protocol_version = IP_SET_PROTOCOL_VERSION, ++ .create = create, ++ .destroy = destroy, ++ .flush = flush, ++ .reqsize = sizeof(struct ip_set_req_iptreemap), ++ .addip = addip, ++ .addip_kernel = addip_kernel, ++ .delip = delip, ++ .delip_kernel = delip_kernel, ++ .testip = testip, ++ .testip_kernel = testip_kernel, ++ .header_size = sizeof(struct ip_set_req_iptreemap_create), ++ .list_header = list_header, ++ .list_members_size = list_members_size, ++ .list_members = list_members, ++ .me = THIS_MODULE, ++}; ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Sven Wegener "); ++MODULE_DESCRIPTION("iptreemap type of IP sets"); ++ ++static int __init ip_set_iptreemap_init(void) ++{ ++ int ret = -ENOMEM; ++ int a; ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) ++ cachep_b = kmem_cache_create("ip_set_iptreemap_b", ++ sizeof(struct ip_set_iptreemap_b), ++ 0, 0, NULL); ++#else ++ cachep_b = kmem_cache_create("ip_set_iptreemap_b", ++ sizeof(struct ip_set_iptreemap_b), ++ 0, 0, NULL, NULL); ++#endif ++ if (!cachep_b) { ++ ip_set_printk("Unable to create ip_set_iptreemap_b slab cache"); ++ goto out; ++ } ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) ++ cachep_c = kmem_cache_create("ip_set_iptreemap_c", ++ sizeof(struct ip_set_iptreemap_c), ++ 0, 0, NULL); ++#else ++ cachep_c = kmem_cache_create("ip_set_iptreemap_c", ++ sizeof(struct ip_set_iptreemap_c), ++ 0, 0, NULL, NULL); ++#endif ++ if (!cachep_c) { ++ ip_set_printk("Unable to create ip_set_iptreemap_c slab cache"); ++ goto outb; ++ } ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) ++ cachep_d = kmem_cache_create("ip_set_iptreemap_d", ++ sizeof(struct ip_set_iptreemap_d), ++ 0, 0, NULL); ++#else ++ cachep_d = kmem_cache_create("ip_set_iptreemap_d", ++ sizeof(struct ip_set_iptreemap_d), ++ 0, 0, NULL, NULL); ++#endif ++ if (!cachep_d) { ++ ip_set_printk("Unable to create ip_set_iptreemap_d slab cache"); ++ goto outc; ++ } ++ ++ fullbitmap_d = kmem_cache_alloc(cachep_d, GFP_KERNEL); ++ if (!fullbitmap_d) ++ goto outd; ++ ++ fullbitmap_c = kmem_cache_alloc(cachep_c, GFP_KERNEL); ++ if (!fullbitmap_c) ++ goto outbitmapd; ++ ++ fullbitmap_b = kmem_cache_alloc(cachep_b, GFP_KERNEL); ++ if (!fullbitmap_b) ++ goto outbitmapc; ++ ++ ret = ip_set_register_set_type(&ip_set_iptreemap); ++ if (0 > ret) ++ goto outbitmapb; ++ ++ /* Now init our global bitmaps */ ++ memset(fullbitmap_d->bitmap, 0xff, sizeof(fullbitmap_d->bitmap)); ++ ++ for (a = 0; a < 256; a++) ++ fullbitmap_c->tree[a] = fullbitmap_d; ++ ++ for (a = 0; a < 256; a++) ++ fullbitmap_b->tree[a] = fullbitmap_c; ++ memset(fullbitmap_b->dirty, 0, sizeof(fullbitmap_b->dirty)); ++ ++ return 0; ++ ++outbitmapb: ++ kmem_cache_free(cachep_b, fullbitmap_b); ++outbitmapc: ++ kmem_cache_free(cachep_c, fullbitmap_c); ++outbitmapd: ++ kmem_cache_free(cachep_d, fullbitmap_d); ++outd: ++ kmem_cache_destroy(cachep_d); ++outc: ++ kmem_cache_destroy(cachep_c); ++outb: ++ kmem_cache_destroy(cachep_b); ++out: ++ ++ return ret; ++} ++ ++static void __exit ip_set_iptreemap_fini(void) ++{ ++ ip_set_unregister_set_type(&ip_set_iptreemap); ++ kmem_cache_free(cachep_d, fullbitmap_d); ++ kmem_cache_free(cachep_c, fullbitmap_c); ++ kmem_cache_free(cachep_b, fullbitmap_b); ++ kmem_cache_destroy(cachep_d); ++ kmem_cache_destroy(cachep_c); ++ kmem_cache_destroy(cachep_b); ++} ++ ++module_init(ip_set_iptreemap_init); ++module_exit(ip_set_iptreemap_fini); +diff -Nru linux-2.6.23/net/ipv4/netfilter/ip_set_macipmap.c linux-2.6.23.pom2patch.set/net/ipv4/netfilter/ip_set_macipmap.c +--- linux-2.6.23/net/ipv4/netfilter/ip_set_macipmap.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.23.pom2patch.set/net/ipv4/netfilter/ip_set_macipmap.c 2007-10-12 11:52:37.000000000 +0200 +@@ -0,0 +1,375 @@ +/* Copyright (C) 2000-2002 Joakim Axelsson + * Patrick Schaaf + * Martin Josefsson @@ -4989,6 +5980,7 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_macipmap.c linux-2.6.21.1.new +#include +#include +#include ++#include +#include +#include +#include @@ -5045,12 +6037,13 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_macipmap.c linux-2.6.21.1.new + ip_set_ip_t ip; + + ip = ntohl(flags[index] & IPSET_SRC ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr ++ : ip_hdr(skb)->daddr); ++#else + ? skb->nh.iph->saddr + : skb->nh.iph->daddr); -+ DP("flag: %s src: %u.%u.%u.%u dst: %u.%u.%u.%u", -+ flags[index] & IPSET_SRC ? "SRC" : "DST", -+ NIPQUAD(skb->nh.iph->saddr), -+ NIPQUAD(skb->nh.iph->daddr)); ++#endif + + if (ip < map->first_ip || ip > map->last_ip) + return 0; @@ -5062,8 +6055,13 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_macipmap.c linux-2.6.21.1.new + (void *) &table[ip - map->first_ip].flags)) { + /* Is mac pointer valid? + * If so, compare... */ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ return (skb_mac_header(skb) >= skb->head ++ && (skb_mac_header(skb) + ETH_HLEN) <= skb->data ++#else + return (skb->mac.raw >= skb->head + && (skb->mac.raw + ETH_HLEN) <= skb->data ++#endif + && (memcmp(eth_hdr(skb)->h_source, + &table[ip - map->first_ip].ethernet, + ETH_ALEN) == 0)); @@ -5120,11 +6118,21 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_macipmap.c linux-2.6.21.1.new + ip_set_ip_t ip; + + ip = ntohl(flags[index] & IPSET_SRC ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr ++ : ip_hdr(skb)->daddr); ++#else + ? skb->nh.iph->saddr + : skb->nh.iph->daddr); ++#endif + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ if (!(skb_mac_header(skb) >= skb->head ++ && (skb_mac_header(skb) + ETH_HLEN) <= skb->data)) ++#else + if (!(skb->mac.raw >= skb->head + && (skb->mac.raw + ETH_HLEN) <= skb->data)) ++#endif + return -EINVAL; + + return __addip(set, ip, eth_hdr(skb)->h_source, hash_ip); @@ -5174,8 +6182,13 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_macipmap.c linux-2.6.21.1.new +{ + return __delip(set, + ntohl(flags[index] & IPSET_SRC ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr ++ : ip_hdr(skb)->daddr), ++#else + ? skb->nh.iph->saddr + : skb->nh.iph->daddr), ++#endif + hash_ip); +} + @@ -5313,24 +6326,24 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_macipmap.c linux-2.6.21.1.new +MODULE_AUTHOR("Jozsef Kadlecsik "); +MODULE_DESCRIPTION("macipmap type of IP sets"); + -+static int __init init(void) ++static int __init ip_set_macipmap_init(void) +{ + init_max_malloc_size(); + return ip_set_register_set_type(&ip_set_macipmap); +} + -+static void __exit fini(void) ++static void __exit ip_set_macipmap_fini(void) +{ + /* FIXME: possible race with ip_set_create() */ + ip_set_unregister_set_type(&ip_set_macipmap); +} + -+module_init(init); -+module_exit(fini); -diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_nethash.c linux-2.6.21.1.new/net/ipv4/netfilter/ip_set_nethash.c ---- linux-2.6.21.1/net/ipv4/netfilter/ip_set_nethash.c 1969-12-31 18:00:00.000000000 -0600 -+++ linux-2.6.21.1.new/net/ipv4/netfilter/ip_set_nethash.c 2007-06-08 16:29:31.833808500 -0500 -@@ -0,0 +1,481 @@ ++module_init(ip_set_macipmap_init); ++module_exit(ip_set_macipmap_fini); +diff -Nru linux-2.6.23/net/ipv4/netfilter/ip_set_nethash.c linux-2.6.23.pom2patch.set/net/ipv4/netfilter/ip_set_nethash.c +--- linux-2.6.23/net/ipv4/netfilter/ip_set_nethash.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.23.pom2patch.set/net/ipv4/netfilter/ip_set_nethash.c 2007-10-12 11:52:37.000000000 +0200 +@@ -0,0 +1,497 @@ +/* Copyright (C) 2003-2004 Jozsef Kadlecsik + * + * This program is free software; you can redistribute it and/or modify @@ -5343,6 +6356,8 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_nethash.c linux-2.6.21.1.new/ +#include +#include +#include ++#include ++#include +#include +#include +#include @@ -5356,7 +6371,6 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_nethash.c linux-2.6.21.1.new/ + +#include +#include -+#include + +static int limit = MAX_RANGE; + @@ -5444,8 +6458,13 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_nethash.c linux-2.6.21.1.new/ +{ + return __testip(set, + ntohl(flags[index] & IPSET_SRC ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr ++ : ip_hdr(skb)->daddr), ++#else + ? skb->nh.iph->saddr + : skb->nh.iph->daddr), ++#endif + hash_ip); +} + @@ -5475,7 +6494,7 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_nethash.c linux-2.6.21.1.new/ +__addip(struct ip_set_nethash *map, ip_set_ip_t ip, unsigned char cidr, + ip_set_ip_t *hash_ip) +{ -+ if (!ip || map->elements > limit) ++ if (!ip || map->elements >= limit) + return -ERANGE; + + *hash_ip = pack(ip, cidr); @@ -5537,8 +6556,13 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_nethash.c linux-2.6.21.1.new/ + struct ip_set_nethash *map = (struct ip_set_nethash *) set->data; + int ret = -ERANGE; + ip_set_ip_t ip = ntohl(flags[index] & IPSET_SRC ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr ++ : ip_hdr(skb)->daddr); ++#else + ? skb->nh.iph->saddr + : skb->nh.iph->daddr); ++#endif + + if (map->cidr[0]) + ret = __addip(map, ip, map->cidr[0], hash_ip); @@ -5666,8 +6690,13 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_nethash.c linux-2.6.21.1.new/ + struct ip_set_nethash *map = (struct ip_set_nethash *) set->data; + int ret = -ERANGE; + ip_set_ip_t ip = ntohl(flags[index] & IPSET_SRC ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr ++ : ip_hdr(skb)->daddr); ++#else + ? skb->nh.iph->saddr + : skb->nh.iph->daddr); ++#endif + + if (map->cidr[0]) + ret = __delip(map, ip, map->cidr[0], hash_ip); @@ -5799,23 +6828,23 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_nethash.c linux-2.6.21.1.new/ +module_param(limit, int, 0600); +MODULE_PARM_DESC(limit, "maximal number of elements stored in the sets"); + -+static int __init init(void) ++static int __init ip_set_nethash_init(void) +{ + return ip_set_register_set_type(&ip_set_nethash); +} + -+static void __exit fini(void) ++static void __exit ip_set_nethash_fini(void) +{ + /* FIXME: possible race with ip_set_create() */ + ip_set_unregister_set_type(&ip_set_nethash); +} + -+module_init(init); -+module_exit(fini); -diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_portmap.c linux-2.6.21.1.new/net/ipv4/netfilter/ip_set_portmap.c ---- linux-2.6.21.1/net/ipv4/netfilter/ip_set_portmap.c 1969-12-31 18:00:00.000000000 -0600 -+++ linux-2.6.21.1.new/net/ipv4/netfilter/ip_set_portmap.c 2007-06-08 16:29:31.833808500 -0500 -@@ -0,0 +1,334 @@ ++module_init(ip_set_nethash_init); ++module_exit(ip_set_nethash_fini); +diff -Nru linux-2.6.23/net/ipv4/netfilter/ip_set_portmap.c linux-2.6.23.pom2patch.set/net/ipv4/netfilter/ip_set_portmap.c +--- linux-2.6.23/net/ipv4/netfilter/ip_set_portmap.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.23.pom2patch.set/net/ipv4/netfilter/ip_set_portmap.c 2007-10-12 11:52:37.000000000 +0200 +@@ -0,0 +1,346 @@ +/* Copyright (C) 2003-2004 Jozsef Kadlecsik + * + * This program is free software; you can redistribute it and/or modify @@ -5830,6 +6859,7 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_portmap.c linux-2.6.21.1.new/ +#include +#include +#include ++#include +#include +#include +#include @@ -5845,9 +6875,12 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_portmap.c linux-2.6.21.1.new/ +static inline ip_set_ip_t +get_port(const struct sk_buff *skb, u_int32_t flags) +{ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ struct iphdr *iph = ip_hdr(skb); ++#else + struct iphdr *iph = skb->nh.iph; ++#endif + u_int16_t offset = ntohs(iph->frag_off) & IP_OFFSET; -+ + switch (iph->protocol) { + case IPPROTO_TCP: { + struct tcphdr tcph; @@ -5856,7 +6889,11 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_portmap.c linux-2.6.21.1.new/ + if (offset) + return INVALID_PORT; + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ if (skb_copy_bits(skb, ip_hdr(skb)->ihl*4, &tcph, sizeof(tcph)) < 0) ++#else + if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &tcph, sizeof(tcph)) < 0) ++#endif + /* No choice either */ + return INVALID_PORT; + @@ -5869,7 +6906,11 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_portmap.c linux-2.6.21.1.new/ + if (offset) + return INVALID_PORT; + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ if (skb_copy_bits(skb, ip_hdr(skb)->ihl*4, &udph, sizeof(udph)) < 0) ++#else + if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &udph, sizeof(udph)) < 0) ++#endif + /* No choice either */ + return INVALID_PORT; + @@ -6137,23 +7178,23 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ip_set_portmap.c linux-2.6.21.1.new/ +MODULE_AUTHOR("Jozsef Kadlecsik "); +MODULE_DESCRIPTION("portmap type of IP sets"); + -+static int __init init(void) ++static int __init ip_set_portmap_init(void) +{ + return ip_set_register_set_type(&ip_set_portmap); +} + -+static void __exit fini(void) ++static void __exit ip_set_portmap_fini(void) +{ + /* FIXME: possible race with ip_set_create() */ + ip_set_unregister_set_type(&ip_set_portmap); +} + -+module_init(init); -+module_exit(fini); -diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ipt_set.c linux-2.6.21.1.new/net/ipv4/netfilter/ipt_set.c ---- linux-2.6.21.1/net/ipv4/netfilter/ipt_set.c 1969-12-31 18:00:00.000000000 -0600 -+++ linux-2.6.21.1.new/net/ipv4/netfilter/ipt_set.c 2007-06-08 16:29:31.833808500 -0500 -@@ -0,0 +1,150 @@ ++module_init(ip_set_portmap_init); ++module_exit(ip_set_portmap_fini); +diff -Nru linux-2.6.23/net/ipv4/netfilter/ipt_set.c linux-2.6.23.pom2patch.set/net/ipv4/netfilter/ipt_set.c +--- linux-2.6.23/net/ipv4/netfilter/ipt_set.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.23.pom2patch.set/net/ipv4/netfilter/ipt_set.c 2007-10-12 11:52:38.000000000 +0200 +@@ -0,0 +1,160 @@ +/* Copyright (C) 2000-2002 Joakim Axelsson + * Patrick Schaaf + * Martin Josefsson @@ -6185,7 +7226,11 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ipt_set.c linux-2.6.21.1.new/net/ipv + return inv; +} + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) ++static bool ++#else +static int ++#endif +match(const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, @@ -6193,7 +7238,9 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ipt_set.c linux-2.6.21.1.new/net/ipv + const struct xt_match *match, +#endif + const void *matchinfo, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) ++ int offset, unsigned int protoff, bool *hotdrop) ++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) + int offset, unsigned int protoff, int *hotdrop) +#else + int offset, int *hotdrop) @@ -6206,7 +7253,11 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ipt_set.c linux-2.6.21.1.new/net/ipv + info->match_set.flags[0] & IPSET_MATCH_INV); +} + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) ++bool ++#else +static int ++#endif +checkentry(const char *tablename, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) + const void *inf, @@ -6304,10 +7355,10 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ipt_set.c linux-2.6.21.1.new/net/ipv + +module_init(ipt_ipset_init); +module_exit(ipt_ipset_fini); -diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ipt_SET.c linux-2.6.21.1.new/net/ipv4/netfilter/ipt_SET.c ---- linux-2.6.21.1/net/ipv4/netfilter/ipt_SET.c 1969-12-31 18:00:00.000000000 -0600 -+++ linux-2.6.21.1.new/net/ipv4/netfilter/ipt_SET.c 2007-06-08 16:29:31.833808500 -0500 -@@ -0,0 +1,168 @@ +diff -Nru linux-2.6.23/net/ipv4/netfilter/ipt_SET.c linux-2.6.23.pom2patch.set/net/ipv4/netfilter/ipt_SET.c +--- linux-2.6.23/net/ipv4/netfilter/ipt_SET.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.23.pom2patch.set/net/ipv4/netfilter/ipt_SET.c 2007-10-12 11:52:37.000000000 +0200 +@@ -0,0 +1,172 @@ +/* Copyright (C) 2000-2002 Joakim Axelsson + * Patrick Schaaf + * Martin Josefsson @@ -6332,7 +7383,7 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ipt_SET.c linux-2.6.21.1.new/net/ipv +#include +#include +#include -+#include ++#include +#include + +static unsigned int @@ -6364,7 +7415,11 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ipt_SET.c linux-2.6.21.1.new/net/ipv + return IPT_CONTINUE; +} + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) ++static bool ++#else +static int ++#endif +checkentry(const char *tablename, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) + const void *e, @@ -6476,10 +7531,10 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/ipt_SET.c linux-2.6.21.1.new/net/ipv + +module_init(ipt_SET_init); +module_exit(ipt_SET_fini); -diff -ruN linux-2.6.21.1/net/ipv4/netfilter/Kconfig linux-2.6.21.1.new/net/ipv4/netfilter/Kconfig ---- linux-2.6.21.1/net/ipv4/netfilter/Kconfig 2007-04-27 16:49:26.000000000 -0500 -+++ linux-2.6.21.1.new/net/ipv4/netfilter/Kconfig 2007-06-08 16:29:31.833808500 -0500 -@@ -657,5 +657,114 @@ +diff -Nru linux-2.6.23/net/ipv4/netfilter/Kconfig linux-2.6.23.pom2patch.set/net/ipv4/netfilter/Kconfig +--- linux-2.6.23/net/ipv4/netfilter/Kconfig 2007-10-09 22:31:38.000000000 +0200 ++++ linux-2.6.23.pom2patch.set/net/ipv4/netfilter/Kconfig 2007-10-12 11:52:38.000000000 +0200 +@@ -402,5 +402,122 @@ Allows altering the ARP packet payload: source and destination hardware and network addresses. @@ -6572,6 +7627,14 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/Kconfig linux-2.6.21.1.new/net/ipv4/ + + To compile it as a module, choose M here. If unsure, say N. + ++config IP_NF_SET_IPTREEMAP ++ tristate "iptreemap set support" ++ depends on IP_NF_SET ++ help ++ This option adds the iptreemap set type support. ++ ++ To compile it as a module, choose M here. If unsure, say N. ++ +config IP_NF_MATCH_SET + tristate "set match support" + depends on IP_NF_SET @@ -6594,10 +7657,10 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/Kconfig linux-2.6.21.1.new/net/ipv4/ + endmenu -diff -ruN linux-2.6.21.1/net/ipv4/netfilter/Makefile linux-2.6.21.1.new/net/ipv4/netfilter/Makefile ---- linux-2.6.21.1/net/ipv4/netfilter/Makefile 2007-04-27 16:49:26.000000000 -0500 -+++ linux-2.6.21.1.new/net/ipv4/netfilter/Makefile 2007-06-08 16:29:31.837808750 -0500 -@@ -90,6 +90,7 @@ +diff -Nru linux-2.6.23/net/ipv4/netfilter/Makefile linux-2.6.23.pom2patch.set/net/ipv4/netfilter/Makefile +--- linux-2.6.23/net/ipv4/netfilter/Makefile 2007-10-09 22:31:38.000000000 +0200 ++++ linux-2.6.23.pom2patch.set/net/ipv4/netfilter/Makefile 2007-10-12 11:52:38.000000000 +0200 +@@ -48,6 +48,7 @@ obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o @@ -6605,7 +7668,7 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/Makefile linux-2.6.21.1.new/net/ipv4 obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o # targets -@@ -105,6 +106,17 @@ +@@ -62,6 +63,18 @@ obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o @@ -6620,6 +7683,7 @@ diff -ruN linux-2.6.21.1/net/ipv4/netfilter/Makefile linux-2.6.21.1.new/net/ipv4 +obj-$(CONFIG_IP_NF_SET_NETHASH) += ip_set_nethash.o +obj-$(CONFIG_IP_NF_SET_IPPORTHASH) += ip_set_ipporthash.o +obj-$(CONFIG_IP_NF_SET_IPTREE) += ip_set_iptree.o ++obj-$(CONFIG_IP_NF_SET_IPTREEMAP) += ip_set_iptreemap.o # generic ARP tables obj-$(CONFIG_IP_NF_ARPTABLES) += arp_tables.o diff --git a/target/linux/generic-2.6/patches-2.6.23/130-netfilter-ipset.patch b/target/linux/generic-2.6/patches/130-netfilter_ipset.patch similarity index 79% rename from target/linux/generic-2.6/patches-2.6.23/130-netfilter-ipset.patch rename to target/linux/generic-2.6/patches/130-netfilter_ipset.patch index d16061bacf..0a63aa8b70 100644 --- a/target/linux/generic-2.6/patches-2.6.23/130-netfilter-ipset.patch +++ b/target/linux/generic-2.6/patches/130-netfilter_ipset.patch @@ -1,7 +1,6 @@ -Index: linux-2.6.23-rc6/include/linux/netfilter_ipv4/ip_set.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.23-rc6/include/linux/netfilter_ipv4/ip_set.h 2007-09-21 16:24:01.000000000 +0800 +diff -Nru ./linux-2.6.21.5/include/linux/netfilter_ipv4/ip_set.h linux-2.6.21.5.pom2patch.set/include/linux/netfilter_ipv4/ip_set.h +--- ./linux-2.6.21.5/include/linux/netfilter_ipv4/ip_set.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.21.5.pom2patch.set/include/linux/netfilter_ipv4/ip_set.h 2007-10-12 14:28:29.000000000 +0200 @@ -0,0 +1,498 @@ +#ifndef _IP_SET_H +#define _IP_SET_H @@ -501,10 +500,9 @@ Index: linux-2.6.23-rc6/include/linux/netfilter_ipv4/ip_set.h +#endif /* __KERNEL__ */ + +#endif /*_IP_SET_H*/ -Index: linux-2.6.23-rc6/include/linux/netfilter_ipv4/ip_set_iphash.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.23-rc6/include/linux/netfilter_ipv4/ip_set_iphash.h 2007-09-21 16:24:01.000000000 +0800 +diff -Nru ./linux-2.6.21.5/include/linux/netfilter_ipv4/ip_set_iphash.h linux-2.6.21.5.pom2patch.set/include/linux/netfilter_ipv4/ip_set_iphash.h +--- ./linux-2.6.21.5/include/linux/netfilter_ipv4/ip_set_iphash.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.21.5.pom2patch.set/include/linux/netfilter_ipv4/ip_set_iphash.h 2007-10-12 14:28:29.000000000 +0200 @@ -0,0 +1,30 @@ +#ifndef __IP_SET_IPHASH_H +#define __IP_SET_IPHASH_H @@ -536,10 +534,9 @@ Index: linux-2.6.23-rc6/include/linux/netfilter_ipv4/ip_set_iphash.h +}; + +#endif /* __IP_SET_IPHASH_H */ -Index: linux-2.6.23-rc6/include/linux/netfilter_ipv4/ip_set_ipmap.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.23-rc6/include/linux/netfilter_ipv4/ip_set_ipmap.h 2007-09-21 16:24:01.000000000 +0800 +diff -Nru ./linux-2.6.21.5/include/linux/netfilter_ipv4/ip_set_ipmap.h linux-2.6.21.5.pom2patch.set/include/linux/netfilter_ipv4/ip_set_ipmap.h +--- ./linux-2.6.21.5/include/linux/netfilter_ipv4/ip_set_ipmap.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.21.5.pom2patch.set/include/linux/netfilter_ipv4/ip_set_ipmap.h 2007-10-12 14:28:29.000000000 +0200 @@ -0,0 +1,56 @@ +#ifndef __IP_SET_IPMAP_H +#define __IP_SET_IPMAP_H @@ -597,10 +594,9 @@ Index: linux-2.6.23-rc6/include/linux/netfilter_ipv4/ip_set_ipmap.h +} + +#endif /* __IP_SET_IPMAP_H */ -Index: linux-2.6.23-rc6/include/linux/netfilter_ipv4/ip_set_ipporthash.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.23-rc6/include/linux/netfilter_ipv4/ip_set_ipporthash.h 2007-09-21 16:24:01.000000000 +0800 +diff -Nru ./linux-2.6.21.5/include/linux/netfilter_ipv4/ip_set_ipporthash.h linux-2.6.21.5.pom2patch.set/include/linux/netfilter_ipv4/ip_set_ipporthash.h +--- ./linux-2.6.21.5/include/linux/netfilter_ipv4/ip_set_ipporthash.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.21.5.pom2patch.set/include/linux/netfilter_ipv4/ip_set_ipporthash.h 2007-10-12 14:28:29.000000000 +0200 @@ -0,0 +1,34 @@ +#ifndef __IP_SET_IPPORTHASH_H +#define __IP_SET_IPPORTHASH_H @@ -636,10 +632,9 @@ Index: linux-2.6.23-rc6/include/linux/netfilter_ipv4/ip_set_ipporthash.h +}; + +#endif /* __IP_SET_IPPORTHASH_H */ -Index: linux-2.6.23-rc6/include/linux/netfilter_ipv4/ip_set_iptree.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.23-rc6/include/linux/netfilter_ipv4/ip_set_iptree.h 2007-09-21 16:24:01.000000000 +0800 +diff -Nru ./linux-2.6.21.5/include/linux/netfilter_ipv4/ip_set_iptree.h linux-2.6.21.5.pom2patch.set/include/linux/netfilter_ipv4/ip_set_iptree.h +--- ./linux-2.6.21.5/include/linux/netfilter_ipv4/ip_set_iptree.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.21.5.pom2patch.set/include/linux/netfilter_ipv4/ip_set_iptree.h 2007-10-12 14:28:29.000000000 +0200 @@ -0,0 +1,40 @@ +#ifndef __IP_SET_IPTREE_H +#define __IP_SET_IPTREE_H @@ -681,10 +676,205 @@ Index: linux-2.6.23-rc6/include/linux/netfilter_ipv4/ip_set_iptree.h +}; + +#endif /* __IP_SET_IPTREE_H */ -Index: linux-2.6.23-rc6/include/linux/netfilter_ipv4/ip_set_macipmap.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.23-rc6/include/linux/netfilter_ipv4/ip_set_macipmap.h 2007-09-21 16:24:01.000000000 +0800 +diff -Nru ./linux-2.6.21.5/include/linux/netfilter_ipv4/ip_set_iptreemap.h linux-2.6.21.5.pom2patch.set/include/linux/netfilter_ipv4/ip_set_iptreemap.h +--- ./linux-2.6.21.5/include/linux/netfilter_ipv4/ip_set_iptreemap.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.21.5.pom2patch.set/include/linux/netfilter_ipv4/ip_set_iptreemap.h 2007-10-12 14:28:29.000000000 +0200 +@@ -0,0 +1,40 @@ ++#ifndef __IP_SET_IPTREEMAP_H ++#define __IP_SET_IPTREEMAP_H ++ ++#include ++ ++#define SETTYPE_NAME "iptreemap" ++ ++#ifdef __KERNEL__ ++struct ip_set_iptreemap_d { ++ unsigned char bitmap[32]; /* x.x.x.y */ ++}; ++ ++struct ip_set_iptreemap_c { ++ struct ip_set_iptreemap_d *tree[256]; /* x.x.y.x */ ++}; ++ ++struct ip_set_iptreemap_b { ++ struct ip_set_iptreemap_c *tree[256]; /* x.y.x.x */ ++ unsigned char dirty[32]; ++}; ++#endif ++ ++struct ip_set_iptreemap { ++ unsigned int gc_interval; ++#ifdef __KERNEL__ ++ struct timer_list gc; ++ struct ip_set_iptreemap_b *tree[256]; /* y.x.x.x */ ++#endif ++}; ++ ++struct ip_set_req_iptreemap_create { ++ unsigned int gc_interval; ++}; ++ ++struct ip_set_req_iptreemap { ++ ip_set_ip_t start; ++ ip_set_ip_t end; ++}; ++ ++#endif /* __IP_SET_IPTREEMAP_H */ +diff -Nru ./linux-2.6.21.5/include/linux/netfilter_ipv4/ip_set_jhash.h linux-2.6.21.5.pom2patch.set/include/linux/netfilter_ipv4/ip_set_jhash.h +--- ./linux-2.6.21.5/include/linux/netfilter_ipv4/ip_set_jhash.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.21.5.pom2patch.set/include/linux/netfilter_ipv4/ip_set_jhash.h 2007-10-12 14:28:29.000000000 +0200 +@@ -0,0 +1,148 @@ ++#ifndef _LINUX_IPSET_JHASH_H ++#define _LINUX_IPSET_JHASH_H ++ ++/* This is a copy of linux/jhash.h but the types u32/u8 are changed ++ * to __u32/__u8 so that the header file can be included into ++ * userspace code as well. Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) ++ */ ++ ++/* jhash.h: Jenkins hash support. ++ * ++ * Copyright (C) 1996 Bob Jenkins (bob_jenkins@burtleburtle.net) ++ * ++ * http://burtleburtle.net/bob/hash/ ++ * ++ * These are the credits from Bob's sources: ++ * ++ * lookup2.c, by Bob Jenkins, December 1996, Public Domain. ++ * hash(), hash2(), hash3, and mix() are externally useful functions. ++ * Routines to test the hash are included if SELF_TEST is defined. ++ * You can use this free for any purpose. It has no warranty. ++ * ++ * Copyright (C) 2003 David S. Miller (davem@redhat.com) ++ * ++ * I've modified Bob's hash to be useful in the Linux kernel, and ++ * any bugs present are surely my fault. -DaveM ++ */ ++ ++/* NOTE: Arguments are modified. */ ++#define __jhash_mix(a, b, c) \ ++{ \ ++ a -= b; a -= c; a ^= (c>>13); \ ++ b -= c; b -= a; b ^= (a<<8); \ ++ c -= a; c -= b; c ^= (b>>13); \ ++ a -= b; a -= c; a ^= (c>>12); \ ++ b -= c; b -= a; b ^= (a<<16); \ ++ c -= a; c -= b; c ^= (b>>5); \ ++ a -= b; a -= c; a ^= (c>>3); \ ++ b -= c; b -= a; b ^= (a<<10); \ ++ c -= a; c -= b; c ^= (b>>15); \ ++} ++ ++/* The golden ration: an arbitrary value */ ++#define JHASH_GOLDEN_RATIO 0x9e3779b9 ++ ++/* The most generic version, hashes an arbitrary sequence ++ * of bytes. No alignment or length assumptions are made about ++ * the input key. ++ */ ++static inline __u32 jhash(void *key, __u32 length, __u32 initval) ++{ ++ __u32 a, b, c, len; ++ __u8 *k = key; ++ ++ len = length; ++ a = b = JHASH_GOLDEN_RATIO; ++ c = initval; ++ ++ while (len >= 12) { ++ a += (k[0] +((__u32)k[1]<<8) +((__u32)k[2]<<16) +((__u32)k[3]<<24)); ++ b += (k[4] +((__u32)k[5]<<8) +((__u32)k[6]<<16) +((__u32)k[7]<<24)); ++ c += (k[8] +((__u32)k[9]<<8) +((__u32)k[10]<<16)+((__u32)k[11]<<24)); ++ ++ __jhash_mix(a,b,c); ++ ++ k += 12; ++ len -= 12; ++ } ++ ++ c += length; ++ switch (len) { ++ case 11: c += ((__u32)k[10]<<24); ++ case 10: c += ((__u32)k[9]<<16); ++ case 9 : c += ((__u32)k[8]<<8); ++ case 8 : b += ((__u32)k[7]<<24); ++ case 7 : b += ((__u32)k[6]<<16); ++ case 6 : b += ((__u32)k[5]<<8); ++ case 5 : b += k[4]; ++ case 4 : a += ((__u32)k[3]<<24); ++ case 3 : a += ((__u32)k[2]<<16); ++ case 2 : a += ((__u32)k[1]<<8); ++ case 1 : a += k[0]; ++ }; ++ ++ __jhash_mix(a,b,c); ++ ++ return c; ++} ++ ++/* A special optimized version that handles 1 or more of __u32s. ++ * The length parameter here is the number of __u32s in the key. ++ */ ++static inline __u32 jhash2(__u32 *k, __u32 length, __u32 initval) ++{ ++ __u32 a, b, c, len; ++ ++ a = b = JHASH_GOLDEN_RATIO; ++ c = initval; ++ len = length; ++ ++ while (len >= 3) { ++ a += k[0]; ++ b += k[1]; ++ c += k[2]; ++ __jhash_mix(a, b, c); ++ k += 3; len -= 3; ++ } ++ ++ c += length * 4; ++ ++ switch (len) { ++ case 2 : b += k[1]; ++ case 1 : a += k[0]; ++ }; ++ ++ __jhash_mix(a,b,c); ++ ++ return c; ++} ++ ++ ++/* A special ultra-optimized versions that knows they are hashing exactly ++ * 3, 2 or 1 word(s). ++ * ++ * NOTE: In partilar the "c += length; __jhash_mix(a,b,c);" normally ++ * done at the end is not done here. ++ */ ++static inline __u32 jhash_3words(__u32 a, __u32 b, __u32 c, __u32 initval) ++{ ++ a += JHASH_GOLDEN_RATIO; ++ b += JHASH_GOLDEN_RATIO; ++ c += initval; ++ ++ __jhash_mix(a, b, c); ++ ++ return c; ++} ++ ++static inline __u32 jhash_2words(__u32 a, __u32 b, __u32 initval) ++{ ++ return jhash_3words(a, b, 0, initval); ++} ++ ++static inline __u32 jhash_1word(__u32 a, __u32 initval) ++{ ++ return jhash_3words(a, 0, 0, initval); ++} ++ ++#endif /* _LINUX_IPSET_JHASH_H */ +diff -Nru ./linux-2.6.21.5/include/linux/netfilter_ipv4/ip_set_macipmap.h linux-2.6.21.5.pom2patch.set/include/linux/netfilter_ipv4/ip_set_macipmap.h +--- ./linux-2.6.21.5/include/linux/netfilter_ipv4/ip_set_macipmap.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.21.5.pom2patch.set/include/linux/netfilter_ipv4/ip_set_macipmap.h 2007-10-12 14:28:29.000000000 +0200 @@ -0,0 +1,38 @@ +#ifndef __IP_SET_MACIPMAP_H +#define __IP_SET_MACIPMAP_H @@ -724,10 +914,9 @@ Index: linux-2.6.23-rc6/include/linux/netfilter_ipv4/ip_set_macipmap.h +}; + +#endif /* __IP_SET_MACIPMAP_H */ -Index: linux-2.6.23-rc6/include/linux/netfilter_ipv4/ip_set_malloc.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.23-rc6/include/linux/netfilter_ipv4/ip_set_malloc.h 2007-09-21 16:24:01.000000000 +0800 +diff -Nru ./linux-2.6.21.5/include/linux/netfilter_ipv4/ip_set_malloc.h linux-2.6.21.5.pom2patch.set/include/linux/netfilter_ipv4/ip_set_malloc.h +--- ./linux-2.6.21.5/include/linux/netfilter_ipv4/ip_set_malloc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.21.5.pom2patch.set/include/linux/netfilter_ipv4/ip_set_malloc.h 2007-10-12 14:28:29.000000000 +0200 @@ -0,0 +1,116 @@ +#ifndef _IP_SET_MALLOC_H +#define _IP_SET_MALLOC_H @@ -845,10 +1034,9 @@ Index: linux-2.6.23-rc6/include/linux/netfilter_ipv4/ip_set_malloc.h +#endif /* __KERNEL__ */ + +#endif /*_IP_SET_MALLOC_H*/ -Index: linux-2.6.23-rc6/include/linux/netfilter_ipv4/ip_set_nethash.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.23-rc6/include/linux/netfilter_ipv4/ip_set_nethash.h 2007-09-21 16:24:01.000000000 +0800 +diff -Nru ./linux-2.6.21.5/include/linux/netfilter_ipv4/ip_set_nethash.h linux-2.6.21.5.pom2patch.set/include/linux/netfilter_ipv4/ip_set_nethash.h +--- ./linux-2.6.21.5/include/linux/netfilter_ipv4/ip_set_nethash.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.21.5.pom2patch.set/include/linux/netfilter_ipv4/ip_set_nethash.h 2007-10-12 14:28:29.000000000 +0200 @@ -0,0 +1,55 @@ +#ifndef __IP_SET_NETHASH_H +#define __IP_SET_NETHASH_H @@ -905,10 +1093,9 @@ Index: linux-2.6.23-rc6/include/linux/netfilter_ipv4/ip_set_nethash.h +} + +#endif /* __IP_SET_NETHASH_H */ -Index: linux-2.6.23-rc6/include/linux/netfilter_ipv4/ip_set_portmap.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.23-rc6/include/linux/netfilter_ipv4/ip_set_portmap.h 2007-09-21 16:24:01.000000000 +0800 +diff -Nru ./linux-2.6.21.5/include/linux/netfilter_ipv4/ip_set_portmap.h linux-2.6.21.5.pom2patch.set/include/linux/netfilter_ipv4/ip_set_portmap.h +--- ./linux-2.6.21.5/include/linux/netfilter_ipv4/ip_set_portmap.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.21.5.pom2patch.set/include/linux/netfilter_ipv4/ip_set_portmap.h 2007-10-12 14:28:29.000000000 +0200 @@ -0,0 +1,25 @@ +#ifndef __IP_SET_PORTMAP_H +#define __IP_SET_PORTMAP_H @@ -935,10 +1122,9 @@ Index: linux-2.6.23-rc6/include/linux/netfilter_ipv4/ip_set_portmap.h +}; + +#endif /* __IP_SET_PORTMAP_H */ -Index: linux-2.6.23-rc6/include/linux/netfilter_ipv4/ipt_set.h -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.23-rc6/include/linux/netfilter_ipv4/ipt_set.h 2007-09-21 16:24:01.000000000 +0800 +diff -Nru ./linux-2.6.21.5/include/linux/netfilter_ipv4/ipt_set.h linux-2.6.21.5.pom2patch.set/include/linux/netfilter_ipv4/ipt_set.h +--- ./linux-2.6.21.5/include/linux/netfilter_ipv4/ipt_set.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.21.5.pom2patch.set/include/linux/netfilter_ipv4/ipt_set.h 2007-10-12 14:28:29.000000000 +0200 @@ -0,0 +1,21 @@ +#ifndef _IPT_SET_H +#define _IPT_SET_H @@ -961,11 +1147,10 @@ Index: linux-2.6.23-rc6/include/linux/netfilter_ipv4/ipt_set.h +}; + +#endif /*_IPT_SET_H*/ -Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.23-rc6/net/ipv4/netfilter/ip_set.c 2007-09-21 16:24:01.000000000 +0800 -@@ -0,0 +1,2001 @@ +diff -Nru ./linux-2.6.21.5/net/ipv4/netfilter/ip_set.c linux-2.6.21.5.pom2patch.set/net/ipv4/netfilter/ip_set.c +--- ./linux-2.6.21.5/net/ipv4/netfilter/ip_set.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.21.5.pom2patch.set/net/ipv4/netfilter/ip_set.c 2007-10-12 14:28:29.000000000 +0200 +@@ -0,0 +1,2003 @@ +/* Copyright (C) 2000-2002 Joakim Axelsson + * Patrick Schaaf + * Copyright (C) 2003-2004 Jozsef Kadlecsik @@ -2896,7 +3081,9 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set.c + .get_optmin = SO_IP_SET, + .get_optmax = SO_IP_SET + 1, + .get = &ip_set_sockfn_get, -+ .use = 0 ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) ++ .owner = THIS_MODULE, ++#endif +}; + +static int max_sets, hash_size; @@ -2908,7 +3095,7 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set.c +MODULE_AUTHOR("Jozsef Kadlecsik "); +MODULE_DESCRIPTION("module implementing core IP set support"); + -+static int __init init(void) ++static int __init ip_set_init(void) +{ + int res; + ip_set_id_t i; @@ -2945,7 +3132,7 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set.c + return 0; +} + -+static void __exit fini(void) ++static void __exit ip_set_fini(void) +{ + /* There can't be any existing set or binding */ + nf_unregister_sockopt(&so_set); @@ -2965,13 +3152,12 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set.c +EXPORT_SYMBOL(ip_set_delip_kernel); +EXPORT_SYMBOL(ip_set_testip_kernel); + -+module_init(init); -+module_exit(fini); -Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_iphash.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_iphash.c 2007-09-21 16:24:01.000000000 +0800 -@@ -0,0 +1,413 @@ ++module_init(ip_set_init); ++module_exit(ip_set_fini); +diff -Nru ./linux-2.6.21.5/net/ipv4/netfilter/ip_set_iphash.c linux-2.6.21.5.pom2patch.set/net/ipv4/netfilter/ip_set_iphash.c +--- ./linux-2.6.21.5/net/ipv4/netfilter/ip_set_iphash.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.21.5.pom2patch.set/net/ipv4/netfilter/ip_set_iphash.c 2007-10-12 14:28:29.000000000 +0200 +@@ -0,0 +1,429 @@ +/* Copyright (C) 2003-2004 Jozsef Kadlecsik + * + * This program is free software; you can redistribute it and/or modify @@ -2984,6 +3170,8 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_iphash.c +#include +#include +#include ++#include ++#include +#include +#include +#include @@ -2992,7 +3180,6 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_iphash.c +#include +#include +#include -+#include + +#include + @@ -3062,8 +3249,13 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_iphash.c +{ + return __testip(set, + ntohl(flags[index] & IPSET_SRC ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + ? ip_hdr(skb)->saddr + : ip_hdr(skb)->daddr), ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr), ++#endif + hash_ip); +} + @@ -3074,7 +3266,7 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_iphash.c + u_int16_t i; + ip_set_ip_t *elem; + -+ if (!ip || map->elements > limit) ++ if (!ip || map->elements >= limit) + return -ERANGE; + + *hash_ip = ip & map->netmask; @@ -3119,8 +3311,13 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_iphash.c +{ + return __addip((struct ip_set_iphash *) set->data, + ntohl(flags[index] & IPSET_SRC -+ ? ip_hdr(skb)->saddr ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr + : ip_hdr(skb)->daddr), ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr), ++#endif + hash_ip); +} + @@ -3242,8 +3439,13 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_iphash.c +{ + return __delip(set, + ntohl(flags[index] & IPSET_SRC ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + ? ip_hdr(skb)->saddr + : ip_hdr(skb)->daddr), ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr), ++#endif + hash_ip); +} + @@ -3372,24 +3574,23 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_iphash.c +module_param(limit, int, 0600); +MODULE_PARM_DESC(limit, "maximal number of elements stored in the sets"); + -+static int __init init(void) ++static int __init ip_set_iphash_init(void) +{ + return ip_set_register_set_type(&ip_set_iphash); +} + -+static void __exit fini(void) ++static void __exit ip_set_iphash_fini(void) +{ + /* FIXME: possible race with ip_set_create() */ + ip_set_unregister_set_type(&ip_set_iphash); +} + -+module_init(init); -+module_exit(fini); -Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_ipmap.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_ipmap.c 2007-09-21 16:24:01.000000000 +0800 -@@ -0,0 +1,327 @@ ++module_init(ip_set_iphash_init); ++module_exit(ip_set_iphash_fini); +diff -Nru ./linux-2.6.21.5/net/ipv4/netfilter/ip_set_ipmap.c linux-2.6.21.5.pom2patch.set/net/ipv4/netfilter/ip_set_ipmap.c +--- ./linux-2.6.21.5/net/ipv4/netfilter/ip_set_ipmap.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.21.5.pom2patch.set/net/ipv4/netfilter/ip_set_ipmap.c 2007-10-12 14:28:29.000000000 +0200 +@@ -0,0 +1,336 @@ +/* Copyright (C) 2000-2002 Joakim Axelsson + * Patrick Schaaf + * Copyright (C) 2003-2004 Jozsef Kadlecsik @@ -3404,13 +3605,14 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_ipmap.c +#include +#include +#include ++#include +#include +#include +#include +#include +#include +#include -+#include ++ +#include + +static inline ip_set_ip_t @@ -3456,17 +3658,15 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_ipmap.c + const u_int32_t *flags, + unsigned char index) +{ -+ int res; -+ -+ DP("flag: %s src: %u.%u.%u.%u dst: %u.%u.%u.%u", -+ flags[index] & IPSET_SRC ? "SRC" : "DST", -+ NIPQUAD(ip_hdr(skb)->saddr), -+ NIPQUAD(ip_hdr(skb)->daddr)); -+ -+ res = __testip(set, -+ ntohl(flags[index] & IPSET_SRC ++ int res = __testip(set, ++ ntohl(flags[index] & IPSET_SRC ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + ? ip_hdr(skb)->saddr + : ip_hdr(skb)->daddr), ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr), ++#endif + hash_ip); + return (res < 0 ? 0 : res); +} @@ -3513,8 +3713,13 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_ipmap.c +{ + return __addip(set, + ntohl(flags[index] & IPSET_SRC -+ ? ip_hdr(skb)->saddr ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr + : ip_hdr(skb)->daddr), ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr), ++#endif + hash_ip); +} + @@ -3559,8 +3764,13 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_ipmap.c +{ + return __delip(set, + ntohl(flags[index] & IPSET_SRC ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + ? ip_hdr(skb)->saddr + : ip_hdr(skb)->daddr), ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr), ++#endif + hash_ip); +} + @@ -3704,24 +3914,23 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_ipmap.c +MODULE_AUTHOR("Jozsef Kadlecsik "); +MODULE_DESCRIPTION("ipmap type of IP sets"); + -+static int __init init(void) ++static int __init ip_set_ipmap_init(void) +{ + return ip_set_register_set_type(&ip_set_ipmap); +} + -+static void __exit fini(void) ++static void __exit ip_set_ipmap_fini(void) +{ + /* FIXME: possible race with ip_set_create() */ + ip_set_unregister_set_type(&ip_set_ipmap); +} + -+module_init(init); -+module_exit(fini); -Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_ipporthash.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_ipporthash.c 2007-09-21 16:24:01.000000000 +0800 -@@ -0,0 +1,535 @@ ++module_init(ip_set_ipmap_init); ++module_exit(ip_set_ipmap_fini); +diff -Nru ./linux-2.6.21.5/net/ipv4/netfilter/ip_set_ipporthash.c linux-2.6.21.5.pom2patch.set/net/ipv4/netfilter/ip_set_ipporthash.c +--- ./linux-2.6.21.5/net/ipv4/netfilter/ip_set_ipporthash.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.21.5.pom2patch.set/net/ipv4/netfilter/ip_set_ipporthash.c 2007-10-12 14:28:29.000000000 +0200 +@@ -0,0 +1,581 @@ +/* Copyright (C) 2003-2004 Jozsef Kadlecsik + * + * This program is free software; you can redistribute it and/or modify @@ -3736,6 +3945,8 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_ipporthash.c +#include +#include +#include ++#include ++#include +#include +#include +#include @@ -3744,7 +3955,6 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_ipporthash.c +#include +#include +#include -+#include + +#include + @@ -3757,7 +3967,11 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_ipporthash.c +static inline ip_set_ip_t +get_port(const struct sk_buff *skb, u_int32_t flags) +{ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + struct iphdr *iph = ip_hdr(skb); ++#else ++ struct iphdr *iph = skb->nh.iph; ++#endif + u_int16_t offset = ntohs(iph->frag_off) & IP_OFFSET; + + switch (iph->protocol) { @@ -3768,7 +3982,11 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_ipporthash.c + if (offset) + return INVALID_PORT; + -+ if (skb_copy_bits(skb, ip_hdrlen(skb), &tcph, sizeof(tcph)) < 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ if (skb_copy_bits(skb, ip_hdr(skb)->ihl*4, &tcph, sizeof(tcph)) < 0) ++#else ++ if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &tcph, sizeof(tcph)) < 0) ++#endif + /* No choice either */ + return INVALID_PORT; + @@ -3781,7 +3999,11 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_ipporthash.c + if (offset) + return INVALID_PORT; + -+ if (skb_copy_bits(skb, ip_hdrlen(skb), &udph, sizeof(udph)) < 0) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ if (skb_copy_bits(skb, ip_hdr(skb)->ihl*4, &udph, sizeof(udph)) < 0) ++#else ++ if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &udph, sizeof(udph)) < 0) ++#endif + /* No choice either */ + return INVALID_PORT; + @@ -3863,28 +4085,41 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_ipporthash.c + unsigned char index) +{ + ip_set_ip_t port; ++ int res; + + if (flags[index+1] == 0) -+ return -EINVAL; ++ return 0; + + port = get_port(skb, flags[index+1]); + + DP("flag: %s src: %u.%u.%u.%u dst: %u.%u.%u.%u", + flags[index] & IPSET_SRC ? "SRC" : "DST", ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + NIPQUAD(ip_hdr(skb)->saddr), + NIPQUAD(ip_hdr(skb)->daddr)); ++#else ++ NIPQUAD(skb->nh.iph->saddr), ++ NIPQUAD(skb->nh.iph->daddr)); ++#endif + DP("flag %s port %u", + flags[index+1] & IPSET_SRC ? "SRC" : "DST", + port); + if (port == INVALID_PORT) + return 0; + -+ return __testip(set, ++ res = __testip(set, + ntohl(flags[index] & IPSET_SRC ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + ? ip_hdr(skb)->saddr + : ip_hdr(skb)->daddr), ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr), ++#endif + port, + hash_ip); ++ return (res < 0 ? 0 : res); ++ +} + +static inline int @@ -3956,8 +4191,13 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_ipporthash.c + + DP("flag: %s src: %u.%u.%u.%u dst: %u.%u.%u.%u", + flags[index] & IPSET_SRC ? "SRC" : "DST", ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + NIPQUAD(ip_hdr(skb)->saddr), + NIPQUAD(ip_hdr(skb)->daddr)); ++#else ++ NIPQUAD(skb->nh.iph->saddr), ++ NIPQUAD(skb->nh.iph->daddr)); ++#endif + DP("flag %s port %u", + flags[index+1] & IPSET_SRC ? "SRC" : "DST", + port); @@ -3966,8 +4206,13 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_ipporthash.c + + return __addip((struct ip_set_ipporthash *) set->data, + ntohl(flags[index] & IPSET_SRC -+ ? ip_hdr(skb)->saddr ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr + : ip_hdr(skb)->daddr), ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr), ++#endif + port, + hash_ip); +} @@ -4101,8 +4346,13 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_ipporthash.c + + DP("flag: %s src: %u.%u.%u.%u dst: %u.%u.%u.%u", + flags[index] & IPSET_SRC ? "SRC" : "DST", ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + NIPQUAD(ip_hdr(skb)->saddr), + NIPQUAD(ip_hdr(skb)->daddr)); ++#else ++ NIPQUAD(skb->nh.iph->saddr), ++ NIPQUAD(skb->nh.iph->daddr)); ++#endif + DP("flag %s port %u", + flags[index+1] & IPSET_SRC ? "SRC" : "DST", + port); @@ -4111,8 +4361,13 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_ipporthash.c + + return __delip(set, + ntohl(flags[index] & IPSET_SRC -+ ? ip_hdr(skb)->saddr ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr + : ip_hdr(skb)->daddr), ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr), ++#endif + port, + hash_ip); +} @@ -4244,24 +4499,23 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_ipporthash.c +module_param(limit, int, 0600); +MODULE_PARM_DESC(limit, "maximal number of elements stored in the sets"); + -+static int __init init(void) ++static int __init ip_set_ipporthash_init(void) +{ + return ip_set_register_set_type(&ip_set_ipporthash); +} + -+static void __exit fini(void) ++static void __exit ip_set_ipporthash_fini(void) +{ + /* FIXME: possible race with ip_set_create() */ + ip_set_unregister_set_type(&ip_set_ipporthash); +} + -+module_init(init); -+module_exit(fini); -Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_iptree.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_iptree.c 2007-09-21 16:24:01.000000000 +0800 -@@ -0,0 +1,571 @@ ++module_init(ip_set_ipporthash_init); ++module_exit(ip_set_ipporthash_fini); +diff -Nru ./linux-2.6.21.5/net/ipv4/netfilter/ip_set_iptree.c linux-2.6.21.5.pom2patch.set/net/ipv4/netfilter/ip_set_iptree.c +--- ./linux-2.6.21.5/net/ipv4/netfilter/ip_set_iptree.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.21.5.pom2patch.set/net/ipv4/netfilter/ip_set_iptree.c 2007-10-12 14:28:29.000000000 +0200 +@@ -0,0 +1,612 @@ +/* Copyright (C) 2005 Jozsef Kadlecsik + * + * This program is free software; you can redistribute it and/or modify @@ -4307,12 +4561,23 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_iptree.c +static kmem_cache_t *leaf_cachep; +#endif + ++#if defined(__LITTLE_ENDIAN) +#define ABCD(a,b,c,d,addrp) do { \ + a = ((unsigned char *)addrp)[3]; \ + b = ((unsigned char *)addrp)[2]; \ + c = ((unsigned char *)addrp)[1]; \ + d = ((unsigned char *)addrp)[0]; \ +} while (0) ++#elif defined(__BIG_ENDIAN) ++#define ABCD(a,b,c,d,addrp) do { \ ++ a = ((unsigned char *)addrp)[0]; \ ++ b = ((unsigned char *)addrp)[1]; \ ++ c = ((unsigned char *)addrp)[2]; \ ++ d = ((unsigned char *)addrp)[3]; \ ++} while (0) ++#else ++#error "Please fix asm/byteorder.h" ++#endif /* __LITTLE_ENDIAN */ + +#define TESTIP_WALK(map, elem, branch) do { \ + if ((map)->tree[elem]) { \ @@ -4340,8 +4605,9 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_iptree.c + TESTIP_WALK(btree, b, ctree); + TESTIP_WALK(ctree, c, dtree); + DP("%lu %lu", dtree->expires[d], jiffies); -+ return !!(map->timeout ? (time_after(dtree->expires[d], jiffies)) -+ : dtree->expires[d]); ++ return dtree->expires[d] ++ && (!map->timeout ++ || time_after(dtree->expires[d], jiffies)); +} + +static int @@ -4371,24 +4637,34 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_iptree.c + + DP("flag: %s src: %u.%u.%u.%u dst: %u.%u.%u.%u", + flags[index] & IPSET_SRC ? "SRC" : "DST", ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + NIPQUAD(ip_hdr(skb)->saddr), + NIPQUAD(ip_hdr(skb)->daddr)); ++#else ++ NIPQUAD(skb->nh.iph->saddr), ++ NIPQUAD(skb->nh.iph->daddr)); ++#endif + + res = __testip(set, + ntohl(flags[index] & IPSET_SRC ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + ? ip_hdr(skb)->saddr + : ip_hdr(skb)->daddr), ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr), ++#endif + hash_ip); + return (res < 0 ? 0 : res); +} + -+#define ADDIP_WALK(map, elem, branch, type, cachep, flags) do { \ ++#define ADDIP_WALK(map, elem, branch, type, cachep) do { \ + if ((map)->tree[elem]) { \ + DP("found %u", elem); \ + branch = (map)->tree[elem]; \ + } else { \ + branch = (type *) \ -+ kmem_cache_alloc(cachep, flags); \ ++ kmem_cache_alloc(cachep, GFP_ATOMIC); \ + if (branch == NULL) \ + return -ENOMEM; \ + memset(branch, 0, sizeof(*branch)); \ @@ -4399,8 +4675,7 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_iptree.c + +static inline int +__addip(struct ip_set *set, ip_set_ip_t ip, unsigned int timeout, -+ ip_set_ip_t *hash_ip, -+ unsigned int __nocast flags) ++ ip_set_ip_t *hash_ip) +{ + struct ip_set_iptree *map = (struct ip_set_iptree *) set->data; + struct ip_set_iptreeb *btree; @@ -4409,7 +4684,7 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_iptree.c + unsigned char a,b,c,d; + int ret = 0; + -+ if (!ip || map->elements > limit) ++ if (!ip || map->elements >= limit) + /* We could call the garbage collector + * but it's probably overkill */ + return -ERANGE; @@ -4417,14 +4692,14 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_iptree.c + *hash_ip = ip; + ABCD(a, b, c, d, hash_ip); + DP("%u %u %u %u timeout %u", a, b, c, d, timeout); -+ ADDIP_WALK(map, a, btree, struct ip_set_iptreeb, branch_cachep, flags); -+ ADDIP_WALK(btree, b, ctree, struct ip_set_iptreec, branch_cachep, flags); -+ ADDIP_WALK(ctree, c, dtree, struct ip_set_iptreed, leaf_cachep, flags); ++ ADDIP_WALK(map, a, btree, struct ip_set_iptreeb, branch_cachep); ++ ADDIP_WALK(btree, b, ctree, struct ip_set_iptreec, branch_cachep); ++ ADDIP_WALK(ctree, c, dtree, struct ip_set_iptreed, leaf_cachep); + if (dtree->expires[d] + && (!map->timeout || time_after(dtree->expires[d], jiffies))) + ret = -EEXIST; + dtree->expires[d] = map->timeout ? (timeout * HZ + jiffies) : 1; -+ /* Lottery */ ++ /* Lottery: I won! */ + if (dtree->expires[d] == 0) + dtree->expires[d] = 1; + DP("%u %lu", d, dtree->expires[d]); @@ -4450,8 +4725,7 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_iptree.c + DP("%u.%u.%u.%u %u", HIPQUAD(req->ip), req->timeout); + return __addip(set, req->ip, + req->timeout ? req->timeout : map->timeout, -+ hash_ip, -+ GFP_ATOMIC); ++ hash_ip); +} + +static int @@ -4465,11 +4739,15 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_iptree.c + + return __addip(set, + ntohl(flags[index] & IPSET_SRC -+ ? ip_hdr(skb)->saddr ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr + : ip_hdr(skb)->daddr), ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr), ++#endif + map->timeout, -+ hash_ip, -+ GFP_ATOMIC); ++ hash_ip); +} + +#define DELIP_WALK(map, elem, branch) do { \ @@ -4530,8 +4808,13 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_iptree.c +{ + return __delip(set, + ntohl(flags[index] & IPSET_SRC -+ ? ip_hdr(skb)->saddr ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr + : ip_hdr(skb)->daddr), ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr), ++#endif + hash_ip); +} + @@ -4792,21 +5075,33 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_iptree.c +module_param(limit, int, 0600); +MODULE_PARM_DESC(limit, "maximal number of elements stored in the sets"); + -+static int __init init(void) ++static int __init ip_set_iptree_init(void) +{ + int ret; + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) ++ branch_cachep = kmem_cache_create("ip_set_iptreeb", ++ sizeof(struct ip_set_iptreeb), ++ 0, 0, NULL); ++#else + branch_cachep = kmem_cache_create("ip_set_iptreeb", + sizeof(struct ip_set_iptreeb), + 0, 0, NULL, NULL); ++#endif + if (!branch_cachep) { + printk(KERN_ERR "Unable to create ip_set_iptreeb slab cache\n"); + ret = -ENOMEM; + goto out; + } ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) ++ leaf_cachep = kmem_cache_create("ip_set_iptreed", ++ sizeof(struct ip_set_iptreed), ++ 0, 0, NULL); ++#else + leaf_cachep = kmem_cache_create("ip_set_iptreed", + sizeof(struct ip_set_iptreed), + 0, 0, NULL, NULL); ++#endif + if (!leaf_cachep) { + printk(KERN_ERR "Unable to create ip_set_iptreed slab cache\n"); + ret = -ENOMEM; @@ -4823,7 +5118,7 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_iptree.c + return ret; +} + -+static void __exit fini(void) ++static void __exit ip_set_iptree_fini(void) +{ + /* FIXME: possible race with ip_set_create() */ + ip_set_unregister_set_type(&ip_set_iptree); @@ -4831,13 +5126,845 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_iptree.c + kmem_cache_destroy(branch_cachep); +} + -+module_init(init); -+module_exit(fini); -Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_macipmap.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_macipmap.c 2007-09-21 16:24:01.000000000 +0800 -@@ -0,0 +1,353 @@ ++module_init(ip_set_iptree_init); ++module_exit(ip_set_iptree_fini); +diff -Nru ./linux-2.6.21.5/net/ipv4/netfilter/ip_set_iptreemap.c linux-2.6.21.5.pom2patch.set/net/ipv4/netfilter/ip_set_iptreemap.c +--- ./linux-2.6.21.5/net/ipv4/netfilter/ip_set_iptreemap.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.21.5.pom2patch.set/net/ipv4/netfilter/ip_set_iptreemap.c 2007-10-12 14:28:29.000000000 +0200 +@@ -0,0 +1,829 @@ ++/* Copyright (C) 2007 Sven Wegener ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published by ++ * the Free Software Foundation. ++ */ ++ ++/* This modules implements the iptreemap ipset type. It uses bitmaps to ++ * represent every single IPv4 address as a single bit. The bitmaps are managed ++ * in a tree structure, where the first three octets of an addresses are used ++ * as an index to find the bitmap and the last octet is used as the bit number. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#define IPTREEMAP_DEFAULT_GC_TIME (5 * 60) ++#define IPTREEMAP_DESTROY_SLEEP (100) ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21) ++static struct kmem_cache *cachep_b; ++static struct kmem_cache *cachep_c; ++static struct kmem_cache *cachep_d; ++#else ++static kmem_cache_t *cachep_b; ++static kmem_cache_t *cachep_c; ++static kmem_cache_t *cachep_d; ++#endif ++ ++static struct ip_set_iptreemap_d *fullbitmap_d; ++static struct ip_set_iptreemap_c *fullbitmap_c; ++static struct ip_set_iptreemap_b *fullbitmap_b; ++ ++#if defined(__LITTLE_ENDIAN) ++#define ABCD(a, b, c, d, addr) \ ++ do { \ ++ a = ((unsigned char *)addr)[3]; \ ++ b = ((unsigned char *)addr)[2]; \ ++ c = ((unsigned char *)addr)[1]; \ ++ d = ((unsigned char *)addr)[0]; \ ++ } while (0) ++#elif defined(__BIG_ENDIAN) ++#define ABCD(a,b,c,d,addrp) do { \ ++ a = ((unsigned char *)addrp)[0]; \ ++ b = ((unsigned char *)addrp)[1]; \ ++ c = ((unsigned char *)addrp)[2]; \ ++ d = ((unsigned char *)addrp)[3]; \ ++} while (0) ++#else ++#error "Please fix asm/byteorder.h" ++#endif /* __LITTLE_ENDIAN */ ++ ++#define TESTIP_WALK(map, elem, branch, full) \ ++ do { \ ++ branch = (map)->tree[elem]; \ ++ if (!branch) \ ++ return 0; \ ++ else if (branch == full) \ ++ return 1; \ ++ } while (0) ++ ++#define ADDIP_WALK(map, elem, branch, type, cachep, full) \ ++ do { \ ++ branch = (map)->tree[elem]; \ ++ if (!branch) { \ ++ branch = (type *) kmem_cache_alloc(cachep, GFP_ATOMIC); \ ++ if (!branch) \ ++ return -ENOMEM; \ ++ memset(branch, 0, sizeof(*branch)); \ ++ (map)->tree[elem] = branch; \ ++ } else if (branch == full) { \ ++ return -EEXIST; \ ++ } \ ++ } while (0) ++ ++#define ADDIP_RANGE_LOOP(map, a, a1, a2, hint, branch, full, cachep, free) \ ++ for (a = a1; a <= a2; a++) { \ ++ branch = (map)->tree[a]; \ ++ if (branch != full) { \ ++ if ((a > a1 && a < a2) || (hint)) { \ ++ if (branch) \ ++ free(branch); \ ++ (map)->tree[a] = full; \ ++ continue; \ ++ } else if (!branch) { \ ++ branch = kmem_cache_alloc(cachep, GFP_ATOMIC); \ ++ if (!branch) \ ++ return -ENOMEM; \ ++ memset(branch, 0, sizeof(*branch)); \ ++ (map)->tree[a] = branch; \ ++ } ++ ++#define ADDIP_RANGE_LOOP_END() \ ++ } \ ++ } ++ ++#define DELIP_WALK(map, elem, branch, cachep, full, flags) \ ++ do { \ ++ branch = (map)->tree[elem]; \ ++ if (!branch) { \ ++ return -EEXIST; \ ++ } else if (branch == full) { \ ++ branch = kmem_cache_alloc(cachep, flags); \ ++ if (!branch) \ ++ return -ENOMEM; \ ++ memcpy(branch, full, sizeof(*full)); \ ++ (map)->tree[elem] = branch; \ ++ } \ ++ } while (0) ++ ++#define DELIP_RANGE_LOOP(map, a, a1, a2, hint, branch, full, cachep, free, flags) \ ++ for (a = a1; a <= a2; a++) { \ ++ branch = (map)->tree[a]; \ ++ if (branch) { \ ++ if ((a > a1 && a < a2) || (hint)) { \ ++ if (branch != full) \ ++ free(branch); \ ++ (map)->tree[a] = NULL; \ ++ continue; \ ++ } else if (branch == full) { \ ++ branch = kmem_cache_alloc(cachep, flags); \ ++ if (!branch) \ ++ return -ENOMEM; \ ++ memcpy(branch, full, sizeof(*branch)); \ ++ (map)->tree[a] = branch; \ ++ } ++ ++#define DELIP_RANGE_LOOP_END() \ ++ } \ ++ } ++ ++#define LOOP_WALK_BEGIN(map, i, branch) \ ++ for (i = 0; i < 256; i++) { \ ++ branch = (map)->tree[i]; \ ++ if (likely(!branch)) \ ++ continue; ++ ++#define LOOP_WALK_END() \ ++ } ++ ++#define LOOP_WALK_BEGIN_GC(map, i, branch, full, cachep, count) \ ++ count = -256; \ ++ for (i = 0; i < 256; i++) { \ ++ branch = (map)->tree[i]; \ ++ if (likely(!branch)) \ ++ continue; \ ++ count++; \ ++ if (branch == full) { \ ++ count++; \ ++ continue; \ ++ } ++ ++#define LOOP_WALK_END_GC(map, i, branch, full, cachep, count) \ ++ if (-256 == count) { \ ++ kmem_cache_free(cachep, branch); \ ++ (map)->tree[i] = NULL; \ ++ } else if (256 == count) { \ ++ kmem_cache_free(cachep, branch); \ ++ (map)->tree[i] = full; \ ++ } \ ++ } ++ ++#define LOOP_WALK_BEGIN_COUNT(map, i, branch, inrange, count) \ ++ for (i = 0; i < 256; i++) { \ ++ if (!(map)->tree[i]) { \ ++ if (inrange) { \ ++ count++; \ ++ inrange = 0; \ ++ } \ ++ continue; \ ++ } \ ++ branch = (map)->tree[i]; ++ ++#define LOOP_WALK_END_COUNT() \ ++ } ++ ++#define MIN(a, b) (a < b ? a : b) ++#define MAX(a, b) (a > b ? a : b) ++ ++#define GETVALUE1(a, a1, b1, r) \ ++ (a == a1 ? b1 : r) ++ ++#define GETVALUE2(a, b, a1, b1, c1, r) \ ++ (a == a1 && b == b1 ? c1 : r) ++ ++#define GETVALUE3(a, b, c, a1, b1, c1, d1, r) \ ++ (a == a1 && b == b1 && c == c1 ? d1 : r) ++ ++#define CHECK1(a, a1, a2, b1, b2, c1, c2, d1, d2) \ ++ ( \ ++ GETVALUE1(a, a1, b1, 0) == 0 \ ++ && GETVALUE1(a, a2, b2, 255) == 255 \ ++ && c1 == 0 \ ++ && c2 == 255 \ ++ && d1 == 0 \ ++ && d2 == 255 \ ++ ) ++ ++#define CHECK2(a, b, a1, a2, b1, b2, c1, c2, d1, d2) \ ++ ( \ ++ GETVALUE2(a, b, a1, b1, c1, 0) == 0 \ ++ && GETVALUE2(a, b, a2, b2, c2, 255) == 255 \ ++ && d1 == 0 \ ++ && d2 == 255 \ ++ ) ++ ++#define CHECK3(a, b, c, a1, a2, b1, b2, c1, c2, d1, d2) \ ++ ( \ ++ GETVALUE3(a, b, c, a1, b1, c1, d1, 0) == 0 \ ++ && GETVALUE3(a, b, c, a2, b2, c2, d2, 255) == 255 \ ++ ) ++ ++ ++static inline void ++free_d(struct ip_set_iptreemap_d *map) ++{ ++ kmem_cache_free(cachep_d, map); ++} ++ ++static inline void ++free_c(struct ip_set_iptreemap_c *map) ++{ ++ struct ip_set_iptreemap_d *dtree; ++ unsigned int i; ++ ++ LOOP_WALK_BEGIN(map, i, dtree) { ++ if (dtree != fullbitmap_d) ++ free_d(dtree); ++ } LOOP_WALK_END(); ++ ++ kmem_cache_free(cachep_c, map); ++} ++ ++static inline void ++free_b(struct ip_set_iptreemap_b *map) ++{ ++ struct ip_set_iptreemap_c *ctree; ++ unsigned int i; ++ ++ LOOP_WALK_BEGIN(map, i, ctree) { ++ if (ctree != fullbitmap_c) ++ free_c(ctree); ++ } LOOP_WALK_END(); ++ ++ kmem_cache_free(cachep_b, map); ++} ++ ++static inline int ++__testip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip) ++{ ++ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; ++ struct ip_set_iptreemap_b *btree; ++ struct ip_set_iptreemap_c *ctree; ++ struct ip_set_iptreemap_d *dtree; ++ unsigned char a, b, c, d; ++ ++ *hash_ip = ip; ++ ++ ABCD(a, b, c, d, hash_ip); ++ ++ TESTIP_WALK(map, a, btree, fullbitmap_b); ++ TESTIP_WALK(btree, b, ctree, fullbitmap_c); ++ TESTIP_WALK(ctree, c, dtree, fullbitmap_d); ++ ++ return !!test_bit(d, (void *) dtree->bitmap); ++} ++ ++static int ++testip(struct ip_set *set, const void *data, size_t size, ip_set_ip_t *hash_ip) ++{ ++ struct ip_set_req_iptreemap *req = (struct ip_set_req_iptreemap *) data; ++ ++ if (size != sizeof(struct ip_set_req_iptreemap)) { ++ ip_set_printk("data length wrong (want %zu, have %zu)", sizeof(struct ip_set_req_iptreemap), size); ++ return -EINVAL; ++ } ++ ++ return __testip(set, req->start, hash_ip); ++} ++ ++static int ++testip_kernel(struct ip_set *set, const struct sk_buff *skb, ip_set_ip_t *hash_ip, const u_int32_t *flags, unsigned char index) ++{ ++ int res; ++ ++ res = __testip(set, ++ ntohl(flags[index] & IPSET_SRC ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr ++ : ip_hdr(skb)->daddr), ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr), ++#endif ++ hash_ip); ++ ++ return (res < 0 ? 0 : res); ++} ++ ++static inline int ++__addip_single(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip) ++{ ++ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; ++ struct ip_set_iptreemap_b *btree; ++ struct ip_set_iptreemap_c *ctree; ++ struct ip_set_iptreemap_d *dtree; ++ unsigned char a, b, c, d; ++ ++ *hash_ip = ip; ++ ++ ABCD(a, b, c, d, hash_ip); ++ ++ ADDIP_WALK(map, a, btree, struct ip_set_iptreemap_b, cachep_b, fullbitmap_b); ++ ADDIP_WALK(btree, b, ctree, struct ip_set_iptreemap_c, cachep_c, fullbitmap_c); ++ ADDIP_WALK(ctree, c, dtree, struct ip_set_iptreemap_d, cachep_d, fullbitmap_d); ++ ++ if (test_and_set_bit(d, (void *) dtree->bitmap)) ++ return -EEXIST; ++ ++ set_bit(b, (void *) btree->dirty); ++ ++ return 0; ++} ++ ++static inline int ++__addip_range(struct ip_set *set, ip_set_ip_t start, ip_set_ip_t end, ip_set_ip_t *hash_ip) ++{ ++ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; ++ struct ip_set_iptreemap_b *btree; ++ struct ip_set_iptreemap_c *ctree; ++ struct ip_set_iptreemap_d *dtree; ++ unsigned int a, b, c, d; ++ unsigned char a1, b1, c1, d1; ++ unsigned char a2, b2, c2, d2; ++ ++ if (start == end) ++ return __addip_single(set, start, hash_ip); ++ ++ *hash_ip = start; ++ ++ ABCD(a1, b1, c1, d1, &start); ++ ABCD(a2, b2, c2, d2, &end); ++ ++ /* This is sooo ugly... */ ++ ADDIP_RANGE_LOOP(map, a, a1, a2, CHECK1(a, a1, a2, b1, b2, c1, c2, d1, d2), btree, fullbitmap_b, cachep_b, free_b) { ++ ADDIP_RANGE_LOOP(btree, b, GETVALUE1(a, a1, b1, 0), GETVALUE1(a, a2, b2, 255), CHECK2(a, b, a1, a2, b1, b2, c1, c2, d1, d2), ctree, fullbitmap_c, cachep_c, free_c) { ++ ADDIP_RANGE_LOOP(ctree, c, GETVALUE2(a, b, a1, b1, c1, 0), GETVALUE2(a, b, a2, b2, c2, 255), CHECK3(a, b, c, a1, a2, b1, b2, c1, c2, d1, d2), dtree, fullbitmap_d, cachep_d, free_d) { ++ for (d = GETVALUE3(a, b, c, a1, b1, c1, d1, 0); d <= GETVALUE3(a, b, c, a2, b2, c2, d2, 255); d++) ++ set_bit(d, (void *) dtree->bitmap); ++ set_bit(b, (void *) btree->dirty); ++ } ADDIP_RANGE_LOOP_END(); ++ } ADDIP_RANGE_LOOP_END(); ++ } ADDIP_RANGE_LOOP_END(); ++ ++ return 0; ++} ++ ++static int ++addip(struct ip_set *set, const void *data, size_t size, ip_set_ip_t *hash_ip) ++{ ++ struct ip_set_req_iptreemap *req = (struct ip_set_req_iptreemap *) data; ++ ++ if (size != sizeof(struct ip_set_req_iptreemap)) { ++ ip_set_printk("data length wrong (want %zu, have %zu)", sizeof(struct ip_set_req_iptreemap), size); ++ return -EINVAL; ++ } ++ ++ return __addip_range(set, MIN(req->start, req->end), MAX(req->start, req->end), hash_ip); ++} ++ ++static int ++addip_kernel(struct ip_set *set, const struct sk_buff *skb, ip_set_ip_t *hash_ip, const u_int32_t *flags, unsigned char index) ++{ ++ ++ return __addip_single(set, ++ ntohl(flags[index] & IPSET_SRC ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr ++ : ip_hdr(skb)->daddr), ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr), ++#endif ++ hash_ip); ++} ++ ++static inline int ++__delip_single(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip, unsigned int __nocast flags) ++{ ++ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; ++ struct ip_set_iptreemap_b *btree; ++ struct ip_set_iptreemap_c *ctree; ++ struct ip_set_iptreemap_d *dtree; ++ unsigned char a,b,c,d; ++ ++ *hash_ip = ip; ++ ++ ABCD(a, b, c, d, hash_ip); ++ ++ DELIP_WALK(map, a, btree, cachep_b, fullbitmap_b, flags); ++ DELIP_WALK(btree, b, ctree, cachep_c, fullbitmap_c, flags); ++ DELIP_WALK(ctree, c, dtree, cachep_d, fullbitmap_d, flags); ++ ++ if (!test_and_clear_bit(d, (void *) dtree->bitmap)) ++ return -EEXIST; ++ ++ set_bit(b, (void *) btree->dirty); ++ ++ return 0; ++} ++ ++static inline int ++__delip_range(struct ip_set *set, ip_set_ip_t start, ip_set_ip_t end, ip_set_ip_t *hash_ip, unsigned int __nocast flags) ++{ ++ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; ++ struct ip_set_iptreemap_b *btree; ++ struct ip_set_iptreemap_c *ctree; ++ struct ip_set_iptreemap_d *dtree; ++ unsigned int a, b, c, d; ++ unsigned char a1, b1, c1, d1; ++ unsigned char a2, b2, c2, d2; ++ ++ if (start == end) ++ return __delip_single(set, start, hash_ip, flags); ++ ++ *hash_ip = start; ++ ++ ABCD(a1, b1, c1, d1, &start); ++ ABCD(a2, b2, c2, d2, &end); ++ ++ /* This is sooo ugly... */ ++ DELIP_RANGE_LOOP(map, a, a1, a2, CHECK1(a, a1, a2, b1, b2, c1, c2, d1, d2), btree, fullbitmap_b, cachep_b, free_b, flags) { ++ DELIP_RANGE_LOOP(btree, b, GETVALUE1(a, a1, b1, 0), GETVALUE1(a, a2, b2, 255), CHECK2(a, b, a1, a2, b1, b2, c1, c2, d1, d2), ctree, fullbitmap_c, cachep_c, free_c, flags) { ++ DELIP_RANGE_LOOP(ctree, c, GETVALUE2(a, b, a1, b1, c1, 0), GETVALUE2(a, b, a2, b2, c2, 255), CHECK3(a, b, c, a1, a2, b1, b2, c1, c2, d1, d2), dtree, fullbitmap_d, cachep_d, free_d, flags) { ++ for (d = GETVALUE3(a, b, c, a1, b1, c1, d1, 0); d <= GETVALUE3(a, b, c, a2, b2, c2, d2, 255); d++) ++ clear_bit(d, (void *) dtree->bitmap); ++ set_bit(b, (void *) btree->dirty); ++ } DELIP_RANGE_LOOP_END(); ++ } DELIP_RANGE_LOOP_END(); ++ } DELIP_RANGE_LOOP_END(); ++ ++ return 0; ++} ++ ++static int ++delip(struct ip_set *set, const void *data, size_t size, ip_set_ip_t *hash_ip) ++{ ++ struct ip_set_req_iptreemap *req = (struct ip_set_req_iptreemap *) data; ++ ++ if (size != sizeof(struct ip_set_req_iptreemap)) { ++ ip_set_printk("data length wrong (want %zu, have %zu)", sizeof(struct ip_set_req_iptreemap), size); ++ return -EINVAL; ++ } ++ ++ return __delip_range(set, MIN(req->start, req->end), MAX(req->start, req->end), hash_ip, GFP_KERNEL); ++} ++ ++static int ++delip_kernel(struct ip_set *set, const struct sk_buff *skb, ip_set_ip_t *hash_ip, const u_int32_t *flags, unsigned char index) ++{ ++ return __delip_single(set, ++ ntohl(flags[index] & IPSET_SRC ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr ++ : ip_hdr(skb)->daddr), ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr), ++#endif ++ hash_ip, ++ GFP_ATOMIC); ++} ++ ++/* Check the status of the bitmap ++ * -1 == all bits cleared ++ * 1 == all bits set ++ * 0 == anything else ++ */ ++static inline int ++bitmap_status(struct ip_set_iptreemap_d *dtree) ++{ ++ unsigned char first = dtree->bitmap[0]; ++ int a; ++ ++ for (a = 1; a < 32; a++) ++ if (dtree->bitmap[a] != first) ++ return 0; ++ ++ return (first == 0 ? -1 : (first == 255 ? 1 : 0)); ++} ++ ++static void ++gc(unsigned long addr) ++{ ++ struct ip_set *set = (struct ip_set *) addr; ++ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; ++ struct ip_set_iptreemap_b *btree; ++ struct ip_set_iptreemap_c *ctree; ++ struct ip_set_iptreemap_d *dtree; ++ unsigned int a, b, c; ++ int i, j, k; ++ ++ write_lock_bh(&set->lock); ++ ++ LOOP_WALK_BEGIN_GC(map, a, btree, fullbitmap_b, cachep_b, i) { ++ LOOP_WALK_BEGIN_GC(btree, b, ctree, fullbitmap_c, cachep_c, j) { ++ if (!test_and_clear_bit(b, (void *) btree->dirty)) ++ continue; ++ LOOP_WALK_BEGIN_GC(ctree, c, dtree, fullbitmap_d, cachep_d, k) { ++ switch (bitmap_status(dtree)) { ++ case -1: ++ kmem_cache_free(cachep_d, dtree); ++ ctree->tree[c] = NULL; ++ k--; ++ break; ++ case 1: ++ kmem_cache_free(cachep_d, dtree); ++ ctree->tree[c] = fullbitmap_d; ++ k++; ++ break; ++ } ++ } LOOP_WALK_END(); ++ } LOOP_WALK_END_GC(btree, b, ctree, fullbitmap_c, cachep_c, k); ++ } LOOP_WALK_END_GC(map, a, btree, fullbitmap_b, cachep_b, j); ++ ++ write_unlock_bh(&set->lock); ++ ++ map->gc.expires = jiffies + map->gc_interval * HZ; ++ add_timer(&map->gc); ++} ++ ++static inline void ++init_gc_timer(struct ip_set *set) ++{ ++ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; ++ ++ init_timer(&map->gc); ++ map->gc.data = (unsigned long) set; ++ map->gc.function = gc; ++ map->gc.expires = jiffies + map->gc_interval * HZ; ++ add_timer(&map->gc); ++} ++ ++static int create(struct ip_set *set, const void *data, size_t size) ++{ ++ struct ip_set_req_iptreemap_create *req = (struct ip_set_req_iptreemap_create *) data; ++ struct ip_set_iptreemap *map; ++ ++ if (size != sizeof(struct ip_set_req_iptreemap_create)) { ++ ip_set_printk("data length wrong (want %zu, have %zu)", sizeof(struct ip_set_req_iptreemap_create), size); ++ return -EINVAL; ++ } ++ ++ map = kzalloc(sizeof(*map), GFP_KERNEL); ++ if (!map) ++ return -ENOMEM; ++ ++ map->gc_interval = req->gc_interval ? req->gc_interval : IPTREEMAP_DEFAULT_GC_TIME; ++ set->data = map; ++ ++ init_gc_timer(set); ++ ++ return 0; ++} ++ ++static inline void __flush(struct ip_set_iptreemap *map) ++{ ++ struct ip_set_iptreemap_b *btree; ++ unsigned int a; ++ ++ LOOP_WALK_BEGIN(map, a, btree); ++ if (btree != fullbitmap_b) ++ free_b(btree); ++ LOOP_WALK_END(); ++} ++ ++static void destroy(struct ip_set *set) ++{ ++ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; ++ ++ while (!del_timer(&map->gc)) ++ msleep(IPTREEMAP_DESTROY_SLEEP); ++ ++ __flush(map); ++ kfree(map); ++ ++ set->data = NULL; ++} ++ ++static void flush(struct ip_set *set) ++{ ++ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; ++ ++ while (!del_timer(&map->gc)) ++ msleep(IPTREEMAP_DESTROY_SLEEP); ++ ++ __flush(map); ++ ++ memset(map, 0, sizeof(*map)); ++ ++ init_gc_timer(set); ++} ++ ++static void list_header(const struct ip_set *set, void *data) ++{ ++ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; ++ struct ip_set_req_iptreemap_create *header = (struct ip_set_req_iptreemap_create *) data; ++ ++ header->gc_interval = map->gc_interval; ++} ++ ++static int list_members_size(const struct ip_set *set) ++{ ++ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; ++ struct ip_set_iptreemap_b *btree; ++ struct ip_set_iptreemap_c *ctree; ++ struct ip_set_iptreemap_d *dtree; ++ unsigned int a, b, c, d, inrange = 0, count = 0; ++ ++ LOOP_WALK_BEGIN_COUNT(map, a, btree, inrange, count) { ++ LOOP_WALK_BEGIN_COUNT(btree, b, ctree, inrange, count) { ++ LOOP_WALK_BEGIN_COUNT(ctree, c, dtree, inrange, count) { ++ for (d = 0; d < 256; d++) { ++ if (test_bit(d, (void *) dtree->bitmap)) { ++ inrange = 1; ++ } else if (inrange) { ++ count++; ++ inrange = 0; ++ } ++ } ++ } LOOP_WALK_END_COUNT(); ++ } LOOP_WALK_END_COUNT(); ++ } LOOP_WALK_END_COUNT(); ++ ++ if (inrange) ++ count++; ++ ++ return (count * sizeof(struct ip_set_req_iptreemap)); ++} ++ ++static inline size_t add_member(void *data, size_t offset, ip_set_ip_t start, ip_set_ip_t end) ++{ ++ struct ip_set_req_iptreemap *entry = (struct ip_set_req_iptreemap *) (data + offset); ++ ++ entry->start = start; ++ entry->end = end; ++ ++ return sizeof(*entry); ++} ++ ++static void list_members(const struct ip_set *set, void *data) ++{ ++ struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; ++ struct ip_set_iptreemap_b *btree; ++ struct ip_set_iptreemap_c *ctree; ++ struct ip_set_iptreemap_d *dtree; ++ unsigned int a, b, c, d, inrange = 0; ++ size_t offset = 0; ++ ip_set_ip_t start = 0, end = 0, ip; ++ ++ LOOP_WALK_BEGIN(map, a, btree) { ++ LOOP_WALK_BEGIN(btree, b, ctree) { ++ LOOP_WALK_BEGIN(ctree, c, dtree) { ++ for (d = 0; d < 256; d++) { ++ if (test_bit(d, (void *) dtree->bitmap)) { ++ ip = ((a << 24) | (b << 16) | (c << 8) | d); ++ if (!inrange) { ++ inrange = 1; ++ start = ip; ++ } else if (end < ip - 1) { ++ offset += add_member(data, offset, start, end); ++ start = ip; ++ } ++ end = ip; ++ } else if (inrange) { ++ offset += add_member(data, offset, start, end); ++ inrange = 0; ++ } ++ } ++ } LOOP_WALK_END(); ++ } LOOP_WALK_END(); ++ } LOOP_WALK_END(); ++ ++ if (inrange) ++ add_member(data, offset, start, end); ++} ++ ++static struct ip_set_type ip_set_iptreemap = { ++ .typename = SETTYPE_NAME, ++ .features = IPSET_TYPE_IP | IPSET_DATA_SINGLE, ++ .protocol_version = IP_SET_PROTOCOL_VERSION, ++ .create = create, ++ .destroy = destroy, ++ .flush = flush, ++ .reqsize = sizeof(struct ip_set_req_iptreemap), ++ .addip = addip, ++ .addip_kernel = addip_kernel, ++ .delip = delip, ++ .delip_kernel = delip_kernel, ++ .testip = testip, ++ .testip_kernel = testip_kernel, ++ .header_size = sizeof(struct ip_set_req_iptreemap_create), ++ .list_header = list_header, ++ .list_members_size = list_members_size, ++ .list_members = list_members, ++ .me = THIS_MODULE, ++}; ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Sven Wegener "); ++MODULE_DESCRIPTION("iptreemap type of IP sets"); ++ ++static int __init ip_set_iptreemap_init(void) ++{ ++ int ret = -ENOMEM; ++ int a; ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) ++ cachep_b = kmem_cache_create("ip_set_iptreemap_b", ++ sizeof(struct ip_set_iptreemap_b), ++ 0, 0, NULL); ++#else ++ cachep_b = kmem_cache_create("ip_set_iptreemap_b", ++ sizeof(struct ip_set_iptreemap_b), ++ 0, 0, NULL, NULL); ++#endif ++ if (!cachep_b) { ++ ip_set_printk("Unable to create ip_set_iptreemap_b slab cache"); ++ goto out; ++ } ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) ++ cachep_c = kmem_cache_create("ip_set_iptreemap_c", ++ sizeof(struct ip_set_iptreemap_c), ++ 0, 0, NULL); ++#else ++ cachep_c = kmem_cache_create("ip_set_iptreemap_c", ++ sizeof(struct ip_set_iptreemap_c), ++ 0, 0, NULL, NULL); ++#endif ++ if (!cachep_c) { ++ ip_set_printk("Unable to create ip_set_iptreemap_c slab cache"); ++ goto outb; ++ } ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) ++ cachep_d = kmem_cache_create("ip_set_iptreemap_d", ++ sizeof(struct ip_set_iptreemap_d), ++ 0, 0, NULL); ++#else ++ cachep_d = kmem_cache_create("ip_set_iptreemap_d", ++ sizeof(struct ip_set_iptreemap_d), ++ 0, 0, NULL, NULL); ++#endif ++ if (!cachep_d) { ++ ip_set_printk("Unable to create ip_set_iptreemap_d slab cache"); ++ goto outc; ++ } ++ ++ fullbitmap_d = kmem_cache_alloc(cachep_d, GFP_KERNEL); ++ if (!fullbitmap_d) ++ goto outd; ++ ++ fullbitmap_c = kmem_cache_alloc(cachep_c, GFP_KERNEL); ++ if (!fullbitmap_c) ++ goto outbitmapd; ++ ++ fullbitmap_b = kmem_cache_alloc(cachep_b, GFP_KERNEL); ++ if (!fullbitmap_b) ++ goto outbitmapc; ++ ++ ret = ip_set_register_set_type(&ip_set_iptreemap); ++ if (0 > ret) ++ goto outbitmapb; ++ ++ /* Now init our global bitmaps */ ++ memset(fullbitmap_d->bitmap, 0xff, sizeof(fullbitmap_d->bitmap)); ++ ++ for (a = 0; a < 256; a++) ++ fullbitmap_c->tree[a] = fullbitmap_d; ++ ++ for (a = 0; a < 256; a++) ++ fullbitmap_b->tree[a] = fullbitmap_c; ++ memset(fullbitmap_b->dirty, 0, sizeof(fullbitmap_b->dirty)); ++ ++ return 0; ++ ++outbitmapb: ++ kmem_cache_free(cachep_b, fullbitmap_b); ++outbitmapc: ++ kmem_cache_free(cachep_c, fullbitmap_c); ++outbitmapd: ++ kmem_cache_free(cachep_d, fullbitmap_d); ++outd: ++ kmem_cache_destroy(cachep_d); ++outc: ++ kmem_cache_destroy(cachep_c); ++outb: ++ kmem_cache_destroy(cachep_b); ++out: ++ ++ return ret; ++} ++ ++static void __exit ip_set_iptreemap_fini(void) ++{ ++ ip_set_unregister_set_type(&ip_set_iptreemap); ++ kmem_cache_free(cachep_d, fullbitmap_d); ++ kmem_cache_free(cachep_c, fullbitmap_c); ++ kmem_cache_free(cachep_b, fullbitmap_b); ++ kmem_cache_destroy(cachep_d); ++ kmem_cache_destroy(cachep_c); ++ kmem_cache_destroy(cachep_b); ++} ++ ++module_init(ip_set_iptreemap_init); ++module_exit(ip_set_iptreemap_fini); +diff -Nru ./linux-2.6.21.5/net/ipv4/netfilter/ip_set_macipmap.c linux-2.6.21.5.pom2patch.set/net/ipv4/netfilter/ip_set_macipmap.c +--- ./linux-2.6.21.5/net/ipv4/netfilter/ip_set_macipmap.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.21.5.pom2patch.set/net/ipv4/netfilter/ip_set_macipmap.c 2007-10-12 14:28:29.000000000 +0200 +@@ -0,0 +1,375 @@ +/* Copyright (C) 2000-2002 Joakim Axelsson + * Patrick Schaaf + * Martin Josefsson @@ -4853,6 +5980,7 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_macipmap.c +#include +#include +#include ++#include +#include +#include +#include @@ -4909,12 +6037,13 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_macipmap.c + ip_set_ip_t ip; + + ip = ntohl(flags[index] & IPSET_SRC -+ ? ip_hdr(skb)->saddr ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr + : ip_hdr(skb)->daddr); -+ DP("flag: %s src: %u.%u.%u.%u dst: %u.%u.%u.%u", -+ flags[index] & IPSET_SRC ? "SRC" : "DST", -+ NIPQUAD(ip_hdr(skb)->saddr), -+ NIPQUAD(ip_hdr(skb)->daddr)); ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr); ++#endif + + if (ip < map->first_ip || ip > map->last_ip) + return 0; @@ -4926,8 +6055,13 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_macipmap.c + (void *) &table[ip - map->first_ip].flags)) { + /* Is mac pointer valid? + * If so, compare... */ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + return (skb_mac_header(skb) >= skb->head + && (skb_mac_header(skb) + ETH_HLEN) <= skb->data ++#else ++ return (skb->mac.raw >= skb->head ++ && (skb->mac.raw + ETH_HLEN) <= skb->data ++#endif + && (memcmp(eth_hdr(skb)->h_source, + &table[ip - map->first_ip].ethernet, + ETH_ALEN) == 0)); @@ -4984,11 +6118,21 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_macipmap.c + ip_set_ip_t ip; + + ip = ntohl(flags[index] & IPSET_SRC -+ ? ip_hdr(skb)->saddr ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr + : ip_hdr(skb)->daddr); ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr); ++#endif + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + if (!(skb_mac_header(skb) >= skb->head + && (skb_mac_header(skb) + ETH_HLEN) <= skb->data)) ++#else ++ if (!(skb->mac.raw >= skb->head ++ && (skb->mac.raw + ETH_HLEN) <= skb->data)) ++#endif + return -EINVAL; + + return __addip(set, ip, eth_hdr(skb)->h_source, hash_ip); @@ -5038,8 +6182,13 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_macipmap.c +{ + return __delip(set, + ntohl(flags[index] & IPSET_SRC -+ ? ip_hdr(skb)->saddr ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr + : ip_hdr(skb)->daddr), ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr), ++#endif + hash_ip); +} + @@ -5177,25 +6326,24 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_macipmap.c +MODULE_AUTHOR("Jozsef Kadlecsik "); +MODULE_DESCRIPTION("macipmap type of IP sets"); + -+static int __init init(void) ++static int __init ip_set_macipmap_init(void) +{ + init_max_malloc_size(); + return ip_set_register_set_type(&ip_set_macipmap); +} + -+static void __exit fini(void) ++static void __exit ip_set_macipmap_fini(void) +{ + /* FIXME: possible race with ip_set_create() */ + ip_set_unregister_set_type(&ip_set_macipmap); +} + -+module_init(init); -+module_exit(fini); -Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_nethash.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_nethash.c 2007-09-21 16:24:01.000000000 +0800 -@@ -0,0 +1,481 @@ ++module_init(ip_set_macipmap_init); ++module_exit(ip_set_macipmap_fini); +diff -Nru ./linux-2.6.21.5/net/ipv4/netfilter/ip_set_nethash.c linux-2.6.21.5.pom2patch.set/net/ipv4/netfilter/ip_set_nethash.c +--- ./linux-2.6.21.5/net/ipv4/netfilter/ip_set_nethash.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.21.5.pom2patch.set/net/ipv4/netfilter/ip_set_nethash.c 2007-10-12 14:28:29.000000000 +0200 +@@ -0,0 +1,497 @@ +/* Copyright (C) 2003-2004 Jozsef Kadlecsik + * + * This program is free software; you can redistribute it and/or modify @@ -5208,6 +6356,8 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_nethash.c +#include +#include +#include ++#include ++#include +#include +#include +#include @@ -5216,7 +6366,6 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_nethash.c +#include +#include +#include -+#include + +#include + @@ -5309,8 +6458,13 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_nethash.c +{ + return __testip(set, + ntohl(flags[index] & IPSET_SRC ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + ? ip_hdr(skb)->saddr + : ip_hdr(skb)->daddr), ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr), ++#endif + hash_ip); +} + @@ -5340,7 +6494,7 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_nethash.c +__addip(struct ip_set_nethash *map, ip_set_ip_t ip, unsigned char cidr, + ip_set_ip_t *hash_ip) +{ -+ if (!ip || map->elements > limit) ++ if (!ip || map->elements >= limit) + return -ERANGE; + + *hash_ip = pack(ip, cidr); @@ -5402,8 +6556,13 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_nethash.c + struct ip_set_nethash *map = (struct ip_set_nethash *) set->data; + int ret = -ERANGE; + ip_set_ip_t ip = ntohl(flags[index] & IPSET_SRC -+ ? ip_hdr(skb)->saddr ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr + : ip_hdr(skb)->daddr); ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr); ++#endif + + if (map->cidr[0]) + ret = __addip(map, ip, map->cidr[0], hash_ip); @@ -5531,8 +6690,13 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_nethash.c + struct ip_set_nethash *map = (struct ip_set_nethash *) set->data; + int ret = -ERANGE; + ip_set_ip_t ip = ntohl(flags[index] & IPSET_SRC -+ ? ip_hdr(skb)->saddr ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) ++ ? ip_hdr(skb)->saddr + : ip_hdr(skb)->daddr); ++#else ++ ? skb->nh.iph->saddr ++ : skb->nh.iph->daddr); ++#endif + + if (map->cidr[0]) + ret = __delip(map, ip, map->cidr[0], hash_ip); @@ -5664,24 +6828,23 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_nethash.c +module_param(limit, int, 0600); +MODULE_PARM_DESC(limit, "maximal number of elements stored in the sets"); + -+static int __init init(void) ++static int __init ip_set_nethash_init(void) +{ + return ip_set_register_set_type(&ip_set_nethash); +} + -+static void __exit fini(void) ++static void __exit ip_set_nethash_fini(void) +{ + /* FIXME: possible race with ip_set_create() */ + ip_set_unregister_set_type(&ip_set_nethash); +} + -+module_init(init); -+module_exit(fini); -Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_portmap.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_portmap.c 2007-09-21 16:24:01.000000000 +0800 -@@ -0,0 +1,334 @@ ++module_init(ip_set_nethash_init); ++module_exit(ip_set_nethash_fini); +diff -Nru ./linux-2.6.21.5/net/ipv4/netfilter/ip_set_portmap.c linux-2.6.21.5.pom2patch.set/net/ipv4/netfilter/ip_set_portmap.c +--- ./linux-2.6.21.5/net/ipv4/netfilter/ip_set_portmap.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.21.5.pom2patch.set/net/ipv4/netfilter/ip_set_portmap.c 2007-10-12 14:28:29.000000000 +0200 +@@ -0,0 +1,346 @@ +/* Copyright (C) 2003-2004 Jozsef Kadlecsik + * + * This program is free software; you can redistribute it and/or modify @@ -5696,6 +6859,7 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_portmap.c +#include +#include +#include ++#include +#include +#include +#include @@ -5711,9 +6875,12 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_portmap.c +static inline ip_set_ip_t +get_port(const struct sk_buff *skb, u_int32_t flags) +{ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + struct iphdr *iph = ip_hdr(skb); ++#else ++ struct iphdr *iph = skb->nh.iph; ++#endif + u_int16_t offset = ntohs(iph->frag_off) & IP_OFFSET; -+ + switch (iph->protocol) { + case IPPROTO_TCP: { + struct tcphdr tcph; @@ -5722,7 +6889,11 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_portmap.c + if (offset) + return INVALID_PORT; + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + if (skb_copy_bits(skb, ip_hdr(skb)->ihl*4, &tcph, sizeof(tcph)) < 0) ++#else ++ if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &tcph, sizeof(tcph)) < 0) ++#endif + /* No choice either */ + return INVALID_PORT; + @@ -5735,7 +6906,11 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_portmap.c + if (offset) + return INVALID_PORT; + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22) + if (skb_copy_bits(skb, ip_hdr(skb)->ihl*4, &udph, sizeof(udph)) < 0) ++#else ++ if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &udph, sizeof(udph)) < 0) ++#endif + /* No choice either */ + return INVALID_PORT; + @@ -6003,24 +7178,23 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ip_set_portmap.c +MODULE_AUTHOR("Jozsef Kadlecsik "); +MODULE_DESCRIPTION("portmap type of IP sets"); + -+static int __init init(void) ++static int __init ip_set_portmap_init(void) +{ + return ip_set_register_set_type(&ip_set_portmap); +} + -+static void __exit fini(void) ++static void __exit ip_set_portmap_fini(void) +{ + /* FIXME: possible race with ip_set_create() */ + ip_set_unregister_set_type(&ip_set_portmap); +} + -+module_init(init); -+module_exit(fini); -Index: linux-2.6.23-rc6/net/ipv4/netfilter/ipt_set.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.23-rc6/net/ipv4/netfilter/ipt_set.c 2007-09-21 16:24:01.000000000 +0800 -@@ -0,0 +1,150 @@ ++module_init(ip_set_portmap_init); ++module_exit(ip_set_portmap_fini); +diff -Nru ./linux-2.6.21.5/net/ipv4/netfilter/ipt_set.c linux-2.6.21.5.pom2patch.set/net/ipv4/netfilter/ipt_set.c +--- ./linux-2.6.21.5/net/ipv4/netfilter/ipt_set.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.21.5.pom2patch.set/net/ipv4/netfilter/ipt_set.c 2007-10-12 14:28:29.000000000 +0200 +@@ -0,0 +1,160 @@ +/* Copyright (C) 2000-2002 Joakim Axelsson + * Patrick Schaaf + * Martin Josefsson @@ -6052,7 +7226,11 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ipt_set.c + return inv; +} + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) ++static bool ++#else +static int ++#endif +match(const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, @@ -6060,7 +7238,9 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ipt_set.c + const struct xt_match *match, +#endif + const void *matchinfo, -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) ++ int offset, unsigned int protoff, bool *hotdrop) ++#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) + int offset, unsigned int protoff, int *hotdrop) +#else + int offset, int *hotdrop) @@ -6073,7 +7253,11 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ipt_set.c + info->match_set.flags[0] & IPSET_MATCH_INV); +} + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) ++bool ++#else +static int ++#endif +checkentry(const char *tablename, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) + const void *inf, @@ -6171,11 +7355,10 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ipt_set.c + +module_init(ipt_ipset_init); +module_exit(ipt_ipset_fini); -Index: linux-2.6.23-rc6/net/ipv4/netfilter/ipt_SET.c -=================================================================== ---- /dev/null 1970-01-01 00:00:00.000000000 +0000 -+++ linux-2.6.23-rc6/net/ipv4/netfilter/ipt_SET.c 2007-09-21 16:24:01.000000000 +0800 -@@ -0,0 +1,169 @@ +diff -Nru ./linux-2.6.21.5/net/ipv4/netfilter/ipt_SET.c linux-2.6.21.5.pom2patch.set/net/ipv4/netfilter/ipt_SET.c +--- ./linux-2.6.21.5/net/ipv4/netfilter/ipt_SET.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.21.5.pom2patch.set/net/ipv4/netfilter/ipt_SET.c 2007-10-12 14:28:29.000000000 +0200 +@@ -0,0 +1,172 @@ +/* Copyright (C) 2000-2002 Joakim Axelsson + * Patrick Schaaf + * Martin Josefsson @@ -6197,7 +7380,6 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ipt_SET.c +#include +#include +#include -+#include +#include +#include +#include @@ -6233,7 +7415,11 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ipt_SET.c + return IPT_CONTINUE; +} + ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) ++static bool ++#else +static int ++#endif +checkentry(const char *tablename, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) + const void *e, @@ -6345,11 +7531,10 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/ipt_SET.c + +module_init(ipt_SET_init); +module_exit(ipt_SET_fini); -Index: linux-2.6.23-rc6/net/ipv4/netfilter/Kconfig -=================================================================== ---- linux-2.6.23-rc6.orig/net/ipv4/netfilter/Kconfig 2007-09-21 16:24:00.000000000 +0800 -+++ linux-2.6.23-rc6/net/ipv4/netfilter/Kconfig 2007-09-21 16:24:01.000000000 +0800 -@@ -426,5 +426,114 @@ +diff -Nru ./linux-2.6.21.5/net/ipv4/netfilter/Kconfig linux-2.6.21.5.pom2patch.set/net/ipv4/netfilter/Kconfig +--- ./linux-2.6.21.5/net/ipv4/netfilter/Kconfig 2007-06-11 20:37:06.000000000 +0200 ++++ linux-2.6.21.5.pom2patch.set/net/ipv4/netfilter/Kconfig 2007-10-12 14:28:29.000000000 +0200 +@@ -657,5 +657,122 @@ Allows altering the ARP packet payload: source and destination hardware and network addresses. @@ -6442,6 +7627,14 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/Kconfig + + To compile it as a module, choose M here. If unsure, say N. + ++config IP_NF_SET_IPTREEMAP ++ tristate "iptreemap set support" ++ depends on IP_NF_SET ++ help ++ This option adds the iptreemap set type support. ++ ++ To compile it as a module, choose M here. If unsure, say N. ++ +config IP_NF_MATCH_SET + tristate "set match support" + depends on IP_NF_SET @@ -6464,19 +7657,18 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/Kconfig + endmenu -Index: linux-2.6.23-rc6/net/ipv4/netfilter/Makefile -=================================================================== ---- linux-2.6.23-rc6.orig/net/ipv4/netfilter/Makefile 2007-09-21 16:24:00.000000000 +0800 -+++ linux-2.6.23-rc6/net/ipv4/netfilter/Makefile 2007-09-21 16:24:01.000000000 +0800 -@@ -48,6 +48,7 @@ +diff -Nru ./linux-2.6.21.5/net/ipv4/netfilter/Makefile linux-2.6.21.5.pom2patch.set/net/ipv4/netfilter/Makefile +--- ./linux-2.6.21.5/net/ipv4/netfilter/Makefile 2007-06-11 20:37:06.000000000 +0200 ++++ linux-2.6.21.5.pom2patch.set/net/ipv4/netfilter/Makefile 2007-10-12 14:28:29.000000000 +0200 +@@ -90,6 +90,7 @@ obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o +obj-$(CONFIG_IP_NF_MATCH_SET) += ipt_set.o obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o - obj-$(CONFIG_IP_NF_MATCH_IPP2P) += ipt_ipp2p.o - obj-$(CONFIG_IP_NF_MATCH_LAYER7) += ipt_layer7.o -@@ -64,6 +65,17 @@ + + # targets +@@ -105,6 +106,18 @@ obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o obj-$(CONFIG_IP_NF_TARGET_CLUSTERIP) += ipt_CLUSTERIP.o obj-$(CONFIG_IP_NF_TARGET_TTL) += ipt_TTL.o @@ -6491,6 +7683,7 @@ Index: linux-2.6.23-rc6/net/ipv4/netfilter/Makefile +obj-$(CONFIG_IP_NF_SET_NETHASH) += ip_set_nethash.o +obj-$(CONFIG_IP_NF_SET_IPPORTHASH) += ip_set_ipporthash.o +obj-$(CONFIG_IP_NF_SET_IPTREE) += ip_set_iptree.o ++obj-$(CONFIG_IP_NF_SET_IPTREEMAP) += ip_set_iptreemap.o # generic ARP tables obj-$(CONFIG_IP_NF_ARPTABLES) += arp_tables.o