diff options
Diffstat (limited to 'drivers/net/bonding')
-rw-r--r-- | drivers/net/bonding/bond_3ad.c | 3 | ||||
-rw-r--r-- | drivers/net/bonding/bond_main.c | 390 | ||||
-rw-r--r-- | drivers/net/bonding/bonding.h | 12 |
3 files changed, 360 insertions, 45 deletions
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 6233c4ffb805..a2e8dda5afac 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c | |||
@@ -2346,7 +2346,6 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev) | |||
2346 | { | 2346 | { |
2347 | struct slave *slave, *start_at; | 2347 | struct slave *slave, *start_at; |
2348 | struct bonding *bond = dev->priv; | 2348 | struct bonding *bond = dev->priv; |
2349 | struct ethhdr *data = (struct ethhdr *)skb->data; | ||
2350 | int slave_agg_no; | 2349 | int slave_agg_no; |
2351 | int slaves_in_agg; | 2350 | int slaves_in_agg; |
2352 | int agg_id; | 2351 | int agg_id; |
@@ -2377,7 +2376,7 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev) | |||
2377 | goto out; | 2376 | goto out; |
2378 | } | 2377 | } |
2379 | 2378 | ||
2380 | slave_agg_no = (data->h_dest[5]^bond->dev->dev_addr[5]) % slaves_in_agg; | 2379 | slave_agg_no = bond->xmit_hash_policy(skb, dev, slaves_in_agg); |
2381 | 2380 | ||
2382 | bond_for_each_slave(bond, slave, i) { | 2381 | bond_for_each_slave(bond, slave, i) { |
2383 | struct aggregator *agg = SLAVE_AD_INFO(slave).port.aggregator; | 2382 | struct aggregator *agg = SLAVE_AD_INFO(slave).port.aggregator; |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 269a5e407349..2c930da90a85 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -475,7 +475,18 @@ | |||
475 | * Solution is to move call to dev_remove_pack outside of the | 475 | * Solution is to move call to dev_remove_pack outside of the |
476 | * spinlock. | 476 | * spinlock. |
477 | * Set version to 2.6.1. | 477 | * Set version to 2.6.1. |
478 | * | 478 | * 2005/06/05 - Jay Vosburgh <fubar@us.ibm.com> |
479 | * - Support for generating gratuitous ARPs in active-backup mode. | ||
480 | * Includes support for VLAN tagging all bonding-generated ARPs | ||
481 | * as needed. Set version to 2.6.2. | ||
482 | * 2005/06/08 - Jason Gabler <jygabler at lbl dot gov> | ||
483 | * - alternate hashing policy support for mode 2 | ||
484 | * * Added kernel parameter "xmit_hash_policy" to allow the selection | ||
485 | * of different hashing policies for mode 2. The original mode 2 | ||
486 | * policy is the default, now found in xmit_hash_policy_layer2(). | ||
487 | * * Added xmit_hash_policy_layer34() | ||
488 | * - Modified by Jay Vosburgh <fubar@us.ibm.com> to also support mode 4. | ||
489 | * Set version to 2.6.3. | ||
479 | */ | 490 | */ |
480 | 491 | ||
481 | //#define BONDING_DEBUG 1 | 492 | //#define BONDING_DEBUG 1 |
@@ -490,7 +501,10 @@ | |||
490 | #include <linux/ptrace.h> | 501 | #include <linux/ptrace.h> |
491 | #include <linux/ioport.h> | 502 | #include <linux/ioport.h> |
492 | #include <linux/in.h> | 503 | #include <linux/in.h> |
504 | #include <net/ip.h> | ||
493 | #include <linux/ip.h> | 505 | #include <linux/ip.h> |
506 | #include <linux/tcp.h> | ||
507 | #include <linux/udp.h> | ||
494 | #include <linux/slab.h> | 508 | #include <linux/slab.h> |
495 | #include <linux/string.h> | 509 | #include <linux/string.h> |
496 | #include <linux/init.h> | 510 | #include <linux/init.h> |
@@ -519,6 +533,7 @@ | |||
519 | #include <linux/ethtool.h> | 533 | #include <linux/ethtool.h> |
520 | #include <linux/if_vlan.h> | 534 | #include <linux/if_vlan.h> |
521 | #include <linux/if_bonding.h> | 535 | #include <linux/if_bonding.h> |
536 | #include <net/route.h> | ||
522 | #include "bonding.h" | 537 | #include "bonding.h" |
523 | #include "bond_3ad.h" | 538 | #include "bond_3ad.h" |
524 | #include "bond_alb.h" | 539 | #include "bond_alb.h" |
@@ -537,6 +552,7 @@ static int use_carrier = 1; | |||
537 | static char *mode = NULL; | 552 | static char *mode = NULL; |
538 | static char *primary = NULL; | 553 | static char *primary = NULL; |
539 | static char *lacp_rate = NULL; | 554 | static char *lacp_rate = NULL; |
555 | static char *xmit_hash_policy = NULL; | ||
540 | static int arp_interval = BOND_LINK_ARP_INTERV; | 556 | static int arp_interval = BOND_LINK_ARP_INTERV; |
541 | static char *arp_ip_target[BOND_MAX_ARP_TARGETS] = { NULL, }; | 557 | static char *arp_ip_target[BOND_MAX_ARP_TARGETS] = { NULL, }; |
542 | 558 | ||
@@ -556,6 +572,8 @@ module_param(primary, charp, 0); | |||
556 | MODULE_PARM_DESC(primary, "Primary network device to use"); | 572 | MODULE_PARM_DESC(primary, "Primary network device to use"); |
557 | module_param(lacp_rate, charp, 0); | 573 | module_param(lacp_rate, charp, 0); |
558 | MODULE_PARM_DESC(lacp_rate, "LACPDU tx rate to request from 802.3ad partner (slow/fast)"); | 574 | MODULE_PARM_DESC(lacp_rate, "LACPDU tx rate to request from 802.3ad partner (slow/fast)"); |
575 | module_param(xmit_hash_policy, charp, 0); | ||
576 | MODULE_PARM_DESC(xmit_hash_policy, "XOR hashing method : 0 for layer 2 (default), 1 for layer 3+4"); | ||
559 | module_param(arp_interval, int, 0); | 577 | module_param(arp_interval, int, 0); |
560 | MODULE_PARM_DESC(arp_interval, "arp interval in milliseconds"); | 578 | MODULE_PARM_DESC(arp_interval, "arp interval in milliseconds"); |
561 | module_param_array(arp_ip_target, charp, NULL, 0); | 579 | module_param_array(arp_ip_target, charp, NULL, 0); |
@@ -574,8 +592,8 @@ static struct proc_dir_entry *bond_proc_dir = NULL; | |||
574 | 592 | ||
575 | static u32 arp_target[BOND_MAX_ARP_TARGETS] = { 0, } ; | 593 | static u32 arp_target[BOND_MAX_ARP_TARGETS] = { 0, } ; |
576 | static int arp_ip_count = 0; | 594 | static int arp_ip_count = 0; |
577 | static u32 my_ip = 0; | ||
578 | static int bond_mode = BOND_MODE_ROUNDROBIN; | 595 | static int bond_mode = BOND_MODE_ROUNDROBIN; |
596 | static int xmit_hashtype= BOND_XMIT_POLICY_LAYER2; | ||
579 | static int lacp_fast = 0; | 597 | static int lacp_fast = 0; |
580 | static int app_abi_ver = 0; | 598 | static int app_abi_ver = 0; |
581 | static int orig_app_abi_ver = -1; /* This is used to save the first ABI version | 599 | static int orig_app_abi_ver = -1; /* This is used to save the first ABI version |
@@ -585,7 +603,6 @@ static int orig_app_abi_ver = -1; /* This is used to save the first ABI version | |||
585 | * command comes from an application using | 603 | * command comes from an application using |
586 | * another ABI version. | 604 | * another ABI version. |
587 | */ | 605 | */ |
588 | |||
589 | struct bond_parm_tbl { | 606 | struct bond_parm_tbl { |
590 | char *modename; | 607 | char *modename; |
591 | int mode; | 608 | int mode; |
@@ -608,9 +625,16 @@ static struct bond_parm_tbl bond_mode_tbl[] = { | |||
608 | { NULL, -1}, | 625 | { NULL, -1}, |
609 | }; | 626 | }; |
610 | 627 | ||
628 | static struct bond_parm_tbl xmit_hashtype_tbl[] = { | ||
629 | { "layer2", BOND_XMIT_POLICY_LAYER2}, | ||
630 | { "layer3+4", BOND_XMIT_POLICY_LAYER34}, | ||
631 | { NULL, -1}, | ||
632 | }; | ||
633 | |||
611 | /*-------------------------- Forward declarations ---------------------------*/ | 634 | /*-------------------------- Forward declarations ---------------------------*/ |
612 | 635 | ||
613 | static inline void bond_set_mode_ops(struct net_device *bond_dev, int mode); | 636 | static inline void bond_set_mode_ops(struct bonding *bond, int mode); |
637 | static void bond_send_gratuitous_arp(struct bonding *bond); | ||
614 | 638 | ||
615 | /*---------------------------- General routines -----------------------------*/ | 639 | /*---------------------------- General routines -----------------------------*/ |
616 | 640 | ||
@@ -659,6 +683,7 @@ static int bond_add_vlan(struct bonding *bond, unsigned short vlan_id) | |||
659 | 683 | ||
660 | INIT_LIST_HEAD(&vlan->vlan_list); | 684 | INIT_LIST_HEAD(&vlan->vlan_list); |
661 | vlan->vlan_id = vlan_id; | 685 | vlan->vlan_id = vlan_id; |
686 | vlan->vlan_ip = 0; | ||
662 | 687 | ||
663 | write_lock_bh(&bond->lock); | 688 | write_lock_bh(&bond->lock); |
664 | 689 | ||
@@ -1468,16 +1493,6 @@ static void bond_change_active_slave(struct bonding *bond, struct slave *new_act | |||
1468 | } | 1493 | } |
1469 | } | 1494 | } |
1470 | 1495 | ||
1471 | if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) { | ||
1472 | if (old_active) { | ||
1473 | bond_set_slave_inactive_flags(old_active); | ||
1474 | } | ||
1475 | |||
1476 | if (new_active) { | ||
1477 | bond_set_slave_active_flags(new_active); | ||
1478 | } | ||
1479 | } | ||
1480 | |||
1481 | if (USES_PRIMARY(bond->params.mode)) { | 1496 | if (USES_PRIMARY(bond->params.mode)) { |
1482 | bond_mc_swap(bond, new_active, old_active); | 1497 | bond_mc_swap(bond, new_active, old_active); |
1483 | } | 1498 | } |
@@ -1488,6 +1503,17 @@ static void bond_change_active_slave(struct bonding *bond, struct slave *new_act | |||
1488 | } else { | 1503 | } else { |
1489 | bond->curr_active_slave = new_active; | 1504 | bond->curr_active_slave = new_active; |
1490 | } | 1505 | } |
1506 | |||
1507 | if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) { | ||
1508 | if (old_active) { | ||
1509 | bond_set_slave_inactive_flags(old_active); | ||
1510 | } | ||
1511 | |||
1512 | if (new_active) { | ||
1513 | bond_set_slave_active_flags(new_active); | ||
1514 | } | ||
1515 | bond_send_gratuitous_arp(bond); | ||
1516 | } | ||
1491 | } | 1517 | } |
1492 | 1518 | ||
1493 | /** | 1519 | /** |
@@ -2694,15 +2720,180 @@ out: | |||
2694 | read_unlock(&bond->lock); | 2720 | read_unlock(&bond->lock); |
2695 | } | 2721 | } |
2696 | 2722 | ||
2723 | |||
2724 | static u32 bond_glean_dev_ip(struct net_device *dev) | ||
2725 | { | ||
2726 | struct in_device *idev; | ||
2727 | struct in_ifaddr *ifa; | ||
2728 | u32 addr = 0; | ||
2729 | |||
2730 | if (!dev) | ||
2731 | return 0; | ||
2732 | |||
2733 | rcu_read_lock(); | ||
2734 | idev = __in_dev_get(dev); | ||
2735 | if (!idev) | ||
2736 | goto out; | ||
2737 | |||
2738 | ifa = idev->ifa_list; | ||
2739 | if (!ifa) | ||
2740 | goto out; | ||
2741 | |||
2742 | addr = ifa->ifa_local; | ||
2743 | out: | ||
2744 | rcu_read_unlock(); | ||
2745 | return addr; | ||
2746 | } | ||
2747 | |||
2748 | static int bond_has_ip(struct bonding *bond) | ||
2749 | { | ||
2750 | struct vlan_entry *vlan, *vlan_next; | ||
2751 | |||
2752 | if (bond->master_ip) | ||
2753 | return 1; | ||
2754 | |||
2755 | if (list_empty(&bond->vlan_list)) | ||
2756 | return 0; | ||
2757 | |||
2758 | list_for_each_entry_safe(vlan, vlan_next, &bond->vlan_list, | ||
2759 | vlan_list) { | ||
2760 | if (vlan->vlan_ip) | ||
2761 | return 1; | ||
2762 | } | ||
2763 | |||
2764 | return 0; | ||
2765 | } | ||
2766 | |||
2767 | /* | ||
2768 | * We go to the (large) trouble of VLAN tagging ARP frames because | ||
2769 | * switches in VLAN mode (especially if ports are configured as | ||
2770 | * "native" to a VLAN) might not pass non-tagged frames. | ||
2771 | */ | ||
2772 | static void bond_arp_send(struct net_device *slave_dev, int arp_op, u32 dest_ip, u32 src_ip, unsigned short vlan_id) | ||
2773 | { | ||
2774 | struct sk_buff *skb; | ||
2775 | |||
2776 | dprintk("arp %d on slave %s: dst %x src %x vid %d\n", arp_op, | ||
2777 | slave_dev->name, dest_ip, src_ip, vlan_id); | ||
2778 | |||
2779 | skb = arp_create(arp_op, ETH_P_ARP, dest_ip, slave_dev, src_ip, | ||
2780 | NULL, slave_dev->dev_addr, NULL); | ||
2781 | |||
2782 | if (!skb) { | ||
2783 | printk(KERN_ERR DRV_NAME ": ARP packet allocation failed\n"); | ||
2784 | return; | ||
2785 | } | ||
2786 | if (vlan_id) { | ||
2787 | skb = vlan_put_tag(skb, vlan_id); | ||
2788 | if (!skb) { | ||
2789 | printk(KERN_ERR DRV_NAME ": failed to insert VLAN tag\n"); | ||
2790 | return; | ||
2791 | } | ||
2792 | } | ||
2793 | arp_xmit(skb); | ||
2794 | } | ||
2795 | |||
2796 | |||
2697 | static void bond_arp_send_all(struct bonding *bond, struct slave *slave) | 2797 | static void bond_arp_send_all(struct bonding *bond, struct slave *slave) |
2698 | { | 2798 | { |
2699 | int i; | 2799 | int i, vlan_id, rv; |
2700 | u32 *targets = bond->params.arp_targets; | 2800 | u32 *targets = bond->params.arp_targets; |
2801 | struct vlan_entry *vlan, *vlan_next; | ||
2802 | struct net_device *vlan_dev; | ||
2803 | struct flowi fl; | ||
2804 | struct rtable *rt; | ||
2701 | 2805 | ||
2702 | for (i = 0; (i < BOND_MAX_ARP_TARGETS) && targets[i]; i++) { | 2806 | for (i = 0; (i < BOND_MAX_ARP_TARGETS) && targets[i]; i++) { |
2703 | arp_send(ARPOP_REQUEST, ETH_P_ARP, targets[i], slave->dev, | 2807 | dprintk("basa: target %x\n", targets[i]); |
2704 | my_ip, NULL, slave->dev->dev_addr, | 2808 | if (list_empty(&bond->vlan_list)) { |
2705 | NULL); | 2809 | dprintk("basa: empty vlan: arp_send\n"); |
2810 | bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i], | ||
2811 | bond->master_ip, 0); | ||
2812 | continue; | ||
2813 | } | ||
2814 | |||
2815 | /* | ||
2816 | * If VLANs are configured, we do a route lookup to | ||
2817 | * determine which VLAN interface would be used, so we | ||
2818 | * can tag the ARP with the proper VLAN tag. | ||
2819 | */ | ||
2820 | memset(&fl, 0, sizeof(fl)); | ||
2821 | fl.fl4_dst = targets[i]; | ||
2822 | fl.fl4_tos = RTO_ONLINK; | ||
2823 | |||
2824 | rv = ip_route_output_key(&rt, &fl); | ||
2825 | if (rv) { | ||
2826 | if (net_ratelimit()) { | ||
2827 | printk(KERN_WARNING DRV_NAME | ||
2828 | ": %s: no route to arp_ip_target %u.%u.%u.%u\n", | ||
2829 | bond->dev->name, NIPQUAD(fl.fl4_dst)); | ||
2830 | } | ||
2831 | continue; | ||
2832 | } | ||
2833 | |||
2834 | /* | ||
2835 | * This target is not on a VLAN | ||
2836 | */ | ||
2837 | if (rt->u.dst.dev == bond->dev) { | ||
2838 | dprintk("basa: rtdev == bond->dev: arp_send\n"); | ||
2839 | bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i], | ||
2840 | bond->master_ip, 0); | ||
2841 | continue; | ||
2842 | } | ||
2843 | |||
2844 | vlan_id = 0; | ||
2845 | list_for_each_entry_safe(vlan, vlan_next, &bond->vlan_list, | ||
2846 | vlan_list) { | ||
2847 | vlan_dev = bond->vlgrp->vlan_devices[vlan->vlan_id]; | ||
2848 | if (vlan_dev == rt->u.dst.dev) { | ||
2849 | vlan_id = vlan->vlan_id; | ||
2850 | dprintk("basa: vlan match on %s %d\n", | ||
2851 | vlan_dev->name, vlan_id); | ||
2852 | break; | ||
2853 | } | ||
2854 | } | ||
2855 | |||
2856 | if (vlan_id) { | ||
2857 | bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i], | ||
2858 | vlan->vlan_ip, vlan_id); | ||
2859 | continue; | ||
2860 | } | ||
2861 | |||
2862 | if (net_ratelimit()) { | ||
2863 | printk(KERN_WARNING DRV_NAME | ||
2864 | ": %s: no path to arp_ip_target %u.%u.%u.%u via rt.dev %s\n", | ||
2865 | bond->dev->name, NIPQUAD(fl.fl4_dst), | ||
2866 | rt->u.dst.dev ? rt->u.dst.dev->name : "NULL"); | ||
2867 | } | ||
2868 | } | ||
2869 | } | ||
2870 | |||
2871 | /* | ||
2872 | * Kick out a gratuitous ARP for an IP on the bonding master plus one | ||
2873 | * for each VLAN above us. | ||
2874 | */ | ||
2875 | static void bond_send_gratuitous_arp(struct bonding *bond) | ||
2876 | { | ||
2877 | struct slave *slave = bond->curr_active_slave; | ||
2878 | struct vlan_entry *vlan; | ||
2879 | struct net_device *vlan_dev; | ||
2880 | |||
2881 | dprintk("bond_send_grat_arp: bond %s slave %s\n", bond->dev->name, | ||
2882 | slave ? slave->dev->name : "NULL"); | ||
2883 | if (!slave) | ||
2884 | return; | ||
2885 | |||
2886 | if (bond->master_ip) { | ||
2887 | bond_arp_send(slave->dev, ARPOP_REPLY, bond->master_ip, | ||
2888 | bond->master_ip, 0); | ||
2889 | } | ||
2890 | |||
2891 | list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { | ||
2892 | vlan_dev = bond->vlgrp->vlan_devices[vlan->vlan_id]; | ||
2893 | if (vlan->vlan_ip) { | ||
2894 | bond_arp_send(slave->dev, ARPOP_REPLY, vlan->vlan_ip, | ||
2895 | vlan->vlan_ip, vlan->vlan_id); | ||
2896 | } | ||
2706 | } | 2897 | } |
2707 | } | 2898 | } |
2708 | 2899 | ||
@@ -2781,7 +2972,7 @@ static void bond_loadbalance_arp_mon(struct net_device *bond_dev) | |||
2781 | */ | 2972 | */ |
2782 | if (((jiffies - slave->dev->trans_start) >= (2*delta_in_ticks)) || | 2973 | if (((jiffies - slave->dev->trans_start) >= (2*delta_in_ticks)) || |
2783 | (((jiffies - slave->dev->last_rx) >= (2*delta_in_ticks)) && | 2974 | (((jiffies - slave->dev->last_rx) >= (2*delta_in_ticks)) && |
2784 | my_ip)) { | 2975 | bond_has_ip(bond))) { |
2785 | 2976 | ||
2786 | slave->link = BOND_LINK_DOWN; | 2977 | slave->link = BOND_LINK_DOWN; |
2787 | slave->state = BOND_STATE_BACKUP; | 2978 | slave->state = BOND_STATE_BACKUP; |
@@ -2920,7 +3111,7 @@ static void bond_activebackup_arp_mon(struct net_device *bond_dev) | |||
2920 | if ((slave != bond->curr_active_slave) && | 3111 | if ((slave != bond->curr_active_slave) && |
2921 | (!bond->current_arp_slave) && | 3112 | (!bond->current_arp_slave) && |
2922 | (((jiffies - slave->dev->last_rx) >= 3*delta_in_ticks) && | 3113 | (((jiffies - slave->dev->last_rx) >= 3*delta_in_ticks) && |
2923 | my_ip)) { | 3114 | bond_has_ip(bond))) { |
2924 | /* a backup slave has gone down; three times | 3115 | /* a backup slave has gone down; three times |
2925 | * the delta allows the current slave to be | 3116 | * the delta allows the current slave to be |
2926 | * taken out before the backup slave. | 3117 | * taken out before the backup slave. |
@@ -2966,8 +3157,8 @@ static void bond_activebackup_arp_mon(struct net_device *bond_dev) | |||
2966 | * if it is up and needs to take over as the curr_active_slave | 3157 | * if it is up and needs to take over as the curr_active_slave |
2967 | */ | 3158 | */ |
2968 | if ((((jiffies - slave->dev->trans_start) >= (2*delta_in_ticks)) || | 3159 | if ((((jiffies - slave->dev->trans_start) >= (2*delta_in_ticks)) || |
2969 | (((jiffies - slave->dev->last_rx) >= (2*delta_in_ticks)) && | 3160 | (((jiffies - slave->dev->last_rx) >= (2*delta_in_ticks)) && |
2970 | my_ip)) && | 3161 | bond_has_ip(bond))) && |
2971 | ((jiffies - slave->jiffies) >= 2*delta_in_ticks)) { | 3162 | ((jiffies - slave->jiffies) >= 2*delta_in_ticks)) { |
2972 | 3163 | ||
2973 | slave->link = BOND_LINK_DOWN; | 3164 | slave->link = BOND_LINK_DOWN; |
@@ -3019,7 +3210,7 @@ static void bond_activebackup_arp_mon(struct net_device *bond_dev) | |||
3019 | /* the current slave must tx an arp to ensure backup slaves | 3210 | /* the current slave must tx an arp to ensure backup slaves |
3020 | * rx traffic | 3211 | * rx traffic |
3021 | */ | 3212 | */ |
3022 | if (slave && my_ip) { | 3213 | if (slave && bond_has_ip(bond)) { |
3023 | bond_arp_send_all(bond, slave); | 3214 | bond_arp_send_all(bond, slave); |
3024 | } | 3215 | } |
3025 | } | 3216 | } |
@@ -3471,10 +3662,67 @@ static int bond_netdev_event(struct notifier_block *this, unsigned long event, v | |||
3471 | return NOTIFY_DONE; | 3662 | return NOTIFY_DONE; |
3472 | } | 3663 | } |
3473 | 3664 | ||
3665 | /* | ||
3666 | * bond_inetaddr_event: handle inetaddr notifier chain events. | ||
3667 | * | ||
3668 | * We keep track of device IPs primarily to use as source addresses in | ||
3669 | * ARP monitor probes (rather than spewing out broadcasts all the time). | ||
3670 | * | ||
3671 | * We track one IP for the main device (if it has one), plus one per VLAN. | ||
3672 | */ | ||
3673 | static int bond_inetaddr_event(struct notifier_block *this, unsigned long event, void *ptr) | ||
3674 | { | ||
3675 | struct in_ifaddr *ifa = ptr; | ||
3676 | struct net_device *vlan_dev, *event_dev = ifa->ifa_dev->dev; | ||
3677 | struct bonding *bond, *bond_next; | ||
3678 | struct vlan_entry *vlan, *vlan_next; | ||
3679 | |||
3680 | list_for_each_entry_safe(bond, bond_next, &bond_dev_list, bond_list) { | ||
3681 | if (bond->dev == event_dev) { | ||
3682 | switch (event) { | ||
3683 | case NETDEV_UP: | ||
3684 | bond->master_ip = ifa->ifa_local; | ||
3685 | return NOTIFY_OK; | ||
3686 | case NETDEV_DOWN: | ||
3687 | bond->master_ip = bond_glean_dev_ip(bond->dev); | ||
3688 | return NOTIFY_OK; | ||
3689 | default: | ||
3690 | return NOTIFY_DONE; | ||
3691 | } | ||
3692 | } | ||
3693 | |||
3694 | if (list_empty(&bond->vlan_list)) | ||
3695 | continue; | ||
3696 | |||
3697 | list_for_each_entry_safe(vlan, vlan_next, &bond->vlan_list, | ||
3698 | vlan_list) { | ||
3699 | vlan_dev = bond->vlgrp->vlan_devices[vlan->vlan_id]; | ||
3700 | if (vlan_dev == event_dev) { | ||
3701 | switch (event) { | ||
3702 | case NETDEV_UP: | ||
3703 | vlan->vlan_ip = ifa->ifa_local; | ||
3704 | return NOTIFY_OK; | ||
3705 | case NETDEV_DOWN: | ||
3706 | vlan->vlan_ip = | ||
3707 | bond_glean_dev_ip(vlan_dev); | ||
3708 | return NOTIFY_OK; | ||
3709 | default: | ||
3710 | return NOTIFY_DONE; | ||
3711 | } | ||
3712 | } | ||
3713 | } | ||
3714 | } | ||
3715 | return NOTIFY_DONE; | ||
3716 | } | ||
3717 | |||
3474 | static struct notifier_block bond_netdev_notifier = { | 3718 | static struct notifier_block bond_netdev_notifier = { |
3475 | .notifier_call = bond_netdev_event, | 3719 | .notifier_call = bond_netdev_event, |
3476 | }; | 3720 | }; |
3477 | 3721 | ||
3722 | static struct notifier_block bond_inetaddr_notifier = { | ||
3723 | .notifier_call = bond_inetaddr_event, | ||
3724 | }; | ||
3725 | |||
3478 | /*-------------------------- Packet type handling ---------------------------*/ | 3726 | /*-------------------------- Packet type handling ---------------------------*/ |
3479 | 3727 | ||
3480 | /* register to receive lacpdus on a bond */ | 3728 | /* register to receive lacpdus on a bond */ |
@@ -3496,6 +3744,46 @@ static void bond_unregister_lacpdu(struct bonding *bond) | |||
3496 | dev_remove_pack(&(BOND_AD_INFO(bond).ad_pkt_type)); | 3744 | dev_remove_pack(&(BOND_AD_INFO(bond).ad_pkt_type)); |
3497 | } | 3745 | } |
3498 | 3746 | ||
3747 | /*---------------------------- Hashing Policies -----------------------------*/ | ||
3748 | |||
3749 | /* | ||
3750 | * Hash for the the output device based upon layer 3 and layer 4 data. If | ||
3751 | * the packet is a frag or not TCP or UDP, just use layer 3 data. If it is | ||
3752 | * altogether not IP, mimic bond_xmit_hash_policy_l2() | ||
3753 | */ | ||
3754 | static int bond_xmit_hash_policy_l34(struct sk_buff *skb, | ||
3755 | struct net_device *bond_dev, int count) | ||
3756 | { | ||
3757 | struct ethhdr *data = (struct ethhdr *)skb->data; | ||
3758 | struct iphdr *iph = skb->nh.iph; | ||
3759 | u16 *layer4hdr = (u16 *)((u32 *)iph + iph->ihl); | ||
3760 | int layer4_xor = 0; | ||
3761 | |||
3762 | if (skb->protocol == __constant_htons(ETH_P_IP)) { | ||
3763 | if (!(iph->frag_off & __constant_htons(IP_MF|IP_OFFSET)) && | ||
3764 | (iph->protocol == IPPROTO_TCP || | ||
3765 | iph->protocol == IPPROTO_UDP)) { | ||
3766 | layer4_xor = htons((*layer4hdr ^ *(layer4hdr + 1))); | ||
3767 | } | ||
3768 | return (layer4_xor ^ | ||
3769 | ((ntohl(iph->saddr ^ iph->daddr)) & 0xffff)) % count; | ||
3770 | |||
3771 | } | ||
3772 | |||
3773 | return (data->h_dest[5] ^ bond_dev->dev_addr[5]) % count; | ||
3774 | } | ||
3775 | |||
3776 | /* | ||
3777 | * Hash for the output device based upon layer 2 data | ||
3778 | */ | ||
3779 | static int bond_xmit_hash_policy_l2(struct sk_buff *skb, | ||
3780 | struct net_device *bond_dev, int count) | ||
3781 | { | ||
3782 | struct ethhdr *data = (struct ethhdr *)skb->data; | ||
3783 | |||
3784 | return (data->h_dest[5] ^ bond_dev->dev_addr[5]) % count; | ||
3785 | } | ||
3786 | |||
3499 | /*-------------------------- Device entry points ----------------------------*/ | 3787 | /*-------------------------- Device entry points ----------------------------*/ |
3500 | 3788 | ||
3501 | static int bond_open(struct net_device *bond_dev) | 3789 | static int bond_open(struct net_device *bond_dev) |
@@ -4060,17 +4348,6 @@ static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_d | |||
4060 | struct bonding *bond = bond_dev->priv; | 4348 | struct bonding *bond = bond_dev->priv; |
4061 | int res = 1; | 4349 | int res = 1; |
4062 | 4350 | ||
4063 | /* if we are sending arp packets, try to at least | ||
4064 | identify our own ip address */ | ||
4065 | if (bond->params.arp_interval && !my_ip && | ||
4066 | (skb->protocol == __constant_htons(ETH_P_ARP))) { | ||
4067 | char *the_ip = (char *)skb->data + | ||
4068 | sizeof(struct ethhdr) + | ||
4069 | sizeof(struct arphdr) + | ||
4070 | ETH_ALEN; | ||
4071 | memcpy(&my_ip, the_ip, 4); | ||
4072 | } | ||
4073 | |||
4074 | read_lock(&bond->lock); | 4351 | read_lock(&bond->lock); |
4075 | read_lock(&bond->curr_slave_lock); | 4352 | read_lock(&bond->curr_slave_lock); |
4076 | 4353 | ||
@@ -4093,14 +4370,13 @@ out: | |||
4093 | } | 4370 | } |
4094 | 4371 | ||
4095 | /* | 4372 | /* |
4096 | * in XOR mode, we determine the output device by performing xor on | 4373 | * In bond_xmit_xor() , we determine the output device by using a pre- |
4097 | * the source and destination hw adresses. If this device is not | 4374 | * determined xmit_hash_policy(), If the selected device is not enabled, |
4098 | * enabled, find the next slave following this xor slave. | 4375 | * find the next active slave. |
4099 | */ | 4376 | */ |
4100 | static int bond_xmit_xor(struct sk_buff *skb, struct net_device *bond_dev) | 4377 | static int bond_xmit_xor(struct sk_buff *skb, struct net_device *bond_dev) |
4101 | { | 4378 | { |
4102 | struct bonding *bond = bond_dev->priv; | 4379 | struct bonding *bond = bond_dev->priv; |
4103 | struct ethhdr *data = (struct ethhdr *)skb->data; | ||
4104 | struct slave *slave, *start_at; | 4380 | struct slave *slave, *start_at; |
4105 | int slave_no; | 4381 | int slave_no; |
4106 | int i; | 4382 | int i; |
@@ -4112,7 +4388,7 @@ static int bond_xmit_xor(struct sk_buff *skb, struct net_device *bond_dev) | |||
4112 | goto out; | 4388 | goto out; |
4113 | } | 4389 | } |
4114 | 4390 | ||
4115 | slave_no = (data->h_dest[5]^bond_dev->dev_addr[5]) % bond->slave_cnt; | 4391 | slave_no = bond->xmit_hash_policy(skb, bond_dev, bond->slave_cnt); |
4116 | 4392 | ||
4117 | bond_for_each_slave(bond, slave, i) { | 4393 | bond_for_each_slave(bond, slave, i) { |
4118 | slave_no--; | 4394 | slave_no--; |
@@ -4208,8 +4484,10 @@ out: | |||
4208 | /* | 4484 | /* |
4209 | * set bond mode specific net device operations | 4485 | * set bond mode specific net device operations |
4210 | */ | 4486 | */ |
4211 | static inline void bond_set_mode_ops(struct net_device *bond_dev, int mode) | 4487 | static inline void bond_set_mode_ops(struct bonding *bond, int mode) |
4212 | { | 4488 | { |
4489 | struct net_device *bond_dev = bond->dev; | ||
4490 | |||
4213 | switch (mode) { | 4491 | switch (mode) { |
4214 | case BOND_MODE_ROUNDROBIN: | 4492 | case BOND_MODE_ROUNDROBIN: |
4215 | bond_dev->hard_start_xmit = bond_xmit_roundrobin; | 4493 | bond_dev->hard_start_xmit = bond_xmit_roundrobin; |
@@ -4219,12 +4497,20 @@ static inline void bond_set_mode_ops(struct net_device *bond_dev, int mode) | |||
4219 | break; | 4497 | break; |
4220 | case BOND_MODE_XOR: | 4498 | case BOND_MODE_XOR: |
4221 | bond_dev->hard_start_xmit = bond_xmit_xor; | 4499 | bond_dev->hard_start_xmit = bond_xmit_xor; |
4500 | if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER34) | ||
4501 | bond->xmit_hash_policy = bond_xmit_hash_policy_l34; | ||
4502 | else | ||
4503 | bond->xmit_hash_policy = bond_xmit_hash_policy_l2; | ||
4222 | break; | 4504 | break; |
4223 | case BOND_MODE_BROADCAST: | 4505 | case BOND_MODE_BROADCAST: |
4224 | bond_dev->hard_start_xmit = bond_xmit_broadcast; | 4506 | bond_dev->hard_start_xmit = bond_xmit_broadcast; |
4225 | break; | 4507 | break; |
4226 | case BOND_MODE_8023AD: | 4508 | case BOND_MODE_8023AD: |
4227 | bond_dev->hard_start_xmit = bond_3ad_xmit_xor; | 4509 | bond_dev->hard_start_xmit = bond_3ad_xmit_xor; |
4510 | if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER34) | ||
4511 | bond->xmit_hash_policy = bond_xmit_hash_policy_l34; | ||
4512 | else | ||
4513 | bond->xmit_hash_policy = bond_xmit_hash_policy_l2; | ||
4228 | break; | 4514 | break; |
4229 | case BOND_MODE_TLB: | 4515 | case BOND_MODE_TLB: |
4230 | case BOND_MODE_ALB: | 4516 | case BOND_MODE_ALB: |
@@ -4273,7 +4559,7 @@ static int __init bond_init(struct net_device *bond_dev, struct bond_params *par | |||
4273 | bond_dev->change_mtu = bond_change_mtu; | 4559 | bond_dev->change_mtu = bond_change_mtu; |
4274 | bond_dev->set_mac_address = bond_set_mac_address; | 4560 | bond_dev->set_mac_address = bond_set_mac_address; |
4275 | 4561 | ||
4276 | bond_set_mode_ops(bond_dev, bond->params.mode); | 4562 | bond_set_mode_ops(bond, bond->params.mode); |
4277 | 4563 | ||
4278 | bond_dev->destructor = free_netdev; | 4564 | bond_dev->destructor = free_netdev; |
4279 | 4565 | ||
@@ -4384,6 +4670,25 @@ static int bond_check_params(struct bond_params *params) | |||
4384 | } | 4670 | } |
4385 | } | 4671 | } |
4386 | 4672 | ||
4673 | if (xmit_hash_policy) { | ||
4674 | if ((bond_mode != BOND_MODE_XOR) && | ||
4675 | (bond_mode != BOND_MODE_8023AD)) { | ||
4676 | printk(KERN_INFO DRV_NAME | ||
4677 | ": xor_mode param is irrelevant in mode %s\n", | ||
4678 | bond_mode_name(bond_mode)); | ||
4679 | } else { | ||
4680 | xmit_hashtype = bond_parse_parm(xmit_hash_policy, | ||
4681 | xmit_hashtype_tbl); | ||
4682 | if (xmit_hashtype == -1) { | ||
4683 | printk(KERN_ERR DRV_NAME | ||
4684 | ": Error: Invalid xmit_hash_policy \"%s\"\n", | ||
4685 | xmit_hash_policy == NULL ? "NULL" : | ||
4686 | xmit_hash_policy); | ||
4687 | return -EINVAL; | ||
4688 | } | ||
4689 | } | ||
4690 | } | ||
4691 | |||
4387 | if (lacp_rate) { | 4692 | if (lacp_rate) { |
4388 | if (bond_mode != BOND_MODE_8023AD) { | 4693 | if (bond_mode != BOND_MODE_8023AD) { |
4389 | printk(KERN_INFO DRV_NAME | 4694 | printk(KERN_INFO DRV_NAME |
@@ -4595,6 +4900,7 @@ static int bond_check_params(struct bond_params *params) | |||
4595 | 4900 | ||
4596 | /* fill params struct with the proper values */ | 4901 | /* fill params struct with the proper values */ |
4597 | params->mode = bond_mode; | 4902 | params->mode = bond_mode; |
4903 | params->xmit_policy = xmit_hashtype; | ||
4598 | params->miimon = miimon; | 4904 | params->miimon = miimon; |
4599 | params->arp_interval = arp_interval; | 4905 | params->arp_interval = arp_interval; |
4600 | params->updelay = updelay; | 4906 | params->updelay = updelay; |
@@ -4669,6 +4975,7 @@ static int __init bonding_init(void) | |||
4669 | 4975 | ||
4670 | rtnl_unlock(); | 4976 | rtnl_unlock(); |
4671 | register_netdevice_notifier(&bond_netdev_notifier); | 4977 | register_netdevice_notifier(&bond_netdev_notifier); |
4978 | register_inetaddr_notifier(&bond_inetaddr_notifier); | ||
4672 | 4979 | ||
4673 | return 0; | 4980 | return 0; |
4674 | 4981 | ||
@@ -4684,6 +4991,7 @@ out_err: | |||
4684 | static void __exit bonding_exit(void) | 4991 | static void __exit bonding_exit(void) |
4685 | { | 4992 | { |
4686 | unregister_netdevice_notifier(&bond_netdev_notifier); | 4993 | unregister_netdevice_notifier(&bond_netdev_notifier); |
4994 | unregister_inetaddr_notifier(&bond_inetaddr_notifier); | ||
4687 | 4995 | ||
4688 | rtnl_lock(); | 4996 | rtnl_lock(); |
4689 | bond_free_all(); | 4997 | bond_free_all(); |
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 8c325308489d..d27f377b3eeb 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h | |||
@@ -25,6 +25,10 @@ | |||
25 | * | 25 | * |
26 | * 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com> | 26 | * 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com> |
27 | * - Code cleanup and style changes | 27 | * - Code cleanup and style changes |
28 | * | ||
29 | * 2005/05/05 - Jason Gabler <jygabler at lbl dot gov> | ||
30 | * - added "xmit_policy" kernel parameter for alternate hashing policy | ||
31 | * support for mode 2 | ||
28 | */ | 32 | */ |
29 | 33 | ||
30 | #ifndef _LINUX_BONDING_H | 34 | #ifndef _LINUX_BONDING_H |
@@ -36,8 +40,8 @@ | |||
36 | #include "bond_3ad.h" | 40 | #include "bond_3ad.h" |
37 | #include "bond_alb.h" | 41 | #include "bond_alb.h" |
38 | 42 | ||
39 | #define DRV_VERSION "2.6.1" | 43 | #define DRV_VERSION "2.6.3" |
40 | #define DRV_RELDATE "October 29, 2004" | 44 | #define DRV_RELDATE "June 8, 2005" |
41 | #define DRV_NAME "bonding" | 45 | #define DRV_NAME "bonding" |
42 | #define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" | 46 | #define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" |
43 | 47 | ||
@@ -137,6 +141,7 @@ | |||
137 | 141 | ||
138 | struct bond_params { | 142 | struct bond_params { |
139 | int mode; | 143 | int mode; |
144 | int xmit_policy; | ||
140 | int miimon; | 145 | int miimon; |
141 | int arp_interval; | 146 | int arp_interval; |
142 | int use_carrier; | 147 | int use_carrier; |
@@ -149,6 +154,7 @@ struct bond_params { | |||
149 | 154 | ||
150 | struct vlan_entry { | 155 | struct vlan_entry { |
151 | struct list_head vlan_list; | 156 | struct list_head vlan_list; |
157 | u32 vlan_ip; | ||
152 | unsigned short vlan_id; | 158 | unsigned short vlan_id; |
153 | }; | 159 | }; |
154 | 160 | ||
@@ -197,6 +203,8 @@ struct bonding { | |||
197 | #endif /* CONFIG_PROC_FS */ | 203 | #endif /* CONFIG_PROC_FS */ |
198 | struct list_head bond_list; | 204 | struct list_head bond_list; |
199 | struct dev_mc_list *mc_list; | 205 | struct dev_mc_list *mc_list; |
206 | int (*xmit_hash_policy)(struct sk_buff *, struct net_device *, int); | ||
207 | u32 master_ip; | ||
200 | u16 flags; | 208 | u16 flags; |
201 | struct ad_bond_info ad_info; | 209 | struct ad_bond_info ad_info; |
202 | struct alb_bond_info alb_info; | 210 | struct alb_bond_info alb_info; |