bonding: fix event handling for stacked bonds [Linux 4.4.179]

bonding: fix event handling for stacked bonds [Linux 4.4.179]

This Linux kernel change "bonding: fix event handling for stacked bonds" is included in the Linux 4.4.179 release. This change is authored by Sabrina Dubroca <sd [at] queasysnail.net> on Fri Apr 12 15:04:10 2019 +0200. The commit for this change in Linux stable tree is d8e18cc (patch) which is from upstream commit 92480b3. The same Linux upstream change may have been applied to various maintained Linux releases and you can find all Linux releases containing changes from upstream 92480b3.

bonding: fix event handling for stacked bonds

[ Upstream commit 92480b3977fd3884649d404cbbaf839b70035699 ]

When a bond is enslaved to another bond, bond_netdev_event() only
handles the event as if the bond is a master, and skips treating the
bond as a slave.

This leads to a refcount leak on the slave, since we don't remove the
adjacency to its master and the master holds a reference on the slave.

Reproducer:
  ip link add bondL type bond
  ip link add bondU type bond
  ip link set bondL master bondU
  ip link del bondL

No "Fixes:" tag, this code is older than git history.

Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

There are 6 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 drivers/net/bonding/bond_main.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index a32dcb6..fde7f5e 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -3067,8 +3067,12 @@ static int bond_netdev_event(struct notifier_block *this,
        return NOTIFY_DONE;

    if (event_dev->flags & IFF_MASTER) {
+       int ret;
+
        netdev_dbg(event_dev, "IFF_MASTER\n");
-       return bond_master_netdev_event(event, event_dev);
+       ret = bond_master_netdev_event(event, event_dev);
+       if (ret != NOTIFY_DONE)
+           return ret;
    }

    if (event_dev->flags & IFF_SLAVE) {

Leave a Reply

Your email address will not be published. Required fields are marked *