From: Oliver <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa>
To: netfilter-devel@vger.kernel.org
Subject: [PATCH v2 1/2] netfilter: ipset: rework hash ext. handling to be more manageable.
Date: Sun, 1 Sep 2013 21:58:41 +0200 [thread overview]
Message-ID: <1378065522-65492-2-git-send-email-oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa> (raw)
In-Reply-To: <1378065522-65492-1-git-send-email-oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa>
From: Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa>
The previous code that handled all the various combinations of ipset
extensions in the hash family consisted of trees of if/else statements
that check all the possible extension combinations. This patch
simplifies that code down to a couple of switch statements and a
preprocessor macro to facilite appropriate setup.
This should significantly reduce the new lines of code that would have
to be introduced to add more extensions in the future.
Signed-off-by: Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa>
---
kernel/include/uapi/linux/netfilter/ipset/ip_set.h | 8 +-
kernel/net/netfilter/ipset/ip_set_hash_gen.h | 121 ++++++++-------------
2 files changed, 54 insertions(+), 75 deletions(-)
diff --git a/kernel/include/uapi/linux/netfilter/ipset/ip_set.h b/kernel/include/uapi/linux/netfilter/ipset/ip_set.h
index 8024cdf..17779ca 100644
--- a/kernel/include/uapi/linux/netfilter/ipset/ip_set.h
+++ b/kernel/include/uapi/linux/netfilter/ipset/ip_set.h
@@ -166,7 +166,11 @@ enum ipset_cmd_flags {
IPSET_FLAG_CMD_MAX = 15,
};
-/* Flags at CADT attribute level, upper half of cmdattrs */
+/* Flags at CADT attribute level, upper half of cmdattrs
+ *
+ * We recycle NOMATCH for TIMEOUT since it is only used for
+ * ipset creation.
+ */
enum ipset_cadt_flags {
IPSET_FLAG_BIT_BEFORE = 0,
IPSET_FLAG_BEFORE = (1 << IPSET_FLAG_BIT_BEFORE),
@@ -174,6 +178,8 @@ enum ipset_cadt_flags {
IPSET_FLAG_PHYSDEV = (1 << IPSET_FLAG_BIT_PHYSDEV),
IPSET_FLAG_BIT_NOMATCH = 2,
IPSET_FLAG_NOMATCH = (1 << IPSET_FLAG_BIT_NOMATCH),
+ IPSET_FLAG_EXT_BEGIN = 2,
+ IPSET_FLAG_WITH_TIMEOUTS = (1 << IPSET_FLAG_EXT_BEGIN),
IPSET_FLAG_BIT_WITH_COUNTERS = 3,
IPSET_FLAG_WITH_COUNTERS = (1 << IPSET_FLAG_BIT_WITH_COUNTERS),
IPSET_FLAG_CADT_MAX = 15,
diff --git a/kernel/net/netfilter/ipset/ip_set_hash_gen.h b/kernel/net/netfilter/ipset/ip_set_hash_gen.h
index 906c778..047a877 100644
--- a/kernel/net/netfilter/ipset/ip_set_hash_gen.h
+++ b/kernel/net/netfilter/ipset/ip_set_hash_gen.h
@@ -1056,6 +1056,7 @@ IPSET_TOKEN(HTYPE, _create)(struct ip_set *set, struct nlattr *tb[], u32 flags)
u32 hashsize = IPSET_DEFAULT_HASHSIZE, maxelem = IPSET_DEFAULT_MAXELEM;
u32 cadt_flags = 0;
u8 hbits;
+ int i = IPSET_FLAG_EXT_BEGIN, t_off = 0, c_off = 0;
#ifdef IP_SET_HASH_WITH_NETMASK
u8 netmask;
#endif
@@ -1134,82 +1135,54 @@ IPSET_TOKEN(HTYPE, _create)(struct ip_set *set, struct nlattr *tb[], u32 flags)
set->variant = &IPSET_TOKEN(HTYPE, 6_variant);
if (tb[IPSET_ATTR_CADT_FLAGS])
- cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]);
- if (cadt_flags & IPSET_FLAG_WITH_COUNTERS) {
- set->extensions |= IPSET_EXT_COUNTER;
- if (tb[IPSET_ATTR_TIMEOUT]) {
- h->timeout =
- ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
- set->extensions |= IPSET_EXT_TIMEOUT;
- if (set->family == NFPROTO_IPV4) {
- h->dsize = sizeof(struct
- IPSET_TOKEN(HTYPE, 4ct_elem));
- h->offset[IPSET_OFFSET_TIMEOUT] =
- offsetof(struct
- IPSET_TOKEN(HTYPE, 4ct_elem),
- timeout);
- h->offset[IPSET_OFFSET_COUNTER] =
- offsetof(struct
- IPSET_TOKEN(HTYPE, 4ct_elem),
- counter);
- IPSET_TOKEN(HTYPE, 4_gc_init)(set,
- IPSET_TOKEN(HTYPE, 4_gc));
- } else {
- h->dsize = sizeof(struct
- IPSET_TOKEN(HTYPE, 6ct_elem));
- h->offset[IPSET_OFFSET_TIMEOUT] =
- offsetof(struct
- IPSET_TOKEN(HTYPE, 6ct_elem),
- timeout);
- h->offset[IPSET_OFFSET_COUNTER] =
- offsetof(struct
- IPSET_TOKEN(HTYPE, 6ct_elem),
- counter);
- IPSET_TOKEN(HTYPE, 6_gc_init)(set,
- IPSET_TOKEN(HTYPE, 6_gc));
- }
- } else {
- if (set->family == NFPROTO_IPV4) {
- h->dsize =
- sizeof(struct
- IPSET_TOKEN(HTYPE, 4c_elem));
- h->offset[IPSET_OFFSET_COUNTER] =
- offsetof(struct
- IPSET_TOKEN(HTYPE, 4c_elem),
- counter);
- } else {
- h->dsize =
- sizeof(struct
- IPSET_TOKEN(HTYPE, 6c_elem));
- h->offset[IPSET_OFFSET_COUNTER] =
- offsetof(struct
- IPSET_TOKEN(HTYPE, 6c_elem),
- counter);
- }
+ cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]) & ~IPSET_FLAG_EXT_BEGIN;
+ if (tb[IPSET_ATTR_TIMEOUT])
+ cadt_flags |= IPSET_FLAG_WITH_TIMEOUTS;
+/* Due to the inherent limitations of a preprocessor macro, all vars are set
+ * and we simply use the ones we need during the flag iteration stage.
+ */
+#define generate_offsets(X,C,T) \
+if(set->family == NFPROTO_IPV4) { \
+ h->dsize = sizeof(struct IPSET_TOKEN(HTYPE, IPSET_TOKEN(4, X))); \
+ c_off = offsetof(struct IPSET_TOKEN(HTYPE, IPSET_TOKEN(4, C)), counter);\
+ t_off = offsetof(struct IPSET_TOKEN(HTYPE, IPSET_TOKEN(4, T)), timeout);\
+} else { \
+ h->dsize = sizeof(struct IPSET_TOKEN(HTYPE, IPSET_TOKEN(4, X))); \
+ c_off = offsetof(struct IPSET_TOKEN(HTYPE, IPSET_TOKEN(4, C)), counter);\
+ t_off = offsetof(struct IPSET_TOKEN(HTYPE, IPSET_TOKEN(4, T)), timeout);\
+}
+ if(!cadt_flags) {
+ generate_offsets(_elem,c_elem,t_elem);
+ } else {
+ switch(cadt_flags) {
+ case (IPSET_FLAG_WITH_COUNTERS |
+ IPSET_FLAG_WITH_TIMEOUTS) :
+ generate_offsets(ct_elem, ct_elem, ct_elem);
+ break;
+ case IPSET_FLAG_WITH_TIMEOUTS :
+ generate_offsets(t_elem, c_elem, t_elem);
+ break;
+ case IPSET_FLAG_WITH_COUNTERS :
+ generate_offsets(c_elem, c_elem, t_elem);
+ break;
}
- } else if (tb[IPSET_ATTR_TIMEOUT]) {
- h->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
- set->extensions |= IPSET_EXT_TIMEOUT;
- if (set->family == NFPROTO_IPV4) {
- h->dsize = sizeof(struct IPSET_TOKEN(HTYPE, 4t_elem));
- h->offset[IPSET_OFFSET_TIMEOUT] =
- offsetof(struct IPSET_TOKEN(HTYPE, 4t_elem),
- timeout);
- IPSET_TOKEN(HTYPE, 4_gc_init)(set,
- IPSET_TOKEN(HTYPE, 4_gc));
- } else {
- h->dsize = sizeof(struct IPSET_TOKEN(HTYPE, 6t_elem));
- h->offset[IPSET_OFFSET_TIMEOUT] =
- offsetof(struct IPSET_TOKEN(HTYPE, 6t_elem),
- timeout);
- IPSET_TOKEN(HTYPE, 6_gc_init)(set,
- IPSET_TOKEN(HTYPE, 6_gc));
+ for(; i < (1 << IPSET_FLAG_CADT_MAX); i = (i << 1)) {
+ switch(cadt_flags & i) {
+ case IPSET_FLAG_WITH_COUNTERS:
+ set->extensions |= IPSET_EXT_COUNTER;
+ h->offset[IPSET_OFFSET_COUNTER] = c_off;
+ break;
+ case IPSET_FLAG_WITH_TIMEOUTS:
+ set->extensions |= IPSET_EXT_TIMEOUT;
+ h->offset[IPSET_OFFSET_TIMEOUT] = t_off;
+ h->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]);
+ if(set->family == NFPROTO_IPV4)
+ IPSET_TOKEN(HTYPE, 4_gc_init)(set, IPSET_TOKEN(HTYPE, 4_gc));
+ else
+ IPSET_TOKEN(HTYPE, 6_gc_init)(set, IPSET_TOKEN(HTYPE, 6_gc));
+ break;
+ }
}
- } else {
- if (set->family == NFPROTO_IPV4)
- h->dsize = sizeof(struct IPSET_TOKEN(HTYPE, 4_elem));
- else
- h->dsize = sizeof(struct IPSET_TOKEN(HTYPE, 6_elem));
}
pr_debug("create %s hashsize %u (%u) maxelem %u: %p(%p)\n",
--
1.8.3.2
next prev parent reply other threads:[~2013-09-01 19:59 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-09-01 19:58 [PATCH v2 0/2] ipset: rework extension handling to be more manageable Oliver
2013-09-01 19:58 ` Oliver [this message]
2013-09-01 19:58 ` [PATCH v2 2/2] netfilter: ipset: rework bitmap ext. " Oliver
2013-09-02 20:04 ` [PATCH v2 0/2] ipset: rework extension " Jozsef Kadlecsik
2013-09-03 10:49 ` Oliver
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1378065522-65492-2-git-send-email-oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa \
--to=oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa \
--cc=netfilter-devel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).