* [PATCH batadv 1/5] batman-adv: store hard_iface as iflink private data
@ 2025-05-19 20:46 Matthias Schiffer
2025-05-19 20:46 ` [PATCH batadv 2/5] batman-adv: only create hardif while a netdev is part of a mesh Matthias Schiffer
` (4 more replies)
0 siblings, 5 replies; 15+ messages in thread
From: Matthias Schiffer @ 2025-05-19 20:46 UTC (permalink / raw)
To: Marek Lindner, Simon Wunderlich, Antonio Quartulli,
Sven Eckelmann
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, b.a.t.m.a.n, netdev, linux-kernel,
Matthias Schiffer
By passing the hard_iface to netdev_master_upper_dev_link() as private
data, we can iterate over hardifs of a mesh interface more efficiently
using netdev_for_each_lower_private*() (instead of iterating over the
global hardif list). In addition, this will enable resolving a hardif
from its netdev using netdev_lower_dev_get_private() and getting rid of
the global list altogether in the following patches.
A similar approach can be seen in the bonding driver.
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
---
net/batman-adv/bat_algo.h | 1 -
net/batman-adv/bat_iv_ogm.c | 25 +++++++--------------
net/batman-adv/bat_v.c | 6 ++---
net/batman-adv/bat_v_elp.c | 7 ++----
net/batman-adv/bat_v_ogm.c | 12 ++++------
net/batman-adv/hard-interface.c | 39 ++++++++++++---------------------
net/batman-adv/main.c | 6 ++---
net/batman-adv/mesh-interface.c | 6 ++---
net/batman-adv/multicast.c | 6 ++---
net/batman-adv/netlink.c | 6 ++---
net/batman-adv/originator.c | 6 ++---
net/batman-adv/send.c | 6 ++---
12 files changed, 43 insertions(+), 83 deletions(-)
diff --git a/net/batman-adv/bat_algo.h b/net/batman-adv/bat_algo.h
index 2c486374af58..980ea75e1e94 100644
--- a/net/batman-adv/bat_algo.h
+++ b/net/batman-adv/bat_algo.h
@@ -14,7 +14,6 @@
#include <linux/types.h>
extern char batadv_routing_algo[];
-extern struct list_head batadv_hardif_list;
void batadv_algo_init(void);
struct batadv_algo_ops *batadv_algo_get(const char *name);
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
index 458879d21d66..54fe38b3b2fd 100644
--- a/net/batman-adv/bat_iv_ogm.c
+++ b/net/batman-adv/bat_iv_ogm.c
@@ -791,6 +791,7 @@ static void batadv_iv_ogm_schedule_buff(struct batadv_hard_iface *hard_iface)
struct batadv_ogm_packet *batadv_ogm_packet;
struct batadv_hard_iface *primary_if, *tmp_hard_iface;
int *ogm_buff_len = &hard_iface->bat_iv.ogm_buff_len;
+ struct list_head *iter;
u32 seqno;
u16 tvlv_len = 0;
unsigned long send_time;
@@ -847,10 +848,7 @@ static void batadv_iv_ogm_schedule_buff(struct batadv_hard_iface *hard_iface)
* interfaces.
*/
rcu_read_lock();
- list_for_each_entry_rcu(tmp_hard_iface, &batadv_hardif_list, list) {
- if (tmp_hard_iface->mesh_iface != hard_iface->mesh_iface)
- continue;
-
+ netdev_for_each_lower_private_rcu(hard_iface->mesh_iface, tmp_hard_iface, iter) {
if (!kref_get_unless_zero(&tmp_hard_iface->refcount))
continue;
@@ -1567,6 +1565,7 @@ static void batadv_iv_ogm_process(const struct sk_buff *skb, int ogm_offset,
bool is_my_oldorig = false;
bool is_my_addr = false;
bool is_my_orig = false;
+ struct list_head *iter;
ogm_packet = (struct batadv_ogm_packet *)(skb->data + ogm_offset);
ethhdr = eth_hdr(skb);
@@ -1603,11 +1602,9 @@ static void batadv_iv_ogm_process(const struct sk_buff *skb, int ogm_offset,
ogm_packet->version, has_directlink_flag);
rcu_read_lock();
- list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
- if (hard_iface->if_status != BATADV_IF_ACTIVE)
- continue;
- if (hard_iface->mesh_iface != if_incoming->mesh_iface)
+ netdev_for_each_lower_private_rcu(if_incoming->mesh_iface, hard_iface, iter) {
+ if (hard_iface->if_status != BATADV_IF_ACTIVE)
continue;
if (batadv_compare_eth(ethhdr->h_source,
@@ -1668,13 +1665,10 @@ static void batadv_iv_ogm_process(const struct sk_buff *skb, int ogm_offset,
if_incoming, BATADV_IF_DEFAULT);
rcu_read_lock();
- list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
+ netdev_for_each_lower_private_rcu(bat_priv->mesh_iface, hard_iface, iter) {
if (hard_iface->if_status != BATADV_IF_ACTIVE)
continue;
- if (hard_iface->mesh_iface != bat_priv->mesh_iface)
- continue;
-
if (!kref_get_unless_zero(&hard_iface->refcount))
continue;
@@ -2142,6 +2136,7 @@ batadv_iv_ogm_neigh_dump(struct sk_buff *msg, struct netlink_callback *cb,
struct batadv_hard_iface *single_hardif)
{
struct batadv_hard_iface *hard_iface;
+ struct list_head *iter;
int i_hardif = 0;
int i_hardif_s = cb->args[0];
int idx = cb->args[1];
@@ -2158,11 +2153,7 @@ batadv_iv_ogm_neigh_dump(struct sk_buff *msg, struct netlink_callback *cb,
i_hardif++;
}
} else {
- list_for_each_entry_rcu(hard_iface, &batadv_hardif_list,
- list) {
- if (hard_iface->mesh_iface != bat_priv->mesh_iface)
- continue;
-
+ netdev_for_each_lower_private_rcu(bat_priv->mesh_iface, hard_iface, iter) {
if (i_hardif++ < i_hardif_s)
continue;
diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c
index c16c2e60889d..de9444714264 100644
--- a/net/batman-adv/bat_v.c
+++ b/net/batman-adv/bat_v.c
@@ -212,6 +212,7 @@ batadv_v_neigh_dump(struct sk_buff *msg, struct netlink_callback *cb,
struct batadv_hard_iface *single_hardif)
{
struct batadv_hard_iface *hard_iface;
+ struct list_head *iter;
int i_hardif = 0;
int i_hardif_s = cb->args[0];
int idx = cb->args[1];
@@ -227,10 +228,7 @@ batadv_v_neigh_dump(struct sk_buff *msg, struct netlink_callback *cb,
i_hardif++;
}
} else {
- list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
- if (hard_iface->mesh_iface != bat_priv->mesh_iface)
- continue;
-
+ netdev_for_each_lower_private_rcu(bat_priv->mesh_iface, hard_iface, iter) {
if (i_hardif++ < i_hardif_s)
continue;
diff --git a/net/batman-adv/bat_v_elp.c b/net/batman-adv/bat_v_elp.c
index 70d6778da0d7..42ec62387ce1 100644
--- a/net/batman-adv/bat_v_elp.c
+++ b/net/batman-adv/bat_v_elp.c
@@ -472,15 +472,12 @@ void batadv_v_elp_iface_activate(struct batadv_hard_iface *primary_iface,
void batadv_v_elp_primary_iface_set(struct batadv_hard_iface *primary_iface)
{
struct batadv_hard_iface *hard_iface;
+ struct list_head *iter;
/* update orig field of every elp iface belonging to this mesh */
rcu_read_lock();
- list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
- if (primary_iface->mesh_iface != hard_iface->mesh_iface)
- continue;
-
+ netdev_for_each_lower_private_rcu(primary_iface->mesh_iface, hard_iface, iter)
batadv_v_elp_iface_activate(primary_iface, hard_iface);
- }
rcu_read_unlock();
}
diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c
index b86bb647da5b..a04685ace339 100644
--- a/net/batman-adv/bat_v_ogm.c
+++ b/net/batman-adv/bat_v_ogm.c
@@ -265,6 +265,7 @@ static void batadv_v_ogm_send_meshif(struct batadv_priv *bat_priv)
struct batadv_ogm2_packet *ogm_packet;
struct sk_buff *skb, *skb_tmp;
unsigned char *ogm_buff;
+ struct list_head *iter;
int ogm_buff_len;
u16 tvlv_len = 0;
int ret;
@@ -301,10 +302,7 @@ static void batadv_v_ogm_send_meshif(struct batadv_priv *bat_priv)
/* broadcast on every interface */
rcu_read_lock();
- list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
- if (hard_iface->mesh_iface != bat_priv->mesh_iface)
- continue;
-
+ netdev_for_each_lower_private_rcu(bat_priv->mesh_iface, hard_iface, iter) {
if (!kref_get_unless_zero(&hard_iface->refcount))
continue;
@@ -859,6 +857,7 @@ static void batadv_v_ogm_process(const struct sk_buff *skb, int ogm_offset,
struct batadv_hard_iface *hard_iface;
struct batadv_ogm2_packet *ogm_packet;
u32 ogm_throughput, link_throughput, path_throughput;
+ struct list_head *iter;
int ret;
ethhdr = eth_hdr(skb);
@@ -921,13 +920,10 @@ static void batadv_v_ogm_process(const struct sk_buff *skb, int ogm_offset,
BATADV_IF_DEFAULT);
rcu_read_lock();
- list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
+ netdev_for_each_lower_private_rcu(bat_priv->mesh_iface, hard_iface, iter) {
if (hard_iface->if_status != BATADV_IF_ACTIVE)
continue;
- if (hard_iface->mesh_iface != bat_priv->mesh_iface)
- continue;
-
if (!kref_get_unless_zero(&hard_iface->refcount))
continue;
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index 558d39dffc23..bace57e4f9a5 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -438,15 +438,13 @@ int batadv_hardif_no_broadcast(struct batadv_hard_iface *if_outgoing,
}
static struct batadv_hard_iface *
-batadv_hardif_get_active(const struct net_device *mesh_iface)
+batadv_hardif_get_active(struct net_device *mesh_iface)
{
struct batadv_hard_iface *hard_iface;
+ struct list_head *iter;
rcu_read_lock();
- list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
- if (hard_iface->mesh_iface != mesh_iface)
- continue;
-
+ netdev_for_each_lower_private_rcu(mesh_iface, hard_iface, iter) {
if (hard_iface->if_status == BATADV_IF_ACTIVE &&
kref_get_unless_zero(&hard_iface->refcount))
goto out;
@@ -508,19 +506,17 @@ batadv_hardif_is_iface_up(const struct batadv_hard_iface *hard_iface)
static void batadv_check_known_mac_addr(const struct batadv_hard_iface *hard_iface)
{
- const struct net_device *mesh_iface = hard_iface->mesh_iface;
+ struct net_device *mesh_iface = hard_iface->mesh_iface;
const struct batadv_hard_iface *tmp_hard_iface;
+ struct list_head *iter;
if (!mesh_iface)
return;
- list_for_each_entry(tmp_hard_iface, &batadv_hardif_list, list) {
+ netdev_for_each_lower_private(mesh_iface, tmp_hard_iface, iter) {
if (tmp_hard_iface == hard_iface)
continue;
- if (tmp_hard_iface->mesh_iface != mesh_iface)
- continue;
-
if (tmp_hard_iface->if_status == BATADV_IF_NOT_IN_USE)
continue;
@@ -545,15 +541,13 @@ static void batadv_hardif_recalc_extra_skbroom(struct net_device *mesh_iface)
unsigned short lower_headroom = 0;
unsigned short lower_tailroom = 0;
unsigned short needed_headroom;
+ struct list_head *iter;
rcu_read_lock();
- list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
+ netdev_for_each_lower_private_rcu(mesh_iface, hard_iface, iter) {
if (hard_iface->if_status == BATADV_IF_NOT_IN_USE)
continue;
- if (hard_iface->mesh_iface != mesh_iface)
- continue;
-
lower_header_len = max_t(unsigned short, lower_header_len,
hard_iface->net_dev->hard_header_len);
@@ -586,17 +580,15 @@ int batadv_hardif_min_mtu(struct net_device *mesh_iface)
{
struct batadv_priv *bat_priv = netdev_priv(mesh_iface);
const struct batadv_hard_iface *hard_iface;
+ struct list_head *iter;
int min_mtu = INT_MAX;
rcu_read_lock();
- list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
+ netdev_for_each_lower_private_rcu(mesh_iface, hard_iface, iter) {
if (hard_iface->if_status != BATADV_IF_ACTIVE &&
hard_iface->if_status != BATADV_IF_TO_BE_ACTIVATED)
continue;
- if (hard_iface->mesh_iface != mesh_iface)
- continue;
-
min_mtu = min_t(int, hard_iface->net_dev->mtu, min_mtu);
}
rcu_read_unlock();
@@ -734,7 +726,7 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
bat_priv = netdev_priv(hard_iface->mesh_iface);
ret = netdev_master_upper_dev_link(hard_iface->net_dev,
- mesh_iface, NULL, NULL, NULL);
+ mesh_iface, hard_iface, NULL, NULL);
if (ret)
goto err_dev;
@@ -803,18 +795,15 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
*
* Return: number of connected/enslaved hard interfaces
*/
-static size_t batadv_hardif_cnt(const struct net_device *mesh_iface)
+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();
- list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
- if (hard_iface->mesh_iface != mesh_iface)
- continue;
-
+ netdev_for_each_lower_private_rcu(mesh_iface, hard_iface, iter)
count++;
- }
rcu_read_unlock();
return count;
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
index c0bc75513355..f1a7233de1da 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -303,16 +303,14 @@ void batadv_mesh_free(struct net_device *mesh_iface)
bool batadv_is_my_mac(struct batadv_priv *bat_priv, const u8 *addr)
{
const struct batadv_hard_iface *hard_iface;
+ struct list_head *iter;
bool is_my_mac = false;
rcu_read_lock();
- list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
+ netdev_for_each_lower_private_rcu(bat_priv->mesh_iface, hard_iface, iter) {
if (hard_iface->if_status != BATADV_IF_ACTIVE)
continue;
- if (hard_iface->mesh_iface != bat_priv->mesh_iface)
- continue;
-
if (batadv_compare_eth(hard_iface->net_dev->dev_addr, addr)) {
is_my_mac = true;
break;
diff --git a/net/batman-adv/mesh-interface.c b/net/batman-adv/mesh-interface.c
index 72f684a4cb73..5872818f4e31 100644
--- a/net/batman-adv/mesh-interface.c
+++ b/net/batman-adv/mesh-interface.c
@@ -1115,9 +1115,9 @@ static void batadv_meshif_destroy_netlink(struct net_device *mesh_iface,
struct batadv_hard_iface *hard_iface;
struct batadv_meshif_vlan *vlan;
- list_for_each_entry(hard_iface, &batadv_hardif_list, list) {
- if (hard_iface->mesh_iface == mesh_iface)
- batadv_hardif_disable_interface(hard_iface);
+ while (!list_empty(&mesh_iface->adj_list.lower)) {
+ hard_iface = netdev_adjacent_get_private(mesh_iface->adj_list.lower.next);
+ batadv_hardif_disable_interface(hard_iface);
}
/* destroy the "untagged" VLAN */
diff --git a/net/batman-adv/multicast.c b/net/batman-adv/multicast.c
index f26892b362e2..70953b5bdfb4 100644
--- a/net/batman-adv/multicast.c
+++ b/net/batman-adv/multicast.c
@@ -254,15 +254,13 @@ static u8 batadv_mcast_mla_rtr_flags_get(struct batadv_priv *bat_priv,
static u8 batadv_mcast_mla_forw_flags_get(struct batadv_priv *bat_priv)
{
const struct batadv_hard_iface *hard_iface;
+ struct list_head *iter;
rcu_read_lock();
- list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
+ netdev_for_each_lower_private_rcu(bat_priv->mesh_iface, hard_iface, iter) {
if (hard_iface->if_status != BATADV_IF_ACTIVE)
continue;
- if (hard_iface->mesh_iface != bat_priv->mesh_iface)
- continue;
-
if (hard_iface->net_dev->mtu < IPV6_MIN_MTU) {
rcu_read_unlock();
return BATADV_NO_FLAGS;
diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c
index c33d2c6cb6c4..41c1e7e0cf0d 100644
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -968,6 +968,7 @@ batadv_netlink_dump_hardif(struct sk_buff *msg, struct netlink_callback *cb)
struct batadv_priv *bat_priv;
int portid = NETLINK_CB(cb->skb).portid;
int skip = cb->args[0];
+ struct list_head *iter;
int i = 0;
mesh_iface = batadv_netlink_get_meshif(cb);
@@ -979,10 +980,7 @@ batadv_netlink_dump_hardif(struct sk_buff *msg, struct netlink_callback *cb)
rtnl_lock();
cb->seq = batadv_hardif_generation << 1 | 1;
- list_for_each_entry(hard_iface, &batadv_hardif_list, list) {
- if (hard_iface->mesh_iface != mesh_iface)
- continue;
-
+ netdev_for_each_lower_private(mesh_iface, hard_iface, iter) {
if (i++ < skip)
continue;
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
index d9cfc5c6b208..2726f2905f3c 100644
--- a/net/batman-adv/originator.c
+++ b/net/batman-adv/originator.c
@@ -1208,6 +1208,7 @@ static bool batadv_purge_orig_node(struct batadv_priv *bat_priv,
struct batadv_neigh_node *best_neigh_node;
struct batadv_hard_iface *hard_iface;
bool changed_ifinfo, changed_neigh;
+ struct list_head *iter;
if (batadv_has_timed_out(orig_node->last_seen,
2 * BATADV_PURGE_TIMEOUT)) {
@@ -1232,13 +1233,10 @@ static bool batadv_purge_orig_node(struct batadv_priv *bat_priv,
/* ... then for all other interfaces. */
rcu_read_lock();
- list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
+ netdev_for_each_lower_private_rcu(bat_priv->mesh_iface, hard_iface, iter) {
if (hard_iface->if_status != BATADV_IF_ACTIVE)
continue;
- if (hard_iface->mesh_iface != bat_priv->mesh_iface)
- continue;
-
if (!kref_get_unless_zero(&hard_iface->refcount))
continue;
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c
index 9d72f4f15b3d..225689b4f17d 100644
--- a/net/batman-adv/send.c
+++ b/net/batman-adv/send.c
@@ -924,6 +924,7 @@ static int __batadv_forw_bcast_packet(struct batadv_priv *bat_priv,
{
struct batadv_hard_iface *hard_iface;
struct batadv_hard_iface *primary_if;
+ struct list_head *iter;
int ret = NETDEV_TX_OK;
primary_if = batadv_primary_if_get_selected(bat_priv);
@@ -931,10 +932,7 @@ static int __batadv_forw_bcast_packet(struct batadv_priv *bat_priv,
return NETDEV_TX_BUSY;
rcu_read_lock();
- list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
- if (hard_iface->mesh_iface != bat_priv->mesh_iface)
- continue;
-
+ netdev_for_each_lower_private_rcu(bat_priv->mesh_iface, hard_iface, iter) {
if (!kref_get_unless_zero(&hard_iface->refcount))
continue;
--
2.49.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH batadv 2/5] batman-adv: only create hardif while a netdev is part of a mesh
2025-05-19 20:46 [PATCH batadv 1/5] batman-adv: store hard_iface as iflink private data Matthias Schiffer
@ 2025-05-19 20:46 ` Matthias Schiffer
2025-05-31 9:16 ` Sven Eckelmann
2025-05-31 9:52 ` Sven Eckelmann
2025-05-19 20:46 ` [PATCH batadv 3/5] batman-adv: remove BATADV_IF_NOT_IN_USE hardif state Matthias Schiffer
` (3 subsequent siblings)
4 siblings, 2 replies; 15+ messages in thread
From: Matthias Schiffer @ 2025-05-19 20:46 UTC (permalink / raw)
To: Marek Lindner, Simon Wunderlich, Antonio Quartulli,
Sven Eckelmann
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, b.a.t.m.a.n, netdev, linux-kernel,
Matthias Schiffer
batman-adv has used netdevice notifiers to create a hardif struct for
every Ethernet-like netdev in the system, instead of just for netdevs
that are actually used for meshing.
This is inefficient in many ways: It requires maintaining a global list
of hardifs (as there is no other place to store the hardif associated
with a netdev), lookups in this list are O(n) in the total number of
interfaces, and the maintenance of this list results in just loading the
batman-adv module to cause a slowdown of certain netdev operations (for
example, deleting n Ethernet netdevs may take O(n^2) because for each
removal, the corresponding hardif needs to be looked up in the global
list).
As the next step towards removing the global list, only create a hardif
struct when an interface is added to a mesh, and destroy it on removal.
Parts of batadv_hardif_add_interface() are merged into
batadv_hardif_enable_interface(), and batadv_hardif_remove_interface()
can be dropped altogether.
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
---
net/batman-adv/hard-interface.c | 131 +++++++++++++-------------------
net/batman-adv/hard-interface.h | 2 +-
net/batman-adv/mesh-interface.c | 13 +---
3 files changed, 53 insertions(+), 93 deletions(-)
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index bace57e4f9a5..7e8c08fbd049 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -694,32 +694,66 @@ batadv_hardif_deactivate_interface(struct batadv_hard_iface *hard_iface)
}
/**
- * batadv_hardif_enable_interface() - Enslave hard interface to mesh interface
- * @hard_iface: hard interface to add to mesh interface
+ * batadv_hardif_enable_interface() - Enslave interface to mesh interface
+ * @net_dev: netdev struct of the interface to add to mesh interface
* @mesh_iface: netdev struct of the mesh interface
*
- * Return: 0 on success or negative error number in case of failure
+ * Return: new hardif on success, NULL for unsupported device types or negative
+ * error number in case of failure
*/
-int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
+int batadv_hardif_enable_interface(struct net_device *net_dev,
struct net_device *mesh_iface)
{
struct batadv_priv *bat_priv;
__be16 ethertype = htons(ETH_P_BATMAN);
int max_header_len = batadv_max_header_len();
+ struct batadv_hard_iface *hard_iface;
unsigned int required_mtu;
unsigned int hardif_mtu;
int ret;
- hardif_mtu = READ_ONCE(hard_iface->net_dev->mtu);
- required_mtu = READ_ONCE(mesh_iface->mtu) + max_header_len;
+ ASSERT_RTNL();
- if (hardif_mtu < ETH_MIN_MTU + max_header_len)
+ if (!batadv_is_valid_iface(net_dev))
return -EINVAL;
- if (hard_iface->if_status != BATADV_IF_NOT_IN_USE)
- goto out;
+ hard_iface = kzalloc(sizeof(*hard_iface), GFP_ATOMIC);
+ if (!hard_iface)
+ return -ENOMEM;
+
+ netdev_hold(net_dev, &hard_iface->dev_tracker, GFP_ATOMIC);
+ hard_iface->net_dev = net_dev;
+
+ hard_iface->mesh_iface = NULL;
+ hard_iface->if_status = BATADV_IF_INACTIVE;
+
+ INIT_LIST_HEAD(&hard_iface->list);
+ INIT_HLIST_HEAD(&hard_iface->neigh_list);
+
+ mutex_init(&hard_iface->bat_iv.ogm_buff_mutex);
+ spin_lock_init(&hard_iface->neigh_list_lock);
+ kref_init(&hard_iface->refcount);
+
+ hard_iface->num_bcasts = BATADV_NUM_BCASTS_DEFAULT;
+ hard_iface->wifi_flags = batadv_wifi_flags_evaluate(net_dev);
+ if (batadv_is_wifi_hardif(hard_iface))
+ hard_iface->num_bcasts = BATADV_NUM_BCASTS_WIRELESS;
+
+ atomic_set(&hard_iface->hop_penalty, 0);
+
+ batadv_v_hardif_init(hard_iface);
kref_get(&hard_iface->refcount);
+ list_add_tail_rcu(&hard_iface->list, &batadv_hardif_list);
+ batadv_hardif_generation++;
+
+ hardif_mtu = READ_ONCE(hard_iface->net_dev->mtu);
+ required_mtu = READ_ONCE(mesh_iface->mtu) + max_header_len;
+
+ if (hardif_mtu < ETH_MIN_MTU + max_header_len) {
+ ret = -EINVAL;
+ goto err_put;
+ }
netdev_hold(mesh_iface, &hard_iface->meshif_dev_tracker, GFP_ATOMIC);
hard_iface->mesh_iface = mesh_iface;
@@ -734,9 +768,6 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
if (ret < 0)
goto err_upper;
- hard_iface->if_status = BATADV_IF_INACTIVE;
-
- kref_get(&hard_iface->refcount);
hard_iface->batman_adv_ptype.type = ethertype;
hard_iface->batman_adv_ptype.func = batadv_batman_skb_recv;
hard_iface->batman_adv_ptype.dev = hard_iface->net_dev;
@@ -773,7 +804,6 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
if (bat_priv->algo_ops->iface.enabled)
bat_priv->algo_ops->iface.enabled(hard_iface);
-out:
return 0;
err_upper:
@@ -781,6 +811,7 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
err_dev:
hard_iface->mesh_iface = NULL;
netdev_put(mesh_iface, &hard_iface->meshif_dev_tracker);
+err_put:
batadv_hardif_put(hard_iface);
return ret;
}
@@ -818,11 +849,16 @@ void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface)
struct batadv_priv *bat_priv = netdev_priv(hard_iface->mesh_iface);
struct batadv_hard_iface *primary_if = NULL;
+ ASSERT_RTNL();
+
batadv_hardif_deactivate_interface(hard_iface);
if (hard_iface->if_status != BATADV_IF_INACTIVE)
goto out;
+ list_del_rcu(&hard_iface->list);
+ batadv_hardif_generation++;
+
batadv_info(hard_iface->mesh_iface, "Removing interface: %s\n",
hard_iface->net_dev->name);
dev_remove_pack(&hard_iface->batman_adv_ptype);
@@ -839,7 +875,7 @@ void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface)
}
bat_priv->algo_ops->iface.disable(hard_iface);
- hard_iface->if_status = BATADV_IF_NOT_IN_USE;
+ hard_iface->if_status = BATADV_IF_TO_BE_REMOVED;
/* delete all references to this hard_iface */
batadv_purge_orig_ref(bat_priv);
@@ -860,64 +896,6 @@ void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface)
batadv_hardif_put(primary_if);
}
-static struct batadv_hard_iface *
-batadv_hardif_add_interface(struct net_device *net_dev)
-{
- struct batadv_hard_iface *hard_iface;
-
- ASSERT_RTNL();
-
- if (!batadv_is_valid_iface(net_dev))
- return NULL;
-
- hard_iface = kzalloc(sizeof(*hard_iface), GFP_ATOMIC);
- if (!hard_iface)
- return NULL;
-
- netdev_hold(net_dev, &hard_iface->dev_tracker, GFP_ATOMIC);
- hard_iface->net_dev = net_dev;
-
- hard_iface->mesh_iface = NULL;
- hard_iface->if_status = BATADV_IF_NOT_IN_USE;
-
- INIT_LIST_HEAD(&hard_iface->list);
- INIT_HLIST_HEAD(&hard_iface->neigh_list);
-
- mutex_init(&hard_iface->bat_iv.ogm_buff_mutex);
- spin_lock_init(&hard_iface->neigh_list_lock);
- kref_init(&hard_iface->refcount);
-
- hard_iface->num_bcasts = BATADV_NUM_BCASTS_DEFAULT;
- hard_iface->wifi_flags = batadv_wifi_flags_evaluate(net_dev);
- if (batadv_is_wifi_hardif(hard_iface))
- hard_iface->num_bcasts = BATADV_NUM_BCASTS_WIRELESS;
-
- atomic_set(&hard_iface->hop_penalty, 0);
-
- batadv_v_hardif_init(hard_iface);
-
- kref_get(&hard_iface->refcount);
- list_add_tail_rcu(&hard_iface->list, &batadv_hardif_list);
- batadv_hardif_generation++;
-
- return hard_iface;
-}
-
-static void batadv_hardif_remove_interface(struct batadv_hard_iface *hard_iface)
-{
- ASSERT_RTNL();
-
- /* first deactivate interface */
- if (hard_iface->if_status != BATADV_IF_NOT_IN_USE)
- batadv_hardif_disable_interface(hard_iface);
-
- if (hard_iface->if_status != BATADV_IF_NOT_IN_USE)
- return;
-
- hard_iface->if_status = BATADV_IF_TO_BE_REMOVED;
- batadv_hardif_put(hard_iface);
-}
-
/**
* batadv_hard_if_event_meshif() - Handle events for mesh interfaces
* @event: NETDEV_* event to handle
@@ -952,10 +930,6 @@ static int batadv_hard_if_event(struct notifier_block *this,
return batadv_hard_if_event_meshif(event, net_dev);
hard_iface = batadv_hardif_get_by_netdev(net_dev);
- if (!hard_iface && (event == NETDEV_REGISTER ||
- event == NETDEV_POST_TYPE_CHANGE))
- hard_iface = batadv_hardif_add_interface(net_dev);
-
if (!hard_iface)
goto out;
@@ -969,10 +943,7 @@ static int batadv_hard_if_event(struct notifier_block *this,
break;
case NETDEV_UNREGISTER:
case NETDEV_PRE_TYPE_CHANGE:
- list_del_rcu(&hard_iface->list);
- batadv_hardif_generation++;
-
- batadv_hardif_remove_interface(hard_iface);
+ batadv_hardif_disable_interface(hard_iface);
break;
case NETDEV_CHANGEMTU:
if (hard_iface->mesh_iface)
diff --git a/net/batman-adv/hard-interface.h b/net/batman-adv/hard-interface.h
index 262a78364742..ebde3d5077a4 100644
--- a/net/batman-adv/hard-interface.h
+++ b/net/batman-adv/hard-interface.h
@@ -73,7 +73,7 @@ bool batadv_is_cfg80211_hardif(struct batadv_hard_iface *hard_iface);
bool batadv_is_wifi_hardif(struct batadv_hard_iface *hard_iface);
struct batadv_hard_iface*
batadv_hardif_get_by_netdev(const struct net_device *net_dev);
-int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
+int batadv_hardif_enable_interface(struct net_device *net_dev,
struct net_device *mesh_iface);
void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface);
int batadv_hardif_min_mtu(struct net_device *mesh_iface);
diff --git a/net/batman-adv/mesh-interface.c b/net/batman-adv/mesh-interface.c
index 5872818f4e31..860c5af5752a 100644
--- a/net/batman-adv/mesh-interface.c
+++ b/net/batman-adv/mesh-interface.c
@@ -835,18 +835,7 @@ static int batadv_meshif_slave_add(struct net_device *dev,
struct net_device *slave_dev,
struct netlink_ext_ack *extack)
{
- struct batadv_hard_iface *hard_iface;
- int ret = -EINVAL;
-
- hard_iface = batadv_hardif_get_by_netdev(slave_dev);
- if (!hard_iface || hard_iface->mesh_iface)
- goto out;
-
- ret = batadv_hardif_enable_interface(hard_iface, dev);
-
-out:
- batadv_hardif_put(hard_iface);
- return ret;
+ return batadv_hardif_enable_interface(slave_dev, dev);
}
/**
--
2.49.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH batadv 3/5] batman-adv: remove BATADV_IF_NOT_IN_USE hardif state
2025-05-19 20:46 [PATCH batadv 1/5] batman-adv: store hard_iface as iflink private data Matthias Schiffer
2025-05-19 20:46 ` [PATCH batadv 2/5] batman-adv: only create hardif while a netdev is part of a mesh Matthias Schiffer
@ 2025-05-19 20:46 ` Matthias Schiffer
2025-05-31 9:18 ` Sven Eckelmann
2025-05-19 20:46 ` [PATCH batadv 4/5] batman-adv: remove global hardif list Matthias Schiffer
` (2 subsequent siblings)
4 siblings, 1 reply; 15+ messages in thread
From: Matthias Schiffer @ 2025-05-19 20:46 UTC (permalink / raw)
To: Marek Lindner, Simon Wunderlich, Antonio Quartulli,
Sven Eckelmann
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, b.a.t.m.a.n, netdev, linux-kernel,
Matthias Schiffer
With hardifs only existing while an interface is part of a mesh, the
BATADV_IF_NOT_IN_USE state has become redundant.
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
---
net/batman-adv/bat_iv_ogm.c | 3 +--
net/batman-adv/bat_v_elp.c | 3 +--
net/batman-adv/hard-interface.c | 9 ---------
net/batman-adv/hard-interface.h | 6 ------
net/batman-adv/originator.c | 4 ----
5 files changed, 2 insertions(+), 23 deletions(-)
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
index 54fe38b3b2fd..c09ca4a896cc 100644
--- a/net/batman-adv/bat_iv_ogm.c
+++ b/net/batman-adv/bat_iv_ogm.c
@@ -866,8 +866,7 @@ static void batadv_iv_ogm_schedule_buff(struct batadv_hard_iface *hard_iface)
static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
{
- if (hard_iface->if_status == BATADV_IF_NOT_IN_USE ||
- hard_iface->if_status == BATADV_IF_TO_BE_REMOVED)
+ if (hard_iface->if_status == BATADV_IF_TO_BE_REMOVED)
return;
mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
diff --git a/net/batman-adv/bat_v_elp.c b/net/batman-adv/bat_v_elp.c
index 42ec62387ce1..7c914bfac340 100644
--- a/net/batman-adv/bat_v_elp.c
+++ b/net/batman-adv/bat_v_elp.c
@@ -301,8 +301,7 @@ static void batadv_v_elp_periodic_work(struct work_struct *work)
goto out;
/* we are in the process of shutting this interface down */
- if (hard_iface->if_status == BATADV_IF_NOT_IN_USE ||
- hard_iface->if_status == BATADV_IF_TO_BE_REMOVED)
+ if (hard_iface->if_status == BATADV_IF_TO_BE_REMOVED)
goto out;
/* the interface was enabled but may not be ready yet */
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index 7e8c08fbd049..89e0e11250ca 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -517,9 +517,6 @@ static void batadv_check_known_mac_addr(const struct batadv_hard_iface *hard_ifa
if (tmp_hard_iface == hard_iface)
continue;
- if (tmp_hard_iface->if_status == BATADV_IF_NOT_IN_USE)
- continue;
-
if (!batadv_compare_eth(tmp_hard_iface->net_dev->dev_addr,
hard_iface->net_dev->dev_addr))
continue;
@@ -545,9 +542,6 @@ static void batadv_hardif_recalc_extra_skbroom(struct net_device *mesh_iface)
rcu_read_lock();
netdev_for_each_lower_private_rcu(mesh_iface, hard_iface, iter) {
- if (hard_iface->if_status == BATADV_IF_NOT_IN_USE)
- continue;
-
lower_header_len = max_t(unsigned short, lower_header_len,
hard_iface->net_dev->hard_header_len);
@@ -950,9 +944,6 @@ static int batadv_hard_if_event(struct notifier_block *this,
batadv_update_min_mtu(hard_iface->mesh_iface);
break;
case NETDEV_CHANGEADDR:
- if (hard_iface->if_status == BATADV_IF_NOT_IN_USE)
- goto hardif_put;
-
batadv_check_known_mac_addr(hard_iface);
bat_priv = netdev_priv(hard_iface->mesh_iface);
diff --git a/net/batman-adv/hard-interface.h b/net/batman-adv/hard-interface.h
index ebde3d5077a4..ace7a0f6f3b6 100644
--- a/net/batman-adv/hard-interface.h
+++ b/net/batman-adv/hard-interface.h
@@ -21,12 +21,6 @@
* enum batadv_hard_if_state - State of a hard interface
*/
enum batadv_hard_if_state {
- /**
- * @BATADV_IF_NOT_IN_USE: interface is not used as slave interface of a
- * batman-adv mesh interface
- */
- BATADV_IF_NOT_IN_USE,
-
/**
* @BATADV_IF_TO_BE_REMOVED: interface will be removed from mesh
* interface
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
index 2726f2905f3c..2e5ea70acbd9 100644
--- a/net/batman-adv/originator.c
+++ b/net/batman-adv/originator.c
@@ -1033,7 +1033,6 @@ batadv_purge_neigh_ifinfo(struct batadv_priv *bat_priv,
/* don't purge if the interface is not (going) down */
if (if_outgoing->if_status != BATADV_IF_INACTIVE &&
- if_outgoing->if_status != BATADV_IF_NOT_IN_USE &&
if_outgoing->if_status != BATADV_IF_TO_BE_REMOVED)
continue;
@@ -1077,7 +1076,6 @@ batadv_purge_orig_ifinfo(struct batadv_priv *bat_priv,
/* don't purge if the interface is not (going) down */
if (if_outgoing->if_status != BATADV_IF_INACTIVE &&
- if_outgoing->if_status != BATADV_IF_NOT_IN_USE &&
if_outgoing->if_status != BATADV_IF_TO_BE_REMOVED)
continue;
@@ -1127,10 +1125,8 @@ batadv_purge_orig_neighbors(struct batadv_priv *bat_priv,
if (batadv_has_timed_out(last_seen, BATADV_PURGE_TIMEOUT) ||
if_incoming->if_status == BATADV_IF_INACTIVE ||
- if_incoming->if_status == BATADV_IF_NOT_IN_USE ||
if_incoming->if_status == BATADV_IF_TO_BE_REMOVED) {
if (if_incoming->if_status == BATADV_IF_INACTIVE ||
- if_incoming->if_status == BATADV_IF_NOT_IN_USE ||
if_incoming->if_status == BATADV_IF_TO_BE_REMOVED)
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
"neighbor purge: originator %pM, neighbor: %pM, iface: %s\n",
--
2.49.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH batadv 4/5] batman-adv: remove global hardif list
2025-05-19 20:46 [PATCH batadv 1/5] batman-adv: store hard_iface as iflink private data Matthias Schiffer
2025-05-19 20:46 ` [PATCH batadv 2/5] batman-adv: only create hardif while a netdev is part of a mesh Matthias Schiffer
2025-05-19 20:46 ` [PATCH batadv 3/5] batman-adv: remove BATADV_IF_NOT_IN_USE hardif state Matthias Schiffer
@ 2025-05-19 20:46 ` Matthias Schiffer
2025-05-31 9:56 ` Sven Eckelmann
2025-05-19 20:46 ` [PATCH batadv 5/5] batman-adv: move hardif generation counter into batadv_priv Matthias Schiffer
2025-05-31 8:31 ` [PATCH batadv 1/5] batman-adv: store hard_iface as iflink private data Sven Eckelmann
4 siblings, 1 reply; 15+ messages in thread
From: Matthias Schiffer @ 2025-05-19 20:46 UTC (permalink / raw)
To: Marek Lindner, Simon Wunderlich, Antonio Quartulli,
Sven Eckelmann
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, b.a.t.m.a.n, netdev, linux-kernel,
Matthias Schiffer
With interfaces being kept track of as iflink private data, there is no
need for the global list anymore. batadv_hardif_get_by_netdev() can now
use netdev_master_upper_dev_get()+netdev_lower_dev_get_private() to find
the hardif corresponding to a netdev.
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
---
net/batman-adv/hard-interface.c | 26 ++++++++++----------------
net/batman-adv/hard-interface.h | 2 +-
net/batman-adv/main.c | 5 -----
net/batman-adv/main.h | 1 -
net/batman-adv/types.h | 3 ---
5 files changed, 11 insertions(+), 26 deletions(-)
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index 89e0e11250ca..5b46104dcf61 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -63,21 +63,19 @@ void batadv_hardif_release(struct kref *ref)
* Return: batadv_hard_iface of net_dev (with increased refcnt), NULL on errors
*/
struct batadv_hard_iface *
-batadv_hardif_get_by_netdev(const struct net_device *net_dev)
+batadv_hardif_get_by_netdev(struct net_device *net_dev)
{
struct batadv_hard_iface *hard_iface;
+ struct net_device *mesh_iface;
- rcu_read_lock();
- list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
- if (hard_iface->net_dev == net_dev &&
- kref_get_unless_zero(&hard_iface->refcount))
- goto out;
- }
+ mesh_iface = netdev_master_upper_dev_get(net_dev);
+ if (!mesh_iface || !batadv_meshif_is_valid(mesh_iface))
+ return NULL;
- hard_iface = NULL;
+ hard_iface = netdev_lower_dev_get_private(mesh_iface, net_dev);
+ if (!kref_get_unless_zero(&hard_iface->refcount))
+ return NULL;
-out:
- rcu_read_unlock();
return hard_iface;
}
@@ -721,7 +719,6 @@ int batadv_hardif_enable_interface(struct net_device *net_dev,
hard_iface->mesh_iface = NULL;
hard_iface->if_status = BATADV_IF_INACTIVE;
- INIT_LIST_HEAD(&hard_iface->list);
INIT_HLIST_HEAD(&hard_iface->neigh_list);
mutex_init(&hard_iface->bat_iv.ogm_buff_mutex);
@@ -738,8 +735,6 @@ int batadv_hardif_enable_interface(struct net_device *net_dev,
batadv_v_hardif_init(hard_iface);
kref_get(&hard_iface->refcount);
- list_add_tail_rcu(&hard_iface->list, &batadv_hardif_list);
- batadv_hardif_generation++;
hardif_mtu = READ_ONCE(hard_iface->net_dev->mtu);
required_mtu = READ_ONCE(mesh_iface->mtu) + max_header_len;
@@ -753,6 +748,7 @@ int batadv_hardif_enable_interface(struct net_device *net_dev,
hard_iface->mesh_iface = mesh_iface;
bat_priv = netdev_priv(hard_iface->mesh_iface);
+ batadv_hardif_generation++;
ret = netdev_master_upper_dev_link(hard_iface->net_dev,
mesh_iface, hard_iface, NULL, NULL);
if (ret)
@@ -850,9 +846,6 @@ void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface)
if (hard_iface->if_status != BATADV_IF_INACTIVE)
goto out;
- list_del_rcu(&hard_iface->list);
- batadv_hardif_generation++;
-
batadv_info(hard_iface->mesh_iface, "Removing interface: %s\n",
hard_iface->net_dev->name);
dev_remove_pack(&hard_iface->batman_adv_ptype);
@@ -876,6 +869,7 @@ void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface)
batadv_purge_outstanding_packets(bat_priv, hard_iface);
netdev_put(hard_iface->mesh_iface, &hard_iface->meshif_dev_tracker);
+ batadv_hardif_generation++;
netdev_upper_dev_unlink(hard_iface->net_dev, hard_iface->mesh_iface);
batadv_hardif_recalc_extra_skbroom(hard_iface->mesh_iface);
diff --git a/net/batman-adv/hard-interface.h b/net/batman-adv/hard-interface.h
index ace7a0f6f3b6..6b210ebe45b3 100644
--- a/net/batman-adv/hard-interface.h
+++ b/net/batman-adv/hard-interface.h
@@ -66,7 +66,7 @@ struct net_device *batadv_get_real_netdev(struct net_device *net_device);
bool batadv_is_cfg80211_hardif(struct batadv_hard_iface *hard_iface);
bool batadv_is_wifi_hardif(struct batadv_hard_iface *hard_iface);
struct batadv_hard_iface*
-batadv_hardif_get_by_netdev(const struct net_device *net_dev);
+batadv_hardif_get_by_netdev(struct net_device *net_dev);
int batadv_hardif_enable_interface(struct net_device *net_dev,
struct net_device *mesh_iface);
void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface);
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
index f1a7233de1da..8e8ea93cf61d 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -61,10 +61,6 @@
#include "tp_meter.h"
#include "translation-table.h"
-/* List manipulations on hardif_list have to be rtnl_lock()'ed,
- * list traversals just rcu-locked
- */
-struct list_head batadv_hardif_list;
unsigned int batadv_hardif_generation;
static int (*batadv_rx_handler[256])(struct sk_buff *skb,
struct batadv_hard_iface *recv_if);
@@ -97,7 +93,6 @@ static int __init batadv_init(void)
if (ret < 0)
return ret;
- INIT_LIST_HEAD(&batadv_hardif_list);
batadv_algo_init();
batadv_recv_handler_init();
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h
index 692109be2210..debc55922fe1 100644
--- a/net/batman-adv/main.h
+++ b/net/batman-adv/main.h
@@ -232,7 +232,6 @@ static inline int batadv_print_vid(unsigned short vid)
return -1;
}
-extern struct list_head batadv_hardif_list;
extern unsigned int batadv_hardif_generation;
extern struct workqueue_struct *batadv_event_workqueue;
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 0ca0fc072fc9..fc84c2a80020 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -166,9 +166,6 @@ enum batadv_hard_iface_wifi_flags {
* struct batadv_hard_iface - network device known to batman-adv
*/
struct batadv_hard_iface {
- /** @list: list node for batadv_hardif_list */
- struct list_head list;
-
/** @if_status: status of the interface for batman-adv */
char if_status;
--
2.49.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH batadv 5/5] batman-adv: move hardif generation counter into batadv_priv
2025-05-19 20:46 [PATCH batadv 1/5] batman-adv: store hard_iface as iflink private data Matthias Schiffer
` (2 preceding siblings ...)
2025-05-19 20:46 ` [PATCH batadv 4/5] batman-adv: remove global hardif list Matthias Schiffer
@ 2025-05-19 20:46 ` Matthias Schiffer
2025-05-31 9:59 ` Sven Eckelmann
2025-05-31 8:31 ` [PATCH batadv 1/5] batman-adv: store hard_iface as iflink private data Sven Eckelmann
4 siblings, 1 reply; 15+ messages in thread
From: Matthias Schiffer @ 2025-05-19 20:46 UTC (permalink / raw)
To: Marek Lindner, Simon Wunderlich, Antonio Quartulli,
Sven Eckelmann
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, b.a.t.m.a.n, netdev, linux-kernel,
Matthias Schiffer
The counter doesn't need to be global.
Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
---
net/batman-adv/hard-interface.c | 4 ++--
net/batman-adv/main.c | 1 -
net/batman-adv/main.h | 2 --
net/batman-adv/netlink.c | 2 +-
net/batman-adv/types.h | 3 +++
5 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index 5b46104dcf61..90968abefba0 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -748,7 +748,7 @@ int batadv_hardif_enable_interface(struct net_device *net_dev,
hard_iface->mesh_iface = mesh_iface;
bat_priv = netdev_priv(hard_iface->mesh_iface);
- batadv_hardif_generation++;
+ bat_priv->hardif_generation++;
ret = netdev_master_upper_dev_link(hard_iface->net_dev,
mesh_iface, hard_iface, NULL, NULL);
if (ret)
@@ -869,7 +869,7 @@ void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface)
batadv_purge_outstanding_packets(bat_priv, hard_iface);
netdev_put(hard_iface->mesh_iface, &hard_iface->meshif_dev_tracker);
- batadv_hardif_generation++;
+ bat_priv->hardif_generation++;
netdev_upper_dev_unlink(hard_iface->net_dev, hard_iface->mesh_iface);
batadv_hardif_recalc_extra_skbroom(hard_iface->mesh_iface);
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
index 8e8ea93cf61d..f3d82d567968 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -61,7 +61,6 @@
#include "tp_meter.h"
#include "translation-table.h"
-unsigned int batadv_hardif_generation;
static int (*batadv_rx_handler[256])(struct sk_buff *skb,
struct batadv_hard_iface *recv_if);
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h
index debc55922fe1..365d92d04c85 100644
--- a/net/batman-adv/main.h
+++ b/net/batman-adv/main.h
@@ -232,8 +232,6 @@ static inline int batadv_print_vid(unsigned short vid)
return -1;
}
-extern unsigned int batadv_hardif_generation;
-
extern struct workqueue_struct *batadv_event_workqueue;
int batadv_mesh_init(struct net_device *mesh_iface);
diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c
index 41c1e7e0cf0d..23a626c63d40 100644
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -978,7 +978,7 @@ batadv_netlink_dump_hardif(struct sk_buff *msg, struct netlink_callback *cb)
bat_priv = netdev_priv(mesh_iface);
rtnl_lock();
- cb->seq = batadv_hardif_generation << 1 | 1;
+ cb->seq = bat_priv->hardif_generation << 1 | 1;
netdev_for_each_lower_private(mesh_iface, hard_iface, iter) {
if (i++ < skip)
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index fc84c2a80020..f490fe436458 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -1727,6 +1727,9 @@ struct batadv_priv {
/** @tp_num: number of currently active tp sessions */
atomic_t tp_num;
+ /** @hardif_generation: generation counter added to netlink hardif dumps */
+ unsigned int hardif_generation;
+
/** @orig_work: work queue callback item for orig node purging */
struct delayed_work orig_work;
--
2.49.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH batadv 1/5] batman-adv: store hard_iface as iflink private data
2025-05-19 20:46 [PATCH batadv 1/5] batman-adv: store hard_iface as iflink private data Matthias Schiffer
` (3 preceding siblings ...)
2025-05-19 20:46 ` [PATCH batadv 5/5] batman-adv: move hardif generation counter into batadv_priv Matthias Schiffer
@ 2025-05-31 8:31 ` Sven Eckelmann
4 siblings, 0 replies; 15+ messages in thread
From: Sven Eckelmann @ 2025-05-31 8:31 UTC (permalink / raw)
To: Marek Lindner, Simon Wunderlich, Antonio Quartulli,
Matthias Schiffer
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, b.a.t.m.a.n, netdev, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 4341 bytes --]
On Monday, 19 May 2025 22:46:28 CEST Matthias Schiffer wrote:
> By passing the hard_iface to netdev_master_upper_dev_link() as private
> data, we can iterate over hardifs of a mesh interface more efficiently
> using netdev_for_each_lower_private*() (instead of iterating over the
> global hardif list). In addition, this will enable resolving a hardif
> from its netdev using netdev_lower_dev_get_private() and getting rid of
> the global list altogether in the following patches.
>
> A similar approach can be seen in the bonding driver.
>
> Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
> ---
> net/batman-adv/bat_algo.h | 1 -
> net/batman-adv/bat_iv_ogm.c | 25 +++++++--------------
> net/batman-adv/bat_v.c | 6 ++---
> net/batman-adv/bat_v_elp.c | 7 ++----
> net/batman-adv/bat_v_ogm.c | 12 ++++------
> net/batman-adv/hard-interface.c | 39 ++++++++++++---------------------
> net/batman-adv/main.c | 6 ++---
> net/batman-adv/mesh-interface.c | 6 ++---
> net/batman-adv/multicast.c | 6 ++---
> net/batman-adv/netlink.c | 6 ++---
> net/batman-adv/originator.c | 6 ++---
> net/batman-adv/send.c | 6 ++---
> 12 files changed, 43 insertions(+), 83 deletions(-)
Looks mostly good - I just want to modify the includes slightly (if it is ok for you):
index c165dede..ba5bea4c 100644
--- a/net/batman-adv/bat_algo.c
+++ b/net/batman-adv/bat_algo.c
@@ -14,6 +14,7 @@
#include <linux/skbuff.h>
#include <linux/stddef.h>
#include <linux/string.h>
+#include <linux/types.h>
#include <net/genetlink.h>
#include <net/netlink.h>
#include <uapi/linux/batman_adv.h>
diff --git a/net/batman-adv/bat_algo.h b/net/batman-adv/bat_algo.h
index 898c71b5..cdd1ccfe 100644
--- a/net/batman-adv/bat_algo.h
+++ b/net/batman-adv/bat_algo.h
@@ -11,7 +11,6 @@
#include <linux/netlink.h>
#include <linux/skbuff.h>
-#include <linux/types.h>
extern char batadv_routing_algo[];
diff --git a/net/batman-adv/bat_v_elp.c b/net/batman-adv/bat_v_elp.c
index 56b6216f..8df2dcc2 100644
--- a/net/batman-adv/bat_v_elp.c
+++ b/net/batman-adv/bat_v_elp.c
@@ -35,7 +35,6 @@
#include <net/cfg80211.h>
#include <uapi/linux/batadv_packet.h>
-#include "bat_algo.h"
#include "bat_v_ogm.h"
#include "hard-interface.h"
#include "log.h"
diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c
index 5c955ac2..cab83d37 100644
--- a/net/batman-adv/bat_v_ogm.c
+++ b/net/batman-adv/bat_v_ogm.c
@@ -22,7 +22,6 @@
#include <linux/mutex.h>
#include <linux/netdevice.h>
#include <linux/random.h>
-#include <linux/rculist.h>
#include <linux/rcupdate.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
@@ -33,7 +32,6 @@
#include <linux/workqueue.h>
#include <uapi/linux/batadv_packet.h>
-#include "bat_algo.h"
#include "hard-interface.h"
#include "hash.h"
#include "log.h"
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
index af1e644b..d41ce799 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -27,7 +27,6 @@
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/printk.h>
-#include <linux/rculist.h>
#include <linux/rcupdate.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c
index 35d7ecee..5afb1b70 100644
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -20,7 +20,6 @@
#include <linux/if_vlan.h>
#include <linux/init.h>
#include <linux/limits.h>
-#include <linux/list.h>
#include <linux/minmax.h>
#include <linux/netdevice.h>
#include <linux/netlink.h>
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
index 5e4168f8..c13e05d3 100644
--- a/net/batman-adv/originator.c
+++ b/net/batman-adv/originator.c
@@ -29,7 +29,6 @@
#include <linux/workqueue.h>
#include <uapi/linux/batadv_packet.h>
-#include "bat_algo.h"
#include "distributed-arp-table.h"
#include "fragmentation.h"
#include "gateway_client.h"
diff --git a/net/batman-adv/send.c b/net/batman-adv/send.c
index 788fcfd1..a9929948 100644
--- a/net/batman-adv/send.c
+++ b/net/batman-adv/send.c
@@ -21,7 +21,6 @@
#include <linux/list.h>
#include <linux/netdevice.h>
#include <linux/printk.h>
-#include <linux/rculist.h>
#include <linux/rcupdate.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
Thanks,
Sven
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH batadv 2/5] batman-adv: only create hardif while a netdev is part of a mesh
2025-05-19 20:46 ` [PATCH batadv 2/5] batman-adv: only create hardif while a netdev is part of a mesh Matthias Schiffer
@ 2025-05-31 9:16 ` Sven Eckelmann
2025-05-31 9:21 ` Sven Eckelmann
2025-05-31 9:52 ` Sven Eckelmann
1 sibling, 1 reply; 15+ messages in thread
From: Sven Eckelmann @ 2025-05-31 9:16 UTC (permalink / raw)
To: Marek Lindner, Simon Wunderlich, Antonio Quartulli,
Matthias Schiffer
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, b.a.t.m.a.n, netdev, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 3376 bytes --]
On Monday, 19 May 2025 22:46:29 CEST Matthias Schiffer wrote:
> @@ -734,9 +768,6 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
> if (ret < 0)
> goto err_upper;
>
> - hard_iface->if_status = BATADV_IF_INACTIVE;
> -
> - kref_get(&hard_iface->refcount);
> hard_iface->batman_adv_ptype.type = ethertype;
> hard_iface->batman_adv_ptype.func = batadv_batman_skb_recv
This is confusing. You remove the reference for the batman_adv_ptype but kept
the `batadv_hardif_put(hard_iface);` after
`dev_remove_pack(&hard_iface->batman_adv_ptype);`.
I think this should be added again and instead following code should receive a
`batadv_hardif_put(hard_iface);` after the `list_del_rcu(&hard_iface->list);`:
> @@ -818,11 +849,16 @@ void batadv_hardif_disable_interface(struct batadv_hard_iface *hard_iface)
> struct batadv_priv *bat_priv = netdev_priv(hard_iface->mesh_iface);
> struct batadv_hard_iface *primary_if = NULL;
>
> + ASSERT_RTNL();
> +
> batadv_hardif_deactivate_interface(hard_iface);
>
> if (hard_iface->if_status != BATADV_IF_INACTIVE)
> goto out;
>
> + list_del_rcu(&hard_iface->list);
> + batadv_hardif_generation++;
> +
> batadv_info(hard_iface->mesh_iface, "Removing interface: %s\n",
> hard_iface->net_dev->name);
> dev_remove_pack(&hard_iface->batman_adv_ptype);
And yes, this means that this needs to be removed in PATCH 3 again - together
with the `kref_get` from this chunk (from PATCH 3):
On Monday, 19 May 2025 22:46:31 CEST Matthias Schiffer wrote:
> @@ -738,8 +735,6 @@ int batadv_hardif_enable_interface(struct net_device *net_dev,
> batadv_v_hardif_init(hard_iface);
>
> kref_get(&hard_iface->refcount);
> - list_add_tail_rcu(&hard_iface->list, &batadv_hardif_list);
> - batadv_hardif_generation++;
>
> hardif_mtu = READ_ONCE(hard_iface->net_dev->mtu);
> required_mtu = READ_ONCE(mesh_iface->mtu) + max_header_len;
Just a question about this part (you don't really need to change it - I am
just interested). Why did you move this MTU check to such a late position in
the code?
> - hardif_mtu = READ_ONCE(hard_iface->net_dev->mtu);
> - required_mtu = READ_ONCE(mesh_iface->mtu) + max_header_len;
> + ASSERT_RTNL();
>
> - if (hardif_mtu < ETH_MIN_MTU + max_header_len)
> + if (!batadv_is_valid_iface(net_dev))
> return -EINVAL;
>
[...]
> + hard_iface = kzalloc(sizeof(*hard_iface), GFP_ATOMIC);
> + if (!hard_iface)
> + return -ENOMEM;
> +
> + netdev_hold(net_dev, &hard_iface->dev_tracker, GFP_ATOMIC);
> + hard_iface->net_dev = net_dev;
[...]
> + hardif_mtu = READ_ONCE(hard_iface->net_dev->mtu);
> + required_mtu = READ_ONCE(mesh_iface->mtu) + max_header_len;
> +
> + if (hardif_mtu < ETH_MIN_MTU + max_header_len) {
> + ret = -EINVAL;
> + goto err_put;
> + }
It made the error handling more complicated. And at the moment, I don't see
the reason. For me, It would have been been more logical to just a a minimal
invasive change like:
> - hardif_mtu = READ_ONCE(hard_iface->net_dev->mtu);
> + hardif_mtu = READ_ONCE(net_dev->mtu);
Thanks,
Sven
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH batadv 3/5] batman-adv: remove BATADV_IF_NOT_IN_USE hardif state
2025-05-19 20:46 ` [PATCH batadv 3/5] batman-adv: remove BATADV_IF_NOT_IN_USE hardif state Matthias Schiffer
@ 2025-05-31 9:18 ` Sven Eckelmann
0 siblings, 0 replies; 15+ messages in thread
From: Sven Eckelmann @ 2025-05-31 9:18 UTC (permalink / raw)
To: Marek Lindner, Simon Wunderlich, Antonio Quartulli,
Matthias Schiffer
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, b.a.t.m.a.n, netdev, linux-kernel,
Matthias Schiffer
[-- Attachment #1: Type: text/plain, Size: 600 bytes --]
On Monday, 19 May 2025 22:46:30 CEST Matthias Schiffer wrote:
> With hardifs only existing while an interface is part of a mesh, the
> BATADV_IF_NOT_IN_USE state has become redundant.
>
> Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
> ---
> net/batman-adv/bat_iv_ogm.c | 3 +--
> net/batman-adv/bat_v_elp.c | 3 +--
> net/batman-adv/hard-interface.c | 9 ---------
> net/batman-adv/hard-interface.h | 6 ------
> net/batman-adv/originator.c | 4 ----
> 5 files changed, 2 insertions(+), 23 deletions(-)
Acked-by: Sven Eckelmann <sven@narfation.org>
Thanks,
Sven
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH batadv 2/5] batman-adv: only create hardif while a netdev is part of a mesh
2025-05-31 9:16 ` Sven Eckelmann
@ 2025-05-31 9:21 ` Sven Eckelmann
0 siblings, 0 replies; 15+ messages in thread
From: Sven Eckelmann @ 2025-05-31 9:21 UTC (permalink / raw)
To: Marek Lindner, Simon Wunderlich, Antonio Quartulli,
Matthias Schiffer
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, b.a.t.m.a.n, netdev, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 290 bytes --]
On Saturday, 31 May 2025 11:16:30 CEST Sven Eckelmann wrote:
> And yes, this means that this needs to be removed in PATCH 3 again - together
> with the `kref_get` from this chunk (from PATCH 3):
Sorry, I meant [PATCH batadv 4/5] batman-adv: remove global hardif list
Kind regards,
Sven
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH batadv 2/5] batman-adv: only create hardif while a netdev is part of a mesh
2025-05-19 20:46 ` [PATCH batadv 2/5] batman-adv: only create hardif while a netdev is part of a mesh Matthias Schiffer
2025-05-31 9:16 ` Sven Eckelmann
@ 2025-05-31 9:52 ` Sven Eckelmann
1 sibling, 0 replies; 15+ messages in thread
From: Sven Eckelmann @ 2025-05-31 9:52 UTC (permalink / raw)
To: Marek Lindner, Simon Wunderlich, Antonio Quartulli,
Matthias Schiffer
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, b.a.t.m.a.n, netdev, linux-kernel,
Matthias Schiffer
[-- Attachment #1: Type: text/plain, Size: 2589 bytes --]
On Monday, 19 May 2025 22:46:29 CEST Matthias Schiffer wrote:
> -int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
> +int batadv_hardif_enable_interface(struct net_device *net_dev,
> struct net_device *mesh_iface)
> {
[....]
> + hard_iface->wifi_flags = batadv_wifi_flags_evaluate(net_dev);
Moving this here should break the WIFI TT flag in scenarios like this:
┌──────┐
┌───────────┼br-lan├──────┐
│ └──────┘ │
│ │
│ │
┌─▼─┐ ┌──▼─┐
│ap0│ │bat0│
└───┘ └──┬─┘
│
│
┌──▼──┐
│mesh0│
└─────┘
ap0 is not the lower interface of any batadv mesh interface but TT ap
isolation is depending on the information stored for this hardif. See:
/**
* batadv_is_wifi_hardif() - check if the given hardif is a wifi interface
* @hard_iface: the device to check
*
* Return: true if the net device is a 802.11 wireless device, false otherwise.
*/
bool batadv_is_wifi_hardif(struct batadv_hard_iface *hard_iface)
{
if (!hard_iface)
return false;
return hard_iface->wifi_flags != 0;
}
bool batadv_tt_local_add(struct net_device *mesh_iface, const u8 *addr,
unsigned short vid, int ifindex, u32 mark)
{
[...]
if (ifindex != BATADV_NULL_IFINDEX)
in_dev = dev_get_by_index(net, ifindex);
if (in_dev)
in_hardif = batadv_hardif_get_by_netdev(in_dev);
[...]
if (batadv_is_wifi_hardif(in_hardif))
tt_local->common.flags |= BATADV_TT_CLIENT_WIFI;
[...]
static bool
_batadv_is_ap_isolated(struct batadv_tt_local_entry *tt_local_entry,
struct batadv_tt_global_entry *tt_global_entry)
{
if (tt_local_entry->common.flags & BATADV_TT_CLIENT_WIFI &&
tt_global_entry->common.flags & BATADV_TT_CLIENT_WIFI)
return true;
/* check if the two clients are marked as isolated */
if (tt_local_entry->common.flags & BATADV_TT_CLIENT_ISOLA &&
tt_global_entry->common.flags & BATADV_TT_CLIENT_ISOLA)
return true;
return false;
}
Kind regards,
Sven
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH batadv 4/5] batman-adv: remove global hardif list
2025-05-19 20:46 ` [PATCH batadv 4/5] batman-adv: remove global hardif list Matthias Schiffer
@ 2025-05-31 9:56 ` Sven Eckelmann
2025-06-01 9:26 ` Matthias Schiffer
0 siblings, 1 reply; 15+ messages in thread
From: Sven Eckelmann @ 2025-05-31 9:56 UTC (permalink / raw)
To: Marek Lindner, Simon Wunderlich, Antonio Quartulli,
Matthias Schiffer
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, b.a.t.m.a.n, netdev, linux-kernel,
Matthias Schiffer
[-- Attachment #1: Type: text/plain, Size: 3058 bytes --]
On Monday, 19 May 2025 22:46:31 CEST Matthias Schiffer wrote:
> struct batadv_hard_iface *
> -batadv_hardif_get_by_netdev(const struct net_device *net_dev)
> +batadv_hardif_get_by_netdev(struct net_device *net_dev)
> {
> struct batadv_hard_iface *hard_iface;
> + struct net_device *mesh_iface;
>
> - rcu_read_lock();
> - list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
> - if (hard_iface->net_dev == net_dev &&
> - kref_get_unless_zero(&hard_iface->refcount))
> - goto out;
> - }
> + mesh_iface = netdev_master_upper_dev_get(net_dev);
> + if (!mesh_iface || !batadv_meshif_is_valid(mesh_iface))
> + return NULL;
>
> - hard_iface = NULL;
> + hard_iface = netdev_lower_dev_get_private(mesh_iface, net_dev);
> + if (!kref_get_unless_zero(&hard_iface->refcount))
> + return NULL;
>
> -out:
> - rcu_read_unlock();
> return hard_iface;
> }
This code is now relying on rtnl_lock() (see `ASSERT_RTNL` in
`netdev_master_upper_dev_get` and most likely some comments somwhere about the
lists used by `netdev_lower_dev_get_private`). But `batadv_tt_local_add` is
using this function without holding this lock all the time. For example during
packet processing.
See for example `batadv_tt_local_add` calls in `batadv_interface_tx`. This
will happen when `skb->skb_iif` is not 0 (so it was forwarded).
Please double check this - I have not actually tested it but just went through
the code.
And saying this, the `batadv_hardif_get_by_netdev` call was also used to
retrieve additional information about alll kind of interfaces - even when they
are not used by batman-adv directly. For example for figuring out if it is a
wifi interface(for the TT wifi flag). With you change here, you are basically
breaking this functionality because you now require that the netdev is a lower
interface of batman-adv. Therefore, things like:
┌──────┐
┌───────────┼br-lan├──────┐
│ └──────┘ │
│ │
│ │
┌─▼─┐ ┌──▼─┐
│ap0│ │bat0│
└───┘ └──┬─┘
│
│
┌──▼──┐
│mesh0│
└─────┘
Is not handled anymore correctly in TT because ap0 is not a lower interface of
any batadv mesh interface. And as result, the ap-isolation feature of TT
will break.
Kind regards,
Sven
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH batadv 5/5] batman-adv: move hardif generation counter into batadv_priv
2025-05-19 20:46 ` [PATCH batadv 5/5] batman-adv: move hardif generation counter into batadv_priv Matthias Schiffer
@ 2025-05-31 9:59 ` Sven Eckelmann
0 siblings, 0 replies; 15+ messages in thread
From: Sven Eckelmann @ 2025-05-31 9:59 UTC (permalink / raw)
To: Marek Lindner, Simon Wunderlich, Antonio Quartulli,
Matthias Schiffer
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, b.a.t.m.a.n, netdev, linux-kernel,
Matthias Schiffer
[-- Attachment #1: Type: text/plain, Size: 272 bytes --]
On Monday, 19 May 2025 22:46:32 CEST Matthias Schiffer wrote:
> The counter doesn't need to be global.
Yes, with the changes from
[PATCH batadv 1/5] batman-adv: store hard_iface as iflink private data
Acked-by: Sven Eckelmann <sven@narfation.org>
Kind regards,
Sven
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH batadv 4/5] batman-adv: remove global hardif list
2025-05-31 9:56 ` Sven Eckelmann
@ 2025-06-01 9:26 ` Matthias Schiffer
2025-06-01 13:10 ` Sven Eckelmann
0 siblings, 1 reply; 15+ messages in thread
From: Matthias Schiffer @ 2025-06-01 9:26 UTC (permalink / raw)
To: Sven Eckelmann, Marek Lindner, Simon Wunderlich,
Antonio Quartulli
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, b.a.t.m.a.n, netdev, linux-kernel
[-- Attachment #1.1: Type: text/plain, Size: 4005 bytes --]
On 31/05/2025 11:56, Sven Eckelmann wrote:
> On Monday, 19 May 2025 22:46:31 CEST Matthias Schiffer wrote:
>> struct batadv_hard_iface *
>> -batadv_hardif_get_by_netdev(const struct net_device *net_dev)
>> +batadv_hardif_get_by_netdev(struct net_device *net_dev)
>> {
>> struct batadv_hard_iface *hard_iface;
>> + struct net_device *mesh_iface;
>>
>> - rcu_read_lock();
>> - list_for_each_entry_rcu(hard_iface, &batadv_hardif_list, list) {
>> - if (hard_iface->net_dev == net_dev &&
>> - kref_get_unless_zero(&hard_iface->refcount))
>> - goto out;
>> - }
>> + mesh_iface = netdev_master_upper_dev_get(net_dev);
>> + if (!mesh_iface || !batadv_meshif_is_valid(mesh_iface))
>> + return NULL;
>>
>> - hard_iface = NULL;
>> + hard_iface = netdev_lower_dev_get_private(mesh_iface, net_dev);
>> + if (!kref_get_unless_zero(&hard_iface->refcount))
>> + return NULL;
>>
>> -out:
>> - rcu_read_unlock();
>> return hard_iface;
>> }
>
> This code is now relying on rtnl_lock() (see `ASSERT_RTNL` in
> `netdev_master_upper_dev_get` and most likely some comments somwhere about the
> lists used by `netdev_lower_dev_get_private`). But `batadv_tt_local_add` is
> using this function without holding this lock all the time. For example during
> packet processing.
>
> See for example `batadv_tt_local_add` calls in `batadv_interface_tx`. This
> will happen when `skb->skb_iif` is not 0 (so it was forwarded).
>
>
> Please double check this - I have not actually tested it but just went through
> the code.
>
>
> And saying this, the `batadv_hardif_get_by_netdev` call was also used to
> retrieve additional information about alll kind of interfaces - even when they
> are not used by batman-adv directly. For example for figuring out if it is a
> wifi interface(for the TT wifi flag). With you change here, you are basically
> breaking this functionality because you now require that the netdev is a lower
> interface of batman-adv. Therefore, things like:
>
>
> ┌──────┐
> ┌───────────┼br-lan├──────┐
> │ └──────┘ │
> │ │
> │ │
> ┌─▼─┐ ┌──▼─┐
> │ap0│ │bat0│
> └───┘ └──┬─┘
> │
> │
> ┌──▼──┐
> │mesh0│
> └─────┘
>
>
> Is not handled anymore correctly in TT because ap0 is not a lower interface of
> any batadv mesh interface. And as result, the ap-isolation feature of TT
> will break.
>
> Kind regards,
> Sven
Hmm, this is a tricky one. Only having the hardifs around while they're
used for meshing means we need some other way to determine the wifi flags -
but doing it on demand for every batadv_tt_local_add() seems like it could
be used to facilitate a DoS on the RTNL by causing large numbers of TT
entries to be added, as the lock needs to be held for resolving the iflink.
One option might be to add a cache for the wifi flag (and possible other
information, I'll have to check if there is anything else), but store it in
the mesh interface, only for interfaces that are bridged with the mesh.
Cache entries could be created on demand when a local TT entry is added for
an unknown IIF; when to remove cache entries is something I'll have to
figure out.
Simpler ideas how to solve this are welcome :)
Best,
Matthias
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 840 bytes --]
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH batadv 4/5] batman-adv: remove global hardif list
2025-06-01 9:26 ` Matthias Schiffer
@ 2025-06-01 13:10 ` Sven Eckelmann
2025-06-01 13:36 ` Sven Eckelmann
0 siblings, 1 reply; 15+ messages in thread
From: Sven Eckelmann @ 2025-06-01 13:10 UTC (permalink / raw)
To: Marek Lindner, Simon Wunderlich, Antonio Quartulli,
Matthias Schiffer
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, b.a.t.m.a.n, netdev, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 16261 bytes --]
On Sunday, 1 June 2025 11:26:25 CEST Matthias Schiffer wrote:
[...]
> > And saying this, the `batadv_hardif_get_by_netdev` call was also used to
> > retrieve additional information about alll kind of interfaces - even when they
> > are not used by batman-adv directly. For example for figuring out if it is a
> > wifi interface(for the TT wifi flag). With you change here, you are basically
> > breaking this functionality because you now require that the netdev is a lower
> > interface of batman-adv. Therefore, things like:
> >
> >
> > ┌──────┐
> > ┌───────────┼br-lan├──────┐
> > │ └──────┘ │
> > │ │
> > │ │
> > ┌─▼─┐ ┌──▼─┐
> > │ap0│ │bat0│
> > └───┘ └──┬─┘
> > │
> > │
> > ┌──▼──┐
> > │mesh0│
> > └─────┘
> >
> >
> > Is not handled anymore correctly in TT because ap0 is not a lower interface of
> > any batadv mesh interface. And as result, the ap-isolation feature of TT
> > will break.
> >
> > Kind regards,
> > Sven
>
> Hmm, this is a tricky one. Only having the hardifs around while they're
> used for meshing means we need some other way to determine the wifi flags -
> but doing it on demand for every batadv_tt_local_add() seems like it could
> be used to facilitate a DoS on the RTNL by causing large numbers of TT
> entries to be added, as the lock needs to be held for resolving the iflink.
Uhm, using a mutex in this place is a bad idea. If batadv_tt_local_add is
called from the non-batadv_interface_tx context then rtnl_lock is already
held - which is not the biggest problem because we can handle this with more
code. But when it is called from the batadv_interface_tx context then it is
usually in a context which doesn't allow sleeping. Here an example output when
adding an rtnl_lock/rtnl_unlock in this place:
[ 9.141427][ T43] =============================
[ 9.141835][ T43] WARNING: suspicious RCU usage
[ 9.142213][ T43] 6.15.0+ #1 Tainted: G O
[ 9.142630][ T43] -----------------------------
[ 9.142981][ T43] ./include/linux/rcupdate.h:409 Illegal context switch in RCU read-side critical section!
[ 9.143674][ T43]
[ 9.143674][ T43] other info that might help us debug this:
[ 9.143674][ T43]
[ 9.144334][ T43]
[ 9.144334][ T43] rcu_scheduler_active = 2, debug_locks = 1
[ 9.144904][ T43] 6 locks held by kworker/1:2/43:
[ 9.145255][ T43] #0: ffff888007be2558 ((wq_completion)mld){+.+.}-{0:0}, at: process_one_work+0xcee/0x1420
[ 9.145944][ T43] #1: ffff88800792fd38 ((work_completion)(&(&idev->mc_ifc_work)->work)){+.+.}-{0:0}, at: process_one_work+0x798/0x1420
[ 9.146713][ T43] #2: ffff88800a58e5a8 (&idev->mc_lock){+.+.}-{4:4}, at: mld_ifc_work+0x2a/0x200
[ 9.147319][ T43] #3: ffffffff83405120 (rcu_read_lock){....}-{1:3}, at: mld_sendpack+0x17f/0xc00
[ 9.147949][ T43] #4: ffffffff83405120 (rcu_read_lock){....}-{1:3}, at: ip6_finish_output2+0x294/0x1650
[ 9.148621][ T43] #5: ffffffff834050c0 (rcu_read_lock_bh){....}-{1:3}, at: __dev_queue_xmit+0x18a/0xff0
[ 9.149286][ T43]
[ 9.149286][ T43] stack backtrace:
[ 9.149743][ T43] CPU: 1 UID: 0 PID: 43 Comm: kworker/1:2 Tainted: G O 6.15.0+ #1 NONE
[ 9.149747][ T43] Tainted: [O]=OOT_MODULE
[ 9.149748][ T43] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.1 11/11/2019
[ 9.149751][ T43] Workqueue: mld mld_ifc_work
[ 9.149754][ T43] Call Trace:
[ 9.149756][ T43] <TASK>
[ 9.149759][ T43] dump_stack_lvl+0x6f/0xa0
[ 9.149764][ T43] lockdep_rcu_suspicious.cold+0x4e/0x8b
[ 9.149768][ T43] __might_resched+0x26a/0x380
[ 9.149771][ T43] ? rcu_read_unlock+0x80/0x80
[ 9.149773][ T43] ? batadv_primary_if_get_selected+0x320/0x320 [batman_adv]
[ 9.149786][ T43] ? mark_held_locks+0x40/0x70
[ 9.149791][ T43] __mutex_lock+0x113/0x1be0
[ 9.149795][ T43] ? batadv_tt_local_add+0x3d4/0x1d20 [batman_adv]
[ 9.149807][ T43] ? batadv_bla_get_backbone_gw+0xad1/0xdf0 [batman_adv]
[ 9.149819][ T43] ? mutex_lock_io_nested+0x18d0/0x18d0
[ 9.149824][ T43] ? batadv_bla_claim_dump_entry.isra.0+0x6d0/0x6d0 [batman_adv]
[ 9.149835][ T43] ? ret_from_fork_asm+0x11/0x20
[ 9.149841][ T43] ? batadv_tt_local_add+0x3d4/0x1d20 [batman_adv]
[ 9.149852][ T43] ? batadv_bla_rx+0xe00/0xe00 [batman_adv]
[ 9.149862][ T43] batadv_tt_local_add+0x3d4/0x1d20 [batman_adv]
[ 9.149878][ T43] ? batadv_tt_global_hash_count+0x110/0x110 [batman_adv]
[ 9.149892][ T43] batadv_interface_tx+0x4b4/0x1820 [batman_adv]
[ 9.149905][ T43] ? batadv_skb_head_push+0x220/0x220 [batman_adv]
[ 9.149917][ T43] ? skb_csum_hwoffload_help+0x650/0x650
[ 9.149922][ T43] dev_hard_start_xmit+0x15c/0x640
[ 9.149926][ T43] ? validate_xmit_skb.isra.0+0x62/0x4a0
[ 9.149930][ T43] __dev_queue_xmit+0x44d/0xff0
[ 9.149933][ T43] ? netdev_core_pick_tx+0x230/0x230
[ 9.149938][ T43] ip6_finish_output2+0x7f8/0x1650
[ 9.149942][ T43] ? icmp6_dst_alloc+0x30a/0x480
[ 9.149946][ T43] mld_sendpack+0x5de/0xc00
[ 9.149951][ T43] ? mld_report_work+0x620/0x620
[ 9.149957][ T43] ? mld_send_cr+0x4ff/0x7f0
[ 9.149961][ T43] mld_ifc_work+0x32/0x200
[ 9.149965][ T43] process_one_work+0x814/0x1420
[ 9.149971][ T43] ? pwq_dec_nr_in_flight+0x540/0x540
[ 9.149977][ T43] ? assign_work+0x168/0x240
[ 9.149980][ T43] worker_thread+0x618/0x1010
[ 9.149985][ T43] ? __kthread_parkme+0xf7/0x260
[ 9.149989][ T43] ? process_one_work+0x1420/0x1420
[ 9.149991][ T43] kthread+0x3bb/0x760
[ 9.149994][ T43] ? kvm_sched_clock_read+0x11/0x20
[ 9.149997][ T43] ? local_clock_noinstr+0x4e/0xe0
[ 9.150000][ T43] ? kthread_is_per_cpu+0xc0/0xc0
[ 9.150002][ T43] ? __lock_release+0x154/0x2a0
[ 9.150005][ T43] ? ret_from_fork+0x1b/0x70
[ 9.150010][ T43] ? kthread_is_per_cpu+0xc0/0xc0
[ 9.150012][ T43] ret_from_fork+0x31/0x70
[ 9.150015][ T43] ? kthread_is_per_cpu+0xc0/0xc0
[ 9.150018][ T43] ret_from_fork_asm+0x11/0x20
[ 9.150025][ T43] </TASK>
[ 9.150026][ T43]
[ 9.171355][ T43] =============================
[ 9.171360][ T43] WARNING: suspicious RCU usage
[ 9.171363][ T43] 6.15.0+ #1 Tainted: G O
[ 9.171366][ T43] -----------------------------
[ 9.171367][ T43] kernel/sched/core.c:8780 Illegal context switch in RCU-bh read-side critical section!
[ 9.171371][ T43]
[ 9.171371][ T43] other info that might help us debug this:
[ 9.171371][ T43]
[ 9.171372][ T43]
[ 9.171372][ T43] rcu_scheduler_active = 2, debug_locks = 1
[ 9.171374][ T43] 6 locks held by kworker/1:2/43:
[ 9.171377][ T43] #0: ffff888007be2558 ((wq_completion)mld){+.+.}-{0:0}, at: process_one_work+0xcee/0x1420
[ 9.171392][ T43] #1: ffff88800792fd38 ((work_completion)(&(&idev->mc_ifc_work)->work)){+.+.}-{0:0}, at: process_one_work+0x798/0x1420
[ 9.171402][ T43] #2: ffff88800a58e5a8 (&idev->mc_lock){+.+.}-{4:4}, at: mld_ifc_work+0x2a/0x200
[ 9.171413][ T43] #3: ffffffff83405120 (rcu_read_lock){....}-{1:3}, at: mld_sendpack+0x17f/0xc00
[ 9.171423][ T43] #4: ffffffff83405120 (rcu_read_lock){....}-{1:3}, at: ip6_finish_output2+0x294/0x1650
[ 9.171433][ T43] #5: ffffffff834050c0 (rcu_read_lock_bh){....}-{1:3}, at: __dev_queue_xmit+0x18a/0xff0
[ 9.171459][ T43]
[ 9.171459][ T43] stack backtrace:
[ 9.171462][ T43] CPU: 1 UID: 0 PID: 43 Comm: kworker/1:2 Tainted: G O 6.15.0+ #1 NONE
[ 9.171467][ T43] Tainted: [O]=OOT_MODULE
[ 9.171468][ T43] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.1 11/11/2019
[ 9.171470][ T43] Workqueue: mld mld_ifc_work
[ 9.171474][ T43] Call Trace:
[ 9.171476][ T43] <TASK>
[ 9.171479][ T43] dump_stack_lvl+0x6f/0xa0
[ 9.171484][ T43] lockdep_rcu_suspicious.cold+0x4e/0x8b
[ 9.171490][ T43] __might_resched+0x336/0x380
[ 9.171493][ T43] ? rcu_read_unlock+0x80/0x80
[ 9.171496][ T43] ? batadv_primary_if_get_selected+0x320/0x320 [batman_adv]
[ 9.171508][ T43] ? mark_held_locks+0x40/0x70
[ 9.171513][ T43] __mutex_lock+0x113/0x1be0
[ 9.171517][ T43] ? batadv_tt_local_add+0x3d4/0x1d20 [batman_adv]
[ 9.171529][ T43] ? batadv_bla_get_backbone_gw+0xad1/0xdf0 [batman_adv]
[ 9.171541][ T43] ? mutex_lock_io_nested+0x18d0/0x18d0
[ 9.171546][ T43] ? batadv_bla_claim_dump_entry.isra.0+0x6d0/0x6d0 [batman_adv]
[ 9.171557][ T43] ? ret_from_fork_asm+0x11/0x20
[ 9.171564][ T43] ? batadv_tt_local_add+0x3d4/0x1d20 [batman_adv]
[ 9.171574][ T43] ? batadv_bla_rx+0xe00/0xe00 [batman_adv]
[ 9.171585][ T43] batadv_tt_local_add+0x3d4/0x1d20 [batman_adv]
[ 9.171601][ T43] ? batadv_tt_global_hash_count+0x110/0x110 [batman_adv]
[ 9.171616][ T43] batadv_interface_tx+0x4b4/0x1820 [batman_adv]
[ 9.171629][ T43] ? batadv_skb_head_push+0x220/0x220 [batman_adv]
[ 9.171641][ T43] ? skb_csum_hwoffload_help+0x650/0x650
[ 9.171647][ T43] dev_hard_start_xmit+0x15c/0x640
[ 9.171650][ T43] ? validate_xmit_skb.isra.0+0x62/0x4a0
[ 9.171654][ T43] __dev_queue_xmit+0x44d/0xff0
[ 9.171657][ T43] ? netdev_core_pick_tx+0x230/0x230
[ 9.171663][ T43] ip6_finish_output2+0x7f8/0x1650
[ 9.171667][ T43] ? icmp6_dst_alloc+0x30a/0x480
[ 9.171671][ T43] mld_sendpack+0x5de/0xc00
[ 9.171676][ T43] ? mld_report_work+0x620/0x620
[ 9.171682][ T43] ? mld_send_cr+0x4ff/0x7f0
[ 9.171686][ T43] mld_ifc_work+0x32/0x200
[ 9.171690][ T43] process_one_work+0x814/0x1420
[ 9.171696][ T43] ? pwq_dec_nr_in_flight+0x540/0x540
[ 9.171702][ T43] ? assign_work+0x168/0x240
[ 9.171706][ T43] worker_thread+0x618/0x1010
[ 9.171710][ T43] ? __kthread_parkme+0xf7/0x260
[ 9.171715][ T43] ? process_one_work+0x1420/0x1420
[ 9.171717][ T43] kthread+0x3bb/0x760
[ 9.171720][ T43] ? kvm_sched_clock_read+0x11/0x20
[ 9.171723][ T43] ? local_clock_noinstr+0x4e/0xe0
[ 9.171727][ T43] ? kthread_is_per_cpu+0xc0/0xc0
[ 9.171729][ T43] ? __lock_release+0x154/0x2a0
[ 9.171732][ T43] ? ret_from_fork+0x1b/0x70
[ 9.171736][ T43] ? kthread_is_per_cpu+0xc0/0xc0
[ 9.171739][ T43] ret_from_fork+0x31/0x70
[ 9.171742][ T43] ? kthread_is_per_cpu+0xc0/0xc0
[ 9.171745][ T43] ret_from_fork_asm+0x11/0x20
[ 9.171752][ T43] </TASK>
[ 9.171754][ T43] BUG: sleeping function called from invalid context at kernel/locking/mutex.c:578
[ 9.171756][ T43] in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 43, name: kworker/1:2
[ 9.171759][ T43] preempt_count: 202, expected: 0
[ 9.171761][ T43] 6 locks held by kworker/1:2/43:
[ 9.171763][ T43] #0: ffff888007be2558 ((wq_completion)mld){+.+.}-{0:0}, at: process_one_work+0xcee/0x1420
[ 9.171774][ T43] #1: ffff88800792fd38 ((work_completion)(&(&idev->mc_ifc_work)->work)){+.+.}-{0:0}, at: process_one_work+0x798/0x1420
[ 9.171784][ T43] #2: ffff88800a58e5a8 (&idev->mc_lock){+.+.}-{4:4}, at: mld_ifc_work+0x2a/0x200
[ 9.171794][ T43] #3: ffffffff83405120 (rcu_read_lock){....}-{1:3}, at: mld_sendpack+0x17f/0xc00
[ 9.171804][ T43] #4: ffffffff83405120 (rcu_read_lock){....}-{1:3}, at: ip6_finish_output2+0x294/0x1650
[ 9.171813][ T43] #5: ffffffff834050c0 (rcu_read_lock_bh){....}-{1:3}, at: __dev_queue_xmit+0x18a/0xff0
[ 9.171823][ T43] CPU: 1 UID: 0 PID: 43 Comm: kworker/1:2 Tainted: G O 6.15.0+ #1 NONE
[ 9.171827][ T43] Tainted: [O]=OOT_MODULE
[ 9.171828][ T43] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.1 11/11/2019
[ 9.171829][ T43] Workqueue: mld mld_ifc_work
[ 9.171832][ T43] Call Trace:
[ 9.171833][ T43] <TASK>
[ 9.171834][ T43] dump_stack_lvl+0x6f/0xa0
[ 9.171838][ T43] __might_resched.cold+0x160/0x1bc
[ 9.171842][ T43] ? rcu_read_unlock+0x80/0x80
[ 9.171844][ T43] ? batadv_primary_if_get_selected+0x320/0x320 [batman_adv]
[ 9.171855][ T43] ? mark_held_locks+0x40/0x70
[ 9.171859][ T43] __mutex_lock+0x113/0x1be0
[ 9.171863][ T43] ? batadv_tt_local_add+0x3d4/0x1d20 [batman_adv]
[ 9.171874][ T43] ? batadv_bla_get_backbone_gw+0xad1/0xdf0 [batman_adv]
[ 9.171886][ T43] ? mutex_lock_io_nested+0x18d0/0x18d0
[ 9.171891][ T43] ? batadv_bla_claim_dump_entry.isra.0+0x6d0/0x6d0 [batman_adv]
[ 9.171902][ T43] ? ret_from_fork_asm+0x11/0x20
[ 9.171908][ T43] ? batadv_tt_local_add+0x3d4/0x1d20 [batman_adv]
[ 9.171919][ T43] ? batadv_bla_rx+0xe00/0xe00 [batman_adv]
[ 9.171929][ T43] batadv_tt_local_add+0x3d4/0x1d20 [batman_adv]
[ 9.171945][ T43] ? batadv_tt_global_hash_count+0x110/0x110 [batman_adv]
[ 9.171960][ T43] batadv_interface_tx+0x4b4/0x1820 [batman_adv]
[ 9.171972][ T43] ? batadv_skb_head_push+0x220/0x220 [batman_adv]
[ 9.171984][ T43] ? skb_csum_hwoffload_help+0x650/0x650
[ 9.171990][ T43] dev_hard_start_xmit+0x15c/0x640
[ 9.171993][ T43] ? validate_xmit_skb.isra.0+0x62/0x4a0
[ 9.171997][ T43] __dev_queue_xmit+0x44d/0xff0
[ 9.172000][ T43] ? netdev_core_pick_tx+0x230/0x230
[ 9.172006][ T43] ip6_finish_output2+0x7f8/0x1650
[ 9.172010][ T43] ? icmp6_dst_alloc+0x30a/0x480
[ 9.172013][ T43] mld_sendpack+0x5de/0xc00
[ 9.172018][ T43] ? mld_report_work+0x620/0x620
[ 9.172024][ T43] ? mld_send_cr+0x4ff/0x7f0
[ 9.172029][ T43] mld_ifc_work+0x32/0x200
[ 9.172032][ T43] process_one_work+0x814/0x1420
[ 9.172039][ T43] ? pwq_dec_nr_in_flight+0x540/0x540
[ 9.172044][ T43] ? assign_work+0x168/0x240
[ 9.172048][ T43] worker_thread+0x618/0x1010
[ 9.172053][ T43] ? __kthread_parkme+0xf7/0x260
[ 9.172056][ T43] ? process_one_work+0x1420/0x1420
[ 9.172059][ T43] kthread+0x3bb/0x760
[ 9.172061][ T43] ? kvm_sched_clock_read+0x11/0x20
[ 9.172065][ T43] ? local_clock_noinstr+0x4e/0xe0
[ 9.172069][ T43] ? kthread_is_per_cpu+0xc0/0xc0
[ 9.172072][ T43] ? __lock_release+0x154/0x2a0
[ 9.172076][ T43] ? ret_from_fork+0x1b/0x70
[ 9.172080][ T43] ? kthread_is_per_cpu+0xc0/0xc0
[ 9.172084][ T43] ret_from_fork+0x31/0x70
[ 9.172089][ T43] ? kthread_is_per_cpu+0xc0/0xc0
[ 9.172092][ T43] ret_from_fork_asm+0x11/0x20
[ 9.172100][ T43] </TASK>
So, even getting the parent (see `ASSERT_RTNL` in
`netdev_master_upper_dev_get`) of the lower interface is a no-go at that
point.
> One option might be to add a cache for the wifi flag (and possible other
> information, I'll have to check if there is anything else), but store it in
> the mesh interface, only for interfaces that are bridged with the mesh.
> Cache entries could be created on demand when a local TT entry is added for
> an unknown IIF; when to remove cache entries is something I'll have to
> figure out.
>
> Simpler ideas how to solve this are welcome :)
Having something like a simple (rcu)hash(table) (yes, similar to the global
hardif list), which only stores entries for non-mesh netdev's when they are
(above) a wifi interface, might be enough. It is only for the
"ap-isolation" feature but I guess that someone will not be happy if we
break it.
Kind regards,
Sven
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH batadv 4/5] batman-adv: remove global hardif list
2025-06-01 13:10 ` Sven Eckelmann
@ 2025-06-01 13:36 ` Sven Eckelmann
0 siblings, 0 replies; 15+ messages in thread
From: Sven Eckelmann @ 2025-06-01 13:36 UTC (permalink / raw)
To: Marek Lindner, Simon Wunderlich, Antonio Quartulli,
Matthias Schiffer
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, b.a.t.m.a.n, netdev, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 836 bytes --]
On Sunday, 1 June 2025 15:10:50 CEST Sven Eckelmann wrote:
> So, even getting the parent (see `ASSERT_RTNL` in
> `netdev_master_upper_dev_get`) of the lower interface is a no-go at that
> point.
I didn't want to say here that this specific operation is necessary here. Just
wanted to point out that operating on these data structures might not always
be possible at that point. This is why I tried to point out that it might be
better to have something "good enough" using RCU which is managed outside this
context (write-only protected using rtnl_lock).
The idea of having something specific to meshif that still manages to detect
(beforehand) if there's a path to `batadv_interface_tx` - while `skb_iif`
remains set to a specific interface along the way - sounds like an
implementation nightmare to me.
Kind regards,
Sven
[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2025-06-01 13:36 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-05-19 20:46 [PATCH batadv 1/5] batman-adv: store hard_iface as iflink private data Matthias Schiffer
2025-05-19 20:46 ` [PATCH batadv 2/5] batman-adv: only create hardif while a netdev is part of a mesh Matthias Schiffer
2025-05-31 9:16 ` Sven Eckelmann
2025-05-31 9:21 ` Sven Eckelmann
2025-05-31 9:52 ` Sven Eckelmann
2025-05-19 20:46 ` [PATCH batadv 3/5] batman-adv: remove BATADV_IF_NOT_IN_USE hardif state Matthias Schiffer
2025-05-31 9:18 ` Sven Eckelmann
2025-05-19 20:46 ` [PATCH batadv 4/5] batman-adv: remove global hardif list Matthias Schiffer
2025-05-31 9:56 ` Sven Eckelmann
2025-06-01 9:26 ` Matthias Schiffer
2025-06-01 13:10 ` Sven Eckelmann
2025-06-01 13:36 ` Sven Eckelmann
2025-05-19 20:46 ` [PATCH batadv 5/5] batman-adv: move hardif generation counter into batadv_priv Matthias Schiffer
2025-05-31 9:59 ` Sven Eckelmann
2025-05-31 8:31 ` [PATCH batadv 1/5] batman-adv: store hard_iface as iflink private data Sven Eckelmann
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).