summaryrefslogtreecommitdiff
path: root/include/net/bonding.h
diff options
context:
space:
mode:
authorJarod Wilson <jarod@redhat.com>2017-04-05 00:32:42 +0300
committerDavid S. Miller <davem@davemloft.net>2017-04-06 04:44:54 +0300
commitfaeeb317a5615076dff1ff44b51e862e6064dbd0 (patch)
tree65733bd519727f40efd9381b98ca6a69e86d1004 /include/net/bonding.h
parent148cbab6cffc8247d7dfd0f2da86c2eb8c55709c (diff)
downloadlinux-faeeb317a5615076dff1ff44b51e862e6064dbd0.tar.xz
bonding: attempt to better support longer hw addresses
People are using bonding over Infiniband IPoIB connections, and who knows what else. Infiniband has a hardware address length of 20 octets (INFINIBAND_ALEN), and the network core defines a MAX_ADDR_LEN of 32. Various places in the bonding code are currently hard-wired to 6 octets (ETH_ALEN), such as the 3ad code, which I've left untouched here. Besides, only alb is currently possible on Infiniband links right now anyway, due to commit 1533e7731522, so the alb code is where most of the changes are. One major component of this change is the addition of a bond_hw_addr_copy function that takes a length argument, instead of using ether_addr_copy everywhere that hardware addresses need to be copied about. The other major component of this change is converting the bonding code from using struct sockaddr for address storage to struct sockaddr_storage, as the former has an address storage space of only 14, while the latter is 128 minus a few, which is necessary to support bonding over device with up to MAX_ADDR_LEN octet hardware addresses. Additionally, this probably fixes up some memory corruption issues with the current code, where it's possible to write an infiniband hardware address into a sockaddr declared on the stack. Lightly tested on a dual mlx4 IPoIB setup, which properly shows a 20-octet hardware address now: $ cat /proc/net/bonding/bond0 Ethernet Channel Bonding Driver: v3.7.1 (April 27, 2011) Bonding Mode: fault-tolerance (active-backup) (fail_over_mac active) Primary Slave: mlx4_ib0 (primary_reselect always) Currently Active Slave: mlx4_ib0 MII Status: up MII Polling Interval (ms): 100 Up Delay (ms): 100 Down Delay (ms): 100 Slave Interface: mlx4_ib0 MII Status: up Speed: Unknown Duplex: Unknown Link Failure Count: 0 Permanent HW addr: 80:00:02:08:fe:80:00:00:00:00:00:00:e4:1d:2d:03:00:1d:67:01 Slave queue ID: 0 Slave Interface: mlx4_ib1 MII Status: up Speed: Unknown Duplex: Unknown Link Failure Count: 0 Permanent HW addr: 80:00:02:09:fe:80:00:00:00:00:00:01:e4:1d:2d:03:00:1d:67:02 Slave queue ID: 0 Also tested with a standard 1Gbps NIC bonding setup (with a mix of e1000 and e1000e cards), running LNST's bonding tests. CC: Jay Vosburgh <j.vosburgh@gmail.com> CC: Veaceslav Falico <vfalico@gmail.com> CC: Andy Gospodarek <andy@greyhouse.net> CC: netdev@vger.kernel.org Signed-off-by: Jarod Wilson <jarod@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net/bonding.h')
-rw-r--r--include/net/bonding.h12
1 files changed, 11 insertions, 1 deletions
diff --git a/include/net/bonding.h b/include/net/bonding.h
index fb2dd97857c4..04a21e8048be 100644
--- a/include/net/bonding.h
+++ b/include/net/bonding.h
@@ -166,7 +166,7 @@ struct slave {
u32 link_failure_count;
u32 speed;
u16 queue_id;
- u8 perm_hwaddr[ETH_ALEN];
+ u8 perm_hwaddr[MAX_ADDR_LEN];
struct ad_slave_info *ad_info;
struct tlb_slave_info tlb_info;
#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -402,6 +402,16 @@ static inline bool bond_slave_can_tx(struct slave *slave)
bond_is_active_slave(slave);
}
+static inline void bond_hw_addr_copy(u8 *dst, const u8 *src, unsigned int len)
+{
+ if (len == ETH_ALEN) {
+ ether_addr_copy(dst, src);
+ return;
+ }
+
+ memcpy(dst, src, len);
+}
+
#define BOND_PRI_RESELECT_ALWAYS 0
#define BOND_PRI_RESELECT_BETTER 1
#define BOND_PRI_RESELECT_FAILURE 2