summaryrefslogtreecommitdiffstats
path: root/kernel/ip_set_macipmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/ip_set_macipmap.c')
-rw-r--r--kernel/ip_set_macipmap.c255
1 files changed, 44 insertions, 211 deletions
diff --git a/kernel/ip_set_macipmap.c b/kernel/ip_set_macipmap.c
index 33e2808..4b2b1de 100644
--- a/kernel/ip_set_macipmap.c
+++ b/kernel/ip_set_macipmap.c
@@ -1,7 +1,7 @@
/* Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu>
* Patrick Schaaf <bof@bof.de>
* Martin Josefsson <gandalf@wlug.westbo.se>
- * Copyright (C) 2003-2004 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
+ * Copyright (C) 2003-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
@@ -13,33 +13,24 @@
#include <linux/module.h>
#include <linux/ip.h>
#include <linux/skbuff.h>
-#include <linux/version.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/if_ether.h>
-#include <linux/vmalloc.h>
-#include <linux/netfilter_ipv4/ip_set_malloc.h>
+#include <linux/netfilter_ipv4/ip_set.h>
+#include <linux/netfilter_ipv4/ip_set_bitmaps.h>
#include <linux/netfilter_ipv4/ip_set_macipmap.h>
static int
-testip(struct ip_set *set, const void *data, size_t size, ip_set_ip_t *hash_ip)
+macipmap_utest(struct ip_set *set, const void *data, size_t size,
+ ip_set_ip_t *hash_ip)
{
- struct ip_set_macipmap *map = set->data;
- struct ip_set_macip *table = map->members;
+ const struct ip_set_macipmap *map = set->data;
+ const struct ip_set_macip *table = map->members;
const struct ip_set_req_macipmap *req = data;
- if (size != sizeof(struct ip_set_req_macipmap)) {
- ip_set_printk("data length wrong (want %zu, have %zu)",
- sizeof(struct ip_set_req_macipmap),
- size);
- return -EINVAL;
- }
-
if (req->ip < map->first_ip || req->ip > map->last_ip)
return -ERANGE;
@@ -57,19 +48,17 @@ testip(struct ip_set *set, const void *data, size_t size, ip_set_ip_t *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)
+macipmap_ktest(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 = set->data;
- struct ip_set_macip *table = map->members;
+ const struct ip_set_macipmap *map = set->data;
+ const struct ip_set_macip *table = map->members;
ip_set_ip_t ip;
- ip = ntohl(flags[index] & IPSET_SRC
- ? ip_hdr(skb)->saddr
- : ip_hdr(skb)->daddr);
+ ip = ipaddr(skb, flags[index]);
if (ip < map->first_ip || ip > map->last_ip)
return 0;
@@ -93,8 +82,8 @@ testip_kernel(struct ip_set *set,
/* returns 0 on success */
static inline int
-__addip(struct ip_set *set,
- ip_set_ip_t ip, const unsigned char *ethernet, ip_set_ip_t *hash_ip)
+macipmap_add(struct ip_set *set, ip_set_ip_t *hash_ip,
+ ip_set_ip_t ip, const unsigned char *ethernet)
{
struct ip_set_macipmap *map = set->data;
struct ip_set_macip *table = map->members;
@@ -111,43 +100,16 @@ __addip(struct ip_set *set,
return 0;
}
-static int
-addip(struct ip_set *set, const void *data, size_t size,
- ip_set_ip_t *hash_ip)
-{
- const struct ip_set_req_macipmap *req = data;
-
- if (size != sizeof(struct ip_set_req_macipmap)) {
- ip_set_printk("data length wrong (want %zu, have %zu)",
- sizeof(struct ip_set_req_macipmap),
- size);
- return -EINVAL;
- }
- return __addip(set, req->ip, req->ethernet, 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 ip;
-
- ip = ntohl(flags[index] & IPSET_SRC
- ? ip_hdr(skb)->saddr
- : ip_hdr(skb)->daddr);
-
- if (!(skb_mac_header(skb) >= skb->head
- && (skb_mac_header(skb) + ETH_HLEN) <= skb->data))
+#define KADT_CONDITION \
+ if (!(skb_mac_header(skb) >= skb->head \
+ && (skb_mac_header(skb) + ETH_HLEN) <= skb->data))\
return -EINVAL;
- return __addip(set, ip, eth_hdr(skb)->h_source, hash_ip);
-}
+UADT(macipmap, add, req->ethernet)
+KADT(macipmap, add, ipaddr, eth_hdr(skb)->h_source)
static inline int
-__delip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip)
+macipmap_del(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
{
struct ip_set_macipmap *map = set->data;
struct ip_set_macip *table = map->members;
@@ -163,173 +125,44 @@ __delip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip)
return 0;
}
-static int
-delip(struct ip_set *set, const void *data, size_t size,
- ip_set_ip_t *hash_ip)
-{
- const struct ip_set_req_macipmap *req = data;
-
- if (size != sizeof(struct ip_set_req_macipmap)) {
- ip_set_printk("data length wrong (want %zu, have %zu)",
- sizeof(struct ip_set_req_macipmap),
- 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);
-}
+#undef KADT_CONDITION
+#define KADT_CONDITION
-static inline size_t members_size(ip_set_ip_t from, ip_set_ip_t to)
-{
- return (size_t)((to - from + 1) * sizeof(struct ip_set_macip));
-}
+UADT(macipmap, del)
+KADT(macipmap, del, ipaddr)
-static int create(struct ip_set *set, const void *data, size_t size)
+static inline int
+__macipmap_create(const struct ip_set_req_macipmap_create *req,
+ struct ip_set_macipmap *map)
{
- size_t newbytes;
- const struct ip_set_req_macipmap_create *req = data;
- struct ip_set_macipmap *map;
-
- if (size != sizeof(struct ip_set_req_macipmap_create)) {
- ip_set_printk("data length wrong (want %zu, have %zu)",
- sizeof(struct ip_set_req_macipmap_create),
- size);
- return -EINVAL;
- }
-
- DP("from %u.%u.%u.%u to %u.%u.%u.%u",
- HIPQUAD(req->from), HIPQUAD(req->to));
-
- if (req->from > req->to) {
- DP("bad ip range");
- return -ENOEXEC;
- }
-
if (req->to - req->from > MAX_RANGE) {
- ip_set_printk("range too big (max %d addresses)",
- MAX_RANGE+1);
+ ip_set_printk("range too big, %d elements (max %d)",
+ req->to - req->from + 1, MAX_RANGE+1);
return -ENOEXEC;
}
-
- map = kmalloc(sizeof(struct ip_set_macipmap), GFP_KERNEL);
- if (!map) {
- DP("out of memory for %d bytes",
- sizeof(struct ip_set_macipmap));
- return -ENOMEM;
- }
map->flags = req->flags;
- map->first_ip = req->from;
- map->last_ip = req->to;
- newbytes = members_size(map->first_ip, map->last_ip);
- map->members = ip_set_malloc(newbytes);
- DP("members: %u %p", newbytes, map->members);
- 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;
-}
-
-static void destroy(struct ip_set *set)
-{
- struct ip_set_macipmap *map = set->data;
-
- ip_set_free(map->members, members_size(map->first_ip, map->last_ip));
- kfree(map);
-
- set->data = NULL;
+ return (req->to - req->from + 1) * sizeof(struct ip_set_macip);
}
-static void flush(struct ip_set *set)
-{
- struct ip_set_macipmap *map = set->data;
- memset(map->members, 0, members_size(map->first_ip, map->last_ip));
-}
+BITMAP_CREATE(macipmap)
+BITMAP_DESTROY(macipmap)
+BITMAP_FLUSH(macipmap)
-static void list_header(const struct ip_set *set, void *data)
+static inline void
+__macipmap_list_header(const struct ip_set_macipmap *map,
+ struct ip_set_req_macipmap_create *header)
{
- const struct ip_set_macipmap *map = set->data;
- struct ip_set_req_macipmap_create *header = data;
-
- DP("list_header %x %x %u", map->first_ip, map->last_ip,
- map->flags);
-
- header->from = map->first_ip;
- header->to = map->last_ip;
header->flags = map->flags;
}
-static int list_members_size(const struct ip_set *set)
-{
- const struct ip_set_macipmap *map = set->data;
-
- DP("%u", members_size(map->first_ip, map->last_ip));
- return members_size(map->first_ip, map->last_ip);
-}
-
-static void list_members(const struct ip_set *set, void *data)
-{
- const struct ip_set_macipmap *map = set->data;
+BITMAP_LIST_HEADER(macipmap)
+BITMAP_LIST_MEMBERS_SIZE(macipmap)
+BITMAP_LIST_MEMBERS(macipmap)
- int bytes = members_size(map->first_ip, map->last_ip);
-
- DP("members: %u %p", bytes, map->members);
- memcpy(data, map->members, bytes);
-}
-
-static struct ip_set_type ip_set_macipmap = {
- .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_macipmap),
- .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_macipmap_create),
- .list_header = &list_header,
- .list_members_size = &list_members_size,
- .list_members = &list_members,
- .me = THIS_MODULE,
-};
+IP_SET_TYPE(macipmap, IPSET_TYPE_IP | IPSET_DATA_SINGLE)
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
MODULE_DESCRIPTION("macipmap type of IP sets");
-static int __init ip_set_macipmap_init(void)
-{
- init_max_page_size();
- return ip_set_register_set_type(&ip_set_macipmap);
-}
-
-static void __exit ip_set_macipmap_fini(void)
-{
- /* FIXME: possible race with ip_set_create() */
- ip_set_unregister_set_type(&ip_set_macipmap);
-}
-
-module_init(ip_set_macipmap_init);
-module_exit(ip_set_macipmap_fini);
+REGISTER_MODULE(macipmap)