X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fipv4%2Fnetfilter%2Fip_set_iptree.c;h=bc4934e261fba1aca511d381c9b5ddc11494d8e4;hb=bd5a19dd4af64aaf2a1cc38033a2bd21a093a497;hp=0d195e32720e71885688332dbefd0e74bf28cc6b;hpb=cee37fe97739d85991964371c1f3a745c00dd236;p=linux-2.6.git diff --git a/net/ipv4/netfilter/ip_set_iptree.c b/net/ipv4/netfilter/ip_set_iptree.c index 0d195e327..bc4934e26 100644 --- a/net/ipv4/netfilter/ip_set_iptree.c +++ b/net/ipv4/netfilter/ip_set_iptree.c @@ -26,6 +26,8 @@ #include +static int limit = MAX_RANGE; + /* Garbage collection interval in seconds: */ #define IPTREE_GC_TIME 5*60 /* Sleep so many milliseconds before trying again @@ -57,6 +59,9 @@ __testip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip) struct ip_set_iptreec *ctree; struct ip_set_iptreed *dtree; unsigned char a,b,c,d; + + if (!ip) + return -ERANGE; *hash_ip = ip; ABCD(a, b, c, d, hash_ip); @@ -134,6 +139,11 @@ __addip(struct ip_set *set, ip_set_ip_t ip, unsigned int timeout, unsigned char a,b,c,d; int ret = 0; + if (!ip || map->elements > limit) + /* We could call the garbage collector + * but it's probably overkill */ + return -ERANGE; + *hash_ip = ip; ABCD(a, b, c, d, hash_ip); DP("%u %u %u %u timeout %u", a, b, c, d, timeout); @@ -148,6 +158,8 @@ __addip(struct ip_set *set, ip_set_ip_t ip, unsigned int timeout, if (dtree->expires[d] == 0) dtree->expires[d] = 1; DP("%u %lu", d, dtree->expires[d]); + if (ret == 0) + map->elements++; return ret; } @@ -206,6 +218,9 @@ __delip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip) struct ip_set_iptreed *dtree; unsigned char a,b,c,d; + if (!ip) + return -ERANGE; + *hash_ip = ip; ABCD(a, b, c, d, hash_ip); DELIP_WALK(map, a, btree); @@ -214,6 +229,7 @@ __delip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip) if (dtree->expires[d]) { dtree->expires[d] = 0; + map->elements--; return 0; } return -EEXIST; @@ -279,9 +295,10 @@ static void ip_tree_gc(unsigned long ul_set) a, b, c, d, dtree->expires[d], jiffies); if (map->timeout - && time_before(dtree->expires[d], jiffies)) + && time_before(dtree->expires[d], jiffies)) { dtree->expires[d] = 0; - else + map->elements--; + } else k = 1; } } @@ -362,6 +379,7 @@ static int create(struct ip_set *set, const void *data, size_t size) } memset(map, 0, sizeof(*map)); map->timeout = req->timeout; + map->elements = 0; set->data = map; init_gc_timer(set); @@ -385,6 +403,7 @@ static void __flush(struct ip_set_iptree *map) LOOP_WALK_END; kmem_cache_free(branch_cachep, btree); LOOP_WALK_END; + map->elements = 0; } static void destroy(struct ip_set *set) @@ -500,6 +519,8 @@ static struct ip_set_type ip_set_iptree = { MODULE_LICENSE("GPL"); MODULE_AUTHOR("Jozsef Kadlecsik "); MODULE_DESCRIPTION("iptree type of IP sets"); +module_param(limit, int, 0600); +MODULE_PARM_DESC(limit, "maximal number of elements stored in the sets"); static int __init init(void) {