aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding/bond_main.c
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 /drivers/net/bonding/bond_main.c
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>
Diffstat (limited to 'drivers/net/bonding/bond_main.c')
-rw-r--r--drivers/net/bonding/bond_main.c48
1 files changed, 38 insertions, 10 deletions
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 }