diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/net/bonding/bond_3ad.c | 3 | ||||
| -rw-r--r-- | drivers/net/bonding/bond_main.c | 107 | ||||
| -rw-r--r-- | drivers/net/bonding/bonding.h | 10 |
3 files changed, 107 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; | |||
| 541 | static char *mode = NULL; | 552 | static char *mode = NULL; |
| 542 | static char *primary = NULL; | 553 | static char *primary = NULL; |
| 543 | static char *lacp_rate = NULL; | 554 | static char *lacp_rate = NULL; |
| 555 | static char *xmit_hash_policy = NULL; | ||
| 544 | static int arp_interval = BOND_LINK_ARP_INTERV; | 556 | static int arp_interval = BOND_LINK_ARP_INTERV; |
| 545 | static char *arp_ip_target[BOND_MAX_ARP_TARGETS] = { NULL, }; | 557 | static char *arp_ip_target[BOND_MAX_ARP_TARGETS] = { NULL, }; |
| 546 | 558 | ||
| @@ -560,6 +572,8 @@ module_param(primary, charp, 0); | |||
| 560 | MODULE_PARM_DESC(primary, "Primary network device to use"); | 572 | MODULE_PARM_DESC(primary, "Primary network device to use"); |
| 561 | module_param(lacp_rate, charp, 0); | 573 | module_param(lacp_rate, charp, 0); |
| 562 | MODULE_PARM_DESC(lacp_rate, "LACPDU tx rate to request from 802.3ad partner (slow/fast)"); | 574 | MODULE_PARM_DESC(lacp_rate, "LACPDU tx rate to request from 802.3ad partner (slow/fast)"); |
| 575 | module_param(xmit_hash_policy, charp, 0); | ||
| 576 | MODULE_PARM_DESC(xmit_hash_policy, "XOR hashing method : 0 for layer 2 (default), 1 for layer 3+4"); | ||
| 563 | module_param(arp_interval, int, 0); | 577 | module_param(arp_interval, int, 0); |
| 564 | MODULE_PARM_DESC(arp_interval, "arp interval in milliseconds"); | 578 | MODULE_PARM_DESC(arp_interval, "arp interval in milliseconds"); |
| 565 | module_param_array(arp_ip_target, charp, NULL, 0); | 579 | module_param_array(arp_ip_target, charp, NULL, 0); |
| @@ -579,6 +593,7 @@ static struct proc_dir_entry *bond_proc_dir = NULL; | |||
| 579 | static u32 arp_target[BOND_MAX_ARP_TARGETS] = { 0, } ; | 593 | static u32 arp_target[BOND_MAX_ARP_TARGETS] = { 0, } ; |
| 580 | static int arp_ip_count = 0; | 594 | static int arp_ip_count = 0; |
| 581 | static int bond_mode = BOND_MODE_ROUNDROBIN; | 595 | static int bond_mode = BOND_MODE_ROUNDROBIN; |
| 596 | static int xmit_hashtype= BOND_XMIT_POLICY_LAYER2; | ||
| 582 | static int lacp_fast = 0; | 597 | static int lacp_fast = 0; |
| 583 | static int app_abi_ver = 0; | 598 | static int app_abi_ver = 0; |
| 584 | static int orig_app_abi_ver = -1; /* This is used to save the first ABI version | 599 | static 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 | |||
| 592 | struct bond_parm_tbl { | 606 | struct 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 | ||
| 628 | static 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 | ||
| 616 | static inline void bond_set_mode_ops(struct net_device *bond_dev, int mode); | 636 | static inline void bond_set_mode_ops(struct bonding *bond, int mode); |
| 617 | static void bond_send_gratuitous_arp(struct bonding *bond); | 637 | static 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 | */ | ||
| 3754 | static 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 | */ | ||
| 3779 | static 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 | ||
| 3729 | static int bond_open(struct net_device *bond_dev) | 3789 | static 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 | */ |
| 4317 | static int bond_xmit_xor(struct sk_buff *skb, struct net_device *bond_dev) | 4377 | static 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 | */ |
| 4428 | static inline void bond_set_mode_ops(struct net_device *bond_dev, int mode) | 4487 | static 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 | ||
| 138 | struct bond_params { | 142 | struct 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; |
