|
@@ -144,8 +144,10 @@ static bool conn_free(struct nf_conncount_list *list,
|
|
|
list->count--;
|
|
|
conn->dead = true;
|
|
|
list_del_rcu(&conn->node);
|
|
|
- if (list->count == 0)
|
|
|
+ if (list->count == 0) {
|
|
|
+ list->dead = true;
|
|
|
free_entry = true;
|
|
|
+ }
|
|
|
|
|
|
spin_unlock_bh(&list->list_lock);
|
|
|
call_rcu(&conn->rcu_head, __conn_free);
|
|
@@ -248,7 +250,7 @@ void nf_conncount_list_init(struct nf_conncount_list *list)
|
|
|
{
|
|
|
spin_lock_init(&list->list_lock);
|
|
|
INIT_LIST_HEAD(&list->head);
|
|
|
- list->count = 1;
|
|
|
+ list->count = 0;
|
|
|
list->dead = false;
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(nf_conncount_list_init);
|
|
@@ -262,6 +264,7 @@ bool nf_conncount_gc_list(struct net *net,
|
|
|
struct nf_conn *found_ct;
|
|
|
unsigned int collected = 0;
|
|
|
bool free_entry = false;
|
|
|
+ bool ret = false;
|
|
|
|
|
|
list_for_each_entry_safe(conn, conn_n, &list->head, node) {
|
|
|
found = find_or_evict(net, list, conn, &free_entry);
|
|
@@ -291,7 +294,15 @@ bool nf_conncount_gc_list(struct net *net,
|
|
|
if (collected > CONNCOUNT_GC_MAX_NODES)
|
|
|
return false;
|
|
|
}
|
|
|
- return false;
|
|
|
+
|
|
|
+ spin_lock_bh(&list->list_lock);
|
|
|
+ if (!list->count) {
|
|
|
+ list->dead = true;
|
|
|
+ ret = true;
|
|
|
+ }
|
|
|
+ spin_unlock_bh(&list->list_lock);
|
|
|
+
|
|
|
+ return ret;
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(nf_conncount_gc_list);
|
|
|
|
|
@@ -417,6 +428,7 @@ insert_tree(struct net *net,
|
|
|
nf_conncount_list_init(&rbconn->list);
|
|
|
list_add(&conn->node, &rbconn->list.head);
|
|
|
count = 1;
|
|
|
+ rbconn->list.count = count;
|
|
|
|
|
|
rb_link_node(&rbconn->node, parent, rbnode);
|
|
|
rb_insert_color(&rbconn->node, root);
|