[netfilter-cvslog] r4352 - in trunk/patch-o-matic-ng/patchlets/set:
. linux/Documentation linux/include/linux/netfilter_ipv4
linux/net/ipv4/netfilter linux-2.6/include/linux/netfilter_ipv4
linux-2.6/net/ipv4/netfilter
kadlec at netfilter.org
kadlec at netfilter.org
Thu Oct 13 10:54:01 CEST 2005
Author: kadlec at netfilter.org
Date: 2005-10-13 10:53:58 +0200 (Thu, 13 Oct 2005)
New Revision: 4352
Added:
trunk/patch-o-matic-ng/patchlets/set/linux-2.6/include/linux/netfilter_ipv4/ip_set_ipporthash.h
trunk/patch-o-matic-ng/patchlets/set/linux-2.6/net/ipv4/netfilter/ip_set_ipporthash.c
trunk/patch-o-matic-ng/patchlets/set/linux/include/linux/netfilter_ipv4/ip_set_ipporthash.h
trunk/patch-o-matic-ng/patchlets/set/linux/net/ipv4/netfilter/ip_set_ipporthash.c
Removed:
trunk/patch-o-matic-ng/patchlets/set/linux-2.6/include/linux/netfilter_ipv4/ip_set_prime.h
trunk/patch-o-matic-ng/patchlets/set/linux/include/linux/netfilter_ipv4/ip_set_prime.h
Modified:
trunk/patch-o-matic-ng/patchlets/set/help
trunk/patch-o-matic-ng/patchlets/set/linux-2.6/include/linux/netfilter_ipv4/ip_set.h
trunk/patch-o-matic-ng/patchlets/set/linux-2.6/include/linux/netfilter_ipv4/ip_set_malloc.h
trunk/patch-o-matic-ng/patchlets/set/linux-2.6/net/ipv4/netfilter/Kconfig.ladd
trunk/patch-o-matic-ng/patchlets/set/linux-2.6/net/ipv4/netfilter/Makefile.ladd_2
trunk/patch-o-matic-ng/patchlets/set/linux-2.6/net/ipv4/netfilter/ip_set.c
trunk/patch-o-matic-ng/patchlets/set/linux-2.6/net/ipv4/netfilter/ip_set_iphash.c
trunk/patch-o-matic-ng/patchlets/set/linux-2.6/net/ipv4/netfilter/ip_set_ipmap.c
trunk/patch-o-matic-ng/patchlets/set/linux-2.6/net/ipv4/netfilter/ip_set_iptree.c
trunk/patch-o-matic-ng/patchlets/set/linux-2.6/net/ipv4/netfilter/ip_set_macipmap.c
trunk/patch-o-matic-ng/patchlets/set/linux-2.6/net/ipv4/netfilter/ip_set_nethash.c
trunk/patch-o-matic-ng/patchlets/set/linux-2.6/net/ipv4/netfilter/ip_set_portmap.c
trunk/patch-o-matic-ng/patchlets/set/linux/Documentation/Configure.help.ladd
trunk/patch-o-matic-ng/patchlets/set/linux/include/linux/netfilter_ipv4/ip_set.h
trunk/patch-o-matic-ng/patchlets/set/linux/include/linux/netfilter_ipv4/ip_set_malloc.h
trunk/patch-o-matic-ng/patchlets/set/linux/net/ipv4/netfilter/Config.in.ladd
trunk/patch-o-matic-ng/patchlets/set/linux/net/ipv4/netfilter/Makefile.ladd
trunk/patch-o-matic-ng/patchlets/set/linux/net/ipv4/netfilter/ip_set.c
trunk/patch-o-matic-ng/patchlets/set/linux/net/ipv4/netfilter/ip_set_iphash.c
trunk/patch-o-matic-ng/patchlets/set/linux/net/ipv4/netfilter/ip_set_ipmap.c
trunk/patch-o-matic-ng/patchlets/set/linux/net/ipv4/netfilter/ip_set_iptree.c
trunk/patch-o-matic-ng/patchlets/set/linux/net/ipv4/netfilter/ip_set_macipmap.c
trunk/patch-o-matic-ng/patchlets/set/linux/net/ipv4/netfilter/ip_set_nethash.c
trunk/patch-o-matic-ng/patchlets/set/linux/net/ipv4/netfilter/ip_set_portmap.c
Log:
GC timer fixes in iptree set type and ipporthash type added (JK)
Modified: trunk/patch-o-matic-ng/patchlets/set/help
===================================================================
--- trunk/patch-o-matic-ng/patchlets/set/help 2005-10-12 12:12:20 UTC (rev 4351)
+++ trunk/patch-o-matic-ng/patchlets/set/help 2005-10-13 08:53:58 UTC (rev 4352)
@@ -3,7 +3,9 @@
address/network address/port has its bit set in/added to the given set.
It also provides a SET target, which can be used to add or remove the
addresses/ports of a packet to/from a set. The currently supported types
-of the sets are: ipmap, macipmap, portmap, iphash, nethash and iptree.
+of the sets are: ipmap, macipmap, portmap, iphash, nethash, ipporthash
+and iptree.
+
It is possible to chain sets together by binding.
The userspace program ipset(8) is required to define and setup IP sets.
Modified: trunk/patch-o-matic-ng/patchlets/set/linux/Documentation/Configure.help.ladd
===================================================================
--- trunk/patch-o-matic-ng/patchlets/set/linux/Documentation/Configure.help.ladd 2005-10-12 12:12:20 UTC (rev 4351)
+++ trunk/patch-o-matic-ng/patchlets/set/linux/Documentation/Configure.help.ladd 2005-10-13 08:53:58 UTC (rev 4352)
@@ -61,6 +61,13 @@
If you want to compile it as a module, say M here and read
<file:Documentation/modules.txt>. If unsure, say `N'.
+ipporthash set type support
+CONFIG_IP_NF_SET_IPPORTHASH
+ This option adds the ipporthash set type support.
+
+ If you want to compile it as a module, say M here and read
+ <file:Documentation/modules.txt>. If unsure, say `N'.
+
iptree set type support
CONFIG_IP_NF_SET_IPTREE
This option adds the iptree set type support.
Modified: trunk/patch-o-matic-ng/patchlets/set/linux/include/linux/netfilter_ipv4/ip_set.h
===================================================================
--- trunk/patch-o-matic-ng/patchlets/set/linux/include/linux/netfilter_ipv4/ip_set.h 2005-10-12 12:12:20 UTC (rev 4351)
+++ trunk/patch-o-matic-ng/patchlets/set/linux/include/linux/netfilter_ipv4/ip_set.h 2005-10-13 08:53:58 UTC (rev 4352)
@@ -81,10 +81,12 @@
#define IPSET_MATCH_INV 0x04 /* Inverse matching */
/*
- * Set types (flavours)
+ * Set features
*/
-#define IPSET_TYPE_IP 0 /* IP address type of set */
-#define IPSET_TYPE_PORT 1 /* Port type of set */
+#define IPSET_TYPE_IP 0x01 /* IP address type of set */
+#define IPSET_TYPE_PORT 0x02 /* Port type of set */
+#define IPSET_DATA_SINGLE 0x04 /* Single data storage */
+#define IPSET_DATA_DOUBLE 0x08 /* Double data storage */
/* Reserved keywords */
#define IPSET_TOKEN_DEFAULT ":default:"
@@ -339,9 +341,10 @@
* return 0 if not in set, 1 if in set.
*/
int (*testip_kernel) (struct ip_set *set,
- const struct sk_buff * skb,
- u_int32_t flags,
- ip_set_ip_t *ip);
+ const struct sk_buff * skb,
+ ip_set_ip_t *ip,
+ const u_int32_t *flags,
+ unsigned char index);
/* test for IP in set (userspace: ipset -T set IP)
* return 0 if not in set, 1 if in set.
@@ -371,9 +374,10 @@
* If the address was not already in the set, 0 is returned.
*/
int (*addip_kernel) (struct ip_set *set,
- const struct sk_buff * skb,
- u_int32_t flags,
- ip_set_ip_t *ip);
+ const struct sk_buff * skb,
+ ip_set_ip_t *ip,
+ const u_int32_t *flags,
+ unsigned char index);
/* remove IP from set (userspace: ipset -D set --entry x)
* Return -EEXIST if the address is NOT in the set,
@@ -391,8 +395,9 @@
*/
int (*delip_kernel) (struct ip_set *set,
const struct sk_buff * skb,
- u_int32_t flags,
- ip_set_ip_t *ip);
+ ip_set_ip_t *ip,
+ const u_int32_t *flags,
+ unsigned char index);
/* new set creation - allocated type specific items
*/
@@ -443,7 +448,7 @@
void *data);
char typename[IP_SET_MAXNAMELEN];
- char typecode;
+ unsigned char features;
int protocol_version;
/* Set this to THIS_MODULE if you are a module, otherwise NULL */
Added: trunk/patch-o-matic-ng/patchlets/set/linux/include/linux/netfilter_ipv4/ip_set_ipporthash.h
===================================================================
--- trunk/patch-o-matic-ng/patchlets/set/linux/include/linux/netfilter_ipv4/ip_set_ipporthash.h 2005-10-12 12:12:20 UTC (rev 4351)
+++ trunk/patch-o-matic-ng/patchlets/set/linux/include/linux/netfilter_ipv4/ip_set_ipporthash.h 2005-10-13 08:53:58 UTC (rev 4352)
@@ -0,0 +1,33 @@
+#ifndef __IP_SET_IPPORTHASH_H
+#define __IP_SET_IPPORTHASH_H
+
+#include <linux/netfilter_ipv4/ip_set.h>
+
+#define SETTYPE_NAME "ipporthash"
+#define MAX_RANGE 0x0000FFFF
+#define INVALID_PORT (MAX_RANGE + 1)
+
+struct ip_set_ipporthash {
+ ip_set_ip_t *members; /* the ipporthash proper */
+ uint32_t hashsize; /* hash size */
+ uint16_t probes; /* max number of probes */
+ uint16_t resize; /* resize factor in percent */
+ ip_set_ip_t first_ip; /* host byte order, included in range */
+ ip_set_ip_t last_ip; /* host byte order, included in range */
+ void *initval[0]; /* initvals for jhash_1word */
+};
+
+struct ip_set_req_ipporthash_create {
+ uint32_t hashsize;
+ uint16_t probes;
+ uint16_t resize;
+ ip_set_ip_t from;
+ ip_set_ip_t to;
+};
+
+struct ip_set_req_ipporthash {
+ ip_set_ip_t ip;
+ ip_set_ip_t port;
+};
+
+#endif /* __IP_SET_IPPORTHASH_H */
Modified: trunk/patch-o-matic-ng/patchlets/set/linux/include/linux/netfilter_ipv4/ip_set_malloc.h
===================================================================
--- trunk/patch-o-matic-ng/patchlets/set/linux/include/linux/netfilter_ipv4/ip_set_malloc.h 2005-10-12 12:12:20 UTC (rev 4351)
+++ trunk/patch-o-matic-ng/patchlets/set/linux/include/linux/netfilter_ipv4/ip_set_malloc.h 2005-10-13 08:53:58 UTC (rev 4352)
@@ -23,7 +23,7 @@
}
struct harray {
- size_t max_arrays;
+ size_t max_elements;
void *arrays[0];
};
@@ -31,14 +31,14 @@
harray_malloc(size_t hashsize, size_t typesize, int flags)
{
struct harray *harray;
- size_t max_arrays, size, i, j;
+ size_t max_elements, size, i, j;
if (typesize > max_malloc_size)
return NULL;
- max_arrays = max_malloc_size/typesize;
- size = hashsize/max_arrays;
- if (hashsize % max_arrays)
+ max_elements = max_malloc_size/typesize;
+ size = hashsize/max_elements;
+ if (hashsize % max_elements)
size++;
/* Last pointer signals end of arrays */
@@ -49,18 +49,18 @@
return NULL;
for (i = 0; i < size - 1; i++) {
- harray->arrays[i] = kmalloc(max_arrays * typesize, flags);
+ harray->arrays[i] = kmalloc(max_elements * typesize, flags);
if (!harray->arrays[i])
goto undo;
- memset(harray->arrays[i], 0, max_arrays * typesize);
+ memset(harray->arrays[i], 0, max_elements * typesize);
}
- harray->arrays[i] = kmalloc((hashsize - i * max_arrays) * typesize,
+ harray->arrays[i] = kmalloc((hashsize - i * max_elements) * typesize,
flags);
if (!harray->arrays[i])
goto undo;
- memset(harray->arrays[i], 0, (hashsize - i * max_arrays) * typesize);
+ memset(harray->arrays[i], 0, (hashsize - i * max_elements) * typesize);
- harray->max_arrays = max_arrays;
+ harray->max_elements = max_elements;
harray->arrays[size] = NULL;
return (void *)harray;
@@ -89,16 +89,16 @@
size_t i;
for (i = 0; harray->arrays[i+1] != NULL; i++)
- memset(harray->arrays[i], 0, harray->max_arrays * typesize);
+ memset(harray->arrays[i], 0, harray->max_elements * typesize);
memset(harray->arrays[i], 0,
- (hashsize - i * harray->max_arrays) * typesize);
+ (hashsize - i * harray->max_elements) * typesize);
}
#define HARRAY_ELEM(h, type, which) \
({ \
struct harray *__h = (struct harray *)(h); \
- ((type)((__h)->arrays[(which)/(__h)->max_arrays]) \
- + (which)%(__h)->max_arrays); \
+ ((type)((__h)->arrays[(which)/(__h)->max_elements]) \
+ + (which)%(__h)->max_elements); \
})
#endif /* __KERNEL__ */
Deleted: trunk/patch-o-matic-ng/patchlets/set/linux/include/linux/netfilter_ipv4/ip_set_prime.h
===================================================================
--- trunk/patch-o-matic-ng/patchlets/set/linux/include/linux/netfilter_ipv4/ip_set_prime.h 2005-10-12 12:12:20 UTC (rev 4351)
+++ trunk/patch-o-matic-ng/patchlets/set/linux/include/linux/netfilter_ipv4/ip_set_prime.h 2005-10-13 08:53:58 UTC (rev 4352)
@@ -1,34 +0,0 @@
-#ifndef __IP_SET_PRIME_H
-#define __IP_SET_PRIME_H
-
-static inline unsigned make_prime_bound(unsigned nr)
-{
- unsigned long long nr64 = nr;
- unsigned long long x = 1;
- nr = 1;
- while (x <= nr64) { x <<= 2; nr <<= 1; }
- return nr;
-}
-
-static inline int make_prime_check(unsigned nr)
-{
- unsigned x = 3;
- unsigned b = make_prime_bound(nr);
- while (x <= b) {
- if (0 == (nr % x)) return 0;
- x += 2;
- }
- return 1;
-}
-
-static unsigned make_prime(unsigned nr)
-{
- if (0 == (nr & 1)) nr--;
- while (nr > 1) {
- if (make_prime_check(nr)) return nr;
- nr -= 2;
- }
- return 2;
-}
-
-#endif /* __IP_SET_PRIME_H */
Modified: trunk/patch-o-matic-ng/patchlets/set/linux/net/ipv4/netfilter/Config.in.ladd
===================================================================
--- trunk/patch-o-matic-ng/patchlets/set/linux/net/ipv4/netfilter/Config.in.ladd 2005-10-12 12:12:20 UTC (rev 4351)
+++ trunk/patch-o-matic-ng/patchlets/set/linux/net/ipv4/netfilter/Config.in.ladd 2005-10-13 08:53:58 UTC (rev 4352)
@@ -11,5 +11,6 @@
dep_tristate ' macipmap set type support' CONFIG_IP_NF_SET_MACIPMAP $CONFIG_IP_NF_SET
dep_tristate ' iphash set type support' CONFIG_IP_NF_SET_IPHASH $CONFIG_IP_NF_SET
dep_tristate ' nethash set type support' CONFIG_IP_NF_SET_NETHASH $CONFIG_IP_NF_SET
+ dep_tristate ' ipporthash set type support' CONFIG_IP_NF_SET_IPPORTHASH $CONFIG_IP_NF_SET
dep_tristate ' iptree set type support' CONFIG_IP_NF_SET_IPTREE $CONFIG_IP_NF_SET
fi
Modified: trunk/patch-o-matic-ng/patchlets/set/linux/net/ipv4/netfilter/Makefile.ladd
===================================================================
--- trunk/patch-o-matic-ng/patchlets/set/linux/net/ipv4/netfilter/Makefile.ladd 2005-10-12 12:12:20 UTC (rev 4351)
+++ trunk/patch-o-matic-ng/patchlets/set/linux/net/ipv4/netfilter/Makefile.ladd 2005-10-13 08:53:58 UTC (rev 4352)
@@ -10,4 +10,5 @@
obj-$(CONFIG_IP_NF_SET_MACIPMAP) += ip_set_macipmap.o
obj-$(CONFIG_IP_NF_SET_IPHASH) += ip_set_iphash.o
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
Modified: trunk/patch-o-matic-ng/patchlets/set/linux/net/ipv4/netfilter/ip_set.c
===================================================================
--- trunk/patch-o-matic-ng/patchlets/set/linux/net/ipv4/netfilter/ip_set.c 2005-10-12 12:12:20 UTC (rev 4351)
+++ trunk/patch-o-matic-ng/patchlets/set/linux/net/ipv4/netfilter/ip_set.c 2005-10-13 08:53:58 UTC (rev 4352)
@@ -96,7 +96,7 @@
% ip_set_bindings_hash_size;
struct ip_set_hash *set_hash;
- MUST_BE_READ_LOCKED(&ip_set_lock);
+ ASSERT_READ_LOCK(&ip_set_lock);
IP_SET_ASSERT(ip_set_list[id]);
DP("set: %s, ip: %u.%u.%u.%u", ip_set_list[id]->name, HIPQUAD(ip));
@@ -113,7 +113,7 @@
static inline void
__set_hash_del(struct ip_set_hash *set_hash)
{
- MUST_BE_WRITE_LOCKED(&ip_set_lock);
+ ASSERT_WRITE_LOCK(&ip_set_lock);
IP_SET_ASSERT(ip_set_list[set_hash->binding]);
__ip_set_put(set_hash->binding);
@@ -130,7 +130,7 @@
IP_SET_ASSERT(ip_set_list[id]);
DP("set: %s, ip: %u.%u.%u.%u", ip_set_list[id]->name, HIPQUAD(ip));
- WRITE_LOCK(&ip_set_lock);
+ write_lock_bh(&ip_set_lock);
set_hash = LIST_FIND(&ip_set_hash[key], ip_hash_cmp,
struct ip_set_hash *, id, ip);
DP("set: %s, ip: %u.%u.%u.%u, binding: %s", ip_set_list[id]->name,
@@ -139,7 +139,7 @@
if (set_hash != NULL)
__set_hash_del(set_hash);
- WRITE_UNLOCK(&ip_set_lock);
+ write_unlock_bh(&ip_set_lock);
return 0;
}
@@ -155,7 +155,7 @@
IP_SET_ASSERT(ip_set_list[binding]);
DP("set: %s, ip: %u.%u.%u.%u, binding: %s", ip_set_list[id]->name,
HIPQUAD(ip), ip_set_list[binding]->name);
- WRITE_LOCK(&ip_set_lock);
+ write_lock_bh(&ip_set_lock);
set_hash = LIST_FIND(&ip_set_hash[key], ip_hash_cmp,
struct ip_set_hash *, id, ip);
if (!set_hash) {
@@ -177,7 +177,7 @@
set_hash->binding = binding;
__ip_set_get(set_hash->binding);
unlock:
- WRITE_UNLOCK(&ip_set_lock);
+ write_unlock_bh(&ip_set_lock);
return ret;
}
@@ -197,7 +197,7 @@
ip_set_id_t __key; \
struct ip_set_hash *__set_hash, *__n; \
\
- MUST_BE_WRITE_LOCKED(&ip_set_lock); \
+ ASSERT_WRITE_LOCK(&ip_set_lock); \
for (__key = 0; __key < ip_set_bindings_hash_size; __key++) { \
list_for_each_entry_safe(__set_hash, __n, &ip_set_hash[__key], list)\
fn(__set_hash , ## args); \
@@ -217,21 +217,23 @@
{
struct ip_set *set;
ip_set_ip_t ip;
- int res, i = 0;
+ int res;
+ unsigned char i = 0;
IP_SET_ASSERT(flags[i]);
- READ_LOCK(&ip_set_lock);
+ read_lock_bh(&ip_set_lock);
do {
set = ip_set_list[index];
IP_SET_ASSERT(set);
DP("set %s, index %u", set->name, index);
read_lock_bh(&set->lock);
- res = set->type->testip_kernel(set, skb, flags[i], &ip);
+ res = set->type->testip_kernel(set, skb, &ip, flags, i++);
read_unlock_bh(&set->lock);
+ i += !!(set->type->features & IPSET_DATA_DOUBLE);
} while (res > 0
- && flags[++i]
+ && flags[i]
&& follow_bindings(index, set, ip));
- READ_UNLOCK(&ip_set_lock);
+ read_unlock_bh(&ip_set_lock);
return res;
}
@@ -243,22 +245,24 @@
{
struct ip_set *set;
ip_set_ip_t ip;
- int res, i= 0;
+ int res;
+ unsigned char i = 0;
IP_SET_ASSERT(flags[i]);
retry:
- READ_LOCK(&ip_set_lock);
+ read_lock_bh(&ip_set_lock);
do {
set = ip_set_list[index];
IP_SET_ASSERT(set);
DP("set %s, index %u", set->name, index);
write_lock_bh(&set->lock);
- res = set->type->addip_kernel(set, skb, flags[i], &ip);
+ res = set->type->addip_kernel(set, skb, &ip, flags, i++);
write_unlock_bh(&set->lock);
+ i += !!(set->type->features & IPSET_DATA_DOUBLE);
} while ((res == 0 || res == -EEXIST)
- && flags[++i]
+ && flags[i]
&& follow_bindings(index, set, ip));
- READ_UNLOCK(&ip_set_lock);
+ read_unlock_bh(&ip_set_lock);
if (res == -EAGAIN
&& set->type->retry
@@ -273,21 +277,23 @@
{
struct ip_set *set;
ip_set_ip_t ip;
- int res, i = 0;
+ int res;
+ unsigned char i = 0;
IP_SET_ASSERT(flags[i]);
- READ_LOCK(&ip_set_lock);
+ read_lock_bh(&ip_set_lock);
do {
set = ip_set_list[index];
IP_SET_ASSERT(set);
DP("set %s, index %u", set->name, index);
write_lock_bh(&set->lock);
- res = set->type->delip_kernel(set, skb, flags[i], &ip);
+ res = set->type->delip_kernel(set, skb, &ip, flags, i++);
write_unlock_bh(&set->lock);
+ i += !!(set->type->features & IPSET_DATA_DOUBLE);
} while ((res == 0 || res == -EEXIST)
- && flags[++i]
+ && flags[i]
&& follow_bindings(index, set, ip));
- READ_UNLOCK(&ip_set_lock);
+ read_unlock_bh(&ip_set_lock);
}
/* Register and deregister settype */
@@ -320,7 +326,7 @@
return -EINVAL;
}
- WRITE_LOCK(&ip_set_lock);
+ write_lock_bh(&ip_set_lock);
if (find_set_type(set_type->typename)) {
/* Duplicate! */
ip_set_printk("'%s' already registered!",
@@ -332,14 +338,14 @@
list_append(&set_type_list, set_type);
DP("'%s' registered.", set_type->typename);
unlock:
- WRITE_UNLOCK(&ip_set_lock);
+ write_unlock_bh(&ip_set_lock);
return ret;
}
void
ip_set_unregister_set_type(struct ip_set_type *set_type)
{
- WRITE_LOCK(&ip_set_lock);
+ write_lock_bh(&ip_set_lock);
if (!find_set_type(set_type->typename)) {
ip_set_printk("'%s' not registered?",
set_type->typename);
@@ -349,7 +355,7 @@
__MOD_DEC_SELF;
DP("'%s' unregistered.", set_type->typename);
unlock:
- WRITE_UNLOCK(&ip_set_lock);
+ write_unlock_bh(&ip_set_lock);
}
@@ -561,13 +567,13 @@
if (binding == IP_SET_INVALID_ID)
return -ENOENT;
- WRITE_LOCK(&ip_set_lock);
+ write_lock_bh(&ip_set_lock);
/* Sets as binding values are referenced */
if (set->binding != IP_SET_INVALID_ID)
__ip_set_put(set->binding);
set->binding = binding;
__ip_set_get(set->binding);
- WRITE_UNLOCK(&ip_set_lock);
+ write_unlock_bh(&ip_set_lock);
return 0;
}
@@ -639,15 +645,15 @@
/* unbind :all: */
if (strcmp(req_bind->binding, IPSET_TOKEN_DEFAULT) == 0) {
/* Default binding of sets */
- WRITE_LOCK(&ip_set_lock);
+ write_lock_bh(&ip_set_lock);
FOREACH_SET_DO(__unbind_default);
- WRITE_UNLOCK(&ip_set_lock);
+ write_unlock_bh(&ip_set_lock);
return 0;
} else if (strcmp(req_bind->binding, IPSET_TOKEN_ALL) == 0) {
/* Flush all bindings of all sets*/
- WRITE_LOCK(&ip_set_lock);
+ write_lock_bh(&ip_set_lock);
FOREACH_HASH_RW_DO(__set_hash_del);
- WRITE_UNLOCK(&ip_set_lock);
+ write_unlock_bh(&ip_set_lock);
return 0;
}
DP("unreachable reached!");
@@ -663,19 +669,19 @@
if (binding == IP_SET_INVALID_ID)
return -ENOENT;
- WRITE_LOCK(&ip_set_lock);
+ write_lock_bh(&ip_set_lock);
/* Sets in hash values are referenced */
__ip_set_put(set->binding);
set->binding = IP_SET_INVALID_ID;
- WRITE_UNLOCK(&ip_set_lock);
+ write_unlock_bh(&ip_set_lock);
return 0;
} else if (strcmp(req_bind->binding, IPSET_TOKEN_ALL) == 0) {
/* Flush all bindings */
- WRITE_LOCK(&ip_set_lock);
+ write_lock_bh(&ip_set_lock);
FOREACH_HASH_RW_DO(__set_hash_del_byid, set->id);
- WRITE_UNLOCK(&ip_set_lock);
+ write_unlock_bh(&ip_set_lock);
return 0;
}
@@ -751,10 +757,10 @@
{
struct ip_set_type *type;
- READ_LOCK(&ip_set_lock);
+ read_lock_bh(&ip_set_lock);
type = find_set_type(typename);
if (type == NULL)
- READ_UNLOCK(&ip_set_lock);
+ read_unlock_bh(&ip_set_lock);
return type;
}
@@ -842,7 +848,7 @@
return -ENOENT;
}
__MOD_INC(set->type->me);
- READ_UNLOCK(&ip_set_lock);
+ read_unlock_bh(&ip_set_lock);
/*
* Without holding any locks, create private part.
@@ -861,7 +867,7 @@
* find free id/index and check that it is not already in
* ip_set_list.
*/
- WRITE_LOCK(&ip_set_lock);
+ write_lock_bh(&ip_set_lock);
if ((res = find_free_id(set->name, &index, &id)) != 0) {
DP("no free id!");
goto cleanup;
@@ -880,11 +886,11 @@
DP("create: '%s' created with index %u, id %u!", set->name, index, id);
set->id = id;
ip_set_list[index] = set;
- WRITE_UNLOCK(&ip_set_lock);
+ write_unlock_bh(&ip_set_lock);
return res;
cleanup:
- WRITE_UNLOCK(&ip_set_lock);
+ write_unlock_bh(&ip_set_lock);
set->type->destroy(set);
__MOD_DEC(set->type->me);
kfree(set);
@@ -901,12 +907,12 @@
IP_SET_ASSERT(set);
DP("set: %s", set->name);
- WRITE_LOCK(&ip_set_lock);
+ write_lock_bh(&ip_set_lock);
FOREACH_HASH_RW_DO(__set_hash_del_byid, set->id);
if (set->binding != IP_SET_INVALID_ID)
__ip_set_put(set->binding);
ip_set_list[index] = NULL;
- WRITE_UNLOCK(&ip_set_lock);
+ write_unlock_bh(&ip_set_lock);
/* Must call it without holding any lock */
set->type->destroy(set);
@@ -977,7 +983,7 @@
int res = 0;
DP("set: %s to %s", set->name, name);
- WRITE_LOCK(&ip_set_lock);
+ write_lock_bh(&ip_set_lock);
for (i = 0; i < ip_set_max; i++) {
if (ip_set_list[i] != NULL
&& strncmp(ip_set_list[i]->name,
@@ -989,7 +995,7 @@
}
strncpy(set->name, name, IP_SET_MAXNAMELEN);
unlock:
- WRITE_UNLOCK(&ip_set_lock);
+ write_unlock_bh(&ip_set_lock);
return res;
}
@@ -1006,12 +1012,12 @@
u_int32_t from_ref;
DP("set: %s to %s", from->name, to->name);
- /* Type can't be changed. Artifical restriction. */
- if (from->type->typecode != to->type->typecode)
+ /* Features must not change. Artifical restriction. */
+ if (from->type->features != to->type->features)
return -ENOEXEC;
/* No magic here: ref munging protected by the mutex */
- WRITE_LOCK(&ip_set_lock);
+ write_lock_bh(&ip_set_lock);
strncpy(from_name, from->name, IP_SET_MAXNAMELEN);
from_ref = atomic_read(&from->ref);
@@ -1023,7 +1029,7 @@
ip_set_list[from_index] = to;
ip_set_list[to_index] = from;
- WRITE_UNLOCK(&ip_set_lock);
+ write_unlock_bh(&ip_set_lock);
return 0;
}
@@ -1345,10 +1351,10 @@
hash_save->binding);
else {
IP_SET_ASSERT(set->binding == IP_SET_INVALID_ID);
- WRITE_LOCK(&ip_set_lock);
+ write_lock_bh(&ip_set_lock);
set->binding = hash_save->binding;
__ip_set_get(set->binding);
- WRITE_UNLOCK(&ip_set_lock);
+ write_unlock_bh(&ip_set_lock);
DP("default binding: %u", set->binding);
}
if (res != 0)
@@ -1980,7 +1986,7 @@
static void __exit fini(void)
{
- /* There can't be any existing set or binding. Racy. */
+ /* There can't be any existing set or binding */
nf_unregister_sockopt(&so_set);
vfree(ip_set_list);
vfree(ip_set_hash);
Modified: trunk/patch-o-matic-ng/patchlets/set/linux/net/ipv4/netfilter/ip_set_iphash.c
===================================================================
--- trunk/patch-o-matic-ng/patchlets/set/linux/net/ipv4/netfilter/ip_set_iphash.c 2005-10-12 12:12:20 UTC (rev 4351)
+++ trunk/patch-o-matic-ng/patchlets/set/linux/net/ipv4/netfilter/ip_set_iphash.c 2005-10-13 08:53:58 UTC (rev 4352)
@@ -79,12 +79,16 @@
}
static int
-testip_kernel(struct ip_set *set, const struct sk_buff *skb,
- u_int32_t flags, ip_set_ip_t *hash_ip)
+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)
{
return __testip(set,
- ntohl(flags & IPSET_SRC ? skb->nh.iph->saddr
- : skb->nh.iph->daddr),
+ ntohl(flags[index] & IPSET_SRC
+ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
hash_ip);
}
@@ -128,12 +132,16 @@
}
static int
-addip_kernel(struct ip_set *set, const struct sk_buff *skb,
- u_int32_t flags, ip_set_ip_t *hash_ip)
+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((struct ip_set_iphash *) set->data,
- ntohl(flags & IPSET_SRC ? skb->nh.iph->saddr
- : skb->nh.iph->daddr),
+ ntohl(flags[index] & IPSET_SRC
+ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
hash_ip);
}
@@ -175,10 +183,10 @@
kfree(tmp);
return -ENOMEM;
}
- tmp->hashsize = hashsize,
- tmp->probes = map->probes,
- tmp->resize = map->resize,
- tmp->netmask = map->netmask,
+ tmp->hashsize = hashsize;
+ tmp->probes = map->probes;
+ tmp->resize = map->resize;
+ tmp->netmask = map->netmask;
memcpy(tmp->initval, map->initval, map->probes * sizeof(uint32_t));
write_lock_bh(&set->lock);
@@ -242,12 +250,16 @@
}
static int
-delip_kernel(struct ip_set *set, const struct sk_buff *skb,
- u_int32_t flags, ip_set_ip_t *hash_ip)
+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(set,
- ntohl(flags & IPSET_SRC ? skb->nh.iph->saddr
- : skb->nh.iph->daddr),
+ ntohl(flags[index] & IPSET_SRC
+ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
hash_ip);
}
@@ -348,7 +360,7 @@
static struct ip_set_type ip_set_iphash = {
.typename = SETTYPE_NAME,
- .typecode = IPSET_TYPE_IP,
+ .features = IPSET_TYPE_IP | IPSET_DATA_SINGLE,
.protocol_version = IP_SET_PROTOCOL_VERSION,
.create = &create,
.destroy = &destroy,
Modified: trunk/patch-o-matic-ng/patchlets/set/linux/net/ipv4/netfilter/ip_set_ipmap.c
===================================================================
--- trunk/patch-o-matic-ng/patchlets/set/linux/net/ipv4/netfilter/ip_set_ipmap.c 2005-10-12 12:12:20 UTC (rev 4351)
+++ trunk/patch-o-matic-ng/patchlets/set/linux/net/ipv4/netfilter/ip_set_ipmap.c 2005-10-13 08:53:58 UTC (rev 4352)
@@ -61,19 +61,21 @@
static int
testip_kernel(struct ip_set *set,
const struct sk_buff *skb,
- u_int32_t flags,
- ip_set_ip_t *hash_ip)
+ ip_set_ip_t *hash_ip,
+ const u_int32_t *flags,
+ unsigned char index)
{
int res;
DP("flag: %s src: %u.%u.%u.%u dst: %u.%u.%u.%u",
- flags & IPSET_SRC ? "SRC" : "DST",
+ flags[index] & IPSET_SRC ? "SRC" : "DST",
NIPQUAD(skb->nh.iph->saddr),
NIPQUAD(skb->nh.iph->daddr));
res = __testip(set,
- ntohl(flags & IPSET_SRC ? skb->nh.iph->saddr
- : skb->nh.iph->daddr),
+ ntohl(flags[index] & IPSET_SRC
+ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
hash_ip);
return (res < 0 ? 0 : res);
}
@@ -112,12 +114,16 @@
}
static int
-addip_kernel(struct ip_set *set, const struct sk_buff *skb,
- u_int32_t flags, ip_set_ip_t *hash_ip)
+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(set,
- ntohl(flags & IPSET_SRC ? skb->nh.iph->saddr
- : skb->nh.iph->daddr),
+ ntohl(flags[index] & IPSET_SRC
+ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
hash_ip);
}
@@ -154,12 +160,16 @@
}
static int
-delip_kernel(struct ip_set *set, const struct sk_buff *skb,
- u_int32_t flags, ip_set_ip_t *hash_ip)
+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(set,
- ntohl(flags & IPSET_SRC ? skb->nh.iph->saddr
- : skb->nh.iph->daddr),
+ ntohl(flags[index] & IPSET_SRC
+ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
hash_ip);
}
@@ -280,7 +290,7 @@
static struct ip_set_type ip_set_ipmap = {
.typename = SETTYPE_NAME,
- .typecode = IPSET_TYPE_IP,
+ .features = IPSET_TYPE_IP | IPSET_DATA_SINGLE,
.protocol_version = IP_SET_PROTOCOL_VERSION,
.create = &create,
.destroy = &destroy,
Added: trunk/patch-o-matic-ng/patchlets/set/linux/net/ipv4/netfilter/ip_set_ipporthash.c
===================================================================
--- trunk/patch-o-matic-ng/patchlets/set/linux/net/ipv4/netfilter/ip_set_ipporthash.c 2005-10-12 12:12:20 UTC (rev 4351)
+++ trunk/patch-o-matic-ng/patchlets/set/linux/net/ipv4/netfilter/ip_set_ipporthash.c 2005-10-13 08:53:58 UTC (rev 4352)
@@ -0,0 +1,525 @@
+/* Copyright (C) 2003-2004 Jozsef Kadlecsik <kadlec at blackhole.kfki.hu>
+ *
+ * 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.
+ */
+
+/* Kernel module implementing an ip+port hash set */
+
+#include <linux/module.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <linux/udp.h>
+#include <linux/skbuff.h>
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv4/ip_set.h>
+#include <linux/errno.h>
+#include <asm/uaccess.h>
+#include <asm/bitops.h>
+#include <asm/softirq.h>
+#include <linux/spinlock.h>
+#include <linux/vmalloc.h>
+#include <linux/random.h>
+
+#include <net/ip.h>
+
+#include <linux/netfilter_ipv4/ip_set_malloc.h>
+#include <linux/netfilter_ipv4/ip_set_ipporthash.h>
+#include <linux/netfilter_ipv4/ip_set_jhash.h>
+
+/* We must handle non-linear skbs */
+static inline ip_set_ip_t
+get_port(const struct sk_buff *skb, u_int32_t flags)
+{
+ struct iphdr *iph = skb->nh.iph;
+ u_int16_t offset = ntohs(iph->frag_off) & IP_OFFSET;
+
+ switch (iph->protocol) {
+ case IPPROTO_TCP: {
+ struct tcphdr tcph;
+
+ /* See comments at tcp_match in ip_tables.c */
+ if (offset)
+ return INVALID_PORT;
+
+ if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &tcph, sizeof(tcph)) < 0)
+ /* No choice either */
+ return INVALID_PORT;
+
+ return ntohs(flags & IPSET_SRC ?
+ tcph.source : tcph.dest);
+ }
+ case IPPROTO_UDP: {
+ struct udphdr udph;
+
+ if (offset)
+ return INVALID_PORT;
+
+ if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &udph, sizeof(udph)) < 0)
+ /* No choice either */
+ return INVALID_PORT;
+
+ return ntohs(flags & IPSET_SRC ?
+ udph.source : udph.dest);
+ }
+ default:
+ return INVALID_PORT;
+ }
+}
+
+static inline __u32
+jhash_ip(const struct ip_set_ipporthash *map, uint16_t i, ip_set_ip_t ip)
+{
+ return jhash_1word(ip, *(((uint32_t *) map->initval) + i));
+}
+
+#define HASH_IP(map, ip, port) (port + ((ip - ((map)->first_ip)) << 16))
+
+static inline __u32
+hash_id(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t port,
+ ip_set_ip_t *hash_ip)
+{
+ struct ip_set_ipporthash *map =
+ (struct ip_set_ipporthash *) set->data;
+ __u32 id;
+ u_int16_t i;
+ ip_set_ip_t *elem;
+
+ *hash_ip = HASH_IP(map, ip, port);
+ DP("set: %s, ipport:%u.%u.%u.%u:%u, %u.%u.%u.%u",
+ set->name, HIPQUAD(ip), port, HIPQUAD(*hash_ip));
+
+ for (i = 0; i < map->probes; i++) {
+ id = jhash_ip(map, i, *hash_ip) % map->hashsize;
+ DP("hash key: %u", id);
+ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, id);
+ if (*elem == *hash_ip)
+ return id;
+ /* No shortcut at testing - there can be deleted
+ * entries. */
+ }
+ return UINT_MAX;
+}
+
+static inline int
+__testip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t port,
+ ip_set_ip_t *hash_ip)
+{
+ struct ip_set_ipporthash *map = (struct ip_set_ipporthash *) set->data;
+
+ if (ip < map->first_ip || ip > map->last_ip)
+ return -ERANGE;
+
+ return (hash_id(set, ip, port, hash_ip) != UINT_MAX);
+}
+
+static int
+testip(struct ip_set *set, const void *data, size_t size,
+ ip_set_ip_t *hash_ip)
+{
+ struct ip_set_req_ipporthash *req =
+ (struct ip_set_req_ipporthash *) data;
+
+ if (size != sizeof(struct ip_set_req_ipporthash)) {
+ ip_set_printk("data length wrong (want %zu, have %zu)",
+ sizeof(struct ip_set_req_ipporthash),
+ size);
+ return -EINVAL;
+ }
+ return __testip(set, req->ip, req->port, 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)
+{
+ ip_set_ip_t port;
+
+ if (flags[index+1] == 0)
+ return -EINVAL;
+
+ 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",
+ NIPQUAD(skb->nh.iph->saddr),
+ NIPQUAD(skb->nh.iph->daddr));
+ DP("flag %s port %u",
+ flags[index+1] & IPSET_SRC ? "SRC" : "DST",
+ port);
+ if (port == INVALID_PORT)
+ return 0;
+
+ return __testip(set,
+ ntohl(flags[index] & IPSET_SRC
+ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
+ port,
+ hash_ip);
+}
+
+static inline int
+__add_haship(struct ip_set_ipporthash *map, ip_set_ip_t hash_ip)
+{
+ __u32 probe;
+ u_int16_t i;
+ ip_set_ip_t *elem;
+
+ for (i = 0; i < map->probes; i++) {
+ probe = jhash_ip(map, i, hash_ip) % map->hashsize;
+ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, probe);
+ if (*elem == hash_ip)
+ return -EEXIST;
+ if (!*elem) {
+ *elem = hash_ip;
+ return 0;
+ }
+ }
+ /* Trigger rehashing */
+ return -EAGAIN;
+}
+
+static inline int
+__addip(struct ip_set_ipporthash *map, ip_set_ip_t ip, ip_set_ip_t port,
+ ip_set_ip_t *hash_ip)
+{
+ if (ip < map->first_ip || ip > map->last_ip)
+ return -ERANGE;
+
+ *hash_ip = HASH_IP(map, ip, port);
+
+ return __add_haship(map, *hash_ip);
+}
+
+static int
+addip(struct ip_set *set, const void *data, size_t size,
+ ip_set_ip_t *hash_ip)
+{
+ struct ip_set_req_ipporthash *req =
+ (struct ip_set_req_ipporthash *) data;
+
+ if (size != sizeof(struct ip_set_req_ipporthash)) {
+ ip_set_printk("data length wrong (want %zu, have %zu)",
+ sizeof(struct ip_set_req_ipporthash),
+ size);
+ return -EINVAL;
+ }
+ return __addip((struct ip_set_ipporthash *) set->data,
+ req->ip, req->port, 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)
+{
+ ip_set_ip_t port;
+
+ if (flags[index+1] == 0)
+ return -EINVAL;
+
+ 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",
+ NIPQUAD(skb->nh.iph->saddr),
+ NIPQUAD(skb->nh.iph->daddr));
+ DP("flag %s port %u",
+ flags[index+1] & IPSET_SRC ? "SRC" : "DST",
+ port);
+ if (port == INVALID_PORT)
+ return -EINVAL;
+
+ return __addip((struct ip_set_ipporthash *) set->data,
+ ntohl(flags[index] & IPSET_SRC
+ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
+ port,
+ hash_ip);
+}
+
+static int retry(struct ip_set *set)
+{
+ struct ip_set_ipporthash *map = (struct ip_set_ipporthash *) set->data;
+ ip_set_ip_t *elem;
+ void *members;
+ u_int32_t i, hashsize = map->hashsize;
+ int res;
+ struct ip_set_ipporthash *tmp;
+
+ if (map->resize == 0)
+ return -ERANGE;
+
+ again:
+ res = 0;
+
+ /* Calculate new hash size */
+ hashsize += (hashsize * map->resize)/100;
+ if (hashsize == map->hashsize)
+ hashsize++;
+
+ ip_set_printk("rehashing of set %s triggered: "
+ "hashsize grows from %u to %u",
+ set->name, map->hashsize, hashsize);
+
+ tmp = kmalloc(sizeof(struct ip_set_ipporthash)
+ + map->probes * sizeof(uint32_t), GFP_ATOMIC);
+ if (!map) {
+ DP("out of memory for %d bytes",
+ sizeof(struct ip_set_ipporthash)
+ + map->probes * sizeof(uint32_t));
+ return -ENOMEM;
+ }
+ tmp->members = harray_malloc(hashsize, sizeof(ip_set_ip_t), GFP_ATOMIC);
+ if (!tmp->members) {
+ DP("out of memory for %d bytes", hashsize * sizeof(ip_set_ip_t));
+ kfree(tmp);
+ return -ENOMEM;
+ }
+ tmp->hashsize = hashsize;
+ tmp->probes = map->probes;
+ tmp->resize = map->resize;
+ tmp->first_ip = map->first_ip;
+ tmp->last_ip = map->last_ip;
+ memcpy(tmp->initval, map->initval, map->probes * sizeof(uint32_t));
+
+ write_lock_bh(&set->lock);
+ map = (struct ip_set_ipporthash *) set->data; /* Play safe */
+ for (i = 0; i < map->hashsize && res == 0; i++) {
+ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, i);
+ if (*elem)
+ res = __add_haship(tmp, *elem);
+ }
+ if (res) {
+ /* Failure, try again */
+ write_unlock_bh(&set->lock);
+ harray_free(tmp->members);
+ kfree(tmp);
+ goto again;
+ }
+
+ /* Success at resizing! */
+ members = map->members;
+
+ map->hashsize = tmp->hashsize;
+ map->members = tmp->members;
+ write_unlock_bh(&set->lock);
+
+ harray_free(members);
+ kfree(tmp);
+
+ return 0;
+}
+
+static inline int
+__delip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t port,
+ ip_set_ip_t *hash_ip)
+{
+ struct ip_set_ipporthash *map = (struct ip_set_ipporthash *) set->data;
+ ip_set_ip_t id;
+ ip_set_ip_t *elem;
+
+ if (ip < map->first_ip || ip > map->last_ip)
+ return -ERANGE;
+
+ id = hash_id(set, ip, port, hash_ip);
+
+ if (id == UINT_MAX)
+ return -EEXIST;
+
+ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, id);
+ *elem = 0;
+
+ 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_ipporthash *req =
+ (struct ip_set_req_ipporthash *) data;
+
+ if (size != sizeof(struct ip_set_req_ipporthash)) {
+ ip_set_printk("data length wrong (want %zu, have %zu)",
+ sizeof(struct ip_set_req_ipporthash),
+ size);
+ return -EINVAL;
+ }
+ return __delip(set, req->ip, req->port, hash_ip);
+}
+
+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)
+{
+ ip_set_ip_t port;
+
+ if (flags[index+1] == 0)
+ return -EINVAL;
+
+ 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",
+ NIPQUAD(skb->nh.iph->saddr),
+ NIPQUAD(skb->nh.iph->daddr));
+ DP("flag %s port %u",
+ flags[index+1] & IPSET_SRC ? "SRC" : "DST",
+ port);
+ if (port == INVALID_PORT)
+ return -EINVAL;
+
+ return __delip(set,
+ ntohl(flags[index] & IPSET_SRC
+ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
+ port,
+ hash_ip);
+}
+
+static int create(struct ip_set *set, const void *data, size_t size)
+{
+ struct ip_set_req_ipporthash_create *req =
+ (struct ip_set_req_ipporthash_create *) data;
+ struct ip_set_ipporthash *map;
+ uint16_t i;
+
+ if (size != sizeof(struct ip_set_req_ipporthash_create)) {
+ ip_set_printk("data length wrong (want %zu, have %zu)",
+ sizeof(struct ip_set_req_ipporthash_create),
+ size);
+ return -EINVAL;
+ }
+
+ if (req->hashsize < 1) {
+ ip_set_printk("hashsize too small");
+ return -ENOEXEC;
+ }
+
+ if (req->probes < 1) {
+ ip_set_printk("probes too small");
+ return -ENOEXEC;
+ }
+
+ map = kmalloc(sizeof(struct ip_set_ipporthash)
+ + req->probes * sizeof(uint32_t), GFP_KERNEL);
+ if (!map) {
+ DP("out of memory for %d bytes",
+ sizeof(struct ip_set_ipporthash)
+ + req->probes * sizeof(uint32_t));
+ return -ENOMEM;
+ }
+ for (i = 0; i < req->probes; i++)
+ get_random_bytes(((uint32_t *) map->initval)+i, 4);
+ map->hashsize = req->hashsize;
+ map->probes = req->probes;
+ map->resize = req->resize;
+ map->first_ip = req->from;
+ map->last_ip = req->to;
+ map->members = harray_malloc(map->hashsize, sizeof(ip_set_ip_t), GFP_KERNEL);
+ if (!map->members) {
+ DP("out of memory for %d bytes", map->hashsize * sizeof(ip_set_ip_t));
+ kfree(map);
+ return -ENOMEM;
+ }
+
+ set->data = map;
+ return 0;
+}
+
+static void destroy(struct ip_set *set)
+{
+ struct ip_set_ipporthash *map = (struct ip_set_ipporthash *) set->data;
+
+ harray_free(map->members);
+ kfree(map);
+
+ set->data = NULL;
+}
+
+static void flush(struct ip_set *set)
+{
+ struct ip_set_ipporthash *map = (struct ip_set_ipporthash *) set->data;
+ harray_flush(map->members, map->hashsize, sizeof(ip_set_ip_t));
+}
+
+static void list_header(const struct ip_set *set, void *data)
+{
+ struct ip_set_ipporthash *map = (struct ip_set_ipporthash *) set->data;
+ struct ip_set_req_ipporthash_create *header =
+ (struct ip_set_req_ipporthash_create *) data;
+
+ header->hashsize = map->hashsize;
+ header->probes = map->probes;
+ header->resize = map->resize;
+ header->from = map->first_ip;
+ header->to = map->last_ip;
+}
+
+static int list_members_size(const struct ip_set *set)
+{
+ struct ip_set_ipporthash *map = (struct ip_set_ipporthash *) set->data;
+
+ return (map->hashsize * sizeof(ip_set_ip_t));
+}
+
+static void list_members(const struct ip_set *set, void *data)
+{
+ struct ip_set_ipporthash *map = (struct ip_set_ipporthash *) set->data;
+ ip_set_ip_t i, *elem;
+
+ for (i = 0; i < map->hashsize; i++) {
+ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, i);
+ ((ip_set_ip_t *)data)[i] = *elem;
+ }
+}
+
+static struct ip_set_type ip_set_ipporthash = {
+ .typename = SETTYPE_NAME,
+ .features = IPSET_TYPE_IP | IPSET_TYPE_PORT | IPSET_DATA_DOUBLE,
+ .protocol_version = IP_SET_PROTOCOL_VERSION,
+ .create = &create,
+ .destroy = &destroy,
+ .flush = &flush,
+ .reqsize = sizeof(struct ip_set_req_ipporthash),
+ .addip = &addip,
+ .addip_kernel = &addip_kernel,
+ .retry = &retry,
+ .delip = &delip,
+ .delip_kernel = &delip_kernel,
+ .testip = &testip,
+ .testip_kernel = &testip_kernel,
+ .header_size = sizeof(struct ip_set_req_ipporthash_create),
+ .list_header = &list_header,
+ .list_members_size = &list_members_size,
+ .list_members = &list_members,
+ .me = THIS_MODULE,
+};
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jozsef Kadlecsik <kadlec at blackhole.kfki.hu>");
+MODULE_DESCRIPTION("ipporthash type of IP sets");
+
+static int __init init(void)
+{
+ return ip_set_register_set_type(&ip_set_ipporthash);
+}
+
+static void __exit fini(void)
+{
+ /* FIXME: possible race with ip_set_create() */
+ ip_set_unregister_set_type(&ip_set_ipporthash);
+}
+
+module_init(init);
+module_exit(fini);
Modified: trunk/patch-o-matic-ng/patchlets/set/linux/net/ipv4/netfilter/ip_set_iptree.c
===================================================================
--- trunk/patch-o-matic-ng/patchlets/set/linux/net/ipv4/netfilter/ip_set_iptree.c 2005-10-12 12:12:20 UTC (rev 4351)
+++ trunk/patch-o-matic-ng/patchlets/set/linux/net/ipv4/netfilter/ip_set_iptree.c 2005-10-13 08:53:58 UTC (rev 4352)
@@ -25,7 +25,7 @@
/* Garbage collection interval in seconds: */
#define IPTREE_GC_TIME 5*60
/* Sleep so many milliseconds before trying again
- * to delete the gc timer at destroying a set */
+ * to delete the gc timer at destroying/flushing a set */
#define IPTREE_DESTROY_SLEEP 100
static kmem_cache_t *branch_cachep;
@@ -84,30 +84,32 @@
static int
testip_kernel(struct ip_set *set,
const struct sk_buff *skb,
- u_int32_t flags,
- ip_set_ip_t *hash_ip)
+ ip_set_ip_t *hash_ip,
+ const u_int32_t *flags,
+ unsigned char index)
{
int res;
DP("flag: %s src: %u.%u.%u.%u dst: %u.%u.%u.%u",
- flags & IPSET_SRC ? "SRC" : "DST",
+ flags[index] & IPSET_SRC ? "SRC" : "DST",
NIPQUAD(skb->nh.iph->saddr),
NIPQUAD(skb->nh.iph->daddr));
res = __testip(set,
- ntohl(flags & IPSET_SRC ? skb->nh.iph->saddr
- : skb->nh.iph->daddr),
+ ntohl(flags[index] & IPSET_SRC
+ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
hash_ip);
return (res < 0 ? 0 : res);
}
-#define ADDIP_WALK(map, elem, branch, type, cachep) do { \
+#define ADDIP_WALK(map, elem, branch, type, cachep, flags) do { \
if ((map)->tree[elem]) { \
DP("found %u", elem); \
branch = (map)->tree[elem]; \
} else { \
branch = (type *) \
- kmem_cache_alloc(cachep, GFP_KERNEL); \
+ kmem_cache_alloc(cachep, flags); \
if (branch == NULL) \
return -ENOMEM; \
memset(branch, 0, sizeof(*branch)); \
@@ -118,7 +120,8 @@
static inline int
__addip(struct ip_set *set, ip_set_ip_t ip, unsigned int timeout,
- ip_set_ip_t *hash_ip)
+ ip_set_ip_t *hash_ip,
+ int flags)
{
struct ip_set_iptree *map = (struct ip_set_iptree *) set->data;
struct ip_set_iptreeb *btree;
@@ -130,9 +133,9 @@
*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);
- ADDIP_WALK(btree, b, ctree, struct ip_set_iptreec, branch_cachep);
- ADDIP_WALK(ctree, c, dtree, struct ip_set_iptreed, leaf_cachep);
+ 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);
if (dtree->expires[d]
&& (!map->timeout || time_after(dtree->expires[d], jiffies)))
ret = -EEXIST;
@@ -158,20 +161,26 @@
DP("%u.%u.%u.%u %u", HIPQUAD(req->ip), req->timeout);
return __addip(set, req->ip,
req->timeout ? req->timeout : map->timeout,
- hash_ip);
+ hash_ip,
+ GFP_KERNEL);
}
static int
-addip_kernel(struct ip_set *set, const struct sk_buff *skb,
- u_int32_t flags, ip_set_ip_t *hash_ip)
+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)
{
struct ip_set_iptree *map = (struct ip_set_iptree *) set->data;
return __addip(set,
- ntohl(flags & IPSET_SRC ? skb->nh.iph->saddr
- : skb->nh.iph->daddr),
+ ntohl(flags[index] & IPSET_SRC
+ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
map->timeout,
- hash_ip);
+ hash_ip,
+ GFP_ATOMIC);
}
#define DELIP_WALK(map, elem, branch) do { \
@@ -220,12 +229,16 @@
}
static int
-delip_kernel(struct ip_set *set, const struct sk_buff *skb,
- u_int32_t flags, ip_set_ip_t *hash_ip)
+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(set,
- ntohl(flags & IPSET_SRC ? skb->nh.iph->saddr
- : skb->nh.iph->daddr),
+ ntohl(flags[index] & IPSET_SRC
+ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
hash_ip);
}
@@ -306,6 +319,21 @@
add_timer(&map->gc);
}
+static inline void init_gc_timer(struct ip_set *set)
+{
+ struct ip_set_iptree *map = (struct ip_set_iptree *) set->data;
+
+ /* Even if there is no timeout for the entries,
+ * we still have to call gc because delete
+ * do not clean up empty branches */
+ map->gc_interval = IPTREE_GC_TIME;
+ init_timer(&map->gc);
+ map->gc.data = (unsigned long) set;
+ map->gc.function = ip_tree_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_iptree_create *req =
@@ -329,16 +357,8 @@
map->timeout = req->timeout;
set->data = map;
- /* If there is no timeout for the entries,
- * we still have to call gc because delete
- * do not clean up empty branches */
- map->gc_interval = IPTREE_GC_TIME;
- init_timer(&map->gc);
- map->gc.data = (unsigned long) set;
- map->gc.function = ip_tree_gc;
- map->gc.expires = jiffies + map->gc_interval * HZ;
- add_timer(&map->gc);
-
+ init_gc_timer(set);
+
return 0;
}
@@ -364,6 +384,7 @@
{
struct ip_set_iptree *map = (struct ip_set_iptree *) set->data;
+ /* gc might be running */
while (!del_timer(&map->gc))
msleep(IPTREE_DESTROY_SLEEP);
__flush(map);
@@ -376,9 +397,14 @@
struct ip_set_iptree *map = (struct ip_set_iptree *) set->data;
unsigned int timeout = map->timeout;
+ /* gc might be running */
+ while (!del_timer(&map->gc))
+ msleep(IPTREE_DESTROY_SLEEP);
__flush(map);
memset(map, 0, sizeof(*map));
map->timeout = timeout;
+
+ init_gc_timer(set);
}
static void list_header(const struct ip_set *set, void *data)
@@ -445,7 +471,7 @@
static struct ip_set_type ip_set_iptree = {
.typename = SETTYPE_NAME,
- .typecode = IPSET_TYPE_IP,
+ .features = IPSET_TYPE_IP | IPSET_DATA_SINGLE,
.protocol_version = IP_SET_PROTOCOL_VERSION,
.create = &create,
.destroy = &destroy,
Modified: trunk/patch-o-matic-ng/patchlets/set/linux/net/ipv4/netfilter/ip_set_macipmap.c
===================================================================
--- trunk/patch-o-matic-ng/patchlets/set/linux/net/ipv4/netfilter/ip_set_macipmap.c 2005-10-12 12:12:20 UTC (rev 4351)
+++ trunk/patch-o-matic-ng/patchlets/set/linux/net/ipv4/netfilter/ip_set_macipmap.c 2005-10-13 08:53:58 UTC (rev 4352)
@@ -57,8 +57,11 @@
}
static int
-testip_kernel(struct ip_set *set, const struct sk_buff *skb,
- u_int32_t flags, ip_set_ip_t *hash_ip)
+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)
{
struct ip_set_macipmap *map =
(struct ip_set_macipmap *) set->data;
@@ -66,10 +69,11 @@
(struct ip_set_macip *) map->members;
ip_set_ip_t ip;
- ip = ntohl(flags & IPSET_SRC ? skb->nh.iph->saddr
- : skb->nh.iph->daddr);
+ ip = ntohl(flags[index] & IPSET_SRC
+ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr);
DP("flag: %s src: %u.%u.%u.%u dst: %u.%u.%u.%u",
- flags & IPSET_SRC ? "SRC" : "DST",
+ flags[index] & IPSET_SRC ? "SRC" : "DST",
NIPQUAD(skb->nh.iph->saddr),
NIPQUAD(skb->nh.iph->daddr));
@@ -131,13 +135,17 @@
}
static int
-addip_kernel(struct ip_set *set, const struct sk_buff *skb,
- u_int32_t flags, ip_set_ip_t *hash_ip)
+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)
{
ip_set_ip_t ip;
- ip = ntohl(flags & IPSET_SRC ? skb->nh.iph->saddr
- : skb->nh.iph->daddr);
+ ip = ntohl(flags[index] & IPSET_SRC
+ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr);
if (!(skb->mac.raw >= skb->head
&& (skb->mac.raw + ETH_HLEN) <= skb->data))
@@ -182,12 +190,16 @@
}
static int
-delip_kernel(struct ip_set *set, const struct sk_buff *skb,
- u_int32_t flags, ip_set_ip_t *hash_ip)
+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(set,
- ntohl(flags & IPSET_SRC ? skb->nh.iph->saddr
- : skb->nh.iph->daddr),
+ ntohl(flags[index] & IPSET_SRC
+ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
hash_ip);
}
@@ -302,7 +314,7 @@
static struct ip_set_type ip_set_macipmap = {
.typename = SETTYPE_NAME,
- .typecode = IPSET_TYPE_IP,
+ .features = IPSET_TYPE_IP | IPSET_DATA_SINGLE,
.protocol_version = IP_SET_PROTOCOL_VERSION,
.create = &create,
.destroy = &destroy,
Modified: trunk/patch-o-matic-ng/patchlets/set/linux/net/ipv4/netfilter/ip_set_nethash.c
===================================================================
--- trunk/patch-o-matic-ng/patchlets/set/linux/net/ipv4/netfilter/ip_set_nethash.c 2005-10-12 12:12:20 UTC (rev 4351)
+++ trunk/patch-o-matic-ng/patchlets/set/linux/net/ipv4/netfilter/ip_set_nethash.c 2005-10-13 08:53:58 UTC (rev 4352)
@@ -102,12 +102,16 @@
}
static int
-testip_kernel(struct ip_set *set, const struct sk_buff *skb,
- u_int32_t flags, ip_set_ip_t *hash_ip)
+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)
{
return __testip(set,
- ntohl(flags & IPSET_SRC ? skb->nh.iph->saddr
- : skb->nh.iph->daddr),
+ ntohl(flags[index] & IPSET_SRC
+ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
hash_ip);
}
@@ -186,13 +190,17 @@
}
static int
-addip_kernel(struct ip_set *set, const struct sk_buff *skb,
- u_int32_t flags, ip_set_ip_t *hash_ip)
+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)
{
struct ip_set_nethash *map = (struct ip_set_nethash *) set->data;
int ret = -ERANGE;
- ip_set_ip_t ip = ntohl(flags & IPSET_SRC ? skb->nh.iph->saddr
- : skb->nh.iph->daddr);
+ ip_set_ip_t ip = ntohl(flags[index] & IPSET_SRC
+ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr);
if (map->cidr[0])
ret = __addip(map, ip, map->cidr[0], hash_ip);
@@ -306,13 +314,17 @@
}
static int
-delip_kernel(struct ip_set *set, const struct sk_buff *skb,
- u_int32_t flags, ip_set_ip_t *hash_ip)
+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)
{
struct ip_set_nethash *map = (struct ip_set_nethash *) set->data;
int ret = -ERANGE;
- ip_set_ip_t ip = ntohl(flags & IPSET_SRC ? skb->nh.iph->saddr
- : skb->nh.iph->daddr);
+ ip_set_ip_t ip = ntohl(flags[index] & IPSET_SRC
+ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr);
if (map->cidr[0])
ret = __delip(map, ip, map->cidr[0], hash_ip);
@@ -416,7 +428,7 @@
static struct ip_set_type ip_set_nethash = {
.typename = SETTYPE_NAME,
- .typecode = IPSET_TYPE_IP,
+ .features = IPSET_TYPE_IP | IPSET_DATA_SINGLE,
.protocol_version = IP_SET_PROTOCOL_VERSION,
.create = &create,
.destroy = &destroy,
Modified: trunk/patch-o-matic-ng/patchlets/set/linux/net/ipv4/netfilter/ip_set_portmap.c
===================================================================
--- trunk/patch-o-matic-ng/patchlets/set/linux/net/ipv4/netfilter/ip_set_portmap.c 2005-10-12 12:12:20 UTC (rev 4351)
+++ trunk/patch-o-matic-ng/patchlets/set/linux/net/ipv4/netfilter/ip_set_portmap.c 2005-10-13 08:53:58 UTC (rev 4352)
@@ -89,13 +89,16 @@
}
static int
-testport_kernel(struct ip_set *set, const struct sk_buff *skb,
- u_int32_t flags, ip_set_ip_t *hash_port)
+testport_kernel(struct ip_set *set,
+ const struct sk_buff *skb,
+ ip_set_ip_t *hash_port,
+ const u_int32_t *flags,
+ unsigned char index)
{
int res;
- ip_set_ip_t port = get_port(skb, flags);
+ ip_set_ip_t port = get_port(skb, flags[index]);
- DP("flag %s port %u", flags & IPSET_SRC ? "SRC" : "DST", port);
+ DP("flag %s port %u", flags[index] & IPSET_SRC ? "SRC" : "DST", port);
if (port == INVALID_PORT)
return 0;
@@ -136,10 +139,13 @@
}
static int
-addport_kernel(struct ip_set *set, const struct sk_buff *skb,
- u_int32_t flags, ip_set_ip_t *hash_port)
+addport_kernel(struct ip_set *set,
+ const struct sk_buff *skb,
+ ip_set_ip_t *hash_port,
+ const u_int32_t *flags,
+ unsigned char index)
{
- ip_set_ip_t port = get_port(skb, flags);
+ ip_set_ip_t port = get_port(skb, flags[index]);
if (port == INVALID_PORT)
return -EINVAL;
@@ -179,10 +185,13 @@
}
static int
-delport_kernel(struct ip_set *set, const struct sk_buff *skb,
- u_int32_t flags, ip_set_ip_t *hash_port)
+delport_kernel(struct ip_set *set,
+ const struct sk_buff *skb,
+ ip_set_ip_t *hash_port,
+ const u_int32_t *flags,
+ unsigned char index)
{
- ip_set_ip_t port = get_port(skb, flags);
+ ip_set_ip_t port = get_port(skb, flags[index]);
if (port == INVALID_PORT)
return -EINVAL;
@@ -283,7 +292,7 @@
static struct ip_set_type ip_set_portmap = {
.typename = SETTYPE_NAME,
- .typecode = IPSET_TYPE_PORT,
+ .features = IPSET_TYPE_PORT | IPSET_DATA_SINGLE,
.protocol_version = IP_SET_PROTOCOL_VERSION,
.create = &create,
.destroy = &destroy,
Modified: trunk/patch-o-matic-ng/patchlets/set/linux-2.6/include/linux/netfilter_ipv4/ip_set.h
===================================================================
--- trunk/patch-o-matic-ng/patchlets/set/linux-2.6/include/linux/netfilter_ipv4/ip_set.h 2005-10-12 12:12:20 UTC (rev 4351)
+++ trunk/patch-o-matic-ng/patchlets/set/linux-2.6/include/linux/netfilter_ipv4/ip_set.h 2005-10-13 08:53:58 UTC (rev 4352)
@@ -81,10 +81,12 @@
#define IPSET_MATCH_INV 0x04 /* Inverse matching */
/*
- * Set types (flavours)
+ * Set features
*/
-#define IPSET_TYPE_IP 0 /* IP address type of set */
-#define IPSET_TYPE_PORT 1 /* Port type of set */
+#define IPSET_TYPE_IP 0x01 /* IP address type of set */
+#define IPSET_TYPE_PORT 0x02 /* Port type of set */
+#define IPSET_DATA_SINGLE 0x04 /* Single data storage */
+#define IPSET_DATA_DOUBLE 0x08 /* Double data storage */
/* Reserved keywords */
#define IPSET_TOKEN_DEFAULT ":default:"
@@ -340,8 +342,9 @@
*/
int (*testip_kernel) (struct ip_set *set,
const struct sk_buff * skb,
- u_int32_t flags,
- ip_set_ip_t *ip);
+ ip_set_ip_t *ip,
+ const u_int32_t *flags,
+ unsigned char index);
/* test for IP in set (userspace: ipset -T set IP)
* return 0 if not in set, 1 if in set.
@@ -372,8 +375,9 @@
*/
int (*addip_kernel) (struct ip_set *set,
const struct sk_buff * skb,
- u_int32_t flags,
- ip_set_ip_t *ip);
+ ip_set_ip_t *ip,
+ const u_int32_t *flags,
+ unsigned char index);
/* remove IP from set (userspace: ipset -D set --entry x)
* Return -EEXIST if the address is NOT in the set,
@@ -391,8 +395,9 @@
*/
int (*delip_kernel) (struct ip_set *set,
const struct sk_buff * skb,
- u_int32_t flags,
- ip_set_ip_t *ip);
+ ip_set_ip_t *ip,
+ const u_int32_t *flags,
+ unsigned char index);
/* new set creation - allocated type specific items
*/
@@ -443,7 +448,7 @@
void *data);
char typename[IP_SET_MAXNAMELEN];
- char typecode;
+ unsigned char features;
int protocol_version;
/* Set this to THIS_MODULE if you are a module, otherwise NULL */
Added: trunk/patch-o-matic-ng/patchlets/set/linux-2.6/include/linux/netfilter_ipv4/ip_set_ipporthash.h
===================================================================
--- trunk/patch-o-matic-ng/patchlets/set/linux-2.6/include/linux/netfilter_ipv4/ip_set_ipporthash.h 2005-10-12 12:12:20 UTC (rev 4351)
+++ trunk/patch-o-matic-ng/patchlets/set/linux-2.6/include/linux/netfilter_ipv4/ip_set_ipporthash.h 2005-10-13 08:53:58 UTC (rev 4352)
@@ -0,0 +1,33 @@
+#ifndef __IP_SET_IPPORTHASH_H
+#define __IP_SET_IPPORTHASH_H
+
+#include <linux/netfilter_ipv4/ip_set.h>
+
+#define SETTYPE_NAME "ipporthash"
+#define MAX_RANGE 0x0000FFFF
+#define INVALID_PORT (MAX_RANGE + 1)
+
+struct ip_set_ipporthash {
+ ip_set_ip_t *members; /* the ipporthash proper */
+ uint32_t hashsize; /* hash size */
+ uint16_t probes; /* max number of probes */
+ uint16_t resize; /* resize factor in percent */
+ ip_set_ip_t first_ip; /* host byte order, included in range */
+ ip_set_ip_t last_ip; /* host byte order, included in range */
+ void *initval[0]; /* initvals for jhash_1word */
+};
+
+struct ip_set_req_ipporthash_create {
+ uint32_t hashsize;
+ uint16_t probes;
+ uint16_t resize;
+ ip_set_ip_t from;
+ ip_set_ip_t to;
+};
+
+struct ip_set_req_ipporthash {
+ ip_set_ip_t ip;
+ ip_set_ip_t port;
+};
+
+#endif /* __IP_SET_IPPORTHASH_H */
Modified: trunk/patch-o-matic-ng/patchlets/set/linux-2.6/include/linux/netfilter_ipv4/ip_set_malloc.h
===================================================================
--- trunk/patch-o-matic-ng/patchlets/set/linux-2.6/include/linux/netfilter_ipv4/ip_set_malloc.h 2005-10-12 12:12:20 UTC (rev 4351)
+++ trunk/patch-o-matic-ng/patchlets/set/linux-2.6/include/linux/netfilter_ipv4/ip_set_malloc.h 2005-10-13 08:53:58 UTC (rev 4352)
@@ -30,7 +30,7 @@
}
struct harray {
- size_t max_arrays;
+ size_t max_elements;
void *arrays[0];
};
@@ -38,7 +38,7 @@
harray_malloc(size_t hashsize, size_t typesize, int flags)
{
struct harray *harray;
- size_t max_arrays, size, i, j;
+ size_t max_elements, size, i, j;
if (!max_malloc_size)
init_max_malloc_size();
@@ -46,9 +46,9 @@
if (typesize > max_malloc_size)
return NULL;
- max_arrays = max_malloc_size/typesize;
- size = hashsize/max_arrays;
- if (hashsize % max_arrays)
+ max_elements = max_malloc_size/typesize;
+ size = hashsize/max_elements;
+ if (hashsize % max_elements)
size++;
/* Last pointer signals end of arrays */
@@ -59,18 +59,18 @@
return NULL;
for (i = 0; i < size - 1; i++) {
- harray->arrays[i] = kmalloc(max_arrays * typesize, flags);
+ harray->arrays[i] = kmalloc(max_elements * typesize, flags);
if (!harray->arrays[i])
goto undo;
- memset(harray->arrays[i], 0, max_arrays * typesize);
+ memset(harray->arrays[i], 0, max_elements * typesize);
}
- harray->arrays[i] = kmalloc((hashsize - i * max_arrays) * typesize,
+ harray->arrays[i] = kmalloc((hashsize - i * max_elements) * typesize,
flags);
if (!harray->arrays[i])
goto undo;
- memset(harray->arrays[i], 0, (hashsize - i * max_arrays) * typesize);
+ memset(harray->arrays[i], 0, (hashsize - i * max_elements) * typesize);
- harray->max_arrays = max_arrays;
+ harray->max_elements = max_elements;
harray->arrays[size] = NULL;
return (void *)harray;
@@ -99,16 +99,16 @@
size_t i;
for (i = 0; harray->arrays[i+1] != NULL; i++)
- memset(harray->arrays[i], 0, harray->max_arrays * typesize);
+ memset(harray->arrays[i], 0, harray->max_elements * typesize);
memset(harray->arrays[i], 0,
- (hashsize - i * harray->max_arrays) * typesize);
+ (hashsize - i * harray->max_elements) * typesize);
}
#define HARRAY_ELEM(h, type, which) \
({ \
struct harray *__h = (struct harray *)(h); \
- ((type)((__h)->arrays[(which)/(__h)->max_arrays]) \
- + (which)%(__h)->max_arrays); \
+ ((type)((__h)->arrays[(which)/(__h)->max_elements]) \
+ + (which)%(__h)->max_elements); \
})
#endif /* __KERNEL__ */
Deleted: trunk/patch-o-matic-ng/patchlets/set/linux-2.6/include/linux/netfilter_ipv4/ip_set_prime.h
===================================================================
--- trunk/patch-o-matic-ng/patchlets/set/linux-2.6/include/linux/netfilter_ipv4/ip_set_prime.h 2005-10-12 12:12:20 UTC (rev 4351)
+++ trunk/patch-o-matic-ng/patchlets/set/linux-2.6/include/linux/netfilter_ipv4/ip_set_prime.h 2005-10-13 08:53:58 UTC (rev 4352)
@@ -1,34 +0,0 @@
-#ifndef __IP_SET_PRIME_H
-#define __IP_SET_PRIME_H
-
-static inline unsigned make_prime_bound(unsigned nr)
-{
- unsigned long long nr64 = nr;
- unsigned long long x = 1;
- nr = 1;
- while (x <= nr64) { x <<= 2; nr <<= 1; }
- return nr;
-}
-
-static inline int make_prime_check(unsigned nr)
-{
- unsigned x = 3;
- unsigned b = make_prime_bound(nr);
- while (x <= b) {
- if (0 == (nr % x)) return 0;
- x += 2;
- }
- return 1;
-}
-
-static unsigned make_prime(unsigned nr)
-{
- if (0 == (nr & 1)) nr--;
- while (nr > 1) {
- if (make_prime_check(nr)) return nr;
- nr -= 2;
- }
- return 2;
-}
-
-#endif /* __IP_SET_PRIME_H */
Modified: trunk/patch-o-matic-ng/patchlets/set/linux-2.6/net/ipv4/netfilter/Kconfig.ladd
===================================================================
--- trunk/patch-o-matic-ng/patchlets/set/linux-2.6/net/ipv4/netfilter/Kconfig.ladd 2005-10-12 12:12:20 UTC (rev 4351)
+++ trunk/patch-o-matic-ng/patchlets/set/linux-2.6/net/ipv4/netfilter/Kconfig.ladd 2005-10-13 08:53:58 UTC (rev 4352)
@@ -71,6 +71,14 @@
To compile it as a module, choose M here. If unsure, say N.
+config IP_NF_SET_IPPORTHASH
+ tristate "ipporthash set support"
+ depends on IP_NF_SET
+ help
+ This option adds the ipporthash set type support.
+
+ To compile it as a module, choose M here. If unsure, say N.
+
config IP_NF_SET_IPTREE
tristate "iptree set support"
depends on IP_NF_SET
Modified: trunk/patch-o-matic-ng/patchlets/set/linux-2.6/net/ipv4/netfilter/Makefile.ladd_2
===================================================================
--- trunk/patch-o-matic-ng/patchlets/set/linux-2.6/net/ipv4/netfilter/Makefile.ladd_2 2005-10-12 12:12:20 UTC (rev 4351)
+++ trunk/patch-o-matic-ng/patchlets/set/linux-2.6/net/ipv4/netfilter/Makefile.ladd_2 2005-10-13 08:53:58 UTC (rev 4352)
@@ -8,4 +8,5 @@
obj-$(CONFIG_IP_NF_SET_MACIPMAP) += ip_set_macipmap.o
obj-$(CONFIG_IP_NF_SET_IPHASH) += ip_set_iphash.o
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
Modified: trunk/patch-o-matic-ng/patchlets/set/linux-2.6/net/ipv4/netfilter/ip_set.c
===================================================================
--- trunk/patch-o-matic-ng/patchlets/set/linux-2.6/net/ipv4/netfilter/ip_set.c 2005-10-12 12:12:20 UTC (rev 4351)
+++ trunk/patch-o-matic-ng/patchlets/set/linux-2.6/net/ipv4/netfilter/ip_set.c 2005-10-13 08:53:58 UTC (rev 4352)
@@ -204,7 +204,8 @@
{
struct ip_set *set;
ip_set_ip_t ip;
- int res, i = 0;
+ int res;
+ unsigned char i = 0;
IP_SET_ASSERT(flags[i]);
read_lock_bh(&ip_set_lock);
@@ -213,10 +214,11 @@
IP_SET_ASSERT(set);
DP("set %s, index %u", set->name, index);
read_lock_bh(&set->lock);
- res = set->type->testip_kernel(set, skb, flags[i], &ip);
+ res = set->type->testip_kernel(set, skb, &ip, flags, i++);
read_unlock_bh(&set->lock);
+ i += !!(set->type->features & IPSET_DATA_DOUBLE);
} while (res > 0
- && flags[++i]
+ && flags[i]
&& follow_bindings(index, set, ip));
read_unlock_bh(&ip_set_lock);
@@ -230,7 +232,8 @@
{
struct ip_set *set;
ip_set_ip_t ip;
- int res, i= 0;
+ int res;
+ unsigned char i = 0;
IP_SET_ASSERT(flags[i]);
retry:
@@ -240,10 +243,11 @@
IP_SET_ASSERT(set);
DP("set %s, index %u", set->name, index);
write_lock_bh(&set->lock);
- res = set->type->addip_kernel(set, skb, flags[i], &ip);
+ res = set->type->addip_kernel(set, skb, &ip, flags, i++);
write_unlock_bh(&set->lock);
+ i += !!(set->type->features & IPSET_DATA_DOUBLE);
} while ((res == 0 || res == -EEXIST)
- && flags[++i]
+ && flags[i]
&& follow_bindings(index, set, ip));
read_unlock_bh(&ip_set_lock);
@@ -260,7 +264,8 @@
{
struct ip_set *set;
ip_set_ip_t ip;
- int res, i = 0;
+ int res;
+ unsigned char i = 0;
IP_SET_ASSERT(flags[i]);
read_lock_bh(&ip_set_lock);
@@ -269,10 +274,11 @@
IP_SET_ASSERT(set);
DP("set %s, index %u", set->name, index);
write_lock_bh(&set->lock);
- res = set->type->delip_kernel(set, skb, flags[i], &ip);
+ res = set->type->delip_kernel(set, skb, &ip, flags, i++);
write_unlock_bh(&set->lock);
+ i += !!(set->type->features & IPSET_DATA_DOUBLE);
} while ((res == 0 || res == -EEXIST)
- && flags[++i]
+ && flags[i]
&& follow_bindings(index, set, ip));
read_unlock_bh(&ip_set_lock);
}
@@ -999,8 +1005,8 @@
u_int32_t from_ref;
DP("set: %s to %s", from->name, to->name);
- /* Type can't be changed. Artifical restriction. */
- if (from->type->typecode != to->type->typecode)
+ /* Features must not change. Artifical restriction. */
+ if (from->type->features != to->type->features)
return -ENOEXEC;
/* No magic here: ref munging protected by the mutex */
Modified: trunk/patch-o-matic-ng/patchlets/set/linux-2.6/net/ipv4/netfilter/ip_set_iphash.c
===================================================================
--- trunk/patch-o-matic-ng/patchlets/set/linux-2.6/net/ipv4/netfilter/ip_set_iphash.c 2005-10-12 12:12:20 UTC (rev 4351)
+++ trunk/patch-o-matic-ng/patchlets/set/linux-2.6/net/ipv4/netfilter/ip_set_iphash.c 2005-10-13 08:53:58 UTC (rev 4352)
@@ -78,12 +78,16 @@
}
static int
-testip_kernel(struct ip_set *set, const struct sk_buff *skb,
- u_int32_t flags, ip_set_ip_t *hash_ip)
+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)
{
return __testip(set,
- ntohl(flags & IPSET_SRC ? skb->nh.iph->saddr
- : skb->nh.iph->daddr),
+ ntohl(flags[index] & IPSET_SRC
+ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
hash_ip);
}
@@ -127,12 +131,16 @@
}
static int
-addip_kernel(struct ip_set *set, const struct sk_buff *skb,
- u_int32_t flags, ip_set_ip_t *hash_ip)
+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((struct ip_set_iphash *) set->data,
- ntohl(flags & IPSET_SRC ? skb->nh.iph->saddr
- : skb->nh.iph->daddr),
+ ntohl(flags[index] & IPSET_SRC
+ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
hash_ip);
}
@@ -174,10 +182,10 @@
kfree(tmp);
return -ENOMEM;
}
- tmp->hashsize = hashsize,
- tmp->probes = map->probes,
- tmp->resize = map->resize,
- tmp->netmask = map->netmask,
+ tmp->hashsize = hashsize;
+ tmp->probes = map->probes;
+ tmp->resize = map->resize;
+ tmp->netmask = map->netmask;
memcpy(tmp->initval, map->initval, map->probes * sizeof(uint32_t));
write_lock_bh(&set->lock);
@@ -241,12 +249,16 @@
}
static int
-delip_kernel(struct ip_set *set, const struct sk_buff *skb,
- u_int32_t flags, ip_set_ip_t *hash_ip)
+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(set,
- ntohl(flags & IPSET_SRC ? skb->nh.iph->saddr
- : skb->nh.iph->daddr),
+ ntohl(flags[index] & IPSET_SRC
+ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
hash_ip);
}
@@ -347,7 +359,7 @@
static struct ip_set_type ip_set_iphash = {
.typename = SETTYPE_NAME,
- .typecode = IPSET_TYPE_IP,
+ .features = IPSET_TYPE_IP | IPSET_DATA_SINGLE,
.protocol_version = IP_SET_PROTOCOL_VERSION,
.create = &create,
.destroy = &destroy,
Modified: trunk/patch-o-matic-ng/patchlets/set/linux-2.6/net/ipv4/netfilter/ip_set_ipmap.c
===================================================================
--- trunk/patch-o-matic-ng/patchlets/set/linux-2.6/net/ipv4/netfilter/ip_set_ipmap.c 2005-10-12 12:12:20 UTC (rev 4351)
+++ trunk/patch-o-matic-ng/patchlets/set/linux-2.6/net/ipv4/netfilter/ip_set_ipmap.c 2005-10-13 08:53:58 UTC (rev 4352)
@@ -60,19 +60,21 @@
static int
testip_kernel(struct ip_set *set,
const struct sk_buff *skb,
- u_int32_t flags,
- ip_set_ip_t *hash_ip)
+ ip_set_ip_t *hash_ip,
+ const u_int32_t *flags,
+ unsigned char index)
{
int res;
DP("flag: %s src: %u.%u.%u.%u dst: %u.%u.%u.%u",
- flags & IPSET_SRC ? "SRC" : "DST",
+ flags[index] & IPSET_SRC ? "SRC" : "DST",
NIPQUAD(skb->nh.iph->saddr),
NIPQUAD(skb->nh.iph->daddr));
res = __testip(set,
- ntohl(flags & IPSET_SRC ? skb->nh.iph->saddr
- : skb->nh.iph->daddr),
+ ntohl(flags[index] & IPSET_SRC
+ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
hash_ip);
return (res < 0 ? 0 : res);
}
@@ -111,12 +113,16 @@
}
static int
-addip_kernel(struct ip_set *set, const struct sk_buff *skb,
- u_int32_t flags, ip_set_ip_t *hash_ip)
+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(set,
- ntohl(flags & IPSET_SRC ? skb->nh.iph->saddr
- : skb->nh.iph->daddr),
+ ntohl(flags[index] & IPSET_SRC
+ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
hash_ip);
}
@@ -153,12 +159,16 @@
}
static int
-delip_kernel(struct ip_set *set, const struct sk_buff *skb,
- u_int32_t flags, ip_set_ip_t *hash_ip)
+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(set,
- ntohl(flags & IPSET_SRC ? skb->nh.iph->saddr
- : skb->nh.iph->daddr),
+ ntohl(flags[index] & IPSET_SRC
+ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
hash_ip);
}
@@ -279,7 +289,7 @@
static struct ip_set_type ip_set_ipmap = {
.typename = SETTYPE_NAME,
- .typecode = IPSET_TYPE_IP,
+ .features = IPSET_TYPE_IP | IPSET_DATA_SINGLE,
.protocol_version = IP_SET_PROTOCOL_VERSION,
.create = &create,
.destroy = &destroy,
Added: trunk/patch-o-matic-ng/patchlets/set/linux-2.6/net/ipv4/netfilter/ip_set_ipporthash.c
===================================================================
--- trunk/patch-o-matic-ng/patchlets/set/linux-2.6/net/ipv4/netfilter/ip_set_ipporthash.c 2005-10-12 12:12:20 UTC (rev 4351)
+++ trunk/patch-o-matic-ng/patchlets/set/linux-2.6/net/ipv4/netfilter/ip_set_ipporthash.c 2005-10-13 08:53:58 UTC (rev 4352)
@@ -0,0 +1,524 @@
+/* Copyright (C) 2003-2004 Jozsef Kadlecsik <kadlec at blackhole.kfki.hu>
+ *
+ * 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.
+ */
+
+/* Kernel module implementing an ip+port hash set */
+
+#include <linux/module.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <linux/udp.h>
+#include <linux/skbuff.h>
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv4/ip_set.h>
+#include <linux/errno.h>
+#include <asm/uaccess.h>
+#include <asm/bitops.h>
+#include <linux/spinlock.h>
+#include <linux/vmalloc.h>
+#include <linux/random.h>
+
+#include <net/ip.h>
+
+#include <linux/netfilter_ipv4/ip_set_malloc.h>
+#include <linux/netfilter_ipv4/ip_set_ipporthash.h>
+#include <linux/netfilter_ipv4/ip_set_jhash.h>
+
+/* We must handle non-linear skbs */
+static inline ip_set_ip_t
+get_port(const struct sk_buff *skb, u_int32_t flags)
+{
+ struct iphdr *iph = skb->nh.iph;
+ u_int16_t offset = ntohs(iph->frag_off) & IP_OFFSET;
+
+ switch (iph->protocol) {
+ case IPPROTO_TCP: {
+ struct tcphdr tcph;
+
+ /* See comments at tcp_match in ip_tables.c */
+ if (offset)
+ return INVALID_PORT;
+
+ if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &tcph, sizeof(tcph)) < 0)
+ /* No choice either */
+ return INVALID_PORT;
+
+ return ntohs(flags & IPSET_SRC ?
+ tcph.source : tcph.dest);
+ }
+ case IPPROTO_UDP: {
+ struct udphdr udph;
+
+ if (offset)
+ return INVALID_PORT;
+
+ if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &udph, sizeof(udph)) < 0)
+ /* No choice either */
+ return INVALID_PORT;
+
+ return ntohs(flags & IPSET_SRC ?
+ udph.source : udph.dest);
+ }
+ default:
+ return INVALID_PORT;
+ }
+}
+
+static inline __u32
+jhash_ip(const struct ip_set_ipporthash *map, uint16_t i, ip_set_ip_t ip)
+{
+ return jhash_1word(ip, *(((uint32_t *) map->initval) + i));
+}
+
+#define HASH_IP(map, ip, port) (port + ((ip - ((map)->first_ip)) << 16))
+
+static inline __u32
+hash_id(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t port,
+ ip_set_ip_t *hash_ip)
+{
+ struct ip_set_ipporthash *map =
+ (struct ip_set_ipporthash *) set->data;
+ __u32 id;
+ u_int16_t i;
+ ip_set_ip_t *elem;
+
+ *hash_ip = HASH_IP(map, ip, port);
+ DP("set: %s, ipport:%u.%u.%u.%u:%u, %u.%u.%u.%u",
+ set->name, HIPQUAD(ip), port, HIPQUAD(*hash_ip));
+
+ for (i = 0; i < map->probes; i++) {
+ id = jhash_ip(map, i, *hash_ip) % map->hashsize;
+ DP("hash key: %u", id);
+ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, id);
+ if (*elem == *hash_ip)
+ return id;
+ /* No shortcut at testing - there can be deleted
+ * entries. */
+ }
+ return UINT_MAX;
+}
+
+static inline int
+__testip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t port,
+ ip_set_ip_t *hash_ip)
+{
+ struct ip_set_ipporthash *map = (struct ip_set_ipporthash *) set->data;
+
+ if (ip < map->first_ip || ip > map->last_ip)
+ return -ERANGE;
+
+ return (hash_id(set, ip, port, hash_ip) != UINT_MAX);
+}
+
+static int
+testip(struct ip_set *set, const void *data, size_t size,
+ ip_set_ip_t *hash_ip)
+{
+ struct ip_set_req_ipporthash *req =
+ (struct ip_set_req_ipporthash *) data;
+
+ if (size != sizeof(struct ip_set_req_ipporthash)) {
+ ip_set_printk("data length wrong (want %zu, have %zu)",
+ sizeof(struct ip_set_req_ipporthash),
+ size);
+ return -EINVAL;
+ }
+ return __testip(set, req->ip, req->port, 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)
+{
+ ip_set_ip_t port;
+
+ if (flags[index+1] == 0)
+ return -EINVAL;
+
+ 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",
+ NIPQUAD(skb->nh.iph->saddr),
+ NIPQUAD(skb->nh.iph->daddr));
+ DP("flag %s port %u",
+ flags[index+1] & IPSET_SRC ? "SRC" : "DST",
+ port);
+ if (port == INVALID_PORT)
+ return 0;
+
+ return __testip(set,
+ ntohl(flags[index] & IPSET_SRC
+ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
+ port,
+ hash_ip);
+}
+
+static inline int
+__add_haship(struct ip_set_ipporthash *map, ip_set_ip_t hash_ip)
+{
+ __u32 probe;
+ u_int16_t i;
+ ip_set_ip_t *elem;
+
+ for (i = 0; i < map->probes; i++) {
+ probe = jhash_ip(map, i, hash_ip) % map->hashsize;
+ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, probe);
+ if (*elem == hash_ip)
+ return -EEXIST;
+ if (!*elem) {
+ *elem = hash_ip;
+ return 0;
+ }
+ }
+ /* Trigger rehashing */
+ return -EAGAIN;
+}
+
+static inline int
+__addip(struct ip_set_ipporthash *map, ip_set_ip_t ip, ip_set_ip_t port,
+ ip_set_ip_t *hash_ip)
+{
+ if (ip < map->first_ip || ip > map->last_ip)
+ return -ERANGE;
+
+ *hash_ip = HASH_IP(map, ip, port);
+
+ return __add_haship(map, *hash_ip);
+}
+
+static int
+addip(struct ip_set *set, const void *data, size_t size,
+ ip_set_ip_t *hash_ip)
+{
+ struct ip_set_req_ipporthash *req =
+ (struct ip_set_req_ipporthash *) data;
+
+ if (size != sizeof(struct ip_set_req_ipporthash)) {
+ ip_set_printk("data length wrong (want %zu, have %zu)",
+ sizeof(struct ip_set_req_ipporthash),
+ size);
+ return -EINVAL;
+ }
+ return __addip((struct ip_set_ipporthash *) set->data,
+ req->ip, req->port, 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)
+{
+ ip_set_ip_t port;
+
+ if (flags[index+1] == 0)
+ return -EINVAL;
+
+ 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",
+ NIPQUAD(skb->nh.iph->saddr),
+ NIPQUAD(skb->nh.iph->daddr));
+ DP("flag %s port %u",
+ flags[index+1] & IPSET_SRC ? "SRC" : "DST",
+ port);
+ if (port == INVALID_PORT)
+ return -EINVAL;
+
+ return __addip((struct ip_set_ipporthash *) set->data,
+ ntohl(flags[index] & IPSET_SRC
+ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
+ port,
+ hash_ip);
+}
+
+static int retry(struct ip_set *set)
+{
+ struct ip_set_ipporthash *map = (struct ip_set_ipporthash *) set->data;
+ ip_set_ip_t *elem;
+ void *members;
+ u_int32_t i, hashsize = map->hashsize;
+ int res;
+ struct ip_set_ipporthash *tmp;
+
+ if (map->resize == 0)
+ return -ERANGE;
+
+ again:
+ res = 0;
+
+ /* Calculate new hash size */
+ hashsize += (hashsize * map->resize)/100;
+ if (hashsize == map->hashsize)
+ hashsize++;
+
+ ip_set_printk("rehashing of set %s triggered: "
+ "hashsize grows from %u to %u",
+ set->name, map->hashsize, hashsize);
+
+ tmp = kmalloc(sizeof(struct ip_set_ipporthash)
+ + map->probes * sizeof(uint32_t), GFP_ATOMIC);
+ if (!map) {
+ DP("out of memory for %d bytes",
+ sizeof(struct ip_set_ipporthash)
+ + map->probes * sizeof(uint32_t));
+ return -ENOMEM;
+ }
+ tmp->members = harray_malloc(hashsize, sizeof(ip_set_ip_t), GFP_ATOMIC);
+ if (!tmp->members) {
+ DP("out of memory for %d bytes", hashsize * sizeof(ip_set_ip_t));
+ kfree(tmp);
+ return -ENOMEM;
+ }
+ tmp->hashsize = hashsize;
+ tmp->probes = map->probes;
+ tmp->resize = map->resize;
+ tmp->first_ip = map->first_ip;
+ tmp->last_ip = map->last_ip;
+ memcpy(tmp->initval, map->initval, map->probes * sizeof(uint32_t));
+
+ write_lock_bh(&set->lock);
+ map = (struct ip_set_ipporthash *) set->data; /* Play safe */
+ for (i = 0; i < map->hashsize && res == 0; i++) {
+ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, i);
+ if (*elem)
+ res = __add_haship(tmp, *elem);
+ }
+ if (res) {
+ /* Failure, try again */
+ write_unlock_bh(&set->lock);
+ harray_free(tmp->members);
+ kfree(tmp);
+ goto again;
+ }
+
+ /* Success at resizing! */
+ members = map->members;
+
+ map->hashsize = tmp->hashsize;
+ map->members = tmp->members;
+ write_unlock_bh(&set->lock);
+
+ harray_free(members);
+ kfree(tmp);
+
+ return 0;
+}
+
+static inline int
+__delip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t port,
+ ip_set_ip_t *hash_ip)
+{
+ struct ip_set_ipporthash *map = (struct ip_set_ipporthash *) set->data;
+ ip_set_ip_t id;
+ ip_set_ip_t *elem;
+
+ if (ip < map->first_ip || ip > map->last_ip)
+ return -ERANGE;
+
+ id = hash_id(set, ip, port, hash_ip);
+
+ if (id == UINT_MAX)
+ return -EEXIST;
+
+ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, id);
+ *elem = 0;
+
+ 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_ipporthash *req =
+ (struct ip_set_req_ipporthash *) data;
+
+ if (size != sizeof(struct ip_set_req_ipporthash)) {
+ ip_set_printk("data length wrong (want %zu, have %zu)",
+ sizeof(struct ip_set_req_ipporthash),
+ size);
+ return -EINVAL;
+ }
+ return __delip(set, req->ip, req->port, hash_ip);
+}
+
+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)
+{
+ ip_set_ip_t port;
+
+ if (flags[index+1] == 0)
+ return -EINVAL;
+
+ 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",
+ NIPQUAD(skb->nh.iph->saddr),
+ NIPQUAD(skb->nh.iph->daddr));
+ DP("flag %s port %u",
+ flags[index+1] & IPSET_SRC ? "SRC" : "DST",
+ port);
+ if (port == INVALID_PORT)
+ return -EINVAL;
+
+ return __delip(set,
+ ntohl(flags[index] & IPSET_SRC
+ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
+ port,
+ hash_ip);
+}
+
+static int create(struct ip_set *set, const void *data, size_t size)
+{
+ struct ip_set_req_ipporthash_create *req =
+ (struct ip_set_req_ipporthash_create *) data;
+ struct ip_set_ipporthash *map;
+ uint16_t i;
+
+ if (size != sizeof(struct ip_set_req_ipporthash_create)) {
+ ip_set_printk("data length wrong (want %zu, have %zu)",
+ sizeof(struct ip_set_req_ipporthash_create),
+ size);
+ return -EINVAL;
+ }
+
+ if (req->hashsize < 1) {
+ ip_set_printk("hashsize too small");
+ return -ENOEXEC;
+ }
+
+ if (req->probes < 1) {
+ ip_set_printk("probes too small");
+ return -ENOEXEC;
+ }
+
+ map = kmalloc(sizeof(struct ip_set_ipporthash)
+ + req->probes * sizeof(uint32_t), GFP_KERNEL);
+ if (!map) {
+ DP("out of memory for %d bytes",
+ sizeof(struct ip_set_ipporthash)
+ + req->probes * sizeof(uint32_t));
+ return -ENOMEM;
+ }
+ for (i = 0; i < req->probes; i++)
+ get_random_bytes(((uint32_t *) map->initval)+i, 4);
+ map->hashsize = req->hashsize;
+ map->probes = req->probes;
+ map->resize = req->resize;
+ map->first_ip = req->from;
+ map->last_ip = req->to;
+ map->members = harray_malloc(map->hashsize, sizeof(ip_set_ip_t), GFP_KERNEL);
+ if (!map->members) {
+ DP("out of memory for %d bytes", map->hashsize * sizeof(ip_set_ip_t));
+ kfree(map);
+ return -ENOMEM;
+ }
+
+ set->data = map;
+ return 0;
+}
+
+static void destroy(struct ip_set *set)
+{
+ struct ip_set_ipporthash *map = (struct ip_set_ipporthash *) set->data;
+
+ harray_free(map->members);
+ kfree(map);
+
+ set->data = NULL;
+}
+
+static void flush(struct ip_set *set)
+{
+ struct ip_set_ipporthash *map = (struct ip_set_ipporthash *) set->data;
+ harray_flush(map->members, map->hashsize, sizeof(ip_set_ip_t));
+}
+
+static void list_header(const struct ip_set *set, void *data)
+{
+ struct ip_set_ipporthash *map = (struct ip_set_ipporthash *) set->data;
+ struct ip_set_req_ipporthash_create *header =
+ (struct ip_set_req_ipporthash_create *) data;
+
+ header->hashsize = map->hashsize;
+ header->probes = map->probes;
+ header->resize = map->resize;
+ header->from = map->first_ip;
+ header->to = map->last_ip;
+}
+
+static int list_members_size(const struct ip_set *set)
+{
+ struct ip_set_ipporthash *map = (struct ip_set_ipporthash *) set->data;
+
+ return (map->hashsize * sizeof(ip_set_ip_t));
+}
+
+static void list_members(const struct ip_set *set, void *data)
+{
+ struct ip_set_ipporthash *map = (struct ip_set_ipporthash *) set->data;
+ ip_set_ip_t i, *elem;
+
+ for (i = 0; i < map->hashsize; i++) {
+ elem = HARRAY_ELEM(map->members, ip_set_ip_t *, i);
+ ((ip_set_ip_t *)data)[i] = *elem;
+ }
+}
+
+static struct ip_set_type ip_set_ipporthash = {
+ .typename = SETTYPE_NAME,
+ .features = IPSET_TYPE_IP | IPSET_TYPE_PORT | IPSET_DATA_DOUBLE,
+ .protocol_version = IP_SET_PROTOCOL_VERSION,
+ .create = &create,
+ .destroy = &destroy,
+ .flush = &flush,
+ .reqsize = sizeof(struct ip_set_req_ipporthash),
+ .addip = &addip,
+ .addip_kernel = &addip_kernel,
+ .retry = &retry,
+ .delip = &delip,
+ .delip_kernel = &delip_kernel,
+ .testip = &testip,
+ .testip_kernel = &testip_kernel,
+ .header_size = sizeof(struct ip_set_req_ipporthash_create),
+ .list_header = &list_header,
+ .list_members_size = &list_members_size,
+ .list_members = &list_members,
+ .me = THIS_MODULE,
+};
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jozsef Kadlecsik <kadlec at blackhole.kfki.hu>");
+MODULE_DESCRIPTION("ipporthash type of IP sets");
+
+static int __init init(void)
+{
+ return ip_set_register_set_type(&ip_set_ipporthash);
+}
+
+static void __exit fini(void)
+{
+ /* FIXME: possible race with ip_set_create() */
+ ip_set_unregister_set_type(&ip_set_ipporthash);
+}
+
+module_init(init);
+module_exit(fini);
Modified: trunk/patch-o-matic-ng/patchlets/set/linux-2.6/net/ipv4/netfilter/ip_set_iptree.c
===================================================================
--- trunk/patch-o-matic-ng/patchlets/set/linux-2.6/net/ipv4/netfilter/ip_set_iptree.c 2005-10-12 12:12:20 UTC (rev 4351)
+++ trunk/patch-o-matic-ng/patchlets/set/linux-2.6/net/ipv4/netfilter/ip_set_iptree.c 2005-10-13 08:53:58 UTC (rev 4352)
@@ -24,7 +24,7 @@
/* Garbage collection interval in seconds: */
#define IPTREE_GC_TIME 5*60
/* Sleep so many milliseconds before trying again
- * to delete the gc timer at destroying a set */
+ * to delete the gc timer at destroying/flushing a set */
#define IPTREE_DESTROY_SLEEP 100
static kmem_cache_t *branch_cachep;
@@ -83,30 +83,32 @@
static int
testip_kernel(struct ip_set *set,
const struct sk_buff *skb,
- u_int32_t flags,
- ip_set_ip_t *hash_ip)
+ ip_set_ip_t *hash_ip,
+ const u_int32_t *flags,
+ unsigned char index)
{
int res;
DP("flag: %s src: %u.%u.%u.%u dst: %u.%u.%u.%u",
- flags & IPSET_SRC ? "SRC" : "DST",
+ flags[index] & IPSET_SRC ? "SRC" : "DST",
NIPQUAD(skb->nh.iph->saddr),
NIPQUAD(skb->nh.iph->daddr));
res = __testip(set,
- ntohl(flags & IPSET_SRC ? skb->nh.iph->saddr
- : skb->nh.iph->daddr),
+ ntohl(flags[index] & IPSET_SRC
+ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
hash_ip);
return (res < 0 ? 0 : res);
}
-#define ADDIP_WALK(map, elem, branch, type, cachep) do { \
+#define ADDIP_WALK(map, elem, branch, type, cachep, flags) do { \
if ((map)->tree[elem]) { \
DP("found %u", elem); \
branch = (map)->tree[elem]; \
} else { \
branch = (type *) \
- kmem_cache_alloc(cachep, GFP_KERNEL); \
+ kmem_cache_alloc(cachep, flags); \
if (branch == NULL) \
return -ENOMEM; \
memset(branch, 0, sizeof(*branch)); \
@@ -117,7 +119,8 @@
static inline int
__addip(struct ip_set *set, ip_set_ip_t ip, unsigned int timeout,
- ip_set_ip_t *hash_ip)
+ ip_set_ip_t *hash_ip,
+ unsigned int __nocast flags)
{
struct ip_set_iptree *map = (struct ip_set_iptree *) set->data;
struct ip_set_iptreeb *btree;
@@ -129,9 +132,9 @@
*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);
- ADDIP_WALK(btree, b, ctree, struct ip_set_iptreec, branch_cachep);
- ADDIP_WALK(ctree, c, dtree, struct ip_set_iptreed, leaf_cachep);
+ 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);
if (dtree->expires[d]
&& (!map->timeout || time_after(dtree->expires[d], jiffies)))
ret = -EEXIST;
@@ -157,20 +160,26 @@
DP("%u.%u.%u.%u %u", HIPQUAD(req->ip), req->timeout);
return __addip(set, req->ip,
req->timeout ? req->timeout : map->timeout,
- hash_ip);
+ hash_ip,
+ GFP_KERNEL);
}
static int
-addip_kernel(struct ip_set *set, const struct sk_buff *skb,
- u_int32_t flags, ip_set_ip_t *hash_ip)
+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)
{
struct ip_set_iptree *map = (struct ip_set_iptree *) set->data;
return __addip(set,
- ntohl(flags & IPSET_SRC ? skb->nh.iph->saddr
- : skb->nh.iph->daddr),
+ ntohl(flags[index] & IPSET_SRC
+ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
map->timeout,
- hash_ip);
+ hash_ip,
+ GFP_ATOMIC);
}
#define DELIP_WALK(map, elem, branch) do { \
@@ -219,12 +228,16 @@
}
static int
-delip_kernel(struct ip_set *set, const struct sk_buff *skb,
- u_int32_t flags, ip_set_ip_t *hash_ip)
+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(set,
- ntohl(flags & IPSET_SRC ? skb->nh.iph->saddr
- : skb->nh.iph->daddr),
+ ntohl(flags[index] & IPSET_SRC
+ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
hash_ip);
}
@@ -305,6 +318,21 @@
add_timer(&map->gc);
}
+static inline void init_gc_timer(struct ip_set *set)
+{
+ struct ip_set_iptree *map = (struct ip_set_iptree *) set->data;
+
+ /* Even if there is no timeout for the entries,
+ * we still have to call gc because delete
+ * do not clean up empty branches */
+ map->gc_interval = IPTREE_GC_TIME;
+ init_timer(&map->gc);
+ map->gc.data = (unsigned long) set;
+ map->gc.function = ip_tree_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_iptree_create *req =
@@ -328,16 +356,8 @@
map->timeout = req->timeout;
set->data = map;
- /* If there is no timeout for the entries,
- * we still have to call gc because delete
- * do not clean up empty branches */
- map->gc_interval = IPTREE_GC_TIME;
- init_timer(&map->gc);
- map->gc.data = (unsigned long) set;
- map->gc.function = ip_tree_gc;
- map->gc.expires = jiffies + map->gc_interval * HZ;
- add_timer(&map->gc);
-
+ init_gc_timer(set);
+
return 0;
}
@@ -363,6 +383,7 @@
{
struct ip_set_iptree *map = (struct ip_set_iptree *) set->data;
+ /* gc might be running */
while (!del_timer(&map->gc))
msleep(IPTREE_DESTROY_SLEEP);
__flush(map);
@@ -375,9 +396,14 @@
struct ip_set_iptree *map = (struct ip_set_iptree *) set->data;
unsigned int timeout = map->timeout;
+ /* gc might be running */
+ while (!del_timer(&map->gc))
+ msleep(IPTREE_DESTROY_SLEEP);
__flush(map);
memset(map, 0, sizeof(*map));
map->timeout = timeout;
+
+ init_gc_timer(set);
}
static void list_header(const struct ip_set *set, void *data)
@@ -444,7 +470,7 @@
static struct ip_set_type ip_set_iptree = {
.typename = SETTYPE_NAME,
- .typecode = IPSET_TYPE_IP,
+ .features = IPSET_TYPE_IP | IPSET_DATA_SINGLE,
.protocol_version = IP_SET_PROTOCOL_VERSION,
.create = &create,
.destroy = &destroy,
Modified: trunk/patch-o-matic-ng/patchlets/set/linux-2.6/net/ipv4/netfilter/ip_set_macipmap.c
===================================================================
--- trunk/patch-o-matic-ng/patchlets/set/linux-2.6/net/ipv4/netfilter/ip_set_macipmap.c 2005-10-12 12:12:20 UTC (rev 4351)
+++ trunk/patch-o-matic-ng/patchlets/set/linux-2.6/net/ipv4/netfilter/ip_set_macipmap.c 2005-10-13 08:53:58 UTC (rev 4352)
@@ -56,8 +56,11 @@
}
static int
-testip_kernel(struct ip_set *set, const struct sk_buff *skb,
- u_int32_t flags, ip_set_ip_t *hash_ip)
+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)
{
struct ip_set_macipmap *map =
(struct ip_set_macipmap *) set->data;
@@ -65,10 +68,11 @@
(struct ip_set_macip *) map->members;
ip_set_ip_t ip;
- ip = ntohl(flags & IPSET_SRC ? skb->nh.iph->saddr
- : skb->nh.iph->daddr);
+ ip = ntohl(flags[index] & IPSET_SRC
+ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr);
DP("flag: %s src: %u.%u.%u.%u dst: %u.%u.%u.%u",
- flags & IPSET_SRC ? "SRC" : "DST",
+ flags[index] & IPSET_SRC ? "SRC" : "DST",
NIPQUAD(skb->nh.iph->saddr),
NIPQUAD(skb->nh.iph->daddr));
@@ -131,13 +135,17 @@
}
static int
-addip_kernel(struct ip_set *set, const struct sk_buff *skb,
- u_int32_t flags, ip_set_ip_t *hash_ip)
+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)
{
ip_set_ip_t ip;
- ip = ntohl(flags & IPSET_SRC ? skb->nh.iph->saddr
- : skb->nh.iph->daddr);
+ ip = ntohl(flags[index] & IPSET_SRC
+ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr);
if (!(skb->mac.raw >= skb->head
&& (skb->mac.raw + ETH_HLEN) <= skb->data))
@@ -182,12 +190,16 @@
}
static int
-delip_kernel(struct ip_set *set, const struct sk_buff *skb,
- u_int32_t flags, ip_set_ip_t *hash_ip)
+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(set,
- ntohl(flags & IPSET_SRC ? skb->nh.iph->saddr
- : skb->nh.iph->daddr),
+ ntohl(flags[index] & IPSET_SRC
+ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
hash_ip);
}
@@ -302,7 +314,7 @@
static struct ip_set_type ip_set_macipmap = {
.typename = SETTYPE_NAME,
- .typecode = IPSET_TYPE_IP,
+ .features = IPSET_TYPE_IP | IPSET_DATA_SINGLE,
.protocol_version = IP_SET_PROTOCOL_VERSION,
.create = &create,
.destroy = &destroy,
Modified: trunk/patch-o-matic-ng/patchlets/set/linux-2.6/net/ipv4/netfilter/ip_set_nethash.c
===================================================================
--- trunk/patch-o-matic-ng/patchlets/set/linux-2.6/net/ipv4/netfilter/ip_set_nethash.c 2005-10-12 12:12:20 UTC (rev 4351)
+++ trunk/patch-o-matic-ng/patchlets/set/linux-2.6/net/ipv4/netfilter/ip_set_nethash.c 2005-10-13 08:53:58 UTC (rev 4352)
@@ -101,12 +101,16 @@
}
static int
-testip_kernel(struct ip_set *set, const struct sk_buff *skb,
- u_int32_t flags, ip_set_ip_t *hash_ip)
+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)
{
return __testip(set,
- ntohl(flags & IPSET_SRC ? skb->nh.iph->saddr
- : skb->nh.iph->daddr),
+ ntohl(flags[index] & IPSET_SRC
+ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr),
hash_ip);
}
@@ -185,13 +189,17 @@
}
static int
-addip_kernel(struct ip_set *set, const struct sk_buff *skb,
- u_int32_t flags, ip_set_ip_t *hash_ip)
+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)
{
struct ip_set_nethash *map = (struct ip_set_nethash *) set->data;
int ret = -ERANGE;
- ip_set_ip_t ip = ntohl(flags & IPSET_SRC ? skb->nh.iph->saddr
- : skb->nh.iph->daddr);
+ ip_set_ip_t ip = ntohl(flags[index] & IPSET_SRC
+ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr);
if (map->cidr[0])
ret = __addip(map, ip, map->cidr[0], hash_ip);
@@ -305,13 +313,17 @@
}
static int
-delip_kernel(struct ip_set *set, const struct sk_buff *skb,
- u_int32_t flags, ip_set_ip_t *hash_ip)
+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)
{
struct ip_set_nethash *map = (struct ip_set_nethash *) set->data;
int ret = -ERANGE;
- ip_set_ip_t ip = ntohl(flags & IPSET_SRC ? skb->nh.iph->saddr
- : skb->nh.iph->daddr);
+ ip_set_ip_t ip = ntohl(flags[index] & IPSET_SRC
+ ? skb->nh.iph->saddr
+ : skb->nh.iph->daddr);
if (map->cidr[0])
ret = __delip(map, ip, map->cidr[0], hash_ip);
@@ -415,7 +427,7 @@
static struct ip_set_type ip_set_nethash = {
.typename = SETTYPE_NAME,
- .typecode = IPSET_TYPE_IP,
+ .features = IPSET_TYPE_IP | IPSET_DATA_SINGLE,
.protocol_version = IP_SET_PROTOCOL_VERSION,
.create = &create,
.destroy = &destroy,
Modified: trunk/patch-o-matic-ng/patchlets/set/linux-2.6/net/ipv4/netfilter/ip_set_portmap.c
===================================================================
--- trunk/patch-o-matic-ng/patchlets/set/linux-2.6/net/ipv4/netfilter/ip_set_portmap.c 2005-10-12 12:12:20 UTC (rev 4351)
+++ trunk/patch-o-matic-ng/patchlets/set/linux-2.6/net/ipv4/netfilter/ip_set_portmap.c 2005-10-13 08:53:58 UTC (rev 4352)
@@ -93,13 +93,16 @@
}
static int
-testport_kernel(struct ip_set *set, const struct sk_buff *skb,
- u_int32_t flags, ip_set_ip_t *hash_port)
+testport_kernel(struct ip_set *set,
+ const struct sk_buff *skb,
+ ip_set_ip_t *hash_port,
+ const u_int32_t *flags,
+ unsigned char index)
{
int res;
- ip_set_ip_t port = get_port(skb, flags);
+ ip_set_ip_t port = get_port(skb, flags[index]);
- DP("flag %s port %u", flags & IPSET_SRC ? "SRC" : "DST", port);
+ DP("flag %s port %u", flags[index] & IPSET_SRC ? "SRC" : "DST", port);
if (port == INVALID_PORT)
return 0;
@@ -140,10 +143,13 @@
}
static int
-addport_kernel(struct ip_set *set, const struct sk_buff *skb,
- u_int32_t flags, ip_set_ip_t *hash_port)
+addport_kernel(struct ip_set *set,
+ const struct sk_buff *skb,
+ ip_set_ip_t *hash_port,
+ const u_int32_t *flags,
+ unsigned char index)
{
- ip_set_ip_t port = get_port(skb, flags);
+ ip_set_ip_t port = get_port(skb, flags[index]);
if (port == INVALID_PORT)
return -EINVAL;
@@ -183,10 +189,13 @@
}
static int
-delport_kernel(struct ip_set *set, const struct sk_buff *skb,
- u_int32_t flags, ip_set_ip_t *hash_port)
+delport_kernel(struct ip_set *set,
+ const struct sk_buff *skb,
+ ip_set_ip_t *hash_port,
+ const u_int32_t *flags,
+ unsigned char index)
{
- ip_set_ip_t port = get_port(skb, flags);
+ ip_set_ip_t port = get_port(skb, flags[index]);
if (port == INVALID_PORT)
return -EINVAL;
@@ -287,7 +296,7 @@
static struct ip_set_type ip_set_portmap = {
.typename = SETTYPE_NAME,
- .typecode = IPSET_TYPE_PORT,
+ .features = IPSET_TYPE_PORT | IPSET_DATA_SINGLE,
.protocol_version = IP_SET_PROTOCOL_VERSION,
.create = &create,
.destroy = &destroy,
More information about the netfilter-cvslog
mailing list