Commit 4ca0d9ac authored by Jarod Wilson's avatar Jarod Wilson Committed by David S. Miller

bonding: show saner speed for broadcast mode

Broadcast mode bonds transmit a copy of all traffic simultaneously out of
all interfaces, so the "speed" of the bond isn't really the aggregate of
all interfaces, but rather, the speed of the slowest active interface.

Also, the type of the speed field is u32, not unsigned long, so adjust
that accordingly, as required to make min() function here without
complaining about mismatching types.

Fixes: bb5b052f ("bond: add support to read speed and duplex via ethtool")
CC: Jay Vosburgh <j.vosburgh@gmail.com>
CC: Veaceslav Falico <vfalico@gmail.com>
CC: Andy Gospodarek <andy@greyhouse.net>
CC: "David S. Miller" <davem@davemloft.net>
CC: netdev@vger.kernel.org
Acked-by: default avatarJay Vosburgh <jay.vosburgh@canonical.com>
Signed-off-by: default avatarJarod Wilson <jarod@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 10a3b7c1
...@@ -4552,13 +4552,23 @@ static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -4552,13 +4552,23 @@ static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev)
return ret; return ret;
} }
static u32 bond_mode_bcast_speed(struct slave *slave, u32 speed)
{
if (speed == 0 || speed == SPEED_UNKNOWN)
speed = slave->speed;
else
speed = min(speed, slave->speed);
return speed;
}
static int bond_ethtool_get_link_ksettings(struct net_device *bond_dev, static int bond_ethtool_get_link_ksettings(struct net_device *bond_dev,
struct ethtool_link_ksettings *cmd) struct ethtool_link_ksettings *cmd)
{ {
struct bonding *bond = netdev_priv(bond_dev); struct bonding *bond = netdev_priv(bond_dev);
unsigned long speed = 0;
struct list_head *iter; struct list_head *iter;
struct slave *slave; struct slave *slave;
u32 speed = 0;
cmd->base.duplex = DUPLEX_UNKNOWN; cmd->base.duplex = DUPLEX_UNKNOWN;
cmd->base.port = PORT_OTHER; cmd->base.port = PORT_OTHER;
...@@ -4570,8 +4580,13 @@ static int bond_ethtool_get_link_ksettings(struct net_device *bond_dev, ...@@ -4570,8 +4580,13 @@ static int bond_ethtool_get_link_ksettings(struct net_device *bond_dev,
*/ */
bond_for_each_slave(bond, slave, iter) { bond_for_each_slave(bond, slave, iter) {
if (bond_slave_can_tx(slave)) { if (bond_slave_can_tx(slave)) {
if (slave->speed != SPEED_UNKNOWN) if (slave->speed != SPEED_UNKNOWN) {
if (BOND_MODE(bond) == BOND_MODE_BROADCAST)
speed = bond_mode_bcast_speed(slave,
speed);
else
speed += slave->speed; speed += slave->speed;
}
if (cmd->base.duplex == DUPLEX_UNKNOWN && if (cmd->base.duplex == DUPLEX_UNKNOWN &&
slave->duplex != DUPLEX_UNKNOWN) slave->duplex != DUPLEX_UNKNOWN)
cmd->base.duplex = slave->duplex; cmd->base.duplex = slave->duplex;
......
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