summaryrefslogtreecommitdiff
path: root/include/net/netfilter/nf_conntrack_zones.h
diff options
context:
space:
mode:
authorDaniel Borkmann <daniel@iogearbox.net>2015-08-14 16:03:40 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2015-08-18 01:24:05 +0200
commit5e8018fc61423e677398d4ad4d72df70b9788e77 (patch)
tree5605633fddd52cf0a677ad6f62fb8bb2e7a46054 /include/net/netfilter/nf_conntrack_zones.h
parentdeedb59039f111c41aa5a54ee384c8e7c08bc78a (diff)
netfilter: nf_conntrack: add efficient mark to zone mapping
This work adds the possibility of deriving the zone id from the skb->mark field in a scalable manner. This allows for having only a single template serving hundreds/thousands of different zones, for example, instead of the need to have one match for each zone as an extra CT jump target. Note that we'd need to have this information attached to the template as at the time when we're trying to lookup a possible ct object, we already need to know zone information for a possible match when going into __nf_conntrack_find_get(). This work provides a minimal implementation for a possible mapping. In order to not add/expose an extra ct->status bit, the zone structure has been extended to carry a flag for deriving the mark. Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'include/net/netfilter/nf_conntrack_zones.h')
-rw-r--r--include/net/netfilter/nf_conntrack_zones.h45
1 files changed, 42 insertions, 3 deletions
diff --git a/include/net/netfilter/nf_conntrack_zones.h b/include/net/netfilter/nf_conntrack_zones.h
index 3942ddf0d4ff..5316c7b3a374 100644
--- a/include/net/netfilter/nf_conntrack_zones.h
+++ b/include/net/netfilter/nf_conntrack_zones.h
@@ -10,9 +10,12 @@
#define NF_CT_DEFAULT_ZONE_DIR (NF_CT_ZONE_DIR_ORIG | NF_CT_ZONE_DIR_REPL)
+#define NF_CT_FLAG_MARK 1
+
struct nf_conntrack_zone {
u16 id;
- u16 dir;
+ u8 flags;
+ u8 dir;
};
extern const struct nf_conntrack_zone nf_ct_zone_dflt;
@@ -32,9 +35,45 @@ nf_ct_zone(const struct nf_conn *ct)
}
static inline const struct nf_conntrack_zone *
-nf_ct_zone_tmpl(const struct nf_conn *tmpl)
+nf_ct_zone_init(struct nf_conntrack_zone *zone, u16 id, u8 dir, u8 flags)
+{
+ zone->id = id;
+ zone->flags = flags;
+ zone->dir = dir;
+
+ return zone;
+}
+
+static inline const struct nf_conntrack_zone *
+nf_ct_zone_tmpl(const struct nf_conn *tmpl, const struct sk_buff *skb,
+ struct nf_conntrack_zone *tmp)
+{
+ const struct nf_conntrack_zone *zone;
+
+ if (!tmpl)
+ return &nf_ct_zone_dflt;
+
+ zone = nf_ct_zone(tmpl);
+ if (zone->flags & NF_CT_FLAG_MARK)
+ zone = nf_ct_zone_init(tmp, skb->mark, zone->dir, 0);
+
+ return zone;
+}
+
+static inline int nf_ct_zone_add(struct nf_conn *ct, gfp_t flags,
+ const struct nf_conntrack_zone *info)
{
- return tmpl ? nf_ct_zone(tmpl) : &nf_ct_zone_dflt;
+#ifdef CONFIG_NF_CONNTRACK_ZONES
+ struct nf_conntrack_zone *nf_ct_zone;
+
+ nf_ct_zone = nf_ct_ext_add(ct, NF_CT_EXT_ZONE, flags);
+ if (!nf_ct_zone)
+ return -ENOMEM;
+
+ nf_ct_zone_init(nf_ct_zone, info->id, info->dir,
+ info->flags);
+#endif
+ return 0;
}
static inline bool nf_ct_zone_matches_dir(const struct nf_conntrack_zone *zone,