aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Vosburgh <fubar@us.ibm.com>2007-12-07 02:40:34 -0500
committerJeff Garzik <jeff@garzik.org>2007-12-07 15:00:32 -0500
commit6f6652be183c8c7cb99c646dd7494ab45e4833ba (patch)
tree8ab3acaa0f7887aad46d0a1dd10f800312d657fa
parentb63bb739a1d24f395c09f88ff43c54c736a60453 (diff)
bonding: Add new layer2+3 hash for xor/802.3ad modes
Add new hash for balance-xor and 802.3ad modes. Originally submitted by "Glenn Griffin" <ggriffin.kernel@gmail.com>; modified by Jay Vosburgh to move setting of hash policy out of line, tweak the documentation update and add version update to 3.2.2. Glenn's original comment follows: Included is a patch for a new xmit_hash_policy for the bonding driver that selects slaves based on MAC and IP information. This is a middle ground between what currently exists in the layer2 only policy and the layer3+4 policy. This policy strives to be fully 802.3ad compliant by transmitting every packet of any particular flow over the same link. As documented the layer3+4 policy is not fully compliant for extreme cases such as ip fragmentation, so this policy is a nice compromise for environments that require full compliance but desire more than the layer2 only policy. Signed-off-by: "Glenn Griffin" <ggriffin.kernel@gmail.com> Signed-off-by: Jay Vosburgh <fubar@us.ibm.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r--Documentation/networking/bonding.txt29
-rw-r--r--drivers/net/bonding/bond_main.c48
-rw-r--r--drivers/net/bonding/bonding.h4
-rw-r--r--include/linux/if_bonding.h3
4 files changed, 69 insertions, 15 deletions
diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt
index 11340625e363..6cc30e0d5795 100644
--- a/Documentation/networking/bonding.txt
+++ b/Documentation/networking/bonding.txt
@@ -554,6 +554,30 @@ xmit_hash_policy
554 554
555 This algorithm is 802.3ad compliant. 555 This algorithm is 802.3ad compliant.
556 556
557 layer2+3
558
559 This policy uses a combination of layer2 and layer3
560 protocol information to generate the hash.
561
562 Uses XOR of hardware MAC addresses and IP addresses to
563 generate the hash. The formula is
564
565 (((source IP XOR dest IP) AND 0xffff) XOR
566 ( source MAC XOR destination MAC ))
567 modulo slave count
568
569 This algorithm will place all traffic to a particular
570 network peer on the same slave. For non-IP traffic,
571 the formula is the same as for the layer2 transmit
572 hash policy.
573
574 This policy is intended to provide a more balanced
575 distribution of traffic than layer2 alone, especially
576 in environments where a layer3 gateway device is
577 required to reach most destinations.
578
579 This algorithm is 802.3ad complient.
580
557 layer3+4 581 layer3+4
558 582
559 This policy uses upper layer protocol information, 583 This policy uses upper layer protocol information,
@@ -589,8 +613,9 @@ xmit_hash_policy
589 or may not tolerate this noncompliance. 613 or may not tolerate this noncompliance.
590 614
591 The default value is layer2. This option was added in bonding 615 The default value is layer2. This option was added in bonding
592version 2.6.3. In earlier versions of bonding, this parameter does 616 version 2.6.3. In earlier versions of bonding, this parameter
593not exist, and the layer2 policy is the only policy. 617 does not exist, and the layer2 policy is the only policy. The
618 layer2+3 value was added for bonding version 3.2.2.
594 619
595 620
5963. Configuring Bonding Devices 6213. Configuring Bonding Devices
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index e4a47149735f..08879d552ae0 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -175,6 +175,7 @@ struct bond_parm_tbl bond_mode_tbl[] = {
175struct bond_parm_tbl xmit_hashtype_tbl[] = { 175struct bond_parm_tbl xmit_hashtype_tbl[] = {
176{ "layer2", BOND_XMIT_POLICY_LAYER2}, 176{ "layer2", BOND_XMIT_POLICY_LAYER2},
177{ "layer3+4", BOND_XMIT_POLICY_LAYER34}, 177{ "layer3+4", BOND_XMIT_POLICY_LAYER34},
178{ "layer2+3", BOND_XMIT_POLICY_LAYER23},
178{ NULL, -1}, 179{ NULL, -1},
179}; 180};
180 181
@@ -3605,6 +3606,24 @@ void bond_unregister_arp(struct bonding *bond)
3605/*---------------------------- Hashing Policies -----------------------------*/ 3606/*---------------------------- Hashing Policies -----------------------------*/
3606 3607
3607/* 3608/*
3609 * Hash for the output device based upon layer 2 and layer 3 data. If
3610 * the packet is not IP mimic bond_xmit_hash_policy_l2()
3611 */
3612static int bond_xmit_hash_policy_l23(struct sk_buff *skb,
3613 struct net_device *bond_dev, int count)
3614{
3615 struct ethhdr *data = (struct ethhdr *)skb->data;
3616 struct iphdr *iph = ip_hdr(skb);
3617
3618 if (skb->protocol == __constant_htons(ETH_P_IP)) {
3619 return ((ntohl(iph->saddr ^ iph->daddr) & 0xffff) ^
3620 (data->h_dest[5] ^ bond_dev->dev_addr[5])) % count;
3621 }
3622
3623 return (data->h_dest[5] ^ bond_dev->dev_addr[5]) % count;
3624}
3625
3626/*
3608 * Hash for the output device based upon layer 3 and layer 4 data. If 3627 * Hash for the output device based upon layer 3 and layer 4 data. If
3609 * the packet is a frag or not TCP or UDP, just use layer 3 data. If it is 3628 * the packet is a frag or not TCP or UDP, just use layer 3 data. If it is
3610 * altogether not IP, mimic bond_xmit_hash_policy_l2() 3629 * altogether not IP, mimic bond_xmit_hash_policy_l2()
@@ -4306,6 +4325,22 @@ out:
4306 4325
4307/*------------------------- Device initialization ---------------------------*/ 4326/*------------------------- Device initialization ---------------------------*/
4308 4327
4328static void bond_set_xmit_hash_policy(struct bonding *bond)
4329{
4330 switch (bond->params.xmit_policy) {
4331 case BOND_XMIT_POLICY_LAYER23:
4332 bond->xmit_hash_policy = bond_xmit_hash_policy_l23;
4333 break;
4334 case BOND_XMIT_POLICY_LAYER34:
4335 bond->xmit_hash_policy = bond_xmit_hash_policy_l34;
4336 break;
4337 case BOND_XMIT_POLICY_LAYER2:
4338 default:
4339 bond->xmit_hash_policy = bond_xmit_hash_policy_l2;
4340 break;
4341 }
4342}
4343
4309/* 4344/*
4310 * set bond mode specific net device operations 4345 * set bond mode specific net device operations
4311 */ 4346 */
@@ -4322,10 +4357,7 @@ void bond_set_mode_ops(struct bonding *bond, int mode)
4322 break; 4357 break;
4323 case BOND_MODE_XOR: 4358 case BOND_MODE_XOR:
4324 bond_dev->hard_start_xmit = bond_xmit_xor; 4359 bond_dev->hard_start_xmit = bond_xmit_xor;
4325 if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER34) 4360 bond_set_xmit_hash_policy(bond);
4326 bond->xmit_hash_policy = bond_xmit_hash_policy_l34;
4327 else
4328 bond->xmit_hash_policy = bond_xmit_hash_policy_l2;
4329 break; 4361 break;
4330 case BOND_MODE_BROADCAST: 4362 case BOND_MODE_BROADCAST:
4331 bond_dev->hard_start_xmit = bond_xmit_broadcast; 4363 bond_dev->hard_start_xmit = bond_xmit_broadcast;
@@ -4333,10 +4365,7 @@ void bond_set_mode_ops(struct bonding *bond, int mode)
4333 case BOND_MODE_8023AD: 4365 case BOND_MODE_8023AD:
4334 bond_set_master_3ad_flags(bond); 4366 bond_set_master_3ad_flags(bond);
4335 bond_dev->hard_start_xmit = bond_3ad_xmit_xor; 4367 bond_dev->hard_start_xmit = bond_3ad_xmit_xor;
4336 if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER34) 4368 bond_set_xmit_hash_policy(bond);
4337 bond->xmit_hash_policy = bond_xmit_hash_policy_l34;
4338 else
4339 bond->xmit_hash_policy = bond_xmit_hash_policy_l2;
4340 break; 4369 break;
4341 case BOND_MODE_ALB: 4370 case BOND_MODE_ALB:
4342 bond_set_master_alb_flags(bond); 4371 bond_set_master_alb_flags(bond);
@@ -4498,8 +4527,7 @@ int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl)
4498 for (i = 0; tbl[i].modename; i++) { 4527 for (i = 0; tbl[i].modename; i++) {
4499 if ((isdigit(*mode_arg) && 4528 if ((isdigit(*mode_arg) &&
4500 tbl[i].mode == simple_strtol(mode_arg, NULL, 0)) || 4529 tbl[i].mode == simple_strtol(mode_arg, NULL, 0)) ||
4501 (strncmp(mode_arg, tbl[i].modename, 4530 (strcmp(mode_arg, tbl[i].modename) == 0)) {
4502 strlen(tbl[i].modename)) == 0)) {
4503 return tbl[i].mode; 4531 return tbl[i].mode;
4504 } 4532 }
4505 } 4533 }
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 61c1b4536d34..ccafc74c5a2b 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -22,8 +22,8 @@
22#include "bond_3ad.h" 22#include "bond_3ad.h"
23#include "bond_alb.h" 23#include "bond_alb.h"
24 24
25#define DRV_VERSION "3.2.1" 25#define DRV_VERSION "3.2.2"
26#define DRV_RELDATE "October 15, 2007" 26#define DRV_RELDATE "December 6, 2007"
27#define DRV_NAME "bonding" 27#define DRV_NAME "bonding"
28#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" 28#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"
29 29
diff --git a/include/linux/if_bonding.h b/include/linux/if_bonding.h
index 84598fa2e9de..65c2d247068b 100644
--- a/include/linux/if_bonding.h
+++ b/include/linux/if_bonding.h
@@ -85,7 +85,8 @@
85 85
86/* hashing types */ 86/* hashing types */
87#define BOND_XMIT_POLICY_LAYER2 0 /* layer 2 (MAC only), default */ 87#define BOND_XMIT_POLICY_LAYER2 0 /* layer 2 (MAC only), default */
88#define BOND_XMIT_POLICY_LAYER34 1 /* layer 3+4 (IP ^ MAC) */ 88#define BOND_XMIT_POLICY_LAYER34 1 /* layer 3+4 (IP ^ (TCP || UDP)) */
89#define BOND_XMIT_POLICY_LAYER23 2 /* layer 2+3 (IP ^ MAC) */
89 90
90typedef struct ifbond { 91typedef struct ifbond {
91 __s32 bond_mode; 92 __s32 bond_mode;