From: Sven Eckelmann 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 Signed-off-by: Sven Eckelmann 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); }