summaryrefslogtreecommitdiffstats
path: root/kernel/ip_set_iptree.c
diff options
context:
space:
mode:
author/C=EU/ST=EU/CN=Jozsef Kadlecsik/emailAddress=kadlec@blackhole.kfki.hu </C=EU/ST=EU/CN=Jozsef Kadlecsik/emailAddress=kadlec@blackhole.kfki.hu>2008-10-20 10:00:26 +0000
committer/C=EU/ST=EU/CN=Jozsef Kadlecsik/emailAddress=kadlec@blackhole.kfki.hu </C=EU/ST=EU/CN=Jozsef Kadlecsik/emailAddress=kadlec@blackhole.kfki.hu>2008-10-20 10:00:26 +0000
commita96e4fca10506462df4ee4035f0f86f09bd9dc34 (patch)
tree103bed0a7ae3608675f371d2ac91f3fa7f3a58cc /kernel/ip_set_iptree.c
parentbc2ddd2d8da1252e78a1f25bd91c1e3cd8016ead (diff)
ipset 2.4 release
userspace changes: - Added KBUILD_OUTPUT support (Sven Wegener) - Fix memory leak in ipset_iptreemap (Sven Wegener) - Fix multiple compiler warnings (Sven Wegener) - ipportiphash, ipportnethash and setlist types added - binding marked as deprecated functionality - element separator token changed to ',' in anticipating IPv6 addresses, old separator tokens are still supported - unnecessary includes removed - ipset does not try to resolve IP addresses when listing the content of sets (default changed) - manpage updated - ChangeLog forked for kernel part kernel part changes: - ipportiphash, ipportnethash and setlist types added - set type modules reworked to avoid code duplication as much as possible, code unification macros - expand_macros Makefile target added to help debugging code unification macros - ip_set_addip_kernel and ip_set_delip_kernel changed from void to int, __ip_set_get_byname and __ip_set_put_byid added for the sake of setlist type - unnecessary includes removed - compatibility fix for kernels >= 2.6.27: semaphore.h was moved from asm/ to linux/ (James King) - ChangeLog forked for kernel part
Diffstat (limited to 'kernel/ip_set_iptree.c')
-rw-r--r--kernel/ip_set_iptree.c170
1 files changed, 35 insertions, 135 deletions
diff --git a/kernel/ip_set_iptree.c b/kernel/ip_set_iptree.c
index 2e0a406..22a94d1 100644
--- a/kernel/ip_set_iptree.c
+++ b/kernel/ip_set_iptree.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
+/* Copyright (C) 2005-2008 Jozsef Kadlecsik <kadlec@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
@@ -7,20 +7,19 @@
/* Kernel module implementing an IP set type: the iptree type */
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/ip.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/delay.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/netfilter_ipv4/ip_set.h>
+#include <linux/netfilter_ipv4/ip_set_bitmaps.h>
#include <linux/netfilter_ipv4/ip_set_iptree.h>
static int limit = MAX_RANGE;
@@ -61,7 +60,7 @@ static __KMEM_CACHE_T__ *leaf_cachep;
} while (0)
static inline int
-__testip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip)
+iptree_test(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
{
struct ip_set_iptree *map = set->data;
struct ip_set_iptreeb *btree;
@@ -84,42 +83,10 @@ __testip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip)
|| time_after(dtree->expires[d], jiffies));
}
-static int
-testip(struct ip_set *set, const void *data, size_t size,
- ip_set_ip_t *hash_ip)
-{
- const struct ip_set_req_iptree *req = data;
+#define KADT_CONDITION
- if (size != sizeof(struct ip_set_req_iptree)) {
- ip_set_printk("data length wrong (want %zu, have %zu)",
- sizeof(struct ip_set_req_iptree),
- size);
- return -EINVAL;
- }
- return __testip(set, req->ip, hash_ip);
-}
-
-static int
-testip_kernel(struct ip_set *set,
- const struct sk_buff *skb,
- ip_set_ip_t *hash_ip,
- const u_int32_t *flags,
- unsigned char index)
-{
- int res;
-
- DP("flag: %s src: %u.%u.%u.%u dst: %u.%u.%u.%u",
- flags[index] & IPSET_SRC ? "SRC" : "DST",
- NIPQUAD(ip_hdr(skb)->saddr),
- NIPQUAD(ip_hdr(skb)->daddr));
-
- res = __testip(set,
- ntohl(flags[index] & IPSET_SRC
- ? ip_hdr(skb)->saddr
- : ip_hdr(skb)->daddr),
- hash_ip);
- return (res < 0 ? 0 : res);
-}
+UADT(iptree, test)
+KADT(iptree, test, ipaddr)
#define ADDIP_WALK(map, elem, branch, type, cachep) do { \
if ((map)->tree[elem]) { \
@@ -137,8 +104,8 @@ testip_kernel(struct ip_set *set,
} while (0)
static inline int
-__addip(struct ip_set *set, ip_set_ip_t ip, unsigned int timeout,
- ip_set_ip_t *hash_ip)
+iptree_add(struct ip_set *set, ip_set_ip_t *hash_ip,
+ ip_set_ip_t ip, unsigned int timeout)
{
struct ip_set_iptree *map = set->data;
struct ip_set_iptreeb *btree;
@@ -161,6 +128,8 @@ __addip(struct ip_set *set, ip_set_ip_t ip, unsigned int timeout,
if (dtree->expires[d]
&& (!map->timeout || time_after(dtree->expires[d], jiffies)))
ret = -EEXIST;
+ if (map->timeout && timeout == 0)
+ timeout = map->timeout;
dtree->expires[d] = map->timeout ? (timeout * HZ + jiffies) : 1;
/* Lottery: I won! */
if (dtree->expires[d] == 0)
@@ -171,41 +140,8 @@ __addip(struct ip_set *set, ip_set_ip_t ip, unsigned int timeout,
return ret;
}
-static int
-addip(struct ip_set *set, const void *data, size_t size,
- ip_set_ip_t *hash_ip)
-{
- struct ip_set_iptree *map = set->data;
- const struct ip_set_req_iptree *req = data;
-
- if (size != sizeof(struct ip_set_req_iptree)) {
- ip_set_printk("data length wrong (want %zu, have %zu)",
- sizeof(struct ip_set_req_iptree),
- size);
- return -EINVAL;
- }
- DP("%u.%u.%u.%u %u", HIPQUAD(req->ip), req->timeout);
- return __addip(set, req->ip,
- req->timeout ? req->timeout : map->timeout,
- 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)
-{
- struct ip_set_iptree *map = set->data;
-
- return __addip(set,
- ntohl(flags[index] & IPSET_SRC
- ? ip_hdr(skb)->saddr
- : ip_hdr(skb)->daddr),
- map->timeout,
- hash_ip);
-}
+UADT(iptree, add, req->timeout)
+KADT(iptree, add, ipaddr, 0)
#define DELIP_WALK(map, elem, branch) do { \
if ((map)->tree[elem]) { \
@@ -215,7 +151,7 @@ addip_kernel(struct ip_set *set,
} while (0)
static inline int
-__delip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip)
+iptree_del(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
{
struct ip_set_iptree *map = set->data;
struct ip_set_iptreeb *btree;
@@ -240,34 +176,8 @@ __delip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip)
return -EEXIST;
}
-static int
-delip(struct ip_set *set, const void *data, size_t size,
- ip_set_ip_t *hash_ip)
-{
- const struct ip_set_req_iptree *req = data;
-
- if (size != sizeof(struct ip_set_req_iptree)) {
- ip_set_printk("data length wrong (want %zu, have %zu)",
- sizeof(struct ip_set_req_iptree),
- size);
- return -EINVAL;
- }
- return __delip(set, req->ip, 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)
-{
- return __delip(set,
- ntohl(flags[index] & IPSET_SRC
- ? ip_hdr(skb)->saddr
- : ip_hdr(skb)->daddr),
- hash_ip);
-}
+UADT(iptree, del)
+KADT(iptree, del, ipaddr)
#define LOOP_WALK_BEGIN(map, i, branch) \
for (i = 0; i < 256; i++) { \
@@ -277,7 +187,8 @@ delip_kernel(struct ip_set *set,
#define LOOP_WALK_END }
-static void ip_tree_gc(unsigned long ul_set)
+static void
+ip_tree_gc(unsigned long ul_set)
{
struct ip_set *set = (struct ip_set *) ul_set;
struct ip_set_iptree *map = set->data;
@@ -347,7 +258,8 @@ static void ip_tree_gc(unsigned long ul_set)
add_timer(&map->gc);
}
-static inline void init_gc_timer(struct ip_set *set)
+static inline void
+init_gc_timer(struct ip_set *set)
{
struct ip_set_iptree *map = set->data;
@@ -362,7 +274,8 @@ static inline void init_gc_timer(struct ip_set *set)
add_timer(&map->gc);
}
-static int create(struct ip_set *set, const void *data, size_t size)
+static int
+iptree_create(struct ip_set *set, const void *data, size_t size)
{
const struct ip_set_req_iptree_create *req = data;
struct ip_set_iptree *map;
@@ -390,7 +303,8 @@ static int create(struct ip_set *set, const void *data, size_t size)
return 0;
}
-static void __flush(struct ip_set_iptree *map)
+static inline void
+__flush(struct ip_set_iptree *map)
{
struct ip_set_iptreeb *btree;
struct ip_set_iptreec *ctree;
@@ -409,7 +323,8 @@ static void __flush(struct ip_set_iptree *map)
map->elements = 0;
}
-static void destroy(struct ip_set *set)
+static void
+iptree_destroy(struct ip_set *set)
{
struct ip_set_iptree *map = set->data;
@@ -421,7 +336,8 @@ static void destroy(struct ip_set *set)
set->data = NULL;
}
-static void flush(struct ip_set *set)
+static void
+iptree_flush(struct ip_set *set)
{
struct ip_set_iptree *map = set->data;
unsigned int timeout = map->timeout;
@@ -436,7 +352,8 @@ static void flush(struct ip_set *set)
init_gc_timer(set);
}
-static void list_header(const struct ip_set *set, void *data)
+static void
+iptree_list_header(const struct ip_set *set, void *data)
{
const struct ip_set_iptree *map = set->data;
struct ip_set_req_iptree_create *header = data;
@@ -444,7 +361,8 @@ static void list_header(const struct ip_set *set, void *data)
header->timeout = map->timeout;
}
-static int list_members_size(const struct ip_set *set)
+static int
+iptree_list_members_size(const struct ip_set *set)
{
const struct ip_set_iptree *map = set->data;
struct ip_set_iptreeb *btree;
@@ -469,7 +387,8 @@ static int list_members_size(const struct ip_set *set)
return (count * sizeof(struct ip_set_req_iptree));
}
-static void list_members(const struct ip_set *set, void *data)
+static void
+iptree_list_members(const struct ip_set *set, void *data)
{
const struct ip_set_iptree *map = set->data;
struct ip_set_iptreeb *btree;
@@ -497,26 +416,7 @@ static void list_members(const struct ip_set *set, void *data)
LOOP_WALK_END;
}
-static struct ip_set_type ip_set_iptree = {
- .typename = SETTYPE_NAME,
- .features = IPSET_TYPE_IP | IPSET_DATA_SINGLE,
- .protocol_version = IP_SET_PROTOCOL_VERSION,
- .create = &create,
- .destroy = &destroy,
- .flush = &flush,
- .reqsize = sizeof(struct ip_set_req_iptree),
- .addip = &addip,
- .addip_kernel = &addip_kernel,
- .delip = &delip,
- .delip_kernel = &delip_kernel,
- .testip = &testip,
- .testip_kernel = &testip_kernel,
- .header_size = sizeof(struct ip_set_req_iptree_create),
- .list_header = &list_header,
- .list_members_size = &list_members_size,
- .list_members = &list_members,
- .me = THIS_MODULE,
-};
+IP_SET_TYPE(iptree, IPSET_TYPE_IP | IPSET_DATA_SINGLE)
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");