mirror of https://gitee.com/openkylin/linux.git
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>
This commit is contained in:
parent
abc86d0f99
commit
c41884ce05
|
@ -92,12 +92,18 @@ struct nf_conn {
|
||||||
/* Have we seen traffic both ways yet? (bitset) */
|
/* Have we seen traffic both ways yet? (bitset) */
|
||||||
unsigned long status;
|
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. */
|
/* Timer function; drops refcnt when it goes off. */
|
||||||
struct timer_list timeout;
|
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)
|
#if defined(CONFIG_NF_CONNTRACK_MARK)
|
||||||
u_int32_t mark;
|
u_int32_t mark;
|
||||||
#endif
|
#endif
|
||||||
|
@ -108,9 +114,6 @@ struct nf_conn {
|
||||||
|
|
||||||
/* Extensions */
|
/* Extensions */
|
||||||
struct nf_ct_ext *ext;
|
struct nf_ct_ext *ext;
|
||||||
#ifdef CONFIG_NET_NS
|
|
||||||
struct net *ct_net;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Storage reserved for other modules, must be the last member */
|
/* Storage reserved for other modules, must be the last member */
|
||||||
union nf_conntrack_proto proto;
|
union nf_conntrack_proto proto;
|
||||||
|
|
|
@ -826,22 +826,19 @@ __nf_conntrack_alloc(struct net *net, u16 zone,
|
||||||
atomic_dec(&net->ct.count);
|
atomic_dec(&net->ct.count);
|
||||||
return ERR_PTR(-ENOMEM);
|
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);
|
spin_lock_init(&ct->lock);
|
||||||
ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple = *orig;
|
ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple = *orig;
|
||||||
ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode.pprev = NULL;
|
ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode.pprev = NULL;
|
||||||
ct->tuplehash[IP_CT_DIR_REPLY].tuple = *repl;
|
ct->tuplehash[IP_CT_DIR_REPLY].tuple = *repl;
|
||||||
/* save hash for reusing when confirming */
|
/* save hash for reusing when confirming */
|
||||||
*(unsigned long *)(&ct->tuplehash[IP_CT_DIR_REPLY].hnnode.pprev) = hash;
|
*(unsigned long *)(&ct->tuplehash[IP_CT_DIR_REPLY].hnnode.pprev) = hash;
|
||||||
|
ct->status = 0;
|
||||||
/* Don't set timer yet: wait for confirmation */
|
/* Don't set timer yet: wait for confirmation */
|
||||||
setup_timer(&ct->timeout, death_by_timeout, (unsigned long)ct);
|
setup_timer(&ct->timeout, death_by_timeout, (unsigned long)ct);
|
||||||
write_pnet(&ct->ct_net, net);
|
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
|
#ifdef CONFIG_NF_CONNTRACK_ZONES
|
||||||
if (zone) {
|
if (zone) {
|
||||||
struct nf_conntrack_zone *nf_ct_zone;
|
struct nf_conntrack_zone *nf_ct_zone;
|
||||||
|
|
Loading…
Reference in New Issue