summaryrefslogtreecommitdiffstats
path: root/kernel/include
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/include
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/include')
-rw-r--r--kernel/include/linux/netfilter_ipv4/ip_set.h86
-rw-r--r--kernel/include/linux/netfilter_ipv4/ip_set_bitmaps.h119
-rw-r--r--kernel/include/linux/netfilter_ipv4/ip_set_getport.h48
-rw-r--r--kernel/include/linux/netfilter_ipv4/ip_set_hashes.h300
-rw-r--r--kernel/include/linux/netfilter_ipv4/ip_set_iphash.h3
-rw-r--r--kernel/include/linux/netfilter_ipv4/ip_set_ipmap.h6
-rw-r--r--kernel/include/linux/netfilter_ipv4/ip_set_ipporthash.h4
-rw-r--r--kernel/include/linux/netfilter_ipv4/ip_set_ipportiphash.h38
-rw-r--r--kernel/include/linux/netfilter_ipv4/ip_set_ipportnethash.h41
-rw-r--r--kernel/include/linux/netfilter_ipv4/ip_set_iptree.h1
-rw-r--r--kernel/include/linux/netfilter_ipv4/ip_set_iptreemap.h2
-rw-r--r--kernel/include/linux/netfilter_ipv4/ip_set_macipmap.h2
-rw-r--r--kernel/include/linux/netfilter_ipv4/ip_set_malloc.h8
-rw-r--r--kernel/include/linux/netfilter_ipv4/ip_set_nethash.h33
-rw-r--r--kernel/include/linux/netfilter_ipv4/ip_set_portmap.h9
-rw-r--r--kernel/include/linux/netfilter_ipv4/ip_set_setlist.h26
16 files changed, 672 insertions, 54 deletions
diff --git a/kernel/include/linux/netfilter_ipv4/ip_set.h b/kernel/include/linux/netfilter_ipv4/ip_set.h
index b8c7202..c29a460 100644
--- a/kernel/include/linux/netfilter_ipv4/ip_set.h
+++ b/kernel/include/linux/netfilter_ipv4/ip_set.h
@@ -87,6 +87,9 @@ typedef uint16_t ip_set_id_t;
#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 */
+#define IPSET_DATA_TRIPLE 0x10 /* Triple data storage */
+#define IPSET_TYPE_IP1 0x20 /* IP address type of set */
+#define IPSET_TYPE_SETNAME 0x40 /* setname type of set */
/* Reserved keywords */
#define IPSET_TOKEN_DEFAULT ":default:"
@@ -296,8 +299,12 @@ static inline int bitmap_bytes(ip_set_ip_t a, ip_set_ip_t b)
return 4 * ((((b - a + 8) / 8) + 3) / 4);
}
+/* General limit for the elements in a set */
+#define MAX_RANGE 0x0000FFFF
+
#ifdef __KERNEL__
#include <linux/netfilter_ipv4/ip_set_compat.h>
+#include <linux/netfilter_ipv4/ip_set_malloc.h>
#define ip_set_printk(format, args...) \
do { \
@@ -482,18 +489,85 @@ struct ip_set_hash {
extern ip_set_id_t ip_set_get_byname(const char name[IP_SET_MAXNAMELEN]);
extern ip_set_id_t ip_set_get_byindex(ip_set_id_t id);
extern void ip_set_put(ip_set_id_t id);
+extern ip_set_id_t __ip_set_get_byname(const char name[IP_SET_MAXNAMELEN],
+ struct ip_set **set);
+extern void __ip_set_put_byid(ip_set_id_t id);
/* API for iptables set match, and SET target */
-extern void ip_set_addip_kernel(ip_set_id_t id,
- const struct sk_buff *skb,
- const u_int32_t *flags);
-extern void ip_set_delip_kernel(ip_set_id_t id,
- const struct sk_buff *skb,
- const u_int32_t *flags);
+extern int ip_set_addip_kernel(ip_set_id_t id,
+ const struct sk_buff *skb,
+ const u_int32_t *flags);
+extern int ip_set_delip_kernel(ip_set_id_t id,
+ const struct sk_buff *skb,
+ const u_int32_t *flags);
extern int ip_set_testip_kernel(ip_set_id_t id,
const struct sk_buff *skb,
const u_int32_t *flags);
+/* Macros to generate functions */
+
+#define STRUCT(pre, type) CONCAT2(pre, type)
+#define CONCAT2(pre, type) struct pre##type
+
+#define FNAME(pre, mid, post) CONCAT3(pre, mid, post)
+#define CONCAT3(pre, mid, post) pre##mid##post
+
+#define UADT0(type, adt, args...) \
+static int \
+FNAME(type,_u,adt)(struct ip_set *set, const void *data, size_t size, \
+ ip_set_ip_t *hash_ip) \
+{ \
+ const STRUCT(ip_set_req_,type) *req = data; \
+ \
+ return FNAME(type,_,adt)(set, hash_ip , ## args); \
+}
+
+#define UADT(type, adt, args...) \
+ UADT0(type, adt, req->ip , ## args)
+
+#define KADT(type, adt, getfn, args...) \
+static int \
+FNAME(type,_k,adt)(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 = getfn(skb, flags[index]); \
+ \
+ KADT_CONDITION \
+ return FNAME(type,_,adt)(set, hash_ip, ip , ##args); \
+}
+
+#define REGISTER_MODULE(type) \
+static int __init ip_set_##type##_init(void) \
+{ \
+ init_max_page_size(); \
+ return ip_set_register_set_type(&ip_set_##type); \
+} \
+ \
+static void __exit ip_set_##type##_fini(void) \
+{ \
+ /* FIXME: possible race with ip_set_create() */ \
+ ip_set_unregister_set_type(&ip_set_##type); \
+} \
+ \
+module_init(ip_set_##type##_init); \
+module_exit(ip_set_##type##_fini);
+
+/* Common functions */
+
+static inline ip_set_ip_t
+ipaddr(const struct sk_buff *skb, u_int32_t flag)
+{
+ return ntohl(flag & IPSET_SRC ? ip_hdr(skb)->saddr : ip_hdr(skb)->daddr);
+}
+
+#define jhash_ip(map, i, ip) jhash_1word(ip, *(map->initval + i))
+
+#define pack_ip_port(map, ip, port) \
+ (port + ((ip - ((map)->first_ip)) << 16))
+
#endif /* __KERNEL__ */
#endif /*_IP_SET_H*/
diff --git a/kernel/include/linux/netfilter_ipv4/ip_set_bitmaps.h b/kernel/include/linux/netfilter_ipv4/ip_set_bitmaps.h
new file mode 100644
index 0000000..916cb80
--- /dev/null
+++ b/kernel/include/linux/netfilter_ipv4/ip_set_bitmaps.h
@@ -0,0 +1,119 @@
+#ifndef __IP_SET_BITMAPS_H
+#define __IP_SET_BITMAPS_H
+
+/* Macros to generate functions */
+
+#define BITMAP_CREATE(type) \
+static int \
+type##_create(struct ip_set *set, const void *data, size_t size) \
+{ \
+ int newbytes; \
+ const struct ip_set_req_##type##_create *req = data; \
+ struct ip_set_##type *map; \
+ \
+ if (req->from > req->to) { \
+ DP("bad range"); \
+ return -ENOEXEC; \
+ } \
+ \
+ map = kmalloc(sizeof(struct ip_set_##type), GFP_KERNEL); \
+ if (!map) { \
+ DP("out of memory for %d bytes", \
+ sizeof(struct ip_set_#type)); \
+ return -ENOMEM; \
+ } \
+ map->first_ip = req->from; \
+ map->last_ip = req->to; \
+ \
+ newbytes = __##type##_create(req, map); \
+ if (newbytes < 0) { \
+ kfree(map); \
+ return newbytes; \
+ } \
+ \
+ map->size = newbytes; \
+ map->members = ip_set_malloc(newbytes); \
+ if (!map->members) { \
+ DP("out of memory for %d bytes", newbytes); \
+ kfree(map); \
+ return -ENOMEM; \
+ } \
+ memset(map->members, 0, newbytes); \
+ \
+ set->data = map; \
+ return 0; \
+}
+
+#define BITMAP_DESTROY(type) \
+static void \
+type##_destroy(struct ip_set *set) \
+{ \
+ struct ip_set_##type *map = set->data; \
+ \
+ ip_set_free(map->members, map->size); \
+ kfree(map); \
+ \
+ set->data = NULL; \
+}
+
+#define BITMAP_FLUSH(type) \
+static void \
+type##_flush(struct ip_set *set) \
+{ \
+ struct ip_set_##type *map = set->data; \
+ memset(map->members, 0, map->size); \
+}
+
+#define BITMAP_LIST_HEADER(type) \
+static void \
+type##_list_header(const struct ip_set *set, void *data) \
+{ \
+ const struct ip_set_##type *map = set->data; \
+ struct ip_set_req_##type##_create *header = data; \
+ \
+ header->from = map->first_ip; \
+ header->to = map->last_ip; \
+ __##type##_list_header(map, header); \
+}
+
+#define BITMAP_LIST_MEMBERS_SIZE(type) \
+static int \
+type##_list_members_size(const struct ip_set *set) \
+{ \
+ const struct ip_set_##type *map = set->data; \
+ \
+ return map->size; \
+}
+
+#define BITMAP_LIST_MEMBERS(type) \
+static void \
+type##_list_members(const struct ip_set *set, void *data) \
+{ \
+ const struct ip_set_##type *map = set->data; \
+ \
+ memcpy(data, map->members, map->size); \
+}
+
+#define IP_SET_TYPE(type, __features) \
+struct ip_set_type ip_set_##type = { \
+ .typename = #type, \
+ .features = __features, \
+ .protocol_version = IP_SET_PROTOCOL_VERSION, \
+ .create = &type##_create, \
+ .destroy = &type##_destroy, \
+ .flush = &type##_flush, \
+ .reqsize = sizeof(struct ip_set_req_##type), \
+ .addip = &type##_uadd, \
+ .addip_kernel = &type##_kadd, \
+ .delip = &type##_udel, \
+ .delip_kernel = &type##_kdel, \
+ .testip = &type##_utest, \
+ .testip_kernel = &type##_ktest, \
+ .header_size = sizeof(struct ip_set_req_##type##_create),\
+ .list_header = &type##_list_header, \
+ .list_members_size = &type##_list_members_size, \
+ .list_members = &type##_list_members, \
+ .me = THIS_MODULE, \
+};
+
+#endif /* __IP_SET_BITMAPS_H */
diff --git a/kernel/include/linux/netfilter_ipv4/ip_set_getport.h b/kernel/include/linux/netfilter_ipv4/ip_set_getport.h
new file mode 100644
index 0000000..9e322bf
--- /dev/null
+++ b/kernel/include/linux/netfilter_ipv4/ip_set_getport.h
@@ -0,0 +1,48 @@
+#ifndef _IP_SET_GETPORT_H
+#define _IP_SET_GETPORT_H
+
+#ifdef __KERNEL__
+
+#define INVALID_PORT (MAX_RANGE + 1)
+
+/* 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 = ip_hdr(skb);
+ 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, ip_hdr(skb)->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, ip_hdr(skb)->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;
+ }
+}
+#endif /* __KERNEL__ */
+
+#endif /*_IP_SET_GETPORT_H*/
diff --git a/kernel/include/linux/netfilter_ipv4/ip_set_hashes.h b/kernel/include/linux/netfilter_ipv4/ip_set_hashes.h
new file mode 100644
index 0000000..405784a
--- /dev/null
+++ b/kernel/include/linux/netfilter_ipv4/ip_set_hashes.h
@@ -0,0 +1,300 @@
+#ifndef __IP_SET_HASHES_H
+#define __IP_SET_HASHES_H
+
+/* Macros to generate functions */
+
+#ifdef __KERNEL__
+#define HASH_RETRY0(type, dtype, cond) \
+static int \
+type##_retry(struct ip_set *set) \
+{ \
+ struct ip_set_##type *map = set->data, *tmp; \
+ dtype *elem; \
+ void *members; \
+ u_int32_t i, hashsize = map->hashsize; \
+ int res; \
+ \
+ 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_##type) \
+ + map->probes * sizeof(uint32_t), GFP_ATOMIC); \
+ if (!tmp) { \
+ DP("out of memory for %d bytes", \
+ sizeof(struct ip_set_##type) \
+ + map->probes * sizeof(uint32_t)); \
+ return -ENOMEM; \
+ } \
+ tmp->members = harray_malloc(hashsize, sizeof(dtype), GFP_ATOMIC);\
+ if (!tmp->members) { \
+ DP("out of memory for %d bytes", hashsize * sizeof(dtype));\
+ kfree(tmp); \
+ return -ENOMEM; \
+ } \
+ tmp->hashsize = hashsize; \
+ tmp->elements = 0; \
+ tmp->probes = map->probes; \
+ tmp->resize = map->resize; \
+ memcpy(tmp->initval, map->initval, map->probes * sizeof(uint32_t));\
+ __##type##_retry(tmp, map); \
+ \
+ write_lock_bh(&set->lock); \
+ map = set->data; /* Play safe */ \
+ for (i = 0; i < map->hashsize && res == 0; i++) { \
+ elem = HARRAY_ELEM(map->members, dtype *, i); \
+ if (cond) \
+ res = __##type##_add(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; \
+}
+
+#define HASH_RETRY(type, dtype) \
+ HASH_RETRY0(type, dtype, *elem)
+
+#define HASH_RETRY2(type, dtype) \
+ HASH_RETRY0(type, dtype, elem->ip || elem->ip1)
+
+#define HASH_CREATE(type, dtype) \
+static int \
+type##_create(struct ip_set *set, const void *data, size_t size) \
+{ \
+ const struct ip_set_req_##type##_create *req = data; \
+ struct ip_set_##type *map; \
+ uint16_t i; \
+ \
+ 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_##type) \
+ + req->probes * sizeof(uint32_t), GFP_KERNEL); \
+ if (!map) { \
+ DP("out of memory for %d bytes", \
+ sizeof(struct ip_set_##type) \
+ + req->probes * sizeof(uint32_t)); \
+ return -ENOMEM; \
+ } \
+ for (i = 0; i < req->probes; i++) \
+ get_random_bytes(((uint32_t *) map->initval)+i, 4); \
+ map->elements = 0; \
+ map->hashsize = req->hashsize; \
+ map->probes = req->probes; \
+ map->resize = req->resize; \
+ if (__##type##_create(req, map)) { \
+ kfree(map); \
+ return -ENOEXEC; \
+ } \
+ map->members = harray_malloc(map->hashsize, sizeof(dtype), GFP_KERNEL);\
+ if (!map->members) { \
+ DP("out of memory for %d bytes", map->hashsize * sizeof(dtype));\
+ kfree(map); \
+ return -ENOMEM; \
+ } \
+ \
+ set->data = map; \
+ return 0; \
+}
+
+#define HASH_DESTROY(type) \
+static void \
+type##_destroy(struct ip_set *set) \
+{ \
+ struct ip_set_##type *map = set->data; \
+ \
+ harray_free(map->members); \
+ kfree(map); \
+ \
+ set->data = NULL; \
+}
+
+#define HASH_FLUSH(type, dtype) \
+static void \
+type##_flush(struct ip_set *set) \
+{ \
+ struct ip_set_##type *map = set->data; \
+ harray_flush(map->members, map->hashsize, sizeof(dtype)); \
+ map->elements = 0; \
+}
+
+#define HASH_FLUSH_CIDR(type, dtype) \
+static void \
+type##_flush(struct ip_set *set) \
+{ \
+ struct ip_set_##type *map = set->data; \
+ harray_flush(map->members, map->hashsize, sizeof(dtype)); \
+ memset(map->cidr, 0, 30 * sizeof(uint8_t)); \
+ memset(map->nets, 0, 30 * sizeof(uint32_t)); \
+ map->elements = 0; \
+}
+
+#define HASH_LIST_HEADER(type) \
+static void \
+type##_list_header(const struct ip_set *set, void *data) \
+{ \
+ const struct ip_set_##type *map = set->data; \
+ struct ip_set_req_##type##_create *header = data; \
+ \
+ header->hashsize = map->hashsize; \
+ header->probes = map->probes; \
+ header->resize = map->resize; \
+ __##type##_list_header(map, header); \
+}
+
+#define HASH_LIST_MEMBERS_SIZE(type, dtype) \
+static int \
+type##_list_members_size(const struct ip_set *set) \
+{ \
+ const struct ip_set_##type *map = set->data; \
+ \
+ return (map->hashsize * sizeof(dtype)); \
+}
+
+#define HASH_LIST_MEMBERS(type, dtype) \
+static void \
+type##_list_members(const struct ip_set *set, void *data) \
+{ \
+ const struct ip_set_##type *map = set->data; \
+ dtype *elem; \
+ uint32_t i; \
+ \
+ for (i = 0; i < map->hashsize; i++) { \
+ elem = HARRAY_ELEM(map->members, dtype *, i); \
+ ((dtype *)data)[i] = *elem; \
+ } \
+}
+
+#define HASH_LIST_MEMBERS_MEMCPY(type, dtype) \
+static void \
+type##_list_members(const struct ip_set *set, void *data) \
+{ \
+ const struct ip_set_##type *map = set->data; \
+ dtype *elem; \
+ uint32_t i; \
+ \
+ for (i = 0; i < map->hashsize; i++) { \
+ elem = HARRAY_ELEM(map->members, dtype *, i); \
+ memcpy((((dtype *)data)+i), elem, sizeof(dtype)); \
+ } \
+}
+
+#define IP_SET_RTYPE(type, __features) \
+struct ip_set_type ip_set_##type = { \
+ .typename = #type, \
+ .features = __features, \
+ .protocol_version = IP_SET_PROTOCOL_VERSION, \
+ .create = &type##_create, \
+ .retry = &type##_retry, \
+ .destroy = &type##_destroy, \
+ .flush = &type##_flush, \
+ .reqsize = sizeof(struct ip_set_req_##type), \
+ .addip = &type##_uadd, \
+ .addip_kernel = &type##_kadd, \
+ .delip = &type##_udel, \
+ .delip_kernel = &type##_kdel, \
+ .testip = &type##_utest, \
+ .testip_kernel = &type##_ktest, \
+ .header_size = sizeof(struct ip_set_req_##type##_create),\
+ .list_header = &type##_list_header, \
+ .list_members_size = &type##_list_members_size, \
+ .list_members = &type##_list_members, \
+ .me = THIS_MODULE, \
+};
+
+/* Helper functions */
+static inline void
+add_cidr_size(uint8_t *cidr, uint8_t size)
+{
+ uint8_t next;
+ int i;
+
+ for (i = 0; i < 30 && cidr[i]; i++) {
+ if (cidr[i] < size) {
+ next = cidr[i];
+ cidr[i] = size;
+ size = next;
+ }
+ }
+ if (i < 30)
+ cidr[i] = size;
+}
+
+static inline void
+del_cidr_size(uint8_t *cidr, uint8_t size)
+{
+ int i;
+
+ for (i = 0; i < 29 && cidr[i]; i++) {
+ if (cidr[i] == size)
+ cidr[i] = size = cidr[i+1];
+ }
+ cidr[29] = 0;
+}
+#endif /* __KERNEL */
+
+#ifndef UINT16_MAX
+#define UINT16_MAX 65535
+#endif
+
+static unsigned char shifts[] = {255, 253, 249, 241, 225, 193, 129, 1};
+
+static inline ip_set_ip_t
+pack_ip_cidr(ip_set_ip_t ip, unsigned char cidr)
+{
+ ip_set_ip_t addr, *paddr = &addr;
+ unsigned char n, t, *a;
+
+ addr = htonl(ip & (0xFFFFFFFF << (32 - (cidr))));
+#ifdef __KERNEL__
+ DP("ip:%u.%u.%u.%u/%u", NIPQUAD(addr), cidr);
+#endif
+ n = cidr / 8;
+ t = cidr % 8;
+ a = &((unsigned char *)paddr)[n];
+ *a = *a /(1 << (8 - t)) + shifts[t];
+#ifdef __KERNEL__
+ DP("n: %u, t: %u, a: %u", n, t, *a);
+ DP("ip:%u.%u.%u.%u/%u, %u.%u.%u.%u",
+ HIPQUAD(ip), cidr, NIPQUAD(addr));
+#endif
+
+ return ntohl(addr);
+}
+
+
+#endif /* __IP_SET_HASHES_H */
diff --git a/kernel/include/linux/netfilter_ipv4/ip_set_iphash.h b/kernel/include/linux/netfilter_ipv4/ip_set_iphash.h
index 7de854b..7551cb2 100644
--- a/kernel/include/linux/netfilter_ipv4/ip_set_iphash.h
+++ b/kernel/include/linux/netfilter_ipv4/ip_set_iphash.h
@@ -4,7 +4,6 @@
#include <linux/netfilter_ipv4/ip_set.h>
#define SETTYPE_NAME "iphash"
-#define MAX_RANGE 0x0000FFFF
struct ip_set_iphash {
ip_set_ip_t *members; /* the iphash proper */
@@ -13,7 +12,7 @@ struct ip_set_iphash {
uint16_t probes; /* max number of probes */
uint16_t resize; /* resize factor in percent */
ip_set_ip_t netmask; /* netmask */
- void *initval[0]; /* initvals for jhash_1word */
+ uint32_t initval[0]; /* initvals for jhash_1word */
};
struct ip_set_req_iphash_create {
diff --git a/kernel/include/linux/netfilter_ipv4/ip_set_ipmap.h b/kernel/include/linux/netfilter_ipv4/ip_set_ipmap.h
index e3390be..2f409d9 100644
--- a/kernel/include/linux/netfilter_ipv4/ip_set_ipmap.h
+++ b/kernel/include/linux/netfilter_ipv4/ip_set_ipmap.h
@@ -4,7 +4,6 @@
#include <linux/netfilter_ipv4/ip_set.h>
#define SETTYPE_NAME "ipmap"
-#define MAX_RANGE 0x0000FFFF
struct ip_set_ipmap {
void *members; /* the ipmap proper */
@@ -13,6 +12,7 @@ struct ip_set_ipmap {
ip_set_ip_t netmask; /* subnet netmask */
ip_set_ip_t sizeid; /* size of set in IPs */
ip_set_ip_t hosts; /* number of hosts in a subnet */
+ size_t size; /* size of the ipmap proper */
};
struct ip_set_req_ipmap_create {
@@ -25,7 +25,7 @@ struct ip_set_req_ipmap {
ip_set_ip_t ip;
};
-static unsigned int
+static inline unsigned int
mask_to_bits(ip_set_ip_t mask)
{
unsigned int bits = 32;
@@ -41,7 +41,7 @@ mask_to_bits(ip_set_ip_t mask)
return bits;
}
-static ip_set_ip_t
+static inline ip_set_ip_t
range_to_mask(ip_set_ip_t from, ip_set_ip_t to, unsigned int *bits)
{
ip_set_ip_t mask = 0xFFFFFFFE;
diff --git a/kernel/include/linux/netfilter_ipv4/ip_set_ipporthash.h b/kernel/include/linux/netfilter_ipv4/ip_set_ipporthash.h
index b715c56..ccec14e 100644
--- a/kernel/include/linux/netfilter_ipv4/ip_set_ipporthash.h
+++ b/kernel/include/linux/netfilter_ipv4/ip_set_ipporthash.h
@@ -4,8 +4,6 @@
#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 */
@@ -15,7 +13,7 @@ struct ip_set_ipporthash {
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 */
+ uint32_t initval[0]; /* initvals for jhash_1word */
};
struct ip_set_req_ipporthash_create {
diff --git a/kernel/include/linux/netfilter_ipv4/ip_set_ipportiphash.h b/kernel/include/linux/netfilter_ipv4/ip_set_ipportiphash.h
new file mode 100644
index 0000000..4d794bf
--- /dev/null
+++ b/kernel/include/linux/netfilter_ipv4/ip_set_ipportiphash.h
@@ -0,0 +1,38 @@
+#ifndef __IP_SET_IPPORTIPHASH_H
+#define __IP_SET_IPPORTIPHASH_H
+
+#include <linux/netfilter_ipv4/ip_set.h>
+
+#define SETTYPE_NAME "ipportiphash"
+
+struct ipportip {
+ ip_set_ip_t ip;
+ ip_set_ip_t ip1;
+};
+
+struct ip_set_ipportiphash {
+ struct ipportip *members; /* the ipportip proper */
+ uint32_t elements; /* number of elements */
+ 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 */
+ uint32_t initval[0]; /* initvals for jhash_1word */
+};
+
+struct ip_set_req_ipportiphash_create {
+ uint32_t hashsize;
+ uint16_t probes;
+ uint16_t resize;
+ ip_set_ip_t from;
+ ip_set_ip_t to;
+};
+
+struct ip_set_req_ipportiphash {
+ ip_set_ip_t ip;
+ ip_set_ip_t port;
+ ip_set_ip_t ip1;
+};
+
+#endif /* __IP_SET_IPPORTIPHASH_H */
diff --git a/kernel/include/linux/netfilter_ipv4/ip_set_ipportnethash.h b/kernel/include/linux/netfilter_ipv4/ip_set_ipportnethash.h
new file mode 100644
index 0000000..9c78a68
--- /dev/null
+++ b/kernel/include/linux/netfilter_ipv4/ip_set_ipportnethash.h
@@ -0,0 +1,41 @@
+#ifndef __IP_SET_IPPORTNETHASH_H
+#define __IP_SET_IPPORTNETHASH_H
+
+#include <linux/netfilter_ipv4/ip_set.h>
+
+#define SETTYPE_NAME "ipportnethash"
+
+struct ipportip {
+ ip_set_ip_t ip;
+ ip_set_ip_t ip1;
+};
+
+struct ip_set_ipportnethash {
+ struct ipportip *members; /* the ipportip proper */
+ uint32_t elements; /* number of elements */
+ 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 */
+ uint8_t cidr[30]; /* CIDR sizes */
+ uint16_t nets[30]; /* nr of nets by CIDR sizes */
+ uint32_t initval[0]; /* initvals for jhash_1word */
+};
+
+struct ip_set_req_ipportnethash_create {
+ uint32_t hashsize;
+ uint16_t probes;
+ uint16_t resize;
+ ip_set_ip_t from;
+ ip_set_ip_t to;
+};
+
+struct ip_set_req_ipportnethash {
+ ip_set_ip_t ip;
+ ip_set_ip_t port;
+ ip_set_ip_t ip1;
+ uint8_t cidr;
+};
+
+#endif /* __IP_SET_IPPORTNETHASH_H */
diff --git a/kernel/include/linux/netfilter_ipv4/ip_set_iptree.h b/kernel/include/linux/netfilter_ipv4/ip_set_iptree.h
index 64e716b..de5cf47 100644
--- a/kernel/include/linux/netfilter_ipv4/ip_set_iptree.h
+++ b/kernel/include/linux/netfilter_ipv4/ip_set_iptree.h
@@ -4,7 +4,6 @@
#include <linux/netfilter_ipv4/ip_set.h>
#define SETTYPE_NAME "iptree"
-#define MAX_RANGE 0x0000FFFF
struct ip_set_iptreed {
unsigned long expires[256]; /* x.x.x.ADDR */
diff --git a/kernel/include/linux/netfilter_ipv4/ip_set_iptreemap.h b/kernel/include/linux/netfilter_ipv4/ip_set_iptreemap.h
index bef576a..a58bc4e 100644
--- a/kernel/include/linux/netfilter_ipv4/ip_set_iptreemap.h
+++ b/kernel/include/linux/netfilter_ipv4/ip_set_iptreemap.h
@@ -33,7 +33,7 @@ struct ip_set_req_iptreemap_create {
};
struct ip_set_req_iptreemap {
- ip_set_ip_t start;
+ ip_set_ip_t ip;
ip_set_ip_t end;
};
diff --git a/kernel/include/linux/netfilter_ipv4/ip_set_macipmap.h b/kernel/include/linux/netfilter_ipv4/ip_set_macipmap.h
index ee34c9b..82ea96d 100644
--- a/kernel/include/linux/netfilter_ipv4/ip_set_macipmap.h
+++ b/kernel/include/linux/netfilter_ipv4/ip_set_macipmap.h
@@ -4,7 +4,6 @@
#include <linux/netfilter_ipv4/ip_set.h>
#define SETTYPE_NAME "macipmap"
-#define MAX_RANGE 0x0000FFFF
/* general flags */
#define IPSET_MACIP_MATCHUNSET 1
@@ -17,6 +16,7 @@ struct ip_set_macipmap {
ip_set_ip_t first_ip; /* host byte order, included in range */
ip_set_ip_t last_ip; /* host byte order, included in range */
u_int32_t flags;
+ size_t size; /* size of the ipmap proper */
};
struct ip_set_req_macipmap_create {
diff --git a/kernel/include/linux/netfilter_ipv4/ip_set_malloc.h b/kernel/include/linux/netfilter_ipv4/ip_set_malloc.h
index d22bed7..8bce667 100644
--- a/kernel/include/linux/netfilter_ipv4/ip_set_malloc.h
+++ b/kernel/include/linux/netfilter_ipv4/ip_set_malloc.h
@@ -2,8 +2,10 @@
#define _IP_SET_MALLOC_H
#ifdef __KERNEL__
+#include <linux/vmalloc.h>
static size_t max_malloc_size = 0, max_page_size = 0;
+static size_t default_max_malloc_size = 131072; /* Guaranteed: slab.c */
static inline int init_max_page_size(void)
{
@@ -12,7 +14,7 @@ static inline int init_max_page_size(void)
#define __GFP_NOWARN 0
/* Guaranteed: slab.c */
- max_malloc_size = max_page_size = 131072;
+ max_malloc_size = max_page_size = default_max_malloc_size;
#else
size_t page_size = 0;
@@ -130,7 +132,7 @@ static inline void * ip_set_malloc(size_t bytes)
{
BUG_ON(max_malloc_size == 0);
- if (bytes > max_malloc_size)
+ if (bytes > default_max_malloc_size)
return vmalloc(bytes);
else
return kmalloc(bytes, GFP_KERNEL | __GFP_NOWARN);
@@ -140,7 +142,7 @@ static inline void ip_set_free(void * data, size_t bytes)
{
BUG_ON(max_malloc_size == 0);
- if (bytes > max_malloc_size)
+ if (bytes > default_max_malloc_size)
vfree(data);
else
kfree(data);
diff --git a/kernel/include/linux/netfilter_ipv4/ip_set_nethash.h b/kernel/include/linux/netfilter_ipv4/ip_set_nethash.h
index 172ef02..eecd68b 100644
--- a/kernel/include/linux/netfilter_ipv4/ip_set_nethash.h
+++ b/kernel/include/linux/netfilter_ipv4/ip_set_nethash.h
@@ -4,7 +4,6 @@
#include <linux/netfilter_ipv4/ip_set.h>
#define SETTYPE_NAME "nethash"
-#define MAX_RANGE 0x0000FFFF
struct ip_set_nethash {
ip_set_ip_t *members; /* the nethash proper */
@@ -12,8 +11,9 @@ struct ip_set_nethash {
uint32_t hashsize; /* hash size */
uint16_t probes; /* max number of probes */
uint16_t resize; /* resize factor in percent */
- unsigned char cidr[30]; /* CIDR sizes */
- void *initval[0]; /* initvals for jhash_1word */
+ uint8_t cidr[30]; /* CIDR sizes */
+ uint16_t nets[30]; /* nr of nets by CIDR sizes */
+ uint32_t initval[0]; /* initvals for jhash_1word */
};
struct ip_set_req_nethash_create {
@@ -24,32 +24,7 @@ struct ip_set_req_nethash_create {
struct ip_set_req_nethash {
ip_set_ip_t ip;
- unsigned char cidr;
+ uint8_t cidr;
};
-static unsigned char shifts[] = {255, 253, 249, 241, 225, 193, 129, 1};
-
-static inline ip_set_ip_t
-pack(ip_set_ip_t ip, unsigned char cidr)
-{
- ip_set_ip_t addr, *paddr = &addr;
- unsigned char n, t, *a;
-
- addr = htonl(ip & (0xFFFFFFFF << (32 - (cidr))));
-#ifdef __KERNEL__
- DP("ip:%u.%u.%u.%u/%u", NIPQUAD(addr), cidr);
-#endif
- n = cidr / 8;
- t = cidr % 8;
- a = &((unsigned char *)paddr)[n];
- *a = *a /(1 << (8 - t)) + shifts[t];
-#ifdef __KERNEL__
- DP("n: %u, t: %u, a: %u", n, t, *a);
- DP("ip:%u.%u.%u.%u/%u, %u.%u.%u.%u",
- HIPQUAD(ip), cidr, NIPQUAD(addr));
-#endif
-
- return ntohl(addr);
-}
-
#endif /* __IP_SET_NETHASH_H */
diff --git a/kernel/include/linux/netfilter_ipv4/ip_set_portmap.h b/kernel/include/linux/netfilter_ipv4/ip_set_portmap.h
index c17165c..1a15380 100644
--- a/kernel/include/linux/netfilter_ipv4/ip_set_portmap.h
+++ b/kernel/include/linux/netfilter_ipv4/ip_set_portmap.h
@@ -4,13 +4,12 @@
#include <linux/netfilter_ipv4/ip_set.h>
#define SETTYPE_NAME "portmap"
-#define MAX_RANGE 0x0000FFFF
-#define INVALID_PORT (MAX_RANGE + 1)
struct ip_set_portmap {
void *members; /* the portmap proper */
- ip_set_ip_t first_port; /* host byte order, included in range */
- ip_set_ip_t last_port; /* host byte order, included in range */
+ ip_set_ip_t first_ip; /* host byte order, included in range */
+ ip_set_ip_t last_ip; /* host byte order, included in range */
+ size_t size; /* size of the ipmap proper */
};
struct ip_set_req_portmap_create {
@@ -19,7 +18,7 @@ struct ip_set_req_portmap_create {
};
struct ip_set_req_portmap {
- ip_set_ip_t port;
+ ip_set_ip_t ip;
};
#endif /* __IP_SET_PORTMAP_H */
diff --git a/kernel/include/linux/netfilter_ipv4/ip_set_setlist.h b/kernel/include/linux/netfilter_ipv4/ip_set_setlist.h
new file mode 100644
index 0000000..55f0afb
--- /dev/null
+++ b/kernel/include/linux/netfilter_ipv4/ip_set_setlist.h
@@ -0,0 +1,26 @@
+#ifndef __IP_SET_SETLIST_H
+#define __IP_SET_SETLIST_H
+
+#include <linux/netfilter_ipv4/ip_set.h>
+
+#define SETTYPE_NAME "setlist"
+
+#define IP_SET_SETLIST_ADD_AFTER 0
+#define IP_SET_SETLIST_ADD_BEFORE 1
+
+struct ip_set_setlist {
+ uint8_t size;
+ ip_set_id_t id[0];
+};
+
+struct ip_set_req_setlist_create {
+ uint8_t size;
+};
+
+struct ip_set_req_setlist {
+ char name[IP_SET_MAXNAMELEN];
+ char ref[IP_SET_MAXNAMELEN];
+ uint8_t before;
+};
+
+#endif /* __IP_SET_SETLIST_H */