diff options
Diffstat (limited to 'drivers/net/bonding')
-rw-r--r-- | drivers/net/bonding/bond_3ad.c | 30 | ||||
-rw-r--r-- | drivers/net/bonding/bond_alb.c | 6 | ||||
-rw-r--r-- | drivers/net/bonding/bond_main.c | 148 | ||||
-rw-r--r-- | drivers/net/bonding/bonding.h | 15 |
4 files changed, 110 insertions, 89 deletions
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index a030e635f001..84fabd69df4c 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c | |||
@@ -1127,7 +1127,7 @@ static void ad_rx_machine(struct lacpdu *lacpdu, struct port *port) | |||
1127 | // INFO_RECEIVED_LOOPBACK_FRAMES | 1127 | // INFO_RECEIVED_LOOPBACK_FRAMES |
1128 | pr_err("%s: An illegal loopback occurred on adapter (%s).\n" | 1128 | pr_err("%s: An illegal loopback occurred on adapter (%s).\n" |
1129 | "Check the configuration to verify that all adapters are connected to 802.3ad compliant switch ports\n", | 1129 | "Check the configuration to verify that all adapters are connected to 802.3ad compliant switch ports\n", |
1130 | port->slave->dev->master->name, port->slave->dev->name); | 1130 | port->slave->bond->dev->name, port->slave->dev->name); |
1131 | return; | 1131 | return; |
1132 | } | 1132 | } |
1133 | __update_selected(lacpdu, port); | 1133 | __update_selected(lacpdu, port); |
@@ -1306,7 +1306,7 @@ static void ad_port_selection_logic(struct port *port) | |||
1306 | } | 1306 | } |
1307 | if (!curr_port) { // meaning: the port was related to an aggregator but was not on the aggregator port list | 1307 | if (!curr_port) { // meaning: the port was related to an aggregator but was not on the aggregator port list |
1308 | pr_warning("%s: Warning: Port %d (on %s) was related to aggregator %d but was not on its port list\n", | 1308 | pr_warning("%s: Warning: Port %d (on %s) was related to aggregator %d but was not on its port list\n", |
1309 | port->slave->dev->master->name, | 1309 | port->slave->bond->dev->name, |
1310 | port->actor_port_number, | 1310 | port->actor_port_number, |
1311 | port->slave->dev->name, | 1311 | port->slave->dev->name, |
1312 | port->aggregator->aggregator_identifier); | 1312 | port->aggregator->aggregator_identifier); |
@@ -1386,7 +1386,7 @@ static void ad_port_selection_logic(struct port *port) | |||
1386 | port->aggregator->aggregator_identifier); | 1386 | port->aggregator->aggregator_identifier); |
1387 | } else { | 1387 | } else { |
1388 | pr_err("%s: Port %d (on %s) did not find a suitable aggregator\n", | 1388 | pr_err("%s: Port %d (on %s) did not find a suitable aggregator\n", |
1389 | port->slave->dev->master->name, | 1389 | port->slave->bond->dev->name, |
1390 | port->actor_port_number, port->slave->dev->name); | 1390 | port->actor_port_number, port->slave->dev->name); |
1391 | } | 1391 | } |
1392 | } | 1392 | } |
@@ -1463,7 +1463,7 @@ static struct aggregator *ad_agg_selection_test(struct aggregator *best, | |||
1463 | 1463 | ||
1464 | default: | 1464 | default: |
1465 | pr_warning("%s: Impossible agg select mode %d\n", | 1465 | pr_warning("%s: Impossible agg select mode %d\n", |
1466 | curr->slave->dev->master->name, | 1466 | curr->slave->bond->dev->name, |
1467 | __get_agg_selection_mode(curr->lag_ports)); | 1467 | __get_agg_selection_mode(curr->lag_ports)); |
1468 | break; | 1468 | break; |
1469 | } | 1469 | } |
@@ -1571,7 +1571,7 @@ static void ad_agg_selection_logic(struct aggregator *agg) | |||
1571 | // check if any partner replys | 1571 | // check if any partner replys |
1572 | if (best->is_individual) { | 1572 | if (best->is_individual) { |
1573 | pr_warning("%s: Warning: No 802.3ad response from the link partner for any adapters in the bond\n", | 1573 | pr_warning("%s: Warning: No 802.3ad response from the link partner for any adapters in the bond\n", |
1574 | best->slave ? best->slave->dev->master->name : "NULL"); | 1574 | best->slave ? best->slave->bond->dev->name : "NULL"); |
1575 | } | 1575 | } |
1576 | 1576 | ||
1577 | best->is_active = 1; | 1577 | best->is_active = 1; |
@@ -1898,7 +1898,7 @@ int bond_3ad_bind_slave(struct slave *slave) | |||
1898 | 1898 | ||
1899 | if (bond == NULL) { | 1899 | if (bond == NULL) { |
1900 | pr_err("%s: The slave %s is not attached to its bond\n", | 1900 | pr_err("%s: The slave %s is not attached to its bond\n", |
1901 | slave->dev->master->name, slave->dev->name); | 1901 | slave->bond->dev->name, slave->dev->name); |
1902 | return -1; | 1902 | return -1; |
1903 | } | 1903 | } |
1904 | 1904 | ||
@@ -1973,7 +1973,7 @@ void bond_3ad_unbind_slave(struct slave *slave) | |||
1973 | // if slave is null, the whole port is not initialized | 1973 | // if slave is null, the whole port is not initialized |
1974 | if (!port->slave) { | 1974 | if (!port->slave) { |
1975 | pr_warning("Warning: %s: Trying to unbind an uninitialized port on %s\n", | 1975 | pr_warning("Warning: %s: Trying to unbind an uninitialized port on %s\n", |
1976 | slave->dev->master->name, slave->dev->name); | 1976 | slave->bond->dev->name, slave->dev->name); |
1977 | return; | 1977 | return; |
1978 | } | 1978 | } |
1979 | 1979 | ||
@@ -2009,7 +2009,7 @@ void bond_3ad_unbind_slave(struct slave *slave) | |||
2009 | 2009 | ||
2010 | if ((new_aggregator->lag_ports == port) && new_aggregator->is_active) { | 2010 | if ((new_aggregator->lag_ports == port) && new_aggregator->is_active) { |
2011 | pr_info("%s: Removing an active aggregator\n", | 2011 | pr_info("%s: Removing an active aggregator\n", |
2012 | aggregator->slave->dev->master->name); | 2012 | aggregator->slave->bond->dev->name); |
2013 | // select new active aggregator | 2013 | // select new active aggregator |
2014 | select_new_active_agg = 1; | 2014 | select_new_active_agg = 1; |
2015 | } | 2015 | } |
@@ -2040,7 +2040,7 @@ void bond_3ad_unbind_slave(struct slave *slave) | |||
2040 | ad_agg_selection_logic(__get_first_agg(port)); | 2040 | ad_agg_selection_logic(__get_first_agg(port)); |
2041 | } else { | 2041 | } else { |
2042 | pr_warning("%s: Warning: unbinding aggregator, and could not find a new aggregator for its ports\n", | 2042 | pr_warning("%s: Warning: unbinding aggregator, and could not find a new aggregator for its ports\n", |
2043 | slave->dev->master->name); | 2043 | slave->bond->dev->name); |
2044 | } | 2044 | } |
2045 | } else { // in case that the only port related to this aggregator is the one we want to remove | 2045 | } else { // in case that the only port related to this aggregator is the one we want to remove |
2046 | select_new_active_agg = aggregator->is_active; | 2046 | select_new_active_agg = aggregator->is_active; |
@@ -2048,7 +2048,7 @@ void bond_3ad_unbind_slave(struct slave *slave) | |||
2048 | ad_clear_agg(aggregator); | 2048 | ad_clear_agg(aggregator); |
2049 | if (select_new_active_agg) { | 2049 | if (select_new_active_agg) { |
2050 | pr_info("%s: Removing an active aggregator\n", | 2050 | pr_info("%s: Removing an active aggregator\n", |
2051 | slave->dev->master->name); | 2051 | slave->bond->dev->name); |
2052 | // select new active aggregator | 2052 | // select new active aggregator |
2053 | ad_agg_selection_logic(__get_first_agg(port)); | 2053 | ad_agg_selection_logic(__get_first_agg(port)); |
2054 | } | 2054 | } |
@@ -2076,7 +2076,7 @@ void bond_3ad_unbind_slave(struct slave *slave) | |||
2076 | ad_clear_agg(temp_aggregator); | 2076 | ad_clear_agg(temp_aggregator); |
2077 | if (select_new_active_agg) { | 2077 | if (select_new_active_agg) { |
2078 | pr_info("%s: Removing an active aggregator\n", | 2078 | pr_info("%s: Removing an active aggregator\n", |
2079 | slave->dev->master->name); | 2079 | slave->bond->dev->name); |
2080 | // select new active aggregator | 2080 | // select new active aggregator |
2081 | ad_agg_selection_logic(__get_first_agg(port)); | 2081 | ad_agg_selection_logic(__get_first_agg(port)); |
2082 | } | 2082 | } |
@@ -2184,7 +2184,7 @@ static int bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u1 | |||
2184 | 2184 | ||
2185 | if (!port->slave) { | 2185 | if (!port->slave) { |
2186 | pr_warning("%s: Warning: port of slave %s is uninitialized\n", | 2186 | pr_warning("%s: Warning: port of slave %s is uninitialized\n", |
2187 | slave->dev->name, slave->dev->master->name); | 2187 | slave->dev->name, slave->bond->dev->name); |
2188 | return ret; | 2188 | return ret; |
2189 | } | 2189 | } |
2190 | 2190 | ||
@@ -2240,7 +2240,7 @@ void bond_3ad_adapter_speed_changed(struct slave *slave) | |||
2240 | // if slave is null, the whole port is not initialized | 2240 | // if slave is null, the whole port is not initialized |
2241 | if (!port->slave) { | 2241 | if (!port->slave) { |
2242 | pr_warning("Warning: %s: speed changed for uninitialized port on %s\n", | 2242 | pr_warning("Warning: %s: speed changed for uninitialized port on %s\n", |
2243 | slave->dev->master->name, slave->dev->name); | 2243 | slave->bond->dev->name, slave->dev->name); |
2244 | return; | 2244 | return; |
2245 | } | 2245 | } |
2246 | 2246 | ||
@@ -2268,7 +2268,7 @@ void bond_3ad_adapter_duplex_changed(struct slave *slave) | |||
2268 | // if slave is null, the whole port is not initialized | 2268 | // if slave is null, the whole port is not initialized |
2269 | if (!port->slave) { | 2269 | if (!port->slave) { |
2270 | pr_warning("%s: Warning: duplex changed for uninitialized port on %s\n", | 2270 | pr_warning("%s: Warning: duplex changed for uninitialized port on %s\n", |
2271 | slave->dev->master->name, slave->dev->name); | 2271 | slave->bond->dev->name, slave->dev->name); |
2272 | return; | 2272 | return; |
2273 | } | 2273 | } |
2274 | 2274 | ||
@@ -2297,7 +2297,7 @@ void bond_3ad_handle_link_change(struct slave *slave, char link) | |||
2297 | // if slave is null, the whole port is not initialized | 2297 | // if slave is null, the whole port is not initialized |
2298 | if (!port->slave) { | 2298 | if (!port->slave) { |
2299 | pr_warning("Warning: %s: link status changed for uninitialized port on %s\n", | 2299 | pr_warning("Warning: %s: link status changed for uninitialized port on %s\n", |
2300 | slave->dev->master->name, slave->dev->name); | 2300 | slave->bond->dev->name, slave->dev->name); |
2301 | return; | 2301 | return; |
2302 | } | 2302 | } |
2303 | 2303 | ||
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 7c9d136e74be..f5e052723029 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c | |||
@@ -507,7 +507,7 @@ static void rlb_update_client(struct rlb_client_info *client_info) | |||
507 | client_info->mac_dst); | 507 | client_info->mac_dst); |
508 | if (!skb) { | 508 | if (!skb) { |
509 | pr_err("%s: Error: failed to create an ARP packet\n", | 509 | pr_err("%s: Error: failed to create an ARP packet\n", |
510 | client_info->slave->dev->master->name); | 510 | client_info->slave->bond->dev->name); |
511 | continue; | 511 | continue; |
512 | } | 512 | } |
513 | 513 | ||
@@ -517,7 +517,7 @@ static void rlb_update_client(struct rlb_client_info *client_info) | |||
517 | skb = vlan_put_tag(skb, client_info->vlan_id); | 517 | skb = vlan_put_tag(skb, client_info->vlan_id); |
518 | if (!skb) { | 518 | if (!skb) { |
519 | pr_err("%s: Error: failed to insert VLAN tag\n", | 519 | pr_err("%s: Error: failed to insert VLAN tag\n", |
520 | client_info->slave->dev->master->name); | 520 | client_info->slave->bond->dev->name); |
521 | continue; | 521 | continue; |
522 | } | 522 | } |
523 | } | 523 | } |
@@ -1043,7 +1043,7 @@ static int alb_set_slave_mac_addr(struct slave *slave, u8 addr[]) | |||
1043 | if (dev_set_mac_address(dev, &s_addr)) { | 1043 | if (dev_set_mac_address(dev, &s_addr)) { |
1044 | pr_err("%s: Error: dev_set_mac_address of dev %s failed!\n" | 1044 | pr_err("%s: Error: dev_set_mac_address of dev %s failed!\n" |
1045 | "ALB mode requires that the base driver support setting the hw address also when the network device's interface is open\n", | 1045 | "ALB mode requires that the base driver support setting the hw address also when the network device's interface is open\n", |
1046 | dev->master->name, dev->name); | 1046 | slave->bond->dev->name, dev->name); |
1047 | return -EOPNOTSUPP; | 1047 | return -EOPNOTSUPP; |
1048 | } | 1048 | } |
1049 | return 0; | 1049 | return 0; |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index b7d45f367d4a..22399374b1e1 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -746,11 +746,9 @@ static void __bond_resend_igmp_join_requests(struct net_device *dev) | |||
746 | { | 746 | { |
747 | struct in_device *in_dev; | 747 | struct in_device *in_dev; |
748 | 748 | ||
749 | rcu_read_lock(); | ||
750 | in_dev = __in_dev_get_rcu(dev); | 749 | in_dev = __in_dev_get_rcu(dev); |
751 | if (in_dev) | 750 | if (in_dev) |
752 | ip_mc_rejoin_groups(in_dev); | 751 | ip_mc_rejoin_groups(in_dev); |
753 | rcu_read_unlock(); | ||
754 | } | 752 | } |
755 | 753 | ||
756 | /* | 754 | /* |
@@ -760,9 +758,10 @@ static void __bond_resend_igmp_join_requests(struct net_device *dev) | |||
760 | */ | 758 | */ |
761 | static void bond_resend_igmp_join_requests(struct bonding *bond) | 759 | static void bond_resend_igmp_join_requests(struct bonding *bond) |
762 | { | 760 | { |
763 | struct net_device *bond_dev, *vlan_dev, *master_dev; | 761 | struct net_device *bond_dev, *vlan_dev, *upper_dev; |
764 | struct vlan_entry *vlan; | 762 | struct vlan_entry *vlan; |
765 | 763 | ||
764 | rcu_read_lock(); | ||
766 | read_lock(&bond->lock); | 765 | read_lock(&bond->lock); |
767 | 766 | ||
768 | bond_dev = bond->dev; | 767 | bond_dev = bond->dev; |
@@ -774,18 +773,14 @@ static void bond_resend_igmp_join_requests(struct bonding *bond) | |||
774 | * if bond is enslaved to a bridge, | 773 | * if bond is enslaved to a bridge, |
775 | * then rejoin all groups on its master | 774 | * then rejoin all groups on its master |
776 | */ | 775 | */ |
777 | master_dev = bond_dev->master; | 776 | upper_dev = netdev_master_upper_dev_get_rcu(bond_dev); |
778 | if (master_dev) | 777 | if (upper_dev && upper_dev->priv_flags & IFF_EBRIDGE) |
779 | if ((master_dev->priv_flags & IFF_EBRIDGE) | 778 | __bond_resend_igmp_join_requests(upper_dev); |
780 | && (bond_dev->priv_flags & IFF_BRIDGE_PORT)) | ||
781 | __bond_resend_igmp_join_requests(master_dev); | ||
782 | 779 | ||
783 | /* rejoin all groups on vlan devices */ | 780 | /* rejoin all groups on vlan devices */ |
784 | list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { | 781 | list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { |
785 | rcu_read_lock(); | ||
786 | vlan_dev = __vlan_find_dev_deep(bond_dev, | 782 | vlan_dev = __vlan_find_dev_deep(bond_dev, |
787 | vlan->vlan_id); | 783 | vlan->vlan_id); |
788 | rcu_read_unlock(); | ||
789 | if (vlan_dev) | 784 | if (vlan_dev) |
790 | __bond_resend_igmp_join_requests(vlan_dev); | 785 | __bond_resend_igmp_join_requests(vlan_dev); |
791 | } | 786 | } |
@@ -794,13 +789,16 @@ static void bond_resend_igmp_join_requests(struct bonding *bond) | |||
794 | queue_delayed_work(bond->wq, &bond->mcast_work, HZ/5); | 789 | queue_delayed_work(bond->wq, &bond->mcast_work, HZ/5); |
795 | 790 | ||
796 | read_unlock(&bond->lock); | 791 | read_unlock(&bond->lock); |
792 | rcu_read_unlock(); | ||
797 | } | 793 | } |
798 | 794 | ||
799 | static void bond_resend_igmp_join_requests_delayed(struct work_struct *work) | 795 | static void bond_resend_igmp_join_requests_delayed(struct work_struct *work) |
800 | { | 796 | { |
801 | struct bonding *bond = container_of(work, struct bonding, | 797 | struct bonding *bond = container_of(work, struct bonding, |
802 | mcast_work.work); | 798 | mcast_work.work); |
799 | rcu_read_lock(); | ||
803 | bond_resend_igmp_join_requests(bond); | 800 | bond_resend_igmp_join_requests(bond); |
801 | rcu_read_unlock(); | ||
804 | } | 802 | } |
805 | 803 | ||
806 | /* | 804 | /* |
@@ -1322,14 +1320,15 @@ static void bond_netpoll_cleanup(struct net_device *bond_dev) | |||
1322 | 1320 | ||
1323 | /*---------------------------------- IOCTL ----------------------------------*/ | 1321 | /*---------------------------------- IOCTL ----------------------------------*/ |
1324 | 1322 | ||
1325 | static int bond_sethwaddr(struct net_device *bond_dev, | 1323 | static void bond_set_dev_addr(struct net_device *bond_dev, |
1326 | struct net_device *slave_dev) | 1324 | struct net_device *slave_dev) |
1327 | { | 1325 | { |
1328 | pr_debug("bond_dev=%p\n", bond_dev); | 1326 | pr_debug("bond_dev=%p\n", bond_dev); |
1329 | pr_debug("slave_dev=%p\n", slave_dev); | 1327 | pr_debug("slave_dev=%p\n", slave_dev); |
1330 | 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); |
1331 | 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); |
1332 | return 0; | 1330 | bond_dev->addr_assign_type = NET_ADDR_SET; |
1331 | call_netdevice_notifiers(NETDEV_CHANGEADDR, bond_dev); | ||
1333 | } | 1332 | } |
1334 | 1333 | ||
1335 | static netdev_features_t bond_fix_features(struct net_device *dev, | 1334 | static netdev_features_t bond_fix_features(struct net_device *dev, |
@@ -1493,6 +1492,27 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb) | |||
1493 | return ret; | 1492 | return ret; |
1494 | } | 1493 | } |
1495 | 1494 | ||
1495 | static int bond_master_upper_dev_link(struct net_device *bond_dev, | ||
1496 | struct net_device *slave_dev) | ||
1497 | { | ||
1498 | int err; | ||
1499 | |||
1500 | err = netdev_master_upper_dev_link(slave_dev, bond_dev); | ||
1501 | if (err) | ||
1502 | return err; | ||
1503 | slave_dev->flags |= IFF_SLAVE; | ||
1504 | rtmsg_ifinfo(RTM_NEWLINK, slave_dev, IFF_SLAVE); | ||
1505 | return 0; | ||
1506 | } | ||
1507 | |||
1508 | static void bond_upper_dev_unlink(struct net_device *bond_dev, | ||
1509 | struct net_device *slave_dev) | ||
1510 | { | ||
1511 | netdev_upper_dev_unlink(slave_dev, bond_dev); | ||
1512 | slave_dev->flags &= ~IFF_SLAVE; | ||
1513 | rtmsg_ifinfo(RTM_NEWLINK, slave_dev, IFF_SLAVE); | ||
1514 | } | ||
1515 | |||
1496 | /* enslave device <slave> to bond device <master> */ | 1516 | /* enslave device <slave> to bond device <master> */ |
1497 | int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | 1517 | int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) |
1498 | { | 1518 | { |
@@ -1609,10 +1629,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1609 | 1629 | ||
1610 | /* 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 |
1611 | * address to be the same as the slave's. */ | 1631 | * address to be the same as the slave's. */ |
1612 | if (is_zero_ether_addr(bond->dev->dev_addr)) | 1632 | if (bond->dev_addr_from_first) |
1613 | memcpy(bond->dev->dev_addr, slave_dev->dev_addr, | 1633 | bond_set_dev_addr(bond->dev, slave_dev); |
1614 | slave_dev->addr_len); | ||
1615 | |||
1616 | 1634 | ||
1617 | new_slave = kzalloc(sizeof(struct slave), GFP_KERNEL); | 1635 | new_slave = kzalloc(sizeof(struct slave), GFP_KERNEL); |
1618 | if (!new_slave) { | 1636 | if (!new_slave) { |
@@ -1655,9 +1673,9 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1655 | } | 1673 | } |
1656 | } | 1674 | } |
1657 | 1675 | ||
1658 | res = netdev_set_bond_master(slave_dev, bond_dev); | 1676 | res = bond_master_upper_dev_link(bond_dev, slave_dev); |
1659 | if (res) { | 1677 | if (res) { |
1660 | pr_debug("Error %d calling netdev_set_bond_master\n", res); | 1678 | pr_debug("Error %d calling bond_master_upper_dev_link\n", res); |
1661 | goto err_restore_mac; | 1679 | goto err_restore_mac; |
1662 | } | 1680 | } |
1663 | 1681 | ||
@@ -1891,7 +1909,7 @@ err_close: | |||
1891 | dev_close(slave_dev); | 1909 | dev_close(slave_dev); |
1892 | 1910 | ||
1893 | err_unset_master: | 1911 | err_unset_master: |
1894 | netdev_set_bond_master(slave_dev, NULL); | 1912 | bond_upper_dev_unlink(bond_dev, slave_dev); |
1895 | 1913 | ||
1896 | err_restore_mac: | 1914 | err_restore_mac: |
1897 | if (!bond->params.fail_over_mac) { | 1915 | if (!bond->params.fail_over_mac) { |
@@ -1936,7 +1954,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1936 | 1954 | ||
1937 | /* slave is not a slave or master is not master of this slave */ | 1955 | /* slave is not a slave or master is not master of this slave */ |
1938 | if (!(slave_dev->flags & IFF_SLAVE) || | 1956 | if (!(slave_dev->flags & IFF_SLAVE) || |
1939 | (slave_dev->master != bond_dev)) { | 1957 | !netdev_has_upper_dev(slave_dev, bond_dev)) { |
1940 | pr_err("%s: Error: cannot release %s.\n", | 1958 | pr_err("%s: Error: cannot release %s.\n", |
1941 | bond_dev->name, slave_dev->name); | 1959 | bond_dev->name, slave_dev->name); |
1942 | return -EINVAL; | 1960 | return -EINVAL; |
@@ -2029,12 +2047,8 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) | |||
2029 | 2047 | ||
2030 | if (bond->slave_cnt == 0) { | 2048 | if (bond->slave_cnt == 0) { |
2031 | bond_set_carrier(bond); | 2049 | bond_set_carrier(bond); |
2032 | 2050 | eth_hw_addr_random(bond_dev); | |
2033 | /* if the last slave was removed, zero the mac address | 2051 | bond->dev_addr_from_first = true; |
2034 | * of the master so it will be set by the application | ||
2035 | * to the mac address of the first slave | ||
2036 | */ | ||
2037 | memset(bond_dev->dev_addr, 0, bond_dev->addr_len); | ||
2038 | 2052 | ||
2039 | if (bond_vlan_used(bond)) { | 2053 | if (bond_vlan_used(bond)) { |
2040 | 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", |
@@ -2080,7 +2094,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) | |||
2080 | netif_addr_unlock_bh(bond_dev); | 2094 | netif_addr_unlock_bh(bond_dev); |
2081 | } | 2095 | } |
2082 | 2096 | ||
2083 | netdev_set_bond_master(slave_dev, NULL); | 2097 | bond_upper_dev_unlink(bond_dev, slave_dev); |
2084 | 2098 | ||
2085 | slave_disable_netpoll(slave); | 2099 | slave_disable_netpoll(slave); |
2086 | 2100 | ||
@@ -2195,7 +2209,7 @@ static int bond_release_all(struct net_device *bond_dev) | |||
2195 | netif_addr_unlock_bh(bond_dev); | 2209 | netif_addr_unlock_bh(bond_dev); |
2196 | } | 2210 | } |
2197 | 2211 | ||
2198 | netdev_set_bond_master(slave_dev, NULL); | 2212 | bond_upper_dev_unlink(bond_dev, slave_dev); |
2199 | 2213 | ||
2200 | slave_disable_netpoll(slave); | 2214 | slave_disable_netpoll(slave); |
2201 | 2215 | ||
@@ -2215,11 +2229,8 @@ static int bond_release_all(struct net_device *bond_dev) | |||
2215 | write_lock_bh(&bond->lock); | 2229 | write_lock_bh(&bond->lock); |
2216 | } | 2230 | } |
2217 | 2231 | ||
2218 | /* zero the mac address of the master so it will be | 2232 | eth_hw_addr_random(bond_dev); |
2219 | * set by the application to the mac address of the | 2233 | bond->dev_addr_from_first = true; |
2220 | * first slave | ||
2221 | */ | ||
2222 | memset(bond_dev->dev_addr, 0, bond_dev->addr_len); | ||
2223 | 2234 | ||
2224 | if (bond_vlan_used(bond)) { | 2235 | if (bond_vlan_used(bond)) { |
2225 | 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", |
@@ -2259,8 +2270,9 @@ static int bond_ioctl_change_active(struct net_device *bond_dev, struct net_devi | |||
2259 | if (!USES_PRIMARY(bond->params.mode)) | 2270 | if (!USES_PRIMARY(bond->params.mode)) |
2260 | return -EINVAL; | 2271 | return -EINVAL; |
2261 | 2272 | ||
2262 | /* Verify that master_dev is indeed the master of slave_dev */ | 2273 | /* Verify that bond_dev is indeed the master of slave_dev */ |
2263 | if (!(slave_dev->flags & IFF_SLAVE) || (slave_dev->master != bond_dev)) | 2274 | if (!(slave_dev->flags & IFF_SLAVE) || |
2275 | !netdev_has_upper_dev(slave_dev, bond_dev)) | ||
2264 | return -EINVAL; | 2276 | return -EINVAL; |
2265 | 2277 | ||
2266 | read_lock(&bond->lock); | 2278 | read_lock(&bond->lock); |
@@ -3258,36 +3270,32 @@ static int bond_master_netdev_event(unsigned long event, | |||
3258 | static int bond_slave_netdev_event(unsigned long event, | 3270 | static int bond_slave_netdev_event(unsigned long event, |
3259 | struct net_device *slave_dev) | 3271 | struct net_device *slave_dev) |
3260 | { | 3272 | { |
3261 | struct net_device *bond_dev = slave_dev->master; | 3273 | struct slave *slave = bond_slave_get_rtnl(slave_dev); |
3262 | struct bonding *bond = netdev_priv(bond_dev); | 3274 | struct bonding *bond = slave->bond; |
3263 | struct slave *slave = NULL; | 3275 | struct net_device *bond_dev = slave->bond->dev; |
3276 | u32 old_speed; | ||
3277 | u8 old_duplex; | ||
3264 | 3278 | ||
3265 | switch (event) { | 3279 | switch (event) { |
3266 | case NETDEV_UNREGISTER: | 3280 | case NETDEV_UNREGISTER: |
3267 | if (bond_dev) { | 3281 | if (bond->setup_by_slave) |
3268 | if (bond->setup_by_slave) | 3282 | bond_release_and_destroy(bond_dev, slave_dev); |
3269 | bond_release_and_destroy(bond_dev, slave_dev); | 3283 | else |
3270 | else | 3284 | bond_release(bond_dev, slave_dev); |
3271 | bond_release(bond_dev, slave_dev); | ||
3272 | } | ||
3273 | break; | 3285 | break; |
3274 | case NETDEV_UP: | 3286 | case NETDEV_UP: |
3275 | case NETDEV_CHANGE: | 3287 | case NETDEV_CHANGE: |
3276 | slave = bond_get_slave_by_dev(bond, slave_dev); | 3288 | old_speed = slave->speed; |
3277 | if (slave) { | 3289 | old_duplex = slave->duplex; |
3278 | u32 old_speed = slave->speed; | ||
3279 | u8 old_duplex = slave->duplex; | ||
3280 | 3290 | ||
3281 | bond_update_speed_duplex(slave); | 3291 | bond_update_speed_duplex(slave); |
3282 | 3292 | ||
3283 | if (bond->params.mode == BOND_MODE_8023AD) { | 3293 | if (bond->params.mode == BOND_MODE_8023AD) { |
3284 | if (old_speed != slave->speed) | 3294 | if (old_speed != slave->speed) |
3285 | bond_3ad_adapter_speed_changed(slave); | 3295 | bond_3ad_adapter_speed_changed(slave); |
3286 | if (old_duplex != slave->duplex) | 3296 | if (old_duplex != slave->duplex) |
3287 | bond_3ad_adapter_duplex_changed(slave); | 3297 | bond_3ad_adapter_duplex_changed(slave); |
3288 | } | ||
3289 | } | 3298 | } |
3290 | |||
3291 | break; | 3299 | break; |
3292 | case NETDEV_DOWN: | 3300 | case NETDEV_DOWN: |
3293 | /* | 3301 | /* |
@@ -3604,6 +3612,7 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd | |||
3604 | struct ifslave k_sinfo; | 3612 | struct ifslave k_sinfo; |
3605 | struct ifslave __user *u_sinfo = NULL; | 3613 | struct ifslave __user *u_sinfo = NULL; |
3606 | struct mii_ioctl_data *mii = NULL; | 3614 | struct mii_ioctl_data *mii = NULL; |
3615 | struct net *net; | ||
3607 | int res = 0; | 3616 | int res = 0; |
3608 | 3617 | ||
3609 | pr_debug("bond_ioctl: master=%s, cmd=%d\n", bond_dev->name, cmd); | 3618 | pr_debug("bond_ioctl: master=%s, cmd=%d\n", bond_dev->name, cmd); |
@@ -3670,10 +3679,12 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd | |||
3670 | break; | 3679 | break; |
3671 | } | 3680 | } |
3672 | 3681 | ||
3673 | if (!capable(CAP_NET_ADMIN)) | 3682 | net = dev_net(bond_dev); |
3683 | |||
3684 | if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) | ||
3674 | return -EPERM; | 3685 | return -EPERM; |
3675 | 3686 | ||
3676 | slave_dev = dev_get_by_name(dev_net(bond_dev), ifr->ifr_slave); | 3687 | slave_dev = dev_get_by_name(net, ifr->ifr_slave); |
3677 | 3688 | ||
3678 | pr_debug("slave_dev=%p:\n", slave_dev); | 3689 | pr_debug("slave_dev=%p:\n", slave_dev); |
3679 | 3690 | ||
@@ -3692,7 +3703,8 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd | |||
3692 | break; | 3703 | break; |
3693 | case BOND_SETHWADDR_OLD: | 3704 | case BOND_SETHWADDR_OLD: |
3694 | case SIOCBONDSETHWADDR: | 3705 | case SIOCBONDSETHWADDR: |
3695 | res = bond_sethwaddr(bond_dev, slave_dev); | 3706 | bond_set_dev_addr(bond_dev, slave_dev); |
3707 | res = 0; | ||
3696 | break; | 3708 | break; |
3697 | case BOND_CHANGE_ACTIVE_OLD: | 3709 | case BOND_CHANGE_ACTIVE_OLD: |
3698 | case SIOCBONDCHANGEACTIVE: | 3710 | case SIOCBONDCHANGEACTIVE: |
@@ -4314,11 +4326,12 @@ void bond_set_mode_ops(struct bonding *bond, int mode) | |||
4314 | } | 4326 | } |
4315 | 4327 | ||
4316 | static void bond_ethtool_get_drvinfo(struct net_device *bond_dev, | 4328 | static void bond_ethtool_get_drvinfo(struct net_device *bond_dev, |
4317 | struct ethtool_drvinfo *drvinfo) | 4329 | struct ethtool_drvinfo *drvinfo) |
4318 | { | 4330 | { |
4319 | strncpy(drvinfo->driver, DRV_NAME, 32); | 4331 | strlcpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver)); |
4320 | strncpy(drvinfo->version, DRV_VERSION, 32); | 4332 | strlcpy(drvinfo->version, DRV_VERSION, sizeof(drvinfo->version)); |
4321 | snprintf(drvinfo->fw_version, 32, "%d", BOND_ABI_VERSION); | 4333 | snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), "%d", |
4334 | BOND_ABI_VERSION); | ||
4322 | } | 4335 | } |
4323 | 4336 | ||
4324 | static const struct ethtool_ops bond_ethtool_ops = { | 4337 | static const struct ethtool_ops bond_ethtool_ops = { |
@@ -4841,6 +4854,13 @@ static int bond_init(struct net_device *bond_dev) | |||
4841 | 4854 | ||
4842 | bond_debug_register(bond); | 4855 | bond_debug_register(bond); |
4843 | 4856 | ||
4857 | /* Ensure valid dev_addr */ | ||
4858 | if (is_zero_ether_addr(bond_dev->dev_addr) && | ||
4859 | bond_dev->addr_assign_type == NET_ADDR_PERM) { | ||
4860 | eth_hw_addr_random(bond_dev); | ||
4861 | bond->dev_addr_from_first = true; | ||
4862 | } | ||
4863 | |||
4844 | __hw_addr_init(&bond->mc_list); | 4864 | __hw_addr_init(&bond->mc_list); |
4845 | return 0; | 4865 | return 0; |
4846 | } | 4866 | } |
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 21b68e5c14fd..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) |
@@ -258,6 +259,9 @@ static inline bool bond_vlan_used(struct bonding *bond) | |||
258 | #define bond_slave_get_rcu(dev) \ | 259 | #define bond_slave_get_rcu(dev) \ |
259 | ((struct slave *) rcu_dereference(dev->rx_handler_data)) | 260 | ((struct slave *) rcu_dereference(dev->rx_handler_data)) |
260 | 261 | ||
262 | #define bond_slave_get_rtnl(dev) \ | ||
263 | ((struct slave *) rtnl_dereference(dev->rx_handler_data)) | ||
264 | |||
261 | /** | 265 | /** |
262 | * Returns NULL if the net_device does not belong to any of the bond's slaves | 266 | * Returns NULL if the net_device does not belong to any of the bond's slaves |
263 | * | 267 | * |
@@ -280,11 +284,9 @@ static inline struct slave *bond_get_slave_by_dev(struct bonding *bond, | |||
280 | 284 | ||
281 | static inline struct bonding *bond_get_bond_by_slave(struct slave *slave) | 285 | static inline struct bonding *bond_get_bond_by_slave(struct slave *slave) |
282 | { | 286 | { |
283 | if (!slave || !slave->dev->master) { | 287 | if (!slave || !slave->bond) |
284 | return NULL; | 288 | return NULL; |
285 | } | 289 | return slave->bond; |
286 | |||
287 | return netdev_priv(slave->dev->master); | ||
288 | } | 290 | } |
289 | 291 | ||
290 | static inline bool bond_is_lb(const struct bonding *bond) | 292 | static inline bool bond_is_lb(const struct bonding *bond) |
@@ -360,10 +362,9 @@ static inline void bond_netpoll_send_skb(const struct slave *slave, | |||
360 | 362 | ||
361 | static inline void bond_set_slave_inactive_flags(struct slave *slave) | 363 | static inline void bond_set_slave_inactive_flags(struct slave *slave) |
362 | { | 364 | { |
363 | struct bonding *bond = netdev_priv(slave->dev->master); | 365 | if (!bond_is_lb(slave->bond)) |
364 | if (!bond_is_lb(bond)) | ||
365 | bond_set_backup_slave(slave); | 366 | bond_set_backup_slave(slave); |
366 | if (!bond->params.all_slaves_active) | 367 | if (!slave->bond->params.all_slaves_active) |
367 | slave->inactive = 1; | 368 | slave->inactive = 1; |
368 | } | 369 | } |
369 | 370 | ||