diff options
Diffstat (limited to 'drivers/net/bonding/bond_main.c')
-rw-r--r-- | drivers/net/bonding/bond_main.c | 48 |
1 files changed, 29 insertions, 19 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index d0aade04e49a..f97569613526 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -764,8 +764,8 @@ static void bond_resend_igmp_join_requests(struct bonding *bond) | |||
764 | struct net_device *bond_dev, *vlan_dev, *upper_dev; | 764 | struct net_device *bond_dev, *vlan_dev, *upper_dev; |
765 | struct vlan_entry *vlan; | 765 | struct vlan_entry *vlan; |
766 | 766 | ||
767 | rcu_read_lock(); | ||
768 | read_lock(&bond->lock); | 767 | read_lock(&bond->lock); |
768 | rcu_read_lock(); | ||
769 | 769 | ||
770 | bond_dev = bond->dev; | 770 | bond_dev = bond->dev; |
771 | 771 | ||
@@ -787,12 +787,19 @@ static void bond_resend_igmp_join_requests(struct bonding *bond) | |||
787 | if (vlan_dev) | 787 | if (vlan_dev) |
788 | __bond_resend_igmp_join_requests(vlan_dev); | 788 | __bond_resend_igmp_join_requests(vlan_dev); |
789 | } | 789 | } |
790 | rcu_read_unlock(); | ||
790 | 791 | ||
791 | if (--bond->igmp_retrans > 0) | 792 | /* We use curr_slave_lock to protect against concurrent access to |
793 | * igmp_retrans from multiple running instances of this function and | ||
794 | * bond_change_active_slave | ||
795 | */ | ||
796 | write_lock_bh(&bond->curr_slave_lock); | ||
797 | if (bond->igmp_retrans > 1) { | ||
798 | bond->igmp_retrans--; | ||
792 | queue_delayed_work(bond->wq, &bond->mcast_work, HZ/5); | 799 | queue_delayed_work(bond->wq, &bond->mcast_work, HZ/5); |
793 | 800 | } | |
801 | write_unlock_bh(&bond->curr_slave_lock); | ||
794 | read_unlock(&bond->lock); | 802 | read_unlock(&bond->lock); |
795 | rcu_read_unlock(); | ||
796 | } | 803 | } |
797 | 804 | ||
798 | static void bond_resend_igmp_join_requests_delayed(struct work_struct *work) | 805 | static void bond_resend_igmp_join_requests_delayed(struct work_struct *work) |
@@ -1362,6 +1369,7 @@ static netdev_features_t bond_fix_features(struct net_device *dev, | |||
1362 | slave->dev->features, | 1369 | slave->dev->features, |
1363 | mask); | 1370 | mask); |
1364 | } | 1371 | } |
1372 | features = netdev_add_tso_features(features, mask); | ||
1365 | 1373 | ||
1366 | out: | 1374 | out: |
1367 | read_unlock(&bond->lock); | 1375 | read_unlock(&bond->lock); |
@@ -1956,6 +1964,10 @@ err_free: | |||
1956 | 1964 | ||
1957 | err_undo_flags: | 1965 | err_undo_flags: |
1958 | bond_compute_features(bond); | 1966 | bond_compute_features(bond); |
1967 | /* Enslave of first slave has failed and we need to fix master's mac */ | ||
1968 | if (bond->slave_cnt == 0 && | ||
1969 | ether_addr_equal(bond_dev->dev_addr, slave_dev->dev_addr)) | ||
1970 | eth_hw_addr_random(bond_dev); | ||
1959 | 1971 | ||
1960 | return res; | 1972 | return res; |
1961 | } | 1973 | } |
@@ -2401,7 +2413,8 @@ static void bond_miimon_commit(struct bonding *bond) | |||
2401 | 2413 | ||
2402 | pr_info("%s: link status definitely up for interface %s, %u Mbps %s duplex.\n", | 2414 | pr_info("%s: link status definitely up for interface %s, %u Mbps %s duplex.\n", |
2403 | bond->dev->name, slave->dev->name, | 2415 | bond->dev->name, slave->dev->name, |
2404 | slave->speed, slave->duplex ? "full" : "half"); | 2416 | slave->speed == SPEED_UNKNOWN ? 0 : slave->speed, |
2417 | slave->duplex ? "full" : "half"); | ||
2405 | 2418 | ||
2406 | /* notify ad that the link status has changed */ | 2419 | /* notify ad that the link status has changed */ |
2407 | if (bond->params.mode == BOND_MODE_8023AD) | 2420 | if (bond->params.mode == BOND_MODE_8023AD) |
@@ -2555,8 +2568,8 @@ static void bond_arp_send(struct net_device *slave_dev, int arp_op, __be32 dest_ | |||
2555 | { | 2568 | { |
2556 | struct sk_buff *skb; | 2569 | struct sk_buff *skb; |
2557 | 2570 | ||
2558 | pr_debug("arp %d on slave %s: dst %x src %x vid %d\n", arp_op, | 2571 | pr_debug("arp %d on slave %s: dst %pI4 src %pI4 vid %d\n", arp_op, |
2559 | slave_dev->name, dest_ip, src_ip, vlan_id); | 2572 | slave_dev->name, &dest_ip, &src_ip, vlan_id); |
2560 | 2573 | ||
2561 | skb = arp_create(arp_op, ETH_P_ARP, dest_ip, slave_dev, src_ip, | 2574 | skb = arp_create(arp_op, ETH_P_ARP, dest_ip, slave_dev, src_ip, |
2562 | NULL, slave_dev->dev_addr, NULL); | 2575 | NULL, slave_dev->dev_addr, NULL); |
@@ -2588,7 +2601,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave) | |||
2588 | __be32 addr; | 2601 | __be32 addr; |
2589 | if (!targets[i]) | 2602 | if (!targets[i]) |
2590 | break; | 2603 | break; |
2591 | pr_debug("basa: target %x\n", targets[i]); | 2604 | pr_debug("basa: target %pI4\n", &targets[i]); |
2592 | if (!bond_vlan_used(bond)) { | 2605 | if (!bond_vlan_used(bond)) { |
2593 | pr_debug("basa: empty vlan: arp_send\n"); | 2606 | pr_debug("basa: empty vlan: arp_send\n"); |
2594 | addr = bond_confirm_addr(bond->dev, targets[i], 0); | 2607 | addr = bond_confirm_addr(bond->dev, targets[i], 0); |
@@ -4470,7 +4483,7 @@ int bond_parse_parm(const char *buf, const struct bond_parm_tbl *tbl) | |||
4470 | 4483 | ||
4471 | static int bond_check_params(struct bond_params *params) | 4484 | static int bond_check_params(struct bond_params *params) |
4472 | { | 4485 | { |
4473 | int arp_validate_value, fail_over_mac_value, primary_reselect_value; | 4486 | int arp_validate_value, fail_over_mac_value, primary_reselect_value, i; |
4474 | 4487 | ||
4475 | /* | 4488 | /* |
4476 | * Convert string parameters. | 4489 | * Convert string parameters. |
@@ -4650,19 +4663,18 @@ static int bond_check_params(struct bond_params *params) | |||
4650 | arp_interval = BOND_LINK_ARP_INTERV; | 4663 | arp_interval = BOND_LINK_ARP_INTERV; |
4651 | } | 4664 | } |
4652 | 4665 | ||
4653 | for (arp_ip_count = 0; | 4666 | for (arp_ip_count = 0, i = 0; |
4654 | (arp_ip_count < BOND_MAX_ARP_TARGETS) && arp_ip_target[arp_ip_count]; | 4667 | (arp_ip_count < BOND_MAX_ARP_TARGETS) && arp_ip_target[i]; i++) { |
4655 | arp_ip_count++) { | ||
4656 | /* not complete check, but should be good enough to | 4668 | /* not complete check, but should be good enough to |
4657 | catch mistakes */ | 4669 | catch mistakes */ |
4658 | __be32 ip = in_aton(arp_ip_target[arp_ip_count]); | 4670 | __be32 ip = in_aton(arp_ip_target[i]); |
4659 | if (!isdigit(arp_ip_target[arp_ip_count][0]) || | 4671 | if (!isdigit(arp_ip_target[i][0]) || ip == 0 || |
4660 | ip == 0 || ip == htonl(INADDR_BROADCAST)) { | 4672 | ip == htonl(INADDR_BROADCAST)) { |
4661 | pr_warning("Warning: bad arp_ip_target module parameter (%s), ARP monitoring will not be performed\n", | 4673 | pr_warning("Warning: bad arp_ip_target module parameter (%s), ARP monitoring will not be performed\n", |
4662 | arp_ip_target[arp_ip_count]); | 4674 | arp_ip_target[i]); |
4663 | arp_interval = 0; | 4675 | arp_interval = 0; |
4664 | } else { | 4676 | } else { |
4665 | arp_target[arp_ip_count] = ip; | 4677 | arp_target[arp_ip_count++] = ip; |
4666 | } | 4678 | } |
4667 | } | 4679 | } |
4668 | 4680 | ||
@@ -4696,8 +4708,6 @@ static int bond_check_params(struct bond_params *params) | |||
4696 | if (miimon) { | 4708 | if (miimon) { |
4697 | pr_info("MII link monitoring set to %d ms\n", miimon); | 4709 | pr_info("MII link monitoring set to %d ms\n", miimon); |
4698 | } else if (arp_interval) { | 4710 | } else if (arp_interval) { |
4699 | int i; | ||
4700 | |||
4701 | pr_info("ARP monitoring set to %d ms, validate %s, with %d target(s):", | 4711 | pr_info("ARP monitoring set to %d ms, validate %s, with %d target(s):", |
4702 | arp_interval, | 4712 | arp_interval, |
4703 | arp_validate_tbl[arp_validate_value].modename, | 4713 | arp_validate_tbl[arp_validate_value].modename, |