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