Commit d639feaa authored by David S. Miller's avatar David S. Miller

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next

Pablo Neira Ayuso says:

====================
The following patchset contains Netfilter updates for your net-next tree,
mostly ipset improvements and enhancements features, they are:

* Don't call ip_nest_end needlessly in the error path from me, suggested
  by Pablo Neira Ayuso, from Jozsef Kadlecsik.

* Fixed sparse warnings about shadowed variable and missing rcu annotation
  and fix of "may be used uninitialized" warnings, also from Jozsef.

* Renamed simple macro names to avoid namespace issues, reported by David
  Laight, again from Jozsef.

* Use fix sized type for timeout in the extension part, and cosmetic
  ordering of matches and targets separatedly in xt_set.c, from Jozsef.

* Support package fragments for IPv4 protos without ports from Anders K.
  Pedersen. For example this allows a hash:ip,port ipset containing the
  entry 192.168.0.1,gre:0 to match all package fragments for PPTP VPN
  tunnels to/from the host. Without this patch only the first package
  fragment (with fragment offset 0) was matched.

* Introduced a new operation to get both setname and family, from Jozsef.
  ip[6]tables set match and SET target need to know the family of the set
  in order to reject adding rules which refer to a set with a non-mathcing
  family. Currently such rules are silently accepted and then ignored
  instead of generating an error message to the user.

* Reworked extensions support in ipset types from Jozsef. The approach of
  defining structures with all variations is not manageable as the
  number of extensions grows. Therefore a blob for the extensions is
  introduced, somewhat similar to conntrack. The support of extensions
  which need a per data destroy function is added as well.

* When an element timed out in a list:set type of set, the garbage
  collector skipped the checking of the next element. So the purging
  was delayed to the next run of the gc, fixed by Jozsef.

* A small Kconfig fix: NETFILTER_NETLINK cannot be selected and
  ipset requires it.

* hash:net,net type from Oliver Smith. The type provides the ability to
  store pairs of subnets in a set.

* Comment for ipset entries from Oliver Smith. This makes possible to
  annotate entries in a set with comments, for example:

  ipset n foo hash:net,net comment
  ipset a foo 10.0.0.0/21,192.168.1.0/24 comment "office nets A and B"

* Fix of hash types resizing with comment extension from Jozsef.

* Fix of new extensions for list:set type when an element is added
  into a slot from where another element was pushed away from Jozsef.

* Introduction of a common function for the listing of the element
  extensions from Jozsef.

* Net namespace support for ipset from Vitaly Lavrov.

* hash:net,port,net type from Oliver Smith, which makes possible
  to store the triples of two subnets and a protocol, port pair in
  a set.

* Get xt_TCPMSS working with net namespace, by Gao feng.

* Use the proper net netnamespace to allocate skbs, also by Gao feng.

* A couple of cleanups for the conntrack SIP helper, by Holger
  Eitzenberger.

* Extend cttimeout to allow setting default conntrack timeouts via
  nfnetlink, so we can get rid of all our sysctl/proc interfaces in
  the future for timeout tuning, from me.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 96f817fe 91cb498e
...@@ -49,31 +49,68 @@ enum ip_set_feature { ...@@ -49,31 +49,68 @@ enum ip_set_feature {
/* Set extensions */ /* Set extensions */
enum ip_set_extension { enum ip_set_extension {
IPSET_EXT_NONE = 0, IPSET_EXT_BIT_TIMEOUT = 0,
IPSET_EXT_BIT_TIMEOUT = 1,
IPSET_EXT_TIMEOUT = (1 << IPSET_EXT_BIT_TIMEOUT), IPSET_EXT_TIMEOUT = (1 << IPSET_EXT_BIT_TIMEOUT),
IPSET_EXT_BIT_COUNTER = 2, IPSET_EXT_BIT_COUNTER = 1,
IPSET_EXT_COUNTER = (1 << IPSET_EXT_BIT_COUNTER), IPSET_EXT_COUNTER = (1 << IPSET_EXT_BIT_COUNTER),
}; IPSET_EXT_BIT_COMMENT = 2,
IPSET_EXT_COMMENT = (1 << IPSET_EXT_BIT_COMMENT),
/* Extension offsets */ /* Mark set with an extension which needs to call destroy */
enum ip_set_offset { IPSET_EXT_BIT_DESTROY = 7,
IPSET_OFFSET_TIMEOUT = 0, IPSET_EXT_DESTROY = (1 << IPSET_EXT_BIT_DESTROY),
IPSET_OFFSET_COUNTER,
IPSET_OFFSET_MAX,
}; };
#define SET_WITH_TIMEOUT(s) ((s)->extensions & IPSET_EXT_TIMEOUT) #define SET_WITH_TIMEOUT(s) ((s)->extensions & IPSET_EXT_TIMEOUT)
#define SET_WITH_COUNTER(s) ((s)->extensions & IPSET_EXT_COUNTER) #define SET_WITH_COUNTER(s) ((s)->extensions & IPSET_EXT_COUNTER)
#define SET_WITH_COMMENT(s) ((s)->extensions & IPSET_EXT_COMMENT)
/* Extension id, in size order */
enum ip_set_ext_id {
IPSET_EXT_ID_COUNTER = 0,
IPSET_EXT_ID_TIMEOUT,
IPSET_EXT_ID_COMMENT,
IPSET_EXT_ID_MAX,
};
/* Extension type */
struct ip_set_ext_type {
/* Destroy extension private data (can be NULL) */
void (*destroy)(void *ext);
enum ip_set_extension type;
enum ipset_cadt_flags flag;
/* Size and minimal alignment */
u8 len;
u8 align;
};
extern const struct ip_set_ext_type ip_set_extensions[];
struct ip_set_ext { struct ip_set_ext {
unsigned long timeout;
u64 packets; u64 packets;
u64 bytes; u64 bytes;
u32 timeout;
char *comment;
};
struct ip_set_counter {
atomic64_t bytes;
atomic64_t packets;
};
struct ip_set_comment {
char *str;
}; };
struct ip_set; struct ip_set;
#define ext_timeout(e, s) \
(unsigned long *)(((void *)(e)) + (s)->offset[IPSET_EXT_ID_TIMEOUT])
#define ext_counter(e, s) \
(struct ip_set_counter *)(((void *)(e)) + (s)->offset[IPSET_EXT_ID_COUNTER])
#define ext_comment(e, s) \
(struct ip_set_comment *)(((void *)(e)) + (s)->offset[IPSET_EXT_ID_COMMENT])
typedef int (*ipset_adtfn)(struct ip_set *set, void *value, typedef int (*ipset_adtfn)(struct ip_set *set, void *value,
const struct ip_set_ext *ext, const struct ip_set_ext *ext,
struct ip_set_ext *mext, u32 cmdflags); struct ip_set_ext *mext, u32 cmdflags);
...@@ -147,7 +184,8 @@ struct ip_set_type { ...@@ -147,7 +184,8 @@ struct ip_set_type {
u8 revision_min, revision_max; u8 revision_min, revision_max;
/* Create set */ /* Create set */
int (*create)(struct ip_set *set, struct nlattr *tb[], u32 flags); int (*create)(struct net *net, struct ip_set *set,
struct nlattr *tb[], u32 flags);
/* Attribute policies */ /* Attribute policies */
const struct nla_policy create_policy[IPSET_ATTR_CREATE_MAX + 1]; const struct nla_policy create_policy[IPSET_ATTR_CREATE_MAX + 1];
...@@ -179,14 +217,45 @@ struct ip_set { ...@@ -179,14 +217,45 @@ struct ip_set {
u8 revision; u8 revision;
/* Extensions */ /* Extensions */
u8 extensions; u8 extensions;
/* Default timeout value, if enabled */
u32 timeout;
/* Element data size */
size_t dsize;
/* Offsets to extensions in elements */
size_t offset[IPSET_EXT_ID_MAX];
/* The type specific data */ /* The type specific data */
void *data; void *data;
}; };
struct ip_set_counter { static inline void
atomic64_t bytes; ip_set_ext_destroy(struct ip_set *set, void *data)
atomic64_t packets; {
}; /* Check that the extension is enabled for the set and
* call it's destroy function for its extension part in data.
*/
if (SET_WITH_COMMENT(set))
ip_set_extensions[IPSET_EXT_ID_COMMENT].destroy(
ext_comment(data, set));
}
static inline int
ip_set_put_flags(struct sk_buff *skb, struct ip_set *set)
{
u32 cadt_flags = 0;
if (SET_WITH_TIMEOUT(set))
if (unlikely(nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
htonl(set->timeout))))
return -EMSGSIZE;
if (SET_WITH_COUNTER(set))
cadt_flags |= IPSET_FLAG_WITH_COUNTERS;
if (SET_WITH_COMMENT(set))
cadt_flags |= IPSET_FLAG_WITH_COMMENT;
if (!cadt_flags)
return 0;
return nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(cadt_flags));
}
static inline void static inline void
ip_set_add_bytes(u64 bytes, struct ip_set_counter *counter) ip_set_add_bytes(u64 bytes, struct ip_set_counter *counter)
...@@ -248,12 +317,13 @@ ip_set_init_counter(struct ip_set_counter *counter, ...@@ -248,12 +317,13 @@ ip_set_init_counter(struct ip_set_counter *counter,
} }
/* register and unregister set references */ /* register and unregister set references */
extern ip_set_id_t ip_set_get_byname(const char *name, struct ip_set **set); extern ip_set_id_t ip_set_get_byname(struct net *net,
extern void ip_set_put_byindex(ip_set_id_t index); const char *name, struct ip_set **set);
extern const char *ip_set_name_byindex(ip_set_id_t index); extern void ip_set_put_byindex(struct net *net, ip_set_id_t index);
extern ip_set_id_t ip_set_nfnl_get(const char *name); extern const char *ip_set_name_byindex(struct net *net, ip_set_id_t index);
extern ip_set_id_t ip_set_nfnl_get_byindex(ip_set_id_t index); extern ip_set_id_t ip_set_nfnl_get(struct net *net, const char *name);
extern void ip_set_nfnl_put(ip_set_id_t index); extern ip_set_id_t ip_set_nfnl_get_byindex(struct net *net, ip_set_id_t index);
extern void ip_set_nfnl_put(struct net *net, ip_set_id_t index);
/* API for iptables set match, and SET target */ /* API for iptables set match, and SET target */
...@@ -272,6 +342,8 @@ extern void *ip_set_alloc(size_t size); ...@@ -272,6 +342,8 @@ extern void *ip_set_alloc(size_t size);
extern void ip_set_free(void *members); extern void ip_set_free(void *members);
extern int ip_set_get_ipaddr4(struct nlattr *nla, __be32 *ipaddr); extern int ip_set_get_ipaddr4(struct nlattr *nla, __be32 *ipaddr);
extern int ip_set_get_ipaddr6(struct nlattr *nla, union nf_inet_addr *ipaddr); extern int ip_set_get_ipaddr6(struct nlattr *nla, union nf_inet_addr *ipaddr);
extern size_t ip_set_elem_len(struct ip_set *set, struct nlattr *tb[],
size_t len);
extern int ip_set_get_extensions(struct ip_set *set, struct nlattr *tb[], extern int ip_set_get_extensions(struct ip_set *set, struct nlattr *tb[],
struct ip_set_ext *ext); struct ip_set_ext *ext);
...@@ -389,13 +461,40 @@ bitmap_bytes(u32 a, u32 b) ...@@ -389,13 +461,40 @@ bitmap_bytes(u32 a, u32 b)
} }
#include <linux/netfilter/ipset/ip_set_timeout.h> #include <linux/netfilter/ipset/ip_set_timeout.h>
#include <linux/netfilter/ipset/ip_set_comment.h>
#define IP_SET_INIT_KEXT(skb, opt, map) \ static inline int
ip_set_put_extensions(struct sk_buff *skb, const struct ip_set *set,
const void *e, bool active)
{
if (SET_WITH_TIMEOUT(set)) {
unsigned long *timeout = ext_timeout(e, set);
if (nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
htonl(active ? ip_set_timeout_get(timeout)
: *timeout)))
return -EMSGSIZE;
}
if (SET_WITH_COUNTER(set) &&
ip_set_put_counter(skb, ext_counter(e, set)))
return -EMSGSIZE;
if (SET_WITH_COMMENT(set) &&
ip_set_put_comment(skb, ext_comment(e, set)))
return -EMSGSIZE;
return 0;
}
#define IP_SET_INIT_KEXT(skb, opt, set) \
{ .bytes = (skb)->len, .packets = 1, \ { .bytes = (skb)->len, .packets = 1, \
.timeout = ip_set_adt_opt_timeout(opt, map) } .timeout = ip_set_adt_opt_timeout(opt, set) }
#define IP_SET_INIT_UEXT(map) \ #define IP_SET_INIT_UEXT(set) \
{ .bytes = ULLONG_MAX, .packets = ULLONG_MAX, \ { .bytes = ULLONG_MAX, .packets = ULLONG_MAX, \
.timeout = (map)->timeout } .timeout = (set)->timeout }
#define IP_SET_INIT_CIDR(a, b) ((a) ? (a) : (b))
#define IPSET_CONCAT(a, b) a##b
#define IPSET_TOKEN(a, b) IPSET_CONCAT(a, b)
#endif /*_IP_SET_H */ #endif /*_IP_SET_H */
#ifndef _IP_SET_COMMENT_H
#define _IP_SET_COMMENT_H
/* Copyright (C) 2013 Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa>
*
* 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__
static inline char*
ip_set_comment_uget(struct nlattr *tb)
{
return nla_data(tb);
}
static inline void
ip_set_init_comment(struct ip_set_comment *comment,
const struct ip_set_ext *ext)
{
size_t len = ext->comment ? strlen(ext->comment) : 0;
if (unlikely(comment->str)) {
kfree(comment->str);
comment->str = NULL;
}
if (!len)
return;
if (unlikely(len > IPSET_MAX_COMMENT_SIZE))
len = IPSET_MAX_COMMENT_SIZE;
comment->str = kzalloc(len + 1, GFP_ATOMIC);
if (unlikely(!comment->str))
return;
strlcpy(comment->str, ext->comment, len + 1);
}
static inline int
ip_set_put_comment(struct sk_buff *skb, struct ip_set_comment *comment)
{
if (!comment->str)
return 0;
return nla_put_string(skb, IPSET_ATTR_COMMENT, comment->str);
}
static inline void
ip_set_comment_free(struct ip_set_comment *comment)
{
if (unlikely(!comment->str))
return;
kfree(comment->str);
comment->str = NULL;
}
#endif
#endif
...@@ -23,8 +23,8 @@ ...@@ -23,8 +23,8 @@
/* Set is defined with timeout support: timeout value may be 0 */ /* Set is defined with timeout support: timeout value may be 0 */
#define IPSET_NO_TIMEOUT UINT_MAX #define IPSET_NO_TIMEOUT UINT_MAX
#define ip_set_adt_opt_timeout(opt, map) \ #define ip_set_adt_opt_timeout(opt, set) \
((opt)->ext.timeout != IPSET_NO_TIMEOUT ? (opt)->ext.timeout : (map)->timeout) ((opt)->ext.timeout != IPSET_NO_TIMEOUT ? (opt)->ext.timeout : (set)->timeout)
static inline unsigned int static inline unsigned int
ip_set_timeout_uget(struct nlattr *tb) ip_set_timeout_uget(struct nlattr *tb)
......
...@@ -107,55 +107,64 @@ enum sdp_header_types { ...@@ -107,55 +107,64 @@ enum sdp_header_types {
SDP_HDR_MEDIA, SDP_HDR_MEDIA,
}; };
extern unsigned int (*nf_nat_sip_hook)(struct sk_buff *skb, struct nf_nat_sip_hooks {
unsigned int protoff, unsigned int (*msg)(struct sk_buff *skb,
unsigned int dataoff, unsigned int protoff,
const char **dptr, unsigned int dataoff,
unsigned int *datalen); const char **dptr,
extern void (*nf_nat_sip_seq_adjust_hook)(struct sk_buff *skb, unsigned int *datalen);
unsigned int protoff, s16 off);
extern unsigned int (*nf_nat_sip_expect_hook)(struct sk_buff *skb, void (*seq_adjust)(struct sk_buff *skb,
unsigned int protoff, unsigned int protoff, s16 off);
unsigned int dataoff,
const char **dptr, unsigned int (*expect)(struct sk_buff *skb,
unsigned int *datalen, unsigned int protoff,
struct nf_conntrack_expect *exp, unsigned int dataoff,
unsigned int matchoff, const char **dptr,
unsigned int matchlen); unsigned int *datalen,
extern unsigned int (*nf_nat_sdp_addr_hook)(struct sk_buff *skb, struct nf_conntrack_expect *exp,
unsigned int protoff, unsigned int matchoff,
unsigned int dataoff, unsigned int matchlen);
const char **dptr,
unsigned int *datalen, unsigned int (*sdp_addr)(struct sk_buff *skb,
unsigned int sdpoff, unsigned int protoff,
enum sdp_header_types type, unsigned int dataoff,
enum sdp_header_types term, const char **dptr,
const union nf_inet_addr *addr); unsigned int *datalen,
extern unsigned int (*nf_nat_sdp_port_hook)(struct sk_buff *skb, unsigned int sdpoff,
unsigned int protoff, enum sdp_header_types type,
unsigned int dataoff, enum sdp_header_types term,
const char **dptr, const union nf_inet_addr *addr);
unsigned int *datalen,
unsigned int matchoff, unsigned int (*sdp_port)(struct sk_buff *skb,
unsigned int matchlen, unsigned int protoff,
u_int16_t port); unsigned int dataoff,
extern unsigned int (*nf_nat_sdp_session_hook)(struct sk_buff *skb, const char **dptr,
unsigned int protoff, unsigned int *datalen,
unsigned int dataoff, unsigned int matchoff,
const char **dptr, unsigned int matchlen,
unsigned int *datalen, u_int16_t port);
unsigned int sdpoff,
const union nf_inet_addr *addr); unsigned int (*sdp_session)(struct sk_buff *skb,
extern unsigned int (*nf_nat_sdp_media_hook)(struct sk_buff *skb, unsigned int protoff,
unsigned int protoff, unsigned int dataoff,
unsigned int dataoff, const char **dptr,
const char **dptr, unsigned int *datalen,
unsigned int *datalen, unsigned int sdpoff,
struct nf_conntrack_expect *rtp_exp, const union nf_inet_addr *addr);
struct nf_conntrack_expect *rtcp_exp,
unsigned int mediaoff, unsigned int (*sdp_media)(struct sk_buff *skb,
unsigned int medialen, unsigned int protoff,
union nf_inet_addr *rtp_addr); unsigned int dataoff,
const char **dptr,
unsigned int *datalen,
struct nf_conntrack_expect *rtp_exp,
struct nf_conntrack_expect *rtcp_exp,
unsigned int mediaoff,
unsigned int medialen,
union nf_inet_addr *rtp_addr);
};
extern const struct nf_nat_sip_hooks *nf_nat_sip_hooks;
int ct_sip_parse_request(const struct nf_conn *ct, const char *dptr, int ct_sip_parse_request(const struct nf_conn *ct, const char *dptr,
unsigned int datalen, unsigned int *matchoff, unsigned int datalen, unsigned int *matchoff,
......
...@@ -10,12 +10,14 @@ ...@@ -10,12 +10,14 @@
#ifndef _UAPI_IP_SET_H #ifndef _UAPI_IP_SET_H
#define _UAPI_IP_SET_H #define _UAPI_IP_SET_H
#include <linux/types.h> #include <linux/types.h>
/* The protocol version */ /* The protocol version */
#define IPSET_PROTOCOL 6 #define IPSET_PROTOCOL 6
/* The maximum permissible comment length we will accept over netlink */
#define IPSET_MAX_COMMENT_SIZE 255
/* The max length of strings including NUL: set and type identifiers */ /* The max length of strings including NUL: set and type identifiers */
#define IPSET_MAXNAMELEN 32 #define IPSET_MAXNAMELEN 32
...@@ -110,6 +112,7 @@ enum { ...@@ -110,6 +112,7 @@ enum {
IPSET_ATTR_IFACE, IPSET_ATTR_IFACE,
IPSET_ATTR_BYTES, IPSET_ATTR_BYTES,
IPSET_ATTR_PACKETS, IPSET_ATTR_PACKETS,
IPSET_ATTR_COMMENT,
__IPSET_ATTR_ADT_MAX, __IPSET_ATTR_ADT_MAX,
}; };
#define IPSET_ATTR_ADT_MAX (__IPSET_ATTR_ADT_MAX - 1) #define IPSET_ATTR_ADT_MAX (__IPSET_ATTR_ADT_MAX - 1)
...@@ -140,6 +143,7 @@ enum ipset_errno { ...@@ -140,6 +143,7 @@ enum ipset_errno {
IPSET_ERR_IPADDR_IPV4, IPSET_ERR_IPADDR_IPV4,
IPSET_ERR_IPADDR_IPV6, IPSET_ERR_IPADDR_IPV6,
IPSET_ERR_COUNTER, IPSET_ERR_COUNTER,
IPSET_ERR_COMMENT,
/* Type specific error codes */ /* Type specific error codes */
IPSET_ERR_TYPE_SPECIFIC = 4352, IPSET_ERR_TYPE_SPECIFIC = 4352,
...@@ -176,6 +180,8 @@ enum ipset_cadt_flags { ...@@ -176,6 +180,8 @@ enum ipset_cadt_flags {
IPSET_FLAG_NOMATCH = (1 << IPSET_FLAG_BIT_NOMATCH), IPSET_FLAG_NOMATCH = (1 << IPSET_FLAG_BIT_NOMATCH),
IPSET_FLAG_BIT_WITH_COUNTERS = 3, IPSET_FLAG_BIT_WITH_COUNTERS = 3,
IPSET_FLAG_WITH_COUNTERS = (1 << IPSET_FLAG_BIT_WITH_COUNTERS), IPSET_FLAG_WITH_COUNTERS = (1 << IPSET_FLAG_BIT_WITH_COUNTERS),
IPSET_FLAG_BIT_WITH_COMMENT = 4,
IPSET_FLAG_WITH_COMMENT = (1 << IPSET_FLAG_BIT_WITH_COMMENT),
IPSET_FLAG_CADT_MAX = 15, IPSET_FLAG_CADT_MAX = 15,
}; };
...@@ -250,6 +256,14 @@ struct ip_set_req_get_set { ...@@ -250,6 +256,14 @@ struct ip_set_req_get_set {
#define IP_SET_OP_GET_BYINDEX 0x00000007 /* Get set name by index */ #define IP_SET_OP_GET_BYINDEX 0x00000007 /* Get set name by index */
/* Uses ip_set_req_get_set */ /* Uses ip_set_req_get_set */
#define IP_SET_OP_GET_FNAME 0x00000008 /* Get set index and family */
struct ip_set_req_get_set_family {
unsigned int op;
unsigned int version;
unsigned int family;
union ip_set_name_index set;
};
#define IP_SET_OP_VERSION 0x00000100 /* Ask kernel version */ #define IP_SET_OP_VERSION 0x00000100 /* Ask kernel version */
struct ip_set_req_version { struct ip_set_req_version {
unsigned int op; unsigned int op;
......
...@@ -6,6 +6,8 @@ enum ctnl_timeout_msg_types { ...@@ -6,6 +6,8 @@ enum ctnl_timeout_msg_types {
IPCTNL_MSG_TIMEOUT_NEW, IPCTNL_MSG_TIMEOUT_NEW,
IPCTNL_MSG_TIMEOUT_GET, IPCTNL_MSG_TIMEOUT_GET,
IPCTNL_MSG_TIMEOUT_DELETE, IPCTNL_MSG_TIMEOUT_DELETE,
IPCTNL_MSG_TIMEOUT_DEFAULT_SET,
IPCTNL_MSG_TIMEOUT_DEFAULT_GET,
IPCTNL_MSG_TIMEOUT_MAX IPCTNL_MSG_TIMEOUT_MAX
}; };
......
menuconfig IP_SET menuconfig IP_SET
tristate "IP set support" tristate "IP set support"
depends on INET && NETFILTER depends on INET && NETFILTER
depends on NETFILTER_NETLINK select NETFILTER_NETLINK
help help
This option adds IP set support to the kernel. This option adds IP set support to the kernel.
In order to define and use the sets, you need the userspace utility In order to define and use the sets, you need the userspace utility
...@@ -90,6 +90,15 @@ config IP_SET_HASH_IPPORTNET ...@@ -90,6 +90,15 @@ config IP_SET_HASH_IPPORTNET
To compile it as a module, choose M here. If unsure, say N. To compile it as a module, choose M here. If unsure, say N.
config IP_SET_HASH_NETPORTNET
tristate "hash:net,port,net set support"
depends on IP_SET
help
This option adds the hash:net,port,net set type support, by which
one can store two IPv4/IPv6 subnets, and a protocol/port in a set.
To compile it as a module, choose M here. If unsure, say N.
config IP_SET_HASH_NET config IP_SET_HASH_NET
tristate "hash:net set support" tristate "hash:net set support"
depends on IP_SET depends on IP_SET
...@@ -99,6 +108,15 @@ config IP_SET_HASH_NET ...@@ -99,6 +108,15 @@ config IP_SET_HASH_NET
To compile it as a module, choose M here. If unsure, say N. To compile it as a module, choose M here. If unsure, say N.
config IP_SET_HASH_NETNET
tristate "hash:net,net set support"
depends on IP_SET
help
This option adds the hash:net,net set type support, by which
one can store IPv4/IPv6 network address/prefix pairs in a set.
To compile it as a module, choose M here. If unsure, say N.
config IP_SET_HASH_NETPORT config IP_SET_HASH_NETPORT
tristate "hash:net,port set support" tristate "hash:net,port set support"
depends on IP_SET depends on IP_SET
......
...@@ -20,6 +20,8 @@ obj-$(CONFIG_IP_SET_HASH_IPPORTNET) += ip_set_hash_ipportnet.o ...@@ -20,6 +20,8 @@ obj-$(CONFIG_IP_SET_HASH_IPPORTNET) += ip_set_hash_ipportnet.o
obj-$(CONFIG_IP_SET_HASH_NET) += ip_set_hash_net.o obj-$(CONFIG_IP_SET_HASH_NET) += ip_set_hash_net.o
obj-$(CONFIG_IP_SET_HASH_NETPORT) += ip_set_hash_netport.o obj-$(CONFIG_IP_SET_HASH_NETPORT) += ip_set_hash_netport.o
obj-$(CONFIG_IP_SET_HASH_NETIFACE) += ip_set_hash_netiface.o obj-$(CONFIG_IP_SET_HASH_NETIFACE) += ip_set_hash_netiface.o
obj-$(CONFIG_IP_SET_HASH_NETNET) += ip_set_hash_netnet.o
obj-$(CONFIG_IP_SET_HASH_NETPORTNET) += ip_set_hash_netportnet.o
# list types # list types
obj-$(CONFIG_IP_SET_LIST_SET) += ip_set_list_set.o obj-$(CONFIG_IP_SET_LIST_SET) += ip_set_list_set.o
...@@ -8,38 +8,32 @@ ...@@ -8,38 +8,32 @@
#ifndef __IP_SET_BITMAP_IP_GEN_H #ifndef __IP_SET_BITMAP_IP_GEN_H
#define __IP_SET_BITMAP_IP_GEN_H #define __IP_SET_BITMAP_IP_GEN_H
#define CONCAT(a, b) a##b #define mtype_do_test IPSET_TOKEN(MTYPE, _do_test)
#define TOKEN(a,b) CONCAT(a, b) #define mtype_gc_test IPSET_TOKEN(MTYPE, _gc_test)
#define mtype_is_filled IPSET_TOKEN(MTYPE, _is_filled)
#define mtype_do_test TOKEN(MTYPE, _do_test) #define mtype_do_add IPSET_TOKEN(MTYPE, _do_add)
#define mtype_gc_test TOKEN(MTYPE, _gc_test) #define mtype_ext_cleanup IPSET_TOKEN(MTYPE, _ext_cleanup)
#define mtype_is_filled TOKEN(MTYPE, _is_filled) #define mtype_do_del IPSET_TOKEN(MTYPE, _do_del)
#define mtype_do_add TOKEN(MTYPE, _do_add) #define mtype_do_list IPSET_TOKEN(MTYPE, _do_list)
#define mtype_do_del TOKEN(MTYPE, _do_del) #define mtype_do_head IPSET_TOKEN(MTYPE, _do_head)
#define mtype_do_list TOKEN(MTYPE, _do_list) #define mtype_adt_elem IPSET_TOKEN(MTYPE, _adt_elem)
#define mtype_do_head TOKEN(MTYPE, _do_head) #define mtype_add_timeout IPSET_TOKEN(MTYPE, _add_timeout)
#define mtype_adt_elem TOKEN(MTYPE, _adt_elem) #define mtype_gc_init IPSET_TOKEN(MTYPE, _gc_init)
#define mtype_add_timeout TOKEN(MTYPE, _add_timeout) #define mtype_kadt IPSET_TOKEN(MTYPE, _kadt)
#define mtype_gc_init TOKEN(MTYPE, _gc_init) #define mtype_uadt IPSET_TOKEN(MTYPE, _uadt)
#define mtype_kadt TOKEN(MTYPE, _kadt) #define mtype_destroy IPSET_TOKEN(MTYPE, _destroy)
#define mtype_uadt TOKEN(MTYPE, _uadt) #define mtype_flush IPSET_TOKEN(MTYPE, _flush)
#define mtype_destroy TOKEN(MTYPE, _destroy) #define mtype_head IPSET_TOKEN(MTYPE, _head)
#define mtype_flush TOKEN(MTYPE, _flush) #define mtype_same_set IPSET_TOKEN(MTYPE, _same_set)
#define mtype_head TOKEN(MTYPE, _head) #define mtype_elem IPSET_TOKEN(MTYPE, _elem)
#define mtype_same_set TOKEN(MTYPE, _same_set) #define mtype_test IPSET_TOKEN(MTYPE, _test)
#define mtype_elem TOKEN(MTYPE, _elem) #define mtype_add IPSET_TOKEN(MTYPE, _add)
#define mtype_test TOKEN(MTYPE, _test) #define mtype_del IPSET_TOKEN(MTYPE, _del)
#define mtype_add TOKEN(MTYPE, _add) #define mtype_list IPSET_TOKEN(MTYPE, _list)
#define mtype_del TOKEN(MTYPE, _del) #define mtype_gc IPSET_TOKEN(MTYPE, _gc)
#define mtype_list TOKEN(MTYPE, _list)
#define mtype_gc TOKEN(MTYPE, _gc)
#define mtype MTYPE #define mtype MTYPE
#define ext_timeout(e, m) \ #define get_ext(set, map, id) ((map)->extensions + (set)->dsize * (id))
(unsigned long *)((e) + (m)->offset[IPSET_OFFSET_TIMEOUT])
#define ext_counter(e, m) \
(struct ip_set_counter *)((e) + (m)->offset[IPSET_OFFSET_COUNTER])
#define get_ext(map, id) ((map)->extensions + (map)->dsize * (id))
static void static void
mtype_gc_init(struct ip_set *set, void (*gc)(unsigned long ul_set)) mtype_gc_init(struct ip_set *set, void (*gc)(unsigned long ul_set))
...@@ -49,10 +43,21 @@ mtype_gc_init(struct ip_set *set, void (*gc)(unsigned long ul_set)) ...@@ -49,10 +43,21 @@ mtype_gc_init(struct ip_set *set, void (*gc)(unsigned long ul_set))
init_timer(&map->gc); init_timer(&map->gc);
map->gc.data = (unsigned long) set; map->gc.data = (unsigned long) set;
map->gc.function = gc; map->gc.function = gc;
map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ; map->gc.expires = jiffies + IPSET_GC_PERIOD(set->timeout) * HZ;
add_timer(&map->gc); add_timer(&map->gc);
} }
static void
mtype_ext_cleanup(struct ip_set *set)
{
struct mtype *map = set->data;
u32 id;
for (id = 0; id < map->elements; id++)
if (test_bit(id, map->members))
ip_set_ext_destroy(set, get_ext(set, map, id));
}
static void static void
mtype_destroy(struct ip_set *set) mtype_destroy(struct ip_set *set)
{ {
...@@ -62,8 +67,11 @@ mtype_destroy(struct ip_set *set) ...@@ -62,8 +67,11 @@ mtype_destroy(struct ip_set *set)
del_timer_sync(&map->gc); del_timer_sync(&map->gc);
ip_set_free(map->members); ip_set_free(map->members);
if (map->dsize) if (set->dsize) {
if (set->extensions & IPSET_EXT_DESTROY)
mtype_ext_cleanup(set);
ip_set_free(map->extensions); ip_set_free(map->extensions);
}
kfree(map); kfree(map);
set->data = NULL; set->data = NULL;
...@@ -74,6 +82,8 @@ mtype_flush(struct ip_set *set) ...@@ -74,6 +82,8 @@ mtype_flush(struct ip_set *set)
{ {
struct mtype *map = set->data; struct mtype *map = set->data;
if (set->extensions & IPSET_EXT_DESTROY)
mtype_ext_cleanup(set);
memset(map->members, 0, map->memsize); memset(map->members, 0, map->memsize);
} }
...@@ -91,12 +101,9 @@ mtype_head(struct ip_set *set, struct sk_buff *skb) ...@@ -91,12 +101,9 @@ mtype_head(struct ip_set *set, struct sk_buff *skb)
nla_put_net32(skb, IPSET_ATTR_MEMSIZE, nla_put_net32(skb, IPSET_ATTR_MEMSIZE,
htonl(sizeof(*map) + htonl(sizeof(*map) +
map->memsize + map->memsize +
map->dsize * map->elements)) || set->dsize * map->elements)))
(SET_WITH_TIMEOUT(set) && goto nla_put_failure;
nla_put_net32(skb, IPSET_ATTR_TIMEOUT, htonl(map->timeout))) || if (unlikely(ip_set_put_flags(skb, set)))
(SET_WITH_COUNTER(set) &&
nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS,
htonl(IPSET_FLAG_WITH_COUNTERS))))
goto nla_put_failure; goto nla_put_failure;
ipset_nest_end(skb, nested); ipset_nest_end(skb, nested);
...@@ -111,16 +118,16 @@ mtype_test(struct ip_set *set, void *value, const struct ip_set_ext *ext, ...@@ -111,16 +118,16 @@ mtype_test(struct ip_set *set, void *value, const struct ip_set_ext *ext,
{ {
struct mtype *map = set->data; struct mtype *map = set->data;
const struct mtype_adt_elem *e = value; const struct mtype_adt_elem *e = value;
void *x = get_ext(map, e->id); void *x = get_ext(set, map, e->id);
int ret = mtype_do_test(e, map); int ret = mtype_do_test(e, map, set->dsize);
if (ret <= 0) if (ret <= 0)
return ret; return ret;
if (SET_WITH_TIMEOUT(set) && if (SET_WITH_TIMEOUT(set) &&
ip_set_timeout_expired(ext_timeout(x, map))) ip_set_timeout_expired(ext_timeout(x, set)))
return 0; return 0;
if (SET_WITH_COUNTER(set)) if (SET_WITH_COUNTER(set))
ip_set_update_counter(ext_counter(x, map), ext, mext, flags); ip_set_update_counter(ext_counter(x, set), ext, mext, flags);
return 1; return 1;
} }
...@@ -130,26 +137,30 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext, ...@@ -130,26 +137,30 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext,
{ {
struct mtype *map = set->data; struct mtype *map = set->data;
const struct mtype_adt_elem *e = value; const struct mtype_adt_elem *e = value;
void *x = get_ext(map, e->id); void *x = get_ext(set, map, e->id);
int ret = mtype_do_add(e, map, flags); int ret = mtype_do_add(e, map, flags, set->dsize);
if (ret == IPSET_ADD_FAILED) { if (ret == IPSET_ADD_FAILED) {
if (SET_WITH_TIMEOUT(set) && if (SET_WITH_TIMEOUT(set) &&
ip_set_timeout_expired(ext_timeout(x, map))) ip_set_timeout_expired(ext_timeout(x, set)))
ret = 0; ret = 0;
else if (!(flags & IPSET_FLAG_EXIST)) else if (!(flags & IPSET_FLAG_EXIST))
return -IPSET_ERR_EXIST; return -IPSET_ERR_EXIST;
/* Element is re-added, cleanup extensions */
ip_set_ext_destroy(set, x);
} }
if (SET_WITH_TIMEOUT(set)) if (SET_WITH_TIMEOUT(set))
#ifdef IP_SET_BITMAP_STORED_TIMEOUT #ifdef IP_SET_BITMAP_STORED_TIMEOUT
mtype_add_timeout(ext_timeout(x, map), e, ext, map, ret); mtype_add_timeout(ext_timeout(x, set), e, ext, set, map, ret);
#else #else
ip_set_timeout_set(ext_timeout(x, map), ext->timeout); ip_set_timeout_set(ext_timeout(x, set), ext->timeout);
#endif #endif
if (SET_WITH_COUNTER(set)) if (SET_WITH_COUNTER(set))
ip_set_init_counter(ext_counter(x, map), ext); ip_set_init_counter(ext_counter(x, set), ext);
if (SET_WITH_COMMENT(set))
ip_set_init_comment(ext_comment(x, set), ext);
return 0; return 0;
} }
...@@ -159,16 +170,27 @@ mtype_del(struct ip_set *set, void *value, const struct ip_set_ext *ext, ...@@ -159,16 +170,27 @@ mtype_del(struct ip_set *set, void *value, const struct ip_set_ext *ext,
{ {
struct mtype *map = set->data; struct mtype *map = set->data;
const struct mtype_adt_elem *e = value; const struct mtype_adt_elem *e = value;
const void *x = get_ext(map, e->id); void *x = get_ext(set, map, e->id);
if (mtype_do_del(e, map) || if (mtype_do_del(e, map))
(SET_WITH_TIMEOUT(set) && return -IPSET_ERR_EXIST;
ip_set_timeout_expired(ext_timeout(x, map))))
ip_set_ext_destroy(set, x);
if (SET_WITH_TIMEOUT(set) &&
ip_set_timeout_expired(ext_timeout(x, set)))
return -IPSET_ERR_EXIST; return -IPSET_ERR_EXIST;
return 0; return 0;
} }
#ifndef IP_SET_BITMAP_STORED_TIMEOUT
static inline bool
mtype_is_filled(const struct mtype_elem *x)
{
return true;
}
#endif
static int static int
mtype_list(const struct ip_set *set, mtype_list(const struct ip_set *set,
struct sk_buff *skb, struct netlink_callback *cb) struct sk_buff *skb, struct netlink_callback *cb)
...@@ -183,13 +205,13 @@ mtype_list(const struct ip_set *set, ...@@ -183,13 +205,13 @@ mtype_list(const struct ip_set *set,
return -EMSGSIZE; return -EMSGSIZE;
for (; cb->args[2] < map->elements; cb->args[2]++) { for (; cb->args[2] < map->elements; cb->args[2]++) {
id = cb->args[2]; id = cb->args[2];
x = get_ext(map, id); x = get_ext(set, map, id);
if (!test_bit(id, map->members) || if (!test_bit(id, map->members) ||
(SET_WITH_TIMEOUT(set) && (SET_WITH_TIMEOUT(set) &&
#ifdef IP_SET_BITMAP_STORED_TIMEOUT #ifdef IP_SET_BITMAP_STORED_TIMEOUT
mtype_is_filled((const struct mtype_elem *) x) && mtype_is_filled((const struct mtype_elem *) x) &&
#endif #endif
ip_set_timeout_expired(ext_timeout(x, map)))) ip_set_timeout_expired(ext_timeout(x, set))))
continue; continue;
nested = ipset_nest_start(skb, IPSET_ATTR_DATA); nested = ipset_nest_start(skb, IPSET_ATTR_DATA);
if (!nested) { if (!nested) {
...@@ -199,23 +221,10 @@ mtype_list(const struct ip_set *set, ...@@ -199,23 +221,10 @@ mtype_list(const struct ip_set *set,
} else } else
goto nla_put_failure; goto nla_put_failure;
} }
if (mtype_do_list(skb, map, id)) if (mtype_do_list(skb, map, id, set->dsize))
goto nla_put_failure; goto nla_put_failure;
if (SET_WITH_TIMEOUT(set)) { if (ip_set_put_extensions(skb, set, x,
#ifdef IP_SET_BITMAP_STORED_TIMEOUT mtype_is_filled((const struct mtype_elem *) x)))
if (nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
htonl(ip_set_timeout_stored(map, id,
ext_timeout(x, map)))))
goto nla_put_failure;
#else
if (nla_put_net32(skb, IPSET_ATTR_TIMEOUT,
htonl(ip_set_timeout_get(
ext_timeout(x, map)))))
goto nla_put_failure;
#endif
}
if (SET_WITH_COUNTER(set) &&
ip_set_put_counter(skb, ext_counter(x, map)))
goto nla_put_failure; goto nla_put_failure;
ipset_nest_end(skb, nested); ipset_nest_end(skb, nested);
} }
...@@ -228,11 +237,11 @@ mtype_list(const struct ip_set *set, ...@@ -228,11 +237,11 @@ mtype_list(const struct ip_set *set,
nla_put_failure: nla_put_failure:
nla_nest_cancel(skb, nested); nla_nest_cancel(skb, nested);
ipset_nest_end(skb, adt);
if (unlikely(id == first)) { if (unlikely(id == first)) {
cb->args[2] = 0; cb->args[2] = 0;
return -EMSGSIZE; return -EMSGSIZE;
} }
ipset_nest_end(skb, adt);
return 0; return 0;
} }
...@@ -241,21 +250,23 @@ mtype_gc(unsigned long ul_set) ...@@ -241,21 +250,23 @@ mtype_gc(unsigned long ul_set)
{ {
struct ip_set *set = (struct ip_set *) ul_set; struct ip_set *set = (struct ip_set *) ul_set;
struct mtype *map = set->data; struct mtype *map = set->data;
const void *x; void *x;
u32 id; u32 id;
/* We run parallel with other readers (test element) /* We run parallel with other readers (test element)
* but adding/deleting new entries is locked out */ * but adding/deleting new entries is locked out */
read_lock_bh(&set->lock); read_lock_bh(&set->lock);
for (id = 0; id < map->elements; id++) for (id = 0; id < map->elements; id++)
if (mtype_gc_test(id, map)) { if (mtype_gc_test(id, map, set->dsize)) {
x = get_ext(map, id); x = get_ext(set, map, id);
if (ip_set_timeout_expired(ext_timeout(x, map))) if (ip_set_timeout_expired(ext_timeout(x, set))) {
clear_bit(id, map->members); clear_bit(id, map->members);
ip_set_ext_destroy(set, x);
}
} }
read_unlock_bh(&set->lock); read_unlock_bh(&set->lock);
map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ; map->gc.expires = jiffies + IPSET_GC_PERIOD(set->timeout) * HZ;
add_timer(&map->gc); add_timer(&map->gc);
} }
......
...@@ -25,12 +25,13 @@ ...@@ -25,12 +25,13 @@
#include <linux/netfilter/ipset/ip_set.h> #include <linux/netfilter/ipset/ip_set.h>
#include <linux/netfilter/ipset/ip_set_bitmap.h> #include <linux/netfilter/ipset/ip_set_bitmap.h>
#define REVISION_MIN 0 #define IPSET_TYPE_REV_MIN 0
#define REVISION_MAX 1 /* Counter support added */ /* 1 Counter support added */
#define IPSET_TYPE_REV_MAX 2 /* Comment support added */
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
IP_SET_MODULE_DESC("bitmap:ip", REVISION_MIN, REVISION_MAX); IP_SET_MODULE_DESC("bitmap:ip", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX);
MODULE_ALIAS("ip_set_bitmap:ip"); MODULE_ALIAS("ip_set_bitmap:ip");
#define MTYPE bitmap_ip #define MTYPE bitmap_ip
...@@ -44,10 +45,7 @@ struct bitmap_ip { ...@@ -44,10 +45,7 @@ struct bitmap_ip {
u32 elements; /* number of max elements in the set */ u32 elements; /* number of max elements in the set */
u32 hosts; /* number of hosts in a subnet */ u32 hosts; /* number of hosts in a subnet */
size_t memsize; /* members size */ size_t memsize; /* members size */
size_t dsize; /* extensions struct size */
size_t offset[IPSET_OFFSET_MAX]; /* Offsets to extensions */
u8 netmask; /* subnet netmask */ u8 netmask; /* subnet netmask */
u32 timeout; /* timeout parameter */
struct timer_list gc; /* garbage collection */ struct timer_list gc; /* garbage collection */
}; };
...@@ -65,20 +63,21 @@ ip_to_id(const struct bitmap_ip *m, u32 ip) ...@@ -65,20 +63,21 @@ ip_to_id(const struct bitmap_ip *m, u32 ip)
/* Common functions */ /* Common functions */
static inline int static inline int
bitmap_ip_do_test(const struct bitmap_ip_adt_elem *e, struct bitmap_ip *map) bitmap_ip_do_test(const struct bitmap_ip_adt_elem *e,
struct bitmap_ip *map, size_t dsize)
{ {
return !!test_bit(e->id, map->members); return !!test_bit(e->id, map->members);
} }
static inline int static inline int
bitmap_ip_gc_test(u16 id, const struct bitmap_ip *map) bitmap_ip_gc_test(u16 id, const struct bitmap_ip *map, size_t dsize)
{ {
return !!test_bit(id, map->members); return !!test_bit(id, map->members);
} }
static inline int static inline int
bitmap_ip_do_add(const struct bitmap_ip_adt_elem *e, struct bitmap_ip *map, bitmap_ip_do_add(const struct bitmap_ip_adt_elem *e, struct bitmap_ip *map,
u32 flags) u32 flags, size_t dsize)
{ {
return !!test_and_set_bit(e->id, map->members); return !!test_and_set_bit(e->id, map->members);
} }
...@@ -90,7 +89,8 @@ bitmap_ip_do_del(const struct bitmap_ip_adt_elem *e, struct bitmap_ip *map) ...@@ -90,7 +89,8 @@ bitmap_ip_do_del(const struct bitmap_ip_adt_elem *e, struct bitmap_ip *map)
} }
static inline int static inline int
bitmap_ip_do_list(struct sk_buff *skb, const struct bitmap_ip *map, u32 id) bitmap_ip_do_list(struct sk_buff *skb, const struct bitmap_ip *map, u32 id,
size_t dsize)
{ {
return nla_put_ipaddr4(skb, IPSET_ATTR_IP, return nla_put_ipaddr4(skb, IPSET_ATTR_IP,
htonl(map->first_ip + id * map->hosts)); htonl(map->first_ip + id * map->hosts));
...@@ -113,7 +113,7 @@ bitmap_ip_kadt(struct ip_set *set, const struct sk_buff *skb, ...@@ -113,7 +113,7 @@ bitmap_ip_kadt(struct ip_set *set, const struct sk_buff *skb,
struct bitmap_ip *map = set->data; struct bitmap_ip *map = set->data;
ipset_adtfn adtfn = set->variant->adt[adt]; ipset_adtfn adtfn = set->variant->adt[adt];
struct bitmap_ip_adt_elem e = { }; struct bitmap_ip_adt_elem e = { };
struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, map); struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
u32 ip; u32 ip;
ip = ntohl(ip4addr(skb, opt->flags & IPSET_DIM_ONE_SRC)); ip = ntohl(ip4addr(skb, opt->flags & IPSET_DIM_ONE_SRC));
...@@ -131,9 +131,9 @@ bitmap_ip_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -131,9 +131,9 @@ bitmap_ip_uadt(struct ip_set *set, struct nlattr *tb[],
{ {
struct bitmap_ip *map = set->data; struct bitmap_ip *map = set->data;
ipset_adtfn adtfn = set->variant->adt[adt]; ipset_adtfn adtfn = set->variant->adt[adt];
u32 ip, ip_to; u32 ip = 0, ip_to = 0;
struct bitmap_ip_adt_elem e = { }; struct bitmap_ip_adt_elem e = { };
struct ip_set_ext ext = IP_SET_INIT_UEXT(map); struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
int ret = 0; int ret = 0;
if (unlikely(!tb[IPSET_ATTR_IP] || if (unlikely(!tb[IPSET_ATTR_IP] ||
...@@ -200,7 +200,7 @@ bitmap_ip_same_set(const struct ip_set *a, const struct ip_set *b) ...@@ -200,7 +200,7 @@ bitmap_ip_same_set(const struct ip_set *a, const struct ip_set *b)
return x->first_ip == y->first_ip && return x->first_ip == y->first_ip &&
x->last_ip == y->last_ip && x->last_ip == y->last_ip &&
x->netmask == y->netmask && x->netmask == y->netmask &&
x->timeout == y->timeout && a->timeout == b->timeout &&
a->extensions == b->extensions; a->extensions == b->extensions;
} }
...@@ -209,25 +209,6 @@ bitmap_ip_same_set(const struct ip_set *a, const struct ip_set *b) ...@@ -209,25 +209,6 @@ bitmap_ip_same_set(const struct ip_set *a, const struct ip_set *b)
struct bitmap_ip_elem { struct bitmap_ip_elem {
}; };
/* Timeout variant */
struct bitmap_ipt_elem {
unsigned long timeout;
};
/* Plain variant with counter */
struct bitmap_ipc_elem {
struct ip_set_counter counter;
};
/* Timeout variant with counter */
struct bitmap_ipct_elem {
unsigned long timeout;
struct ip_set_counter counter;
};
#include "ip_set_bitmap_gen.h" #include "ip_set_bitmap_gen.h"
/* Create bitmap:ip type of sets */ /* Create bitmap:ip type of sets */
...@@ -240,8 +221,8 @@ init_map_ip(struct ip_set *set, struct bitmap_ip *map, ...@@ -240,8 +221,8 @@ init_map_ip(struct ip_set *set, struct bitmap_ip *map,
map->members = ip_set_alloc(map->memsize); map->members = ip_set_alloc(map->memsize);
if (!map->members) if (!map->members)
return false; return false;
if (map->dsize) { if (set->dsize) {
map->extensions = ip_set_alloc(map->dsize * elements); map->extensions = ip_set_alloc(set->dsize * elements);
if (!map->extensions) { if (!map->extensions) {
kfree(map->members); kfree(map->members);
return false; return false;
...@@ -252,7 +233,7 @@ init_map_ip(struct ip_set *set, struct bitmap_ip *map, ...@@ -252,7 +233,7 @@ init_map_ip(struct ip_set *set, struct bitmap_ip *map,
map->elements = elements; map->elements = elements;
map->hosts = hosts; map->hosts = hosts;
map->netmask = netmask; map->netmask = netmask;
map->timeout = IPSET_NO_TIMEOUT; set->timeout = IPSET_NO_TIMEOUT;
set->data = map; set->data = map;
set->family = NFPROTO_IPV4; set->family = NFPROTO_IPV4;
...@@ -261,10 +242,11 @@ init_map_ip(struct ip_set *set, struct bitmap_ip *map, ...@@ -261,10 +242,11 @@ init_map_ip(struct ip_set *set, struct bitmap_ip *map,
} }
static int static int
bitmap_ip_create(struct ip_set *set, struct nlattr *tb[], u32 flags) bitmap_ip_create(struct net *net, struct ip_set *set, struct nlattr *tb[],
u32 flags)
{ {
struct bitmap_ip *map; struct bitmap_ip *map;
u32 first_ip, last_ip, hosts, cadt_flags = 0; u32 first_ip = 0, last_ip = 0, hosts;
u64 elements; u64 elements;
u8 netmask = 32; u8 netmask = 32;
int ret; int ret;
...@@ -336,61 +318,15 @@ bitmap_ip_create(struct ip_set *set, struct nlattr *tb[], u32 flags) ...@@ -336,61 +318,15 @@ bitmap_ip_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
map->memsize = bitmap_bytes(0, elements - 1); map->memsize = bitmap_bytes(0, elements - 1);
set->variant = &bitmap_ip; set->variant = &bitmap_ip;
if (tb[IPSET_ATTR_CADT_FLAGS]) set->dsize = ip_set_elem_len(set, tb, 0);
cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); if (!init_map_ip(set, map, first_ip, last_ip,
if (cadt_flags & IPSET_FLAG_WITH_COUNTERS) { elements, hosts, netmask)) {
set->extensions |= IPSET_EXT_COUNTER; kfree(map);
if (tb[IPSET_ATTR_TIMEOUT]) { return -ENOMEM;
map->dsize = sizeof(struct bitmap_ipct_elem); }
map->offset[IPSET_OFFSET_TIMEOUT] = if (tb[IPSET_ATTR_TIMEOUT]) {
offsetof(struct bitmap_ipct_elem, timeout); set->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
map->offset[IPSET_OFFSET_COUNTER] =
offsetof(struct bitmap_ipct_elem, counter);
if (!init_map_ip(set, map, first_ip, last_ip,
elements, hosts, netmask)) {
kfree(map);
return -ENOMEM;
}
map->timeout = ip_set_timeout_uget(
tb[IPSET_ATTR_TIMEOUT]);
set->extensions |= IPSET_EXT_TIMEOUT;
bitmap_ip_gc_init(set, bitmap_ip_gc);
} else {
map->dsize = sizeof(struct bitmap_ipc_elem);
map->offset[IPSET_OFFSET_COUNTER] =
offsetof(struct bitmap_ipc_elem, counter);
if (!init_map_ip(set, map, first_ip, last_ip,
elements, hosts, netmask)) {
kfree(map);
return -ENOMEM;
}
}
} else if (tb[IPSET_ATTR_TIMEOUT]) {
map->dsize = sizeof(struct bitmap_ipt_elem);
map->offset[IPSET_OFFSET_TIMEOUT] =
offsetof(struct bitmap_ipt_elem, timeout);
if (!init_map_ip(set, map, first_ip, last_ip,
elements, hosts, netmask)) {
kfree(map);
return -ENOMEM;
}
map->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
set->extensions |= IPSET_EXT_TIMEOUT;
bitmap_ip_gc_init(set, bitmap_ip_gc); bitmap_ip_gc_init(set, bitmap_ip_gc);
} else {
map->dsize = 0;
if (!init_map_ip(set, map, first_ip, last_ip,
elements, hosts, netmask)) {
kfree(map);
return -ENOMEM;
}
} }
return 0; return 0;
} }
...@@ -401,8 +337,8 @@ static struct ip_set_type bitmap_ip_type __read_mostly = { ...@@ -401,8 +337,8 @@ static struct ip_set_type bitmap_ip_type __read_mostly = {
.features = IPSET_TYPE_IP, .features = IPSET_TYPE_IP,
.dimension = IPSET_DIM_ONE, .dimension = IPSET_DIM_ONE,
.family = NFPROTO_IPV4, .family = NFPROTO_IPV4,
.revision_min = REVISION_MIN, .revision_min = IPSET_TYPE_REV_MIN,
.revision_max = REVISION_MAX, .revision_max = IPSET_TYPE_REV_MAX,
.create = bitmap_ip_create, .create = bitmap_ip_create,
.create_policy = { .create_policy = {
[IPSET_ATTR_IP] = { .type = NLA_NESTED }, [IPSET_ATTR_IP] = { .type = NLA_NESTED },
...@@ -420,6 +356,7 @@ static struct ip_set_type bitmap_ip_type __read_mostly = { ...@@ -420,6 +356,7 @@ static struct ip_set_type bitmap_ip_type __read_mostly = {
[IPSET_ATTR_LINENO] = { .type = NLA_U32 }, [IPSET_ATTR_LINENO] = { .type = NLA_U32 },
[IPSET_ATTR_BYTES] = { .type = NLA_U64 }, [IPSET_ATTR_BYTES] = { .type = NLA_U64 },
[IPSET_ATTR_PACKETS] = { .type = NLA_U64 }, [IPSET_ATTR_PACKETS] = { .type = NLA_U64 },
[IPSET_ATTR_COMMENT] = { .type = NLA_NUL_STRING },
}, },
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
......
...@@ -25,12 +25,13 @@ ...@@ -25,12 +25,13 @@
#include <linux/netfilter/ipset/ip_set.h> #include <linux/netfilter/ipset/ip_set.h>
#include <linux/netfilter/ipset/ip_set_bitmap.h> #include <linux/netfilter/ipset/ip_set_bitmap.h>
#define REVISION_MIN 0 #define IPSET_TYPE_REV_MIN 0
#define REVISION_MAX 1 /* Counter support added */ /* 1 Counter support added */
#define IPSET_TYPE_REV_MAX 2 /* Comment support added */
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
IP_SET_MODULE_DESC("bitmap:ip,mac", REVISION_MIN, REVISION_MAX); IP_SET_MODULE_DESC("bitmap:ip,mac", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX);
MODULE_ALIAS("ip_set_bitmap:ip,mac"); MODULE_ALIAS("ip_set_bitmap:ip,mac");
#define MTYPE bitmap_ipmac #define MTYPE bitmap_ipmac
...@@ -48,11 +49,8 @@ struct bitmap_ipmac { ...@@ -48,11 +49,8 @@ struct bitmap_ipmac {
u32 first_ip; /* host byte order, included in range */ u32 first_ip; /* host byte order, included in range */
u32 last_ip; /* host byte order, included in range */ u32 last_ip; /* host byte order, included in range */
u32 elements; /* number of max elements in the set */ u32 elements; /* number of max elements in the set */
u32 timeout; /* timeout value */
struct timer_list gc; /* garbage collector */
size_t memsize; /* members size */ size_t memsize; /* members size */
size_t dsize; /* size of element */ struct timer_list gc; /* garbage collector */
size_t offset[IPSET_OFFSET_MAX]; /* Offsets to extensions */
}; };
/* ADT structure for generic function args */ /* ADT structure for generic function args */
...@@ -82,13 +80,13 @@ get_elem(void *extensions, u16 id, size_t dsize) ...@@ -82,13 +80,13 @@ get_elem(void *extensions, u16 id, size_t dsize)
static inline int static inline int
bitmap_ipmac_do_test(const struct bitmap_ipmac_adt_elem *e, bitmap_ipmac_do_test(const struct bitmap_ipmac_adt_elem *e,
const struct bitmap_ipmac *map) const struct bitmap_ipmac *map, size_t dsize)
{ {
const struct bitmap_ipmac_elem *elem; const struct bitmap_ipmac_elem *elem;
if (!test_bit(e->id, map->members)) if (!test_bit(e->id, map->members))
return 0; return 0;
elem = get_elem(map->extensions, e->id, map->dsize); elem = get_elem(map->extensions, e->id, dsize);
if (elem->filled == MAC_FILLED) if (elem->filled == MAC_FILLED)
return e->ether == NULL || return e->ether == NULL ||
ether_addr_equal(e->ether, elem->ether); ether_addr_equal(e->ether, elem->ether);
...@@ -97,13 +95,13 @@ bitmap_ipmac_do_test(const struct bitmap_ipmac_adt_elem *e, ...@@ -97,13 +95,13 @@ bitmap_ipmac_do_test(const struct bitmap_ipmac_adt_elem *e,
} }
static inline int static inline int
bitmap_ipmac_gc_test(u16 id, const struct bitmap_ipmac *map) bitmap_ipmac_gc_test(u16 id, const struct bitmap_ipmac *map, size_t dsize)
{ {
const struct bitmap_ipmac_elem *elem; const struct bitmap_ipmac_elem *elem;
if (!test_bit(id, map->members)) if (!test_bit(id, map->members))
return 0; return 0;
elem = get_elem(map->extensions, id, map->dsize); elem = get_elem(map->extensions, id, dsize);
/* Timer not started for the incomplete elements */ /* Timer not started for the incomplete elements */
return elem->filled == MAC_FILLED; return elem->filled == MAC_FILLED;
} }
...@@ -117,13 +115,13 @@ bitmap_ipmac_is_filled(const struct bitmap_ipmac_elem *elem) ...@@ -117,13 +115,13 @@ bitmap_ipmac_is_filled(const struct bitmap_ipmac_elem *elem)
static inline int static inline int
bitmap_ipmac_add_timeout(unsigned long *timeout, bitmap_ipmac_add_timeout(unsigned long *timeout,
const struct bitmap_ipmac_adt_elem *e, const struct bitmap_ipmac_adt_elem *e,
const struct ip_set_ext *ext, const struct ip_set_ext *ext, struct ip_set *set,
struct bitmap_ipmac *map, int mode) struct bitmap_ipmac *map, int mode)
{ {
u32 t = ext->timeout; u32 t = ext->timeout;
if (mode == IPSET_ADD_START_STORED_TIMEOUT) { if (mode == IPSET_ADD_START_STORED_TIMEOUT) {
if (t == map->timeout) if (t == set->timeout)
/* Timeout was not specified, get stored one */ /* Timeout was not specified, get stored one */
t = *timeout; t = *timeout;
ip_set_timeout_set(timeout, t); ip_set_timeout_set(timeout, t);
...@@ -142,11 +140,11 @@ bitmap_ipmac_add_timeout(unsigned long *timeout, ...@@ -142,11 +140,11 @@ bitmap_ipmac_add_timeout(unsigned long *timeout,
static inline int static inline int
bitmap_ipmac_do_add(const struct bitmap_ipmac_adt_elem *e, bitmap_ipmac_do_add(const struct bitmap_ipmac_adt_elem *e,
struct bitmap_ipmac *map, u32 flags) struct bitmap_ipmac *map, u32 flags, size_t dsize)
{ {
struct bitmap_ipmac_elem *elem; struct bitmap_ipmac_elem *elem;
elem = get_elem(map->extensions, e->id, map->dsize); elem = get_elem(map->extensions, e->id, dsize);
if (test_and_set_bit(e->id, map->members)) { if (test_and_set_bit(e->id, map->members)) {
if (elem->filled == MAC_FILLED) { if (elem->filled == MAC_FILLED) {
if (e->ether && (flags & IPSET_FLAG_EXIST)) if (e->ether && (flags & IPSET_FLAG_EXIST))
...@@ -178,22 +176,12 @@ bitmap_ipmac_do_del(const struct bitmap_ipmac_adt_elem *e, ...@@ -178,22 +176,12 @@ bitmap_ipmac_do_del(const struct bitmap_ipmac_adt_elem *e,
return !test_and_clear_bit(e->id, map->members); return !test_and_clear_bit(e->id, map->members);
} }
static inline unsigned long
ip_set_timeout_stored(struct bitmap_ipmac *map, u32 id, unsigned long *timeout)
{
const struct bitmap_ipmac_elem *elem =
get_elem(map->extensions, id, map->dsize);
return elem->filled == MAC_FILLED ? ip_set_timeout_get(timeout) :
*timeout;
}
static inline int static inline int
bitmap_ipmac_do_list(struct sk_buff *skb, const struct bitmap_ipmac *map, bitmap_ipmac_do_list(struct sk_buff *skb, const struct bitmap_ipmac *map,
u32 id) u32 id, size_t dsize)
{ {
const struct bitmap_ipmac_elem *elem = const struct bitmap_ipmac_elem *elem =
get_elem(map->extensions, id, map->dsize); get_elem(map->extensions, id, dsize);
return nla_put_ipaddr4(skb, IPSET_ATTR_IP, return nla_put_ipaddr4(skb, IPSET_ATTR_IP,
htonl(map->first_ip + id)) || htonl(map->first_ip + id)) ||
...@@ -216,7 +204,7 @@ bitmap_ipmac_kadt(struct ip_set *set, const struct sk_buff *skb, ...@@ -216,7 +204,7 @@ bitmap_ipmac_kadt(struct ip_set *set, const struct sk_buff *skb,
struct bitmap_ipmac *map = set->data; struct bitmap_ipmac *map = set->data;
ipset_adtfn adtfn = set->variant->adt[adt]; ipset_adtfn adtfn = set->variant->adt[adt];
struct bitmap_ipmac_adt_elem e = {}; struct bitmap_ipmac_adt_elem e = {};
struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, map); struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
u32 ip; u32 ip;
/* MAC can be src only */ /* MAC can be src only */
...@@ -245,8 +233,8 @@ bitmap_ipmac_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -245,8 +233,8 @@ bitmap_ipmac_uadt(struct ip_set *set, struct nlattr *tb[],
const struct bitmap_ipmac *map = set->data; const struct bitmap_ipmac *map = set->data;
ipset_adtfn adtfn = set->variant->adt[adt]; ipset_adtfn adtfn = set->variant->adt[adt];
struct bitmap_ipmac_adt_elem e = {}; struct bitmap_ipmac_adt_elem e = {};
struct ip_set_ext ext = IP_SET_INIT_UEXT(map); struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
u32 ip; u32 ip = 0;
int ret = 0; int ret = 0;
if (unlikely(!tb[IPSET_ATTR_IP] || if (unlikely(!tb[IPSET_ATTR_IP] ||
...@@ -285,43 +273,12 @@ bitmap_ipmac_same_set(const struct ip_set *a, const struct ip_set *b) ...@@ -285,43 +273,12 @@ bitmap_ipmac_same_set(const struct ip_set *a, const struct ip_set *b)
return x->first_ip == y->first_ip && return x->first_ip == y->first_ip &&
x->last_ip == y->last_ip && x->last_ip == y->last_ip &&
x->timeout == y->timeout && a->timeout == b->timeout &&
a->extensions == b->extensions; a->extensions == b->extensions;
} }
/* Plain variant */ /* Plain variant */
/* Timeout variant */
struct bitmap_ipmact_elem {
struct {
unsigned char ether[ETH_ALEN];
unsigned char filled;
} __attribute__ ((aligned));
unsigned long timeout;
};
/* Plain variant with counter */
struct bitmap_ipmacc_elem {
struct {
unsigned char ether[ETH_ALEN];
unsigned char filled;
} __attribute__ ((aligned));
struct ip_set_counter counter;
};
/* Timeout variant with counter */
struct bitmap_ipmacct_elem {
struct {
unsigned char ether[ETH_ALEN];
unsigned char filled;
} __attribute__ ((aligned));
unsigned long timeout;
struct ip_set_counter counter;
};
#include "ip_set_bitmap_gen.h" #include "ip_set_bitmap_gen.h"
/* Create bitmap:ip,mac type of sets */ /* Create bitmap:ip,mac type of sets */
...@@ -330,11 +287,11 @@ static bool ...@@ -330,11 +287,11 @@ static bool
init_map_ipmac(struct ip_set *set, struct bitmap_ipmac *map, init_map_ipmac(struct ip_set *set, struct bitmap_ipmac *map,
u32 first_ip, u32 last_ip, u32 elements) u32 first_ip, u32 last_ip, u32 elements)
{ {
map->members = ip_set_alloc((last_ip - first_ip + 1) * map->dsize); map->members = ip_set_alloc(map->memsize);
if (!map->members) if (!map->members)
return false; return false;
if (map->dsize) { if (set->dsize) {
map->extensions = ip_set_alloc(map->dsize * elements); map->extensions = ip_set_alloc(set->dsize * elements);
if (!map->extensions) { if (!map->extensions) {
kfree(map->members); kfree(map->members);
return false; return false;
...@@ -343,7 +300,7 @@ init_map_ipmac(struct ip_set *set, struct bitmap_ipmac *map, ...@@ -343,7 +300,7 @@ init_map_ipmac(struct ip_set *set, struct bitmap_ipmac *map,
map->first_ip = first_ip; map->first_ip = first_ip;
map->last_ip = last_ip; map->last_ip = last_ip;
map->elements = elements; map->elements = elements;
map->timeout = IPSET_NO_TIMEOUT; set->timeout = IPSET_NO_TIMEOUT;
set->data = map; set->data = map;
set->family = NFPROTO_IPV4; set->family = NFPROTO_IPV4;
...@@ -352,10 +309,10 @@ init_map_ipmac(struct ip_set *set, struct bitmap_ipmac *map, ...@@ -352,10 +309,10 @@ init_map_ipmac(struct ip_set *set, struct bitmap_ipmac *map,
} }
static int static int
bitmap_ipmac_create(struct ip_set *set, struct nlattr *tb[], bitmap_ipmac_create(struct net *net, struct ip_set *set, struct nlattr *tb[],
u32 flags) u32 flags)
{ {
u32 first_ip, last_ip, cadt_flags = 0; u32 first_ip = 0, last_ip = 0;
u64 elements; u64 elements;
struct bitmap_ipmac *map; struct bitmap_ipmac *map;
int ret; int ret;
...@@ -399,57 +356,15 @@ bitmap_ipmac_create(struct ip_set *set, struct nlattr *tb[], ...@@ -399,57 +356,15 @@ bitmap_ipmac_create(struct ip_set *set, struct nlattr *tb[],
map->memsize = bitmap_bytes(0, elements - 1); map->memsize = bitmap_bytes(0, elements - 1);
set->variant = &bitmap_ipmac; set->variant = &bitmap_ipmac;
if (tb[IPSET_ATTR_CADT_FLAGS]) set->dsize = ip_set_elem_len(set, tb,
cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); sizeof(struct bitmap_ipmac_elem));
if (cadt_flags & IPSET_FLAG_WITH_COUNTERS) { if (!init_map_ipmac(set, map, first_ip, last_ip, elements)) {
set->extensions |= IPSET_EXT_COUNTER; kfree(map);
if (tb[IPSET_ATTR_TIMEOUT]) { return -ENOMEM;
map->dsize = sizeof(struct bitmap_ipmacct_elem); }
map->offset[IPSET_OFFSET_TIMEOUT] = if (tb[IPSET_ATTR_TIMEOUT]) {
offsetof(struct bitmap_ipmacct_elem, timeout); set->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
map->offset[IPSET_OFFSET_COUNTER] =
offsetof(struct bitmap_ipmacct_elem, counter);
if (!init_map_ipmac(set, map, first_ip, last_ip,
elements)) {
kfree(map);
return -ENOMEM;
}
map->timeout = ip_set_timeout_uget(
tb[IPSET_ATTR_TIMEOUT]);
set->extensions |= IPSET_EXT_TIMEOUT;
bitmap_ipmac_gc_init(set, bitmap_ipmac_gc);
} else {
map->dsize = sizeof(struct bitmap_ipmacc_elem);
map->offset[IPSET_OFFSET_COUNTER] =
offsetof(struct bitmap_ipmacc_elem, counter);
if (!init_map_ipmac(set, map, first_ip, last_ip,
elements)) {
kfree(map);
return -ENOMEM;
}
}
} else if (tb[IPSET_ATTR_TIMEOUT]) {
map->dsize = sizeof(struct bitmap_ipmact_elem);
map->offset[IPSET_OFFSET_TIMEOUT] =
offsetof(struct bitmap_ipmact_elem, timeout);
if (!init_map_ipmac(set, map, first_ip, last_ip, elements)) {
kfree(map);
return -ENOMEM;
}
map->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
set->extensions |= IPSET_EXT_TIMEOUT;
bitmap_ipmac_gc_init(set, bitmap_ipmac_gc); bitmap_ipmac_gc_init(set, bitmap_ipmac_gc);
} else {
map->dsize = sizeof(struct bitmap_ipmac_elem);
if (!init_map_ipmac(set, map, first_ip, last_ip, elements)) {
kfree(map);
return -ENOMEM;
}
set->variant = &bitmap_ipmac;
} }
return 0; return 0;
} }
...@@ -460,8 +375,8 @@ static struct ip_set_type bitmap_ipmac_type = { ...@@ -460,8 +375,8 @@ static struct ip_set_type bitmap_ipmac_type = {
.features = IPSET_TYPE_IP | IPSET_TYPE_MAC, .features = IPSET_TYPE_IP | IPSET_TYPE_MAC,
.dimension = IPSET_DIM_TWO, .dimension = IPSET_DIM_TWO,
.family = NFPROTO_IPV4, .family = NFPROTO_IPV4,
.revision_min = REVISION_MIN, .revision_min = IPSET_TYPE_REV_MIN,
.revision_max = REVISION_MAX, .revision_max = IPSET_TYPE_REV_MAX,
.create = bitmap_ipmac_create, .create = bitmap_ipmac_create,
.create_policy = { .create_policy = {
[IPSET_ATTR_IP] = { .type = NLA_NESTED }, [IPSET_ATTR_IP] = { .type = NLA_NESTED },
...@@ -478,6 +393,7 @@ static struct ip_set_type bitmap_ipmac_type = { ...@@ -478,6 +393,7 @@ static struct ip_set_type bitmap_ipmac_type = {
[IPSET_ATTR_LINENO] = { .type = NLA_U32 }, [IPSET_ATTR_LINENO] = { .type = NLA_U32 },
[IPSET_ATTR_BYTES] = { .type = NLA_U64 }, [IPSET_ATTR_BYTES] = { .type = NLA_U64 },
[IPSET_ATTR_PACKETS] = { .type = NLA_U64 }, [IPSET_ATTR_PACKETS] = { .type = NLA_U64 },
[IPSET_ATTR_COMMENT] = { .type = NLA_NUL_STRING },
}, },
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
......
...@@ -20,12 +20,13 @@ ...@@ -20,12 +20,13 @@
#include <linux/netfilter/ipset/ip_set_bitmap.h> #include <linux/netfilter/ipset/ip_set_bitmap.h>
#include <linux/netfilter/ipset/ip_set_getport.h> #include <linux/netfilter/ipset/ip_set_getport.h>
#define REVISION_MIN 0 #define IPSET_TYPE_REV_MIN 0
#define REVISION_MAX 1 /* Counter support added */ /* 1 Counter support added */
#define IPSET_TYPE_REV_MAX 2 /* Comment support added */
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
IP_SET_MODULE_DESC("bitmap:port", REVISION_MIN, REVISION_MAX); IP_SET_MODULE_DESC("bitmap:port", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX);
MODULE_ALIAS("ip_set_bitmap:port"); MODULE_ALIAS("ip_set_bitmap:port");
#define MTYPE bitmap_port #define MTYPE bitmap_port
...@@ -38,9 +39,6 @@ struct bitmap_port { ...@@ -38,9 +39,6 @@ struct bitmap_port {
u16 last_port; /* host byte order, included in range */ u16 last_port; /* host byte order, included in range */
u32 elements; /* number of max elements in the set */ u32 elements; /* number of max elements in the set */
size_t memsize; /* members size */ size_t memsize; /* members size */
size_t dsize; /* extensions struct size */
size_t offset[IPSET_OFFSET_MAX]; /* Offsets to extensions */
u32 timeout; /* timeout parameter */
struct timer_list gc; /* garbage collection */ struct timer_list gc; /* garbage collection */
}; };
...@@ -59,20 +57,20 @@ port_to_id(const struct bitmap_port *m, u16 port) ...@@ -59,20 +57,20 @@ port_to_id(const struct bitmap_port *m, u16 port)
static inline int static inline int
bitmap_port_do_test(const struct bitmap_port_adt_elem *e, bitmap_port_do_test(const struct bitmap_port_adt_elem *e,
const struct bitmap_port *map) const struct bitmap_port *map, size_t dsize)
{ {
return !!test_bit(e->id, map->members); return !!test_bit(e->id, map->members);
} }
static inline int static inline int
bitmap_port_gc_test(u16 id, const struct bitmap_port *map) bitmap_port_gc_test(u16 id, const struct bitmap_port *map, size_t dsize)
{ {
return !!test_bit(id, map->members); return !!test_bit(id, map->members);
} }
static inline int static inline int
bitmap_port_do_add(const struct bitmap_port_adt_elem *e, bitmap_port_do_add(const struct bitmap_port_adt_elem *e,
struct bitmap_port *map, u32 flags) struct bitmap_port *map, u32 flags, size_t dsize)
{ {
return !!test_and_set_bit(e->id, map->members); return !!test_and_set_bit(e->id, map->members);
} }
...@@ -85,7 +83,8 @@ bitmap_port_do_del(const struct bitmap_port_adt_elem *e, ...@@ -85,7 +83,8 @@ bitmap_port_do_del(const struct bitmap_port_adt_elem *e,
} }
static inline int static inline int
bitmap_port_do_list(struct sk_buff *skb, const struct bitmap_port *map, u32 id) bitmap_port_do_list(struct sk_buff *skb, const struct bitmap_port *map, u32 id,
size_t dsize)
{ {
return nla_put_net16(skb, IPSET_ATTR_PORT, return nla_put_net16(skb, IPSET_ATTR_PORT,
htons(map->first_port + id)); htons(map->first_port + id));
...@@ -106,7 +105,7 @@ bitmap_port_kadt(struct ip_set *set, const struct sk_buff *skb, ...@@ -106,7 +105,7 @@ bitmap_port_kadt(struct ip_set *set, const struct sk_buff *skb,
struct bitmap_port *map = set->data; struct bitmap_port *map = set->data;
ipset_adtfn adtfn = set->variant->adt[adt]; ipset_adtfn adtfn = set->variant->adt[adt];
struct bitmap_port_adt_elem e = {}; struct bitmap_port_adt_elem e = {};
struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, map); struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
__be16 __port; __be16 __port;
u16 port = 0; u16 port = 0;
...@@ -131,7 +130,7 @@ bitmap_port_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -131,7 +130,7 @@ bitmap_port_uadt(struct ip_set *set, struct nlattr *tb[],
struct bitmap_port *map = set->data; struct bitmap_port *map = set->data;
ipset_adtfn adtfn = set->variant->adt[adt]; ipset_adtfn adtfn = set->variant->adt[adt];
struct bitmap_port_adt_elem e = {}; struct bitmap_port_adt_elem e = {};
struct ip_set_ext ext = IP_SET_INIT_UEXT(map); struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
u32 port; /* wraparound */ u32 port; /* wraparound */
u16 port_to; u16 port_to;
int ret = 0; int ret = 0;
...@@ -191,7 +190,7 @@ bitmap_port_same_set(const struct ip_set *a, const struct ip_set *b) ...@@ -191,7 +190,7 @@ bitmap_port_same_set(const struct ip_set *a, const struct ip_set *b)
return x->first_port == y->first_port && return x->first_port == y->first_port &&
x->last_port == y->last_port && x->last_port == y->last_port &&
x->timeout == y->timeout && a->timeout == b->timeout &&
a->extensions == b->extensions; a->extensions == b->extensions;
} }
...@@ -200,25 +199,6 @@ bitmap_port_same_set(const struct ip_set *a, const struct ip_set *b) ...@@ -200,25 +199,6 @@ bitmap_port_same_set(const struct ip_set *a, const struct ip_set *b)
struct bitmap_port_elem { struct bitmap_port_elem {
}; };
/* Timeout variant */
struct bitmap_portt_elem {
unsigned long timeout;
};
/* Plain variant with counter */
struct bitmap_portc_elem {
struct ip_set_counter counter;
};
/* Timeout variant with counter */
struct bitmap_portct_elem {
unsigned long timeout;
struct ip_set_counter counter;
};
#include "ip_set_bitmap_gen.h" #include "ip_set_bitmap_gen.h"
/* Create bitmap:ip type of sets */ /* Create bitmap:ip type of sets */
...@@ -230,8 +210,8 @@ init_map_port(struct ip_set *set, struct bitmap_port *map, ...@@ -230,8 +210,8 @@ init_map_port(struct ip_set *set, struct bitmap_port *map,
map->members = ip_set_alloc(map->memsize); map->members = ip_set_alloc(map->memsize);
if (!map->members) if (!map->members)
return false; return false;
if (map->dsize) { if (set->dsize) {
map->extensions = ip_set_alloc(map->dsize * map->elements); map->extensions = ip_set_alloc(set->dsize * map->elements);
if (!map->extensions) { if (!map->extensions) {
kfree(map->members); kfree(map->members);
return false; return false;
...@@ -239,7 +219,7 @@ init_map_port(struct ip_set *set, struct bitmap_port *map, ...@@ -239,7 +219,7 @@ init_map_port(struct ip_set *set, struct bitmap_port *map,
} }
map->first_port = first_port; map->first_port = first_port;
map->last_port = last_port; map->last_port = last_port;
map->timeout = IPSET_NO_TIMEOUT; set->timeout = IPSET_NO_TIMEOUT;
set->data = map; set->data = map;
set->family = NFPROTO_UNSPEC; set->family = NFPROTO_UNSPEC;
...@@ -248,11 +228,11 @@ init_map_port(struct ip_set *set, struct bitmap_port *map, ...@@ -248,11 +228,11 @@ init_map_port(struct ip_set *set, struct bitmap_port *map,
} }
static int static int
bitmap_port_create(struct ip_set *set, struct nlattr *tb[], u32 flags) bitmap_port_create(struct net *net, struct ip_set *set, struct nlattr *tb[],
u32 flags)
{ {
struct bitmap_port *map; struct bitmap_port *map;
u16 first_port, last_port; u16 first_port, last_port;
u32 cadt_flags = 0;
if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_PORT) || if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
!ip_set_attr_netorder(tb, IPSET_ATTR_PORT_TO) || !ip_set_attr_netorder(tb, IPSET_ATTR_PORT_TO) ||
...@@ -276,53 +256,14 @@ bitmap_port_create(struct ip_set *set, struct nlattr *tb[], u32 flags) ...@@ -276,53 +256,14 @@ bitmap_port_create(struct ip_set *set, struct nlattr *tb[], u32 flags)
map->elements = last_port - first_port + 1; map->elements = last_port - first_port + 1;
map->memsize = map->elements * sizeof(unsigned long); map->memsize = map->elements * sizeof(unsigned long);
set->variant = &bitmap_port; set->variant = &bitmap_port;
if (tb[IPSET_ATTR_CADT_FLAGS]) set->dsize = ip_set_elem_len(set, tb, 0);
cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); if (!init_map_port(set, map, first_port, last_port)) {
if (cadt_flags & IPSET_FLAG_WITH_COUNTERS) { kfree(map);
set->extensions |= IPSET_EXT_COUNTER; return -ENOMEM;
if (tb[IPSET_ATTR_TIMEOUT]) { }
map->dsize = sizeof(struct bitmap_portct_elem); if (tb[IPSET_ATTR_TIMEOUT]) {
map->offset[IPSET_OFFSET_TIMEOUT] = set->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
offsetof(struct bitmap_portct_elem, timeout);
map->offset[IPSET_OFFSET_COUNTER] =
offsetof(struct bitmap_portct_elem, counter);
if (!init_map_port(set, map, first_port, last_port)) {
kfree(map);
return -ENOMEM;
}
map->timeout =
ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
set->extensions |= IPSET_EXT_TIMEOUT;
bitmap_port_gc_init(set, bitmap_port_gc);
} else {
map->dsize = sizeof(struct bitmap_portc_elem);
map->offset[IPSET_OFFSET_COUNTER] =
offsetof(struct bitmap_portc_elem, counter);
if (!init_map_port(set, map, first_port, last_port)) {
kfree(map);
return -ENOMEM;
}
}
} else if (tb[IPSET_ATTR_TIMEOUT]) {
map->dsize = sizeof(struct bitmap_portt_elem);
map->offset[IPSET_OFFSET_TIMEOUT] =
offsetof(struct bitmap_portt_elem, timeout);
if (!init_map_port(set, map, first_port, last_port)) {
kfree(map);
return -ENOMEM;
}
map->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
set->extensions |= IPSET_EXT_TIMEOUT;
bitmap_port_gc_init(set, bitmap_port_gc); bitmap_port_gc_init(set, bitmap_port_gc);
} else {
map->dsize = 0;
if (!init_map_port(set, map, first_port, last_port)) {
kfree(map);
return -ENOMEM;
}
} }
return 0; return 0;
} }
...@@ -333,8 +274,8 @@ static struct ip_set_type bitmap_port_type = { ...@@ -333,8 +274,8 @@ static struct ip_set_type bitmap_port_type = {
.features = IPSET_TYPE_PORT, .features = IPSET_TYPE_PORT,
.dimension = IPSET_DIM_ONE, .dimension = IPSET_DIM_ONE,
.family = NFPROTO_UNSPEC, .family = NFPROTO_UNSPEC,
.revision_min = REVISION_MIN, .revision_min = IPSET_TYPE_REV_MIN,
.revision_max = REVISION_MAX, .revision_max = IPSET_TYPE_REV_MAX,
.create = bitmap_port_create, .create = bitmap_port_create,
.create_policy = { .create_policy = {
[IPSET_ATTR_PORT] = { .type = NLA_U16 }, [IPSET_ATTR_PORT] = { .type = NLA_U16 },
...@@ -349,6 +290,7 @@ static struct ip_set_type bitmap_port_type = { ...@@ -349,6 +290,7 @@ static struct ip_set_type bitmap_port_type = {
[IPSET_ATTR_LINENO] = { .type = NLA_U32 }, [IPSET_ATTR_LINENO] = { .type = NLA_U32 },
[IPSET_ATTR_BYTES] = { .type = NLA_U64 }, [IPSET_ATTR_BYTES] = { .type = NLA_U64 },
[IPSET_ATTR_PACKETS] = { .type = NLA_U64 }, [IPSET_ATTR_PACKETS] = { .type = NLA_U64 },
[IPSET_ATTR_COMMENT] = { .type = NLA_NUL_STRING },
}, },
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
......
This diff is collapsed.
...@@ -102,9 +102,25 @@ ip_set_get_ip4_port(const struct sk_buff *skb, bool src, ...@@ -102,9 +102,25 @@ ip_set_get_ip4_port(const struct sk_buff *skb, bool src,
int protocol = iph->protocol; int protocol = iph->protocol;
/* See comments at tcp_match in ip_tables.c */ /* See comments at tcp_match in ip_tables.c */
if (protocol <= 0 || (ntohs(iph->frag_off) & IP_OFFSET)) if (protocol <= 0)
return false; return false;
if (ntohs(iph->frag_off) & IP_OFFSET)
switch (protocol) {
case IPPROTO_TCP:
case IPPROTO_SCTP:
case IPPROTO_UDP:
case IPPROTO_UDPLITE:
case IPPROTO_ICMP:
/* Port info not available for fragment offset > 0 */
return false;
default:
/* Other protocols doesn't have ports,
so we can match fragments */
*proto = protocol;
return true;
}
return get_port(skb, protocol, protooff, src, port, proto); return get_port(skb, protocol, protooff, src, port, proto);
} }
EXPORT_SYMBOL_GPL(ip_set_get_ip4_port); EXPORT_SYMBOL_GPL(ip_set_get_ip4_port);
......
This diff is collapsed.
...@@ -23,19 +23,20 @@ ...@@ -23,19 +23,20 @@
#include <linux/netfilter/ipset/ip_set.h> #include <linux/netfilter/ipset/ip_set.h>
#include <linux/netfilter/ipset/ip_set_hash.h> #include <linux/netfilter/ipset/ip_set_hash.h>
#define REVISION_MIN 0 #define IPSET_TYPE_REV_MIN 0
#define REVISION_MAX 1 /* Counters support */ /* 1 Counters support */
#define IPSET_TYPE_REV_MAX 2 /* Comments support */
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
IP_SET_MODULE_DESC("hash:ip", REVISION_MIN, REVISION_MAX); IP_SET_MODULE_DESC("hash:ip", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX);
MODULE_ALIAS("ip_set_hash:ip"); MODULE_ALIAS("ip_set_hash:ip");
/* Type specific function prefix */ /* Type specific function prefix */
#define HTYPE hash_ip #define HTYPE hash_ip
#define IP_SET_HASH_WITH_NETMASK #define IP_SET_HASH_WITH_NETMASK
/* IPv4 variants */ /* IPv4 variant */
/* Member elements */ /* Member elements */
struct hash_ip4_elem { struct hash_ip4_elem {
...@@ -43,22 +44,6 @@ struct hash_ip4_elem { ...@@ -43,22 +44,6 @@ struct hash_ip4_elem {
__be32 ip; __be32 ip;
}; };
struct hash_ip4t_elem {
__be32 ip;
unsigned long timeout;
};
struct hash_ip4c_elem {
__be32 ip;
struct ip_set_counter counter;
};
struct hash_ip4ct_elem {
__be32 ip;
struct ip_set_counter counter;
unsigned long timeout;
};
/* Common functions */ /* Common functions */
static inline bool static inline bool
...@@ -99,7 +84,7 @@ hash_ip4_kadt(struct ip_set *set, const struct sk_buff *skb, ...@@ -99,7 +84,7 @@ hash_ip4_kadt(struct ip_set *set, const struct sk_buff *skb,
const struct hash_ip *h = set->data; const struct hash_ip *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt]; ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_ip4_elem e = {}; struct hash_ip4_elem e = {};
struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h); struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
__be32 ip; __be32 ip;
ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &ip); ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &ip);
...@@ -118,8 +103,8 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -118,8 +103,8 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[],
const struct hash_ip *h = set->data; const struct hash_ip *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt]; ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_ip4_elem e = {}; struct hash_ip4_elem e = {};
struct ip_set_ext ext = IP_SET_INIT_UEXT(h); struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
u32 ip, ip_to, hosts; u32 ip = 0, ip_to = 0, hosts;
int ret = 0; int ret = 0;
if (unlikely(!tb[IPSET_ATTR_IP] || if (unlikely(!tb[IPSET_ATTR_IP] ||
...@@ -178,29 +163,13 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -178,29 +163,13 @@ hash_ip4_uadt(struct ip_set *set, struct nlattr *tb[],
return ret; return ret;
} }
/* IPv6 variants */ /* IPv6 variant */
/* Member elements */ /* Member elements */
struct hash_ip6_elem { struct hash_ip6_elem {
union nf_inet_addr ip; union nf_inet_addr ip;
}; };
struct hash_ip6t_elem {
union nf_inet_addr ip;
unsigned long timeout;
};
struct hash_ip6c_elem {
union nf_inet_addr ip;
struct ip_set_counter counter;
};
struct hash_ip6ct_elem {
union nf_inet_addr ip;
struct ip_set_counter counter;
unsigned long timeout;
};
/* Common functions */ /* Common functions */
static inline bool static inline bool
...@@ -253,7 +222,7 @@ hash_ip6_kadt(struct ip_set *set, const struct sk_buff *skb, ...@@ -253,7 +222,7 @@ hash_ip6_kadt(struct ip_set *set, const struct sk_buff *skb,
const struct hash_ip *h = set->data; const struct hash_ip *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt]; ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_ip6_elem e = {}; struct hash_ip6_elem e = {};
struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h); struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip.in6); ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip.in6);
hash_ip6_netmask(&e.ip, h->netmask); hash_ip6_netmask(&e.ip, h->netmask);
...@@ -270,7 +239,7 @@ hash_ip6_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -270,7 +239,7 @@ hash_ip6_uadt(struct ip_set *set, struct nlattr *tb[],
const struct hash_ip *h = set->data; const struct hash_ip *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt]; ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_ip6_elem e = {}; struct hash_ip6_elem e = {};
struct ip_set_ext ext = IP_SET_INIT_UEXT(h); struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
int ret; int ret;
if (unlikely(!tb[IPSET_ATTR_IP] || if (unlikely(!tb[IPSET_ATTR_IP] ||
...@@ -304,8 +273,8 @@ static struct ip_set_type hash_ip_type __read_mostly = { ...@@ -304,8 +273,8 @@ static struct ip_set_type hash_ip_type __read_mostly = {
.features = IPSET_TYPE_IP, .features = IPSET_TYPE_IP,
.dimension = IPSET_DIM_ONE, .dimension = IPSET_DIM_ONE,
.family = NFPROTO_UNSPEC, .family = NFPROTO_UNSPEC,
.revision_min = REVISION_MIN, .revision_min = IPSET_TYPE_REV_MIN,
.revision_max = REVISION_MAX, .revision_max = IPSET_TYPE_REV_MAX,
.create = hash_ip_create, .create = hash_ip_create,
.create_policy = { .create_policy = {
[IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 }, [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 },
...@@ -324,6 +293,7 @@ static struct ip_set_type hash_ip_type __read_mostly = { ...@@ -324,6 +293,7 @@ static struct ip_set_type hash_ip_type __read_mostly = {
[IPSET_ATTR_LINENO] = { .type = NLA_U32 }, [IPSET_ATTR_LINENO] = { .type = NLA_U32 },
[IPSET_ATTR_BYTES] = { .type = NLA_U64 }, [IPSET_ATTR_BYTES] = { .type = NLA_U64 },
[IPSET_ATTR_PACKETS] = { .type = NLA_U64 }, [IPSET_ATTR_PACKETS] = { .type = NLA_U64 },
[IPSET_ATTR_COMMENT] = { .type = NLA_NUL_STRING },
}, },
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
......
...@@ -24,19 +24,20 @@ ...@@ -24,19 +24,20 @@
#include <linux/netfilter/ipset/ip_set_getport.h> #include <linux/netfilter/ipset/ip_set_getport.h>
#include <linux/netfilter/ipset/ip_set_hash.h> #include <linux/netfilter/ipset/ip_set_hash.h>
#define REVISION_MIN 0 #define IPSET_TYPE_REV_MIN 0
/* 1 SCTP and UDPLITE support added */ /* 1 SCTP and UDPLITE support added */
#define REVISION_MAX 2 /* Counters support added */ /* 2 Counters support added */
#define IPSET_TYPE_REV_MAX 3 /* Comments support added */
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
IP_SET_MODULE_DESC("hash:ip,port", REVISION_MIN, REVISION_MAX); IP_SET_MODULE_DESC("hash:ip,port", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX);
MODULE_ALIAS("ip_set_hash:ip,port"); MODULE_ALIAS("ip_set_hash:ip,port");
/* Type specific function prefix */ /* Type specific function prefix */
#define HTYPE hash_ipport #define HTYPE hash_ipport
/* IPv4 variants */ /* IPv4 variant */
/* Member elements */ /* Member elements */
struct hash_ipport4_elem { struct hash_ipport4_elem {
...@@ -46,31 +47,6 @@ struct hash_ipport4_elem { ...@@ -46,31 +47,6 @@ struct hash_ipport4_elem {
u8 padding; u8 padding;
}; };
struct hash_ipport4t_elem {
__be32 ip;
__be16 port;
u8 proto;
u8 padding;
unsigned long timeout;
};
struct hash_ipport4c_elem {
__be32 ip;
__be16 port;
u8 proto;
u8 padding;
struct ip_set_counter counter;
};
struct hash_ipport4ct_elem {
__be32 ip;
__be16 port;
u8 proto;
u8 padding;
struct ip_set_counter counter;
unsigned long timeout;
};
/* Common functions */ /* Common functions */
static inline bool static inline bool
...@@ -116,10 +92,9 @@ hash_ipport4_kadt(struct ip_set *set, const struct sk_buff *skb, ...@@ -116,10 +92,9 @@ hash_ipport4_kadt(struct ip_set *set, const struct sk_buff *skb,
const struct xt_action_param *par, const struct xt_action_param *par,
enum ipset_adt adt, struct ip_set_adt_opt *opt) enum ipset_adt adt, struct ip_set_adt_opt *opt)
{ {
const struct hash_ipport *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt]; ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_ipport4_elem e = { }; struct hash_ipport4_elem e = { };
struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h); struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
if (!ip_set_get_ip4_port(skb, opt->flags & IPSET_DIM_TWO_SRC, if (!ip_set_get_ip4_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
&e.port, &e.proto)) &e.port, &e.proto))
...@@ -136,8 +111,8 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -136,8 +111,8 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
const struct hash_ipport *h = set->data; const struct hash_ipport *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt]; ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_ipport4_elem e = { }; struct hash_ipport4_elem e = { };
struct ip_set_ext ext = IP_SET_INIT_UEXT(h); struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
u32 ip, ip_to, p = 0, port, port_to; u32 ip, ip_to = 0, p = 0, port, port_to;
bool with_ports = false; bool with_ports = false;
int ret; int ret;
...@@ -222,7 +197,7 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -222,7 +197,7 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
return ret; return ret;
} }
/* IPv6 variants */ /* IPv6 variant */
struct hash_ipport6_elem { struct hash_ipport6_elem {
union nf_inet_addr ip; union nf_inet_addr ip;
...@@ -231,31 +206,6 @@ struct hash_ipport6_elem { ...@@ -231,31 +206,6 @@ struct hash_ipport6_elem {
u8 padding; u8 padding;
}; };
struct hash_ipport6t_elem {
union nf_inet_addr ip;
__be16 port;
u8 proto;
u8 padding;
unsigned long timeout;
};
struct hash_ipport6c_elem {
union nf_inet_addr ip;
__be16 port;
u8 proto;
u8 padding;
struct ip_set_counter counter;
};
struct hash_ipport6ct_elem {
union nf_inet_addr ip;
__be16 port;
u8 proto;
u8 padding;
struct ip_set_counter counter;
unsigned long timeout;
};
/* Common functions */ /* Common functions */
static inline bool static inline bool
...@@ -306,10 +256,9 @@ hash_ipport6_kadt(struct ip_set *set, const struct sk_buff *skb, ...@@ -306,10 +256,9 @@ hash_ipport6_kadt(struct ip_set *set, const struct sk_buff *skb,
const struct xt_action_param *par, const struct xt_action_param *par,
enum ipset_adt adt, struct ip_set_adt_opt *opt) enum ipset_adt adt, struct ip_set_adt_opt *opt)
{ {
const struct hash_ipport *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt]; ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_ipport6_elem e = { }; struct hash_ipport6_elem e = { };
struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h); struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
if (!ip_set_get_ip6_port(skb, opt->flags & IPSET_DIM_TWO_SRC, if (!ip_set_get_ip6_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
&e.port, &e.proto)) &e.port, &e.proto))
...@@ -326,7 +275,7 @@ hash_ipport6_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -326,7 +275,7 @@ hash_ipport6_uadt(struct ip_set *set, struct nlattr *tb[],
const struct hash_ipport *h = set->data; const struct hash_ipport *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt]; ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_ipport6_elem e = { }; struct hash_ipport6_elem e = { };
struct ip_set_ext ext = IP_SET_INIT_UEXT(h); struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
u32 port, port_to; u32 port, port_to;
bool with_ports = false; bool with_ports = false;
int ret; int ret;
...@@ -396,8 +345,8 @@ static struct ip_set_type hash_ipport_type __read_mostly = { ...@@ -396,8 +345,8 @@ static struct ip_set_type hash_ipport_type __read_mostly = {
.features = IPSET_TYPE_IP | IPSET_TYPE_PORT, .features = IPSET_TYPE_IP | IPSET_TYPE_PORT,
.dimension = IPSET_DIM_TWO, .dimension = IPSET_DIM_TWO,
.family = NFPROTO_UNSPEC, .family = NFPROTO_UNSPEC,
.revision_min = REVISION_MIN, .revision_min = IPSET_TYPE_REV_MIN,
.revision_max = REVISION_MAX, .revision_max = IPSET_TYPE_REV_MAX,
.create = hash_ipport_create, .create = hash_ipport_create,
.create_policy = { .create_policy = {
[IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 }, [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 },
...@@ -419,6 +368,7 @@ static struct ip_set_type hash_ipport_type __read_mostly = { ...@@ -419,6 +368,7 @@ static struct ip_set_type hash_ipport_type __read_mostly = {
[IPSET_ATTR_LINENO] = { .type = NLA_U32 }, [IPSET_ATTR_LINENO] = { .type = NLA_U32 },
[IPSET_ATTR_BYTES] = { .type = NLA_U64 }, [IPSET_ATTR_BYTES] = { .type = NLA_U64 },
[IPSET_ATTR_PACKETS] = { .type = NLA_U64 }, [IPSET_ATTR_PACKETS] = { .type = NLA_U64 },
[IPSET_ATTR_COMMENT] = { .type = NLA_NUL_STRING },
}, },
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
......
...@@ -24,19 +24,20 @@ ...@@ -24,19 +24,20 @@
#include <linux/netfilter/ipset/ip_set_getport.h> #include <linux/netfilter/ipset/ip_set_getport.h>
#include <linux/netfilter/ipset/ip_set_hash.h> #include <linux/netfilter/ipset/ip_set_hash.h>
#define REVISION_MIN 0 #define IPSET_TYPE_REV_MIN 0
/* 1 SCTP and UDPLITE support added */ /* 1 SCTP and UDPLITE support added */
#define REVISION_MAX 2 /* Counters support added */ /* 2 Counters support added */
#define IPSET_TYPE_REV_MAX 3 /* Comments support added */
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
IP_SET_MODULE_DESC("hash:ip,port,ip", REVISION_MIN, REVISION_MAX); IP_SET_MODULE_DESC("hash:ip,port,ip", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX);
MODULE_ALIAS("ip_set_hash:ip,port,ip"); MODULE_ALIAS("ip_set_hash:ip,port,ip");
/* Type specific function prefix */ /* Type specific function prefix */
#define HTYPE hash_ipportip #define HTYPE hash_ipportip
/* IPv4 variants */ /* IPv4 variant */
/* Member elements */ /* Member elements */
struct hash_ipportip4_elem { struct hash_ipportip4_elem {
...@@ -47,34 +48,6 @@ struct hash_ipportip4_elem { ...@@ -47,34 +48,6 @@ struct hash_ipportip4_elem {
u8 padding; u8 padding;
}; };
struct hash_ipportip4t_elem {
__be32 ip;
__be32 ip2;
__be16 port;
u8 proto;
u8 padding;
unsigned long timeout;
};
struct hash_ipportip4c_elem {
__be32 ip;
__be32 ip2;
__be16 port;
u8 proto;
u8 padding;
struct ip_set_counter counter;
};
struct hash_ipportip4ct_elem {
__be32 ip;
__be32 ip2;
__be16 port;
u8 proto;
u8 padding;
struct ip_set_counter counter;
unsigned long timeout;
};
static inline bool static inline bool
hash_ipportip4_data_equal(const struct hash_ipportip4_elem *ip1, hash_ipportip4_data_equal(const struct hash_ipportip4_elem *ip1,
const struct hash_ipportip4_elem *ip2, const struct hash_ipportip4_elem *ip2,
...@@ -120,10 +93,9 @@ hash_ipportip4_kadt(struct ip_set *set, const struct sk_buff *skb, ...@@ -120,10 +93,9 @@ hash_ipportip4_kadt(struct ip_set *set, const struct sk_buff *skb,
const struct xt_action_param *par, const struct xt_action_param *par,
enum ipset_adt adt, struct ip_set_adt_opt *opt) enum ipset_adt adt, struct ip_set_adt_opt *opt)
{ {
const struct hash_ipportip *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt]; ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_ipportip4_elem e = { }; struct hash_ipportip4_elem e = { };
struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h); struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
if (!ip_set_get_ip4_port(skb, opt->flags & IPSET_DIM_TWO_SRC, if (!ip_set_get_ip4_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
&e.port, &e.proto)) &e.port, &e.proto))
...@@ -141,8 +113,8 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -141,8 +113,8 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
const struct hash_ipportip *h = set->data; const struct hash_ipportip *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt]; ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_ipportip4_elem e = { }; struct hash_ipportip4_elem e = { };
struct ip_set_ext ext = IP_SET_INIT_UEXT(h); struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
u32 ip, ip_to, p = 0, port, port_to; u32 ip, ip_to = 0, p = 0, port, port_to;
bool with_ports = false; bool with_ports = false;
int ret; int ret;
...@@ -231,7 +203,7 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -231,7 +203,7 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
return ret; return ret;
} }
/* IPv6 variants */ /* IPv6 variant */
struct hash_ipportip6_elem { struct hash_ipportip6_elem {
union nf_inet_addr ip; union nf_inet_addr ip;
...@@ -241,34 +213,6 @@ struct hash_ipportip6_elem { ...@@ -241,34 +213,6 @@ struct hash_ipportip6_elem {
u8 padding; u8 padding;
}; };
struct hash_ipportip6t_elem {
union nf_inet_addr ip;
union nf_inet_addr ip2;
__be16 port;
u8 proto;
u8 padding;
unsigned long timeout;
};
struct hash_ipportip6c_elem {
union nf_inet_addr ip;
union nf_inet_addr ip2;
__be16 port;
u8 proto;
u8 padding;
struct ip_set_counter counter;
};
struct hash_ipportip6ct_elem {
union nf_inet_addr ip;
union nf_inet_addr ip2;
__be16 port;
u8 proto;
u8 padding;
struct ip_set_counter counter;
unsigned long timeout;
};
/* Common functions */ /* Common functions */
static inline bool static inline bool
...@@ -319,10 +263,9 @@ hash_ipportip6_kadt(struct ip_set *set, const struct sk_buff *skb, ...@@ -319,10 +263,9 @@ hash_ipportip6_kadt(struct ip_set *set, const struct sk_buff *skb,
const struct xt_action_param *par, const struct xt_action_param *par,
enum ipset_adt adt, struct ip_set_adt_opt *opt) enum ipset_adt adt, struct ip_set_adt_opt *opt)
{ {
const struct hash_ipportip *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt]; ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_ipportip6_elem e = { }; struct hash_ipportip6_elem e = { };
struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h); struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
if (!ip_set_get_ip6_port(skb, opt->flags & IPSET_DIM_TWO_SRC, if (!ip_set_get_ip6_port(skb, opt->flags & IPSET_DIM_TWO_SRC,
&e.port, &e.proto)) &e.port, &e.proto))
...@@ -340,7 +283,7 @@ hash_ipportip6_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -340,7 +283,7 @@ hash_ipportip6_uadt(struct ip_set *set, struct nlattr *tb[],
const struct hash_ipportip *h = set->data; const struct hash_ipportip *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt]; ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_ipportip6_elem e = { }; struct hash_ipportip6_elem e = { };
struct ip_set_ext ext = IP_SET_INIT_UEXT(h); struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
u32 port, port_to; u32 port, port_to;
bool with_ports = false; bool with_ports = false;
int ret; int ret;
...@@ -414,8 +357,8 @@ static struct ip_set_type hash_ipportip_type __read_mostly = { ...@@ -414,8 +357,8 @@ static struct ip_set_type hash_ipportip_type __read_mostly = {
.features = IPSET_TYPE_IP | IPSET_TYPE_PORT | IPSET_TYPE_IP2, .features = IPSET_TYPE_IP | IPSET_TYPE_PORT | IPSET_TYPE_IP2,
.dimension = IPSET_DIM_THREE, .dimension = IPSET_DIM_THREE,
.family = NFPROTO_UNSPEC, .family = NFPROTO_UNSPEC,
.revision_min = REVISION_MIN, .revision_min = IPSET_TYPE_REV_MIN,
.revision_max = REVISION_MAX, .revision_max = IPSET_TYPE_REV_MAX,
.create = hash_ipportip_create, .create = hash_ipportip_create,
.create_policy = { .create_policy = {
[IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 }, [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 },
...@@ -437,6 +380,7 @@ static struct ip_set_type hash_ipportip_type __read_mostly = { ...@@ -437,6 +380,7 @@ static struct ip_set_type hash_ipportip_type __read_mostly = {
[IPSET_ATTR_LINENO] = { .type = NLA_U32 }, [IPSET_ATTR_LINENO] = { .type = NLA_U32 },
[IPSET_ATTR_BYTES] = { .type = NLA_U64 }, [IPSET_ATTR_BYTES] = { .type = NLA_U64 },
[IPSET_ATTR_PACKETS] = { .type = NLA_U64 }, [IPSET_ATTR_PACKETS] = { .type = NLA_U64 },
[IPSET_ATTR_COMMENT] = { .type = NLA_NUL_STRING },
}, },
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
......
...@@ -24,15 +24,16 @@ ...@@ -24,15 +24,16 @@
#include <linux/netfilter/ipset/ip_set_getport.h> #include <linux/netfilter/ipset/ip_set_getport.h>
#include <linux/netfilter/ipset/ip_set_hash.h> #include <linux/netfilter/ipset/ip_set_hash.h>
#define REVISION_MIN 0 #define IPSET_TYPE_REV_MIN 0
/* 1 SCTP and UDPLITE support added */ /* 1 SCTP and UDPLITE support added */
/* 2 Range as input support for IPv4 added */ /* 2 Range as input support for IPv4 added */
/* 3 nomatch flag support added */ /* 3 nomatch flag support added */
#define REVISION_MAX 4 /* Counters support added */ /* 4 Counters support added */
#define IPSET_TYPE_REV_MAX 5 /* Comments support added */
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
IP_SET_MODULE_DESC("hash:ip,port,net", REVISION_MIN, REVISION_MAX); IP_SET_MODULE_DESC("hash:ip,port,net", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX);
MODULE_ALIAS("ip_set_hash:ip,port,net"); MODULE_ALIAS("ip_set_hash:ip,port,net");
/* Type specific function prefix */ /* Type specific function prefix */
...@@ -46,7 +47,7 @@ MODULE_ALIAS("ip_set_hash:ip,port,net"); ...@@ -46,7 +47,7 @@ MODULE_ALIAS("ip_set_hash:ip,port,net");
#define IP_SET_HASH_WITH_PROTO #define IP_SET_HASH_WITH_PROTO
#define IP_SET_HASH_WITH_NETS #define IP_SET_HASH_WITH_NETS
/* IPv4 variants */ /* IPv4 variant */
/* Member elements */ /* Member elements */
struct hash_ipportnet4_elem { struct hash_ipportnet4_elem {
...@@ -58,37 +59,6 @@ struct hash_ipportnet4_elem { ...@@ -58,37 +59,6 @@ struct hash_ipportnet4_elem {
u8 proto; u8 proto;
}; };
struct hash_ipportnet4t_elem {
__be32 ip;
__be32 ip2;
__be16 port;
u8 cidr:7;
u8 nomatch:1;
u8 proto;
unsigned long timeout;
};
struct hash_ipportnet4c_elem {
__be32 ip;
__be32 ip2;
__be16 port;
u8 cidr:7;
u8 nomatch:1;
u8 proto;
struct ip_set_counter counter;
};
struct hash_ipportnet4ct_elem {
__be32 ip;
__be32 ip2;
__be16 port;
u8 cidr:7;
u8 nomatch:1;
u8 proto;
struct ip_set_counter counter;
unsigned long timeout;
};
/* Common functions */ /* Common functions */
static inline bool static inline bool
...@@ -170,9 +140,9 @@ hash_ipportnet4_kadt(struct ip_set *set, const struct sk_buff *skb, ...@@ -170,9 +140,9 @@ hash_ipportnet4_kadt(struct ip_set *set, const struct sk_buff *skb,
const struct hash_ipportnet *h = set->data; const struct hash_ipportnet *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt]; ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_ipportnet4_elem e = { struct hash_ipportnet4_elem e = {
.cidr = h->nets[0].cidr ? h->nets[0].cidr - 1 : HOST_MASK - 1 .cidr = IP_SET_INIT_CIDR(h->nets[0].cidr[0], HOST_MASK) - 1,
}; };
struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h); struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
if (adt == IPSET_TEST) if (adt == IPSET_TEST)
e.cidr = HOST_MASK - 1; e.cidr = HOST_MASK - 1;
...@@ -195,9 +165,9 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -195,9 +165,9 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
const struct hash_ipportnet *h = set->data; const struct hash_ipportnet *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt]; ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_ipportnet4_elem e = { .cidr = HOST_MASK - 1 }; struct hash_ipportnet4_elem e = { .cidr = HOST_MASK - 1 };
struct ip_set_ext ext = IP_SET_INIT_UEXT(h); struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
u32 ip, ip_to, p = 0, port, port_to; u32 ip = 0, ip_to = 0, p = 0, port, port_to;
u32 ip2_from, ip2_to, ip2_last, ip2; u32 ip2_from = 0, ip2_to = 0, ip2_last, ip2;
bool with_ports = false; bool with_ports = false;
u8 cidr; u8 cidr;
int ret; int ret;
...@@ -272,7 +242,7 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -272,7 +242,7 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
if (ip > ip_to) if (ip > ip_to)
swap(ip, ip_to); swap(ip, ip_to);
} else if (tb[IPSET_ATTR_CIDR]) { } else if (tb[IPSET_ATTR_CIDR]) {
u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]); cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
if (!cidr || cidr > 32) if (!cidr || cidr > 32)
return -IPSET_ERR_INVALID_CIDR; return -IPSET_ERR_INVALID_CIDR;
...@@ -306,9 +276,9 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -306,9 +276,9 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
: port; : port;
for (; p <= port_to; p++) { for (; p <= port_to; p++) {
e.port = htons(p); e.port = htons(p);
ip2 = retried ip2 = retried &&
&& ip == ntohl(h->next.ip) ip == ntohl(h->next.ip) &&
&& p == ntohs(h->next.port) p == ntohs(h->next.port)
? ntohl(h->next.ip2) : ip2_from; ? ntohl(h->next.ip2) : ip2_from;
while (!after(ip2, ip2_to)) { while (!after(ip2, ip2_to)) {
e.ip2 = htonl(ip2); e.ip2 = htonl(ip2);
...@@ -328,7 +298,7 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -328,7 +298,7 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
return ret; return ret;
} }
/* IPv6 variants */ /* IPv6 variant */
struct hash_ipportnet6_elem { struct hash_ipportnet6_elem {
union nf_inet_addr ip; union nf_inet_addr ip;
...@@ -339,37 +309,6 @@ struct hash_ipportnet6_elem { ...@@ -339,37 +309,6 @@ struct hash_ipportnet6_elem {
u8 proto; u8 proto;
}; };
struct hash_ipportnet6t_elem {
union nf_inet_addr ip;
union nf_inet_addr ip2;
__be16 port;
u8 cidr:7;
u8 nomatch:1;
u8 proto;
unsigned long timeout;
};
struct hash_ipportnet6c_elem {
union nf_inet_addr ip;
union nf_inet_addr ip2;
__be16 port;
u8 cidr:7;
u8 nomatch:1;
u8 proto;
struct ip_set_counter counter;
};
struct hash_ipportnet6ct_elem {
union nf_inet_addr ip;
union nf_inet_addr ip2;
__be16 port;
u8 cidr:7;
u8 nomatch:1;
u8 proto;
struct ip_set_counter counter;
unsigned long timeout;
};
/* Common functions */ /* Common functions */
static inline bool static inline bool
...@@ -454,9 +393,9 @@ hash_ipportnet6_kadt(struct ip_set *set, const struct sk_buff *skb, ...@@ -454,9 +393,9 @@ hash_ipportnet6_kadt(struct ip_set *set, const struct sk_buff *skb,
const struct hash_ipportnet *h = set->data; const struct hash_ipportnet *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt]; ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_ipportnet6_elem e = { struct hash_ipportnet6_elem e = {
.cidr = h->nets[0].cidr ? h->nets[0].cidr - 1 : HOST_MASK - 1 .cidr = IP_SET_INIT_CIDR(h->nets[0].cidr[0], HOST_MASK) - 1,
}; };
struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h); struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
if (adt == IPSET_TEST) if (adt == IPSET_TEST)
e.cidr = HOST_MASK - 1; e.cidr = HOST_MASK - 1;
...@@ -479,7 +418,7 @@ hash_ipportnet6_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -479,7 +418,7 @@ hash_ipportnet6_uadt(struct ip_set *set, struct nlattr *tb[],
const struct hash_ipportnet *h = set->data; const struct hash_ipportnet *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt]; ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_ipportnet6_elem e = { .cidr = HOST_MASK - 1 }; struct hash_ipportnet6_elem e = { .cidr = HOST_MASK - 1 };
struct ip_set_ext ext = IP_SET_INIT_UEXT(h); struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
u32 port, port_to; u32 port, port_to;
bool with_ports = false; bool with_ports = false;
u8 cidr; u8 cidr;
...@@ -574,8 +513,8 @@ static struct ip_set_type hash_ipportnet_type __read_mostly = { ...@@ -574,8 +513,8 @@ static struct ip_set_type hash_ipportnet_type __read_mostly = {
IPSET_TYPE_NOMATCH, IPSET_TYPE_NOMATCH,
.dimension = IPSET_DIM_THREE, .dimension = IPSET_DIM_THREE,
.family = NFPROTO_UNSPEC, .family = NFPROTO_UNSPEC,
.revision_min = REVISION_MIN, .revision_min = IPSET_TYPE_REV_MIN,
.revision_max = REVISION_MAX, .revision_max = IPSET_TYPE_REV_MAX,
.create = hash_ipportnet_create, .create = hash_ipportnet_create,
.create_policy = { .create_policy = {
[IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 }, [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 },
...@@ -600,6 +539,7 @@ static struct ip_set_type hash_ipportnet_type __read_mostly = { ...@@ -600,6 +539,7 @@ static struct ip_set_type hash_ipportnet_type __read_mostly = {
[IPSET_ATTR_LINENO] = { .type = NLA_U32 }, [IPSET_ATTR_LINENO] = { .type = NLA_U32 },
[IPSET_ATTR_BYTES] = { .type = NLA_U64 }, [IPSET_ATTR_BYTES] = { .type = NLA_U64 },
[IPSET_ATTR_PACKETS] = { .type = NLA_U64 }, [IPSET_ATTR_PACKETS] = { .type = NLA_U64 },
[IPSET_ATTR_COMMENT] = { .type = NLA_NUL_STRING },
}, },
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
......
...@@ -22,21 +22,22 @@ ...@@ -22,21 +22,22 @@
#include <linux/netfilter/ipset/ip_set.h> #include <linux/netfilter/ipset/ip_set.h>
#include <linux/netfilter/ipset/ip_set_hash.h> #include <linux/netfilter/ipset/ip_set_hash.h>
#define REVISION_MIN 0 #define IPSET_TYPE_REV_MIN 0
/* 1 Range as input support for IPv4 added */ /* 1 Range as input support for IPv4 added */
/* 2 nomatch flag support added */ /* 2 nomatch flag support added */
#define REVISION_MAX 3 /* Counters support added */ /* 3 Counters support added */
#define IPSET_TYPE_REV_MAX 4 /* Comments support added */
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
IP_SET_MODULE_DESC("hash:net", REVISION_MIN, REVISION_MAX); IP_SET_MODULE_DESC("hash:net", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX);
MODULE_ALIAS("ip_set_hash:net"); MODULE_ALIAS("ip_set_hash:net");
/* Type specific function prefix */ /* Type specific function prefix */
#define HTYPE hash_net #define HTYPE hash_net
#define IP_SET_HASH_WITH_NETS #define IP_SET_HASH_WITH_NETS
/* IPv4 variants */ /* IPv4 variant */
/* Member elements */ /* Member elements */
struct hash_net4_elem { struct hash_net4_elem {
...@@ -46,31 +47,6 @@ struct hash_net4_elem { ...@@ -46,31 +47,6 @@ struct hash_net4_elem {
u8 cidr; u8 cidr;
}; };
struct hash_net4t_elem {
__be32 ip;
u16 padding0;
u8 nomatch;
u8 cidr;
unsigned long timeout;
};
struct hash_net4c_elem {
__be32 ip;
u16 padding0;
u8 nomatch;
u8 cidr;
struct ip_set_counter counter;
};
struct hash_net4ct_elem {
__be32 ip;
u16 padding0;
u8 nomatch;
u8 cidr;
struct ip_set_counter counter;
unsigned long timeout;
};
/* Common functions */ /* Common functions */
static inline bool static inline bool
...@@ -143,9 +119,9 @@ hash_net4_kadt(struct ip_set *set, const struct sk_buff *skb, ...@@ -143,9 +119,9 @@ hash_net4_kadt(struct ip_set *set, const struct sk_buff *skb,
const struct hash_net *h = set->data; const struct hash_net *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt]; ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_net4_elem e = { struct hash_net4_elem e = {
.cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK .cidr = IP_SET_INIT_CIDR(h->nets[0].cidr[0], HOST_MASK),
}; };
struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h); struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
if (e.cidr == 0) if (e.cidr == 0)
return -EINVAL; return -EINVAL;
...@@ -165,8 +141,8 @@ hash_net4_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -165,8 +141,8 @@ hash_net4_uadt(struct ip_set *set, struct nlattr *tb[],
const struct hash_net *h = set->data; const struct hash_net *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt]; ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_net4_elem e = { .cidr = HOST_MASK }; struct hash_net4_elem e = { .cidr = HOST_MASK };
struct ip_set_ext ext = IP_SET_INIT_UEXT(h); struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
u32 ip = 0, ip_to, last; u32 ip = 0, ip_to = 0, last;
int ret; int ret;
if (unlikely(!tb[IPSET_ATTR_IP] || if (unlikely(!tb[IPSET_ATTR_IP] ||
...@@ -228,7 +204,7 @@ hash_net4_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -228,7 +204,7 @@ hash_net4_uadt(struct ip_set *set, struct nlattr *tb[],
return ret; return ret;
} }
/* IPv6 variants */ /* IPv6 variant */
struct hash_net6_elem { struct hash_net6_elem {
union nf_inet_addr ip; union nf_inet_addr ip;
...@@ -237,31 +213,6 @@ struct hash_net6_elem { ...@@ -237,31 +213,6 @@ struct hash_net6_elem {
u8 cidr; u8 cidr;
}; };
struct hash_net6t_elem {
union nf_inet_addr ip;
u16 padding0;
u8 nomatch;
u8 cidr;
unsigned long timeout;
};
struct hash_net6c_elem {
union nf_inet_addr ip;
u16 padding0;
u8 nomatch;
u8 cidr;
struct ip_set_counter counter;
};
struct hash_net6ct_elem {
union nf_inet_addr ip;
u16 padding0;
u8 nomatch;
u8 cidr;
struct ip_set_counter counter;
unsigned long timeout;
};
/* Common functions */ /* Common functions */
static inline bool static inline bool
...@@ -338,9 +289,9 @@ hash_net6_kadt(struct ip_set *set, const struct sk_buff *skb, ...@@ -338,9 +289,9 @@ hash_net6_kadt(struct ip_set *set, const struct sk_buff *skb,
const struct hash_net *h = set->data; const struct hash_net *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt]; ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_net6_elem e = { struct hash_net6_elem e = {
.cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK .cidr = IP_SET_INIT_CIDR(h->nets[0].cidr[0], HOST_MASK),
}; };
struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h); struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
if (e.cidr == 0) if (e.cidr == 0)
return -EINVAL; return -EINVAL;
...@@ -357,10 +308,9 @@ static int ...@@ -357,10 +308,9 @@ static int
hash_net6_uadt(struct ip_set *set, struct nlattr *tb[], hash_net6_uadt(struct ip_set *set, struct nlattr *tb[],
enum ipset_adt adt, u32 *lineno, u32 flags, bool retried) enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
{ {
const struct hash_net *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt]; ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_net6_elem e = { .cidr = HOST_MASK }; struct hash_net6_elem e = { .cidr = HOST_MASK };
struct ip_set_ext ext = IP_SET_INIT_UEXT(h); struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
int ret; int ret;
if (unlikely(!tb[IPSET_ATTR_IP] || if (unlikely(!tb[IPSET_ATTR_IP] ||
...@@ -406,8 +356,8 @@ static struct ip_set_type hash_net_type __read_mostly = { ...@@ -406,8 +356,8 @@ static struct ip_set_type hash_net_type __read_mostly = {
.features = IPSET_TYPE_IP | IPSET_TYPE_NOMATCH, .features = IPSET_TYPE_IP | IPSET_TYPE_NOMATCH,
.dimension = IPSET_DIM_ONE, .dimension = IPSET_DIM_ONE,
.family = NFPROTO_UNSPEC, .family = NFPROTO_UNSPEC,
.revision_min = REVISION_MIN, .revision_min = IPSET_TYPE_REV_MIN,
.revision_max = REVISION_MAX, .revision_max = IPSET_TYPE_REV_MAX,
.create = hash_net_create, .create = hash_net_create,
.create_policy = { .create_policy = {
[IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 }, [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 },
...@@ -425,6 +375,7 @@ static struct ip_set_type hash_net_type __read_mostly = { ...@@ -425,6 +375,7 @@ static struct ip_set_type hash_net_type __read_mostly = {
[IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 }, [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
[IPSET_ATTR_BYTES] = { .type = NLA_U64 }, [IPSET_ATTR_BYTES] = { .type = NLA_U64 },
[IPSET_ATTR_PACKETS] = { .type = NLA_U64 }, [IPSET_ATTR_PACKETS] = { .type = NLA_U64 },
[IPSET_ATTR_COMMENT] = { .type = NLA_NUL_STRING },
}, },
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
......
...@@ -23,14 +23,15 @@ ...@@ -23,14 +23,15 @@
#include <linux/netfilter/ipset/ip_set.h> #include <linux/netfilter/ipset/ip_set.h>
#include <linux/netfilter/ipset/ip_set_hash.h> #include <linux/netfilter/ipset/ip_set_hash.h>
#define REVISION_MIN 0 #define IPSET_TYPE_REV_MIN 0
/* 1 nomatch flag support added */ /* 1 nomatch flag support added */
/* 2 /0 support added */ /* 2 /0 support added */
#define REVISION_MAX 3 /* Counters support added */ /* 3 Counters support added */
#define IPSET_TYPE_REV_MAX 4 /* Comments support added */
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
IP_SET_MODULE_DESC("hash:net,iface", REVISION_MIN, REVISION_MAX); IP_SET_MODULE_DESC("hash:net,iface", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX);
MODULE_ALIAS("ip_set_hash:net,iface"); MODULE_ALIAS("ip_set_hash:net,iface");
/* Interface name rbtree */ /* Interface name rbtree */
...@@ -134,7 +135,7 @@ iface_add(struct rb_root *root, const char **iface) ...@@ -134,7 +135,7 @@ iface_add(struct rb_root *root, const char **iface)
#define STREQ(a, b) (strcmp(a, b) == 0) #define STREQ(a, b) (strcmp(a, b) == 0)
/* IPv4 variants */ /* IPv4 variant */
struct hash_netiface4_elem_hashed { struct hash_netiface4_elem_hashed {
__be32 ip; __be32 ip;
...@@ -144,7 +145,7 @@ struct hash_netiface4_elem_hashed { ...@@ -144,7 +145,7 @@ struct hash_netiface4_elem_hashed {
u8 elem; u8 elem;
}; };
/* Member elements without timeout */ /* Member elements */
struct hash_netiface4_elem { struct hash_netiface4_elem {
__be32 ip; __be32 ip;
u8 physdev; u8 physdev;
...@@ -154,37 +155,6 @@ struct hash_netiface4_elem { ...@@ -154,37 +155,6 @@ struct hash_netiface4_elem {
const char *iface; const char *iface;
}; };
struct hash_netiface4t_elem {
__be32 ip;
u8 physdev;
u8 cidr;
u8 nomatch;
u8 elem;
const char *iface;
unsigned long timeout;
};
struct hash_netiface4c_elem {
__be32 ip;
u8 physdev;
u8 cidr;
u8 nomatch;
u8 elem;
const char *iface;
struct ip_set_counter counter;
};
struct hash_netiface4ct_elem {
__be32 ip;
u8 physdev;
u8 cidr;
u8 nomatch;
u8 elem;
const char *iface;
struct ip_set_counter counter;
unsigned long timeout;
};
/* Common functions */ /* Common functions */
static inline bool static inline bool
...@@ -265,10 +235,10 @@ hash_netiface4_kadt(struct ip_set *set, const struct sk_buff *skb, ...@@ -265,10 +235,10 @@ hash_netiface4_kadt(struct ip_set *set, const struct sk_buff *skb,
struct hash_netiface *h = set->data; struct hash_netiface *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt]; ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_netiface4_elem e = { struct hash_netiface4_elem e = {
.cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK, .cidr = IP_SET_INIT_CIDR(h->nets[0].cidr[0], HOST_MASK),
.elem = 1, .elem = 1,
}; };
struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h); struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
int ret; int ret;
if (e.cidr == 0) if (e.cidr == 0)
...@@ -319,8 +289,8 @@ hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -319,8 +289,8 @@ hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[],
struct hash_netiface *h = set->data; struct hash_netiface *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt]; ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_netiface4_elem e = { .cidr = HOST_MASK, .elem = 1 }; struct hash_netiface4_elem e = { .cidr = HOST_MASK, .elem = 1 };
struct ip_set_ext ext = IP_SET_INIT_UEXT(h); struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
u32 ip = 0, ip_to, last; u32 ip = 0, ip_to = 0, last;
char iface[IFNAMSIZ]; char iface[IFNAMSIZ];
int ret; int ret;
...@@ -399,7 +369,7 @@ hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -399,7 +369,7 @@ hash_netiface4_uadt(struct ip_set *set, struct nlattr *tb[],
return ret; return ret;
} }
/* IPv6 variants */ /* IPv6 variant */
struct hash_netiface6_elem_hashed { struct hash_netiface6_elem_hashed {
union nf_inet_addr ip; union nf_inet_addr ip;
...@@ -418,37 +388,6 @@ struct hash_netiface6_elem { ...@@ -418,37 +388,6 @@ struct hash_netiface6_elem {
const char *iface; const char *iface;
}; };
struct hash_netiface6t_elem {
union nf_inet_addr ip;
u8 physdev;
u8 cidr;
u8 nomatch;
u8 elem;
const char *iface;
unsigned long timeout;
};
struct hash_netiface6c_elem {
union nf_inet_addr ip;
u8 physdev;
u8 cidr;
u8 nomatch;
u8 elem;
const char *iface;
struct ip_set_counter counter;
};
struct hash_netiface6ct_elem {
union nf_inet_addr ip;
u8 physdev;
u8 cidr;
u8 nomatch;
u8 elem;
const char *iface;
struct ip_set_counter counter;
unsigned long timeout;
};
/* Common functions */ /* Common functions */
static inline bool static inline bool
...@@ -534,10 +473,10 @@ hash_netiface6_kadt(struct ip_set *set, const struct sk_buff *skb, ...@@ -534,10 +473,10 @@ hash_netiface6_kadt(struct ip_set *set, const struct sk_buff *skb,
struct hash_netiface *h = set->data; struct hash_netiface *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt]; ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_netiface6_elem e = { struct hash_netiface6_elem e = {
.cidr = h->nets[0].cidr ? h->nets[0].cidr : HOST_MASK, .cidr = IP_SET_INIT_CIDR(h->nets[0].cidr[0], HOST_MASK),
.elem = 1, .elem = 1,
}; };
struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h); struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
int ret; int ret;
if (e.cidr == 0) if (e.cidr == 0)
...@@ -584,7 +523,7 @@ hash_netiface6_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -584,7 +523,7 @@ hash_netiface6_uadt(struct ip_set *set, struct nlattr *tb[],
struct hash_netiface *h = set->data; struct hash_netiface *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt]; ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_netiface6_elem e = { .cidr = HOST_MASK, .elem = 1 }; struct hash_netiface6_elem e = { .cidr = HOST_MASK, .elem = 1 };
struct ip_set_ext ext = IP_SET_INIT_UEXT(h); struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
char iface[IFNAMSIZ]; char iface[IFNAMSIZ];
int ret; int ret;
...@@ -645,8 +584,8 @@ static struct ip_set_type hash_netiface_type __read_mostly = { ...@@ -645,8 +584,8 @@ static struct ip_set_type hash_netiface_type __read_mostly = {
IPSET_TYPE_NOMATCH, IPSET_TYPE_NOMATCH,
.dimension = IPSET_DIM_TWO, .dimension = IPSET_DIM_TWO,
.family = NFPROTO_UNSPEC, .family = NFPROTO_UNSPEC,
.revision_min = REVISION_MIN, .revision_min = IPSET_TYPE_REV_MIN,
.revision_max = REVISION_MAX, .revision_max = IPSET_TYPE_REV_MAX,
.create = hash_netiface_create, .create = hash_netiface_create,
.create_policy = { .create_policy = {
[IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 }, [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 },
...@@ -668,6 +607,7 @@ static struct ip_set_type hash_netiface_type __read_mostly = { ...@@ -668,6 +607,7 @@ static struct ip_set_type hash_netiface_type __read_mostly = {
[IPSET_ATTR_LINENO] = { .type = NLA_U32 }, [IPSET_ATTR_LINENO] = { .type = NLA_U32 },
[IPSET_ATTR_BYTES] = { .type = NLA_U64 }, [IPSET_ATTR_BYTES] = { .type = NLA_U64 },
[IPSET_ATTR_PACKETS] = { .type = NLA_U64 }, [IPSET_ATTR_PACKETS] = { .type = NLA_U64 },
[IPSET_ATTR_COMMENT] = { .type = NLA_NUL_STRING },
}, },
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
......
This diff is collapsed.
...@@ -23,15 +23,16 @@ ...@@ -23,15 +23,16 @@
#include <linux/netfilter/ipset/ip_set_getport.h> #include <linux/netfilter/ipset/ip_set_getport.h>
#include <linux/netfilter/ipset/ip_set_hash.h> #include <linux/netfilter/ipset/ip_set_hash.h>
#define REVISION_MIN 0 #define IPSET_TYPE_REV_MIN 0
/* 1 SCTP and UDPLITE support added */ /* 1 SCTP and UDPLITE support added */
/* 2 Range as input support for IPv4 added */ /* 2 Range as input support for IPv4 added */
/* 3 nomatch flag support added */ /* 3 nomatch flag support added */
#define REVISION_MAX 4 /* Counters support added */ /* 4 Counters support added */
#define IPSET_TYPE_REV_MAX 5 /* Comments support added */
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
IP_SET_MODULE_DESC("hash:net,port", REVISION_MIN, REVISION_MAX); IP_SET_MODULE_DESC("hash:net,port", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX);
MODULE_ALIAS("ip_set_hash:net,port"); MODULE_ALIAS("ip_set_hash:net,port");
/* Type specific function prefix */ /* Type specific function prefix */
...@@ -45,7 +46,7 @@ MODULE_ALIAS("ip_set_hash:net,port"); ...@@ -45,7 +46,7 @@ MODULE_ALIAS("ip_set_hash:net,port");
*/ */
#define IP_SET_HASH_WITH_NETS_PACKED #define IP_SET_HASH_WITH_NETS_PACKED
/* IPv4 variants */ /* IPv4 variant */
/* Member elements */ /* Member elements */
struct hash_netport4_elem { struct hash_netport4_elem {
...@@ -56,34 +57,6 @@ struct hash_netport4_elem { ...@@ -56,34 +57,6 @@ struct hash_netport4_elem {
u8 nomatch:1; u8 nomatch:1;
}; };
struct hash_netport4t_elem {
__be32 ip;
__be16 port;
u8 proto;
u8 cidr:7;
u8 nomatch:1;
unsigned long timeout;
};
struct hash_netport4c_elem {
__be32 ip;
__be16 port;
u8 proto;
u8 cidr:7;
u8 nomatch:1;
struct ip_set_counter counter;
};
struct hash_netport4ct_elem {
__be32 ip;
__be16 port;
u8 proto;
u8 cidr:7;
u8 nomatch:1;
struct ip_set_counter counter;
unsigned long timeout;
};
/* Common functions */ /* Common functions */
static inline bool static inline bool
...@@ -162,9 +135,9 @@ hash_netport4_kadt(struct ip_set *set, const struct sk_buff *skb, ...@@ -162,9 +135,9 @@ hash_netport4_kadt(struct ip_set *set, const struct sk_buff *skb,
const struct hash_netport *h = set->data; const struct hash_netport *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt]; ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_netport4_elem e = { struct hash_netport4_elem e = {
.cidr = h->nets[0].cidr ? h->nets[0].cidr - 1 : HOST_MASK - 1 .cidr = IP_SET_INIT_CIDR(h->nets[0].cidr[0], HOST_MASK) - 1,
}; };
struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h); struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
if (adt == IPSET_TEST) if (adt == IPSET_TEST)
e.cidr = HOST_MASK - 1; e.cidr = HOST_MASK - 1;
...@@ -186,8 +159,8 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -186,8 +159,8 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[],
const struct hash_netport *h = set->data; const struct hash_netport *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt]; ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_netport4_elem e = { .cidr = HOST_MASK - 1 }; struct hash_netport4_elem e = { .cidr = HOST_MASK - 1 };
struct ip_set_ext ext = IP_SET_INIT_UEXT(h); struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
u32 port, port_to, p = 0, ip = 0, ip_to, last; u32 port, port_to, p = 0, ip = 0, ip_to = 0, last;
bool with_ports = false; bool with_ports = false;
u8 cidr; u8 cidr;
int ret; int ret;
...@@ -287,7 +260,7 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -287,7 +260,7 @@ hash_netport4_uadt(struct ip_set *set, struct nlattr *tb[],
return ret; return ret;
} }
/* IPv6 variants */ /* IPv6 variant */
struct hash_netport6_elem { struct hash_netport6_elem {
union nf_inet_addr ip; union nf_inet_addr ip;
...@@ -297,34 +270,6 @@ struct hash_netport6_elem { ...@@ -297,34 +270,6 @@ struct hash_netport6_elem {
u8 nomatch:1; u8 nomatch:1;
}; };
struct hash_netport6t_elem {
union nf_inet_addr ip;
__be16 port;
u8 proto;
u8 cidr:7;
u8 nomatch:1;
unsigned long timeout;
};
struct hash_netport6c_elem {
union nf_inet_addr ip;
__be16 port;
u8 proto;
u8 cidr:7;
u8 nomatch:1;
struct ip_set_counter counter;
};
struct hash_netport6ct_elem {
union nf_inet_addr ip;
__be16 port;
u8 proto;
u8 cidr:7;
u8 nomatch:1;
struct ip_set_counter counter;
unsigned long timeout;
};
/* Common functions */ /* Common functions */
static inline bool static inline bool
...@@ -407,9 +352,9 @@ hash_netport6_kadt(struct ip_set *set, const struct sk_buff *skb, ...@@ -407,9 +352,9 @@ hash_netport6_kadt(struct ip_set *set, const struct sk_buff *skb,
const struct hash_netport *h = set->data; const struct hash_netport *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt]; ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_netport6_elem e = { struct hash_netport6_elem e = {
.cidr = h->nets[0].cidr ? h->nets[0].cidr - 1 : HOST_MASK - 1, .cidr = IP_SET_INIT_CIDR(h->nets[0].cidr[0], HOST_MASK) - 1,
}; };
struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, h); struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
if (adt == IPSET_TEST) if (adt == IPSET_TEST)
e.cidr = HOST_MASK - 1; e.cidr = HOST_MASK - 1;
...@@ -431,7 +376,7 @@ hash_netport6_uadt(struct ip_set *set, struct nlattr *tb[], ...@@ -431,7 +376,7 @@ hash_netport6_uadt(struct ip_set *set, struct nlattr *tb[],
const struct hash_netport *h = set->data; const struct hash_netport *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt]; ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_netport6_elem e = { .cidr = HOST_MASK - 1 }; struct hash_netport6_elem e = { .cidr = HOST_MASK - 1 };
struct ip_set_ext ext = IP_SET_INIT_UEXT(h); struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
u32 port, port_to; u32 port, port_to;
bool with_ports = false; bool with_ports = false;
u8 cidr; u8 cidr;
...@@ -518,8 +463,8 @@ static struct ip_set_type hash_netport_type __read_mostly = { ...@@ -518,8 +463,8 @@ static struct ip_set_type hash_netport_type __read_mostly = {
.features = IPSET_TYPE_IP | IPSET_TYPE_PORT | IPSET_TYPE_NOMATCH, .features = IPSET_TYPE_IP | IPSET_TYPE_PORT | IPSET_TYPE_NOMATCH,
.dimension = IPSET_DIM_TWO, .dimension = IPSET_DIM_TWO,
.family = NFPROTO_UNSPEC, .family = NFPROTO_UNSPEC,
.revision_min = REVISION_MIN, .revision_min = IPSET_TYPE_REV_MIN,
.revision_max = REVISION_MAX, .revision_max = IPSET_TYPE_REV_MAX,
.create = hash_netport_create, .create = hash_netport_create,
.create_policy = { .create_policy = {
[IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 }, [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 },
...@@ -542,6 +487,7 @@ static struct ip_set_type hash_netport_type __read_mostly = { ...@@ -542,6 +487,7 @@ static struct ip_set_type hash_netport_type __read_mostly = {
[IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 }, [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
[IPSET_ATTR_BYTES] = { .type = NLA_U64 }, [IPSET_ATTR_BYTES] = { .type = NLA_U64 },
[IPSET_ATTR_PACKETS] = { .type = NLA_U64 }, [IPSET_ATTR_PACKETS] = { .type = NLA_U64 },
[IPSET_ATTR_COMMENT] = { .type = NLA_NUL_STRING },
}, },
.me = THIS_MODULE, .me = THIS_MODULE,
}; };
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -625,33 +625,26 @@ static struct nf_ct_helper_expectfn sip_nat = { ...@@ -625,33 +625,26 @@ static struct nf_ct_helper_expectfn sip_nat = {
static void __exit nf_nat_sip_fini(void) static void __exit nf_nat_sip_fini(void)
{ {
RCU_INIT_POINTER(nf_nat_sip_hook, NULL); RCU_INIT_POINTER(nf_nat_sip_hooks, NULL);
RCU_INIT_POINTER(nf_nat_sip_seq_adjust_hook, NULL);
RCU_INIT_POINTER(nf_nat_sip_expect_hook, NULL);
RCU_INIT_POINTER(nf_nat_sdp_addr_hook, NULL);
RCU_INIT_POINTER(nf_nat_sdp_port_hook, NULL);
RCU_INIT_POINTER(nf_nat_sdp_session_hook, NULL);
RCU_INIT_POINTER(nf_nat_sdp_media_hook, NULL);
nf_ct_helper_expectfn_unregister(&sip_nat); nf_ct_helper_expectfn_unregister(&sip_nat);
synchronize_rcu(); synchronize_rcu();
} }
static const struct nf_nat_sip_hooks sip_hooks = {
.msg = nf_nat_sip,
.seq_adjust = nf_nat_sip_seq_adjust,
.expect = nf_nat_sip_expect,
.sdp_addr = nf_nat_sdp_addr,
.sdp_port = nf_nat_sdp_port,
.sdp_session = nf_nat_sdp_session,
.sdp_media = nf_nat_sdp_media,
};
static int __init nf_nat_sip_init(void) static int __init nf_nat_sip_init(void)
{ {
BUG_ON(nf_nat_sip_hook != NULL); BUG_ON(nf_nat_sip_hooks != NULL);
BUG_ON(nf_nat_sip_seq_adjust_hook != NULL); RCU_INIT_POINTER(nf_nat_sip_hooks, &sip_hooks);
BUG_ON(nf_nat_sip_expect_hook != NULL);
BUG_ON(nf_nat_sdp_addr_hook != NULL);
BUG_ON(nf_nat_sdp_port_hook != NULL);
BUG_ON(nf_nat_sdp_session_hook != NULL);
BUG_ON(nf_nat_sdp_media_hook != NULL);
RCU_INIT_POINTER(nf_nat_sip_hook, nf_nat_sip);
RCU_INIT_POINTER(nf_nat_sip_seq_adjust_hook, nf_nat_sip_seq_adjust);
RCU_INIT_POINTER(nf_nat_sip_expect_hook, nf_nat_sip_expect);
RCU_INIT_POINTER(nf_nat_sdp_addr_hook, nf_nat_sdp_addr);
RCU_INIT_POINTER(nf_nat_sdp_port_hook, nf_nat_sdp_port);
RCU_INIT_POINTER(nf_nat_sdp_session_hook, nf_nat_sdp_session);
RCU_INIT_POINTER(nf_nat_sdp_media_hook, nf_nat_sdp_media);
nf_ct_helper_expectfn_register(&sip_nat); nf_ct_helper_expectfn_register(&sip_nat);
return 0; return 0;
} }
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment