diff --git a/batman-adv/Makefile b/batman-adv/Makefile index 0ad565eb3..88cee7e47 100644 --- a/batman-adv/Makefile +++ b/batman-adv/Makefile @@ -4,7 +4,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=batman-adv PKG_VERSION:=2024.3 -PKG_RELEASE:=5 +PKG_RELEASE:=6 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://downloads.open-mesh.org/batman/releases/batman-adv-$(PKG_VERSION) diff --git a/batman-adv/patches/0010-batman-adv-fix-duplicate-MAC-address-check.patch b/batman-adv/patches/0010-batman-adv-fix-duplicate-MAC-address-check.patch new file mode 100644 index 000000000..7aa8b3f52 --- /dev/null +++ b/batman-adv/patches/0010-batman-adv-fix-duplicate-MAC-address-check.patch @@ -0,0 +1,105 @@ +From: Matthias Schiffer +Date: Wed, 16 Apr 2025 20:37:56 +0200 +Subject: batman-adv: fix duplicate MAC address check + +batadv_check_known_mac_addr() is both too lenient and too strict: + +- It is called from batadv_hardif_add_interface(), which means that it + checked interfaces that are not used for batman-adv at all. Move it + to batadv_hardif_enable_interface(). Also, restrict it to hardifs of + the same mesh interface; different mesh interfaces should not interact + at all. The batadv_check_known_mac_addr() argument is changed from + `struct net_device` to `struct batadv_hard_iface` to achieve this. +- The check only cares about hardifs in BATADV_IF_ACTIVE and + BATADV_IF_TO_BE_ACTIVATED states, but interfaces in BATADV_IF_INACTIVE + state should be checked as well, or the following steps will not + result in a warning then they should: + + - Add two interfaces in down state with different MAC addresses to + a mesh as hardifs + - Change the MAC addresses so they conflict + - Set interfaces to up state + + Now there will be two active hardifs with the same MAC address, but no + warning. Fix by only ignoring hardifs in BATADV_IF_NOT_IN_USE state. + +The RCU lock can be dropped, as we're holding RTNL anyways when the +function is called. + +Fixes: c7560658b16b ("[batman-adv] print a warning when an existing mac address is added again") +Signed-off-by: Matthias Schiffer +Signed-off-by: Sven Eckelmann +(cherry picked from commit 4a2b85600c38876b6c76eb7e75d76aef2c60a055) + +--- a/net/batman-adv/hard-interface.c ++++ b/net/batman-adv/hard-interface.c +@@ -505,28 +505,32 @@ batadv_hardif_is_iface_up(const struct b + return false; + } + +-static void batadv_check_known_mac_addr(const struct net_device *net_dev) ++static void batadv_check_known_mac_addr(const struct batadv_hard_iface *hard_iface) + { +- const struct batadv_hard_iface *hard_iface; ++ const struct net_device *soft_iface = hard_iface->soft_iface; ++ const struct batadv_hard_iface *tmp_hard_iface; + +- rcu_read_lock(); +- list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) { +- if (hard_iface->if_status != BATADV_IF_ACTIVE && +- hard_iface->if_status != BATADV_IF_TO_BE_ACTIVATED) ++ if (!soft_iface) ++ return; ++ ++ list_for_each_entry(tmp_hard_iface, &batadv_hardif_list, list) { ++ if (tmp_hard_iface == hard_iface) ++ continue; ++ ++ if (tmp_hard_iface->soft_iface != soft_iface) + continue; + +- if (hard_iface->net_dev == net_dev) ++ if (tmp_hard_iface->if_status == BATADV_IF_NOT_IN_USE) + continue; + +- if (!batadv_compare_eth(hard_iface->net_dev->dev_addr, +- net_dev->dev_addr)) ++ if (!batadv_compare_eth(tmp_hard_iface->net_dev->dev_addr, ++ hard_iface->net_dev->dev_addr)) + continue; + + pr_warn("The newly added mac address (%pM) already exists on: %s\n", +- net_dev->dev_addr, hard_iface->net_dev->name); ++ hard_iface->net_dev->dev_addr, tmp_hard_iface->net_dev->name); + pr_warn("It is strongly recommended to keep mac addresses unique to avoid problems!\n"); + } +- rcu_read_unlock(); + } + + /** +@@ -764,6 +768,8 @@ int batadv_hardif_enable_interface(struc + hard_iface->net_dev->name, hardif_mtu, + required_mtu); + ++ batadv_check_known_mac_addr(hard_iface); ++ + if (batadv_hardif_is_iface_up(hard_iface)) + batadv_hardif_activate_interface(hard_iface); + else +@@ -902,7 +908,6 @@ batadv_hardif_add_interface(struct net_d + + batadv_v_hardif_init(hard_iface); + +- batadv_check_known_mac_addr(hard_iface->net_dev); + kref_get(&hard_iface->refcount); + list_add_tail_rcu(&hard_iface->list, &batadv_hardif_list); + batadv_hardif_generation++; +@@ -994,7 +999,7 @@ static int batadv_hard_if_event(struct n + if (hard_iface->if_status == BATADV_IF_NOT_IN_USE) + goto hardif_put; + +- batadv_check_known_mac_addr(hard_iface->net_dev); ++ batadv_check_known_mac_addr(hard_iface); + + bat_priv = netdev_priv(hard_iface->soft_iface); + bat_priv->algo_ops->iface.update_mac(hard_iface);