From 633b62df0104203591d5c427f6769857571b2540 Mon Sep 17 00:00:00 2001 From: "/C=EU/ST=EU/CN=Jozsef Kadlecsik/emailAddress=kadlec@blackhole.kfki.hu" Date: Wed, 2 Jul 2008 12:20:18 +0000 Subject: Initial ipset release with kernel modules included. --- .../include/linux/netfilter_ipv4/ip_set_malloc.h | 143 +++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 kernel/include/linux/netfilter_ipv4/ip_set_malloc.h (limited to 'kernel/include/linux/netfilter_ipv4/ip_set_malloc.h') diff --git a/kernel/include/linux/netfilter_ipv4/ip_set_malloc.h b/kernel/include/linux/netfilter_ipv4/ip_set_malloc.h new file mode 100644 index 0000000..30701f4 --- /dev/null +++ b/kernel/include/linux/netfilter_ipv4/ip_set_malloc.h @@ -0,0 +1,143 @@ +#ifndef _IP_SET_MALLOC_H +#define _IP_SET_MALLOC_H + +#ifdef __KERNEL__ + +static size_t max_malloc_size = 0, max_page_size = 0; + +static inline bool init_max_page_size(void) +{ + size_t page_size = 0; + +#define CACHE(x) if (max_page_size == 0 || x < max_page_size) \ + page_size = x; +#include +#undef CACHE + if (page_size) { + if (max_malloc_size == 0) + max_malloc_size = page_size; + + max_page_size = page_size; + + return 1; + } + return 0; +} + +struct harray { + size_t max_elements; + void *arrays[0]; +}; + +static inline void * +__harray_malloc(size_t hashsize, size_t typesize, int flags) +{ + struct harray *harray; + size_t max_elements, size, i, j; + + BUG_ON(max_page_size == 0); + + if (typesize > max_page_size) + return NULL; + + max_elements = max_page_size/typesize; + size = hashsize/max_elements; + if (hashsize % max_elements) + size++; + + /* Last pointer signals end of arrays */ + harray = kmalloc(sizeof(struct harray) + (size + 1) * sizeof(void *), + flags); + + if (!harray) + return NULL; + + for (i = 0; i < size - 1; i++) { + harray->arrays[i] = kmalloc(max_elements * typesize, flags); + if (!harray->arrays[i]) + goto undo; + memset(harray->arrays[i], 0, max_elements * 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_elements) * typesize); + + harray->max_elements = max_elements; + harray->arrays[size] = NULL; + + return (void *)harray; + + undo: + for (j = 0; j < i; j++) { + kfree(harray->arrays[j]); + } + kfree(harray); + return NULL; +} + +static inline void * +harray_malloc(size_t hashsize, size_t typesize, int flags) +{ + void *harray; + + do { + harray = __harray_malloc(hashsize, typesize, flags|__GFP_NOWARN); + } while (harray == NULL && init_max_page_size()); + + return harray; +} + +static inline void harray_free(void *h) +{ + struct harray *harray = (struct harray *) h; + size_t i; + + for (i = 0; harray->arrays[i] != NULL; i++) + kfree(harray->arrays[i]); + kfree(harray); +} + +static inline void harray_flush(void *h, size_t hashsize, size_t typesize) +{ + struct harray *harray = (struct harray *) h; + size_t i; + + for (i = 0; harray->arrays[i+1] != NULL; i++) + memset(harray->arrays[i], 0, harray->max_elements * typesize); + memset(harray->arrays[i], 0, + (hashsize - i * harray->max_elements) * typesize); +} + +#define HARRAY_ELEM(h, type, which) \ +({ \ + struct harray *__h = (struct harray *)(h); \ + ((type)((__h)->arrays[(which)/(__h)->max_elements]) \ + + (which)%(__h)->max_elements); \ +}) + +/* General memory allocation and deallocation */ +static inline void * ip_set_malloc(size_t bytes) +{ + BUG_ON(max_malloc_size == 0); + + if (bytes > max_malloc_size) + return vmalloc(bytes); + else + return kmalloc(bytes, GFP_KERNEL | __GFP_NOWARN); +} + +static inline void ip_set_free(void * data, size_t bytes) +{ + BUG_ON(max_malloc_size == 0); + + if (bytes > max_malloc_size) + vfree(data); + else + kfree(data); +} + +#endif /* __KERNEL__ */ + +#endif /*_IP_SET_MALLOC_H*/ -- cgit v1.2.3