Skip to content

Commit

Permalink
netfilter: ipset: bitmap:ip set type support
Browse files Browse the repository at this point in the history
The module implements the bitmap:ip set type in two flavours, without
and with timeout support. In this kind of set one can store IPv4
addresses (or network addresses) from a given range.

In order not to waste memory, the timeout version does not rely on
the kernel timer for every element to be timed out but on garbage
collection. All set types use this mechanism.

Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Signed-off-by: Patrick McHardy <kaber@trash.net>
  • Loading branch information
Jozsef Kadlecsik authored and Patrick McHardy committed Feb 1, 2011
1 parent a7b4f98 commit 72205fc
Show file tree
Hide file tree
Showing 5 changed files with 758 additions and 0 deletions.
31 changes: 31 additions & 0 deletions include/linux/netfilter/ipset/ip_set_bitmap.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#ifndef __IP_SET_BITMAP_H
#define __IP_SET_BITMAP_H

/* Bitmap type specific error codes */
enum {
/* The element is out of the range of the set */
IPSET_ERR_BITMAP_RANGE = IPSET_ERR_TYPE_SPECIFIC,
/* The range exceeds the size limit of the set type */
IPSET_ERR_BITMAP_RANGE_SIZE,
};

#ifdef __KERNEL__
#define IPSET_BITMAP_MAX_RANGE 0x0000FFFF

/* Common functions */

static inline u32
range_to_mask(u32 from, u32 to, u8 *bits)
{
u32 mask = 0xFFFFFFFE;

*bits = 32;
while (--(*bits) > 0 && mask && (to & mask) != from)
mask <<= 1;

return mask;
}

#endif /* __KERNEL__ */

#endif /* __IP_SET_BITMAP_H */
127 changes: 127 additions & 0 deletions include/linux/netfilter/ipset/ip_set_timeout.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
#ifndef _IP_SET_TIMEOUT_H
#define _IP_SET_TIMEOUT_H

/* Copyright (C) 2003-2011 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/

#ifdef __KERNEL__

/* How often should the gc be run by default */
#define IPSET_GC_TIME (3 * 60)

/* Timeout period depending on the timeout value of the given set */
#define IPSET_GC_PERIOD(timeout) \
((timeout/3) ? min_t(u32, (timeout)/3, IPSET_GC_TIME) : 1)

/* Set is defined without timeout support: timeout value may be 0 */
#define IPSET_NO_TIMEOUT UINT_MAX

#define with_timeout(timeout) ((timeout) != IPSET_NO_TIMEOUT)

static inline unsigned int
ip_set_timeout_uget(struct nlattr *tb)
{
unsigned int timeout = ip_set_get_h32(tb);

/* Userspace supplied TIMEOUT parameter: adjust crazy size */
return timeout == IPSET_NO_TIMEOUT ? IPSET_NO_TIMEOUT - 1 : timeout;
}

#ifdef IP_SET_BITMAP_TIMEOUT

/* Bitmap specific timeout constants and macros for the entries */

/* Bitmap entry is unset */
#define IPSET_ELEM_UNSET 0
/* Bitmap entry is set with no timeout value */
#define IPSET_ELEM_PERMANENT (UINT_MAX/2)

static inline bool
ip_set_timeout_test(unsigned long timeout)
{
return timeout != IPSET_ELEM_UNSET &&
(timeout == IPSET_ELEM_PERMANENT ||
time_after(timeout, jiffies));
}

static inline bool
ip_set_timeout_expired(unsigned long timeout)
{
return timeout != IPSET_ELEM_UNSET &&
timeout != IPSET_ELEM_PERMANENT &&
time_before(timeout, jiffies);
}

static inline unsigned long
ip_set_timeout_set(u32 timeout)
{
unsigned long t;

if (!timeout)
return IPSET_ELEM_PERMANENT;

t = timeout * HZ + jiffies;
if (t == IPSET_ELEM_UNSET || t == IPSET_ELEM_PERMANENT)
/* Bingo! */
t++;

return t;
}

static inline u32
ip_set_timeout_get(unsigned long timeout)
{
return timeout == IPSET_ELEM_PERMANENT ? 0 : (timeout - jiffies)/HZ;
}

#else

/* Hash specific timeout constants and macros for the entries */

/* Hash entry is set with no timeout value */
#define IPSET_ELEM_PERMANENT 0

static inline bool
ip_set_timeout_test(unsigned long timeout)
{
return timeout == IPSET_ELEM_PERMANENT ||
time_after(timeout, jiffies);
}

static inline bool
ip_set_timeout_expired(unsigned long timeout)
{
return timeout != IPSET_ELEM_PERMANENT &&
time_before(timeout, jiffies);
}

static inline unsigned long
ip_set_timeout_set(u32 timeout)
{
unsigned long t;

if (!timeout)
return IPSET_ELEM_PERMANENT;

t = timeout * HZ + jiffies;
if (t == IPSET_ELEM_PERMANENT)
/* Bingo! :-) */
t++;

return t;
}

static inline u32
ip_set_timeout_get(unsigned long timeout)
{
return timeout == IPSET_ELEM_PERMANENT ? 0 : (timeout - jiffies)/HZ;
}
#endif /* ! IP_SET_BITMAP_TIMEOUT */

#endif /* __KERNEL__ */

#endif /* _IP_SET_TIMEOUT_H */
9 changes: 9 additions & 0 deletions net/netfilter/ipset/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,13 @@ config IP_SET_MAX
The value can be overriden by the 'max_sets' module
parameter of the 'ip_set' module.

config IP_SET_BITMAP_IP
tristate "bitmap:ip set support"
depends on IP_SET
help
This option adds the bitmap:ip set type support, by which one
can store IPv4 addresses (or network addresse) from a range.

To compile it as a module, choose M here. If unsure, say N.

endif # IP_SET
3 changes: 3 additions & 0 deletions net/netfilter/ipset/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@ ip_set-y := ip_set_core.o ip_set_getport.o pfxlen.o

# ipset core
obj-$(CONFIG_IP_SET) += ip_set.o

# bitmap types
obj-$(CONFIG_IP_SET_BITMAP_IP) += ip_set_bitmap_ip.o
Loading

0 comments on commit 72205fc

Please sign in to comment.