Commit 7565c39d authored by Paolo Abeni's avatar Paolo Abeni
Browse files

Merge branch 'bonding-fix-xfrm-offload-bugs'

Nikolay Aleksandrov says:

====================
bonding: fix xfrm offload bugs

I noticed these problems while reviewing a bond xfrm patch recently.
The fixes are straight-forward, please review carefully the last one
because it has side-effects. This set has passed bond's selftests
and my custom bond stress tests which crash without these fixes.

Note the first patch is not critical, but it simplifies the next fix.
====================

Link: https://patch.msgid.link/20240816114813.326645-1-razor@blackwall.org


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parents 4b3e33fc c4c5c5d2
Loading
Loading
Loading
Loading
+8 −13
Original line number Diff line number Diff line
@@ -582,7 +582,6 @@ static void bond_ipsec_del_sa_all(struct bonding *bond)
		} else {
			slave->dev->xfrmdev_ops->xdo_dev_state_delete(ipsec->xs);
		}
		ipsec->xs->xso.real_dev = NULL;
	}
	spin_unlock_bh(&bond->ipsec_lock);
	rcu_read_unlock();
@@ -599,34 +598,30 @@ static bool bond_ipsec_offload_ok(struct sk_buff *skb, struct xfrm_state *xs)
	struct net_device *real_dev;
	struct slave *curr_active;
	struct bonding *bond;
	int err;
	bool ok = false;

	bond = netdev_priv(bond_dev);
	rcu_read_lock();
	curr_active = rcu_dereference(bond->curr_active_slave);
	if (!curr_active)
		goto out;
	real_dev = curr_active->dev;

	if (BOND_MODE(bond) != BOND_MODE_ACTIVEBACKUP) {
		err = false;
	if (BOND_MODE(bond) != BOND_MODE_ACTIVEBACKUP)
		goto out;
	}

	if (!xs->xso.real_dev) {
		err = false;
	if (!xs->xso.real_dev)
		goto out;
	}

	if (!real_dev->xfrmdev_ops ||
	    !real_dev->xfrmdev_ops->xdo_dev_offload_ok ||
	    netif_is_bond_master(real_dev)) {
		err = false;
	    netif_is_bond_master(real_dev))
		goto out;
	}

	err = real_dev->xfrmdev_ops->xdo_dev_offload_ok(skb, xs);
	ok = real_dev->xfrmdev_ops->xdo_dev_offload_ok(skb, xs);
out:
	rcu_read_unlock();
	return err;
	return ok;
}

static const struct xfrmdev_ops bond_xfrmdev_ops = {
+1 −1
Original line number Diff line number Diff line
@@ -936,7 +936,7 @@ static int bond_option_active_slave_set(struct bonding *bond,
	/* check to see if we are clearing active */
	if (!slave_dev) {
		netdev_dbg(bond->dev, "Clearing current active slave\n");
		RCU_INIT_POINTER(bond->curr_active_slave, NULL);
		bond_change_active_slave(bond, NULL);
		bond_select_active_slave(bond);
	} else {
		struct slave *old_active = rtnl_dereference(bond->curr_active_slave);