aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
authorSven Eckelmann <sven@narfation.org>2026-06-07 14:34:28 +0200
committerSven Eckelmann <sven@narfation.org>2026-06-13 07:51:17 +0200
commitdf97a7107b16375a10a36d7a63e9b4291a8ac680 (patch)
tree187f082f87ed5a9f70b86771e041309c3334084c /net
parentdad4d4b92a9b9f0edb8c66deda049da1b62f6089 (diff)
downloadath-df97a7107b16375a10a36d7a63e9b4291a8ac680.tar.gz
batman-adv: gw: don't deselect gateway with active hardif
The batadv_hardif_cnt() was previously checking if there is an batadv_hard_iface->mesh_iface which is has the same mesh_iface. And since batadv_hardif_disable_interface() was resetting the batadv_hard_iface->mesh_iface after this check, it had to verify whether *1* interface was still part of the mesh_iface before it started the gateway deselection. But after batadv_hardif_cnt() is now checking the lower interfaces of mesh_iface and batadv_hardif_disable_interface() already removed the interface via netdev_upper_dev_unlink() earlier in this function, the check must now make sure that *0* interfaces can be found by batadv_hardif_cnt() before selected gateway must be deselected. Otherwise the deselection would already happen one batadv_hard_iface too early. Because a 0 hardif count from batadv_hardif_cnt() is equal to an empty list, it is possible to replace the counting with a simple list_empty(). Cc: stable@kernel.org Fixes: 7dc284702bcd ("batman-adv: store hard_iface as iflink private data") Reviewed-by: Nora Schiffer <neocturne@universe-factory.net> Signed-off-by: Sven Eckelmann <sven@narfation.org>
Diffstat (limited to 'net')
-rw-r--r--net/batman-adv/hard-interface.c28
1 files changed, 2 insertions, 26 deletions
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index 60cee2c2f2f41..03d01c20a9548 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -815,30 +815,6 @@ err_dev:
}
/**
- * batadv_hardif_cnt() - get number of interfaces enslaved to mesh interface
- * @mesh_iface: mesh interface to check
- *
- * This function is only using RCU for locking - the result can therefore be
- * off when another function is modifying the list at the same time. The
- * caller can use the rtnl_lock to make sure that the count is accurate.
- *
- * Return: number of connected/enslaved hard interfaces
- */
-static size_t batadv_hardif_cnt(struct net_device *mesh_iface)
-{
- struct batadv_hard_iface *hard_iface;
- struct list_head *iter;
- size_t count = 0;
-
- rcu_read_lock();
- netdev_for_each_lower_private_rcu(mesh_iface, hard_iface, iter)
- count++;
- rcu_read_unlock();
-
- return count;
-}
-
-/**
* batadv_hardif_disable_interface() - Remove hard interface from mesh interface
* @hard_iface: hard interface to be removed
*/
@@ -878,8 +854,8 @@ void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface)
netdev_upper_dev_unlink(hard_iface->net_dev, hard_iface->mesh_iface);
batadv_hardif_recalc_extra_skbroom(hard_iface->mesh_iface);
- /* nobody uses this interface anymore */
- if (batadv_hardif_cnt(hard_iface->mesh_iface) <= 1)
+ /* nobody uses this mesh interface anymore */
+ if (list_empty(&hard_iface->mesh_iface->adj_list.lower))
batadv_gw_check_client_stop(bat_priv);
hard_iface->mesh_iface = NULL;