B.A.T.M.A.N Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFC batadv 0/5] batman-adv: allow to specify limits for remote learned objects
@ 2026-05-16 12:35 Sven Eckelmann
  2026-05-16 12:35 ` [PATCH RFC batadv 1/5] batman-adv: limit numbers of parallel learned neighbors Sven Eckelmann
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Sven Eckelmann @ 2026-05-16 12:35 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Sven Eckelmann

There are some concerns that an external entity could spam the batman-adv
related interfaces with random mac addresses. The batman-adv would use more
and more resources to safe things like neighbors, originators, TT, ... and
would at some point run out of resources.

One idea is to limit the number of entries for each resource type could
have. Things which might need limits

* orig_node
* neigh_node
* tt_local_entry
* dat_entry
* bla_backbone_gw
* bla_claim

Things which are limited by other things (maybe)

* hardif_neigh_node
* gw_node
* orig_node_vlan
* orig_info

Unknown how to handle overly large tt_global_entries:

* tt_global_entry

This approach is also used for the bridge since commit bdb4dfda3b41 ("net:
bridge: Track and limit dynamically learned FDB entries"). And it is also
disabled by default.

For the moment, I just want to demonstrate how this might work with some
example code. I didn't invest any time to actually check out the other
items in the list. So, please consider these lists as vague suggestions.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
Sven Eckelmann (5):
      batman-adv: limit numbers of parallel learned neighbors
      batman-adv: limit numbers of parallel learned originators
      batman-adv: limit numbers of parallel learned DAT entries
      batman-adv: limit numbers of parallel learned BLA backbones
      batman-adv: limit numbers of parallel learned BLA claims

 include/uapi/linux/batman_adv.h        | 30 ++++++++++++++++++++
 net/batman-adv/bat_iv_ogm.c            | 13 ++++++++-
 net/batman-adv/bat_v_ogm.c             | 11 ++++++++
 net/batman-adv/bridge_loop_avoidance.c | 22 +++++++++++++++
 net/batman-adv/distributed-arp-table.c | 11 ++++++++
 net/batman-adv/mesh-interface.c        | 15 ++++++++++
 net/batman-adv/netlink.c               | 51 ++++++++++++++++++++++++++++++++++
 net/batman-adv/originator.c            | 14 ++++++++++
 net/batman-adv/types.h                 | 30 ++++++++++++++++++++
 9 files changed, 196 insertions(+), 1 deletion(-)
---
base-commit: 7700c90cbd12d04b8aabb62fe031ce6b31d6a4d9
change-id: 20260516-resource-limit-5c1a32898f7c

Best regards,
--  
Sven Eckelmann <sven@narfation.org>


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH RFC batadv 1/5] batman-adv: limit numbers of parallel learned neighbors
  2026-05-16 12:35 [PATCH RFC batadv 0/5] batman-adv: allow to specify limits for remote learned objects Sven Eckelmann
@ 2026-05-16 12:35 ` Sven Eckelmann
  2026-05-16 12:35 ` [PATCH RFC batadv 2/5] batman-adv: limit numbers of parallel learned originators Sven Eckelmann
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Sven Eckelmann @ 2026-05-16 12:35 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Sven Eckelmann

A malicious actor behind one bridge port may spam the kernel with OGMs with
a random source MAC address, each of which will create a neighbor node
entry, each of which is a dynamic allocation in the kernel. This will at
some point exhaust the available memory.

Mitigate this by maintaining a per meshif count of those automatically
generated entries in neigh_learned, and a limit in neigh_max_learned. If
the limit is hit new entries are not learned anymore.

For backwards compatibility, the default setting of 0 disables the limit.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
 include/uapi/linux/batman_adv.h |  6 ++++++
 net/batman-adv/mesh-interface.c |  3 +++
 net/batman-adv/netlink.c        | 11 +++++++++++
 net/batman-adv/originator.c     | 12 ++++++++++++
 net/batman-adv/types.h          |  6 ++++++
 5 files changed, 38 insertions(+)

diff --git a/include/uapi/linux/batman_adv.h b/include/uapi/linux/batman_adv.h
index 936bcac2..addb6092 100644
--- a/include/uapi/linux/batman_adv.h
+++ b/include/uapi/linux/batman_adv.h
@@ -481,6 +481,12 @@ enum batadv_nl_attrs {
 	 */
 	BATADV_ATTR_MULTICAST_FANOUT,
 
+	/**
+	 * @BATADV_ATTR_NEIGH_MAX_LEARNED: defines the maximum number of neighbors
+	 * which can be learned in parallel
+	 */
+	BATADV_ATTR_NEIGH_MAX_LEARNED,
+
 	/* add attributes above here, update the policy in netlink.c */
 
 	/**
diff --git a/net/batman-adv/mesh-interface.c b/net/batman-adv/mesh-interface.c
index 50c26037..b9302c58 100644
--- a/net/batman-adv/mesh-interface.c
+++ b/net/batman-adv/mesh-interface.c
@@ -790,6 +790,9 @@ static int batadv_meshif_init_late(struct net_device *dev)
 #endif
 	atomic_set(&bat_priv->tp_num, 0);
 
+	atomic_set(&bat_priv->neigh_learned, 0);
+	WRITE_ONCE(bat_priv->neigh_max_learned, 0);
+
 	WRITE_ONCE(bat_priv->tt.local_changes, 0);
 	bat_priv->tt.last_changeset = NULL;
 	bat_priv->tt.last_changeset_len = 0;
diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c
index e52f44e7..915a7d74 100644
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -13,6 +13,7 @@
 #include <linux/bug.h>
 #include <linux/byteorder/generic.h>
 #include <linux/cache.h>
+#include <linux/compiler.h>
 #include <linux/err.h>
 #include <linux/errno.h>
 #include <linux/gfp.h>
@@ -146,6 +147,7 @@ static const struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = {
 	[BATADV_ATTR_ORIG_INTERVAL]		= { .type = NLA_U32 },
 	[BATADV_ATTR_ELP_INTERVAL]		= { .type = NLA_U32 },
 	[BATADV_ATTR_THROUGHPUT_OVERRIDE]	= { .type = NLA_U32 },
+	[BATADV_ATTR_NEIGH_MAX_LEARNED]		= { .type = NLA_U32 },
 };
 
 /**
@@ -347,6 +349,10 @@ static int batadv_netlink_mesh_fill(struct sk_buff *msg,
 			atomic_read(&bat_priv->orig_interval)))
 		goto nla_put_failure;
 
+	if (nla_put_u32(msg, BATADV_ATTR_NEIGH_MAX_LEARNED,
+			READ_ONCE(bat_priv->neigh_max_learned)))
+		goto nla_put_failure;
+
 	batadv_hardif_put(primary_if);
 
 	genlmsg_end(msg, hdr);
@@ -592,6 +598,11 @@ static int batadv_netlink_set_mesh(struct sk_buff *skb, struct genl_info *info)
 		atomic_set(&bat_priv->orig_interval, orig_interval);
 	}
 
+	if (info->attrs[BATADV_ATTR_NEIGH_MAX_LEARNED]) {
+		WRITE_ONCE(bat_priv->neigh_max_learned,
+			   nla_get_u32(info->attrs[BATADV_ATTR_NEIGH_MAX_LEARNED]));
+	}
+
 	batadv_netlink_notify_mesh(bat_priv);
 
 	return 0;
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
index b3468cca..90f553fc 100644
--- a/net/batman-adv/originator.c
+++ b/net/batman-adv/originator.c
@@ -671,6 +671,8 @@ batadv_neigh_node_create(struct batadv_orig_node *orig_node,
 {
 	struct batadv_neigh_node *neigh_node;
 	struct batadv_hardif_neigh_node *hardif_neigh = NULL;
+	u32 neigh_max_learned;
+	int neigh_learned;
 
 	spin_lock_bh(&orig_node->neigh_list_lock);
 
@@ -678,6 +680,11 @@ batadv_neigh_node_create(struct batadv_orig_node *orig_node,
 	if (neigh_node)
 		goto out;
 
+	neigh_max_learned = READ_ONCE(orig_node->bat_priv->neigh_max_learned);
+	neigh_learned = atomic_read(&orig_node->bat_priv->neigh_learned);
+	if (neigh_max_learned && neigh_learned >= neigh_max_learned)
+		goto out;
+
 	hardif_neigh = batadv_hardif_neigh_get_or_create(hard_iface,
 							 neigh_addr, orig_node);
 	if (!hardif_neigh)
@@ -701,6 +708,8 @@ batadv_neigh_node_create(struct batadv_orig_node *orig_node,
 	kref_get(&hardif_neigh->refcount);
 	neigh_node->hardif_neigh = hardif_neigh;
 
+	atomic_inc(&orig_node->bat_priv->neigh_learned);
+
 	/* extra reference for return */
 	kref_init(&neigh_node->refcount);
 
@@ -866,6 +875,8 @@ void batadv_orig_node_release(struct kref *ref)
 				  &orig_node->neigh_list, list) {
 		hlist_del_rcu(&neigh_node->list);
 		batadv_neigh_node_put(neigh_node);
+
+		atomic_dec(&orig_node->bat_priv->neigh_learned);
 	}
 
 	hlist_for_each_entry_safe(orig_ifinfo, node_tmp,
@@ -1144,6 +1155,7 @@ batadv_purge_orig_neighbors(struct batadv_priv *bat_priv,
 
 			hlist_del_rcu(&neigh_node->list);
 			batadv_neigh_node_put(neigh_node);
+			atomic_dec(&bat_priv->neigh_learned);
 		} else {
 			/* only necessary if not the whole neighbor is to be
 			 * deleted, but some interface has been removed.
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index a76afc25..bad73d6b 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -1655,6 +1655,12 @@ struct batadv_priv {
 	/** @meshif_vlan_list_lock: lock protecting meshif_vlan_list */
 	spinlock_t meshif_vlan_list_lock;
 
+	/** @neigh_max_learned: Maximum number of neighbors */
+	u32 neigh_max_learned;
+
+	/** @neigh_learned: current number of learned neighbors */
+	atomic_t neigh_learned;
+
 #ifdef CONFIG_BATMAN_ADV_BLA
 	/** @bla: bridge loop avoidance data */
 	struct batadv_priv_bla bla;

-- 
2.47.3


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH RFC batadv 2/5] batman-adv: limit numbers of parallel learned originators
  2026-05-16 12:35 [PATCH RFC batadv 0/5] batman-adv: allow to specify limits for remote learned objects Sven Eckelmann
  2026-05-16 12:35 ` [PATCH RFC batadv 1/5] batman-adv: limit numbers of parallel learned neighbors Sven Eckelmann
@ 2026-05-16 12:35 ` Sven Eckelmann
  2026-05-16 12:35 ` [PATCH RFC batadv 3/5] batman-adv: limit numbers of parallel learned DAT entries Sven Eckelmann
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Sven Eckelmann @ 2026-05-16 12:35 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Sven Eckelmann

A malicious actor behind one bridge port may spam the kernel with OGMs with
a random source MAC address, each of which will create an originator node
entry, each of which is a dynamic allocation in the kernel. This will at
some point exhaust the available memory.

Mitigate this by maintaining a per meshif count of those automatically
generated entries in orig_learned, and a limit in orig_max_learned. If the
limit is hit new entries are not learned anymore.

For backwards compatibility, the default setting of 0 disables the limit.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
 include/uapi/linux/batman_adv.h |  6 ++++++
 net/batman-adv/bat_iv_ogm.c     | 13 ++++++++++++-
 net/batman-adv/bat_v_ogm.c      | 11 +++++++++++
 net/batman-adv/mesh-interface.c |  3 +++
 net/batman-adv/netlink.c        | 10 ++++++++++
 net/batman-adv/originator.c     |  2 ++
 net/batman-adv/types.h          |  6 ++++++
 7 files changed, 50 insertions(+), 1 deletion(-)

diff --git a/include/uapi/linux/batman_adv.h b/include/uapi/linux/batman_adv.h
index addb6092..b3c04ab0 100644
--- a/include/uapi/linux/batman_adv.h
+++ b/include/uapi/linux/batman_adv.h
@@ -487,6 +487,12 @@ enum batadv_nl_attrs {
 	 */
 	BATADV_ATTR_NEIGH_MAX_LEARNED,
 
+	/**
+	 * @BATADV_ATTR_ORIG_MAX_LEARNED: defines the maximum number of originator
+	 * which can be learned in parallel
+	 */
+	BATADV_ATTR_ORIG_MAX_LEARNED,
+
 	/* add attributes above here, update the policy in netlink.c */
 
 	/**
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
index 74ef7dc2..cc289f55 100644
--- a/net/batman-adv/bat_iv_ogm.c
+++ b/net/batman-adv/bat_iv_ogm.c
@@ -13,6 +13,7 @@
 #include <linux/bug.h>
 #include <linux/byteorder/generic.h>
 #include <linux/cache.h>
+#include <linux/compiler.h>
 #include <linux/container_of.h>
 #include <linux/errno.h>
 #include <linux/etherdevice.h>
@@ -140,24 +141,34 @@ static struct batadv_orig_node *
 batadv_iv_ogm_orig_get(struct batadv_priv *bat_priv, const u8 *addr)
 {
 	struct batadv_orig_node *orig_node;
+	u32 orig_max_learned;
+	int orig_learned;
 	int hash_added;
 
 	orig_node = batadv_orig_hash_find(bat_priv, addr);
 	if (orig_node)
 		return orig_node;
 
+	orig_max_learned = READ_ONCE(bat_priv->orig_max_learned);
+	orig_learned = atomic_read(&bat_priv->orig_learned);
+	if (orig_max_learned && orig_learned >= orig_max_learned)
+		return NULL;
+
 	orig_node = batadv_orig_node_new(bat_priv, addr);
 	if (!orig_node)
 		return NULL;
 
 	spin_lock_init(&orig_node->bat_iv.ogm_cnt_lock);
+	atomic_inc(&bat_priv->orig_learned);
 
 	kref_get(&orig_node->refcount);
 	hash_added = batadv_hash_add(bat_priv->orig_hash, batadv_compare_orig,
 				     batadv_choose_orig, orig_node,
 				     &orig_node->hash_entry);
-	if (hash_added != 0)
+	if (hash_added != 0) {
+		atomic_dec(&bat_priv->orig_learned);
 		goto free_orig_node_hash;
+	}
 
 	return orig_node;
 
diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c
index 9914346a..7a803fcc 100644
--- a/net/batman-adv/bat_v_ogm.c
+++ b/net/batman-adv/bat_v_ogm.c
@@ -10,6 +10,7 @@
 #include <linux/atomic.h>
 #include <linux/bug.h>
 #include <linux/byteorder/generic.h>
+#include <linux/compiler.h>
 #include <linux/container_of.h>
 #include <linux/errno.h>
 #include <linux/etherdevice.h>
@@ -55,16 +56,25 @@ struct batadv_orig_node *batadv_v_ogm_orig_get(struct batadv_priv *bat_priv,
 					       const u8 *addr)
 {
 	struct batadv_orig_node *orig_node;
+	u32 orig_max_learned;
+	int orig_learned;
 	int hash_added;
 
 	orig_node = batadv_orig_hash_find(bat_priv, addr);
 	if (orig_node)
 		return orig_node;
 
+	orig_max_learned = READ_ONCE(bat_priv->orig_max_learned);
+	orig_learned = atomic_read(&bat_priv->orig_learned);
+	if (orig_max_learned && orig_learned >= orig_max_learned)
+		return NULL;
+
 	orig_node = batadv_orig_node_new(bat_priv, addr);
 	if (!orig_node)
 		return NULL;
 
+	atomic_inc(&bat_priv->orig_learned);
+
 	kref_get(&orig_node->refcount);
 	hash_added = batadv_hash_add(bat_priv->orig_hash, batadv_compare_orig,
 				     batadv_choose_orig, orig_node,
@@ -74,6 +84,7 @@ struct batadv_orig_node *batadv_v_ogm_orig_get(struct batadv_priv *bat_priv,
 		batadv_orig_node_put(orig_node);
 		batadv_orig_node_put(orig_node);
 		orig_node = NULL;
+		atomic_dec(&bat_priv->orig_learned);
 	}
 
 	return orig_node;
diff --git a/net/batman-adv/mesh-interface.c b/net/batman-adv/mesh-interface.c
index b9302c58..fad788cc 100644
--- a/net/batman-adv/mesh-interface.c
+++ b/net/batman-adv/mesh-interface.c
@@ -793,6 +793,9 @@ static int batadv_meshif_init_late(struct net_device *dev)
 	atomic_set(&bat_priv->neigh_learned, 0);
 	WRITE_ONCE(bat_priv->neigh_max_learned, 0);
 
+	atomic_set(&bat_priv->orig_learned, 0);
+	WRITE_ONCE(bat_priv->orig_max_learned, 0);
+
 	WRITE_ONCE(bat_priv->tt.local_changes, 0);
 	bat_priv->tt.last_changeset = NULL;
 	bat_priv->tt.last_changeset_len = 0;
diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c
index 915a7d74..2b5fb1d6 100644
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -148,6 +148,7 @@ static const struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = {
 	[BATADV_ATTR_ELP_INTERVAL]		= { .type = NLA_U32 },
 	[BATADV_ATTR_THROUGHPUT_OVERRIDE]	= { .type = NLA_U32 },
 	[BATADV_ATTR_NEIGH_MAX_LEARNED]		= { .type = NLA_U32 },
+	[BATADV_ATTR_ORIG_MAX_LEARNED]		= { .type = NLA_U32 },
 };
 
 /**
@@ -353,6 +354,10 @@ static int batadv_netlink_mesh_fill(struct sk_buff *msg,
 			READ_ONCE(bat_priv->neigh_max_learned)))
 		goto nla_put_failure;
 
+	if (nla_put_u32(msg, BATADV_ATTR_ORIG_MAX_LEARNED,
+			READ_ONCE(bat_priv->orig_max_learned)))
+		goto nla_put_failure;
+
 	batadv_hardif_put(primary_if);
 
 	genlmsg_end(msg, hdr);
@@ -603,6 +608,11 @@ static int batadv_netlink_set_mesh(struct sk_buff *skb, struct genl_info *info)
 			   nla_get_u32(info->attrs[BATADV_ATTR_NEIGH_MAX_LEARNED]));
 	}
 
+	if (info->attrs[BATADV_ATTR_ORIG_MAX_LEARNED]) {
+		WRITE_ONCE(bat_priv->orig_max_learned,
+			   nla_get_u32(info->attrs[BATADV_ATTR_ORIG_MAX_LEARNED]));
+	}
+
 	batadv_netlink_notify_mesh(bat_priv);
 
 	return 0;
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
index 90f553fc..3c48e006 100644
--- a/net/batman-adv/originator.c
+++ b/net/batman-adv/originator.c
@@ -930,6 +930,7 @@ void batadv_originator_free(struct batadv_priv *bat_priv)
 					  head, hash_entry) {
 			hlist_del_rcu(&orig_node->hash_entry);
 			batadv_orig_node_put(orig_node);
+			atomic_dec(&bat_priv->orig_learned);
 		}
 		spin_unlock_bh(list_lock);
 	}
@@ -1297,6 +1298,7 @@ void batadv_purge_orig_ref(struct batadv_priv *bat_priv)
 							  orig_node, -1,
 							  "originator timed out");
 				batadv_orig_node_put(orig_node);
+				atomic_dec(&bat_priv->orig_learned);
 				continue;
 			}
 
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index bad73d6b..75a85f08 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -1661,6 +1661,12 @@ struct batadv_priv {
 	/** @neigh_learned: current number of learned neighbors */
 	atomic_t neigh_learned;
 
+	/** @orig_max_learned: Maximum number of originators */
+	u32 orig_max_learned;
+
+	/** @orig_learned: current number of learned originators */
+	atomic_t orig_learned;
+
 #ifdef CONFIG_BATMAN_ADV_BLA
 	/** @bla: bridge loop avoidance data */
 	struct batadv_priv_bla bla;

-- 
2.47.3


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH RFC batadv 3/5] batman-adv: limit numbers of parallel learned DAT entries
  2026-05-16 12:35 [PATCH RFC batadv 0/5] batman-adv: allow to specify limits for remote learned objects Sven Eckelmann
  2026-05-16 12:35 ` [PATCH RFC batadv 1/5] batman-adv: limit numbers of parallel learned neighbors Sven Eckelmann
  2026-05-16 12:35 ` [PATCH RFC batadv 2/5] batman-adv: limit numbers of parallel learned originators Sven Eckelmann
@ 2026-05-16 12:35 ` Sven Eckelmann
  2026-05-16 12:35 ` [PATCH RFC batadv 4/5] batman-adv: limit numbers of parallel learned BLA backbones Sven Eckelmann
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Sven Eckelmann @ 2026-05-16 12:35 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Sven Eckelmann

A malicious actor behind one bridge port may spam the kernel with OGMs with
a random source MAC address, each of which will create a DAT entry, each of
which is a dynamic allocation in the kernel. This will at some point
exhaust the available memory.

Mitigate this by maintaining a per meshif count of those automatically
generated entries in orig_learned, and a limit in orig_max_learned. If the
limit is hit new entries are not learned anymore.

For backwards compatibility, the default setting of 0 disables the limit.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
 include/uapi/linux/batman_adv.h        |  6 ++++++
 net/batman-adv/distributed-arp-table.c | 11 +++++++++++
 net/batman-adv/mesh-interface.c        |  3 +++
 net/batman-adv/netlink.c               | 10 ++++++++++
 net/batman-adv/types.h                 |  6 ++++++
 5 files changed, 36 insertions(+)

diff --git a/include/uapi/linux/batman_adv.h b/include/uapi/linux/batman_adv.h
index b3c04ab0..cca87d42 100644
--- a/include/uapi/linux/batman_adv.h
+++ b/include/uapi/linux/batman_adv.h
@@ -493,6 +493,12 @@ enum batadv_nl_attrs {
 	 */
 	BATADV_ATTR_ORIG_MAX_LEARNED,
 
+	/**
+	 * @BATADV_ATTR_DAT_MAX_LEARNED: defines the maximum number of DAT entries
+	 * which can be learned in parallel
+	 */
+	BATADV_ATTR_DAT_MAX_LEARNED,
+
 	/* add attributes above here, update the policy in netlink.c */
 
 	/**
diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c
index 0a8bd95e..99569a2f 100644
--- a/net/batman-adv/distributed-arp-table.c
+++ b/net/batman-adv/distributed-arp-table.c
@@ -181,6 +181,7 @@ static void __batadv_dat_purge(struct batadv_priv *bat_priv,
 
 			hlist_del_rcu(&dat_entry->hash_entry);
 			batadv_dat_entry_put(dat_entry);
+			atomic_dec(&bat_priv->dat_learned);
 		}
 		spin_unlock_bh(list_lock);
 	}
@@ -366,6 +367,8 @@ static void batadv_dat_entry_add(struct batadv_priv *bat_priv, __be32 ip,
 				 u8 *mac_addr, unsigned short vid)
 {
 	struct batadv_dat_entry *dat_entry;
+	u32 dat_max_learned;
+	int dat_learned;
 	int hash_added;
 
 	dat_entry = batadv_dat_entry_hash_find(bat_priv, ip, vid);
@@ -381,6 +384,11 @@ static void batadv_dat_entry_add(struct batadv_priv *bat_priv, __be32 ip,
 		goto out;
 	}
 
+	dat_max_learned = READ_ONCE(bat_priv->dat_max_learned);
+	dat_learned = atomic_read(&bat_priv->dat_learned);
+	if (dat_max_learned && dat_learned >= dat_max_learned)
+		goto out;
+
 	dat_entry = kmalloc_obj(*dat_entry, GFP_ATOMIC);
 	if (!dat_entry)
 		goto out;
@@ -391,6 +399,8 @@ static void batadv_dat_entry_add(struct batadv_priv *bat_priv, __be32 ip,
 	dat_entry->last_update = jiffies;
 	kref_init(&dat_entry->refcount);
 
+	atomic_inc(&bat_priv->dat_learned);
+
 	kref_get(&dat_entry->refcount);
 	hash_added = batadv_hash_add(bat_priv->dat.hash, batadv_compare_dat,
 				     batadv_hash_dat, dat_entry,
@@ -399,6 +409,7 @@ static void batadv_dat_entry_add(struct batadv_priv *bat_priv, __be32 ip,
 	if (unlikely(hash_added != 0)) {
 		/* remove the reference for the hash */
 		batadv_dat_entry_put(dat_entry);
+		atomic_dec(&bat_priv->dat_learned);
 		goto out;
 	}
 
diff --git a/net/batman-adv/mesh-interface.c b/net/batman-adv/mesh-interface.c
index fad788cc..851a078d 100644
--- a/net/batman-adv/mesh-interface.c
+++ b/net/batman-adv/mesh-interface.c
@@ -759,6 +759,9 @@ static int batadv_meshif_init_late(struct net_device *dev)
 #endif
 #ifdef CONFIG_BATMAN_ADV_DAT
 	atomic_set(&bat_priv->distributed_arp_table, 1);
+
+	atomic_set(&bat_priv->dat_learned, 0);
+	WRITE_ONCE(bat_priv->dat_max_learned, 0);
 #endif
 #ifdef CONFIG_BATMAN_ADV_MCAST
 	atomic_set(&bat_priv->multicast_mode, 1);
diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c
index 2b5fb1d6..742b1e3e 100644
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -149,6 +149,7 @@ static const struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = {
 	[BATADV_ATTR_THROUGHPUT_OVERRIDE]	= { .type = NLA_U32 },
 	[BATADV_ATTR_NEIGH_MAX_LEARNED]		= { .type = NLA_U32 },
 	[BATADV_ATTR_ORIG_MAX_LEARNED]		= { .type = NLA_U32 },
+	[BATADV_ATTR_DAT_MAX_LEARNED]		= { .type = NLA_U32 },
 };
 
 /**
@@ -298,6 +299,10 @@ static int batadv_netlink_mesh_fill(struct sk_buff *msg,
 	if (nla_put_u8(msg, BATADV_ATTR_DISTRIBUTED_ARP_TABLE_ENABLED,
 		       !!atomic_read(&bat_priv->distributed_arp_table)))
 		goto nla_put_failure;
+
+	if (nla_put_u32(msg, BATADV_ATTR_DAT_MAX_LEARNED,
+			READ_ONCE(bat_priv->dat_max_learned)))
+		goto nla_put_failure;
 #endif /* CONFIG_BATMAN_ADV_DAT */
 
 	if (nla_put_u8(msg, BATADV_ATTR_FRAGMENTATION_ENABLED,
@@ -488,6 +493,11 @@ static int batadv_netlink_set_mesh(struct sk_buff *skb, struct genl_info *info)
 			   !!nla_get_u8(attr));
 		batadv_dat_status_update(bat_priv->mesh_iface);
 	}
+
+	if (info->attrs[BATADV_ATTR_DAT_MAX_LEARNED]) {
+		WRITE_ONCE(bat_priv->dat_max_learned,
+			   nla_get_u32(info->attrs[BATADV_ATTR_DAT_MAX_LEARNED]));
+	}
 #endif /* CONFIG_BATMAN_ADV_DAT */
 
 	if (info->attrs[BATADV_ATTR_FRAGMENTATION_ENABLED]) {
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 75a85f08..32d396dc 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -1553,6 +1553,12 @@ struct batadv_priv {
 	 *  is enabled
 	 */
 	atomic_t distributed_arp_table;
+
+	/** @dat_max_learned: Maximum number of DAT entries */
+	u32 dat_max_learned;
+
+	/** @dat_learned: current number of learned DAT entries */
+	atomic_t dat_learned;
 #endif
 
 #ifdef CONFIG_BATMAN_ADV_MCAST

-- 
2.47.3


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH RFC batadv 4/5] batman-adv: limit numbers of parallel learned BLA backbones
  2026-05-16 12:35 [PATCH RFC batadv 0/5] batman-adv: allow to specify limits for remote learned objects Sven Eckelmann
                   ` (2 preceding siblings ...)
  2026-05-16 12:35 ` [PATCH RFC batadv 3/5] batman-adv: limit numbers of parallel learned DAT entries Sven Eckelmann
@ 2026-05-16 12:35 ` Sven Eckelmann
  2026-05-16 12:35 ` [PATCH RFC batadv 5/5] batman-adv: limit numbers of parallel learned BLA claims Sven Eckelmann
  2026-05-17 17:43 ` [PATCH RFC batadv 0/5] batman-adv: allow to specify limits for remote learned objects Linus Lüssing
  5 siblings, 0 replies; 7+ messages in thread
From: Sven Eckelmann @ 2026-05-16 12:35 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Sven Eckelmann

A malicious actor behind one bridge port may spam the kernel with OGMs with
a random source MAC address, each of which will create a BLA backbone, each
of which is a dynamic allocation in the kernel. This will at some point
exhaust the available memory.

Mitigate this by maintaining a per meshif count of those automatically
generated entries in orig_learned, and a limit in orig_max_learned. If the
limit is hit new entries are not learned anymore.

For backwards compatibility, the default setting of 0 disables the limit.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
 include/uapi/linux/batman_adv.h        |  6 ++++++
 net/batman-adv/bridge_loop_avoidance.c | 11 +++++++++++
 net/batman-adv/mesh-interface.c        |  3 +++
 net/batman-adv/netlink.c               | 10 ++++++++++
 net/batman-adv/types.h                 |  6 ++++++
 5 files changed, 36 insertions(+)

diff --git a/include/uapi/linux/batman_adv.h b/include/uapi/linux/batman_adv.h
index cca87d42..4188d83c 100644
--- a/include/uapi/linux/batman_adv.h
+++ b/include/uapi/linux/batman_adv.h
@@ -499,6 +499,12 @@ enum batadv_nl_attrs {
 	 */
 	BATADV_ATTR_DAT_MAX_LEARNED,
 
+	/**
+	 * @BATADV_ATTR_BLA_BACKBONE_MAX_LEARNED: defines the maximum number of BLA backbone
+	 * which can be learned in parallel
+	 */
+	BATADV_ATTR_BLA_BACKBONE_MAX_LEARNED,
+
 	/* add attributes above here, update the policy in netlink.c */
 
 	/**
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c
index cec11f12..8bb8dec6 100644
--- a/net/batman-adv/bridge_loop_avoidance.c
+++ b/net/batman-adv/bridge_loop_avoidance.c
@@ -494,6 +494,8 @@ batadv_bla_get_backbone_gw(struct batadv_priv *bat_priv, const u8 *orig,
 {
 	struct batadv_bla_backbone_gw *entry;
 	struct batadv_orig_node *orig_node;
+	u32 bla_backbone_max_learned;
+	int bla_backbone_learned;
 	int hash_added;
 
 	entry = batadv_backbone_hash_find(bat_priv, orig, vid);
@@ -505,6 +507,11 @@ batadv_bla_get_backbone_gw(struct batadv_priv *bat_priv, const u8 *orig,
 		   "%s(): not found (%pM, %d), creating new entry\n", __func__,
 		   orig, batadv_print_vid(vid));
 
+	bla_backbone_max_learned = READ_ONCE(bat_priv->bla_backbone_max_learned);
+	bla_backbone_learned = atomic_read(&bat_priv->bla_backbone_learned);
+	if (bla_backbone_max_learned && bla_backbone_learned >= bla_backbone_max_learned)
+		return NULL;
+
 	entry = kzalloc_obj(*entry, GFP_ATOMIC);
 	if (!entry)
 		return NULL;
@@ -520,6 +527,8 @@ batadv_bla_get_backbone_gw(struct batadv_priv *bat_priv, const u8 *orig,
 	INIT_WORK(&entry->report_work, batadv_bla_loopdetect_report);
 	kref_init(&entry->refcount);
 
+	atomic_inc(&bat_priv->bla_backbone_learned);
+
 	kref_get(&entry->refcount);
 	hash_added = batadv_hash_add(bat_priv->bla.backbone_hash,
 				     batadv_compare_backbone_gw,
@@ -529,6 +538,7 @@ batadv_bla_get_backbone_gw(struct batadv_priv *bat_priv, const u8 *orig,
 	if (unlikely(hash_added != 0)) {
 		/* hash failed, free the structure */
 		kfree(entry);
+		atomic_dec(&bat_priv->bla_backbone_learned);
 		return NULL;
 	}
 
@@ -1256,6 +1266,7 @@ static void batadv_bla_purge_backbone_gw(struct batadv_priv *bat_priv, int now)
 
 			hlist_del_rcu(&backbone_gw->hash_entry);
 			batadv_backbone_gw_put(backbone_gw);
+			atomic_dec(&bat_priv->bla_backbone_learned);
 		}
 		spin_unlock_bh(list_lock);
 	}
diff --git a/net/batman-adv/mesh-interface.c b/net/batman-adv/mesh-interface.c
index 851a078d..1594a2d6 100644
--- a/net/batman-adv/mesh-interface.c
+++ b/net/batman-adv/mesh-interface.c
@@ -790,6 +790,9 @@ static int batadv_meshif_init_late(struct net_device *dev)
 	atomic_set(&bat_priv->tt.ogm_append_cnt, 0);
 #ifdef CONFIG_BATMAN_ADV_BLA
 	atomic_set(&bat_priv->bla.num_requests, 0);
+
+	atomic_set(&bat_priv->bla_backbone_learned, 0);
+	WRITE_ONCE(bat_priv->bla_backbone_max_learned, 0);
 #endif
 	atomic_set(&bat_priv->tp_num, 0);
 
diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c
index 742b1e3e..5d4bccdc 100644
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -150,6 +150,7 @@ static const struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = {
 	[BATADV_ATTR_NEIGH_MAX_LEARNED]		= { .type = NLA_U32 },
 	[BATADV_ATTR_ORIG_MAX_LEARNED]		= { .type = NLA_U32 },
 	[BATADV_ATTR_DAT_MAX_LEARNED]		= { .type = NLA_U32 },
+	[BATADV_ATTR_BLA_BACKBONE_MAX_LEARNED]	= { .type = NLA_U32 },
 };
 
 /**
@@ -293,6 +294,10 @@ static int batadv_netlink_mesh_fill(struct sk_buff *msg,
 	if (nla_put_u8(msg, BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE_ENABLED,
 		       !!atomic_read(&bat_priv->bridge_loop_avoidance)))
 		goto nla_put_failure;
+
+	if (nla_put_u32(msg, BATADV_ATTR_BLA_BACKBONE_MAX_LEARNED,
+			READ_ONCE(bat_priv->bla_backbone_max_learned)))
+		goto nla_put_failure;
 #endif /* CONFIG_BATMAN_ADV_BLA */
 
 #ifdef CONFIG_BATMAN_ADV_DAT
@@ -483,6 +488,11 @@ static int batadv_netlink_set_mesh(struct sk_buff *skb, struct genl_info *info)
 			   !!nla_get_u8(attr));
 		batadv_bla_status_update(bat_priv->mesh_iface);
 	}
+
+	if (info->attrs[BATADV_ATTR_BLA_BACKBONE_MAX_LEARNED]) {
+		WRITE_ONCE(bat_priv->bla_backbone_max_learned,
+			   nla_get_u32(info->attrs[BATADV_ATTR_BLA_BACKBONE_MAX_LEARNED]));
+	}
 #endif /* CONFIG_BATMAN_ADV_BLA */
 
 #ifdef CONFIG_BATMAN_ADV_DAT
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 32d396dc..c8976da5 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -1674,6 +1674,12 @@ struct batadv_priv {
 	atomic_t orig_learned;
 
 #ifdef CONFIG_BATMAN_ADV_BLA
+	/** @bla_backbone_max_learned: Maximum number of backbone_gw */
+	u32 bla_backbone_max_learned;
+
+	/** @bla_backbone_learned: current number of learned backbone_gw entries */
+	atomic_t bla_backbone_learned;
+
 	/** @bla: bridge loop avoidance data */
 	struct batadv_priv_bla bla;
 #endif

-- 
2.47.3


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH RFC batadv 5/5] batman-adv: limit numbers of parallel learned BLA claims
  2026-05-16 12:35 [PATCH RFC batadv 0/5] batman-adv: allow to specify limits for remote learned objects Sven Eckelmann
                   ` (3 preceding siblings ...)
  2026-05-16 12:35 ` [PATCH RFC batadv 4/5] batman-adv: limit numbers of parallel learned BLA backbones Sven Eckelmann
@ 2026-05-16 12:35 ` Sven Eckelmann
  2026-05-17 17:43 ` [PATCH RFC batadv 0/5] batman-adv: allow to specify limits for remote learned objects Linus Lüssing
  5 siblings, 0 replies; 7+ messages in thread
From: Sven Eckelmann @ 2026-05-16 12:35 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Sven Eckelmann

A malicious actor behind one bridge port may spam the kernel with OGMs with
a random source MAC address, each of which will create a BLA claim, each of
which is a dynamic allocation in the kernel. This will at some point
exhaust the available memory.

Mitigate this by maintaining a per meshif count of those automatically
generated entries in orig_learned, and a limit in orig_max_learned. If the
limit is hit new entries are not learned anymore.

For backwards compatibility, the default setting of 0 disables the limit.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
 include/uapi/linux/batman_adv.h        |  6 ++++++
 net/batman-adv/bridge_loop_avoidance.c | 11 +++++++++++
 net/batman-adv/mesh-interface.c        |  3 +++
 net/batman-adv/netlink.c               | 10 ++++++++++
 net/batman-adv/types.h                 |  6 ++++++
 5 files changed, 36 insertions(+)

diff --git a/include/uapi/linux/batman_adv.h b/include/uapi/linux/batman_adv.h
index 4188d83c..65d1c0eb 100644
--- a/include/uapi/linux/batman_adv.h
+++ b/include/uapi/linux/batman_adv.h
@@ -505,6 +505,12 @@ enum batadv_nl_attrs {
 	 */
 	BATADV_ATTR_BLA_BACKBONE_MAX_LEARNED,
 
+	/**
+	 * @BATADV_ATTR_BLA_CLAIM_MAX_LEARNED: defines the maximum number of BLA claim
+	 * which can be learned in parallel
+	 */
+	BATADV_ATTR_BLA_CLAIM_MAX_LEARNED,
+
 	/* add attributes above here, update the policy in netlink.c */
 
 	/**
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c
index 8bb8dec6..f39b02f9 100644
--- a/net/batman-adv/bridge_loop_avoidance.c
+++ b/net/batman-adv/bridge_loop_avoidance.c
@@ -320,6 +320,7 @@ batadv_bla_del_backbone_claims(struct batadv_bla_backbone_gw *backbone_gw)
 
 			hlist_del_rcu(&claim->hash_entry);
 			batadv_claim_put(claim);
+			atomic_dec(&backbone_gw->bat_priv->bla_claim_learned);
 		}
 		spin_unlock_bh(list_lock);
 	}
@@ -700,7 +701,9 @@ static void batadv_bla_add_claim(struct batadv_priv *bat_priv,
 	struct batadv_bla_backbone_gw *old_backbone_gw;
 	struct batadv_bla_claim *claim;
 	struct batadv_bla_claim search_claim;
+	u32 bla_claim_max_learned;
 	bool remove_crc = false;
+	int bla_claim_learned;
 	int hash_added;
 
 	ether_addr_copy(search_claim.addr, mac);
@@ -709,6 +712,11 @@ static void batadv_bla_add_claim(struct batadv_priv *bat_priv,
 
 	/* create a new claim entry if it does not exist yet. */
 	if (!claim) {
+		bla_claim_max_learned = READ_ONCE(bat_priv->bla_claim_max_learned);
+		bla_claim_learned = atomic_read(&bat_priv->bla_claim_learned);
+		if (bla_claim_max_learned && bla_claim_learned >= bla_claim_max_learned)
+			return;
+
 		claim = kzalloc_obj(*claim, GFP_ATOMIC);
 		if (!claim)
 			return;
@@ -721,6 +729,8 @@ static void batadv_bla_add_claim(struct batadv_priv *bat_priv,
 		claim->backbone_gw = backbone_gw;
 		kref_init(&claim->refcount);
 
+		atomic_inc(&bat_priv->bla_claim_learned);
+
 		batadv_dbg(BATADV_DBG_BLA, bat_priv,
 			   "%s(): adding new entry %pM, vid %d to hash ...\n",
 			   __func__, mac, batadv_print_vid(vid));
@@ -735,6 +745,7 @@ static void batadv_bla_add_claim(struct batadv_priv *bat_priv,
 			/* only local changes happened. */
 			batadv_backbone_gw_put(backbone_gw);
 			kfree(claim);
+			atomic_dec(&bat_priv->bla_claim_learned);
 			return;
 		}
 	} else {
diff --git a/net/batman-adv/mesh-interface.c b/net/batman-adv/mesh-interface.c
index 1594a2d6..8fd47cef 100644
--- a/net/batman-adv/mesh-interface.c
+++ b/net/batman-adv/mesh-interface.c
@@ -793,6 +793,9 @@ static int batadv_meshif_init_late(struct net_device *dev)
 
 	atomic_set(&bat_priv->bla_backbone_learned, 0);
 	WRITE_ONCE(bat_priv->bla_backbone_max_learned, 0);
+
+	atomic_set(&bat_priv->bla_claim_learned, 0);
+	WRITE_ONCE(bat_priv->bla_claim_max_learned, 0);
 #endif
 	atomic_set(&bat_priv->tp_num, 0);
 
diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c
index 5d4bccdc..8cafbac5 100644
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -151,6 +151,7 @@ static const struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = {
 	[BATADV_ATTR_ORIG_MAX_LEARNED]		= { .type = NLA_U32 },
 	[BATADV_ATTR_DAT_MAX_LEARNED]		= { .type = NLA_U32 },
 	[BATADV_ATTR_BLA_BACKBONE_MAX_LEARNED]	= { .type = NLA_U32 },
+	[BATADV_ATTR_BLA_CLAIM_MAX_LEARNED]	= { .type = NLA_U32 },
 };
 
 /**
@@ -298,6 +299,10 @@ static int batadv_netlink_mesh_fill(struct sk_buff *msg,
 	if (nla_put_u32(msg, BATADV_ATTR_BLA_BACKBONE_MAX_LEARNED,
 			READ_ONCE(bat_priv->bla_backbone_max_learned)))
 		goto nla_put_failure;
+
+	if (nla_put_u32(msg, BATADV_ATTR_BLA_CLAIM_MAX_LEARNED,
+			READ_ONCE(bat_priv->bla_claim_max_learned)))
+		goto nla_put_failure;
 #endif /* CONFIG_BATMAN_ADV_BLA */
 
 #ifdef CONFIG_BATMAN_ADV_DAT
@@ -493,6 +498,11 @@ static int batadv_netlink_set_mesh(struct sk_buff *skb, struct genl_info *info)
 		WRITE_ONCE(bat_priv->bla_backbone_max_learned,
 			   nla_get_u32(info->attrs[BATADV_ATTR_BLA_BACKBONE_MAX_LEARNED]));
 	}
+
+	if (info->attrs[BATADV_ATTR_BLA_CLAIM_MAX_LEARNED]) {
+		WRITE_ONCE(bat_priv->bla_claim_max_learned,
+			   nla_get_u32(info->attrs[BATADV_ATTR_BLA_CLAIM_MAX_LEARNED]));
+	}
 #endif /* CONFIG_BATMAN_ADV_BLA */
 
 #ifdef CONFIG_BATMAN_ADV_DAT
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index c8976da5..6ecc34e1 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -1680,6 +1680,12 @@ struct batadv_priv {
 	/** @bla_backbone_learned: current number of learned backbone_gw entries */
 	atomic_t bla_backbone_learned;
 
+	/** @bla_claim_max_learned: Maximum number of claim */
+	u32 bla_claim_max_learned;
+
+	/** @bla_claim_learned: current number of learned claim entries */
+	atomic_t bla_claim_learned;
+
 	/** @bla: bridge loop avoidance data */
 	struct batadv_priv_bla bla;
 #endif

-- 
2.47.3


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH RFC batadv 0/5] batman-adv: allow to specify limits for remote learned objects
  2026-05-16 12:35 [PATCH RFC batadv 0/5] batman-adv: allow to specify limits for remote learned objects Sven Eckelmann
                   ` (4 preceding siblings ...)
  2026-05-16 12:35 ` [PATCH RFC batadv 5/5] batman-adv: limit numbers of parallel learned BLA claims Sven Eckelmann
@ 2026-05-17 17:43 ` Linus Lüssing
  5 siblings, 0 replies; 7+ messages in thread
From: Linus Lüssing @ 2026-05-17 17:43 UTC (permalink / raw)
  To: Sven Eckelmann; +Cc: b.a.t.m.a.n

On Sat, May 16, 2026 at 02:35:17PM +0200, Sven Eckelmann wrote:
> There are some concerns that an external entity could spam the batman-adv
> related interfaces with random mac addresses. The batman-adv would use more
> and more resources to safe things like neighbors, originators, TT, ... and
> would at some point run out of resources.
> 
> One idea is to limit the number of entries for each resource type could
> have. Things which might need limits
> 
> * orig_node
> * neigh_node
> * tt_local_entry
> * dat_entry
> * bla_backbone_gw
> * bla_claim
> 
> Things which are limited by other things (maybe)
> 
> * hardif_neigh_node
> * gw_node
> * orig_node_vlan
> * orig_info
> 
> Unknown how to handle overly large tt_global_entries:
> 
> * tt_global_entry

For tt_global_entry I think we are currently bound by MTU size and
the maximum of 16 fragments? So ~2000 entries? Which in an IPv6
enabled network, due to one multicast TT entry for each IPv6 address,
would maybe be ~500 hosts. Which isn't much already when considering
that people bridge larger TP-Link Omada / Ubiquiti UniFi setups into
batman-adv at least at Freifunk.

> This approach is also used for the bridge since commit bdb4dfda3b41 ("net:
> bridge: Track and limit dynamically learned FDB entries"). And it is also
> disabled by default.

I agree that it would make sense to agree on similar approaches
for the Linux bridge and batman-adv.

> For the moment, I just want to demonstrate how this might work with some
> example code. I didn't invest any time to actually check out the other
> items in the list. So, please consider these lists as vague suggestions.

Some more, vague thoughts/ideas on what to do when hitting limits:

We now have this new multicast packet type. And have introduced
these "want_all_*" flags. We could also introduce such flags for
unicast. And have a unicast packet delivered to multiple nodes
via the batman-adv multicast packet type.

We could do more "aggregation" of addresses and more broad,
opportunistic delivery when hitting limits.

This could also be useful if some host (accidentally or not)
was using the same MAC address as another host, maybe. To treat
such a unicast MAC address like a multicast one then.


I also would be interested in aggregating/absorption/handover of other
originator('s flags + TT entries) when a node is only connected
via one other node. So that a neighbor node takesover the
responsibility, to save OGM traffic. We have a lot of such leaf
nodes with a single connection in Freifunk setups and could probably
save 2/3 of the OGM traffic by that. And this could be useful for singular nodes with a
cellular modem, to avoid having constant, costly OGM streams to them, by
transparantly, within batman-adv switching them from a full "originator mode",
to a leightweight "TT client mode" with a few ELP hellos or so.


tl;dr: hop-by-hop auto-aggregations should make it harder for an attacker
to DoS from a single position in the network?

Regards, Linus

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2026-05-17 17:43 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-16 12:35 [PATCH RFC batadv 0/5] batman-adv: allow to specify limits for remote learned objects Sven Eckelmann
2026-05-16 12:35 ` [PATCH RFC batadv 1/5] batman-adv: limit numbers of parallel learned neighbors Sven Eckelmann
2026-05-16 12:35 ` [PATCH RFC batadv 2/5] batman-adv: limit numbers of parallel learned originators Sven Eckelmann
2026-05-16 12:35 ` [PATCH RFC batadv 3/5] batman-adv: limit numbers of parallel learned DAT entries Sven Eckelmann
2026-05-16 12:35 ` [PATCH RFC batadv 4/5] batman-adv: limit numbers of parallel learned BLA backbones Sven Eckelmann
2026-05-16 12:35 ` [PATCH RFC batadv 5/5] batman-adv: limit numbers of parallel learned BLA claims Sven Eckelmann
2026-05-17 17:43 ` [PATCH RFC batadv 0/5] batman-adv: allow to specify limits for remote learned objects Linus Lüssing

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox