diff options
Diffstat (limited to 'drivers/net/bonding/bond_main.c')
-rw-r--r-- | drivers/net/bonding/bond_main.c | 121 |
1 files changed, 23 insertions, 98 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 4ce14bdf96dd..66d9dc6e5cac 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -1439,27 +1439,17 @@ static void bond_setup_by_slave(struct net_device *bond_dev, | |||
1439 | } | 1439 | } |
1440 | 1440 | ||
1441 | /* On bonding slaves other than the currently active slave, suppress | 1441 | /* On bonding slaves other than the currently active slave, suppress |
1442 | * duplicates except for 802.3ad ETH_P_SLOW, alb non-mcast/bcast, and | 1442 | * duplicates except for alb non-mcast/bcast. |
1443 | * ARP on active-backup slaves with arp_validate enabled. | ||
1444 | */ | 1443 | */ |
1445 | static bool bond_should_deliver_exact_match(struct sk_buff *skb, | 1444 | static bool bond_should_deliver_exact_match(struct sk_buff *skb, |
1446 | struct slave *slave, | 1445 | struct slave *slave, |
1447 | struct bonding *bond) | 1446 | struct bonding *bond) |
1448 | { | 1447 | { |
1449 | if (bond_is_slave_inactive(slave)) { | 1448 | if (bond_is_slave_inactive(slave)) { |
1450 | if (slave_do_arp_validate(bond, slave) && | ||
1451 | skb->protocol == __cpu_to_be16(ETH_P_ARP)) | ||
1452 | return false; | ||
1453 | |||
1454 | if (bond->params.mode == BOND_MODE_ALB && | 1449 | if (bond->params.mode == BOND_MODE_ALB && |
1455 | skb->pkt_type != PACKET_BROADCAST && | 1450 | skb->pkt_type != PACKET_BROADCAST && |
1456 | skb->pkt_type != PACKET_MULTICAST) | 1451 | skb->pkt_type != PACKET_MULTICAST) |
1457 | return false; | ||
1458 | |||
1459 | if (bond->params.mode == BOND_MODE_8023AD && | ||
1460 | skb->protocol == __cpu_to_be16(ETH_P_SLOW)) | ||
1461 | return false; | 1452 | return false; |
1462 | |||
1463 | return true; | 1453 | return true; |
1464 | } | 1454 | } |
1465 | return false; | 1455 | return false; |
@@ -1483,6 +1473,15 @@ static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb) | |||
1483 | if (bond->params.arp_interval) | 1473 | if (bond->params.arp_interval) |
1484 | slave->dev->last_rx = jiffies; | 1474 | slave->dev->last_rx = jiffies; |
1485 | 1475 | ||
1476 | if (bond->recv_probe) { | ||
1477 | struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC); | ||
1478 | |||
1479 | if (likely(nskb)) { | ||
1480 | bond->recv_probe(nskb, bond, slave); | ||
1481 | dev_kfree_skb(nskb); | ||
1482 | } | ||
1483 | } | ||
1484 | |||
1486 | if (bond_should_deliver_exact_match(skb, slave, bond)) { | 1485 | if (bond_should_deliver_exact_match(skb, slave, bond)) { |
1487 | return RX_HANDLER_EXACT; | 1486 | return RX_HANDLER_EXACT; |
1488 | } | 1487 | } |
@@ -2743,48 +2742,26 @@ static void bond_validate_arp(struct bonding *bond, struct slave *slave, __be32 | |||
2743 | } | 2742 | } |
2744 | } | 2743 | } |
2745 | 2744 | ||
2746 | static int bond_arp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev) | 2745 | static void bond_arp_rcv(struct sk_buff *skb, struct bonding *bond, |
2746 | struct slave *slave) | ||
2747 | { | 2747 | { |
2748 | struct arphdr *arp; | 2748 | struct arphdr *arp; |
2749 | struct slave *slave; | ||
2750 | struct bonding *bond; | ||
2751 | unsigned char *arp_ptr; | 2749 | unsigned char *arp_ptr; |
2752 | __be32 sip, tip; | 2750 | __be32 sip, tip; |
2753 | 2751 | ||
2754 | if (dev->priv_flags & IFF_802_1Q_VLAN) { | 2752 | if (skb->protocol != __cpu_to_be16(ETH_P_ARP)) |
2755 | /* | 2753 | return; |
2756 | * When using VLANS and bonding, dev and oriv_dev may be | ||
2757 | * incorrect if the physical interface supports VLAN | ||
2758 | * acceleration. With this change ARP validation now | ||
2759 | * works for hosts only reachable on the VLAN interface. | ||
2760 | */ | ||
2761 | dev = vlan_dev_real_dev(dev); | ||
2762 | orig_dev = dev_get_by_index_rcu(dev_net(skb->dev),skb->skb_iif); | ||
2763 | } | ||
2764 | |||
2765 | if (!(dev->priv_flags & IFF_BONDING) || !(dev->flags & IFF_MASTER)) | ||
2766 | goto out; | ||
2767 | 2754 | ||
2768 | bond = netdev_priv(dev); | ||
2769 | read_lock(&bond->lock); | 2755 | read_lock(&bond->lock); |
2770 | 2756 | ||
2771 | pr_debug("bond_arp_rcv: bond %s skb->dev %s orig_dev %s\n", | 2757 | pr_debug("bond_arp_rcv: bond %s skb->dev %s\n", |
2772 | bond->dev->name, skb->dev ? skb->dev->name : "NULL", | 2758 | bond->dev->name, skb->dev->name); |
2773 | orig_dev ? orig_dev->name : "NULL"); | ||
2774 | 2759 | ||
2775 | slave = bond_get_slave_by_dev(bond, orig_dev); | 2760 | if (!pskb_may_pull(skb, arp_hdr_len(bond->dev))) |
2776 | if (!slave || !slave_do_arp_validate(bond, slave)) | ||
2777 | goto out_unlock; | ||
2778 | |||
2779 | skb = skb_share_check(skb, GFP_ATOMIC); | ||
2780 | if (!skb) | ||
2781 | goto out_unlock; | ||
2782 | |||
2783 | if (!pskb_may_pull(skb, arp_hdr_len(dev))) | ||
2784 | goto out_unlock; | 2761 | goto out_unlock; |
2785 | 2762 | ||
2786 | arp = arp_hdr(skb); | 2763 | arp = arp_hdr(skb); |
2787 | if (arp->ar_hln != dev->addr_len || | 2764 | if (arp->ar_hln != bond->dev->addr_len || |
2788 | skb->pkt_type == PACKET_OTHERHOST || | 2765 | skb->pkt_type == PACKET_OTHERHOST || |
2789 | skb->pkt_type == PACKET_LOOPBACK || | 2766 | skb->pkt_type == PACKET_LOOPBACK || |
2790 | arp->ar_hrd != htons(ARPHRD_ETHER) || | 2767 | arp->ar_hrd != htons(ARPHRD_ETHER) || |
@@ -2793,9 +2770,9 @@ static int bond_arp_rcv(struct sk_buff *skb, struct net_device *dev, struct pack | |||
2793 | goto out_unlock; | 2770 | goto out_unlock; |
2794 | 2771 | ||
2795 | arp_ptr = (unsigned char *)(arp + 1); | 2772 | arp_ptr = (unsigned char *)(arp + 1); |
2796 | arp_ptr += dev->addr_len; | 2773 | arp_ptr += bond->dev->addr_len; |
2797 | memcpy(&sip, arp_ptr, 4); | 2774 | memcpy(&sip, arp_ptr, 4); |
2798 | arp_ptr += 4 + dev->addr_len; | 2775 | arp_ptr += 4 + bond->dev->addr_len; |
2799 | memcpy(&tip, arp_ptr, 4); | 2776 | memcpy(&tip, arp_ptr, 4); |
2800 | 2777 | ||
2801 | pr_debug("bond_arp_rcv: %s %s/%d av %d sv %d sip %pI4 tip %pI4\n", | 2778 | pr_debug("bond_arp_rcv: %s %s/%d av %d sv %d sip %pI4 tip %pI4\n", |
@@ -2818,9 +2795,6 @@ static int bond_arp_rcv(struct sk_buff *skb, struct net_device *dev, struct pack | |||
2818 | 2795 | ||
2819 | out_unlock: | 2796 | out_unlock: |
2820 | read_unlock(&bond->lock); | 2797 | read_unlock(&bond->lock); |
2821 | out: | ||
2822 | dev_kfree_skb(skb); | ||
2823 | return NET_RX_SUCCESS; | ||
2824 | } | 2798 | } |
2825 | 2799 | ||
2826 | /* | 2800 | /* |
@@ -3407,48 +3381,6 @@ static struct notifier_block bond_inetaddr_notifier = { | |||
3407 | .notifier_call = bond_inetaddr_event, | 3381 | .notifier_call = bond_inetaddr_event, |
3408 | }; | 3382 | }; |
3409 | 3383 | ||
3410 | /*-------------------------- Packet type handling ---------------------------*/ | ||
3411 | |||
3412 | /* register to receive lacpdus on a bond */ | ||
3413 | static void bond_register_lacpdu(struct bonding *bond) | ||
3414 | { | ||
3415 | struct packet_type *pk_type = &(BOND_AD_INFO(bond).ad_pkt_type); | ||
3416 | |||
3417 | /* initialize packet type */ | ||
3418 | pk_type->type = PKT_TYPE_LACPDU; | ||
3419 | pk_type->dev = bond->dev; | ||
3420 | pk_type->func = bond_3ad_lacpdu_recv; | ||
3421 | |||
3422 | dev_add_pack(pk_type); | ||
3423 | } | ||
3424 | |||
3425 | /* unregister to receive lacpdus on a bond */ | ||
3426 | static void bond_unregister_lacpdu(struct bonding *bond) | ||
3427 | { | ||
3428 | dev_remove_pack(&(BOND_AD_INFO(bond).ad_pkt_type)); | ||
3429 | } | ||
3430 | |||
3431 | void bond_register_arp(struct bonding *bond) | ||
3432 | { | ||
3433 | struct packet_type *pt = &bond->arp_mon_pt; | ||
3434 | |||
3435 | if (pt->type) | ||
3436 | return; | ||
3437 | |||
3438 | pt->type = htons(ETH_P_ARP); | ||
3439 | pt->dev = bond->dev; | ||
3440 | pt->func = bond_arp_rcv; | ||
3441 | dev_add_pack(pt); | ||
3442 | } | ||
3443 | |||
3444 | void bond_unregister_arp(struct bonding *bond) | ||
3445 | { | ||
3446 | struct packet_type *pt = &bond->arp_mon_pt; | ||
3447 | |||
3448 | dev_remove_pack(pt); | ||
3449 | pt->type = 0; | ||
3450 | } | ||
3451 | |||
3452 | /*---------------------------- Hashing Policies -----------------------------*/ | 3384 | /*---------------------------- Hashing Policies -----------------------------*/ |
3453 | 3385 | ||
3454 | /* | 3386 | /* |
@@ -3542,14 +3474,14 @@ static int bond_open(struct net_device *bond_dev) | |||
3542 | 3474 | ||
3543 | queue_delayed_work(bond->wq, &bond->arp_work, 0); | 3475 | queue_delayed_work(bond->wq, &bond->arp_work, 0); |
3544 | if (bond->params.arp_validate) | 3476 | if (bond->params.arp_validate) |
3545 | bond_register_arp(bond); | 3477 | bond->recv_probe = bond_arp_rcv; |
3546 | } | 3478 | } |
3547 | 3479 | ||
3548 | if (bond->params.mode == BOND_MODE_8023AD) { | 3480 | if (bond->params.mode == BOND_MODE_8023AD) { |
3549 | INIT_DELAYED_WORK(&bond->ad_work, bond_3ad_state_machine_handler); | 3481 | INIT_DELAYED_WORK(&bond->ad_work, bond_3ad_state_machine_handler); |
3550 | queue_delayed_work(bond->wq, &bond->ad_work, 0); | 3482 | queue_delayed_work(bond->wq, &bond->ad_work, 0); |
3551 | /* register to receive LACPDUs */ | 3483 | /* register to receive LACPDUs */ |
3552 | bond_register_lacpdu(bond); | 3484 | bond->recv_probe = bond_3ad_lacpdu_recv; |
3553 | bond_3ad_initiate_agg_selection(bond, 1); | 3485 | bond_3ad_initiate_agg_selection(bond, 1); |
3554 | } | 3486 | } |
3555 | 3487 | ||
@@ -3560,14 +3492,6 @@ static int bond_close(struct net_device *bond_dev) | |||
3560 | { | 3492 | { |
3561 | struct bonding *bond = netdev_priv(bond_dev); | 3493 | struct bonding *bond = netdev_priv(bond_dev); |
3562 | 3494 | ||
3563 | if (bond->params.mode == BOND_MODE_8023AD) { | ||
3564 | /* Unregister the receive of LACPDUs */ | ||
3565 | bond_unregister_lacpdu(bond); | ||
3566 | } | ||
3567 | |||
3568 | if (bond->params.arp_validate) | ||
3569 | bond_unregister_arp(bond); | ||
3570 | |||
3571 | write_lock_bh(&bond->lock); | 3495 | write_lock_bh(&bond->lock); |
3572 | 3496 | ||
3573 | /* signal timers not to re-arm */ | 3497 | /* signal timers not to re-arm */ |
@@ -3604,6 +3528,7 @@ static int bond_close(struct net_device *bond_dev) | |||
3604 | */ | 3528 | */ |
3605 | bond_alb_deinitialize(bond); | 3529 | bond_alb_deinitialize(bond); |
3606 | } | 3530 | } |
3531 | bond->recv_probe = NULL; | ||
3607 | 3532 | ||
3608 | return 0; | 3533 | return 0; |
3609 | } | 3534 | } |