batman-adv: Fix duplicated OGMs on NETDEV_UP
authorSven Eckelmann <sven@narfation.org>
Mon, 16 Mar 2020 22:30:29 +0000 (23:30 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 20 Mar 2020 09:54:22 +0000 (10:54 +0100)
commit 9e6b5648bbc4cd48fab62cecbb81e9cc3c6e7e88 upstream.

The state of slave interfaces are handled differently depending on whether
the interface is up or not. All active interfaces (IFF_UP) will transmit
OGMs. But for B.A.T.M.A.N. IV, also non-active interfaces are scheduling
(low TTL) OGMs on active interfaces. The code which setups and schedules
the OGMs must therefore already be called when the interfaces gets added as
slave interface and the transmit function must then check whether it has to
send out the OGM or not on the specific slave interface.

But the commit f0d97253fb5f ("batman-adv: remove ogm_emit and ogm_schedule
API calls") moved the setup code from the enable function to the activate
function. The latter is called either when the added slave was already up
when batadv_hardif_enable_interface processed the new interface or when a
NETDEV_UP event was received for this slave interfac. As result, each
NETDEV_UP would schedule a new OGM worker for the interface and thus OGMs
would be send a lot more than expected.

Fixes: f0d97253fb5f ("batman-adv: remove ogm_emit and ogm_schedule API calls")
Reported-by: Linus Lüssing <linus.luessing@c0d3.blue>
Tested-by: Linus Lüssing <linus.luessing@c0d3.blue>
Acked-by: Marek Lindner <mareklindner@neomailbox.ch>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
net/batman-adv/bat_iv_ogm.c
net/batman-adv/hard-interface.c
net/batman-adv/types.h

index 0b2f699244447b91be84da56476e7be18fb57c16..0ed33a9a41b79b2f29069a0c05ecbbdabf956e29 100644 (file)
@@ -2481,7 +2481,7 @@ batadv_iv_ogm_neigh_is_sob(struct batadv_neigh_node *neigh1,
        return ret;
 }
 
-static void batadv_iv_iface_activate(struct batadv_hard_iface *hard_iface)
+static void batadv_iv_iface_enabled(struct batadv_hard_iface *hard_iface)
 {
        /* begin scheduling originator messages on that interface */
        batadv_iv_ogm_schedule(hard_iface);
@@ -2821,8 +2821,8 @@ static void batadv_iv_gw_dump(struct sk_buff *msg, struct netlink_callback *cb,
 static struct batadv_algo_ops batadv_batman_iv __read_mostly = {
        .name = "BATMAN_IV",
        .iface = {
-               .activate = batadv_iv_iface_activate,
                .enable = batadv_iv_ogm_iface_enable,
+               .enabled = batadv_iv_iface_enabled,
                .disable = batadv_iv_ogm_iface_disable,
                .update_mac = batadv_iv_ogm_iface_update_mac,
                .primary_set = batadv_iv_ogm_primary_iface_set,
index c43887fa29a9210f27f29ac3dd373fe627b3326d..63760967712ede23934ecbf608ebb19b7010cec3 100644 (file)
@@ -795,6 +795,9 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
 
        batadv_hardif_recalc_extra_skbroom(soft_iface);
 
+       if (bat_priv->algo_ops->iface.enabled)
+               bat_priv->algo_ops->iface.enabled(hard_iface);
+
 out:
        return 0;
 
index dbeaa015edc98f440f9d75b53890b0af8d4fef1e..7ecf268e6626773f2608de647b363ff9864e61dc 100644 (file)
@@ -1424,6 +1424,7 @@ struct batadv_forw_packet {
  * @activate: start routing mechanisms when hard-interface is brought up
  *  (optional)
  * @enable: init routing info when hard-interface is enabled
+ * @enabled: notification when hard-interface was enabled (optional)
  * @disable: de-init routing info when hard-interface is disabled
  * @update_mac: (re-)init mac addresses of the protocol information
  *  belonging to this hard-interface
@@ -1432,6 +1433,7 @@ struct batadv_forw_packet {
 struct batadv_algo_iface_ops {
        void (*activate)(struct batadv_hard_iface *hard_iface);
        int (*enable)(struct batadv_hard_iface *hard_iface);
+       void (*enabled)(struct batadv_hard_iface *hard_iface);
        void (*disable)(struct batadv_hard_iface *hard_iface);
        void (*update_mac)(struct batadv_hard_iface *hard_iface);
        void (*primary_set)(struct batadv_hard_iface *hard_iface);