[PATCH net 1/1] ipmr: restore a limit for unresolved cache entries

From: Zihan Xi

Date: Fri Aug 28 2026 - 02:56:17 EST


Unresolved multicast cache entries retain up to four received skbs while
waiting for userspace to install an MFC route. The cache entry count was
tracked but no longer bounded, so a stream of distinct source and group
pairs could retain packet memory until the system ran out of memory.

Restore the unresolved-entry limit for both IPv4 and IPv6 multicast
routing. Reject new cache entries once the limit is reached while keeping
existing entries available for normal route resolution.

Fixes: 0079ad8e8dc3 ("ipmr: remove hard code cache_resolve_queue_len limit")
Cc: stable@xxxxxxxxxxxxxxx
Reported-by: Vega <vega@xxxxxxxxxx>
Assisted-by: Codex:gpt-5.4
Signed-off-by: Zihan Xi <zihanx@xxxxxxxxxx>
---
include/linux/mroute_base.h | 3 +++
net/ipv4/ipmr.c | 6 ++++++
net/ipv6/ip6mr.c | 5 +++++
3 files changed, 14 insertions(+)

diff --git a/include/linux/mroute_base.h b/include/linux/mroute_base.h
index 4d55827e9705..af9247bb3f4d 100644
--- a/include/linux/mroute_base.h
+++ b/include/linux/mroute_base.h
@@ -224,6 +224,9 @@ struct mr_table_ops {
void *cmparg_any;
};

+/* Bound unresolved MFC entries and their queued skbs. */
+#define MFC_UNRES_QUEUE_LEN_MAX 10
+
/**
* struct mr_table - a multicast routing table
* @work: used for table destruction
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index e5f2b1c6150d..3155ad921ddc 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -1165,6 +1165,12 @@ static int ipmr_cache_unresolved(struct mr_table *mrt, vifi_t vifi,

if (!found) {
/* Create a new entry if allowable */
+ if (mrt->cache_resolve_queue_len >= MFC_UNRES_QUEUE_LEN_MAX) {
+ c = NULL;
+ err = -ENOBUFS;
+ goto err;
+ }
+
c = ipmr_cache_alloc_unres();
if (!c) {
err = -ENOBUFS;
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 3f2ed9b77deb..551b04d4fa7c 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -1207,6 +1207,11 @@ static int ip6mr_cache_unresolved(struct mr_table *mrt, mifi_t mifi,
/*
* Create a new entry if allowable
*/
+ if (mrt->cache_resolve_queue_len >= MFC_UNRES_QUEUE_LEN_MAX) {
+ c = NULL;
+ err = -ENOBUFS;
+ goto err;
+ }

c = ip6mr_cache_alloc_unres();
if (!c) {
--
2.43.0