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 | |
| 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>
| -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); |
