50 lines
1.9 KiB
Diff
50 lines
1.9 KiB
Diff
From: Sven Eckelmann <sven@narfation.org>
|
|
Date: Sat, 13 Jun 2020 17:59:34 +0200
|
|
Subject: batctl: Only remove batadv interface on hardif reduction
|
|
|
|
A deletion of a hardif from a batadv meshif will also get a success reply
|
|
from the kernel when the hardif was never part of the batadv meshif. If the
|
|
batadv meshif had no attached hardifs before the removal was started, then
|
|
users are then not expecting that the batadv meshif is removed at all.
|
|
|
|
Since the delete operation is not an atomic compare-and-swap operation,
|
|
just check first the number of attached interfaces and only start the
|
|
removal of the batadv meshif when the number attached hardifs was reduced.
|
|
|
|
Fixes: 25022e0b154d ("batctl: Use rtnl to add/remove interfaces")
|
|
Reported-by: Matthias Schiffer <mschiffer@universe-factory.net>
|
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
|
|
|
Origin: upstream, https://git.open-mesh.org/batctl.git/commit/6d49a82cf58ee5ebd6235b6ddaca46febd42f876
|
|
|
|
diff --git a/interface.c b/interface.c
|
|
index 0a694c9f41f71a3dd72ae87b79b28434f7e8918f..138a6cd45744081a04f986fe4be67901b3305b74 100644
|
|
--- a/interface.c
|
|
+++ b/interface.c
|
|
@@ -386,6 +386,7 @@ static int interface(struct state *state, int argc, char **argv)
|
|
int ret;
|
|
unsigned int ifindex;
|
|
unsigned int ifmaster;
|
|
+ unsigned int pre_cnt;
|
|
const char *long_op;
|
|
unsigned int cnt;
|
|
int rest_argc;
|
|
@@ -502,6 +503,8 @@ static int interface(struct state *state, int argc, char **argv)
|
|
goto err;
|
|
}
|
|
|
|
+ pre_cnt = count_interfaces(state->mesh_iface);
|
|
+
|
|
for (i = 1; i < rest_argc; i++) {
|
|
ifindex = if_nametoindex(rest_argv[i]);
|
|
|
|
@@ -531,7 +534,7 @@ static int interface(struct state *state, int argc, char **argv)
|
|
/* check if there is no interface left and then destroy mesh_iface */
|
|
if (!manual_mode && rest_argv[0][0] == 'd') {
|
|
cnt = count_interfaces(state->mesh_iface);
|
|
- if (cnt == 0)
|
|
+ if (cnt == 0 && pre_cnt > 0)
|
|
destroy_interface(state->mesh_iface);
|
|
}
|
|
|