diff options
Diffstat (limited to 'drivers/net/bonding')
-rw-r--r-- | drivers/net/bonding/bond_3ad.c | 11 | ||||
-rw-r--r-- | drivers/net/bonding/bond_3ad.h | 2 | ||||
-rw-r--r-- | drivers/net/bonding/bond_alb.c | 22 | ||||
-rw-r--r-- | drivers/net/bonding/bond_main.c | 58 | ||||
-rw-r--r-- | drivers/net/bonding/bonding.h | 3 |
5 files changed, 73 insertions, 23 deletions
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index a2e8dda5afac..d2f34d5a8083 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c | |||
@@ -2419,22 +2419,19 @@ out: | |||
2419 | return 0; | 2419 | return 0; |
2420 | } | 2420 | } |
2421 | 2421 | ||
2422 | int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype) | 2422 | int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype, struct net_device *orig_dev) |
2423 | { | 2423 | { |
2424 | struct bonding *bond = dev->priv; | 2424 | struct bonding *bond = dev->priv; |
2425 | struct slave *slave = NULL; | 2425 | struct slave *slave = NULL; |
2426 | int ret = NET_RX_DROP; | 2426 | int ret = NET_RX_DROP; |
2427 | 2427 | ||
2428 | if (!(dev->flags & IFF_MASTER)) { | 2428 | if (!(dev->flags & IFF_MASTER)) |
2429 | goto out; | 2429 | goto out; |
2430 | } | ||
2431 | 2430 | ||
2432 | read_lock(&bond->lock); | 2431 | read_lock(&bond->lock); |
2433 | slave = bond_get_slave_by_dev((struct bonding *)dev->priv, | 2432 | slave = bond_get_slave_by_dev((struct bonding *)dev->priv, orig_dev); |
2434 | skb->real_dev); | 2433 | if (!slave) |
2435 | if (slave == NULL) { | ||
2436 | goto out_unlock; | 2434 | goto out_unlock; |
2437 | } | ||
2438 | 2435 | ||
2439 | bond_3ad_rx_indication((struct lacpdu *) skb->data, slave, skb->len); | 2436 | bond_3ad_rx_indication((struct lacpdu *) skb->data, slave, skb->len); |
2440 | 2437 | ||
diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h index f46823894187..673a30af5660 100644 --- a/drivers/net/bonding/bond_3ad.h +++ b/drivers/net/bonding/bond_3ad.h | |||
@@ -295,6 +295,6 @@ void bond_3ad_adapter_duplex_changed(struct slave *slave); | |||
295 | void bond_3ad_handle_link_change(struct slave *slave, char link); | 295 | void bond_3ad_handle_link_change(struct slave *slave, char link); |
296 | int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info); | 296 | int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info); |
297 | int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev); | 297 | int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev); |
298 | int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype); | 298 | int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype, struct net_device *orig_dev); |
299 | #endif //__BOND_3AD_H__ | 299 | #endif //__BOND_3AD_H__ |
300 | 300 | ||
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 5ce606d9dc03..f8fce3961197 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c | |||
@@ -354,15 +354,14 @@ static void rlb_update_entry_from_arp(struct bonding *bond, struct arp_pkt *arp) | |||
354 | _unlock_rx_hashtbl(bond); | 354 | _unlock_rx_hashtbl(bond); |
355 | } | 355 | } |
356 | 356 | ||
357 | static int rlb_arp_recv(struct sk_buff *skb, struct net_device *bond_dev, struct packet_type *ptype) | 357 | static int rlb_arp_recv(struct sk_buff *skb, struct net_device *bond_dev, struct packet_type *ptype, struct net_device *orig_dev) |
358 | { | 358 | { |
359 | struct bonding *bond = bond_dev->priv; | 359 | struct bonding *bond = bond_dev->priv; |
360 | struct arp_pkt *arp = (struct arp_pkt *)skb->data; | 360 | struct arp_pkt *arp = (struct arp_pkt *)skb->data; |
361 | int res = NET_RX_DROP; | 361 | int res = NET_RX_DROP; |
362 | 362 | ||
363 | if (!(bond_dev->flags & IFF_MASTER)) { | 363 | if (!(bond_dev->flags & IFF_MASTER)) |
364 | goto out; | 364 | goto out; |
365 | } | ||
366 | 365 | ||
367 | if (!arp) { | 366 | if (!arp) { |
368 | dprintk("Packet has no ARP data\n"); | 367 | dprintk("Packet has no ARP data\n"); |
@@ -1106,18 +1105,13 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav | |||
1106 | } | 1105 | } |
1107 | } | 1106 | } |
1108 | 1107 | ||
1109 | if (found) { | 1108 | if (!found) |
1110 | /* a slave was found that is using the mac address | 1109 | return 0; |
1111 | * of the new slave | ||
1112 | */ | ||
1113 | printk(KERN_ERR DRV_NAME | ||
1114 | ": Error: the hw address of slave %s is not " | ||
1115 | "unique - cannot enslave it!", | ||
1116 | slave->dev->name); | ||
1117 | return -EINVAL; | ||
1118 | } | ||
1119 | 1110 | ||
1120 | return 0; | 1111 | /* Try setting slave mac to bond address and fall-through |
1112 | to code handling that situation below... */ | ||
1113 | alb_set_slave_mac_addr(slave, bond->dev->dev_addr, | ||
1114 | bond->alb_info.rlb_enabled); | ||
1121 | } | 1115 | } |
1122 | 1116 | ||
1123 | /* The slave's address is equal to the address of the bond. | 1117 | /* The slave's address is equal to the address of the bond. |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 2c930da90a85..94c9f68dd16b 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -1604,6 +1604,44 @@ static int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_ | |||
1604 | return 0; | 1604 | return 0; |
1605 | } | 1605 | } |
1606 | 1606 | ||
1607 | #define BOND_INTERSECT_FEATURES \ | ||
1608 | (NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM) | ||
1609 | |||
1610 | /* | ||
1611 | * Compute the features available to the bonding device by | ||
1612 | * intersection of all of the slave devices' BOND_INTERSECT_FEATURES. | ||
1613 | * Call this after attaching or detaching a slave to update the | ||
1614 | * bond's features. | ||
1615 | */ | ||
1616 | static int bond_compute_features(struct bonding *bond) | ||
1617 | { | ||
1618 | int i; | ||
1619 | struct slave *slave; | ||
1620 | struct net_device *bond_dev = bond->dev; | ||
1621 | int features = bond->bond_features; | ||
1622 | |||
1623 | bond_for_each_slave(bond, slave, i) { | ||
1624 | struct net_device * slave_dev = slave->dev; | ||
1625 | if (i == 0) { | ||
1626 | features |= BOND_INTERSECT_FEATURES; | ||
1627 | } | ||
1628 | features &= | ||
1629 | ~(~slave_dev->features & BOND_INTERSECT_FEATURES); | ||
1630 | } | ||
1631 | |||
1632 | /* turn off NETIF_F_SG if we need a csum and h/w can't do it */ | ||
1633 | if ((features & NETIF_F_SG) && | ||
1634 | !(features & (NETIF_F_IP_CSUM | | ||
1635 | NETIF_F_NO_CSUM | | ||
1636 | NETIF_F_HW_CSUM))) { | ||
1637 | features &= ~NETIF_F_SG; | ||
1638 | } | ||
1639 | |||
1640 | bond_dev->features = features; | ||
1641 | |||
1642 | return 0; | ||
1643 | } | ||
1644 | |||
1607 | /* enslave device <slave> to bond device <master> */ | 1645 | /* enslave device <slave> to bond device <master> */ |
1608 | static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | 1646 | static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) |
1609 | { | 1647 | { |
@@ -1811,6 +1849,8 @@ static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_de | |||
1811 | new_slave->delay = 0; | 1849 | new_slave->delay = 0; |
1812 | new_slave->link_failure_count = 0; | 1850 | new_slave->link_failure_count = 0; |
1813 | 1851 | ||
1852 | bond_compute_features(bond); | ||
1853 | |||
1814 | if (bond->params.miimon && !bond->params.use_carrier) { | 1854 | if (bond->params.miimon && !bond->params.use_carrier) { |
1815 | link_reporting = bond_check_dev_link(bond, slave_dev, 1); | 1855 | link_reporting = bond_check_dev_link(bond, slave_dev, 1); |
1816 | 1856 | ||
@@ -2015,7 +2055,7 @@ err_free: | |||
2015 | 2055 | ||
2016 | err_undo_flags: | 2056 | err_undo_flags: |
2017 | bond_dev->features = old_features; | 2057 | bond_dev->features = old_features; |
2018 | 2058 | ||
2019 | return res; | 2059 | return res; |
2020 | } | 2060 | } |
2021 | 2061 | ||
@@ -2100,6 +2140,8 @@ static int bond_release(struct net_device *bond_dev, struct net_device *slave_de | |||
2100 | /* release the slave from its bond */ | 2140 | /* release the slave from its bond */ |
2101 | bond_detach_slave(bond, slave); | 2141 | bond_detach_slave(bond, slave); |
2102 | 2142 | ||
2143 | bond_compute_features(bond); | ||
2144 | |||
2103 | if (bond->primary_slave == slave) { | 2145 | if (bond->primary_slave == slave) { |
2104 | bond->primary_slave = NULL; | 2146 | bond->primary_slave = NULL; |
2105 | } | 2147 | } |
@@ -2243,6 +2285,8 @@ static int bond_release_all(struct net_device *bond_dev) | |||
2243 | bond_alb_deinit_slave(bond, slave); | 2285 | bond_alb_deinit_slave(bond, slave); |
2244 | } | 2286 | } |
2245 | 2287 | ||
2288 | bond_compute_features(bond); | ||
2289 | |||
2246 | /* now that the slave is detached, unlock and perform | 2290 | /* now that the slave is detached, unlock and perform |
2247 | * all the undo steps that should not be called from | 2291 | * all the undo steps that should not be called from |
2248 | * within a lock. | 2292 | * within a lock. |
@@ -3588,6 +3632,7 @@ static int bond_master_netdev_event(unsigned long event, struct net_device *bond | |||
3588 | static int bond_slave_netdev_event(unsigned long event, struct net_device *slave_dev) | 3632 | static int bond_slave_netdev_event(unsigned long event, struct net_device *slave_dev) |
3589 | { | 3633 | { |
3590 | struct net_device *bond_dev = slave_dev->master; | 3634 | struct net_device *bond_dev = slave_dev->master; |
3635 | struct bonding *bond = bond_dev->priv; | ||
3591 | 3636 | ||
3592 | switch (event) { | 3637 | switch (event) { |
3593 | case NETDEV_UNREGISTER: | 3638 | case NETDEV_UNREGISTER: |
@@ -3626,6 +3671,9 @@ static int bond_slave_netdev_event(unsigned long event, struct net_device *slave | |||
3626 | * TODO: handle changing the primary's name | 3671 | * TODO: handle changing the primary's name |
3627 | */ | 3672 | */ |
3628 | break; | 3673 | break; |
3674 | case NETDEV_FEAT_CHANGE: | ||
3675 | bond_compute_features(bond); | ||
3676 | break; | ||
3629 | default: | 3677 | default: |
3630 | break; | 3678 | break; |
3631 | } | 3679 | } |
@@ -4526,6 +4574,11 @@ static inline void bond_set_mode_ops(struct bonding *bond, int mode) | |||
4526 | } | 4574 | } |
4527 | } | 4575 | } |
4528 | 4576 | ||
4577 | static struct ethtool_ops bond_ethtool_ops = { | ||
4578 | .get_tx_csum = ethtool_op_get_tx_csum, | ||
4579 | .get_sg = ethtool_op_get_sg, | ||
4580 | }; | ||
4581 | |||
4529 | /* | 4582 | /* |
4530 | * Does not allocate but creates a /proc entry. | 4583 | * Does not allocate but creates a /proc entry. |
4531 | * Allowed to fail. | 4584 | * Allowed to fail. |
@@ -4555,6 +4608,7 @@ static int __init bond_init(struct net_device *bond_dev, struct bond_params *par | |||
4555 | bond_dev->stop = bond_close; | 4608 | bond_dev->stop = bond_close; |
4556 | bond_dev->get_stats = bond_get_stats; | 4609 | bond_dev->get_stats = bond_get_stats; |
4557 | bond_dev->do_ioctl = bond_do_ioctl; | 4610 | bond_dev->do_ioctl = bond_do_ioctl; |
4611 | bond_dev->ethtool_ops = &bond_ethtool_ops; | ||
4558 | bond_dev->set_multicast_list = bond_set_multicast_list; | 4612 | bond_dev->set_multicast_list = bond_set_multicast_list; |
4559 | bond_dev->change_mtu = bond_change_mtu; | 4613 | bond_dev->change_mtu = bond_change_mtu; |
4560 | bond_dev->set_mac_address = bond_set_mac_address; | 4614 | bond_dev->set_mac_address = bond_set_mac_address; |
@@ -4591,6 +4645,8 @@ static int __init bond_init(struct net_device *bond_dev, struct bond_params *par | |||
4591 | NETIF_F_HW_VLAN_RX | | 4645 | NETIF_F_HW_VLAN_RX | |
4592 | NETIF_F_HW_VLAN_FILTER); | 4646 | NETIF_F_HW_VLAN_FILTER); |
4593 | 4647 | ||
4648 | bond->bond_features = bond_dev->features; | ||
4649 | |||
4594 | #ifdef CONFIG_PROC_FS | 4650 | #ifdef CONFIG_PROC_FS |
4595 | bond_create_proc_entry(bond); | 4651 | bond_create_proc_entry(bond); |
4596 | #endif | 4652 | #endif |
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index d27f377b3eeb..388196980862 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h | |||
@@ -211,6 +211,9 @@ struct bonding { | |||
211 | struct bond_params params; | 211 | struct bond_params params; |
212 | struct list_head vlan_list; | 212 | struct list_head vlan_list; |
213 | struct vlan_group *vlgrp; | 213 | struct vlan_group *vlgrp; |
214 | /* the features the bonding device supports, independently | ||
215 | * of any slaves */ | ||
216 | int bond_features; | ||
214 | }; | 217 | }; |
215 | 218 | ||
216 | /** | 219 | /** |