aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Vosburgh <fubar@us.ibm.com>2005-06-26 17:54:11 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-06-26 17:54:11 -0400
commit169a3e66637c667b43dab7c319ffd5c99804cad8 (patch)
treef10f7c82ca44b871ae1391c5a3d35a65c463fc9b
parentc3ade5cad07f4d67f2e16a28f3c73d9483a55e0e (diff)
bonding: xor/802.3ad improved slave hash
Add support for alternate slave selection algorithms to bonding balance-xor and 802.3ad modes. Default mode (what we have now: xor of MAC addresses) is "layer2", new choice is "layer3+4", using IP and port information for hashing to select peer. Originally submitted by Jason Gabler for balance-xor mode; modified by Jay Vosburgh to additionally support 802.3ad mode. Jason's original comment is as follows: The attached patch to the Linux Etherchannel Bonding driver modifies the driver's "balance-xor" mode as follows: - alternate hashing policy support for mode 2 * Added kernel parameter "xmit_policy" to allow the specification of different hashing policies for mode 2. The original mode 2 policy is the default, now found in xmit_hash_policy_layer2(). * Added xmit_hash_policy_layer34() This patch was inspired by hashing policies implemented by Cisco, Foundry and IBM, which are explained in Foundry documentation found at: http://www.foundrynet.com/services/documentation/sribcg/Trunking.html#112750 Signed-off-by: Jason Gabler <jygabler@lbl.gov> Signed-off-by: Jay Vosburgh <fubar@us.ibm.com>
-rw-r--r--drivers/net/bonding/bond_3ad.c3
-rw-r--r--drivers/net/bonding/bond_main.c107
-rw-r--r--drivers/net/bonding/bonding.h10
-rw-r--r--include/linux/if_bonding.h7
4 files changed, 114 insertions, 13 deletions
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 6233c4ffb805..a2e8dda5afac 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -2346,7 +2346,6 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
2346{ 2346{
2347 struct slave *slave, *start_at; 2347 struct slave *slave, *start_at;
2348 struct bonding *bond = dev->priv; 2348 struct bonding *bond = dev->priv;
2349 struct ethhdr *data = (struct ethhdr *)skb->data;
2350 int slave_agg_no; 2349 int slave_agg_no;
2351 int slaves_in_agg; 2350 int slaves_in_agg;
2352 int agg_id; 2351 int agg_id;
@@ -2377,7 +2376,7 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
2377 goto out; 2376 goto out;
2378 } 2377 }
2379 2378
2380 slave_agg_no = (data->h_dest[5]^bond->dev->dev_addr[5]) % slaves_in_agg; 2379 slave_agg_no = bond->xmit_hash_policy(skb, dev, slaves_in_agg);
2381 2380
2382 bond_for_each_slave(bond, slave, i) { 2381 bond_for_each_slave(bond, slave, i) {
2383 struct aggregator *agg = SLAVE_AD_INFO(slave).port.aggregator; 2382 struct aggregator *agg = SLAVE_AD_INFO(slave).port.aggregator;
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 545f6fe025a8..2c930da90a85 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -479,6 +479,14 @@
479 * - Support for generating gratuitous ARPs in active-backup mode. 479 * - Support for generating gratuitous ARPs in active-backup mode.
480 * Includes support for VLAN tagging all bonding-generated ARPs 480 * Includes support for VLAN tagging all bonding-generated ARPs
481 * as needed. Set version to 2.6.2. 481 * as needed. Set version to 2.6.2.
482 * 2005/06/08 - Jason Gabler <jygabler at lbl dot gov>
483 * - alternate hashing policy support for mode 2
484 * * Added kernel parameter "xmit_hash_policy" to allow the selection
485 * of different hashing policies for mode 2. The original mode 2
486 * policy is the default, now found in xmit_hash_policy_layer2().
487 * * Added xmit_hash_policy_layer34()
488 * - Modified by Jay Vosburgh <fubar@us.ibm.com> to also support mode 4.
489 * Set version to 2.6.3.
482 */ 490 */
483 491
484//#define BONDING_DEBUG 1 492//#define BONDING_DEBUG 1
@@ -493,7 +501,10 @@
493#include <linux/ptrace.h> 501#include <linux/ptrace.h>
494#include <linux/ioport.h> 502#include <linux/ioport.h>
495#include <linux/in.h> 503#include <linux/in.h>
504#include <net/ip.h>
496#include <linux/ip.h> 505#include <linux/ip.h>
506#include <linux/tcp.h>
507#include <linux/udp.h>
497#include <linux/slab.h> 508#include <linux/slab.h>
498#include <linux/string.h> 509#include <linux/string.h>
499#include <linux/init.h> 510#include <linux/init.h>
@@ -541,6 +552,7 @@ static int use_carrier = 1;
541static char *mode = NULL; 552static char *mode = NULL;
542static char *primary = NULL; 553static char *primary = NULL;
543static char *lacp_rate = NULL; 554static char *lacp_rate = NULL;
555static char *xmit_hash_policy = NULL;
544static int arp_interval = BOND_LINK_ARP_INTERV; 556static int arp_interval = BOND_LINK_ARP_INTERV;
545static char *arp_ip_target[BOND_MAX_ARP_TARGETS] = { NULL, }; 557static char *arp_ip_target[BOND_MAX_ARP_TARGETS] = { NULL, };
546 558
@@ -560,6 +572,8 @@ module_param(primary, charp, 0);
560MODULE_PARM_DESC(primary, "Primary network device to use"); 572MODULE_PARM_DESC(primary, "Primary network device to use");
561module_param(lacp_rate, charp, 0); 573module_param(lacp_rate, charp, 0);
562MODULE_PARM_DESC(lacp_rate, "LACPDU tx rate to request from 802.3ad partner (slow/fast)"); 574MODULE_PARM_DESC(lacp_rate, "LACPDU tx rate to request from 802.3ad partner (slow/fast)");
575module_param(xmit_hash_policy, charp, 0);
576MODULE_PARM_DESC(xmit_hash_policy, "XOR hashing method : 0 for layer 2 (default), 1 for layer 3+4");
563module_param(arp_interval, int, 0); 577module_param(arp_interval, int, 0);
564MODULE_PARM_DESC(arp_interval, "arp interval in milliseconds"); 578MODULE_PARM_DESC(arp_interval, "arp interval in milliseconds");
565module_param_array(arp_ip_target, charp, NULL, 0); 579module_param_array(arp_ip_target, charp, NULL, 0);
@@ -579,6 +593,7 @@ static struct proc_dir_entry *bond_proc_dir = NULL;
579static u32 arp_target[BOND_MAX_ARP_TARGETS] = { 0, } ; 593static u32 arp_target[BOND_MAX_ARP_TARGETS] = { 0, } ;
580static int arp_ip_count = 0; 594static int arp_ip_count = 0;
581static int bond_mode = BOND_MODE_ROUNDROBIN; 595static int bond_mode = BOND_MODE_ROUNDROBIN;
596static int xmit_hashtype= BOND_XMIT_POLICY_LAYER2;
582static int lacp_fast = 0; 597static int lacp_fast = 0;
583static int app_abi_ver = 0; 598static int app_abi_ver = 0;
584static int orig_app_abi_ver = -1; /* This is used to save the first ABI version 599static int orig_app_abi_ver = -1; /* This is used to save the first ABI version
@@ -588,7 +603,6 @@ static int orig_app_abi_ver = -1; /* This is used to save the first ABI version
588 * command comes from an application using 603 * command comes from an application using
589 * another ABI version. 604 * another ABI version.
590 */ 605 */
591
592struct bond_parm_tbl { 606struct bond_parm_tbl {
593 char *modename; 607 char *modename;
594 int mode; 608 int mode;
@@ -611,9 +625,15 @@ static struct bond_parm_tbl bond_mode_tbl[] = {
611{ NULL, -1}, 625{ NULL, -1},
612}; 626};
613 627
628static struct bond_parm_tbl xmit_hashtype_tbl[] = {
629{ "layer2", BOND_XMIT_POLICY_LAYER2},
630{ "layer3+4", BOND_XMIT_POLICY_LAYER34},
631{ NULL, -1},
632};
633
614/*-------------------------- Forward declarations ---------------------------*/ 634/*-------------------------- Forward declarations ---------------------------*/
615 635
616static inline void bond_set_mode_ops(struct net_device *bond_dev, int mode); 636static inline void bond_set_mode_ops(struct bonding *bond, int mode);
617static void bond_send_gratuitous_arp(struct bonding *bond); 637static void bond_send_gratuitous_arp(struct bonding *bond);
618 638
619/*---------------------------- General routines -----------------------------*/ 639/*---------------------------- General routines -----------------------------*/
@@ -3724,6 +3744,46 @@ static void bond_unregister_lacpdu(struct bonding *bond)
3724 dev_remove_pack(&(BOND_AD_INFO(bond).ad_pkt_type)); 3744 dev_remove_pack(&(BOND_AD_INFO(bond).ad_pkt_type));
3725} 3745}
3726 3746
3747/*---------------------------- Hashing Policies -----------------------------*/
3748
3749/*
3750 * Hash for the the output device based upon layer 3 and layer 4 data. If
3751 * the packet is a frag or not TCP or UDP, just use layer 3 data. If it is
3752 * altogether not IP, mimic bond_xmit_hash_policy_l2()
3753 */
3754static int bond_xmit_hash_policy_l34(struct sk_buff *skb,
3755 struct net_device *bond_dev, int count)
3756{
3757 struct ethhdr *data = (struct ethhdr *)skb->data;
3758 struct iphdr *iph = skb->nh.iph;
3759 u16 *layer4hdr = (u16 *)((u32 *)iph + iph->ihl);
3760 int layer4_xor = 0;
3761
3762 if (skb->protocol == __constant_htons(ETH_P_IP)) {
3763 if (!(iph->frag_off & __constant_htons(IP_MF|IP_OFFSET)) &&
3764 (iph->protocol == IPPROTO_TCP ||
3765 iph->protocol == IPPROTO_UDP)) {
3766 layer4_xor = htons((*layer4hdr ^ *(layer4hdr + 1)));
3767 }
3768 return (layer4_xor ^
3769 ((ntohl(iph->saddr ^ iph->daddr)) & 0xffff)) % count;
3770
3771 }
3772
3773 return (data->h_dest[5] ^ bond_dev->dev_addr[5]) % count;
3774}
3775
3776/*
3777 * Hash for the output device based upon layer 2 data
3778 */
3779static int bond_xmit_hash_policy_l2(struct sk_buff *skb,
3780 struct net_device *bond_dev, int count)
3781{
3782 struct ethhdr *data = (struct ethhdr *)skb->data;
3783
3784 return (data->h_dest[5] ^ bond_dev->dev_addr[5]) % count;
3785}
3786
3727/*-------------------------- Device entry points ----------------------------*/ 3787/*-------------------------- Device entry points ----------------------------*/
3728 3788
3729static int bond_open(struct net_device *bond_dev) 3789static int bond_open(struct net_device *bond_dev)
@@ -4310,14 +4370,13 @@ out:
4310} 4370}
4311 4371
4312/* 4372/*
4313 * in XOR mode, we determine the output device by performing xor on 4373 * In bond_xmit_xor() , we determine the output device by using a pre-
4314 * the source and destination hw adresses. If this device is not 4374 * determined xmit_hash_policy(), If the selected device is not enabled,
4315 * enabled, find the next slave following this xor slave. 4375 * find the next active slave.
4316 */ 4376 */
4317static int bond_xmit_xor(struct sk_buff *skb, struct net_device *bond_dev) 4377static int bond_xmit_xor(struct sk_buff *skb, struct net_device *bond_dev)
4318{ 4378{
4319 struct bonding *bond = bond_dev->priv; 4379 struct bonding *bond = bond_dev->priv;
4320 struct ethhdr *data = (struct ethhdr *)skb->data;
4321 struct slave *slave, *start_at; 4380 struct slave *slave, *start_at;
4322 int slave_no; 4381 int slave_no;
4323 int i; 4382 int i;
@@ -4329,7 +4388,7 @@ static int bond_xmit_xor(struct sk_buff *skb, struct net_device *bond_dev)
4329 goto out; 4388 goto out;
4330 } 4389 }
4331 4390
4332 slave_no = (data->h_dest[5]^bond_dev->dev_addr[5]) % bond->slave_cnt; 4391 slave_no = bond->xmit_hash_policy(skb, bond_dev, bond->slave_cnt);
4333 4392
4334 bond_for_each_slave(bond, slave, i) { 4393 bond_for_each_slave(bond, slave, i) {
4335 slave_no--; 4394 slave_no--;
@@ -4425,8 +4484,10 @@ out:
4425/* 4484/*
4426 * set bond mode specific net device operations 4485 * set bond mode specific net device operations
4427 */ 4486 */
4428static inline void bond_set_mode_ops(struct net_device *bond_dev, int mode) 4487static inline void bond_set_mode_ops(struct bonding *bond, int mode)
4429{ 4488{
4489 struct net_device *bond_dev = bond->dev;
4490
4430 switch (mode) { 4491 switch (mode) {
4431 case BOND_MODE_ROUNDROBIN: 4492 case BOND_MODE_ROUNDROBIN:
4432 bond_dev->hard_start_xmit = bond_xmit_roundrobin; 4493 bond_dev->hard_start_xmit = bond_xmit_roundrobin;
@@ -4436,12 +4497,20 @@ static inline void bond_set_mode_ops(struct net_device *bond_dev, int mode)
4436 break; 4497 break;
4437 case BOND_MODE_XOR: 4498 case BOND_MODE_XOR:
4438 bond_dev->hard_start_xmit = bond_xmit_xor; 4499 bond_dev->hard_start_xmit = bond_xmit_xor;
4500 if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER34)
4501 bond->xmit_hash_policy = bond_xmit_hash_policy_l34;
4502 else
4503 bond->xmit_hash_policy = bond_xmit_hash_policy_l2;
4439 break; 4504 break;
4440 case BOND_MODE_BROADCAST: 4505 case BOND_MODE_BROADCAST:
4441 bond_dev->hard_start_xmit = bond_xmit_broadcast; 4506 bond_dev->hard_start_xmit = bond_xmit_broadcast;
4442 break; 4507 break;
4443 case BOND_MODE_8023AD: 4508 case BOND_MODE_8023AD:
4444 bond_dev->hard_start_xmit = bond_3ad_xmit_xor; 4509 bond_dev->hard_start_xmit = bond_3ad_xmit_xor;
4510 if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER34)
4511 bond->xmit_hash_policy = bond_xmit_hash_policy_l34;
4512 else
4513 bond->xmit_hash_policy = bond_xmit_hash_policy_l2;
4445 break; 4514 break;
4446 case BOND_MODE_TLB: 4515 case BOND_MODE_TLB:
4447 case BOND_MODE_ALB: 4516 case BOND_MODE_ALB:
@@ -4490,7 +4559,7 @@ static int __init bond_init(struct net_device *bond_dev, struct bond_params *par
4490 bond_dev->change_mtu = bond_change_mtu; 4559 bond_dev->change_mtu = bond_change_mtu;
4491 bond_dev->set_mac_address = bond_set_mac_address; 4560 bond_dev->set_mac_address = bond_set_mac_address;
4492 4561
4493 bond_set_mode_ops(bond_dev, bond->params.mode); 4562 bond_set_mode_ops(bond, bond->params.mode);
4494 4563
4495 bond_dev->destructor = free_netdev; 4564 bond_dev->destructor = free_netdev;
4496 4565
@@ -4601,6 +4670,25 @@ static int bond_check_params(struct bond_params *params)
4601 } 4670 }
4602 } 4671 }
4603 4672
4673 if (xmit_hash_policy) {
4674 if ((bond_mode != BOND_MODE_XOR) &&
4675 (bond_mode != BOND_MODE_8023AD)) {
4676 printk(KERN_INFO DRV_NAME
4677 ": xor_mode param is irrelevant in mode %s\n",
4678 bond_mode_name(bond_mode));
4679 } else {
4680 xmit_hashtype = bond_parse_parm(xmit_hash_policy,
4681 xmit_hashtype_tbl);
4682 if (xmit_hashtype == -1) {
4683 printk(KERN_ERR DRV_NAME
4684 ": Error: Invalid xmit_hash_policy \"%s\"\n",
4685 xmit_hash_policy == NULL ? "NULL" :
4686 xmit_hash_policy);
4687 return -EINVAL;
4688 }
4689 }
4690 }
4691
4604 if (lacp_rate) { 4692 if (lacp_rate) {
4605 if (bond_mode != BOND_MODE_8023AD) { 4693 if (bond_mode != BOND_MODE_8023AD) {
4606 printk(KERN_INFO DRV_NAME 4694 printk(KERN_INFO DRV_NAME
@@ -4812,6 +4900,7 @@ static int bond_check_params(struct bond_params *params)
4812 4900
4813 /* fill params struct with the proper values */ 4901 /* fill params struct with the proper values */
4814 params->mode = bond_mode; 4902 params->mode = bond_mode;
4903 params->xmit_policy = xmit_hashtype;
4815 params->miimon = miimon; 4904 params->miimon = miimon;
4816 params->arp_interval = arp_interval; 4905 params->arp_interval = arp_interval;
4817 params->updelay = updelay; 4906 params->updelay = updelay;
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 6558af22eda4..d27f377b3eeb 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -25,6 +25,10 @@
25 * 25 *
26 * 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com> 26 * 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com>
27 * - Code cleanup and style changes 27 * - Code cleanup and style changes
28 *
29 * 2005/05/05 - Jason Gabler <jygabler at lbl dot gov>
30 * - added "xmit_policy" kernel parameter for alternate hashing policy
31 * support for mode 2
28 */ 32 */
29 33
30#ifndef _LINUX_BONDING_H 34#ifndef _LINUX_BONDING_H
@@ -36,8 +40,8 @@
36#include "bond_3ad.h" 40#include "bond_3ad.h"
37#include "bond_alb.h" 41#include "bond_alb.h"
38 42
39#define DRV_VERSION "2.6.2" 43#define DRV_VERSION "2.6.3"
40#define DRV_RELDATE "June 5, 2005" 44#define DRV_RELDATE "June 8, 2005"
41#define DRV_NAME "bonding" 45#define DRV_NAME "bonding"
42#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" 46#define DRV_DESCRIPTION "Ethernet Channel Bonding Driver"
43 47
@@ -137,6 +141,7 @@
137 141
138struct bond_params { 142struct bond_params {
139 int mode; 143 int mode;
144 int xmit_policy;
140 int miimon; 145 int miimon;
141 int arp_interval; 146 int arp_interval;
142 int use_carrier; 147 int use_carrier;
@@ -198,6 +203,7 @@ struct bonding {
198#endif /* CONFIG_PROC_FS */ 203#endif /* CONFIG_PROC_FS */
199 struct list_head bond_list; 204 struct list_head bond_list;
200 struct dev_mc_list *mc_list; 205 struct dev_mc_list *mc_list;
206 int (*xmit_hash_policy)(struct sk_buff *, struct net_device *, int);
201 u32 master_ip; 207 u32 master_ip;
202 u16 flags; 208 u16 flags;
203 struct ad_bond_info ad_info; 209 struct ad_bond_info ad_info;
diff --git a/include/linux/if_bonding.h b/include/linux/if_bonding.h
index 57024ce2c74f..84598fa2e9de 100644
--- a/include/linux/if_bonding.h
+++ b/include/linux/if_bonding.h
@@ -35,6 +35,9 @@
35 * 35 *
36 * 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com> 36 * 2003/12/01 - Shmulik Hen <shmulik.hen at intel dot com>
37 * - Code cleanup and style changes 37 * - Code cleanup and style changes
38 *
39 * 2005/05/05 - Jason Gabler <jygabler at lbl dot gov>
40 * - added definitions for various XOR hashing policies
38 */ 41 */
39 42
40#ifndef _LINUX_IF_BONDING_H 43#ifndef _LINUX_IF_BONDING_H
@@ -80,6 +83,10 @@
80 83
81#define BOND_DEFAULT_MAX_BONDS 1 /* Default maximum number of devices to support */ 84#define BOND_DEFAULT_MAX_BONDS 1 /* Default maximum number of devices to support */
82 85
86/* hashing types */
87#define BOND_XMIT_POLICY_LAYER2 0 /* layer 2 (MAC only), default */
88#define BOND_XMIT_POLICY_LAYER34 1 /* layer 3+4 (IP ^ MAC) */
89
83typedef struct ifbond { 90typedef struct ifbond {
84 __s32 bond_mode; 91 __s32 bond_mode;
85 __s32 num_slaves; 92 __s32 num_slaves;