diff options
author | Shlomo Pongratz <shlomop@mellanox.com> | 2012-04-03 18:56:20 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-04-04 18:11:12 -0400 |
commit | 234bcf8a499ee206145c7007d12d9706a254f790 (patch) | |
tree | 2f42f68294a5b1c8093a631d81ed580fee0d0595 /drivers/net/bonding/bond_main.c | |
parent | 2af73d4b2afe826d23e83f3747f850eefbd867ff (diff) |
net/bonding: correctly proxy slave neigh param setup ndo function
The current implemenation was buggy for slaves who use ndo_neigh_setup,
since the networking stack invokes the bonding device ndo entry (from
neigh_params_alloc) before any devices are enslaved, and the bonding
driver can't further delegate the call at that point in time. As a
result when bonding IPoIB devices, the neigh_cleanup hasn't been called.
Fix that by deferring the actual call into the slave ndo_neigh_setup
from the time the bonding neigh_setup is called.
Signed-off-by: Shlomo Pongratz <shlomop@mellanox.com>
Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bonding/bond_main.c')
-rw-r--r-- | drivers/net/bonding/bond_main.c | 51 |
1 files changed, 43 insertions, 8 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 5cb85cb0be4f..fc8a8d5c4dbd 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -3704,17 +3704,52 @@ static void bond_set_multicast_list(struct net_device *bond_dev) | |||
3704 | read_unlock(&bond->lock); | 3704 | read_unlock(&bond->lock); |
3705 | } | 3705 | } |
3706 | 3706 | ||
3707 | static int bond_neigh_setup(struct net_device *dev, struct neigh_parms *parms) | 3707 | static int bond_neigh_init(struct neighbour *n) |
3708 | { | 3708 | { |
3709 | struct bonding *bond = netdev_priv(dev); | 3709 | struct bonding *bond = netdev_priv(n->dev); |
3710 | struct slave *slave = bond->first_slave; | 3710 | struct slave *slave = bond->first_slave; |
3711 | const struct net_device_ops *slave_ops; | ||
3712 | struct neigh_parms parms; | ||
3713 | int ret; | ||
3714 | |||
3715 | if (!slave) | ||
3716 | return 0; | ||
3717 | |||
3718 | slave_ops = slave->dev->netdev_ops; | ||
3719 | |||
3720 | if (!slave_ops->ndo_neigh_setup) | ||
3721 | return 0; | ||
3722 | |||
3723 | parms.neigh_setup = NULL; | ||
3724 | parms.neigh_cleanup = NULL; | ||
3725 | ret = slave_ops->ndo_neigh_setup(slave->dev, &parms); | ||
3726 | if (ret) | ||
3727 | return ret; | ||
3728 | |||
3729 | /* | ||
3730 | * Assign slave's neigh_cleanup to neighbour in case cleanup is called | ||
3731 | * after the last slave has been detached. Assumes that all slaves | ||
3732 | * utilize the same neigh_cleanup (true at this writing as only user | ||
3733 | * is ipoib). | ||
3734 | */ | ||
3735 | n->parms->neigh_cleanup = parms.neigh_cleanup; | ||
3736 | |||
3737 | if (!parms.neigh_setup) | ||
3738 | return 0; | ||
3739 | |||
3740 | return parms.neigh_setup(n); | ||
3741 | } | ||
3742 | |||
3743 | /* | ||
3744 | * The bonding ndo_neigh_setup is called at init time beofre any | ||
3745 | * slave exists. So we must declare proxy setup function which will | ||
3746 | * be used at run time to resolve the actual slave neigh param setup. | ||
3747 | */ | ||
3748 | static int bond_neigh_setup(struct net_device *dev, | ||
3749 | struct neigh_parms *parms) | ||
3750 | { | ||
3751 | parms->neigh_setup = bond_neigh_init; | ||
3711 | 3752 | ||
3712 | if (slave) { | ||
3713 | const struct net_device_ops *slave_ops | ||
3714 | = slave->dev->netdev_ops; | ||
3715 | if (slave_ops->ndo_neigh_setup) | ||
3716 | return slave_ops->ndo_neigh_setup(slave->dev, parms); | ||
3717 | } | ||
3718 | return 0; | 3753 | return 0; |
3719 | } | 3754 | } |
3720 | 3755 | ||