From patchwork Sun Sep 1 19:58:42 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oliver Smith X-Patchwork-Id: 271644 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 988432C0091 for ; Mon, 2 Sep 2013 06:00:49 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755344Ab3IAUAe (ORCPT ); Sun, 1 Sep 2013 16:00:34 -0400 Received: from mail.uptheinter.net ([77.74.196.236]:55038 "EHLO mail.uptheinter.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755220Ab3IAUAb (ORCPT ); Sun, 1 Sep 2013 16:00:31 -0400 Received: from localhost (localhost [127.0.0.1]) by mail.uptheinter.net (Postfix) with ESMTP id B3431A2C73 for ; Sun, 1 Sep 2013 21:00:30 +0100 (BST) X-DKIM: Sendmail DKIM Filter v2.7.2 mail.uptheinter.net B3431A2C73 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa; s=default; t=1378065630; bh=5iq e0+lJ50JtJMi6/He5jq41oMCSefv+fXkdhIE1sso=; h=From:To:Subject:Date: Message-Id:In-Reply-To:References; b=uTZx8VWjC7cwf38PAurGjrb2J0wA4 5EBSEb6WaFHRl06a64JI5FCUIHQCAzzjGAT0Ldt+p1pLOTXP6cp6m/JRo9Sh5ZEIu6D /B2MB/I/p3v2Bg1D7jROFdUR0BOAsdGBwWPNSQgXhVU/0z2B/vc1i+pMOqMmzAsITRv Z80Psg7I= X-Virus-Scanned: amavisd-new at Received: from mail.uptheinter.net ([127.0.0.1]) by localhost (vps2.uptheinter.net [127.0.0.1]) (amavisd-new, port 10024) with LMTP id ENtR_UhvLhG9 for ; Sun, 1 Sep 2013 20:59:52 +0100 (BST) From: Oliver To: netfilter-devel@vger.kernel.org Subject: [PATCH v2 2/2] netfilter: ipset: rework bitmap ext. handling to be more manageable. Date: Sun, 1 Sep 2013 21:58:42 +0200 Message-Id: <1378065522-65492-3-git-send-email-oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <1378065522-65492-1-git-send-email-oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa> References: <1378065522-65492-1-git-send-email-oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa> Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org From: Oliver Smith The previous code that handled all the various combinations of ipset extensions in the bitmap family was largely duplicated across the various types. Additionally, it also had trees of if/else statements that check the possible extension combinations. This patch simplifies and deduplicates most of that code using the same means as the preceeding patch to simplify extension handling within the hash family. 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 --- kernel/net/netfilter/ipset/ip_set_bitmap_gen.h | 55 +++++++++++++++++++ kernel/net/netfilter/ipset/ip_set_bitmap_ip.c | 68 +++--------------------- kernel/net/netfilter/ipset/ip_set_bitmap_ipmac.c | 63 +++------------------- kernel/net/netfilter/ipset/ip_set_bitmap_port.c | 57 ++------------------ 4 files changed, 75 insertions(+), 168 deletions(-) diff --git a/kernel/net/netfilter/ipset/ip_set_bitmap_gen.h b/kernel/net/netfilter/ipset/ip_set_bitmap_gen.h index d39905e..097da65 100644 --- a/kernel/net/netfilter/ipset/ip_set_bitmap_gen.h +++ b/kernel/net/netfilter/ipset/ip_set_bitmap_gen.h @@ -15,6 +15,7 @@ #define mtype_do_del IPSET_TOKEN(MTYPE, _do_del) #define mtype_do_list IPSET_TOKEN(MTYPE, _do_list) #define mtype_do_head IPSET_TOKEN(MTYPE, _do_head) +#define mtype_do_create IPSET_TOKEN(MTYPE, _do_create) #define mtype_adt_elem IPSET_TOKEN(MTYPE, _adt_elem) #define mtype_add_timeout IPSET_TOKEN(MTYPE, _add_timeout) #define mtype_gc_init IPSET_TOKEN(MTYPE, _gc_init) @@ -256,6 +257,60 @@ mtype_gc(unsigned long ul_set) add_timer(&map->gc); } +#define generate_offsets(X,C,T) \ + map->dsize = sizeof(struct IPSET_TOKEN(mtype, X)); \ + c_off = offsetof(struct IPSET_TOKEN(mtype, C), counter); \ + t_off = offsetof(struct IPSET_TOKEN(mtype, T), timeout); + +static inline int +mtype_do_create(struct mtype *map, struct nlattr *tb[], struct ip_set *set, create_args) +{ + unsigned int cadt_flags = 0, i = IPSET_FLAG_EXT_BEGIN; + int c_off = 0, t_off = 0; + + if(tb[IPSET_ATTR_CADT_FLAGS]) + 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; + + if (!cadt_flags) { + map->dsize = 0; + INIT_MAP(); + } 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; + } + for(; i < (1 << IPSET_FLAG_CADT_MAX) ; i = (i << 1)) { + switch (cadt_flags & i) { + case IPSET_FLAG_WITH_COUNTERS: + map->offset[IPSET_OFFSET_COUNTER] = c_off; + set->extensions |= IPSET_EXT_COUNTER; + break; + case IPSET_FLAG_WITH_TIMEOUTS: + map->offset[IPSET_OFFSET_TIMEOUT] = t_off; + set->extensions |= IPSET_EXT_TIMEOUT; + break; + } + } + INIT_MAP(); + /* Since we can't set the timeout until after init, we check again */ + if (cadt_flags & IPSET_FLAG_WITH_TIMEOUTS) { + map->timeout = ip_set_timeout_uget(tb[IPSET_ATTR_TIMEOUT]); + IPSET_TOKEN(mtype, _gc_init)(set, IPSET_TOKEN(mtype, _gc)); + } + } + return 0; +} + static const struct ip_set_type_variant mtype = { .kadt = mtype_kadt, .uadt = mtype_uadt, diff --git a/kernel/net/netfilter/ipset/ip_set_bitmap_ip.c b/kernel/net/netfilter/ipset/ip_set_bitmap_ip.c index ce99d26..8736e75 100644 --- a/kernel/net/netfilter/ipset/ip_set_bitmap_ip.c +++ b/kernel/net/netfilter/ipset/ip_set_bitmap_ip.c @@ -228,8 +228,6 @@ struct bitmap_ipct_elem { struct ip_set_counter counter; }; -#include "ip_set_bitmap_gen.h" - /* Create bitmap:ip type of sets */ static bool @@ -260,11 +258,17 @@ init_map_ip(struct ip_set *set, struct bitmap_ip *map, return true; } +#define create_args u32 first_ip, u32 last_ip, u32 hosts, \ + u64 elements, u8 netmask +#define INIT_MAP() init_map_ip(set, map, first_ip, last_ip, \ + elements, hosts, netmask) +#include "ip_set_bitmap_gen.h" + static int bitmap_ip_create(struct ip_set *set, struct nlattr *tb[], u32 flags) { struct bitmap_ip *map; - u32 first_ip = 0, last_ip = 0, hosts, cadt_flags = 0; + u32 first_ip = 0, last_ip = 0, hosts; u64 elements; u8 netmask = 32; int ret; @@ -336,63 +340,7 @@ bitmap_ip_create(struct ip_set *set, struct nlattr *tb[], u32 flags) map->memsize = bitmap_bytes(0, elements - 1); set->variant = &bitmap_ip; - 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]) { - map->dsize = sizeof(struct bitmap_ipct_elem); - map->offset[IPSET_OFFSET_TIMEOUT] = - offsetof(struct bitmap_ipct_elem, 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); - } else { - map->dsize = 0; - if (!init_map_ip(set, map, first_ip, last_ip, - elements, hosts, netmask)) { - kfree(map); - return -ENOMEM; - } - } - return 0; + return mtype_do_create(map, tb, set, first_ip, last_ip, hosts, elements, netmask); } static struct ip_set_type bitmap_ip_type __read_mostly = { diff --git a/kernel/net/netfilter/ipset/ip_set_bitmap_ipmac.c b/kernel/net/netfilter/ipset/ip_set_bitmap_ipmac.c index 6d5bad9..ba2cd3e 100644 --- a/kernel/net/netfilter/ipset/ip_set_bitmap_ipmac.c +++ b/kernel/net/netfilter/ipset/ip_set_bitmap_ipmac.c @@ -322,8 +322,6 @@ struct bitmap_ipmacct_elem { struct ip_set_counter counter; }; -#include "ip_set_bitmap_gen.h" - /* Create bitmap:ip,mac type of sets */ static bool @@ -351,11 +349,16 @@ init_map_ipmac(struct ip_set *set, struct bitmap_ipmac *map, return true; } +#define create_args u32 first_ip, u32 last_ip, u64 elements +#define INIT_MAP() init_map_ipmac(set, map, first_ip, last_ip, elements) + +#include "ip_set_bitmap_gen.h" + static int bitmap_ipmac_create(struct ip_set *set, struct nlattr *tb[], u32 flags) { - u32 first_ip = 0, last_ip = 0, cadt_flags = 0; + u32 first_ip = 0, last_ip = 0; u64 elements; struct bitmap_ipmac *map; int ret; @@ -399,59 +402,7 @@ bitmap_ipmac_create(struct ip_set *set, struct nlattr *tb[], map->memsize = bitmap_bytes(0, elements - 1); set->variant = &bitmap_ipmac; - 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]) { - map->dsize = sizeof(struct bitmap_ipmacct_elem); - map->offset[IPSET_OFFSET_TIMEOUT] = - offsetof(struct bitmap_ipmacct_elem, 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); - } 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 mtype_do_create(map, tb, set, first_ip, last_ip, elements); } static struct ip_set_type bitmap_ipmac_type = { diff --git a/kernel/net/netfilter/ipset/ip_set_bitmap_port.c b/kernel/net/netfilter/ipset/ip_set_bitmap_port.c index b220489..70a9c09 100644 --- a/kernel/net/netfilter/ipset/ip_set_bitmap_port.c +++ b/kernel/net/netfilter/ipset/ip_set_bitmap_port.c @@ -219,8 +219,6 @@ struct bitmap_portct_elem { struct ip_set_counter counter; }; -#include "ip_set_bitmap_gen.h" - /* Create bitmap:ip type of sets */ static bool @@ -247,12 +245,15 @@ init_map_port(struct ip_set *set, struct bitmap_port *map, return true; } +#define create_args u32 first_port, u32 last_port +#define INIT_MAP() init_map_port(set, map, first_port, last_port) +#include "ip_set_bitmap_gen.h" + static int bitmap_port_create(struct ip_set *set, struct nlattr *tb[], u32 flags) { struct bitmap_port *map; u16 first_port, last_port; - u32 cadt_flags = 0; if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_PORT) || !ip_set_attr_netorder(tb, IPSET_ATTR_PORT_TO) || @@ -276,55 +277,7 @@ bitmap_port_create(struct ip_set *set, struct nlattr *tb[], u32 flags) map->elements = last_port - first_port + 1; map->memsize = map->elements * sizeof(unsigned long); set->variant = &bitmap_port; - 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]) { - map->dsize = sizeof(struct bitmap_portct_elem); - map->offset[IPSET_OFFSET_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); - } else { - map->dsize = 0; - if (!init_map_port(set, map, first_port, last_port)) { - kfree(map); - return -ENOMEM; - } - - } - return 0; + return mtype_do_create(map, tb, set, first_port, last_port); } static struct ip_set_type bitmap_port_type = {