Commit fc09e4a7 authored by Florian Westphal's avatar Florian Westphal Committed by Pablo Neira Ayuso

netfilter: nf_conntrack: reduce resolve_normal_ct args

also mark init_conntrack noinline, in most cases resolve_normal_ct will
find an existing conntrack entry.

text    data     bss     dec     hex filename
16735    5707     176   22618    585a net/netfilter/nf_conntrack_core.o
16687    5707     176   22570    582a net/netfilter/nf_conntrack_core.o
Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 055c4b34
...@@ -1129,7 +1129,7 @@ EXPORT_SYMBOL_GPL(nf_conntrack_free); ...@@ -1129,7 +1129,7 @@ EXPORT_SYMBOL_GPL(nf_conntrack_free);
/* Allocate a new conntrack: we return -ENOMEM if classification /* Allocate a new conntrack: we return -ENOMEM if classification
failed due to stress. Otherwise it really is unclassifiable. */ failed due to stress. Otherwise it really is unclassifiable. */
static struct nf_conntrack_tuple_hash * static noinline struct nf_conntrack_tuple_hash *
init_conntrack(struct net *net, struct nf_conn *tmpl, init_conntrack(struct net *net, struct nf_conn *tmpl,
const struct nf_conntrack_tuple *tuple, const struct nf_conntrack_tuple *tuple,
struct nf_conntrack_l3proto *l3proto, struct nf_conntrack_l3proto *l3proto,
...@@ -1237,21 +1237,20 @@ init_conntrack(struct net *net, struct nf_conn *tmpl, ...@@ -1237,21 +1237,20 @@ init_conntrack(struct net *net, struct nf_conn *tmpl,
return &ct->tuplehash[IP_CT_DIR_ORIGINAL]; return &ct->tuplehash[IP_CT_DIR_ORIGINAL];
} }
/* On success, returns conntrack ptr, sets skb->_nfct | ctinfo */ /* On success, returns 0, sets skb->_nfct | ctinfo */
static inline struct nf_conn * static int
resolve_normal_ct(struct net *net, struct nf_conn *tmpl, resolve_normal_ct(struct net *net, struct nf_conn *tmpl,
struct sk_buff *skb, struct sk_buff *skb,
unsigned int dataoff, unsigned int dataoff,
u_int16_t l3num, u_int16_t l3num,
u_int8_t protonum, u_int8_t protonum,
struct nf_conntrack_l3proto *l3proto, struct nf_conntrack_l3proto *l3proto,
struct nf_conntrack_l4proto *l4proto, struct nf_conntrack_l4proto *l4proto)
int *set_reply,
enum ip_conntrack_info *ctinfo)
{ {
const struct nf_conntrack_zone *zone; const struct nf_conntrack_zone *zone;
struct nf_conntrack_tuple tuple; struct nf_conntrack_tuple tuple;
struct nf_conntrack_tuple_hash *h; struct nf_conntrack_tuple_hash *h;
enum ip_conntrack_info ctinfo;
struct nf_conntrack_zone tmp; struct nf_conntrack_zone tmp;
struct nf_conn *ct; struct nf_conn *ct;
u32 hash; u32 hash;
...@@ -1260,7 +1259,7 @@ resolve_normal_ct(struct net *net, struct nf_conn *tmpl, ...@@ -1260,7 +1259,7 @@ resolve_normal_ct(struct net *net, struct nf_conn *tmpl,
dataoff, l3num, protonum, net, &tuple, l3proto, dataoff, l3num, protonum, net, &tuple, l3proto,
l4proto)) { l4proto)) {
pr_debug("Can't get tuple\n"); pr_debug("Can't get tuple\n");
return NULL; return 0;
} }
/* look for tuple match */ /* look for tuple match */
...@@ -1271,33 +1270,30 @@ resolve_normal_ct(struct net *net, struct nf_conn *tmpl, ...@@ -1271,33 +1270,30 @@ resolve_normal_ct(struct net *net, struct nf_conn *tmpl,
h = init_conntrack(net, tmpl, &tuple, l3proto, l4proto, h = init_conntrack(net, tmpl, &tuple, l3proto, l4proto,
skb, dataoff, hash); skb, dataoff, hash);
if (!h) if (!h)
return NULL; return 0;
if (IS_ERR(h)) if (IS_ERR(h))
return (void *)h; return PTR_ERR(h);
} }
ct = nf_ct_tuplehash_to_ctrack(h); ct = nf_ct_tuplehash_to_ctrack(h);
/* It exists; we have (non-exclusive) reference. */ /* It exists; we have (non-exclusive) reference. */
if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY) { if (NF_CT_DIRECTION(h) == IP_CT_DIR_REPLY) {
*ctinfo = IP_CT_ESTABLISHED_REPLY; ctinfo = IP_CT_ESTABLISHED_REPLY;
/* Please set reply bit if this packet OK */
*set_reply = 1;
} else { } else {
/* Once we've had two way comms, always ESTABLISHED. */ /* Once we've had two way comms, always ESTABLISHED. */
if (test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) { if (test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
pr_debug("normal packet for %p\n", ct); pr_debug("normal packet for %p\n", ct);
*ctinfo = IP_CT_ESTABLISHED; ctinfo = IP_CT_ESTABLISHED;
} else if (test_bit(IPS_EXPECTED_BIT, &ct->status)) { } else if (test_bit(IPS_EXPECTED_BIT, &ct->status)) {
pr_debug("related packet for %p\n", ct); pr_debug("related packet for %p\n", ct);
*ctinfo = IP_CT_RELATED; ctinfo = IP_CT_RELATED;
} else { } else {
pr_debug("new packet for %p\n", ct); pr_debug("new packet for %p\n", ct);
*ctinfo = IP_CT_NEW; ctinfo = IP_CT_NEW;
} }
*set_reply = 0;
} }
nf_ct_set(skb, ct, *ctinfo); nf_ct_set(skb, ct, ctinfo);
return ct; return 0;
} }
unsigned int unsigned int
...@@ -1311,7 +1307,6 @@ nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum, ...@@ -1311,7 +1307,6 @@ nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum,
unsigned int *timeouts; unsigned int *timeouts;
unsigned int dataoff; unsigned int dataoff;
u_int8_t protonum; u_int8_t protonum;
int set_reply = 0;
int ret; int ret;
tmpl = nf_ct_get(skb, &ctinfo); tmpl = nf_ct_get(skb, &ctinfo);
...@@ -1354,23 +1349,22 @@ nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum, ...@@ -1354,23 +1349,22 @@ nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum,
goto out; goto out;
} }
repeat: repeat:
ct = resolve_normal_ct(net, tmpl, skb, dataoff, pf, protonum, ret = resolve_normal_ct(net, tmpl, skb, dataoff, pf, protonum,
l3proto, l4proto, &set_reply, &ctinfo); l3proto, l4proto);
if (!ct) { if (ret < 0) {
/* Not valid part of a connection */
NF_CT_STAT_INC_ATOMIC(net, invalid);
ret = NF_ACCEPT;
goto out;
}
if (IS_ERR(ct)) {
/* Too stressed to deal. */ /* Too stressed to deal. */
NF_CT_STAT_INC_ATOMIC(net, drop); NF_CT_STAT_INC_ATOMIC(net, drop);
ret = NF_DROP; ret = NF_DROP;
goto out; goto out;
} }
NF_CT_ASSERT(skb_nfct(skb)); ct = nf_ct_get(skb, &ctinfo);
if (!ct) {
/* Not valid part of a connection */
NF_CT_STAT_INC_ATOMIC(net, invalid);
ret = NF_ACCEPT;
goto out;
}
/* Decide what timeout policy we want to apply to this flow. */ /* Decide what timeout policy we want to apply to this flow. */
timeouts = nf_ct_timeout_lookup(net, ct, l4proto); timeouts = nf_ct_timeout_lookup(net, ct, l4proto);
...@@ -1395,7 +1389,8 @@ nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum, ...@@ -1395,7 +1389,8 @@ nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum,
goto out; goto out;
} }
if (set_reply && !test_and_set_bit(IPS_SEEN_REPLY_BIT, &ct->status)) if (ctinfo == IP_CT_ESTABLISHED_REPLY &&
!test_and_set_bit(IPS_SEEN_REPLY_BIT, &ct->status))
nf_conntrack_event_cache(IPCT_REPLY, ct); nf_conntrack_event_cache(IPCT_REPLY, ct);
out: out:
if (tmpl) if (tmpl)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment