diff options
author | Laurent Riffard <laurent.riffard@free.fr> | 2006-11-18 06:03:04 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-11-30 06:14:06 -0500 |
commit | 418e8f3d7ef4a30d4b5c84440641c9792a7f83f1 (patch) | |
tree | 9a594b5625f4a90509ed997647f7698e214fafe4 /drivers/net/bonding/bond_main.c | |
parent | c1cb0b77f905a2f5f297e91fafbe766acc143891 (diff) |
[PATCH] bonding: fix an oops when slave device does not provide get_stats
Bonding driver unconditionnaly dereference get_stats function pointer
for each of its slave device. This patch
- adds a check for NULL dev->get_stats pointer in bond_get_stats
- prints a notice when the bonding device enslave a device without
get_stats function.
Signed-off-by: Laurent Riffard <laurent.riffard@free.fr>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/bonding/bond_main.c')
-rw-r--r-- | drivers/net/bonding/bond_main.c | 63 |
1 files changed, 36 insertions, 27 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 17a461152d39..488d8ed9e740 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -1336,6 +1336,13 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1336 | goto err_undo_flags; | 1336 | goto err_undo_flags; |
1337 | } | 1337 | } |
1338 | 1338 | ||
1339 | if (slave_dev->get_stats == NULL) { | ||
1340 | printk(KERN_NOTICE DRV_NAME | ||
1341 | ": %s: the driver for slave device %s does not provide " | ||
1342 | "get_stats function, network statistics will be " | ||
1343 | "inaccurate.\n", bond_dev->name, slave_dev->name); | ||
1344 | } | ||
1345 | |||
1339 | new_slave = kmalloc(sizeof(struct slave), GFP_KERNEL); | 1346 | new_slave = kmalloc(sizeof(struct slave), GFP_KERNEL); |
1340 | if (!new_slave) { | 1347 | if (!new_slave) { |
1341 | res = -ENOMEM; | 1348 | res = -ENOMEM; |
@@ -3605,33 +3612,35 @@ static struct net_device_stats *bond_get_stats(struct net_device *bond_dev) | |||
3605 | read_lock_bh(&bond->lock); | 3612 | read_lock_bh(&bond->lock); |
3606 | 3613 | ||
3607 | bond_for_each_slave(bond, slave, i) { | 3614 | bond_for_each_slave(bond, slave, i) { |
3608 | sstats = slave->dev->get_stats(slave->dev); | 3615 | if (slave->dev->get_stats) { |
3609 | 3616 | sstats = slave->dev->get_stats(slave->dev); | |
3610 | stats->rx_packets += sstats->rx_packets; | 3617 | |
3611 | stats->rx_bytes += sstats->rx_bytes; | 3618 | stats->rx_packets += sstats->rx_packets; |
3612 | stats->rx_errors += sstats->rx_errors; | 3619 | stats->rx_bytes += sstats->rx_bytes; |
3613 | stats->rx_dropped += sstats->rx_dropped; | 3620 | stats->rx_errors += sstats->rx_errors; |
3614 | 3621 | stats->rx_dropped += sstats->rx_dropped; | |
3615 | stats->tx_packets += sstats->tx_packets; | 3622 | |
3616 | stats->tx_bytes += sstats->tx_bytes; | 3623 | stats->tx_packets += sstats->tx_packets; |
3617 | stats->tx_errors += sstats->tx_errors; | 3624 | stats->tx_bytes += sstats->tx_bytes; |
3618 | stats->tx_dropped += sstats->tx_dropped; | 3625 | stats->tx_errors += sstats->tx_errors; |
3619 | 3626 | stats->tx_dropped += sstats->tx_dropped; | |
3620 | stats->multicast += sstats->multicast; | 3627 | |
3621 | stats->collisions += sstats->collisions; | 3628 | stats->multicast += sstats->multicast; |
3622 | 3629 | stats->collisions += sstats->collisions; | |
3623 | stats->rx_length_errors += sstats->rx_length_errors; | 3630 | |
3624 | stats->rx_over_errors += sstats->rx_over_errors; | 3631 | stats->rx_length_errors += sstats->rx_length_errors; |
3625 | stats->rx_crc_errors += sstats->rx_crc_errors; | 3632 | stats->rx_over_errors += sstats->rx_over_errors; |
3626 | stats->rx_frame_errors += sstats->rx_frame_errors; | 3633 | stats->rx_crc_errors += sstats->rx_crc_errors; |
3627 | stats->rx_fifo_errors += sstats->rx_fifo_errors; | 3634 | stats->rx_frame_errors += sstats->rx_frame_errors; |
3628 | stats->rx_missed_errors += sstats->rx_missed_errors; | 3635 | stats->rx_fifo_errors += sstats->rx_fifo_errors; |
3629 | 3636 | stats->rx_missed_errors += sstats->rx_missed_errors; | |
3630 | stats->tx_aborted_errors += sstats->tx_aborted_errors; | 3637 | |
3631 | stats->tx_carrier_errors += sstats->tx_carrier_errors; | 3638 | stats->tx_aborted_errors += sstats->tx_aborted_errors; |
3632 | stats->tx_fifo_errors += sstats->tx_fifo_errors; | 3639 | stats->tx_carrier_errors += sstats->tx_carrier_errors; |
3633 | stats->tx_heartbeat_errors += sstats->tx_heartbeat_errors; | 3640 | stats->tx_fifo_errors += sstats->tx_fifo_errors; |
3634 | stats->tx_window_errors += sstats->tx_window_errors; | 3641 | stats->tx_heartbeat_errors += sstats->tx_heartbeat_errors; |
3642 | stats->tx_window_errors += sstats->tx_window_errors; | ||
3643 | } | ||
3635 | } | 3644 | } |
3636 | 3645 | ||
3637 | read_unlock_bh(&bond->lock); | 3646 | read_unlock_bh(&bond->lock); |