Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Jay Vosburgh and committed by
Jeff Garzik
6f6652be b63bb739

+69 -15
+27 -2
Documentation/networking/bonding.txt
··· 554 554 555 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 581 layer3+4 558 582 559 583 This policy uses upper layer protocol information, ··· 613 589 or may not tolerate this noncompliance. 614 590 615 591 The default value is layer2. This option was added in bonding 616 - version 2.6.3. In earlier versions of bonding, this parameter does 617 - not exist, and the layer2 policy is the only policy. 592 + version 2.6.3. In earlier versions of bonding, this parameter 593 + does not exist, and the layer2 policy is the only policy. The 594 + layer2+3 value was added for bonding version 3.2.2. 618 595 619 596 620 597 3. Configuring Bonding Devices
+38 -10
drivers/net/bonding/bond_main.c
··· 175 175 struct bond_parm_tbl xmit_hashtype_tbl[] = { 176 176 { "layer2", BOND_XMIT_POLICY_LAYER2}, 177 177 { "layer3+4", BOND_XMIT_POLICY_LAYER34}, 178 + { "layer2+3", BOND_XMIT_POLICY_LAYER23}, 178 179 { NULL, -1}, 179 180 }; 180 181 ··· 3606 3605 /*---------------------------- Hashing Policies -----------------------------*/ 3607 3606 3608 3607 /* 3608 + * Hash for the output device based upon layer 2 and layer 3 data. If 3609 + * the packet is not IP mimic bond_xmit_hash_policy_l2() 3610 + */ 3611 + static int bond_xmit_hash_policy_l23(struct sk_buff *skb, 3612 + struct net_device *bond_dev, int count) 3613 + { 3614 + struct ethhdr *data = (struct ethhdr *)skb->data; 3615 + struct iphdr *iph = ip_hdr(skb); 3616 + 3617 + if (skb->protocol == __constant_htons(ETH_P_IP)) { 3618 + return ((ntohl(iph->saddr ^ iph->daddr) & 0xffff) ^ 3619 + (data->h_dest[5] ^ bond_dev->dev_addr[5])) % count; 3620 + } 3621 + 3622 + return (data->h_dest[5] ^ bond_dev->dev_addr[5]) % count; 3623 + } 3624 + 3625 + /* 3609 3626 * Hash for the output device based upon layer 3 and layer 4 data. If 3610 3627 * the packet is a frag or not TCP or UDP, just use layer 3 data. If it is 3611 3628 * altogether not IP, mimic bond_xmit_hash_policy_l2() ··· 4325 4306 4326 4307 /*------------------------- Device initialization ---------------------------*/ 4327 4308 4309 + static void bond_set_xmit_hash_policy(struct bonding *bond) 4310 + { 4311 + switch (bond->params.xmit_policy) { 4312 + case BOND_XMIT_POLICY_LAYER23: 4313 + bond->xmit_hash_policy = bond_xmit_hash_policy_l23; 4314 + break; 4315 + case BOND_XMIT_POLICY_LAYER34: 4316 + bond->xmit_hash_policy = bond_xmit_hash_policy_l34; 4317 + break; 4318 + case BOND_XMIT_POLICY_LAYER2: 4319 + default: 4320 + bond->xmit_hash_policy = bond_xmit_hash_policy_l2; 4321 + break; 4322 + } 4323 + } 4324 + 4328 4325 /* 4329 4326 * set bond mode specific net device operations 4330 4327 */ ··· 4357 4322 break; 4358 4323 case BOND_MODE_XOR: 4359 4324 bond_dev->hard_start_xmit = bond_xmit_xor; 4360 - if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER34) 4361 - bond->xmit_hash_policy = bond_xmit_hash_policy_l34; 4362 - else 4363 - bond->xmit_hash_policy = bond_xmit_hash_policy_l2; 4325 + bond_set_xmit_hash_policy(bond); 4364 4326 break; 4365 4327 case BOND_MODE_BROADCAST: 4366 4328 bond_dev->hard_start_xmit = bond_xmit_broadcast; ··· 4365 4333 case BOND_MODE_8023AD: 4366 4334 bond_set_master_3ad_flags(bond); 4367 4335 bond_dev->hard_start_xmit = bond_3ad_xmit_xor; 4368 - if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER34) 4369 - bond->xmit_hash_policy = bond_xmit_hash_policy_l34; 4370 - else 4371 - bond->xmit_hash_policy = bond_xmit_hash_policy_l2; 4336 + bond_set_xmit_hash_policy(bond); 4372 4337 break; 4373 4338 case BOND_MODE_ALB: 4374 4339 bond_set_master_alb_flags(bond); ··· 4527 4498 for (i = 0; tbl[i].modename; i++) { 4528 4499 if ((isdigit(*mode_arg) && 4529 4500 tbl[i].mode == simple_strtol(mode_arg, NULL, 0)) || 4530 - (strncmp(mode_arg, tbl[i].modename, 4531 - strlen(tbl[i].modename)) == 0)) { 4501 + (strcmp(mode_arg, tbl[i].modename) == 0)) { 4532 4502 return tbl[i].mode; 4533 4503 } 4534 4504 }
+2 -2
drivers/net/bonding/bonding.h
··· 22 22 #include "bond_3ad.h" 23 23 #include "bond_alb.h" 24 24 25 - #define DRV_VERSION "3.2.1" 26 - #define DRV_RELDATE "October 15, 2007" 25 + #define DRV_VERSION "3.2.2" 26 + #define DRV_RELDATE "December 6, 2007" 27 27 #define DRV_NAME "bonding" 28 28 #define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" 29 29
+2 -1
include/linux/if_bonding.h
··· 85 85 86 86 /* hashing types */ 87 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 90 91 typedef struct ifbond { 91 92 __s32 bond_mode;