summaryrefslogtreecommitdiff
path: root/drivers/net/bonding/bond_alb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/bonding/bond_alb.c')
-rw-r--r--drivers/net/bonding/bond_alb.c88
1 files changed, 53 insertions, 35 deletions
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index c80b023092dd..7d7a3cec149a 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -687,7 +687,8 @@ static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond)
/* the arp must be sent on the selected rx channel */
tx_slave = rlb_choose_channel(skb, bond);
if (tx_slave)
- ether_addr_copy(arp->mac_src, tx_slave->dev->dev_addr);
+ bond_hw_addr_copy(arp->mac_src, tx_slave->dev->dev_addr,
+ tx_slave->dev->addr_len);
netdev_dbg(bond->dev, "Server sent ARP Reply packet\n");
} else if (arp->op_code == htons(ARPOP_REQUEST)) {
/* Create an entry in the rx_hashtbl for this client as a
@@ -1017,22 +1018,23 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[],
rcu_read_unlock();
}
-static int alb_set_slave_mac_addr(struct slave *slave, u8 addr[])
+static int alb_set_slave_mac_addr(struct slave *slave, u8 addr[],
+ unsigned int len)
{
struct net_device *dev = slave->dev;
- struct sockaddr s_addr;
+ struct sockaddr_storage ss;
if (BOND_MODE(slave->bond) == BOND_MODE_TLB) {
- memcpy(dev->dev_addr, addr, dev->addr_len);
+ memcpy(dev->dev_addr, addr, len);
return 0;
}
/* for rlb each slave must have a unique hw mac addresses so that
* each slave will receive packets destined to a different mac
*/
- memcpy(s_addr.sa_data, addr, dev->addr_len);
- s_addr.sa_family = dev->type;
- if (dev_set_mac_address(dev, &s_addr)) {
+ memcpy(ss.__data, addr, len);
+ ss.ss_family = dev->type;
+ if (dev_set_mac_address(dev, (struct sockaddr *)&ss)) {
netdev_err(slave->bond->dev, "dev_set_mac_address of dev %s failed! ALB mode requires that the base driver support setting the hw address also when the network device's interface is open\n",
dev->name);
return -EOPNOTSUPP;
@@ -1046,11 +1048,14 @@ static int alb_set_slave_mac_addr(struct slave *slave, u8 addr[])
*/
static void alb_swap_mac_addr(struct slave *slave1, struct slave *slave2)
{
- u8 tmp_mac_addr[ETH_ALEN];
+ u8 tmp_mac_addr[MAX_ADDR_LEN];
- ether_addr_copy(tmp_mac_addr, slave1->dev->dev_addr);
- alb_set_slave_mac_addr(slave1, slave2->dev->dev_addr);
- alb_set_slave_mac_addr(slave2, tmp_mac_addr);
+ bond_hw_addr_copy(tmp_mac_addr, slave1->dev->dev_addr,
+ slave1->dev->addr_len);
+ alb_set_slave_mac_addr(slave1, slave2->dev->dev_addr,
+ slave2->dev->addr_len);
+ alb_set_slave_mac_addr(slave2, tmp_mac_addr,
+ slave1->dev->addr_len);
}
@@ -1177,7 +1182,8 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav
/* Try setting slave mac to bond address and fall-through
* to code handling that situation below...
*/
- alb_set_slave_mac_addr(slave, bond->dev->dev_addr);
+ alb_set_slave_mac_addr(slave, bond->dev->dev_addr,
+ bond->dev->addr_len);
}
/* The slave's address is equal to the address of the bond.
@@ -1202,7 +1208,8 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav
}
if (free_mac_slave) {
- alb_set_slave_mac_addr(slave, free_mac_slave->perm_hwaddr);
+ alb_set_slave_mac_addr(slave, free_mac_slave->perm_hwaddr,
+ free_mac_slave->dev->addr_len);
netdev_warn(bond->dev, "the hw address of slave %s is in use by the bond; giving it the hw address of %s\n",
slave->dev->name, free_mac_slave->dev->name);
@@ -1234,8 +1241,8 @@ static int alb_set_mac_address(struct bonding *bond, void *addr)
{
struct slave *slave, *rollback_slave;
struct list_head *iter;
- struct sockaddr sa;
- char tmp_addr[ETH_ALEN];
+ struct sockaddr_storage ss;
+ char tmp_addr[MAX_ADDR_LEN];
int res;
if (bond->alb_info.rlb_enabled)
@@ -1243,12 +1250,14 @@ static int alb_set_mac_address(struct bonding *bond, void *addr)
bond_for_each_slave(bond, slave, iter) {
/* save net_device's current hw address */
- ether_addr_copy(tmp_addr, slave->dev->dev_addr);
+ bond_hw_addr_copy(tmp_addr, slave->dev->dev_addr,
+ slave->dev->addr_len);
res = dev_set_mac_address(slave->dev, addr);
/* restore net_device's hw address */
- ether_addr_copy(slave->dev->dev_addr, tmp_addr);
+ bond_hw_addr_copy(slave->dev->dev_addr, tmp_addr,
+ slave->dev->addr_len);
if (res)
goto unwind;
@@ -1257,16 +1266,19 @@ static int alb_set_mac_address(struct bonding *bond, void *addr)
return 0;
unwind:
- memcpy(sa.sa_data, bond->dev->dev_addr, bond->dev->addr_len);
- sa.sa_family = bond->dev->type;
+ memcpy(ss.__data, bond->dev->dev_addr, bond->dev->addr_len);
+ ss.ss_family = bond->dev->type;
/* unwind from head to the slave that failed */
bond_for_each_slave(bond, rollback_slave, iter) {
if (rollback_slave == slave)
break;
- ether_addr_copy(tmp_addr, rollback_slave->dev->dev_addr);
- dev_set_mac_address(rollback_slave->dev, &sa);
- ether_addr_copy(rollback_slave->dev->dev_addr, tmp_addr);
+ bond_hw_addr_copy(tmp_addr, rollback_slave->dev->dev_addr,
+ rollback_slave->dev->addr_len);
+ dev_set_mac_address(rollback_slave->dev,
+ (struct sockaddr *)&ss);
+ bond_hw_addr_copy(rollback_slave->dev->dev_addr, tmp_addr,
+ rollback_slave->dev->addr_len);
}
return res;
@@ -1582,7 +1594,8 @@ int bond_alb_init_slave(struct bonding *bond, struct slave *slave)
{
int res;
- res = alb_set_slave_mac_addr(slave, slave->perm_hwaddr);
+ res = alb_set_slave_mac_addr(slave, slave->perm_hwaddr,
+ slave->dev->addr_len);
if (res)
return res;
@@ -1696,17 +1709,20 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave
* and thus filter bond->dev_addr's packets, so force bond's mac
*/
if (BOND_MODE(bond) == BOND_MODE_TLB) {
- struct sockaddr sa;
- u8 tmp_addr[ETH_ALEN];
+ struct sockaddr_storage ss;
+ u8 tmp_addr[MAX_ADDR_LEN];
- ether_addr_copy(tmp_addr, new_slave->dev->dev_addr);
+ bond_hw_addr_copy(tmp_addr, new_slave->dev->dev_addr,
+ new_slave->dev->addr_len);
- memcpy(sa.sa_data, bond->dev->dev_addr, bond->dev->addr_len);
- sa.sa_family = bond->dev->type;
+ bond_hw_addr_copy(ss.__data, bond->dev->dev_addr,
+ bond->dev->addr_len);
+ ss.ss_family = bond->dev->type;
/* we don't care if it can't change its mac, best effort */
- dev_set_mac_address(new_slave->dev, &sa);
+ dev_set_mac_address(new_slave->dev, (struct sockaddr *)&ss);
- ether_addr_copy(new_slave->dev->dev_addr, tmp_addr);
+ bond_hw_addr_copy(new_slave->dev->dev_addr, tmp_addr,
+ new_slave->dev->addr_len);
}
/* curr_active_slave must be set before calling alb_swap_mac_addr */
@@ -1716,7 +1732,8 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave
alb_fasten_mac_swap(bond, swap_slave, new_slave);
} else {
/* set the new_slave to the bond mac address */
- alb_set_slave_mac_addr(new_slave, bond->dev->dev_addr);
+ alb_set_slave_mac_addr(new_slave, bond->dev->dev_addr,
+ bond->dev->addr_len);
alb_send_learning_packets(new_slave, bond->dev->dev_addr,
false);
}
@@ -1726,19 +1743,19 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave
int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr)
{
struct bonding *bond = netdev_priv(bond_dev);
- struct sockaddr *sa = addr;
+ struct sockaddr_storage *ss = addr;
struct slave *curr_active;
struct slave *swap_slave;
int res;
- if (!is_valid_ether_addr(sa->sa_data))
+ if (!is_valid_ether_addr(ss->__data))
return -EADDRNOTAVAIL;
res = alb_set_mac_address(bond, addr);
if (res)
return res;
- memcpy(bond_dev->dev_addr, sa->sa_data, bond_dev->addr_len);
+ bond_hw_addr_copy(bond_dev->dev_addr, ss->__data, bond_dev->addr_len);
/* If there is no curr_active_slave there is nothing else to do.
* Otherwise we'll need to pass the new address to it and handle
@@ -1754,7 +1771,8 @@ int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr)
alb_swap_mac_addr(swap_slave, curr_active);
alb_fasten_mac_swap(bond, swap_slave, curr_active);
} else {
- alb_set_slave_mac_addr(curr_active, bond_dev->dev_addr);
+ alb_set_slave_mac_addr(curr_active, bond_dev->dev_addr,
+ bond_dev->addr_len);
alb_send_learning_packets(curr_active,
bond_dev->dev_addr, false);