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: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
parent
055c4b34b9
commit
fc09e4a75a
|
@ -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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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 @@ repeat:
|
||||||
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)
|
||||||
|
|
Loading…
Reference in New Issue