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

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.orgSigned-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parents 4b3e33fc c4c5c5d2
...@@ -582,7 +582,6 @@ static void bond_ipsec_del_sa_all(struct bonding *bond) ...@@ -582,7 +582,6 @@ static void bond_ipsec_del_sa_all(struct bonding *bond)
} else { } else {
slave->dev->xfrmdev_ops->xdo_dev_state_delete(ipsec->xs); slave->dev->xfrmdev_ops->xdo_dev_state_delete(ipsec->xs);
} }
ipsec->xs->xso.real_dev = NULL;
} }
spin_unlock_bh(&bond->ipsec_lock); spin_unlock_bh(&bond->ipsec_lock);
rcu_read_unlock(); rcu_read_unlock();
...@@ -599,34 +598,30 @@ static bool bond_ipsec_offload_ok(struct sk_buff *skb, struct xfrm_state *xs) ...@@ -599,34 +598,30 @@ static bool bond_ipsec_offload_ok(struct sk_buff *skb, struct xfrm_state *xs)
struct net_device *real_dev; struct net_device *real_dev;
struct slave *curr_active; struct slave *curr_active;
struct bonding *bond; struct bonding *bond;
int err; bool ok = false;
bond = netdev_priv(bond_dev); bond = netdev_priv(bond_dev);
rcu_read_lock(); rcu_read_lock();
curr_active = rcu_dereference(bond->curr_active_slave); curr_active = rcu_dereference(bond->curr_active_slave);
if (!curr_active)
goto out;
real_dev = curr_active->dev; real_dev = curr_active->dev;
if (BOND_MODE(bond) != BOND_MODE_ACTIVEBACKUP) { if (BOND_MODE(bond) != BOND_MODE_ACTIVEBACKUP)
err = false;
goto out; goto out;
}
if (!xs->xso.real_dev) { if (!xs->xso.real_dev)
err = false;
goto out; goto out;
}
if (!real_dev->xfrmdev_ops || if (!real_dev->xfrmdev_ops ||
!real_dev->xfrmdev_ops->xdo_dev_offload_ok || !real_dev->xfrmdev_ops->xdo_dev_offload_ok ||
netif_is_bond_master(real_dev)) { netif_is_bond_master(real_dev))
err = false;
goto out; 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: out:
rcu_read_unlock(); rcu_read_unlock();
return err; return ok;
} }
static const struct xfrmdev_ops bond_xfrmdev_ops = { static const struct xfrmdev_ops bond_xfrmdev_ops = {
......
...@@ -936,7 +936,7 @@ static int bond_option_active_slave_set(struct bonding *bond, ...@@ -936,7 +936,7 @@ static int bond_option_active_slave_set(struct bonding *bond,
/* check to see if we are clearing active */ /* check to see if we are clearing active */
if (!slave_dev) { if (!slave_dev) {
netdev_dbg(bond->dev, "Clearing current active slave\n"); 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); bond_select_active_slave(bond);
} else { } else {
struct slave *old_active = rtnl_dereference(bond->curr_active_slave); struct slave *old_active = rtnl_dereference(bond->curr_active_slave);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment