mirror of
git://git.code.sf.net/p/xtables-addons/xtables-addons
synced 2025-09-08 05:34:58 +02:00
Import ipset-2.3.2 (kernel components)
This commit is contained in:
@@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
* published by the Free Software Foundation.
|
* published by the Free Software Foundation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Kernel module for IP set management */
|
/* Kernel module for IP set management */
|
||||||
@@ -41,14 +41,16 @@ static ip_set_id_t ip_set_bindings_hash_size = CONFIG_IP_NF_SET_HASHSIZE;
|
|||||||
static struct list_head *ip_set_hash; /* hash of bindings */
|
static struct list_head *ip_set_hash; /* hash of bindings */
|
||||||
static unsigned int ip_set_hash_random; /* random seed */
|
static unsigned int ip_set_hash_random; /* random seed */
|
||||||
|
|
||||||
|
#define SETNAME_EQ(a,b) (strncmp(a,b,IP_SET_MAXNAMELEN) == 0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sets are identified either by the index in ip_set_list or by id.
|
* Sets are identified either by the index in ip_set_list or by id.
|
||||||
* The id never changes and is used to find a key in the hash.
|
* The id never changes and is used to find a key in the hash.
|
||||||
* The index may change by swapping and used at all other places
|
* The index may change by swapping and used at all other places
|
||||||
* (set/SET netfilter modules, binding value, etc.)
|
* (set/SET netfilter modules, binding value, etc.)
|
||||||
*
|
*
|
||||||
* Userspace requests are serialized by ip_set_mutex and sets can
|
* Userspace requests are serialized by ip_set_mutex and sets can
|
||||||
* be deleted only from userspace. Therefore ip_set_list locking
|
* be deleted only from userspace. Therefore ip_set_list locking
|
||||||
* must obey the following rules:
|
* must obey the following rules:
|
||||||
*
|
*
|
||||||
* - kernel requests: read and write locking mandatory
|
* - kernel requests: read and write locking mandatory
|
||||||
@@ -86,7 +88,7 @@ __ip_set_find(u_int32_t key, ip_set_id_t id, ip_set_ip_t ip)
|
|||||||
static ip_set_id_t
|
static ip_set_id_t
|
||||||
ip_set_find_in_hash(ip_set_id_t id, ip_set_ip_t ip)
|
ip_set_find_in_hash(ip_set_id_t id, ip_set_ip_t ip)
|
||||||
{
|
{
|
||||||
u_int32_t key = jhash_2words(id, ip, ip_set_hash_random)
|
u_int32_t key = jhash_2words(id, ip, ip_set_hash_random)
|
||||||
% ip_set_bindings_hash_size;
|
% ip_set_bindings_hash_size;
|
||||||
struct ip_set_hash *set_hash;
|
struct ip_set_hash *set_hash;
|
||||||
|
|
||||||
@@ -96,14 +98,14 @@ ip_set_find_in_hash(ip_set_id_t id, ip_set_ip_t ip)
|
|||||||
|
|
||||||
set_hash = __ip_set_find(key, id, ip);
|
set_hash = __ip_set_find(key, id, ip);
|
||||||
|
|
||||||
DP("set: %s, ip: %u.%u.%u.%u, binding: %s", ip_set_list[id]->name,
|
DP("set: %s, ip: %u.%u.%u.%u, binding: %s", ip_set_list[id]->name,
|
||||||
HIPQUAD(ip),
|
HIPQUAD(ip),
|
||||||
set_hash != NULL ? ip_set_list[set_hash->binding]->name : "");
|
set_hash != NULL ? ip_set_list[set_hash->binding]->name : "");
|
||||||
|
|
||||||
return (set_hash != NULL ? set_hash->binding : IP_SET_INVALID_ID);
|
return (set_hash != NULL ? set_hash->binding : IP_SET_INVALID_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
__set_hash_del(struct ip_set_hash *set_hash)
|
__set_hash_del(struct ip_set_hash *set_hash)
|
||||||
{
|
{
|
||||||
ASSERT_WRITE_LOCK(&ip_set_lock);
|
ASSERT_WRITE_LOCK(&ip_set_lock);
|
||||||
@@ -135,7 +137,7 @@ ip_set_hash_del(ip_set_id_t id, ip_set_ip_t ip)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ip_set_hash_add(ip_set_id_t id, ip_set_ip_t ip, ip_set_id_t binding)
|
ip_set_hash_add(ip_set_id_t id, ip_set_ip_t ip, ip_set_id_t binding)
|
||||||
{
|
{
|
||||||
u_int32_t key = jhash_2words(id, ip, ip_set_hash_random)
|
u_int32_t key = jhash_2words(id, ip, ip_set_hash_random)
|
||||||
@@ -145,7 +147,7 @@ ip_set_hash_add(ip_set_id_t id, ip_set_ip_t ip, ip_set_id_t binding)
|
|||||||
|
|
||||||
IP_SET_ASSERT(ip_set_list[id]);
|
IP_SET_ASSERT(ip_set_list[id]);
|
||||||
IP_SET_ASSERT(ip_set_list[binding]);
|
IP_SET_ASSERT(ip_set_list[binding]);
|
||||||
DP("set: %s, ip: %u.%u.%u.%u, binding: %s", ip_set_list[id]->name,
|
DP("set: %s, ip: %u.%u.%u.%u, binding: %s", ip_set_list[id]->name,
|
||||||
HIPQUAD(ip), ip_set_list[binding]->name);
|
HIPQUAD(ip), ip_set_list[binding]->name);
|
||||||
write_lock_bh(&ip_set_lock);
|
write_lock_bh(&ip_set_lock);
|
||||||
set_hash = __ip_set_find(key, id, ip);
|
set_hash = __ip_set_find(key, id, ip);
|
||||||
@@ -224,8 +226,8 @@ ip_set_testip_kernel(ip_set_id_t index,
|
|||||||
res = set->type->testip_kernel(set, skb, &ip, flags, i++);
|
res = set->type->testip_kernel(set, skb, &ip, flags, i++);
|
||||||
read_unlock_bh(&set->lock);
|
read_unlock_bh(&set->lock);
|
||||||
i += !!(set->type->features & IPSET_DATA_DOUBLE);
|
i += !!(set->type->features & IPSET_DATA_DOUBLE);
|
||||||
} while (res > 0
|
} while (res > 0
|
||||||
&& flags[i]
|
&& flags[i]
|
||||||
&& follow_bindings(index, set, ip));
|
&& follow_bindings(index, set, ip));
|
||||||
read_unlock_bh(&ip_set_lock);
|
read_unlock_bh(&ip_set_lock);
|
||||||
|
|
||||||
@@ -254,7 +256,7 @@ ip_set_addip_kernel(ip_set_id_t index,
|
|||||||
write_unlock_bh(&set->lock);
|
write_unlock_bh(&set->lock);
|
||||||
i += !!(set->type->features & IPSET_DATA_DOUBLE);
|
i += !!(set->type->features & IPSET_DATA_DOUBLE);
|
||||||
} while ((res == 0 || res == -EEXIST)
|
} while ((res == 0 || res == -EEXIST)
|
||||||
&& flags[i]
|
&& flags[i]
|
||||||
&& follow_bindings(index, set, ip));
|
&& follow_bindings(index, set, ip));
|
||||||
read_unlock_bh(&ip_set_lock);
|
read_unlock_bh(&ip_set_lock);
|
||||||
|
|
||||||
@@ -285,7 +287,7 @@ ip_set_delip_kernel(ip_set_id_t index,
|
|||||||
write_unlock_bh(&set->lock);
|
write_unlock_bh(&set->lock);
|
||||||
i += !!(set->type->features & IPSET_DATA_DOUBLE);
|
i += !!(set->type->features & IPSET_DATA_DOUBLE);
|
||||||
} while ((res == 0 || res == -EEXIST)
|
} while ((res == 0 || res == -EEXIST)
|
||||||
&& flags[i]
|
&& flags[i]
|
||||||
&& follow_bindings(index, set, ip));
|
&& follow_bindings(index, set, ip));
|
||||||
read_unlock_bh(&ip_set_lock);
|
read_unlock_bh(&ip_set_lock);
|
||||||
}
|
}
|
||||||
@@ -303,7 +305,7 @@ find_set_type(const char *name)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ip_set_register_set_type(struct ip_set_type *set_type)
|
ip_set_register_set_type(struct ip_set_type *set_type)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@@ -319,7 +321,7 @@ ip_set_register_set_type(struct ip_set_type *set_type)
|
|||||||
write_lock_bh(&ip_set_lock);
|
write_lock_bh(&ip_set_lock);
|
||||||
if (find_set_type(set_type->typename)) {
|
if (find_set_type(set_type->typename)) {
|
||||||
/* Duplicate! */
|
/* Duplicate! */
|
||||||
ip_set_printk("'%s' already registered!",
|
ip_set_printk("'%s' already registered!",
|
||||||
set_type->typename);
|
set_type->typename);
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto unlock;
|
goto unlock;
|
||||||
@@ -369,7 +371,7 @@ ip_set_get_byname(const char *name)
|
|||||||
down(&ip_set_app_mutex);
|
down(&ip_set_app_mutex);
|
||||||
for (i = 0; i < ip_set_max; i++) {
|
for (i = 0; i < ip_set_max; i++) {
|
||||||
if (ip_set_list[i] != NULL
|
if (ip_set_list[i] != NULL
|
||||||
&& strcmp(ip_set_list[i]->name, name) == 0) {
|
&& SETNAME_EQ(ip_set_list[i]->name, name)) {
|
||||||
__ip_set_get(i);
|
__ip_set_get(i);
|
||||||
index = i;
|
index = i;
|
||||||
break;
|
break;
|
||||||
@@ -422,7 +424,7 @@ ip_set_find_byname(const char *name)
|
|||||||
|
|
||||||
for (i = 0; i < ip_set_max; i++) {
|
for (i = 0; i < ip_set_max; i++) {
|
||||||
if (ip_set_list[i] != NULL
|
if (ip_set_list[i] != NULL
|
||||||
&& strcmp(ip_set_list[i]->name, name) == 0) {
|
&& SETNAME_EQ(ip_set_list[i]->name, name)) {
|
||||||
index = i;
|
index = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -534,7 +536,7 @@ ip_set_bindip(ip_set_id_t index,
|
|||||||
size_t size)
|
size_t size)
|
||||||
{
|
{
|
||||||
struct ip_set *set = ip_set_list[index];
|
struct ip_set *set = ip_set_list[index];
|
||||||
struct ip_set_req_bind *req_bind;
|
const struct ip_set_req_bind *req_bind;
|
||||||
ip_set_id_t binding;
|
ip_set_id_t binding;
|
||||||
ip_set_ip_t ip;
|
ip_set_ip_t ip;
|
||||||
int res;
|
int res;
|
||||||
@@ -543,18 +545,16 @@ ip_set_bindip(ip_set_id_t index,
|
|||||||
if (size < sizeof(struct ip_set_req_bind))
|
if (size < sizeof(struct ip_set_req_bind))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
req_bind = (struct ip_set_req_bind *) data;
|
req_bind = data;
|
||||||
req_bind->binding[IP_SET_MAXNAMELEN - 1] = '\0';
|
|
||||||
|
|
||||||
if (strcmp(req_bind->binding, IPSET_TOKEN_DEFAULT) == 0) {
|
if (SETNAME_EQ(req_bind->binding, IPSET_TOKEN_DEFAULT)) {
|
||||||
/* Default binding of a set */
|
/* Default binding of a set */
|
||||||
char *binding_name;
|
const char *binding_name;
|
||||||
|
|
||||||
if (size != sizeof(struct ip_set_req_bind) + IP_SET_MAXNAMELEN)
|
if (size != sizeof(struct ip_set_req_bind) + IP_SET_MAXNAMELEN)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
binding_name = (char *)(data + sizeof(struct ip_set_req_bind));
|
binding_name = data + sizeof(struct ip_set_req_bind);
|
||||||
binding_name[IP_SET_MAXNAMELEN - 1] = '\0';
|
|
||||||
|
|
||||||
binding = ip_set_find_byname(binding_name);
|
binding = ip_set_find_byname(binding_name);
|
||||||
if (binding == IP_SET_INVALID_ID)
|
if (binding == IP_SET_INVALID_ID)
|
||||||
@@ -622,7 +622,7 @@ ip_set_unbindip(ip_set_id_t index,
|
|||||||
size_t size)
|
size_t size)
|
||||||
{
|
{
|
||||||
struct ip_set *set;
|
struct ip_set *set;
|
||||||
struct ip_set_req_bind *req_bind;
|
const struct ip_set_req_bind *req_bind;
|
||||||
ip_set_ip_t ip;
|
ip_set_ip_t ip;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
@@ -630,19 +630,18 @@ ip_set_unbindip(ip_set_id_t index,
|
|||||||
if (size < sizeof(struct ip_set_req_bind))
|
if (size < sizeof(struct ip_set_req_bind))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
req_bind = (struct ip_set_req_bind *) data;
|
req_bind = data;
|
||||||
req_bind->binding[IP_SET_MAXNAMELEN - 1] = '\0';
|
|
||||||
|
|
||||||
DP("%u %s", index, req_bind->binding);
|
DP("%u %s", index, req_bind->binding);
|
||||||
if (index == IP_SET_INVALID_ID) {
|
if (index == IP_SET_INVALID_ID) {
|
||||||
/* unbind :all: */
|
/* unbind :all: */
|
||||||
if (strcmp(req_bind->binding, IPSET_TOKEN_DEFAULT) == 0) {
|
if (SETNAME_EQ(req_bind->binding, IPSET_TOKEN_DEFAULT)) {
|
||||||
/* Default binding of sets */
|
/* Default binding of sets */
|
||||||
write_lock_bh(&ip_set_lock);
|
write_lock_bh(&ip_set_lock);
|
||||||
FOREACH_SET_DO(__unbind_default);
|
FOREACH_SET_DO(__unbind_default);
|
||||||
write_unlock_bh(&ip_set_lock);
|
write_unlock_bh(&ip_set_lock);
|
||||||
return 0;
|
return 0;
|
||||||
} else if (strcmp(req_bind->binding, IPSET_TOKEN_ALL) == 0) {
|
} else if (SETNAME_EQ(req_bind->binding, IPSET_TOKEN_ALL)) {
|
||||||
/* Flush all bindings of all sets*/
|
/* Flush all bindings of all sets*/
|
||||||
write_lock_bh(&ip_set_lock);
|
write_lock_bh(&ip_set_lock);
|
||||||
FOREACH_HASH_RW_DO(__set_hash_del);
|
FOREACH_HASH_RW_DO(__set_hash_del);
|
||||||
@@ -655,7 +654,7 @@ ip_set_unbindip(ip_set_id_t index,
|
|||||||
|
|
||||||
set = ip_set_list[index];
|
set = ip_set_list[index];
|
||||||
IP_SET_ASSERT(set);
|
IP_SET_ASSERT(set);
|
||||||
if (strcmp(req_bind->binding, IPSET_TOKEN_DEFAULT) == 0) {
|
if (SETNAME_EQ(req_bind->binding, IPSET_TOKEN_DEFAULT)) {
|
||||||
/* Default binding of set */
|
/* Default binding of set */
|
||||||
ip_set_id_t binding = ip_set_find_byindex(set->binding);
|
ip_set_id_t binding = ip_set_find_byindex(set->binding);
|
||||||
|
|
||||||
@@ -669,7 +668,7 @@ ip_set_unbindip(ip_set_id_t index,
|
|||||||
write_unlock_bh(&ip_set_lock);
|
write_unlock_bh(&ip_set_lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
} else if (strcmp(req_bind->binding, IPSET_TOKEN_ALL) == 0) {
|
} else if (SETNAME_EQ(req_bind->binding, IPSET_TOKEN_ALL)) {
|
||||||
/* Flush all bindings */
|
/* Flush all bindings */
|
||||||
|
|
||||||
write_lock_bh(&ip_set_lock);
|
write_lock_bh(&ip_set_lock);
|
||||||
@@ -696,7 +695,7 @@ ip_set_testbind(ip_set_id_t index,
|
|||||||
size_t size)
|
size_t size)
|
||||||
{
|
{
|
||||||
struct ip_set *set = ip_set_list[index];
|
struct ip_set *set = ip_set_list[index];
|
||||||
struct ip_set_req_bind *req_bind;
|
const struct ip_set_req_bind *req_bind;
|
||||||
ip_set_id_t binding;
|
ip_set_id_t binding;
|
||||||
ip_set_ip_t ip;
|
ip_set_ip_t ip;
|
||||||
int res;
|
int res;
|
||||||
@@ -705,18 +704,16 @@ ip_set_testbind(ip_set_id_t index,
|
|||||||
if (size < sizeof(struct ip_set_req_bind))
|
if (size < sizeof(struct ip_set_req_bind))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
req_bind = (struct ip_set_req_bind *) data;
|
req_bind = data;
|
||||||
req_bind->binding[IP_SET_MAXNAMELEN - 1] = '\0';
|
|
||||||
|
|
||||||
if (strcmp(req_bind->binding, IPSET_TOKEN_DEFAULT) == 0) {
|
if (SETNAME_EQ(req_bind->binding, IPSET_TOKEN_DEFAULT)) {
|
||||||
/* Default binding of set */
|
/* Default binding of set */
|
||||||
char *binding_name;
|
const char *binding_name;
|
||||||
|
|
||||||
if (size != sizeof(struct ip_set_req_bind) + IP_SET_MAXNAMELEN)
|
if (size != sizeof(struct ip_set_req_bind) + IP_SET_MAXNAMELEN)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
binding_name = (char *)(data + sizeof(struct ip_set_req_bind));
|
binding_name = data + sizeof(struct ip_set_req_bind);
|
||||||
binding_name[IP_SET_MAXNAMELEN - 1] = '\0';
|
|
||||||
|
|
||||||
binding = ip_set_find_byname(binding_name);
|
binding = ip_set_find_byname(binding_name);
|
||||||
if (binding == IP_SET_INVALID_ID)
|
if (binding == IP_SET_INVALID_ID)
|
||||||
@@ -737,7 +734,7 @@ ip_set_testbind(ip_set_id_t index,
|
|||||||
&ip);
|
&ip);
|
||||||
DP("set %s, ip: %u.%u.%u.%u, binding %s",
|
DP("set %s, ip: %u.%u.%u.%u, binding %s",
|
||||||
set->name, HIPQUAD(ip), ip_set_list[binding]->name);
|
set->name, HIPQUAD(ip), ip_set_list[binding]->name);
|
||||||
|
|
||||||
if (res >= 0)
|
if (res >= 0)
|
||||||
res = (ip_set_find_in_hash(set->id, ip) == binding)
|
res = (ip_set_find_in_hash(set->id, ip) == binding)
|
||||||
? -EEXIST : 0;
|
? -EEXIST : 0;
|
||||||
@@ -770,7 +767,7 @@ find_free_id(const char *name,
|
|||||||
if (ip_set_list[i] == NULL) {
|
if (ip_set_list[i] == NULL) {
|
||||||
if (*id == IP_SET_INVALID_ID)
|
if (*id == IP_SET_INVALID_ID)
|
||||||
*id = *index = i;
|
*id = *index = i;
|
||||||
} else if (strcmp(name, ip_set_list[i]->name) == 0)
|
} else if (SETNAME_EQ(name, ip_set_list[i]->name))
|
||||||
/* Name clash */
|
/* Name clash */
|
||||||
return -EEXIST;
|
return -EEXIST;
|
||||||
}
|
}
|
||||||
@@ -858,7 +855,7 @@ ip_set_create(const char *name,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Here, we have a valid, constructed set. &ip_set_lock again,
|
* Here, we have a valid, constructed set. &ip_set_lock again,
|
||||||
* find free id/index and check that it is not already in
|
* find free id/index and check that it is not already in
|
||||||
* ip_set_list.
|
* ip_set_list.
|
||||||
*/
|
*/
|
||||||
write_lock_bh(&ip_set_lock);
|
write_lock_bh(&ip_set_lock);
|
||||||
@@ -873,7 +870,7 @@ ip_set_create(const char *name,
|
|||||||
res = -ERANGE;
|
res = -ERANGE;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Finally! Add our shiny new set to the list, and be done.
|
* Finally! Add our shiny new set to the list, and be done.
|
||||||
*/
|
*/
|
||||||
@@ -932,7 +929,7 @@ ip_set_destroy(ip_set_id_t index)
|
|||||||
ip_set_destroy_set(index);
|
ip_set_destroy_set(index);
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; i < ip_set_max; i++) {
|
for (i = 0; i < ip_set_max; i++) {
|
||||||
if (ip_set_list[i] != NULL
|
if (ip_set_list[i] != NULL
|
||||||
&& (atomic_read(&ip_set_list[i]->ref)))
|
&& (atomic_read(&ip_set_list[i]->ref)))
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
@@ -955,7 +952,7 @@ ip_set_flush_set(struct ip_set *set)
|
|||||||
write_unlock_bh(&set->lock);
|
write_unlock_bh(&set->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Flush data in a set - or in all sets
|
* Flush data in a set - or in all sets
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
@@ -982,9 +979,7 @@ ip_set_rename(ip_set_id_t index, const char *name)
|
|||||||
write_lock_bh(&ip_set_lock);
|
write_lock_bh(&ip_set_lock);
|
||||||
for (i = 0; i < ip_set_max; i++) {
|
for (i = 0; i < ip_set_max; i++) {
|
||||||
if (ip_set_list[i] != NULL
|
if (ip_set_list[i] != NULL
|
||||||
&& strncmp(ip_set_list[i]->name,
|
&& SETNAME_EQ(ip_set_list[i]->name, name)) {
|
||||||
name,
|
|
||||||
IP_SET_MAXNAMELEN - 1) == 0) {
|
|
||||||
res = -EEXIST;
|
res = -EEXIST;
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
@@ -1054,8 +1049,7 @@ __set_hash_bindings(struct ip_set_hash *set_hash,
|
|||||||
ip_set_id_t id, void *data, int *used)
|
ip_set_id_t id, void *data, int *used)
|
||||||
{
|
{
|
||||||
if (set_hash->id == id) {
|
if (set_hash->id == id) {
|
||||||
struct ip_set_hash_list *hash_list =
|
struct ip_set_hash_list *hash_list = data + *used;
|
||||||
(struct ip_set_hash_list *)(data + *used);
|
|
||||||
|
|
||||||
hash_list->ip = set_hash->ip;
|
hash_list->ip = set_hash->ip;
|
||||||
hash_list->binding = set_hash->binding;
|
hash_list->binding = set_hash->binding;
|
||||||
@@ -1072,7 +1066,7 @@ static int ip_set_list_set(ip_set_id_t index,
|
|||||||
struct ip_set_list *set_list;
|
struct ip_set_list *set_list;
|
||||||
|
|
||||||
/* Pointer to our header */
|
/* Pointer to our header */
|
||||||
set_list = (struct ip_set_list *) (data + *used);
|
set_list = data + *used;
|
||||||
|
|
||||||
DP("set: %s, used: %d %p %p", set->name, *used, data, data + *used);
|
DP("set: %s, used: %d %p %p", set->name, *used, data, data + *used);
|
||||||
|
|
||||||
@@ -1139,7 +1133,7 @@ static int ip_set_save_set(ip_set_id_t index,
|
|||||||
struct ip_set_save *set_save;
|
struct ip_set_save *set_save;
|
||||||
|
|
||||||
/* Pointer to our header */
|
/* Pointer to our header */
|
||||||
set_save = (struct ip_set_save *) (data + *used);
|
set_save = data + *used;
|
||||||
|
|
||||||
/* Get and ensure header size */
|
/* Get and ensure header size */
|
||||||
if (*used + sizeof(struct ip_set_save) > len)
|
if (*used + sizeof(struct ip_set_save) > len)
|
||||||
@@ -1147,7 +1141,7 @@ static int ip_set_save_set(ip_set_id_t index,
|
|||||||
*used += sizeof(struct ip_set_save);
|
*used += sizeof(struct ip_set_save);
|
||||||
|
|
||||||
set = ip_set_list[index];
|
set = ip_set_list[index];
|
||||||
DP("set: %s, used: %u(%u) %p %p", set->name, *used, len,
|
DP("set: %s, used: %u(%u) %p %p", set->name, *used, len,
|
||||||
data, data + *used);
|
data, data + *used);
|
||||||
|
|
||||||
read_lock_bh(&set->lock);
|
read_lock_bh(&set->lock);
|
||||||
@@ -1196,8 +1190,7 @@ __set_hash_save_bindings(struct ip_set_hash *set_hash,
|
|||||||
{
|
{
|
||||||
if (*res == 0
|
if (*res == 0
|
||||||
&& (id == IP_SET_INVALID_ID || set_hash->id == id)) {
|
&& (id == IP_SET_INVALID_ID || set_hash->id == id)) {
|
||||||
struct ip_set_hash_save *hash_save =
|
struct ip_set_hash_save *hash_save = data + *used;
|
||||||
(struct ip_set_hash_save *)(data + *used);
|
|
||||||
/* Ensure bindings size */
|
/* Ensure bindings size */
|
||||||
if (*used + sizeof(struct ip_set_hash_save) > len) {
|
if (*used + sizeof(struct ip_set_hash_save) > len) {
|
||||||
*res = -ENOMEM;
|
*res = -ENOMEM;
|
||||||
@@ -1224,7 +1217,7 @@ static int ip_set_save_bindings(ip_set_id_t index,
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
/* Marker */
|
/* Marker */
|
||||||
set_save = (struct ip_set_save *) (data + *used);
|
set_save = data + *used;
|
||||||
set_save->index = IP_SET_INVALID_ID;
|
set_save->index = IP_SET_INVALID_ID;
|
||||||
set_save->header_size = 0;
|
set_save->header_size = 0;
|
||||||
set_save->members_size = 0;
|
set_save->members_size = 0;
|
||||||
@@ -1261,12 +1254,12 @@ static int ip_set_restore(void *data,
|
|||||||
/* Get and ensure header size */
|
/* Get and ensure header size */
|
||||||
if (used + sizeof(struct ip_set_restore) > len)
|
if (used + sizeof(struct ip_set_restore) > len)
|
||||||
return line;
|
return line;
|
||||||
set_restore = (struct ip_set_restore *) (data + used);
|
set_restore = data + used;
|
||||||
used += sizeof(struct ip_set_restore);
|
used += sizeof(struct ip_set_restore);
|
||||||
|
|
||||||
/* Ensure data size */
|
/* Ensure data size */
|
||||||
if (used
|
if (used
|
||||||
+ set_restore->header_size
|
+ set_restore->header_size
|
||||||
+ set_restore->members_size > len)
|
+ set_restore->members_size > len)
|
||||||
return line;
|
return line;
|
||||||
|
|
||||||
@@ -1304,7 +1297,7 @@ static int ip_set_restore(void *data,
|
|||||||
res = __ip_set_addip(index,
|
res = __ip_set_addip(index,
|
||||||
data + used + members_size,
|
data + used + members_size,
|
||||||
set->type->reqsize);
|
set->type->reqsize);
|
||||||
if (!(res == 0 || res == -EEXIST))
|
if (!(res == 0 || res == -EEXIST))
|
||||||
return line;
|
return line;
|
||||||
members_size += set->type->reqsize;
|
members_size += set->type->reqsize;
|
||||||
}
|
}
|
||||||
@@ -1325,7 +1318,7 @@ static int ip_set_restore(void *data,
|
|||||||
/* Get and ensure size */
|
/* Get and ensure size */
|
||||||
if (used + sizeof(struct ip_set_hash_save) > len)
|
if (used + sizeof(struct ip_set_hash_save) > len)
|
||||||
return line;
|
return line;
|
||||||
hash_save = (struct ip_set_hash_save *) (data + used);
|
hash_save = data + used;
|
||||||
used += sizeof(struct ip_set_hash_save);
|
used += sizeof(struct ip_set_hash_save);
|
||||||
|
|
||||||
/* hash_save->id is used to store the index */
|
/* hash_save->id is used to store the index */
|
||||||
@@ -1341,7 +1334,7 @@ static int ip_set_restore(void *data,
|
|||||||
set = ip_set_list[hash_save->id];
|
set = ip_set_list[hash_save->id];
|
||||||
/* Null valued IP means default binding */
|
/* Null valued IP means default binding */
|
||||||
if (hash_save->ip)
|
if (hash_save->ip)
|
||||||
res = ip_set_hash_add(set->id,
|
res = ip_set_hash_add(set->id,
|
||||||
hash_save->ip,
|
hash_save->ip,
|
||||||
hash_save->binding);
|
hash_save->binding);
|
||||||
else {
|
else {
|
||||||
@@ -1408,8 +1401,7 @@ ip_set_sockfn_set(struct sock *sk, int optval, void *user, unsigned int len)
|
|||||||
|
|
||||||
if (*op < IP_SET_OP_VERSION) {
|
if (*op < IP_SET_OP_VERSION) {
|
||||||
/* Check the version at the beginning of operations */
|
/* Check the version at the beginning of operations */
|
||||||
struct ip_set_req_version *req_version =
|
struct ip_set_req_version *req_version = data;
|
||||||
(struct ip_set_req_version *) data;
|
|
||||||
if (req_version->version != IP_SET_PROTOCOL_VERSION) {
|
if (req_version->version != IP_SET_PROTOCOL_VERSION) {
|
||||||
res = -EPROTO;
|
res = -EPROTO;
|
||||||
goto done;
|
goto done;
|
||||||
@@ -1418,8 +1410,7 @@ ip_set_sockfn_set(struct sock *sk, int optval, void *user, unsigned int len)
|
|||||||
|
|
||||||
switch (*op) {
|
switch (*op) {
|
||||||
case IP_SET_OP_CREATE:{
|
case IP_SET_OP_CREATE:{
|
||||||
struct ip_set_req_create *req_create
|
struct ip_set_req_create *req_create = data;
|
||||||
= (struct ip_set_req_create *) data;
|
|
||||||
|
|
||||||
if (len < sizeof(struct ip_set_req_create)) {
|
if (len < sizeof(struct ip_set_req_create)) {
|
||||||
ip_set_printk("short CREATE data (want >=%zu, got %u)",
|
ip_set_printk("short CREATE data (want >=%zu, got %u)",
|
||||||
@@ -1437,8 +1428,7 @@ ip_set_sockfn_set(struct sock *sk, int optval, void *user, unsigned int len)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
case IP_SET_OP_DESTROY:{
|
case IP_SET_OP_DESTROY:{
|
||||||
struct ip_set_req_std *req_destroy
|
struct ip_set_req_std *req_destroy = data;
|
||||||
= (struct ip_set_req_std *) data;
|
|
||||||
|
|
||||||
if (len != sizeof(struct ip_set_req_std)) {
|
if (len != sizeof(struct ip_set_req_std)) {
|
||||||
ip_set_printk("invalid DESTROY data (want %zu, got %u)",
|
ip_set_printk("invalid DESTROY data (want %zu, got %u)",
|
||||||
@@ -1446,7 +1436,7 @@ ip_set_sockfn_set(struct sock *sk, int optval, void *user, unsigned int len)
|
|||||||
res = -EINVAL;
|
res = -EINVAL;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (strcmp(req_destroy->name, IPSET_TOKEN_ALL) == 0) {
|
if (SETNAME_EQ(req_destroy->name, IPSET_TOKEN_ALL)) {
|
||||||
/* Destroy all sets */
|
/* Destroy all sets */
|
||||||
index = IP_SET_INVALID_ID;
|
index = IP_SET_INVALID_ID;
|
||||||
} else {
|
} else {
|
||||||
@@ -1463,8 +1453,7 @@ ip_set_sockfn_set(struct sock *sk, int optval, void *user, unsigned int len)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
case IP_SET_OP_FLUSH:{
|
case IP_SET_OP_FLUSH:{
|
||||||
struct ip_set_req_std *req_flush =
|
struct ip_set_req_std *req_flush = data;
|
||||||
(struct ip_set_req_std *) data;
|
|
||||||
|
|
||||||
if (len != sizeof(struct ip_set_req_std)) {
|
if (len != sizeof(struct ip_set_req_std)) {
|
||||||
ip_set_printk("invalid FLUSH data (want %zu, got %u)",
|
ip_set_printk("invalid FLUSH data (want %zu, got %u)",
|
||||||
@@ -1472,7 +1461,7 @@ ip_set_sockfn_set(struct sock *sk, int optval, void *user, unsigned int len)
|
|||||||
res = -EINVAL;
|
res = -EINVAL;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (strcmp(req_flush->name, IPSET_TOKEN_ALL) == 0) {
|
if (SETNAME_EQ(req_flush->name, IPSET_TOKEN_ALL)) {
|
||||||
/* Flush all sets */
|
/* Flush all sets */
|
||||||
index = IP_SET_INVALID_ID;
|
index = IP_SET_INVALID_ID;
|
||||||
} else {
|
} else {
|
||||||
@@ -1488,8 +1477,7 @@ ip_set_sockfn_set(struct sock *sk, int optval, void *user, unsigned int len)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
case IP_SET_OP_RENAME:{
|
case IP_SET_OP_RENAME:{
|
||||||
struct ip_set_req_create *req_rename
|
struct ip_set_req_create *req_rename = data;
|
||||||
= (struct ip_set_req_create *) data;
|
|
||||||
|
|
||||||
if (len != sizeof(struct ip_set_req_create)) {
|
if (len != sizeof(struct ip_set_req_create)) {
|
||||||
ip_set_printk("invalid RENAME data (want %zu, got %u)",
|
ip_set_printk("invalid RENAME data (want %zu, got %u)",
|
||||||
@@ -1510,8 +1498,7 @@ ip_set_sockfn_set(struct sock *sk, int optval, void *user, unsigned int len)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
case IP_SET_OP_SWAP:{
|
case IP_SET_OP_SWAP:{
|
||||||
struct ip_set_req_create *req_swap
|
struct ip_set_req_create *req_swap = data;
|
||||||
= (struct ip_set_req_create *) data;
|
|
||||||
ip_set_id_t to_index;
|
ip_set_id_t to_index;
|
||||||
|
|
||||||
if (len != sizeof(struct ip_set_req_create)) {
|
if (len != sizeof(struct ip_set_req_create)) {
|
||||||
@@ -1537,7 +1524,7 @@ ip_set_sockfn_set(struct sock *sk, int optval, void *user, unsigned int len)
|
|||||||
res = ip_set_swap(index, to_index);
|
res = ip_set_swap(index, to_index);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
break; /* Set identified by id */
|
break; /* Set identified by id */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1554,10 +1541,10 @@ ip_set_sockfn_set(struct sock *sk, int optval, void *user, unsigned int len)
|
|||||||
res = -EINVAL;
|
res = -EINVAL;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
req_adt = (struct ip_set_req_adt *) data;
|
req_adt = data;
|
||||||
|
|
||||||
/* -U :all: :all:|:default: uses IP_SET_INVALID_ID */
|
/* -U :all: :all:|:default: uses IP_SET_INVALID_ID */
|
||||||
if (!(*op == IP_SET_OP_UNBIND_SET
|
if (!(*op == IP_SET_OP_UNBIND_SET
|
||||||
&& req_adt->index == IP_SET_INVALID_ID)) {
|
&& req_adt->index == IP_SET_INVALID_ID)) {
|
||||||
index = ip_set_find_byindex(req_adt->index);
|
index = ip_set_find_byindex(req_adt->index);
|
||||||
if (index == IP_SET_INVALID_ID) {
|
if (index == IP_SET_INVALID_ID) {
|
||||||
@@ -1576,7 +1563,7 @@ ip_set_sockfn_set(struct sock *sk, int optval, void *user, unsigned int len)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ip_set_sockfn_get(struct sock *sk, int optval, void *user, int *len)
|
ip_set_sockfn_get(struct sock *sk, int optval, void *user, int *len)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
@@ -1614,8 +1601,7 @@ ip_set_sockfn_get(struct sock *sk, int optval, void *user, int *len)
|
|||||||
|
|
||||||
if (*op < IP_SET_OP_VERSION) {
|
if (*op < IP_SET_OP_VERSION) {
|
||||||
/* Check the version at the beginning of operations */
|
/* Check the version at the beginning of operations */
|
||||||
struct ip_set_req_version *req_version =
|
struct ip_set_req_version *req_version = data;
|
||||||
(struct ip_set_req_version *) data;
|
|
||||||
if (req_version->version != IP_SET_PROTOCOL_VERSION) {
|
if (req_version->version != IP_SET_PROTOCOL_VERSION) {
|
||||||
res = -EPROTO;
|
res = -EPROTO;
|
||||||
goto done;
|
goto done;
|
||||||
@@ -1624,8 +1610,7 @@ ip_set_sockfn_get(struct sock *sk, int optval, void *user, int *len)
|
|||||||
|
|
||||||
switch (*op) {
|
switch (*op) {
|
||||||
case IP_SET_OP_VERSION: {
|
case IP_SET_OP_VERSION: {
|
||||||
struct ip_set_req_version *req_version =
|
struct ip_set_req_version *req_version = data;
|
||||||
(struct ip_set_req_version *) data;
|
|
||||||
|
|
||||||
if (*len != sizeof(struct ip_set_req_version)) {
|
if (*len != sizeof(struct ip_set_req_version)) {
|
||||||
ip_set_printk("invalid VERSION (want %zu, got %d)",
|
ip_set_printk("invalid VERSION (want %zu, got %d)",
|
||||||
@@ -1641,8 +1626,7 @@ ip_set_sockfn_get(struct sock *sk, int optval, void *user, int *len)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
case IP_SET_OP_GET_BYNAME: {
|
case IP_SET_OP_GET_BYNAME: {
|
||||||
struct ip_set_req_get_set *req_get
|
struct ip_set_req_get_set *req_get = data;
|
||||||
= (struct ip_set_req_get_set *) data;
|
|
||||||
|
|
||||||
if (*len != sizeof(struct ip_set_req_get_set)) {
|
if (*len != sizeof(struct ip_set_req_get_set)) {
|
||||||
ip_set_printk("invalid GET_BYNAME (want %zu, got %d)",
|
ip_set_printk("invalid GET_BYNAME (want %zu, got %d)",
|
||||||
@@ -1656,8 +1640,7 @@ ip_set_sockfn_get(struct sock *sk, int optval, void *user, int *len)
|
|||||||
goto copy;
|
goto copy;
|
||||||
}
|
}
|
||||||
case IP_SET_OP_GET_BYINDEX: {
|
case IP_SET_OP_GET_BYINDEX: {
|
||||||
struct ip_set_req_get_set *req_get
|
struct ip_set_req_get_set *req_get = data;
|
||||||
= (struct ip_set_req_get_set *) data;
|
|
||||||
|
|
||||||
if (*len != sizeof(struct ip_set_req_get_set)) {
|
if (*len != sizeof(struct ip_set_req_get_set)) {
|
||||||
ip_set_printk("invalid GET_BYINDEX (want %zu, got %d)",
|
ip_set_printk("invalid GET_BYINDEX (want %zu, got %d)",
|
||||||
@@ -1673,8 +1656,7 @@ ip_set_sockfn_get(struct sock *sk, int optval, void *user, int *len)
|
|||||||
goto copy;
|
goto copy;
|
||||||
}
|
}
|
||||||
case IP_SET_OP_ADT_GET: {
|
case IP_SET_OP_ADT_GET: {
|
||||||
struct ip_set_req_adt_get *req_get
|
struct ip_set_req_adt_get *req_get = data;
|
||||||
= (struct ip_set_req_adt_get *) data;
|
|
||||||
|
|
||||||
if (*len != sizeof(struct ip_set_req_adt_get)) {
|
if (*len != sizeof(struct ip_set_req_adt_get)) {
|
||||||
ip_set_printk("invalid ADT_GET (want %zu, got %d)",
|
ip_set_printk("invalid ADT_GET (want %zu, got %d)",
|
||||||
@@ -1696,8 +1678,7 @@ ip_set_sockfn_get(struct sock *sk, int optval, void *user, int *len)
|
|||||||
goto copy;
|
goto copy;
|
||||||
}
|
}
|
||||||
case IP_SET_OP_MAX_SETS: {
|
case IP_SET_OP_MAX_SETS: {
|
||||||
struct ip_set_req_max_sets *req_max_sets
|
struct ip_set_req_max_sets *req_max_sets = data;
|
||||||
= (struct ip_set_req_max_sets *) data;
|
|
||||||
ip_set_id_t i;
|
ip_set_id_t i;
|
||||||
|
|
||||||
if (*len != sizeof(struct ip_set_req_max_sets)) {
|
if (*len != sizeof(struct ip_set_req_max_sets)) {
|
||||||
@@ -1707,11 +1688,11 @@ ip_set_sockfn_get(struct sock *sk, int optval, void *user, int *len)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(req_max_sets->set.name, IPSET_TOKEN_ALL) == 0) {
|
if (SETNAME_EQ(req_max_sets->set.name, IPSET_TOKEN_ALL)) {
|
||||||
req_max_sets->set.index = IP_SET_INVALID_ID;
|
req_max_sets->set.index = IP_SET_INVALID_ID;
|
||||||
} else {
|
} else {
|
||||||
req_max_sets->set.name[IP_SET_MAXNAMELEN - 1] = '\0';
|
req_max_sets->set.name[IP_SET_MAXNAMELEN - 1] = '\0';
|
||||||
req_max_sets->set.index =
|
req_max_sets->set.index =
|
||||||
ip_set_find_byname(req_max_sets->set.name);
|
ip_set_find_byname(req_max_sets->set.name);
|
||||||
if (req_max_sets->set.index == IP_SET_INVALID_ID) {
|
if (req_max_sets->set.index == IP_SET_INVALID_ID) {
|
||||||
res = -ENOENT;
|
res = -ENOENT;
|
||||||
@@ -1726,10 +1707,9 @@ ip_set_sockfn_get(struct sock *sk, int optval, void *user, int *len)
|
|||||||
}
|
}
|
||||||
goto copy;
|
goto copy;
|
||||||
}
|
}
|
||||||
case IP_SET_OP_LIST_SIZE:
|
case IP_SET_OP_LIST_SIZE:
|
||||||
case IP_SET_OP_SAVE_SIZE: {
|
case IP_SET_OP_SAVE_SIZE: {
|
||||||
struct ip_set_req_setnames *req_setnames
|
struct ip_set_req_setnames *req_setnames = data;
|
||||||
= (struct ip_set_req_setnames *) data;
|
|
||||||
struct ip_set_name_list *name_list;
|
struct ip_set_name_list *name_list;
|
||||||
struct ip_set *set;
|
struct ip_set *set;
|
||||||
ip_set_id_t i;
|
ip_set_id_t i;
|
||||||
@@ -1747,8 +1727,7 @@ ip_set_sockfn_get(struct sock *sk, int optval, void *user, int *len)
|
|||||||
for (i = 0; i < ip_set_max; i++) {
|
for (i = 0; i < ip_set_max; i++) {
|
||||||
if (ip_set_list[i] == NULL)
|
if (ip_set_list[i] == NULL)
|
||||||
continue;
|
continue;
|
||||||
name_list = (struct ip_set_name_list *)
|
name_list = data + used;
|
||||||
(data + used);
|
|
||||||
used += sizeof(struct ip_set_name_list);
|
used += sizeof(struct ip_set_name_list);
|
||||||
if (used > copylen) {
|
if (used > copylen) {
|
||||||
res = -EAGAIN;
|
res = -EAGAIN;
|
||||||
@@ -1777,7 +1756,7 @@ ip_set_sockfn_get(struct sock *sk, int optval, void *user, int *len)
|
|||||||
+ set->type->header_size
|
+ set->type->header_size
|
||||||
+ set->type->list_members_size(set);
|
+ set->type->list_members_size(set);
|
||||||
/* Sets are identified by id in the hash */
|
/* Sets are identified by id in the hash */
|
||||||
FOREACH_HASH_DO(__set_hash_bindings_size_list,
|
FOREACH_HASH_DO(__set_hash_bindings_size_list,
|
||||||
set->id, &req_setnames->size);
|
set->id, &req_setnames->size);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1800,8 +1779,7 @@ ip_set_sockfn_get(struct sock *sk, int optval, void *user, int *len)
|
|||||||
goto copy;
|
goto copy;
|
||||||
}
|
}
|
||||||
case IP_SET_OP_LIST: {
|
case IP_SET_OP_LIST: {
|
||||||
struct ip_set_req_list *req_list
|
struct ip_set_req_list *req_list = data;
|
||||||
= (struct ip_set_req_list *) data;
|
|
||||||
ip_set_id_t i;
|
ip_set_id_t i;
|
||||||
int used;
|
int used;
|
||||||
|
|
||||||
@@ -1837,8 +1815,7 @@ ip_set_sockfn_get(struct sock *sk, int optval, void *user, int *len)
|
|||||||
goto copy;
|
goto copy;
|
||||||
}
|
}
|
||||||
case IP_SET_OP_SAVE: {
|
case IP_SET_OP_SAVE: {
|
||||||
struct ip_set_req_list *req_save
|
struct ip_set_req_list *req_save = data;
|
||||||
= (struct ip_set_req_list *) data;
|
|
||||||
ip_set_id_t i;
|
ip_set_id_t i;
|
||||||
int used;
|
int used;
|
||||||
|
|
||||||
@@ -1877,8 +1854,7 @@ ip_set_sockfn_get(struct sock *sk, int optval, void *user, int *len)
|
|||||||
goto copy;
|
goto copy;
|
||||||
}
|
}
|
||||||
case IP_SET_OP_RESTORE: {
|
case IP_SET_OP_RESTORE: {
|
||||||
struct ip_set_req_setnames *req_restore
|
struct ip_set_req_setnames *req_restore = data;
|
||||||
= (struct ip_set_req_setnames *) data;
|
|
||||||
int line;
|
int line;
|
||||||
|
|
||||||
if (*len < sizeof(struct ip_set_req_setnames)
|
if (*len < sizeof(struct ip_set_req_setnames)
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
* published by the Free Software Foundation.
|
* published by the Free Software Foundation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Kernel module implementing an ip hash set */
|
/* Kernel module implementing an ip hash set */
|
||||||
@@ -37,7 +37,7 @@ jhash_ip(const struct ip_set_iphash *map, uint16_t i, ip_set_ip_t ip)
|
|||||||
static inline __u32
|
static inline __u32
|
||||||
hash_id(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip)
|
hash_id(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
struct ip_set_iphash *map = (struct ip_set_iphash *) set->data;
|
struct ip_set_iphash *map = set->data;
|
||||||
__u32 id;
|
__u32 id;
|
||||||
u_int16_t i;
|
u_int16_t i;
|
||||||
ip_set_ip_t *elem;
|
ip_set_ip_t *elem;
|
||||||
@@ -68,8 +68,7 @@ static int
|
|||||||
testip(struct ip_set *set, const void *data, size_t size,
|
testip(struct ip_set *set, const void *data, size_t size,
|
||||||
ip_set_ip_t *hash_ip)
|
ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
struct ip_set_req_iphash *req =
|
const struct ip_set_req_iphash *req = data;
|
||||||
(struct ip_set_req_iphash *) data;
|
|
||||||
|
|
||||||
if (size != sizeof(struct ip_set_req_iphash)) {
|
if (size != sizeof(struct ip_set_req_iphash)) {
|
||||||
ip_set_printk("data length wrong (want %zu, have %zu)",
|
ip_set_printk("data length wrong (want %zu, have %zu)",
|
||||||
@@ -81,19 +80,19 @@ testip(struct ip_set *set, const void *data, size_t size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
testip_kernel(struct ip_set *set,
|
testip_kernel(struct ip_set *set,
|
||||||
const struct sk_buff *skb,
|
const struct sk_buff *skb,
|
||||||
ip_set_ip_t *hash_ip,
|
ip_set_ip_t *hash_ip,
|
||||||
const u_int32_t *flags,
|
const u_int32_t *flags,
|
||||||
unsigned char index)
|
unsigned char index)
|
||||||
{
|
{
|
||||||
return __testip(set,
|
return __testip(set,
|
||||||
ntohl(flags[index] & IPSET_SRC
|
ntohl(flags[index] & IPSET_SRC
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
||||||
? ip_hdr(skb)->saddr
|
? ip_hdr(skb)->saddr
|
||||||
: ip_hdr(skb)->daddr),
|
: ip_hdr(skb)->daddr),
|
||||||
#else
|
#else
|
||||||
? skb->nh.iph->saddr
|
? skb->nh.iph->saddr
|
||||||
: skb->nh.iph->daddr),
|
: skb->nh.iph->daddr),
|
||||||
#endif
|
#endif
|
||||||
hash_ip);
|
hash_ip);
|
||||||
@@ -130,8 +129,7 @@ static int
|
|||||||
addip(struct ip_set *set, const void *data, size_t size,
|
addip(struct ip_set *set, const void *data, size_t size,
|
||||||
ip_set_ip_t *hash_ip)
|
ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
struct ip_set_req_iphash *req =
|
const struct ip_set_req_iphash *req = data;
|
||||||
(struct ip_set_req_iphash *) data;
|
|
||||||
|
|
||||||
if (size != sizeof(struct ip_set_req_iphash)) {
|
if (size != sizeof(struct ip_set_req_iphash)) {
|
||||||
ip_set_printk("data length wrong (want %zu, have %zu)",
|
ip_set_printk("data length wrong (want %zu, have %zu)",
|
||||||
@@ -139,23 +137,23 @@ addip(struct ip_set *set, const void *data, size_t size,
|
|||||||
size);
|
size);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
return __addip((struct ip_set_iphash *) set->data, req->ip, hash_ip);
|
return __addip(set->data, req->ip, hash_ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
addip_kernel(struct ip_set *set,
|
addip_kernel(struct ip_set *set,
|
||||||
const struct sk_buff *skb,
|
const struct sk_buff *skb,
|
||||||
ip_set_ip_t *hash_ip,
|
ip_set_ip_t *hash_ip,
|
||||||
const u_int32_t *flags,
|
const u_int32_t *flags,
|
||||||
unsigned char index)
|
unsigned char index)
|
||||||
{
|
{
|
||||||
return __addip((struct ip_set_iphash *) set->data,
|
return __addip((struct ip_set_iphash *) set->data,
|
||||||
ntohl(flags[index] & IPSET_SRC
|
ntohl(flags[index] & IPSET_SRC
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
||||||
? ip_hdr(skb)->saddr
|
? ip_hdr(skb)->saddr
|
||||||
: ip_hdr(skb)->daddr),
|
: ip_hdr(skb)->daddr),
|
||||||
#else
|
#else
|
||||||
? skb->nh.iph->saddr
|
? skb->nh.iph->saddr
|
||||||
: skb->nh.iph->daddr),
|
: skb->nh.iph->daddr),
|
||||||
#endif
|
#endif
|
||||||
hash_ip);
|
hash_ip);
|
||||||
@@ -163,7 +161,7 @@ addip_kernel(struct ip_set *set,
|
|||||||
|
|
||||||
static int retry(struct ip_set *set)
|
static int retry(struct ip_set *set)
|
||||||
{
|
{
|
||||||
struct ip_set_iphash *map = (struct ip_set_iphash *) set->data;
|
struct ip_set_iphash *map = set->data;
|
||||||
ip_set_ip_t hash_ip, *elem;
|
ip_set_ip_t hash_ip, *elem;
|
||||||
void *members;
|
void *members;
|
||||||
u_int32_t i, hashsize = map->hashsize;
|
u_int32_t i, hashsize = map->hashsize;
|
||||||
@@ -185,7 +183,7 @@ static int retry(struct ip_set *set)
|
|||||||
"hashsize grows from %u to %u",
|
"hashsize grows from %u to %u",
|
||||||
set->name, map->hashsize, hashsize);
|
set->name, map->hashsize, hashsize);
|
||||||
|
|
||||||
tmp = kmalloc(sizeof(struct ip_set_iphash)
|
tmp = kmalloc(sizeof(struct ip_set_iphash)
|
||||||
+ map->probes * sizeof(uint32_t), GFP_ATOMIC);
|
+ map->probes * sizeof(uint32_t), GFP_ATOMIC);
|
||||||
if (!tmp) {
|
if (!tmp) {
|
||||||
DP("out of memory for %d bytes",
|
DP("out of memory for %d bytes",
|
||||||
@@ -207,7 +205,7 @@ static int retry(struct ip_set *set)
|
|||||||
memcpy(tmp->initval, map->initval, map->probes * sizeof(uint32_t));
|
memcpy(tmp->initval, map->initval, map->probes * sizeof(uint32_t));
|
||||||
|
|
||||||
write_lock_bh(&set->lock);
|
write_lock_bh(&set->lock);
|
||||||
map = (struct ip_set_iphash *) set->data; /* Play safe */
|
map = set->data; /* Play safe */
|
||||||
for (i = 0; i < map->hashsize && res == 0; i++) {
|
for (i = 0; i < map->hashsize && res == 0; i++) {
|
||||||
elem = HARRAY_ELEM(map->members, ip_set_ip_t *, i);
|
elem = HARRAY_ELEM(map->members, ip_set_ip_t *, i);
|
||||||
if (*elem)
|
if (*elem)
|
||||||
@@ -237,7 +235,7 @@ static int retry(struct ip_set *set)
|
|||||||
static inline int
|
static inline int
|
||||||
__delip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip)
|
__delip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
struct ip_set_iphash *map = (struct ip_set_iphash *) set->data;
|
struct ip_set_iphash *map = set->data;
|
||||||
ip_set_ip_t id, *elem;
|
ip_set_ip_t id, *elem;
|
||||||
|
|
||||||
if (!ip)
|
if (!ip)
|
||||||
@@ -258,8 +256,7 @@ static int
|
|||||||
delip(struct ip_set *set, const void *data, size_t size,
|
delip(struct ip_set *set, const void *data, size_t size,
|
||||||
ip_set_ip_t *hash_ip)
|
ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
struct ip_set_req_iphash *req =
|
const struct ip_set_req_iphash *req = data;
|
||||||
(struct ip_set_req_iphash *) data;
|
|
||||||
|
|
||||||
if (size != sizeof(struct ip_set_req_iphash)) {
|
if (size != sizeof(struct ip_set_req_iphash)) {
|
||||||
ip_set_printk("data length wrong (want %zu, have %zu)",
|
ip_set_printk("data length wrong (want %zu, have %zu)",
|
||||||
@@ -271,19 +268,19 @@ delip(struct ip_set *set, const void *data, size_t size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
delip_kernel(struct ip_set *set,
|
delip_kernel(struct ip_set *set,
|
||||||
const struct sk_buff *skb,
|
const struct sk_buff *skb,
|
||||||
ip_set_ip_t *hash_ip,
|
ip_set_ip_t *hash_ip,
|
||||||
const u_int32_t *flags,
|
const u_int32_t *flags,
|
||||||
unsigned char index)
|
unsigned char index)
|
||||||
{
|
{
|
||||||
return __delip(set,
|
return __delip(set,
|
||||||
ntohl(flags[index] & IPSET_SRC
|
ntohl(flags[index] & IPSET_SRC
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
||||||
? ip_hdr(skb)->saddr
|
? ip_hdr(skb)->saddr
|
||||||
: ip_hdr(skb)->daddr),
|
: ip_hdr(skb)->daddr),
|
||||||
#else
|
#else
|
||||||
? skb->nh.iph->saddr
|
? skb->nh.iph->saddr
|
||||||
: skb->nh.iph->daddr),
|
: skb->nh.iph->daddr),
|
||||||
#endif
|
#endif
|
||||||
hash_ip);
|
hash_ip);
|
||||||
@@ -291,8 +288,7 @@ delip_kernel(struct ip_set *set,
|
|||||||
|
|
||||||
static int create(struct ip_set *set, const void *data, size_t size)
|
static int create(struct ip_set *set, const void *data, size_t size)
|
||||||
{
|
{
|
||||||
struct ip_set_req_iphash_create *req =
|
const struct ip_set_req_iphash_create *req = data;
|
||||||
(struct ip_set_req_iphash_create *) data;
|
|
||||||
struct ip_set_iphash *map;
|
struct ip_set_iphash *map;
|
||||||
uint16_t i;
|
uint16_t i;
|
||||||
|
|
||||||
@@ -313,7 +309,7 @@ static int create(struct ip_set *set, const void *data, size_t size)
|
|||||||
return -ENOEXEC;
|
return -ENOEXEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
map = kmalloc(sizeof(struct ip_set_iphash)
|
map = kmalloc(sizeof(struct ip_set_iphash)
|
||||||
+ req->probes * sizeof(uint32_t), GFP_KERNEL);
|
+ req->probes * sizeof(uint32_t), GFP_KERNEL);
|
||||||
if (!map) {
|
if (!map) {
|
||||||
DP("out of memory for %d bytes",
|
DP("out of memory for %d bytes",
|
||||||
@@ -341,7 +337,7 @@ static int create(struct ip_set *set, const void *data, size_t size)
|
|||||||
|
|
||||||
static void destroy(struct ip_set *set)
|
static void destroy(struct ip_set *set)
|
||||||
{
|
{
|
||||||
struct ip_set_iphash *map = (struct ip_set_iphash *) set->data;
|
struct ip_set_iphash *map = set->data;
|
||||||
|
|
||||||
harray_free(map->members);
|
harray_free(map->members);
|
||||||
kfree(map);
|
kfree(map);
|
||||||
@@ -351,16 +347,15 @@ static void destroy(struct ip_set *set)
|
|||||||
|
|
||||||
static void flush(struct ip_set *set)
|
static void flush(struct ip_set *set)
|
||||||
{
|
{
|
||||||
struct ip_set_iphash *map = (struct ip_set_iphash *) set->data;
|
struct ip_set_iphash *map = set->data;
|
||||||
harray_flush(map->members, map->hashsize, sizeof(ip_set_ip_t));
|
harray_flush(map->members, map->hashsize, sizeof(ip_set_ip_t));
|
||||||
map->elements = 0;
|
map->elements = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void list_header(const struct ip_set *set, void *data)
|
static void list_header(const struct ip_set *set, void *data)
|
||||||
{
|
{
|
||||||
struct ip_set_iphash *map = (struct ip_set_iphash *) set->data;
|
struct ip_set_iphash *map = set->data;
|
||||||
struct ip_set_req_iphash_create *header =
|
struct ip_set_req_iphash_create *header = data;
|
||||||
(struct ip_set_req_iphash_create *) data;
|
|
||||||
|
|
||||||
header->hashsize = map->hashsize;
|
header->hashsize = map->hashsize;
|
||||||
header->probes = map->probes;
|
header->probes = map->probes;
|
||||||
@@ -370,14 +365,14 @@ static void list_header(const struct ip_set *set, void *data)
|
|||||||
|
|
||||||
static int list_members_size(const struct ip_set *set)
|
static int list_members_size(const struct ip_set *set)
|
||||||
{
|
{
|
||||||
struct ip_set_iphash *map = (struct ip_set_iphash *) set->data;
|
const struct ip_set_iphash *map = set->data;
|
||||||
|
|
||||||
return (map->hashsize * sizeof(ip_set_ip_t));
|
return (map->hashsize * sizeof(ip_set_ip_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void list_members(const struct ip_set *set, void *data)
|
static void list_members(const struct ip_set *set, void *data)
|
||||||
{
|
{
|
||||||
struct ip_set_iphash *map = (struct ip_set_iphash *) set->data;
|
const struct ip_set_iphash *map = set->data;
|
||||||
ip_set_ip_t i, *elem;
|
ip_set_ip_t i, *elem;
|
||||||
|
|
||||||
for (i = 0; i < map->hashsize; i++) {
|
for (i = 0; i < map->hashsize; i++) {
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
* published by the Free Software Foundation.
|
* published by the Free Software Foundation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Kernel module implementing an IP set type: the single bitmap type */
|
/* Kernel module implementing an IP set type: the single bitmap type */
|
||||||
@@ -31,7 +31,7 @@ ip_to_id(const struct ip_set_ipmap *map, ip_set_ip_t ip)
|
|||||||
static inline int
|
static inline int
|
||||||
__testip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip)
|
__testip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
struct ip_set_ipmap *map = (struct ip_set_ipmap *) set->data;
|
struct ip_set_ipmap *map = set->data;
|
||||||
|
|
||||||
if (ip < map->first_ip || ip > map->last_ip)
|
if (ip < map->first_ip || ip > map->last_ip)
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
@@ -46,8 +46,7 @@ static int
|
|||||||
testip(struct ip_set *set, const void *data, size_t size,
|
testip(struct ip_set *set, const void *data, size_t size,
|
||||||
ip_set_ip_t *hash_ip)
|
ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
struct ip_set_req_ipmap *req =
|
const struct ip_set_req_ipmap *req = data;
|
||||||
(struct ip_set_req_ipmap *) data;
|
|
||||||
|
|
||||||
if (size != sizeof(struct ip_set_req_ipmap)) {
|
if (size != sizeof(struct ip_set_req_ipmap)) {
|
||||||
ip_set_printk("data length wrong (want %zu, have %zu)",
|
ip_set_printk("data length wrong (want %zu, have %zu)",
|
||||||
@@ -59,7 +58,7 @@ testip(struct ip_set *set, const void *data, size_t size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
testip_kernel(struct ip_set *set,
|
testip_kernel(struct ip_set *set,
|
||||||
const struct sk_buff *skb,
|
const struct sk_buff *skb,
|
||||||
ip_set_ip_t *hash_ip,
|
ip_set_ip_t *hash_ip,
|
||||||
const u_int32_t *flags,
|
const u_int32_t *flags,
|
||||||
@@ -68,10 +67,10 @@ testip_kernel(struct ip_set *set,
|
|||||||
int res = __testip(set,
|
int res = __testip(set,
|
||||||
ntohl(flags[index] & IPSET_SRC
|
ntohl(flags[index] & IPSET_SRC
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
||||||
? ip_hdr(skb)->saddr
|
? ip_hdr(skb)->saddr
|
||||||
: ip_hdr(skb)->daddr),
|
: ip_hdr(skb)->daddr),
|
||||||
#else
|
#else
|
||||||
? skb->nh.iph->saddr
|
? skb->nh.iph->saddr
|
||||||
: skb->nh.iph->daddr),
|
: skb->nh.iph->daddr),
|
||||||
#endif
|
#endif
|
||||||
hash_ip);
|
hash_ip);
|
||||||
@@ -81,7 +80,7 @@ testip_kernel(struct ip_set *set,
|
|||||||
static inline int
|
static inline int
|
||||||
__addip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip)
|
__addip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
struct ip_set_ipmap *map = (struct ip_set_ipmap *) set->data;
|
struct ip_set_ipmap *map = set->data;
|
||||||
|
|
||||||
if (ip < map->first_ip || ip > map->last_ip)
|
if (ip < map->first_ip || ip > map->last_ip)
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
@@ -98,8 +97,7 @@ static int
|
|||||||
addip(struct ip_set *set, const void *data, size_t size,
|
addip(struct ip_set *set, const void *data, size_t size,
|
||||||
ip_set_ip_t *hash_ip)
|
ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
struct ip_set_req_ipmap *req =
|
const struct ip_set_req_ipmap *req = data;
|
||||||
(struct ip_set_req_ipmap *) data;
|
|
||||||
|
|
||||||
if (size != sizeof(struct ip_set_req_ipmap)) {
|
if (size != sizeof(struct ip_set_req_ipmap)) {
|
||||||
ip_set_printk("data length wrong (want %zu, have %zu)",
|
ip_set_printk("data length wrong (want %zu, have %zu)",
|
||||||
@@ -112,28 +110,28 @@ addip(struct ip_set *set, const void *data, size_t size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
addip_kernel(struct ip_set *set,
|
addip_kernel(struct ip_set *set,
|
||||||
const struct sk_buff *skb,
|
const struct sk_buff *skb,
|
||||||
ip_set_ip_t *hash_ip,
|
ip_set_ip_t *hash_ip,
|
||||||
const u_int32_t *flags,
|
const u_int32_t *flags,
|
||||||
unsigned char index)
|
unsigned char index)
|
||||||
{
|
{
|
||||||
return __addip(set,
|
return __addip(set,
|
||||||
ntohl(flags[index] & IPSET_SRC
|
ntohl(flags[index] & IPSET_SRC
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
||||||
? ip_hdr(skb)->saddr
|
? ip_hdr(skb)->saddr
|
||||||
: ip_hdr(skb)->daddr),
|
: ip_hdr(skb)->daddr),
|
||||||
#else
|
#else
|
||||||
? skb->nh.iph->saddr
|
? skb->nh.iph->saddr
|
||||||
: skb->nh.iph->daddr),
|
: skb->nh.iph->daddr),
|
||||||
#endif
|
#endif
|
||||||
hash_ip);
|
hash_ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
__delip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip)
|
__delip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
struct ip_set_ipmap *map = (struct ip_set_ipmap *) set->data;
|
struct ip_set_ipmap *map = set->data;
|
||||||
|
|
||||||
if (ip < map->first_ip || ip > map->last_ip)
|
if (ip < map->first_ip || ip > map->last_ip)
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
@@ -150,8 +148,7 @@ static int
|
|||||||
delip(struct ip_set *set, const void *data, size_t size,
|
delip(struct ip_set *set, const void *data, size_t size,
|
||||||
ip_set_ip_t *hash_ip)
|
ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
struct ip_set_req_ipmap *req =
|
const struct ip_set_req_ipmap *req = data;
|
||||||
(struct ip_set_req_ipmap *) data;
|
|
||||||
|
|
||||||
if (size != sizeof(struct ip_set_req_ipmap)) {
|
if (size != sizeof(struct ip_set_req_ipmap)) {
|
||||||
ip_set_printk("data length wrong (want %zu, have %zu)",
|
ip_set_printk("data length wrong (want %zu, have %zu)",
|
||||||
@@ -170,12 +167,12 @@ delip_kernel(struct ip_set *set,
|
|||||||
unsigned char index)
|
unsigned char index)
|
||||||
{
|
{
|
||||||
return __delip(set,
|
return __delip(set,
|
||||||
ntohl(flags[index] & IPSET_SRC
|
ntohl(flags[index] & IPSET_SRC
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
||||||
? ip_hdr(skb)->saddr
|
? ip_hdr(skb)->saddr
|
||||||
: ip_hdr(skb)->daddr),
|
: ip_hdr(skb)->daddr),
|
||||||
#else
|
#else
|
||||||
? skb->nh.iph->saddr
|
? skb->nh.iph->saddr
|
||||||
: skb->nh.iph->daddr),
|
: skb->nh.iph->daddr),
|
||||||
#endif
|
#endif
|
||||||
hash_ip);
|
hash_ip);
|
||||||
@@ -184,8 +181,7 @@ delip_kernel(struct ip_set *set,
|
|||||||
static int create(struct ip_set *set, const void *data, size_t size)
|
static int create(struct ip_set *set, const void *data, size_t size)
|
||||||
{
|
{
|
||||||
int newbytes;
|
int newbytes;
|
||||||
struct ip_set_req_ipmap_create *req =
|
const struct ip_set_req_ipmap_create *req = data;
|
||||||
(struct ip_set_req_ipmap_create *) data;
|
|
||||||
struct ip_set_ipmap *map;
|
struct ip_set_ipmap *map;
|
||||||
|
|
||||||
if (size != sizeof(struct ip_set_req_ipmap_create)) {
|
if (size != sizeof(struct ip_set_req_ipmap_create)) {
|
||||||
@@ -256,7 +252,7 @@ static int create(struct ip_set *set, const void *data, size_t size)
|
|||||||
|
|
||||||
static void destroy(struct ip_set *set)
|
static void destroy(struct ip_set *set)
|
||||||
{
|
{
|
||||||
struct ip_set_ipmap *map = (struct ip_set_ipmap *) set->data;
|
struct ip_set_ipmap *map = set->data;
|
||||||
|
|
||||||
kfree(map->members);
|
kfree(map->members);
|
||||||
kfree(map);
|
kfree(map);
|
||||||
@@ -266,15 +262,14 @@ static void destroy(struct ip_set *set)
|
|||||||
|
|
||||||
static void flush(struct ip_set *set)
|
static void flush(struct ip_set *set)
|
||||||
{
|
{
|
||||||
struct ip_set_ipmap *map = (struct ip_set_ipmap *) set->data;
|
struct ip_set_ipmap *map = set->data;
|
||||||
memset(map->members, 0, bitmap_bytes(0, map->sizeid - 1));
|
memset(map->members, 0, bitmap_bytes(0, map->sizeid - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void list_header(const struct ip_set *set, void *data)
|
static void list_header(const struct ip_set *set, void *data)
|
||||||
{
|
{
|
||||||
struct ip_set_ipmap *map = (struct ip_set_ipmap *) set->data;
|
const struct ip_set_ipmap *map = set->data;
|
||||||
struct ip_set_req_ipmap_create *header =
|
struct ip_set_req_ipmap_create *header = data;
|
||||||
(struct ip_set_req_ipmap_create *) data;
|
|
||||||
|
|
||||||
header->from = map->first_ip;
|
header->from = map->first_ip;
|
||||||
header->to = map->last_ip;
|
header->to = map->last_ip;
|
||||||
@@ -283,14 +278,14 @@ static void list_header(const struct ip_set *set, void *data)
|
|||||||
|
|
||||||
static int list_members_size(const struct ip_set *set)
|
static int list_members_size(const struct ip_set *set)
|
||||||
{
|
{
|
||||||
struct ip_set_ipmap *map = (struct ip_set_ipmap *) set->data;
|
const struct ip_set_ipmap *map = set->data;
|
||||||
|
|
||||||
return bitmap_bytes(0, map->sizeid - 1);
|
return bitmap_bytes(0, map->sizeid - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void list_members(const struct ip_set *set, void *data)
|
static void list_members(const struct ip_set *set, void *data)
|
||||||
{
|
{
|
||||||
struct ip_set_ipmap *map = (struct ip_set_ipmap *) set->data;
|
const struct ip_set_ipmap *map = set->data;
|
||||||
int bytes = bitmap_bytes(0, map->sizeid - 1);
|
int bytes = bitmap_bytes(0, map->sizeid - 1);
|
||||||
|
|
||||||
memcpy(data, map->members, bytes);
|
memcpy(data, map->members, bytes);
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
* published by the Free Software Foundation.
|
* published by the Free Software Foundation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Kernel module implementing an ip+port hash set */
|
/* Kernel module implementing an ip+port hash set */
|
||||||
@@ -94,8 +94,7 @@ static inline __u32
|
|||||||
hash_id(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t port,
|
hash_id(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t port,
|
||||||
ip_set_ip_t *hash_ip)
|
ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
struct ip_set_ipporthash *map =
|
struct ip_set_ipporthash *map = set->data;
|
||||||
(struct ip_set_ipporthash *) set->data;
|
|
||||||
__u32 id;
|
__u32 id;
|
||||||
u_int16_t i;
|
u_int16_t i;
|
||||||
ip_set_ip_t *elem;
|
ip_set_ip_t *elem;
|
||||||
@@ -120,7 +119,7 @@ static inline int
|
|||||||
__testip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t port,
|
__testip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t port,
|
||||||
ip_set_ip_t *hash_ip)
|
ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
struct ip_set_ipporthash *map = (struct ip_set_ipporthash *) set->data;
|
struct ip_set_ipporthash *map = set->data;
|
||||||
|
|
||||||
if (ip < map->first_ip || ip > map->last_ip)
|
if (ip < map->first_ip || ip > map->last_ip)
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
@@ -132,8 +131,7 @@ static int
|
|||||||
testip(struct ip_set *set, const void *data, size_t size,
|
testip(struct ip_set *set, const void *data, size_t size,
|
||||||
ip_set_ip_t *hash_ip)
|
ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
struct ip_set_req_ipporthash *req =
|
const struct ip_set_req_ipporthash *req = data;
|
||||||
(struct ip_set_req_ipporthash *) data;
|
|
||||||
|
|
||||||
if (size != sizeof(struct ip_set_req_ipporthash)) {
|
if (size != sizeof(struct ip_set_req_ipporthash)) {
|
||||||
ip_set_printk("data length wrong (want %zu, have %zu)",
|
ip_set_printk("data length wrong (want %zu, have %zu)",
|
||||||
@@ -145,7 +143,7 @@ testip(struct ip_set *set, const void *data, size_t size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
testip_kernel(struct ip_set *set,
|
testip_kernel(struct ip_set *set,
|
||||||
const struct sk_buff *skb,
|
const struct sk_buff *skb,
|
||||||
ip_set_ip_t *hash_ip,
|
ip_set_ip_t *hash_ip,
|
||||||
const u_int32_t *flags,
|
const u_int32_t *flags,
|
||||||
@@ -169,18 +167,18 @@ testip_kernel(struct ip_set *set,
|
|||||||
NIPQUAD(skb->nh.iph->daddr));
|
NIPQUAD(skb->nh.iph->daddr));
|
||||||
#endif
|
#endif
|
||||||
DP("flag %s port %u",
|
DP("flag %s port %u",
|
||||||
flags[index+1] & IPSET_SRC ? "SRC" : "DST",
|
flags[index+1] & IPSET_SRC ? "SRC" : "DST",
|
||||||
port);
|
port);
|
||||||
if (port == INVALID_PORT)
|
if (port == INVALID_PORT)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
res = __testip(set,
|
res = __testip(set,
|
||||||
ntohl(flags[index] & IPSET_SRC
|
ntohl(flags[index] & IPSET_SRC
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
||||||
? ip_hdr(skb)->saddr
|
? ip_hdr(skb)->saddr
|
||||||
: ip_hdr(skb)->daddr),
|
: ip_hdr(skb)->daddr),
|
||||||
#else
|
#else
|
||||||
? skb->nh.iph->saddr
|
? skb->nh.iph->saddr
|
||||||
: skb->nh.iph->daddr),
|
: skb->nh.iph->daddr),
|
||||||
#endif
|
#endif
|
||||||
port,
|
port,
|
||||||
@@ -229,8 +227,7 @@ static int
|
|||||||
addip(struct ip_set *set, const void *data, size_t size,
|
addip(struct ip_set *set, const void *data, size_t size,
|
||||||
ip_set_ip_t *hash_ip)
|
ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
struct ip_set_req_ipporthash *req =
|
const struct ip_set_req_ipporthash *req = data;
|
||||||
(struct ip_set_req_ipporthash *) data;
|
|
||||||
|
|
||||||
if (size != sizeof(struct ip_set_req_ipporthash)) {
|
if (size != sizeof(struct ip_set_req_ipporthash)) {
|
||||||
ip_set_printk("data length wrong (want %zu, have %zu)",
|
ip_set_printk("data length wrong (want %zu, have %zu)",
|
||||||
@@ -238,12 +235,11 @@ addip(struct ip_set *set, const void *data, size_t size,
|
|||||||
size);
|
size);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
return __addip((struct ip_set_ipporthash *) set->data,
|
return __addip(set->data, req->ip, req->port, hash_ip);
|
||||||
req->ip, req->port, hash_ip);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
addip_kernel(struct ip_set *set,
|
addip_kernel(struct ip_set *set,
|
||||||
const struct sk_buff *skb,
|
const struct sk_buff *skb,
|
||||||
ip_set_ip_t *hash_ip,
|
ip_set_ip_t *hash_ip,
|
||||||
const u_int32_t *flags,
|
const u_int32_t *flags,
|
||||||
@@ -265,19 +261,19 @@ addip_kernel(struct ip_set *set,
|
|||||||
NIPQUAD(skb->nh.iph->saddr),
|
NIPQUAD(skb->nh.iph->saddr),
|
||||||
NIPQUAD(skb->nh.iph->daddr));
|
NIPQUAD(skb->nh.iph->daddr));
|
||||||
#endif
|
#endif
|
||||||
DP("flag %s port %u",
|
DP("flag %s port %u",
|
||||||
flags[index+1] & IPSET_SRC ? "SRC" : "DST",
|
flags[index+1] & IPSET_SRC ? "SRC" : "DST",
|
||||||
port);
|
port);
|
||||||
if (port == INVALID_PORT)
|
if (port == INVALID_PORT)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
return __addip((struct ip_set_ipporthash *) set->data,
|
return __addip(set->data,
|
||||||
ntohl(flags[index] & IPSET_SRC
|
ntohl(flags[index] & IPSET_SRC
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
||||||
? ip_hdr(skb)->saddr
|
? ip_hdr(skb)->saddr
|
||||||
: ip_hdr(skb)->daddr),
|
: ip_hdr(skb)->daddr),
|
||||||
#else
|
#else
|
||||||
? skb->nh.iph->saddr
|
? skb->nh.iph->saddr
|
||||||
: skb->nh.iph->daddr),
|
: skb->nh.iph->daddr),
|
||||||
#endif
|
#endif
|
||||||
port,
|
port,
|
||||||
@@ -286,7 +282,7 @@ addip_kernel(struct ip_set *set,
|
|||||||
|
|
||||||
static int retry(struct ip_set *set)
|
static int retry(struct ip_set *set)
|
||||||
{
|
{
|
||||||
struct ip_set_ipporthash *map = (struct ip_set_ipporthash *) set->data;
|
struct ip_set_ipporthash *map = set->data;
|
||||||
ip_set_ip_t *elem;
|
ip_set_ip_t *elem;
|
||||||
void *members;
|
void *members;
|
||||||
u_int32_t i, hashsize = map->hashsize;
|
u_int32_t i, hashsize = map->hashsize;
|
||||||
@@ -308,7 +304,7 @@ static int retry(struct ip_set *set)
|
|||||||
"hashsize grows from %u to %u",
|
"hashsize grows from %u to %u",
|
||||||
set->name, map->hashsize, hashsize);
|
set->name, map->hashsize, hashsize);
|
||||||
|
|
||||||
tmp = kmalloc(sizeof(struct ip_set_ipporthash)
|
tmp = kmalloc(sizeof(struct ip_set_ipporthash)
|
||||||
+ map->probes * sizeof(uint32_t), GFP_ATOMIC);
|
+ map->probes * sizeof(uint32_t), GFP_ATOMIC);
|
||||||
if (!tmp) {
|
if (!tmp) {
|
||||||
DP("out of memory for %d bytes",
|
DP("out of memory for %d bytes",
|
||||||
@@ -331,7 +327,7 @@ static int retry(struct ip_set *set)
|
|||||||
memcpy(tmp->initval, map->initval, map->probes * sizeof(uint32_t));
|
memcpy(tmp->initval, map->initval, map->probes * sizeof(uint32_t));
|
||||||
|
|
||||||
write_lock_bh(&set->lock);
|
write_lock_bh(&set->lock);
|
||||||
map = (struct ip_set_ipporthash *) set->data; /* Play safe */
|
map = set->data; /* Play safe */
|
||||||
for (i = 0; i < map->hashsize && res == 0; i++) {
|
for (i = 0; i < map->hashsize && res == 0; i++) {
|
||||||
elem = HARRAY_ELEM(map->members, ip_set_ip_t *, i);
|
elem = HARRAY_ELEM(map->members, ip_set_ip_t *, i);
|
||||||
if (*elem)
|
if (*elem)
|
||||||
@@ -362,7 +358,7 @@ static inline int
|
|||||||
__delip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t port,
|
__delip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t port,
|
||||||
ip_set_ip_t *hash_ip)
|
ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
struct ip_set_ipporthash *map = (struct ip_set_ipporthash *) set->data;
|
struct ip_set_ipporthash *map = set->data;
|
||||||
ip_set_ip_t id;
|
ip_set_ip_t id;
|
||||||
ip_set_ip_t *elem;
|
ip_set_ip_t *elem;
|
||||||
|
|
||||||
@@ -385,8 +381,7 @@ static int
|
|||||||
delip(struct ip_set *set, const void *data, size_t size,
|
delip(struct ip_set *set, const void *data, size_t size,
|
||||||
ip_set_ip_t *hash_ip)
|
ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
struct ip_set_req_ipporthash *req =
|
const struct ip_set_req_ipporthash *req = data;
|
||||||
(struct ip_set_req_ipporthash *) data;
|
|
||||||
|
|
||||||
if (size != sizeof(struct ip_set_req_ipporthash)) {
|
if (size != sizeof(struct ip_set_req_ipporthash)) {
|
||||||
ip_set_printk("data length wrong (want %zu, have %zu)",
|
ip_set_printk("data length wrong (want %zu, have %zu)",
|
||||||
@@ -398,7 +393,7 @@ delip(struct ip_set *set, const void *data, size_t size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
delip_kernel(struct ip_set *set,
|
delip_kernel(struct ip_set *set,
|
||||||
const struct sk_buff *skb,
|
const struct sk_buff *skb,
|
||||||
ip_set_ip_t *hash_ip,
|
ip_set_ip_t *hash_ip,
|
||||||
const u_int32_t *flags,
|
const u_int32_t *flags,
|
||||||
@@ -421,18 +416,18 @@ delip_kernel(struct ip_set *set,
|
|||||||
NIPQUAD(skb->nh.iph->daddr));
|
NIPQUAD(skb->nh.iph->daddr));
|
||||||
#endif
|
#endif
|
||||||
DP("flag %s port %u",
|
DP("flag %s port %u",
|
||||||
flags[index+1] & IPSET_SRC ? "SRC" : "DST",
|
flags[index+1] & IPSET_SRC ? "SRC" : "DST",
|
||||||
port);
|
port);
|
||||||
if (port == INVALID_PORT)
|
if (port == INVALID_PORT)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
return __delip(set,
|
return __delip(set,
|
||||||
ntohl(flags[index] & IPSET_SRC
|
ntohl(flags[index] & IPSET_SRC
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
||||||
? ip_hdr(skb)->saddr
|
? ip_hdr(skb)->saddr
|
||||||
: ip_hdr(skb)->daddr),
|
: ip_hdr(skb)->daddr),
|
||||||
#else
|
#else
|
||||||
? skb->nh.iph->saddr
|
? skb->nh.iph->saddr
|
||||||
: skb->nh.iph->daddr),
|
: skb->nh.iph->daddr),
|
||||||
#endif
|
#endif
|
||||||
port,
|
port,
|
||||||
@@ -441,8 +436,7 @@ delip_kernel(struct ip_set *set,
|
|||||||
|
|
||||||
static int create(struct ip_set *set, const void *data, size_t size)
|
static int create(struct ip_set *set, const void *data, size_t size)
|
||||||
{
|
{
|
||||||
struct ip_set_req_ipporthash_create *req =
|
const struct ip_set_req_ipporthash_create *req = data;
|
||||||
(struct ip_set_req_ipporthash_create *) data;
|
|
||||||
struct ip_set_ipporthash *map;
|
struct ip_set_ipporthash *map;
|
||||||
uint16_t i;
|
uint16_t i;
|
||||||
|
|
||||||
@@ -463,7 +457,7 @@ static int create(struct ip_set *set, const void *data, size_t size)
|
|||||||
return -ENOEXEC;
|
return -ENOEXEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
map = kmalloc(sizeof(struct ip_set_ipporthash)
|
map = kmalloc(sizeof(struct ip_set_ipporthash)
|
||||||
+ req->probes * sizeof(uint32_t), GFP_KERNEL);
|
+ req->probes * sizeof(uint32_t), GFP_KERNEL);
|
||||||
if (!map) {
|
if (!map) {
|
||||||
DP("out of memory for %d bytes",
|
DP("out of memory for %d bytes",
|
||||||
@@ -492,7 +486,7 @@ static int create(struct ip_set *set, const void *data, size_t size)
|
|||||||
|
|
||||||
static void destroy(struct ip_set *set)
|
static void destroy(struct ip_set *set)
|
||||||
{
|
{
|
||||||
struct ip_set_ipporthash *map = (struct ip_set_ipporthash *) set->data;
|
struct ip_set_ipporthash *map = set->data;
|
||||||
|
|
||||||
harray_free(map->members);
|
harray_free(map->members);
|
||||||
kfree(map);
|
kfree(map);
|
||||||
@@ -502,16 +496,15 @@ static void destroy(struct ip_set *set)
|
|||||||
|
|
||||||
static void flush(struct ip_set *set)
|
static void flush(struct ip_set *set)
|
||||||
{
|
{
|
||||||
struct ip_set_ipporthash *map = (struct ip_set_ipporthash *) set->data;
|
struct ip_set_ipporthash *map = set->data;
|
||||||
harray_flush(map->members, map->hashsize, sizeof(ip_set_ip_t));
|
harray_flush(map->members, map->hashsize, sizeof(ip_set_ip_t));
|
||||||
map->elements = 0;
|
map->elements = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void list_header(const struct ip_set *set, void *data)
|
static void list_header(const struct ip_set *set, void *data)
|
||||||
{
|
{
|
||||||
struct ip_set_ipporthash *map = (struct ip_set_ipporthash *) set->data;
|
const struct ip_set_ipporthash *map = set->data;
|
||||||
struct ip_set_req_ipporthash_create *header =
|
struct ip_set_req_ipporthash_create *header = data;
|
||||||
(struct ip_set_req_ipporthash_create *) data;
|
|
||||||
|
|
||||||
header->hashsize = map->hashsize;
|
header->hashsize = map->hashsize;
|
||||||
header->probes = map->probes;
|
header->probes = map->probes;
|
||||||
@@ -522,14 +515,14 @@ static void list_header(const struct ip_set *set, void *data)
|
|||||||
|
|
||||||
static int list_members_size(const struct ip_set *set)
|
static int list_members_size(const struct ip_set *set)
|
||||||
{
|
{
|
||||||
struct ip_set_ipporthash *map = (struct ip_set_ipporthash *) set->data;
|
const struct ip_set_ipporthash *map = set->data;
|
||||||
|
|
||||||
return (map->hashsize * sizeof(ip_set_ip_t));
|
return (map->hashsize * sizeof(ip_set_ip_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void list_members(const struct ip_set *set, void *data)
|
static void list_members(const struct ip_set *set, void *data)
|
||||||
{
|
{
|
||||||
struct ip_set_ipporthash *map = (struct ip_set_ipporthash *) set->data;
|
const struct ip_set_ipporthash *map = set->data;
|
||||||
ip_set_ip_t i, *elem;
|
ip_set_ip_t i, *elem;
|
||||||
|
|
||||||
for (i = 0; i < map->hashsize; i++) {
|
for (i = 0; i < map->hashsize; i++) {
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
* published by the Free Software Foundation.
|
* published by the Free Software Foundation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Kernel module implementing an IP set type: the iptree type */
|
/* Kernel module implementing an IP set type: the iptree type */
|
||||||
@@ -31,8 +31,8 @@ static int limit = MAX_RANGE;
|
|||||||
|
|
||||||
/* Garbage collection interval in seconds: */
|
/* Garbage collection interval in seconds: */
|
||||||
#define IPTREE_GC_TIME 5*60
|
#define IPTREE_GC_TIME 5*60
|
||||||
/* Sleep so many milliseconds before trying again
|
/* Sleep so many milliseconds before trying again
|
||||||
* to delete the gc timer at destroying/flushing a set */
|
* to delete the gc timer at destroying/flushing a set */
|
||||||
#define IPTREE_DESTROY_SLEEP 100
|
#define IPTREE_DESTROY_SLEEP 100
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
|
||||||
@@ -71,7 +71,7 @@ static kmem_cache_t *leaf_cachep;
|
|||||||
static inline int
|
static inline int
|
||||||
__testip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip)
|
__testip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
struct ip_set_iptree *map = (struct ip_set_iptree *) set->data;
|
struct ip_set_iptree *map = set->data;
|
||||||
struct ip_set_iptreeb *btree;
|
struct ip_set_iptreeb *btree;
|
||||||
struct ip_set_iptreec *ctree;
|
struct ip_set_iptreec *ctree;
|
||||||
struct ip_set_iptreed *dtree;
|
struct ip_set_iptreed *dtree;
|
||||||
@@ -96,8 +96,7 @@ static int
|
|||||||
testip(struct ip_set *set, const void *data, size_t size,
|
testip(struct ip_set *set, const void *data, size_t size,
|
||||||
ip_set_ip_t *hash_ip)
|
ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
struct ip_set_req_iptree *req =
|
const struct ip_set_req_iptree *req = data;
|
||||||
(struct ip_set_req_iptree *) data;
|
|
||||||
|
|
||||||
if (size != sizeof(struct ip_set_req_iptree)) {
|
if (size != sizeof(struct ip_set_req_iptree)) {
|
||||||
ip_set_printk("data length wrong (want %zu, have %zu)",
|
ip_set_printk("data length wrong (want %zu, have %zu)",
|
||||||
@@ -109,7 +108,7 @@ testip(struct ip_set *set, const void *data, size_t size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
testip_kernel(struct ip_set *set,
|
testip_kernel(struct ip_set *set,
|
||||||
const struct sk_buff *skb,
|
const struct sk_buff *skb,
|
||||||
ip_set_ip_t *hash_ip,
|
ip_set_ip_t *hash_ip,
|
||||||
const u_int32_t *flags,
|
const u_int32_t *flags,
|
||||||
@@ -128,12 +127,12 @@ testip_kernel(struct ip_set *set,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
res = __testip(set,
|
res = __testip(set,
|
||||||
ntohl(flags[index] & IPSET_SRC
|
ntohl(flags[index] & IPSET_SRC
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
||||||
? ip_hdr(skb)->saddr
|
? ip_hdr(skb)->saddr
|
||||||
: ip_hdr(skb)->daddr),
|
: ip_hdr(skb)->daddr),
|
||||||
#else
|
#else
|
||||||
? skb->nh.iph->saddr
|
? skb->nh.iph->saddr
|
||||||
: skb->nh.iph->daddr),
|
: skb->nh.iph->daddr),
|
||||||
#endif
|
#endif
|
||||||
hash_ip);
|
hash_ip);
|
||||||
@@ -159,7 +158,7 @@ static inline int
|
|||||||
__addip(struct ip_set *set, ip_set_ip_t ip, unsigned int timeout,
|
__addip(struct ip_set *set, ip_set_ip_t ip, unsigned int timeout,
|
||||||
ip_set_ip_t *hash_ip)
|
ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
struct ip_set_iptree *map = (struct ip_set_iptree *) set->data;
|
struct ip_set_iptree *map = set->data;
|
||||||
struct ip_set_iptreeb *btree;
|
struct ip_set_iptreeb *btree;
|
||||||
struct ip_set_iptreec *ctree;
|
struct ip_set_iptreec *ctree;
|
||||||
struct ip_set_iptreed *dtree;
|
struct ip_set_iptreed *dtree;
|
||||||
@@ -194,9 +193,8 @@ static int
|
|||||||
addip(struct ip_set *set, const void *data, size_t size,
|
addip(struct ip_set *set, const void *data, size_t size,
|
||||||
ip_set_ip_t *hash_ip)
|
ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
struct ip_set_iptree *map = (struct ip_set_iptree *) set->data;
|
struct ip_set_iptree *map = set->data;
|
||||||
struct ip_set_req_iptree *req =
|
const struct ip_set_req_iptree *req = data;
|
||||||
(struct ip_set_req_iptree *) data;
|
|
||||||
|
|
||||||
if (size != sizeof(struct ip_set_req_iptree)) {
|
if (size != sizeof(struct ip_set_req_iptree)) {
|
||||||
ip_set_printk("data length wrong (want %zu, have %zu)",
|
ip_set_printk("data length wrong (want %zu, have %zu)",
|
||||||
@@ -211,21 +209,21 @@ addip(struct ip_set *set, const void *data, size_t size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
addip_kernel(struct ip_set *set,
|
addip_kernel(struct ip_set *set,
|
||||||
const struct sk_buff *skb,
|
const struct sk_buff *skb,
|
||||||
ip_set_ip_t *hash_ip,
|
ip_set_ip_t *hash_ip,
|
||||||
const u_int32_t *flags,
|
const u_int32_t *flags,
|
||||||
unsigned char index)
|
unsigned char index)
|
||||||
{
|
{
|
||||||
struct ip_set_iptree *map = (struct ip_set_iptree *) set->data;
|
struct ip_set_iptree *map = set->data;
|
||||||
|
|
||||||
return __addip(set,
|
return __addip(set,
|
||||||
ntohl(flags[index] & IPSET_SRC
|
ntohl(flags[index] & IPSET_SRC
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
||||||
? ip_hdr(skb)->saddr
|
? ip_hdr(skb)->saddr
|
||||||
: ip_hdr(skb)->daddr),
|
: ip_hdr(skb)->daddr),
|
||||||
#else
|
#else
|
||||||
? skb->nh.iph->saddr
|
? skb->nh.iph->saddr
|
||||||
: skb->nh.iph->daddr),
|
: skb->nh.iph->daddr),
|
||||||
#endif
|
#endif
|
||||||
map->timeout,
|
map->timeout,
|
||||||
@@ -239,10 +237,10 @@ addip_kernel(struct ip_set *set,
|
|||||||
return -EEXIST; \
|
return -EEXIST; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
__delip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip)
|
__delip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
struct ip_set_iptree *map = (struct ip_set_iptree *) set->data;
|
struct ip_set_iptree *map = set->data;
|
||||||
struct ip_set_iptreeb *btree;
|
struct ip_set_iptreeb *btree;
|
||||||
struct ip_set_iptreec *ctree;
|
struct ip_set_iptreec *ctree;
|
||||||
struct ip_set_iptreed *dtree;
|
struct ip_set_iptreed *dtree;
|
||||||
@@ -269,8 +267,7 @@ static int
|
|||||||
delip(struct ip_set *set, const void *data, size_t size,
|
delip(struct ip_set *set, const void *data, size_t size,
|
||||||
ip_set_ip_t *hash_ip)
|
ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
struct ip_set_req_iptree *req =
|
const struct ip_set_req_iptree *req = data;
|
||||||
(struct ip_set_req_iptree *) data;
|
|
||||||
|
|
||||||
if (size != sizeof(struct ip_set_req_iptree)) {
|
if (size != sizeof(struct ip_set_req_iptree)) {
|
||||||
ip_set_printk("data length wrong (want %zu, have %zu)",
|
ip_set_printk("data length wrong (want %zu, have %zu)",
|
||||||
@@ -282,19 +279,19 @@ delip(struct ip_set *set, const void *data, size_t size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
delip_kernel(struct ip_set *set,
|
delip_kernel(struct ip_set *set,
|
||||||
const struct sk_buff *skb,
|
const struct sk_buff *skb,
|
||||||
ip_set_ip_t *hash_ip,
|
ip_set_ip_t *hash_ip,
|
||||||
const u_int32_t *flags,
|
const u_int32_t *flags,
|
||||||
unsigned char index)
|
unsigned char index)
|
||||||
{
|
{
|
||||||
return __delip(set,
|
return __delip(set,
|
||||||
ntohl(flags[index] & IPSET_SRC
|
ntohl(flags[index] & IPSET_SRC
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
||||||
? ip_hdr(skb)->saddr
|
? ip_hdr(skb)->saddr
|
||||||
: ip_hdr(skb)->daddr),
|
: ip_hdr(skb)->daddr),
|
||||||
#else
|
#else
|
||||||
? skb->nh.iph->saddr
|
? skb->nh.iph->saddr
|
||||||
: skb->nh.iph->daddr),
|
: skb->nh.iph->daddr),
|
||||||
#endif
|
#endif
|
||||||
hash_ip);
|
hash_ip);
|
||||||
@@ -310,8 +307,8 @@ delip_kernel(struct ip_set *set,
|
|||||||
|
|
||||||
static void ip_tree_gc(unsigned long ul_set)
|
static void ip_tree_gc(unsigned long ul_set)
|
||||||
{
|
{
|
||||||
struct ip_set *set = (void *) ul_set;
|
struct ip_set *set = (struct ip_set *) ul_set;
|
||||||
struct ip_set_iptree *map = (struct ip_set_iptree *) set->data;
|
struct ip_set_iptree *map = set->data;
|
||||||
struct ip_set_iptreeb *btree;
|
struct ip_set_iptreeb *btree;
|
||||||
struct ip_set_iptreec *ctree;
|
struct ip_set_iptreec *ctree;
|
||||||
struct ip_set_iptreed *dtree;
|
struct ip_set_iptreed *dtree;
|
||||||
@@ -380,7 +377,7 @@ static void ip_tree_gc(unsigned long ul_set)
|
|||||||
|
|
||||||
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 = (struct ip_set_iptree *) set->data;
|
struct ip_set_iptree *map = set->data;
|
||||||
|
|
||||||
/* Even if there is no timeout for the entries,
|
/* Even if there is no timeout for the entries,
|
||||||
* we still have to call gc because delete
|
* we still have to call gc because delete
|
||||||
@@ -395,8 +392,7 @@ static inline void init_gc_timer(struct ip_set *set)
|
|||||||
|
|
||||||
static int create(struct ip_set *set, const void *data, size_t size)
|
static int create(struct ip_set *set, const void *data, size_t size)
|
||||||
{
|
{
|
||||||
struct ip_set_req_iptree_create *req =
|
const struct ip_set_req_iptree_create *req = data;
|
||||||
(struct ip_set_req_iptree_create *) data;
|
|
||||||
struct ip_set_iptree *map;
|
struct ip_set_iptree *map;
|
||||||
|
|
||||||
if (size != sizeof(struct ip_set_req_iptree_create)) {
|
if (size != sizeof(struct ip_set_req_iptree_create)) {
|
||||||
@@ -443,7 +439,7 @@ static void __flush(struct ip_set_iptree *map)
|
|||||||
|
|
||||||
static void destroy(struct ip_set *set)
|
static void destroy(struct ip_set *set)
|
||||||
{
|
{
|
||||||
struct ip_set_iptree *map = (struct ip_set_iptree *) set->data;
|
struct ip_set_iptree *map = set->data;
|
||||||
|
|
||||||
/* gc might be running */
|
/* gc might be running */
|
||||||
while (!del_timer(&map->gc))
|
while (!del_timer(&map->gc))
|
||||||
@@ -455,7 +451,7 @@ static void destroy(struct ip_set *set)
|
|||||||
|
|
||||||
static void flush(struct ip_set *set)
|
static void flush(struct ip_set *set)
|
||||||
{
|
{
|
||||||
struct ip_set_iptree *map = (struct ip_set_iptree *) set->data;
|
struct ip_set_iptree *map = set->data;
|
||||||
unsigned int timeout = map->timeout;
|
unsigned int timeout = map->timeout;
|
||||||
|
|
||||||
/* gc might be running */
|
/* gc might be running */
|
||||||
@@ -470,16 +466,15 @@ static void flush(struct ip_set *set)
|
|||||||
|
|
||||||
static void list_header(const struct ip_set *set, void *data)
|
static void list_header(const struct ip_set *set, void *data)
|
||||||
{
|
{
|
||||||
struct ip_set_iptree *map = (struct ip_set_iptree *) set->data;
|
const struct ip_set_iptree *map = set->data;
|
||||||
struct ip_set_req_iptree_create *header =
|
struct ip_set_req_iptree_create *header = data;
|
||||||
(struct ip_set_req_iptree_create *) data;
|
|
||||||
|
|
||||||
header->timeout = map->timeout;
|
header->timeout = map->timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int list_members_size(const struct ip_set *set)
|
static int list_members_size(const struct ip_set *set)
|
||||||
{
|
{
|
||||||
struct ip_set_iptree *map = (struct ip_set_iptree *) set->data;
|
const struct ip_set_iptree *map = set->data;
|
||||||
struct ip_set_iptreeb *btree;
|
struct ip_set_iptreeb *btree;
|
||||||
struct ip_set_iptreec *ctree;
|
struct ip_set_iptreec *ctree;
|
||||||
struct ip_set_iptreed *dtree;
|
struct ip_set_iptreed *dtree;
|
||||||
@@ -504,7 +499,7 @@ static int list_members_size(const struct ip_set *set)
|
|||||||
|
|
||||||
static void list_members(const struct ip_set *set, void *data)
|
static void list_members(const struct ip_set *set, void *data)
|
||||||
{
|
{
|
||||||
struct ip_set_iptree *map = (struct ip_set_iptree *) set->data;
|
const struct ip_set_iptree *map = set->data;
|
||||||
struct ip_set_iptreeb *btree;
|
struct ip_set_iptreeb *btree;
|
||||||
struct ip_set_iptreec *ctree;
|
struct ip_set_iptreec *ctree;
|
||||||
struct ip_set_iptreed *dtree;
|
struct ip_set_iptreed *dtree;
|
||||||
@@ -518,9 +513,9 @@ static void list_members(const struct ip_set *set, void *data)
|
|||||||
for (d = 0; d < 256; d++) {
|
for (d = 0; d < 256; d++) {
|
||||||
if (dtree->expires[d]
|
if (dtree->expires[d]
|
||||||
&& (!map->timeout || time_after(dtree->expires[d], jiffies))) {
|
&& (!map->timeout || time_after(dtree->expires[d], jiffies))) {
|
||||||
entry = (struct ip_set_req_iptree *)(data + offset);
|
entry = data + offset;
|
||||||
entry->ip = ((a << 24) | (b << 16) | (c << 8) | d);
|
entry->ip = ((a << 24) | (b << 16) | (c << 8) | d);
|
||||||
entry->timeout = !map->timeout ? 0
|
entry->timeout = !map->timeout ? 0
|
||||||
: (dtree->expires[d] - jiffies)/HZ;
|
: (dtree->expires[d] - jiffies)/HZ;
|
||||||
offset += sizeof(struct ip_set_req_iptree);
|
offset += sizeof(struct ip_set_req_iptree);
|
||||||
}
|
}
|
||||||
|
@@ -6,12 +6,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* This modules implements the iptreemap ipset type. It uses bitmaps to
|
/* This modules implements the iptreemap ipset type. It uses bitmaps to
|
||||||
* represent every single IPv4 address as a single bit. The bitmaps are managed
|
* represent every single IPv4 address as a bit. The bitmaps are managed in a
|
||||||
* in a tree structure, where the first three octets of an addresses are used
|
* tree structure, where the first three octets of an address are used as an
|
||||||
* as an index to find the bitmap and the last octet is used as the bit number.
|
* index to find the bitmap and the last octet is used as the bit number.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/version.h>
|
#include <linux/version.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/ip.h>
|
#include <linux/ip.h>
|
||||||
#include <linux/skbuff.h>
|
#include <linux/skbuff.h>
|
||||||
@@ -186,9 +187,6 @@ static struct ip_set_iptreemap_b *fullbitmap_b;
|
|||||||
#define LOOP_WALK_END_COUNT() \
|
#define LOOP_WALK_END_COUNT() \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MIN(a, b) (a < b ? a : b)
|
|
||||||
#define MAX(a, b) (a > b ? a : b)
|
|
||||||
|
|
||||||
#define GETVALUE1(a, a1, b1, r) \
|
#define GETVALUE1(a, a1, b1, r) \
|
||||||
(a == a1 ? b1 : r)
|
(a == a1 ? b1 : r)
|
||||||
|
|
||||||
@@ -260,7 +258,7 @@ free_b(struct ip_set_iptreemap_b *map)
|
|||||||
static inline int
|
static inline int
|
||||||
__testip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip)
|
__testip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data;
|
struct ip_set_iptreemap *map = set->data;
|
||||||
struct ip_set_iptreemap_b *btree;
|
struct ip_set_iptreemap_b *btree;
|
||||||
struct ip_set_iptreemap_c *ctree;
|
struct ip_set_iptreemap_c *ctree;
|
||||||
struct ip_set_iptreemap_d *dtree;
|
struct ip_set_iptreemap_d *dtree;
|
||||||
@@ -280,7 +278,7 @@ __testip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip)
|
|||||||
static int
|
static int
|
||||||
testip(struct ip_set *set, const void *data, size_t size, ip_set_ip_t *hash_ip)
|
testip(struct ip_set *set, const void *data, size_t size, ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
struct ip_set_req_iptreemap *req = (struct ip_set_req_iptreemap *) data;
|
const struct ip_set_req_iptreemap *req = data;
|
||||||
|
|
||||||
if (size != sizeof(struct ip_set_req_iptreemap)) {
|
if (size != sizeof(struct ip_set_req_iptreemap)) {
|
||||||
ip_set_printk("data length wrong (want %zu, have %zu)", sizeof(struct ip_set_req_iptreemap), size);
|
ip_set_printk("data length wrong (want %zu, have %zu)", sizeof(struct ip_set_req_iptreemap), size);
|
||||||
@@ -295,13 +293,13 @@ testip_kernel(struct ip_set *set, const struct sk_buff *skb, ip_set_ip_t *hash_i
|
|||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
res = __testip(set,
|
res = __testip(set,
|
||||||
ntohl(flags[index] & IPSET_SRC
|
ntohl(flags[index] & IPSET_SRC
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
||||||
? ip_hdr(skb)->saddr
|
? ip_hdr(skb)->saddr
|
||||||
: ip_hdr(skb)->daddr),
|
: ip_hdr(skb)->daddr),
|
||||||
#else
|
#else
|
||||||
? skb->nh.iph->saddr
|
? skb->nh.iph->saddr
|
||||||
: skb->nh.iph->daddr),
|
: skb->nh.iph->daddr),
|
||||||
#endif
|
#endif
|
||||||
hash_ip);
|
hash_ip);
|
||||||
@@ -326,10 +324,10 @@ __addip_single(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip)
|
|||||||
ADDIP_WALK(btree, b, ctree, struct ip_set_iptreemap_c, cachep_c, fullbitmap_c);
|
ADDIP_WALK(btree, b, ctree, struct ip_set_iptreemap_c, cachep_c, fullbitmap_c);
|
||||||
ADDIP_WALK(ctree, c, dtree, struct ip_set_iptreemap_d, cachep_d, fullbitmap_d);
|
ADDIP_WALK(ctree, c, dtree, struct ip_set_iptreemap_d, cachep_d, fullbitmap_d);
|
||||||
|
|
||||||
if (test_and_set_bit(d, (void *) dtree->bitmap))
|
if (__test_and_set_bit(d, (void *) dtree->bitmap))
|
||||||
return -EEXIST;
|
return -EEXIST;
|
||||||
|
|
||||||
set_bit(b, (void *) btree->dirty);
|
__set_bit(b, (void *) btree->dirty);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -337,7 +335,7 @@ __addip_single(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip)
|
|||||||
static inline int
|
static inline int
|
||||||
__addip_range(struct ip_set *set, ip_set_ip_t start, ip_set_ip_t end, ip_set_ip_t *hash_ip)
|
__addip_range(struct ip_set *set, ip_set_ip_t start, ip_set_ip_t end, ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data;
|
struct ip_set_iptreemap *map = set->data;
|
||||||
struct ip_set_iptreemap_b *btree;
|
struct ip_set_iptreemap_b *btree;
|
||||||
struct ip_set_iptreemap_c *ctree;
|
struct ip_set_iptreemap_c *ctree;
|
||||||
struct ip_set_iptreemap_d *dtree;
|
struct ip_set_iptreemap_d *dtree;
|
||||||
@@ -358,8 +356,8 @@ __addip_range(struct ip_set *set, ip_set_ip_t start, ip_set_ip_t end, ip_set_ip_
|
|||||||
ADDIP_RANGE_LOOP(btree, b, GETVALUE1(a, a1, b1, 0), GETVALUE1(a, a2, b2, 255), CHECK2(a, b, a1, a2, b1, b2, c1, c2, d1, d2), ctree, fullbitmap_c, cachep_c, free_c) {
|
ADDIP_RANGE_LOOP(btree, b, GETVALUE1(a, a1, b1, 0), GETVALUE1(a, a2, b2, 255), CHECK2(a, b, a1, a2, b1, b2, c1, c2, d1, d2), ctree, fullbitmap_c, cachep_c, free_c) {
|
||||||
ADDIP_RANGE_LOOP(ctree, c, GETVALUE2(a, b, a1, b1, c1, 0), GETVALUE2(a, b, a2, b2, c2, 255), CHECK3(a, b, c, a1, a2, b1, b2, c1, c2, d1, d2), dtree, fullbitmap_d, cachep_d, free_d) {
|
ADDIP_RANGE_LOOP(ctree, c, GETVALUE2(a, b, a1, b1, c1, 0), GETVALUE2(a, b, a2, b2, c2, 255), CHECK3(a, b, c, a1, a2, b1, b2, c1, c2, d1, d2), dtree, fullbitmap_d, cachep_d, free_d) {
|
||||||
for (d = GETVALUE3(a, b, c, a1, b1, c1, d1, 0); d <= GETVALUE3(a, b, c, a2, b2, c2, d2, 255); d++)
|
for (d = GETVALUE3(a, b, c, a1, b1, c1, d1, 0); d <= GETVALUE3(a, b, c, a2, b2, c2, d2, 255); d++)
|
||||||
set_bit(d, (void *) dtree->bitmap);
|
__set_bit(d, (void *) dtree->bitmap);
|
||||||
set_bit(b, (void *) btree->dirty);
|
__set_bit(b, (void *) btree->dirty);
|
||||||
} ADDIP_RANGE_LOOP_END();
|
} ADDIP_RANGE_LOOP_END();
|
||||||
} ADDIP_RANGE_LOOP_END();
|
} ADDIP_RANGE_LOOP_END();
|
||||||
} ADDIP_RANGE_LOOP_END();
|
} ADDIP_RANGE_LOOP_END();
|
||||||
@@ -370,14 +368,14 @@ __addip_range(struct ip_set *set, ip_set_ip_t start, ip_set_ip_t end, ip_set_ip_
|
|||||||
static int
|
static int
|
||||||
addip(struct ip_set *set, const void *data, size_t size, ip_set_ip_t *hash_ip)
|
addip(struct ip_set *set, const void *data, size_t size, ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
struct ip_set_req_iptreemap *req = (struct ip_set_req_iptreemap *) data;
|
const struct ip_set_req_iptreemap *req = data;
|
||||||
|
|
||||||
if (size != sizeof(struct ip_set_req_iptreemap)) {
|
if (size != sizeof(struct ip_set_req_iptreemap)) {
|
||||||
ip_set_printk("data length wrong (want %zu, have %zu)", sizeof(struct ip_set_req_iptreemap), size);
|
ip_set_printk("data length wrong (want %zu, have %zu)", sizeof(struct ip_set_req_iptreemap), size);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return __addip_range(set, MIN(req->start, req->end), MAX(req->start, req->end), hash_ip);
|
return __addip_range(set, min(req->start, req->end), max(req->start, req->end), hash_ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -385,12 +383,12 @@ addip_kernel(struct ip_set *set, const struct sk_buff *skb, ip_set_ip_t *hash_ip
|
|||||||
{
|
{
|
||||||
|
|
||||||
return __addip_single(set,
|
return __addip_single(set,
|
||||||
ntohl(flags[index] & IPSET_SRC
|
ntohl(flags[index] & IPSET_SRC
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
||||||
? ip_hdr(skb)->saddr
|
? ip_hdr(skb)->saddr
|
||||||
: ip_hdr(skb)->daddr),
|
: ip_hdr(skb)->daddr),
|
||||||
#else
|
#else
|
||||||
? skb->nh.iph->saddr
|
? skb->nh.iph->saddr
|
||||||
: skb->nh.iph->daddr),
|
: skb->nh.iph->daddr),
|
||||||
#endif
|
#endif
|
||||||
hash_ip);
|
hash_ip);
|
||||||
@@ -399,7 +397,7 @@ addip_kernel(struct ip_set *set, const struct sk_buff *skb, ip_set_ip_t *hash_ip
|
|||||||
static inline int
|
static inline int
|
||||||
__delip_single(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip, unsigned int __nocast flags)
|
__delip_single(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip, unsigned int __nocast flags)
|
||||||
{
|
{
|
||||||
struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data;
|
struct ip_set_iptreemap *map = set->data;
|
||||||
struct ip_set_iptreemap_b *btree;
|
struct ip_set_iptreemap_b *btree;
|
||||||
struct ip_set_iptreemap_c *ctree;
|
struct ip_set_iptreemap_c *ctree;
|
||||||
struct ip_set_iptreemap_d *dtree;
|
struct ip_set_iptreemap_d *dtree;
|
||||||
@@ -413,10 +411,10 @@ __delip_single(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip, unsigne
|
|||||||
DELIP_WALK(btree, b, ctree, cachep_c, fullbitmap_c, flags);
|
DELIP_WALK(btree, b, ctree, cachep_c, fullbitmap_c, flags);
|
||||||
DELIP_WALK(ctree, c, dtree, cachep_d, fullbitmap_d, flags);
|
DELIP_WALK(ctree, c, dtree, cachep_d, fullbitmap_d, flags);
|
||||||
|
|
||||||
if (!test_and_clear_bit(d, (void *) dtree->bitmap))
|
if (!__test_and_clear_bit(d, (void *) dtree->bitmap))
|
||||||
return -EEXIST;
|
return -EEXIST;
|
||||||
|
|
||||||
set_bit(b, (void *) btree->dirty);
|
__set_bit(b, (void *) btree->dirty);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -424,7 +422,7 @@ __delip_single(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip, unsigne
|
|||||||
static inline int
|
static inline int
|
||||||
__delip_range(struct ip_set *set, ip_set_ip_t start, ip_set_ip_t end, ip_set_ip_t *hash_ip, unsigned int __nocast flags)
|
__delip_range(struct ip_set *set, ip_set_ip_t start, ip_set_ip_t end, ip_set_ip_t *hash_ip, unsigned int __nocast flags)
|
||||||
{
|
{
|
||||||
struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data;
|
struct ip_set_iptreemap *map = set->data;
|
||||||
struct ip_set_iptreemap_b *btree;
|
struct ip_set_iptreemap_b *btree;
|
||||||
struct ip_set_iptreemap_c *ctree;
|
struct ip_set_iptreemap_c *ctree;
|
||||||
struct ip_set_iptreemap_d *dtree;
|
struct ip_set_iptreemap_d *dtree;
|
||||||
@@ -445,8 +443,8 @@ __delip_range(struct ip_set *set, ip_set_ip_t start, ip_set_ip_t end, ip_set_ip_
|
|||||||
DELIP_RANGE_LOOP(btree, b, GETVALUE1(a, a1, b1, 0), GETVALUE1(a, a2, b2, 255), CHECK2(a, b, a1, a2, b1, b2, c1, c2, d1, d2), ctree, fullbitmap_c, cachep_c, free_c, flags) {
|
DELIP_RANGE_LOOP(btree, b, GETVALUE1(a, a1, b1, 0), GETVALUE1(a, a2, b2, 255), CHECK2(a, b, a1, a2, b1, b2, c1, c2, d1, d2), ctree, fullbitmap_c, cachep_c, free_c, flags) {
|
||||||
DELIP_RANGE_LOOP(ctree, c, GETVALUE2(a, b, a1, b1, c1, 0), GETVALUE2(a, b, a2, b2, c2, 255), CHECK3(a, b, c, a1, a2, b1, b2, c1, c2, d1, d2), dtree, fullbitmap_d, cachep_d, free_d, flags) {
|
DELIP_RANGE_LOOP(ctree, c, GETVALUE2(a, b, a1, b1, c1, 0), GETVALUE2(a, b, a2, b2, c2, 255), CHECK3(a, b, c, a1, a2, b1, b2, c1, c2, d1, d2), dtree, fullbitmap_d, cachep_d, free_d, flags) {
|
||||||
for (d = GETVALUE3(a, b, c, a1, b1, c1, d1, 0); d <= GETVALUE3(a, b, c, a2, b2, c2, d2, 255); d++)
|
for (d = GETVALUE3(a, b, c, a1, b1, c1, d1, 0); d <= GETVALUE3(a, b, c, a2, b2, c2, d2, 255); d++)
|
||||||
clear_bit(d, (void *) dtree->bitmap);
|
__clear_bit(d, (void *) dtree->bitmap);
|
||||||
set_bit(b, (void *) btree->dirty);
|
__set_bit(b, (void *) btree->dirty);
|
||||||
} DELIP_RANGE_LOOP_END();
|
} DELIP_RANGE_LOOP_END();
|
||||||
} DELIP_RANGE_LOOP_END();
|
} DELIP_RANGE_LOOP_END();
|
||||||
} DELIP_RANGE_LOOP_END();
|
} DELIP_RANGE_LOOP_END();
|
||||||
@@ -457,26 +455,26 @@ __delip_range(struct ip_set *set, ip_set_ip_t start, ip_set_ip_t end, ip_set_ip_
|
|||||||
static int
|
static int
|
||||||
delip(struct ip_set *set, const void *data, size_t size, ip_set_ip_t *hash_ip)
|
delip(struct ip_set *set, const void *data, size_t size, ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
struct ip_set_req_iptreemap *req = (struct ip_set_req_iptreemap *) data;
|
const struct ip_set_req_iptreemap *req = data;
|
||||||
|
|
||||||
if (size != sizeof(struct ip_set_req_iptreemap)) {
|
if (size != sizeof(struct ip_set_req_iptreemap)) {
|
||||||
ip_set_printk("data length wrong (want %zu, have %zu)", sizeof(struct ip_set_req_iptreemap), size);
|
ip_set_printk("data length wrong (want %zu, have %zu)", sizeof(struct ip_set_req_iptreemap), size);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return __delip_range(set, MIN(req->start, req->end), MAX(req->start, req->end), hash_ip, GFP_KERNEL);
|
return __delip_range(set, min(req->start, req->end), max(req->start, req->end), hash_ip, GFP_KERNEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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)
|
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_single(set,
|
return __delip_single(set,
|
||||||
ntohl(flags[index] & IPSET_SRC
|
ntohl(flags[index] & IPSET_SRC
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
||||||
? ip_hdr(skb)->saddr
|
? ip_hdr(skb)->saddr
|
||||||
: ip_hdr(skb)->daddr),
|
: ip_hdr(skb)->daddr),
|
||||||
#else
|
#else
|
||||||
? skb->nh.iph->saddr
|
? skb->nh.iph->saddr
|
||||||
: skb->nh.iph->daddr),
|
: skb->nh.iph->daddr),
|
||||||
#endif
|
#endif
|
||||||
hash_ip,
|
hash_ip,
|
||||||
@@ -505,7 +503,7 @@ static void
|
|||||||
gc(unsigned long addr)
|
gc(unsigned long addr)
|
||||||
{
|
{
|
||||||
struct ip_set *set = (struct ip_set *) addr;
|
struct ip_set *set = (struct ip_set *) addr;
|
||||||
struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data;
|
struct ip_set_iptreemap *map = set->data;
|
||||||
struct ip_set_iptreemap_b *btree;
|
struct ip_set_iptreemap_b *btree;
|
||||||
struct ip_set_iptreemap_c *ctree;
|
struct ip_set_iptreemap_c *ctree;
|
||||||
struct ip_set_iptreemap_d *dtree;
|
struct ip_set_iptreemap_d *dtree;
|
||||||
@@ -516,7 +514,7 @@ gc(unsigned long addr)
|
|||||||
|
|
||||||
LOOP_WALK_BEGIN_GC(map, a, btree, fullbitmap_b, cachep_b, i) {
|
LOOP_WALK_BEGIN_GC(map, a, btree, fullbitmap_b, cachep_b, i) {
|
||||||
LOOP_WALK_BEGIN_GC(btree, b, ctree, fullbitmap_c, cachep_c, j) {
|
LOOP_WALK_BEGIN_GC(btree, b, ctree, fullbitmap_c, cachep_c, j) {
|
||||||
if (!test_and_clear_bit(b, (void *) btree->dirty))
|
if (!__test_and_clear_bit(b, (void *) btree->dirty))
|
||||||
continue;
|
continue;
|
||||||
LOOP_WALK_BEGIN_GC(ctree, c, dtree, fullbitmap_d, cachep_d, k) {
|
LOOP_WALK_BEGIN_GC(ctree, c, dtree, fullbitmap_d, cachep_d, k) {
|
||||||
switch (bitmap_status(dtree)) {
|
switch (bitmap_status(dtree)) {
|
||||||
@@ -544,7 +542,7 @@ gc(unsigned long addr)
|
|||||||
static inline void
|
static inline void
|
||||||
init_gc_timer(struct ip_set *set)
|
init_gc_timer(struct ip_set *set)
|
||||||
{
|
{
|
||||||
struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data;
|
struct ip_set_iptreemap *map = set->data;
|
||||||
|
|
||||||
init_timer(&map->gc);
|
init_timer(&map->gc);
|
||||||
map->gc.data = (unsigned long) set;
|
map->gc.data = (unsigned long) set;
|
||||||
@@ -555,7 +553,7 @@ init_gc_timer(struct ip_set *set)
|
|||||||
|
|
||||||
static int create(struct ip_set *set, const void *data, size_t size)
|
static int create(struct ip_set *set, const void *data, size_t size)
|
||||||
{
|
{
|
||||||
struct ip_set_req_iptreemap_create *req = (struct ip_set_req_iptreemap_create *) data;
|
const struct ip_set_req_iptreemap_create *req = data;
|
||||||
struct ip_set_iptreemap *map;
|
struct ip_set_iptreemap *map;
|
||||||
|
|
||||||
if (size != sizeof(struct ip_set_req_iptreemap_create)) {
|
if (size != sizeof(struct ip_set_req_iptreemap_create)) {
|
||||||
@@ -588,7 +586,7 @@ static inline void __flush(struct ip_set_iptreemap *map)
|
|||||||
|
|
||||||
static void destroy(struct ip_set *set)
|
static void destroy(struct ip_set *set)
|
||||||
{
|
{
|
||||||
struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data;
|
struct ip_set_iptreemap *map = set->data;
|
||||||
|
|
||||||
while (!del_timer(&map->gc))
|
while (!del_timer(&map->gc))
|
||||||
msleep(IPTREEMAP_DESTROY_SLEEP);
|
msleep(IPTREEMAP_DESTROY_SLEEP);
|
||||||
@@ -601,7 +599,7 @@ static void destroy(struct ip_set *set)
|
|||||||
|
|
||||||
static void flush(struct ip_set *set)
|
static void flush(struct ip_set *set)
|
||||||
{
|
{
|
||||||
struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data;
|
struct ip_set_iptreemap *map = set->data;
|
||||||
|
|
||||||
while (!del_timer(&map->gc))
|
while (!del_timer(&map->gc))
|
||||||
msleep(IPTREEMAP_DESTROY_SLEEP);
|
msleep(IPTREEMAP_DESTROY_SLEEP);
|
||||||
@@ -615,15 +613,15 @@ static void flush(struct ip_set *set)
|
|||||||
|
|
||||||
static void list_header(const struct ip_set *set, void *data)
|
static void list_header(const struct ip_set *set, void *data)
|
||||||
{
|
{
|
||||||
struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data;
|
struct ip_set_iptreemap *map = set->data;
|
||||||
struct ip_set_req_iptreemap_create *header = (struct ip_set_req_iptreemap_create *) data;
|
struct ip_set_req_iptreemap_create *header = data;
|
||||||
|
|
||||||
header->gc_interval = map->gc_interval;
|
header->gc_interval = map->gc_interval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int list_members_size(const struct ip_set *set)
|
static int list_members_size(const struct ip_set *set)
|
||||||
{
|
{
|
||||||
struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data;
|
struct ip_set_iptreemap *map = set->data;
|
||||||
struct ip_set_iptreemap_b *btree;
|
struct ip_set_iptreemap_b *btree;
|
||||||
struct ip_set_iptreemap_c *ctree;
|
struct ip_set_iptreemap_c *ctree;
|
||||||
struct ip_set_iptreemap_d *dtree;
|
struct ip_set_iptreemap_d *dtree;
|
||||||
@@ -652,7 +650,7 @@ static int list_members_size(const struct ip_set *set)
|
|||||||
|
|
||||||
static inline size_t add_member(void *data, size_t offset, ip_set_ip_t start, ip_set_ip_t end)
|
static inline size_t add_member(void *data, size_t offset, ip_set_ip_t start, ip_set_ip_t end)
|
||||||
{
|
{
|
||||||
struct ip_set_req_iptreemap *entry = (struct ip_set_req_iptreemap *) (data + offset);
|
struct ip_set_req_iptreemap *entry = data + offset;
|
||||||
|
|
||||||
entry->start = start;
|
entry->start = start;
|
||||||
entry->end = end;
|
entry->end = end;
|
||||||
@@ -662,7 +660,7 @@ static inline size_t add_member(void *data, size_t offset, ip_set_ip_t start, ip
|
|||||||
|
|
||||||
static void list_members(const struct ip_set *set, void *data)
|
static void list_members(const struct ip_set *set, void *data)
|
||||||
{
|
{
|
||||||
struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data;
|
struct ip_set_iptreemap *map = set->data;
|
||||||
struct ip_set_iptreemap_b *btree;
|
struct ip_set_iptreemap_b *btree;
|
||||||
struct ip_set_iptreemap_c *ctree;
|
struct ip_set_iptreemap_c *ctree;
|
||||||
struct ip_set_iptreemap_d *dtree;
|
struct ip_set_iptreemap_d *dtree;
|
||||||
@@ -728,12 +726,12 @@ static int __init ip_set_iptreemap_init(void)
|
|||||||
int a;
|
int a;
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
|
||||||
cachep_b = kmem_cache_create("ip_set_iptreemap_b",
|
cachep_b = kmem_cache_create("ip_set_iptreemap_b",
|
||||||
sizeof(struct ip_set_iptreemap_b),
|
sizeof(struct ip_set_iptreemap_b),
|
||||||
0, 0, NULL);
|
0, 0, NULL);
|
||||||
#else
|
#else
|
||||||
cachep_b = kmem_cache_create("ip_set_iptreemap_b",
|
cachep_b = kmem_cache_create("ip_set_iptreemap_b",
|
||||||
sizeof(struct ip_set_iptreemap_b),
|
sizeof(struct ip_set_iptreemap_b),
|
||||||
0, 0, NULL, NULL);
|
0, 0, NULL, NULL);
|
||||||
#endif
|
#endif
|
||||||
if (!cachep_b) {
|
if (!cachep_b) {
|
||||||
@@ -742,11 +740,11 @@ static int __init ip_set_iptreemap_init(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)
|
||||||
cachep_c = kmem_cache_create("ip_set_iptreemap_c",
|
cachep_c = kmem_cache_create("ip_set_iptreemap_c",
|
||||||
sizeof(struct ip_set_iptreemap_c),
|
sizeof(struct ip_set_iptreemap_c),
|
||||||
0, 0, NULL);
|
0, 0, NULL);
|
||||||
#else
|
#else
|
||||||
cachep_c = kmem_cache_create("ip_set_iptreemap_c",
|
cachep_c = kmem_cache_create("ip_set_iptreemap_c",
|
||||||
sizeof(struct ip_set_iptreemap_c),
|
sizeof(struct ip_set_iptreemap_c),
|
||||||
0, 0, NULL, NULL);
|
0, 0, NULL, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
* published by the Free Software Foundation.
|
* published by the Free Software Foundation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Kernel module implementing an IP set type: the macipmap type */
|
/* Kernel module implementing an IP set type: the macipmap type */
|
||||||
@@ -29,9 +29,9 @@
|
|||||||
static int
|
static int
|
||||||
testip(struct ip_set *set, const void *data, size_t size, ip_set_ip_t *hash_ip)
|
testip(struct ip_set *set, const void *data, size_t size, ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
struct ip_set_macipmap *map = (struct ip_set_macipmap *) set->data;
|
struct ip_set_macipmap *map = set->data;
|
||||||
struct ip_set_macip *table = (struct ip_set_macip *) map->members;
|
struct ip_set_macip *table = map->members;
|
||||||
struct ip_set_req_macipmap *req = (struct ip_set_req_macipmap *) data;
|
const struct ip_set_req_macipmap *req = data;
|
||||||
|
|
||||||
if (size != sizeof(struct ip_set_req_macipmap)) {
|
if (size != sizeof(struct ip_set_req_macipmap)) {
|
||||||
ip_set_printk("data length wrong (want %zu, have %zu)",
|
ip_set_printk("data length wrong (want %zu, have %zu)",
|
||||||
@@ -57,21 +57,19 @@ testip(struct ip_set *set, const void *data, size_t size, ip_set_ip_t *hash_ip)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
testip_kernel(struct ip_set *set,
|
testip_kernel(struct ip_set *set,
|
||||||
const struct sk_buff *skb,
|
const struct sk_buff *skb,
|
||||||
ip_set_ip_t *hash_ip,
|
ip_set_ip_t *hash_ip,
|
||||||
const u_int32_t *flags,
|
const u_int32_t *flags,
|
||||||
unsigned char index)
|
unsigned char index)
|
||||||
{
|
{
|
||||||
struct ip_set_macipmap *map =
|
struct ip_set_macipmap *map = set->data;
|
||||||
(struct ip_set_macipmap *) set->data;
|
struct ip_set_macip *table = map->members;
|
||||||
struct ip_set_macip *table =
|
|
||||||
(struct ip_set_macip *) map->members;
|
|
||||||
ip_set_ip_t ip;
|
ip_set_ip_t ip;
|
||||||
|
|
||||||
ip = ntohl(flags[index] & IPSET_SRC
|
ip = ntohl(flags[index] & IPSET_SRC
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
||||||
? ip_hdr(skb)->saddr
|
? ip_hdr(skb)->saddr
|
||||||
: ip_hdr(skb)->daddr);
|
: ip_hdr(skb)->daddr);
|
||||||
#else
|
#else
|
||||||
? skb->nh.iph->saddr
|
? skb->nh.iph->saddr
|
||||||
@@ -105,17 +103,15 @@ testip_kernel(struct ip_set *set,
|
|||||||
|
|
||||||
/* returns 0 on success */
|
/* returns 0 on success */
|
||||||
static inline int
|
static inline int
|
||||||
__addip(struct ip_set *set,
|
__addip(struct ip_set *set,
|
||||||
ip_set_ip_t ip, unsigned char *ethernet, ip_set_ip_t *hash_ip)
|
ip_set_ip_t ip, const unsigned char *ethernet, ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
struct ip_set_macipmap *map =
|
struct ip_set_macipmap *map = set->data;
|
||||||
(struct ip_set_macipmap *) set->data;
|
struct ip_set_macip *table = map->members;
|
||||||
struct ip_set_macip *table =
|
|
||||||
(struct ip_set_macip *) map->members;
|
|
||||||
|
|
||||||
if (ip < map->first_ip || ip > map->last_ip)
|
if (ip < map->first_ip || ip > map->last_ip)
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
if (test_and_set_bit(IPSET_MACIP_ISSET,
|
if (test_and_set_bit(IPSET_MACIP_ISSET,
|
||||||
(void *) &table[ip - map->first_ip].flags))
|
(void *) &table[ip - map->first_ip].flags))
|
||||||
return -EEXIST;
|
return -EEXIST;
|
||||||
|
|
||||||
@@ -129,8 +125,7 @@ static int
|
|||||||
addip(struct ip_set *set, const void *data, size_t size,
|
addip(struct ip_set *set, const void *data, size_t size,
|
||||||
ip_set_ip_t *hash_ip)
|
ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
struct ip_set_req_macipmap *req =
|
const struct ip_set_req_macipmap *req = data;
|
||||||
(struct ip_set_req_macipmap *) data;
|
|
||||||
|
|
||||||
if (size != sizeof(struct ip_set_req_macipmap)) {
|
if (size != sizeof(struct ip_set_req_macipmap)) {
|
||||||
ip_set_printk("data length wrong (want %zu, have %zu)",
|
ip_set_printk("data length wrong (want %zu, have %zu)",
|
||||||
@@ -142,7 +137,7 @@ addip(struct ip_set *set, const void *data, size_t size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
addip_kernel(struct ip_set *set,
|
addip_kernel(struct ip_set *set,
|
||||||
const struct sk_buff *skb,
|
const struct sk_buff *skb,
|
||||||
ip_set_ip_t *hash_ip,
|
ip_set_ip_t *hash_ip,
|
||||||
const u_int32_t *flags,
|
const u_int32_t *flags,
|
||||||
@@ -152,7 +147,7 @@ addip_kernel(struct ip_set *set,
|
|||||||
|
|
||||||
ip = ntohl(flags[index] & IPSET_SRC
|
ip = ntohl(flags[index] & IPSET_SRC
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
||||||
? ip_hdr(skb)->saddr
|
? ip_hdr(skb)->saddr
|
||||||
: ip_hdr(skb)->daddr);
|
: ip_hdr(skb)->daddr);
|
||||||
#else
|
#else
|
||||||
? skb->nh.iph->saddr
|
? skb->nh.iph->saddr
|
||||||
@@ -174,14 +169,12 @@ addip_kernel(struct ip_set *set,
|
|||||||
static inline int
|
static inline int
|
||||||
__delip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip)
|
__delip(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
struct ip_set_macipmap *map =
|
struct ip_set_macipmap *map = set->data;
|
||||||
(struct ip_set_macipmap *) set->data;
|
struct ip_set_macip *table = map->members;
|
||||||
struct ip_set_macip *table =
|
|
||||||
(struct ip_set_macip *) map->members;
|
|
||||||
|
|
||||||
if (ip < map->first_ip || ip > map->last_ip)
|
if (ip < map->first_ip || ip > map->last_ip)
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
if (!test_and_clear_bit(IPSET_MACIP_ISSET,
|
if (!test_and_clear_bit(IPSET_MACIP_ISSET,
|
||||||
(void *)&table[ip - map->first_ip].flags))
|
(void *)&table[ip - map->first_ip].flags))
|
||||||
return -EEXIST;
|
return -EEXIST;
|
||||||
|
|
||||||
@@ -194,8 +187,7 @@ static int
|
|||||||
delip(struct ip_set *set, const void *data, size_t size,
|
delip(struct ip_set *set, const void *data, size_t size,
|
||||||
ip_set_ip_t *hash_ip)
|
ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
struct ip_set_req_macipmap *req =
|
const struct ip_set_req_macipmap *req = data;
|
||||||
(struct ip_set_req_macipmap *) data;
|
|
||||||
|
|
||||||
if (size != sizeof(struct ip_set_req_macipmap)) {
|
if (size != sizeof(struct ip_set_req_macipmap)) {
|
||||||
ip_set_printk("data length wrong (want %zu, have %zu)",
|
ip_set_printk("data length wrong (want %zu, have %zu)",
|
||||||
@@ -214,12 +206,12 @@ delip_kernel(struct ip_set *set,
|
|||||||
unsigned char index)
|
unsigned char index)
|
||||||
{
|
{
|
||||||
return __delip(set,
|
return __delip(set,
|
||||||
ntohl(flags[index] & IPSET_SRC
|
ntohl(flags[index] & IPSET_SRC
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
||||||
? ip_hdr(skb)->saddr
|
? ip_hdr(skb)->saddr
|
||||||
: ip_hdr(skb)->daddr),
|
: ip_hdr(skb)->daddr),
|
||||||
#else
|
#else
|
||||||
? skb->nh.iph->saddr
|
? skb->nh.iph->saddr
|
||||||
: skb->nh.iph->daddr),
|
: skb->nh.iph->daddr),
|
||||||
#endif
|
#endif
|
||||||
hash_ip);
|
hash_ip);
|
||||||
@@ -233,8 +225,7 @@ static inline size_t members_size(ip_set_ip_t from, ip_set_ip_t to)
|
|||||||
static int create(struct ip_set *set, const void *data, size_t size)
|
static int create(struct ip_set *set, const void *data, size_t size)
|
||||||
{
|
{
|
||||||
size_t newbytes;
|
size_t newbytes;
|
||||||
struct ip_set_req_macipmap_create *req =
|
const struct ip_set_req_macipmap_create *req = data;
|
||||||
(struct ip_set_req_macipmap_create *) data;
|
|
||||||
struct ip_set_macipmap *map;
|
struct ip_set_macipmap *map;
|
||||||
|
|
||||||
if (size != sizeof(struct ip_set_req_macipmap_create)) {
|
if (size != sizeof(struct ip_set_req_macipmap_create)) {
|
||||||
@@ -283,8 +274,7 @@ static int create(struct ip_set *set, const void *data, size_t size)
|
|||||||
|
|
||||||
static void destroy(struct ip_set *set)
|
static void destroy(struct ip_set *set)
|
||||||
{
|
{
|
||||||
struct ip_set_macipmap *map =
|
struct ip_set_macipmap *map = set->data;
|
||||||
(struct ip_set_macipmap *) set->data;
|
|
||||||
|
|
||||||
ip_set_free(map->members, members_size(map->first_ip, map->last_ip));
|
ip_set_free(map->members, members_size(map->first_ip, map->last_ip));
|
||||||
kfree(map);
|
kfree(map);
|
||||||
@@ -294,17 +284,14 @@ static void destroy(struct ip_set *set)
|
|||||||
|
|
||||||
static void flush(struct ip_set *set)
|
static void flush(struct ip_set *set)
|
||||||
{
|
{
|
||||||
struct ip_set_macipmap *map =
|
struct ip_set_macipmap *map = set->data;
|
||||||
(struct ip_set_macipmap *) set->data;
|
|
||||||
memset(map->members, 0, members_size(map->first_ip, map->last_ip));
|
memset(map->members, 0, members_size(map->first_ip, map->last_ip));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void list_header(const struct ip_set *set, void *data)
|
static void list_header(const struct ip_set *set, void *data)
|
||||||
{
|
{
|
||||||
struct ip_set_macipmap *map =
|
const struct ip_set_macipmap *map = set->data;
|
||||||
(struct ip_set_macipmap *) set->data;
|
struct ip_set_req_macipmap_create *header = data;
|
||||||
struct ip_set_req_macipmap_create *header =
|
|
||||||
(struct ip_set_req_macipmap_create *) data;
|
|
||||||
|
|
||||||
DP("list_header %x %x %u", map->first_ip, map->last_ip,
|
DP("list_header %x %x %u", map->first_ip, map->last_ip,
|
||||||
map->flags);
|
map->flags);
|
||||||
@@ -316,8 +303,7 @@ static void list_header(const struct ip_set *set, void *data)
|
|||||||
|
|
||||||
static int list_members_size(const struct ip_set *set)
|
static int list_members_size(const struct ip_set *set)
|
||||||
{
|
{
|
||||||
struct ip_set_macipmap *map =
|
const struct ip_set_macipmap *map = set->data;
|
||||||
(struct ip_set_macipmap *) set->data;
|
|
||||||
|
|
||||||
DP("%u", members_size(map->first_ip, map->last_ip));
|
DP("%u", members_size(map->first_ip, map->last_ip));
|
||||||
return members_size(map->first_ip, map->last_ip);
|
return members_size(map->first_ip, map->last_ip);
|
||||||
@@ -325,8 +311,7 @@ static int list_members_size(const struct ip_set *set)
|
|||||||
|
|
||||||
static void list_members(const struct ip_set *set, void *data)
|
static void list_members(const struct ip_set *set, void *data)
|
||||||
{
|
{
|
||||||
struct ip_set_macipmap *map =
|
const struct ip_set_macipmap *map = set->data;
|
||||||
(struct ip_set_macipmap *) set->data;
|
|
||||||
|
|
||||||
int bytes = members_size(map->first_ip, map->last_ip);
|
int bytes = members_size(map->first_ip, map->last_ip);
|
||||||
|
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
* published by the Free Software Foundation.
|
* published by the Free Software Foundation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Kernel module implementing a cidr nethash set */
|
/* Kernel module implementing a cidr nethash set */
|
||||||
@@ -59,7 +59,7 @@ hash_id_cidr(struct ip_set_nethash *map,
|
|||||||
static inline __u32
|
static inline __u32
|
||||||
hash_id(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip)
|
hash_id(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
struct ip_set_nethash *map = (struct ip_set_nethash *) set->data;
|
struct ip_set_nethash *map = set->data;
|
||||||
__u32 id = UINT_MAX;
|
__u32 id = UINT_MAX;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@@ -75,7 +75,7 @@ static inline int
|
|||||||
__testip_cidr(struct ip_set *set, ip_set_ip_t ip, unsigned char cidr,
|
__testip_cidr(struct ip_set *set, ip_set_ip_t ip, unsigned char cidr,
|
||||||
ip_set_ip_t *hash_ip)
|
ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
struct ip_set_nethash *map = (struct ip_set_nethash *) set->data;
|
struct ip_set_nethash *map = set->data;
|
||||||
|
|
||||||
return (ip && hash_id_cidr(map, ip, cidr, hash_ip) != UINT_MAX);
|
return (ip && hash_id_cidr(map, ip, cidr, hash_ip) != UINT_MAX);
|
||||||
}
|
}
|
||||||
@@ -90,8 +90,7 @@ static int
|
|||||||
testip(struct ip_set *set, const void *data, size_t size,
|
testip(struct ip_set *set, const void *data, size_t size,
|
||||||
ip_set_ip_t *hash_ip)
|
ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
struct ip_set_req_nethash *req =
|
const struct ip_set_req_nethash *req = data;
|
||||||
(struct ip_set_req_nethash *) data;
|
|
||||||
|
|
||||||
if (size != sizeof(struct ip_set_req_nethash)) {
|
if (size != sizeof(struct ip_set_req_nethash)) {
|
||||||
ip_set_printk("data length wrong (want %zu, have %zu)",
|
ip_set_printk("data length wrong (want %zu, have %zu)",
|
||||||
@@ -104,19 +103,19 @@ testip(struct ip_set *set, const void *data, size_t size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
testip_kernel(struct ip_set *set,
|
testip_kernel(struct ip_set *set,
|
||||||
const struct sk_buff *skb,
|
const struct sk_buff *skb,
|
||||||
ip_set_ip_t *hash_ip,
|
ip_set_ip_t *hash_ip,
|
||||||
const u_int32_t *flags,
|
const u_int32_t *flags,
|
||||||
unsigned char index)
|
unsigned char index)
|
||||||
{
|
{
|
||||||
return __testip(set,
|
return __testip(set,
|
||||||
ntohl(flags[index] & IPSET_SRC
|
ntohl(flags[index] & IPSET_SRC
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
||||||
? ip_hdr(skb)->saddr
|
? ip_hdr(skb)->saddr
|
||||||
: ip_hdr(skb)->daddr),
|
: ip_hdr(skb)->daddr),
|
||||||
#else
|
#else
|
||||||
? skb->nh.iph->saddr
|
? skb->nh.iph->saddr
|
||||||
: skb->nh.iph->daddr),
|
: skb->nh.iph->daddr),
|
||||||
#endif
|
#endif
|
||||||
hash_ip);
|
hash_ip);
|
||||||
@@ -180,8 +179,7 @@ static int
|
|||||||
addip(struct ip_set *set, const void *data, size_t size,
|
addip(struct ip_set *set, const void *data, size_t size,
|
||||||
ip_set_ip_t *hash_ip)
|
ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
struct ip_set_req_nethash *req =
|
const struct ip_set_req_nethash *req = data;
|
||||||
(struct ip_set_req_nethash *) data;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (size != sizeof(struct ip_set_req_nethash)) {
|
if (size != sizeof(struct ip_set_req_nethash)) {
|
||||||
@@ -190,28 +188,26 @@ addip(struct ip_set *set, const void *data, size_t size,
|
|||||||
size);
|
size);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
ret = __addip((struct ip_set_nethash *) set->data,
|
ret = __addip(set->data, req->ip, req->cidr, hash_ip);
|
||||||
req->ip, req->cidr, hash_ip);
|
|
||||||
|
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
update_cidr_sizes((struct ip_set_nethash *) set->data,
|
update_cidr_sizes(set->data, req->cidr);
|
||||||
req->cidr);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
addip_kernel(struct ip_set *set,
|
addip_kernel(struct ip_set *set,
|
||||||
const struct sk_buff *skb,
|
const struct sk_buff *skb,
|
||||||
ip_set_ip_t *hash_ip,
|
ip_set_ip_t *hash_ip,
|
||||||
const u_int32_t *flags,
|
const u_int32_t *flags,
|
||||||
unsigned char index)
|
unsigned char index)
|
||||||
{
|
{
|
||||||
struct ip_set_nethash *map = (struct ip_set_nethash *) set->data;
|
struct ip_set_nethash *map = set->data;
|
||||||
int ret = -ERANGE;
|
int ret = -ERANGE;
|
||||||
ip_set_ip_t ip = ntohl(flags[index] & IPSET_SRC
|
ip_set_ip_t ip = ntohl(flags[index] & IPSET_SRC
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
||||||
? ip_hdr(skb)->saddr
|
? ip_hdr(skb)->saddr
|
||||||
: ip_hdr(skb)->daddr);
|
: ip_hdr(skb)->daddr);
|
||||||
#else
|
#else
|
||||||
? skb->nh.iph->saddr
|
? skb->nh.iph->saddr
|
||||||
@@ -226,7 +222,7 @@ addip_kernel(struct ip_set *set,
|
|||||||
|
|
||||||
static int retry(struct ip_set *set)
|
static int retry(struct ip_set *set)
|
||||||
{
|
{
|
||||||
struct ip_set_nethash *map = (struct ip_set_nethash *) set->data;
|
struct ip_set_nethash *map = set->data;
|
||||||
ip_set_ip_t *elem;
|
ip_set_ip_t *elem;
|
||||||
void *members;
|
void *members;
|
||||||
u_int32_t i, hashsize = map->hashsize;
|
u_int32_t i, hashsize = map->hashsize;
|
||||||
@@ -248,7 +244,7 @@ static int retry(struct ip_set *set)
|
|||||||
"hashsize grows from %u to %u",
|
"hashsize grows from %u to %u",
|
||||||
set->name, map->hashsize, hashsize);
|
set->name, map->hashsize, hashsize);
|
||||||
|
|
||||||
tmp = kmalloc(sizeof(struct ip_set_nethash)
|
tmp = kmalloc(sizeof(struct ip_set_nethash)
|
||||||
+ map->probes * sizeof(uint32_t), GFP_ATOMIC);
|
+ map->probes * sizeof(uint32_t), GFP_ATOMIC);
|
||||||
if (!tmp) {
|
if (!tmp) {
|
||||||
DP("out of memory for %d bytes",
|
DP("out of memory for %d bytes",
|
||||||
@@ -270,7 +266,7 @@ static int retry(struct ip_set *set)
|
|||||||
memcpy(tmp->cidr, map->cidr, 30 * sizeof(unsigned char));
|
memcpy(tmp->cidr, map->cidr, 30 * sizeof(unsigned char));
|
||||||
|
|
||||||
write_lock_bh(&set->lock);
|
write_lock_bh(&set->lock);
|
||||||
map = (struct ip_set_nethash *) set->data; /* Play safe */
|
map = set->data; /* Play safe */
|
||||||
for (i = 0; i < map->hashsize && res == 0; i++) {
|
for (i = 0; i < map->hashsize && res == 0; i++) {
|
||||||
elem = HARRAY_ELEM(map->members, ip_set_ip_t *, i);
|
elem = HARRAY_ELEM(map->members, ip_set_ip_t *, i);
|
||||||
if (*elem)
|
if (*elem)
|
||||||
@@ -320,8 +316,7 @@ static int
|
|||||||
delip(struct ip_set *set, const void *data, size_t size,
|
delip(struct ip_set *set, const void *data, size_t size,
|
||||||
ip_set_ip_t *hash_ip)
|
ip_set_ip_t *hash_ip)
|
||||||
{
|
{
|
||||||
struct ip_set_req_nethash *req =
|
const struct ip_set_req_nethash *req = data;
|
||||||
(struct ip_set_req_nethash *) data;
|
|
||||||
|
|
||||||
if (size != sizeof(struct ip_set_req_nethash)) {
|
if (size != sizeof(struct ip_set_req_nethash)) {
|
||||||
ip_set_printk("data length wrong (want %zu, have %zu)",
|
ip_set_printk("data length wrong (want %zu, have %zu)",
|
||||||
@@ -330,22 +325,21 @@ delip(struct ip_set *set, const void *data, size_t size,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
/* TODO: no garbage collection in map->cidr */
|
/* TODO: no garbage collection in map->cidr */
|
||||||
return __delip((struct ip_set_nethash *) set->data,
|
return __delip(set->data, req->ip, req->cidr, hash_ip);
|
||||||
req->ip, req->cidr, hash_ip);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
delip_kernel(struct ip_set *set,
|
delip_kernel(struct ip_set *set,
|
||||||
const struct sk_buff *skb,
|
const struct sk_buff *skb,
|
||||||
ip_set_ip_t *hash_ip,
|
ip_set_ip_t *hash_ip,
|
||||||
const u_int32_t *flags,
|
const u_int32_t *flags,
|
||||||
unsigned char index)
|
unsigned char index)
|
||||||
{
|
{
|
||||||
struct ip_set_nethash *map = (struct ip_set_nethash *) set->data;
|
struct ip_set_nethash *map = set->data;
|
||||||
int ret = -ERANGE;
|
int ret = -ERANGE;
|
||||||
ip_set_ip_t ip = ntohl(flags[index] & IPSET_SRC
|
ip_set_ip_t ip = ntohl(flags[index] & IPSET_SRC
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
|
||||||
? ip_hdr(skb)->saddr
|
? ip_hdr(skb)->saddr
|
||||||
: ip_hdr(skb)->daddr);
|
: ip_hdr(skb)->daddr);
|
||||||
#else
|
#else
|
||||||
? skb->nh.iph->saddr
|
? skb->nh.iph->saddr
|
||||||
@@ -360,8 +354,7 @@ delip_kernel(struct ip_set *set,
|
|||||||
|
|
||||||
static int create(struct ip_set *set, const void *data, size_t size)
|
static int create(struct ip_set *set, const void *data, size_t size)
|
||||||
{
|
{
|
||||||
struct ip_set_req_nethash_create *req =
|
const struct ip_set_req_nethash_create *req = data;
|
||||||
(struct ip_set_req_nethash_create *) data;
|
|
||||||
struct ip_set_nethash *map;
|
struct ip_set_nethash *map;
|
||||||
uint16_t i;
|
uint16_t i;
|
||||||
|
|
||||||
@@ -409,7 +402,7 @@ static int create(struct ip_set *set, const void *data, size_t size)
|
|||||||
|
|
||||||
static void destroy(struct ip_set *set)
|
static void destroy(struct ip_set *set)
|
||||||
{
|
{
|
||||||
struct ip_set_nethash *map = (struct ip_set_nethash *) set->data;
|
struct ip_set_nethash *map = set->data;
|
||||||
|
|
||||||
harray_free(map->members);
|
harray_free(map->members);
|
||||||
kfree(map);
|
kfree(map);
|
||||||
@@ -419,7 +412,7 @@ static void destroy(struct ip_set *set)
|
|||||||
|
|
||||||
static void flush(struct ip_set *set)
|
static void flush(struct ip_set *set)
|
||||||
{
|
{
|
||||||
struct ip_set_nethash *map = (struct ip_set_nethash *) set->data;
|
struct ip_set_nethash *map = set->data;
|
||||||
harray_flush(map->members, map->hashsize, sizeof(ip_set_ip_t));
|
harray_flush(map->members, map->hashsize, sizeof(ip_set_ip_t));
|
||||||
memset(map->cidr, 0, 30 * sizeof(unsigned char));
|
memset(map->cidr, 0, 30 * sizeof(unsigned char));
|
||||||
map->elements = 0;
|
map->elements = 0;
|
||||||
@@ -427,9 +420,8 @@ static void flush(struct ip_set *set)
|
|||||||
|
|
||||||
static void list_header(const struct ip_set *set, void *data)
|
static void list_header(const struct ip_set *set, void *data)
|
||||||
{
|
{
|
||||||
struct ip_set_nethash *map = (struct ip_set_nethash *) set->data;
|
const struct ip_set_nethash *map = set->data;
|
||||||
struct ip_set_req_nethash_create *header =
|
struct ip_set_req_nethash_create *header = data;
|
||||||
(struct ip_set_req_nethash_create *) data;
|
|
||||||
|
|
||||||
header->hashsize = map->hashsize;
|
header->hashsize = map->hashsize;
|
||||||
header->probes = map->probes;
|
header->probes = map->probes;
|
||||||
@@ -438,14 +430,14 @@ static void list_header(const struct ip_set *set, void *data)
|
|||||||
|
|
||||||
static int list_members_size(const struct ip_set *set)
|
static int list_members_size(const struct ip_set *set)
|
||||||
{
|
{
|
||||||
struct ip_set_nethash *map = (struct ip_set_nethash *) set->data;
|
struct ip_set_nethash *map = set->data;
|
||||||
|
|
||||||
return (map->hashsize * sizeof(ip_set_ip_t));
|
return (map->hashsize * sizeof(ip_set_ip_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void list_members(const struct ip_set *set, void *data)
|
static void list_members(const struct ip_set *set, void *data)
|
||||||
{
|
{
|
||||||
struct ip_set_nethash *map = (struct ip_set_nethash *) set->data;
|
const struct ip_set_nethash *map = set->data;
|
||||||
ip_set_ip_t i, *elem;
|
ip_set_ip_t i, *elem;
|
||||||
|
|
||||||
for (i = 0; i < map->hashsize; i++) {
|
for (i = 0; i < map->hashsize; i++) {
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
* published by the Free Software Foundation.
|
* published by the Free Software Foundation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Kernel module implementing a port set type as a bitmap */
|
/* Kernel module implementing a port set type as a bitmap */
|
||||||
@@ -78,7 +78,7 @@ get_port(const struct sk_buff *skb, u_int32_t flags)
|
|||||||
static inline int
|
static inline int
|
||||||
__testport(struct ip_set *set, ip_set_ip_t port, ip_set_ip_t *hash_port)
|
__testport(struct ip_set *set, ip_set_ip_t port, ip_set_ip_t *hash_port)
|
||||||
{
|
{
|
||||||
struct ip_set_portmap *map = (struct ip_set_portmap *) set->data;
|
struct ip_set_portmap *map = set->data;
|
||||||
|
|
||||||
if (port < map->first_port || port > map->last_port)
|
if (port < map->first_port || port > map->last_port)
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
@@ -92,8 +92,7 @@ static int
|
|||||||
testport(struct ip_set *set, const void *data, size_t size,
|
testport(struct ip_set *set, const void *data, size_t size,
|
||||||
ip_set_ip_t *hash_port)
|
ip_set_ip_t *hash_port)
|
||||||
{
|
{
|
||||||
struct ip_set_req_portmap *req =
|
const struct ip_set_req_portmap *req = data;
|
||||||
(struct ip_set_req_portmap *) data;
|
|
||||||
|
|
||||||
if (size != sizeof(struct ip_set_req_portmap)) {
|
if (size != sizeof(struct ip_set_req_portmap)) {
|
||||||
ip_set_printk("data length wrong (want %zu, have %zu)",
|
ip_set_printk("data length wrong (want %zu, have %zu)",
|
||||||
@@ -105,7 +104,7 @@ testport(struct ip_set *set, const void *data, size_t size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
testport_kernel(struct ip_set *set,
|
testport_kernel(struct ip_set *set,
|
||||||
const struct sk_buff *skb,
|
const struct sk_buff *skb,
|
||||||
ip_set_ip_t *hash_port,
|
ip_set_ip_t *hash_port,
|
||||||
const u_int32_t *flags,
|
const u_int32_t *flags,
|
||||||
@@ -126,7 +125,7 @@ testport_kernel(struct ip_set *set,
|
|||||||
static inline int
|
static inline int
|
||||||
__addport(struct ip_set *set, ip_set_ip_t port, ip_set_ip_t *hash_port)
|
__addport(struct ip_set *set, ip_set_ip_t port, ip_set_ip_t *hash_port)
|
||||||
{
|
{
|
||||||
struct ip_set_portmap *map = (struct ip_set_portmap *) set->data;
|
struct ip_set_portmap *map = set->data;
|
||||||
|
|
||||||
if (port < map->first_port || port > map->last_port)
|
if (port < map->first_port || port > map->last_port)
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
@@ -142,8 +141,7 @@ static int
|
|||||||
addport(struct ip_set *set, const void *data, size_t size,
|
addport(struct ip_set *set, const void *data, size_t size,
|
||||||
ip_set_ip_t *hash_port)
|
ip_set_ip_t *hash_port)
|
||||||
{
|
{
|
||||||
struct ip_set_req_portmap *req =
|
const struct ip_set_req_portmap *req = data;
|
||||||
(struct ip_set_req_portmap *) data;
|
|
||||||
|
|
||||||
if (size != sizeof(struct ip_set_req_portmap)) {
|
if (size != sizeof(struct ip_set_req_portmap)) {
|
||||||
ip_set_printk("data length wrong (want %zu, have %zu)",
|
ip_set_printk("data length wrong (want %zu, have %zu)",
|
||||||
@@ -155,7 +153,7 @@ addport(struct ip_set *set, const void *data, size_t size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
addport_kernel(struct ip_set *set,
|
addport_kernel(struct ip_set *set,
|
||||||
const struct sk_buff *skb,
|
const struct sk_buff *skb,
|
||||||
ip_set_ip_t *hash_port,
|
ip_set_ip_t *hash_port,
|
||||||
const u_int32_t *flags,
|
const u_int32_t *flags,
|
||||||
@@ -172,7 +170,7 @@ addport_kernel(struct ip_set *set,
|
|||||||
static inline int
|
static inline int
|
||||||
__delport(struct ip_set *set, ip_set_ip_t port, ip_set_ip_t *hash_port)
|
__delport(struct ip_set *set, ip_set_ip_t port, ip_set_ip_t *hash_port)
|
||||||
{
|
{
|
||||||
struct ip_set_portmap *map = (struct ip_set_portmap *) set->data;
|
struct ip_set_portmap *map = set->data;
|
||||||
|
|
||||||
if (port < map->first_port || port > map->last_port)
|
if (port < map->first_port || port > map->last_port)
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
@@ -188,8 +186,7 @@ static int
|
|||||||
delport(struct ip_set *set, const void *data, size_t size,
|
delport(struct ip_set *set, const void *data, size_t size,
|
||||||
ip_set_ip_t *hash_port)
|
ip_set_ip_t *hash_port)
|
||||||
{
|
{
|
||||||
struct ip_set_req_portmap *req =
|
const struct ip_set_req_portmap *req = data;
|
||||||
(struct ip_set_req_portmap *) data;
|
|
||||||
|
|
||||||
if (size != sizeof(struct ip_set_req_portmap)) {
|
if (size != sizeof(struct ip_set_req_portmap)) {
|
||||||
ip_set_printk("data length wrong (want %zu, have %zu)",
|
ip_set_printk("data length wrong (want %zu, have %zu)",
|
||||||
@@ -201,7 +198,7 @@ delport(struct ip_set *set, const void *data, size_t size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
delport_kernel(struct ip_set *set,
|
delport_kernel(struct ip_set *set,
|
||||||
const struct sk_buff *skb,
|
const struct sk_buff *skb,
|
||||||
ip_set_ip_t *hash_port,
|
ip_set_ip_t *hash_port,
|
||||||
const u_int32_t *flags,
|
const u_int32_t *flags,
|
||||||
@@ -218,8 +215,7 @@ delport_kernel(struct ip_set *set,
|
|||||||
static int create(struct ip_set *set, const void *data, size_t size)
|
static int create(struct ip_set *set, const void *data, size_t size)
|
||||||
{
|
{
|
||||||
int newbytes;
|
int newbytes;
|
||||||
struct ip_set_req_portmap_create *req =
|
const struct ip_set_req_portmap_create *req = data;
|
||||||
(struct ip_set_req_portmap_create *) data;
|
|
||||||
struct ip_set_portmap *map;
|
struct ip_set_portmap *map;
|
||||||
|
|
||||||
if (size != sizeof(struct ip_set_req_portmap_create)) {
|
if (size != sizeof(struct ip_set_req_portmap_create)) {
|
||||||
@@ -265,7 +261,7 @@ static int create(struct ip_set *set, const void *data, size_t size)
|
|||||||
|
|
||||||
static void destroy(struct ip_set *set)
|
static void destroy(struct ip_set *set)
|
||||||
{
|
{
|
||||||
struct ip_set_portmap *map = (struct ip_set_portmap *) set->data;
|
struct ip_set_portmap *map = set->data;
|
||||||
|
|
||||||
kfree(map->members);
|
kfree(map->members);
|
||||||
kfree(map);
|
kfree(map);
|
||||||
@@ -275,15 +271,14 @@ static void destroy(struct ip_set *set)
|
|||||||
|
|
||||||
static void flush(struct ip_set *set)
|
static void flush(struct ip_set *set)
|
||||||
{
|
{
|
||||||
struct ip_set_portmap *map = (struct ip_set_portmap *) set->data;
|
struct ip_set_portmap *map = set->data;
|
||||||
memset(map->members, 0, bitmap_bytes(map->first_port, map->last_port));
|
memset(map->members, 0, bitmap_bytes(map->first_port, map->last_port));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void list_header(const struct ip_set *set, void *data)
|
static void list_header(const struct ip_set *set, void *data)
|
||||||
{
|
{
|
||||||
struct ip_set_portmap *map = (struct ip_set_portmap *) set->data;
|
const struct ip_set_portmap *map = set->data;
|
||||||
struct ip_set_req_portmap_create *header =
|
struct ip_set_req_portmap_create *header = data;
|
||||||
(struct ip_set_req_portmap_create *) data;
|
|
||||||
|
|
||||||
DP("list_header %u %u", map->first_port, map->last_port);
|
DP("list_header %u %u", map->first_port, map->last_port);
|
||||||
|
|
||||||
@@ -293,14 +288,14 @@ static void list_header(const struct ip_set *set, void *data)
|
|||||||
|
|
||||||
static int list_members_size(const struct ip_set *set)
|
static int list_members_size(const struct ip_set *set)
|
||||||
{
|
{
|
||||||
struct ip_set_portmap *map = (struct ip_set_portmap *) set->data;
|
const struct ip_set_portmap *map = set->data;
|
||||||
|
|
||||||
return bitmap_bytes(map->first_port, map->last_port);
|
return bitmap_bytes(map->first_port, map->last_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void list_members(const struct ip_set *set, void *data)
|
static void list_members(const struct ip_set *set, void *data)
|
||||||
{
|
{
|
||||||
struct ip_set_portmap *map = (struct ip_set_portmap *) set->data;
|
const struct ip_set_portmap *map = set->data;
|
||||||
int bytes = bitmap_bytes(map->first_port, map->last_port);
|
int bytes = bitmap_bytes(map->first_port, map->last_port);
|
||||||
|
|
||||||
memcpy(data, map->members, bytes);
|
memcpy(data, map->members, bytes);
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
* published by the Free Software Foundation.
|
* published by the Free Software Foundation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* ipt_SET.c - netfilter target to manipulate IP sets */
|
/* ipt_SET.c - netfilter target to manipulate IP sets */
|
||||||
@@ -78,12 +78,11 @@ checkentry(const char *tablename,
|
|||||||
#endif
|
#endif
|
||||||
void *targinfo,
|
void *targinfo,
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
|
||||||
unsigned int targinfosize,
|
unsigned int targinfosize,
|
||||||
#endif
|
#endif
|
||||||
unsigned int hook_mask)
|
unsigned int hook_mask)
|
||||||
{
|
{
|
||||||
struct ipt_set_info_target *info =
|
struct ipt_set_info_target *info = targinfo;
|
||||||
(struct ipt_set_info_target *) targinfo;
|
|
||||||
ip_set_id_t index;
|
ip_set_id_t index;
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
* published by the Free Software Foundation.
|
* published by the Free Software Foundation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Kernel module to match an IP set. */
|
/* Kernel module to match an IP set. */
|
||||||
@@ -76,8 +76,7 @@ checkentry(const char *tablename,
|
|||||||
#endif
|
#endif
|
||||||
unsigned int hook_mask)
|
unsigned int hook_mask)
|
||||||
{
|
{
|
||||||
struct ipt_set_info_match *info =
|
struct ipt_set_info_match *info = matchinfo;
|
||||||
(struct ipt_set_info_match *) matchinfo;
|
|
||||||
ip_set_id_t index;
|
ip_set_id_t index;
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
|
||||||
|
Reference in New Issue
Block a user