diff options
Diffstat (limited to 'drivers/net/bonding/bond_main.c')
-rw-r--r-- | drivers/net/bonding/bond_main.c | 93 |
1 files changed, 29 insertions, 64 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 5f5b69f37d2..a7d47350ea4 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -3459,6 +3459,28 @@ static int bond_xmit_hash_policy_l34(struct sk_buff *skb, int count) | |||
3459 | 3459 | ||
3460 | /*-------------------------- Device entry points ----------------------------*/ | 3460 | /*-------------------------- Device entry points ----------------------------*/ |
3461 | 3461 | ||
3462 | static void bond_work_init_all(struct bonding *bond) | ||
3463 | { | ||
3464 | INIT_DELAYED_WORK(&bond->mcast_work, | ||
3465 | bond_resend_igmp_join_requests_delayed); | ||
3466 | INIT_DELAYED_WORK(&bond->alb_work, bond_alb_monitor); | ||
3467 | INIT_DELAYED_WORK(&bond->mii_work, bond_mii_monitor); | ||
3468 | if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) | ||
3469 | INIT_DELAYED_WORK(&bond->arp_work, bond_activebackup_arp_mon); | ||
3470 | else | ||
3471 | INIT_DELAYED_WORK(&bond->arp_work, bond_loadbalance_arp_mon); | ||
3472 | INIT_DELAYED_WORK(&bond->ad_work, bond_3ad_state_machine_handler); | ||
3473 | } | ||
3474 | |||
3475 | static void bond_work_cancel_all(struct bonding *bond) | ||
3476 | { | ||
3477 | cancel_delayed_work_sync(&bond->mii_work); | ||
3478 | cancel_delayed_work_sync(&bond->arp_work); | ||
3479 | cancel_delayed_work_sync(&bond->alb_work); | ||
3480 | cancel_delayed_work_sync(&bond->ad_work); | ||
3481 | cancel_delayed_work_sync(&bond->mcast_work); | ||
3482 | } | ||
3483 | |||
3462 | static int bond_open(struct net_device *bond_dev) | 3484 | static int bond_open(struct net_device *bond_dev) |
3463 | { | 3485 | { |
3464 | struct bonding *bond = netdev_priv(bond_dev); | 3486 | struct bonding *bond = netdev_priv(bond_dev); |
@@ -3481,41 +3503,27 @@ static int bond_open(struct net_device *bond_dev) | |||
3481 | } | 3503 | } |
3482 | read_unlock(&bond->lock); | 3504 | read_unlock(&bond->lock); |
3483 | 3505 | ||
3484 | INIT_DELAYED_WORK(&bond->mcast_work, bond_resend_igmp_join_requests_delayed); | 3506 | bond_work_init_all(bond); |
3485 | 3507 | ||
3486 | if (bond_is_lb(bond)) { | 3508 | if (bond_is_lb(bond)) { |
3487 | /* bond_alb_initialize must be called before the timer | 3509 | /* bond_alb_initialize must be called before the timer |
3488 | * is started. | 3510 | * is started. |
3489 | */ | 3511 | */ |
3490 | if (bond_alb_initialize(bond, (bond->params.mode == BOND_MODE_ALB))) { | 3512 | if (bond_alb_initialize(bond, (bond->params.mode == BOND_MODE_ALB))) |
3491 | /* something went wrong - fail the open operation */ | ||
3492 | return -ENOMEM; | 3513 | return -ENOMEM; |
3493 | } | ||
3494 | |||
3495 | INIT_DELAYED_WORK(&bond->alb_work, bond_alb_monitor); | ||
3496 | queue_delayed_work(bond->wq, &bond->alb_work, 0); | 3514 | queue_delayed_work(bond->wq, &bond->alb_work, 0); |
3497 | } | 3515 | } |
3498 | 3516 | ||
3499 | if (bond->params.miimon) { /* link check interval, in milliseconds. */ | 3517 | if (bond->params.miimon) /* link check interval, in milliseconds. */ |
3500 | INIT_DELAYED_WORK(&bond->mii_work, bond_mii_monitor); | ||
3501 | queue_delayed_work(bond->wq, &bond->mii_work, 0); | 3518 | queue_delayed_work(bond->wq, &bond->mii_work, 0); |
3502 | } | ||
3503 | 3519 | ||
3504 | if (bond->params.arp_interval) { /* arp interval, in milliseconds. */ | 3520 | if (bond->params.arp_interval) { /* arp interval, in milliseconds. */ |
3505 | if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) | ||
3506 | INIT_DELAYED_WORK(&bond->arp_work, | ||
3507 | bond_activebackup_arp_mon); | ||
3508 | else | ||
3509 | INIT_DELAYED_WORK(&bond->arp_work, | ||
3510 | bond_loadbalance_arp_mon); | ||
3511 | |||
3512 | queue_delayed_work(bond->wq, &bond->arp_work, 0); | 3521 | queue_delayed_work(bond->wq, &bond->arp_work, 0); |
3513 | if (bond->params.arp_validate) | 3522 | if (bond->params.arp_validate) |
3514 | bond->recv_probe = bond_arp_rcv; | 3523 | bond->recv_probe = bond_arp_rcv; |
3515 | } | 3524 | } |
3516 | 3525 | ||
3517 | if (bond->params.mode == BOND_MODE_8023AD) { | 3526 | if (bond->params.mode == BOND_MODE_8023AD) { |
3518 | INIT_DELAYED_WORK(&bond->ad_work, bond_3ad_state_machine_handler); | ||
3519 | queue_delayed_work(bond->wq, &bond->ad_work, 0); | 3527 | queue_delayed_work(bond->wq, &bond->ad_work, 0); |
3520 | /* register to receive LACPDUs */ | 3528 | /* register to receive LACPDUs */ |
3521 | bond->recv_probe = bond_3ad_lacpdu_recv; | 3529 | bond->recv_probe = bond_3ad_lacpdu_recv; |
@@ -3530,34 +3538,10 @@ static int bond_close(struct net_device *bond_dev) | |||
3530 | struct bonding *bond = netdev_priv(bond_dev); | 3538 | struct bonding *bond = netdev_priv(bond_dev); |
3531 | 3539 | ||
3532 | write_lock_bh(&bond->lock); | 3540 | write_lock_bh(&bond->lock); |
3533 | |||
3534 | bond->send_peer_notif = 0; | 3541 | bond->send_peer_notif = 0; |
3535 | |||
3536 | write_unlock_bh(&bond->lock); | 3542 | write_unlock_bh(&bond->lock); |
3537 | 3543 | ||
3538 | if (bond->params.miimon) { /* link check interval, in milliseconds. */ | 3544 | bond_work_cancel_all(bond); |
3539 | cancel_delayed_work_sync(&bond->mii_work); | ||
3540 | } | ||
3541 | |||
3542 | if (bond->params.arp_interval) { /* arp interval, in milliseconds. */ | ||
3543 | cancel_delayed_work_sync(&bond->arp_work); | ||
3544 | } | ||
3545 | |||
3546 | switch (bond->params.mode) { | ||
3547 | case BOND_MODE_8023AD: | ||
3548 | cancel_delayed_work_sync(&bond->ad_work); | ||
3549 | break; | ||
3550 | case BOND_MODE_TLB: | ||
3551 | case BOND_MODE_ALB: | ||
3552 | cancel_delayed_work_sync(&bond->alb_work); | ||
3553 | break; | ||
3554 | default: | ||
3555 | break; | ||
3556 | } | ||
3557 | |||
3558 | if (delayed_work_pending(&bond->mcast_work)) | ||
3559 | cancel_delayed_work_sync(&bond->mcast_work); | ||
3560 | |||
3561 | if (bond_is_lb(bond)) { | 3545 | if (bond_is_lb(bond)) { |
3562 | /* Must be called only after all | 3546 | /* Must be called only after all |
3563 | * slaves have been released | 3547 | * slaves have been released |
@@ -4436,26 +4420,6 @@ static void bond_setup(struct net_device *bond_dev) | |||
4436 | bond_dev->features |= bond_dev->hw_features; | 4420 | bond_dev->features |= bond_dev->hw_features; |
4437 | } | 4421 | } |
4438 | 4422 | ||
4439 | static void bond_work_cancel_all(struct bonding *bond) | ||
4440 | { | ||
4441 | if (bond->params.miimon && delayed_work_pending(&bond->mii_work)) | ||
4442 | cancel_delayed_work_sync(&bond->mii_work); | ||
4443 | |||
4444 | if (bond->params.arp_interval && delayed_work_pending(&bond->arp_work)) | ||
4445 | cancel_delayed_work_sync(&bond->arp_work); | ||
4446 | |||
4447 | if (bond->params.mode == BOND_MODE_ALB && | ||
4448 | delayed_work_pending(&bond->alb_work)) | ||
4449 | cancel_delayed_work_sync(&bond->alb_work); | ||
4450 | |||
4451 | if (bond->params.mode == BOND_MODE_8023AD && | ||
4452 | delayed_work_pending(&bond->ad_work)) | ||
4453 | cancel_delayed_work_sync(&bond->ad_work); | ||
4454 | |||
4455 | if (delayed_work_pending(&bond->mcast_work)) | ||
4456 | cancel_delayed_work_sync(&bond->mcast_work); | ||
4457 | } | ||
4458 | |||
4459 | /* | 4423 | /* |
4460 | * Destroy a bonding device. | 4424 | * Destroy a bonding device. |
4461 | * Must be under rtnl_lock when this function is called. | 4425 | * Must be under rtnl_lock when this function is called. |
@@ -4706,12 +4670,13 @@ static int bond_check_params(struct bond_params *params) | |||
4706 | arp_ip_count++) { | 4670 | arp_ip_count++) { |
4707 | /* not complete check, but should be good enough to | 4671 | /* not complete check, but should be good enough to |
4708 | catch mistakes */ | 4672 | catch mistakes */ |
4709 | if (!isdigit(arp_ip_target[arp_ip_count][0])) { | 4673 | __be32 ip = in_aton(arp_ip_target[arp_ip_count]); |
4674 | if (!isdigit(arp_ip_target[arp_ip_count][0]) || | ||
4675 | ip == 0 || ip == htonl(INADDR_BROADCAST)) { | ||
4710 | pr_warning("Warning: bad arp_ip_target module parameter (%s), ARP monitoring will not be performed\n", | 4676 | pr_warning("Warning: bad arp_ip_target module parameter (%s), ARP monitoring will not be performed\n", |
4711 | arp_ip_target[arp_ip_count]); | 4677 | arp_ip_target[arp_ip_count]); |
4712 | arp_interval = 0; | 4678 | arp_interval = 0; |
4713 | } else { | 4679 | } else { |
4714 | __be32 ip = in_aton(arp_ip_target[arp_ip_count]); | ||
4715 | arp_target[arp_ip_count] = ip; | 4680 | arp_target[arp_ip_count] = ip; |
4716 | } | 4681 | } |
4717 | } | 4682 | } |