diff options
Diffstat (limited to 'drivers/net/bonding/bond_main.c')
-rw-r--r-- | drivers/net/bonding/bond_main.c | 100 |
1 files changed, 36 insertions, 64 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index b2530b002125..a7d47350ea4b 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -1379,6 +1379,8 @@ static void bond_compute_features(struct bonding *bond) | |||
1379 | struct net_device *bond_dev = bond->dev; | 1379 | struct net_device *bond_dev = bond->dev; |
1380 | netdev_features_t vlan_features = BOND_VLAN_FEATURES; | 1380 | netdev_features_t vlan_features = BOND_VLAN_FEATURES; |
1381 | unsigned short max_hard_header_len = ETH_HLEN; | 1381 | unsigned short max_hard_header_len = ETH_HLEN; |
1382 | unsigned int gso_max_size = GSO_MAX_SIZE; | ||
1383 | u16 gso_max_segs = GSO_MAX_SEGS; | ||
1382 | int i; | 1384 | int i; |
1383 | unsigned int flags, dst_release_flag = IFF_XMIT_DST_RELEASE; | 1385 | unsigned int flags, dst_release_flag = IFF_XMIT_DST_RELEASE; |
1384 | 1386 | ||
@@ -1394,11 +1396,16 @@ static void bond_compute_features(struct bonding *bond) | |||
1394 | dst_release_flag &= slave->dev->priv_flags; | 1396 | dst_release_flag &= slave->dev->priv_flags; |
1395 | if (slave->dev->hard_header_len > max_hard_header_len) | 1397 | if (slave->dev->hard_header_len > max_hard_header_len) |
1396 | max_hard_header_len = slave->dev->hard_header_len; | 1398 | max_hard_header_len = slave->dev->hard_header_len; |
1399 | |||
1400 | gso_max_size = min(gso_max_size, slave->dev->gso_max_size); | ||
1401 | gso_max_segs = min(gso_max_segs, slave->dev->gso_max_segs); | ||
1397 | } | 1402 | } |
1398 | 1403 | ||
1399 | done: | 1404 | done: |
1400 | bond_dev->vlan_features = vlan_features; | 1405 | bond_dev->vlan_features = vlan_features; |
1401 | bond_dev->hard_header_len = max_hard_header_len; | 1406 | bond_dev->hard_header_len = max_hard_header_len; |
1407 | bond_dev->gso_max_segs = gso_max_segs; | ||
1408 | netif_set_gso_max_size(bond_dev, gso_max_size); | ||
1402 | 1409 | ||
1403 | flags = bond_dev->priv_flags & ~IFF_XMIT_DST_RELEASE; | 1410 | flags = bond_dev->priv_flags & ~IFF_XMIT_DST_RELEASE; |
1404 | bond_dev->priv_flags = flags | dst_release_flag; | 1411 | bond_dev->priv_flags = flags | dst_release_flag; |
@@ -3452,6 +3459,28 @@ static int bond_xmit_hash_policy_l34(struct sk_buff *skb, int count) | |||
3452 | 3459 | ||
3453 | /*-------------------------- Device entry points ----------------------------*/ | 3460 | /*-------------------------- Device entry points ----------------------------*/ |
3454 | 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 | |||
3455 | static int bond_open(struct net_device *bond_dev) | 3484 | static int bond_open(struct net_device *bond_dev) |
3456 | { | 3485 | { |
3457 | struct bonding *bond = netdev_priv(bond_dev); | 3486 | struct bonding *bond = netdev_priv(bond_dev); |
@@ -3474,41 +3503,27 @@ static int bond_open(struct net_device *bond_dev) | |||
3474 | } | 3503 | } |
3475 | read_unlock(&bond->lock); | 3504 | read_unlock(&bond->lock); |
3476 | 3505 | ||
3477 | INIT_DELAYED_WORK(&bond->mcast_work, bond_resend_igmp_join_requests_delayed); | 3506 | bond_work_init_all(bond); |
3478 | 3507 | ||
3479 | if (bond_is_lb(bond)) { | 3508 | if (bond_is_lb(bond)) { |
3480 | /* bond_alb_initialize must be called before the timer | 3509 | /* bond_alb_initialize must be called before the timer |
3481 | * is started. | 3510 | * is started. |
3482 | */ | 3511 | */ |
3483 | if (bond_alb_initialize(bond, (bond->params.mode == BOND_MODE_ALB))) { | 3512 | if (bond_alb_initialize(bond, (bond->params.mode == BOND_MODE_ALB))) |
3484 | /* something went wrong - fail the open operation */ | ||
3485 | return -ENOMEM; | 3513 | return -ENOMEM; |
3486 | } | ||
3487 | |||
3488 | INIT_DELAYED_WORK(&bond->alb_work, bond_alb_monitor); | ||
3489 | queue_delayed_work(bond->wq, &bond->alb_work, 0); | 3514 | queue_delayed_work(bond->wq, &bond->alb_work, 0); |
3490 | } | 3515 | } |
3491 | 3516 | ||
3492 | if (bond->params.miimon) { /* link check interval, in milliseconds. */ | 3517 | if (bond->params.miimon) /* link check interval, in milliseconds. */ |
3493 | INIT_DELAYED_WORK(&bond->mii_work, bond_mii_monitor); | ||
3494 | queue_delayed_work(bond->wq, &bond->mii_work, 0); | 3518 | queue_delayed_work(bond->wq, &bond->mii_work, 0); |
3495 | } | ||
3496 | 3519 | ||
3497 | if (bond->params.arp_interval) { /* arp interval, in milliseconds. */ | 3520 | if (bond->params.arp_interval) { /* arp interval, in milliseconds. */ |
3498 | if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) | ||
3499 | INIT_DELAYED_WORK(&bond->arp_work, | ||
3500 | bond_activebackup_arp_mon); | ||
3501 | else | ||
3502 | INIT_DELAYED_WORK(&bond->arp_work, | ||
3503 | bond_loadbalance_arp_mon); | ||
3504 | |||
3505 | queue_delayed_work(bond->wq, &bond->arp_work, 0); | 3521 | queue_delayed_work(bond->wq, &bond->arp_work, 0); |
3506 | if (bond->params.arp_validate) | 3522 | if (bond->params.arp_validate) |
3507 | bond->recv_probe = bond_arp_rcv; | 3523 | bond->recv_probe = bond_arp_rcv; |
3508 | } | 3524 | } |
3509 | 3525 | ||
3510 | if (bond->params.mode == BOND_MODE_8023AD) { | 3526 | if (bond->params.mode == BOND_MODE_8023AD) { |
3511 | INIT_DELAYED_WORK(&bond->ad_work, bond_3ad_state_machine_handler); | ||
3512 | queue_delayed_work(bond->wq, &bond->ad_work, 0); | 3527 | queue_delayed_work(bond->wq, &bond->ad_work, 0); |
3513 | /* register to receive LACPDUs */ | 3528 | /* register to receive LACPDUs */ |
3514 | bond->recv_probe = bond_3ad_lacpdu_recv; | 3529 | bond->recv_probe = bond_3ad_lacpdu_recv; |
@@ -3523,34 +3538,10 @@ static int bond_close(struct net_device *bond_dev) | |||
3523 | struct bonding *bond = netdev_priv(bond_dev); | 3538 | struct bonding *bond = netdev_priv(bond_dev); |
3524 | 3539 | ||
3525 | write_lock_bh(&bond->lock); | 3540 | write_lock_bh(&bond->lock); |
3526 | |||
3527 | bond->send_peer_notif = 0; | 3541 | bond->send_peer_notif = 0; |
3528 | |||
3529 | write_unlock_bh(&bond->lock); | 3542 | write_unlock_bh(&bond->lock); |
3530 | 3543 | ||
3531 | if (bond->params.miimon) { /* link check interval, in milliseconds. */ | 3544 | bond_work_cancel_all(bond); |
3532 | cancel_delayed_work_sync(&bond->mii_work); | ||
3533 | } | ||
3534 | |||
3535 | if (bond->params.arp_interval) { /* arp interval, in milliseconds. */ | ||
3536 | cancel_delayed_work_sync(&bond->arp_work); | ||
3537 | } | ||
3538 | |||
3539 | switch (bond->params.mode) { | ||
3540 | case BOND_MODE_8023AD: | ||
3541 | cancel_delayed_work_sync(&bond->ad_work); | ||
3542 | break; | ||
3543 | case BOND_MODE_TLB: | ||
3544 | case BOND_MODE_ALB: | ||
3545 | cancel_delayed_work_sync(&bond->alb_work); | ||
3546 | break; | ||
3547 | default: | ||
3548 | break; | ||
3549 | } | ||
3550 | |||
3551 | if (delayed_work_pending(&bond->mcast_work)) | ||
3552 | cancel_delayed_work_sync(&bond->mcast_work); | ||
3553 | |||
3554 | if (bond_is_lb(bond)) { | 3545 | if (bond_is_lb(bond)) { |
3555 | /* Must be called only after all | 3546 | /* Must be called only after all |
3556 | * slaves have been released | 3547 | * slaves have been released |
@@ -4429,26 +4420,6 @@ static void bond_setup(struct net_device *bond_dev) | |||
4429 | bond_dev->features |= bond_dev->hw_features; | 4420 | bond_dev->features |= bond_dev->hw_features; |
4430 | } | 4421 | } |
4431 | 4422 | ||
4432 | static void bond_work_cancel_all(struct bonding *bond) | ||
4433 | { | ||
4434 | if (bond->params.miimon && delayed_work_pending(&bond->mii_work)) | ||
4435 | cancel_delayed_work_sync(&bond->mii_work); | ||
4436 | |||
4437 | if (bond->params.arp_interval && delayed_work_pending(&bond->arp_work)) | ||
4438 | cancel_delayed_work_sync(&bond->arp_work); | ||
4439 | |||
4440 | if (bond->params.mode == BOND_MODE_ALB && | ||
4441 | delayed_work_pending(&bond->alb_work)) | ||
4442 | cancel_delayed_work_sync(&bond->alb_work); | ||
4443 | |||
4444 | if (bond->params.mode == BOND_MODE_8023AD && | ||
4445 | delayed_work_pending(&bond->ad_work)) | ||
4446 | cancel_delayed_work_sync(&bond->ad_work); | ||
4447 | |||
4448 | if (delayed_work_pending(&bond->mcast_work)) | ||
4449 | cancel_delayed_work_sync(&bond->mcast_work); | ||
4450 | } | ||
4451 | |||
4452 | /* | 4423 | /* |
4453 | * Destroy a bonding device. | 4424 | * Destroy a bonding device. |
4454 | * Must be under rtnl_lock when this function is called. | 4425 | * Must be under rtnl_lock when this function is called. |
@@ -4699,12 +4670,13 @@ static int bond_check_params(struct bond_params *params) | |||
4699 | arp_ip_count++) { | 4670 | arp_ip_count++) { |
4700 | /* not complete check, but should be good enough to | 4671 | /* not complete check, but should be good enough to |
4701 | catch mistakes */ | 4672 | catch mistakes */ |
4702 | 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)) { | ||
4703 | 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", |
4704 | arp_ip_target[arp_ip_count]); | 4677 | arp_ip_target[arp_ip_count]); |
4705 | arp_interval = 0; | 4678 | arp_interval = 0; |
4706 | } else { | 4679 | } else { |
4707 | __be32 ip = in_aton(arp_ip_target[arp_ip_count]); | ||
4708 | arp_target[arp_ip_count] = ip; | 4680 | arp_target[arp_ip_count] = ip; |
4709 | } | 4681 | } |
4710 | } | 4682 | } |