aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/netfilter/nf_conntrack_netlink.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index ef0eedd70541..70123f48b6c9 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -1150,7 +1150,7 @@ static int ctnetlink_done_list(struct netlink_callback *cb)
1150static int 1150static int
1151ctnetlink_dump_list(struct sk_buff *skb, struct netlink_callback *cb, bool dying) 1151ctnetlink_dump_list(struct sk_buff *skb, struct netlink_callback *cb, bool dying)
1152{ 1152{
1153 struct nf_conn *ct, *last = NULL; 1153 struct nf_conn *ct, *last;
1154 struct nf_conntrack_tuple_hash *h; 1154 struct nf_conntrack_tuple_hash *h;
1155 struct hlist_nulls_node *n; 1155 struct hlist_nulls_node *n;
1156 struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh); 1156 struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
@@ -1163,6 +1163,8 @@ ctnetlink_dump_list(struct sk_buff *skb, struct netlink_callback *cb, bool dying
1163 if (cb->args[2]) 1163 if (cb->args[2])
1164 return 0; 1164 return 0;
1165 1165
1166 last = (struct nf_conn *)cb->args[1];
1167
1166 for (cpu = cb->args[0]; cpu < nr_cpu_ids; cpu++) { 1168 for (cpu = cb->args[0]; cpu < nr_cpu_ids; cpu++) {
1167 struct ct_pcpu *pcpu; 1169 struct ct_pcpu *pcpu;
1168 1170
@@ -1171,7 +1173,6 @@ ctnetlink_dump_list(struct sk_buff *skb, struct netlink_callback *cb, bool dying
1171 1173
1172 pcpu = per_cpu_ptr(net->ct.pcpu_lists, cpu); 1174 pcpu = per_cpu_ptr(net->ct.pcpu_lists, cpu);
1173 spin_lock_bh(&pcpu->lock); 1175 spin_lock_bh(&pcpu->lock);
1174 last = (struct nf_conn *)cb->args[1];
1175 list = dying ? &pcpu->dying : &pcpu->unconfirmed; 1176 list = dying ? &pcpu->dying : &pcpu->unconfirmed;
1176restart: 1177restart:
1177 hlist_nulls_for_each_entry(h, n, list, hnnode) { 1178 hlist_nulls_for_each_entry(h, n, list, hnnode) {
@@ -1190,7 +1191,8 @@ restart:
1190 ct); 1191 ct);
1191 rcu_read_unlock(); 1192 rcu_read_unlock();
1192 if (res < 0) { 1193 if (res < 0) {
1193 nf_conntrack_get(&ct->ct_general); 1194 if (!atomic_inc_not_zero(&ct->ct_general.use))
1195 continue;
1194 cb->args[0] = cpu; 1196 cb->args[0] = cpu;
1195 cb->args[1] = (unsigned long)ct; 1197 cb->args[1] = (unsigned long)ct;
1196 spin_unlock_bh(&pcpu->lock); 1198 spin_unlock_bh(&pcpu->lock);