mirror of
https://github.com/torvalds/linux.git
synced 2024-11-27 06:31:52 +00:00
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>
This commit is contained in:
parent
b63bb739a1
commit
6f6652be18
@ -554,6 +554,30 @@ xmit_hash_policy
|
||||
|
||||
This algorithm is 802.3ad compliant.
|
||||
|
||||
layer2+3
|
||||
|
||||
This policy uses a combination of layer2 and layer3
|
||||
protocol information to generate the hash.
|
||||
|
||||
Uses XOR of hardware MAC addresses and IP addresses to
|
||||
generate the hash. The formula is
|
||||
|
||||
(((source IP XOR dest IP) AND 0xffff) XOR
|
||||
( source MAC XOR destination MAC ))
|
||||
modulo slave count
|
||||
|
||||
This algorithm will place all traffic to a particular
|
||||
network peer on the same slave. For non-IP traffic,
|
||||
the formula is the same as for the layer2 transmit
|
||||
hash policy.
|
||||
|
||||
This policy is intended to provide a more balanced
|
||||
distribution of traffic than layer2 alone, especially
|
||||
in environments where a layer3 gateway device is
|
||||
required to reach most destinations.
|
||||
|
||||
This algorithm is 802.3ad complient.
|
||||
|
||||
layer3+4
|
||||
|
||||
This policy uses upper layer protocol information,
|
||||
@ -589,8 +613,9 @@ xmit_hash_policy
|
||||
or may not tolerate this noncompliance.
|
||||
|
||||
The default value is layer2. This option was added in bonding
|
||||
version 2.6.3. In earlier versions of bonding, this parameter does
|
||||
not exist, and the layer2 policy is the only policy.
|
||||
version 2.6.3. In earlier versions of bonding, this parameter
|
||||
does not exist, and the layer2 policy is the only policy. The
|
||||
layer2+3 value was added for bonding version 3.2.2.
|
||||
|
||||
|
||||
3. Configuring Bonding Devices
|
||||
|
@ -175,6 +175,7 @@ struct bond_parm_tbl bond_mode_tbl[] = {
|
||||
struct bond_parm_tbl xmit_hashtype_tbl[] = {
|
||||
{ "layer2", BOND_XMIT_POLICY_LAYER2},
|
||||
{ "layer3+4", BOND_XMIT_POLICY_LAYER34},
|
||||
{ "layer2+3", BOND_XMIT_POLICY_LAYER23},
|
||||
{ NULL, -1},
|
||||
};
|
||||
|
||||
@ -3604,6 +3605,24 @@ void bond_unregister_arp(struct bonding *bond)
|
||||
|
||||
/*---------------------------- Hashing Policies -----------------------------*/
|
||||
|
||||
/*
|
||||
* Hash for the output device based upon layer 2 and layer 3 data. If
|
||||
* the packet is not IP mimic bond_xmit_hash_policy_l2()
|
||||
*/
|
||||
static int bond_xmit_hash_policy_l23(struct sk_buff *skb,
|
||||
struct net_device *bond_dev, int count)
|
||||
{
|
||||
struct ethhdr *data = (struct ethhdr *)skb->data;
|
||||
struct iphdr *iph = ip_hdr(skb);
|
||||
|
||||
if (skb->protocol == __constant_htons(ETH_P_IP)) {
|
||||
return ((ntohl(iph->saddr ^ iph->daddr) & 0xffff) ^
|
||||
(data->h_dest[5] ^ bond_dev->dev_addr[5])) % count;
|
||||
}
|
||||
|
||||
return (data->h_dest[5] ^ bond_dev->dev_addr[5]) % count;
|
||||
}
|
||||
|
||||
/*
|
||||
* Hash for the output device based upon layer 3 and layer 4 data. If
|
||||
* the packet is a frag or not TCP or UDP, just use layer 3 data. If it is
|
||||
@ -4306,6 +4325,22 @@ out:
|
||||
|
||||
/*------------------------- Device initialization ---------------------------*/
|
||||
|
||||
static void bond_set_xmit_hash_policy(struct bonding *bond)
|
||||
{
|
||||
switch (bond->params.xmit_policy) {
|
||||
case BOND_XMIT_POLICY_LAYER23:
|
||||
bond->xmit_hash_policy = bond_xmit_hash_policy_l23;
|
||||
break;
|
||||
case BOND_XMIT_POLICY_LAYER34:
|
||||
bond->xmit_hash_policy = bond_xmit_hash_policy_l34;
|
||||
break;
|
||||
case BOND_XMIT_POLICY_LAYER2:
|
||||
default:
|
||||
bond->xmit_hash_policy = bond_xmit_hash_policy_l2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* set bond mode specific net device operations
|
||||
*/
|
||||
@ -4322,10 +4357,7 @@ void bond_set_mode_ops(struct bonding *bond, int mode)
|
||||
break;
|
||||
case BOND_MODE_XOR:
|
||||
bond_dev->hard_start_xmit = bond_xmit_xor;
|
||||
if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER34)
|
||||
bond->xmit_hash_policy = bond_xmit_hash_policy_l34;
|
||||
else
|
||||
bond->xmit_hash_policy = bond_xmit_hash_policy_l2;
|
||||
bond_set_xmit_hash_policy(bond);
|
||||
break;
|
||||
case BOND_MODE_BROADCAST:
|
||||
bond_dev->hard_start_xmit = bond_xmit_broadcast;
|
||||
@ -4333,10 +4365,7 @@ void bond_set_mode_ops(struct bonding *bond, int mode)
|
||||
case BOND_MODE_8023AD:
|
||||
bond_set_master_3ad_flags(bond);
|
||||
bond_dev->hard_start_xmit = bond_3ad_xmit_xor;
|
||||
if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER34)
|
||||
bond->xmit_hash_policy = bond_xmit_hash_policy_l34;
|
||||
else
|
||||
bond->xmit_hash_policy = bond_xmit_hash_policy_l2;
|
||||
bond_set_xmit_hash_policy(bond);
|
||||
break;
|
||||
case BOND_MODE_ALB:
|
||||
bond_set_master_alb_flags(bond);
|
||||
@ -4498,8 +4527,7 @@ int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl)
|
||||
for (i = 0; tbl[i].modename; i++) {
|
||||
if ((isdigit(*mode_arg) &&
|
||||
tbl[i].mode == simple_strtol(mode_arg, NULL, 0)) ||
|
||||
(strncmp(mode_arg, tbl[i].modename,
|
||||
strlen(tbl[i].modename)) == 0)) {
|
||||
(strcmp(mode_arg, tbl[i].modename) == 0)) {
|
||||
return tbl[i].mode;
|
||||
}
|
||||
}
|
||||
|
@ -22,8 +22,8 @@
|
||||
#include "bond_3ad.h"
|
||||
#include "bond_alb.h"
|
||||
|
||||
#define DRV_VERSION "3.2.1"
|
||||
#define DRV_RELDATE "October 15, 2007"
|
||||
#define DRV_VERSION "3.2.2"
|
||||
#define DRV_RELDATE "December 6, 2007"
|
||||
#define DRV_NAME "bonding"
|
||||
#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"
|
||||
|
||||
|
@ -85,7 +85,8 @@
|
||||
|
||||
/* hashing types */
|
||||
#define BOND_XMIT_POLICY_LAYER2 0 /* layer 2 (MAC only), default */
|
||||
#define BOND_XMIT_POLICY_LAYER34 1 /* layer 3+4 (IP ^ MAC) */
|
||||
#define BOND_XMIT_POLICY_LAYER34 1 /* layer 3+4 (IP ^ (TCP || UDP)) */
|
||||
#define BOND_XMIT_POLICY_LAYER23 2 /* layer 2+3 (IP ^ MAC) */
|
||||
|
||||
typedef struct ifbond {
|
||||
__s32 bond_mode;
|
||||
|
Loading…
Reference in New Issue
Block a user