Skip to content

Commit 0d3cc50

Browse files
Florian Westphalummakynes
authored andcommitted
netfilter: conntrack: include ecache dying list in dumps
The new pernet dying list includes conntrack entries that await delivery of the 'destroy' event via ctnetlink. The old percpu dying list will be removed soon. Signed-off-by: Florian Westphal <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]>
1 parent 2ed3bf1 commit 0d3cc50

File tree

3 files changed

+55
-0
lines changed

3 files changed

+55
-0
lines changed

include/net/netfilter/nf_conntrack_ecache.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,8 @@ void nf_conntrack_ecache_work(struct net *net, enum nf_ct_ecache_state state);
164164
void nf_conntrack_ecache_pernet_init(struct net *net);
165165
void nf_conntrack_ecache_pernet_fini(struct net *net);
166166

167+
struct nf_conntrack_net_ecache *nf_conn_pernet_ecache(const struct net *net);
168+
167169
static inline bool nf_conntrack_ecache_dwork_pending(const struct net *net)
168170
{
169171
return net->ct.ecache_dwork_pending;

net/netfilter/nf_conntrack_ecache.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,16 @@ enum retry_state {
3838
STATE_DONE,
3939
};
4040

41+
struct nf_conntrack_net_ecache *nf_conn_pernet_ecache(const struct net *net)
42+
{
43+
struct nf_conntrack_net *cnet = nf_ct_pernet(net);
44+
45+
return &cnet->ecache;
46+
}
47+
#if IS_MODULE(CONFIG_NF_CT_NETLINK)
48+
EXPORT_SYMBOL_GPL(nf_conn_pernet_ecache);
49+
#endif
50+
4151
static enum retry_state ecache_work_evict_list(struct nf_conntrack_net *cnet)
4252
{
4353
unsigned long stop = jiffies + ECACHE_MAX_JIFFIES;

net/netfilter/nf_conntrack_netlink.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ struct ctnetlink_list_dump_ctx {
6262
struct nf_conn *last;
6363
unsigned int cpu;
6464
bool done;
65+
bool retrans_done;
6566
};
6667

6768
static int ctnetlink_dump_tuples_proto(struct sk_buff *skb,
@@ -1802,6 +1803,48 @@ ctnetlink_dump_list(struct sk_buff *skb, struct netlink_callback *cb, bool dying
18021803
static int
18031804
ctnetlink_dump_dying(struct sk_buff *skb, struct netlink_callback *cb)
18041805
{
1806+
struct ctnetlink_list_dump_ctx *ctx = (void *)cb->ctx;
1807+
struct nf_conn *last = ctx->last;
1808+
#ifdef CONFIG_NF_CONNTRACK_EVENTS
1809+
const struct net *net = sock_net(skb->sk);
1810+
struct nf_conntrack_net_ecache *ecache_net;
1811+
struct nf_conntrack_tuple_hash *h;
1812+
struct hlist_nulls_node *n;
1813+
#endif
1814+
1815+
if (ctx->retrans_done)
1816+
return ctnetlink_dump_list(skb, cb, true);
1817+
1818+
ctx->last = NULL;
1819+
1820+
#ifdef CONFIG_NF_CONNTRACK_EVENTS
1821+
ecache_net = nf_conn_pernet_ecache(net);
1822+
spin_lock_bh(&ecache_net->dying_lock);
1823+
1824+
hlist_nulls_for_each_entry(h, n, &ecache_net->dying_list, hnnode) {
1825+
struct nf_conn *ct;
1826+
int res;
1827+
1828+
ct = nf_ct_tuplehash_to_ctrack(h);
1829+
if (last && last != ct)
1830+
continue;
1831+
1832+
res = ctnetlink_dump_one_entry(skb, cb, ct, true);
1833+
if (res < 0) {
1834+
spin_unlock_bh(&ecache_net->dying_lock);
1835+
nf_ct_put(last);
1836+
return skb->len;
1837+
}
1838+
1839+
nf_ct_put(last);
1840+
last = NULL;
1841+
}
1842+
1843+
spin_unlock_bh(&ecache_net->dying_lock);
1844+
#endif
1845+
nf_ct_put(last);
1846+
ctx->retrans_done = true;
1847+
18051848
return ctnetlink_dump_list(skb, cb, true);
18061849
}
18071850

0 commit comments

Comments
 (0)