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

netfilter: evict stale entries on netlink dumps

When dumping we already have to look at the entire table, so we might
as well toss those entries whose timeout value is in the past.

We also look at every entry during resize operations.
However, eviction there is not as simple because we hold the
global resize lock so we can't evict without adding a 'expired' list
to drop from later.  Considering that resizes are very rare it doesn't
seem worth doing it.
Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
Acked-by: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent f330a7fd
...@@ -815,14 +815,23 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -815,14 +815,23 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
struct hlist_nulls_node *n; struct hlist_nulls_node *n;
struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh); struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
u_int8_t l3proto = nfmsg->nfgen_family; u_int8_t l3proto = nfmsg->nfgen_family;
int res; struct nf_conn *nf_ct_evict[8];
int res, i;
spinlock_t *lockp; spinlock_t *lockp;
last = (struct nf_conn *)cb->args[1]; last = (struct nf_conn *)cb->args[1];
i = 0;
local_bh_disable(); local_bh_disable();
for (; cb->args[0] < nf_conntrack_htable_size; cb->args[0]++) { for (; cb->args[0] < nf_conntrack_htable_size; cb->args[0]++) {
restart: restart:
while (i) {
i--;
if (nf_ct_should_gc(nf_ct_evict[i]))
nf_ct_kill(nf_ct_evict[i]);
nf_ct_put(nf_ct_evict[i]);
}
lockp = &nf_conntrack_locks[cb->args[0] % CONNTRACK_LOCKS]; lockp = &nf_conntrack_locks[cb->args[0] % CONNTRACK_LOCKS];
nf_conntrack_lock(lockp); nf_conntrack_lock(lockp);
if (cb->args[0] >= nf_conntrack_htable_size) { if (cb->args[0] >= nf_conntrack_htable_size) {
...@@ -834,6 +843,13 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -834,6 +843,13 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
if (NF_CT_DIRECTION(h) != IP_CT_DIR_ORIGINAL) if (NF_CT_DIRECTION(h) != IP_CT_DIR_ORIGINAL)
continue; continue;
ct = nf_ct_tuplehash_to_ctrack(h); ct = nf_ct_tuplehash_to_ctrack(h);
if (nf_ct_is_expired(ct)) {
if (i < ARRAY_SIZE(nf_ct_evict) &&
atomic_inc_not_zero(&ct->ct_general.use))
nf_ct_evict[i++] = ct;
continue;
}
if (!net_eq(net, nf_ct_net(ct))) if (!net_eq(net, nf_ct_net(ct)))
continue; continue;
...@@ -875,6 +891,13 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -875,6 +891,13 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
if (last) if (last)
nf_ct_put(last); nf_ct_put(last);
while (i) {
i--;
if (nf_ct_should_gc(nf_ct_evict[i]))
nf_ct_kill(nf_ct_evict[i]);
nf_ct_put(nf_ct_evict[i]);
}
return skb->len; return skb->len;
} }
......
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