Commit 6f6652be authored by Jay Vosburgh's avatar Jay Vosburgh Committed by Jeff Garzik

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: default avatar"Glenn Griffin" <ggriffin.kernel@gmail.com>
Signed-off-by: default avatarJay Vosburgh <fubar@us.ibm.com>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent b63bb739
...@@ -554,6 +554,30 @@ xmit_hash_policy ...@@ -554,6 +554,30 @@ xmit_hash_policy
This algorithm is 802.3ad compliant. 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 layer3+4
This policy uses upper layer protocol information, This policy uses upper layer protocol information,
...@@ -589,8 +613,9 @@ xmit_hash_policy ...@@ -589,8 +613,9 @@ xmit_hash_policy
or may not tolerate this noncompliance. or may not tolerate this noncompliance.
The default value is layer2. This option was added in bonding The default value is layer2. This option was added in bonding
version 2.6.3. In earlier versions of bonding, this parameter does version 2.6.3. In earlier versions of bonding, this parameter
not exist, and the layer2 policy is the only policy. 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 3. Configuring Bonding Devices
......
...@@ -175,6 +175,7 @@ struct bond_parm_tbl bond_mode_tbl[] = { ...@@ -175,6 +175,7 @@ struct bond_parm_tbl bond_mode_tbl[] = {
struct bond_parm_tbl xmit_hashtype_tbl[] = { struct bond_parm_tbl xmit_hashtype_tbl[] = {
{ "layer2", BOND_XMIT_POLICY_LAYER2}, { "layer2", BOND_XMIT_POLICY_LAYER2},
{ "layer3+4", BOND_XMIT_POLICY_LAYER34}, { "layer3+4", BOND_XMIT_POLICY_LAYER34},
{ "layer2+3", BOND_XMIT_POLICY_LAYER23},
{ NULL, -1}, { NULL, -1},
}; };
...@@ -3604,6 +3605,24 @@ void bond_unregister_arp(struct bonding *bond) ...@@ -3604,6 +3605,24 @@ void bond_unregister_arp(struct bonding *bond)
/*---------------------------- Hashing Policies -----------------------------*/ /*---------------------------- 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 * 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 * the packet is a frag or not TCP or UDP, just use layer 3 data. If it is
...@@ -4306,6 +4325,22 @@ static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev) ...@@ -4306,6 +4325,22 @@ static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev)
/*------------------------- Device initialization ---------------------------*/ /*------------------------- 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 * set bond mode specific net device operations
*/ */
...@@ -4322,10 +4357,7 @@ void bond_set_mode_ops(struct bonding *bond, int mode) ...@@ -4322,10 +4357,7 @@ void bond_set_mode_ops(struct bonding *bond, int mode)
break; break;
case BOND_MODE_XOR: case BOND_MODE_XOR:
bond_dev->hard_start_xmit = bond_xmit_xor; bond_dev->hard_start_xmit = bond_xmit_xor;
if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER34) bond_set_xmit_hash_policy(bond);
bond->xmit_hash_policy = bond_xmit_hash_policy_l34;
else
bond->xmit_hash_policy = bond_xmit_hash_policy_l2;
break; break;
case BOND_MODE_BROADCAST: case BOND_MODE_BROADCAST:
bond_dev->hard_start_xmit = bond_xmit_broadcast; bond_dev->hard_start_xmit = bond_xmit_broadcast;
...@@ -4333,10 +4365,7 @@ void bond_set_mode_ops(struct bonding *bond, int mode) ...@@ -4333,10 +4365,7 @@ void bond_set_mode_ops(struct bonding *bond, int mode)
case BOND_MODE_8023AD: case BOND_MODE_8023AD:
bond_set_master_3ad_flags(bond); bond_set_master_3ad_flags(bond);
bond_dev->hard_start_xmit = bond_3ad_xmit_xor; bond_dev->hard_start_xmit = bond_3ad_xmit_xor;
if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER34) bond_set_xmit_hash_policy(bond);
bond->xmit_hash_policy = bond_xmit_hash_policy_l34;
else
bond->xmit_hash_policy = bond_xmit_hash_policy_l2;
break; break;
case BOND_MODE_ALB: case BOND_MODE_ALB:
bond_set_master_alb_flags(bond); bond_set_master_alb_flags(bond);
...@@ -4498,8 +4527,7 @@ int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl) ...@@ -4498,8 +4527,7 @@ int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl)
for (i = 0; tbl[i].modename; i++) { for (i = 0; tbl[i].modename; i++) {
if ((isdigit(*mode_arg) && if ((isdigit(*mode_arg) &&
tbl[i].mode == simple_strtol(mode_arg, NULL, 0)) || tbl[i].mode == simple_strtol(mode_arg, NULL, 0)) ||
(strncmp(mode_arg, tbl[i].modename, (strcmp(mode_arg, tbl[i].modename) == 0)) {
strlen(tbl[i].modename)) == 0)) {
return tbl[i].mode; return tbl[i].mode;
} }
} }
......
...@@ -22,8 +22,8 @@ ...@@ -22,8 +22,8 @@
#include "bond_3ad.h" #include "bond_3ad.h"
#include "bond_alb.h" #include "bond_alb.h"
#define DRV_VERSION "3.2.1" #define DRV_VERSION "3.2.2"
#define DRV_RELDATE "October 15, 2007" #define DRV_RELDATE "December 6, 2007"
#define DRV_NAME "bonding" #define DRV_NAME "bonding"
#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" #define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"
......
...@@ -85,7 +85,8 @@ ...@@ -85,7 +85,8 @@
/* hashing types */ /* hashing types */
#define BOND_XMIT_POLICY_LAYER2 0 /* layer 2 (MAC only), default */ #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 { typedef struct ifbond {
__s32 bond_mode; __s32 bond_mode;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment