aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2014-11-24 15:25:57 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2014-11-27 12:41:06 +0100
commitc41884ce0562841b98fa9790c9209c9073121a15 (patch)
tree563949243cc2bb9f83bddee7d94ce27ca541cf1c
parentnetfilter: xt_recent: relax ip_pkt_list_tot restrictions (diff)
downloadlinux-dev-c41884ce0562841b98fa9790c9209c9073121a15.tar.xz
linux-dev-c41884ce0562841b98fa9790c9209c9073121a15.zip
netfilter: conntrack: avoid zeroing timer
add a __nfct_init_offset annotation member to struct nf_conn to make it clear which members are covered by the memset when the conntrack is allocated. This avoids zeroing timer_list and ct_net; both are already inited explicitly. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--include/net/netfilter/nf_conntrack.h15
-rw-r--r--net/netfilter/nf_conntrack_core.c11
2 files changed, 13 insertions, 13 deletions
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
index c8a7db605e03..f0daed2b54d1 100644
--- a/include/net/netfilter/nf_conntrack.h
+++ b/include/net/netfilter/nf_conntrack.h
@@ -92,12 +92,18 @@ struct nf_conn {
/* Have we seen traffic both ways yet? (bitset) */
unsigned long status;
- /* If we were expected by an expectation, this will be it */
- struct nf_conn *master;
-
/* Timer function; drops refcnt when it goes off. */
struct timer_list timeout;
+#ifdef CONFIG_NET_NS
+ struct net *ct_net;
+#endif
+ /* all members below initialized via memset */
+ u8 __nfct_init_offset[0];
+
+ /* If we were expected by an expectation, this will be it */
+ struct nf_conn *master;
+
#if defined(CONFIG_NF_CONNTRACK_MARK)
u_int32_t mark;
#endif
@@ -108,9 +114,6 @@ struct nf_conn {
/* Extensions */
struct nf_ct_ext *ext;
-#ifdef CONFIG_NET_NS
- struct net *ct_net;
-#endif
/* Storage reserved for other modules, must be the last member */
union nf_conntrack_proto proto;
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 2c699757bccf..9ef88c8dd68a 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -826,22 +826,19 @@ __nf_conntrack_alloc(struct net *net, u16 zone,
atomic_dec(&net->ct.count);
return ERR_PTR(-ENOMEM);
}
- /*
- * Let ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode.next
- * and ct->tuplehash[IP_CT_DIR_REPLY].hnnode.next unchanged.
- */
- memset(&ct->tuplehash[IP_CT_DIR_MAX], 0,
- offsetof(struct nf_conn, proto) -
- offsetof(struct nf_conn, tuplehash[IP_CT_DIR_MAX]));
spin_lock_init(&ct->lock);
ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple = *orig;
ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode.pprev = NULL;
ct->tuplehash[IP_CT_DIR_REPLY].tuple = *repl;
/* save hash for reusing when confirming */
*(unsigned long *)(&ct->tuplehash[IP_CT_DIR_REPLY].hnnode.pprev) = hash;
+ ct->status = 0;
/* Don't set timer yet: wait for confirmation */
setup_timer(&ct->timeout, death_by_timeout, (unsigned long)ct);
write_pnet(&ct->ct_net, net);
+ memset(&ct->__nfct_init_offset[0], 0,
+ offsetof(struct nf_conn, proto) -
+ offsetof(struct nf_conn, __nfct_init_offset[0]));
#ifdef CONFIG_NF_CONNTRACK_ZONES
if (zone) {
struct nf_conntrack_zone *nf_ct_zone;