diff options
Diffstat (limited to 'drivers/net/bonding/bond_alb.c')
-rw-r--r-- | drivers/net/bonding/bond_alb.c | 88 |
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); |