ipset: fast forward to v4.0

This commit is contained in:
Jan Engelhardt
2009-11-11 14:23:29 +01:00
parent 6f1c1ef0ce
commit 0593b96c2c
42 changed files with 1087 additions and 1894 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -48,7 +48,8 @@
/* /*
* Used so that the kernel module and ipset-binary can match their versions * Used so that the kernel module and ipset-binary can match their versions
*/ */
#define IP_SET_PROTOCOL_VERSION 3 #define IP_SET_PROTOCOL_UNALIGNED 3
#define IP_SET_PROTOCOL_VERSION 4
#define IP_SET_MAXNAMELEN 32 /* set names and set typenames */ #define IP_SET_MAXNAMELEN 32 /* set names and set typenames */
@@ -236,7 +237,7 @@ struct ip_set_req_max_sets {
struct ip_set_req_setnames { struct ip_set_req_setnames {
unsigned op; unsigned op;
ip_set_id_t index; /* set to list/save */ ip_set_id_t index; /* set to list/save */
u_int32_t size; /* size to get setdata/bindings */ u_int32_t size; /* size to get setdata */
/* followed by sets number of struct ip_set_name_list */ /* followed by sets number of struct ip_set_name_list */
}; };
@@ -310,6 +311,11 @@ static inline int bitmap_bytes(ip_set_ip_t a, ip_set_ip_t b)
/* General limit for the elements in a set */ /* General limit for the elements in a set */
#define MAX_RANGE 0x0000FFFF #define MAX_RANGE 0x0000FFFF
/* Alignment: 'unsigned long' unsupported */
#define IPSET_ALIGNTO 4
#define IPSET_ALIGN(len) (((len) + IPSET_ALIGNTO - 1) & ~(IPSET_ALIGNTO - 1))
#define IPSET_VALIGN(len, old) ((old) ? (len) : IPSET_ALIGN(len))
#ifdef __KERNEL__ #ifdef __KERNEL__
#include "ip_set_compat.h" #include "ip_set_compat.h"
#include "ip_set_malloc.h" #include "ip_set_malloc.h"
@@ -358,16 +364,13 @@ struct ip_set_type {
*/ */
int (*testip_kernel) (struct ip_set *set, int (*testip_kernel) (struct ip_set *set,
const struct sk_buff * skb, const struct sk_buff * skb,
ip_set_ip_t *ip, const u_int32_t *flags);
const u_int32_t *flags,
unsigned char index);
/* test for IP in set (userspace: ipset -T set IP) /* test for IP in set (userspace: ipset -T set IP)
* return 0 if not in set, 1 if in set. * return 0 if not in set, 1 if in set.
*/ */
int (*testip) (struct ip_set *set, int (*testip) (struct ip_set *set,
const void *data, u_int32_t size, const void *data, u_int32_t size);
ip_set_ip_t *ip);
/* /*
* Size of the data structure passed by when * Size of the data structure passed by when
@@ -381,8 +384,7 @@ struct ip_set_type {
* If the address was not already in the set, 0 is returned. * If the address was not already in the set, 0 is returned.
*/ */
int (*addip) (struct ip_set *set, int (*addip) (struct ip_set *set,
const void *data, u_int32_t size, const void *data, u_int32_t size);
ip_set_ip_t *ip);
/* Add IP into set (kernel: iptables ... -j SET set src|dst) /* Add IP into set (kernel: iptables ... -j SET set src|dst)
* Return -EEXIST if the address is already in the set, * Return -EEXIST if the address is already in the set,
@@ -390,10 +392,8 @@ struct ip_set_type {
* If the address was not already in the set, 0 is returned. * If the address was not already in the set, 0 is returned.
*/ */
int (*addip_kernel) (struct ip_set *set, int (*addip_kernel) (struct ip_set *set,
const struct sk_buff * skb, const struct sk_buff * skb,
ip_set_ip_t *ip, const u_int32_t *flags);
const u_int32_t *flags,
unsigned char index);
/* remove IP from set (userspace: ipset -D set --entry x) /* remove IP from set (userspace: ipset -D set --entry x)
* Return -EEXIST if the address is NOT in the set, * Return -EEXIST if the address is NOT in the set,
@@ -401,8 +401,7 @@ struct ip_set_type {
* If the address really was in the set, 0 is returned. * If the address really was in the set, 0 is returned.
*/ */
int (*delip) (struct ip_set *set, int (*delip) (struct ip_set *set,
const void *data, u_int32_t size, const void *data, u_int32_t size);
ip_set_ip_t *ip);
/* remove IP from set (kernel: iptables ... -j SET --entry x) /* remove IP from set (kernel: iptables ... -j SET --entry x)
* Return -EEXIST if the address is NOT in the set, * Return -EEXIST if the address is NOT in the set,
@@ -410,10 +409,8 @@ struct ip_set_type {
* If the address really was in the set, 0 is returned. * If the address really was in the set, 0 is returned.
*/ */
int (*delip_kernel) (struct ip_set *set, int (*delip_kernel) (struct ip_set *set,
const struct sk_buff * skb, const struct sk_buff * skb,
ip_set_ip_t *ip, const u_int32_t *flags);
const u_int32_t *flags,
unsigned char index);
/* new set creation - allocated type specific items /* new set creation - allocated type specific items
*/ */
@@ -451,7 +448,7 @@ struct ip_set_type {
/* Listing: Get the size for the set members /* Listing: Get the size for the set members
*/ */
int (*list_members_size) (const struct ip_set *set); int (*list_members_size) (const struct ip_set *set, char dont_align);
/* Listing: Get the set members /* Listing: Get the set members
* *
@@ -461,7 +458,7 @@ struct ip_set_type {
* correct. * correct.
*/ */
void (*list_members) (const struct ip_set *set, void (*list_members) (const struct ip_set *set,
void *data); void *data, char dont_align);
char typename[IP_SET_MAXNAMELEN]; char typename[IP_SET_MAXNAMELEN];
unsigned char features; unsigned char features;
@@ -479,20 +476,11 @@ struct ip_set {
char name[IP_SET_MAXNAMELEN]; /* the name of the set */ char name[IP_SET_MAXNAMELEN]; /* the name of the set */
rwlock_t lock; /* lock for concurrency control */ rwlock_t lock; /* lock for concurrency control */
ip_set_id_t id; /* set id for swapping */ ip_set_id_t id; /* set id for swapping */
ip_set_id_t binding; /* default binding for the set */
atomic_t ref; /* in kernel and in hash references */ atomic_t ref; /* in kernel and in hash references */
struct ip_set_type *type; /* the set types */ struct ip_set_type *type; /* the set types */
void *data; /* pooltype specific data */ void *data; /* pooltype specific data */
}; };
/* Structure to bind set elements to sets */
struct ip_set_hash {
struct list_head list; /* list of clashing entries in hash */
ip_set_ip_t ip; /* ip from set */
ip_set_id_t id; /* set id */
ip_set_id_t binding; /* set we bind the element to */
};
/* register and unregister set references */ /* register and unregister set references */
extern ip_set_id_t ip_set_get_byname(const char name[IP_SET_MAXNAMELEN]); extern ip_set_id_t ip_set_get_byname(const char name[IP_SET_MAXNAMELEN]);
extern ip_set_id_t ip_set_get_byindex(ip_set_id_t index); extern ip_set_id_t ip_set_get_byindex(ip_set_id_t index);
@@ -523,12 +511,11 @@ extern int ip_set_testip_kernel(ip_set_id_t id,
#define UADT0(type, adt, args...) \ #define UADT0(type, adt, args...) \
static int \ static int \
FNAME(type,_u,adt)(struct ip_set *set, const void *data, u_int32_t size,\ FNAME(type,_u,adt)(struct ip_set *set, const void *data, u_int32_t size)\
ip_set_ip_t *hash_ip) \
{ \ { \
const STRUCT(ip_set_req_,type) *req = data; \ const STRUCT(ip_set_req_,type) *req = data; \
\ \
return FNAME(type,_,adt)(set, hash_ip , ## args); \ return FNAME(type,_,adt)(set , ## args); \
} }
#define UADT(type, adt, args...) \ #define UADT(type, adt, args...) \
@@ -538,14 +525,12 @@ FNAME(type,_u,adt)(struct ip_set *set, const void *data, u_int32_t size,\
static int \ static int \
FNAME(type,_k,adt)(struct ip_set *set, \ FNAME(type,_k,adt)(struct ip_set *set, \
const struct sk_buff *skb, \ const struct sk_buff *skb, \
ip_set_ip_t *hash_ip, \ const u_int32_t *flags) \
const u_int32_t *flags, \
unsigned char index) \
{ \ { \
ip_set_ip_t ip = getfn(skb, flags[index]); \ ip_set_ip_t ip = getfn(skb, flags); \
\ \
KADT_CONDITION \ KADT_CONDITION \
return FNAME(type,_,adt)(set, hash_ip, ip , ##args); \ return FNAME(type,_,adt)(set, ip , ##args); \
} }
#define REGISTER_MODULE(type) \ #define REGISTER_MODULE(type) \
@@ -567,9 +552,9 @@ module_exit(ip_set_##type##_fini);
/* Common functions */ /* Common functions */
static inline ip_set_ip_t static inline ip_set_ip_t
ipaddr(const struct sk_buff *skb, u_int32_t flag) ipaddr(const struct sk_buff *skb, const u_int32_t *flags)
{ {
return ntohl(flag & IPSET_SRC ? ip_hdr(skb)->saddr : ip_hdr(skb)->daddr); return ntohl(flags[0] & IPSET_SRC ? ip_hdr(skb)->saddr : ip_hdr(skb)->daddr);
} }
#define jhash_ip(map, i, ip) jhash_1word(ip, *(map->initval + i)) #define jhash_ip(map, i, ip) jhash_1word(ip, *(map->initval + i))
@@ -579,4 +564,6 @@ ipaddr(const struct sk_buff *skb, u_int32_t flag)
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#define UNUSED __attribute__ ((unused))
#endif /*_IP_SET_H*/ #endif /*_IP_SET_H*/

View File

@@ -77,22 +77,21 @@ type##_list_header(const struct ip_set *set, void *data) \
__##type##_list_header(map, header); \ __##type##_list_header(map, header); \
} }
#define BITMAP_LIST_MEMBERS_SIZE(type) \ #define BITMAP_LIST_MEMBERS_SIZE(type, dtype, sizeid, testfn) \
static int \ static int \
type##_list_members_size(const struct ip_set *set) \ type##_list_members_size(const struct ip_set *set, char dont_align) \
{ \ { \
const struct ip_set_##type *map = set->data; \ const struct ip_set_##type *map = set->data; \
ip_set_ip_t i, elements = 0; \
\ \
return map->size; \ if (dont_align) \
} return map->size; \
#define BITMAP_LIST_MEMBERS(type) \
static void \
type##_list_members(const struct ip_set *set, void *data) \
{ \
const struct ip_set_##type *map = set->data; \
\ \
memcpy(data, map->members, map->size); \ for (i = 0; i < sizeid; i++) \
if (testfn) \
elements++; \
\
return elements * IPSET_ALIGN(sizeof(dtype)); \
} }
#define IP_SET_TYPE(type, __features) \ #define IP_SET_TYPE(type, __features) \

View File

@@ -65,7 +65,28 @@ static inline void *kzalloc(size_t size, gfp_t flags)
#define KMEM_CACHE_CREATE(name, size) \ #define KMEM_CACHE_CREATE(name, size) \
kmem_cache_create(name, size, 0, 0, NULL) kmem_cache_create(name, size, 0, 0, NULL)
#endif #endif
#ifndef NIPQUAD
#define NIPQUAD(addr) \
((unsigned char *)&addr)[0], \
((unsigned char *)&addr)[1], \
((unsigned char *)&addr)[2], \
((unsigned char *)&addr)[3]
#endif
#ifndef HIPQUAD
#if defined(__LITTLE_ENDIAN)
#define HIPQUAD(addr) \
((unsigned char *)&addr)[3], \
((unsigned char *)&addr)[2], \
((unsigned char *)&addr)[1], \
((unsigned char *)&addr)[0]
#elif defined(__BIG_ENDIAN)
#define HIPQUAD NIPQUAD
#else
#error "Please fix asm/byteorder.h"
#endif /* __LITTLE_ENDIAN */
#endif
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* _IP_SET_COMPAT_H */ #endif /* _IP_SET_COMPAT_H */

View File

@@ -7,7 +7,7 @@
/* We must handle non-linear skbs */ /* We must handle non-linear skbs */
static inline ip_set_ip_t static inline ip_set_ip_t
get_port(const struct sk_buff *skb, u_int32_t flags) get_port(const struct sk_buff *skb, const u_int32_t *flags)
{ {
struct iphdr *iph = ip_hdr(skb); struct iphdr *iph = ip_hdr(skb);
u_int16_t offset = ntohs(iph->frag_off) & IP_OFFSET; u_int16_t offset = ntohs(iph->frag_off) & IP_OFFSET;
@@ -23,7 +23,7 @@ get_port(const struct sk_buff *skb, u_int32_t flags)
/* No choice either */ /* No choice either */
return INVALID_PORT; return INVALID_PORT;
return ntohs(flags & IPSET_SRC ? return ntohs(flags[0] & IPSET_SRC ?
tcph.source : tcph.dest); tcph.source : tcph.dest);
} }
case IPPROTO_UDP: { case IPPROTO_UDP: {
@@ -36,7 +36,7 @@ get_port(const struct sk_buff *skb, u_int32_t flags)
/* No choice either */ /* No choice either */
return INVALID_PORT; return INVALID_PORT;
return ntohs(flags & IPSET_SRC ? return ntohs(flags[0] & IPSET_SRC ?
udph.source : udph.dest); udph.source : udph.dest);
} }
default: default:

View File

@@ -182,30 +182,31 @@ type##_list_header(const struct ip_set *set, void *data) \
#define HASH_LIST_MEMBERS_SIZE(type, dtype) \ #define HASH_LIST_MEMBERS_SIZE(type, dtype) \
static int \ static int \
type##_list_members_size(const struct ip_set *set) \ type##_list_members_size(const struct ip_set *set, char dont_align) \
{ \ { \
const struct ip_set_##type *map = set->data; \ const struct ip_set_##type *map = set->data; \
\ \
return (map->hashsize * sizeof(dtype)); \ return (map->hashsize * IPSET_VALIGN(sizeof(dtype), dont_align));\
} }
#define HASH_LIST_MEMBERS(type, dtype) \ #define HASH_LIST_MEMBERS(type, dtype) \
static void \ static void \
type##_list_members(const struct ip_set *set, void *data) \ type##_list_members(const struct ip_set *set, void *data, char dont_align)\
{ \ { \
const struct ip_set_##type *map = set->data; \ const struct ip_set_##type *map = set->data; \
dtype *elem; \ dtype *elem, *d; \
uint32_t i; \ uint32_t i; \
\ \
for (i = 0; i < map->hashsize; i++) { \ for (i = 0; i < map->hashsize; i++) { \
elem = HARRAY_ELEM(map->members, dtype *, i); \ elem = HARRAY_ELEM(map->members, dtype *, i); \
((dtype *)data)[i] = *elem; \ d = data + i * IPSET_VALIGN(sizeof(dtype), dont_align); \
*d = *elem; \
} \ } \
} }
#define HASH_LIST_MEMBERS_MEMCPY(type, dtype) \ #define HASH_LIST_MEMBERS_MEMCPY(type, dtype) \
static void \ static void \
type##_list_members(const struct ip_set *set, void *data) \ type##_list_members(const struct ip_set *set, void *data, char dont_align)\
{ \ { \
const struct ip_set_##type *map = set->data; \ const struct ip_set_##type *map = set->data; \
dtype *elem; \ dtype *elem; \
@@ -213,7 +214,8 @@ type##_list_members(const struct ip_set *set, void *data) \
\ \
for (i = 0; i < map->hashsize; i++) { \ for (i = 0; i < map->hashsize; i++) { \
elem = HARRAY_ELEM(map->members, dtype *, i); \ elem = HARRAY_ELEM(map->members, dtype *, i); \
memcpy((((dtype *)data)+i), elem, sizeof(dtype)); \ memcpy(data + i * IPSET_VALIGN(sizeof(dtype), dont_align),\
elem, sizeof(dtype)); \
} \ } \
} }

View File

@@ -25,22 +25,21 @@
static int limit = MAX_RANGE; static int limit = MAX_RANGE;
static inline __u32 static inline __u32
iphash_id(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip) iphash_id(struct ip_set *set, ip_set_ip_t ip)
{ {
struct ip_set_iphash *map = 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;
*hash_ip = ip & map->netmask;
DP("set: %s, ip:%u.%u.%u.%u, %u.%u.%u.%u, %u.%u.%u.%u", ip &= map->netmask;
set->name, HIPQUAD(ip), HIPQUAD(*hash_ip), HIPQUAD(map->netmask)); DP("set: %s, ip:%u.%u.%u.%u", set->name, HIPQUAD(ip));
for (i = 0; i < map->probes; i++) { for (i = 0; i < map->probes; i++) {
id = jhash_ip(map, i, *hash_ip) % map->hashsize; id = jhash_ip(map, i, ip) % map->hashsize;
DP("hash key: %u", id); DP("hash key: %u", id);
elem = HARRAY_ELEM(map->members, ip_set_ip_t *, id); elem = HARRAY_ELEM(map->members, ip_set_ip_t *, id);
if (*elem == *hash_ip) if (*elem == ip)
return id; return id;
/* No shortcut - there can be deleted entries. */ /* No shortcut - there can be deleted entries. */
} }
@@ -48,9 +47,9 @@ iphash_id(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
} }
static inline int static inline int
iphash_test(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip) iphash_test(struct ip_set *set, ip_set_ip_t ip)
{ {
return (ip && iphash_id(set, hash_ip, ip) != UINT_MAX); return (ip && iphash_id(set, ip) != UINT_MAX);
} }
#define KADT_CONDITION #define KADT_CONDITION
@@ -84,16 +83,15 @@ __iphash_add(struct ip_set_iphash *map, ip_set_ip_t *ip)
} }
static inline int static inline int
iphash_add(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip) iphash_add(struct ip_set *set, ip_set_ip_t ip)
{ {
struct ip_set_iphash *map = set->data; struct ip_set_iphash *map = set->data;
if (!ip || map->elements >= limit) if (!ip || map->elements >= limit)
return -ERANGE; return -ERANGE;
*hash_ip = ip & map->netmask; ip &= map->netmask;
return __iphash_add(map, &ip);
return __iphash_add(map, hash_ip);
} }
UADT(iphash, add) UADT(iphash, add)
@@ -108,7 +106,7 @@ __iphash_retry(struct ip_set_iphash *tmp, struct ip_set_iphash *map)
HASH_RETRY(iphash, ip_set_ip_t) HASH_RETRY(iphash, ip_set_ip_t)
static inline int static inline int
iphash_del(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip) iphash_del(struct ip_set *set, ip_set_ip_t ip)
{ {
struct ip_set_iphash *map = set->data; struct ip_set_iphash *map = set->data;
ip_set_ip_t id, *elem; ip_set_ip_t id, *elem;
@@ -116,7 +114,7 @@ iphash_del(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
if (!ip) if (!ip)
return -ERANGE; return -ERANGE;
id = iphash_id(set, hash_ip, ip); id = iphash_id(set, ip);
if (id == UINT_MAX) if (id == UINT_MAX)
return -EEXIST; return -EEXIST;

View File

@@ -4,7 +4,7 @@
#include "ip_set.h" #include "ip_set.h"
#include "ip_set_hashes.h" #include "ip_set_hashes.h"
#define SETTYPE_NAME "iphash" #define SETTYPE_NAME "iphash"
struct ip_set_iphash { struct ip_set_iphash {
ip_set_ip_t *members; /* the iphash proper */ ip_set_ip_t *members; /* the iphash proper */

View File

@@ -22,21 +22,19 @@
static inline ip_set_ip_t static inline ip_set_ip_t
ip_to_id(const struct ip_set_ipmap *map, ip_set_ip_t ip) ip_to_id(const struct ip_set_ipmap *map, ip_set_ip_t ip)
{ {
return (ip - map->first_ip)/map->hosts; return ((ip & map->netmask) - map->first_ip)/map->hosts;
} }
static inline int static inline int
ipmap_test(const struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip) ipmap_test(const struct ip_set *set, ip_set_ip_t ip)
{ {
const struct ip_set_ipmap *map = set->data; const 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;
*hash_ip = ip & map->netmask; DP("set: %s, ip:%u.%u.%u.%u", set->name, HIPQUAD(ip));
DP("set: %s, ip:%u.%u.%u.%u, %u.%u.%u.%u", return !!test_bit(ip_to_id(map, ip), map->members);
set->name, HIPQUAD(ip), HIPQUAD(*hash_ip));
return !!test_bit(ip_to_id(map, *hash_ip), map->members);
} }
#define KADT_CONDITION #define KADT_CONDITION
@@ -45,16 +43,15 @@ UADT(ipmap, test)
KADT(ipmap, test, ipaddr) KADT(ipmap, test, ipaddr)
static inline int static inline int
ipmap_add(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip) ipmap_add(struct ip_set *set, ip_set_ip_t ip)
{ {
struct ip_set_ipmap *map = 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;
*hash_ip = ip & map->netmask; DP("set: %s, ip:%u.%u.%u.%u", set->name, HIPQUAD(ip));
DP("%u.%u.%u.%u, %u.%u.%u.%u", HIPQUAD(ip), HIPQUAD(*hash_ip)); if (test_and_set_bit(ip_to_id(map, ip), map->members))
if (test_and_set_bit(ip_to_id(map, *hash_ip), map->members))
return -EEXIST; return -EEXIST;
return 0; return 0;
@@ -64,16 +61,15 @@ UADT(ipmap, add)
KADT(ipmap, add, ipaddr) KADT(ipmap, add, ipaddr)
static inline int static inline int
ipmap_del(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip) ipmap_del(struct ip_set *set, ip_set_ip_t ip)
{ {
struct ip_set_ipmap *map = 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;
*hash_ip = ip & map->netmask; DP("set: %s, ip:%u.%u.%u.%u", set->name, HIPQUAD(ip));
DP("%u.%u.%u.%u, %u.%u.%u.%u", HIPQUAD(ip), HIPQUAD(*hash_ip)); if (!test_and_clear_bit(ip_to_id(map, ip), map->members))
if (!test_and_clear_bit(ip_to_id(map, *hash_ip), map->members))
return -EEXIST; return -EEXIST;
return 0; return 0;
@@ -130,8 +126,28 @@ __ipmap_list_header(const struct ip_set_ipmap *map,
} }
BITMAP_LIST_HEADER(ipmap) BITMAP_LIST_HEADER(ipmap)
BITMAP_LIST_MEMBERS_SIZE(ipmap) BITMAP_LIST_MEMBERS_SIZE(ipmap, ip_set_ip_t, map->sizeid,
BITMAP_LIST_MEMBERS(ipmap) test_bit(i, map->members))
static void
ipmap_list_members(const struct ip_set *set, void *data, char dont_align)
{
const struct ip_set_ipmap *map = set->data;
uint32_t i, n = 0;
ip_set_ip_t *d;
if (dont_align) {
memcpy(data, map->members, map->size);
return;
}
for (i = 0; i < map->sizeid; i++)
if (test_bit(i, map->members)) {
d = data + n * IPSET_ALIGN(sizeof(ip_set_ip_t));
*d = map->first_ip + i * map->hosts;
n++;
}
}
IP_SET_TYPE(ipmap, IPSET_TYPE_IP | IPSET_DATA_SINGLE) IP_SET_TYPE(ipmap, IPSET_TYPE_IP | IPSET_DATA_SINGLE)

View File

@@ -4,7 +4,7 @@
#include "ip_set.h" #include "ip_set.h"
#include "ip_set_bitmaps.h" #include "ip_set_bitmaps.h"
#define SETTYPE_NAME "ipmap" #define SETTYPE_NAME "ipmap"
struct ip_set_ipmap { struct ip_set_ipmap {
void *members; /* the ipmap proper */ void *members; /* the ipmap proper */

View File

@@ -28,26 +28,23 @@
static int limit = MAX_RANGE; static int limit = MAX_RANGE;
static inline __u32 static inline __u32
ipporthash_id(struct ip_set *set, ip_set_ip_t *hash_ip, ipporthash_id(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t port)
ip_set_ip_t ip, ip_set_ip_t port)
{ {
struct ip_set_ipporthash *map = set->data; struct ip_set_ipporthash *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;
*hash_ip = pack_ip_port(map, ip, port); ip = pack_ip_port(map, ip, port);
DP("set: %s, ipport:%u.%u.%u.%u:%u, %u.%u.%u.%u", if (!ip)
set->name, HIPQUAD(ip), port, HIPQUAD(*hash_ip));
if (!*hash_ip)
return UINT_MAX; return UINT_MAX;
for (i = 0; i < map->probes; i++) { for (i = 0; i < map->probes; i++) {
id = jhash_ip(map, i, *hash_ip) % map->hashsize; id = jhash_ip(map, i, ip) % map->hashsize;
DP("hash key: %u", id); DP("hash key: %u", id);
elem = HARRAY_ELEM(map->members, ip_set_ip_t *, id); elem = HARRAY_ELEM(map->members, ip_set_ip_t *, id);
if (*elem == *hash_ip) if (*elem == ip)
return id; return id;
/* No shortcut - there can be deleted entries. */ /* No shortcut - there can be deleted entries. */
} }
@@ -55,24 +52,23 @@ ipporthash_id(struct ip_set *set, ip_set_ip_t *hash_ip,
} }
static inline int static inline int
ipporthash_test(struct ip_set *set, ip_set_ip_t *hash_ip, ipporthash_test(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t port)
ip_set_ip_t ip, ip_set_ip_t port)
{ {
struct ip_set_ipporthash *map = 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;
return (ipporthash_id(set, hash_ip, ip, port) != UINT_MAX); return (ipporthash_id(set, ip, port) != UINT_MAX);
} }
#define KADT_CONDITION \ #define KADT_CONDITION \
ip_set_ip_t port; \ ip_set_ip_t port; \
\ \
if (flags[index+1] == 0) \ if (flags[1] == 0) \
return 0; \ return 0; \
\ \
port = get_port(skb, flags[index+1]); \ port = get_port(skb, flags++); \
\ \
if (port == INVALID_PORT) \ if (port == INVALID_PORT) \
return 0; return 0;
@@ -106,8 +102,7 @@ __ipporthash_add(struct ip_set_ipporthash *map, ip_set_ip_t *ip)
} }
static inline int static inline int
ipporthash_add(struct ip_set *set, ip_set_ip_t *hash_ip, ipporthash_add(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t port)
ip_set_ip_t ip, ip_set_ip_t port)
{ {
struct ip_set_ipporthash *map = set->data; struct ip_set_ipporthash *map = set->data;
if (map->elements > limit) if (map->elements > limit)
@@ -115,12 +110,12 @@ ipporthash_add(struct ip_set *set, ip_set_ip_t *hash_ip,
if (ip < map->first_ip || ip > map->last_ip) if (ip < map->first_ip || ip > map->last_ip)
return -ERANGE; return -ERANGE;
*hash_ip = pack_ip_port(map, ip, port); ip = pack_ip_port(map, ip, port);
if (!*hash_ip) if (!ip)
return -ERANGE; return -ERANGE;
return __ipporthash_add(map, hash_ip); return __ipporthash_add(map, &ip);
} }
UADT(ipporthash, add, req->port) UADT(ipporthash, add, req->port)
@@ -137,8 +132,7 @@ __ipporthash_retry(struct ip_set_ipporthash *tmp,
HASH_RETRY(ipporthash, ip_set_ip_t) HASH_RETRY(ipporthash, ip_set_ip_t)
static inline int static inline int
ipporthash_del(struct ip_set *set, ip_set_ip_t *hash_ip, ipporthash_del(struct ip_set *set, ip_set_ip_t ip, ip_set_ip_t port)
ip_set_ip_t ip, ip_set_ip_t port)
{ {
struct ip_set_ipporthash *map = set->data; struct ip_set_ipporthash *map = set->data;
ip_set_ip_t id; ip_set_ip_t id;
@@ -147,7 +141,7 @@ ipporthash_del(struct ip_set *set, ip_set_ip_t *hash_ip,
if (ip < map->first_ip || ip > map->last_ip) if (ip < map->first_ip || ip > map->last_ip)
return -ERANGE; return -ERANGE;
id = ipporthash_id(set, hash_ip, ip, port); id = ipporthash_id(set, ip, port);
if (id == UINT_MAX) if (id == UINT_MAX)
return -EEXIST; return -EEXIST;

View File

@@ -4,7 +4,7 @@
#include "ip_set.h" #include "ip_set.h"
#include "ip_set_hashes.h" #include "ip_set_hashes.h"
#define SETTYPE_NAME "ipporthash" #define SETTYPE_NAME "ipporthash"
struct ip_set_ipporthash { struct ip_set_ipporthash {
ip_set_ip_t *members; /* the ipporthash proper */ ip_set_ip_t *members; /* the ipporthash proper */

View File

@@ -31,7 +31,7 @@ static int limit = MAX_RANGE;
jhash_2words(ipport, ip1, *(map->initval + i)) jhash_2words(ipport, ip1, *(map->initval + i))
static inline __u32 static inline __u32
ipportiphash_id(struct ip_set *set, ip_set_ip_t *hash_ip, ipportiphash_id(struct ip_set *set,
ip_set_ip_t ip, ip_set_ip_t port, ip_set_ip_t ip1) ip_set_ip_t ip, ip_set_ip_t port, ip_set_ip_t ip1)
{ {
struct ip_set_ipportiphash *map = set->data; struct ip_set_ipportiphash *map = set->data;
@@ -39,17 +39,15 @@ ipportiphash_id(struct ip_set *set, ip_set_ip_t *hash_ip,
u_int16_t i; u_int16_t i;
struct ipportip *elem; struct ipportip *elem;
*hash_ip = pack_ip_port(map, ip, port); ip = pack_ip_port(map, ip, port);
DP("set: %s, ipport:%u.%u.%u.%u:%u, %u.%u.%u.%u", if (!(ip || ip1))
set->name, HIPQUAD(ip), port, HIPQUAD(*hash_ip));
if (!(*hash_ip || ip1))
return UINT_MAX; return UINT_MAX;
for (i = 0; i < map->probes; i++) { for (i = 0; i < map->probes; i++) {
id = jhash_ip2(map, i, *hash_ip, ip1) % map->hashsize; id = jhash_ip2(map, i, ip, ip1) % map->hashsize;
DP("hash key: %u", id); DP("hash key: %u", id);
elem = HARRAY_ELEM(map->members, struct ipportip *, id); elem = HARRAY_ELEM(map->members, struct ipportip *, id);
if (elem->ip == *hash_ip && elem->ip1 == ip1) if (elem->ip == ip && elem->ip1 == ip1)
return id; return id;
/* No shortcut - there can be deleted entries. */ /* No shortcut - there can be deleted entries. */
} }
@@ -57,7 +55,7 @@ ipportiphash_id(struct ip_set *set, ip_set_ip_t *hash_ip,
} }
static inline int static inline int
ipportiphash_test(struct ip_set *set, ip_set_ip_t *hash_ip, ipportiphash_test(struct ip_set *set,
ip_set_ip_t ip, ip_set_ip_t port, ip_set_ip_t ip1) ip_set_ip_t ip, ip_set_ip_t port, ip_set_ip_t ip1)
{ {
struct ip_set_ipportiphash *map = set->data; struct ip_set_ipportiphash *map = set->data;
@@ -65,17 +63,17 @@ ipportiphash_test(struct ip_set *set, ip_set_ip_t *hash_ip,
if (ip < map->first_ip || ip > map->last_ip) if (ip < map->first_ip || ip > map->last_ip)
return -ERANGE; return -ERANGE;
return (ipportiphash_id(set, hash_ip, ip, port, ip1) != UINT_MAX); return (ipportiphash_id(set, ip, port, ip1) != UINT_MAX);
} }
#define KADT_CONDITION \ #define KADT_CONDITION \
ip_set_ip_t port, ip1; \ ip_set_ip_t port, ip1; \
\ \
if (flags[index+2] == 0) \ if (flags[2] == 0) \
return 0; \ return 0; \
\ \
port = get_port(skb, flags[index+1]); \ port = get_port(skb, flags++); \
ip1 = ipaddr(skb, flags[index+2]); \ ip1 = ipaddr(skb, flags++); \
\ \
if (port == INVALID_PORT) \ if (port == INVALID_PORT) \
return 0; return 0;
@@ -85,23 +83,23 @@ KADT(ipportiphash, test, ipaddr, port, ip1)
static inline int static inline int
__ipportip_add(struct ip_set_ipportiphash *map, __ipportip_add(struct ip_set_ipportiphash *map,
ip_set_ip_t hash_ip, ip_set_ip_t ip1) ip_set_ip_t ip, ip_set_ip_t ip1)
{ {
__u32 probe; __u32 probe;
u_int16_t i; u_int16_t i;
struct ipportip *elem, *slot = NULL; struct ipportip *elem, *slot = NULL;
for (i = 0; i < map->probes; i++) { for (i = 0; i < map->probes; i++) {
probe = jhash_ip2(map, i, hash_ip, ip1) % map->hashsize; probe = jhash_ip2(map, i, ip, ip1) % map->hashsize;
elem = HARRAY_ELEM(map->members, struct ipportip *, probe); elem = HARRAY_ELEM(map->members, struct ipportip *, probe);
if (elem->ip == hash_ip && elem->ip1 == ip1) if (elem->ip == ip && elem->ip1 == ip1)
return -EEXIST; return -EEXIST;
if (!(slot || elem->ip || elem->ip1)) if (!(slot || elem->ip || elem->ip1))
slot = elem; slot = elem;
/* There can be deleted entries, must check all slots */ /* There can be deleted entries, must check all slots */
} }
if (slot) { if (slot) {
slot->ip = hash_ip; slot->ip = ip;
slot->ip1 = ip1; slot->ip1 = ip1;
map->elements++; map->elements++;
return 0; return 0;
@@ -118,7 +116,7 @@ __ipportiphash_add(struct ip_set_ipportiphash *map,
} }
static inline int static inline int
ipportiphash_add(struct ip_set *set, ip_set_ip_t *hash_ip, ipportiphash_add(struct ip_set *set,
ip_set_ip_t ip, ip_set_ip_t port, ip_set_ip_t ip1) ip_set_ip_t ip, ip_set_ip_t port, ip_set_ip_t ip1)
{ {
struct ip_set_ipportiphash *map = set->data; struct ip_set_ipportiphash *map = set->data;
@@ -128,11 +126,11 @@ ipportiphash_add(struct ip_set *set, ip_set_ip_t *hash_ip,
if (ip < map->first_ip || ip > map->last_ip) if (ip < map->first_ip || ip > map->last_ip)
return -ERANGE; return -ERANGE;
*hash_ip = pack_ip_port(map, ip, port); ip = pack_ip_port(map, ip, port);
if (!(*hash_ip || ip1)) if (!(ip || ip1))
return -ERANGE; return -ERANGE;
return __ipportip_add(map, *hash_ip, ip1); return __ipportip_add(map, ip, ip1);
} }
UADT(ipportiphash, add, req->port, req->ip1) UADT(ipportiphash, add, req->port, req->ip1)
@@ -149,7 +147,7 @@ __ipportiphash_retry(struct ip_set_ipportiphash *tmp,
HASH_RETRY2(ipportiphash, struct ipportip) HASH_RETRY2(ipportiphash, struct ipportip)
static inline int static inline int
ipportiphash_del(struct ip_set *set, ip_set_ip_t *hash_ip, ipportiphash_del(struct ip_set *set,
ip_set_ip_t ip, ip_set_ip_t port, ip_set_ip_t ip1) ip_set_ip_t ip, ip_set_ip_t port, ip_set_ip_t ip1)
{ {
struct ip_set_ipportiphash *map = set->data; struct ip_set_ipportiphash *map = set->data;
@@ -159,7 +157,7 @@ ipportiphash_del(struct ip_set *set, ip_set_ip_t *hash_ip,
if (ip < map->first_ip || ip > map->last_ip) if (ip < map->first_ip || ip > map->last_ip)
return -ERANGE; return -ERANGE;
id = ipportiphash_id(set, hash_ip, ip, port, ip1); id = ipportiphash_id(set, ip, port, ip1);
if (id == UINT_MAX) if (id == UINT_MAX)
return -EEXIST; return -EEXIST;

View File

@@ -4,7 +4,7 @@
#include "ip_set.h" #include "ip_set.h"
#include "ip_set_hashes.h" #include "ip_set_hashes.h"
#define SETTYPE_NAME "ipportiphash" #define SETTYPE_NAME "ipportiphash"
struct ipportip { struct ipportip {
ip_set_ip_t ip; ip_set_ip_t ip;

View File

@@ -31,7 +31,7 @@ static int limit = MAX_RANGE;
jhash_2words(ipport, ip1, *(map->initval + i)) jhash_2words(ipport, ip1, *(map->initval + i))
static inline __u32 static inline __u32
ipportnethash_id_cidr(struct ip_set *set, ip_set_ip_t *hash_ip, ipportnethash_id_cidr(struct ip_set *set,
ip_set_ip_t ip, ip_set_ip_t port, ip_set_ip_t ip, ip_set_ip_t port,
ip_set_ip_t ip1, uint8_t cidr) ip_set_ip_t ip1, uint8_t cidr)
{ {
@@ -40,18 +40,16 @@ ipportnethash_id_cidr(struct ip_set *set, ip_set_ip_t *hash_ip,
u_int16_t i; u_int16_t i;
struct ipportip *elem; struct ipportip *elem;
*hash_ip = pack_ip_port(map, ip, port); ip = pack_ip_port(map, ip, port);
DP("set: %s, ipport:%u.%u.%u.%u:%u, %u.%u.%u.%u",
set->name, HIPQUAD(ip), port, HIPQUAD(*hash_ip));
ip1 = pack_ip_cidr(ip1, cidr); ip1 = pack_ip_cidr(ip1, cidr);
if (!(*hash_ip || ip1)) if (!(ip || ip1))
return UINT_MAX; return UINT_MAX;
for (i = 0; i < map->probes; i++) { for (i = 0; i < map->probes; i++) {
id = jhash_ip2(map, i, *hash_ip, ip1) % map->hashsize; id = jhash_ip2(map, i, ip, ip1) % map->hashsize;
DP("hash key: %u", id); DP("hash key: %u", id);
elem = HARRAY_ELEM(map->members, struct ipportip *, id); elem = HARRAY_ELEM(map->members, struct ipportip *, id);
if (elem->ip == *hash_ip && elem->ip1 == ip1) if (elem->ip == ip && elem->ip1 == ip1)
return id; return id;
/* No shortcut - there can be deleted entries. */ /* No shortcut - there can be deleted entries. */
} }
@@ -59,7 +57,7 @@ ipportnethash_id_cidr(struct ip_set *set, ip_set_ip_t *hash_ip,
} }
static inline __u32 static inline __u32
ipportnethash_id(struct ip_set *set, ip_set_ip_t *hash_ip, ipportnethash_id(struct ip_set *set,
ip_set_ip_t ip, ip_set_ip_t port, ip_set_ip_t ip1) ip_set_ip_t ip, ip_set_ip_t port, ip_set_ip_t ip1)
{ {
struct ip_set_ipportnethash *map = set->data; struct ip_set_ipportnethash *map = set->data;
@@ -67,8 +65,7 @@ ipportnethash_id(struct ip_set *set, ip_set_ip_t *hash_ip,
int i; int i;
for (i = 0; i < 30 && map->cidr[i]; i++) { for (i = 0; i < 30 && map->cidr[i]; i++) {
id = ipportnethash_id_cidr(set, hash_ip, ip, port, ip1, id = ipportnethash_id_cidr(set, ip, port, ip1, map->cidr[i]);
map->cidr[i]);
if (id != UINT_MAX) if (id != UINT_MAX)
break; break;
} }
@@ -76,7 +73,7 @@ ipportnethash_id(struct ip_set *set, ip_set_ip_t *hash_ip,
} }
static inline int static inline int
ipportnethash_test_cidr(struct ip_set *set, ip_set_ip_t *hash_ip, ipportnethash_test_cidr(struct ip_set *set,
ip_set_ip_t ip, ip_set_ip_t port, ip_set_ip_t ip, ip_set_ip_t port,
ip_set_ip_t ip1, uint8_t cidr) ip_set_ip_t ip1, uint8_t cidr)
{ {
@@ -85,12 +82,11 @@ ipportnethash_test_cidr(struct ip_set *set, ip_set_ip_t *hash_ip,
if (ip < map->first_ip || ip > map->last_ip) if (ip < map->first_ip || ip > map->last_ip)
return -ERANGE; return -ERANGE;
return (ipportnethash_id_cidr(set, hash_ip, ip, port, ip1, return (ipportnethash_id_cidr(set, ip, port, ip1, cidr) != UINT_MAX);
cidr) != UINT_MAX);
} }
static inline int static inline int
ipportnethash_test(struct ip_set *set, ip_set_ip_t *hash_ip, ipportnethash_test(struct ip_set *set,
ip_set_ip_t ip, ip_set_ip_t port, ip_set_ip_t ip1) ip_set_ip_t ip, ip_set_ip_t port, ip_set_ip_t ip1)
{ {
struct ip_set_ipportnethash *map = set->data; struct ip_set_ipportnethash *map = set->data;
@@ -98,32 +94,30 @@ ipportnethash_test(struct ip_set *set, ip_set_ip_t *hash_ip,
if (ip < map->first_ip || ip > map->last_ip) if (ip < map->first_ip || ip > map->last_ip)
return -ERANGE; return -ERANGE;
return (ipportnethash_id(set, hash_ip, ip, port, ip1) != UINT_MAX); return (ipportnethash_id(set, ip, port, ip1) != UINT_MAX);
} }
static int static int
ipportnethash_utest(struct ip_set *set, const void *data, u_int32_t size, ipportnethash_utest(struct ip_set *set, const void *data, u_int32_t size)
ip_set_ip_t *hash_ip)
{ {
const struct ip_set_req_ipportnethash *req = data; const struct ip_set_req_ipportnethash *req = data;
if (req->cidr <= 0 || req->cidr > 32) if (req->cidr <= 0 || req->cidr > 32)
return -EINVAL; return -EINVAL;
return (req->cidr == 32 return (req->cidr == 32
? ipportnethash_test(set, hash_ip, req->ip, req->port, ? ipportnethash_test(set, req->ip, req->port, req->ip1)
req->ip1) : ipportnethash_test_cidr(set, req->ip, req->port,
: ipportnethash_test_cidr(set, hash_ip, req->ip, req->port,
req->ip1, req->cidr)); req->ip1, req->cidr));
} }
#define KADT_CONDITION \ #define KADT_CONDITION \
ip_set_ip_t port, ip1; \ ip_set_ip_t port, ip1; \
\ \
if (flags[index+2] == 0) \ if (flags[2] == 0) \
return 0; \ return 0; \
\ \
port = get_port(skb, flags[index+1]); \ port = get_port(skb, flags++); \
ip1 = ipaddr(skb, flags[index+2]); \ ip1 = ipaddr(skb, flags++); \
\ \
if (port == INVALID_PORT) \ if (port == INVALID_PORT) \
return 0; return 0;
@@ -132,23 +126,23 @@ KADT(ipportnethash, test, ipaddr, port, ip1)
static inline int static inline int
__ipportnet_add(struct ip_set_ipportnethash *map, __ipportnet_add(struct ip_set_ipportnethash *map,
ip_set_ip_t hash_ip, ip_set_ip_t ip1) ip_set_ip_t ip, ip_set_ip_t ip1)
{ {
__u32 probe; __u32 probe;
u_int16_t i; u_int16_t i;
struct ipportip *elem, *slot = NULL; struct ipportip *elem, *slot = NULL;
for (i = 0; i < map->probes; i++) { for (i = 0; i < map->probes; i++) {
probe = jhash_ip2(map, i, hash_ip, ip1) % map->hashsize; probe = jhash_ip2(map, i, ip, ip1) % map->hashsize;
elem = HARRAY_ELEM(map->members, struct ipportip *, probe); elem = HARRAY_ELEM(map->members, struct ipportip *, probe);
if (elem->ip == hash_ip && elem->ip1 == ip1) if (elem->ip == ip && elem->ip1 == ip1)
return -EEXIST; return -EEXIST;
if (!(slot || elem->ip || elem->ip1)) if (!(slot || elem->ip || elem->ip1))
slot = elem; slot = elem;
/* There can be deleted entries, must check all slots */ /* There can be deleted entries, must check all slots */
} }
if (slot) { if (slot) {
slot->ip = hash_ip; slot->ip = ip;
slot->ip1 = ip1; slot->ip1 = ip1;
map->elements++; map->elements++;
return 0; return 0;
@@ -165,7 +159,7 @@ __ipportnethash_add(struct ip_set_ipportnethash *map,
} }
static inline int static inline int
ipportnethash_add(struct ip_set *set, ip_set_ip_t *hash_ip, ipportnethash_add(struct ip_set *set,
ip_set_ip_t ip, ip_set_ip_t port, ip_set_ip_t ip, ip_set_ip_t port,
ip_set_ip_t ip1, uint8_t cidr) ip_set_ip_t ip1, uint8_t cidr)
{ {
@@ -182,12 +176,12 @@ ipportnethash_add(struct ip_set *set, ip_set_ip_t *hash_ip,
if (map->nets[cidr-1] == UINT16_MAX) if (map->nets[cidr-1] == UINT16_MAX)
return -ERANGE; return -ERANGE;
*hash_ip = pack_ip_port(map, ip, port); ip = pack_ip_port(map, ip, port);
ip1 = pack_ip_cidr(ip1, cidr); ip1 = pack_ip_cidr(ip1, cidr);
if (!(*hash_ip || ip1)) if (!(ip || ip1))
return -ERANGE; return -ERANGE;
ret =__ipportnet_add(map, *hash_ip, ip1); ret =__ipportnet_add(map, ip, ip1);
if (ret == 0) { if (ret == 0) {
if (!map->nets[cidr-1]++) if (!map->nets[cidr-1]++)
add_cidr_size(map->cidr, cidr); add_cidr_size(map->cidr, cidr);
@@ -202,11 +196,11 @@ ipportnethash_add(struct ip_set *set, ip_set_ip_t *hash_ip,
uint8_t cidr = map->cidr[0] ? map->cidr[0] : 31; \ uint8_t cidr = map->cidr[0] ? map->cidr[0] : 31; \
ip_set_ip_t port, ip1; \ ip_set_ip_t port, ip1; \
\ \
if (flags[index+2] == 0) \ if (flags[2] == 0) \
return 0; \ return 0; \
\ \
port = get_port(skb, flags[index+1]); \ port = get_port(skb, flags++); \
ip1 = ipaddr(skb, flags[index+2]); \ ip1 = ipaddr(skb, flags++); \
\ \
if (port == INVALID_PORT) \ if (port == INVALID_PORT) \
return 0; return 0;
@@ -227,7 +221,7 @@ __ipportnethash_retry(struct ip_set_ipportnethash *tmp,
HASH_RETRY2(ipportnethash, struct ipportip) HASH_RETRY2(ipportnethash, struct ipportip)
static inline int static inline int
ipportnethash_del(struct ip_set *set, ip_set_ip_t *hash_ip, ipportnethash_del(struct ip_set *set,
ip_set_ip_t ip, ip_set_ip_t port, ip_set_ip_t ip, ip_set_ip_t port,
ip_set_ip_t ip1, uint8_t cidr) ip_set_ip_t ip1, uint8_t cidr)
{ {
@@ -242,7 +236,7 @@ ipportnethash_del(struct ip_set *set, ip_set_ip_t *hash_ip,
if (cidr <= 0 || cidr >= 32) if (cidr <= 0 || cidr >= 32)
return -EINVAL; return -EINVAL;
id = ipportnethash_id_cidr(set, hash_ip, ip, port, ip1, cidr); id = ipportnethash_id_cidr(set, ip, port, ip1, cidr);
if (id == UINT_MAX) if (id == UINT_MAX)
return -EEXIST; return -EEXIST;

View File

@@ -4,7 +4,7 @@
#include "ip_set.h" #include "ip_set.h"
#include "ip_set_hashes.h" #include "ip_set_hashes.h"
#define SETTYPE_NAME "ipportnethash" #define SETTYPE_NAME "ipportnethash"
struct ipportip { struct ipportip {
ip_set_ip_t ip; ip_set_ip_t ip;

View File

@@ -62,7 +62,7 @@ static __KMEM_CACHE_T__ *leaf_cachep;
} while (0) } while (0)
static inline int static inline int
iptree_test(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip) iptree_test(struct ip_set *set, ip_set_ip_t ip)
{ {
struct ip_set_iptree *map = set->data; struct ip_set_iptree *map = set->data;
struct ip_set_iptreeb *btree; struct ip_set_iptreeb *btree;
@@ -73,8 +73,7 @@ iptree_test(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
if (!ip) if (!ip)
return -ERANGE; return -ERANGE;
*hash_ip = ip; ABCD(a, b, c, d, &ip);
ABCD(a, b, c, d, hash_ip);
DP("%u %u %u %u timeout %u", a, b, c, d, map->timeout); DP("%u %u %u %u timeout %u", a, b, c, d, map->timeout);
TESTIP_WALK(map, a, btree); TESTIP_WALK(map, a, btree);
TESTIP_WALK(btree, b, ctree); TESTIP_WALK(btree, b, ctree);
@@ -106,8 +105,7 @@ KADT(iptree, test, ipaddr)
} while (0) } while (0)
static inline int static inline int
iptree_add(struct ip_set *set, ip_set_ip_t *hash_ip, iptree_add(struct ip_set *set, ip_set_ip_t ip, unsigned int timeout)
ip_set_ip_t ip, unsigned int timeout)
{ {
struct ip_set_iptree *map = set->data; struct ip_set_iptree *map = set->data;
struct ip_set_iptreeb *btree; struct ip_set_iptreeb *btree;
@@ -121,8 +119,7 @@ iptree_add(struct ip_set *set, ip_set_ip_t *hash_ip,
* but it's probably overkill */ * but it's probably overkill */
return -ERANGE; return -ERANGE;
*hash_ip = ip; ABCD(a, b, c, d, &ip);
ABCD(a, b, c, d, hash_ip);
DP("%u %u %u %u timeout %u", a, b, c, d, timeout); DP("%u %u %u %u timeout %u", a, b, c, d, timeout);
ADDIP_WALK(map, a, btree, struct ip_set_iptreeb, branch_cachep); ADDIP_WALK(map, a, btree, struct ip_set_iptreeb, branch_cachep);
ADDIP_WALK(btree, b, ctree, struct ip_set_iptreec, branch_cachep); ADDIP_WALK(btree, b, ctree, struct ip_set_iptreec, branch_cachep);
@@ -153,7 +150,7 @@ KADT(iptree, add, ipaddr, 0)
} while (0) } while (0)
static inline int static inline int
iptree_del(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip) iptree_del(struct ip_set *set, ip_set_ip_t ip)
{ {
struct ip_set_iptree *map = set->data; struct ip_set_iptree *map = set->data;
struct ip_set_iptreeb *btree; struct ip_set_iptreeb *btree;
@@ -164,8 +161,7 @@ iptree_del(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
if (!ip) if (!ip)
return -ERANGE; return -ERANGE;
*hash_ip = ip; ABCD(a, b, c, d, &ip);
ABCD(a, b, c, d, hash_ip);
DELIP_WALK(map, a, btree); DELIP_WALK(map, a, btree);
DELIP_WALK(btree, b, ctree); DELIP_WALK(btree, b, ctree);
DELIP_WALK(ctree, c, dtree); DELIP_WALK(ctree, c, dtree);
@@ -364,7 +360,7 @@ iptree_list_header(const struct ip_set *set, void *data)
} }
static int static int
iptree_list_members_size(const struct ip_set *set) iptree_list_members_size(const struct ip_set *set, char dont_align)
{ {
const struct ip_set_iptree *map = set->data; const struct ip_set_iptree *map = set->data;
struct ip_set_iptreeb *btree; struct ip_set_iptreeb *btree;
@@ -386,20 +382,21 @@ iptree_list_members_size(const struct ip_set *set)
LOOP_WALK_END; LOOP_WALK_END;
DP("members %u", count); DP("members %u", count);
return (count * sizeof(struct ip_set_req_iptree)); return (count * IPSET_VALIGN(sizeof(struct ip_set_req_iptree), dont_align));
} }
static void static void
iptree_list_members(const struct ip_set *set, void *data) iptree_list_members(const struct ip_set *set, void *data, char dont_align)
{ {
const struct ip_set_iptree *map = 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;
unsigned int a,b,c,d; unsigned int a,b,c,d;
size_t offset = 0; size_t offset = 0, datasize;
struct ip_set_req_iptree *entry; struct ip_set_req_iptree *entry;
datasize = IPSET_VALIGN(sizeof(struct ip_set_req_iptree), dont_align);
LOOP_WALK_BEGIN(map, a, btree); LOOP_WALK_BEGIN(map, a, btree);
LOOP_WALK_BEGIN(btree, b, ctree); LOOP_WALK_BEGIN(btree, b, ctree);
LOOP_WALK_BEGIN(ctree, c, dtree); LOOP_WALK_BEGIN(ctree, c, dtree);
@@ -410,7 +407,7 @@ iptree_list_members(const struct ip_set *set, void *data)
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 += datasize;
} }
} }
LOOP_WALK_END; LOOP_WALK_END;

View File

@@ -3,7 +3,7 @@
#include "ip_set.h" #include "ip_set.h"
#define SETTYPE_NAME "iptree" #define SETTYPE_NAME "iptree"
struct ip_set_iptreed { struct ip_set_iptreed {
unsigned long expires[256]; /* x.x.x.ADDR */ unsigned long expires[256]; /* x.x.x.ADDR */

View File

@@ -251,7 +251,7 @@ free_b(struct ip_set_iptreemap_b *map)
} }
static inline int static inline int
iptreemap_test(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip) iptreemap_test(struct ip_set *set, ip_set_ip_t ip)
{ {
struct ip_set_iptreemap *map = set->data; struct ip_set_iptreemap *map = set->data;
struct ip_set_iptreemap_b *btree; struct ip_set_iptreemap_b *btree;
@@ -259,9 +259,7 @@ iptreemap_test(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
struct ip_set_iptreemap_d *dtree; struct ip_set_iptreemap_d *dtree;
unsigned char a, b, c, d; unsigned char a, b, c, d;
*hash_ip = ip; ABCD(a, b, c, d, &ip);
ABCD(a, b, c, d, hash_ip);
TESTIP_WALK(map, a, btree, fullbitmap_b); TESTIP_WALK(map, a, btree, fullbitmap_b);
TESTIP_WALK(btree, b, ctree, fullbitmap_c); TESTIP_WALK(btree, b, ctree, fullbitmap_c);
@@ -276,7 +274,7 @@ UADT(iptreemap, test)
KADT(iptreemap, test, ipaddr) KADT(iptreemap, test, ipaddr)
static inline int static inline int
__addip_single(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip) __addip_single(struct ip_set *set, ip_set_ip_t ip)
{ {
struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data; struct ip_set_iptreemap *map = (struct ip_set_iptreemap *) set->data;
struct ip_set_iptreemap_b *btree; struct ip_set_iptreemap_b *btree;
@@ -284,9 +282,7 @@ __addip_single(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
struct ip_set_iptreemap_d *dtree; struct ip_set_iptreemap_d *dtree;
unsigned char a, b, c, d; unsigned char a, b, c, d;
*hash_ip = ip; ABCD(a, b, c, d, &ip);
ABCD(a, b, c, d, hash_ip);
ADDIP_WALK(map, a, btree, struct ip_set_iptreemap_b, cachep_b, fullbitmap_b); ADDIP_WALK(map, a, btree, struct ip_set_iptreemap_b, cachep_b, fullbitmap_b);
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);
@@ -301,8 +297,7 @@ __addip_single(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
} }
static inline int static inline int
iptreemap_add(struct ip_set *set, ip_set_ip_t *hash_ip, iptreemap_add(struct ip_set *set, ip_set_ip_t start, ip_set_ip_t end)
ip_set_ip_t start, ip_set_ip_t end)
{ {
struct ip_set_iptreemap *map = set->data; struct ip_set_iptreemap *map = set->data;
struct ip_set_iptreemap_b *btree; struct ip_set_iptreemap_b *btree;
@@ -313,9 +308,7 @@ iptreemap_add(struct ip_set *set, ip_set_ip_t *hash_ip,
unsigned char a2, b2, c2, d2; unsigned char a2, b2, c2, d2;
if (start == end) if (start == end)
return __addip_single(set, hash_ip, start); return __addip_single(set, start);
*hash_ip = start;
ABCD(a1, b1, c1, d1, &start); ABCD(a1, b1, c1, d1, &start);
ABCD(a2, b2, c2, d2, &end); ABCD(a2, b2, c2, d2, &end);
@@ -338,8 +331,7 @@ UADT0(iptreemap, add, min(req->ip, req->end), max(req->ip, req->end))
KADT(iptreemap, add, ipaddr, ip) KADT(iptreemap, add, ipaddr, ip)
static inline int static inline int
__delip_single(struct ip_set *set, ip_set_ip_t *hash_ip, __delip_single(struct ip_set *set, ip_set_ip_t ip, gfp_t flags)
ip_set_ip_t ip, gfp_t flags)
{ {
struct ip_set_iptreemap *map = set->data; struct ip_set_iptreemap *map = set->data;
struct ip_set_iptreemap_b *btree; struct ip_set_iptreemap_b *btree;
@@ -347,9 +339,7 @@ __delip_single(struct ip_set *set, ip_set_ip_t *hash_ip,
struct ip_set_iptreemap_d *dtree; struct ip_set_iptreemap_d *dtree;
unsigned char a,b,c,d; unsigned char a,b,c,d;
*hash_ip = ip; ABCD(a, b, c, d, &ip);
ABCD(a, b, c, d, hash_ip);
DELIP_WALK(map, a, btree, cachep_b, fullbitmap_b, flags); DELIP_WALK(map, a, btree, cachep_b, fullbitmap_b, flags);
DELIP_WALK(btree, b, ctree, cachep_c, fullbitmap_c, flags); DELIP_WALK(btree, b, ctree, cachep_c, fullbitmap_c, flags);
@@ -364,7 +354,7 @@ __delip_single(struct ip_set *set, ip_set_ip_t *hash_ip,
} }
static inline int static inline int
iptreemap_del(struct ip_set *set, ip_set_ip_t *hash_ip, iptreemap_del(struct ip_set *set,
ip_set_ip_t start, ip_set_ip_t end, gfp_t flags) ip_set_ip_t start, ip_set_ip_t end, gfp_t flags)
{ {
struct ip_set_iptreemap *map = set->data; struct ip_set_iptreemap *map = set->data;
@@ -376,9 +366,7 @@ iptreemap_del(struct ip_set *set, ip_set_ip_t *hash_ip,
unsigned char a2, b2, c2, d2; unsigned char a2, b2, c2, d2;
if (start == end) if (start == end)
return __delip_single(set, hash_ip, start, flags); return __delip_single(set, start, flags);
*hash_ip = start;
ABCD(a1, b1, c1, d1, &start); ABCD(a1, b1, c1, d1, &start);
ABCD(a2, b2, c2, d2, &end); ABCD(a2, b2, c2, d2, &end);
@@ -518,6 +506,7 @@ static void
iptreemap_flush(struct ip_set *set) iptreemap_flush(struct ip_set *set)
{ {
struct ip_set_iptreemap *map = set->data; struct ip_set_iptreemap *map = set->data;
unsigned int gc_interval = map->gc_interval;
while (!del_timer(&map->gc)) while (!del_timer(&map->gc))
msleep(IPTREEMAP_DESTROY_SLEEP); msleep(IPTREEMAP_DESTROY_SLEEP);
@@ -525,6 +514,7 @@ iptreemap_flush(struct ip_set *set)
__flush(map); __flush(map);
memset(map, 0, sizeof(*map)); memset(map, 0, sizeof(*map));
map->gc_interval = gc_interval;
init_gc_timer(set); init_gc_timer(set);
} }
@@ -539,7 +529,7 @@ iptreemap_list_header(const struct ip_set *set, void *data)
} }
static int static int
iptreemap_list_members_size(const struct ip_set *set) iptreemap_list_members_size(const struct ip_set *set, char dont_align)
{ {
struct ip_set_iptreemap *map = set->data; struct ip_set_iptreemap *map = set->data;
struct ip_set_iptreemap_b *btree; struct ip_set_iptreemap_b *btree;
@@ -565,31 +555,30 @@ iptreemap_list_members_size(const struct ip_set *set)
if (inrange) if (inrange)
count++; count++;
return (count * sizeof(struct ip_set_req_iptreemap)); return (count * IPSET_VALIGN(sizeof(struct ip_set_req_iptreemap), dont_align));
} }
static inline u_int32_t static inline void
add_member(void *data, size_t offset, ip_set_ip_t start, ip_set_ip_t end) add_member(void *data, size_t offset, ip_set_ip_t start, ip_set_ip_t end)
{ {
struct ip_set_req_iptreemap *entry = data + offset; struct ip_set_req_iptreemap *entry = data + offset;
entry->ip = start; entry->ip = start;
entry->end = end; entry->end = end;
return sizeof(*entry);
} }
static void static void
iptreemap_list_members(const struct ip_set *set, void *data) iptreemap_list_members(const struct ip_set *set, void *data, char dont_align)
{ {
struct ip_set_iptreemap *map = 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;
unsigned int a, b, c, d, inrange = 0; unsigned int a, b, c, d, inrange = 0;
size_t offset = 0; size_t offset = 0, datasize;
ip_set_ip_t start = 0, end = 0, ip; ip_set_ip_t start = 0, end = 0, ip;
datasize = IPSET_VALIGN(sizeof(struct ip_set_req_iptreemap), dont_align);
LOOP_WALK_BEGIN(map, a, btree) { LOOP_WALK_BEGIN(map, a, btree) {
LOOP_WALK_BEGIN(btree, b, ctree) { LOOP_WALK_BEGIN(btree, b, ctree) {
LOOP_WALK_BEGIN(ctree, c, dtree) { LOOP_WALK_BEGIN(ctree, c, dtree) {
@@ -600,12 +589,14 @@ iptreemap_list_members(const struct ip_set *set, void *data)
inrange = 1; inrange = 1;
start = ip; start = ip;
} else if (end < ip - 1) { } else if (end < ip - 1) {
offset += add_member(data, offset, start, end); add_member(data, offset, start, end);
offset += datasize;
start = ip; start = ip;
} }
end = ip; end = ip;
} else if (inrange) { } else if (inrange) {
offset += add_member(data, offset, start, end); add_member(data, offset, start, end);
offset += datasize;
inrange = 0; inrange = 0;
} }
} }

View File

@@ -3,7 +3,7 @@
#include "ip_set.h" #include "ip_set.h"
#define SETTYPE_NAME "iptreemap" #define SETTYPE_NAME "iptreemap"
#ifdef __KERNEL__ #ifdef __KERNEL__
struct ip_set_iptreemap_d { struct ip_set_iptreemap_d {

View File

@@ -22,8 +22,7 @@
#include "ip_set_macipmap.h" #include "ip_set_macipmap.h"
static int static int
macipmap_utest(struct ip_set *set, const void *data, u_int32_t size, macipmap_utest(struct ip_set *set, const void *data, u_int32_t size)
ip_set_ip_t *hash_ip)
{ {
const struct ip_set_macipmap *map = set->data; const struct ip_set_macipmap *map = set->data;
const struct ip_set_macip *table = map->members; const struct ip_set_macip *table = map->members;
@@ -32,9 +31,7 @@ macipmap_utest(struct ip_set *set, const void *data, u_int32_t size,
if (req->ip < map->first_ip || req->ip > map->last_ip) if (req->ip < map->first_ip || req->ip > map->last_ip)
return -ERANGE; return -ERANGE;
*hash_ip = req->ip; DP("set: %s, ip:%u.%u.%u.%u", set->name, HIPQUAD(req->ip));
DP("set: %s, ip:%u.%u.%u.%u, %u.%u.%u.%u",
set->name, HIPQUAD(req->ip), HIPQUAD(*hash_ip));
if (table[req->ip - map->first_ip].match) { if (table[req->ip - map->first_ip].match) {
return (memcmp(req->ethernet, return (memcmp(req->ethernet,
&table[req->ip - map->first_ip].ethernet, &table[req->ip - map->first_ip].ethernet,
@@ -47,22 +44,18 @@ macipmap_utest(struct ip_set *set, const void *data, u_int32_t size,
static int static int
macipmap_ktest(struct ip_set *set, macipmap_ktest(struct ip_set *set,
const struct sk_buff *skb, const struct sk_buff *skb,
ip_set_ip_t *hash_ip, const u_int32_t *flags)
const u_int32_t *flags,
unsigned char index)
{ {
const struct ip_set_macipmap *map = set->data; const struct ip_set_macipmap *map = set->data;
const struct ip_set_macip *table = map->members; const struct ip_set_macip *table = map->members;
ip_set_ip_t ip; ip_set_ip_t ip;
ip = ipaddr(skb, flags[index]); ip = ipaddr(skb, flags);
if (ip < map->first_ip || ip > map->last_ip) if (ip < map->first_ip || ip > map->last_ip)
return 0; return 0;
*hash_ip = ip; DP("set: %s, ip:%u.%u.%u.%u", set->name, HIPQUAD(ip));
DP("set: %s, ip:%u.%u.%u.%u, %u.%u.%u.%u",
set->name, HIPQUAD(ip), HIPQUAD(*hash_ip));
if (table[ip - map->first_ip].match) { if (table[ip - map->first_ip].match) {
/* Is mac pointer valid? /* Is mac pointer valid?
* If so, compare... */ * If so, compare... */
@@ -78,7 +71,7 @@ macipmap_ktest(struct ip_set *set,
/* returns 0 on success */ /* returns 0 on success */
static inline int static inline int
macipmap_add(struct ip_set *set, ip_set_ip_t *hash_ip, macipmap_add(struct ip_set *set,
ip_set_ip_t ip, const unsigned char *ethernet) ip_set_ip_t ip, const unsigned char *ethernet)
{ {
struct ip_set_macipmap *map = set->data; struct ip_set_macipmap *map = set->data;
@@ -89,8 +82,7 @@ macipmap_add(struct ip_set *set, ip_set_ip_t *hash_ip,
if (table[ip - map->first_ip].match) if (table[ip - map->first_ip].match)
return -EEXIST; return -EEXIST;
*hash_ip = ip; DP("set: %s, ip: %u.%u.%u.%u", set->name, HIPQUAD(ip));
DP("%u.%u.%u.%u, %u.%u.%u.%u", HIPQUAD(ip), HIPQUAD(*hash_ip));
memcpy(&table[ip - map->first_ip].ethernet, ethernet, ETH_ALEN); memcpy(&table[ip - map->first_ip].ethernet, ethernet, ETH_ALEN);
table[ip - map->first_ip].match = IPSET_MACIP_ISSET; table[ip - map->first_ip].match = IPSET_MACIP_ISSET;
return 0; return 0;
@@ -105,7 +97,7 @@ UADT(macipmap, add, req->ethernet)
KADT(macipmap, add, ipaddr, eth_hdr(skb)->h_source) KADT(macipmap, add, ipaddr, eth_hdr(skb)->h_source)
static inline int static inline int
macipmap_del(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip) macipmap_del(struct ip_set *set, ip_set_ip_t ip)
{ {
struct ip_set_macipmap *map = set->data; struct ip_set_macipmap *map = set->data;
struct ip_set_macip *table = map->members; struct ip_set_macip *table = map->members;
@@ -115,9 +107,8 @@ macipmap_del(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
if (!table[ip - map->first_ip].match) if (!table[ip - map->first_ip].match)
return -EEXIST; return -EEXIST;
*hash_ip = ip;
table[ip - map->first_ip].match = 0; table[ip - map->first_ip].match = 0;
DP("%u.%u.%u.%u, %u.%u.%u.%u", HIPQUAD(ip), HIPQUAD(*hash_ip)); DP("set: %s, ip: %u.%u.%u.%u", set->name, HIPQUAD(ip));
return 0; return 0;
} }
@@ -152,8 +143,32 @@ __macipmap_list_header(const struct ip_set_macipmap *map,
} }
BITMAP_LIST_HEADER(macipmap) BITMAP_LIST_HEADER(macipmap)
BITMAP_LIST_MEMBERS_SIZE(macipmap) BITMAP_LIST_MEMBERS_SIZE(macipmap, struct ip_set_req_macipmap,
BITMAP_LIST_MEMBERS(macipmap) (map->last_ip - map->first_ip + 1),
((const struct ip_set_macip *)map->members)[i].match)
static void
macipmap_list_members(const struct ip_set *set, void *data, char dont_align)
{
const struct ip_set_macipmap *map = set->data;
const struct ip_set_macip *table = map->members;
uint32_t i, n = 0;
struct ip_set_req_macipmap *d;
if (dont_align) {
memcpy(data, map->members, map->size);
return;
}
for (i = 0; i < map->last_ip - map->first_ip + 1; i++)
if (table[i].match) {
d = data + n * IPSET_ALIGN(sizeof(struct ip_set_req_macipmap));
d->ip = map->first_ip + i;
memcpy(d->ethernet, &table[i].ethernet, ETH_ALEN);
n++;
}
}
IP_SET_TYPE(macipmap, IPSET_TYPE_IP | IPSET_DATA_SINGLE) IP_SET_TYPE(macipmap, IPSET_TYPE_IP | IPSET_DATA_SINGLE)

View File

@@ -4,7 +4,7 @@
#include "ip_set.h" #include "ip_set.h"
#include "ip_set_bitmaps.h" #include "ip_set_bitmaps.h"
#define SETTYPE_NAME "macipmap" #define SETTYPE_NAME "macipmap"
/* general flags */ /* general flags */
#define IPSET_MACIP_MATCHUNSET 1 #define IPSET_MACIP_MATCHUNSET 1

View File

@@ -26,7 +26,6 @@ static int limit = MAX_RANGE;
static inline __u32 static inline __u32
nethash_id_cidr(const struct ip_set_nethash *map, nethash_id_cidr(const struct ip_set_nethash *map,
ip_set_ip_t *hash_ip,
ip_set_ip_t ip, ip_set_ip_t ip,
uint8_t cidr) uint8_t cidr)
{ {
@@ -34,15 +33,15 @@ nethash_id_cidr(const struct ip_set_nethash *map,
u_int16_t i; u_int16_t i;
ip_set_ip_t *elem; ip_set_ip_t *elem;
*hash_ip = pack_ip_cidr(ip, cidr); ip = pack_ip_cidr(ip, cidr);
if (!*hash_ip) if (!ip)
return MAX_RANGE; return MAX_RANGE;
for (i = 0; i < map->probes; i++) { for (i = 0; i < map->probes; i++) {
id = jhash_ip(map, i, *hash_ip) % map->hashsize; id = jhash_ip(map, i, ip) % map->hashsize;
DP("hash key: %u", id); DP("hash key: %u", id);
elem = HARRAY_ELEM(map->members, ip_set_ip_t *, id); elem = HARRAY_ELEM(map->members, ip_set_ip_t *, id);
if (*elem == *hash_ip) if (*elem == ip)
return id; return id;
/* No shortcut - there can be deleted entries. */ /* No shortcut - there can be deleted entries. */
} }
@@ -50,14 +49,14 @@ nethash_id_cidr(const struct ip_set_nethash *map,
} }
static inline __u32 static inline __u32
nethash_id(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip) nethash_id(struct ip_set *set, ip_set_ip_t ip)
{ {
const struct ip_set_nethash *map = set->data; const struct ip_set_nethash *map = set->data;
__u32 id = UINT_MAX; __u32 id = UINT_MAX;
int i; int i;
for (i = 0; i < 30 && map->cidr[i]; i++) { for (i = 0; i < 30 && map->cidr[i]; i++) {
id = nethash_id_cidr(map, hash_ip, ip, map->cidr[i]); id = nethash_id_cidr(map, ip, map->cidr[i]);
if (id != UINT_MAX) if (id != UINT_MAX)
break; break;
} }
@@ -65,30 +64,28 @@ nethash_id(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip)
} }
static inline int static inline int
nethash_test_cidr(struct ip_set *set, ip_set_ip_t *hash_ip, nethash_test_cidr(struct ip_set *set, ip_set_ip_t ip, uint8_t cidr)
ip_set_ip_t ip, uint8_t cidr)
{ {
const struct ip_set_nethash *map = set->data; const struct ip_set_nethash *map = set->data;
return (nethash_id_cidr(map, hash_ip, ip, cidr) != UINT_MAX); return (nethash_id_cidr(map, ip, cidr) != UINT_MAX);
} }
static inline int static inline int
nethash_test(struct ip_set *set, ip_set_ip_t *hash_ip, ip_set_ip_t ip) nethash_test(struct ip_set *set, ip_set_ip_t ip)
{ {
return (nethash_id(set, hash_ip, ip) != UINT_MAX); return (nethash_id(set, ip) != UINT_MAX);
} }
static int static int
nethash_utest(struct ip_set *set, const void *data, u_int32_t size, nethash_utest(struct ip_set *set, const void *data, u_int32_t size)
ip_set_ip_t *hash_ip)
{ {
const struct ip_set_req_nethash *req = data; const struct ip_set_req_nethash *req = data;
if (req->cidr <= 0 || req->cidr > 32) if (req->cidr <= 0 || req->cidr > 32)
return -EINVAL; return -EINVAL;
return (req->cidr == 32 ? nethash_test(set, hash_ip, req->ip) return (req->cidr == 32 ? nethash_test(set, req->ip)
: nethash_test_cidr(set, hash_ip, req->ip, req->cidr)); : nethash_test_cidr(set, req->ip, req->cidr));
} }
#define KADT_CONDITION #define KADT_CONDITION
@@ -121,8 +118,7 @@ __nethash_add(struct ip_set_nethash *map, ip_set_ip_t *ip)
} }
static inline int static inline int
nethash_add(struct ip_set *set, ip_set_ip_t *hash_ip, nethash_add(struct ip_set *set, ip_set_ip_t ip, uint8_t cidr)
ip_set_ip_t ip, uint8_t cidr)
{ {
struct ip_set_nethash *map = set->data; struct ip_set_nethash *map = set->data;
int ret; int ret;
@@ -132,12 +128,11 @@ nethash_add(struct ip_set *set, ip_set_ip_t *hash_ip,
if (cidr <= 0 || cidr >= 32) if (cidr <= 0 || cidr >= 32)
return -EINVAL; return -EINVAL;
*hash_ip = pack_ip_cidr(ip, cidr); ip = pack_ip_cidr(ip, cidr);
DP("%u.%u.%u.%u/%u, %u.%u.%u.%u", HIPQUAD(ip), cidr, HIPQUAD(*hash_ip)); if (!ip)
if (!*hash_ip)
return -ERANGE; return -ERANGE;
ret = __nethash_add(map, hash_ip); ret = __nethash_add(map, &ip);
if (ret == 0) { if (ret == 0) {
if (!map->nets[cidr-1]++) if (!map->nets[cidr-1]++)
add_cidr_size(map->cidr, cidr); add_cidr_size(map->cidr, cidr);
@@ -165,8 +160,7 @@ __nethash_retry(struct ip_set_nethash *tmp, struct ip_set_nethash *map)
HASH_RETRY(nethash, ip_set_ip_t) HASH_RETRY(nethash, ip_set_ip_t)
static inline int static inline int
nethash_del(struct ip_set *set, ip_set_ip_t *hash_ip, nethash_del(struct ip_set *set, ip_set_ip_t ip, uint8_t cidr)
ip_set_ip_t ip, uint8_t cidr)
{ {
struct ip_set_nethash *map = set->data; struct ip_set_nethash *map = set->data;
ip_set_ip_t id, *elem; ip_set_ip_t id, *elem;
@@ -174,7 +168,7 @@ nethash_del(struct ip_set *set, ip_set_ip_t *hash_ip,
if (cidr <= 0 || cidr >= 32) if (cidr <= 0 || cidr >= 32)
return -EINVAL; return -EINVAL;
id = nethash_id_cidr(map, hash_ip, ip, cidr); id = nethash_id_cidr(map, ip, cidr);
if (id == UINT_MAX) if (id == UINT_MAX)
return -EEXIST; return -EEXIST;

View File

@@ -4,7 +4,7 @@
#include "ip_set.h" #include "ip_set.h"
#include "ip_set_hashes.h" #include "ip_set_hashes.h"
#define SETTYPE_NAME "nethash" #define SETTYPE_NAME "nethash"
struct ip_set_nethash { struct ip_set_nethash {
ip_set_ip_t *members; /* the nethash proper */ ip_set_ip_t *members; /* the nethash proper */

View File

@@ -23,16 +23,14 @@
#include "ip_set_getport.h" #include "ip_set_getport.h"
static inline int static inline int
portmap_test(const struct ip_set *set, ip_set_ip_t *hash_port, portmap_test(const struct ip_set *set, ip_set_ip_t port)
ip_set_ip_t port)
{ {
const struct ip_set_portmap *map = set->data; const struct ip_set_portmap *map = set->data;
if (port < map->first_ip || port > map->last_ip) if (port < map->first_ip || port > map->last_ip)
return -ERANGE; return -ERANGE;
*hash_port = port; DP("set: %s, port: %u", set->name, port);
DP("set: %s, port:%u, %u", set->name, port, *hash_port);
return !!test_bit(port - map->first_ip, map->members); return !!test_bit(port - map->first_ip, map->members);
} }
@@ -44,7 +42,7 @@ UADT(portmap, test)
KADT(portmap, test, get_port) KADT(portmap, test, get_port)
static inline int static inline int
portmap_add(struct ip_set *set, ip_set_ip_t *hash_port, ip_set_ip_t port) portmap_add(struct ip_set *set, ip_set_ip_t port)
{ {
struct ip_set_portmap *map = set->data; struct ip_set_portmap *map = set->data;
@@ -52,9 +50,8 @@ portmap_add(struct ip_set *set, ip_set_ip_t *hash_port, ip_set_ip_t port)
return -ERANGE; return -ERANGE;
if (test_and_set_bit(port - map->first_ip, map->members)) if (test_and_set_bit(port - map->first_ip, map->members))
return -EEXIST; return -EEXIST;
*hash_port = port; DP("set: %s, port %u", set->name, port);
DP("port %u", port);
return 0; return 0;
} }
@@ -62,7 +59,7 @@ UADT(portmap, add)
KADT(portmap, add, get_port) KADT(portmap, add, get_port)
static inline int static inline int
portmap_del(struct ip_set *set, ip_set_ip_t *hash_port, ip_set_ip_t port) portmap_del(struct ip_set *set, ip_set_ip_t port)
{ {
struct ip_set_portmap *map = set->data; struct ip_set_portmap *map = set->data;
@@ -70,9 +67,8 @@ portmap_del(struct ip_set *set, ip_set_ip_t *hash_port, ip_set_ip_t port)
return -ERANGE; return -ERANGE;
if (!test_and_clear_bit(port - map->first_ip, map->members)) if (!test_and_clear_bit(port - map->first_ip, map->members))
return -EEXIST; return -EEXIST;
*hash_port = port; DP("set: %s, port %u", set->name, port);
DP("port %u", port);
return 0; return 0;
} }
@@ -102,8 +98,28 @@ __portmap_list_header(const struct ip_set_portmap *map,
} }
BITMAP_LIST_HEADER(portmap) BITMAP_LIST_HEADER(portmap)
BITMAP_LIST_MEMBERS_SIZE(portmap) BITMAP_LIST_MEMBERS_SIZE(portmap, ip_set_ip_t, (map->last_ip - map->first_ip + 1),
BITMAP_LIST_MEMBERS(portmap) test_bit(i, map->members))
static void
portmap_list_members(const struct ip_set *set, void *data, char dont_align)
{
const struct ip_set_portmap *map = set->data;
uint32_t i, n = 0;
ip_set_ip_t *d;
if (dont_align) {
memcpy(data, map->members, map->size);
return;
}
for (i = 0; i < map->last_ip - map->first_ip + 1; i++)
if (test_bit(i, map->members)) {
d = data + n * IPSET_ALIGN(sizeof(ip_set_ip_t));
*d = map->first_ip + i;
n++;
}
}
IP_SET_TYPE(portmap, IPSET_TYPE_PORT | IPSET_DATA_SINGLE) IP_SET_TYPE(portmap, IPSET_TYPE_PORT | IPSET_DATA_SINGLE)

View File

@@ -4,7 +4,7 @@
#include "ip_set.h" #include "ip_set.h"
#include "ip_set_bitmaps.h" #include "ip_set_bitmaps.h"
#define SETTYPE_NAME "portmap" #define SETTYPE_NAME "portmap"
struct ip_set_portmap { struct ip_set_portmap {
void *members; /* the portmap proper */ void *members; /* the portmap proper */

View File

@@ -28,8 +28,7 @@ next_index_eq(const struct ip_set_setlist *map, int i, ip_set_id_t index)
} }
static int static int
setlist_utest(struct ip_set *set, const void *data, u_int32_t size, setlist_utest(struct ip_set *set, const void *data, u_int32_t size)
ip_set_ip_t *hash_ip)
{ {
const struct ip_set_setlist *map = set->data; const struct ip_set_setlist *map = set->data;
const struct ip_set_req_setlist *req = data; const struct ip_set_req_setlist *req = data;
@@ -72,10 +71,8 @@ finish:
static int static int
setlist_ktest(struct ip_set *set, setlist_ktest(struct ip_set *set,
const struct sk_buff *skb, const struct sk_buff *skb,
ip_set_ip_t *hash_ip, const u_int32_t *flags)
const u_int32_t *flags,
unsigned char index)
{ {
struct ip_set_setlist *map = set->data; struct ip_set_setlist *map = set->data;
int i, res = 0; int i, res = 0;
@@ -107,8 +104,7 @@ insert_setlist(struct ip_set_setlist *map, int i, ip_set_id_t index)
} }
static int static int
setlist_uadd(struct ip_set *set, const void *data, u_int32_t size, setlist_uadd(struct ip_set *set, const void *data, u_int32_t size)
ip_set_ip_t *hash_ip)
{ {
struct ip_set_setlist *map = set->data; struct ip_set_setlist *map = set->data;
const struct ip_set_req_setlist *req = data; const struct ip_set_req_setlist *req = data;
@@ -156,9 +152,7 @@ finish:
static int static int
setlist_kadd(struct ip_set *set, setlist_kadd(struct ip_set *set,
const struct sk_buff *skb, const struct sk_buff *skb,
ip_set_ip_t *hash_ip, const u_int32_t *flags)
const u_int32_t *flags,
unsigned char index)
{ {
struct ip_set_setlist *map = set->data; struct ip_set_setlist *map = set->data;
int i, res = -EINVAL; int i, res = -EINVAL;
@@ -182,8 +176,7 @@ unshift_setlist(struct ip_set_setlist *map, int i)
} }
static int static int
setlist_udel(struct ip_set *set, const void *data, u_int32_t size, setlist_udel(struct ip_set *set, const void *data, u_int32_t size)
ip_set_ip_t *hash_ip)
{ {
struct ip_set_setlist *map = set->data; struct ip_set_setlist *map = set->data;
const struct ip_set_req_setlist *req = data; const struct ip_set_req_setlist *req = data;
@@ -234,9 +227,7 @@ finish:
static int static int
setlist_kdel(struct ip_set *set, setlist_kdel(struct ip_set *set,
const struct sk_buff *skb, const struct sk_buff *skb,
ip_set_ip_t *hash_ip, const u_int32_t *flags)
const u_int32_t *flags,
unsigned char index)
{ {
struct ip_set_setlist *map = set->data; struct ip_set_setlist *map = set->data;
int i, res = -EINVAL; int i, res = -EINVAL;
@@ -304,21 +295,24 @@ setlist_list_header(const struct ip_set *set, void *data)
} }
static int static int
setlist_list_members_size(const struct ip_set *set) setlist_list_members_size(const struct ip_set *set, char dont_align)
{ {
const struct ip_set_setlist *map = set->data; const struct ip_set_setlist *map = set->data;
return map->size * sizeof(ip_set_id_t); return map->size * IPSET_VALIGN(sizeof(ip_set_id_t), dont_align);
} }
static void static void
setlist_list_members(const struct ip_set *set, void *data) setlist_list_members(const struct ip_set *set, void *data, char dont_align)
{ {
struct ip_set_setlist *map = set->data; struct ip_set_setlist *map = set->data;
ip_set_id_t *d;
int i; int i;
for (i = 0; i < map->size; i++) for (i = 0; i < map->size; i++) {
*((ip_set_id_t *)data + i) = ip_set_id(map->index[i]); d = data + i * IPSET_VALIGN(sizeof(ip_set_id_t), dont_align);
*d = ip_set_id(map->index[i]);
}
} }
IP_SET_TYPE(setlist, IPSET_TYPE_SETNAME | IPSET_DATA_SINGLE) IP_SET_TYPE(setlist, IPSET_TYPE_SETNAME | IPSET_DATA_SINGLE)

View File

@@ -3,7 +3,7 @@
#include "ip_set.h" #include "ip_set.h"
#define SETTYPE_NAME "setlist" #define SETTYPE_NAME "setlist"
#define IP_SET_SETLIST_ADD_AFTER 0 #define IP_SET_SETLIST_ADD_AFTER 0
#define IP_SET_SETLIST_ADD_BEFORE 1 #define IP_SET_SETLIST_ADD_BEFORE 1

View File

@@ -26,13 +26,11 @@ ipset \- administration tool for IP sets
.br .br
.BR "ipset -[EW] " "from-set to-set" .BR "ipset -[EW] " "from-set to-set"
.br .br
.BR "ipset -[ADU] " "set entry" .BR "ipset -[ADT] " "set entry"
.br
.BR "ipset -B " "set entry -b binding"
.br
.BR "ipset -T " "set entry [-b binding]"
.br .br
.BR "ipset -R " .BR "ipset -R "
.br
.BR "ipset -[Vv] "
.SH DESCRIPTION .SH DESCRIPTION
.B ipset .B ipset
is used to set up, maintain and inspect so called IP sets in the Linux is used to set up, maintain and inspect so called IP sets in the Linux
@@ -40,19 +38,9 @@ kernel. Depending on the type, an IP set may store IP addresses, (TCP/UDP)
port numbers or additional informations besides IP addresses: the word IP port numbers or additional informations besides IP addresses: the word IP
means a general term here. See the set type definitions below. means a general term here. See the set type definitions below.
.P .P
Any entry in a set can be bound to another set, which forms a relationship Iptables matches and targets referring to sets creates references, which
between a set element and the set it is bound to. In order to define a protects the given sets in the kernel. A set cannot be removed (destroyed)
binding it is not required that the entry be already added to the set. while there is a single reference pointing to it.
The sets may have a default binding, which is valid for every set element
for which there is no binding defined at all.
.P
IP set bindings pointing to sets and iptables matches and targets
referring to sets creates references, which protects the given sets in
the kernel. A set cannot be removed (destroyed) while there is a single
reference pointing to it.
.P
.B
Please note, binding sets is a deprecated feature and will be removed in a later release. Switch to the multidata type of sets from using bindings.
.SH OPTIONS .SH OPTIONS
The options that are recognized by The options that are recognized by
.B ipset .B ipset
@@ -70,21 +58,13 @@ Create a set identified with setname and specified type.
Type-specific options must be supplied. Type-specific options must be supplied.
.TP .TP
.BI "-X, --destroy " "[\fIsetname\fP]" .BI "-X, --destroy " "[\fIsetname\fP]"
Destroy the specified set, or all sets if none or the keyword Destroy the specified set or all the sets if none is given.
.B
:all:
is specified.
Before destroying the set, all bindings belonging to the
set elements and the default binding of the set are removed.
If the set has got references, nothing is done. If the set has got references, nothing is done.
.TP .TP
.BI "-F, --flush " "[\fIsetname\fP]" .BI "-F, --flush " "[\fIsetname\fP]"
Delete all entries from the specified set, or flush Delete all entries from the specified set or flush
all sets if none or the keyword all sets if none is given.
.B
:all:
is given. Bindings are not affected by the flush operation.
.TP .TP
.BI "-E, --rename " "\fIfrom-setname\fP \fIto-setname\fP" .BI "-E, --rename " "\fIfrom-setname\fP \fIto-setname\fP"
Rename a set. Set identified by to-setname must not exist. Rename a set. Set identified by to-setname must not exist.
@@ -95,102 +75,63 @@ exchange the name of two sets. The referred sets must exist and
identical type of sets can be swapped only. identical type of sets can be swapped only.
.TP .TP
.BI "-L, --list " "[\fIsetname\fP]" .BI "-L, --list " "[\fIsetname\fP]"
List the entries and bindings for the specified set, or for List the entries for the specified set, or for
all sets if none or the keyword all sets if none is given. The
.B .B "-r, --resolve"
:all: option can be used to force name lookups (which may be slow). When the
is given. The
.B "-n, --numeric"
option can be used to suppress name lookups and generate numeric
output. When the
.B "-s, --sorted" .B "-s, --sorted"
option is given, the entries are listed sorted (if the given set option is given, the entries are listed sorted (if the given set
type supports the operation). type supports the operation).
.TP .TP
.BI "-S, --save " "[\fIsetname\fP]" .BI "-S, --save " "[\fIsetname\fP]"
Save the given set, or all sets if none or the keyword Save the given set, or all sets if none is given
.B to stdout in a format that --restore can read.
:all:
is specified to stdout in a format that --restore can read.
.TP .TP
.BI "-R, --restore " .BI "-R, --restore "
Restore a saved session generated by --save. The saved session Restore a saved session generated by --save. The saved session
can be fed from stdin. can be fed from stdin.
When generating a session file please note that the supported commands When generating a session file please note that the supported commands
(create set, add element, bind) must appear in a strict order: first create (create set and add element) must appear in a strict order: first create
the set, then add all elements. Then create the next set, add all its elements the set, then add all elements. Then create the next set, add all its elements
and so on. Finally you can list all binding commands. Also, it is a restore and so on. Also, it is a restore operation, so the sets being restored must
operation, so the sets being restored must not exist. not exist.
.TP .TP
.BI "-A, --add " "\fIsetname\fP \fIIP\fP" .BI "-A, --add " "\fIsetname\fP \fIIP\fP"
Add an IP to a set. Add an IP entry to a set.
.TP .TP
.BI "-D, --del " "\fIsetname\fP \fIIP\fP" .BI "-D, --del " "\fIsetname\fP \fIIP\fP"
Delete an IP from a set. Delete an IP entry from a set.
.TP .TP
.BI "-T, --test " "\fIsetname\fP \fIIP .BI "-T, --test " "\fIsetname\fP \fIIP
Test wether an IP is in a set or not. Exit status number is zero Test wether an IP entry is in a set or not. Exit status number is zero
if the tested IP is in the set and nonzero if it is missing from if the tested IP is in the set and nonzero if it is missing from
the set. the set.
.TP .TP
.BI "-T, --test " "\fIsetname\fP \fIIP\fP \fI--binding\fP \fIto-setname\fP"
Test wether the IP belonging to the set points to the specified binding.
Exit status number is zero if the binding points to the specified set,
otherwise it is nonzero. The keyword
.B
:default:
can be used to test the default binding of the set.
.TP
.BI "-B, --bind " "\fIsetname\fP \fIIP\fP \fI--binding\fP \fIto-setname\fP"
Bind the IP in setname to to-setname.
.TP
.BI "-U, --unbind " "\fIsetname\fP \fIIP\fP"
Delete the binding belonging to IP in set setname.
.TP
.BI "-H, --help " "[settype]" .BI "-H, --help " "[settype]"
Print help and settype specific help if settype specified. Print help and settype specific help if settype specified.
.TP
.BI "-V, -v, --version "
Print program version and protocol version.
.P .P
At the
.B
-B, -U
and
.B
-T
commands you can use the token
.B
:default:
to bind, unbind or test the default binding of a set instead
of an IP. At the
.B
-U
command you can use the token
.B
:all:
to destroy the bindings of all elements of a set.
.SS "OTHER OPTIONS" .SS "OTHER OPTIONS"
The following additional options can be specified: The following additional options can be specified:
.TP .TP
.B "-b, --binding setname" .B "-r, --resolve"
The option specifies the value of the binding for the When listing sets, enforce name lookup. The
.B "-B" program will try to display the IP entries resolved to
binding command, for which it is a mandatory option. host names or services (whenever applicable), which can trigger
You can use it in the .B
.B "-T" slow
test command as well to test bindings. DNS
lookups.
.TP .TP
.B "-s, --sorted" .B "-s, --sorted"
Sorted output. When listing sets, entries are listed sorted. Sorted output. When listing sets, entries are listed sorted.
.TP .TP
.B "-n, --numeric" .B "-n, --numeric"
Numeric output. When listing sets, bindings, IP addresses and Numeric output. When listing sets, IP addresses and
port numbers will be printed in numeric format. By default the port numbers will be printed in numeric format. This is the default.
program will try to display them as host names, network names
or services (whenever applicable), which can trigger
.B
slow
DNS
lookups.
.TP .TP
.B "-q, --quiet" .B "-q, --quiet"
Suppress any output to stdout and stderr. ipset will still return Suppress any output to stdout and stderr. ipset will still return
@@ -224,6 +165,10 @@ When the optional
parameter specified, network addresses will be parameter specified, network addresses will be
stored in the set instead of IP addresses, and the from-IP parameter stored in the set instead of IP addresses, and the from-IP parameter
must be a network address. The CIDR-netmask value must be between 1-31. must be a network address. The CIDR-netmask value must be between 1-31.
.PP
Example:
.IP
ipset \-N test ipmap \-\-network 192.168.0.0/16
.SS macipmap .SS macipmap
The macipmap set type uses a memory range, where each 8 bytes The macipmap set type uses a memory range, where each 8 bytes
represents one IP and a MAC addresses. A macipmap set type can store represents one IP and a MAC addresses. A macipmap set type can store
@@ -319,6 +264,10 @@ parameter. In general higher
probe probe
value results better utilized hash while smaller value value results better utilized hash while smaller value
produces larger, sparser hash. produces larger, sparser hash.
.PP
Example:
.IP
ipset \-N test iphash \-\-probes 2
.SS nethash .SS nethash
The nethash set type uses a hash to store different size of The nethash set type uses a hash to store different size of
network addresses. The network addresses. The
@@ -538,7 +487,7 @@ Options to use when creating a setlist type of set:
.TP .TP
.BR "--size " size .BR "--size " size
Create a setlist type of set with the given size (default 8). Create a setlist type of set with the given size (default 8).
.P .PP
By the By the
.I .I
set set
@@ -562,8 +511,9 @@ and
.I .I
b b
are setlist type of sets then in the command are setlist type of sets then in the command
.TP .IP
iptables -m set --match-set a src,dst -j SET --add-set b src,dst iptables \-m set \-\-match\-set a src,dst \-j SET \-\-add-set b src,dst
.PP
the match and target will skip any set in the match and target will skip any set in
.I a .I a
and and
@@ -589,6 +539,8 @@ use the iphash set type. If you have got random size of netblocks,
use nethash. use nethash.
.P .P
Old separator tokens (':' and '%") are still accepted. Old separator tokens (':' and '%") are still accepted.
.P
Binding support is removed.
.SH DIAGNOSTICS .SH DIAGNOSTICS
Various error messages are printed to standard error. The exit code Various error messages are printed to standard error. The exit code
is 0 for correct functioning. Errors which appear to be caused by is 0 for correct functioning. Errors which appear to be caused by

View File

@@ -30,11 +30,15 @@
#define PROC_SYS_MODPROBE "/proc/sys/kernel/modprobe" #define PROC_SYS_MODPROBE "/proc/sys/kernel/modprobe"
#endif #endif
#define IPSET_VERSION "3.2" #define IPSET_VERSION "4.0"
char program_name[] = "ipset"; char program_name[] = "ipset";
char program_version[] = IPSET_VERSION; char program_version[] = IPSET_VERSION;
const char *ipset_libdir = IPSET_LIB_DIR; static int protocol_version = 0;
#define STREQ(a,b) (strncmp(a,b,IP_SET_MAXNAMELEN) == 0)
#define DONT_ALIGN (protocol_version == IP_SET_PROTOCOL_UNALIGNED)
#define ALIGNED(len) IPSET_VALIGN(len, DONT_ALIGN)
/* The list of loaded set types */ /* The list of loaded set types */
static struct settype *all_settypes = NULL; static struct settype *all_settypes = NULL;
@@ -68,7 +72,7 @@ static unsigned int global_option_offset = 0;
static const char cmdflags[] = { ' ', /* CMD_NONE */ static const char cmdflags[] = { ' ', /* CMD_NONE */
'N', 'X', 'F', 'E', 'W', 'L', 'S', 'R', 'N', 'X', 'F', 'E', 'W', 'L', 'S', 'R',
'A', 'D', 'T', 'B', 'U', 'H', 'V', 'A', 'D', 'T', 'H', 'V',
}; };
/* Options */ /* Options */
@@ -77,11 +81,10 @@ static const char cmdflags[] = { ' ', /* CMD_NONE */
#define OPT_SORTED 0x0002U /* -s */ #define OPT_SORTED 0x0002U /* -s */
#define OPT_QUIET 0x0004U /* -q */ #define OPT_QUIET 0x0004U /* -q */
#define OPT_DEBUG 0x0008U /* -z */ #define OPT_DEBUG 0x0008U /* -z */
#define OPT_BINDING 0x0010U /* -b */
#define OPT_RESOLVE 0x0020U /* -r */ #define OPT_RESOLVE 0x0020U /* -r */
#define NUMBER_OF_OPT 6 #define NUMBER_OF_OPT 5
static const char optflags[] = static const char optflags[] =
{ 'n', 's', 'q', 'z', 'b', 'r' }; { 'n', 's', 'q', 'z', 'r' };
static struct option opts_long[] = { static struct option opts_long[] = {
/* set operations */ /* set operations */
@@ -100,15 +103,10 @@ static struct option opts_long[] = {
{"del", 1, 0, 'D'}, {"del", 1, 0, 'D'},
{"test", 1, 0, 'T'}, {"test", 1, 0, 'T'},
/* binding operations */
{"bind", 1, 0, 'B'},
{"unbind", 1, 0, 'U'},
/* free options */ /* free options */
{"numeric", 0, 0, 'n'}, {"numeric", 0, 0, 'n'},
{"sorted", 0, 0, 's'}, {"sorted", 0, 0, 's'},
{"quiet", 0, 0, 'q'}, {"quiet", 0, 0, 'q'},
{"binding", 1, 0, 'b'},
{"resolve", 0, 0, 'r'}, {"resolve", 0, 0, 'r'},
#ifdef IPSET_DEBUG #ifdef IPSET_DEBUG
@@ -125,7 +123,7 @@ static struct option opts_long[] = {
}; };
static char opts_short[] = static char opts_short[] =
"-N:X::F::E:W:L::S::RA:D:T:B:U:nrsqzb:Vh::H::"; "-N:X::F::E:W:L::S::RA:D:T:nrsqzvVh::H::";
/* Table of legal combinations of commands and options. If any of the /* Table of legal combinations of commands and options. If any of the
* given commands make an option legal, that option is legal. * given commands make an option legal, that option is legal.
@@ -136,22 +134,20 @@ static char opts_short[] =
*/ */
static char commands_v_options[NUMBER_OF_CMD][NUMBER_OF_OPT] = { static char commands_v_options[NUMBER_OF_CMD][NUMBER_OF_OPT] = {
/* -n -s -q -z -b */ /* -n -s -q -z -r */
/*CREATE*/ {'x', 'x', ' ', ' ', 'x', 'x'}, /*CREATE*/ {'x', 'x', ' ', ' ', 'x'},
/*DESTROY*/ {'x', 'x', ' ', ' ', 'x', 'x'}, /*DESTROY*/ {'x', 'x', ' ', ' ', 'x'},
/*FLUSH*/ {'x', 'x', ' ', ' ', 'x', 'x'}, /*FLUSH*/ {'x', 'x', ' ', ' ', 'x'},
/*RENAME*/ {'x', 'x', ' ', ' ', 'x', 'x'}, /*RENAME*/ {'x', 'x', ' ', ' ', 'x'},
/*SWAP*/ {'x', 'x', ' ', ' ', 'x', 'x'}, /*SWAP*/ {'x', 'x', ' ', ' ', 'x'},
/*LIST*/ {' ', ' ', 'x', ' ', 'x', ' '}, /*LIST*/ {' ', ' ', 'x', ' ', ' '},
/*SAVE*/ {'x', 'x', ' ', ' ', 'x', 'x'}, /*SAVE*/ {'x', 'x', ' ', ' ', 'x'},
/*RESTORE*/ {'x', 'x', ' ', ' ', 'x', 'x'}, /*RESTORE*/ {'x', 'x', ' ', ' ', 'x'},
/*ADD*/ {'x', 'x', ' ', ' ', 'x', 'x'}, /*ADD*/ {'x', 'x', ' ', ' ', 'x'},
/*DEL*/ {'x', 'x', ' ', ' ', 'x', 'x'}, /*DEL*/ {'x', 'x', ' ', ' ', 'x'},
/*TEST*/ {'x', 'x', ' ', ' ', ' ', 'x'}, /*TEST*/ {'x', 'x', ' ', ' ', 'x'},
/*BIND*/ {'x', 'x', ' ', ' ', '+', 'x'}, /*HELP*/ {'x', 'x', 'x', ' ', 'x'},
/*UNBIND*/ {'x', 'x', ' ', ' ', 'x', 'x'}, /*VERSION*/ {'x', 'x', 'x', ' ', 'x'},
/*HELP*/ {'x', 'x', 'x', ' ', 'x', 'x'},
/*VERSION*/ {'x', 'x', 'x', ' ', 'x', 'x'},
}; };
/* Main parser function */ /* Main parser function */
@@ -454,25 +450,26 @@ static void check_protocolversion(void)
{ {
struct ip_set_req_version req_version; struct ip_set_req_version req_version;
socklen_t size = sizeof(struct ip_set_req_version); socklen_t size = sizeof(struct ip_set_req_version);
int sockfd = kernel_getsocket();
int res; int res;
req_version.op = IP_SET_OP_VERSION; if (protocol_version)
res = getsockopt(sockfd, SOL_IP, SO_IP_SET, &req_version, &size);
if (res != 0) {
ipset_printf("I'm of protocol version %u.\n"
"Kernel module is not loaded in, "
"cannot verify kernel version.",
IP_SET_PROTOCOL_VERSION);
return; return;
}
if (req_version.version != IP_SET_PROTOCOL_VERSION) req_version.op = IP_SET_OP_VERSION;
res = wrapped_getsockopt(&req_version, &size);
if (res != 0)
exit_error(OTHER_PROBLEM, exit_error(OTHER_PROBLEM,
"Kernel ipset code is of protocol version %u." "Couldn't verify kernel module version!");
if (!(req_version.version == IP_SET_PROTOCOL_VERSION
|| req_version.version == IP_SET_PROTOCOL_UNALIGNED))
exit_error(OTHER_PROBLEM,
"Kernel ip_set module is of protocol version %u."
"I'm of protocol version %u.\n" "I'm of protocol version %u.\n"
"Please upgrade your kernel and/or ipset(8) utillity.", "Please upgrade your kernel and/or ipset(8) utillity.",
req_version.version, IP_SET_PROTOCOL_VERSION); req_version.version, IP_SET_PROTOCOL_VERSION);
protocol_version = req_version.version;
} }
static void set_command(int *cmd, int newcmd) static void set_command(int *cmd, int newcmd)
@@ -594,11 +591,6 @@ char *ip_tostring(ip_set_ip_t ip, unsigned options)
return inet_ntoa(addr); return inet_ntoa(addr);
} }
char *binding_ip_tostring(struct set *set UNUSED,
ip_set_ip_t ip, unsigned options)
{
return ip_tostring(ip, options);
}
char *ip_tostring_numeric(ip_set_ip_t ip) char *ip_tostring_numeric(ip_set_ip_t ip)
{ {
return ip_tostring(ip, OPT_NUMERIC); return ip_tostring(ip, OPT_NUMERIC);
@@ -763,8 +755,7 @@ static struct settype *settype_find(const char *typename)
DP("%s", typename); DP("%s", typename);
while (runner != NULL) { while (runner != NULL) {
if (strncmp(runner->typename, typename, if (STREQ(runner->typename, typename))
IP_SET_MAXNAMELEN) == 0)
return runner; return runner;
runner = runner->next; runner = runner->next;
@@ -886,9 +877,7 @@ struct set *set_find_byname(const char *name)
ip_set_id_t i; ip_set_id_t i;
for (i = 0; i < max_sets; i++) for (i = 0; i < max_sets; i++)
if (set_list[i] if (set_list[i] != NULL && STREQ(set_list[i]->name, name)) {
&& strncmp(set_list[i]->name, name,
IP_SET_MAXNAMELEN) == 0) {
set = set_list[i]; set = set_list[i];
break; break;
} }
@@ -906,9 +895,7 @@ static ip_set_id_t set_find_free_index(const char *name)
if (idx == IP_SET_INVALID_ID if (idx == IP_SET_INVALID_ID
&& set_list[i] == NULL) && set_list[i] == NULL)
idx = i; idx = i;
if (set_list[i] != NULL if (set_list[i] != NULL && STREQ(set_list[i]->name, name))
&& strncmp(set_list[i]->name, name,
IP_SET_MAXNAMELEN) == 0)
exit_error(PARAMETER_PROBLEM, exit_error(PARAMETER_PROBLEM,
"Set %s is already defined, cannot be restored", "Set %s is already defined, cannot be restored",
name); name);
@@ -935,7 +922,7 @@ static void set_create(const char *name, struct settype *settype)
DP("%s %s", name, settype->typename); DP("%s %s", name, settype->typename);
req_create.op = IP_SET_OP_CREATE; req_create.op = IP_SET_OP_CREATE;
req_create.version = IP_SET_PROTOCOL_VERSION; req_create.version = protocol_version;
strcpy(req_create.name, name); strcpy(req_create.name, name);
strcpy(req_create.typename, settype->typename); strcpy(req_create.typename, settype->typename);
@@ -959,14 +946,14 @@ static void set_restore_create(const char *name, struct settype *settype)
{ {
struct set *set; struct set *set;
DP("%s %s %u %u %u %u", name, settype->typename, DP("%s %s %zu %zu %u %u", name, settype->typename,
restore_offset, sizeof(struct ip_set_restore), restore_offset, sizeof(struct ip_set_restore),
settype->create_size, restore_size); settype->create_size, restore_size);
/* Sanity checking */ /* Sanity checking */
if (restore_offset if (restore_offset
+ sizeof(struct ip_set_restore) + ALIGNED(sizeof(struct ip_set_restore))
+ settype->create_size > restore_size) + ALIGNED(settype->create_size) > restore_size)
exit_error(PARAMETER_PROBLEM, exit_error(PARAMETER_PROBLEM,
"Giving up, restore file is screwed up!"); "Giving up, restore file is screwed up!");
@@ -985,11 +972,11 @@ static void set_restore_create(const char *name, struct settype *settype)
DP("name %s, restore index %u", restore_set->name, restore_set->index); DP("name %s, restore index %u", restore_set->name, restore_set->index);
/* Add settype data */ /* Add settype data */
memcpy(restore_data + restore_offset + sizeof(struct ip_set_restore), restore_offset += ALIGNED(sizeof(struct ip_set_restore));
settype->data, settype->create_size); memcpy(restore_data + restore_offset, settype->data, settype->create_size);
restore_offset += sizeof(struct ip_set_restore) restore_offset += ALIGNED(settype->create_size);
+ settype->create_size; DP("restore_offset: %zu", restore_offset);
/* Add set to set_list */ /* Add set to set_list */
set = ipset_malloc(sizeof(struct set)); set = ipset_malloc(sizeof(struct set));
@@ -1009,7 +996,7 @@ static void set_destroy(const char *name, unsigned op, unsigned cmd)
DP("%s %s", cmd == CMD_DESTROY ? "destroy" : "flush", name); DP("%s %s", cmd == CMD_DESTROY ? "destroy" : "flush", name);
req.op = op; req.op = op;
req.version = IP_SET_PROTOCOL_VERSION; req.version = protocol_version;
strcpy(req.name, name); strcpy(req.name, name);
kernel_sendto(cmd, &req, sizeof(struct ip_set_req_std)); kernel_sendto(cmd, &req, sizeof(struct ip_set_req_std));
@@ -1027,7 +1014,7 @@ static void set_rename(const char *name, const char *newname,
name, newname); name, newname);
req.op = op; req.op = op;
req.version = IP_SET_PROTOCOL_VERSION; req.version = protocol_version;
strcpy(req.name, name); strcpy(req.name, name);
strcpy(req.typename, newname); strcpy(req.typename, newname);
@@ -1065,7 +1052,7 @@ tryagain:
} }
/* Get max_sets */ /* Get max_sets */
req_max_sets.op = IP_SET_OP_MAX_SETS; req_max_sets.op = IP_SET_OP_MAX_SETS;
req_max_sets.version = IP_SET_PROTOCOL_VERSION; req_max_sets.version = protocol_version;
strcpy(req_max_sets.set.name, name); strcpy(req_max_sets.set.name, name);
size = sizeof(req_max_sets); size = sizeof(req_max_sets);
kernel_getfrom(CMD_MAX_SETS, &req_max_sets, &size); kernel_getfrom(CMD_MAX_SETS, &req_max_sets, &size);
@@ -1083,8 +1070,8 @@ tryagain:
return 0; return 0;
/* Get setnames */ /* Get setnames */
size = req_size = sizeof(struct ip_set_req_setnames) size = req_size = ALIGNED(sizeof(struct ip_set_req_setnames))
+ req_max_sets.sets * sizeof(struct ip_set_name_list); + req_max_sets.sets * ALIGNED(sizeof(struct ip_set_name_list));
data = ipset_malloc(size); data = ipset_malloc(size);
((struct ip_set_req_setnames *) data)->op = op; ((struct ip_set_req_setnames *) data)->op = op;
((struct ip_set_req_setnames *) data)->index = *idx; ((struct ip_set_req_setnames *) data)->index = *idx;
@@ -1102,8 +1089,8 @@ tryagain:
} }
/* Load in setnames */ /* Load in setnames */
size = sizeof(struct ip_set_req_setnames); size = ALIGNED(sizeof(struct ip_set_req_setnames));
while (size + sizeof(struct ip_set_name_list) <= req_size) { while (size + ALIGNED(sizeof(struct ip_set_name_list)) <= req_size) {
name_list = (struct ip_set_name_list *) name_list = (struct ip_set_name_list *)
(data + size); (data + size);
set = ipset_malloc(sizeof(struct set)); set = ipset_malloc(sizeof(struct set));
@@ -1114,9 +1101,9 @@ tryagain:
set_list[name_list->index] = set; set_list[name_list->index] = set;
DP("loaded %s, type %s, index %u", DP("loaded %s, type %s, index %u",
set->name, set->settype->typename, set->index); set->name, set->settype->typename, set->index);
size += sizeof(struct ip_set_name_list); size += ALIGNED(sizeof(struct ip_set_name_list));
} }
/* Size to get set members, bindings */ /* Size to get set members */
size = ((struct ip_set_req_setnames *)data)->size; size = ((struct ip_set_req_setnames *)data)->size;
free(data); free(data);
@@ -1126,36 +1113,7 @@ tryagain:
/* /*
* Save operation * Save operation
*/ */
static size_t save_bindings(void *data, size_t offset, size_t len) static size_t save_set(void *data, size_t offset, size_t len)
{
struct ip_set_hash_save *hash =
(struct ip_set_hash_save *) (data + offset);
struct set *set;
DP("offset %u, len %u", offset, len);
if (offset + sizeof(struct ip_set_hash_save) > len)
exit_error(OTHER_PROBLEM,
"Save operation failed, try again later.");
set = set_find_byid(hash->id);
if (!(set && set_list[hash->binding]))
exit_error(OTHER_PROBLEM,
"Save binding failed, try again later.");
if (!set->settype->bindip_tostring)
exit_error(OTHER_PROBLEM,
"Internal error, binding is not supported with set %s"
" of settype %s\n",
set->name, set->settype->typename);
printf("-B %s %s -b %s\n",
set->name,
set->settype->bindip_tostring(set, hash->ip, OPT_NUMERIC),
set_list[hash->binding]->name);
return sizeof(struct ip_set_hash_save);
}
static size_t save_set(void *data, int *bindings,
size_t offset, size_t len)
{ {
struct ip_set_save *set_save = struct ip_set_save *set_save =
(struct ip_set_save *) (data + offset); (struct ip_set_save *) (data + offset);
@@ -1163,12 +1121,12 @@ static size_t save_set(void *data, int *bindings,
struct settype *settype; struct settype *settype;
size_t used; size_t used;
DP("offset %u (%u/%u/%u), len %u", offset, DP("offset %zu (%zu/%u/%u), len %zu", offset,
sizeof(struct ip_set_save), sizeof(struct ip_set_save),
set_save->header_size, set_save->members_size, set_save->header_size, set_save->members_size,
len); len);
if (offset + sizeof(struct ip_set_save) > len if (offset + ALIGNED(sizeof(struct ip_set_save)) > len
|| offset + sizeof(struct ip_set_save) || offset + ALIGNED(sizeof(struct ip_set_save))
+ set_save->header_size + set_save->members_size > len) + set_save->header_size + set_save->members_size > len)
exit_error(OTHER_PROBLEM, exit_error(OTHER_PROBLEM,
"Save operation failed, try again later."); "Save operation failed, try again later.");
@@ -1176,8 +1134,7 @@ static size_t save_set(void *data, int *bindings,
DP("index: %u", set_save->index); DP("index: %u", set_save->index);
if (set_save->index == IP_SET_INVALID_ID) { if (set_save->index == IP_SET_INVALID_ID) {
/* Marker */ /* Marker */
*bindings = 1; return ALIGNED(sizeof(struct ip_set_save));
return sizeof(struct ip_set_save);
} }
set = set_list[set_save->index]; set = set_list[set_save->index];
if (!set) if (!set)
@@ -1186,7 +1143,7 @@ static size_t save_set(void *data, int *bindings,
settype = set->settype; settype = set->settype;
/* Init set header */ /* Init set header */
used = sizeof(struct ip_set_save); used = ALIGNED(sizeof(struct ip_set_save));
settype->initheader(set, data + offset + used); settype->initheader(set, data + offset + used);
/* Print create set */ /* Print create set */
@@ -1195,44 +1152,18 @@ static size_t save_set(void *data, int *bindings,
/* Print add IPs */ /* Print add IPs */
used += set_save->header_size; used += set_save->header_size;
settype->saveips(set, data + offset + used, settype->saveips(set, data + offset + used,
set_save->members_size, OPT_NUMERIC); set_save->members_size, OPT_NUMERIC,
DONT_ALIGN);
return (used + set_save->members_size); return (used + set_save->members_size);
} }
static size_t save_default_bindings(void *data, int *bindings)
{
struct ip_set_save *set_save = (struct ip_set_save *) data;
struct set *set;
if (set_save->index == IP_SET_INVALID_ID) {
/* Marker */
*bindings = 1;
return sizeof(struct ip_set_save);
}
set = set_list[set_save->index];
DP("%s, binding %u", set->name, set_save->binding);
if (set_save->binding != IP_SET_INVALID_ID) {
if (!set_list[set_save->binding])
exit_error(OTHER_PROBLEM,
"Save set failed, try again later.");
printf("-B %s %s -b %s\n",
set->name, IPSET_TOKEN_DEFAULT,
set_list[set_save->binding]->name);
}
return (sizeof(struct ip_set_save)
+ set_save->header_size
+ set_save->members_size);
}
static int try_save_sets(const char name[IP_SET_MAXNAMELEN]) static int try_save_sets(const char name[IP_SET_MAXNAMELEN])
{ {
void *data = NULL; void *data = NULL;
socklen_t size, req_size = 0; socklen_t size, req_size = 0;
ip_set_id_t idx; ip_set_id_t idx;
int res = 0, bindings = 0; int res = 0;
time_t now = time(NULL); time_t now = time(NULL);
/* Load set_list from kernel */ /* Load set_list from kernel */
@@ -1240,15 +1171,17 @@ static int try_save_sets(const char name[IP_SET_MAXNAMELEN])
IP_SET_OP_SAVE_SIZE, CMD_SAVE); IP_SET_OP_SAVE_SIZE, CMD_SAVE);
if (size) { if (size) {
/* Get sets, bindings and print them */ /* Get sets and print them */
/* Take into account marker */ /* Take into account marker */
req_size = (size += sizeof(struct ip_set_save)); req_size = (size += ALIGNED(sizeof(struct ip_set_save)));
data = ipset_malloc(size); data = ipset_malloc(size);
((struct ip_set_req_list *) data)->op = IP_SET_OP_SAVE; ((struct ip_set_req_list *) data)->op = IP_SET_OP_SAVE;
((struct ip_set_req_list *) data)->index = idx; ((struct ip_set_req_list *) data)->index = idx;
res = kernel_getfrom_handleerrno(CMD_SAVE, data, &size); res = kernel_getfrom_handleerrno(CMD_SAVE, data, &size);
if (res != 0 || size != req_size) { if (res != 0 || size != req_size) {
DP("Try again: res: %i, size %u, req_size: %u",
res, size, req_size);
free(data); free(data);
return -EAGAIN; return -EAGAIN;
} }
@@ -1258,17 +1191,8 @@ static int try_save_sets(const char name[IP_SET_MAXNAMELEN])
size = 0; size = 0;
while (size < req_size) { while (size < req_size) {
DP("size: %u, req_size: %u", size, req_size); DP("size: %u, req_size: %u", size, req_size);
if (bindings) size += save_set(data, size, req_size);
size += save_bindings(data, size, req_size);
else
size += save_set(data, &bindings, size, req_size);
} }
/* Re-read data to save default bindings */
bindings = 0;
size = 0;
while (size < req_size && bindings == 0)
size += save_default_bindings(data + size, &bindings);
printf("COMMIT\n"); printf("COMMIT\n");
now = time(NULL); now = time(NULL);
printf("# Completed on %s", ctime(&now)); printf("# Completed on %s", ctime(&now));
@@ -1366,7 +1290,7 @@ static void set_restore(char *argv0)
char buffer[1024]; char buffer[1024];
char *ptr, *name = NULL; char *ptr, *name = NULL;
char cmd = ' '; char cmd = ' ';
int first_pass, i, bindings = 0; int first_pass, i;
struct settype *settype = NULL; struct settype *settype = NULL;
struct ip_set_req_setnames *header; struct ip_set_req_setnames *header;
ip_set_id_t idx; ip_set_id_t idx;
@@ -1381,8 +1305,7 @@ static void set_restore(char *argv0)
IP_SET_OP_LIST_SIZE, CMD_RESTORE); IP_SET_OP_LIST_SIZE, CMD_RESTORE);
restore_line = 0; restore_line = 0;
restore_size = sizeof(struct ip_set_req_setnames)/* header */ restore_size = ALIGNED(sizeof(struct ip_set_req_setnames)); /* header */
+ sizeof(struct ip_set_restore); /* marker */
DP("restore_size: %u", restore_size); DP("restore_size: %u", restore_size);
/* First pass: calculate required amount of data */ /* First pass: calculate required amount of data */
while (fgets(buffer, sizeof(buffer), in)) { while (fgets(buffer, sizeof(buffer), in)) {
@@ -1429,13 +1352,9 @@ static void set_restore(char *argv0)
exit_error(PARAMETER_PROBLEM, exit_error(PARAMETER_PROBLEM,
"Missing settype in line %u\n", "Missing settype in line %u\n",
restore_line); restore_line);
if (bindings)
exit_error(PARAMETER_PROBLEM,
"Invalid line %u: create must precede bindings\n",
restore_line);
settype = check_set_typename(ptr); settype = check_set_typename(ptr);
restore_size += sizeof(struct ip_set_restore) restore_size += ALIGNED(sizeof(struct ip_set_restore))
+ settype->create_size; + ALIGNED(settype->create_size);
DP("restore_size (N): %u", restore_size); DP("restore_size (N): %u", restore_size);
break; break;
} }
@@ -1446,20 +1365,10 @@ static void set_restore(char *argv0)
"Add IP to set %s in line %u without " "Add IP to set %s in line %u without "
"preceding corresponding create set line\n", "preceding corresponding create set line\n",
ptr, restore_line); ptr, restore_line);
if (bindings) restore_size += ALIGNED(settype->adt_size);
exit_error(PARAMETER_PROBLEM,
"Invalid line %u: adding entries must precede bindings\n",
restore_line);
restore_size += settype->adt_size;
DP("restore_size (A): %u", restore_size); DP("restore_size (A): %u", restore_size);
break; break;
} }
case 'B': {
bindings = 1;
restore_size += sizeof(struct ip_set_hash_save);
DP("restore_size (B): %u", restore_size);
break;
}
default: { default: {
exit_error(PARAMETER_PROBLEM, exit_error(PARAMETER_PROBLEM,
"Unrecognized restore command in line %u\n", "Unrecognized restore command in line %u\n",
@@ -1471,12 +1380,13 @@ static void set_restore(char *argv0)
if (!restore) if (!restore)
exit_error(PARAMETER_PROBLEM, exit_error(PARAMETER_PROBLEM,
"Missing COMMIT line\n"); "Missing COMMIT line\n");
restore_size += ALIGNED(sizeof(struct ip_set_restore)); /* marker */
DP("restore_size: %u", restore_size); DP("restore_size: %u", restore_size);
restore_data = ipset_malloc(restore_size); restore_data = ipset_malloc(restore_size);
header = (struct ip_set_req_setnames *) restore_data; header = (struct ip_set_req_setnames *) restore_data;
header->op = IP_SET_OP_RESTORE; header->op = IP_SET_OP_RESTORE;
header->size = restore_size; header->size = restore_size;
restore_offset = sizeof(struct ip_set_req_setnames); restore_offset = ALIGNED(sizeof(struct ip_set_req_setnames));
/* Rewind to scan the file again */ /* Rewind to scan the file again */
fseek(in, 0L, SEEK_SET); fseek(in, 0L, SEEK_SET);
@@ -1508,17 +1418,15 @@ static void set_restore(char *argv0)
exit_error(PARAMETER_PROBLEM, exit_error(PARAMETER_PROBLEM,
"Broken restore file\n"); "Broken restore file\n");
do_restore: do_restore:
if (bindings == 0 if (restore_size == (restore_offset + ALIGNED(sizeof(struct ip_set_restore)))) {
&& restore_size ==
(restore_offset + sizeof(struct ip_set_restore))) {
/* No bindings */ /* No bindings */
struct ip_set_restore *marker = struct ip_set_restore *marker =
(struct ip_set_restore *) (restore_data + restore_offset); (struct ip_set_restore *) (restore_data + restore_offset);
DP("restore marker");
marker->index = IP_SET_INVALID_ID; marker->index = IP_SET_INVALID_ID;
marker->header_size = marker->members_size = 0; marker->header_size = marker->members_size = 0;
restore_offset += sizeof(struct ip_set_restore); restore_offset += ALIGNED(sizeof(struct ip_set_restore));
DP("restore marker, restore_offset: %zu", restore_offset);
} }
if (restore_size != restore_offset) if (restore_size != restore_offset)
exit_error(PARAMETER_PROBLEM, exit_error(PARAMETER_PROBLEM,
@@ -1550,8 +1458,10 @@ static struct set *set_adt_get(const char *name)
DP("%s", name); DP("%s", name);
check_protocolversion();
req_adt_get.op = IP_SET_OP_ADT_GET; req_adt_get.op = IP_SET_OP_ADT_GET;
req_adt_get.version = IP_SET_PROTOCOL_VERSION; req_adt_get.version = protocol_version;
strcpy(req_adt_get.set.name, name); strcpy(req_adt_get.set.name, name);
size = sizeof(struct ip_set_req_adt_get); size = sizeof(struct ip_set_req_adt_get);
@@ -1579,15 +1489,15 @@ static int set_adtip(struct set *set, const char *adt,
DP("%s -> %s", set->name, adt); DP("%s -> %s", set->name, adt);
/* Alloc memory for the data to send */ /* Alloc memory for the data to send */
size = sizeof(struct ip_set_req_adt) + set->settype->adt_size ; size = ALIGNED(sizeof(struct ip_set_req_adt)) + set->settype->adt_size ;
DP("alloc size %d", size); DP("alloc size %zu", size);
data = ipset_malloc(size); data = ipset_malloc(size);
/* Fill out the request */ /* Fill out the request */
req_adt = (struct ip_set_req_adt *) data; req_adt = (struct ip_set_req_adt *) data;
req_adt->op = op; req_adt->op = op;
req_adt->index = set->index; req_adt->index = set->index;
memcpy(data + sizeof(struct ip_set_req_adt), memcpy(data + ALIGNED(sizeof(struct ip_set_req_adt)),
set->settype->data, set->settype->adt_size); set->settype->data, set->settype->adt_size);
if (kernel_sendto_handleerrno(cmd, data, size) == -1) if (kernel_sendto_handleerrno(cmd, data, size) == -1)
@@ -1625,155 +1535,22 @@ static void set_restore_add(struct set *set, const char *adt UNUSED)
{ {
DP("%s %s", set->name, adt); DP("%s %s", set->name, adt);
/* Sanity checking */ /* Sanity checking */
if (restore_offset + set->settype->adt_size > restore_size) if (restore_offset + ALIGNED(set->settype->adt_size) > restore_size)
exit_error(PARAMETER_PROBLEM, exit_error(PARAMETER_PROBLEM,
"Giving up, restore file is screwed up!"); "Giving up, restore file is screwed up!");
memcpy(restore_data + restore_offset, memcpy(restore_data + restore_offset,
set->settype->data, set->settype->adt_size); set->settype->data, set->settype->adt_size);
restore_set->members_size += set->settype->adt_size; restore_set->members_size += ALIGNED(set->settype->adt_size);
restore_offset += set->settype->adt_size; restore_offset += ALIGNED(set->settype->adt_size);
}
/* DP("restore_offset: %zu", restore_offset);
* Send bind/unbind/test binding order to kernel for a set
*/
static int set_bind(struct set *set, const char *adt,
const char *binding,
unsigned op, unsigned cmd)
{
struct ip_set_req_bind *req_bind;
size_t size;
void *data;
int res = 0;
/* set may be null: '-U :all: :all:|:default:' */
DP("(%s, %s) -> %s", set ? set->name : IPSET_TOKEN_ALL, adt, binding);
/* Ugly */
if (set != NULL
&& ((strcmp(set->settype->typename, "iptreemap") == 0)
|| (strcmp(set->settype->typename, "ipportiphash") == 0)
|| (strcmp(set->settype->typename, "ipportnethash") == 0)
|| (strcmp(set->settype->typename, "setlist") == 0)))
exit_error(PARAMETER_PROBLEM,
"%s type of sets cannot be used at binding operations\n",
set->settype->typename);
/* Alloc memory for the data to send */
size = sizeof(struct ip_set_req_bind);
if (op != IP_SET_OP_UNBIND_SET && adt[0] == ':')
/* Set default binding */
size += IP_SET_MAXNAMELEN;
else if (!(op == IP_SET_OP_UNBIND_SET && set == NULL))
size += set->settype->adt_size;
DP("alloc size %d", size);
data = ipset_malloc(size);
/* Fill out the request */
req_bind = (struct ip_set_req_bind *) data;
req_bind->op = op;
req_bind->index = set ? set->index : IP_SET_INVALID_ID;
if (adt[0] == ':') {
/* ':default:' and ':all:' */
strncpy(req_bind->binding, adt, IP_SET_MAXNAMELEN);
if (op != IP_SET_OP_UNBIND_SET && adt[0] == ':')
strncpy(data + sizeof(struct ip_set_req_bind),
binding, IP_SET_MAXNAMELEN);
} else {
strncpy(req_bind->binding, binding, IP_SET_MAXNAMELEN);
memcpy(data + sizeof(struct ip_set_req_bind),
set->settype->data, set->settype->adt_size);
}
if (op == IP_SET_OP_TEST_BIND_SET) {
if (kernel_sendto_handleerrno(cmd, data, size) == -1) {
ipset_printf("%s in set %s is bound to %s.",
adt, set->name, binding);
res = 0;
} else {
ipset_printf("%s in set %s is NOT bound to %s.",
adt, set->name, binding);
res = 1;
}
} else
kernel_sendto(cmd, data, size);
free(data);
return res;
}
static void set_restore_bind(struct set *set,
const char *adt,
const char *binding)
{
struct ip_set_hash_save *hash_restore;
if (restore == 1) {
/* Marker */
struct ip_set_restore *marker =
(struct ip_set_restore *) (restore_data + restore_offset);
DP("restore marker");
if (restore_offset + sizeof(struct ip_set_restore)
> restore_size)
exit_error(PARAMETER_PROBLEM,
"Giving up, restore file is screwed up!");
marker->index = IP_SET_INVALID_ID;
marker->header_size = marker->members_size = 0;
restore_offset += sizeof(struct ip_set_restore);
restore = 2;
}
/* Sanity checking */
if (restore_offset + sizeof(struct ip_set_hash_save) > restore_size)
exit_error(PARAMETER_PROBLEM,
"Giving up, restore file is screwed up!");
hash_restore = (struct ip_set_hash_save *) (restore_data + restore_offset);
DP("%s -> %s", adt, binding);
if (strcmp(adt, IPSET_TOKEN_DEFAULT) == 0)
hash_restore->ip = 0;
else {
if (!set->settype->bindip_parse)
exit_error(OTHER_PROBLEM,
"Internal error, binding is not supported with set %s"
" of settype %s\n",
set->name, set->settype->typename);
set->settype->bindip_parse(adt, &hash_restore->ip);
}
hash_restore->id = set->index;
hash_restore->binding = (set_find_byname(binding))->index;
DP("id %u, ip %u, binding %u",
hash_restore->id, hash_restore->ip, hash_restore->binding);
restore_offset += sizeof(struct ip_set_hash_save);
} }
/* /*
* Print operation * Print operation
*/ */
static void print_bindings(struct set *set,
void *data, size_t size, unsigned options,
char * (*printip)(struct set *set,
ip_set_ip_t ip, unsigned options))
{
size_t offset = 0;
struct ip_set_hash_list *hash;
if (offset < size && !printip)
exit_error(OTHER_PROBLEM,
"Internal error, binding is not supported with set %s"
" of settype %s\n",
set->name, set->settype->typename);
while (offset < size) {
hash = (struct ip_set_hash_list *) (data + offset);
printf("%s -> %s\n",
printip(set, hash->ip, options),
set_list[hash->binding]->name);
offset += sizeof(struct ip_set_hash_list);
}
}
/* Help function to set_list() */ /* Help function to set_list() */
static size_t print_set(void *data, unsigned options) static size_t print_set(void *data, unsigned options)
{ {
@@ -1783,15 +1560,14 @@ static size_t print_set(void *data, unsigned options)
size_t offset; size_t offset;
/* Pretty print the set */ /* Pretty print the set */
DP("header size: %u, members size: %u",
setlist->header_size, setlist->members_size);
printf("Name: %s\n", set->name); printf("Name: %s\n", set->name);
printf("Type: %s\n", settype->typename); printf("Type: %s\n", settype->typename);
printf("References: %d\n", setlist->ref); printf("References: %d\n", setlist->ref);
printf("Default binding: %s\n",
setlist->binding == IP_SET_INVALID_ID ? ""
: set_list[setlist->binding]->name);
/* Init header */ /* Init header */
offset = sizeof(struct ip_set_list); offset = ALIGNED(sizeof(struct ip_set_list));
settype->initheader(set, data + offset); settype->initheader(set, data + offset);
/* Pretty print the type header */ /* Pretty print the type header */
@@ -1801,24 +1577,20 @@ static size_t print_set(void *data, unsigned options)
/* Pretty print all IPs */ /* Pretty print all IPs */
printf("Members:\n"); printf("Members:\n");
offset += setlist->header_size; offset += setlist->header_size;
DP("Aligned: %u, offset: %zu, members_size %u\n", !DONT_ALIGN, offset,
setlist->members_size);
if (options & OPT_SORTED) if (options & OPT_SORTED)
settype->printips_sorted(set, data + offset, settype->printips_sorted(set, data + offset,
setlist->members_size, options); setlist->members_size, options,
DONT_ALIGN);
else else
settype->printips(set, data + offset, settype->printips(set, data + offset,
setlist->members_size, options); setlist->members_size, options,
DONT_ALIGN);
/* Print bindings */
printf("Bindings:\n");
offset += setlist->members_size;
if (set->settype->bindip_tostring)
print_bindings(set,
data + offset, setlist->bindings_size, options,
settype->bindip_tostring);
printf("\n"); /* One newline between sets */ printf("\n"); /* One newline between sets */
return (offset + setlist->bindings_size); return (offset + setlist->members_size);
} }
static int try_list_sets(const char name[IP_SET_MAXNAMELEN], static int try_list_sets(const char name[IP_SET_MAXNAMELEN],
@@ -1889,9 +1661,9 @@ static void set_help(const struct settype *settype)
"Usage: %s -N new-set settype [options]\n" "Usage: %s -N new-set settype [options]\n"
" %s -[XFLSH] [set] [options]\n" " %s -[XFLSH] [set] [options]\n"
" %s -[EW] from-set to-set\n" " %s -[EW] from-set to-set\n"
" %s -[ADTU] set IP\n" " %s -[ADT] set IP\n"
" %s -B set IP option\n"
" %s -R\n" " %s -R\n"
" %s -v\n"
" %s -h (print this help information)\n\n", " %s -h (print this help information)\n\n",
program_name, program_version, program_name, program_version,
program_name, program_name, program_name, program_name, program_name, program_name,
@@ -1922,13 +1694,6 @@ static void set_help(const struct settype *settype)
" Deletes an IP from a set\n" " Deletes an IP from a set\n"
" --test -T setname IP \n" " --test -T setname IP \n"
" Tests if an IP exists in a set.\n" " Tests if an IP exists in a set.\n"
" --bind -B setname IP|:default: -b bind-setname\n"
" Bind the IP in setname to bind-setname.\n"
" --unbind -U setname IP|:all:|:default:\n"
" Delete binding belonging to IP,\n"
" all bindings or default binding of setname.\n"
" --unbind -U :all: :all:|:default:\n"
" Delete all bindings or all default bindings.\n"
" --help -H [settype]\n" " --help -H [settype]\n"
" Prints this help, and settype specific help\n" " Prints this help, and settype specific help\n"
" --version -V\n" " --version -V\n"
@@ -1937,8 +1702,7 @@ static void set_help(const struct settype *settype)
" --sorted -s Numeric sort of the IPs in -L\n" " --sorted -s Numeric sort of the IPs in -L\n"
" --numeric -n Numeric output of addresses in a -L (default)\n" " --numeric -n Numeric output of addresses in a -L (default)\n"
" --resolve -r Try to resolve addresses in a -L\n" " --resolve -r Try to resolve addresses in a -L\n"
" --quiet -q Suppress any output to stdout and stderr.\n" " --quiet -q Suppress any output to stdout and stderr.\n");
" --binding -b Specifies the binding for -B\n");
#ifdef IPSET_DEBUG #ifdef IPSET_DEBUG
printf(" --debug -z Enable debugging\n\n"); printf(" --debug -z Enable debugging\n\n");
#else #else
@@ -1970,40 +1734,13 @@ static int parse_adt_cmdline(int command,
{ {
int res = 0; int res = 0;
/* -U :all: :all:|:default: */ *set = restore ? set_find_byname(name) : set_adt_get(name);
if (command == CMD_UNBIND) {
if (strcmp(name, IPSET_TOKEN_ALL) == 0) {
if (strcmp(adt, IPSET_TOKEN_DEFAULT) == 0
|| strcmp(adt, IPSET_TOKEN_ALL) == 0) {
*set = NULL;
*settype = NULL;
return 1;
} else
exit_error(PARAMETER_PROBLEM,
"-U %s requires %s or %s as binding name",
IPSET_TOKEN_ALL,
IPSET_TOKEN_DEFAULT,
IPSET_TOKEN_ALL);
}
}
*set = restore ? set_find_byname(name)
: set_adt_get(name);
/* Reset space for adt data */ /* Reset space for adt data */
*settype = (*set)->settype; *settype = (*set)->settype;
memset((*settype)->data, 0, (*settype)->adt_size); memset((*settype)->data, 0, (*settype)->adt_size);
if ((command == CMD_TEST res = (*settype)->adt_parser(command, adt, (*settype)->data);
|| command == CMD_BIND
|| command == CMD_UNBIND)
&& (strcmp(adt, IPSET_TOKEN_DEFAULT) == 0
|| strcmp(adt, IPSET_TOKEN_ALL) == 0))
res = 1;
else
res = (*settype)->adt_parser(
command,
adt,
(*settype)->data);
return res; return res;
} }
@@ -2018,9 +1755,8 @@ int parse_commandline(int argc, char *argv[])
char *name = NULL; /* All except -H, -R */ char *name = NULL; /* All except -H, -R */
char *newname = NULL; /* -E, -W */ char *newname = NULL; /* -E, -W */
char *adt = NULL; /* -A, -D, -T, -B, -U */ char *adt = NULL; /* -A, -D, -T */
char *binding = NULL; /* -B */ struct set *set = NULL; /* -A, -D, -T */
struct set *set = NULL; /* -A, -D, -T, -B, -U */
struct settype *settype = NULL; /* -N, -H */ struct settype *settype = NULL; /* -N, -H */
char all_sets[] = IPSET_TOKEN_ALL; char all_sets[] = IPSET_TOKEN_ALL;
@@ -2054,11 +1790,14 @@ int parse_commandline(int argc, char *argv[])
break; break;
} }
case 'V':{ /* Version */ case 'V':
printf("%s v%s Protocol version %u.\n", case 'v': { /* Version */
printf("%s v%s, protocol version %u.\n",
program_name, program_version, program_name, program_version,
IP_SET_PROTOCOL_VERSION); IP_SET_PROTOCOL_VERSION);
check_protocolversion(); check_protocolversion();
printf("Kernel module protocol version %u.\n",
protocol_version);
exit(0); exit(0);
} }
@@ -2067,7 +1806,7 @@ int parse_commandline(int argc, char *argv[])
name = check_set_name(optarg); name = check_set_name(optarg);
/* Protect reserved names (binding) */ /* Protect reserved names */
if (name[0] == ':') if (name[0] == ':')
exit_error(PARAMETER_PROBLEM, exit_error(PARAMETER_PROBLEM,
"setname might not start with colon", "setname might not start with colon",
@@ -2142,9 +1881,7 @@ int parse_commandline(int argc, char *argv[])
case 'A': /* Add IP */ case 'A': /* Add IP */
case 'D': /* Del IP */ case 'D': /* Del IP */
case 'T': /* Test IP */ case 'T':{ /* Test IP */
case 'B': /* Bind IP */
case 'U':{ /* Unbind IP */
set_command(&command, find_cmd(c)); set_command(&command, find_cmd(c));
name = check_set_name(optarg); name = check_set_name(optarg);
@@ -2197,11 +1934,6 @@ int parse_commandline(int argc, char *argv[])
break; break;
#endif #endif
case 'b':
add_option(&options, OPT_BINDING);
binding = check_set_name(optarg);
break;
case 1: /* non option */ case 1: /* non option */
printf("Bad argument `%s'\n", optarg); printf("Bad argument `%s'\n", optarg);
exit_tryhelp(PARAMETER_PROBLEM); exit_tryhelp(PARAMETER_PROBLEM);
@@ -2248,6 +1980,8 @@ int parse_commandline(int argc, char *argv[])
generic_opt_check(command, options); generic_opt_check(command, options);
DP("cmd: %c", cmd2char(command)); DP("cmd: %c", cmd2char(command));
check_protocolversion();
switch (command) { switch (command) {
case CMD_CREATE: case CMD_CREATE:
@@ -2298,26 +2032,7 @@ int parse_commandline(int argc, char *argv[])
break; break;
case CMD_TEST: case CMD_TEST:
if (binding) res = set_adtip(set, adt, IP_SET_OP_TEST_IP, CMD_TEST);
res = set_bind(set, adt, binding,
IP_SET_OP_TEST_BIND_SET, CMD_TEST);
else
res = set_adtip(set, adt,
IP_SET_OP_TEST_IP, CMD_TEST);
break;
case CMD_BIND:
fprintf(stderr, "Warning: binding will be removed from the next release.\n"
"Please replace bindigs with sets of ipportmap and ipportiphash types\n");
if (restore)
set_restore_bind(set, adt, binding);
else
set_bind(set, adt, binding,
IP_SET_OP_BIND_SET, CMD_BIND);
break;
case CMD_UNBIND:
set_bind(set, adt, "", IP_SET_OP_UNBIND_SET, CMD_UNBIND);
break; break;
case CMD_HELP: case CMD_HELP:

View File

@@ -56,8 +56,6 @@ enum set_commands {
CMD_ADD, /* -A */ CMD_ADD, /* -A */
CMD_DEL, /* -D */ CMD_DEL, /* -D */
CMD_TEST, /* -T */ CMD_TEST, /* -T */
CMD_BIND, /* -B */
CMD_UNBIND, /* -U */
CMD_HELP, /* -H */ CMD_HELP, /* -H */
CMD_VERSION, /* -V */ CMD_VERSION, /* -V */
NUMBER_OF_CMD = CMD_VERSION, NUMBER_OF_CMD = CMD_VERSION,
@@ -134,22 +132,19 @@ struct settype {
void (*printheader) (struct set *set, unsigned options); void (*printheader) (struct set *set, unsigned options);
/* Pretty print all IPs */ /* Pretty print all IPs */
void (*printips) (struct set *set, void *data, u_int32_t len, unsigned options); void (*printips) (struct set *set, void *data, u_int32_t len,
unsigned options, char dont_align);
/* Pretty print all IPs sorted */ /* Pretty print all IPs sorted */
void (*printips_sorted) (struct set *set, void *data, u_int32_t len, unsigned options); void (*printips_sorted) (struct set *set, void *data, u_int32_t len,
unsigned options, char dont_align);
/* Print save arguments for creating the set */ /* Print save arguments for creating the set */
void (*saveheader) (struct set *set, unsigned options); void (*saveheader) (struct set *set, unsigned options);
/* Print save for all IPs */ /* Print save for all IPs */
void (*saveips) (struct set *set, void *data, u_int32_t len, unsigned options); void (*saveips) (struct set *set, void *data, u_int32_t len,
unsigned options, char dont_align);
/* Conver a single IP (binding) to string */
char * (*bindip_tostring)(struct set *set, ip_set_ip_t ip, unsigned options);
/* Parse an IP at restoring bindings. FIXME */
void (*bindip_parse) (const char *str, ip_set_ip_t * ip);
/* Print usage */ /* Print usage */
void (*usage) (void); void (*usage) (void);
@@ -189,12 +184,12 @@ extern struct set *set_find_byid(ip_set_id_t id);
extern unsigned warn_once; extern unsigned warn_once;
#define BITS_PER_LONG (8*sizeof(unsigned long)) #define BITS_PER_LONG (8*sizeof(ip_set_ip_t))
#define BIT_WORD(nr) ((nr) / BITS_PER_LONG) #define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
static inline int test_bit(int nr, const unsigned long *addr) static inline int test_bit(int nr, const ip_set_ip_t *addr)
{ {
return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1))); return 1 & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
} }
#define UNUSED __attribute__ ((unused)) #define UNUSED __attribute__ ((unused))

View File

@@ -32,7 +32,7 @@
/* Initialize the create. */ /* Initialize the create. */
static void static void
create_init(void *data) iphash_create_init(void *data)
{ {
struct ip_set_req_iphash_create *mydata = data; struct ip_set_req_iphash_create *mydata = data;
@@ -48,7 +48,7 @@ create_init(void *data)
/* Function which parses command options; returns true if it ate an option */ /* Function which parses command options; returns true if it ate an option */
static int static int
create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags) iphash_create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
{ {
struct ip_set_req_iphash_create *mydata = struct ip_set_req_iphash_create *mydata =
(struct ip_set_req_iphash_create *) data; (struct ip_set_req_iphash_create *) data;
@@ -117,7 +117,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
/* Final check; exit if not ok. */ /* Final check; exit if not ok. */
static void static void
create_final(void *data UNUSED, unsigned int flags UNUSED) iphash_create_final(void *data UNUSED, unsigned int flags UNUSED)
{ {
} }
@@ -132,7 +132,7 @@ static const struct option create_opts[] = {
/* Add, del, test parser */ /* Add, del, test parser */
static ip_set_ip_t static ip_set_ip_t
adt_parser(int cmd UNUSED, const char *arg, void *data) iphash_adt_parser(int cmd UNUSED, const char *arg, void *data)
{ {
struct ip_set_req_iphash *mydata = data; struct ip_set_req_iphash *mydata = data;
@@ -149,7 +149,7 @@ adt_parser(int cmd UNUSED, const char *arg, void *data)
*/ */
static void static void
initheader(struct set *set, const void *data) iphash_initheader(struct set *set, const void *data)
{ {
const struct ip_set_req_iphash_create *header = data; const struct ip_set_req_iphash_create *header = data;
struct ip_set_iphash *map = set->settype->header; struct ip_set_iphash *map = set->settype->header;
@@ -178,7 +178,7 @@ mask_to_bits(ip_set_ip_t mask)
} }
static void static void
printheader(struct set *set, unsigned options UNUSED) iphash_printheader(struct set *set, unsigned options UNUSED)
{ {
struct ip_set_iphash *mysetdata = set->settype->header; struct ip_set_iphash *mysetdata = set->settype->header;
@@ -192,7 +192,8 @@ printheader(struct set *set, unsigned options UNUSED)
} }
static void static void
printips(struct set *set UNUSED, void *data, u_int32_t len, unsigned options) iphash_printips(struct set *set UNUSED, void *data, u_int32_t len,
unsigned options, char dont_align)
{ {
size_t offset = 0; size_t offset = 0;
ip_set_ip_t *ip; ip_set_ip_t *ip;
@@ -201,12 +202,12 @@ printips(struct set *set UNUSED, void *data, u_int32_t len, unsigned options)
ip = data + offset; ip = data + offset;
if (*ip) if (*ip)
printf("%s\n", ip_tostring(*ip, options)); printf("%s\n", ip_tostring(*ip, options));
offset += sizeof(ip_set_ip_t); offset += IPSET_VALIGN(sizeof(ip_set_ip_t), dont_align);
} }
} }
static void static void
saveheader(struct set *set, unsigned options UNUSED) iphash_saveheader(struct set *set, unsigned options UNUSED)
{ {
struct ip_set_iphash *mysetdata = set->settype->header; struct ip_set_iphash *mysetdata = set->settype->header;
@@ -221,7 +222,8 @@ saveheader(struct set *set, unsigned options UNUSED)
/* Print save for an IP */ /* Print save for an IP */
static void static void
saveips(struct set *set UNUSED, void *data, u_int32_t len, unsigned options) iphash_saveips(struct set *set UNUSED, void *data, u_int32_t len,
unsigned options, char dont_align)
{ {
size_t offset = 0; size_t offset = 0;
ip_set_ip_t *ip; ip_set_ip_t *ip;
@@ -231,11 +233,12 @@ saveips(struct set *set UNUSED, void *data, u_int32_t len, unsigned options)
if (*ip) if (*ip)
printf("-A %s %s\n", set->name, printf("-A %s %s\n", set->name,
ip_tostring(*ip, options)); ip_tostring(*ip, options));
offset += sizeof(ip_set_ip_t); offset += IPSET_VALIGN(sizeof(ip_set_ip_t), dont_align);
} }
} }
static void usage(void) static void
iphash_usage(void)
{ {
printf printf
("-N set iphash [--hashsize hashsize] [--probes probes ]\n" ("-N set iphash [--hashsize hashsize] [--probes probes ]\n"
@@ -251,29 +254,25 @@ static struct settype settype_iphash = {
/* Create */ /* Create */
.create_size = sizeof(struct ip_set_req_iphash_create), .create_size = sizeof(struct ip_set_req_iphash_create),
.create_init = &create_init, .create_init = iphash_create_init,
.create_parse = &create_parse, .create_parse = iphash_create_parse,
.create_final = &create_final, .create_final = iphash_create_final,
.create_opts = create_opts, .create_opts = create_opts,
/* Add/del/test */ /* Add/del/test */
.adt_size = sizeof(struct ip_set_req_iphash), .adt_size = sizeof(struct ip_set_req_iphash),
.adt_parser = &adt_parser, .adt_parser = iphash_adt_parser,
/* Printing */ /* Printing */
.header_size = sizeof(struct ip_set_iphash), .header_size = sizeof(struct ip_set_iphash),
.initheader = &initheader, .initheader = iphash_initheader,
.printheader = &printheader, .printheader = iphash_printheader,
.printips = &printips, /* We only have the unsorted version */ .printips = iphash_printips,
.printips_sorted = &printips, .printips_sorted = iphash_printips,
.saveheader = &saveheader, .saveheader = iphash_saveheader,
.saveips = &saveips, .saveips = iphash_saveips,
/* Bindings */ .usage = iphash_usage,
.bindip_tostring = &binding_ip_tostring,
.bindip_parse = &parse_ip,
.usage = &usage,
}; };
CONSTRUCTOR(iphash) CONSTRUCTOR(iphash)

View File

@@ -35,7 +35,7 @@
/* Initialize the create. */ /* Initialize the create. */
static void static void
create_init(void *data) ipmap_create_init(void *data)
{ {
struct ip_set_req_ipmap_create *mydata = data; struct ip_set_req_ipmap_create *mydata = data;
@@ -45,7 +45,7 @@ create_init(void *data)
/* Function which parses command options; returns true if it ate an option */ /* Function which parses command options; returns true if it ate an option */
static int static int
create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags) ipmap_create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
{ {
struct ip_set_req_ipmap_create *mydata = data; struct ip_set_req_ipmap_create *mydata = data;
unsigned int bits; unsigned int bits;
@@ -115,7 +115,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
/* Final check; exit if not ok. */ /* Final check; exit if not ok. */
static void static void
create_final(void *data, unsigned int flags) ipmap_create_final(void *data, unsigned int flags)
{ {
struct ip_set_req_ipmap_create *mydata = data; struct ip_set_req_ipmap_create *mydata = data;
ip_set_ip_t range; ip_set_ip_t range;
@@ -188,7 +188,7 @@ static const struct option create_opts[] = {
/* Add, del, test parser */ /* Add, del, test parser */
static ip_set_ip_t static ip_set_ip_t
adt_parser(int cmd UNUSED, const char *arg, void *data) ipmap_adt_parser(int cmd UNUSED, const char *arg, void *data)
{ {
struct ip_set_req_ipmap *mydata = data; struct ip_set_req_ipmap *mydata = data;
@@ -205,7 +205,7 @@ adt_parser(int cmd UNUSED, const char *arg, void *data)
*/ */
static void static void
initheader(struct set *set, const void *data) ipmap_initheader(struct set *set, const void *data)
{ {
const struct ip_set_req_ipmap_create *header = data; const struct ip_set_req_ipmap_create *header = data;
struct ip_set_ipmap *map = set->settype->header; struct ip_set_ipmap *map = set->settype->header;
@@ -234,7 +234,7 @@ initheader(struct set *set, const void *data)
} }
static void static void
printheader(struct set *set, unsigned options) ipmap_printheader(struct set *set, unsigned options)
{ {
struct ip_set_ipmap *mysetdata = set->settype->header; struct ip_set_ipmap *mysetdata = set->settype->header;
@@ -246,9 +246,9 @@ printheader(struct set *set, unsigned options)
printf(" netmask: %d\n", mask_to_bits(mysetdata->netmask)); printf(" netmask: %d\n", mask_to_bits(mysetdata->netmask));
} }
static void static inline void
printips_sorted(struct set *set, void *data, __ipmap_printips_sorted(struct set *set, void *data,
u_int32_t len UNUSED, unsigned options) u_int32_t len UNUSED, unsigned options)
{ {
struct ip_set_ipmap *mysetdata = set->settype->header; struct ip_set_ipmap *mysetdata = set->settype->header;
ip_set_ip_t id; ip_set_ip_t id;
@@ -262,7 +262,26 @@ printips_sorted(struct set *set, void *data,
} }
static void static void
saveheader(struct set *set, unsigned options) ipmap_printips_sorted(struct set *set, void *data,
u_int32_t len, unsigned options,
char dont_align)
{
ip_set_ip_t *ip;
size_t offset = 0;
if (dont_align)
return __ipmap_printips_sorted(set, data, len, options);
while (offset < len) {
DP("offset: %zu, len %u\n", offset, len);
ip = data + offset;
printf("%s\n", ip_tostring(*ip, options));
offset += IPSET_ALIGN(sizeof(ip_set_ip_t));
}
}
static void
ipmap_saveheader(struct set *set, unsigned options)
{ {
struct ip_set_ipmap *mysetdata = set->settype->header; struct ip_set_ipmap *mysetdata = set->settype->header;
@@ -278,8 +297,9 @@ saveheader(struct set *set, unsigned options)
mask_to_bits(mysetdata->netmask)); mask_to_bits(mysetdata->netmask));
} }
static void static inline void
saveips(struct set *set, void *data, u_int32_t len UNUSED, unsigned options) __ipmap_saveips(struct set *set, void *data, u_int32_t len UNUSED,
unsigned options)
{ {
struct ip_set_ipmap *mysetdata = set->settype->header; struct ip_set_ipmap *mysetdata = set->settype->header;
ip_set_ip_t id; ip_set_ip_t id;
@@ -294,7 +314,25 @@ saveips(struct set *set, void *data, u_int32_t len UNUSED, unsigned options)
options)); options));
} }
static void usage(void) static void
ipmap_saveips(struct set *set, void *data, u_int32_t len,
unsigned options, char dont_align)
{
ip_set_ip_t *ip;
size_t offset = 0;
if (dont_align)
return __ipmap_saveips(set, data, len, options);
while (offset < len) {
ip = data + offset;
printf("-A %s %s\n", set->name, ip_tostring(*ip, options));
offset += IPSET_ALIGN(sizeof(ip_set_ip_t));
}
}
static void
ipmap_usage(void)
{ {
printf printf
("-N set ipmap --from IP --to IP [--netmask CIDR-netmask]\n" ("-N set ipmap --from IP --to IP [--netmask CIDR-netmask]\n"
@@ -310,29 +348,25 @@ static struct settype settype_ipmap = {
/* Create */ /* Create */
.create_size = sizeof(struct ip_set_req_ipmap_create), .create_size = sizeof(struct ip_set_req_ipmap_create),
.create_init = &create_init, .create_init = ipmap_create_init,
.create_parse = &create_parse, .create_parse = ipmap_create_parse,
.create_final = &create_final, .create_final = ipmap_create_final,
.create_opts = create_opts, .create_opts = create_opts,
/* Add/del/test */ /* Add/del/test */
.adt_size = sizeof(struct ip_set_req_ipmap), .adt_size = sizeof(struct ip_set_req_ipmap),
.adt_parser = &adt_parser, .adt_parser = ipmap_adt_parser,
/* Printing */ /* Printing */
.header_size = sizeof(struct ip_set_ipmap), .header_size = sizeof(struct ip_set_ipmap),
.initheader = &initheader, .initheader = ipmap_initheader,
.printheader = &printheader, .printheader = ipmap_printheader,
.printips = &printips_sorted, /* We only have sorted version */ .printips = ipmap_printips_sorted,
.printips_sorted = &printips_sorted, .printips_sorted = ipmap_printips_sorted,
.saveheader = &saveheader, .saveheader = ipmap_saveheader,
.saveips = &saveips, .saveips = ipmap_saveips,
/* Bindings */ .usage = ipmap_usage,
.bindip_tostring = &binding_ip_tostring,
.bindip_parse = &parse_ip,
.usage = &usage,
}; };
CONSTRUCTOR(ipmap) CONSTRUCTOR(ipmap)

View File

@@ -32,7 +32,7 @@
/* Initialize the create. */ /* Initialize the create. */
static void static void
create_init(void *data) ipporthash_create_init(void *data)
{ {
struct ip_set_req_ipporthash_create *mydata = data; struct ip_set_req_ipporthash_create *mydata = data;
@@ -46,7 +46,8 @@ create_init(void *data)
/* Function which parses command options; returns true if it ate an option */ /* Function which parses command options; returns true if it ate an option */
static int static int
create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags) ipporthash_create_parse(int c, char *argv[] UNUSED, void *data,
unsigned *flags)
{ {
struct ip_set_req_ipporthash_create *mydata = data; struct ip_set_req_ipporthash_create *mydata = data;
ip_set_ip_t value; ip_set_ip_t value;
@@ -137,7 +138,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
/* Final check; exit if not ok. */ /* Final check; exit if not ok. */
static void static void
create_final(void *data, unsigned int flags) ipporthash_create_final(void *data, unsigned int flags)
{ {
struct ip_set_req_ipporthash_create *mydata = data; struct ip_set_req_ipporthash_create *mydata = data;
@@ -189,7 +190,7 @@ static const struct option create_opts[] = {
/* Add, del, test parser */ /* Add, del, test parser */
static ip_set_ip_t static ip_set_ip_t
adt_parser(int cmd UNUSED, const char *arg, void *data) ipporthash_adt_parser(int cmd UNUSED, const char *arg, void *data)
{ {
struct ip_set_req_ipporthash *mydata = data; struct ip_set_req_ipporthash *mydata = data;
char *saved = ipset_strdup(arg); char *saved = ipset_strdup(arg);
@@ -222,7 +223,7 @@ adt_parser(int cmd UNUSED, const char *arg, void *data)
*/ */
static void static void
initheader(struct set *set, const void *data) ipporthash_initheader(struct set *set, const void *data)
{ {
const struct ip_set_req_ipporthash_create *header = data; const struct ip_set_req_ipporthash_create *header = data;
struct ip_set_ipporthash *map = set->settype->header; struct ip_set_ipporthash *map = set->settype->header;
@@ -236,7 +237,7 @@ initheader(struct set *set, const void *data)
} }
static void static void
printheader(struct set *set, unsigned options) ipporthash_printheader(struct set *set, unsigned options)
{ {
struct ip_set_ipporthash *mysetdata = set->settype->header; struct ip_set_ipporthash *mysetdata = set->settype->header;
@@ -248,7 +249,8 @@ printheader(struct set *set, unsigned options)
} }
static void static void
printips(struct set *set, void *data, u_int32_t len, unsigned options) ipporthash_printips(struct set *set, void *data, u_int32_t len,
unsigned options, char dont_align)
{ {
struct ip_set_ipporthash *mysetdata = set->settype->header; struct ip_set_ipporthash *mysetdata = set->settype->header;
size_t offset = 0; size_t offset = 0;
@@ -264,12 +266,12 @@ printips(struct set *set, void *data, u_int32_t len, unsigned options)
ip_tostring(ip, options), ip_tostring(ip, options),
port_tostring(port, options)); port_tostring(port, options));
} }
offset += sizeof(ip_set_ip_t); offset += IPSET_VALIGN(sizeof(ip_set_ip_t), dont_align);
} }
} }
static void static void
saveheader(struct set *set, unsigned options) ipporthash_saveheader(struct set *set, unsigned options)
{ {
struct ip_set_ipporthash *mysetdata = set->settype->header; struct ip_set_ipporthash *mysetdata = set->settype->header;
@@ -284,7 +286,8 @@ saveheader(struct set *set, unsigned options)
/* Print save for an IP */ /* Print save for an IP */
static void static void
saveips(struct set *set, void *data, u_int32_t len, unsigned options) ipporthash_saveips(struct set *set, void *data, u_int32_t len,
unsigned options, char dont_align)
{ {
struct ip_set_ipporthash *mysetdata = set->settype->header; struct ip_set_ipporthash *mysetdata = set->settype->header;
size_t offset = 0; size_t offset = 0;
@@ -300,27 +303,12 @@ saveips(struct set *set, void *data, u_int32_t len, unsigned options)
ip_tostring(ip, options), ip_tostring(ip, options),
port_tostring(port, options)); port_tostring(port, options));
} }
offset += sizeof(ip_set_ip_t); offset += IPSET_VALIGN(sizeof(ip_set_ip_t), dont_align);
} }
} }
static char buffer[22]; static void
ipporthash_usage(void)
static char *
unpack_ipport_tostring(struct set *set, ip_set_ip_t bip, unsigned options)
{
struct ip_set_ipporthash *mysetdata = set->settype->header;
ip_set_ip_t ip, port;
ip = (bip>>16) + mysetdata->first_ip;
port = (uint16_t) bip;
sprintf(buffer, "%s,%s",
ip_tostring(ip, options), port_tostring(port, options));
return buffer;
}
static void usage(void)
{ {
printf printf
("-N set ipporthash --from IP --to IP\n" ("-N set ipporthash --from IP --to IP\n"
@@ -338,29 +326,25 @@ static struct settype settype_ipporthash = {
/* Create */ /* Create */
.create_size = sizeof(struct ip_set_req_ipporthash_create), .create_size = sizeof(struct ip_set_req_ipporthash_create),
.create_init = &create_init, .create_init = ipporthash_create_init,
.create_parse = &create_parse, .create_parse = ipporthash_create_parse,
.create_final = &create_final, .create_final = ipporthash_create_final,
.create_opts = create_opts, .create_opts = create_opts,
/* Add/del/test */ /* Add/del/test */
.adt_size = sizeof(struct ip_set_req_ipporthash), .adt_size = sizeof(struct ip_set_req_ipporthash),
.adt_parser = &adt_parser, .adt_parser = ipporthash_adt_parser,
/* Printing */ /* Printing */
.header_size = sizeof(struct ip_set_ipporthash), .header_size = sizeof(struct ip_set_ipporthash),
.initheader = &initheader, .initheader = ipporthash_initheader,
.printheader = &printheader, .printheader = ipporthash_printheader,
.printips = &printips, /* We only have the unsorted version */ .printips = ipporthash_printips,
.printips_sorted = &printips, .printips_sorted = ipporthash_printips,
.saveheader = &saveheader, .saveheader = ipporthash_saveheader,
.saveips = &saveips, .saveips = ipporthash_saveips,
/* Bindings */ .usage = ipporthash_usage,
.bindip_tostring = &unpack_ipport_tostring,
.bindip_parse = &parse_ip,
.usage = &usage,
}; };
CONSTRUCTOR(ipporthash) CONSTRUCTOR(ipporthash)

View File

@@ -32,7 +32,7 @@
/* Initialize the create. */ /* Initialize the create. */
static void static void
create_init(void *data) ipportiphash_create_init(void *data)
{ {
struct ip_set_req_ipportiphash_create *mydata = data; struct ip_set_req_ipportiphash_create *mydata = data;
@@ -46,7 +46,8 @@ create_init(void *data)
/* Function which parses command options; returns true if it ate an option */ /* Function which parses command options; returns true if it ate an option */
static int static int
create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags) ipportiphash_create_parse(int c, char *argv[] UNUSED, void *data,
unsigned *flags)
{ {
struct ip_set_req_ipportiphash_create *mydata = data; struct ip_set_req_ipportiphash_create *mydata = data;
ip_set_ip_t value; ip_set_ip_t value;
@@ -137,7 +138,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
/* Final check; exit if not ok. */ /* Final check; exit if not ok. */
static void static void
create_final(void *data, unsigned int flags) ipportiphash_create_final(void *data, unsigned int flags)
{ {
struct ip_set_req_ipportiphash_create *mydata = data; struct ip_set_req_ipportiphash_create *mydata = data;
@@ -189,7 +190,7 @@ static const struct option create_opts[] = {
/* Add, del, test parser */ /* Add, del, test parser */
static ip_set_ip_t static ip_set_ip_t
adt_parser(int cmd UNUSED, const char *arg, void *data) ipportiphash_adt_parser(int cmd UNUSED, const char *arg, void *data)
{ {
struct ip_set_req_ipportiphash *mydata = data; struct ip_set_req_ipportiphash *mydata = data;
char *saved = ipset_strdup(arg); char *saved = ipset_strdup(arg);
@@ -227,7 +228,7 @@ adt_parser(int cmd UNUSED, const char *arg, void *data)
*/ */
static void static void
initheader(struct set *set, const void *data) ipportiphash_initheader(struct set *set, const void *data)
{ {
const struct ip_set_req_ipportiphash_create *header = data; const struct ip_set_req_ipportiphash_create *header = data;
struct ip_set_ipportiphash *map = set->settype->header; struct ip_set_ipportiphash *map = set->settype->header;
@@ -241,7 +242,7 @@ initheader(struct set *set, const void *data)
} }
static void static void
printheader(struct set *set, unsigned options) ipportiphash_printheader(struct set *set, unsigned options)
{ {
struct ip_set_ipportiphash *mysetdata = set->settype->header; struct ip_set_ipportiphash *mysetdata = set->settype->header;
@@ -253,7 +254,8 @@ printheader(struct set *set, unsigned options)
} }
static void static void
printips(struct set *set, void *data, u_int32_t len, unsigned options) ipportiphash_printips(struct set *set, void *data, u_int32_t len,
unsigned options, char dont_align)
{ {
struct ip_set_ipportiphash *mysetdata = set->settype->header; struct ip_set_ipportiphash *mysetdata = set->settype->header;
size_t offset = 0; size_t offset = 0;
@@ -272,12 +274,12 @@ printips(struct set *set, void *data, u_int32_t len, unsigned options)
printf("%s\n", printf("%s\n",
ip_tostring(ipptr->ip1, options)); ip_tostring(ipptr->ip1, options));
} }
offset += sizeof(struct ipportip); offset += IPSET_VALIGN(sizeof(struct ipportip), dont_align);
} }
} }
static void static void
saveheader(struct set *set, unsigned options) ipportiphash_saveheader(struct set *set, unsigned options)
{ {
struct ip_set_ipportiphash *mysetdata = set->settype->header; struct ip_set_ipportiphash *mysetdata = set->settype->header;
@@ -292,7 +294,8 @@ saveheader(struct set *set, unsigned options)
/* Print save for an IP */ /* Print save for an IP */
static void static void
saveips(struct set *set, void *data, u_int32_t len, unsigned options) ipportiphash_saveips(struct set *set, void *data, u_int32_t len,
unsigned options, char dont_align)
{ {
struct ip_set_ipportiphash *mysetdata = set->settype->header; struct ip_set_ipportiphash *mysetdata = set->settype->header;
size_t offset = 0; size_t offset = 0;
@@ -311,11 +314,12 @@ saveips(struct set *set, void *data, u_int32_t len, unsigned options)
printf("%s\n", printf("%s\n",
ip_tostring(ipptr->ip1, options)); ip_tostring(ipptr->ip1, options));
} }
offset += sizeof(struct ipportip); offset += IPSET_VALIGN(sizeof(struct ipportip), dont_align);
} }
} }
static void usage(void) static void
ipportiphash_usage(void)
{ {
printf printf
("-N set ipportiphash --from IP --to IP\n" ("-N set ipportiphash --from IP --to IP\n"
@@ -333,25 +337,25 @@ static struct settype settype_ipportiphash = {
/* Create */ /* Create */
.create_size = sizeof(struct ip_set_req_ipportiphash_create), .create_size = sizeof(struct ip_set_req_ipportiphash_create),
.create_init = &create_init, .create_init = ipportiphash_create_init,
.create_parse = &create_parse, .create_parse = ipportiphash_create_parse,
.create_final = &create_final, .create_final = ipportiphash_create_final,
.create_opts = create_opts, .create_opts = create_opts,
/* Add/del/test */ /* Add/del/test */
.adt_size = sizeof(struct ip_set_req_ipportiphash), .adt_size = sizeof(struct ip_set_req_ipportiphash),
.adt_parser = &adt_parser, .adt_parser = ipportiphash_adt_parser,
/* Printing */ /* Printing */
.header_size = sizeof(struct ip_set_ipportiphash), .header_size = sizeof(struct ip_set_ipportiphash),
.initheader = &initheader, .initheader = ipportiphash_initheader,
.printheader = &printheader, .printheader = ipportiphash_printheader,
.printips = &printips, /* We only have the unsorted version */ .printips = ipportiphash_printips,
.printips_sorted = &printips, .printips_sorted = ipportiphash_printips,
.saveheader = &saveheader, .saveheader = ipportiphash_saveheader,
.saveips = &saveips, .saveips = ipportiphash_saveips,
.usage = &usage, .usage = ipportiphash_usage,
}; };
CONSTRUCTOR(ipportiphash) CONSTRUCTOR(ipportiphash)

View File

@@ -32,7 +32,7 @@
/* Initialize the create. */ /* Initialize the create. */
static void static void
create_init(void *data) ipportnethash_create_init(void *data)
{ {
struct ip_set_req_ipportnethash_create *mydata = data; struct ip_set_req_ipportnethash_create *mydata = data;
@@ -46,7 +46,8 @@ create_init(void *data)
/* Function which parses command options; returns true if it ate an option */ /* Function which parses command options; returns true if it ate an option */
static int static int
create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags) ipportnethash_create_parse(int c, char *argv[] UNUSED, void *data,
unsigned *flags)
{ {
struct ip_set_req_ipportnethash_create *mydata = data; struct ip_set_req_ipportnethash_create *mydata = data;
ip_set_ip_t value; ip_set_ip_t value;
@@ -137,7 +138,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
/* Final check; exit if not ok. */ /* Final check; exit if not ok. */
static void static void
create_final(void *data, unsigned int flags) ipportnethash_create_final(void *data, unsigned int flags)
{ {
struct ip_set_req_ipportnethash_create *mydata = data; struct ip_set_req_ipportnethash_create *mydata = data;
@@ -189,7 +190,7 @@ static const struct option create_opts[] = {
/* Add, del, test parser */ /* Add, del, test parser */
static ip_set_ip_t static ip_set_ip_t
adt_parser(int cmd, const char *arg, void *data) ipportnethash_adt_parser(int cmd, const char *arg, void *data)
{ {
struct ip_set_req_ipportnethash *mydata = data; struct ip_set_req_ipportnethash *mydata = data;
char *saved = ipset_strdup(arg); char *saved = ipset_strdup(arg);
@@ -238,7 +239,7 @@ adt_parser(int cmd, const char *arg, void *data)
*/ */
static void static void
initheader(struct set *set, const void *data) ipportnethash_initheader(struct set *set, const void *data)
{ {
const struct ip_set_req_ipportnethash_create *header = data; const struct ip_set_req_ipportnethash_create *header = data;
struct ip_set_ipportnethash *map = set->settype->header; struct ip_set_ipportnethash *map = set->settype->header;
@@ -252,7 +253,7 @@ initheader(struct set *set, const void *data)
} }
static void static void
printheader(struct set *set, unsigned options) ipportnethash_printheader(struct set *set, unsigned options)
{ {
struct ip_set_ipportnethash *mysetdata = set->settype->header; struct ip_set_ipportnethash *mysetdata = set->settype->header;
@@ -318,7 +319,8 @@ unpack_ip_tostring(ip_set_ip_t ip, unsigned options UNUSED)
} }
static void static void
printips(struct set *set, void *data, u_int32_t len, unsigned options) ipportnethash_printips(struct set *set, void *data, u_int32_t len,
unsigned options, char dont_align)
{ {
struct ip_set_ipportnethash *mysetdata = set->settype->header; struct ip_set_ipportnethash *mysetdata = set->settype->header;
size_t offset = 0; size_t offset = 0;
@@ -337,12 +339,12 @@ printips(struct set *set, void *data, u_int32_t len, unsigned options)
printf("%s\n", printf("%s\n",
unpack_ip_tostring(ipptr->ip1, options)); unpack_ip_tostring(ipptr->ip1, options));
} }
offset += sizeof(struct ipportip); offset += IPSET_VALIGN(sizeof(struct ipportip), dont_align);
} }
} }
static void static void
saveheader(struct set *set, unsigned options) ipportnethash_saveheader(struct set *set, unsigned options)
{ {
struct ip_set_ipportnethash *mysetdata = set->settype->header; struct ip_set_ipportnethash *mysetdata = set->settype->header;
@@ -357,7 +359,8 @@ saveheader(struct set *set, unsigned options)
/* Print save for an IP */ /* Print save for an IP */
static void static void
saveips(struct set *set, void *data, u_int32_t len, unsigned options) ipportnethash_saveips(struct set *set, void *data, u_int32_t len,
unsigned options, char dont_align)
{ {
struct ip_set_ipportnethash *mysetdata = set->settype->header; struct ip_set_ipportnethash *mysetdata = set->settype->header;
size_t offset = 0; size_t offset = 0;
@@ -376,11 +379,12 @@ saveips(struct set *set, void *data, u_int32_t len, unsigned options)
printf("%s\n", printf("%s\n",
unpack_ip_tostring(ipptr->ip, options)); unpack_ip_tostring(ipptr->ip, options));
} }
offset += sizeof(struct ipportip); offset += IPSET_VALIGN(sizeof(struct ipportip), dont_align);
} }
} }
static void usage(void) static void
ipportnethash_usage(void)
{ {
printf printf
("-N set ipportnethash --from IP --to IP\n" ("-N set ipportnethash --from IP --to IP\n"
@@ -398,25 +402,25 @@ static struct settype settype_ipportnethash = {
/* Create */ /* Create */
.create_size = sizeof(struct ip_set_req_ipportnethash_create), .create_size = sizeof(struct ip_set_req_ipportnethash_create),
.create_init = &create_init, .create_init = ipportnethash_create_init,
.create_parse = &create_parse, .create_parse = ipportnethash_create_parse,
.create_final = &create_final, .create_final = ipportnethash_create_final,
.create_opts = create_opts, .create_opts = create_opts,
/* Add/del/test */ /* Add/del/test */
.adt_size = sizeof(struct ip_set_req_ipportnethash), .adt_size = sizeof(struct ip_set_req_ipportnethash),
.adt_parser = &adt_parser, .adt_parser = ipportnethash_adt_parser,
/* Printing */ /* Printing */
.header_size = sizeof(struct ip_set_ipportnethash), .header_size = sizeof(struct ip_set_ipportnethash),
.initheader = &initheader, .initheader = ipportnethash_initheader,
.printheader = &printheader, .printheader = ipportnethash_printheader,
.printips = &printips, /* We only have the unsorted version */ .printips = ipportnethash_printips,
.printips_sorted = &printips, .printips_sorted = ipportnethash_printips,
.saveheader = &saveheader, .saveheader = ipportnethash_saveheader,
.saveips = &saveips, .saveips = ipportnethash_saveips,
.usage = &usage, .usage = ipportnethash_usage,
}; };
CONSTRUCTOR(ipportnethash) CONSTRUCTOR(ipportnethash)

View File

@@ -29,7 +29,7 @@
/* Initialize the create. */ /* Initialize the create. */
static void static void
create_init(void *data) iptree_create_init(void *data)
{ {
struct ip_set_req_iptree_create *mydata = data; struct ip_set_req_iptree_create *mydata = data;
@@ -39,7 +39,7 @@ create_init(void *data)
/* Function which parses command options; returns true if it ate an option */ /* Function which parses command options; returns true if it ate an option */
static int static int
create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags) iptree_create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
{ {
struct ip_set_req_iptree_create *mydata = data; struct ip_set_req_iptree_create *mydata = data;
@@ -63,7 +63,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
/* Final check; exit if not ok. */ /* Final check; exit if not ok. */
static void static void
create_final(void *data UNUSED, unsigned int flags UNUSED) iptree_create_final(void *data UNUSED, unsigned int flags UNUSED)
{ {
} }
@@ -75,7 +75,7 @@ static const struct option create_opts[] = {
/* Add, del, test parser */ /* Add, del, test parser */
static ip_set_ip_t static ip_set_ip_t
adt_parser(int cmd UNUSED, const char *arg, void *data) iptree_adt_parser(int cmd UNUSED, const char *arg, void *data)
{ {
struct ip_set_req_iptree *mydata = data; struct ip_set_req_iptree *mydata = data;
char *saved = ipset_strdup(arg); char *saved = ipset_strdup(arg);
@@ -104,7 +104,7 @@ adt_parser(int cmd UNUSED, const char *arg, void *data)
*/ */
static void static void
initheader(struct set *set, const void *data) iptree_initheader(struct set *set, const void *data)
{ {
const struct ip_set_req_iptree_create *header = data; const struct ip_set_req_iptree_create *header = data;
struct ip_set_iptree *map = set->settype->header; struct ip_set_iptree *map = set->settype->header;
@@ -113,7 +113,7 @@ initheader(struct set *set, const void *data)
} }
static void static void
printheader(struct set *set, unsigned options UNUSED) iptree_printheader(struct set *set, unsigned options UNUSED)
{ {
struct ip_set_iptree *mysetdata = set->settype->header; struct ip_set_iptree *mysetdata = set->settype->header;
@@ -123,7 +123,8 @@ printheader(struct set *set, unsigned options UNUSED)
} }
static void static void
printips_sorted(struct set *set, void *data, u_int32_t len, unsigned options) iptree_printips_sorted(struct set *set, void *data, u_int32_t len,
unsigned options, char dont_align)
{ {
struct ip_set_iptree *mysetdata = set->settype->header; struct ip_set_iptree *mysetdata = set->settype->header;
struct ip_set_req_iptree *req; struct ip_set_req_iptree *req;
@@ -136,12 +137,12 @@ printips_sorted(struct set *set, void *data, u_int32_t len, unsigned options)
req->timeout); req->timeout);
else else
printf("%s\n", ip_tostring(req->ip, options)); printf("%s\n", ip_tostring(req->ip, options));
offset += sizeof(struct ip_set_req_iptree); offset += IPSET_VALIGN(sizeof(struct ip_set_req_iptree), dont_align);
} }
} }
static void static void
saveheader(struct set *set, unsigned options UNUSED) iptree_saveheader(struct set *set, unsigned options UNUSED)
{ {
struct ip_set_iptree *mysetdata = set->settype->header; struct ip_set_iptree *mysetdata = set->settype->header;
@@ -155,7 +156,8 @@ saveheader(struct set *set, unsigned options UNUSED)
} }
static void static void
saveips(struct set *set, void *data, u_int32_t len, unsigned options) iptree_saveips(struct set *set, void *data, u_int32_t len,
unsigned options, char dont_align)
{ {
struct ip_set_iptree *mysetdata = set->settype->header; struct ip_set_iptree *mysetdata = set->settype->header;
struct ip_set_req_iptree *req; struct ip_set_req_iptree *req;
@@ -174,11 +176,12 @@ saveips(struct set *set, void *data, u_int32_t len, unsigned options)
printf("-A %s %s\n", printf("-A %s %s\n",
set->name, set->name,
ip_tostring(req->ip, options)); ip_tostring(req->ip, options));
offset += sizeof(struct ip_set_req_iptree); offset += IPSET_VALIGN(sizeof(struct ip_set_req_iptree), dont_align);
} }
} }
static void usage(void) static void
iptree_usage(void)
{ {
printf printf
("-N set iptree [--timeout value]\n" ("-N set iptree [--timeout value]\n"
@@ -193,29 +196,25 @@ static struct settype settype_iptree = {
/* Create */ /* Create */
.create_size = sizeof(struct ip_set_req_iptree_create), .create_size = sizeof(struct ip_set_req_iptree_create),
.create_init = &create_init, .create_init = iptree_create_init,
.create_parse = &create_parse, .create_parse = iptree_create_parse,
.create_final = &create_final, .create_final = iptree_create_final,
.create_opts = create_opts, .create_opts = create_opts,
/* Add/del/test */ /* Add/del/test */
.adt_size = sizeof(struct ip_set_req_iptree), .adt_size = sizeof(struct ip_set_req_iptree),
.adt_parser = &adt_parser, .adt_parser = iptree_adt_parser,
/* Printing */ /* Printing */
.header_size = sizeof(struct ip_set_iptree), .header_size = sizeof(struct ip_set_iptree),
.initheader = &initheader, .initheader = iptree_initheader,
.printheader = &printheader, .printheader = iptree_printheader,
.printips = &printips_sorted, /* We only have sorted version */ .printips = iptree_printips_sorted, /* We only have sorted version */
.printips_sorted = &printips_sorted, .printips_sorted = iptree_printips_sorted,
.saveheader = &saveheader, .saveheader = iptree_saveheader,
.saveips = &saveips, .saveips = iptree_saveips,
/* Bindings */ .usage = iptree_usage,
.bindip_tostring = &binding_ip_tostring,
.bindip_parse = &parse_ip,
.usage = &usage,
}; };
CONSTRUCTOR(iptree) CONSTRUCTOR(iptree)

View File

@@ -26,7 +26,7 @@
#define OPT_CREATE_GC 0x1 #define OPT_CREATE_GC 0x1
static void static void
create_init(void *data) iptreemap_create_init(void *data)
{ {
struct ip_set_req_iptreemap_create *mydata = data; struct ip_set_req_iptreemap_create *mydata = data;
@@ -34,7 +34,8 @@ create_init(void *data)
} }
static int static int
create_parse(int c, char *argv[] UNUSED, void *data, unsigned int *flags) iptreemap_create_parse(int c, char *argv[] UNUSED, void *data,
unsigned int *flags)
{ {
struct ip_set_req_iptreemap_create *mydata = data; struct ip_set_req_iptreemap_create *mydata = data;
@@ -53,7 +54,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned int *flags)
} }
static void static void
create_final(void *data UNUSED, unsigned int flags UNUSED) iptreemap_create_final(void *data UNUSED, unsigned int flags UNUSED)
{ {
} }
@@ -63,7 +64,7 @@ static const struct option create_opts[] = {
}; };
static ip_set_ip_t static ip_set_ip_t
adt_parser(int cmd UNUSED, const char *arg, void *data) iptreemap_adt_parser(int cmd UNUSED, const char *arg, void *data)
{ {
struct ip_set_req_iptreemap *mydata = data; struct ip_set_req_iptreemap *mydata = data;
ip_set_ip_t mask; ip_set_ip_t mask;
@@ -94,7 +95,7 @@ adt_parser(int cmd UNUSED, const char *arg, void *data)
} }
static void static void
initheader(struct set *set, const void *data) iptreemap_initheader(struct set *set, const void *data)
{ {
const struct ip_set_req_iptreemap_create *header = data; const struct ip_set_req_iptreemap_create *header = data;
struct ip_set_iptreemap *map = set->settype->header; struct ip_set_iptreemap *map = set->settype->header;
@@ -103,7 +104,7 @@ initheader(struct set *set, const void *data)
} }
static void static void
printheader(struct set *set, unsigned int options UNUSED) iptreemap_printheader(struct set *set, unsigned int options UNUSED)
{ {
struct ip_set_iptreemap *mysetdata = set->settype->header; struct ip_set_iptreemap *mysetdata = set->settype->header;
@@ -114,8 +115,8 @@ printheader(struct set *set, unsigned int options UNUSED)
} }
static void static void
printips_sorted(struct set *set UNUSED, void *data, iptreemap_printips_sorted(struct set *set UNUSED, void *data,
u_int32_t len, unsigned int options) u_int32_t len, unsigned int options, char dont_align)
{ {
struct ip_set_req_iptreemap *req; struct ip_set_req_iptreemap *req;
size_t offset = 0; size_t offset = 0;
@@ -128,12 +129,12 @@ printips_sorted(struct set *set UNUSED, void *data,
printf("-%s", ip_tostring(req->end, options)); printf("-%s", ip_tostring(req->end, options));
printf("\n"); printf("\n");
offset += sizeof(struct ip_set_req_iptreemap); offset += IPSET_VALIGN(sizeof(struct ip_set_req_iptreemap), dont_align);
} }
} }
static void static void
saveheader(struct set *set, unsigned int options UNUSED) iptreemap_saveheader(struct set *set, unsigned int options UNUSED)
{ {
struct ip_set_iptreemap *mysetdata = set->settype->header; struct ip_set_iptreemap *mysetdata = set->settype->header;
@@ -146,8 +147,8 @@ saveheader(struct set *set, unsigned int options UNUSED)
} }
static void static void
saveips(struct set *set UNUSED, void *data, iptreemap_saveips(struct set *set UNUSED, void *data,
u_int32_t len, unsigned int options) u_int32_t len, unsigned int options, char dont_align)
{ {
struct ip_set_req_iptreemap *req; struct ip_set_req_iptreemap *req;
size_t offset = 0; size_t offset = 0;
@@ -162,12 +163,12 @@ saveips(struct set *set UNUSED, void *data,
printf("\n"); printf("\n");
offset += sizeof(struct ip_set_req_iptreemap); offset += IPSET_VALIGN(sizeof(struct ip_set_req_iptreemap), dont_align);
} }
} }
static void static void
usage(void) iptreemap_usage(void)
{ {
printf( printf(
"-N set iptreemap --gc interval\n" "-N set iptreemap --gc interval\n"
@@ -182,26 +183,23 @@ static struct settype settype_iptreemap = {
.protocol_version = IP_SET_PROTOCOL_VERSION, .protocol_version = IP_SET_PROTOCOL_VERSION,
.create_size = sizeof(struct ip_set_req_iptreemap_create), .create_size = sizeof(struct ip_set_req_iptreemap_create),
.create_init = &create_init, .create_init = iptreemap_create_init,
.create_parse = &create_parse, .create_parse = iptreemap_create_parse,
.create_final = &create_final, .create_final = iptreemap_create_final,
.create_opts = create_opts, .create_opts = create_opts,
.adt_size = sizeof(struct ip_set_req_iptreemap), .adt_size = sizeof(struct ip_set_req_iptreemap),
.adt_parser = &adt_parser, .adt_parser = iptreemap_adt_parser,
.header_size = sizeof(struct ip_set_iptreemap), .header_size = sizeof(struct ip_set_iptreemap),
.initheader = &initheader, .initheader = iptreemap_initheader,
.printheader = &printheader, .printheader = iptreemap_printheader,
.printips = &printips_sorted, .printips = iptreemap_printips_sorted,
.printips_sorted = &printips_sorted, .printips_sorted = iptreemap_printips_sorted,
.saveheader = &saveheader, .saveheader = iptreemap_saveheader,
.saveips = &saveips, .saveips = iptreemap_saveips,
.bindip_tostring = &binding_ip_tostring, .usage = iptreemap_usage,
.bindip_parse = &parse_ip,
.usage = &usage,
}; };
CONSTRUCTOR(iptreemap) CONSTRUCTOR(iptreemap)

View File

@@ -39,7 +39,7 @@
/* Initialize the create. */ /* Initialize the create. */
static void static void
create_init(void *data UNUSED) macipmap_create_init(void *data UNUSED)
{ {
DP("create INIT"); DP("create INIT");
/* Nothing */ /* Nothing */
@@ -47,7 +47,7 @@ create_init(void *data UNUSED)
/* Function which parses command options; returns true if it ate an option */ /* Function which parses command options; returns true if it ate an option */
static int static int
create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags) macipmap_create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
{ {
struct ip_set_req_macipmap_create *mydata = data; struct ip_set_req_macipmap_create *mydata = data;
@@ -107,7 +107,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
/* Final check; exit if not ok. */ /* Final check; exit if not ok. */
static void static void
create_final(void *data, unsigned int flags) macipmap_create_final(void *data, unsigned int flags)
{ {
struct ip_set_req_macipmap_create *mydata = data; struct ip_set_req_macipmap_create *mydata = data;
@@ -176,7 +176,7 @@ parse_mac(const char *mac, unsigned char *ethernet)
/* Add, del, test parser */ /* Add, del, test parser */
static ip_set_ip_t static ip_set_ip_t
adt_parser(int cmd UNUSED, const char *arg, void *data) macipmap_adt_parser(int cmd UNUSED, const char *arg, void *data)
{ {
struct ip_set_req_macipmap *mydata = data; struct ip_set_req_macipmap *mydata = data;
char *saved = ipset_strdup(arg); char *saved = ipset_strdup(arg);
@@ -209,7 +209,7 @@ adt_parser(int cmd UNUSED, const char *arg, void *data)
*/ */
static void static void
initheader(struct set *set, const void *data) macipmap_initheader(struct set *set, const void *data)
{ {
const struct ip_set_req_macipmap_create *header = data; const struct ip_set_req_macipmap_create *header = data;
struct ip_set_macipmap *map = set->settype->header; struct ip_set_macipmap *map = set->settype->header;
@@ -221,7 +221,7 @@ initheader(struct set *set, const void *data)
} }
static void static void
printheader(struct set *set, unsigned options) macipmap_printheader(struct set *set, unsigned options)
{ {
struct ip_set_macipmap *mysetdata = set->settype->header; struct ip_set_macipmap *mysetdata = set->settype->header;
@@ -243,9 +243,9 @@ print_mac(unsigned char macaddress[ETH_ALEN])
printf(":%02X", macaddress[i]); printf(":%02X", macaddress[i]);
} }
static void static inline void
printips_sorted(struct set *set, void *data, __macipmap_printips_sorted(struct set *set, void *data,
u_int32_t len UNUSED, unsigned options) u_int32_t len UNUSED, unsigned options)
{ {
struct ip_set_macipmap *mysetdata = set->settype->header; struct ip_set_macipmap *mysetdata = set->settype->header;
struct ip_set_macip *table = data; struct ip_set_macip *table = data;
@@ -263,7 +263,27 @@ printips_sorted(struct set *set, void *data,
} }
static void static void
saveheader(struct set *set, unsigned options) macipmap_printips_sorted(struct set *set, void *data,
u_int32_t len, unsigned options,
char dont_align)
{
struct ip_set_req_macipmap *d;
size_t offset = 0;
if (dont_align)
return __macipmap_printips_sorted(set, data, len, options);
while (offset < len) {
d = data + offset;
printf("%s,", ip_tostring(d->ip, options));
print_mac(d->ethernet);
printf("\n");
offset += IPSET_ALIGN(sizeof(struct ip_set_req_macipmap));
}
}
static void
macipmap_saveheader(struct set *set, unsigned options)
{ {
struct ip_set_macipmap *mysetdata = set->settype->header; struct ip_set_macipmap *mysetdata = set->settype->header;
@@ -277,9 +297,9 @@ saveheader(struct set *set, unsigned options)
printf("\n"); printf("\n");
} }
static void static inline void
saveips(struct set *set, void *data, __macipmap_saveips(struct set *set, void *data,
u_int32_t len UNUSED, unsigned options) u_int32_t len UNUSED, unsigned options)
{ {
struct ip_set_macipmap *mysetdata = set->settype->header; struct ip_set_macipmap *mysetdata = set->settype->header;
struct ip_set_macip *table = data; struct ip_set_macip *table = data;
@@ -297,7 +317,28 @@ saveips(struct set *set, void *data,
} }
} }
static void usage(void) static void
macipmap_saveips(struct set *set, void *data,
u_int32_t len, unsigned options,
char dont_align)
{
struct ip_set_req_macipmap *d;
size_t offset = 0;
if (dont_align)
return __macipmap_saveips(set, data, len, options);
while (offset < len) {
d = data + offset;
printf("-A %s %s,", set->name, ip_tostring(d->ip, options));
print_mac(d->ethernet);
printf("\n");
offset += IPSET_ALIGN(sizeof(struct ip_set_req_macipmap));
}
}
static void
macipmap_usage(void)
{ {
printf printf
("-N set macipmap --from IP --to IP [--matchunset]\n" ("-N set macipmap --from IP --to IP [--matchunset]\n"
@@ -313,29 +354,25 @@ static struct settype settype_macipmap = {
/* Create */ /* Create */
.create_size = sizeof(struct ip_set_req_macipmap_create), .create_size = sizeof(struct ip_set_req_macipmap_create),
.create_init = &create_init, .create_init = macipmap_create_init,
.create_parse = &create_parse, .create_parse = macipmap_create_parse,
.create_final = &create_final, .create_final = macipmap_create_final,
.create_opts = create_opts, .create_opts = create_opts,
/* Add/del/test */ /* Add/del/test */
.adt_size = sizeof(struct ip_set_req_macipmap), .adt_size = sizeof(struct ip_set_req_macipmap),
.adt_parser = &adt_parser, .adt_parser = macipmap_adt_parser,
/* Printing */ /* Printing */
.header_size = sizeof(struct ip_set_macipmap), .header_size = sizeof(struct ip_set_macipmap),
.initheader = &initheader, .initheader = macipmap_initheader,
.printheader = &printheader, .printheader = macipmap_printheader,
.printips = &printips_sorted, /* We only have sorted version */ .printips = macipmap_printips_sorted,
.printips_sorted = &printips_sorted, .printips_sorted = macipmap_printips_sorted,
.saveheader = &saveheader, .saveheader = macipmap_saveheader,
.saveips = &saveips, .saveips = macipmap_saveips,
/* Bindings */ .usage = macipmap_usage,
.bindip_tostring = &binding_ip_tostring,
.bindip_parse = &parse_ip,
.usage = &usage,
}; };
CONSTRUCTOR(macipmap) CONSTRUCTOR(macipmap)

View File

@@ -31,7 +31,7 @@
/* Initialize the create. */ /* Initialize the create. */
static void static void
create_init(void *data) nethash_create_init(void *data)
{ {
struct ip_set_req_nethash_create *mydata = data; struct ip_set_req_nethash_create *mydata = data;
@@ -45,7 +45,7 @@ create_init(void *data)
/* Function which parses command options; returns true if it ate an option */ /* Function which parses command options; returns true if it ate an option */
static int static int
create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags) nethash_create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
{ {
struct ip_set_req_nethash_create *mydata = data; struct ip_set_req_nethash_create *mydata = data;
ip_set_ip_t value; ip_set_ip_t value;
@@ -97,7 +97,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
/* Final check; exit if not ok. */ /* Final check; exit if not ok. */
static void static void
create_final(void *data UNUSED, unsigned int flags UNUSED) nethash_create_final(void *data UNUSED, unsigned int flags UNUSED)
{ {
} }
@@ -111,7 +111,7 @@ static const struct option create_opts[] = {
/* Add, del, test parser */ /* Add, del, test parser */
static ip_set_ip_t static ip_set_ip_t
adt_parser(int cmd, const char *arg, void *data) nethash_adt_parser(int cmd, const char *arg, void *data)
{ {
struct ip_set_req_nethash *mydata = data; struct ip_set_req_nethash *mydata = data;
char *saved = ipset_strdup(arg); char *saved = ipset_strdup(arg);
@@ -148,7 +148,7 @@ adt_parser(int cmd, const char *arg, void *data)
*/ */
static void static void
initheader(struct set *set, const void *data) nethash_initheader(struct set *set, const void *data)
{ {
const struct ip_set_req_nethash_create *header = data; const struct ip_set_req_nethash_create *header = data;
struct ip_set_nethash *map = set->settype->header; struct ip_set_nethash *map = set->settype->header;
@@ -160,7 +160,7 @@ initheader(struct set *set, const void *data)
} }
static void static void
printheader(struct set *set, unsigned options UNUSED) nethash_printheader(struct set *set, unsigned options UNUSED)
{ {
struct ip_set_nethash *mysetdata = set->settype->header; struct ip_set_nethash *mysetdata = set->settype->header;
@@ -224,7 +224,8 @@ unpack_ip_tostring(ip_set_ip_t ip, unsigned options UNUSED)
} }
static void static void
printips(struct set *set UNUSED, void *data, u_int32_t len, unsigned options) nethash_printips(struct set *set UNUSED, void *data, u_int32_t len,
unsigned options, char dont_align)
{ {
size_t offset = 0; size_t offset = 0;
ip_set_ip_t *ip; ip_set_ip_t *ip;
@@ -233,12 +234,12 @@ printips(struct set *set UNUSED, void *data, u_int32_t len, unsigned options)
ip = data + offset; ip = data + offset;
if (*ip) if (*ip)
printf("%s\n", unpack_ip_tostring(*ip, options)); printf("%s\n", unpack_ip_tostring(*ip, options));
offset += sizeof(ip_set_ip_t); offset += IPSET_VALIGN(sizeof(ip_set_ip_t), dont_align);
} }
} }
static void static void
saveheader(struct set *set, unsigned options UNUSED) nethash_saveheader(struct set *set, unsigned options UNUSED)
{ {
struct ip_set_nethash *mysetdata = set->settype->header; struct ip_set_nethash *mysetdata = set->settype->header;
@@ -249,7 +250,8 @@ saveheader(struct set *set, unsigned options UNUSED)
/* Print save for an IP */ /* Print save for an IP */
static void static void
saveips(struct set *set UNUSED, void *data, u_int32_t len, unsigned options) nethash_saveips(struct set *set UNUSED, void *data, u_int32_t len,
unsigned options, char dont_align)
{ {
size_t offset = 0; size_t offset = 0;
ip_set_ip_t *ip; ip_set_ip_t *ip;
@@ -259,40 +261,12 @@ saveips(struct set *set UNUSED, void *data, u_int32_t len, unsigned options)
if (*ip) if (*ip)
printf("-A %s %s\n", set->name, printf("-A %s %s\n", set->name,
unpack_ip_tostring(*ip, options)); unpack_ip_tostring(*ip, options));
offset += sizeof(ip_set_ip_t); offset += IPSET_VALIGN(sizeof(ip_set_ip_t), dont_align);
} }
} }
static char *
net_tostring(struct set *set UNUSED, ip_set_ip_t ip, unsigned options)
{
return unpack_ip_tostring(ip, options);
}
static void static void
parse_net(const char *str, ip_set_ip_t *ip) nethash_usage(void)
{
char *saved = ipset_strdup(str);
char *ptr, *tmp = saved;
ip_set_ip_t cidr;
ptr = strsep(&tmp, "/");
if (tmp == NULL)
exit_error(PARAMETER_PROBLEM,
"Missing cidr from `%s'", str);
if (string_to_number(tmp, 1, 31, &cidr))
exit_error(PARAMETER_PROBLEM,
"Out of range cidr `%s' specified", str);
parse_ip(ptr, ip);
ipset_free(saved);
*ip = pack_ip_cidr(*ip, cidr);
}
static void usage(void)
{ {
printf printf
("-N set nethash [--hashsize hashsize] [--probes probes ]\n" ("-N set nethash [--hashsize hashsize] [--probes probes ]\n"
@@ -308,29 +282,25 @@ static struct settype settype_nethash = {
/* Create */ /* Create */
.create_size = sizeof(struct ip_set_req_nethash_create), .create_size = sizeof(struct ip_set_req_nethash_create),
.create_init = &create_init, .create_init = nethash_create_init,
.create_parse = &create_parse, .create_parse = nethash_create_parse,
.create_final = &create_final, .create_final = nethash_create_final,
.create_opts = create_opts, .create_opts = create_opts,
/* Add/del/test */ /* Add/del/test */
.adt_size = sizeof(struct ip_set_req_nethash), .adt_size = sizeof(struct ip_set_req_nethash),
.adt_parser = &adt_parser, .adt_parser = nethash_adt_parser,
/* Printing */ /* Printing */
.header_size = sizeof(struct ip_set_nethash), .header_size = sizeof(struct ip_set_nethash),
.initheader = &initheader, .initheader = nethash_initheader,
.printheader = &printheader, .printheader = nethash_printheader,
.printips = &printips, /* We only have the unsorted version */ .printips = nethash_printips,
.printips_sorted = &printips, .printips_sorted = nethash_printips,
.saveheader = &saveheader, .saveheader = nethash_saveheader,
.saveips = &saveips, .saveips = nethash_saveips,
/* Bindings */ .usage = nethash_usage,
.bindip_tostring = &net_tostring,
.bindip_parse = &parse_net,
.usage = &usage,
}; };
CONSTRUCTOR(nethash) CONSTRUCTOR(nethash)

View File

@@ -32,7 +32,7 @@
/* Initialize the create. */ /* Initialize the create. */
static void static void
create_init(void *data UNUSED) portmap_create_init(void *data UNUSED)
{ {
DP("create INIT"); DP("create INIT");
/* Nothing */ /* Nothing */
@@ -40,7 +40,7 @@ create_init(void *data UNUSED)
/* Function which parses command options; returns true if it ate an option */ /* Function which parses command options; returns true if it ate an option */
static int static int
create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags) portmap_create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
{ {
struct ip_set_req_portmap_create *mydata = data; struct ip_set_req_portmap_create *mydata = data;
@@ -76,7 +76,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags)
/* Final check; exit if not ok. */ /* Final check; exit if not ok. */
static void static void
create_final(void *data, unsigned int flags) portmap_create_final(void *data, unsigned int flags)
{ {
struct ip_set_req_portmap_create *mydata = data; struct ip_set_req_portmap_create *mydata = data;
@@ -113,7 +113,7 @@ static const struct option create_opts[] = {
/* Add, del, test parser */ /* Add, del, test parser */
static ip_set_ip_t static ip_set_ip_t
adt_parser(int cmd UNUSED, const char *arg, void *data) portmap_adt_parser(int cmd UNUSED, const char *arg, void *data)
{ {
struct ip_set_req_portmap *mydata = data; struct ip_set_req_portmap *mydata = data;
@@ -128,7 +128,7 @@ adt_parser(int cmd UNUSED, const char *arg, void *data)
*/ */
static void static void
initheader(struct set *set, const void *data) portmap_initheader(struct set *set, const void *data)
{ {
const struct ip_set_req_portmap_create *header = data; const struct ip_set_req_portmap_create *header = data;
struct ip_set_portmap *map = set->settype->header; struct ip_set_portmap *map = set->settype->header;
@@ -139,7 +139,7 @@ initheader(struct set *set, const void *data)
} }
static void static void
printheader(struct set *set, unsigned options) portmap_printheader(struct set *set, unsigned options)
{ {
struct ip_set_portmap *mysetdata = set->settype->header; struct ip_set_portmap *mysetdata = set->settype->header;
@@ -147,12 +147,12 @@ printheader(struct set *set, unsigned options)
printf(" to: %s\n", port_tostring(mysetdata->last_ip, options)); printf(" to: %s\n", port_tostring(mysetdata->last_ip, options));
} }
static void static inline void
printports_sorted(struct set *set, void *data, __portmap_printips_sorted(struct set *set, void *data,
u_int32_t len UNUSED, unsigned options) u_int32_t len UNUSED, unsigned options)
{ {
struct ip_set_portmap *mysetdata = set->settype->header; struct ip_set_portmap *mysetdata = set->settype->header;
u_int32_t addr = mysetdata->first_ip; ip_set_ip_t addr = mysetdata->first_ip;
DP("%u -- %u", mysetdata->first_ip, mysetdata->last_ip); DP("%u -- %u", mysetdata->first_ip, mysetdata->last_ip);
while (addr <= mysetdata->last_ip) { while (addr <= mysetdata->last_ip) {
@@ -162,15 +162,26 @@ printports_sorted(struct set *set, void *data,
} }
} }
static char * static void
binding_port_tostring(struct set *set UNUSED, portmap_printips_sorted(struct set *set, void *data,
ip_set_ip_t ip, unsigned options) u_int32_t len, unsigned options,
char dont_align)
{ {
return port_tostring(ip, options); ip_set_ip_t *ip;
size_t offset = 0;
if (dont_align)
return __portmap_printips_sorted(set, data, len, options);
while (offset < len) {
ip = data + offset;
printf("%s\n", port_tostring(*ip, options));
offset += IPSET_ALIGN(sizeof(ip_set_ip_t));
}
} }
static void static void
saveheader(struct set *set, unsigned options) portmap_saveheader(struct set *set, unsigned options)
{ {
struct ip_set_portmap *mysetdata = set->settype->header; struct ip_set_portmap *mysetdata = set->settype->header;
@@ -182,14 +193,15 @@ saveheader(struct set *set, unsigned options)
port_tostring(mysetdata->last_ip, options)); port_tostring(mysetdata->last_ip, options));
} }
static void static inline void
saveports(struct set *set, void *data, __portmap_saveips(struct set *set, void *data,
u_int32_t len UNUSED, unsigned options) u_int32_t len UNUSED, unsigned options)
{ {
struct ip_set_portmap *mysetdata = set->settype->header; struct ip_set_portmap *mysetdata = set->settype->header;
u_int32_t addr = mysetdata->first_ip; ip_set_ip_t addr = mysetdata->first_ip;
while (addr <= mysetdata->last_ip) { while (addr <= mysetdata->last_ip) {
DP("addr: %lu, last_ip %lu", (long unsigned)addr, (long unsigned)mysetdata->last_ip);
if (test_bit(addr - mysetdata->first_ip, data)) if (test_bit(addr - mysetdata->first_ip, data))
printf("-A %s %s\n", printf("-A %s %s\n",
set->name, set->name,
@@ -198,7 +210,26 @@ saveports(struct set *set, void *data,
} }
} }
static void usage(void) static void
portmap_saveips(struct set *set, void *data,
u_int32_t len, unsigned options,
char dont_align)
{
ip_set_ip_t *ip;
size_t offset = 0;
if (dont_align)
return __portmap_saveips(set, data, len, options);
while (offset < len) {
ip = data + offset;
printf("-A %s %s\n", set->name, port_tostring(*ip, options));
offset += IPSET_ALIGN(sizeof(ip_set_ip_t));
}
}
static void
portmap_usage(void)
{ {
printf printf
("-N set portmap --from PORT --to PORT\n" ("-N set portmap --from PORT --to PORT\n"
@@ -213,29 +244,25 @@ static struct settype settype_portmap = {
/* Create */ /* Create */
.create_size = sizeof(struct ip_set_req_portmap_create), .create_size = sizeof(struct ip_set_req_portmap_create),
.create_init = &create_init, .create_init = portmap_create_init,
.create_parse = &create_parse, .create_parse = portmap_create_parse,
.create_final = &create_final, .create_final = portmap_create_final,
.create_opts = create_opts, .create_opts = create_opts,
/* Add/del/test */ /* Add/del/test */
.adt_size = sizeof(struct ip_set_req_portmap), .adt_size = sizeof(struct ip_set_req_portmap),
.adt_parser = &adt_parser, .adt_parser = portmap_adt_parser,
/* Printing */ /* Printing */
.header_size = sizeof(struct ip_set_portmap), .header_size = sizeof(struct ip_set_portmap),
.initheader = &initheader, .initheader = portmap_initheader,
.printheader = &printheader, .printheader = portmap_printheader,
.printips = &printports_sorted, /* We only have sorted version */ .printips = portmap_printips_sorted,
.printips_sorted = &printports_sorted, .printips_sorted = portmap_printips_sorted,
.saveheader = &saveheader, .saveheader = portmap_saveheader,
.saveips = &saveports, .saveips = portmap_saveips,
/* Bindings */ .usage = portmap_usage,
.bindip_tostring = &binding_port_tostring,
.bindip_parse = &parse_port,
.usage = &usage,
}; };
CONSTRUCTOR(portmap) CONSTRUCTOR(portmap)

View File

@@ -27,7 +27,7 @@
/* Initialize the create. */ /* Initialize the create. */
static void static void
create_init(void *data) setlist_create_init(void *data)
{ {
struct ip_set_req_setlist_create *mydata = data; struct ip_set_req_setlist_create *mydata = data;
@@ -36,7 +36,8 @@ create_init(void *data)
/* Function which parses command options; returns true if it ate an option */ /* Function which parses command options; returns true if it ate an option */
static int static int
create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags UNUSED) setlist_create_parse(int c, char *argv[] UNUSED, void *data,
unsigned *flags UNUSED)
{ {
struct ip_set_req_setlist_create *mydata = data; struct ip_set_req_setlist_create *mydata = data;
unsigned int size; unsigned int size;
@@ -57,7 +58,7 @@ create_parse(int c, char *argv[] UNUSED, void *data, unsigned *flags UNUSED)
/* Final check; exit if not ok. */ /* Final check; exit if not ok. */
static void static void
create_final(void *data UNUSED, unsigned int flags UNUSED) setlist_create_final(void *data UNUSED, unsigned int flags UNUSED)
{ {
} }
@@ -67,7 +68,8 @@ static const struct option create_opts[] = {
{NULL}, {NULL},
}; };
static void check_setname(const char *name) static void
check_setname(const char *name)
{ {
if (strlen(name) > IP_SET_MAXNAMELEN - 1) if (strlen(name) > IP_SET_MAXNAMELEN - 1)
exit_error(PARAMETER_PROBLEM, exit_error(PARAMETER_PROBLEM,
@@ -77,7 +79,7 @@ static void check_setname(const char *name)
/* Add, del, test parser */ /* Add, del, test parser */
static ip_set_ip_t static ip_set_ip_t
adt_parser(int cmd UNUSED, const char *arg, void *data) setlist_adt_parser(int cmd UNUSED, const char *arg, void *data)
{ {
struct ip_set_req_setlist *mydata = data; struct ip_set_req_setlist *mydata = data;
char *saved = ipset_strdup(arg); char *saved = ipset_strdup(arg);
@@ -115,7 +117,7 @@ adt_parser(int cmd UNUSED, const char *arg, void *data)
*/ */
static void static void
initheader(struct set *set, const void *data) setlist_initheader(struct set *set, const void *data)
{ {
const struct ip_set_req_setlist_create *header = data; const struct ip_set_req_setlist_create *header = data;
struct ip_set_setlist *map = set->settype->header; struct ip_set_setlist *map = set->settype->header;
@@ -125,7 +127,7 @@ initheader(struct set *set, const void *data)
} }
static void static void
printheader(struct set *set, unsigned options UNUSED) setlist_printheader(struct set *set, unsigned options UNUSED)
{ {
struct ip_set_setlist *mysetdata = set->settype->header; struct ip_set_setlist *mysetdata = set->settype->header;
@@ -133,25 +135,29 @@ printheader(struct set *set, unsigned options UNUSED)
} }
static void static void
printips_sorted(struct set *set, void *data, setlist_printips_sorted(struct set *set, void *data,
u_int32_t len UNUSED, unsigned options UNUSED) u_int32_t len UNUSED, unsigned options UNUSED,
char dont_align)
{ {
struct ip_set_setlist *mysetdata = set->settype->header; struct ip_set_setlist *mysetdata = set->settype->header;
int i; int i, asize;
ip_set_id_t id; ip_set_id_t *id;
struct set *elem; struct set *elem;
asize = IPSET_VALIGN(sizeof(ip_set_id_t), dont_align);
for (i = 0; i < mysetdata->size; i++ ) { for (i = 0; i < mysetdata->size; i++ ) {
id = *((ip_set_id_t *)data + i); DP("Try %u", i);
if (id == IP_SET_INVALID_ID) id = (ip_set_id_t *)(data + i * asize);
DP("Try %u, check", i);
if (*id == IP_SET_INVALID_ID)
return; return;
elem = set_find_byid(id); elem = set_find_byid(*id);
printf("%s\n", elem->name); printf("%s\n", elem->name);
} }
} }
static void static void
saveheader(struct set *set, unsigned options UNUSED) setlist_saveheader(struct set *set, unsigned options UNUSED)
{ {
struct ip_set_setlist *mysetdata = set->settype->header; struct ip_set_setlist *mysetdata = set->settype->header;
@@ -161,24 +167,26 @@ saveheader(struct set *set, unsigned options UNUSED)
} }
static void static void
saveips(struct set *set, void *data, setlist_saveips(struct set *set, void *data,
u_int32_t len UNUSED, unsigned options UNUSED) u_int32_t len UNUSED, unsigned options UNUSED, char dont_align)
{ {
struct ip_set_setlist *mysetdata = set->settype->header; struct ip_set_setlist *mysetdata = set->settype->header;
int i; int i, asize;
ip_set_id_t id; ip_set_id_t *id;
struct set *elem; struct set *elem;
asize = IPSET_VALIGN(sizeof(ip_set_id_t), dont_align);
for (i = 0; i < mysetdata->size; i++ ) { for (i = 0; i < mysetdata->size; i++ ) {
id = *((ip_set_id_t *)data + i); id = (ip_set_id_t *)(data + i * asize);
if (id == IP_SET_INVALID_ID) if (*id == IP_SET_INVALID_ID)
return; return;
elem = set_find_byid(id); elem = set_find_byid(*id);
printf("-A %s %s\n", set->name, elem->name); printf("-A %s %s\n", set->name, elem->name);
} }
} }
static void usage(void) static void
setlist_usage(void)
{ {
printf printf
("-N set setlist --size size\n" ("-N set setlist --size size\n"
@@ -193,25 +201,25 @@ static struct settype settype_setlist = {
/* Create */ /* Create */
.create_size = sizeof(struct ip_set_req_setlist_create), .create_size = sizeof(struct ip_set_req_setlist_create),
.create_init = &create_init, .create_init = setlist_create_init,
.create_parse = &create_parse, .create_parse = setlist_create_parse,
.create_final = &create_final, .create_final = setlist_create_final,
.create_opts = create_opts, .create_opts = create_opts,
/* Add/del/test */ /* Add/del/test */
.adt_size = sizeof(struct ip_set_req_setlist), .adt_size = sizeof(struct ip_set_req_setlist),
.adt_parser = &adt_parser, .adt_parser = setlist_adt_parser,
/* Printing */ /* Printing */
.header_size = sizeof(struct ip_set_setlist), .header_size = sizeof(struct ip_set_setlist),
.initheader = &initheader, .initheader = setlist_initheader,
.printheader = &printheader, .printheader = setlist_printheader,
.printips = &printips_sorted, /* We only have sorted version */ .printips = setlist_printips_sorted,
.printips_sorted = &printips_sorted, .printips_sorted = setlist_printips_sorted,
.saveheader = &saveheader, .saveheader = setlist_saveheader,
.saveips = &saveips, .saveips = setlist_saveips,
.usage = &usage, .usage = setlist_usage,
}; };
CONSTRUCTOR(setlist) CONSTRUCTOR(setlist)