* [PATCH 0/8] ipset patches for nf-next
@ 2014-03-06 9:23 Jozsef Kadlecsik
2014-03-06 9:23 ` [PATCH 1/8] netfilter: ipset: Follow manual page behavior for SET target on list:set Jozsef Kadlecsik
` (8 more replies)
0 siblings, 9 replies; 12+ messages in thread
From: Jozsef Kadlecsik @ 2014-03-06 9:23 UTC (permalink / raw)
To: netfilter-devel; +Cc: Pablo Neira Ayuso
Hi Pablo,
Please consider to apply the next series of patches:
* Follow the manual page behavior for the SET target at list:set
type of sets when the set contains both inet and inet6 type of sets,
from Sergey Popovich
* Fix coccinelle warnings about 0/1 return values instead of false/true,
from Fengguang Wu
* Introduce the hash:ip,mark hash type from Vytas Dauksa
* Add markmask option to hash:ip,mark type from Vytas Dauksa
* Prepare the kernel for create option flags when no extension is needed
from Jozsef Kadlecsik
* Fix ABI breakage by the markmask option patch, from Florian Westphal
* Move registration message to init from net_init from Ilia Mirkin
* Add forceadd kernel support for hash set types from Josh Hunt.
You can pull the changes from
git://blackhole.kfki.hu/nf-next master
Thanks,
Jozsef
----------------------------------------------------------------
The following changes since commit 0768b3b3d228c5acf2075f40f3d25cda30011d4f:
netfilter: nf_tables: add optional user data area to rules (2014-02-27 16:56:00 +0100)
are available in the git repository at:
git://blackhole.kfki.hu/nf-next master
for you to fetch changes up to 07cf8f5ae2657ac495b906c68ff3441ff8ba80ba:
netfilter: ipset: add forceadd kernel support for hash set types (2014-03-06 09:31:43 +0100)
----------------------------------------------------------------
Fengguang Wu (1):
netfilter: ipset: Add hash: fix coccinelle warnings
Florian Westphal (1):
netfilter: ipset: kernel: uapi: fix MARKMASK attr ABI breakage
Ilia Mirkin (1):
netfilter: ipset: move registration message to init from net_init
Josh Hunt (1):
netfilter: ipset: add forceadd kernel support for hash set types
Jozsef Kadlecsik (1):
netfilter: ipset: Prepare the kernel for create option flags when no extension is needed
Sergey Popovich (1):
netfilter: ipset: Follow manual page behavior for SET target on list:set
Vytas Dauksa (2):
netfilter: ipset: add hash:ip,mark data type to ipset
netfilter: ipset: add markmask for hash:ip,mark data type
include/linux/netfilter/ipset/ip_set.h | 15 +-
include/uapi/linux/netfilter/ipset/ip_set.h | 12 +
net/netfilter/ipset/Kconfig | 9 +
net/netfilter/ipset/Makefile | 1 +
net/netfilter/ipset/ip_set_core.c | 8 +-
net/netfilter/ipset/ip_set_hash_gen.h | 43 ++++
net/netfilter/ipset/ip_set_hash_ip.c | 3 +-
net/netfilter/ipset/ip_set_hash_ipmark.c | 321 ++++++++++++++++++++++++++
net/netfilter/ipset/ip_set_hash_ipport.c | 3 +-
net/netfilter/ipset/ip_set_hash_ipportip.c | 3 +-
net/netfilter/ipset/ip_set_hash_ipportnet.c | 3 +-
net/netfilter/ipset/ip_set_hash_net.c | 3 +-
net/netfilter/ipset/ip_set_hash_netiface.c | 3 +-
net/netfilter/ipset/ip_set_hash_netnet.c | 10 +-
net/netfilter/ipset/ip_set_hash_netport.c | 3 +-
net/netfilter/ipset/ip_set_hash_netportnet.c | 3 +-
16 files changed, 423 insertions(+), 20 deletions(-)
create mode 100644 net/netfilter/ipset/ip_set_hash_ipmark.c
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 1/8] netfilter: ipset: Follow manual page behavior for SET target on list:set
2014-03-06 9:23 [PATCH 0/8] ipset patches for nf-next Jozsef Kadlecsik
@ 2014-03-06 9:23 ` Jozsef Kadlecsik
2014-03-06 9:23 ` [PATCH 2/8] netfilter: ipset: Add hash: fix coccinelle warnings Jozsef Kadlecsik
` (7 subsequent siblings)
8 siblings, 0 replies; 12+ messages in thread
From: Jozsef Kadlecsik @ 2014-03-06 9:23 UTC (permalink / raw)
To: netfilter-devel; +Cc: Pablo Neira Ayuso
From: Sergey Popovich <popovich_sergei@mail.ru>
ipset(8) for list:set says:
The match will try to find a matching entry in the sets and the
target will try to add an entry to the first set to which it can
be added.
However real behavior is bit differ from described. Consider example:
# ipset create test-1-v4 hash:ip family inet
# ipset create test-1-v6 hash:ip family inet6
# ipset create test-1 list:set
# ipset add test-1 test-1-v4
# ipset add test-1 test-1-v6
# iptables -A INPUT -p tcp --destination-port 25 -j SET --add-set test-1 src
# ip6tables -A INPUT -p tcp --destination-port 25 -j SET --add-set test-1 src
And then when iptables/ip6tables rule matches packet IPSET target
tries to add src from packet to the list:set test-1 where first
entry is test-1-v4 and the second one is test-1-v6.
For IPv4, as it first entry in test-1 src added to test-1-v4
correctly, but for IPv6 src not added!
Placing test-1-v6 to the first element of list:set makes behavior
correct for IPv6, but brokes for IPv4.
This is due to result, returned from ip_set_add() and ip_set_del() from
net/netfilter/ipset/ip_set_core.c when set in list:set equires more
parameters than given or address families do not match (which is this
case).
It seems wrong returning 0 from ip_set_add() and ip_set_del() in
this case, as 0 should be returned only when an element successfuly
added/deleted to/from the set, contrary to ip_set_test() which
returns 0 when no entry exists and >0 when entry found in set.
Signed-off-by: Sergey Popovich <popovich_sergei@mail.ru>
Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
---
net/netfilter/ipset/ip_set_core.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c
index 728a2cf..c6c97b8 100644
--- a/net/netfilter/ipset/ip_set_core.c
+++ b/net/netfilter/ipset/ip_set_core.c
@@ -510,7 +510,7 @@ ip_set_add(ip_set_id_t index, const struct sk_buff *skb,
if (opt->dim < set->type->dimension ||
!(opt->family == set->family || set->family == NFPROTO_UNSPEC))
- return 0;
+ return -IPSET_ERR_TYPE_MISMATCH;
write_lock_bh(&set->lock);
ret = set->variant->kadt(set, skb, par, IPSET_ADD, opt);
@@ -533,7 +533,7 @@ ip_set_del(ip_set_id_t index, const struct sk_buff *skb,
if (opt->dim < set->type->dimension ||
!(opt->family == set->family || set->family == NFPROTO_UNSPEC))
- return 0;
+ return -IPSET_ERR_TYPE_MISMATCH;
write_lock_bh(&set->lock);
ret = set->variant->kadt(set, skb, par, IPSET_DEL, opt);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 2/8] netfilter: ipset: Add hash: fix coccinelle warnings
2014-03-06 9:23 [PATCH 0/8] ipset patches for nf-next Jozsef Kadlecsik
2014-03-06 9:23 ` [PATCH 1/8] netfilter: ipset: Follow manual page behavior for SET target on list:set Jozsef Kadlecsik
@ 2014-03-06 9:23 ` Jozsef Kadlecsik
2014-03-06 9:23 ` [PATCH 3/8] netfilter: ipset: add hash:ip,mark data type to ipset Jozsef Kadlecsik
` (6 subsequent siblings)
8 siblings, 0 replies; 12+ messages in thread
From: Jozsef Kadlecsik @ 2014-03-06 9:23 UTC (permalink / raw)
To: netfilter-devel; +Cc: Pablo Neira Ayuso
From: Fengguang Wu <fengguang.wu@intel.com>
net/netfilter/ipset/ip_set_hash_netnet.c:115:8-9: WARNING: return of 0/1 in function 'hash_netnet4_data_list' with return type bool
/c/kernel-tests/src/cocci/net/netfilter/ipset/ip_set_hash_netnet.c:338:8-9: WARNING: return of 0/1 in function 'hash_netnet6_data_list' with return type bool
Return statements in functions returning bool should use
true/false instead of 1/0.
Generated by: coccinelle/misc/boolreturn.cocci
Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
---
net/netfilter/ipset/ip_set_hash_netnet.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/net/netfilter/ipset/ip_set_hash_netnet.c b/net/netfilter/ipset/ip_set_hash_netnet.c
index 6226803..4e7261d 100644
--- a/net/netfilter/ipset/ip_set_hash_netnet.c
+++ b/net/netfilter/ipset/ip_set_hash_netnet.c
@@ -112,10 +112,10 @@ hash_netnet4_data_list(struct sk_buff *skb,
(flags &&
nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
goto nla_put_failure;
- return 0;
+ return false;
nla_put_failure:
- return 1;
+ return true;
}
static inline void
@@ -334,10 +334,10 @@ hash_netnet6_data_list(struct sk_buff *skb,
(flags &&
nla_put_net32(skb, IPSET_ATTR_CADT_FLAGS, htonl(flags))))
goto nla_put_failure;
- return 0;
+ return false;
nla_put_failure:
- return 1;
+ return true;
}
static inline void
--
1.7.10.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 3/8] netfilter: ipset: add hash:ip,mark data type to ipset
2014-03-06 9:23 [PATCH 0/8] ipset patches for nf-next Jozsef Kadlecsik
2014-03-06 9:23 ` [PATCH 1/8] netfilter: ipset: Follow manual page behavior for SET target on list:set Jozsef Kadlecsik
2014-03-06 9:23 ` [PATCH 2/8] netfilter: ipset: Add hash: fix coccinelle warnings Jozsef Kadlecsik
@ 2014-03-06 9:23 ` Jozsef Kadlecsik
2014-03-06 9:23 ` [PATCH 4/8] netfilter: ipset: add markmask for hash:ip,mark data type Jozsef Kadlecsik
` (5 subsequent siblings)
8 siblings, 0 replies; 12+ messages in thread
From: Jozsef Kadlecsik @ 2014-03-06 9:23 UTC (permalink / raw)
To: netfilter-devel; +Cc: Pablo Neira Ayuso
From: Vytas Dauksa <vytas.dauksa@smoothwall.net>
Introduce packet mark support with new ip,mark hash set. This includes
userspace and kernelspace code, hash:ip,mark set tests and man page
updates.
The intended use of ip,mark set is similar to the ip:port type, but for
protocols which don't use a predictable port number. Instead of port
number it matches a firewall mark determined by a layer 7 filtering
program like opendpi.
As well as allowing or blocking traffic it will also be used for
accounting packets and bytes sent for each protocol.
Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
---
include/linux/netfilter/ipset/ip_set.h | 10 +-
include/uapi/linux/netfilter/ipset/ip_set.h | 1 +
net/netfilter/ipset/Kconfig | 9 +
net/netfilter/ipset/Makefile | 1 +
net/netfilter/ipset/ip_set_hash_ipmark.c | 312 +++++++++++++++++++++++++++
5 files changed, 329 insertions(+), 4 deletions(-)
create mode 100644 net/netfilter/ipset/ip_set_hash_ipmark.c
diff --git a/include/linux/netfilter/ipset/ip_set.h b/include/linux/netfilter/ipset/ip_set.h
index 0c7d01e..4ac00d4 100644
--- a/include/linux/netfilter/ipset/ip_set.h
+++ b/include/linux/netfilter/ipset/ip_set.h
@@ -39,11 +39,13 @@ enum ip_set_feature {
IPSET_TYPE_NAME = (1 << IPSET_TYPE_NAME_FLAG),
IPSET_TYPE_IFACE_FLAG = 5,
IPSET_TYPE_IFACE = (1 << IPSET_TYPE_IFACE_FLAG),
- IPSET_TYPE_NOMATCH_FLAG = 6,
+ IPSET_TYPE_MARK_FLAG = 6,
+ IPSET_TYPE_MARK = (1 << IPSET_TYPE_MARK_FLAG),
+ IPSET_TYPE_NOMATCH_FLAG = 7,
IPSET_TYPE_NOMATCH = (1 << IPSET_TYPE_NOMATCH_FLAG),
/* Strictly speaking not a feature, but a flag for dumping:
* this settype must be dumped last */
- IPSET_DUMP_LAST_FLAG = 7,
+ IPSET_DUMP_LAST_FLAG = 8,
IPSET_DUMP_LAST = (1 << IPSET_DUMP_LAST_FLAG),
};
@@ -171,8 +173,6 @@ struct ip_set_type {
char name[IPSET_MAXNAMELEN];
/* Protocol version */
u8 protocol;
- /* Set features to control swapping */
- u8 features;
/* Set type dimension */
u8 dimension;
/*
@@ -182,6 +182,8 @@ struct ip_set_type {
u8 family;
/* Type revisions */
u8 revision_min, revision_max;
+ /* Set features to control swapping */
+ u16 features;
/* Create set */
int (*create)(struct net *net, struct ip_set *set,
diff --git a/include/uapi/linux/netfilter/ipset/ip_set.h b/include/uapi/linux/netfilter/ipset/ip_set.h
index 25d3b2f..5368f82 100644
--- a/include/uapi/linux/netfilter/ipset/ip_set.h
+++ b/include/uapi/linux/netfilter/ipset/ip_set.h
@@ -82,6 +82,7 @@ enum {
IPSET_ATTR_PROTO, /* 7 */
IPSET_ATTR_CADT_FLAGS, /* 8 */
IPSET_ATTR_CADT_LINENO = IPSET_ATTR_LINENO, /* 9 */
+ IPSET_ATTR_MARK, /* 10 */
/* Reserve empty slots */
IPSET_ATTR_CADT_MAX = 16,
/* Create-only specific attributes */
diff --git a/net/netfilter/ipset/Kconfig b/net/netfilter/ipset/Kconfig
index 44cd4f5..2f7f5c3 100644
--- a/net/netfilter/ipset/Kconfig
+++ b/net/netfilter/ipset/Kconfig
@@ -61,6 +61,15 @@ config IP_SET_HASH_IP
To compile it as a module, choose M here. If unsure, say N.
+config IP_SET_HASH_IPMARK
+ tristate "hash:ip,mark set support"
+ depends on IP_SET
+ help
+ This option adds the hash:ip,mark set type support, by which one
+ can store IPv4/IPv6 address and mark pairs.
+
+ To compile it as a module, choose M here. If unsure, say N.
+
config IP_SET_HASH_IPPORT
tristate "hash:ip,port set support"
depends on IP_SET
diff --git a/net/netfilter/ipset/Makefile b/net/netfilter/ipset/Makefile
index 44b2d38..231f101 100644
--- a/net/netfilter/ipset/Makefile
+++ b/net/netfilter/ipset/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_IP_SET_BITMAP_PORT) += ip_set_bitmap_port.o
# hash types
obj-$(CONFIG_IP_SET_HASH_IP) += ip_set_hash_ip.o
+obj-$(CONFIG_IP_SET_HASH_IPMARK) += ip_set_hash_ipmark.o
obj-$(CONFIG_IP_SET_HASH_IPPORT) += ip_set_hash_ipport.o
obj-$(CONFIG_IP_SET_HASH_IPPORTIP) += ip_set_hash_ipportip.o
obj-$(CONFIG_IP_SET_HASH_IPPORTNET) += ip_set_hash_ipportnet.o
diff --git a/net/netfilter/ipset/ip_set_hash_ipmark.c b/net/netfilter/ipset/ip_set_hash_ipmark.c
new file mode 100644
index 0000000..e56c0d9
--- /dev/null
+++ b/net/netfilter/ipset/ip_set_hash_ipmark.c
@@ -0,0 +1,312 @@
+/* Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
+ * Copyright (C) 2013 Smoothwall Ltd. <vytas.dauksa@smoothwall.net>
+ *
+ * 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.
+ */
+
+/* Kernel module implementing an IP set type: the hash:ip,mark type */
+
+#include <linux/jhash.h>
+#include <linux/module.h>
+#include <linux/ip.h>
+#include <linux/skbuff.h>
+#include <linux/errno.h>
+#include <linux/random.h>
+#include <net/ip.h>
+#include <net/ipv6.h>
+#include <net/netlink.h>
+#include <net/tcp.h>
+
+#include <linux/netfilter.h>
+#include <linux/netfilter/ipset/pfxlen.h>
+#include <linux/netfilter/ipset/ip_set.h>
+#include <linux/netfilter/ipset/ip_set_hash.h>
+
+#define IPSET_TYPE_REV_MIN 0
+#define IPSET_TYPE_REV_MAX 0
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Vytas Dauksa <vytas.dauksa@smoothwall.net>");
+IP_SET_MODULE_DESC("hash:ip,mark", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX);
+MODULE_ALIAS("ip_set_hash:ip,mark");
+
+/* Type specific function prefix */
+#define HTYPE hash_ipmark
+
+/* IPv4 variant */
+
+/* Member elements */
+struct hash_ipmark4_elem {
+ __be32 ip;
+ __u32 mark;
+};
+
+/* Common functions */
+
+static inline bool
+hash_ipmark4_data_equal(const struct hash_ipmark4_elem *ip1,
+ const struct hash_ipmark4_elem *ip2,
+ u32 *multi)
+{
+ return ip1->ip == ip2->ip &&
+ ip1->mark == ip2->mark;
+}
+
+static bool
+hash_ipmark4_data_list(struct sk_buff *skb,
+ const struct hash_ipmark4_elem *data)
+{
+ if (nla_put_ipaddr4(skb, IPSET_ATTR_IP, data->ip) ||
+ nla_put_net32(skb, IPSET_ATTR_MARK, htonl(data->mark)))
+ goto nla_put_failure;
+ return 0;
+
+nla_put_failure:
+ return 1;
+}
+
+static inline void
+hash_ipmark4_data_next(struct hash_ipmark4_elem *next,
+ const struct hash_ipmark4_elem *d)
+{
+ next->ip = d->ip;
+}
+
+#define MTYPE hash_ipmark4
+#define PF 4
+#define HOST_MASK 32
+#define HKEY_DATALEN sizeof(struct hash_ipmark4_elem)
+#include "ip_set_hash_gen.h"
+
+static int
+hash_ipmark4_kadt(struct ip_set *set, const struct sk_buff *skb,
+ const struct xt_action_param *par,
+ enum ipset_adt adt, struct ip_set_adt_opt *opt)
+{
+ ipset_adtfn adtfn = set->variant->adt[adt];
+ struct hash_ipmark4_elem e = { };
+ struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
+
+ e.mark = skb->mark;
+
+ ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip);
+ return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
+}
+
+static int
+hash_ipmark4_uadt(struct ip_set *set, struct nlattr *tb[],
+ enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
+{
+ const struct hash_ipmark *h = set->data;
+ ipset_adtfn adtfn = set->variant->adt[adt];
+ struct hash_ipmark4_elem e = { };
+ struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+ u32 ip, ip_to = 0;
+ int ret;
+
+ if (unlikely(!tb[IPSET_ATTR_IP] ||
+ !ip_set_attr_netorder(tb, IPSET_ATTR_MARK) ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_PACKETS) ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES)))
+ return -IPSET_ERR_PROTOCOL;
+
+ if (tb[IPSET_ATTR_LINENO])
+ *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
+
+ ret = ip_set_get_ipaddr4(tb[IPSET_ATTR_IP], &e.ip) ||
+ ip_set_get_extensions(set, tb, &ext);
+ if (ret)
+ return ret;
+
+ e.mark = ntohl(nla_get_u32(tb[IPSET_ATTR_MARK]));
+
+ if (adt == IPSET_TEST ||
+ !(tb[IPSET_ATTR_IP_TO] || tb[IPSET_ATTR_CIDR])) {
+ ret = adtfn(set, &e, &ext, &ext, flags);
+ return ip_set_eexist(ret, flags) ? 0 : ret;
+ }
+
+ ip_to = ip = ntohl(e.ip);
+ if (tb[IPSET_ATTR_IP_TO]) {
+ ret = ip_set_get_hostipaddr4(tb[IPSET_ATTR_IP_TO], &ip_to);
+ if (ret)
+ return ret;
+ if (ip > ip_to)
+ swap(ip, ip_to);
+ } else if (tb[IPSET_ATTR_CIDR]) {
+ u8 cidr = nla_get_u8(tb[IPSET_ATTR_CIDR]);
+
+ if (!cidr || cidr > 32)
+ return -IPSET_ERR_INVALID_CIDR;
+ ip_set_mask_from_to(ip, ip_to, cidr);
+ }
+
+ if (retried)
+ ip = ntohl(h->next.ip);
+ for (; !before(ip_to, ip); ip++) {
+ e.ip = htonl(ip);
+ ret = adtfn(set, &e, &ext, &ext, flags);
+
+ if (ret && !ip_set_eexist(ret, flags))
+ return ret;
+ else
+ ret = 0;
+ }
+ return ret;
+}
+
+/* IPv6 variant */
+
+struct hash_ipmark6_elem {
+ union nf_inet_addr ip;
+ __u32 mark;
+};
+
+/* Common functions */
+
+static inline bool
+hash_ipmark6_data_equal(const struct hash_ipmark6_elem *ip1,
+ const struct hash_ipmark6_elem *ip2,
+ u32 *multi)
+{
+ return ipv6_addr_equal(&ip1->ip.in6, &ip2->ip.in6) &&
+ ip1->mark == ip2->mark;
+}
+
+static bool
+hash_ipmark6_data_list(struct sk_buff *skb,
+ const struct hash_ipmark6_elem *data)
+{
+ if (nla_put_ipaddr6(skb, IPSET_ATTR_IP, &data->ip.in6) ||
+ nla_put_net32(skb, IPSET_ATTR_MARK, htonl(data->mark)))
+ goto nla_put_failure;
+ return 0;
+
+nla_put_failure:
+ return 1;
+}
+
+static inline void
+hash_ipmark6_data_next(struct hash_ipmark4_elem *next,
+ const struct hash_ipmark6_elem *d)
+{
+}
+
+#undef MTYPE
+#undef PF
+#undef HOST_MASK
+#undef HKEY_DATALEN
+
+#define MTYPE hash_ipmark6
+#define PF 6
+#define HOST_MASK 128
+#define HKEY_DATALEN sizeof(struct hash_ipmark6_elem)
+#define IP_SET_EMIT_CREATE
+#include "ip_set_hash_gen.h"
+
+
+static int
+hash_ipmark6_kadt(struct ip_set *set, const struct sk_buff *skb,
+ const struct xt_action_param *par,
+ enum ipset_adt adt, struct ip_set_adt_opt *opt)
+{
+ ipset_adtfn adtfn = set->variant->adt[adt];
+ struct hash_ipmark6_elem e = { };
+ struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
+
+ e.mark = skb->mark;
+
+ ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip.in6);
+ return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
+}
+
+static int
+hash_ipmark6_uadt(struct ip_set *set, struct nlattr *tb[],
+ enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
+{
+ ipset_adtfn adtfn = set->variant->adt[adt];
+ struct hash_ipmark6_elem e = { };
+ struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+ int ret;
+
+ if (unlikely(!tb[IPSET_ATTR_IP] ||
+ !ip_set_attr_netorder(tb, IPSET_ATTR_MARK) ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_PACKETS) ||
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_BYTES) ||
+ tb[IPSET_ATTR_IP_TO] ||
+ tb[IPSET_ATTR_CIDR]))
+ return -IPSET_ERR_PROTOCOL;
+
+ if (tb[IPSET_ATTR_LINENO])
+ *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
+
+ ret = ip_set_get_ipaddr6(tb[IPSET_ATTR_IP], &e.ip) ||
+ ip_set_get_extensions(set, tb, &ext);
+ if (ret)
+ return ret;
+
+ e.mark = ntohl(nla_get_u32(tb[IPSET_ATTR_MARK]));
+
+ if (adt == IPSET_TEST) {
+ ret = adtfn(set, &e, &ext, &ext, flags);
+ return ip_set_eexist(ret, flags) ? 0 : ret;
+ }
+
+ ret = adtfn(set, &e, &ext, &ext, flags);
+ if (ret && !ip_set_eexist(ret, flags))
+ return ret;
+ else
+ ret = 0;
+
+ return ret;
+}
+
+static struct ip_set_type hash_ipmark_type __read_mostly = {
+ .name = "hash:ip,mark",
+ .protocol = IPSET_PROTOCOL,
+ .features = IPSET_TYPE_IP | IPSET_TYPE_MARK,
+ .dimension = IPSET_DIM_TWO,
+ .family = NFPROTO_UNSPEC,
+ .revision_min = IPSET_TYPE_REV_MIN,
+ .revision_max = IPSET_TYPE_REV_MAX,
+ .create = hash_ipmark_create,
+ .create_policy = {
+ [IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 },
+ [IPSET_ATTR_MAXELEM] = { .type = NLA_U32 },
+ [IPSET_ATTR_PROBES] = { .type = NLA_U8 },
+ [IPSET_ATTR_RESIZE] = { .type = NLA_U8 },
+ [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
+ [IPSET_ATTR_CADT_FLAGS] = { .type = NLA_U32 },
+ },
+ .adt_policy = {
+ [IPSET_ATTR_IP] = { .type = NLA_NESTED },
+ [IPSET_ATTR_IP_TO] = { .type = NLA_NESTED },
+ [IPSET_ATTR_MARK] = { .type = NLA_U32 },
+ [IPSET_ATTR_CIDR] = { .type = NLA_U8 },
+ [IPSET_ATTR_TIMEOUT] = { .type = NLA_U32 },
+ [IPSET_ATTR_LINENO] = { .type = NLA_U32 },
+ [IPSET_ATTR_BYTES] = { .type = NLA_U64 },
+ [IPSET_ATTR_PACKETS] = { .type = NLA_U64 },
+ [IPSET_ATTR_COMMENT] = { .type = NLA_NUL_STRING },
+ },
+ .me = THIS_MODULE,
+};
+
+static int __init
+hash_ipmark_init(void)
+{
+ return ip_set_type_register(&hash_ipmark_type);
+}
+
+static void __exit
+hash_ipmark_fini(void)
+{
+ ip_set_type_unregister(&hash_ipmark_type);
+}
+
+module_init(hash_ipmark_init);
+module_exit(hash_ipmark_fini);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 4/8] netfilter: ipset: add markmask for hash:ip,mark data type
2014-03-06 9:23 [PATCH 0/8] ipset patches for nf-next Jozsef Kadlecsik
` (2 preceding siblings ...)
2014-03-06 9:23 ` [PATCH 3/8] netfilter: ipset: add hash:ip,mark data type to ipset Jozsef Kadlecsik
@ 2014-03-06 9:23 ` Jozsef Kadlecsik
2014-03-06 9:23 ` [PATCH 5/8] netfilter: ipset: Prepare the kernel for create option flags when no extension is needed Jozsef Kadlecsik
` (4 subsequent siblings)
8 siblings, 0 replies; 12+ messages in thread
From: Jozsef Kadlecsik @ 2014-03-06 9:23 UTC (permalink / raw)
To: netfilter-devel; +Cc: Pablo Neira Ayuso
From: Vytas Dauksa <vytas.dauksa@smoothwall.net>
Introduce packet mark mask for hash:ip,mark data type. This allows to
set mark bit filter for the ip set.
Change-Id: Id8dd9ca7e64477c4f7b022a1d9c1a5b187f1c96e
Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
---
include/uapi/linux/netfilter/ipset/ip_set.h | 2 ++
net/netfilter/ipset/ip_set_hash_gen.h | 31 +++++++++++++++++++++++++++
net/netfilter/ipset/ip_set_hash_ipmark.c | 9 ++++++++
3 files changed, 42 insertions(+)
diff --git a/include/uapi/linux/netfilter/ipset/ip_set.h b/include/uapi/linux/netfilter/ipset/ip_set.h
index 5368f82..f636f28 100644
--- a/include/uapi/linux/netfilter/ipset/ip_set.h
+++ b/include/uapi/linux/netfilter/ipset/ip_set.h
@@ -89,6 +89,7 @@ enum {
IPSET_ATTR_GC,
IPSET_ATTR_HASHSIZE,
IPSET_ATTR_MAXELEM,
+ IPSET_ATTR_MARKMASK,
IPSET_ATTR_NETMASK,
IPSET_ATTR_PROBES,
IPSET_ATTR_RESIZE,
@@ -138,6 +139,7 @@ enum ipset_errno {
IPSET_ERR_EXIST,
IPSET_ERR_INVALID_CIDR,
IPSET_ERR_INVALID_NETMASK,
+ IPSET_ERR_INVALID_MARKMASK,
IPSET_ERR_INVALID_FAMILY,
IPSET_ERR_TIMEOUT,
IPSET_ERR_REFERENCED,
diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h
index be6932a..b1eed81 100644
--- a/net/netfilter/ipset/ip_set_hash_gen.h
+++ b/net/netfilter/ipset/ip_set_hash_gen.h
@@ -263,6 +263,9 @@ struct htype {
u32 maxelem; /* max elements in the hash */
u32 elements; /* current element (vs timeout) */
u32 initval; /* random jhash init value */
+#ifdef IP_SET_HASH_WITH_MARKMASK
+ u32 markmask; /* markmask value for mark mask to store */
+#endif
struct timer_list gc; /* garbage collection when timeout enabled */
struct mtype_elem next; /* temporary storage for uadd */
#ifdef IP_SET_HASH_WITH_MULTI
@@ -454,6 +457,9 @@ mtype_same_set(const struct ip_set *a, const struct ip_set *b)
#ifdef IP_SET_HASH_WITH_NETMASK
x->netmask == y->netmask &&
#endif
+#ifdef IP_SET_HASH_WITH_MARKMASK
+ x->markmask == y->markmask &&
+#endif
a->extensions == b->extensions;
}
@@ -908,6 +914,10 @@ mtype_head(struct ip_set *set, struct sk_buff *skb)
nla_put_u8(skb, IPSET_ATTR_NETMASK, h->netmask))
goto nla_put_failure;
#endif
+#ifdef IP_SET_HASH_WITH_MARKMASK
+ if (nla_put_u32(skb, IPSET_ATTR_MARKMASK, h->markmask))
+ goto nla_put_failure;
+#endif
if (nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) ||
nla_put_net32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize)))
goto nla_put_failure;
@@ -1016,6 +1026,9 @@ IPSET_TOKEN(HTYPE, _create)(struct net *net, struct ip_set *set,
struct nlattr *tb[], u32 flags)
{
u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM;
+#ifdef IP_SET_HASH_WITH_MARKMASK
+ u32 markmask;
+#endif
u8 hbits;
#ifdef IP_SET_HASH_WITH_NETMASK
u8 netmask;
@@ -1026,6 +1039,10 @@ IPSET_TOKEN(HTYPE, _create)(struct net *net, struct ip_set *set,
if (!(set->family == NFPROTO_IPV4 || set->family == NFPROTO_IPV6))
return -IPSET_ERR_INVALID_FAMILY;
+
+#ifdef IP_SET_HASH_WITH_MARKMASK
+ markmask = 0xffffffff;
+#endif
#ifdef IP_SET_HASH_WITH_NETMASK
netmask = set->family == NFPROTO_IPV4 ? 32 : 128;
pr_debug("Create set %s with family %s\n",
@@ -1034,6 +1051,9 @@ IPSET_TOKEN(HTYPE, _create)(struct net *net, struct ip_set *set,
if (unlikely(!ip_set_optattr_netorder(tb, IPSET_ATTR_HASHSIZE) ||
!ip_set_optattr_netorder(tb, IPSET_ATTR_MAXELEM) ||
+#ifdef IP_SET_HASH_WITH_MARKMASK
+ !ip_set_optattr_netorder(tb, IPSET_ATTR_MARKMASK) ||
+#endif
!ip_set_optattr_netorder(tb, IPSET_ATTR_TIMEOUT) ||
!ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS)))
return -IPSET_ERR_PROTOCOL;
@@ -1057,6 +1077,14 @@ IPSET_TOKEN(HTYPE, _create)(struct net *net, struct ip_set *set,
return -IPSET_ERR_INVALID_NETMASK;
}
#endif
+#ifdef IP_SET_HASH_WITH_MARKMASK
+ if (tb[IPSET_ATTR_MARKMASK]) {
+ markmask = ntohl(nla_get_u32(tb[IPSET_ATTR_MARKMASK]));
+
+ if ((markmask > 4294967295u) || markmask == 0)
+ return -IPSET_ERR_INVALID_MARKMASK;
+ }
+#endif
hsize = sizeof(*h);
#ifdef IP_SET_HASH_WITH_NETS
@@ -1071,6 +1099,9 @@ IPSET_TOKEN(HTYPE, _create)(struct net *net, struct ip_set *set,
#ifdef IP_SET_HASH_WITH_NETMASK
h->netmask = netmask;
#endif
+#ifdef IP_SET_HASH_WITH_MARKMASK
+ h->markmask = markmask;
+#endif
get_random_bytes(&h->initval, sizeof(h->initval));
set->timeout = IPSET_NO_TIMEOUT;
diff --git a/net/netfilter/ipset/ip_set_hash_ipmark.c b/net/netfilter/ipset/ip_set_hash_ipmark.c
index e56c0d9..1bf8e85 100644
--- a/net/netfilter/ipset/ip_set_hash_ipmark.c
+++ b/net/netfilter/ipset/ip_set_hash_ipmark.c
@@ -34,6 +34,7 @@ MODULE_ALIAS("ip_set_hash:ip,mark");
/* Type specific function prefix */
#define HTYPE hash_ipmark
+#define IP_SET_HASH_WITH_MARKMASK
/* IPv4 variant */
@@ -85,11 +86,13 @@ hash_ipmark4_kadt(struct ip_set *set, const struct sk_buff *skb,
const struct xt_action_param *par,
enum ipset_adt adt, struct ip_set_adt_opt *opt)
{
+ const struct hash_ipmark *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_ipmark4_elem e = { };
struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
e.mark = skb->mark;
+ e.mark &= h->markmask;
ip4addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip);
return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
@@ -122,6 +125,7 @@ hash_ipmark4_uadt(struct ip_set *set, struct nlattr *tb[],
return ret;
e.mark = ntohl(nla_get_u32(tb[IPSET_ATTR_MARK]));
+ e.mark &= h->markmask;
if (adt == IPSET_TEST ||
!(tb[IPSET_ATTR_IP_TO] || tb[IPSET_ATTR_CIDR])) {
@@ -213,11 +217,13 @@ hash_ipmark6_kadt(struct ip_set *set, const struct sk_buff *skb,
const struct xt_action_param *par,
enum ipset_adt adt, struct ip_set_adt_opt *opt)
{
+ const struct hash_ipmark *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_ipmark6_elem e = { };
struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set);
e.mark = skb->mark;
+ e.mark &= h->markmask;
ip6addrptr(skb, opt->flags & IPSET_DIM_ONE_SRC, &e.ip.in6);
return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags);
@@ -227,6 +233,7 @@ static int
hash_ipmark6_uadt(struct ip_set *set, struct nlattr *tb[],
enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
{
+ const struct hash_ipmark *h = set->data;
ipset_adtfn adtfn = set->variant->adt[adt];
struct hash_ipmark6_elem e = { };
struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
@@ -250,6 +257,7 @@ hash_ipmark6_uadt(struct ip_set *set, struct nlattr *tb[],
return ret;
e.mark = ntohl(nla_get_u32(tb[IPSET_ATTR_MARK]));
+ e.mark &= h->markmask;
if (adt == IPSET_TEST) {
ret = adtfn(set, &e, &ext, &ext, flags);
@@ -275,6 +283,7 @@ static struct ip_set_type hash_ipmark_type __read_mostly = {
.revision_max = IPSET_TYPE_REV_MAX,
.create = hash_ipmark_create,
.create_policy = {
+ [IPSET_ATTR_MARKMASK] = { .type = NLA_U32 },
[IPSET_ATTR_HASHSIZE] = { .type = NLA_U32 },
[IPSET_ATTR_MAXELEM] = { .type = NLA_U32 },
[IPSET_ATTR_PROBES] = { .type = NLA_U8 },
--
1.7.10.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 5/8] netfilter: ipset: Prepare the kernel for create option flags when no extension is needed
2014-03-06 9:23 [PATCH 0/8] ipset patches for nf-next Jozsef Kadlecsik
` (3 preceding siblings ...)
2014-03-06 9:23 ` [PATCH 4/8] netfilter: ipset: add markmask for hash:ip,mark data type Jozsef Kadlecsik
@ 2014-03-06 9:23 ` Jozsef Kadlecsik
2014-03-06 9:23 ` [PATCH 6/8] netfilter: ipset: kernel: uapi: fix MARKMASK attr ABI breakage Jozsef Kadlecsik
` (3 subsequent siblings)
8 siblings, 0 replies; 12+ messages in thread
From: Jozsef Kadlecsik @ 2014-03-06 9:23 UTC (permalink / raw)
To: netfilter-devel; +Cc: Pablo Neira Ayuso
Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
---
include/linux/netfilter/ipset/ip_set.h | 2 ++
include/uapi/linux/netfilter/ipset/ip_set.h | 6 ++++++
2 files changed, 8 insertions(+)
diff --git a/include/linux/netfilter/ipset/ip_set.h b/include/linux/netfilter/ipset/ip_set.h
index 4ac00d4..f476bce 100644
--- a/include/linux/netfilter/ipset/ip_set.h
+++ b/include/linux/netfilter/ipset/ip_set.h
@@ -219,6 +219,8 @@ struct ip_set {
u8 revision;
/* Extensions */
u8 extensions;
+ /* Create flags */
+ u8 flags;
/* Default timeout value, if enabled */
u32 timeout;
/* Element data size */
diff --git a/include/uapi/linux/netfilter/ipset/ip_set.h b/include/uapi/linux/netfilter/ipset/ip_set.h
index f636f28..a29a378 100644
--- a/include/uapi/linux/netfilter/ipset/ip_set.h
+++ b/include/uapi/linux/netfilter/ipset/ip_set.h
@@ -188,6 +188,12 @@ enum ipset_cadt_flags {
IPSET_FLAG_CADT_MAX = 15,
};
+/* The flag bits which correspond to the non-extension create flags */
+enum ipset_create_flags {
+ IPSET_CREATE_FLAG_NONE = 0,
+ IPSET_CREATE_FLAG_MAX = 7,
+};
+
/* Commands with settype-specific attributes */
enum ipset_adt {
IPSET_ADD,
--
1.7.10.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 6/8] netfilter: ipset: kernel: uapi: fix MARKMASK attr ABI breakage
2014-03-06 9:23 [PATCH 0/8] ipset patches for nf-next Jozsef Kadlecsik
` (4 preceding siblings ...)
2014-03-06 9:23 ` [PATCH 5/8] netfilter: ipset: Prepare the kernel for create option flags when no extension is needed Jozsef Kadlecsik
@ 2014-03-06 9:23 ` Jozsef Kadlecsik
2014-03-06 9:23 ` [PATCH 7/8] netfilter: ipset: move registration message to init from net_init Jozsef Kadlecsik
` (2 subsequent siblings)
8 siblings, 0 replies; 12+ messages in thread
From: Jozsef Kadlecsik @ 2014-03-06 9:23 UTC (permalink / raw)
To: netfilter-devel; +Cc: Pablo Neira Ayuso
From: Florian Westphal <fw@strlen.de>
commit 2dfb973c0dcc6d2211 (add markmask for hash:ip,mark data type)
inserted IPSET_ATTR_MARKMASK in-between other enum values, i.e.
changing values of all further attributes. This causes 'ipset list'
segfault on existing kernels since ipset no longer finds
IPSET_ATTR_MEMSIZE (it has a different value on kernel side).
Jozsef points out it should be moved below IPSET_ATTR_MARK which
works since there is some extra reserved space after that value.
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
---
include/uapi/linux/netfilter/ipset/ip_set.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/uapi/linux/netfilter/ipset/ip_set.h b/include/uapi/linux/netfilter/ipset/ip_set.h
index a29a378..a1ca244 100644
--- a/include/uapi/linux/netfilter/ipset/ip_set.h
+++ b/include/uapi/linux/netfilter/ipset/ip_set.h
@@ -83,13 +83,13 @@ enum {
IPSET_ATTR_CADT_FLAGS, /* 8 */
IPSET_ATTR_CADT_LINENO = IPSET_ATTR_LINENO, /* 9 */
IPSET_ATTR_MARK, /* 10 */
+ IPSET_ATTR_MARKMASK, /* 11 */
/* Reserve empty slots */
IPSET_ATTR_CADT_MAX = 16,
/* Create-only specific attributes */
IPSET_ATTR_GC,
IPSET_ATTR_HASHSIZE,
IPSET_ATTR_MAXELEM,
- IPSET_ATTR_MARKMASK,
IPSET_ATTR_NETMASK,
IPSET_ATTR_PROBES,
IPSET_ATTR_RESIZE,
@@ -139,7 +139,6 @@ enum ipset_errno {
IPSET_ERR_EXIST,
IPSET_ERR_INVALID_CIDR,
IPSET_ERR_INVALID_NETMASK,
- IPSET_ERR_INVALID_MARKMASK,
IPSET_ERR_INVALID_FAMILY,
IPSET_ERR_TIMEOUT,
IPSET_ERR_REFERENCED,
@@ -147,6 +146,7 @@ enum ipset_errno {
IPSET_ERR_IPADDR_IPV6,
IPSET_ERR_COUNTER,
IPSET_ERR_COMMENT,
+ IPSET_ERR_INVALID_MARKMASK,
/* Type specific error codes */
IPSET_ERR_TYPE_SPECIFIC = 4352,
--
1.7.10.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 7/8] netfilter: ipset: move registration message to init from net_init
2014-03-06 9:23 [PATCH 0/8] ipset patches for nf-next Jozsef Kadlecsik
` (5 preceding siblings ...)
2014-03-06 9:23 ` [PATCH 6/8] netfilter: ipset: kernel: uapi: fix MARKMASK attr ABI breakage Jozsef Kadlecsik
@ 2014-03-06 9:23 ` Jozsef Kadlecsik
2014-03-06 9:23 ` [PATCH 8/8] netfilter: ipset: add forceadd kernel support for hash set types Jozsef Kadlecsik
2014-03-07 10:48 ` [PATCH 0/8] ipset patches for nf-next Pablo Neira Ayuso
8 siblings, 0 replies; 12+ messages in thread
From: Jozsef Kadlecsik @ 2014-03-06 9:23 UTC (permalink / raw)
To: netfilter-devel; +Cc: Pablo Neira Ayuso
From: Ilia Mirkin <imirkin@alum.mit.edu>
Commit 1785e8f473 ("netfiler: ipset: Add net namespace for ipset") moved
the initialization print into net_init, which can get called a lot due
to namespaces. Move it back into init, reduce to pr_info.
Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu>
Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
---
net/netfilter/ipset/ip_set_core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c
index c6c97b8..636cb8d 100644
--- a/net/netfilter/ipset/ip_set_core.c
+++ b/net/netfilter/ipset/ip_set_core.c
@@ -1945,7 +1945,6 @@ ip_set_net_init(struct net *net)
return -ENOMEM;
inst->is_deleted = 0;
rcu_assign_pointer(inst->ip_set_list, list);
- pr_notice("ip_set: protocol %u\n", IPSET_PROTOCOL);
return 0;
}
@@ -1996,6 +1995,7 @@ ip_set_init(void)
nfnetlink_subsys_unregister(&ip_set_netlink_subsys);
return ret;
}
+ pr_info("ip_set: protocol %u\n", IPSET_PROTOCOL);
return 0;
}
--
1.7.10.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 8/8] netfilter: ipset: add forceadd kernel support for hash set types
2014-03-06 9:23 [PATCH 0/8] ipset patches for nf-next Jozsef Kadlecsik
` (6 preceding siblings ...)
2014-03-06 9:23 ` [PATCH 7/8] netfilter: ipset: move registration message to init from net_init Jozsef Kadlecsik
@ 2014-03-06 9:23 ` Jozsef Kadlecsik
2014-03-07 10:48 ` [PATCH 0/8] ipset patches for nf-next Pablo Neira Ayuso
8 siblings, 0 replies; 12+ messages in thread
From: Jozsef Kadlecsik @ 2014-03-06 9:23 UTC (permalink / raw)
To: netfilter-devel; +Cc: Pablo Neira Ayuso
From: Josh Hunt <johunt@akamai.com>
Adds a new property for hash set types, where if a set is created
with the 'forceadd' option and the set becomes full the next addition
to the set may succeed and evict a random entry from the set.
To keep overhead low eviction is done very simply. It checks to see
which bucket the new entry would be added. If the bucket's pos value
is non-zero (meaning there's at least one entry in the bucket) it
replaces the first entry in the bucket. If pos is zero, then it continues
down the normal add process.
This property is useful if you have a set for 'ban' lists where it may
not matter if you release some entries from the set early.
Signed-off-by: Josh Hunt <johunt@akamai.com>
Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
---
include/linux/netfilter/ipset/ip_set.h | 3 +++
include/uapi/linux/netfilter/ipset/ip_set.h | 7 +++++--
net/netfilter/ipset/ip_set_core.c | 2 ++
net/netfilter/ipset/ip_set_hash_gen.h | 12 ++++++++++++
net/netfilter/ipset/ip_set_hash_ip.c | 3 ++-
net/netfilter/ipset/ip_set_hash_ipmark.c | 2 +-
net/netfilter/ipset/ip_set_hash_ipport.c | 3 ++-
net/netfilter/ipset/ip_set_hash_ipportip.c | 3 ++-
net/netfilter/ipset/ip_set_hash_ipportnet.c | 3 ++-
net/netfilter/ipset/ip_set_hash_net.c | 3 ++-
net/netfilter/ipset/ip_set_hash_netiface.c | 3 ++-
net/netfilter/ipset/ip_set_hash_netnet.c | 2 +-
net/netfilter/ipset/ip_set_hash_netport.c | 3 ++-
net/netfilter/ipset/ip_set_hash_netportnet.c | 3 ++-
14 files changed, 40 insertions(+), 12 deletions(-)
diff --git a/include/linux/netfilter/ipset/ip_set.h b/include/linux/netfilter/ipset/ip_set.h
index f476bce..96afc29 100644
--- a/include/linux/netfilter/ipset/ip_set.h
+++ b/include/linux/netfilter/ipset/ip_set.h
@@ -65,6 +65,7 @@ enum ip_set_extension {
#define SET_WITH_TIMEOUT(s) ((s)->extensions & IPSET_EXT_TIMEOUT)
#define SET_WITH_COUNTER(s) ((s)->extensions & IPSET_EXT_COUNTER)
#define SET_WITH_COMMENT(s) ((s)->extensions & IPSET_EXT_COMMENT)
+#define SET_WITH_FORCEADD(s) ((s)->flags & IPSET_CREATE_FLAG_FORCEADD)
/* Extension id, in size order */
enum ip_set_ext_id {
@@ -255,6 +256,8 @@ ip_set_put_flags(struct sk_buff *skb, struct ip_set *set)
cadt_flags |= IPSET_FLAG_WITH_COUNTERS;
if (SET_WITH_COMMENT(set))
cadt_flags |= IPSET_FLAG_WITH_COMMENT;
+ if (SET_WITH_FORCEADD(set))
+ cadt_flags |= IPSET_FLAG_WITH_FORCEADD;
if (!cadt_flags)
return 0;
diff --git a/include/uapi/linux/netfilter/ipset/ip_set.h b/include/uapi/linux/netfilter/ipset/ip_set.h
index a1ca244..78c2f2e 100644
--- a/include/uapi/linux/netfilter/ipset/ip_set.h
+++ b/include/uapi/linux/netfilter/ipset/ip_set.h
@@ -185,13 +185,16 @@ enum ipset_cadt_flags {
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_BIT_WITH_FORCEADD = 5,
+ IPSET_FLAG_WITH_FORCEADD = (1 << IPSET_FLAG_BIT_WITH_FORCEADD),
IPSET_FLAG_CADT_MAX = 15,
};
/* The flag bits which correspond to the non-extension create flags */
enum ipset_create_flags {
- IPSET_CREATE_FLAG_NONE = 0,
- IPSET_CREATE_FLAG_MAX = 7,
+ IPSET_CREATE_FLAG_BIT_FORCEADD = 0,
+ IPSET_CREATE_FLAG_FORCEADD = (1 << IPSET_CREATE_FLAG_BIT_FORCEADD),
+ IPSET_CREATE_FLAG_BIT_MAX = 7,
};
/* Commands with settype-specific attributes */
diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c
index 636cb8d..1172083 100644
--- a/net/netfilter/ipset/ip_set_core.c
+++ b/net/netfilter/ipset/ip_set_core.c
@@ -368,6 +368,8 @@ ip_set_elem_len(struct ip_set *set, struct nlattr *tb[], size_t len)
if (tb[IPSET_ATTR_CADT_FLAGS])
cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
+ if (cadt_flags & IPSET_FLAG_WITH_FORCEADD)
+ set->flags |= IPSET_CREATE_FLAG_FORCEADD;
for (id = 0; id < IPSET_EXT_ID_MAX; id++) {
if (!add_extension(id, cadt_flags, tb))
continue;
diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h
index b1eed81..61c7fb0 100644
--- a/net/netfilter/ipset/ip_set_hash_gen.h
+++ b/net/netfilter/ipset/ip_set_hash_gen.h
@@ -633,6 +633,18 @@ mtype_add(struct ip_set *set, void *value, const struct ip_set_ext *ext,
bool flag_exist = flags & IPSET_FLAG_EXIST;
u32 key, multi = 0;
+ if (h->elements >= h->maxelem && SET_WITH_FORCEADD(set)) {
+ rcu_read_lock_bh();
+ t = rcu_dereference_bh(h->table);
+ key = HKEY(value, h->initval, t->htable_bits);
+ n = hbucket(t,key);
+ if (n->pos) {
+ /* Choosing the first entry in the array to replace */
+ j = 0;
+ goto reuse_slot;
+ }
+ rcu_read_unlock_bh();
+ }
if (SET_WITH_TIMEOUT(set) && h->elements >= h->maxelem)
/* FIXME: when set is full, we slow down here */
mtype_expire(set, h, NLEN(set->family), set->dsize);
diff --git a/net/netfilter/ipset/ip_set_hash_ip.c b/net/netfilter/ipset/ip_set_hash_ip.c
index e65fc24..dd40607 100644
--- a/net/netfilter/ipset/ip_set_hash_ip.c
+++ b/net/netfilter/ipset/ip_set_hash_ip.c
@@ -25,7 +25,8 @@
#define IPSET_TYPE_REV_MIN 0
/* 1 Counters support */
-#define IPSET_TYPE_REV_MAX 2 /* Comments support */
+/* 2 Comments support */
+#define IPSET_TYPE_REV_MAX 3 /* Forceadd support */
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
diff --git a/net/netfilter/ipset/ip_set_hash_ipmark.c b/net/netfilter/ipset/ip_set_hash_ipmark.c
index 1bf8e85..4eff0a2 100644
--- a/net/netfilter/ipset/ip_set_hash_ipmark.c
+++ b/net/netfilter/ipset/ip_set_hash_ipmark.c
@@ -25,7 +25,7 @@
#include <linux/netfilter/ipset/ip_set_hash.h>
#define IPSET_TYPE_REV_MIN 0
-#define IPSET_TYPE_REV_MAX 0
+#define IPSET_TYPE_REV_MAX 1 /* Forceadd support */
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Vytas Dauksa <vytas.dauksa@smoothwall.net>");
diff --git a/net/netfilter/ipset/ip_set_hash_ipport.c b/net/netfilter/ipset/ip_set_hash_ipport.c
index 525a595..7597b82 100644
--- a/net/netfilter/ipset/ip_set_hash_ipport.c
+++ b/net/netfilter/ipset/ip_set_hash_ipport.c
@@ -27,7 +27,8 @@
#define IPSET_TYPE_REV_MIN 0
/* 1 SCTP and UDPLITE support added */
/* 2 Counters support added */
-#define IPSET_TYPE_REV_MAX 3 /* Comments support added */
+/* 3 Comments support added */
+#define IPSET_TYPE_REV_MAX 4 /* Forceadd support added */
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
diff --git a/net/netfilter/ipset/ip_set_hash_ipportip.c b/net/netfilter/ipset/ip_set_hash_ipportip.c
index f563663..672655f 100644
--- a/net/netfilter/ipset/ip_set_hash_ipportip.c
+++ b/net/netfilter/ipset/ip_set_hash_ipportip.c
@@ -27,7 +27,8 @@
#define IPSET_TYPE_REV_MIN 0
/* 1 SCTP and UDPLITE support added */
/* 2 Counters support added */
-#define IPSET_TYPE_REV_MAX 3 /* Comments support added */
+/* 3 Comments support added */
+#define IPSET_TYPE_REV_MAX 4 /* Forceadd support added */
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
diff --git a/net/netfilter/ipset/ip_set_hash_ipportnet.c b/net/netfilter/ipset/ip_set_hash_ipportnet.c
index 5d87fe8..7308d84 100644
--- a/net/netfilter/ipset/ip_set_hash_ipportnet.c
+++ b/net/netfilter/ipset/ip_set_hash_ipportnet.c
@@ -29,7 +29,8 @@
/* 2 Range as input support for IPv4 added */
/* 3 nomatch flag support added */
/* 4 Counters support added */
-#define IPSET_TYPE_REV_MAX 5 /* Comments support added */
+/* 5 Comments support added */
+#define IPSET_TYPE_REV_MAX 6 /* Forceadd support added */
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
diff --git a/net/netfilter/ipset/ip_set_hash_net.c b/net/netfilter/ipset/ip_set_hash_net.c
index 8295cf4..4c7d495 100644
--- a/net/netfilter/ipset/ip_set_hash_net.c
+++ b/net/netfilter/ipset/ip_set_hash_net.c
@@ -26,7 +26,8 @@
/* 1 Range as input support for IPv4 added */
/* 2 nomatch flag support added */
/* 3 Counters support added */
-#define IPSET_TYPE_REV_MAX 4 /* Comments support added */
+/* 4 Comments support added */
+#define IPSET_TYPE_REV_MAX 5 /* Forceadd support added */
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
diff --git a/net/netfilter/ipset/ip_set_hash_netiface.c b/net/netfilter/ipset/ip_set_hash_netiface.c
index b827a0f..db26068 100644
--- a/net/netfilter/ipset/ip_set_hash_netiface.c
+++ b/net/netfilter/ipset/ip_set_hash_netiface.c
@@ -27,7 +27,8 @@
/* 1 nomatch flag support added */
/* 2 /0 support added */
/* 3 Counters support added */
-#define IPSET_TYPE_REV_MAX 4 /* Comments support added */
+/* 4 Comments support added */
+#define IPSET_TYPE_REV_MAX 5 /* Forceadd support added */
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
diff --git a/net/netfilter/ipset/ip_set_hash_netnet.c b/net/netfilter/ipset/ip_set_hash_netnet.c
index 4e7261d..3e99987 100644
--- a/net/netfilter/ipset/ip_set_hash_netnet.c
+++ b/net/netfilter/ipset/ip_set_hash_netnet.c
@@ -24,7 +24,7 @@
#include <linux/netfilter/ipset/ip_set_hash.h>
#define IPSET_TYPE_REV_MIN 0
-#define IPSET_TYPE_REV_MAX 0
+#define IPSET_TYPE_REV_MAX 1 /* Forceadd support added */
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa>");
diff --git a/net/netfilter/ipset/ip_set_hash_netport.c b/net/netfilter/ipset/ip_set_hash_netport.c
index 7097fb0..1c645fb 100644
--- a/net/netfilter/ipset/ip_set_hash_netport.c
+++ b/net/netfilter/ipset/ip_set_hash_netport.c
@@ -28,7 +28,8 @@
/* 2 Range as input support for IPv4 added */
/* 3 nomatch flag support added */
/* 4 Counters support added */
-#define IPSET_TYPE_REV_MAX 5 /* Comments support added */
+/* 5 Comments support added */
+#define IPSET_TYPE_REV_MAX 6 /* Forceadd support added */
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>");
diff --git a/net/netfilter/ipset/ip_set_hash_netportnet.c b/net/netfilter/ipset/ip_set_hash_netportnet.c
index 703d119..c0d2ba7 100644
--- a/net/netfilter/ipset/ip_set_hash_netportnet.c
+++ b/net/netfilter/ipset/ip_set_hash_netportnet.c
@@ -25,7 +25,8 @@
#include <linux/netfilter/ipset/ip_set_hash.h>
#define IPSET_TYPE_REV_MIN 0
-#define IPSET_TYPE_REV_MAX 0 /* Comments support added */
+/* 0 Comments support added */
+#define IPSET_TYPE_REV_MAX 1 /* Forceadd support added */
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa>");
--
1.7.10.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 0/8] ipset patches for nf-next
2014-03-06 9:23 [PATCH 0/8] ipset patches for nf-next Jozsef Kadlecsik
` (7 preceding siblings ...)
2014-03-06 9:23 ` [PATCH 8/8] netfilter: ipset: add forceadd kernel support for hash set types Jozsef Kadlecsik
@ 2014-03-07 10:48 ` Pablo Neira Ayuso
8 siblings, 0 replies; 12+ messages in thread
From: Pablo Neira Ayuso @ 2014-03-07 10:48 UTC (permalink / raw)
To: Jozsef Kadlecsik; +Cc: netfilter-devel
On Thu, Mar 06, 2014 at 10:23:40AM +0100, Jozsef Kadlecsik wrote:
> Hi Pablo,
>
> Please consider to apply the next series of patches:
>
> * Follow the manual page behavior for the SET target at list:set
> type of sets when the set contains both inet and inet6 type of sets,
> from Sergey Popovich
> * Fix coccinelle warnings about 0/1 return values instead of false/true,
> from Fengguang Wu
> * Introduce the hash:ip,mark hash type from Vytas Dauksa
> * Add markmask option to hash:ip,mark type from Vytas Dauksa
> * Prepare the kernel for create option flags when no extension is needed
> from Jozsef Kadlecsik
> * Fix ABI breakage by the markmask option patch, from Florian Westphal
> * Move registration message to init from net_init from Ilia Mirkin
> * Add forceadd kernel support for hash set types from Josh Hunt.
>
> You can pull the changes from
>
> git://blackhole.kfki.hu/nf-next master
Pulled, thanks Jozsef.
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 0/8] ipset patches for nf-next
@ 2014-09-15 21:02 Jozsef Kadlecsik
2014-09-16 16:50 ` Pablo Neira Ayuso
0 siblings, 1 reply; 12+ messages in thread
From: Jozsef Kadlecsik @ 2014-09-15 21:02 UTC (permalink / raw)
To: netfilter-devel; +Cc: Pablo Neira Ayuso
Hi Pablo,
Please consider to apply the next series of patches:
- the new hash:mac type by which it's easy to store
just the MAC addresses in a set
- an optimization to the skbinfo expression, which
suppresses sending zero valued extensions
- the skbinfo extension support to the SET
target from Anton Danilov
- the skbinfo extension support for the list,
hash and bitmap types separatedly
from Anton Danilov
- the skbinfo extension support in the ipset
core from Anton Danilov
- a fix for a static checker warning in
ip_set_core.c, reported by Dan Carpenter
The skbinfo extension makes possible to store
fw mark, tc class and/or hardware queue parameters
together with the set elements and then attach
them to the matchig packets by the SET target.
You can pull the changes from
git://blackhole.kfki.hu/nf-next master
The iptables part of the new SET target functionality
can be found in the iptables git tree, in the ipset
branch.
Thanks,
Jozsef
============================================================================
The following changes since commit 0bbe80e571c7b866afd92a98edd32a969467a7a9:
netfilter: masquerading needs to be independent of x_tables in Kconfig (2014-09-12 09:40:18 +0200)
are available in the git repository at:
git://blackhole.kfki.hu/nf-next master
for you to fetch changes up to 07034aeae152de52c29f032ca995bf9dafbe24e2:
netfilter: ipset: hash:mac type added to ipset (2014-09-15 22:20:21 +0200)
----------------------------------------------------------------
Anton Danilov (5):
netfilter: ipset: Add skbinfo extension kernel support in the ipset core.
netfilter: ipset: Add skbinfo extension kernel support for the bitmap set types.
netfilter: ipset: Add skbinfo extension kernel support for the hash set types.
netfilter: ipset: Add skbinfo extension kernel support for the list set type.
netfilter: ipset: Add skbinfo extension support to SET target.
Jozsef Kadlecsik (3):
netfilter: ipset: Fix static checker warning in ip_set_core.c
netfilter: ipset: send nonzero skbinfo extensions only
netfilter: ipset: hash:mac type added to ipset
include/linux/netfilter/ipset/ip_set.h | 60 +++++++++-
include/uapi/linux/netfilter/ipset/ip_set.h | 12 ++
include/uapi/linux/netfilter/xt_set.h | 10 ++
net/netfilter/ipset/Kconfig | 9 ++
net/netfilter/ipset/Makefile | 1 +
net/netfilter/ipset/ip_set_bitmap_gen.h | 4 +
net/netfilter/ipset/ip_set_bitmap_ip.c | 11 +-
net/netfilter/ipset/ip_set_bitmap_ipmac.c | 11 +-
net/netfilter/ipset/ip_set_bitmap_port.c | 11 +-
net/netfilter/ipset/ip_set_core.c | 30 ++++-
net/netfilter/ipset/ip_set_hash_gen.h | 16 ++-
net/netfilter/ipset/ip_set_hash_ip.c | 14 ++-
net/netfilter/ipset/ip_set_hash_ipmark.c | 14 ++-
net/netfilter/ipset/ip_set_hash_ipport.c | 14 ++-
net/netfilter/ipset/ip_set_hash_ipportip.c | 14 ++-
net/netfilter/ipset/ip_set_hash_ipportnet.c | 14 ++-
net/netfilter/ipset/ip_set_hash_mac.c | 173 +++++++++++++++++++++++++++
net/netfilter/ipset/ip_set_hash_net.c | 16 ++-
net/netfilter/ipset/ip_set_hash_netiface.c | 16 ++-
net/netfilter/ipset/ip_set_hash_netnet.c | 16 ++-
net/netfilter/ipset/ip_set_hash_netport.c | 16 ++-
net/netfilter/ipset/ip_set_hash_netportnet.c | 16 ++-
net/netfilter/ipset/ip_set_list_set.c | 19 ++-
net/netfilter/xt_set.c | 155 ++++++++++++++++++++++++
24 files changed, 635 insertions(+), 37 deletions(-)
create mode 100644 net/netfilter/ipset/ip_set_hash_mac.c
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 0/8] ipset patches for nf-next
2014-09-15 21:02 Jozsef Kadlecsik
@ 2014-09-16 16:50 ` Pablo Neira Ayuso
0 siblings, 0 replies; 12+ messages in thread
From: Pablo Neira Ayuso @ 2014-09-16 16:50 UTC (permalink / raw)
To: Jozsef Kadlecsik; +Cc: netfilter-devel
On Mon, Sep 15, 2014 at 11:02:46PM +0200, Jozsef Kadlecsik wrote:
> Hi Pablo,
>
> Please consider to apply the next series of patches:
>
> - the new hash:mac type by which it's easy to store
> just the MAC addresses in a set
> - an optimization to the skbinfo expression, which
> suppresses sending zero valued extensions
> - the skbinfo extension support to the SET
> target from Anton Danilov
> - the skbinfo extension support for the list,
> hash and bitmap types separatedly
> from Anton Danilov
> - the skbinfo extension support in the ipset
> core from Anton Danilov
> - a fix for a static checker warning in
> ip_set_core.c, reported by Dan Carpenter
>
> The skbinfo extension makes possible to store
> fw mark, tc class and/or hardware queue parameters
> together with the set elements and then attach
> them to the matchig packets by the SET target.
>
> You can pull the changes from
>
> git://blackhole.kfki.hu/nf-next master
Pulled, thanks Jozsef.
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2014-09-16 16:49 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-03-06 9:23 [PATCH 0/8] ipset patches for nf-next Jozsef Kadlecsik
2014-03-06 9:23 ` [PATCH 1/8] netfilter: ipset: Follow manual page behavior for SET target on list:set Jozsef Kadlecsik
2014-03-06 9:23 ` [PATCH 2/8] netfilter: ipset: Add hash: fix coccinelle warnings Jozsef Kadlecsik
2014-03-06 9:23 ` [PATCH 3/8] netfilter: ipset: add hash:ip,mark data type to ipset Jozsef Kadlecsik
2014-03-06 9:23 ` [PATCH 4/8] netfilter: ipset: add markmask for hash:ip,mark data type Jozsef Kadlecsik
2014-03-06 9:23 ` [PATCH 5/8] netfilter: ipset: Prepare the kernel for create option flags when no extension is needed Jozsef Kadlecsik
2014-03-06 9:23 ` [PATCH 6/8] netfilter: ipset: kernel: uapi: fix MARKMASK attr ABI breakage Jozsef Kadlecsik
2014-03-06 9:23 ` [PATCH 7/8] netfilter: ipset: move registration message to init from net_init Jozsef Kadlecsik
2014-03-06 9:23 ` [PATCH 8/8] netfilter: ipset: add forceadd kernel support for hash set types Jozsef Kadlecsik
2014-03-07 10:48 ` [PATCH 0/8] ipset patches for nf-next Pablo Neira Ayuso
-- strict thread matches above, loose matches on Subject: below --
2014-09-15 21:02 Jozsef Kadlecsik
2014-09-16 16:50 ` Pablo Neira Ayuso
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).