diff options
Diffstat (limited to 'drivers/net/bonding')
-rw-r--r-- | drivers/net/bonding/bond_main.c | 12 | ||||
-rw-r--r-- | drivers/net/bonding/bond_sysfs.c | 92 |
2 files changed, 58 insertions, 46 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 6bbd90e1123c..07401a3e256b 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -1976,12 +1976,11 @@ static int __bond_release_one(struct net_device *bond_dev, | |||
1976 | return -EINVAL; | 1976 | return -EINVAL; |
1977 | } | 1977 | } |
1978 | 1978 | ||
1979 | write_unlock_bh(&bond->lock); | ||
1979 | /* unregister rx_handler early so bond_handle_frame wouldn't be called | 1980 | /* unregister rx_handler early so bond_handle_frame wouldn't be called |
1980 | * for this slave anymore. | 1981 | * for this slave anymore. |
1981 | */ | 1982 | */ |
1982 | netdev_rx_handler_unregister(slave_dev); | 1983 | netdev_rx_handler_unregister(slave_dev); |
1983 | write_unlock_bh(&bond->lock); | ||
1984 | synchronize_net(); | ||
1985 | write_lock_bh(&bond->lock); | 1984 | write_lock_bh(&bond->lock); |
1986 | 1985 | ||
1987 | if (!all && !bond->params.fail_over_mac) { | 1986 | if (!all && !bond->params.fail_over_mac) { |
@@ -4847,9 +4846,18 @@ static int __net_init bond_net_init(struct net *net) | |||
4847 | static void __net_exit bond_net_exit(struct net *net) | 4846 | static void __net_exit bond_net_exit(struct net *net) |
4848 | { | 4847 | { |
4849 | struct bond_net *bn = net_generic(net, bond_net_id); | 4848 | struct bond_net *bn = net_generic(net, bond_net_id); |
4849 | struct bonding *bond, *tmp_bond; | ||
4850 | LIST_HEAD(list); | ||
4850 | 4851 | ||
4851 | bond_destroy_sysfs(bn); | 4852 | bond_destroy_sysfs(bn); |
4852 | bond_destroy_proc_dir(bn); | 4853 | bond_destroy_proc_dir(bn); |
4854 | |||
4855 | /* Kill off any bonds created after unregistering bond rtnl ops */ | ||
4856 | rtnl_lock(); | ||
4857 | list_for_each_entry_safe(bond, tmp_bond, &bn->dev_list, bond_list) | ||
4858 | unregister_netdevice_queue(bond->dev, &list); | ||
4859 | unregister_netdevice_many(&list); | ||
4860 | rtnl_unlock(); | ||
4853 | } | 4861 | } |
4854 | 4862 | ||
4855 | static struct pernet_operations bond_net_ops = { | 4863 | static struct pernet_operations bond_net_ops = { |
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index db103e03ba05..ea7a388f4843 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c | |||
@@ -527,7 +527,7 @@ static ssize_t bonding_store_arp_interval(struct device *d, | |||
527 | goto out; | 527 | goto out; |
528 | } | 528 | } |
529 | if (new_value < 0) { | 529 | if (new_value < 0) { |
530 | pr_err("%s: Invalid arp_interval value %d not in range 1-%d; rejected.\n", | 530 | pr_err("%s: Invalid arp_interval value %d not in range 0-%d; rejected.\n", |
531 | bond->dev->name, new_value, INT_MAX); | 531 | bond->dev->name, new_value, INT_MAX); |
532 | ret = -EINVAL; | 532 | ret = -EINVAL; |
533 | goto out; | 533 | goto out; |
@@ -542,14 +542,15 @@ static ssize_t bonding_store_arp_interval(struct device *d, | |||
542 | pr_info("%s: Setting ARP monitoring interval to %d.\n", | 542 | pr_info("%s: Setting ARP monitoring interval to %d.\n", |
543 | bond->dev->name, new_value); | 543 | bond->dev->name, new_value); |
544 | bond->params.arp_interval = new_value; | 544 | bond->params.arp_interval = new_value; |
545 | if (bond->params.miimon) { | 545 | if (new_value) { |
546 | pr_info("%s: ARP monitoring cannot be used with MII monitoring. %s Disabling MII monitoring.\n", | 546 | if (bond->params.miimon) { |
547 | bond->dev->name, bond->dev->name); | 547 | pr_info("%s: ARP monitoring cannot be used with MII monitoring. %s Disabling MII monitoring.\n", |
548 | bond->params.miimon = 0; | 548 | bond->dev->name, bond->dev->name); |
549 | } | 549 | bond->params.miimon = 0; |
550 | if (!bond->params.arp_targets[0]) { | 550 | } |
551 | pr_info("%s: ARP monitoring has been set up, but no ARP targets have been specified.\n", | 551 | if (!bond->params.arp_targets[0]) |
552 | bond->dev->name); | 552 | pr_info("%s: ARP monitoring has been set up, but no ARP targets have been specified.\n", |
553 | bond->dev->name); | ||
553 | } | 554 | } |
554 | if (bond->dev->flags & IFF_UP) { | 555 | if (bond->dev->flags & IFF_UP) { |
555 | /* If the interface is up, we may need to fire off | 556 | /* If the interface is up, we may need to fire off |
@@ -557,10 +558,13 @@ static ssize_t bonding_store_arp_interval(struct device *d, | |||
557 | * timer will get fired off when the open function | 558 | * timer will get fired off when the open function |
558 | * is called. | 559 | * is called. |
559 | */ | 560 | */ |
560 | cancel_delayed_work_sync(&bond->mii_work); | 561 | if (!new_value) { |
561 | queue_delayed_work(bond->wq, &bond->arp_work, 0); | 562 | cancel_delayed_work_sync(&bond->arp_work); |
563 | } else { | ||
564 | cancel_delayed_work_sync(&bond->mii_work); | ||
565 | queue_delayed_work(bond->wq, &bond->arp_work, 0); | ||
566 | } | ||
562 | } | 567 | } |
563 | |||
564 | out: | 568 | out: |
565 | rtnl_unlock(); | 569 | rtnl_unlock(); |
566 | return ret; | 570 | return ret; |
@@ -702,7 +706,7 @@ static ssize_t bonding_store_downdelay(struct device *d, | |||
702 | } | 706 | } |
703 | if (new_value < 0) { | 707 | if (new_value < 0) { |
704 | pr_err("%s: Invalid down delay value %d not in range %d-%d; rejected.\n", | 708 | pr_err("%s: Invalid down delay value %d not in range %d-%d; rejected.\n", |
705 | bond->dev->name, new_value, 1, INT_MAX); | 709 | bond->dev->name, new_value, 0, INT_MAX); |
706 | ret = -EINVAL; | 710 | ret = -EINVAL; |
707 | goto out; | 711 | goto out; |
708 | } else { | 712 | } else { |
@@ -757,8 +761,8 @@ static ssize_t bonding_store_updelay(struct device *d, | |||
757 | goto out; | 761 | goto out; |
758 | } | 762 | } |
759 | if (new_value < 0) { | 763 | if (new_value < 0) { |
760 | pr_err("%s: Invalid down delay value %d not in range %d-%d; rejected.\n", | 764 | pr_err("%s: Invalid up delay value %d not in range %d-%d; rejected.\n", |
761 | bond->dev->name, new_value, 1, INT_MAX); | 765 | bond->dev->name, new_value, 0, INT_MAX); |
762 | ret = -EINVAL; | 766 | ret = -EINVAL; |
763 | goto out; | 767 | goto out; |
764 | } else { | 768 | } else { |
@@ -968,37 +972,37 @@ static ssize_t bonding_store_miimon(struct device *d, | |||
968 | } | 972 | } |
969 | if (new_value < 0) { | 973 | if (new_value < 0) { |
970 | pr_err("%s: Invalid miimon value %d not in range %d-%d; rejected.\n", | 974 | pr_err("%s: Invalid miimon value %d not in range %d-%d; rejected.\n", |
971 | bond->dev->name, new_value, 1, INT_MAX); | 975 | bond->dev->name, new_value, 0, INT_MAX); |
972 | ret = -EINVAL; | 976 | ret = -EINVAL; |
973 | goto out; | 977 | goto out; |
974 | } else { | 978 | } |
975 | pr_info("%s: Setting MII monitoring interval to %d.\n", | 979 | pr_info("%s: Setting MII monitoring interval to %d.\n", |
976 | bond->dev->name, new_value); | 980 | bond->dev->name, new_value); |
977 | bond->params.miimon = new_value; | 981 | bond->params.miimon = new_value; |
978 | if (bond->params.updelay) | 982 | if (bond->params.updelay) |
979 | pr_info("%s: Note: Updating updelay (to %d) since it is a multiple of the miimon value.\n", | 983 | pr_info("%s: Note: Updating updelay (to %d) since it is a multiple of the miimon value.\n", |
980 | bond->dev->name, | 984 | bond->dev->name, |
981 | bond->params.updelay * bond->params.miimon); | 985 | bond->params.updelay * bond->params.miimon); |
982 | if (bond->params.downdelay) | 986 | if (bond->params.downdelay) |
983 | pr_info("%s: Note: Updating downdelay (to %d) since it is a multiple of the miimon value.\n", | 987 | pr_info("%s: Note: Updating downdelay (to %d) since it is a multiple of the miimon value.\n", |
984 | bond->dev->name, | 988 | bond->dev->name, |
985 | bond->params.downdelay * bond->params.miimon); | 989 | bond->params.downdelay * bond->params.miimon); |
986 | if (bond->params.arp_interval) { | 990 | if (new_value && bond->params.arp_interval) { |
987 | pr_info("%s: MII monitoring cannot be used with ARP monitoring. Disabling ARP monitoring...\n", | 991 | pr_info("%s: MII monitoring cannot be used with ARP monitoring. Disabling ARP monitoring...\n", |
988 | bond->dev->name); | 992 | bond->dev->name); |
989 | bond->params.arp_interval = 0; | 993 | bond->params.arp_interval = 0; |
990 | if (bond->params.arp_validate) { | 994 | if (bond->params.arp_validate) |
991 | bond->params.arp_validate = | 995 | bond->params.arp_validate = BOND_ARP_VALIDATE_NONE; |
992 | BOND_ARP_VALIDATE_NONE; | 996 | } |
993 | } | 997 | if (bond->dev->flags & IFF_UP) { |
994 | } | 998 | /* If the interface is up, we may need to fire off |
995 | 999 | * the MII timer. If the interface is down, the | |
996 | if (bond->dev->flags & IFF_UP) { | 1000 | * timer will get fired off when the open function |
997 | /* If the interface is up, we may need to fire off | 1001 | * is called. |
998 | * the MII timer. If the interface is down, the | 1002 | */ |
999 | * timer will get fired off when the open function | 1003 | if (!new_value) { |
1000 | * is called. | 1004 | cancel_delayed_work_sync(&bond->mii_work); |
1001 | */ | 1005 | } else { |
1002 | cancel_delayed_work_sync(&bond->arp_work); | 1006 | cancel_delayed_work_sync(&bond->arp_work); |
1003 | queue_delayed_work(bond->wq, &bond->mii_work, 0); | 1007 | queue_delayed_work(bond->wq, &bond->mii_work, 0); |
1004 | } | 1008 | } |