VYPR
Unrated severityNVD Advisory· Published May 27, 2026· Updated May 27, 2026

CVE-2026-45860

CVE-2026-45860

Description

In the Linux kernel, the following vulnerability has been resolved:

netfilter: nf_conncount: increase the connection clean up limit to 64

After the optimization to only perform one GC per jiffy, a new problem was introduced. If more than 8 new connections are tracked per jiffy the list won't be cleaned up fast enough possibly reaching the limit wrongly.

In order to prevent this issue, only skip the GC if it was already triggered during the same jiffy and the increment is lower than the clean up limit. In addition, increase the clean up limit to 64 connections to avoid triggering GC too often and do more effective GCs.

This has been tested using a HTTP server and several performance tools while having nft_connlimit/xt_connlimit or OVS limit configured.

Output of slowhttptest + OVS limit at 52000 connections:

slow HTTP test status on 340th second: initializing: 0 pending: 432 connected: 51998 error: 0 closed: 0 service available: YES

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Linux kernel netfilter connection tracking GC limit too low under high connection rates, causing false limit hits; fixed by raising cleanup limit to 64 and optimizing GC scheduling.

Vulnerability

The Linux kernel's netfilter connection tracking (nf_conncount) garbage collection (GC) mechanism was optimized to perform only one GC per jiffy. However, if more than 8 new connections were tracked per jiffy, the list would not be cleaned up fast enough, potentially causing the connection limit to be reached incorrectly. This affects kernels using nft_connlimit, xt_connlimit, or OVS limit configurations. The fix increases the cleanup limit to 64 connections and only skips GC if it was already triggered in the same jiffy and the increment is below the limit [1].

Exploitation

An attacker can exploit this by generating a high rate of new connections (e.g., using slow HTTP attacks or other connection-flooding techniques) to exceed the per-jiffy threshold of 8 connections. No authentication or special network position is required beyond the ability to initiate connections to the target service. The attacker does not need to complete the connections; simply initiating many new connections per jiffy can trigger the false limit [1].

Impact

Successful exploitation leads to a denial-of-service condition where legitimate new connections are incorrectly rejected because the connection tracking limit is perceived as reached. This can disrupt services relying on connection limiting, such as HTTP servers or network middleboxes using nft_connlimit or OVS limits. The impact is limited to connection admission; existing connections are unaffected [1].

Mitigation

The fix is included in Linux kernel commit 21d033e472735ecec677f1ae46d6740b5e47a4f3, which is part of the stable kernel releases. Users should update to a kernel version containing this commit. No workaround is documented; upgrading is the recommended mitigation [1].

AI Insight generated on May 27, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected products

1

Patches

16
6e5fa7add3e7

netfilter: nf_conncount: increase the connection clean up limit to 64

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitFernando Fernandez ManceraDec 17, 2025Fixed in 6.18.14via kernel-cna
4 files changed · +22 12
  • include/net/netfilter/nf_conntrack_count.h+1 0 modified
    diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h
    index 52a06de41aa0f9..cf0166520cf338 100644
    --- a/include/net/netfilter/nf_conntrack_count.h
    +++ b/include/net/netfilter/nf_conntrack_count.h
    @@ -13,6 +13,7 @@ struct nf_conncount_list {
     	u32 last_gc;		/* jiffies at most recent gc */
     	struct list_head head;	/* connections with the same filtering key */
     	unsigned int count;	/* length of list */
    +	unsigned int last_gc_count; /* length of list at most recent gc */
     };
     
     struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int keylen);
    
  • include/net/netfilter/nf_conntrack_count.h+1 0 modified
    diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h
    index 52a06de41aa0f9..cf0166520cf338 100644
    --- a/include/net/netfilter/nf_conntrack_count.h
    +++ b/include/net/netfilter/nf_conntrack_count.h
    @@ -13,6 +13,7 @@ struct nf_conncount_list {
     	u32 last_gc;		/* jiffies at most recent gc */
     	struct list_head head;	/* connections with the same filtering key */
     	unsigned int count;	/* length of list */
    +	unsigned int last_gc_count; /* length of list at most recent gc */
     };
     
     struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int keylen);
    
  • net/netfilter/nf_conncount.c+10 6 modified
    diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
    index 8487808c87614f..288936f5c1bf92 100644
    --- a/net/netfilter/nf_conncount.c
    +++ b/net/netfilter/nf_conncount.c
    @@ -34,8 +34,9 @@
     
     #define CONNCOUNT_SLOTS		256U
     
    -#define CONNCOUNT_GC_MAX_NODES	8
    -#define MAX_KEYLEN		5
    +#define CONNCOUNT_GC_MAX_NODES		8
    +#define CONNCOUNT_GC_MAX_COLLECT	64
    +#define MAX_KEYLEN			5
     
     /* we will save the tuples of all connections we care about */
     struct nf_conncount_tuple {
    @@ -182,12 +183,13 @@ static int __nf_conncount_add(struct net *net,
     		goto out_put;
     	}
     
    -	if ((u32)jiffies == list->last_gc)
    +	if ((u32)jiffies == list->last_gc &&
    +	    (list->count - list->last_gc_count) < CONNCOUNT_GC_MAX_COLLECT)
     		goto add_new_node;
     
     	/* check the saved connections */
     	list_for_each_entry_safe(conn, conn_n, &list->head, node) {
    -		if (collect > CONNCOUNT_GC_MAX_NODES)
    +		if (collect > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     
     		found = find_or_evict(net, list, conn);
    @@ -230,6 +232,7 @@ static int __nf_conncount_add(struct net *net,
     		nf_ct_put(found_ct);
     	}
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     add_new_node:
     	if (WARN_ON_ONCE(list->count > INT_MAX)) {
    @@ -277,6 +280,7 @@ void nf_conncount_list_init(struct nf_conncount_list *list)
     	spin_lock_init(&list->list_lock);
     	INIT_LIST_HEAD(&list->head);
     	list->count = 0;
    +	list->last_gc_count = 0;
     	list->last_gc = (u32)jiffies;
     }
     EXPORT_SYMBOL_GPL(nf_conncount_list_init);
    @@ -316,13 +320,14 @@ static bool __nf_conncount_gc_list(struct net *net,
     		}
     
     		nf_ct_put(found_ct);
    -		if (collected > CONNCOUNT_GC_MAX_NODES)
    +		if (collected > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     	}
     
     	if (!list->count)
     		ret = true;
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
  • net/netfilter/nf_conncount.c+10 6 modified
    diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
    index 8487808c87614f..288936f5c1bf92 100644
    --- a/net/netfilter/nf_conncount.c
    +++ b/net/netfilter/nf_conncount.c
    @@ -34,8 +34,9 @@
     
     #define CONNCOUNT_SLOTS		256U
     
    -#define CONNCOUNT_GC_MAX_NODES	8
    -#define MAX_KEYLEN		5
    +#define CONNCOUNT_GC_MAX_NODES		8
    +#define CONNCOUNT_GC_MAX_COLLECT	64
    +#define MAX_KEYLEN			5
     
     /* we will save the tuples of all connections we care about */
     struct nf_conncount_tuple {
    @@ -182,12 +183,13 @@ static int __nf_conncount_add(struct net *net,
     		goto out_put;
     	}
     
    -	if ((u32)jiffies == list->last_gc)
    +	if ((u32)jiffies == list->last_gc &&
    +	    (list->count - list->last_gc_count) < CONNCOUNT_GC_MAX_COLLECT)
     		goto add_new_node;
     
     	/* check the saved connections */
     	list_for_each_entry_safe(conn, conn_n, &list->head, node) {
    -		if (collect > CONNCOUNT_GC_MAX_NODES)
    +		if (collect > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     
     		found = find_or_evict(net, list, conn);
    @@ -230,6 +232,7 @@ static int __nf_conncount_add(struct net *net,
     		nf_ct_put(found_ct);
     	}
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     add_new_node:
     	if (WARN_ON_ONCE(list->count > INT_MAX)) {
    @@ -277,6 +280,7 @@ void nf_conncount_list_init(struct nf_conncount_list *list)
     	spin_lock_init(&list->list_lock);
     	INIT_LIST_HEAD(&list->head);
     	list->count = 0;
    +	list->last_gc_count = 0;
     	list->last_gc = (u32)jiffies;
     }
     EXPORT_SYMBOL_GPL(nf_conncount_list_init);
    @@ -316,13 +320,14 @@ static bool __nf_conncount_gc_list(struct net *net,
     		}
     
     		nf_ct_put(found_ct);
    -		if (collected > CONNCOUNT_GC_MAX_NODES)
    +		if (collected > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     	}
     
     	if (!list->count)
     		ret = true;
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
21d033e47273

netfilter: nf_conncount: increase the connection clean up limit to 64

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitFernando Fernandez ManceraDec 17, 2025Fixed in 7.0via kernel-cna
4 files changed · +22 12
  • include/net/netfilter/nf_conntrack_count.h+1 0 modified
    diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h
    index 52a06de41aa0f9..cf0166520cf338 100644
    --- a/include/net/netfilter/nf_conntrack_count.h
    +++ b/include/net/netfilter/nf_conntrack_count.h
    @@ -13,6 +13,7 @@ struct nf_conncount_list {
     	u32 last_gc;		/* jiffies at most recent gc */
     	struct list_head head;	/* connections with the same filtering key */
     	unsigned int count;	/* length of list */
    +	unsigned int last_gc_count; /* length of list at most recent gc */
     };
     
     struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int keylen);
    
  • include/net/netfilter/nf_conntrack_count.h+1 0 modified
    diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h
    index 52a06de41aa0f9..cf0166520cf338 100644
    --- a/include/net/netfilter/nf_conntrack_count.h
    +++ b/include/net/netfilter/nf_conntrack_count.h
    @@ -13,6 +13,7 @@ struct nf_conncount_list {
     	u32 last_gc;		/* jiffies at most recent gc */
     	struct list_head head;	/* connections with the same filtering key */
     	unsigned int count;	/* length of list */
    +	unsigned int last_gc_count; /* length of list at most recent gc */
     };
     
     struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int keylen);
    
  • net/netfilter/nf_conncount.c+10 6 modified
    diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
    index 8487808c87614f..288936f5c1bf92 100644
    --- a/net/netfilter/nf_conncount.c
    +++ b/net/netfilter/nf_conncount.c
    @@ -34,8 +34,9 @@
     
     #define CONNCOUNT_SLOTS		256U
     
    -#define CONNCOUNT_GC_MAX_NODES	8
    -#define MAX_KEYLEN		5
    +#define CONNCOUNT_GC_MAX_NODES		8
    +#define CONNCOUNT_GC_MAX_COLLECT	64
    +#define MAX_KEYLEN			5
     
     /* we will save the tuples of all connections we care about */
     struct nf_conncount_tuple {
    @@ -182,12 +183,13 @@ static int __nf_conncount_add(struct net *net,
     		goto out_put;
     	}
     
    -	if ((u32)jiffies == list->last_gc)
    +	if ((u32)jiffies == list->last_gc &&
    +	    (list->count - list->last_gc_count) < CONNCOUNT_GC_MAX_COLLECT)
     		goto add_new_node;
     
     	/* check the saved connections */
     	list_for_each_entry_safe(conn, conn_n, &list->head, node) {
    -		if (collect > CONNCOUNT_GC_MAX_NODES)
    +		if (collect > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     
     		found = find_or_evict(net, list, conn);
    @@ -230,6 +232,7 @@ static int __nf_conncount_add(struct net *net,
     		nf_ct_put(found_ct);
     	}
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     add_new_node:
     	if (WARN_ON_ONCE(list->count > INT_MAX)) {
    @@ -277,6 +280,7 @@ void nf_conncount_list_init(struct nf_conncount_list *list)
     	spin_lock_init(&list->list_lock);
     	INIT_LIST_HEAD(&list->head);
     	list->count = 0;
    +	list->last_gc_count = 0;
     	list->last_gc = (u32)jiffies;
     }
     EXPORT_SYMBOL_GPL(nf_conncount_list_init);
    @@ -316,13 +320,14 @@ static bool __nf_conncount_gc_list(struct net *net,
     		}
     
     		nf_ct_put(found_ct);
    -		if (collected > CONNCOUNT_GC_MAX_NODES)
    +		if (collected > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     	}
     
     	if (!list->count)
     		ret = true;
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
  • net/netfilter/nf_conncount.c+10 6 modified
    diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
    index 8487808c87614f..288936f5c1bf92 100644
    --- a/net/netfilter/nf_conncount.c
    +++ b/net/netfilter/nf_conncount.c
    @@ -34,8 +34,9 @@
     
     #define CONNCOUNT_SLOTS		256U
     
    -#define CONNCOUNT_GC_MAX_NODES	8
    -#define MAX_KEYLEN		5
    +#define CONNCOUNT_GC_MAX_NODES		8
    +#define CONNCOUNT_GC_MAX_COLLECT	64
    +#define MAX_KEYLEN			5
     
     /* we will save the tuples of all connections we care about */
     struct nf_conncount_tuple {
    @@ -182,12 +183,13 @@ static int __nf_conncount_add(struct net *net,
     		goto out_put;
     	}
     
    -	if ((u32)jiffies == list->last_gc)
    +	if ((u32)jiffies == list->last_gc &&
    +	    (list->count - list->last_gc_count) < CONNCOUNT_GC_MAX_COLLECT)
     		goto add_new_node;
     
     	/* check the saved connections */
     	list_for_each_entry_safe(conn, conn_n, &list->head, node) {
    -		if (collect > CONNCOUNT_GC_MAX_NODES)
    +		if (collect > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     
     		found = find_or_evict(net, list, conn);
    @@ -230,6 +232,7 @@ static int __nf_conncount_add(struct net *net,
     		nf_ct_put(found_ct);
     	}
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     add_new_node:
     	if (WARN_ON_ONCE(list->count > INT_MAX)) {
    @@ -277,6 +280,7 @@ void nf_conncount_list_init(struct nf_conncount_list *list)
     	spin_lock_init(&list->list_lock);
     	INIT_LIST_HEAD(&list->head);
     	list->count = 0;
    +	list->last_gc_count = 0;
     	list->last_gc = (u32)jiffies;
     }
     EXPORT_SYMBOL_GPL(nf_conncount_list_init);
    @@ -316,13 +320,14 @@ static bool __nf_conncount_gc_list(struct net *net,
     		}
     
     		nf_ct_put(found_ct);
    -		if (collected > CONNCOUNT_GC_MAX_NODES)
    +		if (collected > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     	}
     
     	if (!list->count)
     		ret = true;
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
fa85432d58c8

netfilter: nf_conncount: increase the connection clean up limit to 64

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitFernando Fernandez ManceraDec 17, 2025Fixed in 6.1.165via kernel-cna
4 files changed · +22 12
  • include/net/netfilter/nf_conntrack_count.h+1 0 modified
    diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h
    index 115bb7e572f7d0..bf22661925b813 100644
    --- a/include/net/netfilter/nf_conntrack_count.h
    +++ b/include/net/netfilter/nf_conntrack_count.h
    @@ -13,6 +13,7 @@ struct nf_conncount_list {
     	u32 last_gc;		/* jiffies at most recent gc */
     	struct list_head head;	/* connections with the same filtering key */
     	unsigned int count;	/* length of list */
    +	unsigned int last_gc_count; /* length of list at most recent gc */
     };
     
     struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int family,
    
  • include/net/netfilter/nf_conntrack_count.h+1 0 modified
    diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h
    index 115bb7e572f7d0..bf22661925b813 100644
    --- a/include/net/netfilter/nf_conntrack_count.h
    +++ b/include/net/netfilter/nf_conntrack_count.h
    @@ -13,6 +13,7 @@ struct nf_conncount_list {
     	u32 last_gc;		/* jiffies at most recent gc */
     	struct list_head head;	/* connections with the same filtering key */
     	unsigned int count;	/* length of list */
    +	unsigned int last_gc_count; /* length of list at most recent gc */
     };
     
     struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int family,
    
  • net/netfilter/nf_conncount.c+10 6 modified
    diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
    index 70e9662fe17772..47bdd8d121bb57 100644
    --- a/net/netfilter/nf_conncount.c
    +++ b/net/netfilter/nf_conncount.c
    @@ -34,8 +34,9 @@
     
     #define CONNCOUNT_SLOTS		256U
     
    -#define CONNCOUNT_GC_MAX_NODES	8
    -#define MAX_KEYLEN		5
    +#define CONNCOUNT_GC_MAX_NODES		8
    +#define CONNCOUNT_GC_MAX_COLLECT	64
    +#define MAX_KEYLEN			5
     
     /* we will save the tuples of all connections we care about */
     struct nf_conncount_tuple {
    @@ -182,12 +183,13 @@ static int __nf_conncount_add(struct net *net,
     		goto out_put;
     	}
     
    -	if ((u32)jiffies == list->last_gc)
    +	if ((u32)jiffies == list->last_gc &&
    +	    (list->count - list->last_gc_count) < CONNCOUNT_GC_MAX_COLLECT)
     		goto add_new_node;
     
     	/* check the saved connections */
     	list_for_each_entry_safe(conn, conn_n, &list->head, node) {
    -		if (collect > CONNCOUNT_GC_MAX_NODES)
    +		if (collect > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     
     		found = find_or_evict(net, list, conn);
    @@ -230,6 +232,7 @@ static int __nf_conncount_add(struct net *net,
     		nf_ct_put(found_ct);
     	}
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     add_new_node:
     	if (WARN_ON_ONCE(list->count > INT_MAX)) {
    @@ -277,6 +280,7 @@ void nf_conncount_list_init(struct nf_conncount_list *list)
     	spin_lock_init(&list->list_lock);
     	INIT_LIST_HEAD(&list->head);
     	list->count = 0;
    +	list->last_gc_count = 0;
     	list->last_gc = (u32)jiffies;
     }
     EXPORT_SYMBOL_GPL(nf_conncount_list_init);
    @@ -316,13 +320,14 @@ static bool __nf_conncount_gc_list(struct net *net,
     		}
     
     		nf_ct_put(found_ct);
    -		if (collected > CONNCOUNT_GC_MAX_NODES)
    +		if (collected > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     	}
     
     	if (!list->count)
     		ret = true;
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
  • net/netfilter/nf_conncount.c+10 6 modified
    diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
    index 70e9662fe17772..47bdd8d121bb57 100644
    --- a/net/netfilter/nf_conncount.c
    +++ b/net/netfilter/nf_conncount.c
    @@ -34,8 +34,9 @@
     
     #define CONNCOUNT_SLOTS		256U
     
    -#define CONNCOUNT_GC_MAX_NODES	8
    -#define MAX_KEYLEN		5
    +#define CONNCOUNT_GC_MAX_NODES		8
    +#define CONNCOUNT_GC_MAX_COLLECT	64
    +#define MAX_KEYLEN			5
     
     /* we will save the tuples of all connections we care about */
     struct nf_conncount_tuple {
    @@ -182,12 +183,13 @@ static int __nf_conncount_add(struct net *net,
     		goto out_put;
     	}
     
    -	if ((u32)jiffies == list->last_gc)
    +	if ((u32)jiffies == list->last_gc &&
    +	    (list->count - list->last_gc_count) < CONNCOUNT_GC_MAX_COLLECT)
     		goto add_new_node;
     
     	/* check the saved connections */
     	list_for_each_entry_safe(conn, conn_n, &list->head, node) {
    -		if (collect > CONNCOUNT_GC_MAX_NODES)
    +		if (collect > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     
     		found = find_or_evict(net, list, conn);
    @@ -230,6 +232,7 @@ static int __nf_conncount_add(struct net *net,
     		nf_ct_put(found_ct);
     	}
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     add_new_node:
     	if (WARN_ON_ONCE(list->count > INT_MAX)) {
    @@ -277,6 +280,7 @@ void nf_conncount_list_init(struct nf_conncount_list *list)
     	spin_lock_init(&list->list_lock);
     	INIT_LIST_HEAD(&list->head);
     	list->count = 0;
    +	list->last_gc_count = 0;
     	list->last_gc = (u32)jiffies;
     }
     EXPORT_SYMBOL_GPL(nf_conncount_list_init);
    @@ -316,13 +320,14 @@ static bool __nf_conncount_gc_list(struct net *net,
     		}
     
     		nf_ct_put(found_ct);
    -		if (collected > CONNCOUNT_GC_MAX_NODES)
    +		if (collected > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     	}
     
     	if (!list->count)
     		ret = true;
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
a5c9e14e0e89

netfilter: nf_conncount: increase the connection clean up limit to 64

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitFernando Fernandez ManceraDec 17, 2025Fixed in 5.10.252via kernel-cna
4 files changed · +22 12
  • include/net/netfilter/nf_conntrack_count.h+1 0 modified
    diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h
    index 115bb7e572f7d0..bf22661925b813 100644
    --- a/include/net/netfilter/nf_conntrack_count.h
    +++ b/include/net/netfilter/nf_conntrack_count.h
    @@ -13,6 +13,7 @@ struct nf_conncount_list {
     	u32 last_gc;		/* jiffies at most recent gc */
     	struct list_head head;	/* connections with the same filtering key */
     	unsigned int count;	/* length of list */
    +	unsigned int last_gc_count; /* length of list at most recent gc */
     };
     
     struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int family,
    
  • include/net/netfilter/nf_conntrack_count.h+1 0 modified
    diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h
    index 115bb7e572f7d0..bf22661925b813 100644
    --- a/include/net/netfilter/nf_conntrack_count.h
    +++ b/include/net/netfilter/nf_conntrack_count.h
    @@ -13,6 +13,7 @@ struct nf_conncount_list {
     	u32 last_gc;		/* jiffies at most recent gc */
     	struct list_head head;	/* connections with the same filtering key */
     	unsigned int count;	/* length of list */
    +	unsigned int last_gc_count; /* length of list at most recent gc */
     };
     
     struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int family,
    
  • net/netfilter/nf_conncount.c+10 6 modified
    diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
    index 70e9662fe17772..47bdd8d121bb57 100644
    --- a/net/netfilter/nf_conncount.c
    +++ b/net/netfilter/nf_conncount.c
    @@ -34,8 +34,9 @@
     
     #define CONNCOUNT_SLOTS		256U
     
    -#define CONNCOUNT_GC_MAX_NODES	8
    -#define MAX_KEYLEN		5
    +#define CONNCOUNT_GC_MAX_NODES		8
    +#define CONNCOUNT_GC_MAX_COLLECT	64
    +#define MAX_KEYLEN			5
     
     /* we will save the tuples of all connections we care about */
     struct nf_conncount_tuple {
    @@ -182,12 +183,13 @@ static int __nf_conncount_add(struct net *net,
     		goto out_put;
     	}
     
    -	if ((u32)jiffies == list->last_gc)
    +	if ((u32)jiffies == list->last_gc &&
    +	    (list->count - list->last_gc_count) < CONNCOUNT_GC_MAX_COLLECT)
     		goto add_new_node;
     
     	/* check the saved connections */
     	list_for_each_entry_safe(conn, conn_n, &list->head, node) {
    -		if (collect > CONNCOUNT_GC_MAX_NODES)
    +		if (collect > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     
     		found = find_or_evict(net, list, conn);
    @@ -230,6 +232,7 @@ static int __nf_conncount_add(struct net *net,
     		nf_ct_put(found_ct);
     	}
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     add_new_node:
     	if (WARN_ON_ONCE(list->count > INT_MAX)) {
    @@ -277,6 +280,7 @@ void nf_conncount_list_init(struct nf_conncount_list *list)
     	spin_lock_init(&list->list_lock);
     	INIT_LIST_HEAD(&list->head);
     	list->count = 0;
    +	list->last_gc_count = 0;
     	list->last_gc = (u32)jiffies;
     }
     EXPORT_SYMBOL_GPL(nf_conncount_list_init);
    @@ -316,13 +320,14 @@ static bool __nf_conncount_gc_list(struct net *net,
     		}
     
     		nf_ct_put(found_ct);
    -		if (collected > CONNCOUNT_GC_MAX_NODES)
    +		if (collected > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     	}
     
     	if (!list->count)
     		ret = true;
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
  • net/netfilter/nf_conncount.c+10 6 modified
    diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
    index 70e9662fe17772..47bdd8d121bb57 100644
    --- a/net/netfilter/nf_conncount.c
    +++ b/net/netfilter/nf_conncount.c
    @@ -34,8 +34,9 @@
     
     #define CONNCOUNT_SLOTS		256U
     
    -#define CONNCOUNT_GC_MAX_NODES	8
    -#define MAX_KEYLEN		5
    +#define CONNCOUNT_GC_MAX_NODES		8
    +#define CONNCOUNT_GC_MAX_COLLECT	64
    +#define MAX_KEYLEN			5
     
     /* we will save the tuples of all connections we care about */
     struct nf_conncount_tuple {
    @@ -182,12 +183,13 @@ static int __nf_conncount_add(struct net *net,
     		goto out_put;
     	}
     
    -	if ((u32)jiffies == list->last_gc)
    +	if ((u32)jiffies == list->last_gc &&
    +	    (list->count - list->last_gc_count) < CONNCOUNT_GC_MAX_COLLECT)
     		goto add_new_node;
     
     	/* check the saved connections */
     	list_for_each_entry_safe(conn, conn_n, &list->head, node) {
    -		if (collect > CONNCOUNT_GC_MAX_NODES)
    +		if (collect > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     
     		found = find_or_evict(net, list, conn);
    @@ -230,6 +232,7 @@ static int __nf_conncount_add(struct net *net,
     		nf_ct_put(found_ct);
     	}
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     add_new_node:
     	if (WARN_ON_ONCE(list->count > INT_MAX)) {
    @@ -277,6 +280,7 @@ void nf_conncount_list_init(struct nf_conncount_list *list)
     	spin_lock_init(&list->list_lock);
     	INIT_LIST_HEAD(&list->head);
     	list->count = 0;
    +	list->last_gc_count = 0;
     	list->last_gc = (u32)jiffies;
     }
     EXPORT_SYMBOL_GPL(nf_conncount_list_init);
    @@ -316,13 +320,14 @@ static bool __nf_conncount_gc_list(struct net *net,
     		}
     
     		nf_ct_put(found_ct);
    -		if (collected > CONNCOUNT_GC_MAX_NODES)
    +		if (collected > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     	}
     
     	if (!list->count)
     		ret = true;
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
13eede458fdf

netfilter: nf_conncount: increase the connection clean up limit to 64

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitFernando Fernandez ManceraDec 17, 2025Fixed in 5.15.202via kernel-cna
4 files changed · +22 12
  • include/net/netfilter/nf_conntrack_count.h+1 0 modified
    diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h
    index 115bb7e572f7d0..bf22661925b813 100644
    --- a/include/net/netfilter/nf_conntrack_count.h
    +++ b/include/net/netfilter/nf_conntrack_count.h
    @@ -13,6 +13,7 @@ struct nf_conncount_list {
     	u32 last_gc;		/* jiffies at most recent gc */
     	struct list_head head;	/* connections with the same filtering key */
     	unsigned int count;	/* length of list */
    +	unsigned int last_gc_count; /* length of list at most recent gc */
     };
     
     struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int family,
    
  • include/net/netfilter/nf_conntrack_count.h+1 0 modified
    diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h
    index 115bb7e572f7d0..bf22661925b813 100644
    --- a/include/net/netfilter/nf_conntrack_count.h
    +++ b/include/net/netfilter/nf_conntrack_count.h
    @@ -13,6 +13,7 @@ struct nf_conncount_list {
     	u32 last_gc;		/* jiffies at most recent gc */
     	struct list_head head;	/* connections with the same filtering key */
     	unsigned int count;	/* length of list */
    +	unsigned int last_gc_count; /* length of list at most recent gc */
     };
     
     struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int family,
    
  • net/netfilter/nf_conncount.c+10 6 modified
    diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
    index 70e9662fe17772..47bdd8d121bb57 100644
    --- a/net/netfilter/nf_conncount.c
    +++ b/net/netfilter/nf_conncount.c
    @@ -34,8 +34,9 @@
     
     #define CONNCOUNT_SLOTS		256U
     
    -#define CONNCOUNT_GC_MAX_NODES	8
    -#define MAX_KEYLEN		5
    +#define CONNCOUNT_GC_MAX_NODES		8
    +#define CONNCOUNT_GC_MAX_COLLECT	64
    +#define MAX_KEYLEN			5
     
     /* we will save the tuples of all connections we care about */
     struct nf_conncount_tuple {
    @@ -182,12 +183,13 @@ static int __nf_conncount_add(struct net *net,
     		goto out_put;
     	}
     
    -	if ((u32)jiffies == list->last_gc)
    +	if ((u32)jiffies == list->last_gc &&
    +	    (list->count - list->last_gc_count) < CONNCOUNT_GC_MAX_COLLECT)
     		goto add_new_node;
     
     	/* check the saved connections */
     	list_for_each_entry_safe(conn, conn_n, &list->head, node) {
    -		if (collect > CONNCOUNT_GC_MAX_NODES)
    +		if (collect > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     
     		found = find_or_evict(net, list, conn);
    @@ -230,6 +232,7 @@ static int __nf_conncount_add(struct net *net,
     		nf_ct_put(found_ct);
     	}
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     add_new_node:
     	if (WARN_ON_ONCE(list->count > INT_MAX)) {
    @@ -277,6 +280,7 @@ void nf_conncount_list_init(struct nf_conncount_list *list)
     	spin_lock_init(&list->list_lock);
     	INIT_LIST_HEAD(&list->head);
     	list->count = 0;
    +	list->last_gc_count = 0;
     	list->last_gc = (u32)jiffies;
     }
     EXPORT_SYMBOL_GPL(nf_conncount_list_init);
    @@ -316,13 +320,14 @@ static bool __nf_conncount_gc_list(struct net *net,
     		}
     
     		nf_ct_put(found_ct);
    -		if (collected > CONNCOUNT_GC_MAX_NODES)
    +		if (collected > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     	}
     
     	if (!list->count)
     		ret = true;
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
  • net/netfilter/nf_conncount.c+10 6 modified
    diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
    index 70e9662fe17772..47bdd8d121bb57 100644
    --- a/net/netfilter/nf_conncount.c
    +++ b/net/netfilter/nf_conncount.c
    @@ -34,8 +34,9 @@
     
     #define CONNCOUNT_SLOTS		256U
     
    -#define CONNCOUNT_GC_MAX_NODES	8
    -#define MAX_KEYLEN		5
    +#define CONNCOUNT_GC_MAX_NODES		8
    +#define CONNCOUNT_GC_MAX_COLLECT	64
    +#define MAX_KEYLEN			5
     
     /* we will save the tuples of all connections we care about */
     struct nf_conncount_tuple {
    @@ -182,12 +183,13 @@ static int __nf_conncount_add(struct net *net,
     		goto out_put;
     	}
     
    -	if ((u32)jiffies == list->last_gc)
    +	if ((u32)jiffies == list->last_gc &&
    +	    (list->count - list->last_gc_count) < CONNCOUNT_GC_MAX_COLLECT)
     		goto add_new_node;
     
     	/* check the saved connections */
     	list_for_each_entry_safe(conn, conn_n, &list->head, node) {
    -		if (collect > CONNCOUNT_GC_MAX_NODES)
    +		if (collect > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     
     		found = find_or_evict(net, list, conn);
    @@ -230,6 +232,7 @@ static int __nf_conncount_add(struct net *net,
     		nf_ct_put(found_ct);
     	}
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     add_new_node:
     	if (WARN_ON_ONCE(list->count > INT_MAX)) {
    @@ -277,6 +280,7 @@ void nf_conncount_list_init(struct nf_conncount_list *list)
     	spin_lock_init(&list->list_lock);
     	INIT_LIST_HEAD(&list->head);
     	list->count = 0;
    +	list->last_gc_count = 0;
     	list->last_gc = (u32)jiffies;
     }
     EXPORT_SYMBOL_GPL(nf_conncount_list_init);
    @@ -316,13 +320,14 @@ static bool __nf_conncount_gc_list(struct net *net,
     		}
     
     		nf_ct_put(found_ct);
    -		if (collected > CONNCOUNT_GC_MAX_NODES)
    +		if (collected > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     	}
     
     	if (!list->count)
     		ret = true;
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
3d0994ed0aa1

netfilter: nf_conncount: increase the connection clean up limit to 64

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitFernando Fernandez ManceraDec 17, 2025Fixed in 6.12.75via kernel-cna
4 files changed · +22 12
  • include/net/netfilter/nf_conntrack_count.h+1 0 modified
    diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h
    index 52a06de41aa0f9..cf0166520cf338 100644
    --- a/include/net/netfilter/nf_conntrack_count.h
    +++ b/include/net/netfilter/nf_conntrack_count.h
    @@ -13,6 +13,7 @@ struct nf_conncount_list {
     	u32 last_gc;		/* jiffies at most recent gc */
     	struct list_head head;	/* connections with the same filtering key */
     	unsigned int count;	/* length of list */
    +	unsigned int last_gc_count; /* length of list at most recent gc */
     };
     
     struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int keylen);
    
  • include/net/netfilter/nf_conntrack_count.h+1 0 modified
    diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h
    index 52a06de41aa0f9..cf0166520cf338 100644
    --- a/include/net/netfilter/nf_conntrack_count.h
    +++ b/include/net/netfilter/nf_conntrack_count.h
    @@ -13,6 +13,7 @@ struct nf_conncount_list {
     	u32 last_gc;		/* jiffies at most recent gc */
     	struct list_head head;	/* connections with the same filtering key */
     	unsigned int count;	/* length of list */
    +	unsigned int last_gc_count; /* length of list at most recent gc */
     };
     
     struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int keylen);
    
  • net/netfilter/nf_conncount.c+10 6 modified
    diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
    index 8487808c87614f..288936f5c1bf92 100644
    --- a/net/netfilter/nf_conncount.c
    +++ b/net/netfilter/nf_conncount.c
    @@ -34,8 +34,9 @@
     
     #define CONNCOUNT_SLOTS		256U
     
    -#define CONNCOUNT_GC_MAX_NODES	8
    -#define MAX_KEYLEN		5
    +#define CONNCOUNT_GC_MAX_NODES		8
    +#define CONNCOUNT_GC_MAX_COLLECT	64
    +#define MAX_KEYLEN			5
     
     /* we will save the tuples of all connections we care about */
     struct nf_conncount_tuple {
    @@ -182,12 +183,13 @@ static int __nf_conncount_add(struct net *net,
     		goto out_put;
     	}
     
    -	if ((u32)jiffies == list->last_gc)
    +	if ((u32)jiffies == list->last_gc &&
    +	    (list->count - list->last_gc_count) < CONNCOUNT_GC_MAX_COLLECT)
     		goto add_new_node;
     
     	/* check the saved connections */
     	list_for_each_entry_safe(conn, conn_n, &list->head, node) {
    -		if (collect > CONNCOUNT_GC_MAX_NODES)
    +		if (collect > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     
     		found = find_or_evict(net, list, conn);
    @@ -230,6 +232,7 @@ static int __nf_conncount_add(struct net *net,
     		nf_ct_put(found_ct);
     	}
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     add_new_node:
     	if (WARN_ON_ONCE(list->count > INT_MAX)) {
    @@ -277,6 +280,7 @@ void nf_conncount_list_init(struct nf_conncount_list *list)
     	spin_lock_init(&list->list_lock);
     	INIT_LIST_HEAD(&list->head);
     	list->count = 0;
    +	list->last_gc_count = 0;
     	list->last_gc = (u32)jiffies;
     }
     EXPORT_SYMBOL_GPL(nf_conncount_list_init);
    @@ -316,13 +320,14 @@ static bool __nf_conncount_gc_list(struct net *net,
     		}
     
     		nf_ct_put(found_ct);
    -		if (collected > CONNCOUNT_GC_MAX_NODES)
    +		if (collected > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     	}
     
     	if (!list->count)
     		ret = true;
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
  • net/netfilter/nf_conncount.c+10 6 modified
    diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
    index 8487808c87614f..288936f5c1bf92 100644
    --- a/net/netfilter/nf_conncount.c
    +++ b/net/netfilter/nf_conncount.c
    @@ -34,8 +34,9 @@
     
     #define CONNCOUNT_SLOTS		256U
     
    -#define CONNCOUNT_GC_MAX_NODES	8
    -#define MAX_KEYLEN		5
    +#define CONNCOUNT_GC_MAX_NODES		8
    +#define CONNCOUNT_GC_MAX_COLLECT	64
    +#define MAX_KEYLEN			5
     
     /* we will save the tuples of all connections we care about */
     struct nf_conncount_tuple {
    @@ -182,12 +183,13 @@ static int __nf_conncount_add(struct net *net,
     		goto out_put;
     	}
     
    -	if ((u32)jiffies == list->last_gc)
    +	if ((u32)jiffies == list->last_gc &&
    +	    (list->count - list->last_gc_count) < CONNCOUNT_GC_MAX_COLLECT)
     		goto add_new_node;
     
     	/* check the saved connections */
     	list_for_each_entry_safe(conn, conn_n, &list->head, node) {
    -		if (collect > CONNCOUNT_GC_MAX_NODES)
    +		if (collect > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     
     		found = find_or_evict(net, list, conn);
    @@ -230,6 +232,7 @@ static int __nf_conncount_add(struct net *net,
     		nf_ct_put(found_ct);
     	}
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     add_new_node:
     	if (WARN_ON_ONCE(list->count > INT_MAX)) {
    @@ -277,6 +280,7 @@ void nf_conncount_list_init(struct nf_conncount_list *list)
     	spin_lock_init(&list->list_lock);
     	INIT_LIST_HEAD(&list->head);
     	list->count = 0;
    +	list->last_gc_count = 0;
     	list->last_gc = (u32)jiffies;
     }
     EXPORT_SYMBOL_GPL(nf_conncount_list_init);
    @@ -316,13 +320,14 @@ static bool __nf_conncount_gc_list(struct net *net,
     		}
     
     		nf_ct_put(found_ct);
    -		if (collected > CONNCOUNT_GC_MAX_NODES)
    +		if (collected > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     	}
     
     	if (!list->count)
     		ret = true;
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
0af0812baf2d

netfilter: nf_conncount: increase the connection clean up limit to 64

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitFernando Fernandez ManceraDec 17, 2025Fixed in 6.19.4via kernel-cna
4 files changed · +22 12
  • include/net/netfilter/nf_conntrack_count.h+1 0 modified
    diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h
    index 52a06de41aa0f9..cf0166520cf338 100644
    --- a/include/net/netfilter/nf_conntrack_count.h
    +++ b/include/net/netfilter/nf_conntrack_count.h
    @@ -13,6 +13,7 @@ struct nf_conncount_list {
     	u32 last_gc;		/* jiffies at most recent gc */
     	struct list_head head;	/* connections with the same filtering key */
     	unsigned int count;	/* length of list */
    +	unsigned int last_gc_count; /* length of list at most recent gc */
     };
     
     struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int keylen);
    
  • include/net/netfilter/nf_conntrack_count.h+1 0 modified
    diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h
    index 52a06de41aa0f9..cf0166520cf338 100644
    --- a/include/net/netfilter/nf_conntrack_count.h
    +++ b/include/net/netfilter/nf_conntrack_count.h
    @@ -13,6 +13,7 @@ struct nf_conncount_list {
     	u32 last_gc;		/* jiffies at most recent gc */
     	struct list_head head;	/* connections with the same filtering key */
     	unsigned int count;	/* length of list */
    +	unsigned int last_gc_count; /* length of list at most recent gc */
     };
     
     struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int keylen);
    
  • net/netfilter/nf_conncount.c+10 6 modified
    diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
    index 8487808c87614f..288936f5c1bf92 100644
    --- a/net/netfilter/nf_conncount.c
    +++ b/net/netfilter/nf_conncount.c
    @@ -34,8 +34,9 @@
     
     #define CONNCOUNT_SLOTS		256U
     
    -#define CONNCOUNT_GC_MAX_NODES	8
    -#define MAX_KEYLEN		5
    +#define CONNCOUNT_GC_MAX_NODES		8
    +#define CONNCOUNT_GC_MAX_COLLECT	64
    +#define MAX_KEYLEN			5
     
     /* we will save the tuples of all connections we care about */
     struct nf_conncount_tuple {
    @@ -182,12 +183,13 @@ static int __nf_conncount_add(struct net *net,
     		goto out_put;
     	}
     
    -	if ((u32)jiffies == list->last_gc)
    +	if ((u32)jiffies == list->last_gc &&
    +	    (list->count - list->last_gc_count) < CONNCOUNT_GC_MAX_COLLECT)
     		goto add_new_node;
     
     	/* check the saved connections */
     	list_for_each_entry_safe(conn, conn_n, &list->head, node) {
    -		if (collect > CONNCOUNT_GC_MAX_NODES)
    +		if (collect > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     
     		found = find_or_evict(net, list, conn);
    @@ -230,6 +232,7 @@ static int __nf_conncount_add(struct net *net,
     		nf_ct_put(found_ct);
     	}
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     add_new_node:
     	if (WARN_ON_ONCE(list->count > INT_MAX)) {
    @@ -277,6 +280,7 @@ void nf_conncount_list_init(struct nf_conncount_list *list)
     	spin_lock_init(&list->list_lock);
     	INIT_LIST_HEAD(&list->head);
     	list->count = 0;
    +	list->last_gc_count = 0;
     	list->last_gc = (u32)jiffies;
     }
     EXPORT_SYMBOL_GPL(nf_conncount_list_init);
    @@ -316,13 +320,14 @@ static bool __nf_conncount_gc_list(struct net *net,
     		}
     
     		nf_ct_put(found_ct);
    -		if (collected > CONNCOUNT_GC_MAX_NODES)
    +		if (collected > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     	}
     
     	if (!list->count)
     		ret = true;
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
  • net/netfilter/nf_conncount.c+10 6 modified
    diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
    index 8487808c87614f..288936f5c1bf92 100644
    --- a/net/netfilter/nf_conncount.c
    +++ b/net/netfilter/nf_conncount.c
    @@ -34,8 +34,9 @@
     
     #define CONNCOUNT_SLOTS		256U
     
    -#define CONNCOUNT_GC_MAX_NODES	8
    -#define MAX_KEYLEN		5
    +#define CONNCOUNT_GC_MAX_NODES		8
    +#define CONNCOUNT_GC_MAX_COLLECT	64
    +#define MAX_KEYLEN			5
     
     /* we will save the tuples of all connections we care about */
     struct nf_conncount_tuple {
    @@ -182,12 +183,13 @@ static int __nf_conncount_add(struct net *net,
     		goto out_put;
     	}
     
    -	if ((u32)jiffies == list->last_gc)
    +	if ((u32)jiffies == list->last_gc &&
    +	    (list->count - list->last_gc_count) < CONNCOUNT_GC_MAX_COLLECT)
     		goto add_new_node;
     
     	/* check the saved connections */
     	list_for_each_entry_safe(conn, conn_n, &list->head, node) {
    -		if (collect > CONNCOUNT_GC_MAX_NODES)
    +		if (collect > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     
     		found = find_or_evict(net, list, conn);
    @@ -230,6 +232,7 @@ static int __nf_conncount_add(struct net *net,
     		nf_ct_put(found_ct);
     	}
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     add_new_node:
     	if (WARN_ON_ONCE(list->count > INT_MAX)) {
    @@ -277,6 +280,7 @@ void nf_conncount_list_init(struct nf_conncount_list *list)
     	spin_lock_init(&list->list_lock);
     	INIT_LIST_HEAD(&list->head);
     	list->count = 0;
    +	list->last_gc_count = 0;
     	list->last_gc = (u32)jiffies;
     }
     EXPORT_SYMBOL_GPL(nf_conncount_list_init);
    @@ -316,13 +320,14 @@ static bool __nf_conncount_gc_list(struct net *net,
     		}
     
     		nf_ct_put(found_ct);
    -		if (collected > CONNCOUNT_GC_MAX_NODES)
    +		if (collected > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     	}
     
     	if (!list->count)
     		ret = true;
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
0792ad077d77

netfilter: nf_conncount: increase the connection clean up limit to 64

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitFernando Fernandez ManceraDec 17, 2025Fixed in 6.6.128via kernel-cna
4 files changed · +22 12
  • include/net/netfilter/nf_conntrack_count.h+1 0 modified
    diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h
    index 115bb7e572f7d0..bf22661925b813 100644
    --- a/include/net/netfilter/nf_conntrack_count.h
    +++ b/include/net/netfilter/nf_conntrack_count.h
    @@ -13,6 +13,7 @@ struct nf_conncount_list {
     	u32 last_gc;		/* jiffies at most recent gc */
     	struct list_head head;	/* connections with the same filtering key */
     	unsigned int count;	/* length of list */
    +	unsigned int last_gc_count; /* length of list at most recent gc */
     };
     
     struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int family,
    
  • include/net/netfilter/nf_conntrack_count.h+1 0 modified
    diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h
    index 115bb7e572f7d0..bf22661925b813 100644
    --- a/include/net/netfilter/nf_conntrack_count.h
    +++ b/include/net/netfilter/nf_conntrack_count.h
    @@ -13,6 +13,7 @@ struct nf_conncount_list {
     	u32 last_gc;		/* jiffies at most recent gc */
     	struct list_head head;	/* connections with the same filtering key */
     	unsigned int count;	/* length of list */
    +	unsigned int last_gc_count; /* length of list at most recent gc */
     };
     
     struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int family,
    
  • net/netfilter/nf_conncount.c+10 6 modified
    diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
    index 70e9662fe17772..47bdd8d121bb57 100644
    --- a/net/netfilter/nf_conncount.c
    +++ b/net/netfilter/nf_conncount.c
    @@ -34,8 +34,9 @@
     
     #define CONNCOUNT_SLOTS		256U
     
    -#define CONNCOUNT_GC_MAX_NODES	8
    -#define MAX_KEYLEN		5
    +#define CONNCOUNT_GC_MAX_NODES		8
    +#define CONNCOUNT_GC_MAX_COLLECT	64
    +#define MAX_KEYLEN			5
     
     /* we will save the tuples of all connections we care about */
     struct nf_conncount_tuple {
    @@ -182,12 +183,13 @@ static int __nf_conncount_add(struct net *net,
     		goto out_put;
     	}
     
    -	if ((u32)jiffies == list->last_gc)
    +	if ((u32)jiffies == list->last_gc &&
    +	    (list->count - list->last_gc_count) < CONNCOUNT_GC_MAX_COLLECT)
     		goto add_new_node;
     
     	/* check the saved connections */
     	list_for_each_entry_safe(conn, conn_n, &list->head, node) {
    -		if (collect > CONNCOUNT_GC_MAX_NODES)
    +		if (collect > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     
     		found = find_or_evict(net, list, conn);
    @@ -230,6 +232,7 @@ static int __nf_conncount_add(struct net *net,
     		nf_ct_put(found_ct);
     	}
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     add_new_node:
     	if (WARN_ON_ONCE(list->count > INT_MAX)) {
    @@ -277,6 +280,7 @@ void nf_conncount_list_init(struct nf_conncount_list *list)
     	spin_lock_init(&list->list_lock);
     	INIT_LIST_HEAD(&list->head);
     	list->count = 0;
    +	list->last_gc_count = 0;
     	list->last_gc = (u32)jiffies;
     }
     EXPORT_SYMBOL_GPL(nf_conncount_list_init);
    @@ -316,13 +320,14 @@ static bool __nf_conncount_gc_list(struct net *net,
     		}
     
     		nf_ct_put(found_ct);
    -		if (collected > CONNCOUNT_GC_MAX_NODES)
    +		if (collected > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     	}
     
     	if (!list->count)
     		ret = true;
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
  • net/netfilter/nf_conncount.c+10 6 modified
    diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
    index 70e9662fe17772..47bdd8d121bb57 100644
    --- a/net/netfilter/nf_conncount.c
    +++ b/net/netfilter/nf_conncount.c
    @@ -34,8 +34,9 @@
     
     #define CONNCOUNT_SLOTS		256U
     
    -#define CONNCOUNT_GC_MAX_NODES	8
    -#define MAX_KEYLEN		5
    +#define CONNCOUNT_GC_MAX_NODES		8
    +#define CONNCOUNT_GC_MAX_COLLECT	64
    +#define MAX_KEYLEN			5
     
     /* we will save the tuples of all connections we care about */
     struct nf_conncount_tuple {
    @@ -182,12 +183,13 @@ static int __nf_conncount_add(struct net *net,
     		goto out_put;
     	}
     
    -	if ((u32)jiffies == list->last_gc)
    +	if ((u32)jiffies == list->last_gc &&
    +	    (list->count - list->last_gc_count) < CONNCOUNT_GC_MAX_COLLECT)
     		goto add_new_node;
     
     	/* check the saved connections */
     	list_for_each_entry_safe(conn, conn_n, &list->head, node) {
    -		if (collect > CONNCOUNT_GC_MAX_NODES)
    +		if (collect > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     
     		found = find_or_evict(net, list, conn);
    @@ -230,6 +232,7 @@ static int __nf_conncount_add(struct net *net,
     		nf_ct_put(found_ct);
     	}
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     add_new_node:
     	if (WARN_ON_ONCE(list->count > INT_MAX)) {
    @@ -277,6 +280,7 @@ void nf_conncount_list_init(struct nf_conncount_list *list)
     	spin_lock_init(&list->list_lock);
     	INIT_LIST_HEAD(&list->head);
     	list->count = 0;
    +	list->last_gc_count = 0;
     	list->last_gc = (u32)jiffies;
     }
     EXPORT_SYMBOL_GPL(nf_conncount_list_init);
    @@ -316,13 +320,14 @@ static bool __nf_conncount_gc_list(struct net *net,
     		}
     
     		nf_ct_put(found_ct);
    -		if (collected > CONNCOUNT_GC_MAX_NODES)
    +		if (collected > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     	}
     
     	if (!list->count)
     		ret = true;
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
21d033e47273

netfilter: nf_conncount: increase the connection clean up limit to 64

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.gitFernando Fernandez ManceraDec 17, 2025via nvd-ref
4 files changed · +22 12
  • include/net/netfilter/nf_conntrack_count.h+1 0 modified
    diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h
    index 52a06de41aa0f9..cf0166520cf338 100644
    --- a/include/net/netfilter/nf_conntrack_count.h
    +++ b/include/net/netfilter/nf_conntrack_count.h
    @@ -13,6 +13,7 @@ struct nf_conncount_list {
     	u32 last_gc;		/* jiffies at most recent gc */
     	struct list_head head;	/* connections with the same filtering key */
     	unsigned int count;	/* length of list */
    +	unsigned int last_gc_count; /* length of list at most recent gc */
     };
     
     struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int keylen);
    
  • include/net/netfilter/nf_conntrack_count.h+1 0 modified
    diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h
    index 52a06de41aa0f9..cf0166520cf338 100644
    --- a/include/net/netfilter/nf_conntrack_count.h
    +++ b/include/net/netfilter/nf_conntrack_count.h
    @@ -13,6 +13,7 @@ struct nf_conncount_list {
     	u32 last_gc;		/* jiffies at most recent gc */
     	struct list_head head;	/* connections with the same filtering key */
     	unsigned int count;	/* length of list */
    +	unsigned int last_gc_count; /* length of list at most recent gc */
     };
     
     struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int keylen);
    
  • net/netfilter/nf_conncount.c+10 6 modified
    diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
    index 8487808c87614f..288936f5c1bf92 100644
    --- a/net/netfilter/nf_conncount.c
    +++ b/net/netfilter/nf_conncount.c
    @@ -34,8 +34,9 @@
     
     #define CONNCOUNT_SLOTS		256U
     
    -#define CONNCOUNT_GC_MAX_NODES	8
    -#define MAX_KEYLEN		5
    +#define CONNCOUNT_GC_MAX_NODES		8
    +#define CONNCOUNT_GC_MAX_COLLECT	64
    +#define MAX_KEYLEN			5
     
     /* we will save the tuples of all connections we care about */
     struct nf_conncount_tuple {
    @@ -182,12 +183,13 @@ static int __nf_conncount_add(struct net *net,
     		goto out_put;
     	}
     
    -	if ((u32)jiffies == list->last_gc)
    +	if ((u32)jiffies == list->last_gc &&
    +	    (list->count - list->last_gc_count) < CONNCOUNT_GC_MAX_COLLECT)
     		goto add_new_node;
     
     	/* check the saved connections */
     	list_for_each_entry_safe(conn, conn_n, &list->head, node) {
    -		if (collect > CONNCOUNT_GC_MAX_NODES)
    +		if (collect > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     
     		found = find_or_evict(net, list, conn);
    @@ -230,6 +232,7 @@ static int __nf_conncount_add(struct net *net,
     		nf_ct_put(found_ct);
     	}
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     add_new_node:
     	if (WARN_ON_ONCE(list->count > INT_MAX)) {
    @@ -277,6 +280,7 @@ void nf_conncount_list_init(struct nf_conncount_list *list)
     	spin_lock_init(&list->list_lock);
     	INIT_LIST_HEAD(&list->head);
     	list->count = 0;
    +	list->last_gc_count = 0;
     	list->last_gc = (u32)jiffies;
     }
     EXPORT_SYMBOL_GPL(nf_conncount_list_init);
    @@ -316,13 +320,14 @@ static bool __nf_conncount_gc_list(struct net *net,
     		}
     
     		nf_ct_put(found_ct);
    -		if (collected > CONNCOUNT_GC_MAX_NODES)
    +		if (collected > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     	}
     
     	if (!list->count)
     		ret = true;
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
  • net/netfilter/nf_conncount.c+10 6 modified
    diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
    index 8487808c87614f..288936f5c1bf92 100644
    --- a/net/netfilter/nf_conncount.c
    +++ b/net/netfilter/nf_conncount.c
    @@ -34,8 +34,9 @@
     
     #define CONNCOUNT_SLOTS		256U
     
    -#define CONNCOUNT_GC_MAX_NODES	8
    -#define MAX_KEYLEN		5
    +#define CONNCOUNT_GC_MAX_NODES		8
    +#define CONNCOUNT_GC_MAX_COLLECT	64
    +#define MAX_KEYLEN			5
     
     /* we will save the tuples of all connections we care about */
     struct nf_conncount_tuple {
    @@ -182,12 +183,13 @@ static int __nf_conncount_add(struct net *net,
     		goto out_put;
     	}
     
    -	if ((u32)jiffies == list->last_gc)
    +	if ((u32)jiffies == list->last_gc &&
    +	    (list->count - list->last_gc_count) < CONNCOUNT_GC_MAX_COLLECT)
     		goto add_new_node;
     
     	/* check the saved connections */
     	list_for_each_entry_safe(conn, conn_n, &list->head, node) {
    -		if (collect > CONNCOUNT_GC_MAX_NODES)
    +		if (collect > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     
     		found = find_or_evict(net, list, conn);
    @@ -230,6 +232,7 @@ static int __nf_conncount_add(struct net *net,
     		nf_ct_put(found_ct);
     	}
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     add_new_node:
     	if (WARN_ON_ONCE(list->count > INT_MAX)) {
    @@ -277,6 +280,7 @@ void nf_conncount_list_init(struct nf_conncount_list *list)
     	spin_lock_init(&list->list_lock);
     	INIT_LIST_HEAD(&list->head);
     	list->count = 0;
    +	list->last_gc_count = 0;
     	list->last_gc = (u32)jiffies;
     }
     EXPORT_SYMBOL_GPL(nf_conncount_list_init);
    @@ -316,13 +320,14 @@ static bool __nf_conncount_gc_list(struct net *net,
     		}
     
     		nf_ct_put(found_ct);
    -		if (collected > CONNCOUNT_GC_MAX_NODES)
    +		if (collected > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     	}
     
     	if (!list->count)
     		ret = true;
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
0af0812baf2d

netfilter: nf_conncount: increase the connection clean up limit to 64

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.gitFernando Fernandez ManceraDec 17, 2025via nvd-ref
4 files changed · +22 12
  • include/net/netfilter/nf_conntrack_count.h+1 0 modified
    diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h
    index 52a06de41aa0f9..cf0166520cf338 100644
    --- a/include/net/netfilter/nf_conntrack_count.h
    +++ b/include/net/netfilter/nf_conntrack_count.h
    @@ -13,6 +13,7 @@ struct nf_conncount_list {
     	u32 last_gc;		/* jiffies at most recent gc */
     	struct list_head head;	/* connections with the same filtering key */
     	unsigned int count;	/* length of list */
    +	unsigned int last_gc_count; /* length of list at most recent gc */
     };
     
     struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int keylen);
    
  • include/net/netfilter/nf_conntrack_count.h+1 0 modified
    diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h
    index 52a06de41aa0f9..cf0166520cf338 100644
    --- a/include/net/netfilter/nf_conntrack_count.h
    +++ b/include/net/netfilter/nf_conntrack_count.h
    @@ -13,6 +13,7 @@ struct nf_conncount_list {
     	u32 last_gc;		/* jiffies at most recent gc */
     	struct list_head head;	/* connections with the same filtering key */
     	unsigned int count;	/* length of list */
    +	unsigned int last_gc_count; /* length of list at most recent gc */
     };
     
     struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int keylen);
    
  • net/netfilter/nf_conncount.c+10 6 modified
    diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
    index 8487808c87614f..288936f5c1bf92 100644
    --- a/net/netfilter/nf_conncount.c
    +++ b/net/netfilter/nf_conncount.c
    @@ -34,8 +34,9 @@
     
     #define CONNCOUNT_SLOTS		256U
     
    -#define CONNCOUNT_GC_MAX_NODES	8
    -#define MAX_KEYLEN		5
    +#define CONNCOUNT_GC_MAX_NODES		8
    +#define CONNCOUNT_GC_MAX_COLLECT	64
    +#define MAX_KEYLEN			5
     
     /* we will save the tuples of all connections we care about */
     struct nf_conncount_tuple {
    @@ -182,12 +183,13 @@ static int __nf_conncount_add(struct net *net,
     		goto out_put;
     	}
     
    -	if ((u32)jiffies == list->last_gc)
    +	if ((u32)jiffies == list->last_gc &&
    +	    (list->count - list->last_gc_count) < CONNCOUNT_GC_MAX_COLLECT)
     		goto add_new_node;
     
     	/* check the saved connections */
     	list_for_each_entry_safe(conn, conn_n, &list->head, node) {
    -		if (collect > CONNCOUNT_GC_MAX_NODES)
    +		if (collect > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     
     		found = find_or_evict(net, list, conn);
    @@ -230,6 +232,7 @@ static int __nf_conncount_add(struct net *net,
     		nf_ct_put(found_ct);
     	}
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     add_new_node:
     	if (WARN_ON_ONCE(list->count > INT_MAX)) {
    @@ -277,6 +280,7 @@ void nf_conncount_list_init(struct nf_conncount_list *list)
     	spin_lock_init(&list->list_lock);
     	INIT_LIST_HEAD(&list->head);
     	list->count = 0;
    +	list->last_gc_count = 0;
     	list->last_gc = (u32)jiffies;
     }
     EXPORT_SYMBOL_GPL(nf_conncount_list_init);
    @@ -316,13 +320,14 @@ static bool __nf_conncount_gc_list(struct net *net,
     		}
     
     		nf_ct_put(found_ct);
    -		if (collected > CONNCOUNT_GC_MAX_NODES)
    +		if (collected > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     	}
     
     	if (!list->count)
     		ret = true;
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
  • net/netfilter/nf_conncount.c+10 6 modified
    diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
    index 8487808c87614f..288936f5c1bf92 100644
    --- a/net/netfilter/nf_conncount.c
    +++ b/net/netfilter/nf_conncount.c
    @@ -34,8 +34,9 @@
     
     #define CONNCOUNT_SLOTS		256U
     
    -#define CONNCOUNT_GC_MAX_NODES	8
    -#define MAX_KEYLEN		5
    +#define CONNCOUNT_GC_MAX_NODES		8
    +#define CONNCOUNT_GC_MAX_COLLECT	64
    +#define MAX_KEYLEN			5
     
     /* we will save the tuples of all connections we care about */
     struct nf_conncount_tuple {
    @@ -182,12 +183,13 @@ static int __nf_conncount_add(struct net *net,
     		goto out_put;
     	}
     
    -	if ((u32)jiffies == list->last_gc)
    +	if ((u32)jiffies == list->last_gc &&
    +	    (list->count - list->last_gc_count) < CONNCOUNT_GC_MAX_COLLECT)
     		goto add_new_node;
     
     	/* check the saved connections */
     	list_for_each_entry_safe(conn, conn_n, &list->head, node) {
    -		if (collect > CONNCOUNT_GC_MAX_NODES)
    +		if (collect > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     
     		found = find_or_evict(net, list, conn);
    @@ -230,6 +232,7 @@ static int __nf_conncount_add(struct net *net,
     		nf_ct_put(found_ct);
     	}
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     add_new_node:
     	if (WARN_ON_ONCE(list->count > INT_MAX)) {
    @@ -277,6 +280,7 @@ void nf_conncount_list_init(struct nf_conncount_list *list)
     	spin_lock_init(&list->list_lock);
     	INIT_LIST_HEAD(&list->head);
     	list->count = 0;
    +	list->last_gc_count = 0;
     	list->last_gc = (u32)jiffies;
     }
     EXPORT_SYMBOL_GPL(nf_conncount_list_init);
    @@ -316,13 +320,14 @@ static bool __nf_conncount_gc_list(struct net *net,
     		}
     
     		nf_ct_put(found_ct);
    -		if (collected > CONNCOUNT_GC_MAX_NODES)
    +		if (collected > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     	}
     
     	if (!list->count)
     		ret = true;
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
13eede458fdf

netfilter: nf_conncount: increase the connection clean up limit to 64

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.gitFernando Fernandez ManceraDec 17, 2025via nvd-ref
4 files changed · +22 12
  • include/net/netfilter/nf_conntrack_count.h+1 0 modified
    diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h
    index 115bb7e572f7d0..bf22661925b813 100644
    --- a/include/net/netfilter/nf_conntrack_count.h
    +++ b/include/net/netfilter/nf_conntrack_count.h
    @@ -13,6 +13,7 @@ struct nf_conncount_list {
     	u32 last_gc;		/* jiffies at most recent gc */
     	struct list_head head;	/* connections with the same filtering key */
     	unsigned int count;	/* length of list */
    +	unsigned int last_gc_count; /* length of list at most recent gc */
     };
     
     struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int family,
    
  • include/net/netfilter/nf_conntrack_count.h+1 0 modified
    diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h
    index 115bb7e572f7d0..bf22661925b813 100644
    --- a/include/net/netfilter/nf_conntrack_count.h
    +++ b/include/net/netfilter/nf_conntrack_count.h
    @@ -13,6 +13,7 @@ struct nf_conncount_list {
     	u32 last_gc;		/* jiffies at most recent gc */
     	struct list_head head;	/* connections with the same filtering key */
     	unsigned int count;	/* length of list */
    +	unsigned int last_gc_count; /* length of list at most recent gc */
     };
     
     struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int family,
    
  • net/netfilter/nf_conncount.c+10 6 modified
    diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
    index 70e9662fe17772..47bdd8d121bb57 100644
    --- a/net/netfilter/nf_conncount.c
    +++ b/net/netfilter/nf_conncount.c
    @@ -34,8 +34,9 @@
     
     #define CONNCOUNT_SLOTS		256U
     
    -#define CONNCOUNT_GC_MAX_NODES	8
    -#define MAX_KEYLEN		5
    +#define CONNCOUNT_GC_MAX_NODES		8
    +#define CONNCOUNT_GC_MAX_COLLECT	64
    +#define MAX_KEYLEN			5
     
     /* we will save the tuples of all connections we care about */
     struct nf_conncount_tuple {
    @@ -182,12 +183,13 @@ static int __nf_conncount_add(struct net *net,
     		goto out_put;
     	}
     
    -	if ((u32)jiffies == list->last_gc)
    +	if ((u32)jiffies == list->last_gc &&
    +	    (list->count - list->last_gc_count) < CONNCOUNT_GC_MAX_COLLECT)
     		goto add_new_node;
     
     	/* check the saved connections */
     	list_for_each_entry_safe(conn, conn_n, &list->head, node) {
    -		if (collect > CONNCOUNT_GC_MAX_NODES)
    +		if (collect > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     
     		found = find_or_evict(net, list, conn);
    @@ -230,6 +232,7 @@ static int __nf_conncount_add(struct net *net,
     		nf_ct_put(found_ct);
     	}
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     add_new_node:
     	if (WARN_ON_ONCE(list->count > INT_MAX)) {
    @@ -277,6 +280,7 @@ void nf_conncount_list_init(struct nf_conncount_list *list)
     	spin_lock_init(&list->list_lock);
     	INIT_LIST_HEAD(&list->head);
     	list->count = 0;
    +	list->last_gc_count = 0;
     	list->last_gc = (u32)jiffies;
     }
     EXPORT_SYMBOL_GPL(nf_conncount_list_init);
    @@ -316,13 +320,14 @@ static bool __nf_conncount_gc_list(struct net *net,
     		}
     
     		nf_ct_put(found_ct);
    -		if (collected > CONNCOUNT_GC_MAX_NODES)
    +		if (collected > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     	}
     
     	if (!list->count)
     		ret = true;
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
  • net/netfilter/nf_conncount.c+10 6 modified
    diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
    index 70e9662fe17772..47bdd8d121bb57 100644
    --- a/net/netfilter/nf_conncount.c
    +++ b/net/netfilter/nf_conncount.c
    @@ -34,8 +34,9 @@
     
     #define CONNCOUNT_SLOTS		256U
     
    -#define CONNCOUNT_GC_MAX_NODES	8
    -#define MAX_KEYLEN		5
    +#define CONNCOUNT_GC_MAX_NODES		8
    +#define CONNCOUNT_GC_MAX_COLLECT	64
    +#define MAX_KEYLEN			5
     
     /* we will save the tuples of all connections we care about */
     struct nf_conncount_tuple {
    @@ -182,12 +183,13 @@ static int __nf_conncount_add(struct net *net,
     		goto out_put;
     	}
     
    -	if ((u32)jiffies == list->last_gc)
    +	if ((u32)jiffies == list->last_gc &&
    +	    (list->count - list->last_gc_count) < CONNCOUNT_GC_MAX_COLLECT)
     		goto add_new_node;
     
     	/* check the saved connections */
     	list_for_each_entry_safe(conn, conn_n, &list->head, node) {
    -		if (collect > CONNCOUNT_GC_MAX_NODES)
    +		if (collect > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     
     		found = find_or_evict(net, list, conn);
    @@ -230,6 +232,7 @@ static int __nf_conncount_add(struct net *net,
     		nf_ct_put(found_ct);
     	}
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     add_new_node:
     	if (WARN_ON_ONCE(list->count > INT_MAX)) {
    @@ -277,6 +280,7 @@ void nf_conncount_list_init(struct nf_conncount_list *list)
     	spin_lock_init(&list->list_lock);
     	INIT_LIST_HEAD(&list->head);
     	list->count = 0;
    +	list->last_gc_count = 0;
     	list->last_gc = (u32)jiffies;
     }
     EXPORT_SYMBOL_GPL(nf_conncount_list_init);
    @@ -316,13 +320,14 @@ static bool __nf_conncount_gc_list(struct net *net,
     		}
     
     		nf_ct_put(found_ct);
    -		if (collected > CONNCOUNT_GC_MAX_NODES)
    +		if (collected > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     	}
     
     	if (!list->count)
     		ret = true;
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
3d0994ed0aa1

netfilter: nf_conncount: increase the connection clean up limit to 64

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.gitFernando Fernandez ManceraDec 17, 2025via nvd-ref
4 files changed · +22 12
  • include/net/netfilter/nf_conntrack_count.h+1 0 modified
    diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h
    index 52a06de41aa0f9..cf0166520cf338 100644
    --- a/include/net/netfilter/nf_conntrack_count.h
    +++ b/include/net/netfilter/nf_conntrack_count.h
    @@ -13,6 +13,7 @@ struct nf_conncount_list {
     	u32 last_gc;		/* jiffies at most recent gc */
     	struct list_head head;	/* connections with the same filtering key */
     	unsigned int count;	/* length of list */
    +	unsigned int last_gc_count; /* length of list at most recent gc */
     };
     
     struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int keylen);
    
  • include/net/netfilter/nf_conntrack_count.h+1 0 modified
    diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h
    index 52a06de41aa0f9..cf0166520cf338 100644
    --- a/include/net/netfilter/nf_conntrack_count.h
    +++ b/include/net/netfilter/nf_conntrack_count.h
    @@ -13,6 +13,7 @@ struct nf_conncount_list {
     	u32 last_gc;		/* jiffies at most recent gc */
     	struct list_head head;	/* connections with the same filtering key */
     	unsigned int count;	/* length of list */
    +	unsigned int last_gc_count; /* length of list at most recent gc */
     };
     
     struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int keylen);
    
  • net/netfilter/nf_conncount.c+10 6 modified
    diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
    index 8487808c87614f..288936f5c1bf92 100644
    --- a/net/netfilter/nf_conncount.c
    +++ b/net/netfilter/nf_conncount.c
    @@ -34,8 +34,9 @@
     
     #define CONNCOUNT_SLOTS		256U
     
    -#define CONNCOUNT_GC_MAX_NODES	8
    -#define MAX_KEYLEN		5
    +#define CONNCOUNT_GC_MAX_NODES		8
    +#define CONNCOUNT_GC_MAX_COLLECT	64
    +#define MAX_KEYLEN			5
     
     /* we will save the tuples of all connections we care about */
     struct nf_conncount_tuple {
    @@ -182,12 +183,13 @@ static int __nf_conncount_add(struct net *net,
     		goto out_put;
     	}
     
    -	if ((u32)jiffies == list->last_gc)
    +	if ((u32)jiffies == list->last_gc &&
    +	    (list->count - list->last_gc_count) < CONNCOUNT_GC_MAX_COLLECT)
     		goto add_new_node;
     
     	/* check the saved connections */
     	list_for_each_entry_safe(conn, conn_n, &list->head, node) {
    -		if (collect > CONNCOUNT_GC_MAX_NODES)
    +		if (collect > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     
     		found = find_or_evict(net, list, conn);
    @@ -230,6 +232,7 @@ static int __nf_conncount_add(struct net *net,
     		nf_ct_put(found_ct);
     	}
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     add_new_node:
     	if (WARN_ON_ONCE(list->count > INT_MAX)) {
    @@ -277,6 +280,7 @@ void nf_conncount_list_init(struct nf_conncount_list *list)
     	spin_lock_init(&list->list_lock);
     	INIT_LIST_HEAD(&list->head);
     	list->count = 0;
    +	list->last_gc_count = 0;
     	list->last_gc = (u32)jiffies;
     }
     EXPORT_SYMBOL_GPL(nf_conncount_list_init);
    @@ -316,13 +320,14 @@ static bool __nf_conncount_gc_list(struct net *net,
     		}
     
     		nf_ct_put(found_ct);
    -		if (collected > CONNCOUNT_GC_MAX_NODES)
    +		if (collected > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     	}
     
     	if (!list->count)
     		ret = true;
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
  • net/netfilter/nf_conncount.c+10 6 modified
    diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
    index 8487808c87614f..288936f5c1bf92 100644
    --- a/net/netfilter/nf_conncount.c
    +++ b/net/netfilter/nf_conncount.c
    @@ -34,8 +34,9 @@
     
     #define CONNCOUNT_SLOTS		256U
     
    -#define CONNCOUNT_GC_MAX_NODES	8
    -#define MAX_KEYLEN		5
    +#define CONNCOUNT_GC_MAX_NODES		8
    +#define CONNCOUNT_GC_MAX_COLLECT	64
    +#define MAX_KEYLEN			5
     
     /* we will save the tuples of all connections we care about */
     struct nf_conncount_tuple {
    @@ -182,12 +183,13 @@ static int __nf_conncount_add(struct net *net,
     		goto out_put;
     	}
     
    -	if ((u32)jiffies == list->last_gc)
    +	if ((u32)jiffies == list->last_gc &&
    +	    (list->count - list->last_gc_count) < CONNCOUNT_GC_MAX_COLLECT)
     		goto add_new_node;
     
     	/* check the saved connections */
     	list_for_each_entry_safe(conn, conn_n, &list->head, node) {
    -		if (collect > CONNCOUNT_GC_MAX_NODES)
    +		if (collect > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     
     		found = find_or_evict(net, list, conn);
    @@ -230,6 +232,7 @@ static int __nf_conncount_add(struct net *net,
     		nf_ct_put(found_ct);
     	}
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     add_new_node:
     	if (WARN_ON_ONCE(list->count > INT_MAX)) {
    @@ -277,6 +280,7 @@ void nf_conncount_list_init(struct nf_conncount_list *list)
     	spin_lock_init(&list->list_lock);
     	INIT_LIST_HEAD(&list->head);
     	list->count = 0;
    +	list->last_gc_count = 0;
     	list->last_gc = (u32)jiffies;
     }
     EXPORT_SYMBOL_GPL(nf_conncount_list_init);
    @@ -316,13 +320,14 @@ static bool __nf_conncount_gc_list(struct net *net,
     		}
     
     		nf_ct_put(found_ct);
    -		if (collected > CONNCOUNT_GC_MAX_NODES)
    +		if (collected > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     	}
     
     	if (!list->count)
     		ret = true;
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
6e5fa7add3e7

netfilter: nf_conncount: increase the connection clean up limit to 64

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.gitFernando Fernandez ManceraDec 17, 2025via nvd-ref
4 files changed · +22 12
  • include/net/netfilter/nf_conntrack_count.h+1 0 modified
    diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h
    index 52a06de41aa0f9..cf0166520cf338 100644
    --- a/include/net/netfilter/nf_conntrack_count.h
    +++ b/include/net/netfilter/nf_conntrack_count.h
    @@ -13,6 +13,7 @@ struct nf_conncount_list {
     	u32 last_gc;		/* jiffies at most recent gc */
     	struct list_head head;	/* connections with the same filtering key */
     	unsigned int count;	/* length of list */
    +	unsigned int last_gc_count; /* length of list at most recent gc */
     };
     
     struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int keylen);
    
  • include/net/netfilter/nf_conntrack_count.h+1 0 modified
    diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h
    index 52a06de41aa0f9..cf0166520cf338 100644
    --- a/include/net/netfilter/nf_conntrack_count.h
    +++ b/include/net/netfilter/nf_conntrack_count.h
    @@ -13,6 +13,7 @@ struct nf_conncount_list {
     	u32 last_gc;		/* jiffies at most recent gc */
     	struct list_head head;	/* connections with the same filtering key */
     	unsigned int count;	/* length of list */
    +	unsigned int last_gc_count; /* length of list at most recent gc */
     };
     
     struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int keylen);
    
  • net/netfilter/nf_conncount.c+10 6 modified
    diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
    index 8487808c87614f..288936f5c1bf92 100644
    --- a/net/netfilter/nf_conncount.c
    +++ b/net/netfilter/nf_conncount.c
    @@ -34,8 +34,9 @@
     
     #define CONNCOUNT_SLOTS		256U
     
    -#define CONNCOUNT_GC_MAX_NODES	8
    -#define MAX_KEYLEN		5
    +#define CONNCOUNT_GC_MAX_NODES		8
    +#define CONNCOUNT_GC_MAX_COLLECT	64
    +#define MAX_KEYLEN			5
     
     /* we will save the tuples of all connections we care about */
     struct nf_conncount_tuple {
    @@ -182,12 +183,13 @@ static int __nf_conncount_add(struct net *net,
     		goto out_put;
     	}
     
    -	if ((u32)jiffies == list->last_gc)
    +	if ((u32)jiffies == list->last_gc &&
    +	    (list->count - list->last_gc_count) < CONNCOUNT_GC_MAX_COLLECT)
     		goto add_new_node;
     
     	/* check the saved connections */
     	list_for_each_entry_safe(conn, conn_n, &list->head, node) {
    -		if (collect > CONNCOUNT_GC_MAX_NODES)
    +		if (collect > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     
     		found = find_or_evict(net, list, conn);
    @@ -230,6 +232,7 @@ static int __nf_conncount_add(struct net *net,
     		nf_ct_put(found_ct);
     	}
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     add_new_node:
     	if (WARN_ON_ONCE(list->count > INT_MAX)) {
    @@ -277,6 +280,7 @@ void nf_conncount_list_init(struct nf_conncount_list *list)
     	spin_lock_init(&list->list_lock);
     	INIT_LIST_HEAD(&list->head);
     	list->count = 0;
    +	list->last_gc_count = 0;
     	list->last_gc = (u32)jiffies;
     }
     EXPORT_SYMBOL_GPL(nf_conncount_list_init);
    @@ -316,13 +320,14 @@ static bool __nf_conncount_gc_list(struct net *net,
     		}
     
     		nf_ct_put(found_ct);
    -		if (collected > CONNCOUNT_GC_MAX_NODES)
    +		if (collected > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     	}
     
     	if (!list->count)
     		ret = true;
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
  • net/netfilter/nf_conncount.c+10 6 modified
    diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
    index 8487808c87614f..288936f5c1bf92 100644
    --- a/net/netfilter/nf_conncount.c
    +++ b/net/netfilter/nf_conncount.c
    @@ -34,8 +34,9 @@
     
     #define CONNCOUNT_SLOTS		256U
     
    -#define CONNCOUNT_GC_MAX_NODES	8
    -#define MAX_KEYLEN		5
    +#define CONNCOUNT_GC_MAX_NODES		8
    +#define CONNCOUNT_GC_MAX_COLLECT	64
    +#define MAX_KEYLEN			5
     
     /* we will save the tuples of all connections we care about */
     struct nf_conncount_tuple {
    @@ -182,12 +183,13 @@ static int __nf_conncount_add(struct net *net,
     		goto out_put;
     	}
     
    -	if ((u32)jiffies == list->last_gc)
    +	if ((u32)jiffies == list->last_gc &&
    +	    (list->count - list->last_gc_count) < CONNCOUNT_GC_MAX_COLLECT)
     		goto add_new_node;
     
     	/* check the saved connections */
     	list_for_each_entry_safe(conn, conn_n, &list->head, node) {
    -		if (collect > CONNCOUNT_GC_MAX_NODES)
    +		if (collect > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     
     		found = find_or_evict(net, list, conn);
    @@ -230,6 +232,7 @@ static int __nf_conncount_add(struct net *net,
     		nf_ct_put(found_ct);
     	}
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     add_new_node:
     	if (WARN_ON_ONCE(list->count > INT_MAX)) {
    @@ -277,6 +280,7 @@ void nf_conncount_list_init(struct nf_conncount_list *list)
     	spin_lock_init(&list->list_lock);
     	INIT_LIST_HEAD(&list->head);
     	list->count = 0;
    +	list->last_gc_count = 0;
     	list->last_gc = (u32)jiffies;
     }
     EXPORT_SYMBOL_GPL(nf_conncount_list_init);
    @@ -316,13 +320,14 @@ static bool __nf_conncount_gc_list(struct net *net,
     		}
     
     		nf_ct_put(found_ct);
    -		if (collected > CONNCOUNT_GC_MAX_NODES)
    +		if (collected > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     	}
     
     	if (!list->count)
     		ret = true;
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
a5c9e14e0e89

netfilter: nf_conncount: increase the connection clean up limit to 64

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.gitFernando Fernandez ManceraDec 17, 2025via nvd-ref
4 files changed · +22 12
  • include/net/netfilter/nf_conntrack_count.h+1 0 modified
    diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h
    index 115bb7e572f7d0..bf22661925b813 100644
    --- a/include/net/netfilter/nf_conntrack_count.h
    +++ b/include/net/netfilter/nf_conntrack_count.h
    @@ -13,6 +13,7 @@ struct nf_conncount_list {
     	u32 last_gc;		/* jiffies at most recent gc */
     	struct list_head head;	/* connections with the same filtering key */
     	unsigned int count;	/* length of list */
    +	unsigned int last_gc_count; /* length of list at most recent gc */
     };
     
     struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int family,
    
  • include/net/netfilter/nf_conntrack_count.h+1 0 modified
    diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h
    index 115bb7e572f7d0..bf22661925b813 100644
    --- a/include/net/netfilter/nf_conntrack_count.h
    +++ b/include/net/netfilter/nf_conntrack_count.h
    @@ -13,6 +13,7 @@ struct nf_conncount_list {
     	u32 last_gc;		/* jiffies at most recent gc */
     	struct list_head head;	/* connections with the same filtering key */
     	unsigned int count;	/* length of list */
    +	unsigned int last_gc_count; /* length of list at most recent gc */
     };
     
     struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int family,
    
  • net/netfilter/nf_conncount.c+10 6 modified
    diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
    index 70e9662fe17772..47bdd8d121bb57 100644
    --- a/net/netfilter/nf_conncount.c
    +++ b/net/netfilter/nf_conncount.c
    @@ -34,8 +34,9 @@
     
     #define CONNCOUNT_SLOTS		256U
     
    -#define CONNCOUNT_GC_MAX_NODES	8
    -#define MAX_KEYLEN		5
    +#define CONNCOUNT_GC_MAX_NODES		8
    +#define CONNCOUNT_GC_MAX_COLLECT	64
    +#define MAX_KEYLEN			5
     
     /* we will save the tuples of all connections we care about */
     struct nf_conncount_tuple {
    @@ -182,12 +183,13 @@ static int __nf_conncount_add(struct net *net,
     		goto out_put;
     	}
     
    -	if ((u32)jiffies == list->last_gc)
    +	if ((u32)jiffies == list->last_gc &&
    +	    (list->count - list->last_gc_count) < CONNCOUNT_GC_MAX_COLLECT)
     		goto add_new_node;
     
     	/* check the saved connections */
     	list_for_each_entry_safe(conn, conn_n, &list->head, node) {
    -		if (collect > CONNCOUNT_GC_MAX_NODES)
    +		if (collect > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     
     		found = find_or_evict(net, list, conn);
    @@ -230,6 +232,7 @@ static int __nf_conncount_add(struct net *net,
     		nf_ct_put(found_ct);
     	}
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     add_new_node:
     	if (WARN_ON_ONCE(list->count > INT_MAX)) {
    @@ -277,6 +280,7 @@ void nf_conncount_list_init(struct nf_conncount_list *list)
     	spin_lock_init(&list->list_lock);
     	INIT_LIST_HEAD(&list->head);
     	list->count = 0;
    +	list->last_gc_count = 0;
     	list->last_gc = (u32)jiffies;
     }
     EXPORT_SYMBOL_GPL(nf_conncount_list_init);
    @@ -316,13 +320,14 @@ static bool __nf_conncount_gc_list(struct net *net,
     		}
     
     		nf_ct_put(found_ct);
    -		if (collected > CONNCOUNT_GC_MAX_NODES)
    +		if (collected > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     	}
     
     	if (!list->count)
     		ret = true;
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
  • net/netfilter/nf_conncount.c+10 6 modified
    diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
    index 70e9662fe17772..47bdd8d121bb57 100644
    --- a/net/netfilter/nf_conncount.c
    +++ b/net/netfilter/nf_conncount.c
    @@ -34,8 +34,9 @@
     
     #define CONNCOUNT_SLOTS		256U
     
    -#define CONNCOUNT_GC_MAX_NODES	8
    -#define MAX_KEYLEN		5
    +#define CONNCOUNT_GC_MAX_NODES		8
    +#define CONNCOUNT_GC_MAX_COLLECT	64
    +#define MAX_KEYLEN			5
     
     /* we will save the tuples of all connections we care about */
     struct nf_conncount_tuple {
    @@ -182,12 +183,13 @@ static int __nf_conncount_add(struct net *net,
     		goto out_put;
     	}
     
    -	if ((u32)jiffies == list->last_gc)
    +	if ((u32)jiffies == list->last_gc &&
    +	    (list->count - list->last_gc_count) < CONNCOUNT_GC_MAX_COLLECT)
     		goto add_new_node;
     
     	/* check the saved connections */
     	list_for_each_entry_safe(conn, conn_n, &list->head, node) {
    -		if (collect > CONNCOUNT_GC_MAX_NODES)
    +		if (collect > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     
     		found = find_or_evict(net, list, conn);
    @@ -230,6 +232,7 @@ static int __nf_conncount_add(struct net *net,
     		nf_ct_put(found_ct);
     	}
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     add_new_node:
     	if (WARN_ON_ONCE(list->count > INT_MAX)) {
    @@ -277,6 +280,7 @@ void nf_conncount_list_init(struct nf_conncount_list *list)
     	spin_lock_init(&list->list_lock);
     	INIT_LIST_HEAD(&list->head);
     	list->count = 0;
    +	list->last_gc_count = 0;
     	list->last_gc = (u32)jiffies;
     }
     EXPORT_SYMBOL_GPL(nf_conncount_list_init);
    @@ -316,13 +320,14 @@ static bool __nf_conncount_gc_list(struct net *net,
     		}
     
     		nf_ct_put(found_ct);
    -		if (collected > CONNCOUNT_GC_MAX_NODES)
    +		if (collected > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     	}
     
     	if (!list->count)
     		ret = true;
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
fa85432d58c8

netfilter: nf_conncount: increase the connection clean up limit to 64

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.gitFernando Fernandez ManceraDec 17, 2025via nvd-ref
4 files changed · +22 12
  • include/net/netfilter/nf_conntrack_count.h+1 0 modified
    diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h
    index 115bb7e572f7d0..bf22661925b813 100644
    --- a/include/net/netfilter/nf_conntrack_count.h
    +++ b/include/net/netfilter/nf_conntrack_count.h
    @@ -13,6 +13,7 @@ struct nf_conncount_list {
     	u32 last_gc;		/* jiffies at most recent gc */
     	struct list_head head;	/* connections with the same filtering key */
     	unsigned int count;	/* length of list */
    +	unsigned int last_gc_count; /* length of list at most recent gc */
     };
     
     struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int family,
    
  • include/net/netfilter/nf_conntrack_count.h+1 0 modified
    diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h
    index 115bb7e572f7d0..bf22661925b813 100644
    --- a/include/net/netfilter/nf_conntrack_count.h
    +++ b/include/net/netfilter/nf_conntrack_count.h
    @@ -13,6 +13,7 @@ struct nf_conncount_list {
     	u32 last_gc;		/* jiffies at most recent gc */
     	struct list_head head;	/* connections with the same filtering key */
     	unsigned int count;	/* length of list */
    +	unsigned int last_gc_count; /* length of list at most recent gc */
     };
     
     struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int family,
    
  • net/netfilter/nf_conncount.c+10 6 modified
    diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
    index 70e9662fe17772..47bdd8d121bb57 100644
    --- a/net/netfilter/nf_conncount.c
    +++ b/net/netfilter/nf_conncount.c
    @@ -34,8 +34,9 @@
     
     #define CONNCOUNT_SLOTS		256U
     
    -#define CONNCOUNT_GC_MAX_NODES	8
    -#define MAX_KEYLEN		5
    +#define CONNCOUNT_GC_MAX_NODES		8
    +#define CONNCOUNT_GC_MAX_COLLECT	64
    +#define MAX_KEYLEN			5
     
     /* we will save the tuples of all connections we care about */
     struct nf_conncount_tuple {
    @@ -182,12 +183,13 @@ static int __nf_conncount_add(struct net *net,
     		goto out_put;
     	}
     
    -	if ((u32)jiffies == list->last_gc)
    +	if ((u32)jiffies == list->last_gc &&
    +	    (list->count - list->last_gc_count) < CONNCOUNT_GC_MAX_COLLECT)
     		goto add_new_node;
     
     	/* check the saved connections */
     	list_for_each_entry_safe(conn, conn_n, &list->head, node) {
    -		if (collect > CONNCOUNT_GC_MAX_NODES)
    +		if (collect > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     
     		found = find_or_evict(net, list, conn);
    @@ -230,6 +232,7 @@ static int __nf_conncount_add(struct net *net,
     		nf_ct_put(found_ct);
     	}
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     add_new_node:
     	if (WARN_ON_ONCE(list->count > INT_MAX)) {
    @@ -277,6 +280,7 @@ void nf_conncount_list_init(struct nf_conncount_list *list)
     	spin_lock_init(&list->list_lock);
     	INIT_LIST_HEAD(&list->head);
     	list->count = 0;
    +	list->last_gc_count = 0;
     	list->last_gc = (u32)jiffies;
     }
     EXPORT_SYMBOL_GPL(nf_conncount_list_init);
    @@ -316,13 +320,14 @@ static bool __nf_conncount_gc_list(struct net *net,
     		}
     
     		nf_ct_put(found_ct);
    -		if (collected > CONNCOUNT_GC_MAX_NODES)
    +		if (collected > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     	}
     
     	if (!list->count)
     		ret = true;
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
  • net/netfilter/nf_conncount.c+10 6 modified
    diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
    index 70e9662fe17772..47bdd8d121bb57 100644
    --- a/net/netfilter/nf_conncount.c
    +++ b/net/netfilter/nf_conncount.c
    @@ -34,8 +34,9 @@
     
     #define CONNCOUNT_SLOTS		256U
     
    -#define CONNCOUNT_GC_MAX_NODES	8
    -#define MAX_KEYLEN		5
    +#define CONNCOUNT_GC_MAX_NODES		8
    +#define CONNCOUNT_GC_MAX_COLLECT	64
    +#define MAX_KEYLEN			5
     
     /* we will save the tuples of all connections we care about */
     struct nf_conncount_tuple {
    @@ -182,12 +183,13 @@ static int __nf_conncount_add(struct net *net,
     		goto out_put;
     	}
     
    -	if ((u32)jiffies == list->last_gc)
    +	if ((u32)jiffies == list->last_gc &&
    +	    (list->count - list->last_gc_count) < CONNCOUNT_GC_MAX_COLLECT)
     		goto add_new_node;
     
     	/* check the saved connections */
     	list_for_each_entry_safe(conn, conn_n, &list->head, node) {
    -		if (collect > CONNCOUNT_GC_MAX_NODES)
    +		if (collect > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     
     		found = find_or_evict(net, list, conn);
    @@ -230,6 +232,7 @@ static int __nf_conncount_add(struct net *net,
     		nf_ct_put(found_ct);
     	}
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     add_new_node:
     	if (WARN_ON_ONCE(list->count > INT_MAX)) {
    @@ -277,6 +280,7 @@ void nf_conncount_list_init(struct nf_conncount_list *list)
     	spin_lock_init(&list->list_lock);
     	INIT_LIST_HEAD(&list->head);
     	list->count = 0;
    +	list->last_gc_count = 0;
     	list->last_gc = (u32)jiffies;
     }
     EXPORT_SYMBOL_GPL(nf_conncount_list_init);
    @@ -316,13 +320,14 @@ static bool __nf_conncount_gc_list(struct net *net,
     		}
     
     		nf_ct_put(found_ct);
    -		if (collected > CONNCOUNT_GC_MAX_NODES)
    +		if (collected > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     	}
     
     	if (!list->count)
     		ret = true;
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
0792ad077d77

netfilter: nf_conncount: increase the connection clean up limit to 64

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.gitFernando Fernandez ManceraDec 17, 2025via nvd-ref
4 files changed · +22 12
  • include/net/netfilter/nf_conntrack_count.h+1 0 modified
    diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h
    index 115bb7e572f7d0..bf22661925b813 100644
    --- a/include/net/netfilter/nf_conntrack_count.h
    +++ b/include/net/netfilter/nf_conntrack_count.h
    @@ -13,6 +13,7 @@ struct nf_conncount_list {
     	u32 last_gc;		/* jiffies at most recent gc */
     	struct list_head head;	/* connections with the same filtering key */
     	unsigned int count;	/* length of list */
    +	unsigned int last_gc_count; /* length of list at most recent gc */
     };
     
     struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int family,
    
  • include/net/netfilter/nf_conntrack_count.h+1 0 modified
    diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h
    index 115bb7e572f7d0..bf22661925b813 100644
    --- a/include/net/netfilter/nf_conntrack_count.h
    +++ b/include/net/netfilter/nf_conntrack_count.h
    @@ -13,6 +13,7 @@ struct nf_conncount_list {
     	u32 last_gc;		/* jiffies at most recent gc */
     	struct list_head head;	/* connections with the same filtering key */
     	unsigned int count;	/* length of list */
    +	unsigned int last_gc_count; /* length of list at most recent gc */
     };
     
     struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int family,
    
  • net/netfilter/nf_conncount.c+10 6 modified
    diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
    index 70e9662fe17772..47bdd8d121bb57 100644
    --- a/net/netfilter/nf_conncount.c
    +++ b/net/netfilter/nf_conncount.c
    @@ -34,8 +34,9 @@
     
     #define CONNCOUNT_SLOTS		256U
     
    -#define CONNCOUNT_GC_MAX_NODES	8
    -#define MAX_KEYLEN		5
    +#define CONNCOUNT_GC_MAX_NODES		8
    +#define CONNCOUNT_GC_MAX_COLLECT	64
    +#define MAX_KEYLEN			5
     
     /* we will save the tuples of all connections we care about */
     struct nf_conncount_tuple {
    @@ -182,12 +183,13 @@ static int __nf_conncount_add(struct net *net,
     		goto out_put;
     	}
     
    -	if ((u32)jiffies == list->last_gc)
    +	if ((u32)jiffies == list->last_gc &&
    +	    (list->count - list->last_gc_count) < CONNCOUNT_GC_MAX_COLLECT)
     		goto add_new_node;
     
     	/* check the saved connections */
     	list_for_each_entry_safe(conn, conn_n, &list->head, node) {
    -		if (collect > CONNCOUNT_GC_MAX_NODES)
    +		if (collect > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     
     		found = find_or_evict(net, list, conn);
    @@ -230,6 +232,7 @@ static int __nf_conncount_add(struct net *net,
     		nf_ct_put(found_ct);
     	}
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     add_new_node:
     	if (WARN_ON_ONCE(list->count > INT_MAX)) {
    @@ -277,6 +280,7 @@ void nf_conncount_list_init(struct nf_conncount_list *list)
     	spin_lock_init(&list->list_lock);
     	INIT_LIST_HEAD(&list->head);
     	list->count = 0;
    +	list->last_gc_count = 0;
     	list->last_gc = (u32)jiffies;
     }
     EXPORT_SYMBOL_GPL(nf_conncount_list_init);
    @@ -316,13 +320,14 @@ static bool __nf_conncount_gc_list(struct net *net,
     		}
     
     		nf_ct_put(found_ct);
    -		if (collected > CONNCOUNT_GC_MAX_NODES)
    +		if (collected > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     	}
     
     	if (!list->count)
     		ret = true;
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    
  • net/netfilter/nf_conncount.c+10 6 modified
    diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
    index 70e9662fe17772..47bdd8d121bb57 100644
    --- a/net/netfilter/nf_conncount.c
    +++ b/net/netfilter/nf_conncount.c
    @@ -34,8 +34,9 @@
     
     #define CONNCOUNT_SLOTS		256U
     
    -#define CONNCOUNT_GC_MAX_NODES	8
    -#define MAX_KEYLEN		5
    +#define CONNCOUNT_GC_MAX_NODES		8
    +#define CONNCOUNT_GC_MAX_COLLECT	64
    +#define MAX_KEYLEN			5
     
     /* we will save the tuples of all connections we care about */
     struct nf_conncount_tuple {
    @@ -182,12 +183,13 @@ static int __nf_conncount_add(struct net *net,
     		goto out_put;
     	}
     
    -	if ((u32)jiffies == list->last_gc)
    +	if ((u32)jiffies == list->last_gc &&
    +	    (list->count - list->last_gc_count) < CONNCOUNT_GC_MAX_COLLECT)
     		goto add_new_node;
     
     	/* check the saved connections */
     	list_for_each_entry_safe(conn, conn_n, &list->head, node) {
    -		if (collect > CONNCOUNT_GC_MAX_NODES)
    +		if (collect > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     
     		found = find_or_evict(net, list, conn);
    @@ -230,6 +232,7 @@ static int __nf_conncount_add(struct net *net,
     		nf_ct_put(found_ct);
     	}
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     add_new_node:
     	if (WARN_ON_ONCE(list->count > INT_MAX)) {
    @@ -277,6 +280,7 @@ void nf_conncount_list_init(struct nf_conncount_list *list)
     	spin_lock_init(&list->list_lock);
     	INIT_LIST_HEAD(&list->head);
     	list->count = 0;
    +	list->last_gc_count = 0;
     	list->last_gc = (u32)jiffies;
     }
     EXPORT_SYMBOL_GPL(nf_conncount_list_init);
    @@ -316,13 +320,14 @@ static bool __nf_conncount_gc_list(struct net *net,
     		}
     
     		nf_ct_put(found_ct);
    -		if (collected > CONNCOUNT_GC_MAX_NODES)
    +		if (collected > CONNCOUNT_GC_MAX_COLLECT)
     			break;
     	}
     
     	if (!list->count)
     		ret = true;
     	list->last_gc = (u32)jiffies;
    +	list->last_gc_count = list->count;
     
     	return ret;
     }
    -- 
    cgit 1.3-korg
    
    
    

Vulnerability mechanics

Root cause

"Insufficient garbage collection capacity and overly aggressive GC-skipping logic cause the connection count list to grow beyond the configured limit under high connection rates."

Attack vector

An attacker can send a high rate of new TCP connections (more than 8 per jiffy) to a system that has `nft_connlimit`, `xt_connlimit`, or OVS connection limiting configured [patch_id=2662001]. Because the garbage collector was limited to collecting only 8 nodes per GC pass and was skipped entirely if a GC had already run in the same jiffy, new connections accumulated faster than they could be cleaned up [patch_id=2662001]. This caused the connection count list to grow beyond the intended limit, potentially allowing an attacker to bypass the configured connection limit and exhaust kernel memory [patch_id=2662001].

Affected code

The vulnerability resides in `net/netfilter/nf_conncount.c` within the `__nf_conncount_add` and `__nf_conncount_gc_list` functions, and in the `struct nf_conncount_list` definition in `include/net/netfilter/nf_conntrack_count.h` [patch_id=2662001]. The GC skip logic in `__nf_conncount_add` used a hard limit of 8 (`CONNCOUNT_GC_MAX_NODES`) and unconditionally skipped GC when `(u32)jiffies == list->last_gc`, without tracking how many new connections had been added since the last GC [patch_id=2662001].

What the fix does

The patch introduces a new constant `CONNCOUNT_GC_MAX_COLLECT` set to 64, replacing the previous hard-coded limit of 8 for both the collection loop break condition and the GC-skip threshold [patch_id=2662001]. It adds a `last_gc_count` field to `struct nf_conncount_list` to record the list length at the time of the most recent GC [patch_id=2662001]. The GC-skip condition is changed from "if GC already ran this jiffy, skip entirely" to "if GC already ran this jiffy AND the number of new connections since then is less than 64, skip" [patch_id=2662001]. This ensures that when many new connections arrive in a single jiffy, GC still runs and can collect up to 64 stale entries, preventing the list from growing unbounded [patch_id=2662001].

Preconditions

  • configThe system must have nft_connlimit, xt_connlimit, or OVS connection limiting configured and active.
  • inputThe attacker must be able to establish new TCP connections at a rate exceeding 8 per jiffy.
  • authNo authentication is required; the attack is network-triggered against a reachable service.

Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

8

News mentions

0

No linked articles in our index yet.