diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/bonding/bond_main.c | 38 | ||||
-rw-r--r-- | drivers/net/bonding/bonding.h | 1 |
2 files changed, 20 insertions, 19 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 564cf4231f48..b38c9bf16dec 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -1320,14 +1320,15 @@ static void bond_netpoll_cleanup(struct net_device *bond_dev) | |||
1320 | 1320 | ||
1321 | /*---------------------------------- IOCTL ----------------------------------*/ | 1321 | /*---------------------------------- IOCTL ----------------------------------*/ |
1322 | 1322 | ||
1323 | static int bond_sethwaddr(struct net_device *bond_dev, | 1323 | static void bond_set_dev_addr(struct net_device *bond_dev, |
1324 | struct net_device *slave_dev) | 1324 | struct net_device *slave_dev) |
1325 | { | 1325 | { |
1326 | pr_debug("bond_dev=%p\n", bond_dev); | 1326 | pr_debug("bond_dev=%p\n", bond_dev); |
1327 | pr_debug("slave_dev=%p\n", slave_dev); | 1327 | pr_debug("slave_dev=%p\n", slave_dev); |
1328 | pr_debug("slave_dev->addr_len=%d\n", slave_dev->addr_len); | 1328 | pr_debug("slave_dev->addr_len=%d\n", slave_dev->addr_len); |
1329 | memcpy(bond_dev->dev_addr, slave_dev->dev_addr, slave_dev->addr_len); | 1329 | memcpy(bond_dev->dev_addr, slave_dev->dev_addr, slave_dev->addr_len); |
1330 | return 0; | 1330 | bond_dev->addr_assign_type = NET_ADDR_SET; |
1331 | call_netdevice_notifiers(NETDEV_CHANGEADDR, bond_dev); | ||
1331 | } | 1332 | } |
1332 | 1333 | ||
1333 | static netdev_features_t bond_fix_features(struct net_device *dev, | 1334 | static netdev_features_t bond_fix_features(struct net_device *dev, |
@@ -1628,10 +1629,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1628 | 1629 | ||
1629 | /* If this is the first slave, then we need to set the master's hardware | 1630 | /* If this is the first slave, then we need to set the master's hardware |
1630 | * address to be the same as the slave's. */ | 1631 | * address to be the same as the slave's. */ |
1631 | if (is_zero_ether_addr(bond->dev->dev_addr)) | 1632 | if (bond->dev_addr_from_first) |
1632 | memcpy(bond->dev->dev_addr, slave_dev->dev_addr, | 1633 | bond_set_dev_addr(bond->dev, slave_dev); |
1633 | slave_dev->addr_len); | ||
1634 | |||
1635 | 1634 | ||
1636 | new_slave = kzalloc(sizeof(struct slave), GFP_KERNEL); | 1635 | new_slave = kzalloc(sizeof(struct slave), GFP_KERNEL); |
1637 | if (!new_slave) { | 1636 | if (!new_slave) { |
@@ -2048,12 +2047,8 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) | |||
2048 | 2047 | ||
2049 | if (bond->slave_cnt == 0) { | 2048 | if (bond->slave_cnt == 0) { |
2050 | bond_set_carrier(bond); | 2049 | bond_set_carrier(bond); |
2051 | 2050 | eth_hw_addr_random(bond_dev); | |
2052 | /* if the last slave was removed, zero the mac address | 2051 | bond->dev_addr_from_first = true; |
2053 | * of the master so it will be set by the application | ||
2054 | * to the mac address of the first slave | ||
2055 | */ | ||
2056 | memset(bond_dev->dev_addr, 0, bond_dev->addr_len); | ||
2057 | 2052 | ||
2058 | if (bond_vlan_used(bond)) { | 2053 | if (bond_vlan_used(bond)) { |
2059 | pr_warning("%s: Warning: clearing HW address of %s while it still has VLANs.\n", | 2054 | pr_warning("%s: Warning: clearing HW address of %s while it still has VLANs.\n", |
@@ -2234,11 +2229,8 @@ static int bond_release_all(struct net_device *bond_dev) | |||
2234 | write_lock_bh(&bond->lock); | 2229 | write_lock_bh(&bond->lock); |
2235 | } | 2230 | } |
2236 | 2231 | ||
2237 | /* zero the mac address of the master so it will be | 2232 | eth_hw_addr_random(bond_dev); |
2238 | * set by the application to the mac address of the | 2233 | bond->dev_addr_from_first = true; |
2239 | * first slave | ||
2240 | */ | ||
2241 | memset(bond_dev->dev_addr, 0, bond_dev->addr_len); | ||
2242 | 2234 | ||
2243 | if (bond_vlan_used(bond)) { | 2235 | if (bond_vlan_used(bond)) { |
2244 | pr_warning("%s: Warning: clearing HW address of %s while it still has VLANs.\n", | 2236 | pr_warning("%s: Warning: clearing HW address of %s while it still has VLANs.\n", |
@@ -3708,7 +3700,8 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd | |||
3708 | break; | 3700 | break; |
3709 | case BOND_SETHWADDR_OLD: | 3701 | case BOND_SETHWADDR_OLD: |
3710 | case SIOCBONDSETHWADDR: | 3702 | case SIOCBONDSETHWADDR: |
3711 | res = bond_sethwaddr(bond_dev, slave_dev); | 3703 | bond_set_dev_addr(bond_dev, slave_dev); |
3704 | res = 0; | ||
3712 | break; | 3705 | break; |
3713 | case BOND_CHANGE_ACTIVE_OLD: | 3706 | case BOND_CHANGE_ACTIVE_OLD: |
3714 | case SIOCBONDCHANGEACTIVE: | 3707 | case SIOCBONDCHANGEACTIVE: |
@@ -4858,6 +4851,13 @@ static int bond_init(struct net_device *bond_dev) | |||
4858 | 4851 | ||
4859 | bond_debug_register(bond); | 4852 | bond_debug_register(bond); |
4860 | 4853 | ||
4854 | /* Ensure valid dev_addr */ | ||
4855 | if (is_zero_ether_addr(bond_dev->dev_addr) && | ||
4856 | bond_dev->addr_assign_type == NET_ADDR_PERM) { | ||
4857 | eth_hw_addr_random(bond_dev); | ||
4858 | bond->dev_addr_from_first = true; | ||
4859 | } | ||
4860 | |||
4861 | __hw_addr_init(&bond->mc_list); | 4861 | __hw_addr_init(&bond->mc_list); |
4862 | return 0; | 4862 | return 0; |
4863 | } | 4863 | } |
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 0d282d20b5a8..2baec24388b1 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h | |||
@@ -248,6 +248,7 @@ struct bonding { | |||
248 | /* debugging support via debugfs */ | 248 | /* debugging support via debugfs */ |
249 | struct dentry *debug_dir; | 249 | struct dentry *debug_dir; |
250 | #endif /* CONFIG_DEBUG_FS */ | 250 | #endif /* CONFIG_DEBUG_FS */ |
251 | bool dev_addr_from_first; | ||
251 | }; | 252 | }; |
252 | 253 | ||
253 | static inline bool bond_vlan_used(struct bonding *bond) | 254 | static inline bool bond_vlan_used(struct bonding *bond) |